From d79670ab522eb90af60f4c6abda54ea50326c3b3 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Mon, 2 Feb 2026 21:43:54 +0100 Subject: [PATCH] update --- cron-products.php | 22 +- docs/.DS_Store | Bin 6148 -> 0 bytes docs/.htaccess | 10 - docs/CHANGELOG.txt | 4824 --- docs/csv_import/.htaccess | 10 - docs/csv_import/addresses_import.csv | 17 - docs/csv_import/alias_import.csv | 5 - docs/csv_import/categories_import.csv | 4 - docs/csv_import/combinations_import.csv | 28 - docs/csv_import/customers_import.csv | 10 - docs/csv_import/index.php | 35 - docs/csv_import/manufacturers_import.csv | 63 - docs/csv_import/products_import.csv | 8 - docs/csv_import/store_contacts.csv | 6 - docs/csv_import/suppliers_import.csv | 4 - .../supply_orders_details_import.csv | 21 - docs/csv_import/supply_orders_import.csv | 5 - .../nginx_fpm/prestashop-fpm/Dockerfile | 28 - .../prestashop-fpm/prestashop-php.ini | 14 - .../prestashop-nginx/prestashop-nginx.conf | 143 - .../prestashop-nginx-fpm/Dockerfile | 4 - .../prestashop-nginx.conf | 144 - .../prestashop-nginx-fpm/prestashop-php.ini | 14 - docs/docker/prestashopCli.sh | 98 - docs/index.php | 35 - docs/licenses/LICENSE.txt | 89 - docs/licenses/cropper.txt | 12 - docs/licenses/fileuploader.txt | 20 - docs/licenses/fonts/open-sans.txt | 202 - docs/licenses/fonts/ubuntu-condensed.txt | 96 - docs/licenses/index.php | 35 - docs/licenses/php-sql-parser.txt | 12 - docs/licenses/tinymce-smarty-swift.txt | 460 - docs/server_config/nginx.conf.dist | 196 - download/.htaccess | 10 - download/index.php | 35 - firmeslink/.htaccess | 2 - firmeslink/documents/.htaccess | 2 - firmeslink/documents/6/1/5/4/8/61548-2.pdf | Bin 105209 -> 0 bytes firmeslink/documents/6/2/9/2/6/62926-2.pdf | Bin 50805 -> 0 bytes firmeslink/documents/6/4/0/2/2/64022-2.pdf | Bin 45529 -> 0 bytes firmeslink/documents/6/4/0/9/2/64092-2.pdf | Bin 105275 -> 0 bytes firmeslink/documents/6/4/1/3/6/64136-2.pdf | Bin 103405 -> 0 bytes firmeslink/documents/6/4/1/9/3/64193-2.pdf | Bin 51609 -> 0 bytes firmeslink/documents/6/4/2/0/5/64205-2.pdf | Bin 44372 -> 0 bytes firmeslink/documents/6/4/2/0/6/64206-2.pdf | Bin 46416 -> 0 bytes firmeslink/documents/6/4/2/0/9/64209-2.pdf | Bin 104417 -> 0 bytes firmeslink/documents/6/4/2/1/4/64214-2.pdf | Bin 103376 -> 0 bytes firmeslink/documents/6/4/2/7/6/64276-2.pdf | Bin 105363 -> 0 bytes firmeslink/documents/6/4/2/7/7/64277-2.pdf | Bin 129724 -> 0 bytes firmeslink/documents/6/4/2/7/8/64278-2.pdf | Bin 105112 -> 0 bytes firmeslink/documents/index.php | 3 - firmeslink/index.php | 3 - log.txt | 169 - src/.DS_Store | Bin 6148 -> 0 bytes src/.htaccess | 10 - src/Adapter/Addons/AddonsDataProvider.php | 229 - .../Address/AbstractAddressHandler.php | 95 - .../AbstractCustomerAddressHandler.php | 60 - .../AbstractManufacturerAddressHandler.php | 59 - .../AddCustomerAddressHandler.php | 93 - .../AddManufacturerAddressHandler.php | 90 - .../BulkDeleteAddressHandler.php | 65 - .../CommandHandler/DeleteAddressHandler.php | 51 - .../CommandHandler/EditCartAddressHandler.php | 172 - .../EditCustomerAddressHandler.php | 169 - .../EditManufacturerAddressHandler.php | 115 - .../EditOrderAddressHandler.php | 188 - .../SetRequiredFieldsForAddressHandler.php | 60 - .../GetCustomerAddressForEditingHandler.php | 100 - ...etManufacturerAddressForEditingHandler.php | 65 - .../GetRequiredFieldsForAddressHandler.php | 50 - src/Adapter/AddressFactory.php | 63 - .../Admin/AbstractAdminQueryBuilder.php | 221 - .../Admin/LegacyBlockHelperSubscriber.php | 68 - .../Admin/NotificationsConfiguration.php | 86 - src/Adapter/Admin/PagePreference.php | 124 - src/Adapter/Admin/UrlGenerator.php | 130 - src/Adapter/Assets/AssetUrlGeneratorTrait.php | 78 - .../Attachment/AbstractAttachmentHandler.php | 150 - .../CommandHandler/AddAttachmentHandler.php | 105 - .../BulkDeleteAttachmentsHandler.php | 65 - .../DeleteAttachmentHandler.php | 54 - .../CommandHandler/EditAttachmentHandler.php | 136 - .../GetAttachmentForEditingHandler.php | 78 - .../QueryHandler/GetAttachmentHandler.php | 72 - .../Attribute/AbstractAttributeHandler.php | 79 - ...minAttributeGeneratorControllerWrapper.php | 131 - .../Attribute/AttributeDataProvider.php | 131 - .../BulkDeleteAttributeHandler.php | 55 - .../CommandHandler/DeleteAttributeHandler.php | 53 - .../AbstractAttributeGroupHandler.php | 79 - .../AttributeGroupViewDataProvider.php | 109 - .../BulkDeleteAttributeGroupHandler.php | 52 - .../DeleteAttributeGroupHandler.php | 54 - src/Adapter/Backup/Backup.php | 108 - src/Adapter/Backup/BackupRemover.php | 49 - src/Adapter/Backup/BackupRepository.php | 62 - src/Adapter/Backup/DatabaseBackupCreator.php | 61 - .../BestSalesProductSearchProvider.php | 116 - src/Adapter/CMS/CMSDataProvider.php | 77 - .../CommandHandler/AbstractCmsPageHandler.php | 87 - .../Page/CommandHandler/AddCmsPageHandler.php | 88 - .../BulkDeleteCmsPageHandler.php | 59 - .../BulkDisableCmsPageHandler.php | 80 - .../BulkEnableCmsPageHandler.php | 76 - .../CommandHandler/DeleteCmsPageHandler.php | 57 - .../CommandHandler/EditCmsPageHandler.php | 121 - .../ToggleCmsPageStatusHandler.php | 57 - .../GetCmsCategoryIdForRedirectionHandler.php | 55 - .../GetCmsPageForEditingHandler.php | 97 - .../CMS/PageCategory/CategoriesProvider.php | 130 - .../AbstractCmsPageCategoryHandler.php | 97 - .../AddCmsPageCategoryHandler.php | 84 - .../BulkDeleteCmsPageCategoryHandler.php | 65 - .../BulkDisableCmsPageCategoryHandler.php | 67 - .../BulkEnableCmsPageCategoryHandler.php | 67 - .../DeleteCmsPageCategoryHandler.php | 63 - .../EditCmsPageCategoryHandler.php | 128 - .../ToggleCmsPageCategoryStatusHandler.php | 63 - ...tCmsPageCategoriesForBreadcrumbHandler.php | 111 - .../GetCmsPageCategoryForEditingHandler.php | 75 - ...etCmsPageCategoryNameForListingHandler.php | 87 - ...eParentCategoryIdForRedirectionHandler.php | 58 - src/Adapter/Cache/CacheAdapter.php | 64 - src/Adapter/Cache/CacheClearer.php | 135 - src/Adapter/Cache/CachingConfiguration.php | 157 - .../Cache/Clearer/ClassIndexCacheClearer.php | 46 - .../Cache/Clearer/MediaCacheClearer.php | 46 - .../Cache/Clearer/SmartyCacheClearer.php | 46 - .../Cache/Clearer/SymfonyCacheClearer.php | 46 - src/Adapter/Cache/Clearer/XmlCacheClearer.php | 46 - .../CombineCompressCacheConfiguration.php | 225 - src/Adapter/Cache/MemcacheServerManager.php | 121 - src/Adapter/CacheManager.php | 47 - src/Adapter/Carrier/CarrierDataProvider.php | 127 - .../Carrier/CarrierOptionsConfiguration.php | 89 - src/Adapter/Carrier/HandlingConfiguration.php | 89 - src/Adapter/Cart/AbstractCartHandler.php | 64 - src/Adapter/Cart/CartPresenter.php | 35 - .../AddCartRuleToCartHandler.php | 133 - .../AddCustomizationHandler.php | 202 - .../AddProductToCartHandler.php | 115 - .../CreateEmptyCustomerCartHandler.php | 90 - .../RemoveCartRuleFromCartHandler.php | 50 - .../RemoveProductFromCartHandler.php | 89 - .../SendCartToCustomerHandler.php | 142 - .../UpdateCartAddressesHandler.php | 88 - .../UpdateCartCarrierHandler.php | 124 - .../UpdateCartCurrencyHandler.php | 107 - .../UpdateCartDeliverySettingsHandler.php | 250 - .../UpdateCartLanguageHandler.php | 99 - .../UpdateProductPriceInCartHandler.php | 83 - .../UpdateProductQuantityInCartHandler.php | 249 - .../Cart/Comparator/CartProductUpdate.php | 142 - .../Comparator/CartProductsComparator.php | 210 - .../GetCartForOrderCreationHandler.php | 559 - .../QueryHandler/GetCartForViewingHandler.php | 314 - .../GetLastEmptyCustomerCartHandler.php | 76 - .../CommandHandler/AddCartRuleHandler.php | 220 - .../LegacyDiscountApplicationType.php | 55 - .../QueryHandler/SearchCartRulesHandler.php | 73 - .../AbstractCatalogPriceRuleHandler.php | 94 - .../AddCatalogPriceRuleHandler.php | 104 - .../BulkDeleteCatalogPriceRuleHandler.php | 52 - .../DeleteCatalogPriceRuleHandler.php | 51 - .../EditCatalogPriceRuleHandler.php | 152 - .../GetCatalogPriceRuleForEditingHandler.php | 72 - .../AdminCategoryControllerWrapper.php | 45 - src/Adapter/Category/CategoryDataProvider.php | 271 - .../CategoryProductSearchProvider.php | 122 - .../Category/CategoryViewDataProvider.php | 113 - .../AbstractDeleteCategoryHandler.php | 75 - .../CommandHandler/AddCategoryHandler.php | 117 - .../CommandHandler/AddRootCategoryHandler.php | 123 - .../BulkDeleteCategoriesHandler.php | 68 - .../BulkUpdateCategoriesStatusHandler.php | 63 - .../DeleteCategoryCoverImageHandler.php | 171 - .../CommandHandler/DeleteCategoryHandler.php | 67 - ...eleteCategoryMenuThumbnailImageHandler.php | 107 - .../CommandHandler/EditCategoryHandler.php | 121 - .../EditRootCategoryHandler.php | 113 - .../SetCategoryIsEnabledHandler.php | 59 - .../UpdateCategoryPositionHandler.php | 77 - .../GetCategoryForEditingHandler.php | 231 - .../GetCategoryIsEnabledHandler.php | 53 - src/Adapter/ClassLang.php | 64 - src/Adapter/CombinationDataProvider.php | 198 - src/Adapter/Configuration.php | 341 - .../CommandHandler/SwitchDebugModeHandler.php | 70 - .../Configuration/KpiConfiguration.php | 55 - .../Configuration/LogsConfiguration.php | 80 - src/Adapter/Configuration/PhpParameters.php | 99 - .../CommandHandler/AddContactHandler.php | 133 - .../CommandHandler/EditContactHandler.php | 158 - .../GetContactForEditingHandler.php | 85 - .../ContainerBuilderExtensionInterface.php | 49 - .../ContainerParametersExtension.php | 91 - .../Container/DoctrineBuilderExtension.php | 73 - src/Adapter/Container/LegacyContainer.php | 41 - .../Container/LegacyContainerBuilder.php | 44 - .../Container/LegacyContainerInterface.php | 41 - src/Adapter/ContainerBuilder.php | 244 - src/Adapter/ContainerFinder.php | 79 - src/Adapter/ContextStateManager.php | 285 - .../Converter/ExcelToCsvFileConverter.php | 95 - src/Adapter/CoreException.php | 34 - src/Adapter/Country/CountryDataProvider.php | 137 - .../Country/CountryRequiredFieldsProvider.php | 68 - .../CountryZipCodeRequirementsProvider.php | 97 - .../GetCountryRequiredFieldsHandler.php | 60 - .../CreditSlipTemplateTypeProvider.php | 44 - .../GetCreditSlipIdsByDateRangeHandler.php | 68 - .../AbstractCurrencyHandler.php | 281 - .../AddOfficialCurrencyHandler.php | 156 - .../AddUnofficialCurrencyHandler.php | 102 - .../CurrencyCommandValidator.php | 164 - .../CommandHandler/DeleteCurrencyHandler.php | 125 - .../EditOfficialCurrencyHandler.php | 85 - .../EditUnofficialCurrencyHandler.php | 99 - .../RefreshExchangeRatesHandler.php | 55 - .../ToggleCurrencyStatusHandler.php | 125 - ...oggleExchangeRateAutomatizationHandler.php | 258 - src/Adapter/Currency/CurrencyDataProvider.php | 173 - src/Adapter/Currency/CurrencyManager.php | 60 - .../GetCurrencyExchangeRateHandler.php | 66 - .../GetCurrencyForEditingHandler.php | 90 - .../GetReferenceCurrencyHandler.php | 107 - .../AbstractCustomerHandler.php | 69 - .../CommandHandler/AddCustomerHandler.php | 153 - .../BulkDeleteCustomerHandler.php | 60 - .../BulkDisableCustomerHandler.php | 54 - .../BulkEnableCustomerHandler.php | 54 - .../CommandHandler/DeleteCustomerHandler.php | 61 - .../CommandHandler/EditCustomerHandler.php | 254 - .../SetPrivateNoteAboutCustomerHandler.php | 56 - .../SetRequiredFieldsForCustomerHandler.php | 52 - .../TransformGuestToCustomerHandler.php | 96 - .../Customer/CustomerConfiguration.php | 93 - src/Adapter/Customer/CustomerDataProvider.php | 128 - src/Adapter/Customer/CustomerDataSource.php | 41 - .../QueryHandler/GetCustomerCartsHandler.php | 95 - .../GetCustomerForAddressCreationHandler.php | 78 - .../GetCustomerForEditingHandler.php | 84 - .../GetCustomerForViewingHandler.php | 601 - .../QueryHandler/GetCustomerOrdersHandler.php | 103 - .../GetRequiredFieldsForCustomerHandler.php | 59 - .../QueryHandler/SearchCustomersHandler.php | 85 - .../AddOrderCustomerMessageHandler.php | 264 - .../ForwardCustomerThreadHandler.php | 337 - .../ReplyToCustomerThreadHandler.php | 174 - .../GetCustomerThreadForViewingHandler.php | 388 - src/Adapter/Database.php | 102 - src/Adapter/Debug/DebugMode.php | 185 - src/Adapter/Debug/DebugModeConfiguration.php | 156 - .../Domain/AbstractObjectModelHandler.php | 164 - .../Email/EmailConfigurationTester.php | 115 - src/Adapter/Email/EmailLogEraser.php | 85 - src/Adapter/Employee/AvatarProvider.php | 57 - .../Employee/ContextEmployeeProvider.php | 96 - src/Adapter/Employee/EmployeeDataProvider.php | 56 - .../Employee/EmployeeFormAccessChecker.php | 104 - src/Adapter/Employee/FormLanguageChanger.php | 62 - .../Employee/NavigationMenuToggler.php | 58 - src/Adapter/EntityMapper.php | 119 - src/Adapter/EntityMetaDataRetriever.php | 60 - src/Adapter/Environment.php | 99 - src/Adapter/Feature/CombinationFeature.php | 87 - .../CommandHandler/AddFeatureHandler.php | 67 - .../CommandHandler/EditFeatureHandler.php | 73 - src/Adapter/Feature/FeatureDataProvider.php | 75 - src/Adapter/Feature/FeatureFeature.php | 87 - src/Adapter/Feature/GroupFeature.php | 87 - src/Adapter/Feature/MultistoreFeature.php | 95 - .../GetFeatureForEditingHandler.php | 57 - src/Adapter/File/HtaccessFileGenerator.php | 87 - src/Adapter/File/RobotsTextFileGenerator.php | 45 - .../File/Uploader/AttachmentFileUploader.php | 149 - .../CarrierForOrderChoiceProvider.php | 79 - .../CategoryTreeChoiceProvider.php | 99 - .../CountryStateByIdChoiceProvider.php | 94 - .../CurrencySymbolByIdChoiceProvider.php | 51 - .../EmployeeNameByIdChoiceProvider.php | 54 - .../GenderByIdChoiceProvider.php | 52 - .../GroupByIdChoiceProvider.php | 83 - .../InstalledPaymentModulesChoiceProvider.php | 56 - .../ManufacturerNameByIdChoiceProvider.php | 61 - .../OrderCountriesChoiceProvider.php | 71 - .../OrderInvoiceByIdChoiceProvider.php | 73 - .../ProfileByIdChoiceProvider.php | 64 - .../ResourcesChoiceProvider.php | 53 - .../ChoiceProvider/RiskByIdChoiceProvider.php | 54 - .../ShopNameByIdChoiceProvider.php | 50 - .../ChoiceProvider/ShopTreeChoiceProvider.php | 77 - .../TaxRuleGroupChoiceProvider.php | 51 - src/Adapter/GeneralConfiguration.php | 88 - .../GeolocationByIpAddressConfiguration.php | 80 - ...ocationIpAddressWhitelistConfiguration.php | 81 - .../GeolocationOptionsConfiguration.php | 86 - .../CategoryForViewAccessibilityChecker.php | 59 - ...teriaWithCategoryParentIdFilterFactory.php | 159 - src/Adapter/Group/GroupDataProvider.php | 59 - .../Group/Provider/DefaultGroupsProvider.php | 95 - src/Adapter/Hook/HookDispatcher.php | 205 - src/Adapter/Hook/HookInformationProvider.php | 71 - src/Adapter/HookManager.php | 86 - src/Adapter/Hosting/HostingInformation.php | 102 - src/Adapter/Image/ImageRetriever.php | 297 - .../Image/Uploader/AbstractImageUploader.php | 173 - .../Uploader/CategoryCoverImageUploader.php | 136 - .../CategoryMenuThumbnailUploader.php | 126 - .../CategoryThumbnailImageUploader.php | 90 - .../Uploader/ManufacturerImageUploader.php | 123 - .../Image/Uploader/SupplierImageUploader.php | 70 - src/Adapter/ImageManager.php | 141 - src/Adapter/Import/CsvFileOpener.php | 97 - src/Adapter/Import/DataMatchSaver.php | 77 - .../Import/Handler/AbstractImportHandler.php | 507 - .../Import/Handler/CategoryImportHandler.php | 553 - .../Import/Handler/ImportHandlerFinder.php | 64 - .../Import/Handler/ProductImportHandler.php | 1420 - src/Adapter/Import/ImageCopier.php | 250 - src/Adapter/Import/ImportDataFormatter.php | 155 - src/Adapter/Import/ImportEntityDeleter.php | 311 - .../Invoice/InvoiceOptionsConfiguration.php | 114 - .../Invoice/InvoiceTemplateTypeProvider.php | 44 - .../Invoice/OrderInvoiceDataProvider.php | 65 - src/Adapter/Kpi/AbandonedCartKpi.php | 64 - src/Adapter/Kpi/AverageCustomerAgeKpi.php | 86 - src/Adapter/Kpi/AverageOrderValueKpi.php | 67 - .../Kpi/AverageProductsInCategoryKpi.php | 92 - src/Adapter/Kpi/ConversionRateKpi.php | 67 - src/Adapter/Kpi/DisabledCategoriesKpi.php | 91 - src/Adapter/Kpi/EmptyCategoriesKpi.php | 100 - src/Adapter/Kpi/EnabledLanguagesKpi.php | 101 - src/Adapter/Kpi/MainCountryKpi.php | 93 - .../Kpi/MostCommonCustomersGenderKpi.php | 90 - src/Adapter/Kpi/NetProfitPerVisitKpi.php | 63 - .../Kpi/NewsletterRegistrationsKpi.php | 91 - src/Adapter/Kpi/OrdersPerCustomerKpi.php | 86 - src/Adapter/Kpi/ShoppingCartTotalKpi.php | 118 - src/Adapter/Kpi/TopCategoryKpi.php | 109 - src/Adapter/Kpi/TranslationsKpi.php | 92 - .../AbstractLanguageHandler.php | 147 - .../CommandHandler/AddLanguageHandler.php | 132 - .../BulkDeleteLanguagesHandler.php | 84 - .../BulkToggleLanguagesStatusHandler.php | 75 - .../CommandHandler/DeleteLanguageHandler.php | 82 - .../CommandHandler/EditLanguageHandler.php | 239 - .../ToggleLanguageStatusHandler.php | 73 - src/Adapter/Language/LanguageActivator.php | 68 - src/Adapter/Language/LanguageCopier.php | 265 - src/Adapter/Language/LanguageDataProvider.php | 101 - .../LanguageFlagThumbnailProvider.php | 77 - src/Adapter/Language/LanguageImageManager.php | 203 - .../Language/LanguagePackInstaller.php | 85 - src/Adapter/Language/LanguageValidator.php | 44 - .../Language/Pack/LanguagePackImporter.php | 110 - .../GetLanguageForEditingHandler.php | 80 - .../Language/RTL/InstalledLanguageChecker.php | 59 - src/Adapter/LegacyContext.php | 346 - src/Adapter/LegacyHookSubscriber.php | 302 - src/Adapter/LegacyLogger.php | 170 - .../Localization/AdvancedConfiguration.php | 87 - src/Adapter/Localization/LegacyTranslator.php | 73 - .../Localization/LocalUnitsConfiguration.php | 93 - .../LocalizationConfiguration.php | 141 - src/Adapter/Mail/MailingInformation.php | 57 - .../MailPartialTemplateRenderer.php | 86 - .../MailPreviewVariablesBuilder.php | 440 - .../MailTemplate/MailTemplateTwigRenderer.php | 188 - .../AbstractManufacturerHandler.php | 64 - .../AbstractManufacturerCommandHandler.php | 77 - .../CommandHandler/AddManufacturerHandler.php | 95 - .../BulkDeleteManufacturerHandler.php | 51 - .../BulkToggleManufacturerStatusHandler.php | 51 - .../DeleteManufacturerHandler.php | 49 - .../EditManufacturerHandler.php | 99 - .../ToggleManufacturerStatusHandler.php | 49 - .../Manufacturer/ManufacturerDataProvider.php | 53 - .../ManufacturerLogoThumbnailProvider.php | 68 - .../ManufacturerProductSearchProvider.php | 102 - .../GetManufacturerForEditingHandler.php | 103 - .../GetManufacturerForViewingHandler.php | 163 - .../Media/MediaServerConfiguration.php | 143 - .../Meta/CommandHandler/AddMetaHandler.php | 174 - .../Meta/CommandHandler/EditMetaHandler.php | 168 - src/Adapter/Meta/MetaDataProvider.php | 143 - src/Adapter/Meta/MetaEraser.php | 81 - .../QueryHandler/GetMetaForEditingHandler.php | 70 - .../GetPagesForLayoutCustomizationHandler.php | 70 - .../Meta/SEOOptionsDataConfiguration.php | 84 - .../Meta/SetUpUrlsDataConfiguration.php | 145 - src/Adapter/Meta/ShopUrlDataConfiguration.php | 134 - .../Meta/UrlSchemaDataConfiguration.php | 137 - .../Module/AdminModuleDataProvider.php | 520 - .../ModuleComplexConfigurationInterface.php | 43 - .../Configuration/ModuleSelfConfigurator.php | 506 - src/Adapter/Module/Module.php | 483 - src/Adapter/Module/ModuleDataProvider.php | 306 - src/Adapter/Module/ModuleDataUpdater.php | 122 - src/Adapter/Module/ModulePresenter.php | 35 - src/Adapter/Module/ModuleZip.php | 104 - src/Adapter/Module/ModuleZipManager.php | 221 - .../Module/PaymentModuleListProvider.php | 114 - .../Presenter/PaymentModulesPresenter.php | 110 - .../PrestaTrust/ModuleEventSubscriber.php | 104 - .../Module/PrestaTrust/PrestaTrustChecker.php | 273 - .../Tab/ModuleTabManagementSubscriber.php | 97 - src/Adapter/Module/Tab/ModuleTabRegister.php | 434 - .../Module/Tab/ModuleTabUnregister.php | 153 - src/Adapter/Module/TabModuleListProvider.php | 47 - .../NewProductsProductSearchProvider.php | 127 - src/Adapter/News/NewsDataProvider.php | 175 - ...EmployeeNotificationLastElementHandler.php | 47 - .../GetNotificationLastElementsHandler.php | 77 - src/Adapter/Number/RoundModeConverter.php | 59 - src/Adapter/ObjectPresenter.php | 35 - .../OptionalFeaturesConfiguration.php | 109 - src/Adapter/Order/AbstractOrderHandler.php | 176 - .../AbstractOrderCommandHandler.php | 224 - .../AddCartRuleToOrderHandler.php | 266 - .../AddOrderFromBackOfficeHandler.php | 195 - .../CommandHandler/AddPaymentHandler.php | 79 - .../AddProductToOrderHandler.php | 608 - .../BulkChangeOrderStatusHandler.php | 131 - .../CancelOrderProductHandler.php | 248 - .../ChangeOrderCurrencyHandler.php | 234 - .../ChangeOrderDeliveryAddressHandler.php | 90 - .../ChangeOrderInvoiceAddressHandler.php | 87 - .../DeleteCartRuleFromOrderHandler.php | 166 - .../DeleteProductFromOrderHandler.php | 137 - .../DuplicateOrderCartHandler.php | 83 - .../CommandHandler/GenerateInvoiceHandler.php | 57 - .../IssuePartialRefundHandler.php | 184 - .../IssueReturnProductHandler.php | 184 - .../IssueStandardRefundHandler.php | 193 - .../ResendOrderEmailHandler.php | 69 - .../SendProcessOrderEmailHandler.php | 190 - .../UpdateInvoiceNoteHandler.php | 59 - .../UpdateOrderShippingDetailsHandler.php | 126 - .../UpdateOrderStatusHandler.php | 115 - .../UpdateProductInOrderHandler.php | 232 - .../Delivery/SlipOptionsConfiguration.php | 90 - .../Order/Delivery/SlipPdfConfiguration.php | 103 - src/Adapter/Order/GeneralConfiguration.php | 102 - .../Order/GiftOptionsConfiguration.php | 87 - src/Adapter/Order/Invoice.php | 44 - src/Adapter/Order/OrderAmountUpdater.php | 512 - src/Adapter/Order/OrderDetailUpdater.php | 471 - src/Adapter/Order/OrderPresenter.php | 35 - .../Order/OrderProductQuantityUpdater.php | 507 - src/Adapter/Order/OrderReturnPresenter.php | 37 - src/Adapter/Order/OrderSiblingProvider.php | 55 - .../GetOrderForViewingHandler.php | 808 - .../QueryHandler/GetOrderPreviewHandler.php | 234 - .../GetOrderProductsForViewingHandler.php | 317 - .../Order/Refund/OrderProductRemover.php | 243 - .../Order/Refund/OrderRefundCalculator.php | 277 - .../Order/Refund/OrderRefundSummary.php | 179 - .../Order/Refund/OrderRefundUpdater.php | 91 - src/Adapter/Order/Refund/OrderSlipCreator.php | 337 - src/Adapter/Order/Refund/VoucherGenerator.php | 167 - .../AbstractOrderMessageHandler.php | 55 - .../CommandHandler/AddOrderMessageHandler.php | 72 - .../BulkDeleteOrderMessageHandler.php | 59 - .../DeleteOrderMessageHandler.php | 57 - .../EditOrderMessageHandler.php | 72 - .../OrderMessage/OrderMessageProvider.php | 55 - .../GetOrderMessageForEditingHandler.php | 56 - .../OrderState/OrderStateDataProvider.php | 44 - src/Adapter/PDF/CreditSlipPdfGenerator.php | 129 - src/Adapter/PDF/DeliverySlipPdfGenerator.php | 79 - src/Adapter/PDF/OrderInvoicePdfGenerator.php | 79 - src/Adapter/PDF/PDFGenerator.php | 69 - src/Adapter/Pack/PackDataProvider.php | 55 - .../Preferences/PreferencesConfiguration.php | 110 - src/Adapter/Presenter/AbstractLazyArray.php | 392 - src/Adapter/Presenter/Cart/CartPresenter.php | 669 - .../Presenter/Module/ModulePresenter.php | 135 - .../Presenter/Object/ObjectPresenter.php | 99 - .../Presenter/Order/OrderDetailLazyArray.php | 257 - .../Presenter/Order/OrderLazyArray.php | 463 - .../Presenter/Order/OrderPresenter.php | 50 - .../Presenter/Order/OrderReturnLazyArray.php | 145 - .../Presenter/Order/OrderReturnPresenter.php | 72 - .../Order/OrderSubtotalLazyArray.php | 224 - src/Adapter/Presenter/PresenterInterface.php | 37 - .../Presenter/Product/ProductLazyArray.php | 1050 - .../Product/ProductListingLazyArray.php | 67 - .../Product/ProductListingPresenter.php | 59 - .../Presenter/Product/ProductPresenter.php | 94 - .../PricesDropProductSearchProvider.php | 121 - .../Product/AdminProductDataProvider.php | 472 - .../Product/AdminProductDataUpdater.php | 299 - src/Adapter/Product/AdminProductWrapper.php | 951 - .../Product/AttachmentDataProvider.php | 52 - .../AssignProductToCategoryHandler.php | 64 - .../UpdateProductStatusCommandHandler.php | 57 - .../FilterCategoriesRequestPurifier.php | 57 - src/Adapter/Product/GeneralConfiguration.php | 105 - src/Adapter/Product/ListParametersUpdater.php | 143 - src/Adapter/Product/PackItemsManager.php | 101 - src/Adapter/Product/PageConfiguration.php | 101 - .../Product/PaginationConfiguration.php | 92 - src/Adapter/Product/PriceCalculator.php | 212 - src/Adapter/Product/PriceFormatter.php | 67 - .../Product/ProductColorsRetriever.php | 47 - src/Adapter/Product/ProductDataProvider.php | 166 - .../GetProductIsEnabledHandler.php | 53 - .../QueryHandler/SearchProductsHandler.php | 318 - src/Adapter/Product/StockConfiguration.php | 107 - .../CommandHandler/AbstractProfileHandler.php | 53 - .../CommandHandler/AddProfileHandler.php | 58 - .../BulkDeleteProfileHandler.php | 101 - .../CommandHandler/DeleteProfileHandler.php | 97 - .../CommandHandler/EditProfileHandler.php | 77 - .../Employee/AbstractEmployeeHandler.php | 52 - .../AbstractEmployeeHandler.php | 98 - .../CommandHandler/AddEmployeeHandler.php | 140 - .../BulkDeleteEmployeeHandler.php | 57 - .../BulkUpdateEmployeeStatusHandler.php | 54 - .../CommandHandler/DeleteEmployeeHandler.php | 56 - .../CommandHandler/EditEmployeeHandler.php | 190 - .../ToggleEmployeeStatusHandler.php | 52 - .../GetEmployeeEmailByIdHandler.php | 45 - .../GetEmployeeForEditingHandler.php | 68 - src/Adapter/Profile/ProfileDataProvider.php | 81 - .../GetProfileForEditingHandler.php | 71 - .../CheckMissingOrUpdatedFiles.php | 81 - src/Adapter/Requirement/CheckRequirements.php | 154 - src/Adapter/RoundingMapper.php | 62 - src/Adapter/Routes/DefaultRouteProvider.php | 87 - src/Adapter/Routes/RouteValidator.php | 67 - src/Adapter/Routing/AdminLinkBuilder.php | 110 - .../Routing/LegacyHelperLinkBuilder.php | 111 - .../Search/SearchProductSearchProvider.php | 147 - src/Adapter/Security/Admin.php | 110 - src/Adapter/Security/SslMiddleware.php | 74 - src/Adapter/ServiceLocator.php | 67 - .../CommandHandler/UploadLogosHandler.php | 166 - src/Adapter/Shop/Context.php | 231 - src/Adapter/Shop/MaintenanceConfiguration.php | 84 - .../QueryHandler/GetLogosPathsHandler.php | 131 - src/Adapter/Shop/ShopInformation.php | 64 - src/Adapter/Shop/ShopUrlDataProvider.php | 85 - src/Adapter/Shop/Url/BaseUrlProvider.php | 57 - src/Adapter/Shop/Url/CategoryProvider.php | 62 - src/Adapter/Shop/Url/CmsProvider.php | 62 - .../Smarty/SmartyCacheConfiguration.php | 96 - .../AbstractSpecificPriceHandler.php | 83 - .../AddSpecificPriceHandler.php | 120 - ...eleteSpecificPriceByCartProductHandler.php | 59 - .../CommandHandler/AddSqlRequestHandler.php | 68 - .../BulkDeleteSqlRequestHandler.php | 60 - .../DeleteSqlRequestHandler.php | 69 - .../CommandHandler/EditSqlRequestHandler.php | 77 - .../GetDatabaseTableFieldsListHandler.php | 59 - .../GetDatabaseTablesListHandler.php | 50 - .../GetSqlRequestExecutionResultHandler.php | 100 - .../GetSqlRequestForEditingHandler.php | 94 - src/Adapter/SqlManager/SqlQueryValidator.php | 415 - .../SqlRequestFormDataValidator.php | 74 - src/Adapter/StockManager.php | 220 - .../Supplier/AbstractSupplierHandler.php | 120 - .../AbstractDeleteSupplierHandler.php | 162 - .../CommandHandler/AddSupplierHandler.php | 136 - .../BulkDeleteSupplierHandler.php | 58 - .../BulkDisableSupplierHandler.php | 67 - .../BulkEnableSupplierHandler.php | 67 - .../CommandHandler/DeleteSupplierHandler.php | 57 - .../CommandHandler/EditSupplierHandler.php | 139 - .../ToggleSupplierStatusHandler.php | 63 - .../GetSupplierForEditingHandler.php | 109 - .../GetSupplierForViewingHandler.php | 177 - .../Supplier/SupplierAddressProvider.php | 47 - src/Adapter/Supplier/SupplierDataProvider.php | 94 - .../SupplierLogoThumbnailProvider.php | 74 - .../Supplier/SupplierOrderValidator.php | 47 - .../SupplierProductSearchProvider.php | 115 - src/Adapter/Support/ContactDeleter.php | 77 - src/Adapter/Support/ContactRepository.php | 46 - src/Adapter/SymfonyContainer.php | 63 - src/Adapter/System/SystemInformation.php | 79 - src/Adapter/Tab/TabDataProvider.php | 134 - src/Adapter/Tax/AbstractTaxHandler.php | 61 - .../Tax/CommandHandler/AddTaxHandler.php | 69 - .../CommandHandler/BulkDeleteTaxHandler.php | 59 - .../BulkToggleTaxStatusHandler.php | 59 - .../Tax/CommandHandler/DeleteTaxHandler.php | 57 - .../Tax/CommandHandler/EditTaxHandler.php | 72 - .../CommandHandler/ToggleTaxStatusHandler.php | 58 - .../Tax/Ecotax/ProductEcotaxResetter.php | 44 - .../QueryHandler/GetTaxForEditingHandler.php | 53 - src/Adapter/Tax/TaxRuleDataProvider.php | 130 - .../AbstractTaxRulesGroupHandler.php | 105 - .../BulkDeleteTaxRulesGroupHandler.php | 65 - .../BulkSetTaxRulesGroupStatusHandler.php | 65 - .../DeleteTaxRulesGroupHandler.php | 54 - .../SetTaxRulesGroupStatusHandler.php | 56 - .../GetTaxRulesGroupForEditingHandler.php | 52 - ...hemeMultiStoreSettingsFormDataProvider.php | 93 - src/Adapter/Tools.php | 281 - .../Translations/TranslationRouteFinder.php | 215 - src/Adapter/Twig/LocaleExtension.php | 65 - .../Upload/UploadQuotaConfiguration.php | 140 - src/Adapter/Validate.php | 138 - .../Warehouse/WarehouseDataProvider.php | 79 - .../AbstractWebserviceKeyHandler.php | 58 - .../AddWebserviceKeyHandler.php | 94 - .../EditWebserviceKeyHandler.php | 106 - .../GetWebserviceKeyForEditingHandler.php | 75 - .../Webservice/WebserviceConfiguration.php | 84 - .../Webservice/WebserviceKeyEraser.php | 80 - .../WebserviceKeyStatusModifier.php | 112 - src/Core/Addon/AddonInterface.php | 42 - src/Core/Addon/AddonListFilter.php | 189 - src/Core/Addon/AddonListFilterOrigin.php | 41 - src/Core/Addon/AddonListFilterStatus.php | 39 - src/Core/Addon/AddonListFilterType.php | 37 - src/Core/Addon/AddonListItem.php | 37 - src/Core/Addon/AddonManagerInterface.php | 44 - src/Core/Addon/AddonRepositoryInterface.php | 49 - src/Core/Addon/AddonsCollection.php | 269 - .../Module/AddonListFilterDeviceStatus.php | 36 - .../UnconfirmedModuleActionException.php | 129 - src/Core/Addon/Module/ModuleInterface.php | 76 - src/Core/Addon/Module/ModuleManager.php | 701 - .../Addon/Module/ModuleManagerBuilder.php | 256 - src/Core/Addon/Module/ModuleRepository.php | 645 - .../Module/ModuleRepositoryInterface.php | 65 - .../Exception/ThemeAlreadyExistsException.php | 61 - .../Theme/Exception/ThemeUploadException.php | 40 - src/Core/Addon/Theme/Theme.php | 257 - src/Core/Addon/Theme/ThemeCollection.php | 269 - src/Core/Addon/Theme/ThemeExporter.php | 141 - src/Core/Addon/Theme/ThemeManager.php | 603 - src/Core/Addon/Theme/ThemeManagerBuilder.php | 94 - .../Theme/ThemePageLayoutsCustomizer.php | 73 - .../ThemePageLayoutsCustomizerInterface.php | 38 - src/Core/Addon/Theme/ThemeProvider.php | 71 - .../Addon/Theme/ThemeProviderInterface.php | 47 - src/Core/Addon/Theme/ThemeRepository.php | 156 - .../Addon/Theme/ThemeUploaderInterface.php | 42 - src/Core/Addon/Theme/ThemeValidator.php | 163 - src/Core/Addon/Theme/ThemeZipUploader.php | 105 - ...ttributeGroupViewDataProviderInterface.php | 49 - src/Core/B2b/B2bFeature.php | 89 - src/Core/Backup/BackupCollection.php | 53 - src/Core/Backup/BackupCollectionInterface.php | 49 - src/Core/Backup/BackupInterface.php | 77 - .../Comparator/BackupByDateComparator.php | 43 - .../Comparator/BackupComparatorInterface.php | 45 - .../BackupOptionsConfiguration.php | 84 - src/Core/Backup/Exception/BackupException.php | 36 - .../DirectoryIsNotWritableException.php | 34 - .../Backup/Listing/BackupGridDataFactory.php | 157 - .../Backup/Manager/BackupCreatorInterface.php | 42 - .../Backup/Manager/BackupRemoverInterface.php | 42 - .../Repository/BackupRepositoryInterface.php | 42 - src/Core/CMS/CMSRepository.php | 78 - src/Core/CMS/CMSRoleRepository.php | 45 - src/Core/CMS/CmsPageViewDataProvider.php | 79 - .../CMS/CmsPageViewDataProviderInterface.php | 42 - src/Core/Cache/Clearer/CacheClearerChain.php | 56 - .../Cache/Clearer/CacheClearerInterface.php | 38 - src/Core/Cart/AmountImmutable.php | 122 - src/Core/Cart/Calculator.php | 378 - src/Core/Cart/CartRow.php | 514 - src/Core/Cart/CartRowCollection.php | 103 - src/Core/Cart/CartRuleCalculator.php | 312 - src/Core/Cart/CartRuleCollection.php | 83 - src/Core/Cart/CartRuleData.php | 86 - src/Core/Cart/Fees.php | 205 - src/Core/Checkout/TermsAndConditions.php | 138 - src/Core/CommandBus/CommandBusInterface.php | 40 - .../CommandBus/ExecutedCommandRegistry.php | 133 - .../Middleware/CommandRegisterMiddleware.php | 81 - .../CommandBus/Parser/CommandDefinition.php | 84 - .../Parser/CommandDefinitionParser.php | 96 - .../CommandBus/Parser/CommandTypeParser.php | 44 - .../CommandBus/TacticianCommandBusAdapter.php | 56 - .../DataConfigurationInterface.php | 54 - src/Core/Configuration/IniConfiguration.php | 82 - .../Configuration/PhpExtensionChecker.php | 41 - .../PhpExtensionCheckerInterface.php | 42 - .../Configuration/UploadSizeConfiguration.php | 59 - .../UploadSizeConfigurationInterface.php | 40 - src/Core/ConfigurationInterface.php | 34 - .../AddressDniRequiredValidator.php | 75 - .../AddressStateRequiredValidator.php | 77 - .../AddressZipCodeValidator.php | 102 - .../CleanHtmlValidator.php | 87 - .../Constraints/AddressDniRequired.php | 55 - .../Constraints/AddressStateRequired.php | 53 - .../Constraints/AddressZipCode.php | 55 - .../Constraints/CleanHtml.php | 47 - .../Constraints/CustomerName.php | 46 - .../Constraints/DateRange.php | 46 - .../Constraints/DefaultLanguage.php | 47 - .../Constraints/ExistingCustomerEmail.php | 46 - .../Constraints/IsUrlRewrite.php | 49 - .../Constraints/NotBlankWhenRequired.php | 46 - .../Constraints/Reduction.php | 50 - .../Constraints/TypedRegex.php | 79 - .../CustomerNameValidator.php | 106 - .../DateRangeValidator.php | 78 - .../DefaultLanguageValidator.php | 76 - .../ExistingCustomerEmailValidator.php | 69 - .../Factory/CustomerNameValidatorFactory.php | 61 - .../IsUrlRewriteValidator.php | 115 - .../NotBlankWhenRequiredValidator.php | 40 - .../ReductionValidator.php | 142 - .../TypedRegexValidator.php | 157 - src/Core/ContainerBuilder.php | 51 - ...CountryRequiredFieldsProviderInterface.php | 46 - .../Country/CountryZipCodeRequirements.php | 119 - ...ryZipCodeRequirementsProviderInterface.php | 39 - .../CreditSlipOptionsConfiguration.php | 79 - src/Core/Crypto/Hashing.php | 139 - .../CurrencyDataProviderInterface.php | 121 - src/Core/Currency/CurrencyGridDataFactory.php | 126 - .../Exception/CurrencyFeedException.php | 38 - src/Core/Currency/ExchangeRateProvider.php | 234 - .../Customer/CustomerDataSourceInterface.php | 37 - src/Core/Data/AbstractTypedCollection.php | 167 - src/Core/Data/Layer/AbstractDataLayer.php | 296 - src/Core/Data/Layer/DataLayerException.php | 34 - src/Core/Domain/Address/AddressSettings.php | 63 - .../Command/AbstractEditAddressCommand.php | 415 - .../Command/AddCustomerAddressCommand.php | 304 - .../Command/AddManufacturerAddressCommand.php | 266 - .../Command/BulkDeleteAddressCommand.php | 71 - .../Address/Command/DeleteAddressCommand.php | 59 - .../Command/EditCartAddressCommand.php | 104 - .../Command/EditCustomerAddressCommand.php | 59 - .../EditManufacturerAddressCommand.php | 356 - .../Command/EditOrderAddressCommand.php | 104 - .../SetRequiredFieldsForAddressCommand.php | 77 - .../AddCustomerAddressHandlerInterface.php | 43 - ...AddManufacturerAddressHandlerInterface.php | 43 - .../BulkDeleteAddressHandlerInterface.php | 40 - .../DeleteAddressHandlerInterface.php | 40 - .../EditCartAddressHandlerInterface.php | 44 - .../EditCustomerAddressHandlerInterface.php | 43 - ...ditManufacturerAddressHandlerInterface.php | 40 - .../EditOrderAddressHandlerInterface.php | 44 - ...quiredFieldsForAddressHandlerInterface.php | 40 - .../Configuration/AddressConstraint.php | 100 - .../Exception/AddressConstraintException.php | 48 - .../Address/Exception/AddressException.php | 36 - .../Exception/AddressNotFoundException.php | 34 - .../Exception/BulkDeleteAddressException.php | 61 - .../Exception/CannotAddAddressException.php | 34 - ...otSetRequiredFieldsForAddressException.php | 34 - .../CannotUpdateAddressException.php | 34 - .../CannotUpdateCartAddressException.php | 35 - .../CannotUpdateOrderAddressException.php | 35 - .../Exception/DeleteAddressException.php | 43 - .../InvalidAddressFieldException.php | 34 - .../InvalidAddressRequiredFieldsException.php | 34 - .../Query/GetCustomerAddressForEditing.php | 59 - .../GetManufacturerAddressForEditing.php | 59 - .../Query/GetRequiredFieldsForAddress.php | 34 - ...tomerAddressForEditingHandlerInterface.php | 43 - ...turerAddressForEditingHandlerInterface.php | 43 - ...quiredFieldsForAddressHandlerInterface.php | 39 - .../QueryResult/EditableCustomerAddress.php | 348 - .../EditableManufacturerAddress.php | 265 - .../Domain/Address/ValueObject/AddressId.php | 73 - .../Address/ValueObject/RequiredFields.php | 56 - .../AttachmentFileUploaderInterface.php | 38 - .../Command/AddAttachmentCommand.php | 141 - .../Command/BulkDeleteAttachmentsCommand.php | 66 - .../Command/DeleteAttachmentCommand.php | 56 - .../Command/EditAttachmentCommand.php | 180 - .../AddAttachmentHandlerInterface.php | 40 - .../BulkDeleteAttachmentsHandlerInterface.php | 40 - .../DeleteAttachmentHandlerInterface.php | 40 - .../EditAttachmentHandlerInterface.php | 37 - .../Configuration/AttachmentConstraint.php | 45 - .../AttachmentConstraintException.php | 47 - .../Exception/AttachmentException.php | 36 - .../Exception/AttachmentNotFoundException.php | 34 - .../AttachmentUploadFailedException.php | 34 - .../BulkDeleteAttachmentsException.php | 61 - .../CannotAddAttachmentException.php | 34 - .../CannotUnlinkAttachmentException.php | 56 - .../CannotUpdateAttachmentException.php | 34 - .../Exception/DeleteAttachmentException.php | 34 - .../Exception/EmptyFileException.php | 34 - .../Domain/Attachment/Query/GetAttachment.php | 56 - .../Query/GetAttachmentForEditing.php | 59 - ...etAttachmentForEditingHandlerInterface.php | 40 - .../GetAttachmentHandlerInterface.php | 43 - .../Attachment/QueryResult/Attachment.php | 69 - .../QueryResult/EditableAttachment.php | 114 - .../Attachment/ValueObject/AttachmentId.php | 72 - src/Core/Domain/Cart/CartAddressType.php | 38 - .../Cart/Command/AddCartRuleToCartCommand.php | 72 - .../Cart/Command/AddCustomizationCommand.php | 90 - .../Cart/Command/AddProductToCartCommand.php | 151 - .../CreateEmptyCustomerCartCommand.php | 56 - .../Command/RemoveCartRuleFromCartCommand.php | 72 - .../Command/RemoveProductFromCartCommand.php | 109 - .../Command/SendCartToCustomerCommand.php | 56 - .../Command/UpdateCartAddressesCommand.php | 109 - .../Cart/Command/UpdateCartCarrierCommand.php | 74 - .../Command/UpdateCartCurrencyCommand.php | 72 - .../UpdateCartDeliverySettingsCommand.php | 118 - .../Command/UpdateCartLanguageCommand.php | 72 - .../UpdateProductPriceInCartCommand.php | 115 - .../UpdateProductQuantityInCartCommand.php | 168 - .../AddCartRuleToCartHandlerInterface.php | 40 - .../AddCustomizationHandlerInterface.php | 43 - .../AddProductToCartHandlerInterface.php | 40 - ...reateEmptyCustomerCartHandlerInterface.php | 43 - ...RemoveCartRuleFromCartHandlerInterface.php | 40 - .../RemoveProductFromCartHandlerInterface.php | 40 - .../SendCartToCustomerHanlderInterface.php | 40 - .../UpdateCartAddressesHandlerInterface.php | 40 - .../UpdateCartCarrierHandlerInterface.php | 40 - .../UpdateCartCurrencyHandlerInterface.php | 40 - ...teCartDeliverySettingsHandlerInterface.php | 37 - .../UpdateCartLanguageHandlerInterface.php | 40 - ...dateProductPriceInCartHandlerInterface.php | 40 - ...eProductQuantityInCartHandlerInterface.php | 40 - .../Exception/CannotUpdateCartException.php | 35 - .../Exception/CartConstraintException.php | 48 - .../Domain/Cart/Exception/CartException.php | 36 - .../Cart/Exception/CartNotFoundException.php | 34 - .../Exception/InvalidAddressTypeException.php | 35 - .../Exception/InvalidGiftMessageException.php | 32 - .../Exception/MinimalQuantityException.php | 62 - .../Cart/Query/GetCartForOrderCreation.php | 93 - .../Domain/Cart/Query/GetCartForViewing.php | 56 - .../Cart/Query/GetLastEmptyCustomerCart.php | 56 - ...etCartForOrderCreationHandlerInterface.php | 38 - .../GetCartForViewingHandlerInterface.php | 43 - ...tLastEmptyCustomerCartHandlerInterface.php | 43 - .../Cart/QueryResult/CartForOrderCreation.php | 173 - .../CartForOrderCreation/CartAddress.php | 119 - .../CartDeliveryOption.php | 84 - .../CartForOrderCreation/CartProduct.php | 216 - .../CartForOrderCreation/CartRule.php | 103 - .../CartForOrderCreation/CartShipping.php | 151 - .../CartForOrderCreation/CartSummary.php | 183 - .../CartForOrderCreation/Customization.php | 67 - .../CustomizationFieldData.php | 82 - src/Core/Domain/Cart/QueryResult/CartView.php | 116 - src/Core/Domain/Cart/ValueObject/CartId.php | 62 - .../CartRule/Command/AddCartRuleCommand.php | 621 - .../AddCartRuleHandlerInterface.php | 43 - .../CannotDeleteCartRuleException.php | 31 - .../Exception/CartRuleConstraintException.php | 99 - .../CartRule/Exception/CartRuleException.php | 36 - .../Exception/CartRuleValidityException.php | 37 - .../InvalidCartRuleDiscountValueException.php | 60 - .../InvalidCartRuleValueException.php | 36 - .../Domain/CartRule/Query/SearchCartRules.php | 54 - .../SearchCartRulesHandlerInterface.php | 43 - .../CartRule/QueryResult/FoundCartRule.php | 87 - .../CartRuleAction/AmountDiscountAction.php | 102 - .../CartRuleAction/CartRuleActionBuilder.php | 144 - .../CartRuleActionBuilderInterface.php | 80 - .../CartRuleActionInterface.php | 65 - .../CartRuleAction/FreeShippingAction.php | 84 - .../CartRuleAction/GiftProductAction.php | 83 - .../PercentageDiscountAction.php | 102 - .../CartRule/ValueObject/CartRuleId.php | 69 - .../ValueObject/DiscountApplicationType.php | 87 - .../CartRule/ValueObject/GiftProduct.php | 92 - .../ValueObject/MoneyAmountCondition.php | 86 - .../ValueObject/PercentageDiscount.php | 75 - .../Command/AddCatalogPriceRuleCommand.php | 256 - .../BulkDeleteCatalogPriceRuleCommand.php | 71 - .../Command/DeleteCatalogPriceRuleCommand.php | 59 - .../Command/EditCatalogPriceRuleCommand.php | 312 - .../AddCatalogPriceRuleHandlerInterface.php | 43 - ...DeleteCatalogPriceRuleHandlerInterface.php | 40 - ...DeleteCatalogPriceRuleHandlerInterface.php | 40 - .../EditCatalogPriceRuleHandlerInterface.php | 40 - .../CannotDeleteCatalogPriceRuleException.php | 43 - .../CannotUpdateCatalogPriceRuleException.php | 34 - .../CatalogPriceRuleConstraintException.php | 48 - .../Exception/CatalogPriceRuleException.php | 36 - .../CatalogPriceRuleNotFoundException.php | 34 - .../Query/GetCatalogPriceRuleForEditing.php | 59 - ...logPriceRuleForEditingHandlerInterface.php | 43 - .../QueryResult/EditableCatalogPriceRule.php | 236 - .../ValueObject/CatalogPriceRuleId.php | 73 - .../Category/Command/AddCategoryCommand.php | 326 - .../Command/AddRootCategoryCommand.php | 293 - .../Command/BulkDeleteCategoriesCommand.php | 112 - .../Command/BulkDisableCategoriesCommand.php | 45 - .../Command/BulkEnableCategoriesCommand.php | 47 - .../BulkUpdateCategoriesStatusCommand.php | 115 - .../Command/DeleteCategoryCommand.php | 72 - .../DeleteCategoryCoverImageCommand.php | 56 - ...eleteCategoryMenuThumbnailImageCommand.php | 72 - .../Category/Command/EditCategoryCommand.php | 335 - .../Command/EditRootCategoryCommand.php | 300 - .../Command/SetCategoryIsEnabledCommand.php | 71 - .../Command/UpdateCategoryPositionCommand.php | 116 - .../AddCategoryHandlerInterface.php | 40 - .../AddRootCategoryHandlerInterface.php | 40 - .../BulkDeleteCategoriesHandlerInterface.php | 40 - ...UpdateCategoriesStatusHandlerInterface.php | 40 - ...leteCategoryCoverImageHandlerInterface.php | 40 - .../DeleteCategoryHandlerInterface.php | 40 - ...goryMenuThumbnailImageHandlerInterface.php | 40 - .../EditCategoryHandlerInterface.php | 40 - .../EditRootCategoryHandlerInterface.php | 40 - .../SetCategoryIsEnabledHandlerInterface.php | 40 - ...UpdateCategoryPositionHandlerInterface.php | 40 - .../Exception/CannotAddCategoryException.php | 34 - .../Exception/CannotDeleteImageException.php | 40 - ...nnotDeleteRootCategoryForShopException.php | 34 - .../Exception/CannotEditCategoryException.php | 34 - .../CannotUpdateCategoryStatusException.php | 34 - .../Exception/CategoryConstraintException.php | 73 - .../Category/Exception/CategoryException.php | 36 - .../Exception/CategoryNotFoundException.php | 62 - .../FailedToDeleteCategoryException.php | 34 - .../MenuThumbnailsLimitException.php | 34 - .../Category/Query/GetCategoryForEditing.php | 56 - .../Category/Query/GetCategoryIsEnabled.php | 56 - .../GetCategoryForEditingHandlerInterface.php | 43 - .../GetCategoryIsEnabledHandlerInterface.php | 42 - .../Category/QueryResult/EditableCategory.php | 306 - src/Core/Domain/Category/SeoSettings.php | 53 - .../ValueObject/CategoryDeleteMode.php | 108 - .../Category/ValueObject/CategoryId.php | 78 - .../Category/ValueObject/MenuThumbnailId.php | 73 - .../CmsPage/Command/AddCmsPageCommand.php | 204 - .../Command/BulkDeleteCmsPageCommand.php | 71 - .../Command/BulkDisableCmsPageCommand.php | 71 - .../Command/BulkEnableCmsPageCommand.php | 71 - .../CmsPage/Command/DeleteCmsPageCommand.php | 59 - .../CmsPage/Command/EditCmsPageCommand.php | 313 - .../Command/ToggleCmsPageStatusCommand.php | 59 - .../AddCmsPageHandlerInterface.php | 43 - .../BulkDeleteCmsPageHandlerInterface.php | 40 - .../BulkDisableCmsPageHandlerInterface.php | 40 - .../BulkEnableCmsPageHandlerInterface.php | 40 - .../DeleteCmsPageHandlerInterface.php | 40 - .../EditCmsPageHandlerInterface.php | 40 - .../ToggleCmsPageStatusHandlerInterface.php | 40 - .../Exception/CannotAddCmsPageException.php | 34 - .../CannotDeleteCmsPageException.php | 43 - .../CannotDisableCmsPageException.php | 34 - .../Exception/CannotEditCmsPageException.php | 34 - .../CannotEnableCmsPageException.php | 34 - .../CannotToggleCmsPageException.php | 34 - .../CmsPage/Exception/CmsPageException.php | 36 - .../Exception/CmsPageNotFoundException.php | 34 - .../Query/GetCmsCategoryIdForRedirection.php | 60 - .../CmsPage/Query/GetCmsPageForEditing.php | 59 - ...tegoryIdHandlerForRedirectionInterface.php | 43 - .../GetCmsPageForEditingHandlerInterface.php | 43 - .../CmsPage/QueryResult/EditableCmsPage.php | 241 - .../Domain/CmsPage/ValueObject/CmsPageId.php | 73 - .../AbstractBulkCmsPageCategoryCommand.php | 44 - .../AbstractCmsPageCategoryCommand.php | 112 - .../Command/AddCmsPageCategoryCommand.php | 245 - .../BulkDeleteCmsPageCategoryCommand.php | 76 - .../BulkDisableCmsPageCategoryCommand.php | 77 - .../BulkEnableCmsPageCategoryCommand.php | 76 - .../Command/DeleteCmsPageCategoryCommand.php | 59 - .../Command/EditCmsPageCategoryCommand.php | 299 - .../ToggleCmsPageCategoryStatusCommand.php | 59 - .../AddCmsPageCategoryHandlerInterface.php | 43 - ...kDeleteCmsPageCategoryHandlerInterface.php | 40 - ...DisableCmsPageCategoryHandlerInterface.php | 40 - ...kEnableCmsPageCategoryHandlerInterface.php | 40 - .../DeleteCmsPageCategoryHandlerInterface.php | 40 - .../EditCmsPageCategoryHandlerInterface.php | 40 - ...eCmsPageCategoryStatusHandlerInterface.php | 40 - .../CannotAddCmsPageCategoryException.php | 34 - .../CannotDeleteCmsPageCategoryException.php | 43 - .../CannotDisableCmsPageCategoryException.php | 34 - .../CannotEnableCmsPageCategoryException.php | 34 - ...otToggleCmsPageCategoryStatusException.php | 34 - .../CannotUpdateCmsPageCategoryException.php | 34 - .../CmsPageCategoryConstraintException.php | 84 - .../Exception/CmsPageCategoryException.php | 36 - .../CmsPageCategoryNotFoundException.php | 34 - .../GetCmsPageCategoriesForBreadcrumb.php | 62 - .../Query/GetCmsPageCategoryForEditing.php | 59 - .../GetCmsPageCategoryNameForListing.php | 34 - ...tCmsPageParentCategoryIdForRedirection.php | 60 - ...ategoriesForBreadcrumbHandlerInterface.php | 43 - ...PageCategoryForEditingHandlerInterface.php | 43 - ...CategoryNameForListingHandlerInterface.php | 42 - ...tegoryIdForRedirectionHandlerInterface.php | 44 - .../QueryResult/Breadcrumb.php | 57 - .../QueryResult/BreadcrumbItem.php | 74 - .../QueryResult/EditableCmsPageCategory.php | 186 - .../ValueObject/CmsPageCategoryId.php | 78 - .../Command/SwitchDebugModeCommand.php | 54 - .../SwitchDebugModeHandlerInterface.php | 40 - .../ShopConfigurationInterface.php | 61 - .../Command/AbstractContactCommand.php | 71 - .../Contact/Command/AddContactCommand.php | 178 - .../Contact/Command/EditContactCommand.php | 207 - .../AddContactHandlerInterface.php | 43 - .../EditContactHandlerInterface.php | 40 - .../Exception/CannotAddContactException.php | 34 - .../CannotUpdateContactException.php | 34 - .../Exception/ContactConstraintException.php | 54 - .../Contact/Exception/ContactException.php | 36 - .../Exception/ContactNotFoundException.php | 34 - .../Contact/Query/GetContactForEditing.php | 57 - .../GetContactForEditingHandlerInterface.php | 43 - .../Contact/QueryResult/EditableContact.php | 144 - .../Domain/Contact/ValueObject/ContactId.php | 72 - .../Exception/CountryConstraintException.php | 35 - .../Country/Exception/CountryException.php | 36 - .../Exception/CountryNotFoundException.php | 34 - .../Query/GetCountryRequiredFields.php | 59 - ...tCountryRequiredFieldsHandlerInterface.php | 43 - .../QueryResult/CountryRequiredFields.php | 65 - .../Domain/Country/ValueObject/CountryId.php | 71 - .../Domain/Country/ZipCodePatternResolver.php | 55 - .../ZipCodePatternResolverInterface.php | 49 - .../CreditSlipConstraintException.php | 38 - .../Exception/CreditSlipException.php | 36 - .../Exception/CreditSlipNotFoundException.php | 38 - .../Query/GetCreditSlipIdsByDateRange.php | 71 - ...editSlipIdsByDateRangeHandlerInterface.php | 43 - .../CreditSlip/ValueObject/CreditSlipId.php | 73 - .../Currency/Command/AddCurrencyCommand.php | 235 - .../Command/AddUnofficialCurrencyCommand.php | 34 - .../Command/DeleteCurrencyCommand.php | 59 - .../Currency/Command/EditCurrencyCommand.php | 255 - .../Command/EditUnofficialCurrencyCommand.php | 60 - .../Command/RefreshExchangeRatesCommand.php | 34 - .../Command/ToggleCurrencyStatusCommand.php | 59 - ...oggleExchangeRateAutomatizationCommand.php | 74 - .../AddCurrencyHandlerInterface.php | 43 - .../AddUnofficialCurrencyHandlerInterface.php | 43 - .../DeleteCurrencyHandlerInterface.php | 42 - .../EditCurrencyHandlerInterface.php | 40 - ...EditUnofficialCurrencyHandlerInterface.php | 40 - .../RefreshExchangeRatesHandlerInterface.php | 40 - .../ToggleCurrencyStatusHandlerInterface.php | 42 - ...angeRateAutomatizationHandlerInterface.php | 40 - .../AutomateExchangeRatesUpdateException.php | 36 - .../CannotCreateCurrencyException.php | 34 - .../CannotDeleteCurrencyException.php | 34 - .../CannotDeleteDefaultCurrencyException.php | 34 - .../CannotDisableDefaultCurrencyException.php | 34 - .../CannotRefreshExchangeRatesException.php | 34 - .../CannotToggleCurrencyException.php | 34 - .../CannotUpdateCurrencyException.php | 34 - .../Exception/CurrencyConstraintException.php | 96 - .../Currency/Exception/CurrencyException.php | 45 - .../Exception/CurrencyNotFoundException.php | 34 - .../DefaultCurrencyInMultiShopException.php | 85 - .../ExchangeRateNotFoundException.php | 35 - .../InvalidUnofficialCurrencyException.php | 61 - .../Query/GetCurrencyExchangeRate.php | 59 - .../Currency/Query/GetCurrencyForEditing.php | 59 - .../Currency/Query/GetReferenceCurrency.php | 61 - ...etCurrencyExchangeRateHandlerInterface.php | 43 - .../GetCurrencyForEditingHandlerInterface.php | 42 - .../GetReferenceCurrencyHandlerInterface.php | 43 - .../Currency/QueryResult/EditableCurrency.php | 222 - .../Currency/QueryResult/ExchangeRate.php | 56 - .../QueryResult/ReferenceCurrency.php | 144 - .../Currency/ValueObject/AlphaIsoCode.php | 76 - .../Currency/ValueObject/CurrencyId.php | 62 - .../Currency/ValueObject/ExchangeRate.php | 86 - .../Currency/ValueObject/NumericIsoCode.php | 76 - .../Domain/Currency/ValueObject/Precision.php | 70 - .../Customer/Command/AddCustomerCommand.php | 397 - .../Command/BulkDeleteCustomerCommand.php | 82 - .../Command/BulkDisableCustomerCommand.php | 66 - .../Command/BulkEnableCustomerCommand.php | 66 - .../Command/DeleteCustomerCommand.php | 72 - .../Customer/Command/EditCustomerCommand.php | 513 - .../SetPrivateNoteAboutCustomerCommand.php | 86 - .../SetRequiredFieldsForCustomerCommand.php | 75 - .../TransformGuestToCustomerCommand.php | 56 - .../AddCustomerHandlerInterface.php | 43 - .../BulkDeleteCustomerHandlerInterface.php | 40 - .../BulkDisableCustomerHandlerInterface.php | 40 - .../BulkEnableCustomerHandlerInterface.php | 40 - .../DeleteCustomerHandlerInterface.php | 40 - .../EditCustomerHandlerInterface.php | 40 - ...ivateNoteAboutCustomerHandlerInterface.php | 40 - ...uiredFieldsForCustomerHandlerInterface.php | 40 - ...ansformGuestToCustomerHandlerInterface.php | 40 - ...tSetRequiredFieldsForCustomerException.php | 34 - .../CustomerByEmailNotFoundException.php | 34 - .../Exception/CustomerConstraintException.php | 68 - .../CustomerDefaultGroupAccessException.php | 35 - .../Customer/Exception/CustomerException.php | 36 - .../Exception/CustomerNotFoundException.php | 61 - .../CustomerTransformationException.php | 43 - .../DuplicateCustomerEmailException.php | 61 - .../Exception/InvalidCustomerIdException.php | 34 - ...InvalidCustomerRequiredFieldsException.php | 34 - ...MissingCustomerRequiredFieldsException.php | 59 - .../Customer/Query/GetCustomerCarts.php | 56 - .../Query/GetCustomerForAddressCreation.php | 56 - .../Customer/Query/GetCustomerForEditing.php | 56 - .../Customer/Query/GetCustomerForViewing.php | 56 - .../Customer/Query/GetCustomerOrders.php | 56 - .../Query/GetRequiredFieldsForCustomer.php | 34 - .../Domain/Customer/Query/SearchCustomers.php | 68 - .../GetCustomerCartsHandlerInterface.php | 43 - ...omerForAddressCreationHandlerInterface.php | 43 - .../GetCustomerForEditingHandlerInterface.php | 43 - .../GetCustomerForViewingHandlerInterface.php | 43 - .../GetCustomerOrdersHandlerInterface.php | 43 - ...uiredFieldsForCustomerHandlerInterface.php | 42 - .../SearchCustomersHandlerInterface.php | 42 - .../AddressCreationCustomerInformation.php | 111 - .../QueryResult/AddressInformation.php | 144 - .../QueryResult/BoughtProductInformation.php | 103 - .../Customer/QueryResult/CartInformation.php | 103 - .../Customer/QueryResult/CartSummary.php | 87 - .../QueryResult/DiscountInformation.php | 119 - .../Customer/QueryResult/EditableCustomer.php | 333 - .../QueryResult/GeneralInformation.php | 69 - .../Customer/QueryResult/GroupInformation.php | 69 - .../QueryResult/LastConnectionInformation.php | 135 - .../QueryResult/MessageInformation.php | 99 - .../Customer/QueryResult/OrderInformation.php | 129 - .../Customer/QueryResult/OrderSummary.php | 136 - .../QueryResult/OrdersInformation.php | 84 - .../QueryResult/PersonalInformation.php | 263 - .../QueryResult/ProductsInformation.php | 69 - .../QueryResult/ReferrerInformation.php | 84 - .../QueryResult/SentEmailInformation.php | 99 - .../Customer/QueryResult/Subscriptions.php | 66 - .../Customer/QueryResult/ViewableCustomer.php | 249 - .../QueryResult/ViewedProductInformation.php | 84 - .../Domain/Customer/ValueObject/ApeCode.php | 72 - .../Domain/Customer/ValueObject/Birthday.php | 118 - .../ValueObject/CustomerDeleteMethod.php | 88 - .../Customer/ValueObject/CustomerId.php | 68 - .../Domain/Customer/ValueObject/Email.php | 41 - .../Domain/Customer/ValueObject/FirstName.php | 93 - .../Domain/Customer/ValueObject/LastName.php | 93 - .../Domain/Customer/ValueObject/Password.php | 83 - .../Customer/ValueObject/RequiredField.php | 51 - .../AddOrderCustomerMessageCommand.php | 104 - ...ddOrderCustomerMessageHandlerInterface.php | 37 - .../Exception/CannotSendEmailException.php | 31 - .../CustomerMessageConstraintException.php | 33 - .../Exception/CustomerMessageException.php | 34 - .../Command/ForwardCustomerThreadCommand.php | 142 - .../Command/ReplyToCustomerThreadCommand.php | 71 - .../UpdateCustomerThreadStatusCommand.php | 72 - .../ForwardCustomerThreadHandlerInterface.php | 40 - .../ReplyToCustomerThreadHandlerInterface.php | 40 - .../UpdateCustomerThreadStatusHandler.php | 77 - ...teCustomerThreadStatusHandlerInterface.php | 40 - .../Exception/CustomerServiceException.php | 36 - .../CustomerThreadNotFoundException.php | 34 - .../Query/GetCustomerServiceSignature.php | 56 - .../Query/GetCustomerThreadForViewing.php | 56 - .../GetCustomerServiceSignatureHandler.php | 59 - ...stomerServiceSignatureHandlerInterface.php | 42 - ...stomerThreadForViewingHandlerInterface.php | 43 - .../QueryResult/CustomerInformation.php | 161 - .../QueryResult/CustomerThreadMessage.php | 183 - .../QueryResult/CustomerThreadTimeline.php | 52 - .../CustomerThreadTimelineItem.php | 135 - .../QueryResult/CustomerThreadView.php | 154 - .../ValueObject/CustomerThreadId.php | 60 - .../ValueObject/CustomerThreadMessageType.php | 43 - .../ValueObject/CustomerThreadStatus.php | 72 - .../Employee/Command/AddEmployeeCommand.php | 188 - .../Command/BulkDeleteEmployeeCommand.php | 66 - .../BulkUpdateEmployeeStatusCommand.php | 82 - .../Command/DeleteEmployeeCommand.php | 56 - .../Employee/Command/EditEmployeeCommand.php | 297 - .../Command/ToggleEmployeeStatusCommand.php | 56 - .../AddEmployeeHandlerInterface.php | 43 - .../BulkDeleteEmployeeHandlerInterface.php | 40 - ...lkUpdateEmployeeStatusHandlerInterface.php | 40 - .../DeleteEmployeeHandlerInterface.php | 40 - .../EditEmployeeHandlerInterface.php | 40 - .../ToggleEmployeeStatusHandlerInterface.php | 40 - .../Exception/AdminEmployeeException.php | 38 - .../CannotDeleteEmployeeException.php | 61 - .../CannotDeleteWarehouseManagerException.php | 34 - .../Exception/EmailAlreadyUsedException.php | 61 - .../EmployeeCannotChangeItselfException.php | 38 - .../Exception/EmployeeConstraintException.php | 58 - .../Employee/Exception/EmployeeException.php | 36 - .../Exception/EmployeeNotFoundException.php | 61 - .../Exception/InvalidEmployeeIdException.php | 34 - .../Exception/InvalidPasswordException.php | 34 - .../Exception/InvalidProfileException.php | 34 - .../MissingShopAssociationException.php | 34 - .../Employee/Query/GetEmployeeEmailById.php | 53 - .../Employee/Query/GetEmployeeForEditing.php | 56 - .../GetEmployeeEmailByIdHandlerInterface.php | 40 - .../GetEmployeeForEditingHandlerInterface.php | 43 - .../Employee/QueryResult/EditableEmployee.php | 204 - .../Employee/ValueObject/EmployeeId.php | 72 - .../Domain/Employee/ValueObject/FirstName.php | 93 - .../Domain/Employee/ValueObject/LastName.php | 93 - .../Domain/Employee/ValueObject/Password.php | 80 - .../Exception/DomainConstraintException.php | 58 - src/Core/Domain/Exception/DomainException.php | 36 - .../Domain/Exception/FileUploadException.php | 43 - .../Exception/InvalidSortingException.php | 37 - .../Feature/Command/AddFeatureCommand.php | 87 - .../Feature/Command/EditFeatureCommand.php | 111 - .../AddFeatureHandlerInterface.php | 43 - .../EditFeatureHandlerInterface.php | 40 - .../Exception/CannotAddFeatureException.php | 34 - .../Exception/CannotEditFeatureException.php | 34 - .../Exception/FeatureConstraintException.php | 43 - .../Feature/Exception/FeatureException.php | 36 - .../Exception/FeatureNotFoundException.php | 34 - .../Exception/InvalidFeatureIdException.php | 34 - .../Feature/Query/GetFeatureForEditing.php | 56 - .../GetFeatureForEditingHandlerInterface.php | 43 - .../Feature/QueryResult/EditableFeature.php | 86 - .../Domain/Feature/ValueObject/FeatureId.php | 70 - .../Language/Command/AddLanguageCommand.php | 204 - .../Command/BulkDeleteLanguagesCommand.php | 71 - .../BulkToggleLanguagesStatusCommand.php | 101 - .../Command/DeleteLanguageCommand.php | 56 - .../Language/Command/EditLanguageCommand.php | 320 - .../Command/ToggleLanguageStatusCommand.php | 88 - .../AddLanguageHandlerInterface.php | 43 - .../BulkDeleteLanguagesHandlerInterface.php | 40 - ...kToggleLanguagesStatusHandlerInterface.php | 40 - .../DeleteLanguageHandlerInterface.php | 40 - .../EditLanguageHandlerInterface.php | 40 - .../ToggleLanguageStatusHandlerInterface.php | 40 - .../CannotDisableDefaultLanguageException.php | 34 - .../Exception/CopyingNoPictureException.php | 48 - .../Exception/DefaultLanguageException.php | 48 - .../Exception/LanguageConstraintException.php | 53 - .../Language/Exception/LanguageException.php | 40 - .../LanguageImageUploadingException.php | 43 - .../Exception/LanguageNotFoundException.php | 61 - .../Language/Query/GetLanguageForEditing.php | 56 - .../GetLanguageForEditingHandlerInterface.php | 43 - .../Language/QueryResult/EditableLanguage.php | 187 - .../Domain/Language/ValueObject/IsoCode.php | 76 - .../Language/ValueObject/LanguageId.php | 68 - .../Domain/Language/ValueObject/TagIETF.php | 72 - .../GenerateThemeMailTemplatesCommand.php | 111 - ...nerateThemeMailTemplatesCommandHandler.php | 106 - ...meMailTemplatesCommandHandlerInterface.php | 40 - .../Command/AddManufacturerCommand.php | 167 - .../Command/BulkDeleteManufacturerCommand.php | 71 - .../BulkToggleManufacturerStatusCommand.php | 102 - .../Command/DeleteManufacturerCommand.php | 59 - .../Command/EditManufacturerCommand.php | 256 - .../ToggleManufacturerStatusCommand.php | 89 - .../AddManufacturerHandlerInterface.php | 43 - ...BulkDeleteManufacturerHandlerInterface.php | 40 - ...ggleManufacturerStatusHandlerInterface.php | 40 - .../DeleteManufacturerHandlerInterface.php | 40 - .../EditManufacturerHandlerInterface.php | 40 - ...ggleManufacturerStatusHandlerInterface.php | 40 - .../Exception/DeleteManufacturerException.php | 43 - .../ManufacturerConstraintException.php | 43 - .../Exception/ManufacturerException.php | 36 - .../ManufacturerImageUploadingException.php | 48 - .../ManufacturerNotFoundException.php | 34 - .../Exception/UpdateManufacturerException.php | 43 - .../Query/GetManufacturerForEditing.php | 59 - .../Query/GetManufacturerForViewing.php | 72 - ...ManufacturerForEditingHandlerInterface.php | 43 - ...ManufacturerForViewingHandlerInterface.php | 43 - .../QueryResult/EditableManufacturer.php | 201 - .../QueryResult/ViewableManufacturer.php | 84 - .../ValueObject/ManufacturerId.php | 73 - .../Meta/Command/AbstractMetaCommand.php | 51 - .../Domain/Meta/Command/AddMetaCommand.php | 177 - .../Domain/Meta/Command/EditMetaCommand.php | 206 - .../AddMetaHandlerInterface.php | 45 - .../EditMetaHandlerInterface.php | 42 - .../Meta/Exception/CannotAddMetaException.php | 34 - .../Exception/CannotEditMetaException.php | 34 - .../Exception/MetaConstraintException.php | 58 - .../Domain/Meta/Exception/MetaException.php | 36 - .../Meta/Exception/MetaNotFoundException.php | 34 - .../Domain/Meta/Query/GetMetaForEditing.php | 61 - .../Query/GetPagesForLayoutCustomization.php | 34 - .../GetMetaForEditingHandlerInterface.php | 45 - ...ForLayoutCustomizationHandlerInterface.php | 40 - .../Domain/Meta/QueryResult/EditableMeta.php | 145 - .../QueryResult/LayoutCustomizationPage.php | 84 - src/Core/Domain/Meta/ValueObject/MetaId.php | 74 - src/Core/Domain/Meta/ValueObject/Name.php | 72 - ...EmployeeNotificationLastElementCommand.php | 61 - ...tionLastElementCommandHandlerInterface.php | 40 - .../Exception/NotificationException.php | 36 - .../Query/GetNotificationLastElements.php | 61 - ...tificationLastElementsHandlerInterface.php | 43 - .../QueryResult/NotificationResult.php | 233 - .../QueryResult/NotificationsResult.php | 88 - .../QueryResult/NotificationsResults.php | 86 - .../Domain/Notification/ValueObject/Type.php | 79 - .../Domain/Order/CancellationActionType.php | 45 - .../Order/Command/AbstractRefundCommand.php | 178 - .../Command/AddCartRuleToOrderCommand.php | 147 - .../Command/AddOrderFromBackOfficeCommand.php | 149 - .../Command/BulkChangeOrderStatusCommand.php | 86 - .../Command/CancelOrderProductCommand.php | 72 - .../Command/ChangeOrderCurrencyCommand.php | 72 - .../ChangeOrderDeliveryAddressCommand.php | 72 - .../ChangeOrderInvoiceAddressCommand.php | 72 - .../DeleteCartRuleFromOrderCommand.php | 71 - .../Command/DuplicateOrderCartCommand.php | 56 - .../Command/IssuePartialRefundCommand.php | 117 - .../Command/IssueReturnProductCommand.php | 77 - .../Command/IssueStandardRefundCommand.php | 103 - .../Order/Command/ResendOrderEmailCommand.php | 78 - .../Command/SendProcessOrderEmailCommand.php | 59 - .../UpdateOrderShippingDetailsCommand.php | 101 - .../Command/UpdateOrderStatusCommand.php | 71 - .../AddCartRuleToOrderHandlerInterface.php | 40 - ...AddOrderFromBackOfficeHandlerInterface.php | 43 - .../BulkChangeOrderStatusHandlerInterface.php | 40 - .../CancelOrderProductHandlerInterface.php | 40 - .../ChangeOrderCurrencyHandlerInterface.php | 40 - ...geOrderDeliveryAddressHandlerInterface.php | 40 - ...ngeOrderInvoiceAddressHandlerInterface.php | 40 - ...eleteCartRuleFromOrderHandlerInterface.php | 40 - .../DuplicateOrderCartHandlerInterface.php | 43 - .../IssuePartialRefundHandlerInterface.php | 40 - .../IssueReturnProductHandlerInterface.php | 40 - .../IssueStandardRefundHandlerInterface.php | 40 - .../ResendOrderEmailHandlerInterface.php | 37 - .../SendProcessOrderEmailHandlerInterface.php | 40 - ...teOrderShippingDetailsHandlerInterface.php | 40 - .../UpdateOrderStatusHandlerInterface.php | 40 - .../CancelProductFromOrderException.php | 34 - ...nnotEditDeliveredOrderProductException.php | 31 - .../CannotFindProductInOrderException.php | 35 - .../Exception/CannotUpdateOrderException.php | 35 - .../Exception/ChangeOrderStatusException.php | 97 - ...eteCustomizedProductFromOrderException.php | 34 - .../DeleteProductFromOrderException.php | 34 - .../Exception/DuplicateOrderCartException.php | 34 - .../DuplicateProductInOrderException.php | 33 - ...uplicateProductInOrderInvoiceException.php | 62 - .../Exception/InvalidAddressTypeException.php | 35 - .../Exception/InvalidAmountException.php | 34 - .../InvalidCancelProductException.php | 85 - .../Exception/InvalidOrderStateException.php | 68 - .../InvalidProductQuantityException.php | 35 - .../Exception/InvalidRefundException.php | 85 - .../NegativePaymentAmountException.php | 34 - .../Exception/OrderConstraintException.php | 38 - .../Exception/OrderEmailSendException.php | 43 - .../Domain/Order/Exception/OrderException.php | 36 - .../Exception/OrderNotFoundException.php | 62 - .../ReturnProductDisabledException.php | 34 - .../TransistEmailSendingException.php | 34 - .../Command/GenerateInvoiceCommand.php | 56 - .../Command/UpdateInvoiceNoteCommand.php | 71 - .../GenerateOrderInvoiceHandlerInterface.php | 40 - .../UpdateInvoiceNoteHandlerInterface.php | 40 - .../Invoice/Exception/InvoiceException.php | 36 - .../Exception/InvoiceNotFoundException.php | 34 - .../Invoice/ValueObject/OrderInvoiceId.php | 60 - src/Core/Domain/Order/OrderAddressType.php | 38 - src/Core/Domain/Order/OrderConstraints.php | 35 - src/Core/Domain/Order/OrderDiscountType.php | 48 - src/Core/Domain/Order/OrderDocumentType.php | 39 - .../Payment/Command/AddPaymentCommand.php | 176 - .../AddPaymentHandlerInterface.php | 40 - .../Payment/Exception/PaymentException.php | 36 - .../Payment/ValueObject/OrderPaymentId.php | 60 - .../Command/AddProductToOrderCommand.php | 271 - .../Command/DeleteProductFromOrderCommand.php | 71 - .../Command/UpdateProductInOrderCommand.php | 158 - .../AddProductToOrderHandlerInterface.php | 40 - ...DeleteProductFromOrderHandlerInterface.php | 40 - .../UpdateProductInOrderHandlerInterface.php | 40 - .../Product/Exception/ProductException.php | 36 - .../Domain/Order/Query/GetOrderForViewing.php | 77 - .../Domain/Order/Query/GetOrderPreview.php | 53 - .../Query/GetOrderProductsForViewing.php | 140 - .../GetOrderForViewingHandlerInterface.php | 40 - .../GetOrderPreviewHandlerInterface.php | 43 - ...rderProductsForViewingHandlerInterface.php | 43 - .../QueryResult/LinkedOrderForViewing.php | 89 - .../QueryResult/LinkedOrdersForViewing.php | 59 - .../QueryResult/OrderCarrierForViewing.php | 182 - .../QueryResult/OrderCustomerForViewing.php | 198 - .../QueryResult/OrderDiscountForViewing.php | 96 - .../QueryResult/OrderDiscountsForViewing.php | 61 - .../QueryResult/OrderDocumentForViewing.php | 166 - .../QueryResult/OrderDocumentsForViewing.php | 89 - .../Order/QueryResult/OrderForViewing.php | 540 - .../QueryResult/OrderHistoryForViewing.php | 77 - .../OrderInvoiceAddressForViewing.php | 219 - .../OrderMessageDateForViewing.php | 67 - .../QueryResult/OrderMessageForViewing.php | 196 - .../QueryResult/OrderMessagesForViewing.php | 75 - .../QueryResult/OrderPaymentForViewing.php | 198 - .../QueryResult/OrderPaymentsForViewing.php | 113 - .../Domain/Order/QueryResult/OrderPreview.php | 119 - .../OrderPreviewInvoiceDetails.php | 233 - .../QueryResult/OrderPreviewProductDetail.php | 151 - .../OrderPreviewShippingDetails.php | 249 - .../QueryResult/OrderPricesForViewing.php | 245 - .../OrderProductCustomizationForViewing.php | 101 - .../OrderProductCustomizationsForViewing.php | 86 - .../QueryResult/OrderProductForViewing.php | 533 - .../QueryResult/OrderProductsForViewing.php | 61 - .../QueryResult/OrderReturnForViewing.php | 166 - .../QueryResult/OrderReturnsForViewing.php | 59 - .../OrderShippingAddressForViewing.php | 205 - .../QueryResult/OrderShippingForViewing.php | 129 - .../QueryResult/OrderSourceForViewing.php | 100 - .../QueryResult/OrderSourcesForViewing.php | 61 - .../QueryResult/OrderStatusForViewing.php | 166 - .../Domain/Order/Status/OrderStatusColor.php | 70 - .../Order/ValueObject/OrderDetailRefund.php | 146 - src/Core/Domain/Order/ValueObject/OrderId.php | 70 - src/Core/Domain/Order/VoucherRefundType.php | 49 - .../Command/AddOrderMessageCommand.php | 79 - .../Command/BulkDeleteOrderMessageCommand.php | 58 - .../Command/DeleteOrderMessageCommand.php | 56 - .../Command/EditOrderMessageCommand.php | 86 - .../AddOrderMessageHandlerInterface.php | 43 - ...BulkDeleteOrderMessageHandlerInterface.php | 40 - .../DeleteOrderMessageHandlerInterface.php | 40 - .../EditOrderMessageHandlerInterface.php | 40 - .../OrderMessageConstraintException.php | 31 - .../Exception/OrderMessageException.php | 38 - .../OrderMessageNotFoundException.php | 66 - .../OrderMessage/OrderMessageConstraint.php | 36 - .../Query/GetOrderMessageForEditing.php | 56 - ...OrderMessageForEditingHandlerInterface.php | 43 - .../QueryResult/EditableOrderMessage.php | 86 - .../ValueObject/OrderMessageId.php | 54 - .../Command/BulkDeleteAttributeCommand.php | 71 - .../Command/DeleteAttributeCommand.php | 59 - .../BulkDeleteAttributeHandlerInterface.php | 40 - .../DeleteAttributeHandlerInterface.php | 40 - .../AttributeConstraintException.php | 38 - .../Exception/AttributeException.php | 36 - .../Exception/AttributeNotFoundException.php | 34 - .../Exception/DeleteAttributeException.php | 43 - .../Attribute/ValueObject/AttributeId.php | 73 - .../BulkDeleteAttributeGroupCommand.php | 71 - .../Command/DeleteAttributeGroupCommand.php | 59 - ...lkDeleteAttributeGroupHandlerInterface.php | 40 - .../DeleteAttributeGroupHandlerInterface.php | 40 - .../AttributeGroupConstraintException.php | 38 - .../Exception/AttributeGroupException.php | 36 - .../AttributeGroupNotFoundException.php | 34 - .../DeleteAttributeGroupException.php | 43 - .../ValueObject/AttributeGroupId.php | 81 - .../CombinationConstraintException.php | 35 - .../Exception/CombinationException.php | 36 - .../Combination/ValueObject/CombinationId.php | 71 - .../AssignProductToCategoryCommand.php | 100 - .../Command/UpdateProductStatusCommand.php | 73 - ...ssignProductToCategoryHandlerInterface.php | 37 - ...teProductStatusCommandHandlerInterface.php | 40 - .../Customization/CustomizationSettings.php | 38 - .../CustomizationConstraintException.php | 48 - .../Exception/CustomizationException.php | 36 - .../ValueObject/CustomizationId.php | 68 - ...CannotAssignProductToCategoryException.php | 34 - .../CannotUpdateProductException.php | 34 - .../Exception/ProductConstraintException.php | 35 - .../ProductCustomizationNotFoundException.php | 34 - .../Product/Exception/ProductException.php | 36 - .../Exception/ProductNotFoundException.php | 34 - .../Exception/ProductOutOfStockException.php | 34 - .../Product/Query/GetProductIsEnabled.php | 58 - .../Domain/Product/Query/SearchProducts.php | 137 - .../GetProductIsEnabledHandlerInterface.php | 42 - .../SearchProductsHandlerInterface.php | 43 - .../Product/QueryResult/FoundProduct.php | 215 - .../QueryResult/ProductCombination.php | 177 - .../QueryResult/ProductCustomizationField.php | 106 - .../Domain/Product/ValueObject/ProductId.php | 68 - .../Command/AbstractProfileCommand.php | 74 - .../Profile/Command/AddProfileCommand.php | 34 - .../Command/BulkDeleteProfileCommand.php | 66 - .../Profile/Command/DeleteProfileCommand.php | 56 - .../Profile/Command/EditProfileCommand.php | 61 - .../AddProfileHandlerInterface.php | 43 - .../BulkDeleteProfileHandlerInterface.php | 42 - .../DeleteProfileHandlerInterface.php | 42 - .../EditProfileHandlerInterface.php | 40 - ...CannotDeleteSuperAdminProfileException.php | 34 - .../FailedToDeleteProfileException.php | 48 - .../Exception/ProfileConstraintException.php | 38 - .../Profile/Exception/ProfileException.php | 36 - .../Exception/ProfileNotFoundException.php | 34 - src/Core/Domain/Profile/ProfileSettings.php | 35 - .../Profile/Query/GetProfileForEditing.php | 56 - .../GetProfileForEditingHandlerInterface.php | 42 - .../Profile/QueryResult/EditableProfile.php | 71 - .../Domain/Profile/ValueObject/ProfileId.php | 77 - .../Shop/Command/UploadLogosCommand.php | 179 - .../UploadLogosHandlerInterface.php | 40 - src/Core/Domain/Shop/DTO/ShopLogoSettings.php | 76 - .../NotSupportedFaviconExtensionException.php | 34 - ...otSupportedLogoImageExtensionException.php | 31 - .../Domain/Shop/Exception/ShopException.php | 36 - src/Core/Domain/Shop/Query/GetLogosPaths.php | 34 - .../GetLogosPathsHandlerInterface.php | 43 - .../Domain/Shop/QueryResult/LogosPaths.php | 103 - .../Shop/ValueObject/ShopConstraint.php | 127 - .../Domain/Shop/ValueObject/ShopGroupId.php | 76 - src/Core/Domain/Shop/ValueObject/ShopId.php | 77 - .../Command/CloseShowcaseCardCommand.php | 83 - .../CloseShowcaseCardHandler.php | 69 - .../CloseShowcaseCardHandlerInterface.php | 42 - .../Domain/ShowcaseCard/ConfigurationMap.php | 80 - .../InvalidShowcaseCardNameException.php | 35 - .../Exception/ShowcaseCardException.php | 37 - .../Query/GetShowcaseCardIsClosed.php | 82 - .../GetShowcaseCardIsClosedHandler.php | 72 - ...etShowcaseCardIsClosedHandlerInterface.php | 44 - .../ShowcaseCard/ValueObject/ShowcaseCard.php | 125 - .../Command/AddSpecificPriceCommand.php | 378 - ...eleteSpecificPriceByCartProductCommand.php | 91 - .../AddSpecificPriceHandlerInterface.php | 43 - ...ificPriceByCartProductHandlerInterface.php | 40 - .../SpecificPriceConstraintException.php | 48 - .../Exception/SpecificPriceException.php | 36 - .../SpecificPriceNotFoundException.php | 34 - .../ValueObject/SpecificPriceId.php | 73 - .../Command/AddSqlRequestCommand.php | 114 - .../Command/BulkDeleteSqlRequestCommand.php | 80 - .../Command/DeleteSqlRequestCommand.php | 68 - .../Command/EditSqlRequestCommand.php | 135 - .../Command/SaveSqlRequestSettingsCommand.php | 87 - .../AddSqlRequestHandlerInterface.php | 42 - .../BulkDeleteSqlRequestHandlerInterface.php | 40 - .../DeleteSqlRequestHandlerInterface.php | 42 - .../EditSqlRequestHandlerInterface.php | 40 - .../SaveSqlRequestSettingsHandler.php | 76 - ...SaveSqlRequestSettingsHandlerInterface.php | 40 - .../SqlManagement/DatabaseTableFields.php | 79 - .../SqlManagement/DatabaseTablesList.php | 78 - .../SqlManagement/EditableSqlRequest.php | 141 - .../CannotAddSqlRequestException.php | 34 - .../CannotDeleteSqlRequestException.php | 43 - .../CannotEditSqlRequestException.php | 34 - .../SqlManagementConstraintException.php | 53 - .../Exception/SqlManagementException.php | 36 - .../SqlRequestConstraintException.php | 53 - .../Exception/SqlRequestException.php | 34 - .../Exception/SqlRequestNotFoundException.php | 34 - .../SqlRequestSettingsConstraintException.php | 36 - .../Query/GetDatabaseTableFieldsList.php | 76 - .../Query/GetDatabaseTablesList.php | 34 - .../Query/GetSqlRequestExecutionResult.php | 59 - .../Query/GetSqlRequestForEditing.php | 59 - .../Query/GetSqlRequestSettings.php | 34 - ...atabaseTableFieldsListHandlerInterface.php | 43 - .../GetDatabaseTablesListHandlerInterface.php | 43 - ...RequestExecutionResultHandlerInterface.php | 43 - ...etSqlRequestForEditingHandlerInterface.php | 40 - .../GetSqlRequestSettingsHandler.php | 84 - .../GetSqlRequestSettingsHandlerInterface.php | 43 - .../SqlRequestExecutionResult.php | 69 - .../SqlManagement/SqlRequestSettings.php | 67 - .../ValueObject/DatabaseTableField.php | 110 - .../ValueObject/SqlRequestId.php | 62 - .../Exception/StateConstraintException.php | 35 - .../Domain/State/Exception/StateException.php | 36 - src/Core/Domain/State/ValueObject/StateId.php | 71 - .../Command/AbstractBulkSupplierCommand.php | 44 - .../Supplier/Command/AddSupplierCommand.php | 295 - .../Command/BulkDeleteSupplierCommand.php | 77 - .../Command/BulkDisableSupplierCommand.php | 77 - .../Command/BulkEnableSupplierCommand.php | 77 - .../Command/DeleteSupplierCommand.php | 59 - .../Supplier/Command/EditSupplierCommand.php | 459 - .../Command/ToggleSupplierStatusCommand.php | 59 - .../AddSupplierHandlerInterface.php | 43 - .../BulkDeleteSupplierHandlerInterface.php | 40 - .../BulkDisableSupplierHandlerInterface.php | 40 - .../BulkEnableSupplierHandlerInterface.php | 40 - .../DeleteSupplierHandlerInterface.php | 40 - .../EditSupplierHandlerInterface.php | 40 - .../ToggleSupplierStatusHandlerInterface.php | 40 - .../CannotDeleteSupplierAddressException.php | 34 - .../CannotDeleteSupplierException.php | 48 - ...DeleteSupplierProductRelationException.php | 34 - .../CannotToggleSupplierStatusException.php | 34 - .../CannotUpdateSupplierStatusException.php | 34 - .../Exception/SupplierConstraintException.php | 38 - .../Supplier/Exception/SupplierException.php | 36 - .../Exception/SupplierNotFoundException.php | 34 - .../Supplier/Query/GetSupplierForEditing.php | 60 - .../Supplier/Query/GetSupplierForViewing.php | 75 - .../GetSupplierForEditingHandlerInterface.php | 43 - .../GetSupplierForViewingHandlerInterface.php | 43 - .../Supplier/QueryResult/EditableSupplier.php | 330 - .../Supplier/QueryResult/ViewableSupplier.php | 69 - src/Core/Domain/Supplier/SupplierSettings.php | 53 - .../Supplier/ValueObject/SupplierId.php | 71 - src/Core/Domain/Tax/Command/AddTaxCommand.php | 92 - .../Tax/Command/BulkDeleteTaxCommand.php | 71 - .../Command/BulkToggleTaxStatusCommand.php | 102 - .../Domain/Tax/Command/DeleteTaxCommand.php | 58 - .../Domain/Tax/Command/EditTaxCommand.php | 134 - .../Tax/Command/ToggleTaxStatusCommand.php | 90 - .../CommandHandler/AddTaxHandlerInterface.php | 40 - .../BulkDeleteTaxHandlerInterface.php | 40 - .../BulkToggleTaxStatusHandlerInterface.php | 40 - .../DeleteTaxHandlerInterface.php | 40 - .../EditTaxHandlerInterface.php | 40 - .../ToggleTaxStatusHandlerInterface.php | 40 - .../Tax/Exception/DeleteTaxException.php | 43 - .../Tax/Exception/TaxConstraintException.php | 43 - .../Domain/Tax/Exception/TaxException.php | 36 - .../Tax/Exception/TaxNotFoundException.php | 34 - .../Tax/Exception/UpdateTaxException.php | 43 - .../Domain/Tax/Query/GetTaxForEditing.php | 56 - .../GetTaxForEditingHandlerInterface.php | 43 - .../Domain/Tax/QueryResult/EditableTax.php | 103 - src/Core/Domain/Tax/ValueObject/TaxId.php | 62 - .../BulkDeleteTaxRulesGroupCommand.php | 71 - .../BulkSetTaxRulesGroupStatusCommand.php | 86 - .../Command/DeleteTaxRulesGroupCommand.php | 59 - .../Command/SetTaxRulesGroupStatusCommand.php | 74 - ...ulkDeleteTaxRulesGroupHandlerInterface.php | 40 - ...gleTaxRulesGroupStatusHandlerInterface.php | 40 - .../DeleteTaxRulesGroupHandlerInterface.php | 40 - ...gleTaxRulesGroupStatusHandlerInterface.php | 40 - ...CannotBulkDeleteTaxRulesGroupException.php | 55 - ...CannotBulkUpdateTaxRulesGroupException.php | 61 - .../CannotDeleteTaxRulesGroupException.php | 34 - .../CannotUpdateTaxRulesGroupException.php | 38 - .../TaxRulesGroupConstraintException.php | 38 - .../Exception/TaxRulesGroupException.php | 36 - .../TaxRulesGroupNotFoundException.php | 34 - .../Query/GetTaxRulesGroupForEditing.php | 59 - ...axRulesGroupForEditingHandlerInterface.php | 43 - .../QueryResult/EditableTaxRulesGroup.php | 71 - .../ValueObject/TaxRulesGroupId.php | 71 - .../AdaptThemeToRTLLanguagesCommand.php | 56 - .../Theme/Command/DeleteThemeCommand.php | 56 - .../Theme/Command/EnableThemeCommand.php | 56 - .../Theme/Command/ImportThemeCommand.php | 56 - .../Command/ResetThemeLayoutsCommand.php | 56 - .../AdaptThemeToRTLLanguagesHandler.php | 70 - ...aptThemeToRTLLanguagesHandlerInterface.php | 40 - .../CommandHandler/DeleteThemeHandler.php | 62 - .../DeleteThemeHandlerInterface.php | 40 - .../CommandHandler/EnableThemeHandler.php | 101 - .../EnableThemeHandlerInterface.php | 40 - .../CommandHandler/ImportThemeHandler.php | 99 - .../ImportThemeHandlerInterface.php | 40 - .../ResetThemeLayoutsHandler.php | 60 - .../ResetThemeLayoutsHandlerInterface.php | 40 - ...annotAdaptThemeToRTLLanguagesException.php | 34 - .../Exception/CannotDeleteThemeException.php | 34 - .../Exception/CannotEnableThemeException.php | 34 - .../CannotResetThemeLayoutsException.php | 34 - .../FailedToEnableThemeModuleException.php | 54 - .../ImportedThemeAlreadyExistsException.php | 61 - .../Exception/InvalidThemeNameException.php | 34 - ...NotSupportedThemeImportSourceException.php | 34 - .../Exception/ThemeConstraintException.php | 53 - .../Domain/Theme/Exception/ThemeException.php | 36 - .../Theme/ValueObject/ThemeImportSource.php | 125 - .../Domain/Theme/ValueObject/ThemeName.php | 83 - src/Core/Domain/ValueObject/Email.php | 124 - src/Core/Domain/ValueObject/Money.php | 79 - src/Core/Domain/ValueObject/QuerySorting.php | 77 - src/Core/Domain/ValueObject/Reduction.php | 140 - .../Command/AddWebserviceKeyCommand.php | 121 - .../Command/EditWebserviceKeyCommand.php | 182 - .../AddWebserviceKeyHandlerInterface.php | 43 - .../EditWebserviceKeyHandlerInterface.php | 40 - .../DuplicateWebserviceKeyException.php | 34 - .../WebserviceConstraintException.php | 38 - .../Exception/WebserviceException.php | 36 - .../WebserviceKeyNotFoundException.php | 34 - .../Query/GetWebserviceKeyForEditing.php | 56 - ...ebserviceKeyForEditingHandlerInterface.php | 43 - .../QueryResult/EditableWebserviceKey.php | 137 - .../Domain/Webservice/ValueObject/Key.php | 73 - .../Webservice/ValueObject/Permission.php | 58 - .../ValueObject/WebserviceKeyId.php | 68 - .../EmailConfigurationTesterInterface.php | 42 - src/Core/Email/EmailDataConfigurator.php | 90 - src/Core/Email/EmailLister.php | 97 - src/Core/Email/EmailLogEraserInterface.php | 49 - src/Core/Email/MailOption.php | 70 - src/Core/Email/SmtpDataConfigurator.php | 101 - src/Core/Email/SwiftMailerValidation.php | 72 - .../EmployeeFormAccessCheckerInterface.php | 62 - .../Employee/Access/ProfileAccessChecker.php | 69 - .../Access/ProfileAccessCheckerInterface.php | 43 - src/Core/Employee/AvatarProviderInterface.php | 40 - .../ContextEmployeeProviderInterface.php | 68 - .../EmployeeDataProviderInterface.php | 51 - .../Employee/FormLanguageChangerInterface.php | 40 - .../NavigationMenuTogglerInterface.php | 40 - src/Core/Encoding/CharsetEncoding.php | 43 - src/Core/EnvironmentInterface.php | 55 - .../Exception/ContainerNotFoundException.php | 31 - src/Core/Exception/CoreException.php | 34 - src/Core/Exception/DatabaseException.php | 34 - src/Core/Exception/FileNotFoundException.php | 31 - src/Core/Exception/IOException.php | 59 - .../Exception/InvalidArgumentException.php | 31 - .../NonASCIIInLocalPartException.php | 36 - src/Core/Exception/ProductException.php | 34 - .../Exception/TranslatableCoreException.php | 141 - src/Core/Exception/TranslatedException.php | 34 - src/Core/Exception/TypeException.php | 35 - src/Core/Export/Data/ExportableData.php | 69 - .../Export/Data/ExportableDataInterface.php | 47 - src/Core/Export/Exception/ExportException.php | 36 - .../Export/Exception/FileWritingException.php | 38 - src/Core/Export/ExportDirectory.php | 70 - .../Export/FileWriter/ExportCsvFileWriter.php | 76 - .../Export/FileWriter/FileWriterInterface.php | 46 - src/Core/Feature/FeatureInterface.php | 52 - src/Core/Feature/TokenInUrls.php | 45 - .../File/Converter/FileConverterInterface.php | 44 - src/Core/File/FileFinderInterface.php | 40 - src/Core/File/InvoiceModelFinder.php | 79 - src/Core/Filter/CollectionFilter.php | 96 - src/Core/Filter/FilterException.php | 32 - src/Core/Filter/FilterInterface.php | 39 - src/Core/Filter/FrontEndObject/CartFilter.php | 53 - .../FrontEndObject/ConfigurationFilter.php | 52 - .../Filter/FrontEndObject/CustomerFilter.php | 62 - .../EmbeddedAttributesFilter.php | 76 - src/Core/Filter/FrontEndObject/MainFilter.php | 78 - .../Filter/FrontEndObject/ProductFilter.php | 125 - .../SearchResultProductFilter.php | 73 - src/Core/Filter/FrontEndObject/ShopFilter.php | 45 - src/Core/Filter/HashMapWhitelistFilter.php | 210 - .../AddressRequiredFieldsChoiceProvider.php | 44 - .../CanonicalRedirectTypeChoiceProvider.php | 82 - .../CarrierByReferenceChoiceProvider.php | 85 - .../CategoryDeleteModeChoiceProvider.php | 84 - .../CmsCategoriesChoiceProvider.php | 76 - .../ContactByIdChoiceProvider.php | 73 - .../CountryByIdChoiceProvider.php | 146 - .../CountryByIsoCodeChoiceProvider.php | 75 - .../CurrencyByIdChoiceProvider.php | 66 - .../CurrencyNameByIsoCodeChoiceProvider.php | 72 - .../CustomerAddressesChoiceProvider.php | 84 - .../CustomerDeleteMethodChoiceProvider.php | 73 - .../CustomerRequiredFieldsChoiceProvider.php | 60 - ...omerServiceOrderMessagesChoiceProvider.php | 59 - ...ServiceOrderMessagesNameChoiceProvider.php | 59 - .../DefaultMetaPageNameChoiceProvider.php | 101 - .../EmailContentTypeChoiceProvider.php | 62 - .../GroupByIdChoiceProvider.php | 73 - .../ImportEntityFieldChoiceProvider.php | 85 - ...ImportMatchConfigurationChoiceProvider.php | 63 - .../InvoiceModelByNameChoiceProvider.php | 70 - .../LanguageByIdChoiceProvider.php | 67 - .../ChoiceProvider/LanguageChoiceProvider.php | 68 - ...ocalizationPackByIsoCodeChoiceProvider.php | 130 - .../MailMethodChoiceProvider.php | 96 - .../MailThemeChoiceProvider.php | 72 - .../ModuleByNameChoiceProvider.php | 65 - .../ModuleMetaPageNameChoiceProvider.php | 99 - ...NonInstalledLocalizationChoiceProvider.php | 89 - .../OrderDiscountTypeChoiceProvider.php | 56 - .../OrderStateByIdChoiceProvider.php | 120 - .../PermissionsChoiceProvider.php | 65 - .../PriceReductionTypeChoiceProvider.php | 61 - .../ChoiceProvider/ProfileChoiceProvider.php | 62 - .../ChoiceProvider/StatusChoiceProvider.php | 62 - .../Form/ChoiceProvider/TabChoiceProvider.php | 74 - .../TaxAddressTypeChoiceProvider.php | 59 - .../TaxInclusionChoiceProvider.php | 60 - .../ThemeByNameChoiceProvider.php | 65 - .../ThemeByNameWithEmailsChoiceProvider.php | 70 - .../ChoiceProvider/ThemeChoiceProvider.php | 67 - .../ThemePageLayoutsChoiceProvider.php | 63 - .../ChoiceProvider/ThemeZipChoiceProvider.php | 72 - .../TimezoneByNameChoiceProvider.php | 66 - .../TranslationTypeChoiceProvider.php | 63 - ...onfigurableFormChoiceProviderInterface.php | 40 - src/Core/Form/DTO/ShopRestriction.php | 70 - src/Core/Form/DTO/ShopRestrictionField.php | 70 - .../FormChoiceAttributeProviderInterface.php | 41 - src/Core/Form/FormChoiceProviderInterface.php | 40 - src/Core/Form/FormDataProviderInterface.php | 49 - src/Core/Form/FormHandler.php | 137 - src/Core/Form/FormHandlerInterface.php | 52 - .../Builder/FormBuilder.php | 130 - .../Builder/FormBuilderFactory.php | 72 - .../Builder/FormBuilderFactoryInterface.php | 43 - .../Builder/FormBuilderInterface.php | 56 - .../DataHandler/AddressFormDataHandler.php | 175 - .../DataHandler/AttachmentFormDataHandler.php | 138 - .../CancellationFormDataHandler.php | 84 - .../CartAddressFormDataHandler.php | 134 - .../CatalogPriceRuleFormDataHandler.php | 153 - .../DataHandler/CategoryFormDataHandler.php | 201 - .../CmsPageCategoryFormDataHandler.php | 104 - .../DataHandler/CmsPageFormDataHandler.php | 117 - .../DataHandler/ContactFormDataHandler.php | 95 - .../DataHandler/CurrencyFormDataHandler.php | 135 - .../DataHandler/CustomerFormDataHandler.php | 177 - .../DataHandler/EmployeeFormDataHandler.php | 197 - .../DataHandler/FeatureFormDataHandler.php | 80 - .../DataHandler/FormDataHandlerInterface.php | 50 - .../DataHandler/LanguageFormDataHandler.php | 116 - .../ManufacturerAddressFormDataHandler.php | 139 - .../ManufacturerFormDataHandler.php | 125 - .../DataHandler/MetaFormDataHandler.php | 90 - .../OrderAddressFormDataHandler.php | 134 - .../OrderMessageFormDataHandler.php | 70 - .../PartialRefundFormDataHandler.php | 85 - .../DataHandler/ProfileFormDataHandler.php | 71 - .../ReturnProductFormDataHandler.php | 82 - .../RootCategoryFormDataHandler.php | 189 - .../DataHandler/SqlRequestFormDataHandler.php | 76 - .../StandardRefundFormDataHandler.php | 84 - .../DataHandler/SupplierFormDataHandler.php | 179 - .../DataHandler/TaxFormDataHandler.php | 86 - .../WebserviceKeyFormDataHandler.php | 99 - .../DataProvider/AddressFormDataProvider.php | 101 - .../AttachmentFormDataProvider.php | 75 - .../CancelProductFormDataProvider.php | 86 - .../CatalogPriceRuleFormDataProvider.php | 108 - .../DataProvider/CategoryFormDataProvider.php | 117 - .../CmsPageCategoryFormDataProvider.php | 91 - .../DataProvider/CmsPageFormDataProvider.php | 98 - .../DataProvider/ContactFormDataProvider.php | 101 - .../DataProvider/CurrencyFormDataProvider.php | 92 - .../DataProvider/CustomerFormDataProvider.php | 141 - .../DataProvider/EmployeeFormDataProvider.php | 103 - .../DataProvider/FeatureFormDataProvider.php | 95 - .../FormDataProviderInterface.php | 49 - .../DataProvider/LanguageFormDataProvider.php | 111 - .../ManufacturerAddressFormDataProvider.php | 98 - .../ManufacturerFormDataProvider.php | 106 - .../DataProvider/MetaFormDataProvider.php | 75 - .../OrderMessageFormDataProvider.php | 72 - .../DataProvider/ProfileFormDataProvider.php | 71 - .../SqlRequestFormDataProvider.php | 75 - .../DataProvider/SupplierFormDataProvider.php | 127 - .../DataProvider/TaxFormDataProvider.php | 75 - .../WebserviceKeyFormDataProvider.php | 107 - .../Handler/FormHandler.php | 177 - .../Handler/FormHandlerFactory.php | 80 - .../Handler/FormHandlerFactoryInterface.php | 44 - .../Handler/FormHandlerInterface.php | 54 - .../Handler/FormHandlerResult.php | 128 - .../Handler/FormHandlerResultInterface.php | 54 - ...StoreSettingsFormDataProviderInterface.php | 41 - .../Foundation/Database/DatabaseInterface.php | 34 - .../EntityDataInconsistencyException.php | 31 - .../Foundation/Database/EntityInterface.php | 44 - .../Foundation/Database/EntityManager.php | 130 - .../Database/EntityManager/QueryBuilder.php | 75 - .../Foundation/Database/EntityMetaData.php | 69 - .../Database/EntityNotFoundException.php | 31 - .../Foundation/Database/EntityRepository.php | 232 - src/Core/Foundation/Database/Exception.php | 33 - .../Exception/InvalidVersionException.php | 51 - src/Core/Foundation/Filesystem/Exception.php | 33 - src/Core/Foundation/Filesystem/FileSystem.php | 146 - src/Core/Foundation/IoC/Container.php | 168 - src/Core/Foundation/IoC/Exception.php | 33 - .../Templating/PresenterInterface.php | 32 - .../Templating/RenderableInterface.php | 36 - .../Foundation/Templating/RenderableProxy.php | 54 - src/Core/Foundation/Version.php | 394 - .../GeoLite/GeoLiteCityChecker.php | 59 - .../GeoLite/GeoLiteCityCheckerInterface.php | 40 - src/Core/Grid/Action/AbstractGridAction.php | 153 - .../Grid/Action/Bulk/AbstractBulkAction.php | 125 - .../Grid/Action/Bulk/BulkActionCollection.php | 66 - .../Bulk/BulkActionCollectionInterface.php | 51 - .../Grid/Action/Bulk/BulkActionInterface.php | 79 - .../Action/Bulk/Type/ButtonBulkAction.php | 62 - .../Category/DeleteCategoriesBulkAction.php | 56 - .../Customer/DeleteCustomersBulkAction.php | 57 - .../Bulk/Type/ModalFormSubmitBulkAction.php | 59 - .../Action/Bulk/Type/SubmitBulkAction.php | 67 - src/Core/Grid/Action/GridActionCollection.php | 67 - .../Action/GridActionCollectionInterface.php | 51 - src/Core/Grid/Action/GridActionInterface.php | 95 - src/Core/Grid/Action/ModalOptions.php | 89 - .../Grid/Action/Row/AbstractRowAction.php | 166 - .../AccessibilityCheckerInterface.php | 42 - .../DeleteProfileAccessibilityChecker.php | 56 - .../PrintDeliverySlipAccessibilityChecker.php | 41 - .../PrintInvoiceAccessibilityChecker.php | 41 - .../Grid/Action/Row/RowActionCollection.php | 45 - .../Row/RowActionCollectionInterface.php | 44 - .../Grid/Action/Row/RowActionInterface.php | 104 - .../Type/Category/DeleteCategoryRowAction.php | 60 - .../Type/Customer/DeleteCustomerRowAction.php | 58 - .../Grid/Action/Row/Type/LinkRowAction.php | 91 - .../Grid/Action/Row/Type/SubmitRowAction.php | 99 - src/Core/Grid/Action/Type/LinkGridAction.php | 60 - .../Grid/Action/Type/SimpleGridAction.php | 40 - .../Grid/Action/Type/SubmitGridAction.php | 62 - .../Grid/Collection/AbstractCollection.php | 89 - src/Core/Grid/Column/AbstractColumn.php | 135 - src/Core/Grid/Column/ColumnCollection.php | 163 - .../Grid/Column/ColumnCollectionInterface.php | 79 - src/Core/Grid/Column/ColumnInterface.php | 80 - .../Type/Attribute/AttributeColorColumn.php | 59 - src/Core/Grid/Column/Type/BooleanColumn.php | 65 - .../Type/Category/CategoryPositionColumn.php | 66 - src/Core/Grid/Column/Type/ColorColumn.php | 59 - .../Grid/Column/Type/Common/ActionColumn.php | 54 - .../Grid/Column/Type/Common/BadgeColumn.php | 66 - .../Column/Type/Common/BulkActionColumn.php | 53 - .../Grid/Column/Type/Common/ChoiceColumn.php | 69 - .../Column/Type/Common/DateTimeColumn.php | 63 - .../Column/Type/Common/DraggableColumn.php | 52 - .../Column/Type/Common/IdentifierColumn.php | 72 - .../Grid/Column/Type/Common/ImageColumn.php | 60 - .../Grid/Column/Type/Common/LinkColumn.php | 92 - .../Column/Type/Common/PositionColumn.php | 77 - .../Grid/Column/Type/Common/ToggleColumn.php | 87 - src/Core/Grid/Column/Type/DataColumn.php | 63 - .../Column/Type/DisableableLinkColumn.php | 92 - .../Employee/EmployeeNameWithAvatarColumn.php | 55 - src/Core/Grid/Column/Type/LinkGroupColumn.php | 57 - .../Grid/Column/Type/OrderPriceColumn.php | 61 - src/Core/Grid/Column/Type/PreviewColumn.php | 65 - .../Type/Status/SeverityLevelColumn.php | 59 - .../AttachmentGridDataFactoryDecorator.php | 160 - .../Factory/AttributeGroupGridDataFactory.php | 81 - .../CatalogPriceRuleGridDataFactory.php | 99 - .../Grid/Data/Factory/CategoryDataFactory.php | 82 - .../Factory/CreditSlipGridDataFactory.php | 94 - .../CustomerGridDataFactoryDecorator.php | 120 - .../Data/Factory/DoctrineGridDataFactory.php | 120 - .../Factory/EmptyCategoryGridDataFactory.php | 82 - .../Data/Factory/GridDataFactoryInterface.php | 43 - .../Data/Factory/LanguageGridDataFactory.php | 92 - .../ManufacturerAddressGridDataFactory.php | 86 - .../Factory/ManufacturerGridDataFactory.php | 98 - .../Data/Factory/OrderGridDataFactory.php | 108 - .../Data/Factory/SupplierGridDataFactory.php | 92 - src/Core/Grid/Data/GridData.php | 86 - src/Core/Grid/Data/GridDataInterface.php | 56 - ...bstractFilterableGridDefinitionFactory.php | 44 - .../Factory/AbstractGridDefinitionFactory.php | 153 - .../Factory/AddressGridDefinitionFactory.php | 292 - .../AttachmentGridDefinitionFactory.php | 267 - .../AttributeGridDefinitionFactory.php | 295 - .../AttributeGroupGridDefinitionFactory.php | 241 - .../Factory/BackupDefinitionFactory.php | 153 - .../Factory/BulkDeleteActionTrait.php | 69 - .../CatalogPriceRuleGridDefinitionFactory.php | 347 - .../Factory/CategoryGridDefinitionFactory.php | 369 - .../CmsPageCategoryDefinitionFactory.php | 360 - .../Factory/CmsPageDefinitionFactory.php | 378 - .../Factory/ContactGridDefinitionFactory.php | 252 - .../CreditSlipGridDefinitionFactory.php | 188 - .../Factory/CurrencyGridDefinitionFactory.php | 189 - .../Factory/CustomerGridDefinitionFactory.php | 444 - .../Factory/EmailLogsDefinitionFactory.php | 289 - .../Factory/EmployeeGridDefinitionFactory.php | 323 - ...lterableGridDefinitionFactoryInterface.php | 44 - .../GridDefinitionFactoryInterface.php | 42 - .../Factory/LanguageGridDefinitionFactory.php | 329 - .../Factory/LogGridDefinitionFactory.php | 268 - ...nufacturerAddressGridDefinitionFactory.php | 286 - .../ManufacturerGridDefinitionFactory.php | 263 - ...MerchandiseReturnGridDefinitionFactory.php | 156 - .../Factory/MetaGridDefinitionFactory.php | 227 - .../AbstractProductGridDefinitionFactory.php | 202 - .../DisabledProductGridDefinitionFactory.php | 138 - .../EmptyCategoryGridDefinitionFactory.php | 218 - ...ctWithCombinationGridDefinitionFactory.php | 47 - ...ithoutCombinationGridDefinitionFactory.php | 47 - ...ithoutDescriptionGridDefinitionFactory.php | 43 - ...oductWithoutImageGridDefinitionFactory.php | 43 - ...oductWithoutPriceGridDefinitionFactory.php | 43 - .../Factory/OrderGridDefinitionFactory.php | 505 - .../OrderMessageGridDefinitionFactory.php | 210 - .../Factory/ProfileGridDefinitionFactory.php | 230 - .../RequestSqlGridDefinitionFactory.php | 252 - .../Factory/SupplierGridDefinitionFactory.php | 281 - .../Factory/TaxGridDefinitionFactory.php | 252 - .../TaxRulesGroupGridDefinitionFactory.php | 238 - .../WebserviceKeyDefinitionFactory.php | 275 - src/Core/Grid/Definition/GridDefinition.php | 186 - .../Definition/GridDefinitionInterface.php | 78 - .../Exception/ColumnNotFoundException.php | 33 - .../Grid/Exception/ExceptionInterface.php | 34 - .../Exception/InvalidActionDataException.php | 33 - .../Exception/InvalidColumnDataException.php | 33 - .../Grid/Exception/InvalidDataException.php | 33 - .../Exception/MissingColumnInRowException.php | 36 - .../UnsupportedParameterException.php | 33 - .../Factory/CategoryGridFactoryDecorator.php | 152 - .../Grid/Filter/CategoryFilterFormFactory.php | 104 - .../Grid/Filter/CmsPageFilterFormFactory.php | 103 - src/Core/Grid/Filter/Filter.php | 115 - src/Core/Grid/Filter/FilterCollection.php | 82 - .../Grid/Filter/FilterCollectionInterface.php | 58 - .../FilterFormFactoryFormActionDecorator.php | 96 - src/Core/Grid/Filter/FilterInterface.php | 79 - .../Grid/Filter/GridFilterFormFactory.php | 92 - .../Filter/GridFilterFormFactoryInterface.php | 45 - src/Core/Grid/Grid.php | 108 - src/Core/Grid/GridFactory.php | 106 - src/Core/Grid/GridFactoryInterface.php | 44 - src/Core/Grid/GridInterface.php | 66 - .../Exception/PositionDataException.php | 34 - .../Position/Exception/PositionException.php | 36 - .../Exception/PositionUpdateException.php | 34 - .../Grid/Position/GridPositionUpdater.php | 84 - .../Position/GridPositionUpdaterInterface.php | 48 - src/Core/Grid/Position/PositionDefinition.php | 104 - .../Position/PositionDefinitionInterface.php | 64 - .../Grid/Position/PositionModification.php | 88 - .../PositionModificationCollection.php | 78 - ...ositionModificationCollectionInterface.php | 61 - .../PositionModificationInterface.php | 55 - src/Core/Grid/Position/PositionUpdate.php | 88 - .../Grid/Position/PositionUpdateFactory.php | 149 - .../PositionUpdateFactoryInterface.php | 48 - .../Grid/Position/PositionUpdateInterface.php | 57 - .../DoctrinePositionUpdateHandler.php | 120 - .../PositionUpdateHandlerInterface.php | 79 - src/Core/Grid/Presenter/GridPresenter.php | 170 - .../Grid/Presenter/GridPresenterInterface.php | 44 - .../Query/AbstractDoctrineQueryBuilder.php | 55 - src/Core/Grid/Query/AddressQueryBuilder.php | 184 - .../Grid/Query/AttachmentQueryBuilder.php | 174 - .../Grid/Query/AttributeGroupQueryBuilder.php | 209 - src/Core/Grid/Query/AttributeQueryBuilder.php | 208 - .../Query/CatalogPriceRuleQueryBuilder.php | 210 - src/Core/Grid/Query/CategoryQueryBuilder.php | 242 - .../Query/CmsPageCategoryQueryBuilder.php | 220 - src/Core/Grid/Query/CmsPageQueryBuilder.php | 202 - src/Core/Grid/Query/ContactQueryBuilder.php | 146 - .../Grid/Query/CreditSlipQueryBuilder.php | 161 - src/Core/Grid/Query/CurrencyQueryBuilder.php | 161 - src/Core/Grid/Query/CustomerQueryBuilder.php | 270 - .../Query/DoctrineQueryBuilderInterface.php | 54 - src/Core/Grid/Query/DoctrineQueryParser.php | 123 - .../DoctrineSearchCriteriaApplicator.php | 67 - ...trineSearchCriteriaApplicatorInterface.php | 56 - src/Core/Grid/Query/EmailLogsQueryBuilder.php | 126 - src/Core/Grid/Query/EmployeeQueryBuilder.php | 192 - .../Query/Filter/DoctrineFilterApplicator.php | 87 - .../DoctrineFilterApplicatorInterface.php | 42 - src/Core/Grid/Query/Filter/SqlFilters.php | 67 - src/Core/Grid/Query/LanguageQueryBuilder.php | 128 - .../Query/ManufacturerAddressQueryBuilder.php | 164 - .../Grid/Query/ManufacturerQueryBuilder.php | 153 - .../Query/MerchandiseReturnQueryBuilder.php | 187 - src/Core/Grid/Query/MetaQueryBuilder.php | 160 - .../AbstractProductQueryBuilder.php | 179 - .../DisabledProductQueryBuilder.php | 81 - .../Monitoring/EmptyCategoryQueryBuilder.php | 199 - ...oQtyProductWithCombinationQueryBuilder.php | 94 - ...yProductWithoutCombinationQueryBuilder.php | 94 - .../ProductWithoutDescriptionQueryBuilder.php | 77 - .../ProductWithoutImageQueryBuilder.php | 88 - .../ProductWithoutPriceQueryBuilder.php | 89 - .../Grid/Query/OrderMessageQueryBuilder.php | 143 - src/Core/Grid/Query/OrderQueryBuilder.php | 316 - src/Core/Grid/Query/ProfileQueryBuilder.php | 134 - src/Core/Grid/Query/QueryParserInterface.php | 41 - src/Core/Grid/Query/SupplierQueryBuilder.php | 246 - src/Core/Grid/Query/TaxQueryBuilder.php | 149 - .../Grid/Query/TaxRulesGroupQueryBuilder.php | 155 - .../Grid/Query/WebserviceKeyQueryBuilder.php | 151 - src/Core/Grid/Record/RecordCollection.php | 51 - .../Grid/Record/RecordCollectionInterface.php | 43 - .../DecoratedSearchCriteriaFactory.php | 44 - src/Core/Grid/Search/SearchCriteria.php | 114 - .../Grid/Search/SearchCriteriaInterface.php | 58 - src/Core/Group/Provider/DefaultGroup.php | 69 - src/Core/Group/Provider/DefaultGroups.php | 104 - .../DefaultGroupsProviderInterface.php | 38 - .../Generator/HookDescriptionGenerator.php | 161 - .../HookDescriptionGeneratorInterface.php | 42 - src/Core/Hook/Hook.php | 69 - src/Core/Hook/HookDescription.php | 84 - src/Core/Hook/HookDispatcher.php | 159 - src/Core/Hook/HookDispatcherAwareTrait.php | 52 - src/Core/Hook/HookDispatcherInterface.php | 70 - src/Core/Hook/HookInterface.php | 47 - ...GridDefinitionHookByServiceIdsProvider.php | 154 - .../HookByFormTypeProviderInterface.php | 40 - .../HookByServiceIdsProviderInterface.php | 40 - ...entifiableObjectHookByFormTypeProvider.php | 154 - src/Core/Hook/RenderedHook.php | 77 - src/Core/Hook/RenderedHookInterface.php | 54 - src/Core/Image/Deleter/ImageFileDeleter.php | 109 - .../Deleter/ImageFileDeleterInterface.php | 53 - src/Core/Image/ImageProviderInterface.php | 42 - src/Core/Image/ImageTypeRepository.php | 105 - .../Image/Parser/ImageTagSourceParser.php | 70 - .../Parser/ImageTagSourceParserInterface.php | 40 - .../Exception/ImageOptimizationException.php | 34 - .../Exception/ImageUploadException.php | 33 - .../Exception/MemoryLimitException.php | 33 - .../UploadedImageConstraintException.php | 36 - .../Image/Uploader/ImageUploaderInterface.php | 43 - .../Import/Access/ImportAccessChecker.php | 56 - .../Access/ImportAccessCheckerInterface.php | 40 - .../Import/Configuration/ImportConfig.php | 215 - .../Configuration/ImportConfigFactory.php | 66 - .../ImportConfigFactoryInterface.php | 44 - .../Configuration/ImportConfigInterface.php | 112 - .../Configuration/ImportRuntimeConfig.php | 257 - .../ImportRuntimeConfigFactory.php | 51 - .../ImportRuntimeConfigFactoryInterface.php | 44 - .../ImportRuntimeConfigInterface.php | 156 - .../Import/CsvValueSeparatorNormalizer.php | 44 - src/Core/Import/Entity.php | 80 - .../Entity/ImportEntityDeleterInterface.php | 40 - src/Core/Import/EntityField/EntityField.php | 103 - .../EntityField/EntityFieldCollection.php | 148 - .../EntityFieldCollectionInterface.php | 69 - .../EntityField/EntityFieldInterface.php | 61 - .../Provider/AddressFieldsProvider.php | 95 - .../Provider/AliasFieldsProvider.php | 78 - .../Provider/CategoryFieldsProvider.php | 94 - .../Provider/CombinationFieldsProvider.php | 119 - .../Provider/CustomerFieldsProvider.php | 92 - .../Provider/EntityFieldsProviderFinder.php | 60 - .../EntityFieldsProviderFinderInterface.php | 42 - .../EntityFieldsProviderInterface.php | 42 - .../Provider/ProductFieldsProvider.php | 193 - .../Provider/StoreContactFieldsProvider.php | 96 - .../Provider/SupplierFieldsProvider.php | 88 - .../Exception/EmptyDataRowException.php | 34 - src/Core/Import/Exception/ImportException.php | 36 - .../Exception/InvalidDataRowException.php | 34 - .../NotSupportedImportEntityException.php | 34 - .../NotSupportedImportTypeException.php | 34 - .../Exception/SkippedIterationException.php | 34 - .../UnavailableImportFileException.php | 34 - .../Exception/UnreadableFileException.php | 34 - src/Core/Import/File/CsvFileReader.php | 106 - src/Core/Import/File/DataCell/DataCell.php | 69 - .../File/DataCell/DataCellInterface.php | 47 - .../Import/File/DataCell/EmptyDataCell.php | 49 - src/Core/Import/File/DataRow/DataRow.php | 133 - .../Import/File/DataRow/DataRowCollection.php | 108 - .../DataRow/DataRowCollectionInterface.php | 52 - .../DataRow/DataRowCollectionPresenter.php | 81 - .../DataRowCollectionPresenterInterface.php | 42 - .../Import/File/DataRow/DataRowInterface.php | 70 - .../Import/File/DataRow/DataRowPresenter.php | 52 - .../DataRow/DataRowPresenterInterface.php | 42 - .../Factory/DataRowCollectionFactory.php | 70 - .../DataRowCollectionFactoryInterface.php | 46 - src/Core/Import/File/FileFinder.php | 72 - src/Core/Import/File/FileOpenerInterface.php | 42 - src/Core/Import/File/FileReaderInterface.php | 48 - src/Core/Import/File/FileRemoval.php | 57 - src/Core/Import/File/FileUploader.php | 139 - .../Handler/ImportHandlerFinderInterface.php | 42 - .../Import/Handler/ImportHandlerInterface.php | 99 - src/Core/Import/ImportDirectory.php | 101 - src/Core/Import/ImportSettings.php | 60 - src/Core/Import/Importer.php | 238 - src/Core/Import/ImporterInterface.php | 52 - src/Core/Import/Sample/SampleFileProvider.php | 71 - .../Sample/SampleFileProviderInterface.php | 44 - src/Core/Import/StringNormalizerInterface.php | 42 - .../Validator/ImportRequestValidator.php | 46 - .../ImportRequestValidatorInterface.php | 42 - .../Exception/InvalidArgumentException.php | 65 - src/Core/Kpi/KpiInterface.php | 34 - src/Core/Kpi/RenderableKpi.php | 40 - src/Core/Kpi/Row/HookableKpiRowFactory.php | 148 - src/Core/Kpi/Row/KpiRow.php | 103 - src/Core/Kpi/Row/KpiRowFactory.php | 70 - src/Core/Kpi/Row/KpiRowFactoryInterface.php | 40 - src/Core/Kpi/Row/KpiRowInterface.php | 62 - src/Core/Kpi/Row/KpiRowPresenter.php | 53 - src/Core/Kpi/Row/KpiRowPresenterInterface.php | 40 - .../Language/Copier/LanguageCopierConfig.php | 99 - .../Copier/LanguageCopierConfigInterface.php | 61 - .../Copier/LanguageCopierInterface.php | 42 - .../Language/LanguageActivatorInterface.php | 47 - .../Language/LanguageDefaultFontsCatalog.php | 71 - src/Core/Language/LanguageInterface.php | 76 - .../Language/LanguageRepositoryInterface.php | 63 - .../Language/LanguageValidatorInterface.php | 42 - .../Import/LanguagePackImporterInterface.php | 42 - .../Pack/LanguagePackInstallerInterface.php | 43 - .../Loader/LanguagePackLoaderInterface.php | 40 - .../Pack/Loader/RemoteLanguagePackLoader.php | 69 - .../RTL/InstalledLanguageCheckerInterface.php | 40 - .../Localization/CLDR/ComputingPrecision.php | 48 - .../CLDR/ComputingPrecisionInterface.php | 44 - src/Core/Localization/CLDR/Currency.php | 171 - src/Core/Localization/CLDR/CurrencyData.php | 248 - .../CLDR/CurrencyDataLayerInterface.php | 72 - .../Localization/CLDR/CurrencyInterface.php | 80 - .../CLDR/DataLayer/CurrencyCache.php | 126 - .../CLDR/DataLayer/LocaleCache.php | 125 - .../CLDR/DataLayer/LocaleReference.php | 95 - src/Core/Localization/CLDR/Locale.php | 320 - src/Core/Localization/CLDR/LocaleData.php | 371 - .../CLDR/LocaleDataLayerInterface.php | 76 - .../Localization/CLDR/LocaleDataSource.php | 64 - .../Localization/CLDR/LocaleInterface.php | 164 - .../Localization/CLDR/LocaleRepository.php | 68 - .../Localization/CLDR/NumberSymbolsData.php | 504 - src/Core/Localization/CLDR/Reader.php | 670 - .../Localization/CLDR/ReaderInterface.php | 44 - src/Core/Localization/Currency.php | 222 - .../Currency/CurrencyCollection.php | 159 - .../Localization/Currency/CurrencyData.php | 283 - .../Currency/CurrencyDataLayerInterface.php | 73 - .../Currency/CurrencyDataSource.php | 115 - .../Currency/DataLayer/CurrencyCache.php | 129 - .../Currency/DataLayer/CurrencyDatabase.php | 149 - .../Currency/DataLayer/CurrencyInstalled.php | 97 - .../Currency/DataLayer/CurrencyReference.php | 127 - .../Currency/DataSourceInterface.php | 79 - .../Currency/LocalizedCurrencyId.php | 82 - .../Currency/PatternTransformer.php | 147 - src/Core/Localization/Currency/Repository.php | 124 - .../Currency/RepositoryInterface.php | 73 - src/Core/Localization/CurrencyInterface.php | 118 - .../Exception/LocalizationException.php | 36 - .../LocalizationFileNotFoundException.php | 31 - src/Core/Localization/Locale.php | 185 - src/Core/Localization/Locale/Repository.php | 246 - .../Locale/RepositoryInterface.php | 46 - src/Core/Localization/LocaleInterface.php | 54 - src/Core/Localization/Number/Formatter.php | 403 - .../Pack/Factory/LocalizationPackFactory.php | 43 - .../LocalizationPackFactoryInterface.php | 42 - .../Import/LocalizationPackImportConfig.php | 91 - .../LocalizationPackImportConfigInterface.php | 64 - .../Pack/Import/LocalizationPackImporter.php | 181 - .../LocalizationPackImporterInterface.php | 42 - .../Loader/AbstractLocalizationPackLoader.php | 54 - .../Loader/LocalLocalizationPackLoader.php | 80 - .../LocalizationPackLoaderInterface.php | 51 - .../Loader/RemoteLocalizationPackLoader.php | 87 - .../RTL/Exception/GenerationException.php | 36 - src/Core/Localization/RTL/Processor.php | 242 - .../RTL/StyleSheetProcessorFactory.php | 78 - .../StyleSheetProcessorFactoryInterface.php | 38 - .../Localization/RTL/StylesheetGenerator.php | 232 - .../Localization/Specification/Factory.php | 284 - .../Localization/Specification/Number.php | 345 - .../Specification/NumberCollection.php | 148 - .../Specification/NumberInterface.php | 115 - .../Specification/NumberSymbolList.php | 400 - .../Localization/Specification/Percentage.php | 39 - src/Core/Localization/Specification/Price.php | 190 - src/Core/MailTemplate/FolderThemeCatalog.php | 134 - src/Core/MailTemplate/FolderThemeScanner.php | 184 - src/Core/MailTemplate/Layout/Layout.php | 97 - .../MailTemplate/Layout/LayoutCollection.php | 85 - .../Layout/LayoutCollectionInterface.php | 74 - .../MailTemplate/Layout/LayoutInterface.php | 61 - .../Layout/LayoutVariablesBuilder.php | 97 - .../LayoutVariablesBuilderInterface.php | 50 - .../MailTemplate/MailTemplateGenerator.php | 133 - .../MailTemplate/MailTemplateInterface.php | 62 - .../MailTemplateRendererInterface.php | 66 - .../MailTemplate/MailThemeConfiguration.php | 96 - src/Core/MailTemplate/Theme.php | 81 - .../MailTemplate/ThemeCatalogInterface.php | 57 - src/Core/MailTemplate/ThemeCollection.php | 55 - .../MailTemplate/ThemeCollectionInterface.php | 59 - src/Core/MailTemplate/ThemeInterface.php | 47 - .../Transformation/AbstractTransformation.php | 79 - .../CSSInlineTransformation.php | 103 - .../HTMLToTextTransformation.php | 57 - .../MailVariablesTransformation.php | 75 - .../TransformationCollection.php | 40 - .../TransformationCollectionInterface.php | 51 - .../TransformationInterface.php | 61 - .../MerchandiseReturnOptionsConfiguration.php | 91 - src/Core/Meta/MetaDataProviderInterface.php | 74 - .../PaymentRestrictionsConfigurator.php | 202 - ...ymentRestrictionsConfiguratorInterface.php | 69 - .../PaymentModuleListProviderInterface.php | 40 - .../TabModuleListProviderInterface.php | 42 - .../Module/Exception/ModuleErrorException.php | 39 - .../Module/Exception/ModuleErrorInterface.php | 35 - src/Core/Module/HookConfigurator.php | 118 - src/Core/Module/HookRepository.php | 262 - src/Core/Module/ModuleInterface.php | 35 - src/Core/Module/WidgetInterface.php | 34 - src/Core/Multistore/MultistoreConfig.php | 38 - .../MultistoreContextCheckerInterface.php | 54 - src/Core/Order/InvoiceInterface.php | 40 - .../OrderInvoiceDataProviderInterface.php | 61 - .../Order/OrderSiblingProviderInterface.php | 46 - .../Order/OrderStateDataProviderInterface.php | 42 - .../PDF/Exception/MissingDataException.php | 34 - src/Core/PDF/Exception/PdfException.php | 36 - src/Core/PDF/PDFGeneratorInterface.php | 40 - .../PDF/PDFTemplateTypeProviderInterface.php | 40 - .../PaymentModulePreferencesConfiguration.php | 107 - src/Core/Payment/PaymentOption.php | 374 - .../Payment/PaymentOptionFormDecorator.php | 71 - src/Core/Product/ProductAdminDrawer.php | 134 - src/Core/Product/ProductCsvExporter.php | 112 - src/Core/Product/ProductExporterInterface.php | 42 - src/Core/Product/ProductExtraContent.php | 116 - .../Product/ProductExtraContentFinder.php | 57 - src/Core/Product/ProductInterface.php | 36 - src/Core/Product/ProductListingPresenter.php | 37 - .../Product/ProductPresentationSettings.php | 44 - src/Core/Product/ProductPresenter.php | 37 - .../InvalidSortOrderDirectionException.php | 48 - src/Core/Product/Search/Facet.php | 233 - src/Core/Product/Search/FacetCollection.php | 73 - .../Search/FacetsRendererInterface.php | 55 - src/Core/Product/Search/Filter.php | 254 - src/Core/Product/Search/Pagination.php | 173 - .../Product/Search/ProductSearchContext.php | 142 - .../Search/ProductSearchProviderInterface.php | 44 - .../Product/Search/ProductSearchQuery.php | 294 - .../Product/Search/ProductSearchResult.php | 191 - src/Core/Product/Search/SortOrder.php | 260 - src/Core/Product/Search/SortOrderFactory.php | 61 - .../Product/Search/SortOrdersCollection.php | 71 - .../Product/Search/URLFragmentSerializer.php | 131 - src/Core/Proxy/CachedFileFinderProxy.php | 65 - src/Core/Repository/RepositoryInterface.php | 42 - src/Core/Routing/EntityLinkBuilderFactory.php | 66 - .../Routing/EntityLinkBuilderInterface.php | 58 - .../Exception/BuilderNotFoundException.php | 37 - .../Search/Builder/AbstractFiltersBuilder.php | 68 - .../AbstractRepositoryFiltersBuilder.php | 88 - .../Search/Builder/ChainedFiltersBuilder.php | 85 - .../Search/Builder/ClassFiltersBuilder.php | 77 - .../Search/Builder/EventFiltersBuilder.php | 63 - .../Builder/FiltersBuilderCollection.php | 43 - .../Builder/FiltersBuilderInterface.php | 71 - .../Search/Builder/PersistFiltersBuilder.php | 77 - .../Builder/RepositoryFiltersBuilder.php | 94 - .../Search/Builder/RequestFiltersBuilder.php | 93 - src/Core/Search/ControllerAction.php | 77 - src/Core/Search/Filters.php | 140 - src/Core/Search/Filters/AddressFilters.php | 53 - src/Core/Search/Filters/AttachmentFilters.php | 53 - src/Core/Search/Filters/AttributeFilters.php | 53 - .../Search/Filters/AttributeGroupFilters.php | 53 - src/Core/Search/Filters/BackupFilters.php | 49 - .../Filters/CatalogPriceRuleFilters.php | 53 - src/Core/Search/Filters/CategoryFilters.php | 53 - .../Search/Filters/CmsPageCategoryFilters.php | 52 - src/Core/Search/Filters/CmsPageFilters.php | 49 - src/Core/Search/Filters/ContactFilters.php | 49 - src/Core/Search/Filters/CreditSlipFilters.php | 53 - src/Core/Search/Filters/CurrencyFilters.php | 53 - src/Core/Search/Filters/CustomerFilters.php | 53 - src/Core/Search/Filters/EmailLogsFilter.php | 49 - src/Core/Search/Filters/EmployeeFilters.php | 49 - src/Core/Search/Filters/LanguageFilters.php | 53 - src/Core/Search/Filters/LogsFilters.php | 50 - .../Filters/ManufacturerAddressFilters.php | 53 - .../Search/Filters/ManufacturerFilters.php | 53 - .../Filters/MerchandiseReturnFilters.php | 52 - src/Core/Search/Filters/MetaFilters.php | 49 - .../Monitoring/DisabledProductFilters.php | 53 - .../Monitoring/EmptyCategoryFilters.php | 53 - .../NoQtyProductWithCombinationFilters.php | 53 - .../NoQtyProductWithoutCombinationFilters.php | 53 - .../ProductWithoutDescriptionFilters.php | 53 - .../Monitoring/ProductWithoutImageFilters.php | 53 - .../Monitoring/ProductWithoutPriceFilters.php | 53 - src/Core/Search/Filters/OrderFilters.php | 53 - .../Search/Filters/OrderMessageFilters.php | 53 - src/Core/Search/Filters/ProfileFilters.php | 49 - src/Core/Search/Filters/RequestSqlFilters.php | 46 - src/Core/Search/Filters/SupplierFilters.php | 55 - src/Core/Search/Filters/TaxFilters.php | 49 - .../Search/Filters/TaxRulesGroupFilters.php | 49 - .../Search/Filters/WebserviceKeyFilters.php | 49 - src/Core/Search/SearchParameters.php | 87 - src/Core/Search/SearchParametersInterface.php | 55 - src/Core/Security/FolderGuardInterface.php | 44 - src/Core/Security/HtaccessFolderGuard.php | 74 - src/Core/Session/SessionInterface.php | 82 - src/Core/Shop/LogoUploader.php | 203 - src/Core/Shop/ShopContextInterface.php | 40 - src/Core/Shop/Url/UrlProviderInterface.php | 38 - .../Configuration/SqlRequestConfiguration.php | 132 - .../Exporter/SqlRequestExporter.php | 66 - .../Exporter/SqlRequestExporterInterface.php | 47 - src/Core/Stock/StockManager.php | 419 - src/Core/String/CharacterCleaner.php | 46 - .../Support/ContactRepositoryInterface.php | 42 - .../Ecotax/ProductEcotaxResetterInterface.php | 38 - src/Core/Tax/TaxOptionsConfiguration.php | 122 - .../EmployeeOptionsConfiguration.php | 105 - .../Employee/Configuration/OptionsChecker.php | 72 - .../Configuration/OptionsCheckerInterface.php | 40 - src/Core/Translation/Locale/Converter.php | 101 - src/Core/Util/ArabicToLatinDigitConverter.php | 91 - src/Core/Util/BoolParser.php | 47 - src/Core/Util/ColorBrightnessCalculator.php | 72 - src/Core/Util/DateTime/DateTime.php | 48 - src/Core/Util/DateTime/TimeDefinition.php | 43 - src/Core/Util/File/FileSizeConverter.php | 54 - src/Core/Util/File/YamlParser.php | 110 - .../HelperCard/DocumentationLinkProvider.php | 75 - .../DocumentationLinkProviderInterface.php | 40 - ...CardDocumentationDoesNotExistException.php | 36 - .../InternationalizedDomainNameConverter.php | 49 - src/Core/Util/String/StringModifier.php | 45 - .../Util/String/StringModifierInterface.php | 40 - src/Core/Util/String/StringValidator.php | 71 - .../Util/String/StringValidatorInterface.php | 65 - src/Core/Util/Url/BackUrlProvider.php | 47 - src/Core/Util/Url/UrlFileChecker.php | 78 - src/Core/Util/Url/UrlFileCheckerInterface.php | 47 - src/Core/Validation/Validator.php | 69 - src/Core/Validation/ValidatorInterface.php | 49 - .../Webservice/ServerRequirementsChecker.php | 173 - .../ServerRequirementsCheckerInterface.php | 40 - .../Api/QueryParamsCollection.php | 740 - .../QueryStockMovementParamsCollection.php | 73 - .../Api/QueryStockParamsCollection.php | 90 - .../Api/QueryTranslationParamsCollection.php | 62 - src/PrestaShopBundle/Api/Stock/Movement.php | 64 - .../Api/Stock/MovementsCollection.php | 75 - src/PrestaShopBundle/Cache/CacheWarmer.php | 58 - .../Cache/Factory/CacheSubscriberFactory.php | 48 - .../Cache/LocalizationWarmer.php | 83 - .../Cache/ModuleTemplateCacheWarmer.php | 114 - ...ppendConfigurationFileHooksListCommand.php | 242 - ...ppendHooksListForSqlUpgradeFileCommand.php | 268 - .../CheckTranslationDuplicatesCommand.php | 121 - .../Command/ExportThemeCommand.php | 64 - .../Command/GenerateMailTemplatesCommand.php | 108 - .../Command/LegacyLinkLinterCommand.php | 91 - .../Command/ListCommandsAndQueriesCommand.php | 71 - .../Command/ModuleCommand.php | 196 - .../Command/NamingConventionLinterCommand.php | 89 - .../SecurityAnnotationLinterCommand.php | 86 - .../Command/ThemeEnablerCommand.php | 94 - .../Command/UpdateEUTaxruleGroupsCommand.php | 242 - .../Command/UpdateLicensesCommand.php | 376 - .../Command/UpdateSchemaCommand.php | 224 - .../Component/CsvResponse.php | 297 - .../Controller/Admin/AddonsController.php | 121 - .../Admin/AttachementProductController.php | 84 - .../Controller/Admin/AttributeController.php | 329 - .../Controller/Admin/CategoryController.php | 163 - .../Admin/CombinationController.php | 107 - .../Controller/Admin/CommonController.php | 404 - .../AdministrationController.php | 103 - .../AdvancedParameters/BackupController.php | 300 - .../AdvancedParameters/EmailController.php | 276 - .../AdvancedParameters/EmployeeController.php | 562 - .../AdvancedParameters/ImportController.php | 417 - .../ImportDataConfigurationController.php | 171 - .../AdvancedParameters/LogsController.php | 167 - .../MemcacheServerController.php | 194 - .../PerformanceController.php | 127 - .../AdvancedParameters/ProfileController.php | 300 - .../SqlManagerController.php | 594 - .../SystemInformationController.php | 103 - .../WebserviceController.php | 365 - .../ShopParameters/ContactsController.php | 321 - .../CustomerPreferencesController.php | 97 - .../ShopParameters/MaintenanceController.php | 107 - .../ShopParameters/MetaController.php | 477 - .../OrderPreferencesController.php | 90 - .../ShopParameters/PreferencesController.php | 133 - .../ProductPreferencesController.php | 99 - .../Configure/ShowcaseCardController.php | 93 - .../Controller/Admin/ErrorController.php | 56 - .../Controller/Admin/FeatureController.php | 76 - .../Admin/FrameworkBundleAdminController.php | 529 - .../Improve/Design/CmsPageController.php | 1201 - .../Improve/Design/MailThemeController.php | 548 - .../Improve/Design/PositionsController.php | 234 - .../Improve/Design/ThemeCatalogController.php | 87 - .../Admin/Improve/Design/ThemeController.php | 606 - .../International/CurrencyController.php | 567 - .../International/GeolocationController.php | 110 - .../International/LanguageController.php | 399 - .../International/LocalizationController.php | 161 - .../Improve/International/StateController.php | 67 - .../Improve/International/TaxController.php | 414 - .../International/TaxRulesGroupController.php | 343 - .../Admin/Improve/ModuleController.php | 826 - .../Improve/Modules/AddonsStoreController.php | 90 - .../Improve/Modules/AlertsController.php | 61 - .../Modules/ModuleAbstractController.php | 126 - .../Improve/Modules/UpdatesController.php | 49 - .../Payment/PaymentMethodsController.php | 69 - .../Payment/PaymentPreferencesController.php | 122 - .../Shipping/PreferencesController.php | 91 - .../Controller/Admin/ProductController.php | 1307 - .../Admin/ProductImageController.php | 195 - .../Controller/Admin/SecurityController.php | 63 - .../Admin/Sell/Address/AddressController.php | 685 - .../Sell/Catalog/AttachmentController.php | 361 - .../Sell/Catalog/AttributeController.php | 262 - .../Sell/Catalog/AttributeGroupController.php | 251 - .../Admin/Sell/Catalog/CartRuleController.php | 71 - .../Catalog/CatalogPriceRuleController.php | 292 - .../Admin/Sell/Catalog/CategoryController.php | 842 - .../Admin/Sell/Catalog/FeatureController.php | 188 - .../Sell/Catalog/ManufacturerController.php | 786 - .../Sell/Catalog/MonitoringController.php | 258 - .../Admin/Sell/Catalog/SupplierController.php | 547 - .../Sell/Customer/CustomerController.php | 963 - .../CustomerThreadController.php | 265 - .../MerchandiseReturnController.php | 86 - .../OrderMessageController.php | 249 - .../Admin/Sell/Order/ActionsBarButton.php | 81 - .../Sell/Order/ActionsBarButtonInterface.php | 80 - .../Order/ActionsBarButtonsCollection.php | 40 - .../Admin/Sell/Order/CartController.php | 668 - .../Admin/Sell/Order/CreditSlipController.php | 203 - .../Admin/Sell/Order/DeliveryController.php | 128 - .../Admin/Sell/Order/InvoicesController.php | 147 - .../Admin/Sell/Order/OrderController.php | 1975 -- .../Admin/SpecificPriceController.php | 285 - .../Controller/Admin/StockController.php | 51 - .../Controller/Admin/SupplierController.php | 116 - .../Admin/TranslationsController.php | 293 - .../Admin/VirtualProductController.php | 172 - .../Controller/Admin/WarehouseController.php | 97 - .../Controller/Api/ApiController.php | 209 - .../Controller/Api/AttributeController.php | 49 - .../Controller/Api/CategoryController.php | 49 - .../Controller/Api/FeatureController.php | 49 - .../Controller/Api/I18nController.php | 61 - .../Improve/Design/PositionsController.php | 76 - .../Controller/Api/ManufacturerController.php | 49 - .../Controller/Api/StockController.php | 269 - .../Api/StockMovementController.php | 95 - .../Controller/Api/SupplierController.php | 49 - .../Controller/Api/TranslationController.php | 415 - .../FiltersBuilderResolver.php | 74 - .../SearchParametersResolver.php | 228 - .../CommandsAndQueriesDataCollector.php | 94 - .../DataCollector/HookDataCollector.php | 137 - .../DataCollector/HookRegistry.php | 162 - .../AddOnsConfiguration.php | 94 - .../Compiler/CommandAndQueryCollectorPass.php | 70 - .../Compiler/ContainerInjectionPass.php | 77 - .../Compiler/DynamicRolePass.php | 62 - .../GridDefinitionServiceIdsCollectorPass.php | 82 - ...entifiableObjectFormTypesCollectorPass.php | 99 - .../Compiler/LoadServicesFromModulesPass.php | 84 - .../Compiler/ModulesDoctrineCompilerPass.php | 148 - .../OptionsFormHookNameCollectorPass.php | 170 - .../OverrideTranslatorServiceCompilerPass.php | 50 - .../OverrideTwigServiceCompilerPass.php | 51 - .../PopulateTranslationProvidersPass.php | 56 - .../RemoveXmlCompiledContainerPass.php | 55 - .../Compiler/RouterPass.php | 48 - .../Config/ConfigYamlLoader.php | 105 - .../PrestaShopExtension.php | 82 - src/PrestaShopBundle/Entity/AdminFilter.php | 373 - src/PrestaShopBundle/Entity/Attribute.php | 228 - .../Entity/AttributeGroup.php | 236 - .../Entity/AttributeGroupLang.php | 172 - src/PrestaShopBundle/Entity/AttributeLang.php | 141 - src/PrestaShopBundle/Entity/Lang.php | 365 - src/PrestaShopBundle/Entity/ModuleHistory.php | 198 - .../Entity/ProductDownload.php | 284 - .../Entity/ProductIdentity.php | 83 - .../Repository/AdminFilterRepository.php | 190 - .../AttributeGroupLangRepository.php | 37 - .../Repository/AttributeGroupRepository.php | 37 - .../Repository/AttributeLangRepository.php | 37 - .../Entity/Repository/AttributeRepository.php | 100 - .../Entity/Repository/CategoryRepository.php | 165 - .../Repository/FeatureAttributeRepository.php | 230 - .../Repository/ImportMatchRepository.php | 122 - .../Entity/Repository/LangRepository.php | 113 - .../Entity/Repository/LogRepository.php | 276 - .../Repository/ManufacturerRepository.php | 111 - .../Entity/Repository/ModuleRepository.php | 146 - .../Entity/Repository/NormalizeFieldTrait.php | 81 - .../Repository/OrderInvoiceRepository.php | 86 - .../Repository/RequestSqlRepository.php | 140 - .../Entity/Repository/ShopGroupRepository.php | 37 - .../Entity/Repository/ShopRepository.php | 44 - .../Repository/StockManagementRepository.php | 555 - .../Repository/StockMovementRepository.php | 305 - .../Entity/Repository/StockRepository.php | 390 - .../Entity/Repository/SupplierRepository.php | 106 - .../Entity/Repository/TabLangRepository.php | 37 - .../Entity/Repository/TabRepository.php | 116 - .../Entity/Repository/TimezoneRepository.php | 74 - .../Repository/TranslationRepository.php | 56 - src/PrestaShopBundle/Entity/Shop.php | 242 - src/PrestaShopBundle/Entity/ShopGroup.php | 243 - src/PrestaShopBundle/Entity/StockMvt.php | 498 - src/PrestaShopBundle/Entity/Tab.php | 214 - src/PrestaShopBundle/Entity/TabLang.php | 117 - src/PrestaShopBundle/Entity/Translation.php | 197 - .../Event/Dispatcher/NullDispatcher.php | 83 - .../Event/FilterSearchCriteriaEvent.php | 72 - .../Event/ModuleManagementEvent.php | 52 - .../Event/ModuleZipManagementEvent.php | 50 - .../EventListener/AccessDeniedListener.php | 174 - .../ActionDispatcherLegacyHooksSubscriber.php | 112 - .../BackUrlRedirectResponseListener.php | 102 - .../EventListener/DemoModeEnabledListener.php | 197 - .../FilterCategorySearchCriteriaListener.php | 72 - ...rCmsPageCategorySearchCriteriaListener.php | 95 - .../LegacyParametersListener.php | 74 - .../EventListener/LegacyUrlListener.php | 69 - .../EventListener/ModuleActivatedListener.php | 208 - .../EventListener/ModuleGuardListener.php | 101 - .../MultishopCommandListener.php | 87 - .../EventListener/TokenizedUrlsListener.php | 121 - .../EventListener/UserLocaleListener.php | 60 - .../Exception/FileUploadException.php | 34 - .../Exception/HookModuleNotFoundException.php | 33 - .../Exception/InvalidLanguageException.php | 38 - .../Exception/InvalidModuleException.php | 33 - .../InvalidPaginationParamsException.php | 50 - .../Exception/NotImplementedException.php | 33 - .../Exception/ProductNotFoundException.php | 33 - .../Exception/ServiceDefinitionException.php | 53 - .../Exception/UpdateProductException.php | 36 - .../Performance/CachingType.php | 158 - .../Performance/CombineCompressCacheType.php | 63 - .../Performance/DebugModeType.php | 68 - .../Performance/MediaServersType.php | 71 - .../Performance/MemcacheServerType.php | 68 - .../Performance/OptionalFeaturesType.php | 88 - .../PerformanceFormDataProvider.php | 116 - .../Performance/PerformanceFormHandler.php | 93 - .../Performance/SmartyType.php | 104 - .../Catalog/Category/AbstractCategoryType.php | 244 - .../Admin/Catalog/Category/CategoryType.php | 79 - .../Catalog/Category/RootCategoryType.php | 31 - .../Form/Admin/Category/SimpleCategory.php | 122 - .../Administration/FormDataProvider.php | 86 - .../Administration/GeneralType.php | 74 - .../Administration/NotificationsType.php | 70 - .../Administration/UploadQuotaType.php | 85 - .../Backup/BackupDataProvider.php | 67 - .../Backup/BackupOptionsType.php | 47 - .../EmailConfigurationFormDataProvider.php | 109 - .../Email/EmailConfigurationType.php | 96 - .../Email/SmtpConfigurationType.php | 73 - .../Email/TestEmailSendingType.php | 53 - .../EmployeeOptionsFormDataProvider.php | 67 - .../Employee/EmployeeOptionsType.php | 76 - .../Employee/EmployeeType.php | 262 - ...mportDataConfigurationFormDataProvider.php | 173 - .../Import/ImportDataConfigurationType.php | 111 - .../Import/ImportFormDataProvider.php | 125 - .../ImportFormDataProviderInterface.php | 53 - .../Import/ImportFormHandler.php | 112 - .../Import/ImportFormHandlerInterface.php | 53 - .../AdvancedParameters/Import/ImportType.php | 103 - .../Logs/LogsByEmailType.php | 68 - .../Logs/LogsFormDataProvider.php | 63 - .../Profile/ProfileType.php | 83 - .../RequestSql/SqlRequestFormDataProvider.php | 237 - .../RequestSql/SqlRequestFormHandler.php | 125 - .../SqlRequestSettingsFormDataProvider.php | 67 - .../RequestSql/SqlRequestSettingsType.php | 50 - .../RequestSql/SqlRequestType.php | 76 - .../WebserviceConfigurationType.php | 70 - .../Webservice/WebserviceFormDataProvider.php | 68 - .../Webservice/WebserviceKeyType.php | 164 - .../ShopParameters/Contact/ContactType.php | 145 - .../CustomerPreferencesDataProvider.php | 103 - .../CustomerPreferencesFormHandler.php | 79 - .../CustomerPreferences/GeneralType.php | 71 - .../General/MaintenanceFormDataProvider.php | 65 - .../General/MaintenanceType.php | 99 - .../General/PreferencesFormDataProvider.php | 65 - .../General/PreferencesFormHandler.php | 84 - .../General/PreferencesType.php | 201 - .../OrderPreferences/GeneralType.php | 149 - .../OrderPreferences/GiftOptionsType.php | 124 - .../OrderPreferencesFormDataProvider.php | 167 - .../ProductPreferences/GeneralType.php | 87 - .../ProductPreferences/PageType.php | 80 - .../ProductPreferences/PaginationType.php | 88 - .../ProductPreferencesFormDataProvider.php | 163 - .../ProductPreferencesFormHandler.php | 72 - .../ProductPreferences/StockType.php | 97 - .../Meta/MetaSettingsFormDataProvider.php | 234 - .../TrafficSeo/Meta/MetaType.php | 182 - .../TrafficSeo/Meta/SEOOptionsType.php | 47 - .../TrafficSeo/Meta/SetUpUrlType.php | 95 - .../TrafficSeo/Meta/ShopUrlType.php | 91 - .../TrafficSeo/Meta/UrlSchemaType.php | 82 - .../ForwardCustomerThreadType.php | 93 - .../Admin/Extension/HelpTextExtension.php | 68 - .../Extension/RowAttributesExtension.php | 76 - .../Form/Admin/Feature/ProductFeature.php | 165 - .../Design/MailTheme/GenerateMailsType.php | 91 - .../MailTheme/MailThemeConfigurationType.php | 61 - .../MailTheme/MailThemeFormDataProvider.php | 63 - .../MailTheme/TranslateMailsBodyType.php | 52 - .../Design/Pages/CmsPageCategoryType.php | 207 - .../Improve/Design/Pages/CmsPageType.php | 301 - .../Theme/AdaptThemeToRTLLanguagesType.php | 67 - .../Improve/Design/Theme/ImportThemeType.php | 96 - .../PageLayoutCustomizationFormFactory.php | 106 - ...ayoutCustomizationFormFactoryInterface.php | 43 - .../Theme/PageLayoutsCustomizationType.php | 68 - .../Theme/ShopLogosFormDataProvider.php | 133 - .../Improve/Design/Theme/ShopLogosType.php | 316 - .../Currencies/CurrencyExchangeRateType.php | 62 - .../Currencies/CurrencyFormDataProvider.php | 85 - .../International/Currencies/CurrencyType.php | 246 - .../GeolocationByIpAddressType.php | 47 - .../GeolocationFormDataProvider.php | 138 - .../GeolocationIpAddressWhitelistType.php | 64 - .../Geolocation/GeolocationOptionsType.php | 106 - .../International/Language/LanguageType.php | 173 - .../AdvancedConfigurationType.php | 48 - .../ImportLocalizationPackType.php | 106 - .../Localization/LocalUnitsType.php | 50 - .../LocalizationConfigurationType.php | 103 - .../LocalizationFormDataProvider.php | 91 - .../Tax/TaxOptionsFormDataProvider.php | 67 - .../International/Tax/TaxOptionsType.php | 91 - .../Improve/International/Tax/TaxType.php | 121 - .../Translations/AddUpdateLanguageType.php | 72 - .../Translations/CopyLanguageType.php | 84 - .../Translations/ExportThemeLanguageType.php | 74 - .../Translations/ModifyTranslationsType.php | 120 - .../TranslationsSettingsFormHandler.php | 98 - .../PaymentModulePreferencesType.php | 300 - .../PaymentPreferencesFormDataProvider.php | 68 - .../Preferences/CarrierOptionsType.php | 111 - .../Shipping/Preferences/HandlingType.php | 104 - .../PreferencesFormDataProvider.php | 129 - .../Form/Admin/Product/ProductAttachement.php | 118 - .../Form/Admin/Product/ProductCategories.php | 88 - .../Form/Admin/Product/ProductCombination.php | 250 - .../Admin/Product/ProductCombinationBulk.php | 125 - .../Form/Admin/Product/ProductCustomField.php | 105 - .../Form/Admin/Product/ProductInformation.php | 350 - .../Form/Admin/Product/ProductOptions.php | 310 - .../Form/Admin/Product/ProductPrice.php | 241 - .../Form/Admin/Product/ProductQuantity.php | 338 - .../Form/Admin/Product/ProductSeo.php | 203 - .../Form/Admin/Product/ProductShipping.php | 240 - .../Admin/Product/ProductSpecificPrice.php | 337 - .../Product/ProductSupplierCombination.php | 127 - .../Form/Admin/Product/ProductVirtual.php | 164 - .../Product/ProductWarehouseCombination.php | 102 - .../Sell/Address/CustomerAddressType.php | 393 - .../Sell/Address/ManufacturerAddressType.php | 334 - .../Address/RequiredFieldsAddressType.php | 64 - .../Admin/Sell/Attachment/AttachmentType.php | 94 - .../Form/Admin/Sell/Catalog/FeatureType.php | 77 - .../CatalogPriceRule/CatalogPriceRuleType.php | 249 - .../Sell/Category/DeleteCategoriesType.php | 72 - .../Form/Admin/Sell/Customer/CustomerType.php | 257 - .../Sell/Customer/DeleteCustomersType.php | 74 - .../Admin/Sell/Customer/PrivateNoteType.php | 68 - .../Sell/Customer/RequiredFieldsType.php | 63 - .../Customer/TransferGuestAccountType.php | 47 - ...rchandiseReturnOptionsFormDataProvider.php | 67 - .../MerchandiseReturnOptionsType.php | 61 - .../Sell/CustomerService/OrderMessageType.php | 86 - .../ReplyToCustomerThreadType.php | 78 - .../Sell/Manufacturer/ManufacturerType.php | 201 - .../Admin/Sell/Order/AddOrderCartRuleType.php | 131 - .../Admin/Sell/Order/AddProductRowType.php | 173 - .../Admin/Sell/Order/CancelProductType.php | 159 - .../Form/Admin/Sell/Order/CartSummaryType.php | 119 - .../Sell/Order/ChangeOrderAddressType.php | 94 - .../Sell/Order/ChangeOrderCurrencyType.php | 96 - .../Sell/Order/ChangeOrdersStatusType.php | 82 - .../CreditSlipOptionsFormDataProvider.php | 67 - .../CreditSlip/CreditSlipOptionsType.php | 72 - .../CreditSlip/GeneratePdfByDateType.php | 102 - .../Delivery/SlipOptionsFormDataProvider.php | 65 - .../Sell/Order/Delivery/SlipOptionsType.php | 71 - .../Delivery/SlipPdfFormDataProvider.php | 63 - .../Admin/Sell/Order/Delivery/SlipPdfType.php | 75 - .../Admin/Sell/Order/EditProductRowType.php | 152 - .../Order/Invoices/GenerateByDateType.php | 67 - .../Order/Invoices/GenerateByStatusType.php | 107 - .../Invoices/InvoiceByDateFormHandler.php | 96 - .../Invoices/InvoiceByStatusFormHandler.php | 107 - .../Invoices/InvoiceOptionsDataProvider.php | 104 - .../Order/Invoices/InvoiceOptionsType.php | 130 - .../Invoices/InvoicesByDateDataProvider.php | 113 - .../Invoices/InvoicesByStatusDataProvider.php | 76 - .../Admin/Sell/Order/OrderMessageType.php | 116 - .../Admin/Sell/Order/OrderPaymentType.php | 146 - .../Sell/Order/UpdateOrderShippingType.php | 82 - .../Sell/Order/UpdateOrderStatusType.php | 74 - .../Form/Admin/Sell/Supplier/SupplierType.php | 376 - .../Form/Admin/Type/AddonsConnectType.php | 77 - .../Admin/Type/CategoryChoiceTreeType.php | 70 - .../Form/Admin/Type/ChangePasswordType.php | 145 - .../Admin/Type/ChoiceCategoriesTreeType.php | 97 - .../Type/Common/Team/ProfileChoiceType.php | 72 - .../Form/Admin/Type/CommonAbstractType.php | 90 - .../Form/Admin/Type/CountryChoiceType.php | 127 - .../Form/Admin/Type/CustomContentType.php | 65 - .../Form/Admin/Type/CustomMoneyType.php | 57 - .../Form/Admin/Type/DatePickerType.php | 95 - .../Form/Admin/Type/DateRangeType.php | 74 - .../Form/Admin/Type/EmailType.php | 50 - .../Form/Admin/Type/FormattedTextareaType.php | 86 - .../Form/Admin/Type/GeneratableTextType.php | 70 - .../Admin/Type/IntegerMinMaxFilterType.php | 83 - .../Form/Admin/Type/IpAddressType.php | 52 - .../Type/Material/MaterialChoiceTableType.php | 64 - .../Type/Material/MaterialChoiceTreeType.php | 153 - .../MaterialMultipleChoiceTableType.php | 127 - .../Form/Admin/Type/MoneyWithSuffixType.php | 83 - .../Admin/Type/NumberMinMaxFilterType.php | 72 - .../Form/Admin/Type/ReductionType.php | 76 - .../Form/Admin/Type/ResizableTextType.php | 79 - .../Form/Admin/Type/SearchAndResetType.php | 122 - .../Form/Admin/Type/ShopChoiceTreeType.php | 92 - .../Type/ShopRestrictionCheckboxType.php | 71 - .../Form/Admin/Type/SwitchType.php | 81 - .../Form/Admin/Type/TextEmptyType.php | 57 - .../Admin/Type/TextWithLengthCounterType.php | 75 - .../Type/TextWithRecommendedLengthType.php | 67 - .../Form/Admin/Type/TextWithUnitType.php | 75 - .../Form/Admin/Type/TextareaEmptyType.php | 57 - .../Form/Admin/Type/TranslatableType.php | 351 - .../Form/Admin/Type/TranslateTextType.php | 103 - .../Form/Admin/Type/TranslateType.php | 163 - .../Form/Admin/Type/TranslatorAwareType.php | 82 - .../Type/TypeaheadCustomerCollectionType.php | 132 - .../Type/TypeaheadProductCollectionType.php | 155 - .../TypeaheadProductPackCollectionType.php | 113 - .../Form/Admin/Type/YesAndNoChoiceType.php | 59 - .../ArabicToLatinDigitDataTransformer.php | 71 - ...ltLanguageToFilledArrayDataTransformer.php | 91 - .../IDNConverterDataTransformer.php | 68 - ...ringArrayToIntegerArrayDataTransformer.php | 59 - .../Form/Extension/DataListExtension.php | 68 - .../Constraints/TinyMceMaxLength.php | 50 - .../Constraints/TinyMceMaxLengthValidator.php | 51 - .../Install/AbstractInstall.php | 71 - src/PrestaShopBundle/Install/Database.php | 132 - src/PrestaShopBundle/Install/DatabaseDump.php | 156 - src/PrestaShopBundle/Install/Install.php | 1174 - src/PrestaShopBundle/Install/Language.php | 138 - src/PrestaShopBundle/Install/LanguageList.php | 196 - src/PrestaShopBundle/Install/Simplexml.php | 77 - src/PrestaShopBundle/Install/SqlLoader.php | 143 - src/PrestaShopBundle/Install/System.php | 87 - src/PrestaShopBundle/Install/Upgrade.php | 1237 - src/PrestaShopBundle/Install/XmlLoader.php | 1434 - .../Kernel/ModuleRepository.php | 99 - .../Kernel/ModuleRepositoryFactory.php | 152 - .../Model/AdminModelAdapter.php | 55 - .../Model/Product/AdminModelAdapter.php | 969 - src/PrestaShopBundle/PrestaShopBundle.php | 77 - .../Resources/config/routing.yml | 8 - .../Resources/config/routing/admin.yml | 23 - .../config/routing/admin/_common.yml | 62 - .../config/routing/admin/_errors.yml | 5 - .../config/routing/admin/_security.yml | 5 - .../routing/admin/configure/_configure.yml | 16 - .../_advanced_parameters.yml | 43 - .../advanced_parameters/administration.yml | 15 - .../configure/advanced_parameters/backup.yml | 55 - .../configure/advanced_parameters/email.yml | 60 - .../advanced_parameters/employee.yml | 108 - .../configure/advanced_parameters/import.yml | 96 - .../configure/advanced_parameters/logs.yml | 30 - .../advanced_parameters/performance.yml | 58 - .../advanced_parameters/profiles.yml | 55 - .../advanced_parameters/sql_request.yml | 97 - .../system_information.yml | 16 - .../advanced_parameters/webservice.yml | 91 - .../shop_parameters/_shop_parameters.yml | 27 - .../configure/shop_parameters/contacts.yml | 51 - .../shop_parameters/customer_preferences.yml | 15 - .../configure/shop_parameters/maintenance.yml | 15 - .../admin/configure/shop_parameters/meta.yml | 67 - .../shop_parameters/order_preferences.yml | 15 - .../configure/shop_parameters/preferences.yml | 15 - .../shop_parameters/product_preferences.yml | 15 - .../config/routing/admin/improve/_improve.yml | 19 - .../routing/admin/improve/design/_design.yml | 19 - .../improve/design/_mail_theme_deprecated.yml | 22 - .../admin/improve/design/cms_pages.yml | 178 - .../admin/improve/design/mail_theme.yml | 95 - .../admin/improve/design/positions.yml | 15 - .../routing/admin/improve/design/theme.yml | 85 - .../admin/improve/design/theme_catalog.yml | 7 - .../improve/international/_international.yml | 31 - .../improve/international/currencies.yml | 82 - .../improve/international/geolocation.yml | 15 - .../admin/improve/international/language.yml | 71 - .../improve/international/localization.yml | 23 - .../admin/improve/international/state.yml | 6 - .../admin/improve/international/tax.yml | 91 - .../international/tax_rules_groups.yml | 85 - .../improve/international/translations.yml | 46 - .../admin/improve/modules/_modules.yml | 122 - .../routing/admin/improve/modules/addons.yml | 11 - .../admin/improve/payment/payment_methods.yml | 7 - .../admin/improve/payment/preferences.yml | 15 - .../admin/improve/shipping/preferences.yml | 16 - .../config/routing/admin/sell/_sell.yml | 22 - .../routing/admin/sell/catalog/_catalog.yml | 41 - .../routing/admin/sell/catalog/attachment.yml | 69 - .../routing/admin/sell/catalog/attribute.yml | 85 - .../admin/sell/catalog/attribute_group.yml | 87 - .../routing/admin/sell/catalog/cart_rule.yml | 8 - .../admin/sell/catalog/catalog_price_rule.yml | 56 - .../routing/admin/sell/catalog/categories.yml | 149 - .../routing/admin/sell/catalog/features.yml | 19 - .../admin/sell/catalog/manufacturer.yml | 157 - .../routing/admin/sell/catalog/monitoring.yml | 14 - .../sell/catalog/products/attributes.yml | 42 - .../sell/catalog/products/categories.yml | 15 - .../sell/catalog/products/combinations.yml | 16 - .../admin/sell/catalog/products/features.yml | 8 - .../admin/sell/catalog/products/product.yml | 102 - .../admin/sell/catalog/products/products.yml | 110 - .../sell/catalog/products/specific_prices.yml | 42 - .../admin/sell/catalog/products/suppliers.yml | 10 - .../sell/catalog/products/warehouses.yml | 8 - .../routing/admin/sell/catalog/suppliers.yml | 106 - .../routing/admin/sell/customer/_customer.yml | 7 - .../routing/admin/sell/customer/addresses.yml | 93 - .../routing/admin/sell/customer/customers.yml | 199 - .../customer_service/_customer_service.yml | 11 - .../customer_service/customer_threads.yml | 39 - .../customer_service/merchandise_return.yml | 25 - .../sell/customer_service/order_message.yml | 59 - .../routing/admin/sell/orders/_orders.yml | 19 - .../routing/admin/sell/orders/carts.yml | 152 - .../admin/sell/orders/credit_slips.yml | 43 - .../admin/sell/orders/delivery_slips.yml | 15 - .../routing/admin/sell/orders/invoices.yml | 35 - .../routing/admin/sell/orders/orders.yml | 398 - .../config/routing/admin/sell/stocks.yml | 14 - .../Resources/config/routing/api.yml | 39 - .../config/routing/api/attributes.yml | 5 - .../config/routing/api/categories.yml | 5 - .../Resources/config/routing/api/features.yml | 5 - .../Resources/config/routing/api/i18n.yml | 7 - .../routing/api/improve/design/positions.yml | 6 - .../config/routing/api/manufacturers.yml | 5 - .../config/routing/api/stock_movements.yml | 30 - .../Resources/config/routing/api/stocks.yml | 48 - .../config/routing/api/suppliers.yml | 5 - .../config/routing/api/translations.yml | 30 - .../Resources/config/services.yml | 8 - .../config/services/adapter/address.yml | 81 - .../config/services/adapter/admin.yml | 18 - .../config/services/adapter/attachment.yml | 59 - .../config/services/adapter/attribute.yml | 15 - .../services/adapter/attribute_group.yml | 15 - .../config/services/adapter/backup.yml | 12 - .../config/services/adapter/cache.yml | 18 - .../config/services/adapter/cart.yml | 131 - .../config/services/adapter/cart_rule.yml | 15 - .../services/adapter/catalog_price_rule.yml | 33 - .../config/services/adapter/category.yml | 116 - .../config/services/adapter/cms_page.yml | 60 - .../services/adapter/cms_page_category.yml | 94 - .../config/services/adapter/common.yml | 28 - .../config/services/adapter/configuration.yml | 10 - .../config/services/adapter/contact.yml | 30 - .../config/services/adapter/context.yml | 14 - .../config/services/adapter/country.yml | 22 - .../config/services/adapter/credit_slip.yml | 9 - .../config/services/adapter/currency.yml | 109 - .../config/services/adapter/customer.yml | 115 - .../services/adapter/customer_message.yml | 15 - .../services/adapter/customer_service.yml | 36 - .../services/adapter/data_configuration.yml | 258 - .../config/services/adapter/data_provider.yml | 117 - .../services/adapter/data_provider_common.yml | 12 - .../config/services/adapter/email.yml | 12 - .../config/services/adapter/employee.yml | 77 - .../config/services/adapter/feature.yml | 18 - .../config/services/adapter/form.yml | 64 - .../config/services/adapter/grid.yml | 19 - .../config/services/adapter/group.yml | 9 - .../config/services/adapter/image.yml | 20 - .../config/services/adapter/import.yml | 93 - .../Resources/config/services/adapter/kpi.yml | 100 - .../config/services/adapter/language.yml | 64 - .../config/services/adapter/mail_template.yml | 32 - .../config/services/adapter/manufacturer.yml | 56 - .../config/services/adapter/meta.yml | 48 - .../config/services/adapter/module.yml | 83 - .../config/services/adapter/news.yml | 31 - .../config/services/adapter/notification.yml | 16 - .../config/services/adapter/order.yml | 275 - .../config/services/adapter/order_message.yml | 38 - .../Resources/config/services/adapter/pdf.yml | 2 - .../config/services/adapter/pdf/generator.yml | 32 - .../adapter/pdf/template_type_provider.yml | 9 - .../config/services/adapter/prestatrust.yml | 19 - .../config/services/adapter/product.yml | 67 - .../config/services/adapter/profile.yml | 37 - .../config/services/adapter/routes.yml | 6 - .../config/services/adapter/services.yml | 134 - .../config/services/adapter/shop.yml | 36 - .../config/services/adapter/shop_feature.yml | 25 - .../services/adapter/specific_price.yml | 15 - .../config/services/adapter/sql_manager.yml | 59 - .../config/services/adapter/supplier.yml | 89 - .../Resources/config/services/adapter/tax.yml | 45 - .../services/adapter/tax_rules_group.yml | 33 - .../config/services/adapter/theme.yml | 9 - .../config/services/adapter/twig.yml | 10 - .../config/services/adapter/webservice.yml | 29 - .../Resources/config/services/alias.yml | 13 - .../Resources/config/services/bundle/api.yml | 25 - .../config/services/bundle/cache.yml | 29 - .../config/services/bundle/controller.yml | 135 - .../config/services/bundle/data_collector.yml | 32 - .../config/services/bundle/event_listener.yml | 112 - .../Resources/config/services/bundle/form.yml | 2 - .../services/bundle/form/form_builder.yml | 17 - .../bundle/form/form_data_provider.yml | 194 - .../bundle/form/form_data_transformer.yml | 21 - .../services/bundle/form/form_extension.yml | 29 - .../services/bundle/form/form_factory.yml | 10 - .../services/bundle/form/form_handler.yml | 390 - .../config/services/bundle/form/form_type.yml | 1148 - .../bundle/form/form_type/webservice.yml | 14 - .../Resources/config/services/bundle/grid.yml | 15 - .../config/services/bundle/repository.yml | 123 - .../config/services/bundle/routing.yml | 59 - .../config/services/bundle/security.yml | 21 - .../config/services/bundle/services.yml | 108 - .../config/services/bundle/translation.yml | 189 - .../Resources/config/services/bundle/twig.yml | 120 - .../config/services/bundle/utils.yml | 11 - .../Resources/config/services/core/addon.yml | 59 - .../config/services/core/attribute_group.yml | 9 - .../Resources/config/services/core/b2b.yml | 8 - .../Resources/config/services/core/backup.yml | 19 - .../Resources/config/services/core/cache.yml | 21 - .../config/services/core/circuit_breaker.yml | 33 - .../Resources/config/services/core/cldr.yml | 91 - .../config/services/core/cms_page.yml | 8 - .../config/services/core/command_bus.yml | 31 - .../Resources/config/services/core/common.yml | 2 - .../config/services/core/configuration.yml | 15 - .../services/core/constraint_validator.yml | 60 - .../config/services/core/currency.yml | 36 - .../Resources/config/services/core/domain.yml | 2 - .../config/services/core/domain/cart.yml | 3 - .../config/services/core/domain/country.yml | 6 - .../services/core/domain/customer_service.yml | 12 - .../services/core/domain/showcase_card.yml | 28 - .../services/core/domain/sql_management.yml | 23 - .../config/services/core/domain/theme.yml | 46 - .../config/services/core/employee.yml | 15 - .../Resources/config/services/core/export.yml | 13 - .../Resources/config/services/core/file.yml | 16 - .../Resources/config/services/core/form.yml | 2 - .../services/core/form/choice_provider.yml | 247 - .../services/core/form/form_builder.yml | 170 - .../services/core/form/form_data_handler.yml | 167 - .../services/core/form/form_data_provider.yml | 140 - .../services/core/form/form_handler.yml | 179 - .../config/services/core/foundation.yml | 12 - .../config/services/core/geolocation.yml | 8 - .../Resources/config/services/core/grid.yml | 44 - .../core/grid/accessibility_checker.yml | 14 - .../core/grid/doctrine_query_builder.yml | 291 - .../services/core/grid/grid_data_factory.yml | 359 - .../core/grid/grid_definition_factory.yml | 253 - .../services/core/grid/grid_factory.yml | 297 - .../core/grid/grid_filter_form_factory.yml | 38 - .../grid/grid_position_definition_factory.yml | 34 - .../Resources/config/services/core/hook.yml | 88 - .../Resources/config/services/core/image.yml | 11 - .../Resources/config/services/core/import.yml | 128 - .../Resources/config/services/core/kpi.yml | 59 - .../config/services/core/language.yml | 15 - .../config/services/core/localization.yml | 31 - .../config/services/core/mail_template.yml | 50 - .../Resources/config/services/core/module.yml | 11 - .../Resources/config/services/core/search.yml | 62 - .../config/services/core/security.yml | 11 - .../Resources/config/services/core/shop.yml | 8 - .../config/services/core/sql_request.yml | 14 - .../Resources/config/services/core/string.yml | 6 - .../config/services/core/translation.yml | 8 - .../Resources/config/services/core/util.yml | 23 - .../config/services/core/util/file_size.yml | 6 - .../config/services/core/util/helper_card.yml | 73 - .../config/services/core/util/string.yml | 9 - .../config/services/core/validation.yml | 8 - .../config/services/core/webservice.yml | 11 - .../views/Admin/Category/categories.html.twig | 31 - .../Common/Grid/Actions/Bulk/button.html.twig | 34 - .../Actions/Bulk/delete_categories.html.twig | 32 - .../Actions/Bulk/delete_customers.html.twig | 32 - .../Actions/Bulk/modal_form_submit.html.twig | 33 - .../Common/Grid/Actions/Bulk/submit.html.twig | 40 - .../Common/Grid/Actions/Grid/link.html.twig | 33 - .../Common/Grid/Actions/Grid/simple.html.twig | 34 - .../Common/Grid/Actions/Grid/submit.html.twig | 40 - .../Actions/Row/delete_category.html.twig | 48 - .../Actions/Row/delete_customer.html.twig | 48 - .../Common/Grid/Actions/Row/link.html.twig | 55 - .../Common/Grid/Actions/Row/submit.html.twig | 62 - .../Grid/Blocks/EmptyState/_default.html.twig | 29 - .../Blocks/EmptyState/attachment.html.twig | 39 - .../Blocks/EmptyState/credit_slip.html.twig | 38 - .../Grid/Blocks/EmptyState/order.html.twig | 35 - .../Grid/Blocks/EmptyState/supplier.html.twig | 39 - .../Grid/Blocks/Table/empty_row.html.twig | 38 - .../Grid/Blocks/Table/filters_row.html.twig | 42 - .../Grid/Blocks/Table/headers_row.html.twig | 32 - .../Common/Grid/Blocks/bulk_actions.html.twig | 42 - .../Blocks/bulk_actions_select_all.html.twig | 34 - .../Common/Grid/Blocks/grid_actions.html.twig | 71 - .../Common/Grid/Blocks/pagination.html.twig | 48 - .../Admin/Common/Grid/Blocks/table.html.twig | 56 - .../Grid/Columns/Content/action.html.twig | 107 - .../Columns/Content/attribute_color.html.twig | 26 - .../Grid/Columns/Content/badge.html.twig | 35 - .../Grid/Columns/Content/boolean.html.twig | 30 - .../Columns/Content/bulk_action.html.twig | 36 - .../Content/category_position.html.twig | 46 - .../Grid/Columns/Content/choice.html.twig | 65 - .../Grid/Columns/Content/color.html.twig | 30 - .../Grid/Columns/Content/data.html.twig | 26 - .../Grid/Columns/Content/date_time.html.twig | 32 - .../Content/disableable_link.html.twig | 35 - .../Grid/Columns/Content/draggable.html.twig | 28 - .../employee_name_with_avatar.html.twig | 36 - .../Grid/Columns/Content/identifier.html.twig | 48 - .../Grid/Columns/Content/image.html.twig | 26 - .../Grid/Columns/Content/link.html.twig | 51 - .../Grid/Columns/Content/link_group.html.twig | 34 - .../Columns/Content/order_price.html.twig | 34 - .../Grid/Columns/Content/position.html.twig | 28 - .../Columns/Content/position_handle.html.twig | 36 - .../Grid/Columns/Content/preview.html.twig | 40 - .../Columns/Content/severity_level.html.twig | 51 - .../Grid/Columns/Content/toggle.html.twig | 42 - .../Columns/Header/Content/action.html.twig | 27 - .../Columns/Header/Content/default.html.twig | 34 - .../Header/Content/position_handle.html.twig | 24 - .../views/Admin/Common/Grid/grid.html.twig | 60 - .../Admin/Common/Grid/grid_panel.html.twig | 51 - .../views/Admin/Common/Kpi/kpi_row.html.twig | 46 - .../Common/_partials/_form_field.html.twig | 26 - .../Admin/Common/_partials/_sidebar.html.twig | 36 - .../views/Admin/Common/pagination.html.twig | 69 - .../Common/pagination_quicknav.html.twig | 46 - .../Admin/Common/recommendedModules.html.twig | 49 - .../Backup/Blocks/backup_form.html.twig | 35 - .../Backup/Blocks/backup_info.html.twig | 54 - .../Backup/Blocks/backup_warning.html.twig | 44 - .../Backup/Blocks/download_file.html.twig | 42 - .../Backup/Blocks/options.html.twig | 73 - .../Backup/download_view.html.twig | 53 - .../AdvancedParameters/Backup/index.html.twig | 72 - .../Blocks/import_available_fields.html.twig | 44 - .../Blocks/import_file_history.html.twig | 106 - .../Blocks/import_panel.html.twig | 182 - .../Blocks/import_sample_files.html.twig | 47 - .../Blocks/email_configuration.html.twig | 82 - .../Email/Blocks/email_logs_grid.html.twig | 37 - .../Email/Blocks/smtp_configuration.html.twig | 101 - .../Email/Blocks/test_email_sending.html.twig | 69 - .../AdvancedParameters/Email/index.html.twig | 56 - .../Blocks/employee_options.html.twig | 95 - .../Employee/Blocks/form.html.twig | 251 - .../Employee/Blocks/showcase_card.html.twig | 45 - .../Employee/create.html.twig | 53 - .../Employee/edit.html.twig | 66 - .../Employee/index.html.twig | 64 - .../import_data_configuration.html.twig | 174 - .../Blocks/import_modal.html.twig | 87 - .../ImportDataConfiguration/index.html.twig | 47 - .../ImportPage/import.html.twig | 59 - .../LogsPage/Blocks/severity_levels.html.twig | 59 - .../LogsPage/index.html.twig | 83 - .../Profiles/Blocks/form.html.twig | 56 - .../Profiles/create.html.twig | 40 - .../Profiles/edit.html.twig | 40 - .../Profiles/index.html.twig | 43 - .../Blocks/db_tables_panel.html.twig | 82 - .../RequestSql/Blocks/form.html.twig | 69 - .../Blocks/settings_panel.html.twig | 57 - .../RequestSql/create.html.twig | 54 - .../RequestSql/edit.html.twig | 54 - .../RequestSql/index.html.twig | 78 - .../RequestSql/view.html.twig | 78 - .../Webservice/Blocks/form.html.twig | 88 - .../Webservice/create.html.twig | 41 - .../Webservice/edit.html.twig | 41 - .../Webservice/index.html.twig | 81 - .../Webservice/webservice_settings.html.twig | 79 - .../administration.html.twig | 172 - .../memcache_servers.html.twig | 78 - .../AdvancedParameters/performance.html.twig | 226 - .../system_information.html.twig | 287 - .../customer_preferences_general.html.twig | 92 - .../product_preferences_general.html.twig | 102 - .../Blocks/product_preferences_page.html.twig | 101 - .../product_preferences_pagination.html.twig | 71 - .../product_preferences_stock.html.twig | 116 - .../Contact/Contacts/Blocks/form.html.twig | 79 - .../Contact/Contacts/create.html.twig | 40 - .../Contact/Contacts/edit.html.twig | 40 - .../Contact/Contacts/index.html.twig | 43 - .../order_preferences_general.html.twig | 49 - .../order_preferences_gift_options.html.twig | 49 - .../order_preferences.html.twig | 46 - .../Blocks/domain_name_management.html.twig | 56 - .../TrafficSeo/Meta/Blocks/form.html.twig | 105 - .../TrafficSeo/Meta/Blocks/keyword.html.twig | 39 - .../Meta/Blocks/meta_showcase_card.html.twig | 45 - .../Blocks/robots_file_generation.html.twig | 65 - .../seo_options_configuration.html.twig | 56 - .../set_up_urls_configuration.html.twig | 116 - .../Blocks/shop_urls_configuration.html.twig | 115 - .../Blocks/url_schema_configuration.html.twig | 165 - .../TrafficSeo/Meta/create.html.twig | 39 - .../TrafficSeo/Meta/edit.html.twig | 39 - .../TrafficSeo/Meta/index.html.twig | 81 - .../customer_preferences.html.twig | 36 - .../ShopParameters/maintenance.html.twig | 82 - .../ShopParameters/preferences.html.twig | 184 - .../product_preferences.html.twig | 52 - .../views/Admin/Exception/error.html.twig | 88 - .../Admin/Helpers/bootstrap_popup.html.twig | 84 - .../Admin/Helpers/dropdown_menu.html.twig | 73 - .../Admin/Helpers/range_inputs.html.twig | 123 - .../Admin/Helpers/range_slider.html.twig | 96 - .../Design/Cms/Blocks/breadcrumb.html.twig | 53 - .../Design/Cms/Blocks/category_form.html.twig | 102 - .../Improve/Design/Cms/Blocks/form.html.twig | 58 - .../Cms/Blocks/listing_panel_footer.html.twig | 31 - .../Design/Cms/Blocks/seo_preview.html.twig | 26 - .../Design/Cms/Blocks/showcase_card.html.twig | 40 - .../Admin/Improve/Design/Cms/add.html.twig | 40 - .../Design/Cms/create_category.html.twig | 42 - .../Admin/Improve/Design/Cms/edit.html.twig | 41 - .../Design/Cms/edit_category.html.twig | 43 - .../Admin/Improve/Design/Cms/index.html.twig | 82 - .../Blocks/configuration_form.html.twig | 65 - .../Blocks/generate_mails_form.html.twig | 101 - .../Blocks/list_mail_theme_layouts.html.twig | 121 - .../Blocks/list_mail_themes.html.twig | 71 - .../translate_mails_body_form.html.twig | 61 - .../Improve/Design/MailTheme/index.html.twig | 52 - .../Design/MailTheme/preview.html.twig | 34 - .../Theme/Blocks/Partials/logo_card.html.twig | 37 - .../Blocks/Partials/theme_card.html.twig | 52 - .../Partials/theme_card_container.html.twig | 29 - .../Partials/theme_catalog_card.html.twig | 47 - .../Theme/Blocks/delete_theme_modal.html.twig | 50 - .../Blocks/layouts_configuration.html.twig | 59 - .../Theme/Blocks/logo_configuration.html.twig | 154 - .../Theme/Blocks/multishop_switch.html.twig | 38 - .../Theme/Blocks/rtl_configuration.html.twig | 70 - .../Theme/Blocks/use_theme_modal.html.twig | 50 - .../Theme/customize_page_layouts.html.twig | 74 - .../Improve/Design/Theme/import.html.twig | 132 - .../Improve/Design/Theme/index.html.twig | 171 - .../ThemesCatalogPage/addons_store.html.twig | 29 - .../Admin/Improve/Design/positions.html.twig | 214 - .../Currency/Blocks/exchange_rates.html.twig | 69 - .../Currency/Blocks/form.html.twig | 159 - .../International/Currency/create.html.twig | 39 - .../International/Currency/edit.html.twig | 39 - .../International/Currency/index.html.twig | 60 - .../geolocation_by_ip_address.html.twig | 53 - ...geolocation_ip_address_whitelist.html.twig | 64 - .../Blocks/geolocation_options.html.twig | 87 - .../International/Geolocation/index.html.twig | 69 - .../Language/Blocks/form.html.twig | 110 - .../International/Language/create.html.twig | 43 - .../International/Language/edit.html.twig | 43 - .../International/Language/index.html.twig | 67 - .../Blocks/advanced_configuration.html.twig | 61 - .../Blocks/configuration.html.twig | 103 - .../import_localization_pack_block.html.twig | 80 - .../Localization/Blocks/local_units.html.twig | 77 - .../Localization/index.html.twig | 62 - .../International/Tax/Blocks/form.html.twig | 79 - .../Tax/Blocks/tax_options.html.twig | 98 - .../International/Tax/create.html.twig | 40 - .../Improve/International/Tax/edit.html.twig | 42 - .../Improve/International/Tax/index.html.twig | 52 - .../TaxRulesGroup/index.html.twig | 41 - .../Blocks/add_update_language.html.twig | 69 - .../Blocks/copy_language.html.twig | 95 - .../Blocks/export_language.html.twig | 80 - .../Blocks/modify_translations.html.twig | 110 - .../translations_settings.html.twig | 66 - .../Improve/Module/addons_store.html.twig | 29 - .../Blocks/payment_modules_list.html.twig | 70 - .../PaymentMethods/payment_methods.html.twig | 49 - .../payment_preferences_form_block.html.twig | 141 - .../Preferences/payment_preferences.html.twig | 66 - ...ping_preferences_carrier_options.html.twig | 69 - .../shipping_preferences_handling.html.twig | 83 - .../Preferences/preferences.html.twig | 40 - .../Module/Includes/action_button.html.twig | 42 - .../Module/Includes/action_menu.html.twig | 71 - .../Admin/Module/Includes/card_grid.html.twig | 121 - .../Includes/card_grid_addons.html.twig | 33 - .../Admin/Module/Includes/card_list.html.twig | 112 - .../Includes/card_list_addons.html.twig | 35 - .../Includes/card_manage_installed.html.twig | 36 - .../card_notification_configure.html.twig | 32 - .../card_notification_update.html.twig | 50 - .../Module/Includes/categories_card.html.twig | 32 - .../Module/Includes/categories_grid.html.twig | 32 - .../Module/Includes/dropdown_bulk.html.twig | 48 - .../Includes/dropdown_categories.html.twig | 65 - .../dropdown_categories_catalog.html.twig | 56 - .../Module/Includes/dropdown_status.html.twig | 50 - .../Admin/Module/Includes/grid.html.twig | 38 - .../Module/Includes/grid_loader.html.twig | 59 - .../Includes/grid_manage_empty.html.twig | 33 - .../Includes/grid_manage_installed.html.twig | 29 - .../grid_manage_recently_used.html.twig | 31 - .../grid_notification_configure.html.twig | 35 - .../grid_notification_update.html.twig | 35 - .../Admin/Module/Includes/menu_top.html.twig | 69 - .../Includes/modal_addons_connect.html.twig | 110 - .../Module/Includes/modal_confirm.html.twig | 124 - .../modal_confirm_bulk_action.html.twig | 58 - .../modal_confirm_prestatrust.html.twig | 73 - .../Module/Includes/modal_import.html.twig | 90 - .../Module/Includes/modal_read_more.html.twig | 27 - .../modal_read_more_content.html.twig | 207 - .../Admin/Module/Includes/see_more.html.twig | 34 - .../Admin/Module/Includes/sorting.html.twig | 48 - .../Module/Includes/tab-module-line.html.twig | 74 - .../views/Admin/Module/alerts.html.twig | 47 - .../Admin/Module/catalog-refresh.html.twig | 31 - .../views/Admin/Module/catalog.html.twig | 63 - .../views/Admin/Module/common.html.twig | 46 - .../views/Admin/Module/manage.html.twig | 64 - .../Admin/Module/tab-modules-list.html.twig | 77 - .../views/Admin/Module/updates.html.twig | 50 - .../CatalogPage/Blocks/filters.html.twig | 150 - .../CatalogPage/Blocks/tools.html.twig | 52 - .../Forms/form_edit_dropdown.html.twig | 67 - .../CatalogPage/Forms/form_products.html.twig | 80 - .../Product/CatalogPage/Lists/list.html.twig | 143 - .../CatalogPage/Lists/list_quicknav.html.twig | 99 - .../Lists/products_table.html.twig | 211 - .../Product/CatalogPage/catalog.html.twig | 231 - .../CatalogPage/catalog_empty.html.twig | 43 - .../ProductPage/Blocks/footer.html.twig | 151 - .../ProductPage/Blocks/header.html.twig | 94 - .../Product/ProductPage/Blocks/tabs.html.twig | 44 - .../Forms/form_categories.html.twig | 80 - .../Forms/form_combination.html.twig | 269 - .../form_combination_collection.html.twig | 27 - .../Forms/form_combinations.html.twig | 207 - .../Forms/form_combinations_bulk.html.twig | 101 - .../Forms/form_custom_fields.html.twig | 57 - .../form_edit_specific_price_modal.html.twig | 44 - .../ProductPage/Forms/form_feature.html.twig | 48 - .../Forms/form_manufacturer.html.twig | 47 - .../Forms/form_related_products.html.twig | 46 - .../ProductPage/Forms/form_seo.html.twig | 135 - .../ProductPage/Forms/form_shipping.html.twig | 161 - .../Forms/form_specific_price.html.twig | 174 - .../Forms/form_supplier_choice.html.twig | 72 - .../Forms/form_supplier_combination.html.twig | 72 - .../form_warehouse_combination.html.twig | 67 - .../ProductPage/Panels/combinations.html.twig | 191 - .../ProductPage/Panels/essentials.html.twig | 274 - .../ProductPage/Panels/options.html.twig | 228 - .../ProductPage/Panels/pricing.html.twig | 225 - .../Product/ProductPage/Panels/seo.html.twig | 39 - .../ProductPage/disabled_form_alert.html.twig | 35 - .../Product/ProductPage/product.html.twig | 354 - .../Product/Themes/categories_theme.html.twig | 61 - .../views/Admin/ProductImage/form.html.twig | 45 - .../Admin/Security/compromised.html.twig | 72 - .../Admin/Sell/Address/Blocks/form.html.twig | 153 - .../Address/Blocks/required_fields.html.twig | 56 - .../views/Admin/Sell/Address/add.html.twig | 40 - .../views/Admin/Sell/Address/edit.html.twig | 40 - .../views/Admin/Sell/Address/index.html.twig | 66 - .../Address/modal_create_success.html.twig | 51 - .../Catalog/Attachment/Blocks/form.html.twig | 85 - .../Sell/Catalog/Attachment/add.html.twig | 40 - .../Sell/Catalog/Attachment/edit.html.twig | 40 - .../Sell/Catalog/Attachment/index.html.twig | 43 - .../Sell/Catalog/Attribute/index.html.twig | 61 - .../Blocks/showcase_card.html.twig | 48 - .../Catalog/AttributeGroup/index.html.twig | 60 - .../CatalogPriceRule/Blocks/form.html.twig | 104 - .../Catalog/CatalogPriceRule/create.html.twig | 42 - .../Catalog/CatalogPriceRule/edit.html.twig | 42 - .../Catalog/CatalogPriceRule/index.html.twig | 52 - .../Categories/Blocks/breadcrumb.html.twig | 60 - .../Categories/Blocks/cover_image.html.twig | 49 - .../Categories/Blocks/delete_block.html.twig | 63 - .../Blocks/delete_categories_modal.html.twig | 51 - .../Catalog/Categories/Blocks/form.html.twig | 213 - .../Categories/Blocks/javascripts.html.twig | 28 - .../Blocks/listing_panel_footer.html.twig | 37 - .../Blocks/menu_thumbnail_images.html.twig | 47 - .../Categories/Blocks/showcase_card.html.twig | 48 - .../Blocks/thumbnail_image.html.twig | 35 - .../Sell/Catalog/Categories/create.html.twig | 42 - .../Catalog/Categories/create_root.html.twig | 42 - .../Sell/Catalog/Categories/edit.html.twig | 47 - .../Catalog/Categories/edit_root.html.twig | 47 - .../Sell/Catalog/Categories/index.html.twig | 86 - .../Blocks/disabled_feature_warning.html.twig | 35 - .../Catalog/Features/Blocks/form.html.twig | 69 - .../Blocks/form_javascripts.html.twig | 28 - .../Sell/Catalog/Features/create.html.twig | 48 - .../Sell/Catalog/Features/edit.html.twig | 48 - .../Address/Blocks/form.html.twig | 120 - .../Manufacturer/Address/create.html.twig | 40 - .../Manufacturer/Address/edit.html.twig | 40 - .../Blocks/View/addresses.html.twig | 80 - .../Blocks/View/products.html.twig | 120 - .../Manufacturer/Blocks/form.html.twig | 121 - .../Sell/Catalog/Manufacturer/add.html.twig | 43 - .../Sell/Catalog/Manufacturer/edit.html.twig | 43 - .../Sell/Catalog/Manufacturer/index.html.twig | 66 - .../Catalog/Manufacturer/logo_image.html.twig | 28 - .../Sell/Catalog/Manufacturer/view.html.twig | 46 - .../Monitoring/Blocks/showcase_card.html.twig | 48 - .../Sell/Catalog/Monitoring/index.html.twig | 120 - .../Suppliers/Blocks/View/products.html.twig | 92 - .../Catalog/Suppliers/Blocks/form.html.twig | 162 - .../Sell/Catalog/Suppliers/add.html.twig | 43 - .../Sell/Catalog/Suppliers/edit.html.twig | 43 - .../Sell/Catalog/Suppliers/index.html.twig | 53 - .../Catalog/Suppliers/logo_image.html.twig | 28 - .../Sell/Catalog/Suppliers/view.html.twig | 34 - .../Blocks/Index/required_fields.html.twig | 49 - .../Customer/Blocks/View/addresses.html.twig | 120 - .../Blocks/View/bought_products.html.twig | 58 - .../Sell/Customer/Blocks/View/carts.html.twig | 77 - .../Customer/Blocks/View/discounts.html.twig | 104 - .../Customer/Blocks/View/groups.html.twig | 69 - .../Blocks/View/last_connections.html.twig | 60 - .../Customer/Blocks/View/messages.html.twig | 62 - .../Customer/Blocks/View/orders.html.twig | 156 - .../View/personal_information.html.twig | 184 - .../Blocks/View/private_note.html.twig | 46 - .../Blocks/View/sent_emails.html.twig | 60 - .../Blocks/View/viewed_products.html.twig | 56 - .../Customer/Blocks/delete_modal.html.twig | 53 - .../Admin/Sell/Customer/Blocks/form.html.twig | 141 - .../Sell/Customer/Blocks/javascript.html.twig | 29 - .../Customer/Blocks/showcase_card.html.twig | 45 - .../Admin/Sell/Customer/create.html.twig | 43 - .../views/Admin/Sell/Customer/edit.html.twig | 44 - .../views/Admin/Sell/Customer/index.html.twig | 118 - .../Customer/modal_create_success.html.twig | 48 - .../views/Admin/Sell/Customer/view.html.twig | 63 - .../Block/customer_information.html.twig | 84 - .../Block/forward_thread_modal.html.twig | 101 - .../Block/thread_actions.html.twig | 43 - .../Block/thread_messages.html.twig | 83 - .../CustomerThread/Block/timeline.html.twig | 69 - .../Block/your_answer.html.twig | 64 - .../CustomerThread/view.html.twig | 74 - .../Blocks/options.html.twig | 64 - .../MerchandiseReturn/index.html.twig | 54 - .../OrderMessage/Blocks/form.html.twig | 58 - .../OrderMessage/create.html.twig | 40 - .../OrderMessage/edit.html.twig | 40 - .../OrderMessage/index.html.twig | 41 - .../Cart/Blocks/View/cart_summary.html.twig | 215 - .../View/customer_information.html.twig | 72 - .../Blocks/View/order_information.html.twig | 60 - .../Admin/Sell/Order/Cart/view.html.twig | 64 - .../Blocks/credit_slip_options.html.twig | 60 - .../CreditSlip/Blocks/pdf_by_date.html.twig | 64 - .../Sell/Order/CreditSlip/index.html.twig | 59 - .../Admin/Sell/Order/Delivery/slip.html.twig | 118 - .../Blocks/generate_by_date.html.twig | 63 - .../Blocks/generate_by_status.html.twig | 78 - .../Invoices/Blocks/invoice_options.html.twig | 139 - .../Sell/Order/Invoices/invoices.html.twig | 51 - .../Order/Blocks/Create/addresses.html.twig | 72 - .../Order/Order/Blocks/Create/cart.html.twig | 261 - .../Order/Blocks/Create/cart_rules.html.twig | 89 - .../Order/Blocks/Create/customer.html.twig | 247 - .../Order/Blocks/Create/shipping.html.twig | 123 - .../Order/Blocks/Create/summary.html.twig | 126 - .../Modal/add_order_discount_modal.html.twig | 107 - .../View/Modal/add_product_modal.html.twig | 117 - .../update_customer_address_modal.html.twig | 61 - .../View/Modal/update_product_modal.html.twig | 24 - .../Modal/update_shipping_modal.html.twig | 78 - .../Modal/view_all_messages_modal.html.twig | 59 - .../Modal/view_product_pack_modal.html.twig | 81 - .../Blocks/View/add_product_row.html.twig | 91 - .../Order/Blocks/View/customer.html.twig | 253 - .../Order/Order/Blocks/View/details.html.twig | 128 - .../Order/Blocks/View/details_card.html.twig | 34 - .../Order/Blocks/View/discount_list.html.twig | 49 - .../Order/Blocks/View/documents.html.twig | 149 - .../Blocks/View/edit_product_row.html.twig | 58 - .../View/extra_order_button_actions.html.twig | 90 - .../Order/Order/Blocks/View/header.html.twig | 53 - .../Order/Order/Blocks/View/history.html.twig | 75 - .../Order/Blocks/View/linked_orders.html.twig | 75 - .../Blocks/View/merchandise_returns.html.twig | 63 - .../Order/Blocks/View/messages.html.twig | 109 - .../Order/Blocks/View/msg_list_item.html.twig | 65 - .../Order/Blocks/View/order_actions.html.twig | 125 - .../Blocks/View/order_navigation.html.twig | 46 - .../Order/Blocks/View/payments.html.twig | 155 - .../Blocks/View/payments_alert.html.twig | 24 - .../View/print_order_statistics.html.twig | 66 - .../Order/Blocks/View/print_title.html.twig | 31 - .../Order/Order/Blocks/View/product.html.twig | 181 - .../Order/Blocks/View/product_list.html.twig | 10 - .../Order/Blocks/View/products.html.twig | 257 - .../Order/Blocks/View/shipping.html.twig | 101 - .../Order/Order/Blocks/View/sources.html.twig | 63 - .../change_orders_status_modal.html.twig | 56 - .../Admin/Sell/Order/Order/create.html.twig | 71 - .../Admin/Sell/Order/Order/index.html.twig | 60 - .../Admin/Sell/Order/Order/preview.html.twig | 193 - .../Admin/Sell/Order/Order/view.html.twig | 125 - .../views/Admin/Stock/overview.html.twig | 73 - .../Admin/Translations/overview.html.twig | 58 - .../bootstrap_4_horizontal_layout.html.twig | 151 - .../bootstrap_4_layout.html.twig | 827 - .../form_div_layout.html.twig | 420 - .../form_max_length.html.twig | 46 - .../form_table_layout.html.twig | 68 - .../Admin/TwigTemplateForm/material.html.twig | 101 - .../prestashop_ui_kit.html.twig | 128 - .../prestashop_ui_kit_base.html.twig | 849 - .../TwigTemplateForm/typeahead.html.twig | 305 - .../commands_and_queries.html.twig | 122 - .../views/Admin/WebProfiler/config.html.twig | 274 - .../WebProfiler/hooks_collector.html.twig | 165 - .../Resources/views/Admin/layout.html.twig | 104 - .../Resources/views/Admin/macros.html.twig | 310 - .../Converter/AbstractLegacyRouteProvider.php | 150 - .../Converter/CacheKeyGeneratorInterface.php | 44 - .../Routing/Converter/CacheProvider.php | 133 - .../Exception/AlreadyConvertedException.php | 36 - .../Converter/Exception/ArgumentException.php | 34 - .../Exception/RouteNotFoundException.php | 36 - .../Converter/Exception/RoutingException.php | 36 - .../Converter/LegacyParametersConverter.php | 93 - .../Routing/Converter/LegacyRoute.php | 178 - .../LegacyRouteProviderInterface.php | 81 - .../Routing/Converter/LegacyUrlConverter.php | 249 - .../Routing/Converter/RouterProvider.php | 87 - .../Converter/RoutingCacheKeyGenerator.php | 134 - .../Routing/Linter/AdminRouteProvider.php | 67 - .../Linter/Exception/LinterException.php | 36 - .../Exception/NamingConventionException.php | 52 - .../Routing/Linter/LegacyLinkLinter.php | 50 - .../Routing/Linter/NamingConventionLinter.php | 103 - .../Routing/Linter/RouteLinterInterface.php | 43 - .../Linter/SecurityAnnotationLinter.php | 101 - .../Routing/YamlModuleLoader.php | 113 - .../Security/Admin/Employee.php | 190 - .../Security/Admin/EmployeeProvider.php | 122 - .../Security/Annotation/AdminSecurity.php | 135 - .../Security/Annotation/DemoRestricted.php | 149 - .../Security/Annotation/ModuleActivated.php | 151 - .../Security/Role/DynamicRoleHierarchy.php | 39 - .../Security/Voter/PageVoter.php | 117 - .../Service/Cache/Refresh.php | 45 - .../Service/Command/AbstractCommand.php | 117 - .../DataProvider/Admin/AddonsInterface.php | 43 - .../DataProvider/Admin/CategoriesProvider.php | 247 - .../DataProvider/Admin/ModuleInterface.php | 42 - .../DataProvider/Admin/ProductInterface.php | 124 - .../DataProvider/Admin/RecommendedModules.php | 109 - .../DataProvider/Marketplace/ApiClient.php | 346 - .../Service/DataProvider/StockInterface.php | 42 - .../Service/DataProvider/UserProvider.php | 71 - .../DataUpdater/Admin/ProductInterface.php | 106 - .../Database/DoctrineNamingStrategy.php | 72 - .../Service/Database/Upgrade.php | 47 - .../Grid/ControllerResponseBuilder.php | 106 - .../Service/Grid/ResponseBuilder.php | 102 - .../Hook/HookContentClassInterface.php | 32 - .../Service/Hook/HookDispatcher.php | 47 - .../Service/Hook/HookEvent.php | 78 - .../Service/Hook/HookFinder.php | 228 - .../Service/Hook/RenderingHookEvent.php | 101 - .../Service/Log/LogHandler.php | 48 - .../Service/ProductService.php | 54 - .../Service/Routing/Router.php | 101 - .../AdminPagePreferenceInterface.php | 64 - .../AdminUrlGeneratorFactory.php | 77 - .../Service/TranslationService.php | 355 - .../Translation/Api/AbstractApi.php | 58 - .../Translation/Api/InternationalApi.php | 62 - .../Translation/Api/StockApi.php | 90 - .../Translation/Constraints/PassVsprintf.php | 43 - .../Constraints/PassVsprintfValidator.php | 63 - .../Translation/DataCollectorTranslator.php | 35 - .../Translation/DomainNormalizer.php | 56 - .../InvalidLegacyTranslationKeyException.php | 71 - .../LegacyFileFormattingException.php | 53 - .../Exception/UnsupportedLocaleException.php | 68 - .../Exception/UnsupportedModuleException.php | 50 - .../Translation/Exporter/ThemeExporter.php | 410 - .../Extractor/LegacyModuleExtractor.php | 127 - .../LegacyModuleExtractorInterface.php | 48 - .../Translation/Extractor/ThemeExtractor.php | 290 - .../Factory/ProviderNotFoundException.php | 41 - .../Factory/ThemeTranslationsFactory.php | 103 - .../Factory/TranslationsFactory.php | 82 - .../Factory/TranslationsFactoryInterface.php | 61 - .../Loader/DatabaseTranslationLoader.php | 130 - .../Translation/Loader/LegacyFileLoader.php | 98 - .../Translation/Loader/LegacyFileReader.php | 74 - .../Loader/LegacyTranslationKey.php | 128 - .../Loader/SqlTranslationLoader.php | 107 - .../Translation/PrestaShopTranslatorTrait.php | 208 - .../Translation/Provider/AbstractProvider.php | 273 - .../Provider/BackOfficeProvider.php | 71 - .../Provider/DatabaseCatalogueInterface.php | 42 - .../ExternalModuleLegacySystemProvider.php | 322 - .../Provider/FrontOfficeProvider.php | 88 - .../Provider/MailsBodyProvider.php | 65 - .../Translation/Provider/MailsProvider.php | 65 - .../Translation/Provider/ModuleProvider.php | 83 - .../Translation/Provider/ModulesProvider.php | 66 - .../Translation/Provider/OthersProvider.php | 66 - .../Provider/ProviderInterface.php | 70 - .../Translation/Provider/SearchProvider.php | 196 - .../Provider/SearchProviderInterface.php | 45 - .../Translation/Provider/ThemeProvider.php | 240 - .../Provider/TranslationFinder.php | 156 - .../Provider/TranslationFinderTrait.php | 59 - .../Provider/UseDefaultCatalogueInterface.php | 51 - .../Provider/UseModuleInterface.php | 45 - .../Provider/XliffCatalogueInterface.php | 40 - .../Translation/Translator.php | 48 - .../Translation/TranslatorAwareTrait.php | 64 - .../Translation/TranslatorComponent.php | 39 - .../Translation/TranslatorLanguageLoader.php | 109 - .../Translation/TranslatorLanguageTrait.php | 52 - .../Translation/View/TreeBuilder.php | 316 - src/PrestaShopBundle/Twig/AdminExtension.php | 84 - .../Twig/ContextIsoCodeProviderExtension.php | 64 - .../Twig/DataFormatterExtension.php | 143 - .../ColorBrightnessCalculatorExtension.php | 63 - .../Extension/DocumentationLinkExtension.php | 63 - .../Twig/Extension/GridExtension.php | 226 - .../Extension/JsRouterMetadataExtension.php | 93 - .../Twig/Extension/LocalizationExtension.php | 91 - .../Twig/Extension/NumberExtension.php | 52 - .../Extension/PathWithBackUrlExtension.php | 114 - src/PrestaShopBundle/Twig/HookExtension.php | 208 - src/PrestaShopBundle/Twig/LayoutExtension.php | 270 - .../Twig/Locator/ModuleTemplateIterator.php | 109 - .../Twig/Locator/ModuleTemplateLoader.php | 67 - .../Twig/TranslationsExtension.php | 573 - src/PrestaShopBundle/Utils/FloatParser.php | 103 - src/PrestaShopBundle/Utils/ZipManager.php | 57 - .../css/012cf6a10129e2275d79d6adac7f3b02.woff | Bin 57620 -> 0 bytes .../css/0266b05265f317a7409560b751cd61e8.svg | 16 - .../css/082a71677e756fb75817e8f262a07cb4.svg | 18 - .../css/154da4697acc779b55af0a67f1241e4e.ttf | Bin 279268 -> 0 bytes .../199038f07312bfc6f0aabd3ed6a2b64d.woff2 | Bin 160208 -> 0 bytes .../19c1b868764c0e4d15a45d3f61250488.woff2 | Bin 161480 -> 0 bytes .../css/22c0528acb6d9cd5bf4c8f96381bc05c.svg | 38 - .../css/2fd9c16b805724d590c0cff96da070a4.ttf | Bin 414820 -> 0 bytes .../css/332f555bb44cdc394d6c799df0c03389.woff | Bin 166492 -> 0 bytes .../css/36bff72dcba3098b4b70b482b22c29ab.svg | 16 - .../css/3935e107ea61866e60d7946dc6a962f1.svg | 14 - .../css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg | 18 - .../css/3d34be670a7f15086e512282b97ae35e.svg | 19092 ----------- .../css/3d4a907b1b7a232654324a3dd7ae4aa3.eot | Bin 414994 -> 0 bytes .../css/3f81521029cc8a9a703419c4a74704a0.woff | Bin 173164 -> 0 bytes .../css/4f6ff3639c1e5728b905b650c1a06e75.ttf | Bin 290436 -> 0 bytes .../570eb83859dc23dd0eec423a49e147fe.woff2 | Bin 44300 -> 0 bytes .../css/5dc400bcedda37b13f35cb44623193cf.svg | 27050 --------------- .../css/5ea9fdf2293930126fa9c544968009ae.svg | 27184 ---------------- .../css/7988be8b63edf9c4accebf94d5db7927.svg | 16 - .../7a3ebca0cba2e2c6090e84e1d77e0f94.woff2 | Bin 121368 -> 0 bytes .../css/7c24d4275efcbe8891f78378b7c808e0.svg | 16 - .../css/80e74ff9406650e53bbec1e292c2c094.svg | 24745 -------------- .../css/846c191efd3d0aacde5a916cf2ebf1a4.woff | Bin 221000 -> 0 bytes .../css/8b05d51ede908907d65695558974d86f.svg | 14 - .../css/99db8adec61e4fcf5586e1afa549b432.svg | 18 - .../css/a165a42685795361b25593effb32fdb1.ttf | Bin 415132 -> 0 bytes .../css/a37b0c01c0baf1888ca812cc0508f6e2.ttf | Bin 128180 -> 0 bytes .../css/a67175d1ea11389d9107bd8c08f9d7d7.svg | 38 - .../a68cfe9d548950edf5df102269877edd.woff2 | Bin 126924 -> 0 bytes .../css/a77ade19de3d3762dfbf1fe553b293cc.eot | Bin 279454 -> 0 bytes .../css/afb2ed6d67613a724a420a39b4fe5b0d.svg | 16 - .../css/b1db819132e64a3e01911a1413c33acf.svg | 16 - .../css/b467416c449eb823029e16347b2ea510.eot | Bin 290642 -> 0 bytes .../css/c1a65805f759901a39d10eb854c1dcf2.svg | 16 - .../css/c2183257e7a697769df4200c547551f1.woff | Bin 219992 -> 0 bytes .../css/cf2f3c1d5c7cb02c29f61964313148e1.svg | 16 - themes/classic/assets/css/custom.css | 4 - themes/classic/assets/css/custom_rtl.css | 4 - .../css/d1a435fd2571e67858a31ee954b52278.svg | 38 - .../css/d3fbae74a276a9f6cf1d6241f29b61a3.svg | 14 - .../css/e049aeb07a2ae1627933e8e58d3886d2.svg | 18 - .../css/e79bfd88537def476913f3ed52f4f4b3.eot | Bin 143258 -> 0 bytes .../css/eeb9224f85430652fd070e4e64129aa4.eot | Bin 415310 -> 0 bytes themes/classic/assets/css/error.css | 50 - themes/classic/assets/css/error_rtl.css | 50 - .../css/f255af0bbbe837e79f7821827f9c6f10.svg | 24 - .../css/ffddcb3736980b23405b31142a324b62.svg | 38 - themes/classic/assets/css/theme.css | 7 - themes/classic/assets/css/theme.rtlfix | 41 - themes/classic/assets/css/theme_rtl.css | 48 - themes/classic/assets/img/modules/index.php | 36 - .../img/modules/leoblog/1/b/b-blog-1.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-2.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-3.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-4.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-5.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-6.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/1/b/b-blog-7.jpg | Bin 65725 -> 0 bytes .../assets/img/modules/leoblog/1/b/index.php | 36 - .../1/c/[themeforest]_Floral_banner.jpg | Bin 46252 -> 0 bytes .../img/modules/leoblog/1/c/category-1.jpg | Bin 45193 -> 0 bytes .../img/modules/leoblog/1/c/category-2.jpg | Bin 45193 -> 0 bytes .../img/modules/leoblog/1/c/category-3.jpg | Bin 45193 -> 0 bytes .../assets/img/modules/leoblog/1/c/index.php | 36 - .../assets/img/modules/leoblog/1/index.php | 36 - .../assets/img/modules/leoblog/index.php | 36 - .../img/modules/leoblog/sample/b/b-blog-1.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-2.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-3.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-4.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-5.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-6.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/b-blog-7.jpg | Bin 65725 -> 0 bytes .../img/modules/leoblog/sample/b/index.php | 36 - .../sample/c/[themeforest]_Floral_banner.jpg | Bin 46252 -> 0 bytes .../modules/leoblog/sample/c/category-1.jpg | Bin 45193 -> 0 bytes .../modules/leoblog/sample/c/category-2.jpg | Bin 45193 -> 0 bytes .../modules/leoblog/sample/c/category-3.jpg | Bin 45193 -> 0 bytes .../img/modules/leoblog/sample/c/index.php | 36 - .../img/modules/leoblog/sample/index.php | 36 - themes/classic/assets/js/custom.js | 4 - themes/classic/assets/js/theme.js | 1 - themes/classic/config/.htaccess | 10 - themes/classic/config/theme.yml | 131 - themes/classic/lang/pl.php | 0 .../views/templates/hook/blockreassurance.tpl | 38 - .../views/templates/widget/contactform.tpl | 135 - .../classic/modules/ps_advertising/index.php | 35 - .../modules/ps_advertising/ps_advertising.tpl | 28 - .../classic/modules/ps_banner/ps_banner.tpl | 31 - .../modules/ps_bestsellers/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_bestsellers.tpl | 37 - .../ps_bestsellers/views/templates/index.php | 35 - .../modules/ps_brandlist/views/index.php | 35 - .../views/templates/_partials/brand_form.tpl | 33 - .../views/templates/_partials/brand_text.tpl | 36 - .../views/templates/_partials/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_brandlist.tpl | 41 - .../ps_brandlist/views/templates/index.php | 35 - .../ps_categoryproducts/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../templates/hook/ps_categoryproducts.tpl | 38 - .../views/templates/index.php | 35 - .../views/templates/hook/ps_categorytree.tpl | 67 - themes/classic/modules/ps_contactinfo/nav.tpl | 42 - .../ps_contactinfo/ps_contactinfo-rich.tpl | 62 - .../modules/ps_contactinfo/ps_contactinfo.tpl | 74 - .../modules/ps_crossselling/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_crossselling.tpl | 33 - .../ps_crossselling/views/templates/index.php | 35 - .../ps_currencyselector.tpl | 46 - .../ps_customeraccountlinks.tpl | 51 - .../ps_customersignin/ps_customersignin.tpl | 56 - .../modules/ps_emailalerts/views/index.php | 35 - .../views/templates/hook/index.php | 34 - .../templates/hook/my-account-footer.tpl | 30 - .../views/templates/hook/my-account.tpl | 32 - .../ps_emailalerts/views/templates/index.php | 34 - .../templates/hook/ps_emailsubscription.tpl | 74 - .../ps_facetedsearch/ps_facetedsearch.tpl | 36 - .../templates/hook/ps_featuredproducts.tpl | 37 - .../views/templates/hook/slider.tpl | 60 - .../ps_languageselector.tpl | 49 - .../templates/hook/hookDisplayFooter.tpl | 44 - .../views/templates/hook/linkblock.tpl | 58 - .../modules/ps_mainmenu/ps_mainmenu.tpl | 39 - .../modules/ps_newproducts/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_newproducts.tpl | 39 - .../ps_newproducts/views/templates/index.php | 35 - .../modules/ps_productinfo/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_productinfo.tpl | 43 - .../ps_productinfo/views/templates/index.php | 35 - .../modules/ps_rssfeed/views/index.php | 35 - .../ps_rssfeed/views/templates/hook/index.php | 35 - .../views/templates/hook/ps_rssfeed.tpl | 39 - .../ps_rssfeed/views/templates/index.php | 35 - .../modules/ps_searchbar/ps_searchbar.tpl | 36 - .../views/templates/hook/ps_sharebuttons.tpl | 37 - .../classic/modules/ps_shoppingcart/modal.tpl | 83 - .../ps_shoppingcart-product-line.tpl | 59 - .../ps_shoppingcart/ps_shoppingcart.tpl | 39 - .../ps_socialfollow/ps_socialfollow.tpl | 34 - .../modules/ps_specials/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_specials.tpl | 38 - .../ps_specials/views/templates/index.php | 35 - .../modules/ps_supplierlist/views/index.php | 35 - .../views/templates/_partials/index.php | 35 - .../templates/_partials/supplier_form.tpl | 33 - .../templates/_partials/supplier_text.tpl | 36 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_supplierlist.tpl | 41 - .../ps_supplierlist/views/templates/index.php | 35 - .../modules/ps_viewedproduct/views/index.php | 35 - .../views/templates/hook/index.php | 35 - .../views/templates/hook/ps_viewedproduct.tpl | 32 - .../views/templates/index.php | 35 - themes/classic/preview.png | Bin 141698 -> 0 bytes themes/classic/preview.webp | Bin 31008 -> 0 bytes .../templates/_partials/breadcrumb.tpl | 40 - themes/classic/templates/_partials/footer.tpl | 56 - .../templates/_partials/form-errors.tpl | 35 - .../templates/_partials/form-fields.tpl | 195 - themes/classic/templates/_partials/head.tpl | 70 - themes/classic/templates/_partials/header.tpl | 90 - .../templates/_partials/javascript.tpl | 41 - .../templates/_partials/notifications.tpl | 78 - .../templates/_partials/pagination.tpl | 64 - .../templates/_partials/stylesheets.tpl | 33 - .../catalog/_partials/active_filters.tpl | 43 - .../catalog/_partials/category-header.tpl | 41 - .../templates/catalog/_partials/facets.tpl | 168 - .../catalog/_partials/miniatures/brand.tpl | 37 - .../catalog/_partials/miniatures/category.tpl | 37 - .../_partials/miniatures/pack-product.tpl | 54 - .../catalog/_partials/miniatures/product.tpl | 109 - .../catalog/_partials/product-activation.tpl | 38 - .../catalog/_partials/product-add-to-cart.tpl | 88 - .../_partials/product-additional-info.tpl | 27 - .../_partials/product-cover-thumbnails.tpl | 60 - .../_partials/product-customization.tpl | 69 - .../catalog/_partials/product-details.tpl | 91 - .../catalog/_partials/product-discounts.tpl | 49 - .../catalog/_partials/product-flags.tpl | 31 - .../_partials/product-images-modal.tpl | 60 - .../catalog/_partials/product-prices.tpl | 114 - .../catalog/_partials/product-variants.tpl | 69 - .../catalog/_partials/products-bottom.tpl | 6 - .../catalog/_partials/products-top.tpl | 56 - .../templates/catalog/_partials/products.tpl | 44 - .../templates/catalog/_partials/quickview.tpl | 79 - .../catalog/_partials/sort-orders.tpl | 47 - .../catalog/_partials/variant-links.tpl | 16 - themes/classic/templates/catalog/brands.tpl | 44 - .../templates/catalog/listing/best-sales.tpl | 5 - .../templates/catalog/listing/category.tpl | 29 - .../catalog/listing/manufacturer.tpl | 31 - .../catalog/listing/new-products.tpl | 5 - .../templates/catalog/listing/prices-drop.tpl | 5 - .../catalog/listing/product-list.tpl | 73 - .../templates/catalog/listing/search.tpl | 5 - .../templates/catalog/listing/supplier.tpl | 30 - .../templates/catalog/manufacturers.tpl | 25 - themes/classic/templates/catalog/product.tpl | 268 - .../classic/templates/catalog/suppliers.tpl | 29 - .../checkout/_partials/address-form.tpl | 46 - .../_partials/address-selector-block.tpl | 72 - .../_partials/cart-detailed-actions.tpl | 45 - .../_partials/cart-detailed-product-line.tpl | 175 - .../_partials/cart-detailed-totals.tpl | 58 - .../checkout/_partials/cart-detailed.tpl | 42 - .../_partials/cart-summary-items-subtotal.tpl | 30 - .../_partials/cart-summary-product-line.tpl | 44 - .../_partials/cart-summary-subtotals.tpl | 44 - .../_partials/cart-summary-totals.tpl | 54 - .../checkout/_partials/cart-summary.tpl | 69 - .../checkout/_partials/cart-voucher.tpl | 91 - .../checkout/_partials/customer-form.tpl | 50 - .../templates/checkout/_partials/footer.tpl | 29 - .../templates/checkout/_partials/header.tpl | 76 - .../checkout/_partials/login-form.tpl | 37 - .../_partials/order-confirmation-table.tpl | 136 - .../_partials/order-final-summary-table.tpl | 38 - .../_partials/order-final-summary.tpl | 103 - .../checkout/_partials/steps/addresses.tpl | 137 - .../_partials/steps/checkout-step.tpl | 46 - .../checkout/_partials/steps/payment.tpl | 167 - .../_partials/steps/personal-information.tpl | 98 - .../checkout/_partials/steps/shipping.tpl | 124 - .../checkout/_partials/steps/unreachable.tpl | 31 - .../classic/templates/checkout/cart-empty.tpl | 45 - themes/classic/templates/checkout/cart.tpl | 87 - .../templates/checkout/checkout-process.tpl | 30 - .../classic/templates/checkout/checkout.tpl | 94 - .../templates/checkout/order-confirmation.tpl | 110 - .../cms/_partials/sitemap-nested-list.tpl | 38 - themes/classic/templates/cms/category.tpl | 53 - themes/classic/templates/cms/page.tpl | 47 - themes/classic/templates/cms/sitemap.tpl | 52 - themes/classic/templates/cms/stores.tpl | 88 - themes/classic/templates/contact.tpl | 37 - .../customer/_partials/address-form.tpl | 63 - .../customer/_partials/block-address.tpl | 45 - .../customer/_partials/customer-form.tpl | 54 - .../customer/_partials/login-form.tpl | 60 - .../customer/_partials/my-account-links.tpl | 34 - .../_partials/order-detail-no-return.tpl | 175 - .../_partials/order-detail-return.tpl | 253 - .../customer/_partials/order-messages.tpl | 85 - themes/classic/templates/customer/address.tpl | 39 - .../classic/templates/customer/addresses.tpl | 46 - .../templates/customer/authentication.tpl | 46 - .../classic/templates/customer/discount.tpl | 96 - .../templates/customer/guest-login.tpl | 79 - .../templates/customer/guest-tracking.tpl | 70 - themes/classic/templates/customer/history.tpl | 119 - .../classic/templates/customer/identity.tpl | 33 - .../classic/templates/customer/my-account.tpl | 111 - .../templates/customer/order-detail.tpl | 213 - .../templates/customer/order-follow.tpl | 98 - .../templates/customer/order-return.tpl | 151 - .../classic/templates/customer/order-slip.tpl | 80 - themes/classic/templates/customer/page.tpl | 46 - .../templates/customer/password-email.tpl | 74 - .../templates/customer/password-infos.tpl | 50 - .../templates/customer/password-new.tpl | 90 - .../templates/customer/registration.tpl | 39 - themes/classic/templates/errors/404.tpl | 33 - themes/classic/templates/errors/forbidden.tpl | 30 - .../classic/templates/errors/maintenance.tpl | 61 - themes/classic/templates/errors/not-found.tpl | 40 - .../templates/errors/restricted-country.tpl | 55 - .../classic/templates/errors/static/500.html | 0 .../classic/templates/errors/static/503.html | 0 themes/classic/templates/index.tpl | 37 - .../templates/layouts/layout-both-columns.tpl | 112 - .../templates/layouts/layout-content-only.tpl | 41 - .../templates/layouts/layout-error.tpl | 55 - .../templates/layouts/layout-full-width.tpl | 38 - .../templates/layouts/layout-left-column.tpl | 37 - .../templates/layouts/layout-right-column.tpl | 37 - themes/classic/templates/page.tpl | 58 - tools/.htaccess | 9 - tools/index.php | 35 - tools/profiling/.htaccess | 10 - tools/profiling/Controller.php | 759 - tools/profiling/Db.php | 125 - tools/profiling/ObjectModel.php | 54 - tools/profiling/Tools.php | 117 - tools/profiling/index.php | 35 - translations/.DS_Store | Bin 6148 -> 0 bytes translations/cldr/.htaccess | 10 - translations/export/index.php | 35 - translations/index.php | 35 - translations/sf-en-GB.zip | Bin 544346 -> 0 bytes translations/sf-pl-PL.zip | Bin 668930 -> 0 bytes 3984 files changed, 19 insertions(+), 477170 deletions(-) delete mode 100644 docs/.DS_Store delete mode 100644 docs/.htaccess delete mode 100644 docs/CHANGELOG.txt delete mode 100644 docs/csv_import/.htaccess delete mode 100644 docs/csv_import/addresses_import.csv delete mode 100644 docs/csv_import/alias_import.csv delete mode 100644 docs/csv_import/categories_import.csv delete mode 100644 docs/csv_import/combinations_import.csv delete mode 100644 docs/csv_import/customers_import.csv delete mode 100644 docs/csv_import/index.php delete mode 100644 docs/csv_import/manufacturers_import.csv delete mode 100644 docs/csv_import/products_import.csv delete mode 100644 docs/csv_import/store_contacts.csv delete mode 100644 docs/csv_import/suppliers_import.csv delete mode 100644 docs/csv_import/supply_orders_details_import.csv delete mode 100644 docs/csv_import/supply_orders_import.csv delete mode 100644 docs/docker/nginx_fpm/prestashop-fpm/Dockerfile delete mode 100644 docs/docker/nginx_fpm/prestashop-fpm/prestashop-php.ini delete mode 100644 docs/docker/nginx_fpm/prestashop-nginx/prestashop-nginx.conf delete mode 100644 docs/docker/nginx_fpm_supervisord/prestashop-nginx-fpm/Dockerfile delete mode 100644 docs/docker/nginx_fpm_supervisord/prestashop-nginx-fpm/prestashop-nginx.conf delete mode 100644 docs/docker/nginx_fpm_supervisord/prestashop-nginx-fpm/prestashop-php.ini delete mode 100644 docs/docker/prestashopCli.sh delete mode 100644 docs/index.php delete mode 100644 docs/licenses/LICENSE.txt delete mode 100644 docs/licenses/cropper.txt delete mode 100644 docs/licenses/fileuploader.txt delete mode 100644 docs/licenses/fonts/open-sans.txt delete mode 100644 docs/licenses/fonts/ubuntu-condensed.txt delete mode 100644 docs/licenses/index.php delete mode 100644 docs/licenses/php-sql-parser.txt delete mode 100644 docs/licenses/tinymce-smarty-swift.txt delete mode 100644 docs/server_config/nginx.conf.dist delete mode 100644 download/.htaccess delete mode 100644 download/index.php delete mode 100644 firmeslink/.htaccess delete mode 100644 firmeslink/documents/.htaccess delete mode 100644 firmeslink/documents/6/1/5/4/8/61548-2.pdf delete mode 100644 firmeslink/documents/6/2/9/2/6/62926-2.pdf delete mode 100644 firmeslink/documents/6/4/0/2/2/64022-2.pdf delete mode 100644 firmeslink/documents/6/4/0/9/2/64092-2.pdf delete mode 100644 firmeslink/documents/6/4/1/3/6/64136-2.pdf delete mode 100644 firmeslink/documents/6/4/1/9/3/64193-2.pdf delete mode 100644 firmeslink/documents/6/4/2/0/5/64205-2.pdf delete mode 100644 firmeslink/documents/6/4/2/0/6/64206-2.pdf delete mode 100644 firmeslink/documents/6/4/2/0/9/64209-2.pdf delete mode 100644 firmeslink/documents/6/4/2/1/4/64214-2.pdf delete mode 100644 firmeslink/documents/6/4/2/7/6/64276-2.pdf delete mode 100644 firmeslink/documents/6/4/2/7/7/64277-2.pdf delete mode 100644 firmeslink/documents/6/4/2/7/8/64278-2.pdf delete mode 100644 firmeslink/documents/index.php delete mode 100644 firmeslink/index.php delete mode 100644 log.txt delete mode 100644 src/.DS_Store delete mode 100644 src/.htaccess delete mode 100644 src/Adapter/Addons/AddonsDataProvider.php delete mode 100644 src/Adapter/Address/AbstractAddressHandler.php delete mode 100644 src/Adapter/Address/AbstractCustomerAddressHandler.php delete mode 100644 src/Adapter/Address/AbstractManufacturerAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/AddCustomerAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/AddManufacturerAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/BulkDeleteAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/DeleteAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/EditCartAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/EditCustomerAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/EditManufacturerAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/EditOrderAddressHandler.php delete mode 100644 src/Adapter/Address/CommandHandler/SetRequiredFieldsForAddressHandler.php delete mode 100644 src/Adapter/Address/QueryHandler/GetCustomerAddressForEditingHandler.php delete mode 100644 src/Adapter/Address/QueryHandler/GetManufacturerAddressForEditingHandler.php delete mode 100644 src/Adapter/Address/QueryHandler/GetRequiredFieldsForAddressHandler.php delete mode 100644 src/Adapter/AddressFactory.php delete mode 100644 src/Adapter/Admin/AbstractAdminQueryBuilder.php delete mode 100644 src/Adapter/Admin/LegacyBlockHelperSubscriber.php delete mode 100644 src/Adapter/Admin/NotificationsConfiguration.php delete mode 100644 src/Adapter/Admin/PagePreference.php delete mode 100644 src/Adapter/Admin/UrlGenerator.php delete mode 100644 src/Adapter/Assets/AssetUrlGeneratorTrait.php delete mode 100644 src/Adapter/Attachment/AbstractAttachmentHandler.php delete mode 100644 src/Adapter/Attachment/CommandHandler/AddAttachmentHandler.php delete mode 100644 src/Adapter/Attachment/CommandHandler/BulkDeleteAttachmentsHandler.php delete mode 100644 src/Adapter/Attachment/CommandHandler/DeleteAttachmentHandler.php delete mode 100644 src/Adapter/Attachment/CommandHandler/EditAttachmentHandler.php delete mode 100644 src/Adapter/Attachment/QueryHandler/GetAttachmentForEditingHandler.php delete mode 100644 src/Adapter/Attachment/QueryHandler/GetAttachmentHandler.php delete mode 100644 src/Adapter/Attribute/AbstractAttributeHandler.php delete mode 100644 src/Adapter/Attribute/AdminAttributeGeneratorControllerWrapper.php delete mode 100644 src/Adapter/Attribute/AttributeDataProvider.php delete mode 100644 src/Adapter/Attribute/CommandHandler/BulkDeleteAttributeHandler.php delete mode 100644 src/Adapter/Attribute/CommandHandler/DeleteAttributeHandler.php delete mode 100644 src/Adapter/AttributeGroup/AbstractAttributeGroupHandler.php delete mode 100644 src/Adapter/AttributeGroup/AttributeGroupViewDataProvider.php delete mode 100644 src/Adapter/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandler.php delete mode 100644 src/Adapter/AttributeGroup/CommandHandler/DeleteAttributeGroupHandler.php delete mode 100644 src/Adapter/Backup/Backup.php delete mode 100644 src/Adapter/Backup/BackupRemover.php delete mode 100644 src/Adapter/Backup/BackupRepository.php delete mode 100644 src/Adapter/Backup/DatabaseBackupCreator.php delete mode 100644 src/Adapter/BestSales/BestSalesProductSearchProvider.php delete mode 100644 src/Adapter/CMS/CMSDataProvider.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/AbstractCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/AddCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/BulkDeleteCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/BulkDisableCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/BulkEnableCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/DeleteCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/EditCmsPageHandler.php delete mode 100644 src/Adapter/CMS/Page/CommandHandler/ToggleCmsPageStatusHandler.php delete mode 100644 src/Adapter/CMS/Page/QueryHandler/GetCmsCategoryIdForRedirectionHandler.php delete mode 100644 src/Adapter/CMS/Page/QueryHandler/GetCmsPageForEditingHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CategoriesProvider.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/AbstractCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/AddCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/BulkDisableCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/BulkEnableCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/DeleteCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/EditCmsPageCategoryHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryForEditingHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandler.php delete mode 100644 src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandler.php delete mode 100644 src/Adapter/Cache/CacheAdapter.php delete mode 100644 src/Adapter/Cache/CacheClearer.php delete mode 100644 src/Adapter/Cache/CachingConfiguration.php delete mode 100644 src/Adapter/Cache/Clearer/ClassIndexCacheClearer.php delete mode 100644 src/Adapter/Cache/Clearer/MediaCacheClearer.php delete mode 100644 src/Adapter/Cache/Clearer/SmartyCacheClearer.php delete mode 100644 src/Adapter/Cache/Clearer/SymfonyCacheClearer.php delete mode 100644 src/Adapter/Cache/Clearer/XmlCacheClearer.php delete mode 100644 src/Adapter/Cache/CombineCompressCacheConfiguration.php delete mode 100644 src/Adapter/Cache/MemcacheServerManager.php delete mode 100644 src/Adapter/CacheManager.php delete mode 100644 src/Adapter/Carrier/CarrierDataProvider.php delete mode 100644 src/Adapter/Carrier/CarrierOptionsConfiguration.php delete mode 100644 src/Adapter/Carrier/HandlingConfiguration.php delete mode 100644 src/Adapter/Cart/AbstractCartHandler.php delete mode 100644 src/Adapter/Cart/CartPresenter.php delete mode 100644 src/Adapter/Cart/CommandHandler/AddCartRuleToCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/AddCustomizationHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/AddProductToCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/CreateEmptyCustomerCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/RemoveCartRuleFromCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/RemoveProductFromCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/SendCartToCustomerHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateCartAddressesHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateCartCarrierHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateCartCurrencyHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateCartLanguageHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateProductPriceInCartHandler.php delete mode 100644 src/Adapter/Cart/CommandHandler/UpdateProductQuantityInCartHandler.php delete mode 100644 src/Adapter/Cart/Comparator/CartProductUpdate.php delete mode 100644 src/Adapter/Cart/Comparator/CartProductsComparator.php delete mode 100644 src/Adapter/Cart/QueryHandler/GetCartForOrderCreationHandler.php delete mode 100644 src/Adapter/Cart/QueryHandler/GetCartForViewingHandler.php delete mode 100644 src/Adapter/Cart/QueryHandler/GetLastEmptyCustomerCartHandler.php delete mode 100644 src/Adapter/CartRule/CommandHandler/AddCartRuleHandler.php delete mode 100644 src/Adapter/CartRule/LegacyDiscountApplicationType.php delete mode 100644 src/Adapter/CartRule/QueryHandler/SearchCartRulesHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/AbstractCatalogPriceRuleHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandler.php delete mode 100644 src/Adapter/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandler.php delete mode 100644 src/Adapter/Category/AdminCategoryControllerWrapper.php delete mode 100644 src/Adapter/Category/CategoryDataProvider.php delete mode 100644 src/Adapter/Category/CategoryProductSearchProvider.php delete mode 100644 src/Adapter/Category/CategoryViewDataProvider.php delete mode 100644 src/Adapter/Category/CommandHandler/AbstractDeleteCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/AddCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/AddRootCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/BulkDeleteCategoriesHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/BulkUpdateCategoriesStatusHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/DeleteCategoryCoverImageHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/DeleteCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/EditCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/EditRootCategoryHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/SetCategoryIsEnabledHandler.php delete mode 100644 src/Adapter/Category/CommandHandler/UpdateCategoryPositionHandler.php delete mode 100644 src/Adapter/Category/QueryHandler/GetCategoryForEditingHandler.php delete mode 100644 src/Adapter/Category/QueryHandler/GetCategoryIsEnabledHandler.php delete mode 100644 src/Adapter/ClassLang.php delete mode 100644 src/Adapter/CombinationDataProvider.php delete mode 100644 src/Adapter/Configuration.php delete mode 100644 src/Adapter/Configuration/CommandHandler/SwitchDebugModeHandler.php delete mode 100644 src/Adapter/Configuration/KpiConfiguration.php delete mode 100644 src/Adapter/Configuration/LogsConfiguration.php delete mode 100644 src/Adapter/Configuration/PhpParameters.php delete mode 100644 src/Adapter/Contact/CommandHandler/AddContactHandler.php delete mode 100644 src/Adapter/Contact/CommandHandler/EditContactHandler.php delete mode 100644 src/Adapter/Contact/QueryHandler/GetContactForEditingHandler.php delete mode 100644 src/Adapter/Container/ContainerBuilderExtensionInterface.php delete mode 100644 src/Adapter/Container/ContainerParametersExtension.php delete mode 100644 src/Adapter/Container/DoctrineBuilderExtension.php delete mode 100644 src/Adapter/Container/LegacyContainer.php delete mode 100644 src/Adapter/Container/LegacyContainerBuilder.php delete mode 100644 src/Adapter/Container/LegacyContainerInterface.php delete mode 100644 src/Adapter/ContainerBuilder.php delete mode 100644 src/Adapter/ContainerFinder.php delete mode 100644 src/Adapter/ContextStateManager.php delete mode 100644 src/Adapter/Converter/ExcelToCsvFileConverter.php delete mode 100644 src/Adapter/CoreException.php delete mode 100644 src/Adapter/Country/CountryDataProvider.php delete mode 100644 src/Adapter/Country/CountryRequiredFieldsProvider.php delete mode 100644 src/Adapter/Country/CountryZipCodeRequirementsProvider.php delete mode 100644 src/Adapter/Country/QueryHandler/GetCountryRequiredFieldsHandler.php delete mode 100644 src/Adapter/CreditSlip/CreditSlipTemplateTypeProvider.php delete mode 100644 src/Adapter/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/AbstractCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/AddOfficialCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/AddUnofficialCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/CurrencyCommandValidator.php delete mode 100644 src/Adapter/Currency/CommandHandler/DeleteCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/EditOfficialCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/EditUnofficialCurrencyHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/RefreshExchangeRatesHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/ToggleCurrencyStatusHandler.php delete mode 100644 src/Adapter/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandler.php delete mode 100644 src/Adapter/Currency/CurrencyDataProvider.php delete mode 100644 src/Adapter/Currency/CurrencyManager.php delete mode 100644 src/Adapter/Currency/QueryHandler/GetCurrencyExchangeRateHandler.php delete mode 100644 src/Adapter/Currency/QueryHandler/GetCurrencyForEditingHandler.php delete mode 100644 src/Adapter/Currency/QueryHandler/GetReferenceCurrencyHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/AbstractCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/AddCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/BulkDeleteCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/BulkDisableCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/BulkEnableCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/DeleteCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/EditCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/SetRequiredFieldsForCustomerHandler.php delete mode 100644 src/Adapter/Customer/CommandHandler/TransformGuestToCustomerHandler.php delete mode 100644 src/Adapter/Customer/CustomerConfiguration.php delete mode 100644 src/Adapter/Customer/CustomerDataProvider.php delete mode 100644 src/Adapter/Customer/CustomerDataSource.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetCustomerCartsHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetCustomerForAddressCreationHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetCustomerForEditingHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetCustomerOrdersHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/GetRequiredFieldsForCustomerHandler.php delete mode 100644 src/Adapter/Customer/QueryHandler/SearchCustomersHandler.php delete mode 100644 src/Adapter/CustomerService/CommandHandler/AddOrderCustomerMessageHandler.php delete mode 100644 src/Adapter/CustomerService/CommandHandler/ForwardCustomerThreadHandler.php delete mode 100644 src/Adapter/CustomerService/CommandHandler/ReplyToCustomerThreadHandler.php delete mode 100644 src/Adapter/CustomerService/QueryHandler/GetCustomerThreadForViewingHandler.php delete mode 100644 src/Adapter/Database.php delete mode 100644 src/Adapter/Debug/DebugMode.php delete mode 100644 src/Adapter/Debug/DebugModeConfiguration.php delete mode 100644 src/Adapter/Domain/AbstractObjectModelHandler.php delete mode 100644 src/Adapter/Email/EmailConfigurationTester.php delete mode 100644 src/Adapter/Email/EmailLogEraser.php delete mode 100644 src/Adapter/Employee/AvatarProvider.php delete mode 100644 src/Adapter/Employee/ContextEmployeeProvider.php delete mode 100644 src/Adapter/Employee/EmployeeDataProvider.php delete mode 100644 src/Adapter/Employee/EmployeeFormAccessChecker.php delete mode 100644 src/Adapter/Employee/FormLanguageChanger.php delete mode 100644 src/Adapter/Employee/NavigationMenuToggler.php delete mode 100644 src/Adapter/EntityMapper.php delete mode 100644 src/Adapter/EntityMetaDataRetriever.php delete mode 100644 src/Adapter/Environment.php delete mode 100644 src/Adapter/Feature/CombinationFeature.php delete mode 100644 src/Adapter/Feature/CommandHandler/AddFeatureHandler.php delete mode 100644 src/Adapter/Feature/CommandHandler/EditFeatureHandler.php delete mode 100644 src/Adapter/Feature/FeatureDataProvider.php delete mode 100644 src/Adapter/Feature/FeatureFeature.php delete mode 100644 src/Adapter/Feature/GroupFeature.php delete mode 100644 src/Adapter/Feature/MultistoreFeature.php delete mode 100644 src/Adapter/Feature/QueryHandler/GetFeatureForEditingHandler.php delete mode 100644 src/Adapter/File/HtaccessFileGenerator.php delete mode 100644 src/Adapter/File/RobotsTextFileGenerator.php delete mode 100644 src/Adapter/File/Uploader/AttachmentFileUploader.php delete mode 100644 src/Adapter/Form/ChoiceProvider/CarrierForOrderChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/CategoryTreeChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/CountryStateByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/CurrencySymbolByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/EmployeeNameByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/GenderByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/GroupByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/InstalledPaymentModulesChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/ManufacturerNameByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/OrderCountriesChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/OrderInvoiceByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/ProfileByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/ResourcesChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/RiskByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/ShopNameByIdChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/ShopTreeChoiceProvider.php delete mode 100644 src/Adapter/Form/ChoiceProvider/TaxRuleGroupChoiceProvider.php delete mode 100644 src/Adapter/GeneralConfiguration.php delete mode 100644 src/Adapter/Geolocation/GeolocationByIpAddressConfiguration.php delete mode 100644 src/Adapter/Geolocation/GeolocationIpAddressWhitelistConfiguration.php delete mode 100644 src/Adapter/Geolocation/GeolocationOptionsConfiguration.php delete mode 100644 src/Adapter/Grid/Action/Row/AccessibilityChecker/CategoryForViewAccessibilityChecker.php delete mode 100644 src/Adapter/Grid/Search/Factory/SearchCriteriaWithCategoryParentIdFilterFactory.php delete mode 100644 src/Adapter/Group/GroupDataProvider.php delete mode 100644 src/Adapter/Group/Provider/DefaultGroupsProvider.php delete mode 100644 src/Adapter/Hook/HookDispatcher.php delete mode 100644 src/Adapter/Hook/HookInformationProvider.php delete mode 100644 src/Adapter/HookManager.php delete mode 100644 src/Adapter/Hosting/HostingInformation.php delete mode 100644 src/Adapter/Image/ImageRetriever.php delete mode 100644 src/Adapter/Image/Uploader/AbstractImageUploader.php delete mode 100644 src/Adapter/Image/Uploader/CategoryCoverImageUploader.php delete mode 100644 src/Adapter/Image/Uploader/CategoryMenuThumbnailUploader.php delete mode 100644 src/Adapter/Image/Uploader/CategoryThumbnailImageUploader.php delete mode 100644 src/Adapter/Image/Uploader/ManufacturerImageUploader.php delete mode 100644 src/Adapter/Image/Uploader/SupplierImageUploader.php delete mode 100644 src/Adapter/ImageManager.php delete mode 100644 src/Adapter/Import/CsvFileOpener.php delete mode 100644 src/Adapter/Import/DataMatchSaver.php delete mode 100644 src/Adapter/Import/Handler/AbstractImportHandler.php delete mode 100644 src/Adapter/Import/Handler/CategoryImportHandler.php delete mode 100644 src/Adapter/Import/Handler/ImportHandlerFinder.php delete mode 100644 src/Adapter/Import/Handler/ProductImportHandler.php delete mode 100644 src/Adapter/Import/ImageCopier.php delete mode 100644 src/Adapter/Import/ImportDataFormatter.php delete mode 100644 src/Adapter/Import/ImportEntityDeleter.php delete mode 100644 src/Adapter/Invoice/InvoiceOptionsConfiguration.php delete mode 100644 src/Adapter/Invoice/InvoiceTemplateTypeProvider.php delete mode 100644 src/Adapter/Invoice/OrderInvoiceDataProvider.php delete mode 100644 src/Adapter/Kpi/AbandonedCartKpi.php delete mode 100644 src/Adapter/Kpi/AverageCustomerAgeKpi.php delete mode 100644 src/Adapter/Kpi/AverageOrderValueKpi.php delete mode 100644 src/Adapter/Kpi/AverageProductsInCategoryKpi.php delete mode 100644 src/Adapter/Kpi/ConversionRateKpi.php delete mode 100644 src/Adapter/Kpi/DisabledCategoriesKpi.php delete mode 100644 src/Adapter/Kpi/EmptyCategoriesKpi.php delete mode 100644 src/Adapter/Kpi/EnabledLanguagesKpi.php delete mode 100644 src/Adapter/Kpi/MainCountryKpi.php delete mode 100644 src/Adapter/Kpi/MostCommonCustomersGenderKpi.php delete mode 100644 src/Adapter/Kpi/NetProfitPerVisitKpi.php delete mode 100644 src/Adapter/Kpi/NewsletterRegistrationsKpi.php delete mode 100644 src/Adapter/Kpi/OrdersPerCustomerKpi.php delete mode 100644 src/Adapter/Kpi/ShoppingCartTotalKpi.php delete mode 100644 src/Adapter/Kpi/TopCategoryKpi.php delete mode 100644 src/Adapter/Kpi/TranslationsKpi.php delete mode 100644 src/Adapter/Language/CommandHandler/AbstractLanguageHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/AddLanguageHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/BulkDeleteLanguagesHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/BulkToggleLanguagesStatusHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/DeleteLanguageHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/EditLanguageHandler.php delete mode 100644 src/Adapter/Language/CommandHandler/ToggleLanguageStatusHandler.php delete mode 100644 src/Adapter/Language/LanguageActivator.php delete mode 100644 src/Adapter/Language/LanguageCopier.php delete mode 100644 src/Adapter/Language/LanguageDataProvider.php delete mode 100644 src/Adapter/Language/LanguageFlagThumbnailProvider.php delete mode 100644 src/Adapter/Language/LanguageImageManager.php delete mode 100644 src/Adapter/Language/LanguagePackInstaller.php delete mode 100644 src/Adapter/Language/LanguageValidator.php delete mode 100644 src/Adapter/Language/Pack/LanguagePackImporter.php delete mode 100644 src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php delete mode 100644 src/Adapter/Language/RTL/InstalledLanguageChecker.php delete mode 100644 src/Adapter/LegacyContext.php delete mode 100644 src/Adapter/LegacyHookSubscriber.php delete mode 100644 src/Adapter/LegacyLogger.php delete mode 100644 src/Adapter/Localization/AdvancedConfiguration.php delete mode 100644 src/Adapter/Localization/LegacyTranslator.php delete mode 100644 src/Adapter/Localization/LocalUnitsConfiguration.php delete mode 100644 src/Adapter/Localization/LocalizationConfiguration.php delete mode 100644 src/Adapter/Mail/MailingInformation.php delete mode 100644 src/Adapter/MailTemplate/MailPartialTemplateRenderer.php delete mode 100644 src/Adapter/MailTemplate/MailPreviewVariablesBuilder.php delete mode 100644 src/Adapter/MailTemplate/MailTemplateTwigRenderer.php delete mode 100644 src/Adapter/Manufacturer/AbstractManufacturerHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/AbstractManufacturerCommandHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/AddManufacturerHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/BulkDeleteManufacturerHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/DeleteManufacturerHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/EditManufacturerHandler.php delete mode 100644 src/Adapter/Manufacturer/CommandHandler/ToggleManufacturerStatusHandler.php delete mode 100644 src/Adapter/Manufacturer/ManufacturerDataProvider.php delete mode 100644 src/Adapter/Manufacturer/ManufacturerLogoThumbnailProvider.php delete mode 100644 src/Adapter/Manufacturer/ManufacturerProductSearchProvider.php delete mode 100644 src/Adapter/Manufacturer/QueryHandler/GetManufacturerForEditingHandler.php delete mode 100644 src/Adapter/Manufacturer/QueryHandler/GetManufacturerForViewingHandler.php delete mode 100644 src/Adapter/Media/MediaServerConfiguration.php delete mode 100644 src/Adapter/Meta/CommandHandler/AddMetaHandler.php delete mode 100644 src/Adapter/Meta/CommandHandler/EditMetaHandler.php delete mode 100644 src/Adapter/Meta/MetaDataProvider.php delete mode 100644 src/Adapter/Meta/MetaEraser.php delete mode 100644 src/Adapter/Meta/QueryHandler/GetMetaForEditingHandler.php delete mode 100644 src/Adapter/Meta/QueryHandler/GetPagesForLayoutCustomizationHandler.php delete mode 100644 src/Adapter/Meta/SEOOptionsDataConfiguration.php delete mode 100644 src/Adapter/Meta/SetUpUrlsDataConfiguration.php delete mode 100644 src/Adapter/Meta/ShopUrlDataConfiguration.php delete mode 100644 src/Adapter/Meta/UrlSchemaDataConfiguration.php delete mode 100644 src/Adapter/Module/AdminModuleDataProvider.php delete mode 100644 src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php delete mode 100644 src/Adapter/Module/Configuration/ModuleSelfConfigurator.php delete mode 100644 src/Adapter/Module/Module.php delete mode 100644 src/Adapter/Module/ModuleDataProvider.php delete mode 100644 src/Adapter/Module/ModuleDataUpdater.php delete mode 100644 src/Adapter/Module/ModulePresenter.php delete mode 100644 src/Adapter/Module/ModuleZip.php delete mode 100644 src/Adapter/Module/ModuleZipManager.php delete mode 100644 src/Adapter/Module/PaymentModuleListProvider.php delete mode 100644 src/Adapter/Module/Presenter/PaymentModulesPresenter.php delete mode 100644 src/Adapter/Module/PrestaTrust/ModuleEventSubscriber.php delete mode 100644 src/Adapter/Module/PrestaTrust/PrestaTrustChecker.php delete mode 100644 src/Adapter/Module/Tab/ModuleTabManagementSubscriber.php delete mode 100644 src/Adapter/Module/Tab/ModuleTabRegister.php delete mode 100644 src/Adapter/Module/Tab/ModuleTabUnregister.php delete mode 100644 src/Adapter/Module/TabModuleListProvider.php delete mode 100644 src/Adapter/NewProducts/NewProductsProductSearchProvider.php delete mode 100644 src/Adapter/News/NewsDataProvider.php delete mode 100644 src/Adapter/Notification/CommandHandler/UpdateEmployeeNotificationLastElementHandler.php delete mode 100644 src/Adapter/Notification/QueryHandler/GetNotificationLastElementsHandler.php delete mode 100644 src/Adapter/Number/RoundModeConverter.php delete mode 100644 src/Adapter/ObjectPresenter.php delete mode 100644 src/Adapter/OptionalFeatures/OptionalFeaturesConfiguration.php delete mode 100644 src/Adapter/Order/AbstractOrderHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/AbstractOrderCommandHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/AddCartRuleToOrderHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/AddOrderFromBackOfficeHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/AddPaymentHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/AddProductToOrderHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/BulkChangeOrderStatusHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/CancelOrderProductHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/ChangeOrderCurrencyHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/ChangeOrderDeliveryAddressHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/ChangeOrderInvoiceAddressHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/DeleteCartRuleFromOrderHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/DeleteProductFromOrderHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/DuplicateOrderCartHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/GenerateInvoiceHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/IssuePartialRefundHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/IssueReturnProductHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/ResendOrderEmailHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/SendProcessOrderEmailHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/UpdateInvoiceNoteHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/UpdateOrderStatusHandler.php delete mode 100644 src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php delete mode 100644 src/Adapter/Order/Delivery/SlipOptionsConfiguration.php delete mode 100644 src/Adapter/Order/Delivery/SlipPdfConfiguration.php delete mode 100644 src/Adapter/Order/GeneralConfiguration.php delete mode 100644 src/Adapter/Order/GiftOptionsConfiguration.php delete mode 100644 src/Adapter/Order/Invoice.php delete mode 100644 src/Adapter/Order/OrderAmountUpdater.php delete mode 100644 src/Adapter/Order/OrderDetailUpdater.php delete mode 100644 src/Adapter/Order/OrderPresenter.php delete mode 100644 src/Adapter/Order/OrderProductQuantityUpdater.php delete mode 100644 src/Adapter/Order/OrderReturnPresenter.php delete mode 100644 src/Adapter/Order/OrderSiblingProvider.php delete mode 100644 src/Adapter/Order/QueryHandler/GetOrderForViewingHandler.php delete mode 100644 src/Adapter/Order/QueryHandler/GetOrderPreviewHandler.php delete mode 100644 src/Adapter/Order/QueryHandler/GetOrderProductsForViewingHandler.php delete mode 100644 src/Adapter/Order/Refund/OrderProductRemover.php delete mode 100644 src/Adapter/Order/Refund/OrderRefundCalculator.php delete mode 100644 src/Adapter/Order/Refund/OrderRefundSummary.php delete mode 100644 src/Adapter/Order/Refund/OrderRefundUpdater.php delete mode 100644 src/Adapter/Order/Refund/OrderSlipCreator.php delete mode 100644 src/Adapter/Order/Refund/VoucherGenerator.php delete mode 100644 src/Adapter/OrderMessage/AbstractOrderMessageHandler.php delete mode 100644 src/Adapter/OrderMessage/CommandHandler/AddOrderMessageHandler.php delete mode 100644 src/Adapter/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandler.php delete mode 100644 src/Adapter/OrderMessage/CommandHandler/DeleteOrderMessageHandler.php delete mode 100644 src/Adapter/OrderMessage/CommandHandler/EditOrderMessageHandler.php delete mode 100644 src/Adapter/OrderMessage/OrderMessageProvider.php delete mode 100644 src/Adapter/OrderMessage/QueryHandler/GetOrderMessageForEditingHandler.php delete mode 100644 src/Adapter/OrderState/OrderStateDataProvider.php delete mode 100644 src/Adapter/PDF/CreditSlipPdfGenerator.php delete mode 100644 src/Adapter/PDF/DeliverySlipPdfGenerator.php delete mode 100644 src/Adapter/PDF/OrderInvoicePdfGenerator.php delete mode 100644 src/Adapter/PDF/PDFGenerator.php delete mode 100644 src/Adapter/Pack/PackDataProvider.php delete mode 100644 src/Adapter/Preferences/PreferencesConfiguration.php delete mode 100644 src/Adapter/Presenter/AbstractLazyArray.php delete mode 100644 src/Adapter/Presenter/Cart/CartPresenter.php delete mode 100644 src/Adapter/Presenter/Module/ModulePresenter.php delete mode 100644 src/Adapter/Presenter/Object/ObjectPresenter.php delete mode 100644 src/Adapter/Presenter/Order/OrderDetailLazyArray.php delete mode 100644 src/Adapter/Presenter/Order/OrderLazyArray.php delete mode 100644 src/Adapter/Presenter/Order/OrderPresenter.php delete mode 100644 src/Adapter/Presenter/Order/OrderReturnLazyArray.php delete mode 100644 src/Adapter/Presenter/Order/OrderReturnPresenter.php delete mode 100644 src/Adapter/Presenter/Order/OrderSubtotalLazyArray.php delete mode 100644 src/Adapter/Presenter/PresenterInterface.php delete mode 100644 src/Adapter/Presenter/Product/ProductLazyArray.php delete mode 100644 src/Adapter/Presenter/Product/ProductListingLazyArray.php delete mode 100644 src/Adapter/Presenter/Product/ProductListingPresenter.php delete mode 100644 src/Adapter/Presenter/Product/ProductPresenter.php delete mode 100644 src/Adapter/PricesDrop/PricesDropProductSearchProvider.php delete mode 100644 src/Adapter/Product/AdminProductDataProvider.php delete mode 100644 src/Adapter/Product/AdminProductDataUpdater.php delete mode 100644 src/Adapter/Product/AdminProductWrapper.php delete mode 100644 src/Adapter/Product/AttachmentDataProvider.php delete mode 100644 src/Adapter/Product/CommandHandler/AssignProductToCategoryHandler.php delete mode 100644 src/Adapter/Product/CommandHandler/UpdateProductStatusCommandHandler.php delete mode 100644 src/Adapter/Product/FilterCategoriesRequestPurifier.php delete mode 100644 src/Adapter/Product/GeneralConfiguration.php delete mode 100644 src/Adapter/Product/ListParametersUpdater.php delete mode 100644 src/Adapter/Product/PackItemsManager.php delete mode 100644 src/Adapter/Product/PageConfiguration.php delete mode 100644 src/Adapter/Product/PaginationConfiguration.php delete mode 100644 src/Adapter/Product/PriceCalculator.php delete mode 100644 src/Adapter/Product/PriceFormatter.php delete mode 100644 src/Adapter/Product/ProductColorsRetriever.php delete mode 100644 src/Adapter/Product/ProductDataProvider.php delete mode 100644 src/Adapter/Product/QueryHandler/GetProductIsEnabledHandler.php delete mode 100644 src/Adapter/Product/QueryHandler/SearchProductsHandler.php delete mode 100644 src/Adapter/Product/StockConfiguration.php delete mode 100644 src/Adapter/Profile/CommandHandler/AbstractProfileHandler.php delete mode 100644 src/Adapter/Profile/CommandHandler/AddProfileHandler.php delete mode 100644 src/Adapter/Profile/CommandHandler/BulkDeleteProfileHandler.php delete mode 100644 src/Adapter/Profile/CommandHandler/DeleteProfileHandler.php delete mode 100644 src/Adapter/Profile/CommandHandler/EditProfileHandler.php delete mode 100644 src/Adapter/Profile/Employee/AbstractEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/AbstractEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/AddEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/BulkDeleteEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/BulkUpdateEmployeeStatusHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/DeleteEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/EditEmployeeHandler.php delete mode 100644 src/Adapter/Profile/Employee/CommandHandler/ToggleEmployeeStatusHandler.php delete mode 100644 src/Adapter/Profile/Employee/QueryHandler/GetEmployeeEmailByIdHandler.php delete mode 100644 src/Adapter/Profile/Employee/QueryHandler/GetEmployeeForEditingHandler.php delete mode 100644 src/Adapter/Profile/ProfileDataProvider.php delete mode 100644 src/Adapter/Profile/QueryHandler/GetProfileForEditingHandler.php delete mode 100644 src/Adapter/Requirement/CheckMissingOrUpdatedFiles.php delete mode 100644 src/Adapter/Requirement/CheckRequirements.php delete mode 100644 src/Adapter/RoundingMapper.php delete mode 100644 src/Adapter/Routes/DefaultRouteProvider.php delete mode 100644 src/Adapter/Routes/RouteValidator.php delete mode 100644 src/Adapter/Routing/AdminLinkBuilder.php delete mode 100644 src/Adapter/Routing/LegacyHelperLinkBuilder.php delete mode 100644 src/Adapter/Search/SearchProductSearchProvider.php delete mode 100644 src/Adapter/Security/Admin.php delete mode 100644 src/Adapter/Security/SslMiddleware.php delete mode 100644 src/Adapter/ServiceLocator.php delete mode 100644 src/Adapter/Shop/CommandHandler/UploadLogosHandler.php delete mode 100644 src/Adapter/Shop/Context.php delete mode 100644 src/Adapter/Shop/MaintenanceConfiguration.php delete mode 100644 src/Adapter/Shop/QueryHandler/GetLogosPathsHandler.php delete mode 100644 src/Adapter/Shop/ShopInformation.php delete mode 100644 src/Adapter/Shop/ShopUrlDataProvider.php delete mode 100644 src/Adapter/Shop/Url/BaseUrlProvider.php delete mode 100644 src/Adapter/Shop/Url/CategoryProvider.php delete mode 100644 src/Adapter/Shop/Url/CmsProvider.php delete mode 100644 src/Adapter/Smarty/SmartyCacheConfiguration.php delete mode 100644 src/Adapter/SpecificPrice/AbstractSpecificPriceHandler.php delete mode 100644 src/Adapter/SpecificPrice/CommandHandler/AddSpecificPriceHandler.php delete mode 100644 src/Adapter/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandler.php delete mode 100644 src/Adapter/SqlManager/CommandHandler/AddSqlRequestHandler.php delete mode 100644 src/Adapter/SqlManager/CommandHandler/BulkDeleteSqlRequestHandler.php delete mode 100644 src/Adapter/SqlManager/CommandHandler/DeleteSqlRequestHandler.php delete mode 100644 src/Adapter/SqlManager/CommandHandler/EditSqlRequestHandler.php delete mode 100644 src/Adapter/SqlManager/QueryHandler/GetDatabaseTableFieldsListHandler.php delete mode 100644 src/Adapter/SqlManager/QueryHandler/GetDatabaseTablesListHandler.php delete mode 100644 src/Adapter/SqlManager/QueryHandler/GetSqlRequestExecutionResultHandler.php delete mode 100644 src/Adapter/SqlManager/QueryHandler/GetSqlRequestForEditingHandler.php delete mode 100644 src/Adapter/SqlManager/SqlQueryValidator.php delete mode 100644 src/Adapter/SqlManager/SqlRequestFormDataValidator.php delete mode 100644 src/Adapter/StockManager.php delete mode 100644 src/Adapter/Supplier/AbstractSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/AbstractDeleteSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/AddSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/BulkDeleteSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/BulkDisableSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/BulkEnableSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/DeleteSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/EditSupplierHandler.php delete mode 100644 src/Adapter/Supplier/CommandHandler/ToggleSupplierStatusHandler.php delete mode 100644 src/Adapter/Supplier/QueryHandler/GetSupplierForEditingHandler.php delete mode 100644 src/Adapter/Supplier/QueryHandler/GetSupplierForViewingHandler.php delete mode 100644 src/Adapter/Supplier/SupplierAddressProvider.php delete mode 100644 src/Adapter/Supplier/SupplierDataProvider.php delete mode 100644 src/Adapter/Supplier/SupplierLogoThumbnailProvider.php delete mode 100644 src/Adapter/Supplier/SupplierOrderValidator.php delete mode 100644 src/Adapter/Supplier/SupplierProductSearchProvider.php delete mode 100644 src/Adapter/Support/ContactDeleter.php delete mode 100644 src/Adapter/Support/ContactRepository.php delete mode 100644 src/Adapter/SymfonyContainer.php delete mode 100644 src/Adapter/System/SystemInformation.php delete mode 100644 src/Adapter/Tab/TabDataProvider.php delete mode 100644 src/Adapter/Tax/AbstractTaxHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/AddTaxHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/BulkDeleteTaxHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/BulkToggleTaxStatusHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/DeleteTaxHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/EditTaxHandler.php delete mode 100644 src/Adapter/Tax/CommandHandler/ToggleTaxStatusHandler.php delete mode 100644 src/Adapter/Tax/Ecotax/ProductEcotaxResetter.php delete mode 100644 src/Adapter/Tax/QueryHandler/GetTaxForEditingHandler.php delete mode 100644 src/Adapter/Tax/TaxRuleDataProvider.php delete mode 100644 src/Adapter/TaxRulesGroup/AbstractTaxRulesGroupHandler.php delete mode 100644 src/Adapter/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandler.php delete mode 100644 src/Adapter/TaxRulesGroup/CommandHandler/BulkSetTaxRulesGroupStatusHandler.php delete mode 100644 src/Adapter/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandler.php delete mode 100644 src/Adapter/TaxRulesGroup/CommandHandler/SetTaxRulesGroupStatusHandler.php delete mode 100644 src/Adapter/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandler.php delete mode 100644 src/Adapter/Theme/ThemeMultiStoreSettingsFormDataProvider.php delete mode 100644 src/Adapter/Tools.php delete mode 100644 src/Adapter/Translations/TranslationRouteFinder.php delete mode 100644 src/Adapter/Twig/LocaleExtension.php delete mode 100644 src/Adapter/Upload/UploadQuotaConfiguration.php delete mode 100644 src/Adapter/Validate.php delete mode 100644 src/Adapter/Warehouse/WarehouseDataProvider.php delete mode 100644 src/Adapter/Webservice/CommandHandler/AbstractWebserviceKeyHandler.php delete mode 100644 src/Adapter/Webservice/CommandHandler/AddWebserviceKeyHandler.php delete mode 100644 src/Adapter/Webservice/CommandHandler/EditWebserviceKeyHandler.php delete mode 100644 src/Adapter/Webservice/QueryHandler/GetWebserviceKeyForEditingHandler.php delete mode 100644 src/Adapter/Webservice/WebserviceConfiguration.php delete mode 100644 src/Adapter/Webservice/WebserviceKeyEraser.php delete mode 100644 src/Adapter/Webservice/WebserviceKeyStatusModifier.php delete mode 100644 src/Core/Addon/AddonInterface.php delete mode 100644 src/Core/Addon/AddonListFilter.php delete mode 100644 src/Core/Addon/AddonListFilterOrigin.php delete mode 100644 src/Core/Addon/AddonListFilterStatus.php delete mode 100644 src/Core/Addon/AddonListFilterType.php delete mode 100644 src/Core/Addon/AddonListItem.php delete mode 100644 src/Core/Addon/AddonManagerInterface.php delete mode 100644 src/Core/Addon/AddonRepositoryInterface.php delete mode 100644 src/Core/Addon/AddonsCollection.php delete mode 100644 src/Core/Addon/Module/AddonListFilterDeviceStatus.php delete mode 100644 src/Core/Addon/Module/Exception/UnconfirmedModuleActionException.php delete mode 100644 src/Core/Addon/Module/ModuleInterface.php delete mode 100644 src/Core/Addon/Module/ModuleManager.php delete mode 100644 src/Core/Addon/Module/ModuleManagerBuilder.php delete mode 100644 src/Core/Addon/Module/ModuleRepository.php delete mode 100644 src/Core/Addon/Module/ModuleRepositoryInterface.php delete mode 100644 src/Core/Addon/Theme/Exception/ThemeAlreadyExistsException.php delete mode 100644 src/Core/Addon/Theme/Exception/ThemeUploadException.php delete mode 100644 src/Core/Addon/Theme/Theme.php delete mode 100644 src/Core/Addon/Theme/ThemeCollection.php delete mode 100644 src/Core/Addon/Theme/ThemeExporter.php delete mode 100644 src/Core/Addon/Theme/ThemeManager.php delete mode 100644 src/Core/Addon/Theme/ThemeManagerBuilder.php delete mode 100644 src/Core/Addon/Theme/ThemePageLayoutsCustomizer.php delete mode 100644 src/Core/Addon/Theme/ThemePageLayoutsCustomizerInterface.php delete mode 100644 src/Core/Addon/Theme/ThemeProvider.php delete mode 100644 src/Core/Addon/Theme/ThemeProviderInterface.php delete mode 100644 src/Core/Addon/Theme/ThemeRepository.php delete mode 100644 src/Core/Addon/Theme/ThemeUploaderInterface.php delete mode 100644 src/Core/Addon/Theme/ThemeValidator.php delete mode 100644 src/Core/Addon/Theme/ThemeZipUploader.php delete mode 100644 src/Core/AttributeGroup/AttributeGroupViewDataProviderInterface.php delete mode 100644 src/Core/B2b/B2bFeature.php delete mode 100644 src/Core/Backup/BackupCollection.php delete mode 100644 src/Core/Backup/BackupCollectionInterface.php delete mode 100644 src/Core/Backup/BackupInterface.php delete mode 100644 src/Core/Backup/Comparator/BackupByDateComparator.php delete mode 100644 src/Core/Backup/Comparator/BackupComparatorInterface.php delete mode 100644 src/Core/Backup/Configuration/BackupOptionsConfiguration.php delete mode 100644 src/Core/Backup/Exception/BackupException.php delete mode 100644 src/Core/Backup/Exception/DirectoryIsNotWritableException.php delete mode 100644 src/Core/Backup/Listing/BackupGridDataFactory.php delete mode 100644 src/Core/Backup/Manager/BackupCreatorInterface.php delete mode 100644 src/Core/Backup/Manager/BackupRemoverInterface.php delete mode 100644 src/Core/Backup/Repository/BackupRepositoryInterface.php delete mode 100644 src/Core/CMS/CMSRepository.php delete mode 100644 src/Core/CMS/CMSRoleRepository.php delete mode 100644 src/Core/CMS/CmsPageViewDataProvider.php delete mode 100644 src/Core/CMS/CmsPageViewDataProviderInterface.php delete mode 100644 src/Core/Cache/Clearer/CacheClearerChain.php delete mode 100644 src/Core/Cache/Clearer/CacheClearerInterface.php delete mode 100644 src/Core/Cart/AmountImmutable.php delete mode 100644 src/Core/Cart/Calculator.php delete mode 100644 src/Core/Cart/CartRow.php delete mode 100644 src/Core/Cart/CartRowCollection.php delete mode 100644 src/Core/Cart/CartRuleCalculator.php delete mode 100644 src/Core/Cart/CartRuleCollection.php delete mode 100644 src/Core/Cart/CartRuleData.php delete mode 100644 src/Core/Cart/Fees.php delete mode 100644 src/Core/Checkout/TermsAndConditions.php delete mode 100644 src/Core/CommandBus/CommandBusInterface.php delete mode 100644 src/Core/CommandBus/ExecutedCommandRegistry.php delete mode 100644 src/Core/CommandBus/Middleware/CommandRegisterMiddleware.php delete mode 100644 src/Core/CommandBus/Parser/CommandDefinition.php delete mode 100644 src/Core/CommandBus/Parser/CommandDefinitionParser.php delete mode 100644 src/Core/CommandBus/Parser/CommandTypeParser.php delete mode 100644 src/Core/CommandBus/TacticianCommandBusAdapter.php delete mode 100644 src/Core/Configuration/DataConfigurationInterface.php delete mode 100644 src/Core/Configuration/IniConfiguration.php delete mode 100644 src/Core/Configuration/PhpExtensionChecker.php delete mode 100644 src/Core/Configuration/PhpExtensionCheckerInterface.php delete mode 100644 src/Core/Configuration/UploadSizeConfiguration.php delete mode 100644 src/Core/Configuration/UploadSizeConfigurationInterface.php delete mode 100644 src/Core/ConfigurationInterface.php delete mode 100644 src/Core/ConstraintValidator/AddressDniRequiredValidator.php delete mode 100644 src/Core/ConstraintValidator/AddressStateRequiredValidator.php delete mode 100644 src/Core/ConstraintValidator/AddressZipCodeValidator.php delete mode 100644 src/Core/ConstraintValidator/CleanHtmlValidator.php delete mode 100644 src/Core/ConstraintValidator/Constraints/AddressDniRequired.php delete mode 100644 src/Core/ConstraintValidator/Constraints/AddressStateRequired.php delete mode 100644 src/Core/ConstraintValidator/Constraints/AddressZipCode.php delete mode 100644 src/Core/ConstraintValidator/Constraints/CleanHtml.php delete mode 100644 src/Core/ConstraintValidator/Constraints/CustomerName.php delete mode 100644 src/Core/ConstraintValidator/Constraints/DateRange.php delete mode 100644 src/Core/ConstraintValidator/Constraints/DefaultLanguage.php delete mode 100644 src/Core/ConstraintValidator/Constraints/ExistingCustomerEmail.php delete mode 100644 src/Core/ConstraintValidator/Constraints/IsUrlRewrite.php delete mode 100644 src/Core/ConstraintValidator/Constraints/NotBlankWhenRequired.php delete mode 100644 src/Core/ConstraintValidator/Constraints/Reduction.php delete mode 100644 src/Core/ConstraintValidator/Constraints/TypedRegex.php delete mode 100644 src/Core/ConstraintValidator/CustomerNameValidator.php delete mode 100644 src/Core/ConstraintValidator/DateRangeValidator.php delete mode 100644 src/Core/ConstraintValidator/DefaultLanguageValidator.php delete mode 100644 src/Core/ConstraintValidator/ExistingCustomerEmailValidator.php delete mode 100644 src/Core/ConstraintValidator/Factory/CustomerNameValidatorFactory.php delete mode 100644 src/Core/ConstraintValidator/IsUrlRewriteValidator.php delete mode 100644 src/Core/ConstraintValidator/NotBlankWhenRequiredValidator.php delete mode 100644 src/Core/ConstraintValidator/ReductionValidator.php delete mode 100644 src/Core/ConstraintValidator/TypedRegexValidator.php delete mode 100644 src/Core/ContainerBuilder.php delete mode 100644 src/Core/Country/CountryRequiredFieldsProviderInterface.php delete mode 100644 src/Core/Country/CountryZipCodeRequirements.php delete mode 100644 src/Core/Country/CountryZipCodeRequirementsProviderInterface.php delete mode 100644 src/Core/CreditSlip/CreditSlipOptionsConfiguration.php delete mode 100644 src/Core/Crypto/Hashing.php delete mode 100644 src/Core/Currency/CurrencyDataProviderInterface.php delete mode 100644 src/Core/Currency/CurrencyGridDataFactory.php delete mode 100644 src/Core/Currency/Exception/CurrencyFeedException.php delete mode 100644 src/Core/Currency/ExchangeRateProvider.php delete mode 100644 src/Core/Customer/CustomerDataSourceInterface.php delete mode 100644 src/Core/Data/AbstractTypedCollection.php delete mode 100644 src/Core/Data/Layer/AbstractDataLayer.php delete mode 100644 src/Core/Data/Layer/DataLayerException.php delete mode 100644 src/Core/Domain/Address/AddressSettings.php delete mode 100644 src/Core/Domain/Address/Command/AbstractEditAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/AddCustomerAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/AddManufacturerAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/BulkDeleteAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/DeleteAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/EditCartAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/EditCustomerAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/EditManufacturerAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/EditOrderAddressCommand.php delete mode 100644 src/Core/Domain/Address/Command/SetRequiredFieldsForAddressCommand.php delete mode 100644 src/Core/Domain/Address/CommandHandler/AddCustomerAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/AddManufacturerAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/BulkDeleteAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/DeleteAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/EditCartAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/EditCustomerAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/EditManufacturerAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/EditOrderAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/CommandHandler/SetRequiredFieldsForAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/Configuration/AddressConstraint.php delete mode 100644 src/Core/Domain/Address/Exception/AddressConstraintException.php delete mode 100644 src/Core/Domain/Address/Exception/AddressException.php delete mode 100644 src/Core/Domain/Address/Exception/AddressNotFoundException.php delete mode 100644 src/Core/Domain/Address/Exception/BulkDeleteAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/CannotAddAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/CannotSetRequiredFieldsForAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/CannotUpdateAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/CannotUpdateCartAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/CannotUpdateOrderAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/DeleteAddressException.php delete mode 100644 src/Core/Domain/Address/Exception/InvalidAddressFieldException.php delete mode 100644 src/Core/Domain/Address/Exception/InvalidAddressRequiredFieldsException.php delete mode 100644 src/Core/Domain/Address/Query/GetCustomerAddressForEditing.php delete mode 100644 src/Core/Domain/Address/Query/GetManufacturerAddressForEditing.php delete mode 100644 src/Core/Domain/Address/Query/GetRequiredFieldsForAddress.php delete mode 100644 src/Core/Domain/Address/QueryHandler/GetCustomerAddressForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Address/QueryHandler/GetManufacturerAddressForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Address/QueryHandler/GetRequiredFieldsForAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Address/QueryResult/EditableCustomerAddress.php delete mode 100644 src/Core/Domain/Address/QueryResult/EditableManufacturerAddress.php delete mode 100644 src/Core/Domain/Address/ValueObject/AddressId.php delete mode 100644 src/Core/Domain/Address/ValueObject/RequiredFields.php delete mode 100644 src/Core/Domain/Attachment/AttachmentFileUploaderInterface.php delete mode 100644 src/Core/Domain/Attachment/Command/AddAttachmentCommand.php delete mode 100644 src/Core/Domain/Attachment/Command/BulkDeleteAttachmentsCommand.php delete mode 100644 src/Core/Domain/Attachment/Command/DeleteAttachmentCommand.php delete mode 100644 src/Core/Domain/Attachment/Command/EditAttachmentCommand.php delete mode 100644 src/Core/Domain/Attachment/CommandHandler/AddAttachmentHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/CommandHandler/BulkDeleteAttachmentsHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/CommandHandler/DeleteAttachmentHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/CommandHandler/EditAttachmentHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/Configuration/AttachmentConstraint.php delete mode 100644 src/Core/Domain/Attachment/Exception/AttachmentConstraintException.php delete mode 100644 src/Core/Domain/Attachment/Exception/AttachmentException.php delete mode 100644 src/Core/Domain/Attachment/Exception/AttachmentNotFoundException.php delete mode 100644 src/Core/Domain/Attachment/Exception/AttachmentUploadFailedException.php delete mode 100644 src/Core/Domain/Attachment/Exception/BulkDeleteAttachmentsException.php delete mode 100644 src/Core/Domain/Attachment/Exception/CannotAddAttachmentException.php delete mode 100644 src/Core/Domain/Attachment/Exception/CannotUnlinkAttachmentException.php delete mode 100644 src/Core/Domain/Attachment/Exception/CannotUpdateAttachmentException.php delete mode 100644 src/Core/Domain/Attachment/Exception/DeleteAttachmentException.php delete mode 100644 src/Core/Domain/Attachment/Exception/EmptyFileException.php delete mode 100644 src/Core/Domain/Attachment/Query/GetAttachment.php delete mode 100644 src/Core/Domain/Attachment/Query/GetAttachmentForEditing.php delete mode 100644 src/Core/Domain/Attachment/QueryHandler/GetAttachmentForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/QueryHandler/GetAttachmentHandlerInterface.php delete mode 100644 src/Core/Domain/Attachment/QueryResult/Attachment.php delete mode 100644 src/Core/Domain/Attachment/QueryResult/EditableAttachment.php delete mode 100644 src/Core/Domain/Attachment/ValueObject/AttachmentId.php delete mode 100644 src/Core/Domain/Cart/CartAddressType.php delete mode 100644 src/Core/Domain/Cart/Command/AddCartRuleToCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/AddCustomizationCommand.php delete mode 100644 src/Core/Domain/Cart/Command/AddProductToCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/CreateEmptyCustomerCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/RemoveCartRuleFromCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/RemoveProductFromCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/SendCartToCustomerCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateCartAddressesCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateCartCarrierCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateCartCurrencyCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateCartDeliverySettingsCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateCartLanguageCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateProductPriceInCartCommand.php delete mode 100644 src/Core/Domain/Cart/Command/UpdateProductQuantityInCartCommand.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/AddCartRuleToCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/AddCustomizationHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/AddProductToCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/CreateEmptyCustomerCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/RemoveCartRuleFromCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/RemoveProductFromCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/SendCartToCustomerHanlderInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateCartAddressesHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateCartCarrierHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateCartCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateCartDeliverySettingsHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateCartLanguageHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateProductPriceInCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/CommandHandler/UpdateProductQuantityInCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/Exception/CannotUpdateCartException.php delete mode 100644 src/Core/Domain/Cart/Exception/CartConstraintException.php delete mode 100644 src/Core/Domain/Cart/Exception/CartException.php delete mode 100644 src/Core/Domain/Cart/Exception/CartNotFoundException.php delete mode 100644 src/Core/Domain/Cart/Exception/InvalidAddressTypeException.php delete mode 100644 src/Core/Domain/Cart/Exception/InvalidGiftMessageException.php delete mode 100644 src/Core/Domain/Cart/Exception/MinimalQuantityException.php delete mode 100644 src/Core/Domain/Cart/Query/GetCartForOrderCreation.php delete mode 100644 src/Core/Domain/Cart/Query/GetCartForViewing.php delete mode 100644 src/Core/Domain/Cart/Query/GetLastEmptyCustomerCart.php delete mode 100644 src/Core/Domain/Cart/QueryHandler/GetCartForOrderCreationHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/QueryHandler/GetCartForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/QueryHandler/GetLastEmptyCustomerCartHandlerInterface.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartAddress.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartDeliveryOption.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartProduct.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartRule.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartShipping.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartSummary.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/Customization.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CustomizationFieldData.php delete mode 100644 src/Core/Domain/Cart/QueryResult/CartView.php delete mode 100644 src/Core/Domain/Cart/ValueObject/CartId.php delete mode 100644 src/Core/Domain/CartRule/Command/AddCartRuleCommand.php delete mode 100644 src/Core/Domain/CartRule/CommandHandler/AddCartRuleHandlerInterface.php delete mode 100644 src/Core/Domain/CartRule/Exception/CannotDeleteCartRuleException.php delete mode 100644 src/Core/Domain/CartRule/Exception/CartRuleConstraintException.php delete mode 100644 src/Core/Domain/CartRule/Exception/CartRuleException.php delete mode 100644 src/Core/Domain/CartRule/Exception/CartRuleValidityException.php delete mode 100644 src/Core/Domain/CartRule/Exception/InvalidCartRuleDiscountValueException.php delete mode 100644 src/Core/Domain/CartRule/Exception/InvalidCartRuleValueException.php delete mode 100644 src/Core/Domain/CartRule/Query/SearchCartRules.php delete mode 100644 src/Core/Domain/CartRule/QueryHandler/SearchCartRulesHandlerInterface.php delete mode 100644 src/Core/Domain/CartRule/QueryResult/FoundCartRule.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/AmountDiscountAction.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilder.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilderInterface.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionInterface.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/FreeShippingAction.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/GiftProductAction.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleAction/PercentageDiscountAction.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/CartRuleId.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/DiscountApplicationType.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/GiftProduct.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/MoneyAmountCondition.php delete mode 100644 src/Core/Domain/CartRule/ValueObject/PercentageDiscount.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Command/AddCatalogPriceRuleCommand.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Command/BulkDeleteCatalogPriceRuleCommand.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Command/DeleteCatalogPriceRuleCommand.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Command/EditCatalogPriceRuleCommand.php delete mode 100644 src/Core/Domain/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandlerInterface.php delete mode 100644 src/Core/Domain/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandlerInterface.php delete mode 100644 src/Core/Domain/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandlerInterface.php delete mode 100644 src/Core/Domain/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandlerInterface.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Exception/CannotDeleteCatalogPriceRuleException.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Exception/CannotUpdateCatalogPriceRuleException.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleConstraintException.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleException.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleNotFoundException.php delete mode 100644 src/Core/Domain/CatalogPriceRule/Query/GetCatalogPriceRuleForEditing.php delete mode 100644 src/Core/Domain/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/CatalogPriceRule/QueryResult/EditableCatalogPriceRule.php delete mode 100644 src/Core/Domain/CatalogPriceRule/ValueObject/CatalogPriceRuleId.php delete mode 100644 src/Core/Domain/Category/Command/AddCategoryCommand.php delete mode 100644 src/Core/Domain/Category/Command/AddRootCategoryCommand.php delete mode 100644 src/Core/Domain/Category/Command/BulkDeleteCategoriesCommand.php delete mode 100644 src/Core/Domain/Category/Command/BulkDisableCategoriesCommand.php delete mode 100644 src/Core/Domain/Category/Command/BulkEnableCategoriesCommand.php delete mode 100644 src/Core/Domain/Category/Command/BulkUpdateCategoriesStatusCommand.php delete mode 100644 src/Core/Domain/Category/Command/DeleteCategoryCommand.php delete mode 100644 src/Core/Domain/Category/Command/DeleteCategoryCoverImageCommand.php delete mode 100644 src/Core/Domain/Category/Command/DeleteCategoryMenuThumbnailImageCommand.php delete mode 100644 src/Core/Domain/Category/Command/EditCategoryCommand.php delete mode 100644 src/Core/Domain/Category/Command/EditRootCategoryCommand.php delete mode 100644 src/Core/Domain/Category/Command/SetCategoryIsEnabledCommand.php delete mode 100644 src/Core/Domain/Category/Command/UpdateCategoryPositionCommand.php delete mode 100644 src/Core/Domain/Category/CommandHandler/AddCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/AddRootCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/BulkDeleteCategoriesHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/BulkUpdateCategoriesStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/DeleteCategoryCoverImageHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/DeleteCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/EditCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/EditRootCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/SetCategoryIsEnabledHandlerInterface.php delete mode 100644 src/Core/Domain/Category/CommandHandler/UpdateCategoryPositionHandlerInterface.php delete mode 100644 src/Core/Domain/Category/Exception/CannotAddCategoryException.php delete mode 100644 src/Core/Domain/Category/Exception/CannotDeleteImageException.php delete mode 100644 src/Core/Domain/Category/Exception/CannotDeleteRootCategoryForShopException.php delete mode 100644 src/Core/Domain/Category/Exception/CannotEditCategoryException.php delete mode 100644 src/Core/Domain/Category/Exception/CannotUpdateCategoryStatusException.php delete mode 100644 src/Core/Domain/Category/Exception/CategoryConstraintException.php delete mode 100644 src/Core/Domain/Category/Exception/CategoryException.php delete mode 100644 src/Core/Domain/Category/Exception/CategoryNotFoundException.php delete mode 100644 src/Core/Domain/Category/Exception/FailedToDeleteCategoryException.php delete mode 100644 src/Core/Domain/Category/Exception/MenuThumbnailsLimitException.php delete mode 100644 src/Core/Domain/Category/Query/GetCategoryForEditing.php delete mode 100644 src/Core/Domain/Category/Query/GetCategoryIsEnabled.php delete mode 100644 src/Core/Domain/Category/QueryHandler/GetCategoryForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Category/QueryHandler/GetCategoryIsEnabledHandlerInterface.php delete mode 100644 src/Core/Domain/Category/QueryResult/EditableCategory.php delete mode 100644 src/Core/Domain/Category/SeoSettings.php delete mode 100644 src/Core/Domain/Category/ValueObject/CategoryDeleteMode.php delete mode 100644 src/Core/Domain/Category/ValueObject/CategoryId.php delete mode 100644 src/Core/Domain/Category/ValueObject/MenuThumbnailId.php delete mode 100644 src/Core/Domain/CmsPage/Command/AddCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/BulkDeleteCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/BulkDisableCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/BulkEnableCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/DeleteCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/EditCmsPageCommand.php delete mode 100644 src/Core/Domain/CmsPage/Command/ToggleCmsPageStatusCommand.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/AddCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/BulkDeleteCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/BulkDisableCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/BulkEnableCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/DeleteCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/EditCmsPageHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/CommandHandler/ToggleCmsPageStatusHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotAddCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotDeleteCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotDisableCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotEditCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotEnableCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CannotToggleCmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CmsPageException.php delete mode 100644 src/Core/Domain/CmsPage/Exception/CmsPageNotFoundException.php delete mode 100644 src/Core/Domain/CmsPage/Query/GetCmsCategoryIdForRedirection.php delete mode 100644 src/Core/Domain/CmsPage/Query/GetCmsPageForEditing.php delete mode 100644 src/Core/Domain/CmsPage/QueryHandler/GetCmsCategoryIdHandlerForRedirectionInterface.php delete mode 100644 src/Core/Domain/CmsPage/QueryHandler/GetCmsPageForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPage/QueryResult/EditableCmsPage.php delete mode 100644 src/Core/Domain/CmsPage/ValueObject/CmsPageId.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/AbstractBulkCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/AbstractCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/AddCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/BulkDeleteCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/BulkDisableCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/BulkEnableCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/DeleteCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/EditCmsPageCategoryCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/Command/ToggleCmsPageCategoryStatusCommand.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/AddCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/BulkDisableCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/BulkEnableCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/DeleteCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/EditCmsPageCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotAddCmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotDeleteCmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotDisableCmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotEnableCmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotToggleCmsPageCategoryStatusException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CannotUpdateCmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryConstraintException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryNotFoundException.php delete mode 100644 src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoriesForBreadcrumb.php delete mode 100644 src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryForEditing.php delete mode 100644 src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryNameForListing.php delete mode 100644 src/Core/Domain/CmsPageCategory/Query/GetCmsPageParentCategoryIdForRedirection.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandlerInterface.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryResult/Breadcrumb.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryResult/BreadcrumbItem.php delete mode 100644 src/Core/Domain/CmsPageCategory/QueryResult/EditableCmsPageCategory.php delete mode 100644 src/Core/Domain/CmsPageCategory/ValueObject/CmsPageCategoryId.php delete mode 100644 src/Core/Domain/Configuration/Command/SwitchDebugModeCommand.php delete mode 100644 src/Core/Domain/Configuration/CommandHandler/SwitchDebugModeHandlerInterface.php delete mode 100644 src/Core/Domain/Configuration/ShopConfigurationInterface.php delete mode 100644 src/Core/Domain/Contact/Command/AbstractContactCommand.php delete mode 100644 src/Core/Domain/Contact/Command/AddContactCommand.php delete mode 100644 src/Core/Domain/Contact/Command/EditContactCommand.php delete mode 100644 src/Core/Domain/Contact/CommandHandler/AddContactHandlerInterface.php delete mode 100644 src/Core/Domain/Contact/CommandHandler/EditContactHandlerInterface.php delete mode 100644 src/Core/Domain/Contact/Exception/CannotAddContactException.php delete mode 100644 src/Core/Domain/Contact/Exception/CannotUpdateContactException.php delete mode 100644 src/Core/Domain/Contact/Exception/ContactConstraintException.php delete mode 100644 src/Core/Domain/Contact/Exception/ContactException.php delete mode 100644 src/Core/Domain/Contact/Exception/ContactNotFoundException.php delete mode 100644 src/Core/Domain/Contact/Query/GetContactForEditing.php delete mode 100644 src/Core/Domain/Contact/QueryHandler/GetContactForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Contact/QueryResult/EditableContact.php delete mode 100644 src/Core/Domain/Contact/ValueObject/ContactId.php delete mode 100644 src/Core/Domain/Country/Exception/CountryConstraintException.php delete mode 100644 src/Core/Domain/Country/Exception/CountryException.php delete mode 100644 src/Core/Domain/Country/Exception/CountryNotFoundException.php delete mode 100644 src/Core/Domain/Country/Query/GetCountryRequiredFields.php delete mode 100644 src/Core/Domain/Country/QueryHandler/GetCountryRequiredFieldsHandlerInterface.php delete mode 100644 src/Core/Domain/Country/QueryResult/CountryRequiredFields.php delete mode 100644 src/Core/Domain/Country/ValueObject/CountryId.php delete mode 100644 src/Core/Domain/Country/ZipCodePatternResolver.php delete mode 100644 src/Core/Domain/Country/ZipCodePatternResolverInterface.php delete mode 100644 src/Core/Domain/CreditSlip/Exception/CreditSlipConstraintException.php delete mode 100644 src/Core/Domain/CreditSlip/Exception/CreditSlipException.php delete mode 100644 src/Core/Domain/CreditSlip/Exception/CreditSlipNotFoundException.php delete mode 100644 src/Core/Domain/CreditSlip/Query/GetCreditSlipIdsByDateRange.php delete mode 100644 src/Core/Domain/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandlerInterface.php delete mode 100644 src/Core/Domain/CreditSlip/ValueObject/CreditSlipId.php delete mode 100644 src/Core/Domain/Currency/Command/AddCurrencyCommand.php delete mode 100644 src/Core/Domain/Currency/Command/AddUnofficialCurrencyCommand.php delete mode 100644 src/Core/Domain/Currency/Command/DeleteCurrencyCommand.php delete mode 100644 src/Core/Domain/Currency/Command/EditCurrencyCommand.php delete mode 100644 src/Core/Domain/Currency/Command/EditUnofficialCurrencyCommand.php delete mode 100644 src/Core/Domain/Currency/Command/RefreshExchangeRatesCommand.php delete mode 100644 src/Core/Domain/Currency/Command/ToggleCurrencyStatusCommand.php delete mode 100644 src/Core/Domain/Currency/Command/ToggleExchangeRateAutomatizationCommand.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/AddCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/AddUnofficialCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/DeleteCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/EditCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/EditUnofficialCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/RefreshExchangeRatesHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/ToggleCurrencyStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/Exception/AutomateExchangeRatesUpdateException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotCreateCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotDeleteCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotDeleteDefaultCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotDisableDefaultCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotRefreshExchangeRatesException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotToggleCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CannotUpdateCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CurrencyConstraintException.php delete mode 100644 src/Core/Domain/Currency/Exception/CurrencyException.php delete mode 100644 src/Core/Domain/Currency/Exception/CurrencyNotFoundException.php delete mode 100644 src/Core/Domain/Currency/Exception/DefaultCurrencyInMultiShopException.php delete mode 100644 src/Core/Domain/Currency/Exception/ExchangeRateNotFoundException.php delete mode 100644 src/Core/Domain/Currency/Exception/InvalidUnofficialCurrencyException.php delete mode 100644 src/Core/Domain/Currency/Query/GetCurrencyExchangeRate.php delete mode 100644 src/Core/Domain/Currency/Query/GetCurrencyForEditing.php delete mode 100644 src/Core/Domain/Currency/Query/GetReferenceCurrency.php delete mode 100644 src/Core/Domain/Currency/QueryHandler/GetCurrencyExchangeRateHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/QueryHandler/GetCurrencyForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/QueryHandler/GetReferenceCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Currency/QueryResult/EditableCurrency.php delete mode 100644 src/Core/Domain/Currency/QueryResult/ExchangeRate.php delete mode 100644 src/Core/Domain/Currency/QueryResult/ReferenceCurrency.php delete mode 100644 src/Core/Domain/Currency/ValueObject/AlphaIsoCode.php delete mode 100644 src/Core/Domain/Currency/ValueObject/CurrencyId.php delete mode 100644 src/Core/Domain/Currency/ValueObject/ExchangeRate.php delete mode 100644 src/Core/Domain/Currency/ValueObject/NumericIsoCode.php delete mode 100644 src/Core/Domain/Currency/ValueObject/Precision.php delete mode 100644 src/Core/Domain/Customer/Command/AddCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/BulkDeleteCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/BulkDisableCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/BulkEnableCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/DeleteCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/EditCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/SetPrivateNoteAboutCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/SetRequiredFieldsForCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/Command/TransformGuestToCustomerCommand.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/AddCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/BulkDeleteCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/BulkDisableCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/BulkEnableCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/DeleteCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/EditCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/SetRequiredFieldsForCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/CommandHandler/TransformGuestToCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/Exception/CannotSetRequiredFieldsForCustomerException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerByEmailNotFoundException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerConstraintException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerDefaultGroupAccessException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerNotFoundException.php delete mode 100644 src/Core/Domain/Customer/Exception/CustomerTransformationException.php delete mode 100644 src/Core/Domain/Customer/Exception/DuplicateCustomerEmailException.php delete mode 100644 src/Core/Domain/Customer/Exception/InvalidCustomerIdException.php delete mode 100644 src/Core/Domain/Customer/Exception/InvalidCustomerRequiredFieldsException.php delete mode 100644 src/Core/Domain/Customer/Exception/MissingCustomerRequiredFieldsException.php delete mode 100644 src/Core/Domain/Customer/Query/GetCustomerCarts.php delete mode 100644 src/Core/Domain/Customer/Query/GetCustomerForAddressCreation.php delete mode 100644 src/Core/Domain/Customer/Query/GetCustomerForEditing.php delete mode 100644 src/Core/Domain/Customer/Query/GetCustomerForViewing.php delete mode 100644 src/Core/Domain/Customer/Query/GetCustomerOrders.php delete mode 100644 src/Core/Domain/Customer/Query/GetRequiredFieldsForCustomer.php delete mode 100644 src/Core/Domain/Customer/Query/SearchCustomers.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetCustomerCartsHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetCustomerForAddressCreationHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetCustomerForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetCustomerForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetCustomerOrdersHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/GetRequiredFieldsForCustomerHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryHandler/SearchCustomersHandlerInterface.php delete mode 100644 src/Core/Domain/Customer/QueryResult/AddressCreationCustomerInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/AddressInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/BoughtProductInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/CartInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/CartSummary.php delete mode 100644 src/Core/Domain/Customer/QueryResult/DiscountInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/EditableCustomer.php delete mode 100644 src/Core/Domain/Customer/QueryResult/GeneralInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/GroupInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/LastConnectionInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/MessageInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/OrderInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/OrderSummary.php delete mode 100644 src/Core/Domain/Customer/QueryResult/OrdersInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/PersonalInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/ProductsInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/ReferrerInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/SentEmailInformation.php delete mode 100644 src/Core/Domain/Customer/QueryResult/Subscriptions.php delete mode 100644 src/Core/Domain/Customer/QueryResult/ViewableCustomer.php delete mode 100644 src/Core/Domain/Customer/QueryResult/ViewedProductInformation.php delete mode 100644 src/Core/Domain/Customer/ValueObject/ApeCode.php delete mode 100644 src/Core/Domain/Customer/ValueObject/Birthday.php delete mode 100644 src/Core/Domain/Customer/ValueObject/CustomerDeleteMethod.php delete mode 100644 src/Core/Domain/Customer/ValueObject/CustomerId.php delete mode 100644 src/Core/Domain/Customer/ValueObject/Email.php delete mode 100644 src/Core/Domain/Customer/ValueObject/FirstName.php delete mode 100644 src/Core/Domain/Customer/ValueObject/LastName.php delete mode 100644 src/Core/Domain/Customer/ValueObject/Password.php delete mode 100644 src/Core/Domain/Customer/ValueObject/RequiredField.php delete mode 100644 src/Core/Domain/CustomerMessage/Command/AddOrderCustomerMessageCommand.php delete mode 100644 src/Core/Domain/CustomerMessage/CommandHandler/AddOrderCustomerMessageHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerMessage/Exception/CannotSendEmailException.php delete mode 100644 src/Core/Domain/CustomerMessage/Exception/CustomerMessageConstraintException.php delete mode 100644 src/Core/Domain/CustomerMessage/Exception/CustomerMessageException.php delete mode 100644 src/Core/Domain/CustomerService/Command/ForwardCustomerThreadCommand.php delete mode 100644 src/Core/Domain/CustomerService/Command/ReplyToCustomerThreadCommand.php delete mode 100644 src/Core/Domain/CustomerService/Command/UpdateCustomerThreadStatusCommand.php delete mode 100644 src/Core/Domain/CustomerService/CommandHandler/ForwardCustomerThreadHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerService/CommandHandler/ReplyToCustomerThreadHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandler.php delete mode 100644 src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerService/Exception/CustomerServiceException.php delete mode 100644 src/Core/Domain/CustomerService/Exception/CustomerThreadNotFoundException.php delete mode 100644 src/Core/Domain/CustomerService/Query/GetCustomerServiceSignature.php delete mode 100644 src/Core/Domain/CustomerService/Query/GetCustomerThreadForViewing.php delete mode 100644 src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandler.php delete mode 100644 src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerService/QueryHandler/GetCustomerThreadForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/CustomerService/QueryResult/CustomerInformation.php delete mode 100644 src/Core/Domain/CustomerService/QueryResult/CustomerThreadMessage.php delete mode 100644 src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimeline.php delete mode 100644 src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimelineItem.php delete mode 100644 src/Core/Domain/CustomerService/QueryResult/CustomerThreadView.php delete mode 100644 src/Core/Domain/CustomerService/ValueObject/CustomerThreadId.php delete mode 100644 src/Core/Domain/CustomerService/ValueObject/CustomerThreadMessageType.php delete mode 100644 src/Core/Domain/CustomerService/ValueObject/CustomerThreadStatus.php delete mode 100644 src/Core/Domain/Employee/Command/AddEmployeeCommand.php delete mode 100644 src/Core/Domain/Employee/Command/BulkDeleteEmployeeCommand.php delete mode 100644 src/Core/Domain/Employee/Command/BulkUpdateEmployeeStatusCommand.php delete mode 100644 src/Core/Domain/Employee/Command/DeleteEmployeeCommand.php delete mode 100644 src/Core/Domain/Employee/Command/EditEmployeeCommand.php delete mode 100644 src/Core/Domain/Employee/Command/ToggleEmployeeStatusCommand.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/AddEmployeeHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/BulkDeleteEmployeeHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/BulkUpdateEmployeeStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/DeleteEmployeeHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/EditEmployeeHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/CommandHandler/ToggleEmployeeStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/Exception/AdminEmployeeException.php delete mode 100644 src/Core/Domain/Employee/Exception/CannotDeleteEmployeeException.php delete mode 100644 src/Core/Domain/Employee/Exception/CannotDeleteWarehouseManagerException.php delete mode 100644 src/Core/Domain/Employee/Exception/EmailAlreadyUsedException.php delete mode 100644 src/Core/Domain/Employee/Exception/EmployeeCannotChangeItselfException.php delete mode 100644 src/Core/Domain/Employee/Exception/EmployeeConstraintException.php delete mode 100644 src/Core/Domain/Employee/Exception/EmployeeException.php delete mode 100644 src/Core/Domain/Employee/Exception/EmployeeNotFoundException.php delete mode 100644 src/Core/Domain/Employee/Exception/InvalidEmployeeIdException.php delete mode 100644 src/Core/Domain/Employee/Exception/InvalidPasswordException.php delete mode 100644 src/Core/Domain/Employee/Exception/InvalidProfileException.php delete mode 100644 src/Core/Domain/Employee/Exception/MissingShopAssociationException.php delete mode 100644 src/Core/Domain/Employee/Query/GetEmployeeEmailById.php delete mode 100644 src/Core/Domain/Employee/Query/GetEmployeeForEditing.php delete mode 100644 src/Core/Domain/Employee/QueryHandler/GetEmployeeEmailByIdHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/QueryHandler/GetEmployeeForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Employee/QueryResult/EditableEmployee.php delete mode 100644 src/Core/Domain/Employee/ValueObject/EmployeeId.php delete mode 100644 src/Core/Domain/Employee/ValueObject/FirstName.php delete mode 100644 src/Core/Domain/Employee/ValueObject/LastName.php delete mode 100644 src/Core/Domain/Employee/ValueObject/Password.php delete mode 100644 src/Core/Domain/Exception/DomainConstraintException.php delete mode 100644 src/Core/Domain/Exception/DomainException.php delete mode 100644 src/Core/Domain/Exception/FileUploadException.php delete mode 100644 src/Core/Domain/Exception/InvalidSortingException.php delete mode 100644 src/Core/Domain/Feature/Command/AddFeatureCommand.php delete mode 100644 src/Core/Domain/Feature/Command/EditFeatureCommand.php delete mode 100644 src/Core/Domain/Feature/CommandHandler/AddFeatureHandlerInterface.php delete mode 100644 src/Core/Domain/Feature/CommandHandler/EditFeatureHandlerInterface.php delete mode 100644 src/Core/Domain/Feature/Exception/CannotAddFeatureException.php delete mode 100644 src/Core/Domain/Feature/Exception/CannotEditFeatureException.php delete mode 100644 src/Core/Domain/Feature/Exception/FeatureConstraintException.php delete mode 100644 src/Core/Domain/Feature/Exception/FeatureException.php delete mode 100644 src/Core/Domain/Feature/Exception/FeatureNotFoundException.php delete mode 100644 src/Core/Domain/Feature/Exception/InvalidFeatureIdException.php delete mode 100644 src/Core/Domain/Feature/Query/GetFeatureForEditing.php delete mode 100644 src/Core/Domain/Feature/QueryHandler/GetFeatureForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Feature/QueryResult/EditableFeature.php delete mode 100644 src/Core/Domain/Feature/ValueObject/FeatureId.php delete mode 100644 src/Core/Domain/Language/Command/AddLanguageCommand.php delete mode 100644 src/Core/Domain/Language/Command/BulkDeleteLanguagesCommand.php delete mode 100644 src/Core/Domain/Language/Command/BulkToggleLanguagesStatusCommand.php delete mode 100644 src/Core/Domain/Language/Command/DeleteLanguageCommand.php delete mode 100644 src/Core/Domain/Language/Command/EditLanguageCommand.php delete mode 100644 src/Core/Domain/Language/Command/ToggleLanguageStatusCommand.php delete mode 100644 src/Core/Domain/Language/CommandHandler/AddLanguageHandlerInterface.php delete mode 100644 src/Core/Domain/Language/CommandHandler/BulkDeleteLanguagesHandlerInterface.php delete mode 100644 src/Core/Domain/Language/CommandHandler/BulkToggleLanguagesStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Language/CommandHandler/DeleteLanguageHandlerInterface.php delete mode 100644 src/Core/Domain/Language/CommandHandler/EditLanguageHandlerInterface.php delete mode 100644 src/Core/Domain/Language/CommandHandler/ToggleLanguageStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Language/Exception/CannotDisableDefaultLanguageException.php delete mode 100644 src/Core/Domain/Language/Exception/CopyingNoPictureException.php delete mode 100644 src/Core/Domain/Language/Exception/DefaultLanguageException.php delete mode 100644 src/Core/Domain/Language/Exception/LanguageConstraintException.php delete mode 100644 src/Core/Domain/Language/Exception/LanguageException.php delete mode 100644 src/Core/Domain/Language/Exception/LanguageImageUploadingException.php delete mode 100644 src/Core/Domain/Language/Exception/LanguageNotFoundException.php delete mode 100644 src/Core/Domain/Language/Query/GetLanguageForEditing.php delete mode 100644 src/Core/Domain/Language/QueryHandler/GetLanguageForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Language/QueryResult/EditableLanguage.php delete mode 100644 src/Core/Domain/Language/ValueObject/IsoCode.php delete mode 100644 src/Core/Domain/Language/ValueObject/LanguageId.php delete mode 100644 src/Core/Domain/Language/ValueObject/TagIETF.php delete mode 100644 src/Core/Domain/MailTemplate/Command/GenerateThemeMailTemplatesCommand.php delete mode 100644 src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandler.php delete mode 100644 src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/Command/AddManufacturerCommand.php delete mode 100644 src/Core/Domain/Manufacturer/Command/BulkDeleteManufacturerCommand.php delete mode 100644 src/Core/Domain/Manufacturer/Command/BulkToggleManufacturerStatusCommand.php delete mode 100644 src/Core/Domain/Manufacturer/Command/DeleteManufacturerCommand.php delete mode 100644 src/Core/Domain/Manufacturer/Command/EditManufacturerCommand.php delete mode 100644 src/Core/Domain/Manufacturer/Command/ToggleManufacturerStatusCommand.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/AddManufacturerHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/BulkDeleteManufacturerHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/DeleteManufacturerHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/EditManufacturerHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/CommandHandler/ToggleManufacturerStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/DeleteManufacturerException.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/ManufacturerConstraintException.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/ManufacturerException.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/ManufacturerImageUploadingException.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/ManufacturerNotFoundException.php delete mode 100644 src/Core/Domain/Manufacturer/Exception/UpdateManufacturerException.php delete mode 100644 src/Core/Domain/Manufacturer/Query/GetManufacturerForEditing.php delete mode 100644 src/Core/Domain/Manufacturer/Query/GetManufacturerForViewing.php delete mode 100644 src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Manufacturer/QueryResult/EditableManufacturer.php delete mode 100644 src/Core/Domain/Manufacturer/QueryResult/ViewableManufacturer.php delete mode 100644 src/Core/Domain/Manufacturer/ValueObject/ManufacturerId.php delete mode 100644 src/Core/Domain/Meta/Command/AbstractMetaCommand.php delete mode 100644 src/Core/Domain/Meta/Command/AddMetaCommand.php delete mode 100644 src/Core/Domain/Meta/Command/EditMetaCommand.php delete mode 100644 src/Core/Domain/Meta/CommandHandler/AddMetaHandlerInterface.php delete mode 100644 src/Core/Domain/Meta/CommandHandler/EditMetaHandlerInterface.php delete mode 100644 src/Core/Domain/Meta/Exception/CannotAddMetaException.php delete mode 100644 src/Core/Domain/Meta/Exception/CannotEditMetaException.php delete mode 100644 src/Core/Domain/Meta/Exception/MetaConstraintException.php delete mode 100644 src/Core/Domain/Meta/Exception/MetaException.php delete mode 100644 src/Core/Domain/Meta/Exception/MetaNotFoundException.php delete mode 100644 src/Core/Domain/Meta/Query/GetMetaForEditing.php delete mode 100644 src/Core/Domain/Meta/Query/GetPagesForLayoutCustomization.php delete mode 100644 src/Core/Domain/Meta/QueryHandler/GetMetaForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Meta/QueryHandler/GetPagesForLayoutCustomizationHandlerInterface.php delete mode 100644 src/Core/Domain/Meta/QueryResult/EditableMeta.php delete mode 100644 src/Core/Domain/Meta/QueryResult/LayoutCustomizationPage.php delete mode 100644 src/Core/Domain/Meta/ValueObject/MetaId.php delete mode 100644 src/Core/Domain/Meta/ValueObject/Name.php delete mode 100644 src/Core/Domain/Notification/Command/UpdateEmployeeNotificationLastElementCommand.php delete mode 100644 src/Core/Domain/Notification/CommandHandler/UpdateEmployeeNotificationLastElementCommandHandlerInterface.php delete mode 100644 src/Core/Domain/Notification/Exception/NotificationException.php delete mode 100644 src/Core/Domain/Notification/Query/GetNotificationLastElements.php delete mode 100644 src/Core/Domain/Notification/QueryHandler/GetNotificationLastElementsHandlerInterface.php delete mode 100644 src/Core/Domain/Notification/QueryResult/NotificationResult.php delete mode 100644 src/Core/Domain/Notification/QueryResult/NotificationsResult.php delete mode 100644 src/Core/Domain/Notification/QueryResult/NotificationsResults.php delete mode 100644 src/Core/Domain/Notification/ValueObject/Type.php delete mode 100644 src/Core/Domain/Order/CancellationActionType.php delete mode 100644 src/Core/Domain/Order/Command/AbstractRefundCommand.php delete mode 100644 src/Core/Domain/Order/Command/AddCartRuleToOrderCommand.php delete mode 100644 src/Core/Domain/Order/Command/AddOrderFromBackOfficeCommand.php delete mode 100644 src/Core/Domain/Order/Command/BulkChangeOrderStatusCommand.php delete mode 100644 src/Core/Domain/Order/Command/CancelOrderProductCommand.php delete mode 100644 src/Core/Domain/Order/Command/ChangeOrderCurrencyCommand.php delete mode 100644 src/Core/Domain/Order/Command/ChangeOrderDeliveryAddressCommand.php delete mode 100644 src/Core/Domain/Order/Command/ChangeOrderInvoiceAddressCommand.php delete mode 100644 src/Core/Domain/Order/Command/DeleteCartRuleFromOrderCommand.php delete mode 100644 src/Core/Domain/Order/Command/DuplicateOrderCartCommand.php delete mode 100644 src/Core/Domain/Order/Command/IssuePartialRefundCommand.php delete mode 100644 src/Core/Domain/Order/Command/IssueReturnProductCommand.php delete mode 100644 src/Core/Domain/Order/Command/IssueStandardRefundCommand.php delete mode 100644 src/Core/Domain/Order/Command/ResendOrderEmailCommand.php delete mode 100644 src/Core/Domain/Order/Command/SendProcessOrderEmailCommand.php delete mode 100644 src/Core/Domain/Order/Command/UpdateOrderShippingDetailsCommand.php delete mode 100644 src/Core/Domain/Order/Command/UpdateOrderStatusCommand.php delete mode 100644 src/Core/Domain/Order/CommandHandler/AddCartRuleToOrderHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/AddOrderFromBackOfficeHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/BulkChangeOrderStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/CancelOrderProductHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/ChangeOrderCurrencyHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/ChangeOrderDeliveryAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/ChangeOrderInvoiceAddressHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/DeleteCartRuleFromOrderHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/DuplicateOrderCartHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/IssuePartialRefundHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/IssueReturnProductHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/IssueStandardRefundHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/ResendOrderEmailHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/SendProcessOrderEmailHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/UpdateOrderShippingDetailsHandlerInterface.php delete mode 100644 src/Core/Domain/Order/CommandHandler/UpdateOrderStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Exception/CancelProductFromOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/CannotEditDeliveredOrderProductException.php delete mode 100644 src/Core/Domain/Order/Exception/CannotFindProductInOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/CannotUpdateOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/ChangeOrderStatusException.php delete mode 100644 src/Core/Domain/Order/Exception/DeleteCustomizedProductFromOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/DeleteProductFromOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/DuplicateOrderCartException.php delete mode 100644 src/Core/Domain/Order/Exception/DuplicateProductInOrderException.php delete mode 100644 src/Core/Domain/Order/Exception/DuplicateProductInOrderInvoiceException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidAddressTypeException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidAmountException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidCancelProductException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidOrderStateException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidProductQuantityException.php delete mode 100644 src/Core/Domain/Order/Exception/InvalidRefundException.php delete mode 100644 src/Core/Domain/Order/Exception/NegativePaymentAmountException.php delete mode 100644 src/Core/Domain/Order/Exception/OrderConstraintException.php delete mode 100644 src/Core/Domain/Order/Exception/OrderEmailSendException.php delete mode 100644 src/Core/Domain/Order/Exception/OrderException.php delete mode 100644 src/Core/Domain/Order/Exception/OrderNotFoundException.php delete mode 100644 src/Core/Domain/Order/Exception/ReturnProductDisabledException.php delete mode 100644 src/Core/Domain/Order/Exception/TransistEmailSendingException.php delete mode 100644 src/Core/Domain/Order/Invoice/Command/GenerateInvoiceCommand.php delete mode 100644 src/Core/Domain/Order/Invoice/Command/UpdateInvoiceNoteCommand.php delete mode 100644 src/Core/Domain/Order/Invoice/CommandHandler/GenerateOrderInvoiceHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Invoice/CommandHandler/UpdateInvoiceNoteHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Invoice/Exception/InvoiceException.php delete mode 100644 src/Core/Domain/Order/Invoice/Exception/InvoiceNotFoundException.php delete mode 100644 src/Core/Domain/Order/Invoice/ValueObject/OrderInvoiceId.php delete mode 100644 src/Core/Domain/Order/OrderAddressType.php delete mode 100644 src/Core/Domain/Order/OrderConstraints.php delete mode 100644 src/Core/Domain/Order/OrderDiscountType.php delete mode 100644 src/Core/Domain/Order/OrderDocumentType.php delete mode 100644 src/Core/Domain/Order/Payment/Command/AddPaymentCommand.php delete mode 100644 src/Core/Domain/Order/Payment/CommandHandler/AddPaymentHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Payment/Exception/PaymentException.php delete mode 100644 src/Core/Domain/Order/Payment/ValueObject/OrderPaymentId.php delete mode 100644 src/Core/Domain/Order/Product/Command/AddProductToOrderCommand.php delete mode 100644 src/Core/Domain/Order/Product/Command/DeleteProductFromOrderCommand.php delete mode 100644 src/Core/Domain/Order/Product/Command/UpdateProductInOrderCommand.php delete mode 100644 src/Core/Domain/Order/Product/CommandHandler/AddProductToOrderHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Product/CommandHandler/DeleteProductFromOrderHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Product/CommandHandler/UpdateProductInOrderHandlerInterface.php delete mode 100644 src/Core/Domain/Order/Product/Exception/ProductException.php delete mode 100644 src/Core/Domain/Order/Query/GetOrderForViewing.php delete mode 100644 src/Core/Domain/Order/Query/GetOrderPreview.php delete mode 100644 src/Core/Domain/Order/Query/GetOrderProductsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryHandler/GetOrderForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Order/QueryHandler/GetOrderPreviewHandlerInterface.php delete mode 100644 src/Core/Domain/Order/QueryHandler/GetOrderProductsForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Order/QueryResult/LinkedOrderForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/LinkedOrdersForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderCarrierForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderCustomerForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderDiscountForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderDiscountsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderDocumentForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderDocumentsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderHistoryForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderInvoiceAddressForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderMessageDateForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderMessageForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderMessagesForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPaymentForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPaymentsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPreview.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPreviewInvoiceDetails.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPreviewProductDetail.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPreviewShippingDetails.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderPricesForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderProductCustomizationForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderProductCustomizationsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderProductForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderProductsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderReturnForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderReturnsForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderShippingAddressForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderShippingForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderSourceForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderSourcesForViewing.php delete mode 100644 src/Core/Domain/Order/QueryResult/OrderStatusForViewing.php delete mode 100644 src/Core/Domain/Order/Status/OrderStatusColor.php delete mode 100644 src/Core/Domain/Order/ValueObject/OrderDetailRefund.php delete mode 100644 src/Core/Domain/Order/ValueObject/OrderId.php delete mode 100644 src/Core/Domain/Order/VoucherRefundType.php delete mode 100644 src/Core/Domain/OrderMessage/Command/AddOrderMessageCommand.php delete mode 100644 src/Core/Domain/OrderMessage/Command/BulkDeleteOrderMessageCommand.php delete mode 100644 src/Core/Domain/OrderMessage/Command/DeleteOrderMessageCommand.php delete mode 100644 src/Core/Domain/OrderMessage/Command/EditOrderMessageCommand.php delete mode 100644 src/Core/Domain/OrderMessage/CommandHandler/AddOrderMessageHandlerInterface.php delete mode 100644 src/Core/Domain/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandlerInterface.php delete mode 100644 src/Core/Domain/OrderMessage/CommandHandler/DeleteOrderMessageHandlerInterface.php delete mode 100644 src/Core/Domain/OrderMessage/CommandHandler/EditOrderMessageHandlerInterface.php delete mode 100644 src/Core/Domain/OrderMessage/Exception/OrderMessageConstraintException.php delete mode 100644 src/Core/Domain/OrderMessage/Exception/OrderMessageException.php delete mode 100644 src/Core/Domain/OrderMessage/Exception/OrderMessageNotFoundException.php delete mode 100644 src/Core/Domain/OrderMessage/OrderMessageConstraint.php delete mode 100644 src/Core/Domain/OrderMessage/Query/GetOrderMessageForEditing.php delete mode 100644 src/Core/Domain/OrderMessage/QueryHandler/GetOrderMessageForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/OrderMessage/QueryResult/EditableOrderMessage.php delete mode 100644 src/Core/Domain/OrderMessage/ValueObject/OrderMessageId.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Command/BulkDeleteAttributeCommand.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Command/DeleteAttributeCommand.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/BulkDeleteAttributeHandlerInterface.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/DeleteAttributeHandlerInterface.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeConstraintException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeNotFoundException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/Exception/DeleteAttributeException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Attribute/ValueObject/AttributeId.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Command/BulkDeleteAttributeGroupCommand.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Command/DeleteAttributeGroupCommand.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandlerInterface.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/CommandHandler/DeleteAttributeGroupHandlerInterface.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupConstraintException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupNotFoundException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/Exception/DeleteAttributeGroupException.php delete mode 100644 src/Core/Domain/Product/AttributeGroup/ValueObject/AttributeGroupId.php delete mode 100644 src/Core/Domain/Product/Combination/Exception/CombinationConstraintException.php delete mode 100644 src/Core/Domain/Product/Combination/Exception/CombinationException.php delete mode 100644 src/Core/Domain/Product/Combination/ValueObject/CombinationId.php delete mode 100644 src/Core/Domain/Product/Command/AssignProductToCategoryCommand.php delete mode 100644 src/Core/Domain/Product/Command/UpdateProductStatusCommand.php delete mode 100644 src/Core/Domain/Product/CommandHandler/AssignProductToCategoryHandlerInterface.php delete mode 100644 src/Core/Domain/Product/CommandHandler/UpdateProductStatusCommandHandlerInterface.php delete mode 100644 src/Core/Domain/Product/Customization/CustomizationSettings.php delete mode 100644 src/Core/Domain/Product/Customization/Exception/CustomizationConstraintException.php delete mode 100644 src/Core/Domain/Product/Customization/Exception/CustomizationException.php delete mode 100644 src/Core/Domain/Product/Customization/ValueObject/CustomizationId.php delete mode 100644 src/Core/Domain/Product/Exception/CannotAssignProductToCategoryException.php delete mode 100644 src/Core/Domain/Product/Exception/CannotUpdateProductException.php delete mode 100644 src/Core/Domain/Product/Exception/ProductConstraintException.php delete mode 100644 src/Core/Domain/Product/Exception/ProductCustomizationNotFoundException.php delete mode 100644 src/Core/Domain/Product/Exception/ProductException.php delete mode 100644 src/Core/Domain/Product/Exception/ProductNotFoundException.php delete mode 100644 src/Core/Domain/Product/Exception/ProductOutOfStockException.php delete mode 100644 src/Core/Domain/Product/Query/GetProductIsEnabled.php delete mode 100644 src/Core/Domain/Product/Query/SearchProducts.php delete mode 100644 src/Core/Domain/Product/QueryHandler/GetProductIsEnabledHandlerInterface.php delete mode 100644 src/Core/Domain/Product/QueryHandler/SearchProductsHandlerInterface.php delete mode 100644 src/Core/Domain/Product/QueryResult/FoundProduct.php delete mode 100644 src/Core/Domain/Product/QueryResult/ProductCombination.php delete mode 100644 src/Core/Domain/Product/QueryResult/ProductCustomizationField.php delete mode 100644 src/Core/Domain/Product/ValueObject/ProductId.php delete mode 100644 src/Core/Domain/Profile/Command/AbstractProfileCommand.php delete mode 100644 src/Core/Domain/Profile/Command/AddProfileCommand.php delete mode 100644 src/Core/Domain/Profile/Command/BulkDeleteProfileCommand.php delete mode 100644 src/Core/Domain/Profile/Command/DeleteProfileCommand.php delete mode 100644 src/Core/Domain/Profile/Command/EditProfileCommand.php delete mode 100644 src/Core/Domain/Profile/CommandHandler/AddProfileHandlerInterface.php delete mode 100644 src/Core/Domain/Profile/CommandHandler/BulkDeleteProfileHandlerInterface.php delete mode 100644 src/Core/Domain/Profile/CommandHandler/DeleteProfileHandlerInterface.php delete mode 100644 src/Core/Domain/Profile/CommandHandler/EditProfileHandlerInterface.php delete mode 100644 src/Core/Domain/Profile/Exception/CannotDeleteSuperAdminProfileException.php delete mode 100644 src/Core/Domain/Profile/Exception/FailedToDeleteProfileException.php delete mode 100644 src/Core/Domain/Profile/Exception/ProfileConstraintException.php delete mode 100644 src/Core/Domain/Profile/Exception/ProfileException.php delete mode 100644 src/Core/Domain/Profile/Exception/ProfileNotFoundException.php delete mode 100644 src/Core/Domain/Profile/ProfileSettings.php delete mode 100644 src/Core/Domain/Profile/Query/GetProfileForEditing.php delete mode 100644 src/Core/Domain/Profile/QueryHandler/GetProfileForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Profile/QueryResult/EditableProfile.php delete mode 100644 src/Core/Domain/Profile/ValueObject/ProfileId.php delete mode 100644 src/Core/Domain/Shop/Command/UploadLogosCommand.php delete mode 100644 src/Core/Domain/Shop/CommandHandler/UploadLogosHandlerInterface.php delete mode 100644 src/Core/Domain/Shop/DTO/ShopLogoSettings.php delete mode 100644 src/Core/Domain/Shop/Exception/NotSupportedFaviconExtensionException.php delete mode 100644 src/Core/Domain/Shop/Exception/NotSupportedLogoImageExtensionException.php delete mode 100644 src/Core/Domain/Shop/Exception/ShopException.php delete mode 100644 src/Core/Domain/Shop/Query/GetLogosPaths.php delete mode 100644 src/Core/Domain/Shop/QueryHandler/GetLogosPathsHandlerInterface.php delete mode 100644 src/Core/Domain/Shop/QueryResult/LogosPaths.php delete mode 100644 src/Core/Domain/Shop/ValueObject/ShopConstraint.php delete mode 100644 src/Core/Domain/Shop/ValueObject/ShopGroupId.php delete mode 100644 src/Core/Domain/Shop/ValueObject/ShopId.php delete mode 100644 src/Core/Domain/ShowcaseCard/Command/CloseShowcaseCardCommand.php delete mode 100644 src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandler.php delete mode 100644 src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandlerInterface.php delete mode 100644 src/Core/Domain/ShowcaseCard/ConfigurationMap.php delete mode 100644 src/Core/Domain/ShowcaseCard/Exception/InvalidShowcaseCardNameException.php delete mode 100644 src/Core/Domain/ShowcaseCard/Exception/ShowcaseCardException.php delete mode 100644 src/Core/Domain/ShowcaseCard/Query/GetShowcaseCardIsClosed.php delete mode 100644 src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandler.php delete mode 100644 src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandlerInterface.php delete mode 100644 src/Core/Domain/ShowcaseCard/ValueObject/ShowcaseCard.php delete mode 100644 src/Core/Domain/SpecificPrice/Command/AddSpecificPriceCommand.php delete mode 100644 src/Core/Domain/SpecificPrice/Command/DeleteSpecificPriceByCartProductCommand.php delete mode 100644 src/Core/Domain/SpecificPrice/CommandHandler/AddSpecificPriceHandlerInterface.php delete mode 100644 src/Core/Domain/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandlerInterface.php delete mode 100644 src/Core/Domain/SpecificPrice/Exception/SpecificPriceConstraintException.php delete mode 100644 src/Core/Domain/SpecificPrice/Exception/SpecificPriceException.php delete mode 100644 src/Core/Domain/SpecificPrice/Exception/SpecificPriceNotFoundException.php delete mode 100644 src/Core/Domain/SpecificPrice/ValueObject/SpecificPriceId.php delete mode 100644 src/Core/Domain/SqlManagement/Command/AddSqlRequestCommand.php delete mode 100644 src/Core/Domain/SqlManagement/Command/BulkDeleteSqlRequestCommand.php delete mode 100644 src/Core/Domain/SqlManagement/Command/DeleteSqlRequestCommand.php delete mode 100644 src/Core/Domain/SqlManagement/Command/EditSqlRequestCommand.php delete mode 100644 src/Core/Domain/SqlManagement/Command/SaveSqlRequestSettingsCommand.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/AddSqlRequestHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/BulkDeleteSqlRequestHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/DeleteSqlRequestHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/EditSqlRequestHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandler.php delete mode 100644 src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/DatabaseTableFields.php delete mode 100644 src/Core/Domain/SqlManagement/DatabaseTablesList.php delete mode 100644 src/Core/Domain/SqlManagement/EditableSqlRequest.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/CannotAddSqlRequestException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/CannotDeleteSqlRequestException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/CannotEditSqlRequestException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlManagementConstraintException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlManagementException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlRequestConstraintException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlRequestException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlRequestNotFoundException.php delete mode 100644 src/Core/Domain/SqlManagement/Exception/SqlRequestSettingsConstraintException.php delete mode 100644 src/Core/Domain/SqlManagement/Query/GetDatabaseTableFieldsList.php delete mode 100644 src/Core/Domain/SqlManagement/Query/GetDatabaseTablesList.php delete mode 100644 src/Core/Domain/SqlManagement/Query/GetSqlRequestExecutionResult.php delete mode 100644 src/Core/Domain/SqlManagement/Query/GetSqlRequestForEditing.php delete mode 100644 src/Core/Domain/SqlManagement/Query/GetSqlRequestSettings.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTableFieldsListHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTablesListHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestExecutionResultHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandler.php delete mode 100644 src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandlerInterface.php delete mode 100644 src/Core/Domain/SqlManagement/SqlRequestExecutionResult.php delete mode 100644 src/Core/Domain/SqlManagement/SqlRequestSettings.php delete mode 100644 src/Core/Domain/SqlManagement/ValueObject/DatabaseTableField.php delete mode 100644 src/Core/Domain/SqlManagement/ValueObject/SqlRequestId.php delete mode 100644 src/Core/Domain/State/Exception/StateConstraintException.php delete mode 100644 src/Core/Domain/State/Exception/StateException.php delete mode 100644 src/Core/Domain/State/ValueObject/StateId.php delete mode 100644 src/Core/Domain/Supplier/Command/AbstractBulkSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/AddSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/BulkDeleteSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/BulkDisableSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/BulkEnableSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/DeleteSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/EditSupplierCommand.php delete mode 100644 src/Core/Domain/Supplier/Command/ToggleSupplierStatusCommand.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/AddSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/BulkDeleteSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/BulkDisableSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/BulkEnableSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/DeleteSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/EditSupplierHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/CommandHandler/ToggleSupplierStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/Exception/CannotDeleteSupplierAddressException.php delete mode 100644 src/Core/Domain/Supplier/Exception/CannotDeleteSupplierException.php delete mode 100644 src/Core/Domain/Supplier/Exception/CannotDeleteSupplierProductRelationException.php delete mode 100644 src/Core/Domain/Supplier/Exception/CannotToggleSupplierStatusException.php delete mode 100644 src/Core/Domain/Supplier/Exception/CannotUpdateSupplierStatusException.php delete mode 100644 src/Core/Domain/Supplier/Exception/SupplierConstraintException.php delete mode 100644 src/Core/Domain/Supplier/Exception/SupplierException.php delete mode 100644 src/Core/Domain/Supplier/Exception/SupplierNotFoundException.php delete mode 100644 src/Core/Domain/Supplier/Query/GetSupplierForEditing.php delete mode 100644 src/Core/Domain/Supplier/Query/GetSupplierForViewing.php delete mode 100644 src/Core/Domain/Supplier/QueryHandler/GetSupplierForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/QueryHandler/GetSupplierForViewingHandlerInterface.php delete mode 100644 src/Core/Domain/Supplier/QueryResult/EditableSupplier.php delete mode 100644 src/Core/Domain/Supplier/QueryResult/ViewableSupplier.php delete mode 100644 src/Core/Domain/Supplier/SupplierSettings.php delete mode 100644 src/Core/Domain/Supplier/ValueObject/SupplierId.php delete mode 100644 src/Core/Domain/Tax/Command/AddTaxCommand.php delete mode 100644 src/Core/Domain/Tax/Command/BulkDeleteTaxCommand.php delete mode 100644 src/Core/Domain/Tax/Command/BulkToggleTaxStatusCommand.php delete mode 100644 src/Core/Domain/Tax/Command/DeleteTaxCommand.php delete mode 100644 src/Core/Domain/Tax/Command/EditTaxCommand.php delete mode 100644 src/Core/Domain/Tax/Command/ToggleTaxStatusCommand.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/AddTaxHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/BulkDeleteTaxHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/BulkToggleTaxStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/DeleteTaxHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/EditTaxHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/CommandHandler/ToggleTaxStatusHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/Exception/DeleteTaxException.php delete mode 100644 src/Core/Domain/Tax/Exception/TaxConstraintException.php delete mode 100644 src/Core/Domain/Tax/Exception/TaxException.php delete mode 100644 src/Core/Domain/Tax/Exception/TaxNotFoundException.php delete mode 100644 src/Core/Domain/Tax/Exception/UpdateTaxException.php delete mode 100644 src/Core/Domain/Tax/Query/GetTaxForEditing.php delete mode 100644 src/Core/Domain/Tax/QueryHandler/GetTaxForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Tax/QueryResult/EditableTax.php delete mode 100644 src/Core/Domain/Tax/ValueObject/TaxId.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Command/BulkDeleteTaxRulesGroupCommand.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Command/BulkSetTaxRulesGroupStatusCommand.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Command/DeleteTaxRulesGroupCommand.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Command/SetTaxRulesGroupStatusCommand.php delete mode 100644 src/Core/Domain/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandlerInterface.php delete mode 100644 src/Core/Domain/TaxRulesGroup/CommandHandler/BulkToggleTaxRulesGroupStatusHandlerInterface.php delete mode 100644 src/Core/Domain/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandlerInterface.php delete mode 100644 src/Core/Domain/TaxRulesGroup/CommandHandler/ToggleTaxRulesGroupStatusHandlerInterface.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/CannotBulkDeleteTaxRulesGroupException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/CannotBulkUpdateTaxRulesGroupException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/CannotDeleteTaxRulesGroupException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/CannotUpdateTaxRulesGroupException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupConstraintException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupNotFoundException.php delete mode 100644 src/Core/Domain/TaxRulesGroup/Query/GetTaxRulesGroupForEditing.php delete mode 100644 src/Core/Domain/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/TaxRulesGroup/QueryResult/EditableTaxRulesGroup.php delete mode 100644 src/Core/Domain/TaxRulesGroup/ValueObject/TaxRulesGroupId.php delete mode 100644 src/Core/Domain/Theme/Command/AdaptThemeToRTLLanguagesCommand.php delete mode 100644 src/Core/Domain/Theme/Command/DeleteThemeCommand.php delete mode 100644 src/Core/Domain/Theme/Command/EnableThemeCommand.php delete mode 100644 src/Core/Domain/Theme/Command/ImportThemeCommand.php delete mode 100644 src/Core/Domain/Theme/Command/ResetThemeLayoutsCommand.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandler.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandlerInterface.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/DeleteThemeHandler.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/DeleteThemeHandlerInterface.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/EnableThemeHandler.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/EnableThemeHandlerInterface.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/ImportThemeHandler.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/ImportThemeHandlerInterface.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandler.php delete mode 100644 src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandlerInterface.php delete mode 100644 src/Core/Domain/Theme/Exception/CannotAdaptThemeToRTLLanguagesException.php delete mode 100644 src/Core/Domain/Theme/Exception/CannotDeleteThemeException.php delete mode 100644 src/Core/Domain/Theme/Exception/CannotEnableThemeException.php delete mode 100644 src/Core/Domain/Theme/Exception/CannotResetThemeLayoutsException.php delete mode 100644 src/Core/Domain/Theme/Exception/FailedToEnableThemeModuleException.php delete mode 100644 src/Core/Domain/Theme/Exception/ImportedThemeAlreadyExistsException.php delete mode 100644 src/Core/Domain/Theme/Exception/InvalidThemeNameException.php delete mode 100644 src/Core/Domain/Theme/Exception/NotSupportedThemeImportSourceException.php delete mode 100644 src/Core/Domain/Theme/Exception/ThemeConstraintException.php delete mode 100644 src/Core/Domain/Theme/Exception/ThemeException.php delete mode 100644 src/Core/Domain/Theme/ValueObject/ThemeImportSource.php delete mode 100644 src/Core/Domain/Theme/ValueObject/ThemeName.php delete mode 100644 src/Core/Domain/ValueObject/Email.php delete mode 100644 src/Core/Domain/ValueObject/Money.php delete mode 100644 src/Core/Domain/ValueObject/QuerySorting.php delete mode 100644 src/Core/Domain/ValueObject/Reduction.php delete mode 100644 src/Core/Domain/Webservice/Command/AddWebserviceKeyCommand.php delete mode 100644 src/Core/Domain/Webservice/Command/EditWebserviceKeyCommand.php delete mode 100644 src/Core/Domain/Webservice/CommandHandler/AddWebserviceKeyHandlerInterface.php delete mode 100644 src/Core/Domain/Webservice/CommandHandler/EditWebserviceKeyHandlerInterface.php delete mode 100644 src/Core/Domain/Webservice/Exception/DuplicateWebserviceKeyException.php delete mode 100644 src/Core/Domain/Webservice/Exception/WebserviceConstraintException.php delete mode 100644 src/Core/Domain/Webservice/Exception/WebserviceException.php delete mode 100644 src/Core/Domain/Webservice/Exception/WebserviceKeyNotFoundException.php delete mode 100644 src/Core/Domain/Webservice/Query/GetWebserviceKeyForEditing.php delete mode 100644 src/Core/Domain/Webservice/QueryHandler/GetWebserviceKeyForEditingHandlerInterface.php delete mode 100644 src/Core/Domain/Webservice/QueryResult/EditableWebserviceKey.php delete mode 100644 src/Core/Domain/Webservice/ValueObject/Key.php delete mode 100644 src/Core/Domain/Webservice/ValueObject/Permission.php delete mode 100644 src/Core/Domain/Webservice/ValueObject/WebserviceKeyId.php delete mode 100644 src/Core/Email/EmailConfigurationTesterInterface.php delete mode 100644 src/Core/Email/EmailDataConfigurator.php delete mode 100644 src/Core/Email/EmailLister.php delete mode 100644 src/Core/Email/EmailLogEraserInterface.php delete mode 100644 src/Core/Email/MailOption.php delete mode 100644 src/Core/Email/SmtpDataConfigurator.php delete mode 100644 src/Core/Email/SwiftMailerValidation.php delete mode 100644 src/Core/Employee/Access/EmployeeFormAccessCheckerInterface.php delete mode 100644 src/Core/Employee/Access/ProfileAccessChecker.php delete mode 100644 src/Core/Employee/Access/ProfileAccessCheckerInterface.php delete mode 100644 src/Core/Employee/AvatarProviderInterface.php delete mode 100644 src/Core/Employee/ContextEmployeeProviderInterface.php delete mode 100644 src/Core/Employee/EmployeeDataProviderInterface.php delete mode 100644 src/Core/Employee/FormLanguageChangerInterface.php delete mode 100644 src/Core/Employee/NavigationMenuTogglerInterface.php delete mode 100644 src/Core/Encoding/CharsetEncoding.php delete mode 100644 src/Core/EnvironmentInterface.php delete mode 100644 src/Core/Exception/ContainerNotFoundException.php delete mode 100644 src/Core/Exception/CoreException.php delete mode 100644 src/Core/Exception/DatabaseException.php delete mode 100644 src/Core/Exception/FileNotFoundException.php delete mode 100644 src/Core/Exception/IOException.php delete mode 100644 src/Core/Exception/InvalidArgumentException.php delete mode 100644 src/Core/Exception/NonASCIIInLocalPartException.php delete mode 100644 src/Core/Exception/ProductException.php delete mode 100644 src/Core/Exception/TranslatableCoreException.php delete mode 100644 src/Core/Exception/TranslatedException.php delete mode 100644 src/Core/Exception/TypeException.php delete mode 100644 src/Core/Export/Data/ExportableData.php delete mode 100644 src/Core/Export/Data/ExportableDataInterface.php delete mode 100644 src/Core/Export/Exception/ExportException.php delete mode 100644 src/Core/Export/Exception/FileWritingException.php delete mode 100644 src/Core/Export/ExportDirectory.php delete mode 100644 src/Core/Export/FileWriter/ExportCsvFileWriter.php delete mode 100644 src/Core/Export/FileWriter/FileWriterInterface.php delete mode 100644 src/Core/Feature/FeatureInterface.php delete mode 100644 src/Core/Feature/TokenInUrls.php delete mode 100644 src/Core/File/Converter/FileConverterInterface.php delete mode 100644 src/Core/File/FileFinderInterface.php delete mode 100644 src/Core/File/InvoiceModelFinder.php delete mode 100644 src/Core/Filter/CollectionFilter.php delete mode 100644 src/Core/Filter/FilterException.php delete mode 100644 src/Core/Filter/FilterInterface.php delete mode 100644 src/Core/Filter/FrontEndObject/CartFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/ConfigurationFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/CustomerFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/EmbeddedAttributesFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/MainFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/ProductFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/SearchResultProductFilter.php delete mode 100644 src/Core/Filter/FrontEndObject/ShopFilter.php delete mode 100644 src/Core/Filter/HashMapWhitelistFilter.php delete mode 100644 src/Core/Form/ChoiceProvider/AddressRequiredFieldsChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CanonicalRedirectTypeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CarrierByReferenceChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CategoryDeleteModeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CmsCategoriesChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ContactByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CountryByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CountryByIsoCodeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CurrencyByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CurrencyNameByIsoCodeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CustomerAddressesChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CustomerDeleteMethodChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CustomerRequiredFieldsChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/DefaultMetaPageNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/EmailContentTypeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/GroupByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ImportEntityFieldChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ImportMatchConfigurationChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/InvoiceModelByNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/LanguageByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/LanguageChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/LocalizationPackByIsoCodeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/MailMethodChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/MailThemeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ModuleByNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ModuleMetaPageNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/NonInstalledLocalizationChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/OrderDiscountTypeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/OrderStateByIdChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/PermissionsChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/PriceReductionTypeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ProfileChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/StatusChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/TabChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/TaxAddressTypeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/TaxInclusionChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ThemeByNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ThemeByNameWithEmailsChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ThemeChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ThemePageLayoutsChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/ThemeZipChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/TimezoneByNameChoiceProvider.php delete mode 100644 src/Core/Form/ChoiceProvider/TranslationTypeChoiceProvider.php delete mode 100644 src/Core/Form/ConfigurableFormChoiceProviderInterface.php delete mode 100644 src/Core/Form/DTO/ShopRestriction.php delete mode 100644 src/Core/Form/DTO/ShopRestrictionField.php delete mode 100644 src/Core/Form/FormChoiceAttributeProviderInterface.php delete mode 100644 src/Core/Form/FormChoiceProviderInterface.php delete mode 100644 src/Core/Form/FormDataProviderInterface.php delete mode 100644 src/Core/Form/FormHandler.php delete mode 100644 src/Core/Form/FormHandlerInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/Builder/FormBuilder.php delete mode 100644 src/Core/Form/IdentifiableObject/Builder/FormBuilderFactory.php delete mode 100644 src/Core/Form/IdentifiableObject/Builder/FormBuilderFactoryInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/Builder/FormBuilderInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/AddressFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/AttachmentFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CancellationFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CartAddressFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CatalogPriceRuleFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CategoryFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CmsPageCategoryFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CmsPageFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/ContactFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CurrencyFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/CustomerFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/EmployeeFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/FeatureFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/FormDataHandlerInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/LanguageFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/ManufacturerAddressFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/ManufacturerFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/MetaFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/OrderAddressFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/OrderMessageFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/PartialRefundFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/ProfileFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/ReturnProductFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/RootCategoryFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/SqlRequestFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/StandardRefundFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/SupplierFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/TaxFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataHandler/WebserviceKeyFormDataHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/AddressFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/AttachmentFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CancelProductFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CatalogPriceRuleFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CategoryFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CmsPageCategoryFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CmsPageFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/ContactFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CurrencyFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/CustomerFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/EmployeeFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/FeatureFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/FormDataProviderInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/ManufacturerAddressFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/ManufacturerFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/MetaFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/OrderMessageFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/ProfileFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/SqlRequestFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/SupplierFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/TaxFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/DataProvider/WebserviceKeyFormDataProvider.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandler.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandlerFactory.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandlerFactoryInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandlerInterface.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandlerResult.php delete mode 100644 src/Core/Form/IdentifiableObject/Handler/FormHandlerResultInterface.php delete mode 100644 src/Core/Form/MultiStoreSettingsFormDataProviderInterface.php delete mode 100644 src/Core/Foundation/Database/DatabaseInterface.php delete mode 100644 src/Core/Foundation/Database/EntityDataInconsistencyException.php delete mode 100644 src/Core/Foundation/Database/EntityInterface.php delete mode 100644 src/Core/Foundation/Database/EntityManager.php delete mode 100644 src/Core/Foundation/Database/EntityManager/QueryBuilder.php delete mode 100644 src/Core/Foundation/Database/EntityMetaData.php delete mode 100644 src/Core/Foundation/Database/EntityNotFoundException.php delete mode 100644 src/Core/Foundation/Database/EntityRepository.php delete mode 100644 src/Core/Foundation/Database/Exception.php delete mode 100644 src/Core/Foundation/Exception/InvalidVersionException.php delete mode 100644 src/Core/Foundation/Filesystem/Exception.php delete mode 100644 src/Core/Foundation/Filesystem/FileSystem.php delete mode 100644 src/Core/Foundation/IoC/Container.php delete mode 100644 src/Core/Foundation/IoC/Exception.php delete mode 100644 src/Core/Foundation/Templating/PresenterInterface.php delete mode 100644 src/Core/Foundation/Templating/RenderableInterface.php delete mode 100644 src/Core/Foundation/Templating/RenderableProxy.php delete mode 100644 src/Core/Foundation/Version.php delete mode 100644 src/Core/Geolocation/GeoLite/GeoLiteCityChecker.php delete mode 100644 src/Core/Geolocation/GeoLite/GeoLiteCityCheckerInterface.php delete mode 100644 src/Core/Grid/Action/AbstractGridAction.php delete mode 100644 src/Core/Grid/Action/Bulk/AbstractBulkAction.php delete mode 100644 src/Core/Grid/Action/Bulk/BulkActionCollection.php delete mode 100644 src/Core/Grid/Action/Bulk/BulkActionCollectionInterface.php delete mode 100644 src/Core/Grid/Action/Bulk/BulkActionInterface.php delete mode 100644 src/Core/Grid/Action/Bulk/Type/ButtonBulkAction.php delete mode 100644 src/Core/Grid/Action/Bulk/Type/Catalog/Category/DeleteCategoriesBulkAction.php delete mode 100644 src/Core/Grid/Action/Bulk/Type/Customer/DeleteCustomersBulkAction.php delete mode 100644 src/Core/Grid/Action/Bulk/Type/ModalFormSubmitBulkAction.php delete mode 100644 src/Core/Grid/Action/Bulk/Type/SubmitBulkAction.php delete mode 100644 src/Core/Grid/Action/GridActionCollection.php delete mode 100644 src/Core/Grid/Action/GridActionCollectionInterface.php delete mode 100644 src/Core/Grid/Action/GridActionInterface.php delete mode 100644 src/Core/Grid/Action/ModalOptions.php delete mode 100644 src/Core/Grid/Action/Row/AbstractRowAction.php delete mode 100644 src/Core/Grid/Action/Row/AccessibilityChecker/AccessibilityCheckerInterface.php delete mode 100644 src/Core/Grid/Action/Row/AccessibilityChecker/DeleteProfileAccessibilityChecker.php delete mode 100644 src/Core/Grid/Action/Row/AccessibilityChecker/PrintDeliverySlipAccessibilityChecker.php delete mode 100644 src/Core/Grid/Action/Row/AccessibilityChecker/PrintInvoiceAccessibilityChecker.php delete mode 100644 src/Core/Grid/Action/Row/RowActionCollection.php delete mode 100644 src/Core/Grid/Action/Row/RowActionCollectionInterface.php delete mode 100644 src/Core/Grid/Action/Row/RowActionInterface.php delete mode 100644 src/Core/Grid/Action/Row/Type/Category/DeleteCategoryRowAction.php delete mode 100644 src/Core/Grid/Action/Row/Type/Customer/DeleteCustomerRowAction.php delete mode 100644 src/Core/Grid/Action/Row/Type/LinkRowAction.php delete mode 100644 src/Core/Grid/Action/Row/Type/SubmitRowAction.php delete mode 100644 src/Core/Grid/Action/Type/LinkGridAction.php delete mode 100644 src/Core/Grid/Action/Type/SimpleGridAction.php delete mode 100644 src/Core/Grid/Action/Type/SubmitGridAction.php delete mode 100644 src/Core/Grid/Collection/AbstractCollection.php delete mode 100644 src/Core/Grid/Column/AbstractColumn.php delete mode 100644 src/Core/Grid/Column/ColumnCollection.php delete mode 100644 src/Core/Grid/Column/ColumnCollectionInterface.php delete mode 100644 src/Core/Grid/Column/ColumnInterface.php delete mode 100644 src/Core/Grid/Column/Type/Attribute/AttributeColorColumn.php delete mode 100644 src/Core/Grid/Column/Type/BooleanColumn.php delete mode 100644 src/Core/Grid/Column/Type/Category/CategoryPositionColumn.php delete mode 100644 src/Core/Grid/Column/Type/ColorColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/ActionColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/BadgeColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/BulkActionColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/ChoiceColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/DateTimeColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/DraggableColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/IdentifierColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/ImageColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/LinkColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/PositionColumn.php delete mode 100644 src/Core/Grid/Column/Type/Common/ToggleColumn.php delete mode 100644 src/Core/Grid/Column/Type/DataColumn.php delete mode 100644 src/Core/Grid/Column/Type/DisableableLinkColumn.php delete mode 100644 src/Core/Grid/Column/Type/Employee/EmployeeNameWithAvatarColumn.php delete mode 100644 src/Core/Grid/Column/Type/LinkGroupColumn.php delete mode 100644 src/Core/Grid/Column/Type/OrderPriceColumn.php delete mode 100644 src/Core/Grid/Column/Type/PreviewColumn.php delete mode 100644 src/Core/Grid/Column/Type/Status/SeverityLevelColumn.php delete mode 100644 src/Core/Grid/Data/Factory/AttachmentGridDataFactoryDecorator.php delete mode 100644 src/Core/Grid/Data/Factory/AttributeGroupGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/CatalogPriceRuleGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/CategoryDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/CreditSlipGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/CustomerGridDataFactoryDecorator.php delete mode 100644 src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/EmptyCategoryGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/GridDataFactoryInterface.php delete mode 100644 src/Core/Grid/Data/Factory/LanguageGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/ManufacturerAddressGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/ManufacturerGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/OrderGridDataFactory.php delete mode 100644 src/Core/Grid/Data/Factory/SupplierGridDataFactory.php delete mode 100644 src/Core/Grid/Data/GridData.php delete mode 100644 src/Core/Grid/Data/GridDataInterface.php delete mode 100644 src/Core/Grid/Definition/Factory/AbstractFilterableGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/AddressGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/AttachmentGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/AttributeGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/AttributeGroupGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/BackupDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/BulkDeleteActionTrait.php delete mode 100644 src/Core/Grid/Definition/Factory/CatalogPriceRuleGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CategoryGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CmsPageCategoryDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CmsPageDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/ContactGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CreditSlipGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CurrencyGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/CustomerGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/EmailLogsDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/EmployeeGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/FilterableGridDefinitionFactoryInterface.php delete mode 100644 src/Core/Grid/Definition/Factory/GridDefinitionFactoryInterface.php delete mode 100644 src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/LogGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/ManufacturerAddressGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/ManufacturerGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/MerchandiseReturnGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/MetaGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/AbstractProductGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/DisabledProductGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/EmptyCategoryGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithCombinationGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithoutCombinationGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutDescriptionGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutImageGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutPriceGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/OrderGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/OrderMessageGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/ProfileGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/RequestSqlGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/SupplierGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/TaxGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/TaxRulesGroupGridDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/Factory/WebserviceKeyDefinitionFactory.php delete mode 100644 src/Core/Grid/Definition/GridDefinition.php delete mode 100644 src/Core/Grid/Definition/GridDefinitionInterface.php delete mode 100644 src/Core/Grid/Exception/ColumnNotFoundException.php delete mode 100644 src/Core/Grid/Exception/ExceptionInterface.php delete mode 100644 src/Core/Grid/Exception/InvalidActionDataException.php delete mode 100644 src/Core/Grid/Exception/InvalidColumnDataException.php delete mode 100644 src/Core/Grid/Exception/InvalidDataException.php delete mode 100644 src/Core/Grid/Exception/MissingColumnInRowException.php delete mode 100644 src/Core/Grid/Exception/UnsupportedParameterException.php delete mode 100644 src/Core/Grid/Factory/CategoryGridFactoryDecorator.php delete mode 100644 src/Core/Grid/Filter/CategoryFilterFormFactory.php delete mode 100644 src/Core/Grid/Filter/CmsPageFilterFormFactory.php delete mode 100644 src/Core/Grid/Filter/Filter.php delete mode 100644 src/Core/Grid/Filter/FilterCollection.php delete mode 100644 src/Core/Grid/Filter/FilterCollectionInterface.php delete mode 100644 src/Core/Grid/Filter/FilterFormFactoryFormActionDecorator.php delete mode 100644 src/Core/Grid/Filter/FilterInterface.php delete mode 100644 src/Core/Grid/Filter/GridFilterFormFactory.php delete mode 100644 src/Core/Grid/Filter/GridFilterFormFactoryInterface.php delete mode 100644 src/Core/Grid/Grid.php delete mode 100644 src/Core/Grid/GridFactory.php delete mode 100644 src/Core/Grid/GridFactoryInterface.php delete mode 100644 src/Core/Grid/GridInterface.php delete mode 100644 src/Core/Grid/Position/Exception/PositionDataException.php delete mode 100644 src/Core/Grid/Position/Exception/PositionException.php delete mode 100644 src/Core/Grid/Position/Exception/PositionUpdateException.php delete mode 100644 src/Core/Grid/Position/GridPositionUpdater.php delete mode 100644 src/Core/Grid/Position/GridPositionUpdaterInterface.php delete mode 100644 src/Core/Grid/Position/PositionDefinition.php delete mode 100644 src/Core/Grid/Position/PositionDefinitionInterface.php delete mode 100644 src/Core/Grid/Position/PositionModification.php delete mode 100644 src/Core/Grid/Position/PositionModificationCollection.php delete mode 100644 src/Core/Grid/Position/PositionModificationCollectionInterface.php delete mode 100644 src/Core/Grid/Position/PositionModificationInterface.php delete mode 100644 src/Core/Grid/Position/PositionUpdate.php delete mode 100644 src/Core/Grid/Position/PositionUpdateFactory.php delete mode 100644 src/Core/Grid/Position/PositionUpdateFactoryInterface.php delete mode 100644 src/Core/Grid/Position/PositionUpdateInterface.php delete mode 100644 src/Core/Grid/Position/UpdateHandler/DoctrinePositionUpdateHandler.php delete mode 100644 src/Core/Grid/Position/UpdateHandler/PositionUpdateHandlerInterface.php delete mode 100644 src/Core/Grid/Presenter/GridPresenter.php delete mode 100644 src/Core/Grid/Presenter/GridPresenterInterface.php delete mode 100644 src/Core/Grid/Query/AbstractDoctrineQueryBuilder.php delete mode 100644 src/Core/Grid/Query/AddressQueryBuilder.php delete mode 100644 src/Core/Grid/Query/AttachmentQueryBuilder.php delete mode 100644 src/Core/Grid/Query/AttributeGroupQueryBuilder.php delete mode 100644 src/Core/Grid/Query/AttributeQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CatalogPriceRuleQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CategoryQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CmsPageCategoryQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CmsPageQueryBuilder.php delete mode 100644 src/Core/Grid/Query/ContactQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CreditSlipQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CurrencyQueryBuilder.php delete mode 100644 src/Core/Grid/Query/CustomerQueryBuilder.php delete mode 100644 src/Core/Grid/Query/DoctrineQueryBuilderInterface.php delete mode 100644 src/Core/Grid/Query/DoctrineQueryParser.php delete mode 100644 src/Core/Grid/Query/DoctrineSearchCriteriaApplicator.php delete mode 100644 src/Core/Grid/Query/DoctrineSearchCriteriaApplicatorInterface.php delete mode 100644 src/Core/Grid/Query/EmailLogsQueryBuilder.php delete mode 100644 src/Core/Grid/Query/EmployeeQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Filter/DoctrineFilterApplicator.php delete mode 100644 src/Core/Grid/Query/Filter/DoctrineFilterApplicatorInterface.php delete mode 100644 src/Core/Grid/Query/Filter/SqlFilters.php delete mode 100644 src/Core/Grid/Query/LanguageQueryBuilder.php delete mode 100644 src/Core/Grid/Query/ManufacturerAddressQueryBuilder.php delete mode 100644 src/Core/Grid/Query/ManufacturerQueryBuilder.php delete mode 100644 src/Core/Grid/Query/MerchandiseReturnQueryBuilder.php delete mode 100644 src/Core/Grid/Query/MetaQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/AbstractProductQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/DisabledProductQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/EmptyCategoryQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/NoQtyProductWithCombinationQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/NoQtyProductWithoutCombinationQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/ProductWithoutDescriptionQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/ProductWithoutImageQueryBuilder.php delete mode 100644 src/Core/Grid/Query/Monitoring/ProductWithoutPriceQueryBuilder.php delete mode 100644 src/Core/Grid/Query/OrderMessageQueryBuilder.php delete mode 100644 src/Core/Grid/Query/OrderQueryBuilder.php delete mode 100644 src/Core/Grid/Query/ProfileQueryBuilder.php delete mode 100644 src/Core/Grid/Query/QueryParserInterface.php delete mode 100644 src/Core/Grid/Query/SupplierQueryBuilder.php delete mode 100644 src/Core/Grid/Query/TaxQueryBuilder.php delete mode 100644 src/Core/Grid/Query/TaxRulesGroupQueryBuilder.php delete mode 100644 src/Core/Grid/Query/WebserviceKeyQueryBuilder.php delete mode 100644 src/Core/Grid/Record/RecordCollection.php delete mode 100644 src/Core/Grid/Record/RecordCollectionInterface.php delete mode 100644 src/Core/Grid/Search/Factory/DecoratedSearchCriteriaFactory.php delete mode 100644 src/Core/Grid/Search/SearchCriteria.php delete mode 100644 src/Core/Grid/Search/SearchCriteriaInterface.php delete mode 100644 src/Core/Group/Provider/DefaultGroup.php delete mode 100644 src/Core/Group/Provider/DefaultGroups.php delete mode 100644 src/Core/Group/Provider/DefaultGroupsProviderInterface.php delete mode 100644 src/Core/Hook/Generator/HookDescriptionGenerator.php delete mode 100644 src/Core/Hook/Generator/HookDescriptionGeneratorInterface.php delete mode 100644 src/Core/Hook/Hook.php delete mode 100644 src/Core/Hook/HookDescription.php delete mode 100644 src/Core/Hook/HookDispatcher.php delete mode 100644 src/Core/Hook/HookDispatcherAwareTrait.php delete mode 100644 src/Core/Hook/HookDispatcherInterface.php delete mode 100644 src/Core/Hook/HookInterface.php delete mode 100644 src/Core/Hook/Provider/GridDefinitionHookByServiceIdsProvider.php delete mode 100644 src/Core/Hook/Provider/HookByFormTypeProviderInterface.php delete mode 100644 src/Core/Hook/Provider/HookByServiceIdsProviderInterface.php delete mode 100644 src/Core/Hook/Provider/IdentifiableObjectHookByFormTypeProvider.php delete mode 100644 src/Core/Hook/RenderedHook.php delete mode 100644 src/Core/Hook/RenderedHookInterface.php delete mode 100644 src/Core/Image/Deleter/ImageFileDeleter.php delete mode 100644 src/Core/Image/Deleter/ImageFileDeleterInterface.php delete mode 100644 src/Core/Image/ImageProviderInterface.php delete mode 100644 src/Core/Image/ImageTypeRepository.php delete mode 100644 src/Core/Image/Parser/ImageTagSourceParser.php delete mode 100644 src/Core/Image/Parser/ImageTagSourceParserInterface.php delete mode 100644 src/Core/Image/Uploader/Exception/ImageOptimizationException.php delete mode 100644 src/Core/Image/Uploader/Exception/ImageUploadException.php delete mode 100644 src/Core/Image/Uploader/Exception/MemoryLimitException.php delete mode 100644 src/Core/Image/Uploader/Exception/UploadedImageConstraintException.php delete mode 100644 src/Core/Image/Uploader/ImageUploaderInterface.php delete mode 100644 src/Core/Import/Access/ImportAccessChecker.php delete mode 100644 src/Core/Import/Access/ImportAccessCheckerInterface.php delete mode 100644 src/Core/Import/Configuration/ImportConfig.php delete mode 100644 src/Core/Import/Configuration/ImportConfigFactory.php delete mode 100644 src/Core/Import/Configuration/ImportConfigFactoryInterface.php delete mode 100644 src/Core/Import/Configuration/ImportConfigInterface.php delete mode 100644 src/Core/Import/Configuration/ImportRuntimeConfig.php delete mode 100644 src/Core/Import/Configuration/ImportRuntimeConfigFactory.php delete mode 100644 src/Core/Import/Configuration/ImportRuntimeConfigFactoryInterface.php delete mode 100644 src/Core/Import/Configuration/ImportRuntimeConfigInterface.php delete mode 100644 src/Core/Import/CsvValueSeparatorNormalizer.php delete mode 100644 src/Core/Import/Entity.php delete mode 100644 src/Core/Import/Entity/ImportEntityDeleterInterface.php delete mode 100644 src/Core/Import/EntityField/EntityField.php delete mode 100644 src/Core/Import/EntityField/EntityFieldCollection.php delete mode 100644 src/Core/Import/EntityField/EntityFieldCollectionInterface.php delete mode 100644 src/Core/Import/EntityField/EntityFieldInterface.php delete mode 100644 src/Core/Import/EntityField/Provider/AddressFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/AliasFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/CategoryFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/CombinationFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/CustomerFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/EntityFieldsProviderFinder.php delete mode 100644 src/Core/Import/EntityField/Provider/EntityFieldsProviderFinderInterface.php delete mode 100644 src/Core/Import/EntityField/Provider/EntityFieldsProviderInterface.php delete mode 100644 src/Core/Import/EntityField/Provider/ProductFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/StoreContactFieldsProvider.php delete mode 100644 src/Core/Import/EntityField/Provider/SupplierFieldsProvider.php delete mode 100644 src/Core/Import/Exception/EmptyDataRowException.php delete mode 100644 src/Core/Import/Exception/ImportException.php delete mode 100644 src/Core/Import/Exception/InvalidDataRowException.php delete mode 100644 src/Core/Import/Exception/NotSupportedImportEntityException.php delete mode 100644 src/Core/Import/Exception/NotSupportedImportTypeException.php delete mode 100644 src/Core/Import/Exception/SkippedIterationException.php delete mode 100644 src/Core/Import/Exception/UnavailableImportFileException.php delete mode 100644 src/Core/Import/Exception/UnreadableFileException.php delete mode 100644 src/Core/Import/File/CsvFileReader.php delete mode 100644 src/Core/Import/File/DataCell/DataCell.php delete mode 100644 src/Core/Import/File/DataCell/DataCellInterface.php delete mode 100644 src/Core/Import/File/DataCell/EmptyDataCell.php delete mode 100644 src/Core/Import/File/DataRow/DataRow.php delete mode 100644 src/Core/Import/File/DataRow/DataRowCollection.php delete mode 100644 src/Core/Import/File/DataRow/DataRowCollectionInterface.php delete mode 100644 src/Core/Import/File/DataRow/DataRowCollectionPresenter.php delete mode 100644 src/Core/Import/File/DataRow/DataRowCollectionPresenterInterface.php delete mode 100644 src/Core/Import/File/DataRow/DataRowInterface.php delete mode 100644 src/Core/Import/File/DataRow/DataRowPresenter.php delete mode 100644 src/Core/Import/File/DataRow/DataRowPresenterInterface.php delete mode 100644 src/Core/Import/File/DataRow/Factory/DataRowCollectionFactory.php delete mode 100644 src/Core/Import/File/DataRow/Factory/DataRowCollectionFactoryInterface.php delete mode 100644 src/Core/Import/File/FileFinder.php delete mode 100644 src/Core/Import/File/FileOpenerInterface.php delete mode 100644 src/Core/Import/File/FileReaderInterface.php delete mode 100644 src/Core/Import/File/FileRemoval.php delete mode 100644 src/Core/Import/File/FileUploader.php delete mode 100644 src/Core/Import/Handler/ImportHandlerFinderInterface.php delete mode 100644 src/Core/Import/Handler/ImportHandlerInterface.php delete mode 100644 src/Core/Import/ImportDirectory.php delete mode 100644 src/Core/Import/ImportSettings.php delete mode 100644 src/Core/Import/Importer.php delete mode 100644 src/Core/Import/ImporterInterface.php delete mode 100644 src/Core/Import/Sample/SampleFileProvider.php delete mode 100644 src/Core/Import/Sample/SampleFileProviderInterface.php delete mode 100644 src/Core/Import/StringNormalizerInterface.php delete mode 100644 src/Core/Import/Validator/ImportRequestValidator.php delete mode 100644 src/Core/Import/Validator/ImportRequestValidatorInterface.php delete mode 100644 src/Core/Kpi/Exception/InvalidArgumentException.php delete mode 100644 src/Core/Kpi/KpiInterface.php delete mode 100644 src/Core/Kpi/RenderableKpi.php delete mode 100644 src/Core/Kpi/Row/HookableKpiRowFactory.php delete mode 100644 src/Core/Kpi/Row/KpiRow.php delete mode 100644 src/Core/Kpi/Row/KpiRowFactory.php delete mode 100644 src/Core/Kpi/Row/KpiRowFactoryInterface.php delete mode 100644 src/Core/Kpi/Row/KpiRowInterface.php delete mode 100644 src/Core/Kpi/Row/KpiRowPresenter.php delete mode 100644 src/Core/Kpi/Row/KpiRowPresenterInterface.php delete mode 100644 src/Core/Language/Copier/LanguageCopierConfig.php delete mode 100644 src/Core/Language/Copier/LanguageCopierConfigInterface.php delete mode 100644 src/Core/Language/Copier/LanguageCopierInterface.php delete mode 100644 src/Core/Language/LanguageActivatorInterface.php delete mode 100644 src/Core/Language/LanguageDefaultFontsCatalog.php delete mode 100644 src/Core/Language/LanguageInterface.php delete mode 100644 src/Core/Language/LanguageRepositoryInterface.php delete mode 100644 src/Core/Language/LanguageValidatorInterface.php delete mode 100644 src/Core/Language/Pack/Import/LanguagePackImporterInterface.php delete mode 100644 src/Core/Language/Pack/LanguagePackInstallerInterface.php delete mode 100644 src/Core/Language/Pack/Loader/LanguagePackLoaderInterface.php delete mode 100644 src/Core/Language/Pack/Loader/RemoteLanguagePackLoader.php delete mode 100644 src/Core/Language/RTL/InstalledLanguageCheckerInterface.php delete mode 100644 src/Core/Localization/CLDR/ComputingPrecision.php delete mode 100644 src/Core/Localization/CLDR/ComputingPrecisionInterface.php delete mode 100644 src/Core/Localization/CLDR/Currency.php delete mode 100644 src/Core/Localization/CLDR/CurrencyData.php delete mode 100644 src/Core/Localization/CLDR/CurrencyDataLayerInterface.php delete mode 100644 src/Core/Localization/CLDR/CurrencyInterface.php delete mode 100644 src/Core/Localization/CLDR/DataLayer/CurrencyCache.php delete mode 100644 src/Core/Localization/CLDR/DataLayer/LocaleCache.php delete mode 100644 src/Core/Localization/CLDR/DataLayer/LocaleReference.php delete mode 100644 src/Core/Localization/CLDR/Locale.php delete mode 100644 src/Core/Localization/CLDR/LocaleData.php delete mode 100644 src/Core/Localization/CLDR/LocaleDataLayerInterface.php delete mode 100644 src/Core/Localization/CLDR/LocaleDataSource.php delete mode 100644 src/Core/Localization/CLDR/LocaleInterface.php delete mode 100644 src/Core/Localization/CLDR/LocaleRepository.php delete mode 100644 src/Core/Localization/CLDR/NumberSymbolsData.php delete mode 100644 src/Core/Localization/CLDR/Reader.php delete mode 100644 src/Core/Localization/CLDR/ReaderInterface.php delete mode 100644 src/Core/Localization/Currency.php delete mode 100644 src/Core/Localization/Currency/CurrencyCollection.php delete mode 100644 src/Core/Localization/Currency/CurrencyData.php delete mode 100644 src/Core/Localization/Currency/CurrencyDataLayerInterface.php delete mode 100644 src/Core/Localization/Currency/CurrencyDataSource.php delete mode 100644 src/Core/Localization/Currency/DataLayer/CurrencyCache.php delete mode 100644 src/Core/Localization/Currency/DataLayer/CurrencyDatabase.php delete mode 100644 src/Core/Localization/Currency/DataLayer/CurrencyInstalled.php delete mode 100644 src/Core/Localization/Currency/DataLayer/CurrencyReference.php delete mode 100644 src/Core/Localization/Currency/DataSourceInterface.php delete mode 100644 src/Core/Localization/Currency/LocalizedCurrencyId.php delete mode 100644 src/Core/Localization/Currency/PatternTransformer.php delete mode 100644 src/Core/Localization/Currency/Repository.php delete mode 100644 src/Core/Localization/Currency/RepositoryInterface.php delete mode 100644 src/Core/Localization/CurrencyInterface.php delete mode 100644 src/Core/Localization/Exception/LocalizationException.php delete mode 100644 src/Core/Localization/Exception/LocalizationFileNotFoundException.php delete mode 100644 src/Core/Localization/Locale.php delete mode 100644 src/Core/Localization/Locale/Repository.php delete mode 100644 src/Core/Localization/Locale/RepositoryInterface.php delete mode 100644 src/Core/Localization/LocaleInterface.php delete mode 100644 src/Core/Localization/Number/Formatter.php delete mode 100644 src/Core/Localization/Pack/Factory/LocalizationPackFactory.php delete mode 100644 src/Core/Localization/Pack/Factory/LocalizationPackFactoryInterface.php delete mode 100644 src/Core/Localization/Pack/Import/LocalizationPackImportConfig.php delete mode 100644 src/Core/Localization/Pack/Import/LocalizationPackImportConfigInterface.php delete mode 100644 src/Core/Localization/Pack/Import/LocalizationPackImporter.php delete mode 100644 src/Core/Localization/Pack/Import/LocalizationPackImporterInterface.php delete mode 100644 src/Core/Localization/Pack/Loader/AbstractLocalizationPackLoader.php delete mode 100644 src/Core/Localization/Pack/Loader/LocalLocalizationPackLoader.php delete mode 100644 src/Core/Localization/Pack/Loader/LocalizationPackLoaderInterface.php delete mode 100644 src/Core/Localization/Pack/Loader/RemoteLocalizationPackLoader.php delete mode 100644 src/Core/Localization/RTL/Exception/GenerationException.php delete mode 100644 src/Core/Localization/RTL/Processor.php delete mode 100644 src/Core/Localization/RTL/StyleSheetProcessorFactory.php delete mode 100644 src/Core/Localization/RTL/StyleSheetProcessorFactoryInterface.php delete mode 100644 src/Core/Localization/RTL/StylesheetGenerator.php delete mode 100644 src/Core/Localization/Specification/Factory.php delete mode 100644 src/Core/Localization/Specification/Number.php delete mode 100644 src/Core/Localization/Specification/NumberCollection.php delete mode 100644 src/Core/Localization/Specification/NumberInterface.php delete mode 100644 src/Core/Localization/Specification/NumberSymbolList.php delete mode 100644 src/Core/Localization/Specification/Percentage.php delete mode 100644 src/Core/Localization/Specification/Price.php delete mode 100644 src/Core/MailTemplate/FolderThemeCatalog.php delete mode 100644 src/Core/MailTemplate/FolderThemeScanner.php delete mode 100644 src/Core/MailTemplate/Layout/Layout.php delete mode 100644 src/Core/MailTemplate/Layout/LayoutCollection.php delete mode 100644 src/Core/MailTemplate/Layout/LayoutCollectionInterface.php delete mode 100644 src/Core/MailTemplate/Layout/LayoutInterface.php delete mode 100644 src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php delete mode 100644 src/Core/MailTemplate/Layout/LayoutVariablesBuilderInterface.php delete mode 100644 src/Core/MailTemplate/MailTemplateGenerator.php delete mode 100644 src/Core/MailTemplate/MailTemplateInterface.php delete mode 100644 src/Core/MailTemplate/MailTemplateRendererInterface.php delete mode 100644 src/Core/MailTemplate/MailThemeConfiguration.php delete mode 100644 src/Core/MailTemplate/Theme.php delete mode 100644 src/Core/MailTemplate/ThemeCatalogInterface.php delete mode 100644 src/Core/MailTemplate/ThemeCollection.php delete mode 100644 src/Core/MailTemplate/ThemeCollectionInterface.php delete mode 100644 src/Core/MailTemplate/ThemeInterface.php delete mode 100644 src/Core/MailTemplate/Transformation/AbstractTransformation.php delete mode 100644 src/Core/MailTemplate/Transformation/CSSInlineTransformation.php delete mode 100644 src/Core/MailTemplate/Transformation/HTMLToTextTransformation.php delete mode 100644 src/Core/MailTemplate/Transformation/MailVariablesTransformation.php delete mode 100644 src/Core/MailTemplate/Transformation/TransformationCollection.php delete mode 100644 src/Core/MailTemplate/Transformation/TransformationCollectionInterface.php delete mode 100644 src/Core/MailTemplate/Transformation/TransformationInterface.php delete mode 100644 src/Core/MerchandiseReturn/Configuration/MerchandiseReturnOptionsConfiguration.php delete mode 100644 src/Core/Meta/MetaDataProviderInterface.php delete mode 100644 src/Core/Module/Configuration/PaymentRestrictionsConfigurator.php delete mode 100644 src/Core/Module/Configuration/PaymentRestrictionsConfiguratorInterface.php delete mode 100644 src/Core/Module/DataProvider/PaymentModuleListProviderInterface.php delete mode 100644 src/Core/Module/DataProvider/TabModuleListProviderInterface.php delete mode 100644 src/Core/Module/Exception/ModuleErrorException.php delete mode 100644 src/Core/Module/Exception/ModuleErrorInterface.php delete mode 100644 src/Core/Module/HookConfigurator.php delete mode 100644 src/Core/Module/HookRepository.php delete mode 100644 src/Core/Module/ModuleInterface.php delete mode 100644 src/Core/Module/WidgetInterface.php delete mode 100644 src/Core/Multistore/MultistoreConfig.php delete mode 100644 src/Core/Multistore/MultistoreContextCheckerInterface.php delete mode 100644 src/Core/Order/InvoiceInterface.php delete mode 100644 src/Core/Order/OrderInvoiceDataProviderInterface.php delete mode 100644 src/Core/Order/OrderSiblingProviderInterface.php delete mode 100644 src/Core/Order/OrderStateDataProviderInterface.php delete mode 100644 src/Core/PDF/Exception/MissingDataException.php delete mode 100644 src/Core/PDF/Exception/PdfException.php delete mode 100644 src/Core/PDF/PDFGeneratorInterface.php delete mode 100644 src/Core/PDF/PDFTemplateTypeProviderInterface.php delete mode 100644 src/Core/Payment/PaymentModulePreferencesConfiguration.php delete mode 100644 src/Core/Payment/PaymentOption.php delete mode 100644 src/Core/Payment/PaymentOptionFormDecorator.php delete mode 100644 src/Core/Product/ProductAdminDrawer.php delete mode 100644 src/Core/Product/ProductCsvExporter.php delete mode 100644 src/Core/Product/ProductExporterInterface.php delete mode 100644 src/Core/Product/ProductExtraContent.php delete mode 100644 src/Core/Product/ProductExtraContentFinder.php delete mode 100644 src/Core/Product/ProductInterface.php delete mode 100644 src/Core/Product/ProductListingPresenter.php delete mode 100644 src/Core/Product/ProductPresentationSettings.php delete mode 100644 src/Core/Product/ProductPresenter.php delete mode 100644 src/Core/Product/Search/Exception/InvalidSortOrderDirectionException.php delete mode 100644 src/Core/Product/Search/Facet.php delete mode 100644 src/Core/Product/Search/FacetCollection.php delete mode 100644 src/Core/Product/Search/FacetsRendererInterface.php delete mode 100644 src/Core/Product/Search/Filter.php delete mode 100644 src/Core/Product/Search/Pagination.php delete mode 100644 src/Core/Product/Search/ProductSearchContext.php delete mode 100644 src/Core/Product/Search/ProductSearchProviderInterface.php delete mode 100644 src/Core/Product/Search/ProductSearchQuery.php delete mode 100644 src/Core/Product/Search/ProductSearchResult.php delete mode 100644 src/Core/Product/Search/SortOrder.php delete mode 100644 src/Core/Product/Search/SortOrderFactory.php delete mode 100644 src/Core/Product/Search/SortOrdersCollection.php delete mode 100644 src/Core/Product/Search/URLFragmentSerializer.php delete mode 100644 src/Core/Proxy/CachedFileFinderProxy.php delete mode 100644 src/Core/Repository/RepositoryInterface.php delete mode 100644 src/Core/Routing/EntityLinkBuilderFactory.php delete mode 100644 src/Core/Routing/EntityLinkBuilderInterface.php delete mode 100644 src/Core/Routing/Exception/BuilderNotFoundException.php delete mode 100644 src/Core/Search/Builder/AbstractFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/AbstractRepositoryFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/ChainedFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/ClassFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/EventFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/FiltersBuilderCollection.php delete mode 100644 src/Core/Search/Builder/FiltersBuilderInterface.php delete mode 100644 src/Core/Search/Builder/PersistFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/RepositoryFiltersBuilder.php delete mode 100644 src/Core/Search/Builder/RequestFiltersBuilder.php delete mode 100644 src/Core/Search/ControllerAction.php delete mode 100644 src/Core/Search/Filters.php delete mode 100644 src/Core/Search/Filters/AddressFilters.php delete mode 100644 src/Core/Search/Filters/AttachmentFilters.php delete mode 100644 src/Core/Search/Filters/AttributeFilters.php delete mode 100644 src/Core/Search/Filters/AttributeGroupFilters.php delete mode 100644 src/Core/Search/Filters/BackupFilters.php delete mode 100644 src/Core/Search/Filters/CatalogPriceRuleFilters.php delete mode 100644 src/Core/Search/Filters/CategoryFilters.php delete mode 100644 src/Core/Search/Filters/CmsPageCategoryFilters.php delete mode 100644 src/Core/Search/Filters/CmsPageFilters.php delete mode 100644 src/Core/Search/Filters/ContactFilters.php delete mode 100644 src/Core/Search/Filters/CreditSlipFilters.php delete mode 100644 src/Core/Search/Filters/CurrencyFilters.php delete mode 100644 src/Core/Search/Filters/CustomerFilters.php delete mode 100644 src/Core/Search/Filters/EmailLogsFilter.php delete mode 100644 src/Core/Search/Filters/EmployeeFilters.php delete mode 100644 src/Core/Search/Filters/LanguageFilters.php delete mode 100644 src/Core/Search/Filters/LogsFilters.php delete mode 100644 src/Core/Search/Filters/ManufacturerAddressFilters.php delete mode 100644 src/Core/Search/Filters/ManufacturerFilters.php delete mode 100644 src/Core/Search/Filters/MerchandiseReturnFilters.php delete mode 100644 src/Core/Search/Filters/MetaFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/DisabledProductFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/EmptyCategoryFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/NoQtyProductWithCombinationFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/NoQtyProductWithoutCombinationFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/ProductWithoutDescriptionFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/ProductWithoutImageFilters.php delete mode 100644 src/Core/Search/Filters/Monitoring/ProductWithoutPriceFilters.php delete mode 100644 src/Core/Search/Filters/OrderFilters.php delete mode 100644 src/Core/Search/Filters/OrderMessageFilters.php delete mode 100644 src/Core/Search/Filters/ProfileFilters.php delete mode 100644 src/Core/Search/Filters/RequestSqlFilters.php delete mode 100644 src/Core/Search/Filters/SupplierFilters.php delete mode 100644 src/Core/Search/Filters/TaxFilters.php delete mode 100644 src/Core/Search/Filters/TaxRulesGroupFilters.php delete mode 100644 src/Core/Search/Filters/WebserviceKeyFilters.php delete mode 100644 src/Core/Search/SearchParameters.php delete mode 100644 src/Core/Search/SearchParametersInterface.php delete mode 100644 src/Core/Security/FolderGuardInterface.php delete mode 100644 src/Core/Security/HtaccessFolderGuard.php delete mode 100644 src/Core/Session/SessionInterface.php delete mode 100644 src/Core/Shop/LogoUploader.php delete mode 100644 src/Core/Shop/ShopContextInterface.php delete mode 100644 src/Core/Shop/Url/UrlProviderInterface.php delete mode 100644 src/Core/SqlManager/Configuration/SqlRequestConfiguration.php delete mode 100644 src/Core/SqlManager/Exporter/SqlRequestExporter.php delete mode 100644 src/Core/SqlManager/Exporter/SqlRequestExporterInterface.php delete mode 100644 src/Core/Stock/StockManager.php delete mode 100644 src/Core/String/CharacterCleaner.php delete mode 100644 src/Core/Support/ContactRepositoryInterface.php delete mode 100644 src/Core/Tax/Ecotax/ProductEcotaxResetterInterface.php delete mode 100644 src/Core/Tax/TaxOptionsConfiguration.php delete mode 100644 src/Core/Team/Employee/Configuration/EmployeeOptionsConfiguration.php delete mode 100644 src/Core/Team/Employee/Configuration/OptionsChecker.php delete mode 100644 src/Core/Team/Employee/Configuration/OptionsCheckerInterface.php delete mode 100644 src/Core/Translation/Locale/Converter.php delete mode 100644 src/Core/Util/ArabicToLatinDigitConverter.php delete mode 100644 src/Core/Util/BoolParser.php delete mode 100644 src/Core/Util/ColorBrightnessCalculator.php delete mode 100644 src/Core/Util/DateTime/DateTime.php delete mode 100644 src/Core/Util/DateTime/TimeDefinition.php delete mode 100644 src/Core/Util/File/FileSizeConverter.php delete mode 100644 src/Core/Util/File/YamlParser.php delete mode 100644 src/Core/Util/HelperCard/DocumentationLinkProvider.php delete mode 100644 src/Core/Util/HelperCard/DocumentationLinkProviderInterface.php delete mode 100644 src/Core/Util/HelperCard/HelperCardDocumentationDoesNotExistException.php delete mode 100644 src/Core/Util/InternationalizedDomainNameConverter.php delete mode 100644 src/Core/Util/String/StringModifier.php delete mode 100644 src/Core/Util/String/StringModifierInterface.php delete mode 100644 src/Core/Util/String/StringValidator.php delete mode 100644 src/Core/Util/String/StringValidatorInterface.php delete mode 100644 src/Core/Util/Url/BackUrlProvider.php delete mode 100644 src/Core/Util/Url/UrlFileChecker.php delete mode 100644 src/Core/Util/Url/UrlFileCheckerInterface.php delete mode 100644 src/Core/Validation/Validator.php delete mode 100644 src/Core/Validation/ValidatorInterface.php delete mode 100644 src/Core/Webservice/ServerRequirementsChecker.php delete mode 100644 src/Core/Webservice/ServerRequirementsCheckerInterface.php delete mode 100644 src/PrestaShopBundle/Api/QueryParamsCollection.php delete mode 100644 src/PrestaShopBundle/Api/QueryStockMovementParamsCollection.php delete mode 100644 src/PrestaShopBundle/Api/QueryStockParamsCollection.php delete mode 100644 src/PrestaShopBundle/Api/QueryTranslationParamsCollection.php delete mode 100644 src/PrestaShopBundle/Api/Stock/Movement.php delete mode 100644 src/PrestaShopBundle/Api/Stock/MovementsCollection.php delete mode 100644 src/PrestaShopBundle/Cache/CacheWarmer.php delete mode 100644 src/PrestaShopBundle/Cache/Factory/CacheSubscriberFactory.php delete mode 100644 src/PrestaShopBundle/Cache/LocalizationWarmer.php delete mode 100644 src/PrestaShopBundle/Cache/ModuleTemplateCacheWarmer.php delete mode 100644 src/PrestaShopBundle/Command/AppendConfigurationFileHooksListCommand.php delete mode 100644 src/PrestaShopBundle/Command/AppendHooksListForSqlUpgradeFileCommand.php delete mode 100644 src/PrestaShopBundle/Command/CheckTranslationDuplicatesCommand.php delete mode 100644 src/PrestaShopBundle/Command/ExportThemeCommand.php delete mode 100644 src/PrestaShopBundle/Command/GenerateMailTemplatesCommand.php delete mode 100644 src/PrestaShopBundle/Command/LegacyLinkLinterCommand.php delete mode 100644 src/PrestaShopBundle/Command/ListCommandsAndQueriesCommand.php delete mode 100644 src/PrestaShopBundle/Command/ModuleCommand.php delete mode 100644 src/PrestaShopBundle/Command/NamingConventionLinterCommand.php delete mode 100644 src/PrestaShopBundle/Command/SecurityAnnotationLinterCommand.php delete mode 100644 src/PrestaShopBundle/Command/ThemeEnablerCommand.php delete mode 100644 src/PrestaShopBundle/Command/UpdateEUTaxruleGroupsCommand.php delete mode 100644 src/PrestaShopBundle/Command/UpdateLicensesCommand.php delete mode 100644 src/PrestaShopBundle/Command/UpdateSchemaCommand.php delete mode 100644 src/PrestaShopBundle/Component/CsvResponse.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/AddonsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/AttachementProductController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/AttributeController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/CategoryController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/CombinationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/CommonController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/BackupController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmailController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmployeeController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportDataConfigurationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/MemcacheServerController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ProfileController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SqlManagerController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SystemInformationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/CustomerPreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Configure/ShowcaseCardController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/ErrorController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/FeatureController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Design/CmsPageController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Design/MailThemeController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Design/PositionsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeCatalogController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/CurrencyController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/StateController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/International/TaxRulesGroupController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/ModuleController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Modules/AddonsStoreController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Modules/AlertsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Modules/ModuleAbstractController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Modules/UpdatesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentMethodsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentPreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/ProductController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/ProductImageController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/SecurityController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Address/AddressController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttachmentController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeGroupController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CatalogPriceRuleController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CategoryController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/FeatureController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/ManufacturerController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/MonitoringController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Catalog/SupplierController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/CustomerThreadController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/MerchandiseReturnController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/OrderMessageController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButton.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButtonInterface.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButtonsCollection.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/CartController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/CreditSlipController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/DeliveryController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/InvoicesController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/Sell/Order/OrderController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/SpecificPriceController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/StockController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/SupplierController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/TranslationsController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/VirtualProductController.php delete mode 100644 src/PrestaShopBundle/Controller/Admin/WarehouseController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/ApiController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/AttributeController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/CategoryController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/FeatureController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/I18nController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/Improve/Design/PositionsController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/ManufacturerController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/StockController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/StockMovementController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/SupplierController.php delete mode 100644 src/PrestaShopBundle/Controller/Api/TranslationController.php delete mode 100644 src/PrestaShopBundle/Controller/ArgumentResolver/FiltersBuilderResolver.php delete mode 100644 src/PrestaShopBundle/Controller/ArgumentResolver/SearchParametersResolver.php delete mode 100644 src/PrestaShopBundle/DataCollector/CommandsAndQueriesDataCollector.php delete mode 100644 src/PrestaShopBundle/DataCollector/HookDataCollector.php delete mode 100644 src/PrestaShopBundle/DataCollector/HookRegistry.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/AddOnsConfiguration.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/CommandAndQueryCollectorPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/ContainerInjectionPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/DynamicRolePass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/GridDefinitionServiceIdsCollectorPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/IdentifiableObjectFormTypesCollectorPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/LoadServicesFromModulesPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/ModulesDoctrineCompilerPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/OptionsFormHookNameCollectorPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/OverrideTranslatorServiceCompilerPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/OverrideTwigServiceCompilerPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/PopulateTranslationProvidersPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/RemoveXmlCompiledContainerPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Compiler/RouterPass.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/Config/ConfigYamlLoader.php delete mode 100644 src/PrestaShopBundle/DependencyInjection/PrestaShopExtension.php delete mode 100644 src/PrestaShopBundle/Entity/AdminFilter.php delete mode 100644 src/PrestaShopBundle/Entity/Attribute.php delete mode 100644 src/PrestaShopBundle/Entity/AttributeGroup.php delete mode 100644 src/PrestaShopBundle/Entity/AttributeGroupLang.php delete mode 100644 src/PrestaShopBundle/Entity/AttributeLang.php delete mode 100644 src/PrestaShopBundle/Entity/Lang.php delete mode 100644 src/PrestaShopBundle/Entity/ModuleHistory.php delete mode 100644 src/PrestaShopBundle/Entity/ProductDownload.php delete mode 100644 src/PrestaShopBundle/Entity/ProductIdentity.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/AdminFilterRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/AttributeGroupLangRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/AttributeGroupRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/AttributeLangRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/AttributeRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/CategoryRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/FeatureAttributeRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/ImportMatchRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/LangRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/LogRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/ManufacturerRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/ModuleRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/NormalizeFieldTrait.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/OrderInvoiceRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/RequestSqlRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/ShopGroupRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/ShopRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/StockManagementRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/StockMovementRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/StockRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/SupplierRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/TabLangRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/TabRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/TimezoneRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Repository/TranslationRepository.php delete mode 100644 src/PrestaShopBundle/Entity/Shop.php delete mode 100644 src/PrestaShopBundle/Entity/ShopGroup.php delete mode 100644 src/PrestaShopBundle/Entity/StockMvt.php delete mode 100644 src/PrestaShopBundle/Entity/Tab.php delete mode 100644 src/PrestaShopBundle/Entity/TabLang.php delete mode 100644 src/PrestaShopBundle/Entity/Translation.php delete mode 100644 src/PrestaShopBundle/Event/Dispatcher/NullDispatcher.php delete mode 100644 src/PrestaShopBundle/Event/FilterSearchCriteriaEvent.php delete mode 100644 src/PrestaShopBundle/Event/ModuleManagementEvent.php delete mode 100644 src/PrestaShopBundle/Event/ModuleZipManagementEvent.php delete mode 100644 src/PrestaShopBundle/EventListener/AccessDeniedListener.php delete mode 100644 src/PrestaShopBundle/EventListener/ActionDispatcherLegacyHooksSubscriber.php delete mode 100644 src/PrestaShopBundle/EventListener/BackUrlRedirectResponseListener.php delete mode 100644 src/PrestaShopBundle/EventListener/DemoModeEnabledListener.php delete mode 100644 src/PrestaShopBundle/EventListener/FilterCategorySearchCriteriaListener.php delete mode 100644 src/PrestaShopBundle/EventListener/FilterCmsPageCategorySearchCriteriaListener.php delete mode 100644 src/PrestaShopBundle/EventListener/LegacyParametersListener.php delete mode 100644 src/PrestaShopBundle/EventListener/LegacyUrlListener.php delete mode 100644 src/PrestaShopBundle/EventListener/ModuleActivatedListener.php delete mode 100644 src/PrestaShopBundle/EventListener/ModuleGuardListener.php delete mode 100644 src/PrestaShopBundle/EventListener/MultishopCommandListener.php delete mode 100644 src/PrestaShopBundle/EventListener/TokenizedUrlsListener.php delete mode 100644 src/PrestaShopBundle/EventListener/UserLocaleListener.php delete mode 100644 src/PrestaShopBundle/Exception/FileUploadException.php delete mode 100644 src/PrestaShopBundle/Exception/HookModuleNotFoundException.php delete mode 100644 src/PrestaShopBundle/Exception/InvalidLanguageException.php delete mode 100644 src/PrestaShopBundle/Exception/InvalidModuleException.php delete mode 100644 src/PrestaShopBundle/Exception/InvalidPaginationParamsException.php delete mode 100644 src/PrestaShopBundle/Exception/NotImplementedException.php delete mode 100644 src/PrestaShopBundle/Exception/ProductNotFoundException.php delete mode 100644 src/PrestaShopBundle/Exception/ServiceDefinitionException.php delete mode 100644 src/PrestaShopBundle/Exception/UpdateProductException.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/CachingType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/CombineCompressCacheType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/DebugModeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/MediaServersType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/MemcacheServerType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/OptionalFeaturesType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/PerformanceFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/PerformanceFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/AdvancedParameters/Performance/SmartyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Catalog/Category/AbstractCategoryType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Catalog/Category/CategoryType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Catalog/Category/RootCategoryType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Category/SimpleCategory.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Administration/FormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Administration/GeneralType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Administration/NotificationsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Administration/UploadQuotaType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Backup/BackupDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Backup/BackupOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Email/EmailConfigurationFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Email/EmailConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Email/SmtpConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Email/TestEmailSendingType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Employee/EmployeeOptionsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Employee/EmployeeOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Employee/EmployeeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportDataConfigurationFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportDataConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportFormDataProviderInterface.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportFormHandlerInterface.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Import/ImportType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Logs/LogsByEmailType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Logs/LogsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Profile/ProfileType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/RequestSql/SqlRequestFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/RequestSql/SqlRequestFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/RequestSql/SqlRequestSettingsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/RequestSql/SqlRequestSettingsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/RequestSql/SqlRequestType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Webservice/WebserviceConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Webservice/WebserviceFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/AdvancedParameters/Webservice/WebserviceKeyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/Contact/ContactType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/CustomerPreferences/CustomerPreferencesDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/CustomerPreferences/CustomerPreferencesFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/CustomerPreferences/GeneralType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/MaintenanceFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/MaintenanceType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/General/PreferencesType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/OrderPreferences/GeneralType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/OrderPreferences/GiftOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/OrderPreferences/OrderPreferencesFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/GeneralType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/PageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/PaginationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/ProductPreferencesFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/ProductPreferencesFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/ProductPreferences/StockType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/MetaSettingsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/MetaType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/SEOOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/SetUpUrlType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/ShopUrlType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Configure/ShopParameters/TrafficSeo/Meta/UrlSchemaType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/CustomerService/CustomerThread/ForwardCustomerThreadType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Extension/HelpTextExtension.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Extension/RowAttributesExtension.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Feature/ProductFeature.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/MailTheme/GenerateMailsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/MailTheme/MailThemeConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/MailTheme/MailThemeFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/MailTheme/TranslateMailsBodyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Pages/CmsPageCategoryType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Pages/CmsPageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/AdaptThemeToRTLLanguagesType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/ImportThemeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/PageLayoutCustomizationFormFactory.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/PageLayoutCustomizationFormFactoryInterface.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/PageLayoutsCustomizationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/ShopLogosFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Design/Theme/ShopLogosType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Currencies/CurrencyExchangeRateType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Currencies/CurrencyFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Currencies/CurrencyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Geolocation/GeolocationByIpAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Geolocation/GeolocationFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Geolocation/GeolocationIpAddressWhitelistType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Geolocation/GeolocationOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Language/LanguageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Localization/AdvancedConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Localization/ImportLocalizationPackType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Localization/LocalUnitsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Localization/LocalizationConfigurationType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Localization/LocalizationFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Tax/TaxOptionsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Tax/TaxOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Tax/TaxType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Translations/AddUpdateLanguageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Translations/CopyLanguageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Translations/ExportThemeLanguageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Translations/ModifyTranslationsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/International/Translations/TranslationsSettingsFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Payment/Preferences/PaymentModulePreferencesType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Payment/Preferences/PaymentPreferencesFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Shipping/Preferences/CarrierOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Shipping/Preferences/HandlingType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Improve/Shipping/Preferences/PreferencesFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductAttachement.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductCategories.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductCombination.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductCombinationBulk.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductCustomField.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductInformation.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductOptions.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductPrice.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductQuantity.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductSeo.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductShipping.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductSpecificPrice.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductSupplierCombination.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductVirtual.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Product/ProductWarehouseCombination.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Address/CustomerAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Address/ManufacturerAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Address/RequiredFieldsAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Attachment/AttachmentType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Catalog/FeatureType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/CatalogPriceRule/CatalogPriceRuleType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Category/DeleteCategoriesType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Customer/CustomerType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Customer/DeleteCustomersType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Customer/PrivateNoteType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Customer/RequiredFieldsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Customer/TransferGuestAccountType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/CustomerService/OrderMessageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/CustomerService/ReplyToCustomerThreadType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Manufacturer/ManufacturerType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/AddOrderCartRuleType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/AddProductRowType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/CancelProductType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/CartSummaryType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderCurrencyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrdersStatusType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/GeneratePdfByDateType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfFormDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/EditProductRowType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByDateType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByStatusType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByDateFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByStatusFormHandler.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByDateDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByStatusDataProvider.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/OrderMessageType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/OrderPaymentType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderShippingType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderStatusType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Sell/Supplier/SupplierType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/AddonsConnectType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/CategoryChoiceTreeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ChangePasswordType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ChoiceCategoriesTreeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/Common/Team/ProfileChoiceType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/CommonAbstractType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/CountryChoiceType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/CustomContentType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/CustomMoneyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/DatePickerType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/DateRangeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/EmailType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/FormattedTextareaType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/GeneratableTextType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/IntegerMinMaxFilterType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/IpAddressType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTableType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTreeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/Material/MaterialMultipleChoiceTableType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/MoneyWithSuffixType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/NumberMinMaxFilterType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ReductionType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ResizableTextType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/SearchAndResetType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ShopChoiceTreeType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/ShopRestrictionCheckboxType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/SwitchType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TextEmptyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TextWithLengthCounterType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TextWithRecommendedLengthType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TextWithUnitType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TextareaEmptyType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TranslatableType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TranslateTextType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TranslateType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TranslatorAwareType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TypeaheadCustomerCollectionType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductCollectionType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductPackCollectionType.php delete mode 100644 src/PrestaShopBundle/Form/Admin/Type/YesAndNoChoiceType.php delete mode 100644 src/PrestaShopBundle/Form/DataTransformer/ArabicToLatinDigitDataTransformer.php delete mode 100644 src/PrestaShopBundle/Form/DataTransformer/DefaultLanguageToFilledArrayDataTransformer.php delete mode 100644 src/PrestaShopBundle/Form/DataTransformer/IDNConverterDataTransformer.php delete mode 100644 src/PrestaShopBundle/Form/DataTransformer/StringArrayToIntegerArrayDataTransformer.php delete mode 100644 src/PrestaShopBundle/Form/Extension/DataListExtension.php delete mode 100644 src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLength.php delete mode 100644 src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLengthValidator.php delete mode 100644 src/PrestaShopBundle/Install/AbstractInstall.php delete mode 100644 src/PrestaShopBundle/Install/Database.php delete mode 100644 src/PrestaShopBundle/Install/DatabaseDump.php delete mode 100644 src/PrestaShopBundle/Install/Install.php delete mode 100644 src/PrestaShopBundle/Install/Language.php delete mode 100644 src/PrestaShopBundle/Install/LanguageList.php delete mode 100644 src/PrestaShopBundle/Install/Simplexml.php delete mode 100644 src/PrestaShopBundle/Install/SqlLoader.php delete mode 100644 src/PrestaShopBundle/Install/System.php delete mode 100644 src/PrestaShopBundle/Install/Upgrade.php delete mode 100644 src/PrestaShopBundle/Install/XmlLoader.php delete mode 100644 src/PrestaShopBundle/Kernel/ModuleRepository.php delete mode 100644 src/PrestaShopBundle/Kernel/ModuleRepositoryFactory.php delete mode 100644 src/PrestaShopBundle/Model/AdminModelAdapter.php delete mode 100644 src/PrestaShopBundle/Model/Product/AdminModelAdapter.php delete mode 100644 src/PrestaShopBundle/PrestaShopBundle.php delete mode 100644 src/PrestaShopBundle/Resources/config/routing.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/_common.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/_errors.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/_security.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/_configure.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/_advanced_parameters.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/administration.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/backup.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/email.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/employee.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/import.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/logs.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/performance.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/profiles.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/sql_request.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/system_information.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/webservice.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/_shop_parameters.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/contacts.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/customer_preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/maintenance.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/meta.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/order_preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/product_preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/_improve.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_design.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_mail_theme_deprecated.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/cms_pages.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/mail_theme.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/positions.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme_catalog.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/_international.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/currencies.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/geolocation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/language.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/localization.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/state.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax_rules_groups.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/international/translations.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/_modules.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/addons.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/payment_methods.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/improve/shipping/preferences.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/_sell.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/_catalog.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attachment.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute_group.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/cart_rule.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/catalog_price_rule.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/categories.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/features.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/manufacturer.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/monitoring.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/attributes.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/categories.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/combinations.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/features.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/product.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/products.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/specific_prices.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/suppliers.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/warehouses.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/suppliers.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/_customer.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/addresses.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/customers.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/_customer_service.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/customer_threads.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/merchandise_return.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/order_message.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/_orders.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/carts.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/credit_slips.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/delivery_slips.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/invoices.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/orders.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/admin/sell/stocks.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/attributes.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/categories.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/features.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/i18n.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/improve/design/positions.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/manufacturers.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/stock_movements.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/stocks.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/suppliers.yml delete mode 100644 src/PrestaShopBundle/Resources/config/routing/api/translations.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/address.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/admin.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/attachment.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/attribute.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/attribute_group.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/backup.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/cache.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/cart.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/cart_rule.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/catalog_price_rule.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/category.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/cms_page.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/cms_page_category.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/common.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/configuration.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/contact.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/context.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/country.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/credit_slip.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/currency.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/customer.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/customer_message.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/customer_service.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/data_configuration.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/data_provider.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/data_provider_common.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/email.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/employee.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/feature.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/form.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/grid.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/group.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/image.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/import.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/kpi.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/language.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/mail_template.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/manufacturer.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/meta.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/module.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/news.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/notification.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/order.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/order_message.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/pdf.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/pdf/generator.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/pdf/template_type_provider.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/prestatrust.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/product.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/profile.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/routes.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/services.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/shop.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/shop_feature.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/specific_price.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/sql_manager.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/supplier.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/tax.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/tax_rules_group.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/theme.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/twig.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/adapter/webservice.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/alias.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/api.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/cache.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/controller.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/data_collector.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/event_listener.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_builder.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_provider.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_transformer.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_extension.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_handler.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_type.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/form/form_type/webservice.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/grid.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/repository.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/routing.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/security.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/services.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/translation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/twig.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/bundle/utils.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/addon.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/attribute_group.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/b2b.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/backup.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/cache.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/circuit_breaker.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/cldr.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/cms_page.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/command_bus.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/common.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/configuration.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/constraint_validator.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/currency.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/cart.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/country.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/customer_service.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/showcase_card.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/sql_management.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/domain/theme.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/employee.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/export.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/file.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form/choice_provider.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form/form_builder.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form/form_data_handler.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form/form_data_provider.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/form/form_handler.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/foundation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/geolocation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/accessibility_checker.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/doctrine_query_builder.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/grid_data_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/grid_definition_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/grid_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/grid_filter_form_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/grid/grid_position_definition_factory.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/hook.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/image.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/import.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/kpi.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/language.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/localization.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/mail_template.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/module.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/search.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/security.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/shop.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/sql_request.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/string.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/translation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/util.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/util/file_size.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/util/helper_card.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/util/string.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/validation.yml delete mode 100644 src/PrestaShopBundle/Resources/config/services/core/webservice.yml delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Category/categories.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/button.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_categories.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_customers.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/modal_form_submit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/submit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/link.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/simple.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/submit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_category.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_customer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/link.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/submit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/attachment.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/credit_slip.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/order.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/supplier.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/empty_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/filters_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/headers_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions_select_all.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/grid_actions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/pagination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/action.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/attribute_color.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/badge.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/boolean.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/bulk_action.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/category_position.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/choice.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/color.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/data.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/date_time.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/disableable_link.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/draggable.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/employee_name_with_avatar.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/identifier.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/image.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link_group.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/order_price.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position_handle.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/preview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/severity_level.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/toggle.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/action.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/default.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/position_handle.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid_panel.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/Kpi/kpi_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_form_field.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_sidebar.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/pagination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/pagination_quicknav.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Common/recommendedModules.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_info.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_warning.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/download_file.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/download_view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_available_fields.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_file_history.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_panel.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_sample_files.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_logs_grid.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/smtp_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/test_email_sending.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/employee_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_data_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/severity_levels.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/settings_panel.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/webservice_settings.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/administration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/memcache_servers.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/performance.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/system_information.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/customer_preferences_general.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_general.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_page.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_pagination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_stock.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_general.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_gift_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/order_preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/domain_name_management.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/meta_showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/robots_file_generation.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/seo_options_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/set_up_urls_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/shop_urls_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/url_schema_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/customer_preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/maintenance.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/product_preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Exception/error.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Helpers/bootstrap_popup.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Helpers/dropdown_menu.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Helpers/range_inputs.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Helpers/range_slider.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/breadcrumb.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/category_form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/listing_panel_footer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/seo_preview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/add.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/create_category.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit_category.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/configuration_form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/generate_mails_form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_theme_layouts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_themes.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/translate_mails_body_form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/preview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_catalog_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/delete_theme_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/layouts_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/logo_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/multishop_switch.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/rtl_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/use_theme_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/customize_page_layouts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/import.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/ThemesCatalogPage/addons_store.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Design/positions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/exchange_rates.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_by_ip_address.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_ip_address_whitelist.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/advanced_configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/configuration.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/import_localization_pack_block.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/local_units.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/tax_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/TaxRulesGroup/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/add_update_language.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/copy_language.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/export_language.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/modify_translations.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/translations_settings.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Module/addons_store.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/payment_methods.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/Blocks/payment_preferences_form_block.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/payment_preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_carrier_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_handling.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/preferences.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_button.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_menu.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid_addons.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list_addons.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_manage_installed.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_configure.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_update.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_grid.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_bulk.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories_catalog.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_status.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_loader.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_installed.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_recently_used.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_configure.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_update.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/menu_top.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_addons_connect.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_bulk_action.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_prestatrust.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_import.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more_content.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/see_more.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/sorting.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/Includes/tab-module-line.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/alerts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/catalog-refresh.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/catalog.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/common.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/manage.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/tab-modules-list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Module/updates.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/filters.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_edit_dropdown.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list_quicknav.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/products_table.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog_empty.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/footer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/header.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/tabs.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_categories.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination_collection.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations_bulk.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_custom_fields.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_edit_specific_price_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_feature.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_manufacturer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_related_products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_specific_price.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_choice.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_combination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_warehouse_combination.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/seo.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/disabled_form_alert.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Product/Themes/categories_theme.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/ProductImage/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Security/compromised.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/required_fields.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/add.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Address/modal_create_success.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/add.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attribute/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/breadcrumb.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/cover_image.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_block.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/listing_panel_footer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/menu_thumbnail_images.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/thumbnail_image.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create_root.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit_root.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/addresses.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/add.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/logo_image.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/View/products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/add.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/logo_image.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/Index/required_fields.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/addresses.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/bought_products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/carts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/discounts.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/groups.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/last_connections.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/messages.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/orders.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/personal_information.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/private_note.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/sent_emails.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/viewed_products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/delete_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/javascript.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/showcase_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/modal_create_success.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/customer_information.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/forward_thread_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_actions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_messages.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/timeline.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/your_answer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/Blocks/options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/edit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/cart_summary.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/customer_information.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/order_information.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/credit_slip_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/pdf_by_date.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Delivery/slip.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_date.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_status.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/invoice_options.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/invoices.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/addresses.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart_rules.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/customer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/shipping.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_order_discount_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_product_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_customer_address_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_product_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_all_messages_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_product_pack_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/customer.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/documents.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/extra_order_button_actions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/header.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/history.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/linked_orders.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/merchandise_returns.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/messages.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/msg_list_item.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_actions.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_navigation.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments_alert.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_order_statistics.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_title.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/products.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/sources.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/change_orders_status_modal.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/create.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/index.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Stock/overview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/Translations/overview.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_horizontal_layout.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_layout.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_div_layout.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_max_length.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_table_layout.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/material.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/typeahead.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/WebProfiler/commands_and_queries.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/WebProfiler/config.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/WebProfiler/hooks_collector.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/layout.html.twig delete mode 100644 src/PrestaShopBundle/Resources/views/Admin/macros.html.twig delete mode 100644 src/PrestaShopBundle/Routing/Converter/AbstractLegacyRouteProvider.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/CacheKeyGeneratorInterface.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/CacheProvider.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/Exception/AlreadyConvertedException.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/Exception/ArgumentException.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/Exception/RouteNotFoundException.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/Exception/RoutingException.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/LegacyParametersConverter.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/LegacyRoute.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/LegacyRouteProviderInterface.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/LegacyUrlConverter.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/RouterProvider.php delete mode 100644 src/PrestaShopBundle/Routing/Converter/RoutingCacheKeyGenerator.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/AdminRouteProvider.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/Exception/LinterException.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/Exception/NamingConventionException.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/LegacyLinkLinter.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/NamingConventionLinter.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/RouteLinterInterface.php delete mode 100644 src/PrestaShopBundle/Routing/Linter/SecurityAnnotationLinter.php delete mode 100644 src/PrestaShopBundle/Routing/YamlModuleLoader.php delete mode 100644 src/PrestaShopBundle/Security/Admin/Employee.php delete mode 100644 src/PrestaShopBundle/Security/Admin/EmployeeProvider.php delete mode 100644 src/PrestaShopBundle/Security/Annotation/AdminSecurity.php delete mode 100644 src/PrestaShopBundle/Security/Annotation/DemoRestricted.php delete mode 100644 src/PrestaShopBundle/Security/Annotation/ModuleActivated.php delete mode 100644 src/PrestaShopBundle/Security/Role/DynamicRoleHierarchy.php delete mode 100644 src/PrestaShopBundle/Security/Voter/PageVoter.php delete mode 100644 src/PrestaShopBundle/Service/Cache/Refresh.php delete mode 100644 src/PrestaShopBundle/Service/Command/AbstractCommand.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Admin/AddonsInterface.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Admin/ModuleInterface.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Admin/ProductInterface.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Admin/RecommendedModules.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/Marketplace/ApiClient.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/StockInterface.php delete mode 100644 src/PrestaShopBundle/Service/DataProvider/UserProvider.php delete mode 100644 src/PrestaShopBundle/Service/DataUpdater/Admin/ProductInterface.php delete mode 100644 src/PrestaShopBundle/Service/Database/DoctrineNamingStrategy.php delete mode 100644 src/PrestaShopBundle/Service/Database/Upgrade.php delete mode 100644 src/PrestaShopBundle/Service/Grid/ControllerResponseBuilder.php delete mode 100644 src/PrestaShopBundle/Service/Grid/ResponseBuilder.php delete mode 100644 src/PrestaShopBundle/Service/Hook/HookContentClassInterface.php delete mode 100644 src/PrestaShopBundle/Service/Hook/HookDispatcher.php delete mode 100644 src/PrestaShopBundle/Service/Hook/HookEvent.php delete mode 100644 src/PrestaShopBundle/Service/Hook/HookFinder.php delete mode 100644 src/PrestaShopBundle/Service/Hook/RenderingHookEvent.php delete mode 100644 src/PrestaShopBundle/Service/Log/LogHandler.php delete mode 100644 src/PrestaShopBundle/Service/ProductService.php delete mode 100644 src/PrestaShopBundle/Service/Routing/Router.php delete mode 100644 src/PrestaShopBundle/Service/TransitionalBehavior/AdminPagePreferenceInterface.php delete mode 100644 src/PrestaShopBundle/Service/TransitionalBehavior/AdminUrlGeneratorFactory.php delete mode 100644 src/PrestaShopBundle/Service/TranslationService.php delete mode 100644 src/PrestaShopBundle/Translation/Api/AbstractApi.php delete mode 100644 src/PrestaShopBundle/Translation/Api/InternationalApi.php delete mode 100644 src/PrestaShopBundle/Translation/Api/StockApi.php delete mode 100644 src/PrestaShopBundle/Translation/Constraints/PassVsprintf.php delete mode 100644 src/PrestaShopBundle/Translation/Constraints/PassVsprintfValidator.php delete mode 100644 src/PrestaShopBundle/Translation/DataCollectorTranslator.php delete mode 100644 src/PrestaShopBundle/Translation/DomainNormalizer.php delete mode 100644 src/PrestaShopBundle/Translation/Exception/InvalidLegacyTranslationKeyException.php delete mode 100644 src/PrestaShopBundle/Translation/Exception/LegacyFileFormattingException.php delete mode 100644 src/PrestaShopBundle/Translation/Exception/UnsupportedLocaleException.php delete mode 100644 src/PrestaShopBundle/Translation/Exception/UnsupportedModuleException.php delete mode 100644 src/PrestaShopBundle/Translation/Exporter/ThemeExporter.php delete mode 100644 src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractor.php delete mode 100644 src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractorInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Extractor/ThemeExtractor.php delete mode 100644 src/PrestaShopBundle/Translation/Factory/ProviderNotFoundException.php delete mode 100644 src/PrestaShopBundle/Translation/Factory/ThemeTranslationsFactory.php delete mode 100644 src/PrestaShopBundle/Translation/Factory/TranslationsFactory.php delete mode 100644 src/PrestaShopBundle/Translation/Factory/TranslationsFactoryInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Loader/DatabaseTranslationLoader.php delete mode 100644 src/PrestaShopBundle/Translation/Loader/LegacyFileLoader.php delete mode 100644 src/PrestaShopBundle/Translation/Loader/LegacyFileReader.php delete mode 100644 src/PrestaShopBundle/Translation/Loader/LegacyTranslationKey.php delete mode 100644 src/PrestaShopBundle/Translation/Loader/SqlTranslationLoader.php delete mode 100644 src/PrestaShopBundle/Translation/PrestaShopTranslatorTrait.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/AbstractProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/BackOfficeProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/DatabaseCatalogueInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/ExternalModuleLegacySystemProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/FrontOfficeProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/MailsBodyProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/MailsProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/ModuleProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/ModulesProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/OthersProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/ProviderInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/SearchProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/SearchProviderInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/ThemeProvider.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/TranslationFinder.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/TranslationFinderTrait.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/UseDefaultCatalogueInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/UseModuleInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Provider/XliffCatalogueInterface.php delete mode 100644 src/PrestaShopBundle/Translation/Translator.php delete mode 100644 src/PrestaShopBundle/Translation/TranslatorAwareTrait.php delete mode 100644 src/PrestaShopBundle/Translation/TranslatorComponent.php delete mode 100644 src/PrestaShopBundle/Translation/TranslatorLanguageLoader.php delete mode 100644 src/PrestaShopBundle/Translation/TranslatorLanguageTrait.php delete mode 100644 src/PrestaShopBundle/Translation/View/TreeBuilder.php delete mode 100644 src/PrestaShopBundle/Twig/AdminExtension.php delete mode 100644 src/PrestaShopBundle/Twig/ContextIsoCodeProviderExtension.php delete mode 100644 src/PrestaShopBundle/Twig/DataFormatterExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/ColorBrightnessCalculatorExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/DocumentationLinkExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/GridExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/JsRouterMetadataExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/LocalizationExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/NumberExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Extension/PathWithBackUrlExtension.php delete mode 100644 src/PrestaShopBundle/Twig/HookExtension.php delete mode 100644 src/PrestaShopBundle/Twig/LayoutExtension.php delete mode 100644 src/PrestaShopBundle/Twig/Locator/ModuleTemplateIterator.php delete mode 100644 src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php delete mode 100644 src/PrestaShopBundle/Twig/TranslationsExtension.php delete mode 100644 src/PrestaShopBundle/Utils/FloatParser.php delete mode 100644 src/PrestaShopBundle/Utils/ZipManager.php delete mode 100644 themes/classic/assets/css/012cf6a10129e2275d79d6adac7f3b02.woff delete mode 100644 themes/classic/assets/css/0266b05265f317a7409560b751cd61e8.svg delete mode 100644 themes/classic/assets/css/082a71677e756fb75817e8f262a07cb4.svg delete mode 100644 themes/classic/assets/css/154da4697acc779b55af0a67f1241e4e.ttf delete mode 100644 themes/classic/assets/css/199038f07312bfc6f0aabd3ed6a2b64d.woff2 delete mode 100644 themes/classic/assets/css/19c1b868764c0e4d15a45d3f61250488.woff2 delete mode 100644 themes/classic/assets/css/22c0528acb6d9cd5bf4c8f96381bc05c.svg delete mode 100644 themes/classic/assets/css/2fd9c16b805724d590c0cff96da070a4.ttf delete mode 100644 themes/classic/assets/css/332f555bb44cdc394d6c799df0c03389.woff delete mode 100644 themes/classic/assets/css/36bff72dcba3098b4b70b482b22c29ab.svg delete mode 100644 themes/classic/assets/css/3935e107ea61866e60d7946dc6a962f1.svg delete mode 100644 themes/classic/assets/css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg delete mode 100644 themes/classic/assets/css/3d34be670a7f15086e512282b97ae35e.svg delete mode 100644 themes/classic/assets/css/3d4a907b1b7a232654324a3dd7ae4aa3.eot delete mode 100644 themes/classic/assets/css/3f81521029cc8a9a703419c4a74704a0.woff delete mode 100644 themes/classic/assets/css/4f6ff3639c1e5728b905b650c1a06e75.ttf delete mode 100644 themes/classic/assets/css/570eb83859dc23dd0eec423a49e147fe.woff2 delete mode 100644 themes/classic/assets/css/5dc400bcedda37b13f35cb44623193cf.svg delete mode 100644 themes/classic/assets/css/5ea9fdf2293930126fa9c544968009ae.svg delete mode 100644 themes/classic/assets/css/7988be8b63edf9c4accebf94d5db7927.svg delete mode 100644 themes/classic/assets/css/7a3ebca0cba2e2c6090e84e1d77e0f94.woff2 delete mode 100644 themes/classic/assets/css/7c24d4275efcbe8891f78378b7c808e0.svg delete mode 100644 themes/classic/assets/css/80e74ff9406650e53bbec1e292c2c094.svg delete mode 100644 themes/classic/assets/css/846c191efd3d0aacde5a916cf2ebf1a4.woff delete mode 100644 themes/classic/assets/css/8b05d51ede908907d65695558974d86f.svg delete mode 100644 themes/classic/assets/css/99db8adec61e4fcf5586e1afa549b432.svg delete mode 100644 themes/classic/assets/css/a165a42685795361b25593effb32fdb1.ttf delete mode 100644 themes/classic/assets/css/a37b0c01c0baf1888ca812cc0508f6e2.ttf delete mode 100644 themes/classic/assets/css/a67175d1ea11389d9107bd8c08f9d7d7.svg delete mode 100644 themes/classic/assets/css/a68cfe9d548950edf5df102269877edd.woff2 delete mode 100644 themes/classic/assets/css/a77ade19de3d3762dfbf1fe553b293cc.eot delete mode 100644 themes/classic/assets/css/afb2ed6d67613a724a420a39b4fe5b0d.svg delete mode 100644 themes/classic/assets/css/b1db819132e64a3e01911a1413c33acf.svg delete mode 100644 themes/classic/assets/css/b467416c449eb823029e16347b2ea510.eot delete mode 100644 themes/classic/assets/css/c1a65805f759901a39d10eb854c1dcf2.svg delete mode 100644 themes/classic/assets/css/c2183257e7a697769df4200c547551f1.woff delete mode 100644 themes/classic/assets/css/cf2f3c1d5c7cb02c29f61964313148e1.svg delete mode 100644 themes/classic/assets/css/custom.css delete mode 100644 themes/classic/assets/css/custom_rtl.css delete mode 100644 themes/classic/assets/css/d1a435fd2571e67858a31ee954b52278.svg delete mode 100644 themes/classic/assets/css/d3fbae74a276a9f6cf1d6241f29b61a3.svg delete mode 100644 themes/classic/assets/css/e049aeb07a2ae1627933e8e58d3886d2.svg delete mode 100644 themes/classic/assets/css/e79bfd88537def476913f3ed52f4f4b3.eot delete mode 100644 themes/classic/assets/css/eeb9224f85430652fd070e4e64129aa4.eot delete mode 100644 themes/classic/assets/css/error.css delete mode 100644 themes/classic/assets/css/error_rtl.css delete mode 100644 themes/classic/assets/css/f255af0bbbe837e79f7821827f9c6f10.svg delete mode 100644 themes/classic/assets/css/ffddcb3736980b23405b31142a324b62.svg delete mode 100644 themes/classic/assets/css/theme.css delete mode 100644 themes/classic/assets/css/theme.rtlfix delete mode 100644 themes/classic/assets/css/theme_rtl.css delete mode 100644 themes/classic/assets/img/modules/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-1.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-2.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-3.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-4.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-5.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-6.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/b-blog-7.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/b/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/1/c/[themeforest]_Floral_banner.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/c/category-1.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/c/category-2.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/c/category-3.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/1/c/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/1/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-1.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-2.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-3.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-4.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-5.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-6.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/b-blog-7.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/b/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/c/[themeforest]_Floral_banner.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/c/category-1.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/c/category-2.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/c/category-3.jpg delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/c/index.php delete mode 100644 themes/classic/assets/img/modules/leoblog/sample/index.php delete mode 100644 themes/classic/assets/js/custom.js delete mode 100644 themes/classic/assets/js/theme.js delete mode 100644 themes/classic/config/.htaccess delete mode 100644 themes/classic/config/theme.yml delete mode 100644 themes/classic/lang/pl.php delete mode 100644 themes/classic/modules/blockreassurance/views/templates/hook/blockreassurance.tpl delete mode 100644 themes/classic/modules/contactform/views/templates/widget/contactform.tpl delete mode 100644 themes/classic/modules/ps_advertising/index.php delete mode 100644 themes/classic/modules/ps_advertising/ps_advertising.tpl delete mode 100644 themes/classic/modules/ps_banner/ps_banner.tpl delete mode 100644 themes/classic/modules/ps_bestsellers/views/index.php delete mode 100644 themes/classic/modules/ps_bestsellers/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_bestsellers/views/templates/hook/ps_bestsellers.tpl delete mode 100644 themes/classic/modules/ps_bestsellers/views/templates/index.php delete mode 100644 themes/classic/modules/ps_brandlist/views/index.php delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/_partials/brand_form.tpl delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/_partials/brand_text.tpl delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/_partials/index.php delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/hook/ps_brandlist.tpl delete mode 100644 themes/classic/modules/ps_brandlist/views/templates/index.php delete mode 100644 themes/classic/modules/ps_categoryproducts/views/index.php delete mode 100644 themes/classic/modules/ps_categoryproducts/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_categoryproducts/views/templates/hook/ps_categoryproducts.tpl delete mode 100644 themes/classic/modules/ps_categoryproducts/views/templates/index.php delete mode 100644 themes/classic/modules/ps_categorytree/views/templates/hook/ps_categorytree.tpl delete mode 100644 themes/classic/modules/ps_contactinfo/nav.tpl delete mode 100644 themes/classic/modules/ps_contactinfo/ps_contactinfo-rich.tpl delete mode 100644 themes/classic/modules/ps_contactinfo/ps_contactinfo.tpl delete mode 100644 themes/classic/modules/ps_crossselling/views/index.php delete mode 100644 themes/classic/modules/ps_crossselling/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_crossselling/views/templates/hook/ps_crossselling.tpl delete mode 100644 themes/classic/modules/ps_crossselling/views/templates/index.php delete mode 100644 themes/classic/modules/ps_currencyselector/ps_currencyselector.tpl delete mode 100644 themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl delete mode 100644 themes/classic/modules/ps_customersignin/ps_customersignin.tpl delete mode 100644 themes/classic/modules/ps_emailalerts/views/index.php delete mode 100644 themes/classic/modules/ps_emailalerts/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_emailalerts/views/templates/hook/my-account-footer.tpl delete mode 100644 themes/classic/modules/ps_emailalerts/views/templates/hook/my-account.tpl delete mode 100644 themes/classic/modules/ps_emailalerts/views/templates/index.php delete mode 100644 themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl delete mode 100644 themes/classic/modules/ps_facetedsearch/ps_facetedsearch.tpl delete mode 100644 themes/classic/modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl delete mode 100644 themes/classic/modules/ps_imageslider/views/templates/hook/slider.tpl delete mode 100644 themes/classic/modules/ps_languageselector/ps_languageselector.tpl delete mode 100644 themes/classic/modules/ps_legalcompliance/views/templates/hook/hookDisplayFooter.tpl delete mode 100644 themes/classic/modules/ps_linklist/views/templates/hook/linkblock.tpl delete mode 100644 themes/classic/modules/ps_mainmenu/ps_mainmenu.tpl delete mode 100644 themes/classic/modules/ps_newproducts/views/index.php delete mode 100644 themes/classic/modules/ps_newproducts/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_newproducts/views/templates/hook/ps_newproducts.tpl delete mode 100644 themes/classic/modules/ps_newproducts/views/templates/index.php delete mode 100644 themes/classic/modules/ps_productinfo/views/index.php delete mode 100644 themes/classic/modules/ps_productinfo/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_productinfo/views/templates/hook/ps_productinfo.tpl delete mode 100644 themes/classic/modules/ps_productinfo/views/templates/index.php delete mode 100644 themes/classic/modules/ps_rssfeed/views/index.php delete mode 100644 themes/classic/modules/ps_rssfeed/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_rssfeed/views/templates/hook/ps_rssfeed.tpl delete mode 100644 themes/classic/modules/ps_rssfeed/views/templates/index.php delete mode 100644 themes/classic/modules/ps_searchbar/ps_searchbar.tpl delete mode 100644 themes/classic/modules/ps_sharebuttons/views/templates/hook/ps_sharebuttons.tpl delete mode 100644 themes/classic/modules/ps_shoppingcart/modal.tpl delete mode 100644 themes/classic/modules/ps_shoppingcart/ps_shoppingcart-product-line.tpl delete mode 100644 themes/classic/modules/ps_shoppingcart/ps_shoppingcart.tpl delete mode 100644 themes/classic/modules/ps_socialfollow/ps_socialfollow.tpl delete mode 100644 themes/classic/modules/ps_specials/views/index.php delete mode 100644 themes/classic/modules/ps_specials/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_specials/views/templates/hook/ps_specials.tpl delete mode 100644 themes/classic/modules/ps_specials/views/templates/index.php delete mode 100644 themes/classic/modules/ps_supplierlist/views/index.php delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/_partials/index.php delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_form.tpl delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_text.tpl delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/hook/ps_supplierlist.tpl delete mode 100644 themes/classic/modules/ps_supplierlist/views/templates/index.php delete mode 100644 themes/classic/modules/ps_viewedproduct/views/index.php delete mode 100644 themes/classic/modules/ps_viewedproduct/views/templates/hook/index.php delete mode 100644 themes/classic/modules/ps_viewedproduct/views/templates/hook/ps_viewedproduct.tpl delete mode 100644 themes/classic/modules/ps_viewedproduct/views/templates/index.php delete mode 100644 themes/classic/preview.png delete mode 100644 themes/classic/preview.webp delete mode 100644 themes/classic/templates/_partials/breadcrumb.tpl delete mode 100644 themes/classic/templates/_partials/footer.tpl delete mode 100644 themes/classic/templates/_partials/form-errors.tpl delete mode 100644 themes/classic/templates/_partials/form-fields.tpl delete mode 100644 themes/classic/templates/_partials/head.tpl delete mode 100644 themes/classic/templates/_partials/header.tpl delete mode 100644 themes/classic/templates/_partials/javascript.tpl delete mode 100644 themes/classic/templates/_partials/notifications.tpl delete mode 100644 themes/classic/templates/_partials/pagination.tpl delete mode 100644 themes/classic/templates/_partials/stylesheets.tpl delete mode 100644 themes/classic/templates/catalog/_partials/active_filters.tpl delete mode 100644 themes/classic/templates/catalog/_partials/category-header.tpl delete mode 100644 themes/classic/templates/catalog/_partials/facets.tpl delete mode 100644 themes/classic/templates/catalog/_partials/miniatures/brand.tpl delete mode 100644 themes/classic/templates/catalog/_partials/miniatures/category.tpl delete mode 100644 themes/classic/templates/catalog/_partials/miniatures/pack-product.tpl delete mode 100644 themes/classic/templates/catalog/_partials/miniatures/product.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-activation.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-add-to-cart.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-additional-info.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-customization.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-details.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-discounts.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-flags.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-images-modal.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-prices.tpl delete mode 100644 themes/classic/templates/catalog/_partials/product-variants.tpl delete mode 100644 themes/classic/templates/catalog/_partials/products-bottom.tpl delete mode 100644 themes/classic/templates/catalog/_partials/products-top.tpl delete mode 100644 themes/classic/templates/catalog/_partials/products.tpl delete mode 100644 themes/classic/templates/catalog/_partials/quickview.tpl delete mode 100644 themes/classic/templates/catalog/_partials/sort-orders.tpl delete mode 100644 themes/classic/templates/catalog/_partials/variant-links.tpl delete mode 100644 themes/classic/templates/catalog/brands.tpl delete mode 100644 themes/classic/templates/catalog/listing/best-sales.tpl delete mode 100644 themes/classic/templates/catalog/listing/category.tpl delete mode 100644 themes/classic/templates/catalog/listing/manufacturer.tpl delete mode 100644 themes/classic/templates/catalog/listing/new-products.tpl delete mode 100644 themes/classic/templates/catalog/listing/prices-drop.tpl delete mode 100644 themes/classic/templates/catalog/listing/product-list.tpl delete mode 100644 themes/classic/templates/catalog/listing/search.tpl delete mode 100644 themes/classic/templates/catalog/listing/supplier.tpl delete mode 100644 themes/classic/templates/catalog/manufacturers.tpl delete mode 100644 themes/classic/templates/catalog/product.tpl delete mode 100644 themes/classic/templates/catalog/suppliers.tpl delete mode 100644 themes/classic/templates/checkout/_partials/address-form.tpl delete mode 100644 themes/classic/templates/checkout/_partials/address-selector-block.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-detailed.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-summary-items-subtotal.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-summary-product-line.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-summary-subtotals.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-summary-totals.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-summary.tpl delete mode 100644 themes/classic/templates/checkout/_partials/cart-voucher.tpl delete mode 100644 themes/classic/templates/checkout/_partials/customer-form.tpl delete mode 100644 themes/classic/templates/checkout/_partials/footer.tpl delete mode 100644 themes/classic/templates/checkout/_partials/header.tpl delete mode 100644 themes/classic/templates/checkout/_partials/login-form.tpl delete mode 100644 themes/classic/templates/checkout/_partials/order-confirmation-table.tpl delete mode 100644 themes/classic/templates/checkout/_partials/order-final-summary-table.tpl delete mode 100644 themes/classic/templates/checkout/_partials/order-final-summary.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/addresses.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/checkout-step.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/payment.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/personal-information.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/shipping.tpl delete mode 100644 themes/classic/templates/checkout/_partials/steps/unreachable.tpl delete mode 100644 themes/classic/templates/checkout/cart-empty.tpl delete mode 100644 themes/classic/templates/checkout/cart.tpl delete mode 100644 themes/classic/templates/checkout/checkout-process.tpl delete mode 100644 themes/classic/templates/checkout/checkout.tpl delete mode 100644 themes/classic/templates/checkout/order-confirmation.tpl delete mode 100644 themes/classic/templates/cms/_partials/sitemap-nested-list.tpl delete mode 100644 themes/classic/templates/cms/category.tpl delete mode 100644 themes/classic/templates/cms/page.tpl delete mode 100644 themes/classic/templates/cms/sitemap.tpl delete mode 100644 themes/classic/templates/cms/stores.tpl delete mode 100644 themes/classic/templates/contact.tpl delete mode 100644 themes/classic/templates/customer/_partials/address-form.tpl delete mode 100644 themes/classic/templates/customer/_partials/block-address.tpl delete mode 100644 themes/classic/templates/customer/_partials/customer-form.tpl delete mode 100644 themes/classic/templates/customer/_partials/login-form.tpl delete mode 100644 themes/classic/templates/customer/_partials/my-account-links.tpl delete mode 100644 themes/classic/templates/customer/_partials/order-detail-no-return.tpl delete mode 100644 themes/classic/templates/customer/_partials/order-detail-return.tpl delete mode 100644 themes/classic/templates/customer/_partials/order-messages.tpl delete mode 100644 themes/classic/templates/customer/address.tpl delete mode 100644 themes/classic/templates/customer/addresses.tpl delete mode 100644 themes/classic/templates/customer/authentication.tpl delete mode 100644 themes/classic/templates/customer/discount.tpl delete mode 100644 themes/classic/templates/customer/guest-login.tpl delete mode 100644 themes/classic/templates/customer/guest-tracking.tpl delete mode 100644 themes/classic/templates/customer/history.tpl delete mode 100644 themes/classic/templates/customer/identity.tpl delete mode 100644 themes/classic/templates/customer/my-account.tpl delete mode 100644 themes/classic/templates/customer/order-detail.tpl delete mode 100644 themes/classic/templates/customer/order-follow.tpl delete mode 100644 themes/classic/templates/customer/order-return.tpl delete mode 100644 themes/classic/templates/customer/order-slip.tpl delete mode 100644 themes/classic/templates/customer/page.tpl delete mode 100644 themes/classic/templates/customer/password-email.tpl delete mode 100644 themes/classic/templates/customer/password-infos.tpl delete mode 100644 themes/classic/templates/customer/password-new.tpl delete mode 100644 themes/classic/templates/customer/registration.tpl delete mode 100644 themes/classic/templates/errors/404.tpl delete mode 100644 themes/classic/templates/errors/forbidden.tpl delete mode 100644 themes/classic/templates/errors/maintenance.tpl delete mode 100644 themes/classic/templates/errors/not-found.tpl delete mode 100644 themes/classic/templates/errors/restricted-country.tpl delete mode 100644 themes/classic/templates/errors/static/500.html delete mode 100644 themes/classic/templates/errors/static/503.html delete mode 100644 themes/classic/templates/index.tpl delete mode 100644 themes/classic/templates/layouts/layout-both-columns.tpl delete mode 100644 themes/classic/templates/layouts/layout-content-only.tpl delete mode 100644 themes/classic/templates/layouts/layout-error.tpl delete mode 100644 themes/classic/templates/layouts/layout-full-width.tpl delete mode 100644 themes/classic/templates/layouts/layout-left-column.tpl delete mode 100644 themes/classic/templates/layouts/layout-right-column.tpl delete mode 100644 themes/classic/templates/page.tpl delete mode 100644 tools/.htaccess delete mode 100644 tools/index.php delete mode 100644 tools/profiling/.htaccess delete mode 100644 tools/profiling/Controller.php delete mode 100644 tools/profiling/Db.php delete mode 100644 tools/profiling/ObjectModel.php delete mode 100644 tools/profiling/Tools.php delete mode 100644 tools/profiling/index.php delete mode 100644 translations/.DS_Store delete mode 100644 translations/cldr/.htaccess delete mode 100644 translations/export/index.php delete mode 100644 translations/index.php delete mode 100644 translations/sf-en-GB.zip delete mode 100644 translations/sf-pl-PL.zip diff --git a/cron-products.php b/cron-products.php index 2f02c367..601f13ad 100644 --- a/cron-products.php +++ b/cron-products.php @@ -1,18 +1,27 @@ " . PHP_EOL; +} + $mdb = new medoo( [ 'database_type' => 'mysql', - 'database_name' => 'host439372_redline', + 'database_name' => 'host439372_b2b', 'server' => 'localhost', - 'username' => 'host439372_redline', - 'password' => 'zak2VVsmvAsqGFx7', + 'username' => 'host439372_b2b', + 'password' => 'BNbuvNMs22Dq48drp6Ee', 'charset' => 'utf8' ] ); +log_msg('Start: przeliczanie cen zestawów (pack).'); $rows = $mdb -> select( 'ps_product', '*', [ 'cache_is_pack' => 1 ] ); +log_msg('Znaleziono zestawów: ' . count($rows)); foreach ( $rows as $row ) { + log_msg('Przeliczam cenę zestawu ID: ' . $row['id_product']); $summary_price = 0; $rows2 = $mdb -> select( 'ps_pack', '*', [ 'id_product_pack' => $row['id_product'] ] ); foreach ( $rows2 as $row2 ) @@ -23,11 +32,16 @@ foreach ( $rows as $row ) $mdb -> update( 'ps_product', [ 'price' => $summary_price ], [ 'id_product' => $row['id_product'] ] ); $mdb -> update( 'ps_product_shop', [ 'price' => $summary_price ], [ 'id_product' => $row['id_product'] ] ); + log_msg('Zapisano cenę zestawu ID: ' . $row['id_product'] . ' = ' . $summary_price); } +log_msg('Start: przeliczanie stanów magazynowych zestawów (pack).'); + $rows = $mdb -> select( 'ps_product', '*', [ 'cache_is_pack' => 1 ] ); +log_msg('Znaleziono zestawów: ' . count($rows)); foreach ( $rows as $row ) { + log_msg('Przeliczam stan magazynowy zestawu ID: ' . $row['id_product']); $product_quantity = 999999999; $rows2 = $mdb -> select( 'ps_pack', '*', [ 'id_product_pack' => $row['id_product'] ] ); @@ -41,5 +55,7 @@ foreach ( $rows as $row ) } $mdb -> update( 'ps_stock_available', [ 'quantity' => $product_quantity ], [ 'id_product' => $row['id_product'] ] ); + log_msg('Zapisano stan magazynowy zestawu ID: ' . $row['id_product'] . ' = ' . $product_quantity); } +log_msg('Koniec: zakończono przetwarzanie zestawów.'); ?> \ No newline at end of file diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index c536509aacb37d61bc1c38c3deda36c807a603b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-ve05I#deX%SLK#NZ^o@X!Enj7I{W!AW+gvON8 zgl-GbG9U_w0)I^b{&s5=)0FP1O}X!PIB2xuG#OjMPv>QENg73+VcNlb@cQ;~+243M zDUai z28$7N>(SKXqN?xnV)A^R4`+M|YvnmDit~7>Gv>8z*i7&yp%30>47Eno2iJkekaqVM zN9Va79nZKfSU=BtxeSj#Y347sS_M$E*@7*L(uxA2fG99ifcFOtXAB)?7R}ay#vB2F z6$~3gzs?P%G@36YZFc? zv?#48APV>jtlP^v*Z{_`F#?kx0V9JnqQFWO_yVqFo;Lsh diff --git a/docs/.htaccess b/docs/.htaccess deleted file mode 100644 index 3de9e400..00000000 --- a/docs/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order deny,allow - Deny from all - - -# Apache 2.4 - - Require all denied - diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt deleted file mode 100644 index 24932952..00000000 --- a/docs/CHANGELOG.txt +++ /dev/null @@ -1,4824 +0,0 @@ -Copyright since 2007 PrestaShop SA and Contributors -PrestaShop is an International Registered Trademark & Property of PrestaShop SA - -NOTICE OF LICENSE - -This source file is subject to the Open Software License (OSL 3.0) -that is bundled with this package in the file LICENSE.md. -It is also available through the world-wide-web at this URL: -https://opensource.org/licenses/OSL-3.0 -If you did not receive a copy of the license and are unable to -obtain it through the world-wide-web, please send an email -to license@prestashop.com so we can send you a copy immediately. - -DISCLAIMER - -Do not edit or add to this file if you wish to upgrade PrestaShop to newer -versions in the future. If you wish to customize PrestaShop for your -needs please refer to https://devdocs.prestashop.com/ for more information. - -@author PrestaShop SA and Contributors -@copyright Since 2007 PrestaShop SA and Contributors -@license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - -Release Notes for PrestaShop 1.7 --------------------------------- -#################################### -# v1.7.7.1 - (2021-01-11) -#################################### - -- Back Office: - - Improvement: - - #22020: Take shop id into account when getting a language list for an order (by @matthieu-rolland) - - #22028: Update out of stock mail wording (by @jolelievre) - - Bug fix: - - #21692: Refresh order products when a product is added or deleted (by @sowbiba) - - #22535: Method assertCmsCategoryExists doesn't return anything, it throws an exception (by @PierreRambaud) - - #22082: Hide product quantity in Order view page when stock management is disabled (by @jolelievre) - - #22299: Use OrderDetail prices when modifying an Order (by @jolelievre) - - #21795: Fix wrong product quantity after adding a product triggering a free gift (by @matthieu-rolland) - - #22175: Added error when a customization is not found (by @Progi1984) - - #21912: Use language_code when locale is empty to get CLDR data (by @atomiix) - - #22171: When refreshing an order, display shipping price if needed (by @Progi1984) - - #22406: Fixed pagination in Product Quick Navigation Popup (by @Progi1984) - - #21977: Add debounce to quantity change of order create product (by @NeOMakinG) - - #22291: Fixed Pagination of Sell > Orders > Credits Slips page (by @Progi1984) - - #22214: Fix numeric_iso_code in the upgrade to 1.7.7.1 (by @atomiix) - - #22126: Fix bug on displayed price's calculation in BO order page under specific conditions (by @matthieu-rolland) - - #22246: Integrate ContextStateManager into refund handlers (by @jolelievre) - - #21568: Fixed in Create Order the update of cart rules when changing adress (by @Progi1984) - - #22189: Trigger input when a predefined message is applied (by @Progi1984) - - #22077: Create Order - Fix remove cart rule when amount is not reached (by @sowbiba) - - #22101: Fix product selections when creating/updating tags (by @atomiix) - - #22099: Fix employee filter for the Logs page (by @atomiix) - - #22059: Add Payments block refresher - Refresh when product is added or removed from Order (by @sowbiba) - - #21992: Make customer note TYPE_STRING instead of TYPE_HTML (by @atomiix) - - #21980: Fixed the error message for a combination with a min quantity for sale (by @Progi1984) -- Front Office: - - Bug fix: - - #22296: Center products on category list on mobile (by @NeOMakinG) - - #22241: Fix duplicated hook data after product page refresh (by @Hlavtox) - - #22103: Display combination image in product pack list (by @jolelievre) -- Core: - - Bug fix: - - #22532: Hook keys must be in lowercase (by @PierreRambaud) - - #22432: Don't redirect to http from https if it is homepage (by @ludoc) - - #22293: Use PS cache config as driver.cache (by @atomiix) - - #22274: Fix upgrade from ps < 1.7.0.0 (by @atomiix) - - #22289: Removed module Linklist update from upgrade script (by @Progi1984) - - #21988: Fix order detail total amount update when rounding is per item (by @matthieu-rolland) -- Tests: - - Improvement: - - #22198: Add static cache resets (by @matthieu-rolland) - - Refactoring: - - #22543: Add test 'Page for terms and conditions' (by @nesrineabdmouleh) - - #22523: Add test 'Activate merchandise returns' (by @nesrineabdmouleh) - - #22521: Refactoring alert blocks in UI tests (by @boubkerbribri) - - #22491: Add test 'View customer service message page' (by @nesrineabdmouleh) - - #22490: Add new FO tests 'Edit account information' (by @boubkerbribri) - - #22433: Add test 'Check to delete shop groups' (by @nesrineabdmouleh) - - #22446: Add test 'Quick edit order status' (by @nesrineabdmouleh) - - #22454: Add test 'Quick edit alias status' (by @nesrineabdmouleh) - - #22455: Add requirement block to README in UI tests (by @boubkerbribri) - - #22434: Refactoring FO login page in UI tests and add new page for create account page (by @boubkerbribri) - - #22428: Add new command to run all UI tests and check step identifiers in all campaigns (by @boubkerbribri) - - #22423: Add new test 'Change carrier position' (by @boubkerbribri) - - #22408: Rename functions in UI tests (by @boubkerbribri) - - #22345: Add tests on products page (by @boubkerbribri) - - #22012: Fix random fails in travis CI (by @boubkerbribri) - - #22209: Backport fix on UI sort tests (by @boubkerbribri) - - #22172: Backport UI tests (by @boubkerbribri) - -#################################### -# v1.7.7.0 - (2020-12-02) -#################################### - -- Back Office: - - Bug fix: - - #22191: Validate currency localized names (by @jolelievre) - - #22013: Handle parallel updates from CartRules when updating a product in Order (by @jolelievre) - - #22018: Order zero ratio for order detail tax (by @matks) - - #21781: Remove gifted quantity from product order quantity (by @sowbiba) - - #21994: Remove or cancel all products (by @jolelievre) - - #21721: Handle Shop context override in order editing (by @jolelievre) - - #21816: Remove useless logic Product customization images in Order Page and handle exotic chars in name (by @matks) - - #21853: Add missing use in CancelOrderProductHandler (by @matks) - - #21830: Correctly generate cart error messages (by @jolelievre) - - #21555: Fixed increment button when adding a product out of stock and with allow order (by @Progi1984) - - #21526: Improved Error message in New Order Page when adding a minimal product (by @Progi1984) - - #21557: Fix product pagination when adding a product in an empty order (by @atomiix) -- Front Office: - - Bug fix: - - #21981: Make sure favicon, stores_icon and logo are correctly settled for themes (by @PierreRambaud) -- Core: - - Bug fix: - - #22178: Set numeric_iso_code & precision in currency from CLDR when upgrading (by @atomiix) - - #22182: Update pear/archive_tar to 1.4.11 (by @PierreRambaud) - - #22174: Use displayHeader hook instead of Header (by @atomiix) - - #22164: Fix upgrade script from < 1.7.6.0 to 1.7.7.0 (by @atomiix) - - #22146: Remove --classmap-authoritative when building release (by @atomiix) - - #22130: Fix dependency which is targeting the v1.3.0 instead of the 1.3 branch (by @PierreRambaud) - - #21975: Correctly substring fields before update, remove duplicates and add missing sql queries (by @PierreRambaud) -- Installer: - - Improvement: - - #21957: Update latest native modules (by @jolelievre) - - Bug fix: - - #21953: Fix "column count doesn't match value count" error during upgrade (by @okom3pom) -- Localization: - - Improvement: - - #22063: Last translation updates (by @jolelievre) -- Tests: - - Refactoring: - - #22055: Delete spaces in the end of title name in faker for UI tests (by @boubkerbribri) - -#################################### -# v1.7.7.0-rc.1 - (2020-11-03) -#################################### - -- Back Office: - - Improvement: - - #21435: Add hooks for the AdminLoginController, AdminController, FrontController and Controller (by @PierreRambaud) - - #20903: [BC Break] Update Order amount when its addresses are modified (by @jolelievre) - - #21203: Build assets for 177 (by @jolelievre) - - #21190: Add missing security annotation on new 177 routes (by @jolelievre) - - #21025: Make legacy parameters from routing accessible in migrated pages (by @jolelievre) - - Bug fix: - - #21666: Recompute price tax excluded only when the price is different from catalog (by @jolelievre) - - #21574: Allow ContextStateManager to stash contexts (by @jolelievre) - - #21523: Several fixes found via PHPStan while mergin to develop (by @jolelievre) - - #21447: Synchronize OrderDetail with Cart when removing a voucher (by @PierreRambaud) - - #21467: Fix help link in Create order (by @atomiix) - - #21458: Two Time actionAdminLoginControllerResetBefore (by @okom3pom) - - #21432: Fixed Configuration when Disabling/Enabling Shop (by @Progi1984) - - #21326: Set order currency to added cart rule (by @sowbiba) - - #21331: Enable Gift and Recycled Packaging switches (by @matks) - - #21232: Fix tab modules list (by @sowbiba) - - #21343: Fix status dropdown of order listing page not being well displayed using rtl language (by @NeOMakinG) - - #21317: Notifications bell icon read fix (Backport) (by @okom3pom) - - #21344: Move product search controller that was not in the right place (by @jolelievre) - - #20882: Recompute specific price tax excluded when mismatch with price tax included (by @matthieu-rolland) - - #21310: Fix delete order state confirmation (by @sowbiba) - - #21195: Replaced SQL query to fetch modules hooked on stat hook by Hook function to have a singl Source of Truth (by @matks) - - #20760: Add Order - View customer details : Check if nav-bar exist to avoid console errors (by @sowbiba) - - #20628: Restore selectors in Order Page for GDPR to make GDPR module compliant with 1.7.7.0 (by @matks) - - #21045: Fix Features page throwing an exception after specific steps are made (by @atomiix) - - #21031: Fix bad range error when setting free shipping on a previously not free shipping carrier (by @atomiix) - - #21048: Fix [BO- Stores page] Sort by post code not working (by @PululuK) - - #20911: Fix glyph.png asset path (by @okom3pom) - - #20960: Fix bulk actions in Carriers page (by @atomiix) - - #20936: Fix navbar scroll on mobile display (by @sowbiba) - - #20902: Keep order detail from being updated in BO > Order detail page, when product doesn't exist anymore (by @matthieu-rolland) - - #20906: Duplicate product in order invoices (by @jolelievre) - - #20796: Fix OrderReturnState should not use soft delete (by @atomiix) - - #20798: Do not recalculate shipping if PS_ORDER_RECALCULATE_SHIPPING is false (by @atomiix) - - #20792: Fix cannot add twice a product out of stock but allowed to be ordered (by @atomiix) - - #20757: Save customer message on order creation from BO (by @sowbiba) - - #20734: Allow to create Order from BO using soft deleted address (by @matks) - - #20704: Expose missing route (by @atomiix) - - #20603: Redirect to customer when canceling new customer address creation (by @ks129) - - #20714: Fix max attribute on qty input of an out of stock attribute available on create order (by @NeOMakinG) - - #20684: Fix empty optional customization exception when creating BO order (by @atomiix) - - #20145: Product management and specific prices new rules in Order (by @jolelievre) - - #20755: Fix free shipping cart rules not added/deleted in create order (by @atomiix) - - #20729: Fix price width is too small on some devices by setting a min-width (by @NeOMakinG) - - #20644: Check for address id before creating CartAddress (by @atomiix) - - #20626: Fix duplicate ids in order page (by @PierreRambaud) -- Front Office: - - Improvement: - - #21507: Build core assets (by @jolelievre) - - #20920: Fix jquery migrate being loaded two times in FO (by @matthieu-rolland) - - Bug fix: - - #21362: Possibility to check if we're in product quick view mode (by @kpodemski) - - #20927: Avoid possible notice due to breaking change (by @kpodemski) - - #21297: Fix variable name in order_customer_comment.html.twig (by @okom3pom) - - #21266: Fix wrong combination image shown when clicking to zoom (by @atomiix) - - #20598: Do not reconvert discounts (by @atomiix) -- Core: - - Improvement: - - #21449: Update modules (blockreassurance/dashtrends/ps_checkpayment/welcome) (by @Progi1984) - - #21138: Add changelog for the 1.7.6.8 version (by @PierreRambaud) - - #21124: Bump version to 1.7.6.8, bump contactform version (by @PierreRambaud) - - #20794: Send an 'action' parameter to actionProductCancel hook (by @matthieu-rolland) - - #20738: Disable jquery migrate deprecation messages when prestashop debug mode is off (by @matthieu-rolland) - - Bug fix: - - #21609: Make PrestaShop compatible with composer 2.0 (by @atomiix) - - #21390: Fix getting proper cover for image (by @kpodemski) - - #GHSA-rc8c-v7rq-q392: Stored XSS in upload files (by @PierreRambaud) - - #GHSA-5cp2-r794-w37w: Potential XSS injection with contact form (by @PierreRambaud) - - #GHSA-fghq-8h87-826g: Blind SQLi in Catalog Product edition (by @PierreRambaud) - - #20992: Update live polyfill in BO, FO core theme, and remove it from FO classic theme (by @matthieu-rolland) - - #20741: Fix cumulative free gift + percentage discounts (by @atomiix) - - #20693: Cancel/Refunds... adding missing hooks and cancel product refactor (by @matthieu-rolland) - - #20758: Fix cumulative percentage behat test (by @matthieu-rolland) - - Refactoring: - - #20378: Use Computing precision instead of hardcoded 2 (by @matks) -- Installer: - - Improvement: - - #21178: Update modules for 177 (by @jolelievre) - - Bug fix: - - #20201: Fix throw InstallControllerHttpSystem::trans during installation process (by @mushroot) -- Localization: - - Improvement: - - #21607: Update translation catalogs (by @jolelievre) - - #21509: Update catalog with latest wordings (by @jolelievre) - - #21179: Update translation catalogues for 177 (by @jolelievre) -- Tests: - - Improvement: - - #21497: Improve behat config which did not use appropriate format for paths (by @jolelievre) - - #20850: Add behat tests for order shipping computing, and add new carriers fixtures (by @jolelievre) - - Bug fix: - - #21532: Update behat and gerkhin to allow debugging in PHPStorm (by @jolelievre) - - Refactoring: - - #21544: Fix image name for CRUD title test (by @boubkerbribri) - - #21512: Add tests 'Helper card' for catalog pages (by @boubkerbribri) - - #21508: Add test 'CRUD search engines' (by @boubkerbribri) - - #21505: Add test pagination stores (by @boubkerbribri) - - #21481: Add test 'Sort and pagination price rule' (by @nesrineabdmouleh) - - #21473: Add test 'Filter sort and pagination order status' (by @nesrineabdmouleh) - - #21462: Add var for visible selectors in methods (by @nesrineabdmouleh) - - #21459: Add test 'CRUD order status' (by @nesrineabdmouleh) - - #21452: Fix page name in orders tests (by @boubkerbribri) - - #21399: Add test 'Help card on attributes page' (by @boubkerbribri) - - #21405: Add test 'Filter, sort and pagination search engines' (by @boubkerbribri) - - #21403: Add test 'Sort and pagination countries table' (by @nesrineabdmouleh) - - #21411: Add test 'Sort and pagination states table' (by @nesrineabdmouleh) - - #21415: Add test 'Filter, sort and pagination tax rules group' (by @nesrineabdmouleh) - - #21433: Fix a small error in nightly 14-10-2020 (by @nesrineabdmouleh) - - #21402: Add test 'Sort and pagination zones table' (by @nesrineabdmouleh) - - #21385: Add test 'Filter and bulk actions catalog price rules' (by @nesrineabdmouleh) - - #21396: Add navigation when selecting pagination limit (by @boubkerbribri) - - #21367: Add test 'CRUD catalog price rule' (by @nesrineabdmouleh) - - #21334: Create state with only iso code that does not exist (by @boubkerbribri) - - #21341: Fix test 'CRUD carrier' in nightly 07/10/2020 (by @nesrineabdmouleh) - - #21339: Delete all references to ttc in UI folder (by @boubkerbribri) - - #21327: Create first test 'Computing precision set to 3' for UI tests new campaign 'Regression' (by @boubkerbribri) - - #21324: Add new test 'Change position for attributes and values' (by @boubkerbribri) - - #21308: Fix tests errors in nightly 04/10/2020 (by @nesrineabdmouleh) - - #21302: Change UI tests workflow name (by @boubkerbribri) - - #21255: Add test 'Sort and pagination shopping carts' (by @nesrineabdmouleh) - - #21265: Fix tests errors in nightly 02/10/2020 (by @nesrineabdmouleh) - - #21256: Fix test 'Filter shopping carts' (by @nesrineabdmouleh) - - #21188: Refactoring create cart rule and faker in tests (by @boubkerbribri) - - #21225: Add test 'Filter shopping carts' (by @nesrineabdmouleh) - - #21147: Add test 'Filter sort and pagination carriers' (by @nesrineabdmouleh) - - #21184: Avoid creating new state with existing iso code (by @boubkerbribri) - - #21162: Add a DB_SERVER global variable for tests (by @SD1982) - - #21182: Add test 'Pagination and sort cart rule' (by @nesrineabdmouleh) - - #21122: Add github action to check eslint and step identifier doubles for UI tests (by @boubkerbribri) - - #21139: Change faker for locations tests (by @boubkerbribri) - - #21123: Add test 'Sort and pagination attributes' (by @nesrineabdmouleh) - - #21064: Add test 'Crud carrier' (by @nesrineabdmouleh) - - #21116: Fix Error in last PR to force playwright@1.0.2 (by @boubkerbribri) - - #20935: Add test 'Bulk actions countries' (by @boubkerbribri) - - #21097: Downgrade playwright to version 1.0.2 (by @boubkerbribri) - - #21090: Unskip test 'Sort by post code' in stores page after fixing issue (by @boubkerbribri) - - #21089: Increase timeout for 'Sort' tests (by @boubkerbribri) - - #21043: Fix test context in 'Sort and pagination image settings' (by @nesrineabdmouleh) - - #21056: Fix tests errors in nightly 18-09-20 (by @boubkerbribri) - - #21040: Add test 'Sort Stores' (by @boubkerbribri) - - #20847: Add test 'Configure contact details' (by @nesrineabdmouleh) - - #20997: Add test 'Sort and pagination image settings' (by @nesrineabdmouleh) - - #21029: Delete force install playwright on docker (by @boubkerbribri) - - #20988: Fix 'CRUD Cart Rule' Test (by @boubkerbribri) - - #20932: Add test 'Bulk actions states' (by @boubkerbribri) - - #20961: Add test 'Filter, quick edit and bulk actions cart rules' (by @boubkerbribri) - - #20922: Add test 'CRUD states' (by @boubkerbribri) - - #20919: Add test 'Bulk actions zones' (by @boubkerbribri) - - #20913: Avoid creating the same name for different values using faker (by @boubkerbribri) - - #20899: Add test 'CRUD Zone' (by @boubkerbribri) - - #20896: Add test 'Filter and quick edit states' (by @boubkerbribri) - - #20876: Add test 'Filter and quick edit zone' (by @boubkerbribri) - - #20873: Improve pagination on customers test (by @boubkerbribri) - - #20883: Fix duplicates steps identifiers in UI tests (by @boubkerbribri) - - #20881: Add test 'Filter and quick edit countries' (by @boubkerbribri) - - #20859: Add test 'CRUD tax Rule' (by @nesrineabdmouleh) - - #20831: Add test 'CRUD country' (by @nesrineabdmouleh) - - #20802: Add test 'CRUD cart rule' (by @nesrineabdmouleh) - - #20759: Add test 'Bulk delete attributes' (by @boubkerbribri) - - #20724: Add test 'Default pack stock management' (by @nesrineabdmouleh) - - #20749: Add tests 'Filter features' and 'Filter feature values' (by @boubkerbribri) - - #20735: Add test 'CRUD attributes and values' (by @boubkerbribri) - - #20692: Add tests 'Filter attributes' and 'Filter attribute values' (by @boubkerbribri) - - #20683: Fix faker data - Title's name should take at most 20 characters (by @boubkerbribri) - - #20599: Functional tests - Add CRUD and Bulk actions tests for image types (by @boubkerbribri) - - #20551: Functional tests - Add tests 'CRUD and bulk delete Groups' (by @boubkerbribri) - -#################################### -# v1.7.7.0-beta.2 - (2020-08-18) -#################################### - -- Back Office: - - New feature: - - #19704: Migrate linked orders (by @matks) - - #19697: Add order sources in Order View page (by @matks) - - Improvement: - - #20529: Fix links in footer - https is better than http (by @matks) - - #20311: Mark deprecated order hooks for 1.7.7 as such (by @matks) - - #20124: Use /usr/sbin/sendmail instead of mail() in config wording (by @atomiix) - - #20039: Make customization image downloadable in BO order page (by @matthieu-rolland) - - #19903: Auto create symfony roles (by @jolelievre) - - #19854: Add trace information to Command/Query debugger (by @eternoendless) - - #19730: Enable fancybox for edit an address in View an Order page (by @matks) - - #19597: Add order table empty state (by @atomiix) - - #19582: Order products pagination (by @jolelievre) - - Bug fix: - - #20571: Return an int instead of a float (in some cases) for Pack::getQuantity() (by @atomiix) - - #20451: Fix TinyMCE error on product page (by @NeOMakinG) - - #20538: Fix order cart rule deletion (by @matthieu-rolland) - - #20524: Fix bad call in HTMLTemplateOrderSlip (by @matks) - - #20477: Fixed cast for primary key in PrestaShopCollection (by @Progi1984) - - #20492: Remove call to updateOrderInvoice - not needed anymore (by @matks) - - #20482: Set CartRule amount with tax in BO instead of without tax (by @atomiix) - - #20335: Remove discount from order (persist state) (by @jolelievre) - - #20457: Include product name and employee name in out of stock email (by @ks129) - - #20461: Fixed Modal "View pack content" (by @Progi1984) - - #20433: Dont show root category on category grid search results (by @matks) - - #20284: Order address country (by @jolelievre) - - #20198: Product supplier_reference is not updated when saving a product in the BO (by @PierreRambaud) - - #20319: Cannot remove attributes if token is disabled (by @PierreRambaud) - - #20303: Fix bad redirection after error in address controller - edit usecase (by @matks) - - #20263: Fix bad redirection after error in address controller (by @matks) - - #20111: Fix order max quantity (by @jolelievre) - - #20083: Refactoring of the Order Updater and multiple related bugfixes (by @jolelievre) - - #20166: Return Response to provide a good error message when import directory doesnt exist (by @matks) - - #20126: Correctly uncheck previous default combination (by @Amazzing) - - #19970: Create specific price when product price is updated in order (by @sowbiba) - - #19937: Fixed position action button in Order Page (by @Progi1984) - - #17399: Expand Categories search capabilities for categories listing home page and avoid going from subcategory to root category when using grid filters (by @matks) - - #19929: Fixes the import configuration save (by @Progi1984) - - #19955: Rename AddCustomizationFieldsCommand to AddCustomizationCommand (by @zuk3975) - - #19646: Synchronize cart_product and order_detail when quantity is changed (by @sowbiba) - - #19828: Check for ::GRID_ID when definition is AbstractGridDefinitionFactory (by @atomiix) - - #19778: Cast changelogs to array for twig (by @atomiix) - - #19698: Fix order view total discounts (by @zuk3975) - - #19712: Move smarty variables assignments in initHeader instead of init function (by @PierreRambaud) - - #19820: Hooks displayAdminOrderTabLink or displayAdminOrderTabContent displayed not escaped to allow raw HTML (by @clotaire202) - - #19796: Missing fancybox plugin in new theme pages (by @PierreRambaud) - - #19506: Handle AbstractGridDefinitionFactory compatibility (by @matks) - - #19716: Remove i18n access restrictions (by @PierreRambaud) - - #19546: Fix scrollbar on order page when adding product (by @antoinedamiron) - - #19448: Fix AdminModulesController fatal error (by @Matt75) - - #19452: Fix to show the Modules tab in the product editor - backport of #19216 to 1.7.7.x (by @matks) - - #18875: BO - Create Order page - Defined the order status relative to payment (by @Progi1984) - - #18456: Update cart currency when order currency changes (by @sowbiba) - - #18923: Multistore: Fix error when viewing an order with custom product made on secondary shop (by @matthieu-rolland) - - #19205: Fix catalog price rule - Currency sort and filter not working & save button design - Backports of #19020 and #19021 for 1.7.7.x (by @matks) - - #19108: Extend OrderController with FrameworkBundleAdminController instead of CommonController (by @zuk3975) - - #19103: Redirect to dashboard when employee default page is unauthorized (by @sowbiba) - - #19089: Fix bug keeping user from accessing his profile page in BO (by @matthieu-rolland) - - #19086: BO - New Product - In MultiLang BO, the default name input wasn't in the employee language (by @Progi1984) - - #19039: Fix product pagination in order with customization (by @atomiix) - - #19032: Update ps_themecusto to the latest version (by @atomiix) - - #19058: Refresh invoices total when product price is updated (by @sowbiba) - - #18580: In BO Product page, use ecotax excl. tax instead of tax incl. (by @matks) - - #17179: Fix free gift product in Order create page (by @zuk3975) - - Refactoring: - - #19981: Refactor cancel product and bug fix (by @matthieu-rolland) - - #18984: Remove legacy files for Order page (by @matks) -- Front Office: - - Improvement: - - #19706: Don't try to translate using domain unless the "d" parameter is present (by @eternoendless) - - Bug fix: - - #20555: Fix images quickview also updating product page by changing product i… (by @NeOMakinG) - - #19631: FO: fix cumulative percentage reduction amount value in cart (by @matthieu-rolland) - - #19896: Fix lang dropdown by adding jquery migrate (by @NeOMakinG) - - #19437: Make product image in list overridable (by @jolelievre) - - #19139: Do not use cache while checking if an order exists (by @PierreRambaud) - - #19456: Fix voucher display for single customer - backport of #19443 to 1.7.7.x (by @matks) - - #19395: Return 404 in frontoffice if return merchandise is disabed (by @clotaire202) - - #17502: Fix cart voucher values in cart summary and checkout summary (by @arouiadib) - - #19347: Use Country from global namespace (by @prestamodule) - - #18993: Fix discount display on multicurrency context (by @sowbiba) - - #18884: FO: Display 'free' as shipping cost in the cart when a cart rule grants free shipping (by @matthieu-rolland) -- Core: - - New feature: - - #19782: Allow modules to disable routing prefix with specific parameter (by @matks) - - Improvement: - - #20547: Update module productcommentsto v4.1.0 (by @matks) - - #20137: Computing precision: set minimum computing precision value to zero (by @matthieu-rolland) - - #20324: Set editorconfig to indent yml files using 4 spaces instead of two (by @eternoendless) - - #19461: Remove MBO-related api calls from core (by @atomiix) - - #19752: Update licenses headers (by @PierreRambaud) - - #19556: Update modules (contactform/ps_imageslider/ps_sharebuttons/statspersonalinfos) (by @Progi1984) - - Bug fix: - - #20570: Update _PS_JQUERY_VERSION_ to match the included jQuery version (by @eternoendless) - - #12578: Fix wrong use of alias when registering new hook (by @eternoendless) - - #20408: Fix bug on Invoices tax detail (by @matthieu-rolland) - - #20398: Fixed Cache Problem in Language & Currency (by @Progi1984) - - #15049: Fix wrong hook names (by @eternoendless) - - #20192: Remove tables upgrade lines related to gamification module (by @PierreRambaud) - - #18532: Increase precision for DECIMAL fields in database (by @atomiix) - - #19581: Fix bugs occuring when an order state is deleted but still assigned to orders (by @matthieu-rolland) - - #19858: Update jquery.live.polyfill npm dependency (by @PierreRambaud) - - #19657: Deprecate hookcount and add missing hook in hook.xml (by @atomiix) - - #19016: Add mapping for Doctrine core entities on front environment (by @jolelievre) - - #19409: Add missing index.php in upload directory (by @PierreRambaud) - - #18811: Introduce CompilerPass to perform ControllerAwareTrait injection (by @matks) - - #15871: Avoid error when trying to translate an invalid module (by @PululuK) - - #19063: Fix simplfied url not properly set for multilang categories (by @matthieu-rolland) - - #18697: Fix error when updating a used address with no DNI (by @shaffe-fr) - - #18845: Add tag controller.service_arguments to PrestaShop controllers (by @matks) - - #18851: Build assets for Beta (by @jolelievre) - - Refactoring: - - #19748: Update decimal library (by @jolelievre) -- Installer: - - Improvement: - - #19788: Allow user to choose to drop existing tables or not even when not in dev mode (by @Progi1984) - - #19694: Allow user to choose to install demo products or not even when not in dev mode (by @eternoendless) - - Bug fix: - - #20122: Fix session tables charset (by @jolelievre) - - #19887: Add missing comma (by @atomiix) - - #19274: Add a missing comma in 1.7.7.0 upgrade file (by @Quetzacoalt91) - - #18834: Remove newsletter registration during installation (by @PierreRambaud) -- Web Services: - - Bug fix: - - #18859: Defined Currency Context if needed in WebService Context (by @Progi1984) -- Localization: - - Improvement: - - #19897: Update German tax rates (by @Progi1984) - - #18902: Avoid nested wordings chains (by @jolelievre) -- Tests: - - Improvement: - - #20312: Improve combination tests, use IDs instead of names to check quantities (by @jolelievre) - - Bug fix: - - #18613: Cart rule order tests (by @jolelievre) - - Refactoring: - - #20586: Functional tests - Add test 'Filter image types' (by @boubkerbribri) - - #20486: Functional tests - Enable/Disable display attributes in product meta title (by @nesrineabdmouleh) - - #20569: Functional tests - Add new tests for stores page (by @boubkerbribri) - - #20559: Functional tests - Add test 'Filter stores' (by @boubkerbribri) - - #20543: Functional tests - Add test 'Filter groups' (by @boubkerbribri) - - #20539: Functional tests - Update exchange rate (by @nesrineabdmouleh) - - #20502: Functional tests - Add new test 'Create customer from create order page' (by @boubkerbribri) - - #20540: Functional tests - Add tests for seo pages (by @boubkerbribri) - - #20521: Functional tests - Add new test 'Configure module' (by @boubkerbribri) - - #20468: Functional tests - Search hook in Positions page (by @nesrineabdmouleh) - - #20460: Functional tests - Update test filter categories (by @boubkerbribri) - - #20450: Functional tests - Update linkchecker urls (by @boubkerbribri) - - #20459: Functional tests - Add new test 'Select default Theme' (by @boubkerbribri) - - #20440: Functional tests - Enable using loginCommon with different user than default one (by @boubkerbribri) - - #20439: Functional tests - Avoid 'home' as new category to create (by @boubkerbribri) - - #20418: Functional tests - Add tests for titles page (by @boubkerbribri) - - #20394: Functional tests - Add test 'Search customers in create order page' (by @boubkerbribri) - - #20302: Functional tests - Add update a language (by @nesrineabdmouleh) - - #20368: Functional tests - Add browser listeners to tests (by @boubkerbribri) - - #20360: Functional tests - Reset orders before going to order view page (by @boubkerbribri) - - #20318: Functional tests - Add new test 'View guest from orders page' (by @boubkerbribri) - - #20293: Functional tests - Add new test 'Carrier restrictions' (by @boubkerbribri) - - #20280: Functional tests - Create new test 'View customer from orders page' (by @boubkerbribri) - - #20241: Functional tests - Modify translation (by @nesrineabdmouleh) - - #20215: Functional tests - Add checking order status in FO after update status in BO (by @boubkerbribri) - - #20210: Functional tests - Add 'Sort orders' tests (by @boubkerbribri) - - #19997: Functional tests - Separate browser page and page objects (by @boubkerbribri) - - #20086: Functional tests - Test pagination of products table (by @nesrineabdmouleh) - - #20046: Functional tests - Do not skip steps in CRUD category and subcategory scenario (by @boubkerbribri) - - #19983: Functional tests - Update playwright version (by @nesrineabdmouleh) - - #19785: Functional tests - Delete unused selectors and methods (by @nesrineabdmouleh) - - #19920: Functional tests - Wait for neworkidle in wait for navigation function (by @boubkerbribri) - - #19727: Functional tests - Update linkchecker for playwright (by @boubkerbribri) - - #19802: Delete test identifiers redundant and license notice in all tests (by @nesrineabdmouleh) - - #19775: Functional tests - Improve delete categories by bulk action ad set required fields function (by @boubkerbribri) - - #19749: Functional tests - Fix wait for navigation and disable category tests (by @boubkerbribri) - - #19725: Functional tests - Increase timeout after disabling a category (by @boubkerbribri) - - #19653: Functional tests - Switch tests to playwright (instead of puppeteer) (by @boubkerbribri) - - #19489: Remove unused test (by @SimonGrn) - - #19339: Functional tests - Update tests contexts (by @boubkerbribri) - - #19235: Functional tests - Test pagination and sort of pages and categories (by @nesrineabdmouleh) - - #19208: Functional tests - Test pagination of suppliers table (by @nesrineabdmouleh) - - #19257: Functional tests - Delete bo base page shop params tests (by @boubkerbribri) - - #19210: Functional tests - Test pagination of files table (by @nesrineabdmouleh) - - #19206: Functional tests - Delete bo base page from design tests (by @boubkerbribri) - - #19202: Functional tests - Delete bo base page from catalog tests (by @boubkerbribri) - - #19223: Functional tests - Delete test filter stocks by categories (by @boubkerbribri) - - #19203: Functional tests - Pagination brands and addresses (by @nesrineabdmouleh) - - #19186: Functional tests - Test pagination of categories table (by @nesrineabdmouleh) - - #19194: Functional tests - Delete bo base page customers tests (by @boubkerbribri) - - #19185: Functional tests - Delete BoBasePage from order messages tests (by @boubkerbribri) - - #19183: Functional tests - Delete bo base page for advanced params tests (by @boubkerbribri) - - #19158: Functional tests - Test customers pagination (by @nesrineabdmouleh) - - #19160: Functional tests - Test addresses pagination (by @nesrineabdmouleh) - - #19138: Functional tests - Delete boBasePage for tests modules (by @boubkerbribri) - - #19153: Functional tests - Delete BoBasePage from payment tests (by @boubkerbribri) - - #19159: Functional tests - Delete bo base page from international tests (by @boubkerbribri) - - #19157: Functional tests - Delete bo base page from invoices tests (by @boubkerbribri) - - #19137: Functional tests - Sort order messages table (by @nesrineabdmouleh) - - #19027: Functional tests - Export sql query (by @nesrineabdmouleh) - - #19126: Functional tests - Sort all tables in monitoring page (by @nesrineabdmouleh) - - #19133: Functional tests - Delete boBasePage for functional tests orders (by @boubkerbribri) - - #19067: Functional tests - Sort profiles (by @nesrineabdmouleh) - - #19127: Functional tests - Delete bo base page from sanity tests (by @boubkerbribri) - - #19069: Functional tests - Profiles pagination (by @nesrineabdmouleh) - - #19088: Functional tests - Filter and sort files (by @nesrineabdmouleh) - - #19109: Functional tests - Add test subscribe to newsletter from BO (by @boubkerbribri) - - #19071: Functional tests - Add test taxes pagination (by @boubkerbribri) - - #19092: Functional tests - Edit home category (by @nesrineabdmouleh) - - #19074: Functional tests - Add test pagination order message (by @boubkerbribri) - - #19066: Functional test - Add test quick edit languages (by @boubkerbribri) - - #19004: Functional tests - Sort suppliers table (by @nesrineabdmouleh) - - #18990: Functional tests - Enable/Disable log emails (by @nesrineabdmouleh) - - #18977: Functional tests - Test pages pagination (by @nesrineabdmouleh) - - #18877: Functional tests - Change selectors for FO pages (by @nesrineabdmouleh) - - #18899: Functional tests - Country restrictions (by @nesrineabdmouleh) - - #18871: Functional tests - Update default currency (by @nesrineabdmouleh) - - #18963: Functional tests - Test page category pagination (by @nesrineabdmouleh) - - #18886: Functional tests - Fix test invoices and products settings (by @boubkerbribri) - - #18896: Functional tests - Change selectors for design pages (by @boubkerbribri) - - #18868: Functional tests - Change selectors for modules pages (by @boubkerbribri) - - #18922: Functional tests - Delete not working test (by @boubkerbribri) - - #18862: Functional tests - Change selectors for shop parameters pages (by @boubkerbribri) - - #18873: Functional tests - Change selectors for customers pages (by @boubkerbribri) - - #18870: Functional tests - Change selectors for customer services pages (by @boubkerbribri) - - #18878: Functional tests - Change selectors for international pages (by @boubkerbribri) - - #18866: Functional tests - Fix adding customer to voucher (by @boubkerbribri) - - #18849: Functional tests - Change selectors for catalog pages (by @boubkerbribri) - -#################################### -# v1.7.7.0-beta.1 - (2020-05-13) -#################################### - -- Back Office: - - New feature: - - #18464: Add modal to customer address listing on bulk action (by @matthieu-rolland) - - #18063: Use localized dates for order page (by @matks) - - #17752: Add Prev/Next order button in the Order page (by @tdavidsonas88) - - #17660: Migration of order view page printing functionality and layout changes - part 4 (by @matks) - - #17416: Migrate standard refund and return products in order page (by @jolelievre) - - #16820: Enable confirm modal for catalog > files listing for bulk delete action (by @matks) - - #16668: Integrate a Vue component to manage Currency customization in the BO (by @jolelievre) - - #16467: Migrate partial refund (by @matthieu-rolland) - - #16815: Unhide new migrated Catalog > Files Symfony page (by @matks) - - #16255: Migration of order view page messages block (by @tomas862) - - #14972: Add/Edit a currency with the CLDR implementation (by @jolelievre) - - #16065: Migrate Shipping block of new Order View page (by @sarjon) - - #14682: Add preview extension for Grids (by @sarjon) - - #15995: Migrate create order part 3. Implement vouchers managing (by @zuk3975) - - #16008: Add Order status update in Order View page (by @sarjon) - - #15908: Introduce list dropdown - used in order list page (by @tomas862) - - #14320: Introduce NumberMinMaxFilterType and IntegerMinMaxFilterType (by @tomas862) - - #14198: Add Commands/Queries Profiler tab (by @sarjon) - - #10780: Introduce custom error pages (by @sarjon) - - #13593: Automated hooks discovery and updating hooks list in xml and sql files for modern pages using Grid and FormBuilder (by @tomas862) - - Improvement: - - #18329: View order page: Display correction - 2 (by @NeOMakinG) - - #17385: Confirm modal on restoring currency settings (by @sowbiba) - - #17959: Enable new Orders page (by @matks) - - #17090: Allow "add address" and "add customer" and "edit address" buttons to be handled in modal (by @matks) - - #17702: Order Page: Keep email failure from blocking product cancellation (and some refactor) (by @matthieu-rolland) - - #17568: Increase order price font size and colors for better contrast (by @atomiix) - - #16287: Don't duplicate currencies in DB when creating a formerly deleted one (by @matthieu-rolland) - - #17583: Migration 1.7.7.x Register all new hooks (by @tdavidsonas88) - - #17478: Cherry picked the changes from develop related to Refactor UI kit form #16964 and applied to 1.7.7.x (by @tdavidsonas88) - - #17456: Introduces checkbox in list filter row (by @tomas862) - - #17287: Enable bulk delete modal for Languages, Taxes, CMS Pages, CMS Cats (by @matks) - - #17135: Orders > Product : Display "Stock Location" column only if it is not empty (by @Progi1984) - - #17211: Reintegrate partial refund in the order view page (by @jolelievre) - - #16722: Orders > Products : Display content of a pack (by @Progi1984) - - #17286: Enable bulk delete modal for Suppliers, Brands, Brand adresses (by @matks) - - #16150: Migrate order product management (by @sarjon) - - #17079: Improve modal object without using this (by @NeOMakinG) - - #16821: Add empty states for Catalog > Files and Orders > Credit slips pages (by @matks) - - #16658: Use tab attribute as fallback when a module does not have category (by @PierreRambaud) - - #16432: Module alias in webpack configuration for the new-theme (by @PierreRambaud) - - #16440: Added indexes for product reference and supplier_reference (by @Gamesh) - - #16570: Provides several UX improvements for order pages and allows to change order addresses (by @matks) - - #16662: Fix PHP docblocks (by @mfurga) - - #16552: Add generic ButtonBulkAction and javascript to handle open in tabs (by @jolelievre) - - #16318: Make migrated order page's grid rows clickable (by @matthieu-rolland) - - #16532: Remove useless debug controller actions (by @matks) - - #15958: New design on module positions page (by @Progi1984) - - #15707: Improve query performance in order status update due very slow StockManager.php queries (by @gennaris) - - #16304: Change wording of lifetime of BO cookies help label (by @atomiix) - - #16046: Migrate Documents block of Order View page (by @sarjon) - - #16084: Migrate Merchandise returns for Orders view (by @sarjon) - - #16281: Update wording and add a link in product options tab (by @marionf) - - #16278: Use https links to doc instead of http (by @matks) - - #16033: Introduces kpi design update for orders listing page - also includes layout changes for all kpi's in migrated pages (by @tomas862) - - #16088: Disable Customer group selection checkbox when single customer is set… (by @atomiix) - - #16224: Add tax information in combination table (by @marionf) - - #16230: Add tax information for ecotax field (by @marionf) - - #14809: Allow modifying email body contents (by @jolelievre) - - #16090: Implement new Order View header (by @sarjon) - - #16060: Minor improvements for Orders list (by @sarjon) - - #15798: Remove optin field from the employee creation form (by @matthieu-rolland) - - #15886: Improve pop up information on Category deletion (by @Progi1984) - - #15084: Remove price precision in admin shop preferences (by @matthieu-rolland) - - #15808: Introduce icons instead of dropdown column for Orders page list (by @tomas862) - - #15245: Update jQuery to 3.4.1 in the legacy Back Office pages (by @matthieu-rolland) - - #14396: Migrate Catalog > Attributes&Features > Features > Add new/edit feature page (blocked by faceted_search update) (by @rokaszygmantas) - - #15130: Simplify rendering of forms (by @sarjon) - - #15761: Fix order view page wordings (by @matks) - - #12855: Add Manufacturer Part Number in product codes (by @rblaurin) - - #14767: Behat tests for Seo & Urls page commands - some code improvements (by @tomas862) - - #15765: Fix parameter $id_hook phpdoc (by @JBWModules) - - #15484: Add Malagasy language (by @OneDotIT) - - #14689: Fix BO menu scrollbar size on small screens (by @PierreRambaud) - - #14679: Introduce automatic Tab registration with symfony routes, menu now handles disabled modules (by @jolelievre) - - #14586: Implement Circuit Breaker for fetching blog news (by @Progi1984) - - #14249: Case-insensitive hook dispatching (by @tomas862) - - #13198: Create SF command to return routes with missing _legacy_link (by @zuk3975) - - #13472: Create SF command to list tactician commands and queries (by @zuk3975) - - #13241: Add grid extension to disable filters submit button when filters are empty (by @zuk3975) - - Bug fix: - - #18812: Fix invoices refresh when adding product in an order (by @atomiix) - - #18764: Fix exception when deleting address from customer view (by @sowbiba) - - #18524: Remove ability to apply discount on all invoices in order view page (by @zuk3975) - - #18635: Show confirm modal when adding product with new invoice (by @zuk3975) - - #18566: Fix bad display of customizable product on create order page by removing margin and overflow (by @NeOMakinG) - - #18445: Fix tooltip on product buttons of Order View staying on the page after delete and not being visible when adding a product (by @NeOMakinG) - - #18200: Fix "weird behaviour when filling the quantity field with letters of symbols" (by @arouiadib) - - #18544: Show new invoice information when adding product with new invoice in BO Order (by @zuk3975) - - #18196: Refresh documents tab when adding product in order view page (by @atomiix) - - #18686: Rename CountryChoiceType options using camel case convention (by @jolelievre) - - #18641: Show confirmation modal before deleting order messages (by @zuk3975) - - #18348: Cart products update (by @jolelievre) - - #17852: Fix exception when adding negative amount/percentage discount in order view (by @atomiix) - - #18515: Fix some css to avoid max width on many languages (by @NeOMakinG) - - #18438: Fix currency buttons on edit and add page not aligned by adding styles and changing markup (by @NeOMakinG) - - #18437: Fix sidebar not displayed in BO order page (by @matthieu-rolland) - - #18204: BO : Order > Products : The block discounts was not displayed after adding a product (by @Progi1984) - - #17736: Fix products search results order in SearchProductsHandler (by @zuk3975) - - #18321: Do not stack free shipping vouchers on total: shipping fees applied once (by @matks) - - #18228: Improve common search controller for backward compatibility (by @jolelievre) - - #17850: Rework OrderRefundCalculator to use Number (by @zuk3975) - - #18416: Fix overflow on main-menu and adjust workaround on last items in menu (by @NeOMakinG) - - #18419: Fix currency symbol in orders list (by @sowbiba) - - #17927: Wrong prices in edit order with secondary currency (by @sowbiba) - - #18334: Add FancyBox in create order page details button (by @jolelievre) - - #18326: Fix messages block in order view page (by @zuk3975) - - #18373: Avoid date time split in Grids (by @jolelievre) - - #18205: BO : Add Product on Order : Use previous cart rather than creating a new one (by @Progi1984) - - #18347: Hide order preview stock location column if empty (by @atomiix) - - #18305: Fix count query with customer filter (by @atomiix) - - #17864: Extract order products to separate query (by @zuk3975) - - #17938: Fix conversion when adding payment to order (by @sowbiba) - - #17801: View and Create Order feedbacks corrections (by @NeOMakinG) - - #18164: Use hasBeenPaid instead of hasInvoice to enable refund feature (by @jolelievre) - - #18266: Add target options to index grid of orders on customer column (by @NeOMakinG) - - #17526: Fix customer address form (by @zuk3975) - - #17853: BO: Fix shipping price tax issue on order creation page (by @matthieu-rolland) - - #18288: Fix wrong number of orders when filter 'New client' on (by @atomiix) - - #18294: Return null when value is an empty string in ArabicToLatinDigitDataTransformer (by @atomiix) - - #18208: Increase quantity when adding an already added product when creating order (by @atomiix) - - #17975: Convert arabic/persian digits to latin digits in DatePickerType (by @atomiix) - - #18102: Fix sidebar submenu opening by changing style and adding JS (by @NeOMakinG) - - #18245: Fix orders page dropdown going under header by adding a flip false property (by @NeOMakinG) - - #18124: Modifying address from order should duplicate it and soft delete former address (by @jolelievre) - - #18246: Add check when adding a product in an order that it is not out of stock (by @jolelievre) - - #18168: Prevent adding or editing an invalid product quantity on order (by @jolelievre) - - #18202: Do not display shipping address when order is virtual product only (by @atomiix) - - #17861: Add vertical scroll to customization fields in BO order create page (by @zuk3975) - - #18091: Display gift message into migrated Order page (by @matks) - - #17881: Fix Search by product name & category doesn't work in the second of the Stocks page (by @arouiadib) - - #18146: After creating new voucher from orders/new, I get redirected to voucher list, not a new order (by @tdavidsonas88) - - #17849: Fix orders page dropdown going under header by removing the fixed property (by @NeOMakinG) - - #17672: Rework ChangeOrderCurrencyHandler to private methods (by @zuk3975) - - #17292: Fixes undefined vars in some migrated controllers (by @zuk3975) - - #18101: Fix typo in hook descriptions (by @jolelievre) - - #17476: Don't allow comma in order payment amount field (by @atomiix) - - #17986: Fix "Module Manager" menu item not being translatable (by @eternoendless) - - #17839: Wrap OrderController::viewAction in try-catch (by @zuk3975) - - #17482: Allow token for TokenisedUrlsListener class and in form using the method=GET attribute (by @PierreRambaud) - - #18054: In RTL I have to click 3 times on the checkbox to select the product (by @tdavidsonas88) - - #17985: Fix customer informations on order page when customer is a guest (by @matthieu-rolland) - - #18045: Fix selector for invoice note manager (by @tdavidsonas88) - - #17742: Fix country states input toggle on page load (by @zuk3975) - - #17650: Fixed display for first cell (select all & input) in grid (by @Progi1984) - - #17877: Fix bug when adding a discount on order page (by @matthieu-rolland) - - #17804: Fix bug when changing addresses on virtual product command (by @matthieu-rolland) - - #17913: Remove useless TinyMCE scripts from brand form pages (by @jolelievre) - - #17799: Order Page: Fix private note that cannot be emptied (by @matthieu-rolland) - - #17973: Fix pagination on migrated order listing (by @matthieu-rolland) - - #17884: Use constant for reduction type in CatalogPriceRuleGridDataFactory (by @zuk3975) - - #17796: Fix new wording without domain (by @eternoendless) - - #17535: Fix deleted customer's order preview/details (by @atomiix) - - #17700: Wrong address update when changing the shipping adresse of an order (by @atomiix) - - #17305: Adds optional DNI field and missing post_code handling in supplier form (by @zuk3975) - - #17220: Fix multiple bugs in order view page (by @zuk3975) - - #17641: Fixed Exception for not defined variables when editing a product quantity in an order (by @Progi1984) - - #17649: Fix wrong address edit link in order detail (by @atomiix) - - #17614: Missing assets generation (by @PierreRambaud) - - #17612: Fixed Empty Option in Smarty Form in Advanced Parameters > Performance (by @Progi1984) - - #17547: Fix grids, when search finds no result we still display filters and reset button (by @matks) - - #17448: Fix create order info missing (by @atomiix) - - #17531: Remove irrelevant Todo in order messages (by @zuk3975) - - #17444: Change tinymce lang when changeLanguage event is fired (by @NeOMakinG) - - #17465: Fix create order customization/combinations (by @atomiix) - - #17366: Added missing admin security annotations (by @RaimondasSapola) - - #17421: Delete free shipping voucher after creating an order on BO (by @zuk3975) - - #17445: Fix wrong address edit link (by @atomiix) - - #17241: Do not allow negative amount in order payment block (by @atomiix) - - #17325: Fix cart re-rendering after customer not found in Order creation (by @zuk3975) - - #17381: Show product customizations in the order BO page (by @atomiix) - - #17373: Fix currency localization (by @atomiix) - - #17413: Fixed warning about Maxmind DB in Geolocalization page (by @Progi1984) - - #17377: Fix modal not being hidden sometimes (by @atomiix) - - #17404: Fix order creation bug due to wrong computing precision (by @matthieu-rolland) - - #17191: Translate exception message when customer not found on address creation form (by @sowbiba) - - #17279: Fix monitoring page sorting (by @matks) - - #17331: ProfileId accepts int and string as input type although int value is required (by @jolelievre) - - #17291: Display symbols in form in case of error, remove DefaultLanguage constraint (by @jolelievre) - - #17180: Fix suppliers form description to be optional (by @zuk3975) - - #17232: Rebuild Create an Order page assets (by @matks) - - #17229: Recompute FOSJSRouting JSON file (by @matks) - - #17132: Javascript errors in BO's webservice and login page (by @matthieu-rolland) - - #16883: Fixed filtering for date in Back Office / Logs (by @PrestaworksNiklas) - - #16860: Fix United Kingdom VAT issue for all EU countries (by @jf-viguier) - - #16765: Fix recursive check of updated files (by @Darhazer) - - #16946: Modified the string in success alert for attachements bulk deletion (by @arouiadib) - - #16307: Cast employeeId to int in the bulk update employee command (by @atomiix) - - #16074: Prioritize customer search by id when saving an address (by @levyn) - - #16510: Avoid dropdowns from module page to appear under header element (by @NeOMakinG) - - #16560: Fix header for migrated Orders pages (by @matks) - - #16548: Use CMSCategory instead of CMS object model (by @PierreRambaud) - - #16542: Fix specific prices not being displayed in the BO (by @PierreRambaud) - - #16541: Fix pagination on product page listing (by @PierreRambaud) - - #16535: Fix TinyMCE not loading on safari in CMS page (by @NeOMakinG) - - #16530: Use country id while creating the Supplier form (by @PierreRambaud) - - #16457: Enable TinyMCE on add/edit supplier page BO (by @matks) - - #16461: Display display_name instead of name in theme card and add author.url (by @NeOMakinG) - - #16392: Fix error when trying to the change the quantity of a free product in an order in the BO (by @Progi1984) - - #16394: Fix typo in condition (by @mvorisek) - - #16375: Fix wrong case sensitiveness for email addresses (by @PierreRambaud) - - #16360: Fix output buffer not closed in Twig\HookExtension::renderHooksArray (by @jnvsor) - - #16319: Use customer group price display preference when displaying orders in BO (by @matks) - - #16312: Fix incorrect display value in Price Tab of admin product controller (by @WebXYAgency) - - #16159: Fix category checkbox redirect (by @atomiix) - - #16225: Fix prices display in new order page (by @sarjon) - - #16285: Fix ajax spinner not disappearing after Ajax is done (by @eternoendless) - - #16209: Use local fonts in BO default theme (by @eternoendless) - - #16271: Remove useless checkbox in product options tab for attached files (by @marionf) - - #16266: Fix ajax exception when search for a product in order creation page (by @matthieu-rolland) - - #16075: Some fixes to Orders page (by @sarjon) - - #16222: Fix error when deleting order cart rule (by @sarjon) - - #16175: Fix label not in place on BO products page in Filter by categories (by @atomiix) - - #16123: Delete supplier's address only if no other shops use it (by @atomiix) - - #16045: Fix swap-select values not being submitted in generated AdminController forms (by @L3RAZ) - - #15906: Fixes issue Undefined index _route (by @Gamesh) - - #16089: Fix "Invalid parameter: '' cannot be interpreted as a number" error (by @Progi1984) - - #16071: Fix "Call to a member function formatPrice() on null" fatal error (by @Progi1984) - - #15511: Make sure the keys used for translation are case sensitive (by @jocel1) - - #15926: Fix error SQL in getRecurseCategory method (by @marionf) - - #15909: Fix for product images in multishop BO (by @PrestaworksJonas) - - #15900: Replace usages of jQuery.live usages and add polyfill (by @matthieu-rolland) - - #15757: Fix monitoring grids id configuration (by @zuk3975) - - #15428: Add check for required fields in BO > Country > Address format (by @matthieu-rolland) - - #15514: Add condition to avoid duplicate invoice line. (by @FlorentinGarnier) - - #15111: Fix wording domains (by @eternoendless) - - #15712: Fix tabs on the product page when in Polish (by @Progi1984) - - #15546: Fix bad combination dropdown in cart rule (by @idnovate) - - #14925: Copy images from SCSS directory to the public directory when building the new theme (by @Progi1984) - - #15429: Fix Add an Employee Handler with int casting required (by @matks) - - #15397: Escape Employee email in avatar block (by @PierreRambaud) - - #15325: Remove reference to non existent css file (by @eternoendless) - - #14879: Allow changing the position of products in a category in the catalog > product page (by @PierreRambaud) - - #14168: Add missing check for CMS page category existence on create/edit actions (by @zuk3975) - - #14959: Add duplicate prices feature (by @202-ecommerce) - - #15005: Fix incorrect last visit date in the customer grid (by @cirykpopeye) - - #14977: Fix Search customer in specific group (by @khouloudbelguith) - - #13730: Fix wrong price display in BO when using a specific price in a different currency (by @123monsite-regis) - - #12903: Match multiline translation expressions in modules (by @unlocomqx) - - #12497: Fix issue with the link Manage tax rules in the pricing tab (by @khouloudbelguith) - - #13980: Execute displayAdminLogin hook without shop context (by @idnovate) - - #14656: Fix editing shop association in Category and Manufacturer (by @zuk3975) - - #14307: Fix manufacturers grid logo to not depend from shop context (by @zuk3975) - - #14543: Wrong path of products thumbnails in back office (by @matthieu-rolland) - - #14540: Update Import controller to get errors for bad category import (by @webmak) - - #14613: Fix broken translations in module list page (by @matthieu-rolland) - - #14466: Fix saving of selected BO language (by @rokaszygmantas) - - #14530: Use Preview link without option for seo preview (by @PierreRambaud) - - #14525: Fix php warning in php 7.2 in case of JSON output (by @202-ecommerce) - - #12997: Add disabled visual effect on disabled elements on the translation interface (by @francoispeyret) - - #14308: Fix wrong tax when duplicating product in BO with several taxes (multishop) (by @202-ecommerce) - - #14310: Adds missing fields validation in tax create/edit handlers (by @zuk3975) - - #14450: Whitelist filters for the Logs Page (by @Progi1984) - - #13959: Fix duplicate include of JS files in BO (by @idnovate) - - #14223: Fix unescaped dash in character group in autoloader regex (by @mvorisek) - - #14292: Update php-cs-fixer to latest version (by @MathiasReker) - - #13971: Fix dashboard sales stats to account for taxes and shipping costs (by @ComonSoft) - - #13894: Hook displayBackOfficeTop should be in nav container (by @jf-viguier) - - #13382: Remove money symbol from specific price reduction field (by @YeLnatSs) - - #14004: Fix generate path thumbnail image (by @dariusakafest) - - #13798: Use password input type for imap password field (by @marionf) - - #13571: Enable grid search button by default (by @zuk3975) - - #13572: Add FiltersSubmitButtonEnablerExtension to profiles page (by @zuk3975) - - #13454: Fix on product redirect in SEO tabs (by @YeLnatSs) - - #13425: Fix border inside tabs even when counter is empty (by @YeLnatSs) - - Refactoring: - - #18130: Use grid common search action where possible (1.7.7.x controllers only) (by @zuk3975) - - #17907: Fix TinyMCEEditor that shouldn't handle language switching by adding a TranslatableField (by @NeOMakinG) - - #17528: Fix all 1.7.7.x controllers and routes to comply with conventions (by @tdavidsonas88) - - #17715: Fix print css (by @matks) - - #17187: Delete migrated AdminRequestSqlController again - part 2 (by @matks) - - #17077: Remove unused legacy Customer Adresses files (by @matks) - - #17169: Refacto partial refund handler (by @jolelievre) - - #17175: Replace partialRefund form/builder/dataProvider with CancelProduct (by @matthieu-rolland) - - #16207: Migrate summary block of BO create order page (by @zuk3975) - - #15300: Migration for Sell > Customers > Addresses create/edit forms (by @RaimondasSapola) - - #15003: Migration Catalog > Files and Catalog > Files Edit and create forms (by @RaimondasSapola) - - #16588: Unhide monitoring sf page (by @matks) - - #16621: Remove legacy unused Order Slip files (by @matks) - - #13903: Migrate Sell > Orders > Credit slips page (by @zuk3975) - - #16267: Finish migration "Catalog > Monitoring" page (by @atomiix) - - #14288: Migrate Customer Service view (by @sarjon) - - #15229: Migration of Sell > Customers > Addresses page (by @RaimondasSapola) - - #13716: Migrate Sell > Catalog > Catalog price rule create/edit action (by @zuk3975) - - #15915: Migration of International > Taxes > Tax rules page (by @matks) - - #15982: Migrate product component for Orders page (by @RaimondasSapola) - - #16022: Migrate order action and status block (by @sarjon) - - #15901: Implement discounts management in Order View page (by @sarjon) - - #15899: Migrate BO order creation page - part 2. Handle shipping block (by @zuk3975) - - #15955: Migrate Customer block of Order view page (by @sarjon) - - #15778: Migrate Payment block of Order view page (by @sarjon) - - #14040: Migrate Sell > Catalog > Attributes & Features > Attributes list (by @zuk3975) - - #14864: Migrate Catalog > Files page (by @RaimondasSapola) - - #15814: Implement cart information providing in BO order creation page - part 1 (by @zuk3975) - - #15766: Prepare Twig templates for Add Order page (by @zuk3975) - - #15650: Migrate "Catalog > Brand & Suppliers > Suppliers create/edit action (by @matks) - - #13584: Migrate Sell > Catalog > Discounts > Catalog Price Rules list (by @zuk3975) - - #14707: Migration of "add cart rule" action (by @rokaszygmantas) - - #14991: Fix Monitoring grids data for multishop (by @zuk3975) - - #14869: Removes AdminPreferencesController again (by @matks) - - #14873: Remove AdminManufacturer controller again (by @matks) - - #14800: Add category to product CQRS command (by @matthieu-rolland) - - #14872: Delete migrated AdminCmsController again (by @matks) - - #13529: Migrate Sell > Catalog > Monitoring listing action (by @zuk3975) - - #13515: Migrate Sell > Catalog Brands & Suppliers > Suppliers view action (by @zuk3975) -- Front Office: - - New feature: - - #17410: Add FO hook displayFooterCategory (by @matks) - - #16013: New design for homepage slider on mobile (by @Progi1984) - - #14033: Introduce FO JS event showErrorNextToAddtoCartButton to handle shoppingcart error returns (by @matks) - - Improvement: - - #18221: Backport #16837 to 1.7.7.x : Add breadcrumbs to my account pages (by @matks) - - #17577: Prevent email enumeration (by @PierreRambaud) - - #16857: Changing brand page style (by @NeOMakinG) - - #16524: Switch select of ps_brandlist to a bootstrap dropdown (by @NeOMakinG) - - #16526: Change suppliers select into bootstrap dropdown (by @NeOMakinG) - - #16340: Fix bullets of bulleted lists being removed by default (by @rdy4ever) - - #16052: Fix Very strict selector div.delivery-option (by @davidglezz) - - #16180: Use Media Server for assets (CSS, JS, Images) (by @Progi1984) - - #16069: Change wording in FO when there is specific price by quantity (by @atomiix) - - #16063: Improve wording on order confirmation email (by @atomiix) - - #16126: Change checkout button wording (by @atomiix) - - #15916: Set emailsubscription input required (by @davidglezz) - - #15501: Updated blockReassurance in composer.json (by @Progi1984) - - #13517: Show free shipping indication only if appropriate (by @hacchus) - - #15750: Update jQuery to 3.4.1 in Core theme and Classic theme (by @matthieu-rolland) - - #15176: Enable modules to know the current checkout process step (by @matks) - - #15603: Allow access to Checkout process (by @matks) - - #15271: Use aria-label instead of .sr-only hidden span (by @davidglezz) - - #15354: Updated prestashop/ps_emailsubscription to 2.5.0, prestashop/ps_facetedsearch to 3.2.1, prestashop/ps_contactinfo to 3.2.0 (by @Progi1984) - - #15013: Fix URLs for non-default combinations (by @Amazzing) - - #14539: Make email display dependant on configuration from ps_contactinfo module (by @matthieu-rolland) - - #15055: Fix duplicate class attribute in HTML element (by @asf-harlock) - - #14710: Make last breadcrumb element not clickable (by @matthieu-rolland) - - #12883: Add breadcrumb to the suppliers page (by @SebBareyre) - - #12882: Add breadcrumb to the best sales page (by @SebBareyre) - - #12881: Add breadcrumb to the prices drop page (by @SebBareyre) - - #12880: Add breadcrumb to the new products page (by @SebBareyre) - - #14214: Handle shoppingcart error returns properly - part 2 (by @matks) - - #14437: Translate aria-label in modal close button (by @davidglezz) - - #14049: Allow template vars override in hook actionFrontControllerSetVariables (by @Matt75) - - #13383: UI improvements for classic theme (by @YeLnatSs) - - #14079: Update Smarty comments to reflect related blocks (by @prestamodule) - - Bug fix: - - #18427: Fix issue when there is a quantity discount on combination products (by @matthieu-rolland) - - #18743: Fix FO Exception after category add on multilang shop (by @sowbiba) - - #17917: Use appropriate hook name in contact right column (by @jolelievre) - - #18061: Order page: fix stock value update when editing a product (by @matthieu-rolland) - - #17843: Fix classic them subcategories in menu displayed hover menu by improving JS selector (by @NeOMakinG) - - #18073: Checkout address edition is failing due to missing id_address in action (by @PierreRambaud) - - #17767: Multishop - BO : Fix orders not appearing in order list for shared space shops (by @matthieu-rolland) - - #17901: The button add to cart shouldn't be enabled when minimal quantity > quantity (by @arouiadib) - - #17438: Fix submenu not displayed on mobile on classic theme (by @NeOMakinG) - - #17677: Reintroduce hook displayAdditionalCustomerAddressFields (by @eternoendless) - - #16863: Fix a bug where product images were not scrollable after product refresh (by @NeOMakinG) - - #17342: Make rewrite pattern non greedy (by @andromaque) - - #17349: Classic Theme : enable some hooks for BlockReassurance (by @Progi1984) - - #16520: Fix contact layout not working at all (by @NeOMakinG) - - #16574: Fix product cannot be deleted from cart IF another customization is made and not added to cart yet (by @Hlavtox) - - #16724: Fix multiple cart rules calculation (by @atomiix) - - #17005: Adding default "Select" when sort not up in FO is selected on category page (by @NeOMakinG) - - #16856: Show list bullets on product page and align it (by @NeOMakinG) - - #17002: Correcting price alignment on RTL language (by @NeOMakinG) - - #16915: Protect checkout forms to avoid submitting multiple times (by @atomiix) - - #16868: Show "No picture" image instead of broken one (by @prestamodule) - - #16638: Fix logic and display of customer's cart rules (by @Hlavtox) - - #16528: Change links block style in carrier process (by @NeOMakinG) - - #16571: Fix total tax in order confirmation (by @Hlavtox) - - #16531: Round remaining value of reduction amount (by @202-ecommerce) - - #16550: Fix var not displayed in emails when mail address is in uppercase (by @marionf) - - #16504: Display 3 products on the same line on home with 2 columns layout (by @NeOMakinG) - - #16503: Hide pack products' prices when the show price option is disabled (by @NeOMakinG) - - #16478: Fix shipping method design in payment tunnel (by @NeOMakinG) - - #16250: Fix wrong product alignment in product lists for smaller devices (by @rdy4ever) - - #16468: Fix issue where html tags from ps_emailsubscription module would be escaped and not interpreted as HTML (by @NeOMakinG) - - #16087: Fix no carriers in checkout bad cart rules (by @matks) - - #16147: Add CSS sizes for images in custom text block (by @Klemart3D) - - #16235: Fix how discounts are displayed in cart summary when using vouchers (by @matthieu-rolland) - - #16049: Fix number of DL & expiration date being displayed in the download virtual product mail (by @atomiix) - - #16114: Add missing placeholder in the Private Note textarea (by @atomiix) - - #16085: Get locale from Context current locale instead of repository in OrderDetailLazyArray (by @Progi1984) - - #15987: Check if customized product image exists before trying to delete it (by @jf-viguier) - - #16014: Fix html being displayed in download virtual product text mail (by @atomiix) - - #15872: Check mimum quantity for products in the basket order (by @matthieu-rolland) - - #15623: Do not allow to put item in cart if available quantity is 0 (by @matks) - - #15851: Fixed missing translation for tax label (by @JevgenijVisockij) - - #15706: Wrong combinaison reference in customer account order history (by @PululuK) - - #15799: Fix association of payment methods with delivery module (by @Seleda) - - #15840: Do not apply htmlentities before insterting message in db (by @matthieu-rolland) - - #15549: Fix calculation price in group reductions when in tax excluded mode (by @matthieu-rolland) - - #15297: Fix missing wrapper in quickview displayProductAdditionalInfo hook (by @dheerajwebkul) - - #15758: Fix image not correctly resized in FO product listing if height is too high (by @PierreRambaud) - - #14489: Disallow ordering a product that was transformed from regular into product with combinations (by @202-ecommerce) - - #15748: Use cover photo in listing instead of default combination (by @PierreRambaud) - - #13022: Remove deprecated customization constants & fix undefined index notice (by @shaffe-fr) - - #15739: Fix product not being added to cart after deleting product customisation (by @PeeyushAgrawalWebkul) - - #15710: Prevent rage clicking on checkout steps submit button (by @rdy4ever) - - #15216: Allow users to edit address alias during checkout (by @pauloffb) - - #15533: Disallow showing bad cart to FO user (by @matks) - - #15632: Remove unneccessary slash on Home category breadcrumb (by @JBWModules) - - #15399: Fix bug keeping users from choosing a carrier before cart order completion (by @matthieu-rolland) - - #15512: Fix unclosed

html tag (by @davidglezz) - - #15314: Fix not being able to remove automatically applied cart rule (by @damiandominella) - - #15352: Fix quicksearch results missing the category name (by @JulianEberius) - - #15368: Fix breadcrumb SEO (by @davidglezz) - - #15326: Fix color name not appearing over the color block in the product pages (by @dineshbadrukhiya) - - #15357: Fix typo and avoid card-block border show when note is empty (by @PrestaShark) - - #15276: Fix one column row without colspan (by @davidglezz) - - #14937: Fix display bug in classic theme when hooking the ps_emailsubscription module to the left column (by @Progi1984) - - #15167: Fix not product not appearing in search results after having enabled it (by @PeeyushAgrawalWebkul) - - #14727: Fix compile id {render} override issue on theme (by @202-ecommerce) - - #14819: Fix create account sitemap link (by @Thomas-lhuillier) - - #13677: Fix submenu hiding menu in classic theme (by @YeLnatSs) - - #14558: Implement Schema ItemList for products listing & Fix Schema Product (by @Progi1984) - - #14587: Fix issue when searching for long words in FO (by @matthieu-rolland) - - #14567: Remove image in about us CMS page (by @marionf) - - #14507: Fix bug in FO translations with multiple resources and tpl inclusions (by @202-ecommerce) - - #14422: Refactor theme usage of product flags - apply DRY (by @matks) - - #14452: Allow to buy a product without stock when other combinations have stock and unavailable product attributes are not displayed (by @Progi1984) - - #14263: Fix display voucher conversion between currencies (by @tomlev) - - #14385: Fixed duplicated block name (by @aleksiuno) - - #13804: Fix shared smarty compilation ID across shops / themes (by @202-ecommerce) - - #13687: Fix notice when trying to create a return for an order item that has already been returned (by @Codencode) - - #13704: Fix exclude discounted products on CartRule (by @tomlev) - - #13387: Fix image size in summary not limited (by @YeLnatSs) - - Refactoring: - - #15277: Combine two equal adjacent selectors (by @davidglezz) - - #15284: Make color and texture consistent when both are set (by @davidglezz) - - #16099: Make checkout js code easier to understand (by @atomiix) - - #15083: Use aria-label instead of hidden sr-only span in variant links (by @pojebunny) -- Core: - - New feature: - - #18475: Enable controllers as a service through autowiring (by @matks) - - #14428: Introduce fuzzy search (by @Lathanao) - - #14134: Combine consecutive issets() (by @Quetzacoalt91) - - #13384: Add naming convention linter (by @sarjon) - - #13200: Add SecurityAnnotation linter (by @sarjon) - - Improvement: - - #18201: Optimize the 1.7.7 translation catalog (by @matthieu-rolland) - - #18617: Make computing precision matching currency's display precision (by @matthieu-rolland) - - #17734: Register new hook displayFooterCategory for 1770 and rename order hooks (by @matks) - - #18050: Use proper computing precision in payment module (by @matthieu-rolland) - - #17889: Add displayAdditionalCustomerAddressFields hook during update (by @matthieu-rolland) - - #17731: Fix license headers (by @matks) - - #17149: Cancel product (by @matthieu-rolland) - - #17579: Update license headers 2020 (by @PierreRambaud) - - #17537: Increase timeout to download translation packages from 5 to 20 seconds (by @jolelievre) - - #13761: Add compatibility with PHP 7.3 (by @mickaelandrieu) - - #8770: Remove file 'fileType' when deleting images (by @marekhanus) - - #17067: PHPDocumentation on Category constructor (by @zalexki) - - #16714: Update composer.json requirements (by @gavinkalika) - - #17048: Update nginx configuration (by @PierreRambaud) - - #16144: Migrate hooks for new Order view page (by @sarjon) - - #16789: Security policy (by @PierreRambaud) - - #16383: Currencies are customizable and prices are shown accordingly (by @jolelievre) - - #16429: Upgrade Smarty to v3.1.34 (by @matks) - - #14894: Use utf8mb4 charset to support emoji (by @PierreRambaud) - - #16454: Add comments about DataLang (by @eternoendless) - - #16404: Improve cache for staticPrice for products with combinations (by @Progi1984) - - #16433: Update license headers (by @matks) - - #16316: Allow to define authorized MIME types in ImageManager::validateUpload() (by @Progi1984) - - #16310: Add ps_dataprivacy, productcomments and ps_crossselling as native modules (by @PierreRambaud) - - #15902: Use the correct environment depending on what you are doing (dev, test, and prod) (by @PierreRambaud) - - #16331: Add "total_shipping_tax_excl" and "total_shipping_tax_incl" in email data (by @yannicka) - - #16176: Increase maximum hook length to 191 characters (by @eternoendless) - - #15022: Migration of Sell > Customer Service > Merchandise Returns page (by @rokaszygmantas) - - #16241: Improve install doc (by @matks) - - #16237: Set Demo mode only if undefined (by @Quetzacoalt91) - - #16097: Improvement on product image generation for high definition images. (by @Prestaworks) - - #16041: Remove google plus from login footer (by @mohamedaitbella) - - #13636: Add zones for: Austria, Switzerland, Denkmark, Netherlands, Thailand (by @manfield) - - #15755: Make CLDR Specification\Number immutable (by @Progi1984) - - #14665: Allow to display/hide manufacturers and suppliers independently (by @matthieu-rolland) - - #15656: Update license headers (by @matks) - - #15723: Fix typos (by @Zzareb) - - #15551: Update php docs on currency class (by @zalexki) - - #15552: Update php docs for class customer (by @FlorianBergeron) - - #15557: Update php docs in class PaymentModule (by @FlorianBergeron) - - #15555: Fix php docs in class Mail (by @FlorianBergeron) - - #15550: Update php docs for link class (by @FlorianBergeron) - - #15520: Remove old docs files (by @matks) - - #15340: Update minimum compatibility to PHP 7.1.3 (by @eternoendless) - - #15393: Update php docs for PaymentModule::getCurrency() (by @v4lux) - - #14838: Update invalid characters in Customer Creation & Update error messages and tips (by @Progi1984) - - #14951: Update PrestaShopCollection.php docs on getFirst method return type (by @zalexki) - - #15010: Make EmployeeId accept integers only (by @gavinkalika) - - #15079: Fix phpdoc for parameter type in module::updatePosition() (by @zalexki) - - #14949: Update Module.php docs on version property type (by @zalexki) - - #13830: Remove duplicate var in cart.php (by @davidglezz) - - #13906: Update CLDR data to 35.1 (by @eternoendless) - - #14691: Update version to 1.7.7.0 (by @jolelievre) - - #14246: Add doctrine filters applicator (by @sarjon) - - #14545: Remove english emails since they are generated now (by @jolelievre) - - #14116: Do not set a cookie if it finally has not changed (by @jocel1) - - #14232: Fix string line ending (by @MathiasReker) - - #14233: Use __DIR__ constant (by @MathiasReker) - - #14165: Fix Phpdoc (by @Matt75) - - #13803: Make the movement of the Grid columns really easy (by @mickaelandrieu) - - #13818: Remove redundant condition in cart.php (by @davidglezz) - - #13606: Fix phpdoc on Module class (by @Matt75) - - #13486: Fix coding style on develop (by @matks) - - #13236: Add ajax support for @AdminSecurity annotation (by @sarjon) - - #13119: Allow hookAdditionalCustomerFormFields and --AddressFormFields to modify fields positions (by @rblaurin) - - Bug fix: - - #18851: Build assets for Beta (by @jolelievre) - - #18234: Fix guest to customer transformation issue (by @matthieu-rolland) - - #17561: Allow cyrilic domain names in email addresses (by @atomiix) - - #18144: Fix CartRule : Discount on selected product excluding discounted products (by @Progi1984) - - #17733: Unwanted spaces in 1.7.7.0.sql file (by @matks) - - #17288: Upgrade Symfony 3.4 (by @mvorisek) - - #17307: Do not force memory_limit in index_cli.php (by @PierreRambaud) - - #17254: Fix deleted products not being displayed in orders (by @atomiix) - - #17246: Update Cs Fixer configuration (by @PierreRambaud) - - #15942: Fix docker compose not being able to stat files (by @PierreRambaud) - - #16733: Fix new connection detection (by @mvorisek) - - #16635: Fix discount calculation if two gift-cartrules exist for the same product. (by @Hlavtox) - - #16586: Do not escape translations when using the legacy translator from the new one (by @PierreRambaud) - - #16459: Fix behavior of Module::isRegisteredInHook() (by @Matt75) - - #16410: Make sure to get correct lang fields for shop (by @kpodemski) - - #16465: Upgrade SQL scripts can use DB_NAME, release creator regex fix, Tab.enable upgrade script fixed (by @jolelievre) - - #16334: Fix wrong flag on some languages (by @eternoendless) - - #16213: Make id_order available everywhere where order_name is available (by @atomiix) - - #12379: Fix of the carrier choice in payment preferences, product editor and cart rules (by @Rolige) - - #16072: Remove require config.inc.php on all commands and fix a notice (by @202-ecommerce) - - #16111: Check that ShippingCostTax values are not null before being formatted (by @Progi1984) - - #15805: Fix Cannot use object of type ParameterBag as array (by @davidglezz) - - #15974: Fix wrong verification of number of languages (by @dariusakafest) - - #15967: Use midnight for birthdate verification (by @eternoendless) - - #15903: Hide bad vouchers that should not be displayed to customers (by @matks) - - #15616: Refuse empty customer first and last names (by @matks) - - #15642: Fix wrong breadcrumb on home category (by @jocel1) - - #15625: Properly cleanup the customization table if no more customized_data (by @jocel1) - - #15577: Update symfony/phpunit-bridge dependency for security reason (by @PierreRambaud) - - #15447: Re-enable port in shop domains (by @matks) - - #15437: Finalize Update License Command (by @matks) - - #15439: Give more memory to php-cs-fixer (by @matks) - - #15426: Fix license headers (by @matks) - - #14609: Fix modules translations files in theme erased by modules translations that are in modules folder (by @bm-services) - - #14702: Fixes wrong visitor group assumed on multistore (by @matthieu-rolland) - - #15027: Fix typo in Employee processing (by @gavinkalika) - - #14601: Revert removed templates for mail dynamic contents, order mails mainly, create MailPartialTemplateRenderer to manage this feature (by @jolelievre) - - #14859: Move i18n.prestashop.net into https and remove unwanted file (by @PierreRambaud) - - #14352: Move Cart secure_key setter at the right place (by @jocel1) - - #14089: Fix shop URL with port in header HOST (by @202-ecommerce) - - #14529: Fix position problem on a fresh install (by @PierreRambaud) - - #14560: Typo fix on bug issue template (by @PierreRambaud) - - #13983: Fix empty tag in webservice XML response (by @pumamood) - - #14403: Fix cookie collisions from PR # 14116 and improve overall security (by @mvorisek) - - #14043: Check if Combination id is set before deleting Associations from database to prevent accidentally removing all products without attributes from all carts (by @kazeno) - - #14273: Fix SQL error due do while not ended (by @123monsite-regis) - - #13711: Compare strictly value of hook name when getting modules registered on it (by @Quetzacoalt91) - - #13609: Fix dispatched hook on the Grid presenter: actionGridFilterFormModifier (by @mickaelandrieu) - - #13542: Merge 1.7.6.x to develop - 23/04/2019 (by @matks) - - #13232: Fix wrong cart calculation using rules with free Gift (by @123monsite-regis) - - Refactoring: - - #18564: Refactoring using OrderAmountUpdater (by @Progi1984) - - #15965: Implement CQRS on Notifications (by @atomiix) - - #15448: Replace uses of deprecated Tools::displayPrice in favor of Locale::formatPrice() (by @Progi1984) - - #14970: Migration of Order message page (by @sarjon) - - #15388: Migration of Orders View page (by @sarjon) - - #15371: Fix duplicate retrieval of attributes color list (by @lvancrayelynghe) - - #13988: Migrates Orders list - part 1 (by @sarjon) - - #14065: Migrate Shopping Carts view page (by @sarjon) - - #13712: Prepare Command API for migrating Order view page (by @sarjon) - - #13554: Prepares Command/Query API for migrating "Create order" page (by @sarjon) - - #13736: Replace all calls to $this->l() in controllers (by @eternoendless) -- Installer: - - Improvement: - - #17914: Add index on product table for fresh install (by @jolelievre) - - #16527: Check memory_limit during installation (by @PierreRambaud) - - #16104: Update order status colors (by @sarjon) - - #15888: Update jQuery to 3.4.1 in installation pages (by @matthieu-rolland) - - Bug fix: - - #17642: Fix SQL request for order detail (by @jolelievre) - - #16941: Bad wording when installation check (by @gavinkalika) - - #16506: Set minimum PHP version to 7.1.3 (and not 7.1) (by @eternoendless) - - #16305: Fix SQL upgrade for 1.7.7.0 (missing FROM) (by @matks) - - #15404: Update Postal Code of South Korea (by @khouloudbelguith) - - #15131: Fix permanent redirection in installer (by @mickaelandrieu) -- Web Services: - - Improvement: - - #8769: Auto generate link_rewrite and do not require it when creating category via webservice (by @marekhanus) - - Bug fix: - - #14899: Make the container available in WebService environment (by @Progi1984) -- Localization: - - New feature: - - #17763: Update catalog for 1.7.7.0 (by @jolelievre) - - #17645: Backport #16927 (by @atomiix) - - #16173: Add Ivory Coast as a supported country (by @SylNicky) - - Improvement: - - #16834: Switch zone for BA, LI, and UA (by @LouiseBonnard) - - #16690: Add Khmer language (by @LouiseBonnard) - - #16489: Remove unofficial languages from language packs (by @eternoendless) - - #16416: Added albanian & korean to the installer (by @Progi1984) - - #15627: Added states to India (by @Progi1984) - - #16078: Update Argentinian conversion and tax rates (by @LouiseBonnard) - - #16291: Update tax rates for several countries (by @eternoendless) - - #16079: Update Azerbaijani tax rates (by @LouiseBonnard) - - #16292: Add missing languages to localization packs (by @eternoendless) - - #16244: Update Costa Rican, Peruvian and Brazilian tax rates (by @LouiseBonnard) - - #16218: Add and update tax rates (by @LouiseBonnard) - - #16190: Update Moldavian tax rates (by @LouiseBonnard) - - #16189: Update Japanese tax rates (by @LouiseBonnard) - - #16193: Update Norwegian tax rates (by @LouiseBonnard) - - #16181: Update Ecuadorian tax rates (by @LouiseBonnard) - - #16188: Update Iranian tax rates (by @LouiseBonnard) - - #16182: Update Egyptian tax rates (by @LouiseBonnard) - - #16183: Update Fijian tax rates (by @LouiseBonnard) - - #16186: Update Indonesian tax rates (by @LouiseBonnard) - - #16185: Update Guyanan tax rates (by @LouiseBonnard) - - #16187: Update Israeli tax rates (by @LouiseBonnard) - - #16179: Update Dominican Republic tax rates (by @LouiseBonnard) - - #16161: Update Colombian tax rates (by @LouiseBonnard) - - #16160: Update Swiss tax rates (by @LouiseBonnard) - - #16000: Update Indian tax rates (by @ashishsharawat) - - #16055: Update Greek tax rates (by @LouiseBonnard) - - #16020: Update Turkish currency sign (by @LouiseBonnard) - - #15968: Update Swedish tax rates (by @LouiseBonnard) - - #15969: Update Mexican tax rates (by @LouiseBonnard) - - #15618: Switched zone for Croatia from "Europe (non-UE)" to "Europe" (by @Progi1984) - - Bug fix: - - #18420: Change error message for invalid product quantity (by @jolelievre) - - #18504: Fix wording in classic guest mail template (by @jolelievre) - - #17757: Fix cancel product type translation domain (by @jolelievre) - - Refactoring: - - #18652: Remove useless traduction wordings and exception codes (by @jolelievre) - - #16347: Update CLDR to latest version 36 (2019-10-04) (by @ziegenberg) -- Tests: - - New feature: - - #17094: Add twig lint check and move bash script from tests-legacy to tests (by @matks) - - Improvement: - - #18540: Improve nightly log reports (by @PierreRambaud) - - #17965: Add HTML IDs and classes to View Customer BO page (by @matks) - - #17532: Fix PHP CS Fixer configuration: disable single_line_throw and backport #17328 (by @matks) - - #17028: Behat tests for Customer, Address features handlers (by @tdavidsonas88) - - #16525: Behat tests for orders in the Back Office. Various Behat features created and scenarios added (by @tdavidsonas88) - - #16966: Cover Category CommandHandlers and QueryHandlers by behat tests (by @tdavidsonas88) - - #16776: Cover Contact CommandHandlers and QueryHandlers by behat tests (by @tdavidsonas88) - - #16807: Travis: update config for dpl v2 (by @mvorisek) - - #16712: Add unit test for profile ID test (by @gavinkalika) - - #16757: Add behat tests for miscellaneous command/handlers: SwitchDebugMode, CloseShowcaseCard, GetShowcaseCardIsClosed, GenerateThemeMailTemplates, AddEmployee (by @tdavidsonas88) - - #16317: Only trigger deploy on cron task, and tests on push / pull requests (by @PierreRambaud) - - #15586: Remove deprecated StarterTheme tests (by @matks) - - #14971: Trigger nightly report (by @PierreRambaud) - - #14670: Add Behat tests for Customer commands (by @sarjon) - - #14725: Move travis scope from 5.6 to 7.1 (by @matks) - - #14287: Behat tests for Category (by @sarjon) - - #14231: Remove expectedException PHPUnit annotation (by @MathiasReker) - - #14109: Cover Webservice key management with Behat tests (by @sarjon) - - #14235: Remove unused imports (by @MathiasReker) - - #14234: Add missing braces (by @MathiasReker) - - #13790: Add Behat tests for Currency Domain (by @sarjon) - - #13862: Improve E2E report (by @PierreRambaud) - - #13018: Only run deploy if the triggered commit is recent (by @PierreRambaud) - - #13495: Add behat tests for customer Commands and Queries (part 1) (by @matks) - - Bug fix: - - #18548: Composer failed to be installed properly (by @PierreRambaud) - - #18339: Fix behat tests that add payments (by @jolelievre) - - #18239: Update tests data with taxes to fix behat tests (by @jolelievre) - - #18023: Modify test data generation to handle price with taxes (by @jolelievre) - - #17746: Restore GA for PHP CS Fixer (by @matks) - - #17643: CS fix (by @jolelievre) - - #16809: Fix date parsing in tests when TZ is changed to non-UTC during tests (by @mvorisek) - - #16998: Fix #16997 - assertion of first/classic theme from unsorted list (by @mvorisek) - - #15912: Fix missing currency in behat test (by @matthieu-rolland) - - #15848: Fix E2E dockerfile as npm is not anymore in the nodejs package (by @PierreRambaud) - - #15519: Fix Close browser after each scenario (by @boubkerbribri) - - #15161: Remove another faulty e2e test from Travis (by @matks) - - #14531: Remove another faulty e2e test from Travis (by @matks) - - #14491: Disable Selenium Guest scenario as it fails randomly (by @matks) - - #13826: Enable global kernel for legacy compatibility for Behat tests (by @matks) - - #13827: Revert "Only run deploy if the triggered commit is recent" (by @PierreRambaud) - - #13824: Update tests and package-lock (by @PierreRambaud) - - Refactoring: - - #18843: Functional tests - Create edit view voucher in customer information page (by @nesrineabdmouleh) - - #18840: Functional tests - Change selectors for advanced params pages (by @boubkerbribri) - - #18832: Functional tests - Change selectors orders pages (by @boubkerbribri) - - #18804: Change selectors (by @SimonGrn) - - #18800: Functional tests - Fix number of element in table for emails logs page (by @boubkerbribri) - - #18797: Functional tests - Refacto tests order settings (by @boubkerbribri) - - #18775: Functional tests - Renaming functions in files.js (by @boubkerbribri) - - #18774: Functional tests - Fix test filter email logs (by @boubkerbribri) - - #18575: Functional tests - Fix delete with bulk actions address (by @nesrineabdmouleh) - - #18753: Functional tests - Fix test name export languages (by @boubkerbribri) - - #18477: Functional tests - Product settings label oos allowed/denied backorders (by @nesrineabdmouleh) - - #18754: Functional tests - View customer (by @nesrineabdmouleh) - - #18756: Functional tests - Add test delivery time out of stocks (by @boubkerbribri) - - #18745: Functional tests - Improve test 'Filter stocks by categories' (by @boubkerbribri) - - #18718: Functional tests - Refacto credit slips tests (by @boubkerbribri) - - #18716: Functional tests - Fix tests enable brands and suppliers pages (by @boubkerbribri) - - #18720: Functional tests - change url for reporting (by @SimonGrn) - - #18688: Update README files for tests directory (by @SimonGrn) - - #18682: Functional tests - Fix wrong import for tests modules (by @boubkerbribri) - - #18670: Fix tests that are always green when the shop is broken (by @nesrineabdmouleh) - - #18677: Functional tests - Fix call for module (by @SimonGrn) - - #18639: Functional tests - Moving FO pages (by @boubkerbribri) - - #18669: Functional tests - Add delete modal to test bulk delete order messages (by @boubkerbribri) - - #18662: Functional tests - Fix customer creation in BO (by @boubkerbribri) - - #18631: Functional tests - Refacto orders and invoices tests (by @boubkerbribri) - - #18616: Functional tests - Add test download sample files for import (by @boubkerbribri) - - #18621: Functional tests - Add test 'Update default products order' (by @boubkerbribri) - - #18577: Functional tests - Update some tests titles (by @boubkerbribri) - - #18207: Functional tests - Product settings enable/disable display discounted price (by @nesrineabdmouleh) - - #18505: Functional tests - Payment > Preferences test group restrictions (by @nesrineabdmouleh) - - #18490: Functional tests - Add test 'Send a test email' (by @boubkerbribri) - - #18436: Functional tests - Add test 'Enable delivery time in stock products' (by @boubkerbribri) - - #18486: Functional tests - Fix test filter stocks by category (by @boubkerbribri) - - #18426: Functional tests - Add test for order setting gift options (by @boubkerbribri) - - #18452: Functional tests - Add tests Help card for pages employees, profiles, db backups, sql manager and webservice (by @boubkerbribri) - - #18457: Functional tests - Add filter customer to 'Filter orders' tests (by @boubkerbribri) - - #18465: Functional tests - Add test 'Export languages' in translations page (by @boubkerbribri) - - #18442: Functional tests - Add tests help card for pages Localization, Currencies and Languages (by @boubkerbribri) - - #18435: Functional tests - Localization test default language (by @nesrineabdmouleh) - - #18422: Functional tests - Product settings test label of in-stock products (by @nesrineabdmouleh) - - #18401: Functional tests - Filter delete and delete with bulk actions email (by @nesrineabdmouleh) - - #18375: Functional tests - Product settings enable/disable stock management (by @nesrineabdmouleh) - - #18332: Functional tests - Wait for navigation in go to maintenance tab function (by @boubkerbribri) - - #18369: Functional tests - Add test 'Sort cms pages' (by @boubkerbribri) - - #18367: Functional tests - Add tests helper card for brands and suppliers (by @boubkerbribri) - - #18350: Functional tests - Add test 'Bulk update orders status' (by @boubkerbribri) - - #18313: Functional tests - CRUD sql query (by @nesrineabdmouleh) - - #18371: Functional tests - Order settings enable/disable terms of service (by @nesrineabdmouleh) - - #18308: Functional tests - Add test 'Check delivery slip downloaded from list' (by @boubkerbribri) - - #18311: Functional tests - Add new client filter to order test (by @boubkerbribri) - - #18342: Functional tests - Add test 'Filter stocks by category' (by @boubkerbribri) - - #18290: Functional tests - Test minimum purchase total required in order to validate the order (by @nesrineabdmouleh) - - #18317: Functional tests - Add test 'Update number of products displayed per page' (by @boubkerbribri) - - #18306: Functional tests - Add test 'Check invoice downloaded from orders list' (by @boubkerbribri) - - #18161: Functional tests - Add test Enable and disable B2B mode (by @boubkerbribri) - - #18269: Functional tests - Add test 'Help card' for Stocks page (by @nesrineabdmouleh) - - #18268: Functional tests - Add test 'Help card' for Monitoring page (by @nesrineabdmouleh) - - #18272: Functional tests - Add test 'Export Orders' (by @boubkerbribri) - - #18267: Functional tests - Fix update successful message on addresses page (by @boubkerbribri) - - #18197: Functional tests - Order settings enable/disable reordering option (by @nesrineabdmouleh) - - #18231: Functional tests - Fix default timeout for waiting for selector (by @boubkerbribri) - - #18242: Functional tests - Add test 'Help card' for orders page (by @boubkerbribri) - - #18250: Functional tests - Add test 'Filter orders' (by @boubkerbribri) - - #18216: Functional tests - Retry to create Browser 3 times if first one fails (by @boubkerbribri) - - #18224: Functional tests - Product settings enable/disable allow ordering out of stock (by @nesrineabdmouleh) - - #18227: Functional tests - Fix selector for tests categories (by @boubkerbribri) - - #17981: Functional tests - Fix invoices and credit slips tests (by @boubkerbribri) - - #18198: Fix test 'display unavailable product attributes' (by @boubkerbribri) - - #18180: Functional tests - Add tests 'Help card' for customers and addresses (by @boubkerbribri) - - #18178: Functional tests - Add test 'Export brands' (by @boubkerbribri) - - #18112: Functional tests - Refactoring products tests (by @boubkerbribri) - - #18191: Functional tests - Order settings enable/disable guest checkout (by @nesrineabdmouleh) - - #18158: Functional tests - Add test 'Export customers' (by @boubkerbribri) - - #18148: Functional tests - Customer settings enable/disable partner offer (by @nesrineabdmouleh) - - #18174: Functional tests - Product settings separator of attribute anchor on the product links (by @nesrineabdmouleh) - - #17805: Functional tests - Order settings enable/disable final summary (by @nesrineabdmouleh) - - #17891: Functional tests - Product settings enable/disable display unavailable product attributes (by @nesrineabdmouleh) - - #18081: Functional tests - Enable/Disable multistore (by @nesrineabdmouleh) - - #18145: Functional tests - Customer settings ask for birth date (by @nesrineabdmouleh) - - #18143: Functional tests - Shop Parameters > Traffic & SEO test helper card (by @nesrineabdmouleh) - - #18156: Functional tests - Fix nightly 16-03 (by @boubkerbribri) - - #18149: Functional tests - Add test Export Categories to csv (by @boubkerbribri) - - #18133: Functional tests - Design > Pages test helper card (by @nesrineabdmouleh) - - #17921: Functional tests - Enable disable webservice key (by @nesrineabdmouleh) - - #18071: Functional tests - Customers set required fields (by @nesrineabdmouleh) - - #18002: Functional tests - Refacto customer settings redisplay cart at login (by @nesrineabdmouleh) - - #17982: Functional tests - Categories page test helper card (by @nesrineabdmouleh) - - #18056: Functional tests - Back to default sort in test 'Sort Products' (by @boubkerbribri) - - #18001: Functional tests - Refacto product settings default activation status (by @nesrineabdmouleh) - - #17998: Functional tests - Refacto product settings force update friendly URL (by @nesrineabdmouleh) - - #17997: Functional tests- Refacto product settings new days number (by @nesrineabdmouleh) - - #17996: Functional tests - Refacto product settings catalog mode (by @nesrineabdmouleh) - - #17989: Functional tests - Refacto product settings display remaining quantities (by @nesrineabdmouleh) - - #17974: Functional tests - Refacto product settings display available quantities (by @nesrineabdmouleh) - - #17948: Functional tests - Fix problem of generate files by date for nightly 29-02 (by @nesrineabdmouleh) - - #17960: Functional tests - Accept GDPR if only exist (by @boubkerbribri) - - #17910: Functional tests - Improving FO tests by adding wait for cart to disappear (by @boubkerbribri) - - #17699: Functional Tests - Product settings choose quantity discounts based on (by @nesrineabdmouleh) - - #17872: Functional tests - Invoices > Other options - delete check legal free text from scenario (by @nesrineabdmouleh) - - #17836: Funtional tests - Fix employee faker (by @boubkerbribri) - - #17795: Functional tests - Payment>Preferences Configure currency restriction (by @nesrineabdmouleh) - - #17829: Functional tests - Shop Parameters> General enable/disable display brands (by @nesrineabdmouleh) - - #17754: Functional tests - Product settings display remaining quantity in product page (by @nesrineabdmouleh) - - #17828: Functional tests - Shop Parameters> General enable/disable display suppliers (by @nesrineabdmouleh) - - #17779: Functional tests - Add new tests 'Sort categories' and 'Change category position' (by @boubkerbribri) - - #17824: Functional tests - Fix sending emails in nightly (by @boubkerbribri) - - #17772: Functional tests - Add test 'Sort Addresses' (by @boubkerbribri) - - #17775: Functional tests - Customer settings enable/disable send email after registration (by @nesrineabdmouleh) - - #17762: Functional tests - Add test 'Import localization pack' (by @boubkerbribri) - - #17756: Functional tests - Add test 'Sort customers' (by @boubkerbribri) - - #17741: Functional tests - Add test 'Sort contacts' (by @boubkerbribri) - - #17735: Functional tests - Adding wait for navigation in goToHomePage function (by @boubkerbribri) - - #17722: Functional tests - Product settings Enable/Disable display available quantities (by @nesrineabdmouleh) - - #17724: Functional tests - Add test 'Sort brands and addresses' (by @boubkerbribri) - - #17720: Functional tests - Add test 'Sort products' (by @boubkerbribri) - - #17710: Functional tests - Add movement check after update stocks quantity (by @boubkerbribri) - - #17714: Functional tests - Fix Sort tests (by @boubkerbribri) - - #17697: Functional tests - Add test 'Sort Taxes' (by @boubkerbribri) - - #17708: Functional tests - Fix validation message selector name (by @nesrineabdmouleh) - - #17605: Functional tests - Product settings enable/disable default activation status (by @nesrineabdmouleh) - - #17640: Functional tests - Customer settings enable/disable re-display cart at login (by @nesrineabdmouleh) - - #17693: Functional tests - Add test 'Sort languages' (by @boubkerbribri) - - #17530: Functional tests - Add context to functional tests (Modules And Design) (by @boubkerbribri) - - #17534: Functional tests - Add context for advanced params tests (by @boubkerbribri) - - #17543: Functional tests - Add context for shop params tests (by @boubkerbribri) - - #17567: Functional tests - Add context to international tests (by @boubkerbribri) - - #17582: Functional tests - Add context to customers, addresses and customer service tests (by @boubkerbribri) - - #17674: Functional tests - Add context to catalog tests (by @boubkerbribri) - - #17678: Functional tests - Add context to orders tests (by @boubkerbribri) - - #17652: Functional tests - Fix monitoring test (by @nesrineabdmouleh) - - #17620: Functional tests - 02_orders/ Reduce legal free text length to 10 characters (by @nesrineabdmouleh) - - #17624: Functional tests - Product settings enable/disable force update friendly url (by @nesrineabdmouleh) - - #17566: Functional tests - CRUD web service key (by @nesrineabdmouleh) - - #17555: Functional tests - Product settings max size short description (by @nesrineabdmouleh) - - #17559: Functional tests - Fix select all grid selector (by @boubkerbribri) - - #17388: Functional tests - Product settings test new days number (by @nesrineabdmouleh) - - #17518: Functional test - Add data file for module categories (by @boubkerbribri) - - #17499: Functional tests - Add new test Filter modules by categories (by @boubkerbribri) - - #17495: Functional tests - Add test for monitoring product without description (by @boubkerbribri) - - #17440: Functional tests - Add new test bulk actions languages (by @boubkerbribri) - - #17443: Functional tests - Add delete modal for tests (taxes and cms pages) (by @boubkerbribri) - - #17418: Functional tests - adding additional information to tests (by @boubkerbribri) - - #17405: Functional tests - Improve test enableDisableAccentedURL (by @boubkerbribri) - - #17386: Functional tests - Enable unofficial currency (by @boubkerbribri) - - #17375: Functional tests - Enable disable accented url (by @nesrineabdmouleh) - - #17372: Functional tests - Activate tests Profiles (by @boubkerbribri) - - #17213: Functional tests - Enable disable catalog mode from product settings page (by @nesrineabdmouleh) - - #17329: Functional tests - Fix delete with bulk actions (brand, brand address, supplier) tests (by @nesrineabdmouleh) - - #17301: Functional tests - Enable/Disable friendly url (by @nesrineabdmouleh) - - #17281: Functional tests - Addresses bulk actions (by @nesrineabdmouleh) - - #17216: Functional tests - CRUD customer address (by @nesrineabdmouleh) - - #17272: Functional tests - Limit the legal free text length to 50 (by @nesrineabdmouleh) - - #17202: Functional tests - Add numbers for all directories (by @nesrineabdmouleh) - - #17201: Functional Tests - Fix "emailThemes/01_previewEmailThemes" test (by @nesrineabdmouleh) - - #17183: Sanity tests - Fix CRUD standard product with combinations test (by @nesrineabdmouleh) - - #17168: Functional tests - Fix test customer bulk action (by @boubkerbribri) - - #17167: Functional Tests - Fix Enable Disable shop automated test (by @SimonGrn) - - #17155: Refacto partial refund along with behat tests (by @jolelievre) - - #17154: Functional tests - Fix test employee and maintenance (by @boubkerbribri) - - #17129: Functional tests - Set FR text value for custom maintenance text (by @nesrineabdmouleh) - - #17092: Functional tests - Fix other options test (by @nesrineabdmouleh) - - #17091: Functional tests - Fix Crud language test (by @boubkerbribri) - - #17084: Functional tests - Fix error in the test Enable/Disable invoices (by @nesrineabdmouleh) - - #16632: Replace deprecated "create_function" (by @mvorisek) - - #17076: Tests - Fix dockerfile for puppeteer (by @boubkerbribri) - - #17027: Functional tests - add test 'Filter modules by status' (by @boubkerbribri) - - #17061: Functional tests - Add base page for localization (by @boubkerbribri) - - #17066: Functional tests - Update confirm delete files method (by @boubkerbribri) - - #17060: Functional tests - Filter addresses table (by @nesrineabdmouleh) - - #17047: Functional tests - Enable disable image in delivery slip file (by @nesrineabdmouleh) - - #17049: Functional tests - Contact bulk actions (by @nesrineabdmouleh) - - #17052: Functional tests - Add new test 'Crud language test' (by @boubkerbribri) - - #17029: Functional Tests - Enable/Disable shop (by @nesrineabdmouleh) - - #16963: Functional tests - add test 'filter languages' (by @boubkerbribri) - - #17041: Functional tests - Fix tests brands and skip test Create unofficial currencies (by @boubkerbribri) - - #17009: Functional tests - add test 'Preview Email Themes' (by @boubkerbribri) - - #16967: Functional Tests - Add number verification for delivery slip file (by @nesrineabdmouleh) - - #16962: Functional tests - Crud contact (by @nesrineabdmouleh) - - #17013: Functional tests - Separate tests team employees and profiles (by @boubkerbribri) - - #17017: Functional tests - Update file bulk action delete message (by @boubkerbribri) - - #17006: Functional tests - Fix supplier name and zip code (by @boubkerbribri) - - #17003: Functional tests - Fix date format (mm/dd/yyyy) (by @nesrineabdmouleh) - - #16960: Functional Tests - Add prefix verification for delivery slip file (by @nesrineabdmouleh) - - #16922: Functional tests - Add Bulk actions for file tests (by @nesrineabdmouleh) - - #16905: Functional Tests - Add monitoring products test (by @boubkerbribri) - - #16923: Functional tests - Bulk delete backups (by @boubkerbribri) - - #16959: Functional tests - Add new test : CRUD Seo Page (by @boubkerbribri) - - #16914: Functional Test - Add new test : filter SEO pages grid (by @boubkerbribri) - - #16931: Functional tests - add test filter stocks by status (by @boubkerbribri) - - #16886: Functional Tests - Generate delivery slip by date (by @nesrineabdmouleh) - - #16909: Functional tests - Add filter contacts tests (by @nesrineabdmouleh) - - #16908: Functional Test - Add new test CRUD files (by @boubkerbribri) - - #16900: Functional tests - Disable tests profile including creation (by @boubkerbribri) - - #16897: Tests - Fix tests : invoices options (by @boubkerbribri) - - #16884: Functional Tests - Test credit slip options (by @nesrineabdmouleh) - - #16882: Functional Tests - Generate credit slip by date (by @nesrineabdmouleh) - - #16881: Functional tests - Fix tests 'CRUD customer' and 'CRUD Category' (by @boubkerbribri) - - #16831: Functional Tests - Create, check and filter credit slips (by @nesrineabdmouleh) - - #16875: Functional Tests - Delete Category from monitoring page (by @boubkerbribri) - - #16772: Functional Tests - Test prefix in the invoice file name (by @nesrineabdmouleh) - - #16861: Functional test : Activate Employees bulk actions test (by @boubkerbribri) - - #16848: Functional tests - add test Create DB Backup (by @boubkerbribri) - - #16756: Functional tests - Add test Create unofficial currency (by @boubkerbribri) - - #16775: Functional Tests - Enable/Disable current year in the invoice file name (by @nesrineabdmouleh) - - #16801: Functional tests - add test create and delete link widget (by @boubkerbribri) - - #16791: Functional Tests - Test some options in the invoice file (by @nesrineabdmouleh) - - #16771: Functionnal tests - Add test "Filter and bulk delete order messages" (by @boubkerbribri) - - #16784: Tests - Fix checkout FO (by @boubkerbribri) - - #16747: Functional Tests - Enable/Disable tax breakdown (by @nesrineabdmouleh) - - #16766: Functional test - Fix global variable call in the test (by @nesrineabdmouleh) - - #16748: Functional tests - Fix expect on test currencies (by @boubkerbribri) - - #16761: Functional test - CRUD order message (by @boubkerbribri) - - #16764: Tests - Fix sanity on nightly (by @boubkerbribri) - - #16759: Functional Tests - Enable/Disable product image in the invoice (by @nesrineabdmouleh) - - #16750: Sanity tests - Can't install prestashop with same db in prod mode (by @boubkerbribri) - - #16731: Tests - Disable dev mode while testing with docker (by @boubkerbribri) - - #16727: Functional tests - Fix test CRUD profile (by @boubkerbribri) - - #16721: Functional tests - Fix echange rate on test currency (by @boubkerbribri) - - #16708: Tests - Fix eslint errors on linkchecker (by @boubkerbribri) - - #16699: Functional Tests - add test create official currency (by @boubkerbribri) - - #16705: Functional tests - Add test 'Bulk Edit Quantity in stocks' (by @boubkerbribri) - - #16659: Tests Update README.md and DOCKER.md (by @boubkerbribri) - - #16679: Functional Tests - Fix describe message for generate invoice by date/status (by @nesrineabdmouleh) - - #16681: Tests - Fix errors in functional tests (by @boubkerbribri) - - #16674: Functional Tests - Add BO tests for invoice options Enable/Disable (by @nesrineabdmouleh) - - #16666: Tests - Running tests with user root (by @boubkerbribri) - - #16655: Functional Tests - Add BO tests for generate invoice by status (by @nesrineabdmouleh) - - #16647: Tests - Using pptruser to run tests with download (by @boubkerbribri) - - #16644: Tests - Fix logout used in Employee tests (by @boubkerbribri) - - #16566: Functional Tests - Add BO tests for generate invoice by date (by @nesrineabdmouleh) - - #16612: Functional tests - Adding test update Quantity on catalog-stocks page (by @boubkerbribri) - - #16534: Tests - Adding scripts to run puppteer tests on nightly for develop (by @boubkerbribri) - - #16564: Tests - Fixing tests 04_filterAndQuickEditCategories (functional campaign) (by @boubkerbribri) - - #16533: Test- Update functional test Supplier (by @boubkerbribri) - - #16496: Tests - Fix test CRUD Page Category in functional campaign (by @boubkerbribri) - - #16492: Tests - Skip all scenarios Employees bulk actions (by @boubkerbribri) - - #16479: Tests - Using foreach for sanity tests products (by @boubkerbribri) - - #16480: Tests - Using foreach for sanity tests orders (by @boubkerbribri) - - #16469: Functional tests - fix Employees tests (by @boubkerbribri) - - #16127: Functional Tests - Add BO tests for Design>Pages (by @nesrineabdmouleh) - - #16289: Functional Tests - Add BO tests for Team>employees and profiles (by @nesrineabdmouleh) - - #16456: Functional tests - add simple filter tests for stocks (by @boubkerbribri) - - #16376: Functional Tests - Add BO tests for Filter And Quick Edit products (by @nesrineabdmouleh) - - #16448: Running Sanity and functional tests faster (by @boubkerbribri) - - #16450: Tests - Replace duplicated steps with foreach in brands tests (by @boubkerbribri) - - #16408: Tests - Replace duplicated steps with foreach in customers tests (by @boubkerbribri) - - #16407: Tests - Replace duplicated steps with foreach in categories tests (by @boubkerbribri) - - #16414: Tests - Replace duplicated steps with foreach in taxes tests (by @boubkerbribri) - - #16403: Tests - Replace duplicated steps with foreach for brands tests (by @boubkerbribri) - - #16405: Tests - Replace duplicated steps with foreach in suppliers tests (by @boubkerbribri) - - #16399: Tests - Delete replaces in tests Taxes (by @boubkerbribri) - - #16395: Tests - Delete replaces in tests Customers (by @boubkerbribri) - - #16330: Tests - Delete replaces in tests and use new methods instead (by @boubkerbribri) - - #16387: Tests - Delete replaces in tests categories (by @boubkerbribri) - - #16373: Tests - Using employees demo file for installation (by @boubkerbribri) - - #16371: Tests - Delete replaces and use new methods instead in Supplier tests (by @boubkerbribri) - - #16332: Tests - using same demo elements (by @boubkerbribri) - - #16296: Functional Tests - Add BO tests for Supplier (by @boubkerbribri) - - #16297: Functional tests - Using the correct element in loop for brands tests (by @boubkerbribri) - - #16309: Tests - Separate BO pages (by @boubkerbribri) - - #16216: Tests - Add functional tests command to package.json (by @boubkerbribri) - - #16194: Tests - Refactoring puppeteer tests (by @boubkerbribri) - - #16125: Functional Tests - Add BO tests for Brands (by @boubkerbribri) - - #16156: Tests - Update name of catalog Menu link in BO (by @boubkerbribri) - - #15988: Functional Tests - Add tests for categories (by @nesrineabdmouleh) - - #15980: Linkchecker update (by @SimonGrn) - - #16018: Sanity Tests - Refacto of all tests (by @boubkerbribri) - - #16005: Tests - Adding env file for docker (by @boubkerbribri) - - #15978: Functional Tests - Add BO tests for taxes (by @boubkerbribri) - - #15984: Test - Improve quick view product (by @boubkerbribri) - - #15905: Tests - Add module alias (by @boubkerbribri) - - #15865: Functional Tests - Add BO tests for customers (by @boubkerbribri) - - #15868: Update puppeteer Tests description on package.json (by @boubkerbribri) - - #15811: Tests - Fix Login Test (by @boubkerbribri) - - #15790: Tests - Remove chai from Page Objects (by @boubkerbribri) - - #15772: Tests - Fix global Vars in linkchecker (by @boubkerbribri) - - #15754: Tests - Change structure of file globals.js (by @boubkerbribri) - - #15735: Sanity Tests with puppeteer - Refacto of InstallShopTest (by @boubkerbribri) - - #15651: Add common FO page - Puppeteer (by @nesrineabdmouleh) - - #15730: Update ReadMe file for puppeteer tests folder (by @boubkerbribri) - - #15634: Add demo data files and fix the concerned tests - Sanity tests (by @nesrineabdmouleh) - - #15630: Moving login test in a commonTests directory (by @boubkerbribri) - - #15584: Replace mocha scenario and test with describe and it functions (by @boubkerbribri) - - #15556: Add Sanity tests on travis build (by @boubkerbribri) - - #15509: Remove the smoke tests campaign - Puppeteer (by @nesrineabdmouleh) - - #15470: Add Checkout FO to Sanity tests puppeteer (by @boubkerbribri) - - #15421: Cart FO tests with puppeteer - Sanity tests campaign (by @nesrineabdmouleh) - - #15422: Add Sanity tests products BO (by @boubkerbribri) - - #15415: Fixing esLint errors in project (by @boubkerbribri) - - #15355: Adding sanity tests products BO (by @boubkerbribri) - - #14170: Add Behat tests for CMS page commands (by @zuk3975) - - #15312: Order BO tests with puppeteer - Sanity tests campaign (by @nesrineabdmouleh) - - #15389: Catalog FO tests with puppeteer - Sanity tests campaign (by @nesrineabdmouleh) - - #14132: Behavioral tests for Tax commands (by @zuk3975) - - #15301: Renaming data names - Smoke tests (by @nesrineabdmouleh) - - #15262: Sort smoke tests by adding number to the names (by @boubkerbribri) - - #14145: Behavioral tests for Manufacturer commands (by @zuk3975) - - #15163: Docker for test AutoUpgrade (by @boubkerbribri) - - #15206: Smoke tests - Fix the product selector in the FO (by @nesrineabdmouleh) - - #15156: Adding new Test UpgradeShop with puppeteer (by @boubkerbribri) - - #15155: Update expect usage in puppeteer tests (by @boubkerbribri) - - #15151: All BO classes should inherit from BObasePage (by @boubkerbribri) - - #15031: Fix install prestashop test - Smoke tests (by @nesrineabdmouleh) - - #15024: Rename files and test directory - Smoke tests campaign (by @nesrineabdmouleh) - - #14902: Check the Front Office test with puppeteer - Smoke tests campaign (by @nesrineabdmouleh) - - #14825: Fix some minor problems on the "crawling BO" smoke test (by @SimonGrn) - - #14815: Add a new smoke test: crawling BO (by @SimonGrn) - - #14764: Install prestashop test with puppeteer (by @boubkerbribri) - - #14593: First POM implementation (by @SimonGrn) - - #14612: Update docker for puppeteer (by @boubkerbribri) - - #14508: Integrate Puppeteer to check links on FO and BO (by @mbadrani) - - #13772: Correct usage of fixtures on behat tests for taxes (by @tomlev) - -#################################### -# v1.7.6.9 - (2020-11-16) -#################################### -- Core: - - Bug fix: - - #GHSA-frf2-c9q3-qg9m: Improper Access Control with submitReorder function (by @PierreRambaud) - -#################################### -# v1.7.6.8 - (2020-09-24) -#################################### -- Core: - - Improvement: - - #21124: Bump version to 1.7.6.8, bump contactform version (by @PierreRambaud) - - Bug fix: - - #GHSA-rc8c-v7rq-q392: Stored XSS in upload files (by @PierreRambaud) - - #GHSA-5cp2-r794-w37w: Potential XSS injection with contact form (by @PierreRambaud) - - #GHSA-fghq-8h87-826g: Blind SQLi in Catalog Product edition (by @PierreRambaud) - -#################################### -# v1.7.6.7 - (2020-07-03) -#################################### -- Front Office: - - Bug fix: - - #20052: Fix product page event theme sided not getting fired (by @NeOMakinG) - -#################################### -# v1.7.6.6 - (2020-07-01) -#################################### -- Back Office: - - Bug fix: - - #19814: Change buttons in modal bulk of module page to avoid black color (by @NeOMakinG) - - #18975: BO - Customer View page - Added Green alert when editing a voucher (by @Progi1984) - - #19942: Cast changelogs to array for twig - Backport of #19778 (by @atomiix) - - #19718: Remove i18n access restrictions (by @PierreRambaud) - - #19990: Fix BO page Module permission checks (by @jolelievre) -- Front Office: - - Improvement: - - #19800: Add a new selector in order to select the product page more precisely (by @NeOMakinG) -- Core: - - Improvement: - - #19943: Update Composer dependencies and prestashop module versions (by @PierreRambaud) - - #19980: Update version number to 1.7.6.6 (by @matks) - - #19979: Update outdated assets in 176x (by @matks) - - #19984: Update license headers for PS 1.7.6.6 (by @matks) - - Bug fix: - - #19010: Added missing required_once for Datas class (by @atomiix) - - #19986: Fix php7-only code into 1766 (by @matks) - - #20018: Remove COLLATION placeholder from 1.7.6.6.sql (by @matks) - - #GHSA-mc98-xjm3-c4fm - External control of configuration setting in the dashboard (by @PierreRambaud) - - #GHSA-997j-f42g-x57c - Information exposure in upload directory (by @PierreRambaud) - - #GHSA-492w-2pp5-xhvg - Information disclosure in release archive (by @PierreRambaud) - - #GHSA-ccvh-jh5x-mpg4 - Improper authentication (by @PierreRambaud) - - #GHSA-xp3x-3h8q-c386 - Improper access controls in Carrier page, Module Manager and Module Positions (by @PierreRambaud) - - #GHSA-qgh4-95j7-p3vj - Reflected XSS in product page (by @PierreRambaud) - - #GHSA-v4pg-q2cv-f7x4 - Stored XSS in AdminQuickAccesses (by @PierreRambaud) -- Web Services: - - Bug fix: - - #18969: Make api backward compatible for Currencies (by @atomiix) - -#################################### -# v1.7.6.5 - (2020-04-17) -#################################### -- Back Office: - - Bug fix: - - #18637: Fix sidebar not displayed in BO Add employee page (by @Progi1984) - - #18607: Fix wrong number of "Last emails" in BO - Customer View page (by @PululuK) - - #17920: Wrong redirection when using the quick search for a category (by @PululuK) - - #18064: Fix error when trying to translate Serbian using the BO interface (by @eternoendless) -- Front Office: - - Bug fix: - - #18633: Convert cart rule value when order currency is different (by @sowbiba) - - #18493: Change product redirection rules to redirect to valid attribute url (by @jolelievre) - - #18103: Duplicate address when submitting a form with errors (by @PierreRambaud) -- Core: - - Improvement: - - #18638: Update version to 1.7.6.5 (by @PierreRambaud) - - Bug fix: - - #GHSA-cvjj-grfv-f56w - Improper access control on product page with combinations, attachments and specific prices (by @PierreRambaud) - - #GHSA-4wxg-33h3-3w5r - Improper access control on product attributes page (by @PierreRambaud) - - #GHSA-r6rp-6gv6-r9hq - Improper access control on customers search (by @PierreRambaud) - - #GHSA-74vp-ww64-w2gm - Improper Access Control (by @PierreRambaud) - - #GHSA-98j8-hvjv-x47j - Reflected XSS related in import page (by @PierreRambaud) - - #GHSA-j3r6-33hf-m8wh - Reflected XSS with back parameter (by @PierreRambaud) - - #GHSA-mrpj-67mq-3fr5 - Reflected XSS on Exception page (by @PierreRambaud) - - #GHSA-q6pr-42v5-v97q - Reflected XSS on AdminCarts page (by @PierreRambaud) - - #GHSA-rpg3-f23r-jmqv - Reflected XSS on Search page (by @PierreRambaud) - - #GHSA-m2x6-c2c6-pjrx - Reflected XSS with dashboard calendar (by @PierreRambaud) - - #GHSA-375w-q56h-h7qc - Open redirection when using back parameter (by @PierreRambaud) - - #GHSA-87jh-7xpg-6v93 - Reflected XSS on AdminFeatures page (by @PierreRambaud) - - #GHSA-7fmr-5vcc-329j - Reflected XSS on AdminAttributesGroups page (by @PierreRambaud) - - #GHSA-48vj-vvr6-jj4f - Reflected XSS in security compromised page (by @PierreRambaud) - -- Installer: - - Bug fix: - - #18491: Installation under CLI doesn't take BASE_URI and Apache rewrite in consideration (by @PierreRambaud) - - #18451: Use scandir instead of readdir to get sorted entities (by @PierreRambaud) -- Tests: - - Bug fix: - - #18309: Change test fixtures that need to be in the future (by @jolelievre) - -#################################### -# v1.7.6.4 - (2020-03-02) -#################################### -- Back Office: - - Bug fix: - - #17711: Fix a bug on safari where SEO preview on create page was not updated (by @NeOMakinG) - - #17613: Files translations.css and product_page.css do not exist (by @PierreRambaud) - - #17395: Can't explore a category when all subcats are disabled (by @PululuK) -- Front Office: - - Improvement: - - #17638: Prevent email enumeration (by @PierreRambaud) - - Bug fix: - - #17457: Disable add-to-cart button when product/attribute combination is not available (by @sowbiba) - - #16616: Fix round remaining value of reduction amount (backport #16531) (by @matks) - - #17608: Email subject doesn't support html entities (by @Progi1984) -- Core: - - Bug fix: - - #17846: Fix exception thrown when editing a customer with a bad email address (by @atomiix) - - #17433: Do not escape translations when using the legacy translator from the new one (by @Progi1984) - - #17306: Do not force memory_limit in index_cli.php (by @PierreRambaud) - -#################################### -# v1.7.6.3 - (2020-01-20) -#################################### -- Back Office: - - Improvement: - - #17036: Protect modules vendor folder on install/upgrade/enable (by @jolelievre) - - Bug fix: - - #16906: Handle profile name above 32 chars exception (by @atomiix) - - #17087: Define alert message when error are found in Category Form (by @Progi1984) - - #17065: Fix encoding on product name in viewed product (by @Progi1984) - - #17071: Fix recursive check of updated files - backport of #16765 (by @matks) - - #16742: Can't export data more than filters limits (by @PierreRambaud) - - #16696: Fix email theme permission (by @atomiix) - - #16746: Attributes bo_css & bo_theme can be empty (by @PierreRambaud) - - #16729: Cost price & unit price are erased when saving with a supplier (by @PierreRambaud) - - #16888: Fix customer comment template (by @jolelievre) - - #16294: Fix email not translated when installing a new language (by @atomiix) - - #16648: Fix customer statuses not being able to toggle when optin field is required (by @matthieu-rolland) -- Front Office: - - Bug fix: - - #17248: Added RTL Style for Classic Theme (by @Progi1984) - - #16852: Fix a bug where changing quantity on product quickview adds products tags on ever products (by @NeOMakinG) - - #17030: Ignore rtl assets and remove _rtl.css files (by @NeOMakinG) -- Core: - - Bug fix: - - #17050: Quick access error when having a wrong url (by @PierreRambaud) - - #16893: Fix yml config parse typo (by @mvorisek) - - #16522: Prevent getter from changing class state (by @eternoendless) - - Refactoring: - - #17130: Make $localizedSymbols variable to be compatible with develop (by @atomiix) -- Web Services: - - Bug fix: - - #17069: Fix Currency i18n fields issue in webservice (by @atomiix) - -#################################### -# v1.7.6.2 - (2019-11-28) -#################################### -- Back Office: - - Bug fix: - - #16365: Viewed products - the date is showing product id - not a date (by @khouloudbelguith) - - #16265: Fix category checkbox redirect (Backport #16159) (by @atomiix) - - #16153: Add missing field type DNI in brand address form (by @jolelievre) - - #16158: Fix filter not being taken into account in grid export (by @matthieu-rolland) - - #16172: Remove constraint on siret in CustomerType (by @matthieu-rolland) - - #16047: Handle multistore customers sharing in customers listing at group level (by @matks) - - #16036: Add redirect routes on security annotation of Category pages (by @jolelievre) - - #15643: Allow CLDR to display deleted/inactive currencies (by @jolelievre) - - #15859: Add clickable row option for grid actions (by @jolelievre) - - #15880: Fix wrong data mapping in export (by @eternoendless) - - #15855: Allow anonymous mode for AdminController (by @PierreRambaud) - - #15856: Must use min-with instead max-widght for the Profile button (by @PierreRambaud) - - #15685: Unable to create new supplier when VAT identification number is mandatory (by @PierreRambaud) - - #15665: Wrong selector expression, unable to move parent category (by @PierreRambaud) - - #15660: Fix tracking url in Theme and Logo page (by @jolelievre) - - #15658: Use empty legacy action parameter (by @jolelievre) - - #15382: Remove useless and buggy identifier computation (by @jolelievre) -- Front Office: - - Bug fix: - - #16423: Use default attribute when no one are passed in front page (by @PierreRambaud) - - #16274: Fix contact us email display (by @atomiix) - - #15964: Use product url (including combination) rather than canonical one in the miniatures (by @jolelievre) - - #15963: Add rel="nofollow" to prestashop website link (by @matks) - - #15930: Fix on product-flags class for product cards (by @Progi1984) -- Core: - - Improvement: - - #16203: Update version to 1.7.6.2 (by @atomiix) - - Bug fix: - - #16500: Incorrect email subject and template variable {shop_name} (by @PierreRambaud) - - #16335: Update id_order_state at the right place (by @atomiix) - - #16258: Remove unnecessary require_once config.inc (by @matks) - - #16026: Remove final keyword from Lang entity (by @jolelievre) - - #15917: Define use_debug_toolbar even if it's not set in parameters.php (by @PierreRambaud) - - #15691: Cart rules mustn't be auto added automatically in some cases (by @PierreRambaud) - - #15621: Revert "Fix lang table multi-store data issue" (by @matks) - - #15731: Webservices shouldn't display warning when running with fpm or Nginx (by @PierreRambaud) - - #15515: SqlTranslator must throw a NotFoundResourceException (by @PierreRambaud) -- Tests: - - Bug fix: - - #15847: Npm is not anymore in the nodejs package (by @PierreRambaud) - - #15895: Add management of an env var to disable debug toolbar in travis tests (by @jolelievre) - - #15590: Remove selenium tests (by @PierreRambaud) - -#################################### -# v1.7.6.1 - (2019-08-26) -#################################### -- Back Office: - - Bug fix: - - #15173: CLDR has access to all currencies regardless of the current shop (by @jolelievre) - - #15139: Make module and email translations work again when using a theme other than classic (by @eternoendless) - - #14966: Keep BO from using two different translators in parallel (by @matthieu-rolland) - - #15030: Get all categories in category tree form (not only enabled ones) (by @matthieu-rolland) - - #14962: Fix error preventing to translate backoffice wordings when using a theme other than classic (by @eternoendless) - - #15017: Improve translation test module (by @eternoendless) - - #14721: Manage edit/view link for customers in HelperList (by @jolelievre) - - #15036: Fix supplier display after import (by @jolelievre) - - #14719: Scan translation keys from email themes (by @jolelievre) - - #14938: Fix error when loading theme that includes a translations directory but no translations (by @eternoendless) - - #14926: Fix logs filtering (by @sarjon) - - #14671: Make sure token is properly used in legacy context (by @PierreRambaud) - - #14914: Date picker calendar is shown in wrong place when rendered downwards in grid (by @PierreRambaud) - - #14828: Cannot save the "No Picture Image" (by @PierreRambaud) - - #14805: Fix unclosed div tag (by @sarjon) - - #14701: Fix log delete all action on Logs page (by @matks) - - #14605: Do not use encodeURIComponent with POST data (by @PierreRambaud) - - #14673: Fix Orders view page link to transform guest to customer (by @matks) -- Front Office: - - Bug fix: - - #15042: Only disable following steps in the checkout process when the current step has a continue button (by @jolelievre) - - #14945: Fixed {firstname} typo in order customer comment mail in 1.7.6.x (by @dheerajwebkul) - - #14786: Sprintf function broken in 1.7.6 for custom module templates (by @roja45) - - #14863: Prevent uninstall of Product Comments module (by @templatin) -- Core: - - Improvement: - - #14579: Fix many things that were supposed to be removed during build not being removed (by @eternoendless) - - Bug fix: - - #15132: Fix abstract service declaration (by @eternoendless) - - #14711: Update Decimal library to 1.2.0 (by @eternoendless) - - #14833: Bad currency format for Czech language (by @PierreRambaud) - - #14664: Update precision and numeric iso code of currencies (by @Quetzacoalt91) -- Installer: - - Bug fix: - - #14620: Init properly the Kernel on major *manual* upgrades (by @Quetzacoalt91) - - #14739: Keep Composer.lock file in release (by @jolelievre) -- Web Services: - - Bug fix: - - #14953: Initialize container in WebService environment (by @matthieu-rolland) -- Localization: - - Bug fix: - - #15051: Fix translations (by @jolelievre) -- Tests: - - Refactoring: - - #14356: Fix "02_autoupgrade" in install_upgrade campaign (by @nesrineabdmouleh) - -#################################### -# v1.7.6.0 - (2019-07-09) -#################################### -- Back Office: - - Bug fix: - - #14532: Check if index.php file exists before ignoring it (by @jolelievre) -- Core: - - Refactoring: - - #14552: Use variable instead of recomputing (by @jolelievre) - -#################################### -# v1.7.6.0 RC 2 - (2019-07-05) -#################################### -- Back Office: - - Bug fix: - - #14460: Ignore index.php files in Doctrine entities scanning - - #14401: Fix grid calendar - -- Front Office: - - Bug fix: - - #14444: Check if selected address belongs to user - - #14395: Classic theme force all type number to not have arrows - -- Core: - - Improvement: - - #14438: Testing the factory with number and price specifications - - Bug fix: - - #14453: Update facetedsearch to 3.0.6 - - #14400: Wrong way to retrieve CLDR information - -#################################### -# v1.7.6.0 RC 1 - (2019-06-25) -#################################### -- Back Office: - - Improvement: - - #14239: Introduce the usage of Module user-displayable exceptions to handle module errors (part 2) - - #14008: Adds missing form data arguments in hooks - - #13779: Allow to overwrite theme mails if they have modules OR mail templates - - #13722: Filter themes without override in email generation form - - Bug fix: - - #14364: View button doesn't have href - - #14331: Handle bad theme error nicely - - #14290: Extend customer page - - #14259: Avoid bug when creating manually created a language - - #14248: Cannot use accented URL with arabic language - - #14242: Module form_rest() outside div - - #14220: Set schema form rendered when it contains no children - - #14189: Fix manufacturer controller using wrong DomainException ns - - #14172: Add missing form_errors for identifiable object forms - - #13984: Fix bo categories - - #14152: Adjust employee avatar size - - #14156: Add missing null check in EditCmsPageHandler - - #14101: Fix missing permission roles - - #14137: Adds missing form_rest in Shop Parameters > Preferences - - #14107: Do not allow the selection of any subcategories - - #14084: Fixes updating name and symbol for currency - - #14021: Improved error handling when theme is uploaded or activated - - #14091: Do not use specific prices when displaying price with tax in BO product catalog - - #14029: Missing legacy link for themes page - - #14028: Add explanations about SEO cards - - #14030: Add missing legacy link for translations routes - - #13875: Added help property (backported from Symfony 4 framework) - - #14007: Fix currency precision from CLDR at install - - #13774: Includes missing theme & logo page validation handling for logo and icon images - - #13916: Fixes saving private note about customer from order page - - #13820: Fixes form_rest placing - - #13956: Restore legacy controller and template files deleted late in beta - - #13840: Fix resetting sort and items per page on list filters reset action - - #13887: Fix saving customer with required fields - - #13813: Fixes toggling Category status in Monitoring page - - #13866: Fix cart rule calculation for free gift - - #13857: Missing legacy links fix for employess controller - - #13797: Adds missing legacy links for currency controller - - #13777: Incorrect translation arguments passed in cms page form - - #13690: Theme and logo page design fixes - - #13821: Fix manufacturers, taxes lists id filtering - - #13165: Fix multilanguage fields configuration - - #13764: Fixes customer view url in notifications bar - - #13763: Fix help sidebar display in Customers page - - #13765: Fix sql manager bulk actions - -- Front Office: - - Improvement: - - #14180: Improve right block on cart and checkout page - - #14138: Add comment in Customer registration form, add better error message - - Bug fix: - - #14325: Refresh product flags on ajax call when product page is refreshed - - #14298: Fix english mail generation on fresh install - - #14309: Simplify the installation language to its minimum - - #14296: Fix carrier display in order confirmation email - - #14251: Fix categories wordbreak - - #14190: You need to be authenticated to play with addresses - - #14166: Fix categories cover images which had an incorrect format - - #14163: Add missing quotes in error message - - #13370: Fix cart refresh after voucher removal - - #14075: Fix: If Ask for birth date option is disabled, an exception is displayed in the FO - - #13905: Step clickable and not - Checkout page - - #12891: Fix bug on block social in footer - - #13780: Fix displayed discount on tax excluded cart display - -- Core: - - Improvement: - - #14284: Update to Faceted search 3.0.5 - - #13925: Add getter for current locale - - #14197: Update facetedsearch dependency - - #14010: Update some license headers that were outdated - - #14011: Update outdated CSS assets - - #13778: Add new hooks for Symfony migrated pages in XML install file and SQL upgrade - - Bug fix: - - #14324: Use Admin.Actions instead Admin.International.Help - - #14316: Reapply changes from PR switching on PHPSpreadsheet - - #14300: &= prevents result to be a boolean - - #13795: Updates to Domain - - #13919: Tax must be returned depending on PS_TAX_DISPLAY only - - #13923: Make sure index exist before getting value for gift message - - #14027: Fix BC break on Toggle column parameter - - #13885: Force array cache for doctrine - - #13808: Update Symfony to latest patch version to fix ICU version problem - - #13665: Final retail price is not displayed due to missing CLDR files - -- Installer: - - Bug fix: - - #14243: Fix translation catalogue - - #14225: Update facetedsearch cache - -#################################### -# v1.7.6.0-beta.1 - (2019-05-13) -#################################### -- Back Office: - - New feature: - - #13221: Allow trans() to fall back on the legacy translation system when used with modules (by @eternoendless) - - #12974: Cms page category listing position update (by @tomas862) - - #13004: Integrate new modern mail theme (compiled from MJML) (by @jolelievre) - - #12981: Migration of "Design -> pages -> cms page listing" (by @tomas862) - - #12647: Migration of "Design -> pages -> add new / edit page category" (by @tomas862) - - #12163: Migration of shop parameters->contact->contacts add new edit contact form (by @tomas862) - - #12706: Kpis list are now customizables using hooks (by @mickaelandrieu) - - #10595: Migration of "Shop parameters >Traffic & SEO > SEO & URL > Add new / edit page" form (by @tomas862) - - #12046: Introduce Mail Template Generator (by @jolelievre) - - #10877: Migration of "Design > Pages" page cms category listing (by @tomas862) - - #11894: Migration of international/localization/currencies page form and some exchange rate actions (by @tomas862) - - #12128: Add migrated customers page helper card (by @matks) - - #11153: Migration of "Catalog > Brand & Suppliers > Suppliers" listing (by @tomas862) - - #10774: Migration of "International > Localization > Currencies" page listing (by @tomas862) - - #11484: Add final price column in products list (by @PrestaShark) - - #10992: Migrate Customer view page (by @sarjon) - - #11408: Migrate Categories Add/Edit actions - tests fixed (by @matks) - - #11049: Add Helper Card to Employees page (by @sarjon) - - #11075: Improve AdminSecurity and DemoRestricted annotations to allow to pass query parameters to keep (by @tomas862) - - #10120: Migration of Advanced Parameters -> Import (Step 2) (by @rokaszygmantas) - - #10790: Migrate Employee options configuration (by @sarjon) - - Improvement: - - #13603: Add id for orders view page to ease E2E testing (by @matks) - - #13404: Add missing showcase card in CMS page (by @tomas862) - - #13234: Add Showcase card in Categories page (by @sarjon) - - #13158: Fix error bubbling inside the translatable type (by @tomas862) - - #13125: Add CMS page listing position update functionality (by @tomas862) - - #13048: Integrate mail generator (by @jolelievre) - - #12331: Migration of Theme & Logo page with style and ux improvements (by @tomas862) - - #12436: Introduces new File type input design for all new and migrated back-office pages (by @tomas862) - - #13123: Display shop path in Information page (by @unlocomqx) - - #12707: New design for employee profile [Back-Office] (by @YeLnatSs) - - #13033: Filter out registered hooks in module positions list (by @unlocomqx) - - #12914: Significantly reduce number of SQL requests to get the employee authorizations (by @Quetzacoalt91) - - #13095: Update dashboard links (by @eternoendless) - - #13012: Update Twig to v1.38 (by @matks) - - #12850: "Module Manager" tab should be the first tab in Modules Tab (by @rblaurin) - - #12214: Migrate "Advanced Parameters > Team > Employees > Add new employee" page (by @rokaszygmantas) - - #12928: Allow multiple grids on same page (by @jolelievre) - - #12971: Enable customers page (by @sarjon) - - #12945: Build assets (by @matks) - - #12644: Add margin between buttons on Traffic & SEO page (by @YeLnatSs) - - #12699: Refacto addons store controller and handle addons failure (by @matks) - - #12838: Replace hardcoded currency sign in specific price form (by @metineren) - - #12784: Add module main class parse error to log message (by @teemumantynen) - - #12717: Add re-usable rewrite link copier service (by @tomas862) - - #12505: Improve error handling in migrated controllers (by @sarjon) - - #12761: Remove timeout from product image upload (by @JohnMidity) - - #12713: Enable usage of roles for Module Updates and Module Alerts pages and manage access (by @matks) - - #12622: Refactor AddonsStoreController to use annotations and some improvements (by @matks) - - #12316: Update access rules for SystemInformationController and MemcacheServer (by @matks) - - #10911: Build new theme using Webpack 4 (by @CaptainYouz) - - #12094: Refactor OrderPreferencesController to use annotations (by @matks) - - #12076: Refacto ProductPreferencesController to use annotations (by @matks) - - #12074: Refacto PreferencesController to use annotations (by @matks) - - #12098: Refactor Shipping/ referencesController to use annotations (by @matks) - - #12097: Refacto PaymentMethodsController to use annotations (by @matks) - - #12099: Refactor MaintenanceController to use annotations (by @matks) - - #12077: Refacto ThemeCatalogController to use annotations (by @matks) - - #11439: Migrate Customer list actions (by @sarjon) - - #11561: Migrate legacy import logic to adapters and hide Import page 2 (by @rokaszygmantas) - - #11877: Align grid search and reset buttons to the right (by @tomas862) - - #11481: Add cover & menu thumbnail images deleting for category (by @sarjon) - - #11919: Use env variable for admin dir with default value in assets build script (by @spolischook) - - #11785: Update dependencies with security breaches (by @jolelievre) - - #11732: Avoid using short bool (by @MathiasReker) - - #11735: Elseif instead of else if (by @MathiasReker) - - #11739: Remove blackslash (by @MathiasReker) - - #11741: Use brackets for index brace (by @MathiasReker) - - #11235: Prevent unnecessary Order objects from being created in Admin Orders (by @mnastalski) - - #10199: Fix quantity placeholder issue in the Stock management page (by @CaptainYouz) - - #11160: Form handling improvements in import page step 1 and 2 (by @rokaszygmantas) - - #11095: Update grid design regarding grid gear icon position and dropdown toggle icon modification (by @tomas862) - - #11266: Allow BO hooks to use the method $this->render() (by @Quetzacoalt91) - - #11093: Set sortable flag by default to "true" on ToggleColumn (by @tomas862) - - Bug fix: - - #13381: Use tinymce in migrated pages (by @matks) - - #13481: Improve preview and test mail feature, improve and fix a few templates (by @jolelievre) - - #13643: Fixes incorrect hook names for identifiable object forms. (by @tomas862) - - #13219: ScrollIntoView if field is invalid (by @PierreRambaud) - - #13623: Fix categories deleting in bulk action (by @sarjon) - - #13372: Add missing security annotations (by @rokaszygmantas) - - #13504: Fix backoffice translations for third-party modules (by @eternoendless) - - #13576: Fix deleting profile (by @sarjon) - - #13563: Do not get data from null currency (by @Quetzacoalt91) - - #13233: Enable 'back' GET parameter management (by @tomas862) - - #13550: Add missing check in Manufacturer image uploader (by @zuk3975) - - #13547: Deprecate Language::installEmailsLanguagePack (by @jolelievre) - - #13484: Fixes Categories grid filtering by position (by @sarjon) - - #13535: Fix responsive showcase cards (by @YeLnatSs) - - #13508: Enable ChoiceTree javascript in manufacturers form (by @zuk3975) - - #13528: Fix calendar overflow (by @zuk3975) - - #13152: Updates characters length for Category meta fields (by @sarjon) - - #13477: Fix issue on order with free gift (by @tomlev) - - #13439: Improvements on LegacyUrlConverter, "tab" alias, insensitive and prevent infinite redirection loop (by @jolelievre) - - #13431: Fix parameters list in product lookup (by @Quetzacoalt91) - - #13434: Remove material icons on SQL manager page (by @marionf) - - #13429: Build outdated assets for 1.7.6.x (by @matks) - - #13367: Remove deactivated currencies from new CLDR (by @tomlev) - - #13351: Mail generator fixes (by @jolelievre) - - #13363: Fix syntax error in tpl (by @Quetzacoalt91) - - #13349: Make all grids responsive (by @eternoendless) - - #13273: Fix domain errors (by @matks) - - #13264: Restores deleted generatable_text_widget from template (by @sarjon) - - #13216: Enable help bar on suppliers page (by @PierreRambaud) - - #13199: Fix Profiles form twig template compatibility with twig v2 (by @matks) - - #13108: Fix missing lang entries in Configuration (by @rblaurin) - - #13177: Fix notice undefined index: icon on Design -> Positions (by @Matt75) - - #13161: Remove icons from Customers form (by @sarjon) - - #12931: Make footer on product page spread itself when the menu is hidden (by @dineshbadrukhiya) - - #13157: Fix Add/Edit brand icon (by @matks) - - #13145: Fix bug with incorrect error display within the forms (by @tomas862) - - #13093: Add missing label and delete legacy tax controller as it was migrated (by @rokaszygmantas) - - #13105: Validate theme zip file and show error messages (by @rokaszygmantas) - - #13088: Ensure translations are always saved with the selected theme in back office (by @mickaelandrieu) - - #13122: Fix notice when iso code does not exist in array (by @Quetzacoalt91) - - #13104: Fix bad variable in Customers Add/Edit template (by @matks) - - #13094: Fix product demo link_rewrite (by @marionf) - - #13079: Fix visual glitches in new theme (by @eternoendless) - - #13054: Escape all import output data (by @PierreRambaud) - - #13043: Fix to handle fancybox customer creation in Add an Order page (by @matks) - - #13063: Module Manager: Use categoryParentEnglishName instead of category name (by @PierreRambaud) - - #13066: Fix npm install not working anymore on new-theme (by @PierreRambaud) - - #12523: Solved problem with texture upload when attribute has hex color (by @kpodemski) - - #13049: Fix BO scaling in mobile (by @eternoendless) - - #12705: Update OrderHistory to manage {followup} & {shipping_number} vars in all email templates, not only in in_transit template (by @jf-viguier) - - #12946: Fix recurring technical error when saving modifications in a Carrier (by @Matt75) - - #12897: Enable lite display for new theme (by @matks) - - #12874: Fix Symfony console crash because of DocumentationLinkProvider service definition (by @jolelievre) - - #12788: Remove html escaping of errors (by @bilfeldt) - - #12794: Add missing columns in products_import.csv (by @rblaurin) - - #12730: Fix fatal error in product catalog when short description is too long (by @rblaurin) - - #12751: Fix saving shop association in migrated add/edit forms (by @rokaszygmantas) - - #12787: Add legacy links to all meta page routes (by @tomas862) - - #12711: Fix shipping cost becoming free if more than a half or available quantity ordered (by @LedCloud) - - #12723: Fix specific price without discount being added (by @rblaurin) - - #12709: Refactor MetaController to secure search usage (by @matks) - - #12716: Prevent including jQuery in the new theme (by @eternoendless) - - #12668: Fix help sidebar when adding/editing language (by @sarjon) - - #12465: Fix duplicate HTML id (by @mickaelandrieu) - - #12563: Fix error in admin panel when visiting a category that's not under Index (by @mowcixo) - - #12597: The lang parameter in the url is now shop dependent (by @helgvor-stoll) - - #12471: Use AdminSecurity annotation for ajax call for Sql Manager (by @matks) - - #12479: Avoid module sorting function warnings when module data is invalid (by @matks) - - #8993: Fix HTML formated configuration not saved (by @shaffe-fr) - - #11175: Allow product default supplier reference to be updated, if the product supplier is already attached to the product (by @simondaigre) - - #12240: Adds missing argument in MetaController which caused page crash (by @tomas862) - - #12096: Fix access rights to Administration page (by @matks) - - #12140: Default carrier name was displayed as 0 (by @Gitdyr) - - #11693: Fix search feature value and pagination (by @studiox3) - - #12052: SERP: Avoid mutating a prop directly + fix url encode (by @PierreRambaud) - - #11854: Add customer_message table name into SQL request (by @Klemart3D) - - #11932: Can't sort tax included for now (by @PierreRambaud) - - #11936: Description has a max length and can not exceeded (by @PierreRambaud) - - #11922: Fix searching issue in the Credit Slips page (by @khouloudbelguith) - - #11907: Fix error when updating the product details in order (by @PeeyushAgrawalWebkul) - - #11851: Fix error "getimagesize(): php_network_getaddresses" when trying to change the order status to payment accepted (by @PierreRambaud) - - #11850: Fix header (by @PierreRambaud) - - #11200: Fix address changes not impacted when creating an order from another order (by @jf-viguier) - - #11201: Addresses changes not impacted when creating an order from another order (by @jf-viguier) - - #11526: Fix wrong protocol in the File Manager Dialog (by @freakstatic) - - #11535: Display the right front url in multistore menu (by @jolelievre) - - #10981: Change BO product list price source for multistore (by @mafisz) - - #11256: Fixes error reported in #9687, regarding carrier list in the modal to ... (by @manfield) - - #11424: Improvement needs on hover of "Ok" button of source code modal on product page (by @dineshbadrukhiya) - - #10904: Fix date filtering in AdminSpecificPriceRuleController (by @Matt75) - - #11179: Fix sorting issue in the webservice page (by @khouloudbelguith) - - #10535: Fix typos (by @MathiasReker) - - #10930: Allow product import to change previous id_category_default when you force ID (by @itisco) - - #10939: Fix bad annotation in AttributeGroupLang, AttributeLang and TabLang (by @Fabuloops) - - #10808: Adjusted URL to be SSL agnostic (by @alu-) - - #10924: Fix right side block of attribute and attribute groups in combination tab not appearing (by @dineshbadrukhiya) - - #10781: Fixes new webservice list behavior in multishop context and fixes warning message display (by @tomas862) - - Refactoring: - - #13466: Brand and address export actions (by @zuk3975) - - #13251: Removes unnecessary return on update everywhere (by @tomas862) - - #13144: Cms page fixes (by @zuk3975) - - #13162: Tax page fixes (by @zuk3975) - - #13164: Manufacturer page fixes (by @zuk3975) - - #13159: Remove 'Constraint' suffix from TypedRegex constraint and validator (by @zuk3975) - - #12795: Brand address create/edit actions migration (by @zuk3975) - - #12995: Migrate Cms page create/edit actions (by @zuk3975) - - #13076: Migrate Add/Edit Profiles page (by @sarjon) - - #13014: Final Migration of Categories page (by @sarjon) - - #13067: Fix manufacturers namespace typos and wrong typecasts in commands (by @zuk3975) - - #12735: Brands create/edit migration (by @zuk3975) - - #12641: Migrate tax create/edit form (by @zuk3975) - - #12912: Fix Traffic and SEO route paths (by @matks) - - #12423: Taxes list migration (by @zuk3975) - - #12610: Taxes Options configuration form migration (by @zuk3975) - - #11470: Improve birthdate validation (by @zessx) - - #11723: Migrate customer Add/Edit actions (by @sarjon) - - #11519: Migrate Customers KPIs and required fields configuration (by @sarjon) - - #11527: Migrate customer view actions (by @sarjon) -- Front Office: - - New feature: - - #13103: Introduce new hooks displayProductActions & displayPersonalInformationTop (by @Quetzacoalt91) - - Improvement: - - #13047: New design for prices and taxes (by @YeLnatSs) - - #13135: Add variable to tell if prices are tax included or not (by @eternoendless) - - #13009: Change product canonical url to parent, no more redirection (by @jolelievre) - - #12564: Allow Doctrine entities in modules, make doctrine available for FO, modules autoload on FO (by @jolelievre) - - #11943: Improve performance by avoiding parsing YAML files during ModuleManagerBuilder init (by @jocel1) - - #10253: Add modal-dialog-centered class to classic theme (by @CaptainYouz) - - #12748: Remove obsolete P3P policy (by @MathiasReker) - - #12753: Allow ipv6 to be used in htaccess redirects (by @Quetzacoalt91) - - #12017: Weak token implementation (by @PierreRambaud) - - #11534: Move scroll forcing from core to classic (by @dennispw) - - #10487: Added breadcrumb to the manufacturers pages (by @SebBareyre) - - #11661: Reset quantity value to min value after adding to cart (by @jolelievre) - - #11614: Allow modules to add custom product flags (by @kpodemski) - - #11607: Remove useless space (by @MathiasReker) - - #11491: Classic theme footer block design improvement (by @dineshbadrukhiya) - - #11455: Remove unnecessary spaces on header of the checkout page (by @dineshbadrukhiya) - - #11362: Dont expose Powered-By: Prestashop (by @MathiasReker) - - #11215: Remove inline-style color in test-data (by @dineshbadrukhiya) - - #10769: Keep variant id_attribute in ProductLazyArray (by @Piraito) - - Bug fix: - - #13664: Remove id_attribute parameter from product link when it is equal to 0 (by @jolelievre) - - #13617: Fix not null voucher with free shipping producing php error (by @tomlev) - - #13635: Fix product link should not include attribute parameter equals to zero (by @jolelievre) - - #13407: Fix labels display computing (by @jolelievre) - - #13578: Automatically add dni field in Address format for countries which need it (by @jolelievre) - - #13440: Change checkout behaviour (needs to be validated after meeting) (by @jolelievre) - - #13411: Hide tax label in front when tax display is disabled in the shop (by @jolelievre) - - #13525: Fix currency display on not existing language (by @tomlev) - - #13003: Add behat tests for free shipping (by @tomlev) - - #13261: Fix lang on currency install (by @tomlev) - - #13201: Fix search results if shop has non-default 'visitor' group and categories that are only accessible for the non-default visitor group (by @fgschaefer) - - #13218: Fix breadcrumb in search results page leads to 404 page (by @PierreRambaud) - - #12872: Fix label "Web only" (by @YeLnatSs) - - #13150: Add a missing space that could trigger an SQL error (by @chrisvanberg) - - #13106: Do not go to the latest step when you change a previous step state in checkout (by @PierreRambaud) - - #12893: Fix bug on contact when mail is too long (by @YeLnatSs) - - #13081: Empty filter should not be shown (by @PierreRambaud) - - #11688: Fix catalog mode in products list and product page (by @jolelievre) - - #12391: Fix Broken Authentication and Session Management (by @arnaudschaeffer) - - #12892: Limit carrier image size on checkout page (by @YeLnatSs) - - #12964: Wrong specific price refresh on product page with combinations (by @PierreRambaud) - - #12965: Fix wrong cart calculation when using cart rule with virtual products (by @tomlev) - - #12817: Robots should not index search content (by @watou) - - #12733: Changed the regex to force space and hyphen in postcode validation (by @jojotjebaby) - - #12696: Fix missing comma in sql upgrade file (by @tomlev) - - #12403: Attribute min not allowed on element input at this point, change type from text to number (by @dominictayloruk) - - #12406: Revert "Fix translation on account creation email error" (by @marionf) - - #12341: Use show_price to display price in schema.org tags (by @arnaudschaeffer) - - #12227: Fix ps_viewedproduct in classic theme (by @SharakPL) - - #10341: Fix main page slider display on all devices (by @CaptainYouz) - - #12023: When downloading a virtual good, check if the order was made by the current user (by @garnele007) - - #10297: Fix image dimensions in Product Card view (by @CaptainYouz) - - #11726: Force DNI fields required if associated Country needs it (by @jolelievre) - - #10294: Fix minimum order amount for secondary currency (by @sadlyblue) - - #11754: Fix wrong discount details on order page / on invoice (by @tomlev) - - #11608: Fix deprecated jquery shortcut function 'load' (by @Fabuloops) - - #11745: Fix for password recovery error messages (by @web-fu) - - #11656: Correctly display percentage in cart (by @jolelievre) - - #11645: Fix discount computing to take combination into account (by @jolelievre) - - #11604: Fix wrong html attribute (by @SebBareyre) - - #11576: Add .gif support to webpack.config.js (by @adviva) - - #11605: Remove useless space (by @SebBareyre) - - #11495: Fix category description below the image (by @dineshbadrukhiya) - - #11563: Fix typo for "Environment" comment (by @Klemart3D) - - #9041: Fix override of ProductController (by @nenes25) - - #11103: Fix discount display when display preference is set without tax (by @tomlev) - - #11282: Convert customization price to current currency (by @unlocomqx) - - #11419: Noto Sans fonts updated to version 2.001 hinted (by @ProBackup-nl) - - #10867: Remove inline-style of Arial font (by @MathiasReker) - - #10643: Fix password validation message when password is too short (by @rdy4ever) -- Core: - - New feature: - - #12708: Deprecate admin endpoints outside index.php (by @Quetzacoalt91) - - #11321: Translation Manager of Back Office can now manage legacy translations of modules (by @mickaelandrieu) - - #9337: Migrate "Brands" listing page (a.k.a manufacturers) (by @sarjon) - - #12758: Added a Theme Enabler command (by @mickaelandrieu) - - #10455: New CLDR implementation (by @tomlev) - - #12284: Include script handler to manage installation of modules (by @mickaelandrieu) - - #12089: Implement AbstractTypedCollection with tests (by @jolelievre) - - #10974: Implement form handlers for SqlManager form - part 1 (by @sarjon) - - #10839: Migrate languages list (by @sarjon) - - #10197: Added a schema generator (by @mickaelandrieu) - - #9132: Add hook for extra fields on customer address form (by @PeeyushAgrawalWebkul) - - #10816: Migrate "Layout customization" part of Them & Logo controller (by @sarjon) - - #10797: Migrate Employee list (by @sarjon) - - #10864: Implement image source parser (by @sarjon) - - #10160: Migrate categories listing (by @sarjon) - - Improvement: - - #13735: Update native modules (by @eternoendless) - - #13402: Add new hooks of 1.7.6.0 in fixtures (by @Quetzacoalt91) - - #13238: Update themes folders license headers (by @matks) - - #13239: Update js folder license headers (by @matks) - - #13237: Update tests folders license headers (by @matks) - - #13235: Update src folder license headers (by @matks) - - #12941: Remove unnecessary return on update (by @eternoendless) - - #12999: Remove calls to old CLDR (by @Quetzacoalt91) - - #13141: Performance: avoid useless attributes queries (by @123monsite-regis) - - #12996: Domain improvements: naming and namespace (by @sarjon) - - #11730: Use of static instead of ClassName (by @MathiasReker) - - #11970: Unary operator spaces (by @MathiasReker) - - #11977: Function declaration (by @MathiasReker) - - #11975: Space after semicolon (by @MathiasReker) - - #13008: Adds phpdoc on range objectmodel (by @Matt75) - - #12782: Fixes for migrated Categories add/edit actions (by @sarjon) - - #12956: Customization - improve phpdoc and constants usage (by @Matt75) - - #12959: Make Tools curl throw an exception when it fails in dev mode (by @matks) - - #10406: Document and add tests to Faceted Search system (by @mickaelandrieu) - - #12251: Improve version (by @eternoendless) - - #12749: Remove 9 duplicates from array in getProductAttributeWhitelist(). Items sorted to check dupes. (by @toslan) - - #12810: Install ps_faviconnotificationbo automatically (by @eternoendless) - - #12808: Deprecate Cart::addExtraCarriers() (by @eternoendless) - - #12570: Add Drag & Drop styling for category position column (by @sarjon) - - #12346: Add Category form builder & handler (by @sarjon) - - #12498: Add showcase card for Suppliers list (by @sarjon) - - #12598: Restore composer file (by @PierreRambaud) - - #12532: Updated Core using new version of Composer script handler (by @mickaelandrieu) - - #12208: Add filter on the modules folder to avoid caching all files by Twig (by @Quetzacoalt91) - - #10783: Migration of Advanced Parameters > Team > Profiles page. (by @rokaszygmantas) - - #11968: Switch case space (by @MathiasReker) - - #11859: Replace tabs with spaces in htaccess (by @MathiasReker) - - #11961: Improvements in the Domain namespace (by @sarjon) - - #12247: Bump version to 1.7.6.0 (by @eternoendless) - - #12222: Add notice for docker-compose (by @PierreRambaud) - - #12211: Add breadcrumb to the search results page (by @SebBareyre) - - #11992: Replace calls to is_null by comparison (by @MathiasReker) - - #12082: Update Nginx configuration for multishop (by @PierreRambaud) - - #12150: Allow specific versions of libs to be ignored (by @Quetzacoalt91) - - #12031: Make pre-commit execute linter only if php files have been staged (by @eternoendless) - - #11985: PHP unit test case static method calls (by @MathiasReker) - - #11899: Introduce HelperList title_icon property (by @matks) - - #11866: Order imports (by @MathiasReker) - - #11867: Remove unneeded curly braces (by @MathiasReker) - - #11869: Remove unneeded control parentheses (by @MathiasReker) - - #11857: Replace tabs with spaces (by @MathiasReker) - - #11823: Fix namespace (by @MathiasReker) - - #11781: Fix blank lines: Add and remove (by @MathiasReker) - - #11729: Use binary mode to write files (by @MathiasReker) - - #10486: Split grid service definitions in separate files (by @sarjon) - - #10533: Add old product ID on actionProductAdd hook when duplicating a product (by @duGuillaume) - - #10975: Introduced a new function for Products.php for retrive a product ID given it reference (by @runningz) - - #11696: Combine consecutive issets (by @MathiasReker) - - #11708: Modernize types casting (by @MathiasReker) - - #11710: Include is not a function (by @MathiasReker) - - #11695: Array indentation (by @MathiasReker) - - #11685: Fix php-cs-fixer "non printable character" (by @MathiasReker) - - #11736: Remove unused imports (by @MathiasReker) - - #11757: Remove empty statement (by @MathiasReker) - - #11744: Fix PhpDoc Validate::isColor() (by @EdouardTack) - - #11697: Combine consecutive unsets (by @MathiasReker) - - #11635: Improve use of protocol (by @MathiasReker) - - #11738: No PHP closing tag and no EOL (by @MathiasReker) - - #11712: Normalize use of operators (by @MathiasReker) - - #11733: Add function type (by @MathiasReker) - - #11734: Remove comma in single array (by @MathiasReker) - - #11709: Use echo instead of print (by @MathiasReker) - - #11707: Do not use alias functions (by @MathiasReker) - - #11704: Remove useless return (by @MathiasReker) - - #11703: Do not use short echo tags (by @MathiasReker) - - #11701: Use logical operators (by @MathiasReker) - - #11699: Hash to slash comment (by @MathiasReker) - - #11694: Align multiline comment (by @MathiasReker) - - #11653: Allow override of _PS_DEBUG_PROFILING_ (by @SebBareyre) - - #11678: Fix use of protocol (by @MathiasReker) - - #11672: Non printable character (by @MathiasReker) - - #11643: Additional PHP Improvements (by @MathiasReker) - - #11666: Fully qualified strict types (by @MathiasReker) - - #11667: Heredoc to nowdoc (by @MathiasReker) - - #11671: Use constant instead of function (by @MathiasReker) - - #11669: Improve error suppression (by @MathiasReker) - - #11566: Build all the assets using a single command (by @eternoendless) - - #11313: Only call ntree regeneration at this end of a WS call and optimize regenerateEntireNtree (by @jocel1) - - #11510: Add PHP 7.3 polyfills (by @Quetzacoalt91) - - #11397: Add total_shipping_tax_excl, incl in email data (by @sitte) - - #11417: Lossless compression of all images (by @MathiasReker) - - #11246: Replace deprecated library PhpExcel by PhpSpreadsheet (by @MartinFinkenflugel) - - #11249: Fix declaration of method arguments (by @Seleda) - - #11140: Remove unreachable code (by @idnovate) - - #11139: Deprecate legacy Db service (by @sarjon) - - #10770: Update CacheClearer adapter (by @sarjon) - - #10777: Migration of Shop parameters > Contact > Contacts page. (by @rokaszygmantas) - - #10834: Allow release creator to be run without version parameter (by @Quetzacoalt91) - - #10699: Change getcwd() for __DIR__ (by @DanielBoettner) - - #10704: Add TranslatableType (by @sarjon) - - #9247: Add themes in gitignore (except classic) (by @Quetzacoalt91) - - Bug fix: - - #13684: Wrong discount subtotal when customergroup is set to use ex taxes (by @tomlev) - - #13604: Forbid URLS to be added in customer names (by @PierreRambaud) - - #13605: Add missing translation domains (by @matks) - - #13560: Remove duplicate method call (by @eternoendless) - - #13540: Update upgrade scripts to PS 1.7.6.0 (by @Quetzacoalt91) - - #13470: Removes GetDefaultGroupHandler adapter (by @sarjon) - - #13435: Fixes option for MaterialMultipleChoiceTableType (by @sarjon) - - #13409: Do not call removed cldr lib (by @Quetzacoalt91) - - #13353: Fixes default Customer group overriding (by @sarjon) - - #13189: Harmonize Grids naming (by @sarjon) - - #13256: Fixes to Customer subdomain & controller (by @sarjon) - - #13246: Add missing hook description (by @eternoendless) - - #13242: Add missing hook description for additionalCustomerAddressFields (by @eternoendless) - - #13222: Do not try to install an unsupported language (by @PierreRambaud) - - #13208: Fix broken page when requesting a duplicate _legacy_link (by @PierreRambaud) - - #13209: Properly set error headers (by @jocel1) - - #13146: Fixes missing fields validation in Language command handlers (by @sarjon) - - #13115: Fix strpos arguments order (by @quasilyte) - - #12550: Improve the way VAT is managed for price calculation (by @prestamodule) - - #13057: Fix search action configuration for grids (by @sarjon) - - #12967: Foward $locale to Translate::getModuleTranslation() (by @eternoendless) - - #11962: Do not stripslashes value from _GET & _POST (by @PierreRambaud) - - #12960: DoctrineBuilderExtension uses YamlParser for its config (by @jolelievre) - - #12940: Do not look for translations if no locale (by @matks) - - #12841: Add deprecation notice for hook actionAjaxDieBefore (by @eternoendless) - - #12803: Fallback on language code when locale is empty (by @Quetzacoalt91) - - #12756: Fix bug when overriding the Address class (by @dariusakafest) - - #12739: Revert new theme to Webpack 2 (by @PierreRambaud) - - #12559: Remove translations from db when Language is deleted (by @sarjon) - - #12152: Fix timezone standard is ignored (by @michaesc) - - #11764: Fix undefined property (by @idnovate) - - #12473: Order Creation: fix out of stock status (by @rGaillard) - - #12484: Fix missing tag for CustomerType (by @sarjon) - - #12124: Remove unwanted umask (by @PierreRambaud) - - #12399: Actually use arguments passed to CountryDataProvider->getCountries() (by @TysonAndre) - - #12397: Fix use of array_merge in HookFinder->addExpectedInstanceClasses (by @TysonAndre) - - #12367: Move PositionColumn in its original folder (by @Quetzacoalt91) - - #12344: Fix translation on account creation email error (by @SebBareyre) - - #11442: Fixed the problem with the type of a return value in Module::onInstall() (by @zapalm) - - #12139: Fix some Symfony service definitions (by @matks) - - #12125: Fix bad GridFactory service definition (by @matks) - - #12014: Unify algorithm for calculating average tax rate for products in a cart (by @eternoendless) - - #12010: Make filtering of LazyArrays return a new instance (by @eternoendless) - - #12015: Fix typo in example Nginx config file (by @mwht) - - #11809: Fix misuse of information returned by getimagesize (by @olivier-monaco) - - #11876: Fix lang table multi-store data issue (by @Dan-Orchard) - - #11892: Fix missing const definition (by @sarjon) - - #11895: Fix categories grid id (by @sarjon) - - #11884: Do not allow null for low_stock_alert (by @eternoendless) - - #11706: Fix implode calls (by @MathiasReker) - - #11679: Fix issue with deleting a category with subcategories on Multistore (by @MathiasReker) - - #11691: Fix bug on pdf logo path (by @SebBareyre) - - #11747: Convert comments to php docs in some cases (by @MathiasReker) - - #11731: Fix typo in Phpdoc (by @MathiasReker) - - #11714: Fix line ending (by @MathiasReker) - - #11711: Add missing braces (by @MathiasReker) - - #11559: Keep first try of translator initialization in memory (by @Quetzacoalt91) - - #11564: Fix shop name in the subject of mail (by @khouloudbelguith) - - #9034: Added missing Rewrite base on Api rule (by @123monsite-regis) - - #10465: Fixed bug on inc/dec product quantity in cart with vouchers discounts (by @sete391) - - #11469: Fix SQL update when last_connection_date is null (by @Quetzacoalt91) - - #11204: Fix incorrect comparison when out of stock (by @andromaque) - - #11202: Fix a bug where PrestaShop cookie is set on every page when a cookie value is NULL (by @jocel1) - - #11214: Handle bad address use case for Carrier Tax Rate (by @matks) - - #11151: Fix MailsProvider service declaration name (by @mickaelandrieu) - - #11168: Remove Throwable from core (by @sarjon) - - #10917: Add getConfiguration to PrestaShopBundle (by @Quetzacoalt91) - - #10536: Delete search indexes after deleting a product (by @MathiasReker) - - #10722: Update Smarty and Symfony to latest (by @eternoendless) - - #9042: Fix controller override (by @nenes25) - - #12243: Update gitignore (by @PierreRambaud) - - #13171: Outdated assets (by @PierreRambaud) - - Refactoring: - - #12926: Migration of Manufacturers view action (by @sarjon) - - #11783: Migrate customers searching via ajax (by @sarjon) - - #12766: Remove duplicate CLDR service (by @matks) - - #12447: Remove legacy Webservice controller (by @sarjon) - - #12446: Enable new Languages page (by @sarjon) - - #12398: Fix unused variables where straightforward to do so (by @TysonAndre) - - #12293: Migrate actions of Languages list (by @sarjon) - - #12400: Remove a harmless duplicate array entry in PositionsController (by @TysonAndre) - - #12263: Migrate Add/Edit actions for webservice keys (by @sarjon) - - #11997: Happy new year 2019 (by @Quetzacoalt91) - - #11135: Migrate Employees list actions (by @sarjon) - - #12249: Migrate legacy test TermsAndConditionsTest and refactor related class (by @matks) - - #11885: Migration of Languages adding/editing (by @sarjon) - - #11169: Migrate Theme & Logo (by @sarjon) - - #12022: Use Symfony Cache Clear in ModuleManager instead of deprecated CacheClearer (by @matks) - - #10916: Migrate customers listing (by @sarjon) -- Installer: - - New feature: - - #12864: Remove ps_legalcompliance from composer.json (by @Quetzacoalt91) - - Improvement: - - #13734: Update translations catalogue for 1.7.6 (by @eternoendless) - - #13069: Update demo features (by @marionf) - - Bug fix: - - #13471: Set null values when trying to retrieve the non-existing default shop (by @Quetzacoalt91) - - #13223: Fix SQL syntax error in upgrade file to PS 1.7.6 (by @Quetzacoalt91) - - #13078: Revert "Fix delivery slips failure when upgrading" (by @Quetzacoalt91) - - #12666: Fix delivery slips failure when upgrading (by @rblaurin) - - #12155: Fix fixtures not generating thumbnails (by @PierreRambaud) - - #12141: Change php requirements in INSTALL.txt (by @PierreRambaud) - - #9366: Don't display the system step if mandatory requirements are OK (by @rGaillard) -- Web Services: - - Improvement: - - #12329: API and Products: Add missing combination IDs in the pack content (by @Quetzacoalt91) - - #11938: Make customer's product customization information reachable in WebServices (by @eternoendless) - - Bug fix: - - #12836: Fixes fatal error when trying to get the images of a product with no images (by @mowcixo) - - #12201: Fix SQL exception when creating a product_option without values (by @mowcixo) - - #11902: Fix API error with php 7.2 (by @DelecroixQuentin) - - #11192: Correctly call hook for product update in Product class (by @alexll) -- Localization: - - Bug fix: - - #10843: Fix typo in download_product.txt (by @antonellamarengo) - - Refactoring: - - #12747: Fix PhpDoc for AttributeGroupCore::getAttributes() (by @BadPixxel) -- Tests: - - New feature: - - #13167: Move lint checks in GitHub action (by @Quetzacoalt91) - - #12091: Geo-location: By IP address (by @ansar21mallouli) - - #12086: Location: zone and country (by @ansar21mallouli) - - #12049: Change position, unhook and transplant a module (by @ansar21mallouli) - - #12030: Filters by category in catalog page (by @ansar21mallouli) - - #12001: Filters in catalog page (by @ansar21mallouli) - - #12007: Delivery slip test (by @YosraAk) - - #11897: Generate invoice pdf by date and status (by @hadrich-hatem) - - #11891: Credit slip, credit slip pdf and credit slip options (by @hadrich-hatem) - - #11804: Localization: local units and configuration (by @ansar21mallouli) - - #11800: Create, edit and delete feature (by @hadrich-hatem) - - #11768: Import localization pack (by @ansar21mallouli) - - #11766: Create, edit, delete, exchange rate currency (by @ansar21mallouli) - - #9309: Check buttons in header product page (by @hadrich-hatem) - - #9312: Check order details (selenium tests) (by @fatmaBouchekoua) - - #11184: Advanced localization (by @ansar21mallouli) - - #9341: Identity (Selenium tests) (by @fatmaBouchekoua) - - Improvement: - - #13356: Adds unit tests for FormHandlerFactory (by @sarjon) - - #13176: Allow to use date as parameter for nightly builds (by @PierreRambaud) - - #13127: Do not run tests with the StarterTheme anymore (by @Quetzacoalt91) - - #13052: Remove usage of TRAVIS_BUILD_DIR (by @PierreRambaud) - - #12804: Use string value for CSRF token in DeliveryControllerTest (by @matks) - - #12793: Allow Travis phpHigh build to fail as it is an informative check, not not a mandatory check (by @matks) - - #12495: Add a descriptif comment for the broken test "installation language <> country " (by @YosraAk) - - #12490: Add a descriptive comment for the broken test "create_edit_delete_contact" (by @YosraAk) - - #12488: Add a descriptif comment for the broken test "create_edit_delete_language" (by @YosraAk) - - #12496: Add a descriptif comment for the broken test "autoupgrade" (by @YosraAk) - - #12494: Add a descriptif comment for the broken test "sort filter file" (by @YosraAk) - - #12493: Add a descriptif comment for the broken test "linkWidget" (by @YosraAk) - - #12492: Add a descriptif comment for the broken test "page" (by @YosraAk) - - #12491: Add a descriptif comment for the broken test "category" (by @YosraAk) - - #12487: Add a descriptif comment for the broken test "configuration" (by @YosraAk) - - #12482: Add a descriptif comment for the broken test "Delete category" (by @YosraAk) - - #12486: Add a descriptif comment for the broken test "read_more_module" (by @YosraAk) - - #12485: Add a descriptif comment for the broken test "create_feature" (by @YosraAk) - - #12481: Add a descriptif comment for the broken test "create_product_with_combination" (by @YosraAk) - - #12480: Add a descriptif comment for the broken test "shopping_carts_view" (by @YosraAk) - - #12021: Add unit tests for CommandBus, DocumentationLinkProvider and UrlFileChecker (by @matks) - - #12378: Improve report files generation (by @PierreRambaud) - - #12369: Fix deprecation notices reported by Composer (by @Quetzacoalt91) - - #12304: Add unit tests for Core IdentifiableObject classes (by @matks) - - #12324: Separate nightly tests and reports (by @PierreRambaud) - - #12298: Improve logging for nightly tests (by @PierreRambaud) - - #12232: Add unit tests for Core/Kpi (by @matks) - - #12256: Wrong duration time while combine nightly tests reports (by @PierreRambaud) - - #12183: Restore survival test for Import page (by @matks) - - #12188: Add test link id (by @ansar21mallouli) - - #11725: Nightly tests build on Google Cloud Platform (by @PierreRambaud) - - #11920: Add advice when lint fails + Display all files in error in Travis lint job (by @Quetzacoalt91) - - #12060: Enable PHP CS Fixer on tests folder (by @matks) - - #11865: PHP unit set up tear down visibility (by @MathiasReker) - - #11677: Fix wrong name (by @MathiasReker) - - #11674: Simplify PHP unit construct (by @MathiasReker) - - #11675: Simplify PHP unit expectations (by @MathiasReker) - - #11676: Use camelcase instead of snakecase in functions (by @MathiasReker) - - #11565: Allow tests high and fix conflicts in file (by @PierreRambaud) - - #11237: Improved survival tests (by @mickaelandrieu) - - #10724: Clean php-cs-fixer files (by @matks) - - #9421: Update test high : create product with combination/create virtual … (by @fouratachour) - - Bug fix: - - #13464: Apply CS Fixer on 1.7.6.x (by @Quetzacoalt91) - - #13113: Fix typo on static (by @Quetzacoalt91) - - #12574: Fix PositionsControllerTest for good (by @jolelievre) - - #12238: Wrong directory to check if there are files reported by mochawesome (by @PierreRambaud) - - #12225: Add a json check when running report combine (by @PierreRambaud) - - #12210: Update nightly tests (by @PierreRambaud) - - #12166: Update php-cs-fixer to a recent version to be compatible with PHP7.3 (by @PierreRambaud) - - #12079: Fix static cache reset on ObjectModel (by @tomlev) - - #10477: Added an Error Data Listener (by @mickaelandrieu) - - #12013: Isolate legacy tests into suites to fix develop branch (by @matks) - - #11898: Fix travis script for running tests and fix broken tests (by @matks) - - #11549: Fix unable to build tests container (by @PierreRambaud) - - #11306: Fix linter jobs of Travis (by @Quetzacoalt91) - - Refactoring: - - #13686: Add close welcome module for tests 11_international (by @boubkerbribri) - - #13683: Add close welcome module for tests 10_modules (by @boubkerbribri) - - #13680: Fix tests customer (by @boubkerbribri) - - #13630: Fix Onboarding close method (by @boubkerbribri) - - #13656: Fix for tests in order test suite (by @SimonGrn) - - #13657: Fix the check of the success message when saving and deleting a currency (by @nesrineabdmouleh) - - #13667: Fix test Feature 1 create edit delete feature (by @boubkerbribri) - - #13676: Add close welcome modal for tests Manufacturer (by @boubkerbribri) - - #13693: Fix first test of the order test suite (by @SimonGrn) - - #13696: Add welcome module for tests discount (by @boubkerbribri) - - #13700: Fix test 3 of the shop parameters test suite (by @SimonGrn) - - #13637: Add handling of the welcome modal and document the blocking issue for the last step (by @SimonGrn) - - #13661: Fix for test 4 of the order test suite after canonical url fix (by @SimonGrn) - - #13651: Adding close welcome module in tests product (by @boubkerbribri) - - #13659: Adding close welcome module in tests Attribute (by @boubkerbribri) - - #13612: Fix test 05 create order without account (by @boubkerbribri) - - #13615: Fix test Product suite full (by @nesrineabdmouleh) - - #13545: Fix test Employee Suite Full (by @boubkerbribri) - - #13616: Fix method used to change quantity (by @SimonGrn) - - #13602: Fix for test 2 of the orders test suite (by @SimonGrn) - - #13502: Fix test Category suite full (by @boubkerbribri) - - #13597: Fix test 09_delivery_slips_pdf_and_options (by @boubkerbribri) - - #13570: Fix broken selectors and logic for the test suite 9 (customer) (by @SimonGrn) - - #13588: Fixing some tests orders (by @boubkerbribri) - - #13581: Fix test feature update (by @ntiepresta) - - #13568: Fix tests 10_module Suite Full (by @boubkerbribri) - - #13561: Fix for tests 1 and 2 of the shop parameters test suite (by @SimonGrn) - - #13503: FIx test Create Attribute Suite Full (by @boubkerbribri) - - #13534: Fix tests manufacturer (by @boubkerbribri) - - #13552: Fix tests International/localization and international/taxes (by @boubkerbribri) - - #13536: Fixes e2e broken selectors (by @mbadrani) - - #12634: Behat cart tests (by @tomlev) - - #12679: Add some fixes to the campaign full (by @YosraAk) - - #12678: Create virtual product (by @ansar21mallouli) - - #12431: Update product quantity test (by @YosraAk) - - #12362: Go to next and previous page test (by @ansar21mallouli) - - #12355: Print the delivery slip (by @ansar21mallouli) - - #12351: Update create order in FO test (by @YosraAk) - - #12343: Print invoice order (by @ansar21mallouli) - - #12317: Create order in BO test (by @ansar21mallouli) - - #12315: Create order as a guest test and update readme file (by @YosraAk) - - #12289: Update sort module test (by @ansar21mallouli) - - #12281: Update zip module test (by @YosraAk) - - #12266: Migrate ImageTagSourceParserTest in tests folder (by @matks) - - #12272: Add checkFile step after downloading a file (by @YosraAk) - - #12245: Update check notifications test (by @ansar21mallouli) - - #12219: Update click on discover test (by @ansar21mallouli) - - #12220: Update file tests (by @YosraAk) - - #12217: Update search module test (by @ansar21mallouli) - - #12206: Installation test (by @ansar21mallouli) - - #12190: Update check the addons catalog page test (by @ansar21mallouli) - - #12181: Update onboarding test (by @YosraAk) - - #12122: Add a new brand address test (by @ansar21mallouli) - - #12115: Update create manufacturers test (by @ansar21mallouli) - - #12112: Update bulk actions in catalog page test (by @ansar21mallouli) - - #12104: Update delete shopping cart test (by @ansar21mallouli) - - #12067: Add some fixes to the campaign full (by @YosraAk) - - #12054: Migrate legacy unit test for Hashing (by @matks) - - #12045: Update autoupgrade test (by @YosraAk) - - #11776: Fix campaign full tests on develop branch (by @YosraAk) - - #11525: Introduce modern unit tests for new test structure (by @matks) - - #11529: Migrate tests-legacy tests to namespace LegacyTests (by @matks) - - #11464: Cleanup /tests directory (by @sarjon) - -#################################### -# v1.7.5.2 - (2019-05-02) -#################################### -- Core: - - Bug fix: - - #13599: Forbid URLs to be added in customer names (by @PierreRambaud) - - #13580: Fixed dispatched hook on the Grid presenter (by @mickaelandrieu) - - #13567: Improve name validation (by @eternoendless) - - #13549: Forbid URLs to be inserted into Name fields (by @matks) -- Tests: - - Refactoring: - - #13583: Fix selector in E2E tests for addons catalog page and another one in the autoupgrade test (by @nesrineabdmouleh) - -#################################### -# v1.7.5.1 - (2019-02-18) -#################################### -- Back Office: - - Bug fix: - - #12507: Add hookDispatcher in GridFactory constructor, HookDispatcherAwareTrait has a safer getter - - #12234: Force refresh of tinymce editors in product page step 1 - - #12402: Fix first attribute generation when not choosing first attribute - - #12372: Fix provider warehouse routes - - #12370: RTL fixes: profile, select and notification dropdown, popover tooltips, stock quantity arrows - - #12395: Change stock alert z index to be on top of header - - #12354: Fix cancel button on Safari browser - - #12361: Refacto SearchParameters and SearchParametersResolver for pagination - - #12205: Fix bulk module actions - - #12277: Prevent usage of enter key in search hook input - - #12236: SERP: Textarea from tinymce requires jquery to return the text value - - #12016: Update module & service link in upgrade - - #12196: Fix RTL glitches - - #12111: Keep showcase cards closed - - #11923: Fix error in SERP component when using non-alphanumeric characters - -- Front Office: - - Improvement: - - #12327: Make it possible to enable/disable attribute name on page title - - Bug fix: - - #12337: Slow combination update due to delay before request - -- Core: - - Bug fix: - - #12543: Update vulnerable dependencies - - #12389: Fixed grid hook calls - - #12292: Allow arabic numbers in link rewrite - - #12106: Robots.txt with multilang/multishop - - #11995: Fix undefined INTL_IDNA_VARIANT_UTS46 if intl ICU < 4.6 - - #11814: Fix typos and duplicate code in upgrade SQL - -- Installer: - - Bug fix: - - #11937: Check if intl is installed in installer - -#################################### -# v1.7.5.0 - (2018-12-17) -#################################### -- Front Office: - - Bug fix: - - #11777: Do not perform updateProductRequest() AJAX call if no valid data input - -#################################### -# v1.7.5.0 RC 1 - (2018-12-10) -#################################### -- Back Office: - - Improvement: - - #11533: Disable oProxyCommand when imap.enable_insecure_rsh does not exists - - #11466: Revert separated module buttons - - #11147: PositionColummn UI/UX modifications - - Bug fix: - - #11644: Fix ID replacement in urls generated by symfony - - #11584: Fix displayAdminProductsExtra hook content display in V1.7.5.0 beta - - #11600: Translate module categories - - #11572: Clear cache on module action - - #11579: Remove deprecated functions - - #11531: Fix all miswritten getAdminLink calls in templates - - #11339: Fix default values on import page - - #11508: Escape javascript and html strings - - #11475: Impossible to change position of products - - #11486: Fix layout - - #11478: Changes the redirection url after store update - - #11279: Allow product ordering on explicit request - - #11463: Fix admin translation redirect - - #11448: Remove useless trad files in install for persian - - #11447: Escape everything! - - #11421: Display configure button only if module is configurable - - #11416: Fix customer/address delete resulting in error on cart page - - #11410: Changing primary domain name no longer reindexes simplified URLs - - #11309: Add LegacyContext::getLegacyAdminLink - - #11407: Module manager sorting - - #11394: Fix crashing for bulk actions - - #11384: Add an rtlfix file to correctly hide the right side bar in rtl languages - - #11311: Be able to disable Help Link on Back Office pages - - #11337: Show more logs in admin - - #11344: Manage redirection after email translation - - #11312: Prevent short description limit to be set at 0 - - #10956: Fix product features - - #11287: Fix filemanager security breaches - -- Front Office: - - Bug fix: - - #10964: Fix bug in ajax quantity refresh - - #11261: Fixed inconsistent locale in Front Office - -- Core: - - Improvement: - - #11070: Feature/module manager categories - - #11058: Add Hindi, Mexican & Bosnian languages - - Bug fix: - - #11603: Fixed CVE-2018-19277 - - #11601: Update ps_checkpayment to latest version - - #11376: Some strings need to be escaped - - #11385: Fix missing dot in wording - - #11345: Update translations catalog - - #10845: Minor services naming fix - - #11300: Fix error on tab unregistration when handled by the module - - #9316: Fix Cart::autoAddToCart using undefined customer when called from BO - -- Installer: - - Improvement: - - #11357: Improve install warning message for beta builds - -#################################### -# v1.7.5.0 beta 1 - (2018-11-08) -#################################### -- Back Office: - - New feature: - - #10906: Add new native module ps_faviconnotificationbo - - #10414: Link modules routes, position column and extension, GridPositionUpdater - - #10422: Add stock location through ps_stock_available table - - #10234: Migration of Shop parameters -> Traffic & Seo -> Seo & urls page - - #9444: Add search engine result preview on product page - - #10208: Migration of Advanced Parameters -> Webservice -> listing - - #9465: Enable 'edit specific price' button on BO Product page which opens a pop-in - - #9449: Migration of Improve -> International -> Translations page - - #9305: Introduce ToggleColumn for Grid component - - #9310: Migrate "Configure > Advanced Parameters > Webservices" - part 1 (configuration form) - - #9457: Enable Logs page - - #9377: Migrate E-mail page - - #8984: Introduced advanced and reusable search system - - #9153: Be able to declare modern controllers in modules - - #9192: Migrate Payment methods page - - Improvement: - - #11035: Optimize legacy links in dev mode - - #11063: Improve PositionColumn to allow more route params - - #10868: Manage backward compatibility of legacy links - - #10901: Make Logger stdout configurable using env variables - - #10725: Hide delete button on ordered cart - - #10569: Update Grid definition Ids - - #10529: Implement empty states aka Showcase blocks - - #10440: Change categories in Module Manager - - #10485: Minor migrated Webservice improvements - - #9287: Separate module action buttons - - #10426: Handle boolean returns from RequestSql validation - - #10416: Improve perceived form horizontal alignment - - #10311: Small improvements for Webservice list - - #10358: Update list and settings layout - - #10265: Move Logs page JS to appropriate location - - #9471: Build Back Office default theme using Webpack 4 - - #10170: Small ux optimizations - - #9454: Notifications tab + new hierarchy - - #9451: Replace PrestaTrust property with setter - - #9228: Migrate module positions - - #9447: Migrate Backup page - - #9430: Update modern forms layout - - #8710: Improved Product catalogAction - - #9206: Migrate "Configure > Advanced Parameters > Database > SQL Manager" page - - #9397: Update style of forms on new pages - - #8690: Improved performance of Product List page - - #9410: Improve grid search and reset buttons - - #9306: Add a link to the addons' favicon generator - - #9242: Introducing reusable way to display KPIs blocks in Back Office modern pages - - #9225: Migrate "Improve > Payment > Preferences" page - - #9210: Duplicate array keys - - #9137: Improve routing of PrestaShop application - - #9139: Migrate Sell > Orders > Delivery Slips - - Bug fix: - - #11182: The deletion of themes must depends on Employee permissions - - #10898: Fixed performance rights on Performance Clear Cache action - - #11136: Fix param name on email delete all bulk action - - #11123: Make the E2E tests wait for the first load of the BO with welcome module enabled - - #11111: Revert "Apply quotes around the column names would make all the SQL r… - - #11071: Avoid glitch on checkbox click - - #10991: Fix sorting issue in the SQL Manager page - - #10861: Fix fixed height of TinyMce fields - - #10718: Add missing styles on empty state SEO & Traffic page - - #11032: Min height product image dropzone - - #10936: Prevent unvalidated form without checkboxes - - #10436: Style issue on BO - - #10968: Fix General options configuration - - #10967: Fix Bad annotations (backport of #10939) - - #10949: Update help panel position on legacy pages - - #10856: Fatal error when saving product with tags - - #10946: Allow errors without field to be displayed on product form - - #10950: Update module breadcrumb in category page - - #10810: Allow URL in search result preview to be live updated - - #10684: Avoid displaying the addon modal twice, change form names/IDs to avoid collision - - #10857: Use parent javascripts used for displaying help - - #10862: Fixes bug when filter reset functionality sometimes does not work - - #10751: [BO] Fix bug when filter stores by name or address - - #10835: Fix import module - - #10814: Restore legacy sql manager page 175 - - #10778: Enable pagination when offset is set - - #10788: Allow url in search preview to use several lines - - #10796: Reuse getAdminLink instead of copy pasting its content - - #10752: Use the right PrestaShop namespace for twig templates - - #10735: Module translations aren't working when using Smarty Extend into TPL in BO - - #10741: Fix import form alignment - - #10728: FilterParametersUpdater manages filters in a better way - - #10462: Fix wrong display of the brand page - - #10726: Module manager improvement (search, categories, configure button) - - #10736: Use new routes for quick access - - #10681: Fix module catalog js & css issues - - #10705: Move position column template - - #10656: Fix grid ids in migrated JS - - #10601: Use attr('data-') instead of data - - #10448: Fatal error while adding tags - - #10382: Bug when advanced stock management is enabled in Product Shipping page - - #10571: Fix broken service definition - - #8237: Fixed bug in AdminGroupsController when adding ModulesRestrictions to group in multishop configuration - - #10435: Removed onclick from URL column in BO Shop URLs - - #10427: Get link of the first ACTIVE tab in nav - - #10295: Display the company name in outstanding orders - - #10291: Fix the display of textarea in the category page - - #10375: Fix category tree in BO Products Catalog page - - #10361: Only load Vue Serp component if available - - #10135: PDF documents unformatted - - #9324: Fixed the Show SQL query action - - #10202: Fix 'edit specific price' modal behavior bugs and display - - #9453: Allow import entity to be preselected - - #10322: Wrong variable name - - #10326: Manage getAdminBaseLink in LegacyContext::getAdminLink - - #10302: Images aren't displayed in combinations with new products - - #10281: Fixed minor issues on Logs Grid page - - #10260: Fix help sidebar not working in the Stock page - - #10223: Fixed DB backup page - - #10221: Product Page: fix visual glitches in categories filter - - #10242: Fix wrong translations - - #10233: HookDispatcher dispatchMultiple doesn't exists anymore - - #10169: Images aren't displayed in combinations - - #10201: Errors when saving memcached configuration - - #10165: Add form handler for Translations settings forms - - #10139: Remove legacy AdminBackup controller - - #9352: Fix 'recommended modules' popin behavior in BO - - #9466: Fix combination generation - - #10042: With undefined function call (Fixed #10041) - - #9450: Modify Link::getAdminLink in MultipleShop mode - - #9407: Display NOK PrestaShop requirements - - #9455: Removed all translations errors from localization page - - #9334: Fix sample file download & fields load via ajax in Import - - #9399: Fix ajax in 500 in product page - - #9389: Fixed path to updated files in System Information page - - #9259: Make PrestaShop fully compatible with Twig 2+ - - #9369: Combinations not working when token is disabled - - #9318: Make documentation link on the dashboard point to the 1.7 docs instead of 1.6 - - #9333: Small fixes for Sell -> Orders -> Invoices page - - #9267: Unable to copy theme translations - - #9286: Grid/reset action - - #9300: Fix grid sorting by - - #9265: Can't upload an image in the product page - - #9255: Fix rendering of theme catalog page - - #9235: Corrects a bug when importing store contacts - - #9215: Adapted module URLs for new routing - - #9195: Fixed mixed up display in some cases at partial refunds - - #9198: Add use statement for AppKernel - - #9171: Fixed namespace of Delivery Slips controller - - #9170: Fix smarty condition count - - #9149: Error with quota fields - -- Front Office: - - Improvement: - - #11156: Rollback product canonical - - #11084: Update modules for new 1.7.5 version - - #11015: Adding/Deleting voucher on checkout payment step should refresh amount on payment block - - #10229: Mobile Menu: improve UX/UI of the mobile menu - - #10484: Fix: classic theme footer block design #10483 - - #9459: Show the category block in the list page on first page only - - #9472: Modify category pagination for SEO purposes - - #9362: Add breadcrumb to the contact page - - #9456: Modify product canonical url and title value - - #10207: Voucher button is too long in Cart - - #9458: Change brand and supplier default rule for SEO purposes - - #9463: Change the default redirection behaviour to product category - - #9417: Override CustomerAddressForm->submit method more easily - - #9097: Fix phone fieldtype - - #9110: Make checkbox labels clickable on the classic theme - - Bug fix: - - #11055: Fix minimum quantity blocking - - #10812: Display the specific reference for each combination's product - - #10447: Double h1 tag on category page - - #10750: Do not display product Reference if empty - - #10428: Fixes issue #10417 incorrect argument order - - #10438: Fix for Issue #10433 : Update lastName and firstName max size - - #10267: Product List: pack flag visual problem - - #10350: Fix empty row when social title is empty - - #10347: Fix htaccess to support Apache 2.4 webservers - - #10352: Fix htaccess to support Apache 2.4 webservers - - #10279: Check minimal quantity - - #10254: Fix getTotalWeight Notice - - #10232: Generate front core assets - - #10230: Add magic methods on LazyArray classes for object-like use - - #9387: Fix for browser back button on product page - - #10195: Fix the bootstrap classes for left-column ID - - #9405: Error when adding product in cart or editing quantity - - #9469: Do not display product Specific References if empty - - #9462: Fix wrong rules in robots.txt - - #9441: Fix 403 error when accessing localhost using IPv6 (Maxmind Database exists) - - #9422: Add missing appendArray in OrderReturnLazyArray (BOOM-6039) - - #9433: Add customizations field in product whitelist - - #9445: Change out of stock condition with greater or equals - - #9446: Fix welcome page variable injection by adding missing % - - #9429: Add formatted field file_size_formatted in attachments - - #9390: Combination issue while trying to change size on a product page - - #9403: Convert ProductLazyArray when using render function - - #9368: Detect if there is already GET param in URL - - #9372: Update OrderFollowController.php - - #9381: Fix label "Use this address for invoice too'" - - #9373: Prevent users from doubleclick on Payment button from #9351 - - #9276: Fix product quantity in order return details table - - #9353: Correctly handle hyphens in search index - - #9219: Fix delivery time not shown - - #9214: Fix products pagination without URL rewriting - - #9211: Updated page parameter name in Link and Meta classes - - #9069: Fix gift wrapping fees - -- Core: - - New feature: - - #9281: Allow overriding of every part of Grid templates - - #9460: Implementation of CQRS in SqlManager page - - #10241: Add Tactician command/query bus - - #9344: Add function to display information message - - #9230: Migration of Sell > Orders > Invoices page - - #9094: Migrate Improve > Shipping > Preferences controller - - #8990: Introduced Grid system - - #9116: Migrate localization page - - #9174: Added a service to manage PrestaShop versions (may deprecate _PS_VERSION_) - - #9121: Make commands from PrestaShop modules available in PrestaShop application - - #9007: Migrate Shop parameters -> Order settings page - - Improvement: - - #11068: Prevent CS Fixer from adding a trailing dot to the first paragraph of phpdoc - - #11078: Update dependency for security reason - - #10905: Update catalog - - #10883: Missing translations - - #10863: Update translations catalog for 1.7.5 - - #10662: Update native modules - - #10464: Undeclared property in the PaymentModule class - - #9292: Update pull-request template with additional PR types - - #9402: Improve grid data providers - - #9356: Add new variable in product.php, to sort features in front - - #10219: Minor grid improvements - - #8744: Prefer Hook::coreRenderWidget - - #10151: Replaced Forge URL with GitHub issues - - #9396: Update version to 1.7.5.0 - - #10138: Avoid a DB query in Address:isUsed() in case of new Address - - #9470: Refactored the Grid component - - #10110: Replace Forge with GitHub issues in PR template - - #9440: Ease CustomerAddressForm customization - - #9437: Introducing HookDispatcherInterface - - #9554: Update links to use GitHub issues in README.md and CONTRIBUTING.md - - #9467: Build core theme using Webpack 4 and jQuery 2.2.4 - - #9461: Update Readme - - #9442: Decouple filters and columns - - #9428: Added a new hook to custom SwiftMessage before sending mail - - #9452: Small naming update in grid - - #7612: Added new actionFrontControllerSetVariables hook - - #9291: Small FrameworkBundleAdminController clean up - - #9426: Add comment line to Address.php - - #9432: Make it unnecessary to append a '_' to the controller name when using the AdminSecurity annotation - - #9424: Issues templates - - #9404: Add gsitemap - - #9320: Phpdocs2 - - #9384: Update README.md - - #9342: Make grid.js more extendable - - #8904: Add new presenter implementation optimized for performances (lazy loading) - - #9319: Phpdocs - - #9250: Implement addBefore() & addAfter() methods of ColumnCollection - - #9264: Avoid AJAX request if we didn't have a refresh URL in the core cart JS file - - #9293: Rename routing file catalog.yml to _catalog.yml to follow routing structure - - #9282: Cleanup ModuleTemplateLoader - - #9283: Update column naming - - #9256: Improve resolving of column options - - #9254: Merge 1.7.4.x in develop - - #9201: Refactor Version class and client code and add unit tests - - #9208: Glob and scandir without sorting are faster - - #9229: Merge 1.7.4.x in develop - - #9207: Replace array_push calls behaving as $array[] since it works faster than invoking functions in PHP - - #9199: Introduced Survival tests for new modern pages - - #9205: Improve form choice providers - - #9209: Callable calls in loops, repetitive calls - - #9204: Remove leftover routing files - - #9176: Migrate "Improve > International > Localization > Geolocation" page - - #9066: Refactor Dispatcher::useDefaultController() - - #9182: Merge 1.7.4.x in develop - - #9154: Migrate Theme Catalog Page of Design Section - - #9162: Remove useless line for meta_title - - #8956: Add customization ID to cart ajax response and updateCart event data - - #9163: Case mismatch in class/function/method call - - #9155: Updated contributor list - - #9146: Merge 1.7.4.x in develop - - #9037: Permit IDE completion with PHP doc - - #9096: Clean up service yml files - - #9067: Refactor Controller class (minor changes) - - #9115: 1.7.4.x into develop - - #9109: 1.7.4.x into develop - - #9053: Add missing package-lock.json files - - #9091: Update develop with 1.7.4.x changes - - #9056: Deprecate polyfill function array_replace() - - #9068: Refactor Cart::checkQuantities() - - #9062: Improved errors management if Dev mode is enabled - - #9071: Refactor AbstractCartTest - - #9061: Removed redundant checks and added docblock in Tools::getIsset function - - #9035: Add package-lock.json file - - Bug fix: - - #10446: Increase max size of reference, meta_title, meta_description email, password, firstname, lastname and company. - - #11066: Fix wording in wrong domain - - #11076: Fix wordings - - #10933: Fix translation catalog - - #11030: Harmonize migrated controllers - - #10865: Fix compatibility with PHP 5.6 for PS exception - - #10840: Update Smarty and Symfony to latest - - #10837: Remove rebuild of SymfonyRequirements file after every composer run - - #10795: Use https only for API calls and limit use of guzzle - - #10696: Check $sfRouter before using it - - #10743: Execute query modification hook before fetching data - - #10376: Update HTML purifier - - #10419: Change Javascript indent to 2 spaces, per AirBnb rules - - #10363: Fix undefined method in query parser - - #10337: Remove hard-coded-version in assets URL - - #9475: Make title different from meta title on CMS for SEO purpose - - #10287: Fixed pre-commit hook script - - #10227: Fixed error with inheritance - - #9343: Fix function comment of Module class - - #10200: Bring back Addons Catalog controller - - #10218: Fix falsy value returned by upgrade script - - #10182: Fix deprecated call to Tools::replaceByAbsoluteURL - - #10155: Fix trusted modules cache creation - - #9474: Files from translations folder can not be accessed - - #9436: Remove unused taxes - - #9244: Fixed Apache Optimization - - #9285: Allow more than 36 products per page - - #9386: Merge 1.7.4.2 into develop - - #9047: Fixed nginx config for symfony controllers - - #9289: Version/update release creator - - #9145: Bug correction when changing shipped state - - #9231: Fixed missing call of ObjectModel hooks in CMSCategory::delete() - - #9257: Allow overriding getRobotsContent in Tools.php - - #9234: Fix override handling when PS_DISABLE_OVERRIDES is used - - #9243: Fix show sql action in logs page - - #9120: Fix empty text transformer to not treat zero as empty text - - #9241: Fix Version service namespace usage - - #9203: Fixed bug with friendly URLs and Media Servers - - #9190: Fixed DataConfigurationInterface PHPDoc - - #9105: Check if key exists before checking the value - - #9156: Fix missing security event listeners registration - - #9140: Update composer dependencies - - #9122: Add safety returns after ajaxRender calls - - #9039: Ajax will never die - - #9095: Fix translations order settings and remove unused templates - - #9050: Fix HookConfigurator: Filter certain non-arrays from theme.yml - - #9098: Rename variable $producPropertiesCache (fix typo) - -- Installer: - - New feature: - - #9401: Check at installation if PrestaShop version is the latest - - Improvement: - - #10909: Made the installed theme configurable - - #9340: Update rel="noopener noreferrer" - - #10106: Add Galician language in the installer - - #10104: Add Latvian language in the installer - - #9414: Add arabic language in installer - - #9411: Indian Localization improved - - Bug fix: - - #11206: Installer: always clean test assets even if filesystem tests fail, an… - - #11209: Ignore irrelevant SF warning aout composer at install - - #10296: Init Kernel when possible during installation process - - #10410: Fix fixtures inconsistencies - - #9464: Fix geolocation whitelist - - #9425: Fix step name retrieved in the installer - - #9409: Symfony requirements file now compatible with PHP 7.2 - -- Web Services: - - Bug fix: - - #10117: Fix bug shipping number is empty in {followup} - - #9439: Fix Error 500 from API request with PHP 7.2 - - #9202: Preserve position in category when adding a new Product using Web services - -#################################### -# v1.7.4.4 - (2018-11-06) -#################################### -- Back Office: - - Bug fix: - - #11228: Avoid warning in WebServiceRequest - - #11285: Fix filemanager security breaches - -#################################### -# v1.7.4.3 - (2018-07-27) -#################################### -- Core: - - Bug fix: - - #10829: Hide arguments in debug trace page - -#################################### -# v1.7.4.2 - (2018-07-27) -#################################### -- Back Office: - - Bug fix: - - #9358: AdminSearchController.php : Parameter must be an array or an object that implements Countable - - #9359: Allow configuration to save html data - - #9330: It is impossible to create a SQL query "SELECT" - SQL Manager page - - #9326: Module translations aren't working when using Smarty Extend into TPL - - #9327: Fixed Product form when stock management is disabled - - #9322: Backward compatibility of $this->isCached() in modules - - #9279: Fix detection of APCu on Performance page -- Front Office: - - Bug fix: - - #9378: Generate core.js - - #9374: Fix multishop price calculation - - #9364: Fix JS error after add to cart - - #9365: Wrong generated template path when using getCurrentSubTemplate with a full path name. - - #9357: Core.js typeerror after updatecart - - #9335: Url does not update when changing product attributes -- Core: - - Bug fix: - - #9348: Fixed a misnamed variable - - #9345: Can't install prestashop in dev mode with open_basedir - - #9339: Fix bug extra space: htaccess directive order -- Installer: - - Improvement: - - #9361: Set allow_url_fopen optional in the system step - - Bug fix: - - #9371: Ntree regeneration should be done also if the entity arg is empty during install - - #9355: Allow to install PrestaShop without allow_url_fopen enabled -- Tests: - - Improvement: - - #9321: Add some fixes to the script and update scenario of onboarding - -#################################### -# v1.7.4.1 - (2018-07-16) -#################################### -- Back Office: - - Improvement: - - #9311: Apply shop context in configuration - - Bug fix: - - #9299: Fix error while duplicating a product when catalog specific price rules are stored - - #9297: Fix display when a module uses $this->bootstrap = false; - - #9261: Update Controller name for link generation to modules catalog - - #9268: Added .htaccess to var folder -- Front Office: - - Bug fix: - - #9315: Fix not visible category display - - #9295: Fix free shipping display on cart - - #9270: Apache 2.4 configuration - - #9252: Add combinations in cart summary -- Core: - - Bug fix: - - #9288: Fix Cart::isVirtualCart() method when cart is empty - - #9298: Fix/remove mbo from tests - - #9220: Ability to use widget block from specific hook - - #9269: Update ps_themecusto to version 1.0.6 - - #9237: Fixed bug with friendly URLs and Media Servers - - #9101: Fix have cart rule today -- Installer: - - Improvement: - - #9302: Reduce the number of ajax calls if the fixtures are not too larges and if there's enough memory available - - Bug fix: - - #9271: Catch more exceptions during install & display the error intead of a JS error - - #9258: Limit subquery results in upgrade sql 1.7.0.0 - -#################################### -# v1.7.4.0 - (2018-07-03) -#################################### -- Back Office: - - New feature: - - #9117: Add theme custo - - #8920: Migrate Shop Parameters -> Customer Settings - - #8680: Migration of page Shop Parameters > Product Settings - - #8705: Introduce switch type in forms - - #8604: Migration of page Shop Parameters > General > Maintenance - - Improvement: - - #9189: Hide disabled level 3 tabs in the BO - - #8914: Improve header BO design - - #9102: Update BO theme to Bootstrap 4 final - - #5102: Select not ordered cart directly in SQL instead of excluding ordered cart in PHP - - #9008: Use getBoolean() instead of get() when configuration is bool in Product Settings page - - #8927: Remove default theme schemes (no longer used) - - #8947: Hooks for recommended modules & themes - - #8908: Refactored Form Handling management - - #8916: Add tips in the back office to improve user experience - - #8637: Update back-office menu style - - #8837: Replace Open Sans font with Vazir font for Farsi (BO new theme) - - #8836: Replace Open Sans font with Vazir font for Farsi (BO default theme) - - #8896: Optimize breadcrumb computation performances - - #8814: Module tab new subtree - - #8523: Migrate Logs page to Symfony - - #8924: Refactored Back Office controllers - - #8368: Implement dynamic form customization - - #8859: Passing language ID for Store object instance - - #8899: Optimize stock queries - - #8790: Optimize reserved product quantity update - - #8515: Upgrade Symfony to 3.4 LTS - - #8645: Modify string for product page - - #8489: Improved Product pages templates management - - #8547: Better performance in order template - - #8557: Added more informations from args in Hooks profiler - - #8365: Migrate Administration Page to Symfony - - #8244: Show installed modules by default instead of the modules selection - - #8479: Removed old emailing category - - Bug fix: - - #9223: SSL field is only available is accessed using HTTPS protocol - - #9221: We should be able to activate SSL - - #9212: Fix position of PrestaShop logo when in RTL - - #9194: Handle 1.7 method in update function 'add_new_tab' - - #9183: restore missing translation keys - - #9173: Registered all namespaces in ModuleTemplateLoader class - - #9181: Use CustomerPreferencesFormHandler to handle specific tabs toggling for B2B mode - - #9175: Missing requirement message - - #9169: Fix product attachment list - - #9160: Fix 500 while getting order total - - #9133: Regression with DatePicker and checkboxes on stock page (catalogue > stock) - - #9157: State filter in catalog page doesn't work - - #9151: Fix undefined method trans() when loggin on the marketplace from the module page - - #9143: Fix unknown key route error in customer settings page - - #9082: Error while searching for a product - - #9089: Catch module theme installation error, add error message for invalid module - - #9028: Introduced re-usable authorization system - - #9118: Fix BO login icons - - #9113: Fix wrong css file on BO login page - - #9106: Add a product removal confirmation - - #9077: Update welcome module version - - #9076: Fixed duplicate carts in back office - - #9084: Saved confirmation message isn't displayed anymore in translation page - - #9074: Ordering product in BO doesn't work - - #9086: Fix template on attachment delete - - #9081: Can't enable maintenance mode - - #9046: Reduced permission levels for theme edition - - #9051: Bad link in breadcrumbs in symfony pages - - #9044: Fix delivery time labels not displayed - - #9040: Fix Smarty.class.php class not found - - #8938: Display tabs on the module page with the generic method - - #9023: Avoid infinite redirects if unhandled exception during BO authentication - - #8838: Fix tinymce RTL text direction - - #9004: Fixed search on manufacturer's name - - #8995: Display the notification count on the proper tab - - #8932: Fix display error on module selection list - - #8830: Fix uninitialized $moreStepLabels in AdminImportController - - #8945: Return default values when api is unavailable - - #8933: Fix bug on saving store hours - - #8895: Allow override of every modern template - - #8918: Add unlimited timeout to dropzone configuration - - #8700: Admin permission detection of Role classe name - - #8909: Allow autoloading in modules for services use in BO - - #8944: Hide Logs page - - #8923: Fixed url redirection on Administration page - - #8912: Fixed template path - - #8910: Collect all hooks for the debugger - - #8890: Fix display of image form in product page - - #8864: Removed almost all deprecations on Product page - - #8863: Fixed misuse of magic routing - - #8529: Fix bug alignment sidebar menuCollapse Admin theme - - #8865: Fixed CCC settings - - #8872: Validator:validateValue is not available in Symfony3 - - #8613: Fixes AdminController's processDeleteImage() redirect after URL - - #8672: Move submit button to the right in sf forms - - #8580: Added Back Office missing roles - - #8611: Fixed bad display manufacturer when multishop - - #8617: Fix/suppliers block refresh - - #8588: Add parameter to setMedia - - #8599: Move Advanced Parameters section to Configure section (Cherry pick) - - #8524: Fixed forms deprecation (Symfony3) on performance page - - #8481: Don't display error if AdminShopGroup doesn't exist - -- Front Office: - - Improvement: - - #8774: Ajax calls for product availability status in front refactored - - #8833: Hide empty list if all variations are out of stock - - #8469: Add a few optimisations to speed up the display of the order history page and to allow potential override to skip unneeded costly informations - - #8792: Update url in Readme :) - - #8741: Improve SEO - Hn tags in Classic Theme - - #8652: SEO - Add hreflang links for multilang pages - - #8563: Add FORCE INDEX to workaround bug in MySQL - - #8474: Allow developers to add items to breadcrumb from tpl - - Bug fix: - - #9172: Fix auto-remove carrier-specific voucher when changing carrier - - #9138: [FO] Fix notice on brands page - - #9227: Add alt tag for images categories - - #9134: Fix undefined index on supplier page in FO - - #9080: Fix Punycode problem when register - - #9055: The special offers are disappearing suddenly - - #9036: Fix infinite loop on multiple vouchers - - #9073: Fix gift wrapping fees added even if not checked - - #9027: Fix wrong schema of "InStock" for Out of stock products - - #8972: Discount / Wrong variable use in loop for mobile - - #9017: Fix wrong parameter verification, allowing redirection to arbitrary URL - - #9016: Corrected email subscription form input type - - #8411: Refactor Cart getOrderTotal - - #8902: Display the "No Image" image for Products with no image - - #8884: QUERY_STRING is not set on all environments - - #8866: Fixed breadcrumb links in ProductController - - #8823: Fixed broken search after #8741 - - #8636: An error on servers with PHP 7+ - - #8548: Remove useless die in StoresController - -- Core: - - New feature: - - #8781: Getting Currency data from Currency data layers middleware stack - - #8888: New Locale integration tests - - #8935: CLDR : Replace legacy number and price formatting - - #8246: Make PS compatible with PHP 7.2 - - #8882: Migrate import page - - #8883: Migrate ShopParameters->General page - - #8732: CLDR reference data (files) reader - - #8722: CLDR Locale Cache data layer - - #8718: Renamed locale and currency data objects (no more use of "bag") - - #8698: CLDR Data layers - - #8693: Number specification Repository, Locale Repository - - #8683: Locale entity needs to aggregate Price Specifications (one by installed currency) - - #8667: CLDR currency (interface, entity and repository) - - #8662: Moved CLDR to Core - - #8597: CLDR number formatter - - #8581: CLDR specification entities - - Improvement: - - #9167: Update native module versions - - #9079: Added $result (from facet) in hook filterProductSearch - - #9048: Removed if statment - - #9038: Update pull request template - - #9022: Make bin/console executable - - #8996: New doc block for method, reduced code of method - - #9020: Update to right name, markdown with links and more - - #9021: Create LICENCE.md - - #9018: Add copyright information to the license. - - #8979: Move administration page to proper location - - #8980: Remove deprecated message for DataCollectorInterface - - #8970: Improved readability - - #8959: Able to pass hook as a parameter - - #7944: Call getPackageShippingCost of modules even if carrier is free - - #8929: Merge 1.7.3.1 into develop - - #8853: Make override of object models easy - - #8876: Disable Symfony tokenization in routing - - #8270: Allow modifying IdentityController to save personal information without password - - #8514: Added GroupBy option for actionAdminProductsListingFieldsModifier hook - - #8885: Improve PrestaShopBundle config structure - - #8811: Merge 1.7.3.x - - #8764: Change all links to PrestaShop Help/Addons/Developers from http to https - - #8756: Update license headers for 2018 - - #8709: OrderDetailsController should use Tools::getRemoteAddr() function instead of instead of $_SERVER['REMOTE_ADDR'] - - #8656: Fix services naming - - #8663: Merge 1.7.3.x into develop - - #8623: Merge 1.7.3.x into develop - - #8625: Update README.md - - #8583: Add help for upgrade file - - #8566: Use official Smarty lib - - #8606: Fixed newsletter registration date doc - - #8561: Make Symfony form management more robust - - #8602: Handle form request after authorization check in PerformanceController - - #8546: Add some missing Phpdoc in SpecificPrice - - #8405: Update PrestaShop deps: Symfony3, PHP 5.6 and PHPUnit 5.7 - - #8486: Refactor code in ControllerCore and AbstractFormCore - - #8483: Module name in order details data - - Bug fix: - - #9233: Updated dependencies - - #9226: Fixed access to Front Office container from modules - - #9216: Make deprecation warnings opt-in - - #9188: Fix wrong test in left join condition - - #9064: Fixed list of activated modules - - #9054: Added missing use statment in AddonsCollection class - - #9024: Merge 1.7.3.2 into develop - - #9029: Revert CLDR integration - - #8985: Fixed order gets wrong status when ordered all qty of the product. - - #9010: Check if template_vars if an array before merge in OrderHistory::sendEmail() - - #8767: Show prices within a tax if it's needed - - #8998: Create missing subfolders in folder override/classes - - #8954: Allowed robots access to assets requierd to be mobile-friendly - - #8976: Set cache driver in container instead of env var CACHE_DRIVER - - #8982: Merge 1.7.3.x into develop - - #8831: Better handling of invalid modules from Addons API - - #8962: Properly handle set of the PK value in the EntityMapper - - #8960: Fixed undefined class constant - - #8600: Fix fatal on array_merge if query in addMissingProductFields returns no result - - #8757: Prevent using "¤" and "|" as customer name - - #8928: Change php version in server configuration - - #8926: Fix deprecation message - - #8754: Fix non-filtered meta by filterHtmlContent hook - - #8743: Fix the links sent in the mails (multilingualism) - - #8685: Fixed link_rewrite argument for getImageLink(). - - #8689: Fix translator in prod mode - - #8674: Rename old paths of cache and logs for SF 3 - - #8694: Product name error if not english - - #8399: Fix search relevance wrong sort order - - #8458: Default AJAX Relevance search sort order is wrong - - #8577: Synced 1.7.3 into develop - - #8582: On CLI, display simple information on PrestaShopException - - #8576: Added new gitignore directives about translation packs - - #8573: Added docs about CSV import samples - - #8558: Merge 1.7 into develop - - #8530: Merge 1.7.3 into develop - - #8511: Fix array declaration - - #8488: Fix robots.txt, exclude order param - -- Installer: - - New feature: - - #7721: Add docker compose - - Improvement: - - #8889: Add tests for getDirectories - - #8788: Speed up test_dir with a lot of files present in a directory - - #8789: Do not call search::indexation at each entity creation - - #8668: Allow to setup the shop with SSL by default using CLI installer - - Bug fix: - - #9052: Fix error populating tables when installing in Greek - - #8981: Set explicit version of MySQL in docker-compose.yml - - #8020: Fix not handled new tab ID during migration - - #8556: Fix store hours migration - -- Localization: - - Improvement: - - #8997: Fix TVA rate in Tunisia - - Bug fix: - - #9200: Fix duplicate wording - - #9196: Fix wrong translation domain - - #9197: Fix duplicate wording - - -#################################### -# v1.7.3.4 - (2018-06-27) -#################################### -- Core: - - Improvement: - - #9222: Improve cookie encryption - -#################################### -# v1.7.3.3 - (2018-05-24) -#################################### -- Back Office: - - Bug fix: - - #9026: Fixed display error on back office module selection list -- Front Office: - - New feature: - - #9099: Follow-up to: display GDPR consent checkbox in contactform - - Improvement: - - #9104: Add compliance to GDPR law for ps_emailsubscription module - -#################################### -# v1.7.3.2 - (2018-05-03) -#################################### -- Back Office: - - Improvement: - - #8834: Adds missing Persian translations for data and samples - - Bug fix: - - #8752: Check product availability before validating orders - - #8975: Fix broken "you must first create a new language" link in BO Translations - - #8965: Fix theme install with prestatrust modules - - #8517: Fixed bug when using 2 swap in 1 form - - #8948: Fixed update of combinations - - #8762: Specific price created for a cart is displayed in the front end as the product price -- Front Office: - - Improvement: - - #8835: Replace Noto Sans font with Vazir font for Farsi in Classic theme - - Bug fix: - - #9005: Fix cannot order oos product even if it's allowed - - #8951: Fix error display on cart quantity edition - - #8946: Fix button show password height on Safari - - #8940: Check product availability in order step - - #8931: Out of stock message display only if customer can order the product -- Core: - - Bug fix: - - #8973: Fixed undefined class constant - - #8850: Fix profile permission array construction - - #8679: Catch Throwable errors on CLI install and check Theme instance in context -- Installer: - - Improvement: - - #8843: Minor install improvements - - Bug fix: - - #8949: Remove addition of . folder in release archives -- Localization: - - Improvement: - - #8832: Update Iran tax rate - -#################################### -# v1.7.3.1 - (2018-04-09) -#################################### -- Back Office: - - New feature: - - #8849: Add User club and UserVoice on BO link footer - - Improvement: - - #8664: Change employee icon - - #8500: Make sure shop list in header is scrollable with lot of items - - #8780: Improve BO speed by removing menu images - - #8725: Replace Google+ link on BO footer by Youtube link - - Bug fix: - - #8925: Stop generating RTL css file for the default theme using SASS - - #8921: Fixed CDN management in Performance page - - #8871: Improved rendering of combinations in Product page - - #8779: Little css override for modal title - - #8631: Request module zip for upgrade ONLY when the version available is higher - - #8714: Update loaded details from database on module action - - #8696: Fix translation issue during language install - - #8648: Fix modal backdrop not removed when uninstalling a module - - #8618: Fix type warning in order detail - - #8525: "No tax" price option is now well saved in admin product page - - #8476: Fix customer search in new order form - - #8234: Fixed bug on save specific price priority for specific product -- Front Office: - - Bug fix: - - #8873: Fix contactform module issues - - #8856: Fixed undefined variables when an url is called in ajax - - #8847: Override advertising module on classic template to fix image width - - #8845: Fix search bar on header when it moves from hook and improve header structure #2 - - #7775: Resolve incompatibility between canonical redirections, attributes and product route not only containing rewrite - - #8846: Fix menu width and submenu hover on header - - #8522: Fixed specific price percentage rounding on front product page -- Core: - - Improvement: - - #8867: Rely on the right legacy container if available on modules - - #8584: Update toCamelCase - - #8795: Minor improvements during install - - Bug fix: - - #8922: Fixed access to Front Office container from modules - - #8766: Show unit price within a tax in order confirmation e-mail - - #8607: Fix pack stock issues - - #8711: Default AJAX Relevance search sort order is wrong - - #8803: Stop full object exposure on the front end - - #8708: Debug of Tools::strReplaceFirst that do not correctly compare the return of strpos + PhpDoc - - #8498: Fixed bug on reorder with free gift in the cart - - #8543: Layout broken by cache clear - - #8669: Make sure all adresses are reset on cart - - #8462: Fix empty module return on actionEmailSendBefore breaks all email send - - #8277: CustomerAddressFormatter states were queried without the status (active) check causing disabling states in BO useless -- Installer: - - Improvement: - - #8860: Make the dezipper great again - - #8806: Sample products in FA - - Bug fix: - - #8913: Fix issue with pack in fixtures (installer) - - #8891: Fix dezipper redirect - - #8858: Include docs when creating zip build -- Tests: - - New feature: - - #8812: Delete product - - #8829: Add script for screenshot display on Travis - - Improvement: - - #8881: Check the pagination of product in the Front Office - - #8898: Check generated combinations table - - #8903: Add some fixes to the script - - #8813: Check the product discount in the Front Office - - #8805: Reset module Welcome if the RESUME button does not exist - - #8878: Check the appearance of tinymce field on the product page - - #8854: Check the change of the default combination from the edition page - - #8819: Fix sort product script - - #8810: Check the total price in the shopping cart - - #8815: Re-enable functional tests - - Bug fix: - - #8842: Fixed Travis build (update Chrome browser version) - - #8746: Make file copy on ModuleSelfConfiguration mockable - -#################################### -# v1.7.3.0 - (2018-02-28) -#################################### -- Back Office: - - New feature: - - #8378: Integration of PrestaTrust in module management - - #8419: Product Page - Shipping: delivery times - - #8396: Send an email on low stock - - #8390: Add Icelandic as supported language - - #8249: Display "Generate RTL stylesheets" section - - #8218: Add bulk edition in stocks - - #8293: Low-stock alert configuration in the Product Page - - Improvement: - - #8796: Update theme preview image - - #8659: Re-enable uglify on the new theme - - #8559: Fix search bar style on symfony pages - - #8502: Unavailable product message is now the same for any action in cart page - - #8495: Improved how to detect if a module is a payment module - - #8401: Add a new hook on AdminCutomers view > Addresses actions - - #8472: Customized Debug toolbar with PrestaShop application information - - #8271: Add multiple feature with the same type but different values to product - - #8326: Fix stock design - - #8026: Translate store schedules, name and address from BO - - #8372: Migrate Modules Catalogue page to Symfony - - #8385: Wording for 1.7.3 - - #8395: Add translation domains to legacy templates - - #8254: Migrate System information page to Symfony - - #8318: Fix translations page new ui kit - - #8311: Fix module page new ui kit - - #8297: Fix product page new ui kit - - #8284: Catalog page with new ui kit - - #8278: Use the brand new UI Kit - - #8260: Remove CSS included directly in twig files - - #8202: Add caching for theme yaml file - - #8208: Add active filter in stock management - - #8204: Fix str2url js with new chars - - #8127: Do not throw exception on API request error for module categories - - Bug fix: - - #8777: Fix directory listing - - #8761: use json_encode instead of serialize - - #8737: Fixed combination images selection - - #8704: Support Arabic numbers in the Product page - - #8702: Fix RTL visual glitches - - #8671: Fix visual regressions on Firefox - - #8697: Added Back Office missing roles - - #8616: Fix dropdown buttons space - - #8610: Fixed undefined function .size using jQuery 3 - - #8574: Moved Advanced Parameters section to Configure section - - #8569: Fix category filter dropdown glitches - - #8550: Introduced a consistent method to get route name if Hooks dispatched in modern pages - - #8562: Fix alert boxes using bulleted lists - - #8565: Fixed mass action fields positioning in admin catalog page - - #8545: Urlencode to prevent some XSS injection - - #8526: Fixed display of Category tree on Product page - - #8555: Restore tooltips on performance symfony page - - #8552: Notifs dropdown open/close is bugged on SF pages - - #8553: Fix UI kit problems - - #8549: Fixed Hooks data collector display - - #8520: Fix modal display on product page - - #8521: Update style of product combination tokens - - #8496: Fixed category tree arrows behavior - - #8509: Update the default product order with ID desc - - #8512: Fix menu collapse button alignment - - #8507: Avoid null as caching system in shop params - - #8501: Fixed PrestaShop version on Addons Store url iframe - - #8506: Fix smtp undefined in system information - - #8503: Fix/undefined none cache option - - #8494: Reduce javascript execution time on product pages - - #8491: Fixed admin category tree radio buttons positioning - - #8265: Remove duplicate call to trans for modules - - #8480: Fixed PrestaShop docs link in debug toolbar - - #8477: Added displayDashboardToolbarTopMenu and displayDashboardToolbarIcons hooks - - #8442: Fixed duplication of hooks in pages migrated to Symfony - - #8468: Fix wrong typehinting on attribute prices - - #8461: Fixing data duplication when using 1-click upgrade multiple times - - #8456: Fix JS error on Performance page - - #8440: Invalid path to look at config.defines.inc file permissions - - #8451: Fix several UI problems - - #8452: Catalog controler wrongly use by default desc sorting instead of "last" - - #8436: Fixed invalid selector on feature removal (Product page) - - #8438: Fixed product url preview - - #8421: Module page quicks - - #7986: Fixed bug where address required fields were required for any address type (customer, brand...) - - #8391: Fixed missing translations of Information System page - - #8097: Fix save carrier with invalid ranges - - #8413: Empty default label for product configuration - - #8414: Fix the button of add a new customization field in the product page - - #8406: Fix low-stock display - - #8269: Refacto of module permission checks - - #8255: Fix import products without Force all ID numbers - - #8388: RTL fixtures and improvements in BO - - #8370: Fixed silenced error - - #8375: Fix product page blocks spacing - - #8377: Fixed minor visual issue in Information page - - #8355: Fix product pages tabs - - #8359: Fix module dropdown - - #8322: Fix stock alert - - #8147: Display transporter block in RTL - - #8148: Fix bug employee thumbnail - - #8253: Add class to fix input style bug in AdminOrders controller - - #8163: Fix encoded back URL - - #8066: Allow admin folder name inside quick access link - - #8203: Fix width of column too small of pdf invoice - - #8149: Change attribute groupe name with not public name for BO - -- Front Office: - - Improvement: - - #8739: Demo products - - #8264: Improve performance of subselect query when fetching attributes of current group - - #7924: Add amount discount on product thumbnails - - #8060: Make the store email clickable in the footer - - Bug fix: - - #8490: Fix undefined offset on new products - - #8478: Fix shopping cart when allow checkout with wrongly product - - #8447: Add cover to allowed properties in ajax requests - - #7873: Fix bug after removing product customization - - #8435: Fixed bug where invalid address message is displayed only for billing address even if both are invalid - - #8348: Fix SQL error when product search starts with an hyphen - - #8416: Display properly ps_linklist on classic with widgets - - #8425: Use regexp instead of simple explode for complex attributes in CartPresenter - - #7975: Fix checkout exception when adding required field to address - - #8408: Missing name attribute form date fields - - #8382: Remove mistake ltr directions in rtl css files - - #8351: Add id_product_attribute to productLink - - #8331: Display errors on change password (lost) - - #8314: Fix the except_pages in theme.yml - - #8281: Fixes wrong images on order confirmation page with simple products - - #8225: Use PS_GUEST_CHECKOUT_ENABLED ... only in checkout - - #8195: Reintroduced the guest allowance check in FrontController. - - #8207: Fixed bug in the link tracking number for the detail order - -- Core: - - New feature: - - #8513: Add the possibility to build a release version - - #8342: Make modules act like Symfony Bundles - - #8467: RTL - Merge conflict - - #8347: Added methods to check in which context module is executed - - #8327: Added a new collector for Hooks - - #8300: Import / Export features from the Stock Overview page - - #8248: Change CSS files path to RTL stylesheets if needed - - #8243: Add new method to generate RTL stylesheets - - #8128: Sample config file for Nginx server - - Improvement: - - #8713: String to translate for 1.7.3 - - #8691: Add RTL generation for modules and some rtl fixtures - - #8657: Integrate RTL CSS generation in the core - - #8605: Specify version for all PS native modules - - #8570: Set version on prestashop/translationtools-bundle - - #8527: Enable the Symfony serializer service - - #8402: Optimize cart rule performances - - #8455: Make urls available on maintenance & restricted country templates - - #8465: Remove useless method from Customer class - - #8403: Optimise shipping cost computation - - #8381: Remove risky and useless sprintf() calls - - #8409: Improve cache - - #8453: Improve order presenter performance - - #8441: Use DISTINCT in query to improve uninstall() method in Module class - - #8279: Migrate Performance page to Symfony - - #8415: Remove product description length limit - - #8209: Remove useless call to addRoute for multilanguages shops - - #8410: Improve getContextualValue performances by reducing the number of calls to getOrderTotal - - #8392: Improved loading of translations - - #8339: Array-check in additional form fields from modules - - #8317: CSS fixtures for Right-to-Left languages - - #8268: Add possibility to reset modules in theme.yml - - #8289: Add export folder to the file .gitignore - - #8220: Product settings: availabilty label and delivery time configuration - - #8252: Add context in legacy module translation function - - #8242: RTL fix: Add a library to composer.json file - - #8241: Fix json file and some translation for Persian language - - #8188: Clean some variables/code - - #8217: Make SymfonyContainer available from 1 location - - #8183: Clean some variables/code - - #7997: Fix coding standards issues - - #8048: Pass param content_only param to overrideLayoutTemplate call - - #8117: Improve database connection character set declaration - - #8083: Remove confusion about cart rule code check - - Bug fix: - - #8794: Fix customizable demo product without customizable field - - #8719: Fix missing CLDR supplemental directory - - #8643: Removed duplicate line in upgrade file - - #8608: Missing japanese lang flag - - #8589: Fix issue with tmp dir - - #8586: Fix release creation - - #8572: Change default file_get_content default timeout - - #8460: Validate::isDateOrNull() should accept '0000-00-00' - - #8470: Be able to identify a modern page in modules - - #8471: Allow to sort bestsellers by sales - - #8459: Force query build arg_separator to & - - #8362: Fixed bug in Access::getRoles() - - #8432: Fix fatal $sql_values string to array - - #8417: Fix missing cache invalidation in the backoffice - - #8407: Fixing missing employee in ModuleManagerBuilder - - #8307: Fix bug js and css cache file name don't change - - #8261: CustomerAddressFormCore validation was not working fine with hook… - - #8386: Rebuild all assets with UI kit beta - - #8354: Update composer dependencies - - #8352: Fix already defined class during upgrade process from 1.6 to 1.7 - - #8328: Add DB prefix in delete() method all time $add_prefix is set to true - - #8302: Change version phpExcel for PHP7 - - #8291: Fix merge problem - - #8247: Fixed issue with empty locale - - #8134: Fixed bug in addMissingProductFields that gives array_merge the p… - - #8198: The t must be capital in namespace - - #8181: Change visibility of properties in class CheckoutSession - - #8214: Fixed foreach warning on empty hook return - - #7799: searchTag now uses product_shop.visibility - -- Installer: - - New feature: - - #8336: More Japanese for installer - - #8299: Adding Japanese to the installer - - #8245: Generate RTL stylsheets when installation language is RTL - - Improvement: - - #8306: Add a new quick access - - #8219: Updating the PrestaShop images for installer last step - - #8189: Change order for Countries/Zones/States tabs - - Bug fix: - - #8670: Fix store hours migration - - #8484: Display generic exception message when error occurs on cli installation - - #8257: Change installation tutorial link to 1.7 version - - #8192: Write permission must be check for app/Resources/translations - - #8193: Use proper folder for theme templates - -- Web Services: - - Bug fix: - - #8393: Remove obsolete unescaping on JSON output - -#################################### -# v1.7.2.5 - (2018-02-21) -#################################### -- Back Office: - - Bug fix: - - #8755: Fix directory listing - - #8772: Replace serialize with json_encode - -- Core: - - Bug fix: - - #8591: Update Translation Bundle version in composer - -#################################### -# v1.7.2.4 - (2017-10-24) -#################################### -- Front Office: - - Bug fix: - - #8433: Fix product information leak on the front office - -#################################### -# v1.7.2.3 - (2017-10-05) -#################################### -- Back Office: - - Improvement: - - #7810: Add a loading spinner into product page - - Bug fix: - - #8366: Use default country instead of translator locale for marketplace API - - #7938: Update bulk action combinations number after delete or add combination - - #8232: Fixed bug in AdminCartRulesController when limiting the validity … - - #8346: Fix the currency display in supply order - - #8287: Fix the category search in the product page - - #8288: Fix displaying empty zip code of tax rule - -- Front Office: - - Bug fix: - - #7848: Fix switching combination when the product is offline - - #7781: Add error message when updating quantity wanted input - - #8283: Currency exchange fixes on product page - -- Core: - - Improvement: - - #8360: Fixing the version for core modules ps_legalcompliance ps_linklist ps_customtext ps_customeraccountlinks - - Bug fix: - - #8380: Fix Context::getTranslator() cache - - #8361: Fix conflict between two cart rules and a single product cart - - #8213: Voucher issue fix - -- Web Services: - - Bug fix: - - #8275: Fix update product with WS - -#################################### -# v1.7.2.2 - (2017-08-31) -#################################### -- Back Office: - - Bug fix: - - #8238: Fix wrong final combination price if BC Math is not available - - #8063: Display texture image in combination form - - #8057: Save before generate combinations - - #8266: Fix error while reaching AdminModules - -- Front Office: - - Improvement: - - #8082: Scroll top to product list when paginate - -- Core: - - Improvement: - - #8212: Optimize specific price computing by executing the query only when needed - - Bug fix: - - #8210: Fix missing product limit/offset when ordering by price on Sale page - - #8138: Fix tax calculation when vat number is used - -#################################### -# v1.7.2.1 - (2017-08-16) -#################################### -- Back Office: - - Improvement: - - #8140: Update modules page design - - Bug fix: - - #8236: Fix module modal layout - - #8046: Fix legacy submenu laptop - - #8141: Fix the module "translate" button with the new link of translation page - - #8173: Fix the search error with white spaces in stock page - - #8160: Fix the style of product reference in the stock management page - - #8166: Fix the misalignment of the search button in the stock page - - #8167: Fix the search tags in the stock management - -- Front Office: - - Improvement: - - #8205: Fix custom content link opening in the same page - - #8145: Fix custom content link opening in the same page - - #7855: Add link to products for Pack - - Bug fix: - - #8206: Fix flags on products front-office - - #8152: Make the slider appears on Mobile view - - #8191: Fix flags on products front-office - - #8155: Fix the style of forgotten password page - - #8169: Fix typo in bootstrap class - - #7716: Fix displaying product thumbnails - - #8111: Fix unclosed tag - - #8170: Limit the description's image by the size of description's frame - -- Core: - - Improvement: - - #8201: Speed up search queries (17) - - Bug fix: - - #8228: Optimise synchronization stock sql - - #8215: Add translations in database when importing theme - - #8165: Use MessageCatalog function to get all message - - #8186: Improve stock sql performance - -- Installer: - - Bug fix: - - #8021: Use correct module name column for authorization role - - -#################################### -# v1.7.2.0 - (2017-07-20) -#################################### -- Back Office: - - New feature: - - #8080: Translations confirmation modal - - #7808: Add tooltips on product's combination image - - #8031: Placeholder width in declination page - - #8027: Currencies live exchanges rates upload - - #7910: Can translate submenu tab! - - #7865: Fix redirect payment module retrieving good category - - Improvement: - - #8096: Add ids to recommended-payment & carriers & others - - #8098: Wording update for 1.7.2 catalog - - #8004: Fix displayed combination creation field - - #8008: Clean AdminProductsController - - #7911: Fix style of selected customer in product page - - #7835: Translations page rework & Stock management - - #7956: Remove length validation from ISBN field - - #7972: 1.7.2 wording update - BO + FO - - #7980: Fix html tags to get the current ISO country code - - #7942: Code Optimization - - #7933: Add translation domains to more BO templates - - #7820: Improve tag tips in product page - - #7887: Allow filtering of modules by display name inside the translations controller - - #7882: Add translations domains to BO templates - - #7613: Add new hooks to admin product page - - #7839: Add sprintf check constraint on translations - - #7834: Use most used tax for product creation on BO - - #7863: Add firstname & lastname on address form - - #7784: Complete category tooltip in Product Page - - #7735: Add translation domains to order templates - - #7706: Rewrite string to translate it more easily - - #7715: Change text tooltip in SEO - - #7618: Update addons authentication form - - Bug fix: - - #8161: Fix reset translation button - - #8074: Fix authorization panel - - #8129: Fix translations behavior - - #8135: Last wording update for 1.7.2.x - - #8093: Fix stock management filters - - #8094: Fix stock datepicker - - #8119: Fix the display of placeholder in combinations tab - - #8076: Fix upgrade button with update from disk - - #8107: Fix module enabling when ~ in theme.yml - - #8085: Fix JS event thrown on module uninstall - - #8106: Fix the upload quota for the product image - - #8120: Update catalog - - #8109: Fix the weird syntax in customer information page - - #8095: Feedback on translation page - - #8077: Revert Stock to singular - - #8068: Stock Management fixes - - #8065: Feedback on translation page - - #8054: Fix api category tree - - #8059: Fix missing use in ModuleDataUpdater - - #8052: Fix strings for specific price rules - - #7939: Fix the categories tree - - #8003: Fixed import store in backoffice - - #8044: Fix the conversion_rate in the order_payment table - - #8045: GSA quick fixes - - #8039: Translations feedback - - #7934: Fix float conversion from strings using comma as decimal separator - - #8041: Feedback stock management - - #8024: Fix legacy submenu laptop - - #8016: Display module confirm uninstall message - - #8014: Show Duplicate option when multishop selected - - #8007: Update Country in Store Contacts CSV File - - #7983: Add discount to cart - - #7853: Fix selecting category for product - - #7923: Fix displayed price on cart (HT/TTC) - - #7989: "Slightly" improve performance on Modules > notifications tab - - #7987: Fallback datepicker if needed - - #7978: Update diplayed module count on successful uninstall - - #7922: Fix redirection when filtering in attribute's value - - #7916: Fix min width to select filters - - #7964: Fix flush of local cache when adding a new specific price - - #7698: Unable to unselect the last image associated to a combination - - #7894: Fix bug when having more than three product image - - #7955: Don't get admin notifications while it's all disabled - - #7957: Add Missing space - - #7951: Fix displayed shortcut in product page - - #7937: Add missing simple quote in Design -> Images view - - #7932: Fix fatal on order page - - #7921: Fix trans errors of old translation page - - #7903: Fix moving module from a hook to another one - - #7837: Image not displayed in BO when creating new store - - #7898: Merge PRs from 1.7.1.x - - #7861: Bug with override AdminProductsController - - #7864: Fix recommended modules popup on legacy BO - - #7875: Fix datepicker design - - #7817: Introduce tinymce constraint & fixed short_description length - - #7809: No order notification message was wrong - - #7792: Remove all bourbon deprecations - - #7777: Make module actions translatable - - #7763: Updated path in maintenance message - - #7623: Avoid silencious fail of simple category creation from product form - - #7680: Fixed javascript bug on form submission - - #7662: Fix show currency name in tab "Catalog Price Rules" for option "All currencies" - - #7590: Fix bug on uploading too large images -- Front Office: - - New feature: - - #7833: Added message delivery information on checkout process - - Improvement: - - #8034: Apache rules for .woff2 font files - - #7998: Format error message - - #7990: Remove banner hidden class for mobile device - - #7564: Enabling category canonical redirection - - #7780: Allow to define module front controllers layout - - #7661: Update wording cart-detailed-actions.tpl - - #7566: Send response data to emitted events - - #7521: Consistency & additionnal infos - - #7554: Allow HTML in notifications - - #7688: Introduce new hooks for main wrapper - - #7880: Feat/classic improvements - - #7836: Harmonization of Brand name variable - wording - - #7813: Close thumbs modal when area under thumbs is clicked - - #7020: Improve front-end accessibility - - #7681: Improve readability on Classic theme - - Bug fix: - - #8142: Fix the price update on quantity change on cart - - #8121: Limit the description's image by the size of description's frame - - #8132: Fix the height of the "Show password" button - - #8088: Auto width for the selector on product page - - #8012: Show the forbiden message on product page - - #8040: Wrong close of 'product_tabs' {block} in product.tpl - - #7959: Empty customization ID after adding to cart - - #8009: Remove contact form after submit - - #8036: Fix cart front - - #8005: Fix legal compliance in footer in mobile display - - #8010: Make the edit link translatable - - #7952: Add class selected to selected address - - #8019: Missing product-flag class on product miniature - - #8006: Fix classic responsive - - #7992: Fix refresh availability of product - - #7994: Optimize search::find queries - - #7816: Order in catalog for calculate vouchers - - #7926: Fix mobile style toggling - - #7909: Wording checkout delivery - - #7907: Edit address for a Guest - - #7866: Fixed full size order-item table - - #7796: Fix address form Ajax refresh - - #7602: Let translate the edit label on order checkout -- Core: - - New feature: - - #8053: Add theme configurator translation & update catalog - - #7760: Allow free order - - #7889: Introduce module self configurator feature - - #7825: Handle multishop in console commands - - #7778: Remove lang dependancies for module manager and add cli command - - #7840: Add command to check duplicates in translation catalog - - #7567: Introduce release script - - Improvement: - - #7941: Add total amount TTC in credit slip - - #7523: Change all OrderController private methods and var to protected - - #7304: Fixed processChangeProductInCart method - - #7931: Update comments of Validate class - - #7678: Disable php in the "img" directory - - #7827: Fix spelling from conversation to conversion rate. - - #7912: Increase carrier delay length - - #7899: Refactoring naming - - #5082: Override admin and front controllers of modules - - #7871: Failure during module catalog fetch do not throw an exception anymore - - #7666: Use HTTPS where available in README.md - - #7606: Updates README.md file. - - Bug fix: - - #8118: Extract theme with default translation in any language - - #8101: Fix the tab permissions when only one profile - - #8103: Fix get attributes in order presenter - - #8124: Remove Finder from depency injection - - #8108: Fix update prefix sql - - #8070: Module tab registration must check filenames - - #8056: Fix type of errors variable in module configuration feature - - #8058: Fix missing @Template annotation created by refactoring - - #8047: License, composer, catalog, assets - - #8028: Update regex for tab registration - - #7996: Fix product with combinations auto-indexation - - #7984: Fix module loading for upgrade process and version displayed - - #7966: Use the right array index while getting controller tab name - - #7862: Throw module events right after each action and remove reset - - #7962: Fix wrong keys for cache - - #7557: Increase size of the hours column in PREFIX_store db table - - #7965: Allow .ico to /img, provide error server - - #7936: Fix value giftWrapping in OrderPresenter.php - - #7563: Update customerExists function in Customer.php - - #7915: Rethrow an exception instead of calling die when there is an erro… - - #7914: Changed SearchController extend to allow override - - #7904: Initialize getSynopsisDetails() output as an array instead of '' - - #7811: Display the login form after an failed authentication - - #7838: Return empty array instead of false. - - #7872: Display translated strings properly in SF debugger! - - #7852: Improve upgrade command - - #7611: Removed setSortOption in ProductSearchQuery - - #7609: Removed return duplication from search provider -- Installer: - - New feature: - - #7744: Adding 5 languages to the installer (SK, UK, ET, EL, FI) - - Improvement: - - #7977: Drop unused fields from ps_product_lang - - Bug fix: - - #8087: Translate fixtures with CLI install - - #8049: Reflect new Finnish tax rate in tax rule group names - - #8055: Fix update sql for upgrade - - #7981: Fix upgrade from very old versions - - #8018: URL update for installer - - #7993: Avoid INSTALL_PATH re-define error - - #7879: Set allow_url_fopen mandatory - - #7832: Fix install/upgrade/upgrade.php for php-5.4 syntax - - #7601: Use new module name for OrderState creation -- Web Services: - - Bug fix: - - #7664: Retrieve text only from selected customization - - #5352: Fix webservice unit_price_ratio set to 0 -- Localization: - - New feature: - - #7828: New localization packs - DZ, KR, MA, ZA - - Improvement: - - #7949: India states update - - #8000: Install Deutsch instead of Deutsch CH for Switzerland - - #7696: Update colombian tax rate - - #7818: Replace EN (US) by EN (UK) in UK localization pack - - -#################################### -# v1.7.1.2 - (2017-06-07) -#################################### -- Back Office: - - Bug fix: - - #7891: Set value for Short Desc - - #7860: Deny legacy module page view - - #7789: Message Customer on order details page - - #7801: Choose Theme on Mail Translation - - #7790: Add a scrollbar for TinyMCE - - #7783: Versions completions for the max value - - #7807: Partial revert of 0c42257 to fix profiling mode in BO - - - Front Office: - - Bug fix: - - #7795: Fix allow order value - - #7773: Fix for CMS tree on sitemap - - #7785: Fix slide down of carrier extra content in order funnel - - #7797: Translate file upload button label - - #7805: Fix word break classic - - #7762: Allow image for categories when no description - - #7761: Refresh product line on quantity change in cart & Show discount to cart summary - - #7747: Fix the except_pages in theme.yml - - #7745: Fix radio buttons on faceted search - - #7759: Convert voucher value - - - Core: - - Bug fix: - - #7901: Use composer cacert file by default - - #7826: Allowed redirect protocol with Tools::file_get_content (curl) - - #7800: Fix assets path when theme has the same name than PS - - #7770: Return array when it's wanted if the hook doesn't exist - - #7766: Fix displayError when string is using sprintf - - #7740: Fix missing {url entity=product id=X} - - #7752: Upgrade theme modules & disabling them in the same time that the theme - - - Installer: - - Bug fix: - - #7846: Fix install/upgrade/upgrade.php for php-5.4 syntax - - - Web Services: - - Bug fix: - - #7732: Change variable from string to array for php 7 - - -#################################### -# v1.7.1.1 - (2017-04-19) -#################################### -- Back Office: - - Bug fix: - - #7769: Fix the datepicker to use locale instead of iso code - - #7738: Fix access to domainized modules translations - - #7723: Fix catalog ASC sorting - - #7724: Fix translations theme export on Windows - - #7690: Incorrect translation on Symfony page (problems with TinyMCE) - - #7730: Alphabetically sort features on product page - - - Front Office: - - Bug fix: - - #7710: Fix country change in checkout form - - #7742: Fix for image change in zoom modal window - - #7734: Catch the exception when a template is missing in prod mode - - #7720: Display product reference when product has no combination - - #7689: Save zero to id_state if country has no states - - #7729: Fixed display amount with good taxes - - #7726: Fixed Terms and conditions popup on mobile not possible to close - - #7693: Password controller must be in SSL when available - - - Core: - - Bug fix: - - #7776: Fix cache on install - - #7753: Added nullable for Tab entity - - #7746: Doctrine without foreign for autoupgrade backup - - #7714: Module code cleanup and fix module action in details modal - - #7739: Allow modules compliancy on 3 digits - - - Installer: - - Improvement: - - #7743: Allow 255 char to company field in Adress - - -#################################### -# v1.7.1.0 - (2017-04-03) -#################################### -- Back Office: - - New feature: - - #7619: Add responsive nav-bar - - #7529: Product module page - - #7508: Mail in-transit improvement (webservice, markup) - - #7491: Allow to exclude tax and shipping in affiliation sales total - - #7287: Add counter to the inputs - - #6906: Implement "Update all" modules feature - - Improvement: - - #7596: Add displayProductPageDrawer hook - - #7570: Notification after theme reset, warning about images regeneration - - #7576: Remove useless meta_title - - #7573: Two wordings on the module tab of the product page - - #7551: Restore compiled assets - - #7516: Check if hook exists before get hook module exec list - - #7439: Header BO responsive (legacy part) - - #7497: Display shipping max. refundable amount in order partial refund form - - #7206: Update wording form.html.twig - - #7435: Remove initForm* from old product controller - - #7467: Update comment for jQuery migrate - - #7256: Add notifications counter - - #7421: Remove useless isset - - #7405: Domains tree on translations page now on more than 2 levels - - #7373: Add a new hook on dashboard - - #7364: Sort products in descending order - - #7315: Fix integration issues with translation page - - #7352: Reduce width of brand select input - - #7320: Only display the module you want to translate - - #7254: Add redirect to category for product not available - - #6712: Rename the productDisplayButtons hook to productDisplayAdditionalInfo - - #7308: Add version to help api feedback - - #7280: Change locales json - - #7175: Test admin controllers - - #7025: Add translation domains to Adv. param controllers 2 - - #7238: Harmonize wording cms.xml tab.xml - - #6990: Change Stores controller option from 'Status' to 'Active' - - #7100: Add some more translation domains to controllers - - #7230: Change PS color for tinymce - - #7188: Add text format selector to TinyMCE - - #6743: Implement optionnal but specific action to display on module page - - #7015: Set new product cover when current is deleted - - #7098: Removed sensor parameter from Google Maps JS API - - #6776: Do not display empty module categories - - #3915: Removed _includeContainer ; never more used - - Bug fix: - - #7701: Fix access denied on Customers Service - - #7668: Implode Translation Permission - - #7670: Allow upgrade for modules coming from Must-have json - - #7646: Fix imageFolder path for colorPicker inputs - - #7665: Fix inactive request in HookEvent - - #7663: Fix issue of Module notification page after 1.7.0.x backport - - #7648: Fix product attachments lookup - - #7585: Fix placeholder width in product options - - #7627: Fix wrong domain for product module page - - #7616: Fix getAvailableFields malformed json - - #7599: Fix required custom field alignment - - #7584: Employee permissions not saved - - #7586: Fix chosen width - - #7542: Update default catalog & compile assets - - #7572: Fix bug with TinyMCE button - - #7574: Fix tab registration (non-instantiated module) - - #7568: Fix default products sorting order - - #7559: Fix filter image icon - - #7552: Callback on HelperList should have highest priority - - #7546: Prevent widgets to break back-office - - #7544: Fix module configure button when in dropdown - - #7535: Fix desktop menu regressions - - #7534: Remove call to an undefined attribute - - #7520: Fix minors integration issues on sidebar - - #7513: Refresh forms for specific price - - #7514: Fix product customization duplication - - #7511: Fix back-office order - - #7503: Add missing attributes on function removeProduct - - #7507: Fix unclosed tag - - #7496: You can now search for a customer with several words - - #7492: Add missing metadata to translations catalogues on export - - #7486: Fix incorrect product-list-colors caching - - #7489: Update deleteFeatures() for Multi-shop - - #7481: Bug Fix on Save product - - #7479: Fix problem with default combination - - #6950: BO: allow disabled by item in Helper Form - - #7474: Fix Administering email setting whith/without log - - #7455: Fix Module configure permission - - #7473: Update ObjectModelCore::getFieldsLang - - #7470: Fix image doesn't exists - - #7449: Update keyboard shortcuts in product page - - #7462: Update invoice pdf - - #7459: Fix id_order ambiguous search - - #7454: Fixed use of hook return value in customer address validation - - #7444: Update the dashboardTop hook - - #7436: Remove tinymce synchronous loading - - #7415: Display correct quantities for shared stock - - #7428: Update wording AdminPerformanceController.php - - #7150: Fix "Uncaught ReferenceError: prestashop is not defined" - - #7395: Add the disabled categories in product page - - #7406: Custom error-layout for maintenance/restricted country page - - #7404: Replace "Default-bootstrap" in Translations tab - - #7390: Changed ID column name in CSV products export - - #7389: Fix translation page integration issues - - #7380: Remove wrong URL encoding from AdminStockMvtController - - #7371: Fix nested categories cache id - - #7366: Fix wrong domain - - #7332: Redirect with message when root category is not available for a shop - - #6997: Fix buttons alignments on modal on import page - - #7139: Fix product redirection from back office search results - - #7341: Update version on profile configuration page - - #6775: Add potential email error in order bulk action message failure. - - #6833: Deleted space and : in sql manager page - - #7330: Fix email translation edit when file doesn't exist - - #7115: Fix "Other translations" save action - - #7281: Module action template can now be used everywhere - - #7282: Fix selection of boolean option - - #7260: Set product image container to static position - - #7270: Add number of selected images in edit combination page - - #7255: Remove hardcoded version from help links - - #7196: Update keyboard shortcut in product page for preview - - #7251: Fix quick links with apostrophes - - #7236: Partial refund tax method always tax incl. - - #7039: Fix friendly url text on product page - - #7071: Add hints on some category fields - - #7229: Do not check module download on upgrade - - #7052: Fixed help wording for Tax Rules Group - - #7210: Fix date filter on dashboard when entering BO - - #7215: TinyMCE media plugin shouldn't be activated twice - - #7204: Fix import information display - - #7171: Fix rights issues on legacy module page - - #6942: Fix modules translation form - - #7180: Fixed "new client" column in orders list - - #6935: Fix localization pack import - - #7174: Fix warning on BO - - #6988: Clear cache on url rewriting settings modification - - #6996: Fix products alignment in delivery slip pdf - - #7019: Fix fancybox on cart rules conditions - - #6970: Fix virtual product file removal - - #6976: Fix error on layout when warnings exist - - #7023: Fix permission issues when creating modules sandbox folders recursively - - #6742: Fixed file attachment on product form - - #7050: Fix fallback dataformate duplicate value - - #7060: Fix save product when empty name in default lang - - #7136: Fixed search and redirection to module - - #6992: Fixed warning on AdminStore Controller - - #7010: Disable FK checks during DB export - - #7007: Display preview button in 13 inches - - #6930: Fixed bulk actions affecting single products - - #7048: Fix access to payment preferences - - #6926: Fixed payment methods of carriers - - #6978: Fixed security issue on SpecificPrice class - - #6957: Fix email preview in translation page - - #6955: Fix updating positions when sorting products - - #6953: Fix recommended modules modal window - - #6941: Fix email translations - - #6936: Return empty array on API error for customer data - - #6920: Fixed translation choice in BO - - #6891: Remove z-index of ps tagger reset button - - #6921: Removed warning notice on translation - - #6898: Fixed imagesController icons - - #6764: Add hotkeys on product page - - #6797: Display missing hook (displayCustomerAccountForm) - - #6825: Fixed wrong order detail updated - - #6858: Fixed css animation on onboarding - - #6868: Fix theme export - - #6812: Encrypt modules cookies - - #6857: Fixed error compile - - #6799: Add missing hook call for actionSubmitAccountBefore - - #6748: Fixed customers registration in Back Office - - #6811: Fixed border style of translation textarea - - #6805: Remove synchronous call to the CLDR - - #6778: Fix create combination - - #6793: Fixed employee password validation - - #6792: Use the correct email template for employee password recovery - - #6758: Fixed load of Jquery-ui JS/CSS cache - - #6750: Fixed delete combination on product - - - Front Office: - - New feature: - - #7675: Allow delivery module to confirm the checkout step - - #6903: Ported emailalert on classic - - #6886: Ported ps_crosseling module on classic - - #6881: Ported module ps_viewedproduct on classic - - #6878: Ported ps_specials module on classic - - #6877: Ported ps_newsproduct on classic - - #6871: Ported ps_supplierlist on classic & some fix on ps_brandlist - - #6866: Ported module ps_brandlist on classic - - #6828: Ported module ps_rssfeed for classic - - #6800: Ported module ps_productinfo for classic - - #6820: Ported bestsellers module on classic - - Improvement: - - #7575: Restore hook displayProductListReviews on catalog - - #6908: Add customization message - - #7478: Expose checkout process to inheriting classes - - #7362: Add smarty blocks everywhere - - #7384: Fix alerts icons and margin - - #7309: Integrate sitemap - - #7344: Hide virtual product download link until it's paid - - #7314: Integrate forgotten password alerts - - #7243: Add "quick_view" block to classic theme - - #7199: Fix "There is 0 product." label - - #7076: Add external libraries - - #7104: Add missing translation keys in home slider - - #6875: Replace Open Sans with Noto Sans - - #6766: Export translations when exporting theme - - Bug fix: - - #7694: Fixed a typo in template Product - - #7684: Incorrect event dataset call - - #7686: Fix Mixed-Content issues when SSL partially enabled - - #7657: Fix translation cache preventing load of new language - - #7603: Validate lengths of fields submitted from registration form - - #7636: Fix wrong translation/variable syntax - - #7617: Fix out of stock combination hiding - - #7561: Remove fakepath - - #7598: Fix registration form validation - - #7594: Restore hook displayBanner - - #7533: Fix url rewrite starting with numbers - - #7518: Fix front initcontent and My account display - - #7512: Fix a problem when a voucher is added on checkout - - #7500: Add cart in prestashop javascript object - - #7368: Allow HTML in customization when it's displayed by a module - - #7475: Fix hook name due to conflict resolution - - #7372: Bug fix for specific product combination cases - - #7461: Add manufacturer name in cart products - - #7453: Fix %email% are not replaced by user's email when asking a new password - - #7446: Remove wrong opening table tag - - #7445: Fix div tag in ordersummary header - - #7433: Fix button on the same line in order confirmation modal - - #7116: Fix some facets design - - #5053: Orders amount currency fixed - - #7410: Redirect to 404 when CMS page doesn't exist - - #7409: Fix empty title tag in CMS category - - #7345: Product with 0 quantity should be buyable when stock management is disabled - - #7361: Mobile Cart - Carriers Improperly integrated - - #7378: Fix FrontController#setTemplate default locale parameter - - #7365: Mobile Cart - Improperly integrated Fields - - #7272: Fixed bug when logged in customer can access login/registration p… - - #7358: Fix duplicate payment submissions and address initialization - - #7343: Check whether order is paid before serving a virtual product download - - #6597: Add carriage return to store information - - #7329: Fix arrow click & position - - #7323: Fix fatal when requesting product refresh without product id in cart - - #7297: Fix clean filter event handler - - #7264: Display Add to cart button in product listing - - #7259: Fix missing displayNavFullWidth into checkout - - #7247: Fix search bar icon display - - #7182: Remove useless vars display_column_* - - #7202: Fix order return format in OrderReturnPresenter - - #7009: Remove box-shadow around contact form in classic - - #7170: Fix classic's override of ps_imageslider - - #6995: Fix empty cart on logout display - - #6972: Add missing nofilter after display hook - - #7166: Fix total products label - - #7037: Fix breadcrumb margin on classic - - #7042: Add download link for virtual products - - #6987: Fix changing combination when catalog mode is enabled - - #6980: Fix undefined event in core.js - - #6905: Fix category images generation - - #6892: Revert to Bootstrap 4 alpha 4 - - #6847: Fix geolocation - - #6829: Fix PDF generation by removing non existing files requirement - - #6790: Replaced placeholder with email in notification - - #6808: Fix fatal on Best Sales - - #6741: Properly translate isbn, ean and upc - - #6774: Ported ps_categoryproducts for classic theme - - #6780: Add missing link on footer - - #6752: Remove extra tag block closed - - - Core: - - New feature: - - #5922: Install module tabs automatically - - #7291: Happy new Year PrestaShop! - - Improvement: - - #7621: Allows multiple retro names for a hook - - #7685: Don't update url_rewrite with upside lang - - #7679: Upside down language for crowdin - - #7669: Updated wording - - #7625: All we need to autoupgrade! - - #7577: Improved model namescape handling - - #7592: Default catalog update - - #7562: Add missing domains - - #7536: Add windows 8.1 & 10 to guest useragent - - #7532: Use Address:initialize to manage default state in one area - - #7522: Make sure that invoice siblings are related to the same order id - - #7524: Revert "Check if hook exists before get hook module exec list" - - #7495: Remove some globals - - #7490: Pass the object we're displaying to the action{$controller}FormMo… - - #6959: Convert namespaced object model class names to hook compatible names - - #7480: Sql fix & documentation - - #7468: Allow rel="nofollow" in anchors - - #7443: Add actionEmailSendBefore hook - - #6327: Deprecate getOrderByCartId method, add alternative - - #7456: Pass variables of hook `actionProductSearchComplete` by link - - #7442: Add new hook 'actionClearCache' - - #7440: Add new hook actionOutputHTMLBefore - - #7403: Make email templates parent/child compatible - - #7413: Optimized products counting in BO product list - - #7269: Webservices now show PS validation errors - - #7289: Code standard fixes & improvements - - #7335: Re-introduce server media - - #6911: Added dependency injection container in legacy - - #7142: Replace specific cache management with doctrine cache for module catalog - - #7298: Add file line number where the error occured - - #7265: Product.php optimization if not $id_cart - - #7183: Add app/config/config.php to gitignore - - #7093: Move entity repositories in existing subfolder - - #7178: Use ModuleZipManager for addons downloads - - #7177: Doctrine optimizations - - #6734: Generate robots.txt on install - - #7095: Add Reply-To recipient name to Mail::send() - - #7157: Be able to send an e-mail with multiple BCC - - #6694: Send email in English if current language don't have email template - - #6918: Allowed to add remote assets - - #6753: Improve global performances - - Bug fix: - - #7719: Delete unique key name for ps_profile_lang - - #7711: Use trans() instead of undefined l() - - #7700: Fixes needed for upgrade - - #7708: Use the browser country prior to the shop one - - #7705: Hide upside down language - - #7652: Rename id_product_redirected variable - - #7683: Remove clear cache for autoupgrade - - #7674: Fix ThemeValidator for child themes - - #7653: Fix invoice generation - - #7589: Fix missing reference symbol into Product::getProductProperties - - #7635: Update robot.txt using english - - #7629: Merge 1.7.0.x on 1.7.1.x - - #7633: Fix doctrine association between translation and lang - - #7597: Change CLDR url - - #7593: Fix the product page - - #7587: Increase curl timeout to 60s - - #7509: Format price for noPackPrice in product and Gift wrapping - - #7569: Fix entity integrity for upgrade - - #7538: Add composer.lock in order to fix composer install - - #7539: Update licences - - #7531: Payment method title extended to 255 characters - - #6681: Fix work authorization for (back|front)-office. After transition from RC1 to RC2. - - #7519: Fix fatal when no product to set in CategorySearchProvider - - #7312: Fixed Huge Bug for passed validation - - #7505: Fix nonexistent field on customer - - #7501: Do not display related product id customer can't see it - - #7485: Don't convert already converted currency - - #7502: Prevents problem with missing params in getWidgetVariables() - - #7499: Use UTF-8 for PaymentOptions - - #7482: Use default state for tax purposes - - #7488: Allow quotes in translation strings - - #7483: Update Mail lang settings - - #7148: Fix send to multiple addresses with different names - - #7477: Only link orders with same cart - - #7476: IdLang shouldn't be <= 0 - - #7471: Fix installation & tab entity - - #7472: Add "use instead" doc on method display as deprecated when possible - - #7463: Use boolean variables for tracking configuration value type - - #7466: Improvement in SpecificPrice::getSpecificPrice - - #7464: Calculate carrier price on the real order price - - #7460: Superfluous table alias - - #7457: Harmonize hook - - #7438: Add 2 new hooks actionDispatcherBefore and actionDispatcherAfter - - #7452: Revert "CO: fix Validate::isUnsignedInt" - - #7441: Add displayAfterProductThumb hook - - #7437: Use 1.7.1 modules - - #7430: Fixed rendering condition of default groups form - - #7429: Fix Validate::isUnsignedInt - - #7293: Fix dependencies definitions - - #7382: Use shop email as sender for template order_customer_comment - - #7334: Remove smartyDump() in Smarty config - - #7425: Update composer with modules - - #7420: Use the right modules branch - - #6928: Fix Cart cache key on CartRules - - #7401: Change some translated strings - - #7412: Fix logger namespace for ServiceLocator - - #7402: Update doc import files - - #7400: Fix array_merge call on null - - #7399: Fix pdf header - - #7393: Deprecate Tools::displayError() - - #6527: Fixed Geolocation behavior for NON existing countries - - #7386: Fix empty query - - #7316: Fixed bug that erases current customization fields - - #7277: Improve MARIA DB compatibility - - #7348: Fix wrong domain - - #7346: Fix getPriceWithoutReduct default id_product_attribute - - #7321: Improved translator performances - - #6722: Fix uncaught IOException on module deletion - - #7311: Introduce new hooks filtered & use it for product/category/brand/supplier/cms & html content - - #7313: Add actionSearch hook on ProductSearchProvider - - #7328: Fix store image & implement generation - - #7163: Enable the cart rule feature when updating one if it's enabled - - #7222: Fixed method Order::isVirtual - - #7257: Impossible to uninstall module when overridden file is missing - - #7241: Add native email missing - - #7194: Fix issue on translations without params - - #7235: Fix getImageLink for watermark module - - #7237: Fix pack price calc when using non-default attributes - - #7225: Fix missing subfolder in Repository namespace - - #6904: Fixes for module upgrade with zip upload - - #7211: Add missing SQL alias - - #7176: Set size limits on Doctrine Translation entity - - #7164: Update Mail::send documentation - - #7096: Use english email template as fallback in getEmailTemplateContent - - #7056: Restore deprecated method - - #7061: Fix command description - - #7111: Fix notice on $currency_to which may be null - - #7109: Fix unregisteration of Stylesheet by ID - - #7108: Fix unregisteration of JavaScript by ID - - #7014: Removed realpath for assets - - #6966: Fixed tools var - - #7126: Merge 1.7.0.x on develop - - #7081: Fixed CORS setting the header - - #7069: Protect translations display against XSS injections - - #7034: Use the locale to fallback on the good one in CLDR Repository - - #6927: Fix sprintf condition - - #6974: Created temporary file in cache directory - - #6929: Fix Cookie standalone mode - - #7013: Load autoload first - - #6994: Fixed on included files for autoupgrade - - #6848: Refresh CA bundle - - #6925: Prevent password reset on user check by email - - #6902: Fix PHP version for composer - - #6895: Fixed path windows assets - - #6890: Fixed translation render - - #6883: Fix multilang configuration insert - - #6803: Fix AJAX sync calls - Partial revert of 840fb00 - - #6856: Cart cache key should take id_zone into account - - #6849: Fixed missing escape - - #6872: Fixed path for windows - - #6831: Use module_name to get error on upload - - #6798: Hook:exec should always return an array when array_return = true - - #6837: Fix fatal if payment module return a non array result - - #6761: Clean installation files from deleted hooks - - #6816: Fixed hook & moved hook before body - - #6802: Configured Twig autoescape option - - #6779: Fixed module cache with 2 systems - - #6745: Fixed path for asset directory - - #6755: Fixed customer account add/update hook call - - #6739: Fix changed namespace - - - Installer: - - New feature: - - #7021: Adding country Tanzania - - Improvement: - - #7691: Remove awaiting Paypal order status - - #7517: Refactoring of the upgrade, to be easily usable in the auto upgrade module - - #7363: Update install with trans from crowdin - - #7302: Refacto 1.7.1.0.sql & remove 1.7.1.x.sql - - #7306: Add installed modules to quick access - - #7083: Updated tabs in FR - - #6939: Increase memory limit - - #6859: Declare default timezone when none is available - - Bug fix: - - #7638: Fix language refresh on dropdown change - - #7579: Avoid ERR_TOO_MANY_REDIRECTS at install - - #7571: Fix installation for languages without fixtures - - #7375: Fix error message display in installer - - #7374: Import sql upgrade from 1.6.x - - #6965: Add missing hooks actionObjectProductInCartDelete(Before|After) - - #7082: Small fixes for installer - - #7283: Do not launch install wizard if no write access to the cache folder - - #7057: Change india address form - - #7138: Fix wrong extension in the install.txt - - #7085: Update configuration.xml in SV - - #6817: Do not create parameters.php during install - - #7064: Install.txt file & documentation link update - - #7032: Required fileinfo extension - - #7053: Fix settings migration script - - #6967: Caught broken environment exception - - #6944: Add default message on ajax error in installer - - #6887: Add JSON, SimpleXML and DOM extensions as install requirements - - #6818: Clear the cache before trying to update the DB schema - - #6864: Fixed redirect on installer - - #6854: Add cURL check at installation - - #6845: Fix BDD required during install - - #6769: Added PS_MAINTENANCE_TEXT key in database - - - Web Services: - - Bug fix: - - #6910: Add watermark to new product images - -#################################### -# v1.7.0.5 - (2017-02-06) -#################################### -- Back Office: - - Bug fix: - - #7450: Fix some automator problem - - #7408: Fix deletion of virtual product attachment - - #7396: Fix products actions - - #7383: Add some cast on variables - - #7394: Fix fatal on getModulesToEnable() - - #7379: Fix image icon - - #7318: Fix saving decimals in AdminProduct combination form - - #7301: Translate categories tree in product page - - #7325: Add success message when import localization is ok - - #7324: No default reference on catalog - - #7326: Fix attachment file - - - Front Office: - - Bug fix: - - #7410: Redirect to 404 when CMS page doesn't exist - - #7340: Fix translations error from module with sprintf - - #6972: Add missing nofilter after display hook - - - Core: - - Improvement: - - #7360: Add config.php to the file .gitignore - - #7353: Update Israel VAT to 17% - - Bug fix: - - #7465: Protect some folders - - #7424: Update composer with modules - - #7354: Filter theme / module inputs - - #7418: Alter currency name to varchar(64) - - #7419: Use the right modules branch - - #7411: Refacto to get translation files - - #7407: Do not load index.php file in catalogue - - #7397: Fix email override path - - #7387: Fallback dataformate duplicate value - - #7347: Use the right attributes separator into the cart - - #7388: Fix clear media cache - - #7385: Fix function call - - #7351: Replace PCRE e modifier with callback - - -#################################### -# v1.7.0.4 - (2017-01-10) -#################################### -- Back Office: - - Bug fix: - - #7303: Add some test before use finfo - - #7292: Fix log page email hint - - #7295: Fix the customer thread timeline display - - #7118: Add parent menu permission if sub-menu is selected - - #7252: Fix product page ajax calls when url contains numbers - - #7193: Fix modules translation form - - #7271: Fix import theme for windows & special name - - #7267: Fix preview button action - - - Front Office: - - Bug fix: - - #7286: Use the right wording when guest is disabled - - #7195: Fix wrong displayed discount when it's higher than price - - #7162: Add error message when ordering number of item greater than quantity - - #7186: Always return a current order state - - #7185: Fix quick view in safari browser - - #7276: Add option with product to getManufacturer, getSupplier - - #7278: Do not let Classic override jQuery - - #7266: Fix category images generation - - #7248: Fix multishop popup design - - #7297: Fix clean filter event handler - - - Core: - - Bug fix: - - #7310: Protect translated strings from XSS - - #7114: Set curl as main solution and fopen as fallback - - #7279: Fix escaped translations - - #7275: Fix module translations priority - - #7263: Fix module uninstall when overridden file is missing - - #7194: Fix issue on translations without params - - - Installer: - - Bug fix: - - #7307: Fix croatian install adding quick_access - - #7296: Adding missing tabs in IT + VN + SR, and other tab updates - - #7274: Fix installer in Canadian and catalog cache - - #7284: Fix localization install for language not in data/lang - - #7294: Use the right locale for French Canadian - - -#################################### -# v1.7.0.3 - (2016-12-16) -#################################### -- Back Office: - - Bug fix: - - #7169: Add Request to hook parameters - - #7151: Allow installed modules translation from translation page - - #7024: Fixed product permissions - - #7153: Update docs & compile - - #7143: Fixed image of module on Payment page - - #7091: Fix some of the functions on the product page (JS) - - #7090: Fix error when saving traslations (1.7.0.0) - - #7028: Removed module card on uninstall - - #7215: TinyMCE media plugin shouldn't be activated twice - - - Front Office: - - Bug fix: - - #7130: Fix nav header menu icon on classic - - #7046: Fix classic css override of featuredproduct - - #7160: Fix sort by text display - - #7131: Fix bootstrap version - - #7077: Fix "too much recursion" error on ajax search - - #7078: Fix select filter & filter criteria by ajax - - - Core: - - Improvement: - - #6984: Use the right languages name - - #7146: Updated README - - Bug fix: - - #7224: Removed finfo use for theme upload - - #7205: Fix warnings in translate.php - - #7200: Fix module install and blank screen after PS install - - #7197: Check in Symfony catalog for translations for native modules - - #7191: Shutdown addons client on error - - #7190: Escape translated strings to prevent XSS - - #7187: Fix already defines smarty function - - #7184: Fix inactive scope for request in HookManager - - #7173: Revert "BO: fixed other XSS issues on translation module page" - - #7165: Licences & assets - - #7156: Fix SmartyLazyLoader for multiple smarty instances - - #7087: Protect translations display against XSS injections - - #7129: Fix timeout option for guzzle config - - #7144: Use default catalog as a fallback - - #7119: Use PhpParser to check parse errors in modules - - #7134: Fix mails with invoices - - #7080: Add unit price to order confirmation mail (1.7.0.0) - - #7096: Use english email template as fallback in getEmailTemplateContent - - -#################################### -# v1.7.0.2 - (2016-11-23) -#################################### -- Back Office: - - Bug fix: - - #7070: Fixed bulk actions affecting single products - - #7058: Disable FK checks during DB export - - #7063: Fix related product removal - - #7008: Display preview button on 13 inches - - #6958: Fix email preview in translation page - -- Front Office: - - Bug fix: - - #7027: Filtered embedded product properties - - #7043: Add download link for virtual products - -- Core: - - Improvement: - - #7022: Allowed to add remote assets - - Bug fix: - - #7038: Send email in English if current language don't have email template - - #7026: Protect translations display against XSS injections - - #7033: Use the locale to fallback on the good one in CLDR Repository - - #6986: Fix sprintf condition - - #7054: Fix Cookie standalone mode - - -#################################### -# v1.7.0.1 - (2016-11-16) -#################################### -- Back Office: - - Bug fix: - - #6975: Fix updating positions when sorting products - - #6977: Fixed security issue on SpecificPrice class - - #6952: Fix recommended modules modal window - - #6962: Fixed translation choice in BO - - #6951: Fixed notice on module translations - - #6940: Fix email translations - - #6937: Return empty array on API error for customer data - -- Front Office: - - Bug fix: - - #6991: Fix changing combination when catalog mode is enabled - - #6979: Fix undefined event in core.js - -- Core: - - Improvement: - - #6982: Improved performances on Windows/NFS filesytem - - Bug fix: - - #7012: Load autoload earlier - - #6971: Fixed on included files for autoupgrade - - #6989: Fix fatal if payment module return a non array result - - #6973: Created temporary file in cache directory - - #6969: Prevent password reset on user check by email - - -#################################### -# v1.7.0.0 - (2016-11-03) -#################################### - New Release! diff --git a/docs/csv_import/.htaccess b/docs/csv_import/.htaccess deleted file mode 100644 index c914413e..00000000 --- a/docs/csv_import/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order allow,deny - Allow from all - - -# Apache 2.4 - - Require all granted - diff --git a/docs/csv_import/addresses_import.csv b/docs/csv_import/addresses_import.csv deleted file mode 100644 index c4549418..00000000 --- a/docs/csv_import/addresses_import.csv +++ /dev/null @@ -1,17 +0,0 @@ -Address ID;Alias*;Active (0/1);Customer e-mail*;Customer ID;Manufacturer;Supplier;Company;Lastname*;Firstname*;Address 1*;Address 2;Zipcode*;City*;Country*;State;Other;Phone;Mobile Phone;VAT number;DNI -1;Peter.Pan / New York;1;Peter.Pan@prestashop.com;;;;;Pan;Peter;360W, 42nd Street;;12001;New York;United States;New York;;01 02 03 04 05;06 02 03 04 05;;; -2;Wendy.Moira.Darling / New York;1;Wendy.Moira.Darling@prestashop.com;;;;;Darling;Wendy Moira;360W, 42nd Street;;12001;New York;United States;New York;;01 02 03 04 05;06 02 03 04 05;;; -3;Wendy.Moira.Darling / London;1;Wendy.Moira.Darling@prestashop.com;;;;;Darling;Wendy Moira;Lansdowne road 50 London;Kensington;W11;London;United Kingdom;;;01 02 03 04 05;06 02 03 04 05;;; -4;Tiger.Lily / Arizona;1;Tiger.Lily@prestashop.com;;;;;Lily;Tiger;Brackin Ranch Road;;86001;Flagstaff;United States;Arizona;;01 02 03 04 05;06 02 03 04 05;;; -5;Tiger.Lily / Le Chesnay;1;Tiger.Lily@prestashop.com;;;;;Lily;Tiger;53 passage des pas sages;;78150;Le Chesnay;France;;;01 02 03 04 05;06 02 03 04 05;;; -6;James.Hook / Home;1;James.Hook@prestashop.com;;;;;Hook;James;Mass Gravesite;P.O. Box 007;2101;Cayman Brac;Cayman Islands;;;01 02 03 04 05;06 02 03 04 05;;; -7;James Hook / Pro;1;James.Hook@prestashop.com;;;;Räuber Schätze GmBH;Hook;James;12 Leipziger Platz;;13505;Berlin;Germany;;;01 02 03 04 05;06 02 03 04 05;;; -8;Tinker.Bell / Napaiiri;1;Tinker.Bell@prestashop.com;;;;Santa Clauss Inc.;Bell;Tinker;Tähtikuja 1;;96930;Napapiiri;Finland;;;01 02 03 04 05;06 02 03 04 05;;; -9;Smee / Fiji;1;Bob.Smee@prestashop.com;;;;;Smee;Bob;Cross Island rd 321;Vanua Levu;;Savusavu;Fiji;;;01 02 03 04 05;06 02 03 04 05;;; -10;Smee / Portland;1;Bob.Smee@prestashop.com;;;;Lattice Semiconductor;Smee;Bob;5555 NE Moore Ct;;97124;Hillsboro;United States;Oregon;;01 02 03 04 05;06 02 03 04 05;;; -11;Tictac Crocodile / Home;1;Tictac.Crocodile@prestashop.com;;;;;Crocodile;Tictac;Old State Rd 4A;Saddlebunch keys;33040;Bay Point;United States;Florida;Beware the Shark :);01 02 03 04 05;06 02 03 04 05;;; -12;Apple / address1;1;;;Apple;;;Doe;John;1–6 Infinite Loop;;95014;Cupertino;United States;California;;01 02 03 04 05;06 02 03 04 05;;; -13;Shure / address1;1;;;Shure;;;Non-Doe;John;5800W Touhy Avenue;;60714;Niles;United States;Illinois;;01 02 03 04 05;06 02 03 04 05;;; -14;Shure / address2;1;;;Shure;;;Schuss-mayer;Kurt;Jakob-Dieffenbacher-Str. 12;;75031;Eppingen;Germany;;;01 02 03 04 05;06 02 03 04 05;;; -15;UPS / address1;1;;;;U.P.S;;Austin;Steve;55NE Glenlake Parkway;;30328;Atlanta;United States;Georgia;;01 02 03 04 05;06 02 03 04 05;;; -16;FedEX / address1;1;;;;FedEX;;Noland;Chuck;3640 Hacks Cross Rd;;32125;Memphis;United States;Tennessee;;01 02 03 04 05;06 02 03 04 05;;; diff --git a/docs/csv_import/alias_import.csv b/docs/csv_import/alias_import.csv deleted file mode 100644 index 00a21893..00000000 --- a/docs/csv_import/alias_import.csv +++ /dev/null @@ -1,5 +0,0 @@ -Alias ID;Alias *;Search *;Active (0/1) -1;ano, anno, nona;nano;1 -2;ipdo, idop, podi;ipod;1 -3;McBook, Mbcook;MacBook;1 -4;Blekin;Belkin;1 diff --git a/docs/csv_import/categories_import.csv b/docs/csv_import/categories_import.csv deleted file mode 100644 index c358fff2..00000000 --- a/docs/csv_import/categories_import.csv +++ /dev/null @@ -1,4 +0,0 @@ -Category ID;Active (0/1);Name *;Parent category;Root category (0/1);Description;Meta title;Meta keywords;Meta description;URL rewritten;Image URL -10;1;iPods;Home;0;Now that you can buy movies from the iTunes Store and sync them to your iPod, the whole world is your theater.;Meta title-iPods;Meta keywords-iPods;Meta description-iPods;music-ipods;http://yourlinktotheimage.com/img1000.jpg -11;1;Accessories;Home;0;Wonderful accessories for your iPod;Meta title-Accessories;Meta keywords-Accessories;Meta description-Accessories;accessories-ipod;http://yourlinktotheimage.com/img1001.jpg -12;1;Laptops;Home;0;The latest Intel processor, a bigger hard drive, plenty of memory, and even more new features all fit inside just one liberating inch. The new Mac laptops have the performance, power, and connectivity of a desktop computer. Without the desk part.;Meta title-Laptops;Meta keywords-Laptops;Meta description-Laptops;laptops;http://yourlinktotheimage.com/img1002.jpg diff --git a/docs/csv_import/combinations_import.csv b/docs/csv_import/combinations_import.csv deleted file mode 100644 index 2ba7a2c5..00000000 --- a/docs/csv_import/combinations_import.csv +++ /dev/null @@ -1,28 +0,0 @@ -Product ID*;Attribute (Name:Type:Position)*;Value (Value:Position)*;Supplier reference;Reference;EAN13;UPC;Wholesale price;Impact on price;Ecotax;Quantity;Minimal quantity;Low stock level;Impact on weight;Default (0 = No, 1 = Yes);Combination available date;Image position;Image URLs (x,y,z...);Image alt texts (x,y,z...);ID / Name of shop;Advanced Stock Managment;Depends on stock;Warehouse -1;Color:color:0, Disk space:select:1;Blue:0, 16GB:1;RF-Nano-Blue-16GB;RP-Nano-Blue-16GB;0000080446392;116052426077;100;40;0;10;1;;0;0;2014-01-01;1;http://youdomain.com/img.jpg,http://youdomain.com/img.jpg;First alt text,Second alt text;1;0;0;0; -1;Color:color:0, Disk space:select:1;Blue:0, 8GB:1;RF-Nano-Blue-8GB;RP-Nano-Blue-8GB;0000080446393;457698445011;80;0;0;10;1;0;0;0;2014-01-02;2;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Yellow:0, 16GB:1;RF-Nano-Yellow-16GB;RP-Nano-Yellow-16GB;0000080446394;541661772012;100;40;0;10;1;1;0;0;2014-01-03;3;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Yellow:0, 8GB:1;RF-Nano-Yellow-8GB;RP-Nano-Yellow-8GB;0000080446395;080064075921;80;0;0;10;1;2;0;1;2014-01-04;4;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Metal:0, 16GB:1;RF-Nano-Metal-16GB;RP-Nano-Metal-16GB;0000080446396;943284585394;100;40;0;10;1;3;0;0;2014-01-05;5;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Metal:0, 8GB:1;RF-Nano-Metal-8GB;RP-Nano-Metal-8GB;0000080446397;779589194980;80;0;0;10;1;;0;0;2014-01-06;6;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Black:0, 16GB:1;RF-Nano-Black-16GB;RP-Nano-Black-16GB;0000080446398;633319125866;100;40;0;10;1;0;0;0;2014-01-07;7;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Black:0, 8GB:1;RF-Nano-Black-8GB;RP-Nano-Black-8GB;0000080446399;397444719890;80;0;0;10;1;1;0;0;2014-01-08;8;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Orange:0, 16GB:1;RF-Nano-Orange-16GB;RP-Nano-Orange-16GB;0000080446400;295437962413;100;40;0;10;1;2;0;0;2014-01-09;9;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Orange:0, 8GB:1;RF-Nano-Orange-8GB;RP-Nano-Orange-8GB;0000080446401;879526174964;80;0;0;10;1;3;0;0;2014-01-10;10;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Pink:0, 16GB:1;RF-Nano-Pink-16GB;RP-Nano-Pink-16GB;0000080446402;850089888307;100;40;0;10;1;;0;0;2014-01-11;11;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Pink:0, 8GB:1;RF-Nano-Pink-8GB;RP-Nano-Pink-8GB;0000080446403;681363175404;80;0;0;10;1;0;0;0;2014-01-12;12;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Green:0, 16GB:1;RF-Nano-Green-16GB;RP-Nano-Green-16GB;0000080446404;343278201887;100;40;0;10;1;1;0;0;2014-01-13;13;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Green:0, 8GB:1;RF-Nano-Green-8GB;RP-Nano-Green-8GB;0000080446405;910409113499;80;0;0;10;1;2;0;0;2014-01-14;14;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Purple:0, 16GB:1;RF-Nano-Purple-16GB;RP-Nano-Purple-16GB;0000080446406;835747175053;100;40;0;10;1;3;0;0;2014-01-15;15;http://youdomain.com/img.jpg;First alt text;0;0;0; -1;Color:color:0, Disk space:select:1;Purple:0, 8GB:1;RF-Nano-Purple-8GB;RP-Nano-Purple-8GB;0000080446407;825739577313;80;0;0;10;1;;0;0;2014-01-16;16;http://youdomain.com/img.jpg;First alt text;0;0;0; -2;Color:color:0;Metal:0;RF-Shuffle-Metal;RP-Shuffle-Metal;0685387000000;623892618739;40;0;0;12;1;0;0;1;2014-01-17;1;http://youdomain.com/img.jpg;First alt text;0;0;0; -2;Color:color:0;Blue:0;RF-Shuffle-Blue;RP-Shuffle-Blue;0685387000000;848279119061;40;0;0;12;1;1;0;0;2014-01-18;2;http://youdomain.com/img.jpg;First alt text;0;0;0; -2;Color:color:0;Pink:0;RF-Shuffle-Pink;RP-Shuffle-Pink;0685387000000;745140261407;40;0;0;12;1;2;0;0;2014-01-19;3;http://youdomain.com/img.jpg;First alt text;0;0;0; -2;Color:color:0;Green:0;RF-Shuffle-Green;RP-Shuffle-Green;0685387000000;180143857886;40;0;0;12;1;3;0;0;2014-01-20;4;http://youdomain.com/img.jpg;First alt text;0;0;0; -3;Color:color:0, Disk space:select:1, ICU:select:2;Metal:0, 80GB Parallel ATA Drive @ 4200 rpm:1, 1.60GHz Intel Core 2 Duo:2;RF-MacBookAir80GB-1.6MHz;RP-MacBookAir80GB-1.6MHz;0123457000000;959149242374;0;750;0;10;1;;0;0;2014-01-21;1;http://youdomain.com/img.jpg;First alt text;0;0;0; -3;Color:color:0, Disk space:select:1, ICU:select:2;Metal:0, 80GB Parallel ATA Drive @ 4200 rpm:1, 1.80GHz Intel Core 2 Duo:2;RF-MacBookAir80GB-1.6MHz;RP-MacBookAir80GB-1.6MHz;0123457000000;110179337894;0;0;0;10;1;0;0;1;2014-01-22;2;http://youdomain.com/img.jpg;First alt text;0;0;0; -3;Color:color:0, Disk space:select:1, ICU:select:2;Metal:0, Optional 64GB solid-state drive:1, 1.60GHz Intel Core 2 Duo:2;RF-MacBookAir64GB-1.8MHz;RP-MacBookAir64GB-1.8MHz;0123457000000;576786535242;0;225;0;10;1;1;0;0;2014-01-23;3;http://youdomain.com/img.jpg;First alt text;0;0;0; -3;Color:color:0, Disk space:select:1, ICU:select:2;Metal:0, Optional 64GB solid-state drive:1, 1.60GHz Intel Core 2 Duo:2;RF-MacBookAir64GB-1.8MHz;RP-MacBookAir64GB-1.8MHz;0123457000000;288200093419;0;975;0;10;1;2;0;0;2014-01-24;4;http://youdomain.com/img.jpg;First alt text;0;0;0; -5;Disk space:select:1;8GB:0;RF-IpodTouch8GB;RP-IpodTouch8GB;8456120000000;626733005930;200;0;0;10;1;3;0;1;2014-01-25;1;http://youdomain.com/img.jpg;First alt text;0;0;0; -5;Disk space:select:1;16GB:0;RF-IpodTouch16GB;RP-IpodTouch16GB;8456120000000;604116319829;250;75;0;10;1;;0;0;2014-01-26;2;http://youdomain.com/img.jpg;First alt text;0;0;0; -5;Disk space:select:1;32GB:0;RF-IpodTouch32GB;RP-IpodTouch32GB;8456120000000;635894030063;300;150;0;10;1;0;0;0;2014-01-27;3;http://youdomain.com/img.jpg;First alt text;0;0;0; diff --git a/docs/csv_import/customers_import.csv b/docs/csv_import/customers_import.csv deleted file mode 100644 index ddd2a588..00000000 --- a/docs/csv_import/customers_import.csv +++ /dev/null @@ -1,10 +0,0 @@ -Customer ID;Active (0/1);Titles ID (Mr = 1, Ms = 2, else 0);Email *;Password *;Birthday (yyyy-mm-dd);Last Name *;First Name *;Newsletter (0/1);Opt-in (0/1);Registration date (yyyy-mm-dd);Groups (x,y,z...);Default group ID -1;1;1;Peter.Pan@prestashop.com;123456789;1987-04-02;Pan;Peter;1;0;2015-01-10;Customer;3 -2;1;2;Wendy.Moira.Darling@prestashop.com;123456789;1989-11-12;Darling;Wendy Moira;1;0;2014-05-12;Customer;3 -3;1;2;Tiger.Lily@prestashop.com;123456789;1982-02-28;Lily;Tiger;1;0;2013-09-25;Customer;3 -4;1;1;James.Hook@prestashop.com;123456789;1952-12-04;Hook;James;0;1;2015-07-13;Customer, Carribean;4 -5;1;2;Tinker.Bell@prestashop.com;123456789;1900-01-01;Bell;Tinker;1;1;2015-03-05;Customer;3 -6;1;1;Bob.Smee@prestashop.com;123456789;1971-10-21;Smee;Bob;1;1;2013-04-29;Customer;3 -7;1;1;Tictac.Crocodile@prestashop.com;123456789;1991-09-27;Crocodile;Tictac;0;0;2014-10-30;Customer, Carribean;4 -8;1;1;Jack.Banning@prestashop.com;123456789;2003-07-05;Banning;Jack;0;0;2014-12-10;Kids;5 -9;0;2;Maggie.Banning@prestashop.com;123456789;2006-02-27;Banning;Maggie;0;0;2015-07-11;Kids;5 diff --git a/docs/csv_import/index.php b/docs/csv_import/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/docs/csv_import/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/docs/csv_import/manufacturers_import.csv b/docs/csv_import/manufacturers_import.csv deleted file mode 100644 index 2635dd72..00000000 --- a/docs/csv_import/manufacturers_import.csv +++ /dev/null @@ -1,63 +0,0 @@ -Manufacturer ID;Active (0/1);Name *;Description;Short description;Meta title;Meta keywords;Meta description;Image URL -1;1;Apple;"

The company was founded on April 1, 1976, and incorporated as Apple Computer, Inc. on January 3, 1977.The word ""Computer"" was removed from its name on January 9, 2007, the same day Steve Jobs introduced the iPhone, reflecting its shifted focus towards consumer electronics.

Apple is the world's second-largest information technology company by revenue after Samsung Electronics, and the world's third-largest mobile phone maker after Samsung and Nokia.Fortune magazine named Apple the most admired company in the United States in 2008, and in the world from 2008 to 2012. However, the company has received criticism for its contractors' labor practices, and for Apple's own environmental and business practices.

As of May 2013, Apple maintains 408 retail stores in fourteen countries as well as the online Apple Store and iTunes Store, the latter of which is the world's largest music retailer. Apple is the largest publicly traded corporation in the world by market capitalization, with an estimated value of US$415 billion as of March 2013. As of Sept 29 2012, the company had 72,800 permanent full-time employees and 3,300 temporary full-time employees worldwide. Its worldwide annual revenue in 2012 totalled $156 billion. In May 2013, Apple entered the top ten of the Fortune 500 list of companies for the first time, rising 11 places above its 2012 ranking to take the sixth position.

-

-

(For more, go to the original article on Wikipedia)

";"

-
-
-

-

Apple Inc., formerly Apple Computer, Inc., is an American multinational corporation headquartered in Cupertino, California that designs, develops, and sells consumer electronics, computer software and personal computers.

";MetaTitle-Apple;MetaKeywords-Apple;Meta description-Apple;http://localhost/prestashop/img/m/1.jpg -2;1;Shure;"


-

Company history

-

Shure was founded by Sidney N. Shure in 1925 as ""The Shure Radio Company"", selling radio parts kits in the days before complete manufactured radios were available. The company's office was located at 19 South Wells Street in downtown Chicago, Illinois. The following year, Shure published its first direct mail catalog, which was one of only six radio parts catalogs in the United States at the time. By 1928, the company had grown to over 75 employees, and Sidney's brother, Samuel J. Shure, joined the company, which was renamed Shure Brothers Company. The company moved into new offices at 335 West Madison Street in Chicago. In 1929, with the advent of the Great Depression and the increased availability of factory-built radios, Shure Brothers Company was forced to greatly reduce their staff and became the exclusive US distributor of a small microphone manufacturer. In 1930, Samuel J. Shure left the company.

-

In 1931, Shure and engineer Ralph Glover began development of the first Shure microphone, and the following year, the Model 33N Two-Button Carbon Microphone was introduced, making Shure one of only four microphone manufacturers in the U.S.. Shure's first condenser microphone, crystal microphone, and microphone suspension support system (for which they received their first patent) were all introduced that same decade. In 1939, Shure introduced the Model 55 Unidyne Microphone, which went on to become one of the world's most recognized microphones.

-

In 1941, Shure was contracted by the United States armed forces to supply microphones during World War II, and by the following year, the T-17B was the microphone most widely used by the U.S. Army and Navy. Shure also manufactured throat, headset, and oxygen mask microphones, and adopted the United States Military Standard for all Shure microphones.

-

By the mid-1940s, Shure was also manufacturing and supplying phonograph cartridges to major phonograph manufacturers including Philco, RCA, Emerson, Magnavox, Admiral, and Motorola, and was the largest producer of phonograph cartridges in the U.S. at that time. Among Shure's innovations in phonograph cartridge design was Ralph Glover and Ben Bauer's ""needle-tilt"" principle for minimizing record wear while improving sound reproduction, and Jim Kogen's engineering concept of ""trackability."" Shure produced the first phonograph cartridge capable of playing both long-playing and 78 rpm records, the first cartridge with tracking force of only one gram, and the first cartridge meeting the requirements of stereo recording. At the peak of Shure's phonograph cartridge production, the company was producing approximately 28,000 cartridges per day, with 25,000 of those coming from a Shure phonograph cartridge plant in Phoenix, Arizona. After the introduction of compact discs in the 1980s reduced the demand for phonograph cartridges, Shure closed the Phoenix facility but continued manufacturing phonograph cartridges, and continues to manufacture them today.

-

Shure also developed and produced products for medical applications. In 1937, their 66A piezoelectric stethophone was designed to accurately reproduce chest sounds, and in the early 1960s, the SP-5, SP-5S and SP-6 stethoscope pickups were produced. Shure also produced hearing aid cartridges used in hearing aid products from manufacturers like Maico, Telex, Dictograph, Otarian, Vocalite, and Trimm.

-

In 1956, Shure moved its corporate headquarters to Hartrey Avenue in Evanston, Illinois, where it remained for 47 years. Beginning in the 1956, Shure manufactured magnetic tape recording heads and two years later, the company announced it was ready to mass-produce 4-ch recording heads. By 1964, however, Shure announced it would no longer produce tape recording heads due to increased competition.

-

In 1953, Shure introduced their first wireless microphone system for performers, and in 1959, they introduced the Unidyne III Microphone, which was the predecessor to the SM57, which would be introduced, along with the SM58, six years later. Shure also produced portable equipment for broadcast field recording like Vocal Master, the M67 Portable Mixer, and the FP31 Portable Mixer. In 1990, Shure entered the wireless microphone market with the L-Series.

-

In 1981, James Kogen, Executive Vice President, Operations, was promoted to President and General Manager of Shure. In 1995, Sidney N. Shure died at the age of 93, and Rose L. Shure was elected Chairman of the Board of Directors. In 1996, James Kogen retired; Santo (Sandy) LaMantia, Vice President of Engineering, was named President and CEO. Shure Brothers Incorporated was officially renamed Shure Incorporated in 1999.

-

In 2001, Shure acquired the Popper Stopper brand of studio pop filters from Middle Atlantic Products Inc. The following year, Shure adopted hearing conservation as the company’s corporate cause and established the Shure Bid for Hearing program. In 2003, Shure moved into new corporate headquarters in Niles, Illinois, into a building designed by architect Helmut Jahn which was originally the headquarters of HA•LO Industries. The 65,000-square-foot (6,000 m2) Technology Annex designed by Krueck and Sexton Architects, opened in 2005, houses Shure's Performance Listening Center. In 2008, Shure celebrated the opening of The S.N. Shure Theater and Interactive Display at their corporate headquarters.

-

International offices

-
    -
  • 1991: Shure Europe GmbH opened in Heilbronn, Germany to provide sales, service and support to Shure distribution centers in 34 European countries.
  • -
  • 1999: Shure Asia Limited is opened in Hong Kong to serve Distribution Centers and distributors throughout Asia and the Pacific Rim.
  • -
  • 2002: Shure Distribution GmbH established as a subsidiary of Shure Europe GmbH, to handle direct sales with Shure dealers in Germany.
  • -
  • 2003: HW International, Shure's United Kingdom Distribution Center, acquired and renamed Shure Distribution UK.
  • -
  • 2005: Sales and marketing office opened in Shanghai, China.
  • -
  • 2006: Sales and marketing office opened in Tokyo, Japan.
  • -
  • 2010: New subsidiary formed in the Netherlands
  • -
-

Production facility expansion

-
    -
  • 1982: Manufacturing facility opened in Wheeling, Illinois
  • -
  • 1983: Phonograph cartridge manufacturing facility opened in Agua Prieta, Mexico
  • -
  • 1984: Wired microphone manufacturing facility opened in Juarez, Mexico
  • -
  • 1989: Juarez, Mexico facility expanded
  • -
  • 1994: Agua Prieta facility expanded in 1994
  • -
  • 2005: Manufacturing facility opened in Suzhou, China
  • -
-


-

(For more, go to the original article on Wikipedia)

";"

-

-

-

Shure Incorporated is an American corporation originally founded by Sidney N. Shure in Chicago, Illinois in 1925 as a supplier of radio parts kits. The company became a consumer and professional audio-electronics manufacturer of microphones, wireless microphone systems, phonograph cartridges, discussion systems, mixers, and digital signal processing.

-

The company also produces listening products, including headphones, high-end earbuds and personal monitor systems.

";MetaTitle-Shure;MetaKeywords-Shure;Meta description-Shure;http://localhost/prestashop/img/m/2.jpg -3;1;Sony;"


-

History

-

Sony found its beginning in the wake of World War II. In 1946, Masaru Ibuka started an electronics shop in a bomb-damaged department store building in Tokyo. The company had $530 in capital and a total of eight employees. The next year, he was joined by his colleague, Akio Morita, and they founded a company called Tokyo Tsushin Kogyo (Tokyo Telecommunications Engineering Corporation). The company built Japan's first tape recorder, called the Type-G. In 1958 the company name was changed to Sony.

-

In the early 1950s, Ibuka traveled in the United States and heard about Bell Labs' invention of the...

-

(For more, go to the original article on Wikipedia)

";"

-

-

-


-

Sony Corporation, commonly referred to as Sony, is a Japanese multinational conglomerate corporation headquartered in Konan Minato, Tokyo, Japan. Its diversified business is primarily focused on the electronics, game, entertainment and financial services sectors. The company is one of the leading manufacturers of electronic products for the consumer and professional markets. Sony is ranked 87th on the 2012 list of Fortune Global 500.

";MetaTitle-Sony;MetaKeywords-Sony;Meta description-Sony;http://localhost/prestashop/img/m/3.jpg -4;1;Samsung;"

Samsung was founded by Lee Byung-chul in 1938 as a trading company. Over the next three decades the group diversified into areas including food processing, textiles, insurance, securities and retail. Samsung entered the electronics industry in the late 1960s and the construction and shipbuilding industries in the mid-1970s; these areas would drive its subsequent growth. Following Lee's death in 1987, Samsung was separated into four business groups – Samsung Group, Shinsegae Group, CJ Group and Hansol Group. Since the 1990s Samsung has increasingly globalized its activities, and electronics, particularly mobile phones and semiconductors, have become its most important source of income.

-

Notable Samsung industrial subsidiaries include Samsung Electronics (the world's largest information technology company measured by 2012 revenues, and 4th in market value), Samsung Heavy Industries (the world's 2nd-largest shipbuilder measured by 2010 revenues), and Samsung Engineering and Samsung C&T (respectively the world's 13th and 36th-largest construction companies). Other notable subsidiaries include Samsung Life Insurance (the world's 14th-largest life insurance company), Samsung Everland (operator of Everland Resort, the oldest theme park in South Korea), Samsung Techwin (an aerospace, surveillance and defense company) and Cheil Worldwide (the world's 16th-largest advertising agency measured by 2011 revenues).

-

Samsung has a powerful influence on South Korea's economic development, politics, media and culture, and has been a major driving force behind the ""Miracle on the Han River"". Its affiliate companies produce around a fifth of South Korea's total exports. Samsung's revenue was equal to 17% of the South Korea's $1,082 billion GDP.

-

In 2013, Samsung began construction on building the world's largest ...

-

(For more, go to the original article on Wikipedia)

";"


-
-
-
-


-

Samsung Group is a South Korean multinational conglomerate company headquartered in Samsung Town, Seoul. It comprises numerous subsidiaries and affiliated businesses, most of them united under the Samsung brand, and is the largest South Korean chaebol (business conglomerate).

";MetaTitle-Samsung;MetaKeywords-Samsung;Meta description-Samsung;http://localhost/prestashop/img/m/4.jpg diff --git a/docs/csv_import/products_import.csv b/docs/csv_import/products_import.csv deleted file mode 100644 index 01faa8e0..00000000 --- a/docs/csv_import/products_import.csv +++ /dev/null @@ -1,8 +0,0 @@ -Product ID;Active (0/1);Name *;Categories (x,y,z...);Price tax excluded;Tax rules ID;Wholesale price;On sale (0/1);Discount amount;Discount percent;Discount from (yyyy-mm-dd);Discount to (yyyy-mm-dd);Reference #;Supplier reference #;Supplier;Manufacturer;EAN13;UPC;Ecotax;Width;Height;Depth;Weight;Delivery time of in-stock products;Delivery time of out-of-stock products with allowed orders;Quantity;Minimal quantity;Low stock level;Send me an email when the quantity is under this level;Visibility;Additional shipping cost;Unity;Unit price;Summary;Description;Tags (x,y,z...);Meta title;Meta keywords;Meta description;URL rewritten;Text when in stock;Text when backorder allowed;Available for order (0 = No, 1 = Yes);Product available date;Product creation date;Show price (0 = No, 1 = Yes);Image URLs (x,y,z...);Image alt texts (x,y,z...);Delete existing images (0 = No, 1 = Yes);Feature(Name:Value:Position);Available online only (0 = No, 1 = Yes);Condition;Customizable (0 = No, 1 = Yes);Uploadable files (0 = No, 1 = Yes);Text fields (0 = No, 1 = Yes);Out of stock action;Virtual product;File URL;Number of allowed downloads;Expiration date;Number of days;ID / Name of shop;Advanced stock management;Depends On Stock;Warehouse;Acessories (x,y,z...) -1;1;iPod Nano;iPods;100;1;80;1;;5.5;2013-06-01;2018-12-31;RP-demo_1;RF-demo_1;Applestore;Apple;1234567890123;;1;0.6;0.2;0.4;0.068357;;;160;1;0;0;;;;;

New design.

;

New design.

;apple, ipod, nano;Meta title-Nano;Meta keywords-Nano;Meta description-Nano;iPod-Nano;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-01;1;http://localhost/prestashop/img/p/1/5/15.jpg,http://localhost/prestashop/img/p/2/3/23.jpg;First alt text,Second alt text;0;;0;new;0;0;0;0;0;;;;;0;0;0;0; -2;1;iPod shuffle;iPods;60;1;40;1;;;2013-06-01;2018-12-31;RP-demo_2;RF-demo_2;Applestore;Apple;1234567890123;;1;0.1;0.1;0.1;0.027563;;;120;1;1;0;both;;;;

New design.

;

New design.

;ipod, shuffle;Meta title-Shuffle;Meta keywords-Shuffle;Meta description-Shuffle;iPod-shuffle;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-02;1;http://localhost/prestashop/img/p/2/3/23.jpg;First alt text;0;;0;new;0;0;0;0;0;;;;;0;0;0;0; -3;1;MacBook Air;Laptops;1500;1;1000;1;100;;2013-06-01;2018-12-31;RP-demo_3;RF-demo_3;Applestore;Apple;1234567890123;;2;1.31;0.3;1;2.976846;;;400;1;2;0;catalog;;;;

New design.

;

New design.

;MacBook, Air;Meta title-McBookAir;Meta keywords-McBookAir;Meta description-McBookAir;MacBook-Air;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-03;1;http://localhost/prestashop/img/p/1/1.jpg;First alt text;1;;0;new;0;0;0;0;0;;;;;0;0;0;0; -4;1;MacBook;Laptops;1150;1;750;1;;;2013-06-01;2018-12-31;RP-demo_4;RF-demo_4;Applestore;Apple;1234567890123;;2;1.31;0.3;1;4.454244;;;75;1;3;1;search;;;;

New design.

;

New design.

;MacBook, Pro;Meta title-McBookPro;Meta keywords-McBookPro;Meta description-McBookPro;MacBook;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-04;1;http://localhost/prestashop/img/p/6/6.jpg;First alt text;1;;0;new;0;0;0;0;0;;;;;0;0;0;0; -5;1;iPod touch;iPods;240;1;150;1;;;2013-06-01;2018-12-31;RP-demo_5;RF-demo_5;Applestore;Apple;1234567890123;;1;0.6;0.2;0.4;0.194046;;;120;1;;0;none;;;;

New design.

;

New design.

;Ipod touch;Meta title-IpodTouch;Meta keywords-IpodTouch;Meta description-IpodTouch;iPod-touch;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-05;1;http://localhost/prestashop/img/p/7/7.jpg;First alt text;0;;1;used;0;0;0;0;0;;;;;0;0;0;0; -6;1;Belkin Leather Folio for iPod nano - Black / Chocolate;Accessories;25;1;150;1;;;2013-06-01;2018-12-31;RP-demo_6;RF-demo_6;Nippon Electronic Import;Belkin;1234567890123;;0;0.6;0.2;0.4;0.038588;;;25;1;0;1;;20;;;

New design.

;

New design.

;Folio, leather;Meta title-BelkinLeatherFolio;Meta keywords-BelkinLeatherFolio;Meta description-BelkinLeatherFolio;Belkin-Leather-Folio-for-iPod-nano---Black-Chocolate;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-06;1;http://localhost/prestashop/img/p/1/3/13.jpg;First alt text;0;;1;refurbished;0;0;0;0;0;;;;;0;0;0;0; -7;1;Shure SE210 Sound-Isolating Earphones for iPod and iPhone;Accessories;125;2;80;1;;;2013-06-01;2018-12-31;RP-demo_7;RF-demo_7;Shure Online Store;Shure;1234567890123;;0;0.1;0.1;0.1;0.040793;;;15;1;1;1;;;;;

New design.

;

New design.

;Headphones;Meta title-ShureEarphones;Meta keywords-ShureEarphones;Meta description-ShureEarphones;Shure-SE210-Sound-Isolating-Earphones-for-iPod-and-iPhone;In Stock;Current supply. Ordering availlable;1;2013-03-01;2013-01-07;1;http://localhost/prestashop/img/p/1/4/14.jpg;First alt text;0;;1;new;0;0;0;0;0;;;;;0;0;0;0; diff --git a/docs/csv_import/store_contacts.csv b/docs/csv_import/store_contacts.csv deleted file mode 100644 index 375efa31..00000000 --- a/docs/csv_import/store_contacts.csv +++ /dev/null @@ -1,6 +0,0 @@ -Store ID;active;name;address1;address2;postcode;state;city;country;latitude;longitude;phone;fax;email;note;hours;image -1;1;Dade County;3030 SW 8th St Miami;;33135;Florida;Miami;United States;25.76500500;-80.24379700;;;;;"09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,10:00 - 16:00,10:00 - 16:00";http://yourlinktotheimage.com/img1.jpg -2;1;E Fort Lauderdale;1000 Northeast 4th Ave Fort Lauderdale;;33304;Florida;Miami;United States;26.13793600;-80.13943500;;;;;"09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,10:00 - 16:00,10:00 - 16:00";http://yourlinktotheimage.com/img2.jpg -3;1;Pembroke Pines;11001 Pines Blvd Pembroke Pines;;33026;Florida;Miami;United States;26.00998700;-80.29447200;;;;;"09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,10:00 - 16:00,10:00 - 16:00";http://yourlinktotheimage.com/img3.jpg -4;1;Coconut Grove;2999 SW 32nd Avenue;;33133;Florida;Miami;United States;25.73629600;-80.24479700;;;;;"09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,10:00 - 16:00,10:00 - 16:00";http://yourlinktotheimage.com/img4.jpg -5;1;N Miami/Biscayne;12055 Biscayne Blvd;;33181;Florida;Miami;United States;25.88674000;-80.16329200;;;;;"09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,09:00 - 19:00,10:00 - 16:00,10:00 - 16:00";http://yourlinktotheimage.com/img5.jpg diff --git a/docs/csv_import/suppliers_import.csv b/docs/csv_import/suppliers_import.csv deleted file mode 100644 index a7720885..00000000 --- a/docs/csv_import/suppliers_import.csv +++ /dev/null @@ -1,4 +0,0 @@ -Supplier ID;Active (0/1);Name *;Description;Short description;Meta title;Meta keywords;Meta description;Image URL -1;1;Applestore;

The Apple Store is a chain of retail stores owned and operated by Apple Inc., dealing in computers and consumer electronics. The stores sell Macintosh personal computers, software, iPods, iPads, iPhones, third-party accessories, and other consumer electronics such as Apple TV. Some high profile stores feature a Theatre for presentations and workshops and a Studio for training with Apple products; all stores offer a Genius Bar for technical support and repairs, as well as free workshops available to the public. Under the leadership of Ron Johnson, the former Senior Vice President of Retail Operations, the Apple Stores have, according to an article in the New York Times, been responsible for "[turning] the boring computer sales floor into a sleek playroom filled with gadgets".

;Meta title-Applestore;Meta keywords-Applestore;Meta description-Applestore;http://localhost/prestashop/img/su/Pic-of-this-supplier.jpg -2;1;Shure Online Store;

- No description -

;

- No description -

;Meta title-Shure Online Store;Meta keywords-Shure Online Store;Meta description-Shure Online Store;http://localhost/prestashop/img/su/Pic-of-this-supplier-2.jpg -3;1;Nippon Electronic Import;

- No description -

;

- No description -

;Meta title-Nippon Electronic Import;Meta keywords-Nippon Electronic Import;Meta description-Nippon Electronic Import;http://localhost/prestashop/img/su/Pic-of-this-supplier-3.jpg diff --git a/docs/csv_import/supply_orders_details_import.csv b/docs/csv_import/supply_orders_details_import.csv deleted file mode 100644 index bfc16136..00000000 --- a/docs/csv_import/supply_orders_details_import.csv +++ /dev/null @@ -1,21 +0,0 @@ -Supply Order Reference *;Product ID *;Product Attribute ID;Unit Price (tax excl.)*;Quantity Expected *;Discount Rate;Tax Rate -Ref Apple 01;1;1;100;25;0;19,6 -Ref Apple 01;1;2;80;25;0;19,6 -Ref Apple 01;1;3;100;25;0;19,6 -Ref Apple 01;1;4;80;25;0;19,6 -Ref Apple 01;1;5;100;25;0;19,6 -Ref Apple 01;1;6;80;25;0;19,6 -Ref Apple 01;1;7;100;25;0;19,6 -Ref Apple 01;1;8;80;25;0;19,6 -Ref Apple 01;1;9;100;25;0;19,6 -Ref Apple 01;1;10;80;25;0;19,6 -Ref Apple 01;1;11;100;25;0;19,6 -Ref Apple 01;1;12;80;25;0;19,6 -Ref Apple 01;1;13;100;25;0;19,6 -Ref Apple 01;1;14;80;25;0;19,6 -Ref Apple 01;1;15;100;25;0;19,6 -Ref Apple 01;1;16;80;25;0;19,6 -Ref Apple 01;2;17;40;25;0;19,6 -Ref Apple 01;2;18;40;25;0;19,6 -Ref Apple 01;2;19;40;25;0;19,6 -Ref Apple 01;2;20;40;25;0;19,6 diff --git a/docs/csv_import/supply_orders_import.csv b/docs/csv_import/supply_orders_import.csv deleted file mode 100644 index 30d1777d..00000000 --- a/docs/csv_import/supply_orders_import.csv +++ /dev/null @@ -1,5 +0,0 @@ -Supply Order ID;Supplier ID *;Lang ID;Warehouse ID *;Currency ID *;Supply Order Reference *;Delivery Date (Y-M-D)*;Discount Rate;Template -1;1;1;1;1;Ref Apple 01;2013-11-01;; -2;3;1;1;1;Nippon Electronic Import;2013-11-01;; -3;2;1;1;1;Shure Online Store;2013-11-01;; -4;1;1;2;2;Ref Apple 02;2013-11-01;; diff --git a/docs/docker/nginx_fpm/prestashop-fpm/Dockerfile b/docs/docker/nginx_fpm/prestashop-fpm/Dockerfile deleted file mode 100644 index d1be5113..00000000 --- a/docs/docker/nginx_fpm/prestashop-fpm/Dockerfile +++ /dev/null @@ -1,28 +0,0 @@ -FROM php:7.1-fpm-alpine -ARG UID=1001 - -RUN apk add --no-cache \ - tzdata \ - zlib-dev \ - libjpeg-turbo-dev \ - libmcrypt-dev \ - pcre-dev \ - libpng-dev \ - freetype-dev \ - libxml2-dev \ - icu-dev - -ENV TZ Europe/Paris - -RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \ - && docker-php-ext-install iconv intl pdo_mysql mbstring soap gd zip - -RUN docker-php-source extract \ - && if [ -d "/usr/src/php/ext/mysql" ]; then docker-php-ext-install mysql; fi \ - && if [ -d "/usr/src/php/ext/mcrypt" ]; then docker-php-ext-install mcrypt; fi \ - && if [ -d "/usr/src/php/ext/opcache" ]; then docker-php-ext-install opcache; fi \ - && docker-php-source delete - -COPY prestashop-php.ini /usr/local/etc/php/conf.d/prestashop-php.ini - -RUN adduser -D -H -u ${UID} prestashop diff --git a/docs/docker/nginx_fpm/prestashop-fpm/prestashop-php.ini b/docs/docker/nginx_fpm/prestashop-fpm/prestashop-php.ini deleted file mode 100644 index 338279cd..00000000 --- a/docs/docker/nginx_fpm/prestashop-fpm/prestashop-php.ini +++ /dev/null @@ -1,14 +0,0 @@ -[PHP] - -; This directive determines whether or not PHP will recognize code between -; tags as PHP source which should be processed as such. It is -; generally recommended that should be used and that this feature -; should be disabled, as enabling it may result in issues when generating XML -; documents, however this remains supported for backward compatibility reasons. -; Note that this directive does not control the tags as PHP source which should be processed as such. It is -; generally recommended that should be used and that this feature -; should be disabled, as enabling it may result in issues when generating XML -; documents, however this remains supported for backward compatibility reasons. -; Note that this directive does not control the - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/docs/licenses/LICENSE.txt b/docs/licenses/LICENSE.txt deleted file mode 100644 index a77cc9fd..00000000 --- a/docs/licenses/LICENSE.txt +++ /dev/null @@ -1,89 +0,0 @@ -Copyright (c) Since 2007 PrestaShop. - -Open Software License v. 3.0 (OSL-3.0) - -This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Open Software License version 3.0 - -1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: -a) to reproduce the Original Work in copies, either alone or as part of a collective work; -b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; -c) to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License; -d) to perform the Original Work publicly; and -e) to display the Original Work publicly. - -2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - -3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - -4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - -5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - -6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - -7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - -8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - -9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - -10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - -11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - -12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - -13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - -14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - -16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. - -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -Academic Free License ("AFL") v. 3.0 - -This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: - -Licensed under the Academic Free License version 3.0 - -1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following: -a) to reproduce the Original Work in copies, either alone or as part of a collective work; -b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work; -c) to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License; -d) to perform the Original Work publicly; and -e) to display the Original Work publicly. - -2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works. - -3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work. - -4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license. - -5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c). - -6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. - -7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer. - -8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation. - -9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c). - -10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. - -11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License. - -12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. - -13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. - -14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. - -16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process. diff --git a/docs/licenses/cropper.txt b/docs/licenses/cropper.txt deleted file mode 100644 index f696f253..00000000 --- a/docs/licenses/cropper.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2006, David Spurr (www.defusion.org.uk) -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -http://www.opensource.org/licenses/bsd-license.php \ No newline at end of file diff --git a/docs/licenses/fileuploader.txt b/docs/licenses/fileuploader.txt deleted file mode 100644 index 85515c28..00000000 --- a/docs/licenses/fileuploader.txt +++ /dev/null @@ -1,20 +0,0 @@ -File uploader component is licensed under the following licenses, choose one that suits your needs better. - -- MIT license - -The MIT License (MIT) -Copyright (c) 2010 Andrew Valums - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -- GNU GPL 2 or later -http://www.gnu.org/licenses/gpl-2.0.txt - -- GNU LGPL 2 or later -http://www.gnu.org/licenses/lgpl-2.0.txt - -© 2010 Andrew Valums diff --git a/docs/licenses/fonts/open-sans.txt b/docs/licenses/fonts/open-sans.txt deleted file mode 100644 index d6456956..00000000 --- a/docs/licenses/fonts/open-sans.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/docs/licenses/fonts/ubuntu-condensed.txt b/docs/licenses/fonts/ubuntu-condensed.txt deleted file mode 100644 index ae78a8f9..00000000 --- a/docs/licenses/fonts/ubuntu-condensed.txt +++ /dev/null @@ -1,96 +0,0 @@ -------------------------------- -UBUNTU FONT LICENCE Version 1.0 -------------------------------- - -PREAMBLE -This licence allows the licensed fonts to be used, studied, modified and -redistributed freely. The fonts, including any derivative works, can be -bundled, embedded, and redistributed provided the terms of this licence -are met. The fonts and derivatives, however, cannot be released under -any other licence. The requirement for fonts to remain under this -licence does not require any document created using the fonts or their -derivatives to be published under this licence, as long as the primary -purpose of the document is not to be a vehicle for the distribution of -the fonts. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this licence and clearly marked as such. This may -include source files, build scripts and documentation. - -"Original Version" refers to the collection of Font Software components -as received under this licence. - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to -a new environment. - -"Copyright Holder(s)" refers to all individuals and companies who have a -copyright ownership of the Font Software. - -"Substantially Changed" refers to Modified Versions which can be easily -identified as dissimilar to the Font Software by users of the Font -Software comparing the Original Version with the Modified Version. - -To "Propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification and with or without charging -a redistribution fee), making available to the public, and in some -countries other activities as well. - -PERMISSION & CONDITIONS -This licence does not grant any rights under trademark law and all such -rights are reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of the Font Software, to propagate the Font Software, subject to -the below conditions: - -1) Each copy of the Font Software must contain the above copyright -notice and this licence. These can be included either as stand-alone -text files, human-readable headers or in the appropriate machine- -readable metadata fields within text or binary files as long as those -fields can be easily viewed by the user. - -2) The font name complies with the following: -(a) The Original Version must retain its name, unmodified. -(b) Modified Versions which are Substantially Changed must be renamed to -avoid use of the name of the Original Version or similar names entirely. -(c) Modified Versions which are not Substantially Changed must be -renamed to both (i) retain the name of the Original Version and (ii) add -additional naming elements to distinguish the Modified Version from the -Original Version. The name of such Modified Versions must be the name of -the Original Version, with "derivative X" where X represents the name of -the new work, appended to that name. - -3) The name(s) of the Copyright Holder(s) and any contributor to the -Font Software shall not be used to promote, endorse or advertise any -Modified Version, except (i) as required by this licence, (ii) to -acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with -their explicit written permission. - -4) The Font Software, modified or unmodified, in part or in whole, must -be distributed entirely under this licence, and must not be distributed -under any other licence. The requirement for fonts to remain under this -licence does not affect any document created using the Font Software, -except any version of the Font Software extracted from a document -created using the Font Software may only be distributed under this -licence. - -TERMINATION -This licence becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF -COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER -DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/licenses/index.php b/docs/licenses/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/docs/licenses/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/docs/licenses/php-sql-parser.txt b/docs/licenses/php-sql-parser.txt deleted file mode 100644 index c3e2031e..00000000 --- a/docs/licenses/php-sql-parser.txt +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2011, greenlion (http://code.google.com/p/php-sql-parser/) -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -http://www.opensource.org/licenses/bsd-license.php \ No newline at end of file diff --git a/docs/licenses/tinymce-smarty-swift.txt b/docs/licenses/tinymce-smarty-swift.txt deleted file mode 100644 index 070b42c7..00000000 --- a/docs/licenses/tinymce-smarty-swift.txt +++ /dev/null @@ -1,460 +0,0 @@ -TinyMCE, Smarty and Swift are licenced under LGPL : - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS diff --git a/docs/server_config/nginx.conf.dist b/docs/server_config/nginx.conf.dist deleted file mode 100644 index cef3dfa4..00000000 --- a/docs/server_config/nginx.conf.dist +++ /dev/null @@ -1,196 +0,0 @@ -# ------------------------------------------------------------------------------------------------- -# The following file is provided as-is by PrestaShop as an example configuration for your Nginx server. -# It may be incomplete, and remember you must adapt it for your own server's needs! -# Based on the work of MattLoyeD and Michael Dekker. -# ------------------------------------------------------------------------------------------------- - -server { - # Ipv4 - listen 80; - - # IPv6 - # listen [::]:80; - - # SSL Ipv4 & v6 - # listen 443 ssl; - # listen [::]:443 ssl; - - # Your SSL Certificates, don't forget to take a look at Certbot (https://certbot.eff.org) - # ssl_certificate /etc/ssl/fullchain.pem; - # ssl_certificate_key /etc/ssl/privkey.pem; - - # ssl_session_timeout 24h; - # ssl_session_cache shared:SSL:10m; - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:AES128-SHA:!ADH:!AECDH:!MD5; - # ssl_prefer_server_ciphers on; - # Do not forget to create this file before with OpenSSL : "openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048" - # ssl_dhparam /etc/nginx/ssl/dhparam.pem; - - # [REQUIRED EDIT] Your domain name goes here - server_name server_name example.com www.example.com; - - # [REQUIRED EDIT] Absolute path to your website root on the filesystem - root /path/to/prestashop; - - index index.php; - - # Redirect 404 errors to prestashop - error_page 404 /index.php?controller=404; - - # Gzip Settings, convert all types. - gzip on; - gzip_vary on; - gzip_proxied any; - - # Can be enhance to 5, but it can slow you server - # gzip_comp_level 5; - # gzip_min_length 256; - - gzip_types - application/atom+xml - application/javascript - application/json - application/ld+json - application/manifest+json - application/rss+xml - application/vnd.geo+json - application/vnd.ms-fontobject - application/x-font-ttf - application/x-web-app-manifest+json - application/xhtml+xml - application/xml - font/opentype - image/bmp - image/svg+xml - image/x-icon - text/cache-manifest - text/css - text/plain - text/vcard - text/vnd.rim.location.xloc - text/vtt - text/x-component - text/x-cross-domain-policy; - - gzip_disable "MSIE [1-6]\.(?!.*SV1)"; - - # HSTS (Force clients to interact with your website using HTTPS only) - # For enhanced security, register your site here: https://hstspreload.org/ - # WARNING: Don't use this if your site is not fully on HTTPS! - # add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" preload; always; - - # Cloudflare / Max CDN fix - location ~* \.(eot|otf|ttf|woff(?:2)?)$ { - add_header Access-Control-Allow-Origin *; - } - - # Do not save logs for these - location = /favicon.ico { - auth_basic off; - allow all; - log_not_found off; - access_log off; - } - - location = /robots.txt { - auth_basic off; - allow all; - log_not_found off; - access_log off; - } - - # [REQUIRED EDIT IF MULTILANG] - # rewrite ^/fr$ /fr/ redirect; - # rewrite ^/fr/(.*) /$1; - - # Images - rewrite ^/([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$1$2$3.jpg last; - rewrite ^/([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$1$2$3$4.jpg last; - rewrite ^/([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$1$2$3$4$5.jpg last; - rewrite ^/([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg last; - rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg last; - rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg last; - rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg last; - rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg last; - rewrite ^/c/([0-9]+)(-[.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+.jpg$ /img/c/$1$2$3.jpg last; - rewrite ^/c/([a-zA-Z_-]+)(-[0-9]+)?/.+.jpg$ /img/c/$1$2.jpg last; - - # AlphaImageLoader for IE and fancybox - rewrite ^images_ie/?([^/]+)\.(jpe?g|png|gif)$ js/jquery/plugins/fancybox/images/$1.$2 last; - - # Web service API - rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last; - - # Installation sandbox - rewrite ^(/install(?:-dev)?/sandbox)/(.*) /$1/test.php last; - - # [REQUIRED EDIT] Change this block to your admin folder - location /admin-dev/ { - if (!-e $request_filename) { - rewrite ^/.*$ /admin-dev/index.php last; - } - } - - - # File security - # .htaccess .DS_Store .htpasswd etc - location ~ /\. { - deny all; - } - # Source code directories - location ~ ^/(app|bin|cache|classes|config|controllers|docs|localization|override|src|tests|tools|translations|travis-scripts|vendor|var)/ { - deny all; - } - # vendor in modules directory - location ~ ^/modules/.*/vendor/ { - deny all; - } - # Prevent exposing other sensitive files - location ~ \.(yml|log|tpl|twig|sass)$ { - deny all; - } - - # Prevent injection of php files - location /upload { - location ~ \.php$ { - deny all; - } - } - location /img { - location ~ \.php$ { - deny all; - } - } - - # PHP FPM part - location ~ \.php$ { - # Verify that the file exists, redirect to index if not - try_files $fastcgi_script_name /index.php$uri&$args =404; - - fastcgi_index index.php; - - # Environment variables for PHP - fastcgi_split_path_info ^(.+\.php)(/.+)$; - - include fastcgi_params; - - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - - # [REQUIRED EDIT] Connection to PHP-FPM - choose one - # fastcgi_pass 127.0.0.1:9000; - fastcgi_pass unix:/run/php/php7.0-fpm.sock; - - fastcgi_keep_conn on; - fastcgi_read_timeout 30s; - fastcgi_send_timeout 30s; - - # In case of long loading or 502 / 504 errors - # fastcgi_buffer_size 256k; - # fastcgi_buffers 256 16k; - # fastcgi_busy_buffers_size 256k; - client_max_body_size 10M; - } -} diff --git a/download/.htaccess b/download/.htaccess deleted file mode 100644 index 3de9e400..00000000 --- a/download/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order deny,allow - Deny from all - - -# Apache 2.4 - - Require all denied - diff --git a/download/index.php b/download/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/download/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/firmeslink/.htaccess b/firmeslink/.htaccess deleted file mode 100644 index 896fbc5a..00000000 --- a/firmeslink/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all \ No newline at end of file diff --git a/firmeslink/documents/.htaccess b/firmeslink/documents/.htaccess deleted file mode 100644 index 896fbc5a..00000000 --- a/firmeslink/documents/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -Order deny,allow -Deny from all \ No newline at end of file diff --git a/firmeslink/documents/6/1/5/4/8/61548-2.pdf b/firmeslink/documents/6/1/5/4/8/61548-2.pdf deleted file mode 100644 index 5278d0a2c294def0c98fa1617b7f3ab47a50f240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105209 zcmb??Lv$ug6lI)rY&#v>R>yY7NykRVwr$(C^(7tK#uwYxm&`vii<#YQW>@c?`(C|! zPA#hH+()S_F3HHs!~svae=xfU&q~Td>R@aQFCf6I?BrnTYGUR@N+afAXXIpJNvbAF z3(qX(WM<^z@E`hLqLi7vnbZG@%>P4_#3V!&N&mxCjU4|Ys<|3lo0+(f(x{p_Iykxf zhp1b**qZ%c@&77iv9P#=^?R!p+XX$ihm^!b1IDo`Qqv|AQhV z1aD?<`ac`z{67NZ&Fn2)EJ-=od0AQEng4ghO3K5_!@~j3ENNxy@}D+lN!$N67dJC; zFg1h!uZpwFfAZ|$J#sF4VSUs!-i1GNHqEKVO{sblr{t-U6C{8A3J@VpP6$EwQb7Ir zh+SeL770B-8id3@1VMhvCj$oA6?I)@v+7!VK}T0-HtecDS(Whdo#%WLf~x%ZviagG z{QZ)g>2u@kB|Q6(<3v3aF(!%hGuin$OXK>GcOl!cGkDDNsK@LfouN`8O9XR|3cgaG z#r-&k`5bg5E@OjMb_2m99xIyz`60Bnh|QqwI?%GSnI8gTEZT#XGdE~pARFn*x3tIo z+@AbBrN5%%2y$&WLFKitFy!+#Kjn>orqpr8-TRoW2RQEFmbIXRzJ$fyODk8=D=EgI z9}^r(ev*SAcWG{|KHxwdT^T)B(T@~Pn5zDBP>Jzv^T@Kr^;!;INyv+E8xm$5Y4#&WYk0n4{`lsXJv>EkQzM6idlfXM)&~E_7CS!>Wy6czMe$ zD#8)UWE>%WQsG*H*&?1SD9KJ*TuwVhBxOA3m4FHW^k(iOtK4F?6|TI0Iow2ns|%6D z0=bu>@QiMZ`Mj?!<425ux>R!+Iz1~f6eW~r4)q0SV z>7rwnX!aRX%Lsu>N}pL_O~m&2^Zp0jhpNO)VOjMVc}z6_yw}S-q)Wn+d2cBXEpjcE zR3^s{KV3`edxug@EzWAQ@O6xPMNUAkdi;vXqmoN*Qw0p=mZ%bGyn~j|KT=p;4TI7W zn(Cz>jP$}VXO{Kmu|rPr@BbGQKy@+X`gQ zwl&z*#P&|_q;ZT>Fs2KoL*75!cgq@TEW?tPYRQWB8D#xJn1f6&YOR;@bzf9_WQaC8 zW5D6`g1iGH!^mR2?ojkH^itQSx6_O+S8v3(d>4bLdlMOO&BW%BtF2IU_VO99&Bjcl z*JPj3WcxHWsKX}}*XeP_&F;lJfA7!$X})FrWV8z}HFi|OtJ#-((=xA4S^-s>7n((k zxK=cpFh|NH=iztkD8*K+6YYpVtd=yUV#zM-gCj5NqTY&^gGYv5MgL;vImjUanulM9 zeNe^rg5B6a-F3*zAJ3THX}a z7@zh@*u!=#RZIy@gj=FAd)1r8y!OWy#OA4{KF80s$Qq1R>K&W%=b>lkjrLaI`L9SJ zZ2;=giwe`zFB$HFly+mp>mhd($$fCIEQ11W32lHmx*F^LK_*Ty8Eo(GiLj=<*Er*Y z+uV>FOfD>7rY*K^zzyF@Ka+)K1O2+WTk`8pP}h~|OEcuF&=m6C2cLI7DA#wUFO4OF z60dlj+DzJ0mDQS09G@;WapZvCP$%k!%__77M$jdHiH;~`C!yFhKZkxcC4I7e0+5`a z@=g9-AT1l0RGvbUoccC_H8D9+J)t|HR3%rdj#II@Ox^mkHl9mHw`99Wu*A2DsNFKH zF-<$IH4UKUQjM~8j<@73?D} zw0%jmLc^SbbMZ2!vEYALYTNY4BbTaw4(3U$FUGe??@Q`S;afD+5V>GcQ|?6Mt))YU zlE{%4`JRPdtXJqK3uPcI(iK9KmX}nYP(SCd1i5r|>Fe74NY|N4p^DiXuiY!!g_mfM zge{w0A$eB(C5|wE{Zfrn&lzGN2$Q4NoVdo@K>n; zlW!z#k;cT2?$Ug4v=m3n zIr8qUx*i3P`nO(jf%sif@TaIFyOI;>_JyrpklB!Z!tkGJMObYDFC^XU&lTnpBR-;N7=IOw7fK}1Ua6(##{43F`usn60_`)Orn{vCVBB1VSx|! zi#Ua02xP^Qzo>-d5T3HF;NI*jSUnC+BpO2@6+7GMRQ zwV$QNiUCauyPJcjM7I)Ra%&<#3<}6Xj-q7w7GQ4 zcB6YEI$IJ(&I^ruHtC8Ns~o@lYh$t&k$Tt@-xN0;_1iocSrvEVOMBI0nKv2-s^KPq z4n;NhF^7q7)ijlt@{dK(*_Vrdm+*G}_lHp9>xd{YDjYjGgwvLaBaWd)zQZpccDoG4 zCEib~6HCk=4^GemwI##pR8V7%O7hn%e((*H54BOOMs(^6$En<6A>MR9z8i8&!<&{T zl}vh_ABOZ{8^D;@3_2hre}!Wkf)RUGtL^pokGAbZtwV=a5q<|_jMph zZKYnP)A+5a^n|g}u*Y&Q=Snr^c|1W6g&9m3Zxv81W z+q~psp{J6#ou0B&O4az6kDjfIx@pKFnmq~vQlmCwR@E4KagMBmMlOGX0gm!Q?_k)G zQ@1-6p}Ct=1wzN3x~p|YK(`{4b3Xn;e8NLl$Rhz6h=?q6QU4cZC-1dvJ^!t7=<4=J zSzL9Xr*mlg3K0+0RB?!BHOr>avj^&cJ|3XpAJHGz>j{zNEa=!&S1jo|UJla;_pz;n zEkbMLAEB(6WgJ)r4~liOX@npwWA=QUjqJpqWKQo;7B2FmU z4=Sgpe>9La_clWuGNSM_Nuc7BH~p{_gTPLV^(L!FvUB1-A++x)o0e%lZyG%IIGM`% zjgernaxXyMl;|KqdRBw`RUfej&T7_ zy05BhgwE6lDXYONh`>|k!o~)|R*=o*!RwX}uQmIk_K?XndJ89b3k&7QGRGu~#zaK5*%0}*R+NfT)f0Vx;9&_+h#F*P5yJv*4 zcv}o^AqyL!4|G;~`ABuM8Ia#NB8CTew-HcQ-W4f=-c0QMt#h_X25u|OBCs-ozqD{0 zkSc9lkOR7tM^P$-%2&5v84JIANBek|&C1S--g1EG-1jOAtaH009I#EzklNZl0a{@N zQYs?@{|r*Ho68j7J<@r%NiBu&quX+|`AJb?Z|-idx0jB~wHu)DN0xEjxTj^U$@~r6 z>_n;#gu;V`Sd%-H#OBH=ymE04JV@@4W-|gfdk<#!Vq&ZGSV;Sg{Rh13_6!9FbOr6L zW4oIgXKXjmBg@wizrTq5$|CWIEpG$%#pIA)j89|pbq0xU%ipVdQV}k~jH(J_0xQTk zos!gTGD?1G{|vq3uca`vul#XfMJuEb^UZ6AO%K!HXmni_&}^S^SA%rt;b&ID1)?XG zOGuud;)8}U&9^4;hytbThjLEPG$b);DCKOd;W|YbVr6KUn53@iFKeyxG%Gk{9J%uM z#=;)qcb5ItHq&qT*nAYrPJ+-_T`EFHSPR%9WPY)-%~_Ohaxhlt&tIAfDFh}cv<9-S zx9;@U*w&Bgvg2fOpcJso4t0^S$f)mJnh}h0eyorDP_seii`*ihUTKk*$5+)f*vx?e zWCh!k0~}L3=-m&ox!eC_#&<4}YfHSA1p5`i>{Y|T8s%?~NOx!l+sBx<%Yj35Kgk+cGl!PHw))MV{ z2_jt#jz2-=;?M7iq^!hakG-uC{4Ch_WaOxnk!&&o)TC}smyW_i0j=_ognX4d8EP9A zD{F;|Kfm7hBT~k!W+YzDy0r7|6I`B$NXa6BD0 z=9He+iKOZDv3gUpd6AZ~UQ&vI4^2uk=)w64;wwqizY-U>OG$LSc{)&uK1Gc4j<_n# zuO@C3noeb_X2q1`_!I=&!?C#Qi>$P%kL$@7EP>mK?y0&iPg6hF=HLc9Yq5Xef!hfY zquvc0di{}cdvJ-qDT#j7&9Z}Pi&77rLWn_vX^arYO|yV4>G--mOtr`%A=t{~&O0ZF zJAN`zr@ULc4&azSOp*ND6R=io7>u!WL{n3XP`f22+2m<^NXf^Js3P`PM91e!znIlq z(TbqDbW5FeO!2W%Xn=2hzm8AJKYWa(2UdMpEl1kqoal_A3749XhecT2wP-G2QiEE~ z!-e^0Ik)+R5-D1ZSAw%kNT26aI)hf|#f1tCHpK>8j2qgHIFS7?0u3Aiik(3|aQ?)X z7$Wt_Q8Hm4aJ%%Ruo++-f!ZQSEa+MYF=A_Aj*LnaaGvZ6%{g-H%NApmie>75pr#Ct zC?-^YC&3;YZN+`UADK=B@nZR9rkRHLN`7a2Q0P^`apT?nR)ze89VCVq*Wpq_uYimQ z@+MzcpPoe2VH6&?sQSh@=A;>Q%*=Xza=_KGza?;w>Elr>~#{b#N3QrBHBw>Y_DghXJ&x! z?*4%dgjnVA#y3cl55`>W(qvmMdLGp2RCroFIn}j8)+;@ENCmRV=+)uSaMIc-!CbmQ zDA39j`;le}QcL;U(G?%{ryb%BLSUNzl6P4kR1KlXu=38a)~pl z2gKb$f-Wx(*$+b1ce6f z-(^1OuVBUtHdfLax{!Nyczf6 zodC006wH-~;zzOEZdI|6T{fm<^r;l=$zUnmGV8_)`(3#uE>-&UQyW{G0L1QE?@}39(8+!U@3wY(kW$H_(=^} ztrDH$I2YwQIl-;43D+0IH-5>Y&!|+?-P*e( z6t~K*EChQgN_VW@_?4HTIsE=%tcZPa1yhR7M8M;ZegEIhB@QlbHSVt`b?GF~4L@Ih z#H##`7xgYjf7DFVdIHK@J)|J+k#6YRZphtBMDnuu*#3Yv;p4sk+t zNAWy*saP!T-7;o;)<-XouA6KSi5H*p@Prz(-jC5kH;{%oKimiTIPk_yB+kG5yFz@y z^L|;J?U>Si6c=w4gh@XXdz z8!wZVD6(abQ5w>Q@D*)=_4rfX#$xvHC$EglAVxbpLapN4GPcAR*%jwW;!7xTl?C6D zvCPG_>8o^(p4_VC6Y*$ra17eH2=|46w3v;IIb2i-;$BLGf23@&0YRIw;ww1eSNf#S~!CwUFd9mfT~5O0zR*GNMW{(O(_H{47QJ_FQ5Hf3?TXb=BuHr^@ex%NkX?f7Fn~m&Tl*5mA*UaC zf1kBNxCaA$Ek`)XCh&(cCw$0Uy4h1SQ(B#QJ@IChg;bDB==aHDiV`5N9+`I8EkAgy z*sq|oO59Q1F!jgWF2d)=H1t_&n)PXoZ2}Es(F76oV4RUpP5Q;ca_u3%;A^Bd!bNpC z{{}`Rs>j_S!na@bGxk4-0%msKa>jevmwtlgXrDm|oM0c4!b9_%Jx+K}5`Mm^qVHtL zZ|q~JBDzxZX`Gmh7X5(yF?(yC8X;AYrq5Kn{G(*(e^q&7vWH*Du)dX2BnqerU6& z+FR3m)lV>6-?|hp7mW~>=wQzaf2uHrTwre5-Zu@#*-~lXrgHIW!q;Lz{gkHtj?DVSLC9H|+o+rauBphURs}T^6b$6AJ4wm0dxF9rUTrdcL6CgQVs`K^io@mGW z8uRc`&ouol4DNiwyNkDb z_Fev99MTBS1728+JcQo^$9H1dr{TO0U34&Cppt-);W zhjVmuuTCs(tY9-${Paeg0K856?~^WAFBtF7Ph9M%|fQAf7H5)TucMW?eMt z`5(WVz#d(+83jpZoJA*VBF+XB`kW#j-1hw!|2y#8?Kf>A|6-mcSqS20F zYg`Q=ZvF<8`$fNRPl9`6rrQ+gef!{KUR$uy~2Fm#|L-;%qOb^%XLG_F&AZpj|KX_d; z2XSxa8}pK>x!^)`7;N+y9R#o39+GURKlD&ON>>h+M&C)X`jI=U9$al{S;9X8pUtud zw)z&8`u%t>6^|s)+D3+QnqyDu4$>}8ehG_b{}Ad(P0zm%2o(7_hsf~bnbXjl{05~| zD)N<2GqcLSx(CW-9(-0d+LHH{^b&cE=u=)iIOOC5e|K_IUUol+s$&$^puQHzh;C?o zT+JB3tdwY()TC-?d|fJTooSlRU_3iRuvH$+FmdE9wjp_4W{9~Z+%_flPCy0=pU4FK zIQHJ9KNH}^yEo$QEFCP#@E*h5k~{uT(=)ItEh01``WQ8#C7|J)RT#-SQP;lbT#~9g zu;6@0@d4`7m3C|Khu%I!pr*`oCHACEtAkV0EiOQw)f9-X6u*zoO$)6=4SUXv73dwY zv07fYyl~66ERPFLt3Sw}V&(>rGwoMYZ{br zpGZH7Q>mUSz8Q##gcP z#xkIgPEd3+Al~gVB4Vw2U;UC!ppdXzmJ|l}Ii6nZcm4a>vP7n5O zAS8T1o_`?zfE$DLIov|tvQ7OcxB>SOCP#QCFV^1x!t4l+Hly+^_<-$MR!g?-)N$1KW`DlsCWdwpRYi?$6R0XJyG+oK*t zuJF5^(uea$SU5OgVg4tKEr90<$NyU9Y0o214AsXU;gxmrEkvd^;9$pI2oM($=Eb?Q zrWwA+HLHlG#W9k$qG&=E#Un1*+SOTW!@2)3K7B-AC*_s_L0x~^PSzy5@ggZBEB{T< z`3Ccay_b|LVYoe$-4wzvQ#k&xx&ratbGb5}fy)MdFzu>1Z-I?A2PW?KMCBuhN+o}T zP0ZdEY*x5+bdL?scE4sOcS^cj4U!4BsboB(A3yv(H)EvE=lWf(*tk9K^#!FVO>@_K*Y!c;B&e{;hL$67DY;;CS`S{(Jmnuh~mgA?3P2J47tX z692~+YMbF&=yggU=uzF*1Q!X@!o+)MJE>u@LYvAjZgh4b=)J~`I02fW%=26^t6~dL zyDykZXQE({4s+y*eM~EnBz^web?(8ikmV7{#YvDv%Qz?c>{KoHMyf{qyZ49uplOcp zLheYGvlZfH@N|PsU}#w8#~Dt>b@22f4!)7c7KVSYXKQA9r{>~UA-FHX?paNF6uZjl zi$wvESMRT5{RG1TfEP28a|W>TyaXlRY2@1(^KZfES$?*+rYg1IJLbllAN)Um^93b& zcUTge98H(fa-iW`<_CkYSnxxQNuTR-z5g}wRHoH-=Jj|^iPmD~vthUU=&FG^{|~RQ z57?2sEg5{*iT6r+td~8PUa|P2kEmhH$s4FoboGO}Y_)8-K3|xOcaW8Gd~i5KT9Vqp z4elp8hqOF$^~V(I1q3*V45KS@m8V}UQY>{A@o4Jhf-d-}@pDwX5B%@!9uDb5mMgjs z=uWPGBcF#sI8)1uF6fHbcJxm-)CCcP1IzcHuJ291PvG;UfAtPP{duN8=ac?6P3CR8 zca1$YJ6@C#{uS)i;FQ5f$RZg;(Ehvh}VwrmYY0<%+f^%d>{A4t>gMh^C&+|?*#5%=z`uD zKqkX^y@GuFL4=F*Hi5x0yY!OB?FtAV_S)!xyfITt zrn2X91m$LCd4_4gYytNOsoUs^5FD z=6TJ{NrWST(04?wP}nL)yYOzTlQO7~D`g8K+`mRiSNXI@T2O}RNAgP43%}#TKOiT5 zI@Sv7^0yE%fYb|hy{+v>VYvzX@Sp2DFdEs=+5rgOy{l=dHv^Y4JSc3E)C1Whc z&tn!YPZ+sx4T|uNYouCc=3Hrihb!@xDsL{gBm6eZw{sN?e(!89YTlmY*%XXjyae0{ zlwS14Hg6yBRQFDLPOi^Puqe9Ik9@$)Qv=0BfH(6bNBumq;PGF*mDNZ|ZAN`U5@uOa zmr}>LO(Z=@4|Tk|!E#8Ox&5D z7U6#NyUg4f0_S`tvk62?_1vDR2yCWfPX}4CW*0}Xn}{x z0^4^Hu+5%vdm%Nnd(H^}NM|nnANSu9YSeK15^74QkG6b9LqL-p}1Ov5st6AZW7onjo2V(NW4$nHEt3v;*6Y19bErOk0SULKp+qN7D#C0}jVfkJ<(2D$-u=iuZtPj+Vukl3Jz?v@pTpk(*yy0Sd>< ze9bXm=8fw%{k6%K%-KFMdqpMlQqULVlF@bZUF$9Du5QL4(nBQ96sMlVsE(zu=&U8c zz!&>k$)wgLC#fZSn4c5;445(l4Br>Y(dB*BR-sPGcqvd;Jh$5tEPziAI*ICy@q_n2 zIfkT5|B^i!S5oct!NVH!FXQM;eDAN9{DShmr(z89%u$tpD5Z{Jr$1#c7Tu1Z->D7C zZP&crrt^~$R`Z5gi}e(a@7Z9QQ-@E?4;JFb^aMt`^(ICg;x)9xd-q^M3Uxpqm|>ZX z)vJbOMR424+#^1C4HStB0k zJP_i$VXsjJdJ^|N@n+ysWKzm8#61x$Rb#%)8W_q0(~H^3m6Sd(3$A+v^dAmT?dI_; zafd-*%m#D_&mJBjBKIn$%KicsFO z(4k$LVI|n?FP-xP$5}Kxrgzz)I|`)Y&%4}7rV%`5ekFD-H)5Cz+S70Cg`#eJeWKWb<9nx9AC=aisyOU+%>Exky;`oe(b!kINGtTebet_s+qo7s-L`5uXC}xmUS)zMnWHD56Q> zTb;Mc-#Swg`kY@KEK|KeQswWdx3CfAPF^tA9-yTQS8LpA)#+=4{{+ys^ZAw81lQz% z82Sr4W(1#2;Zjox?WVQl*R{f6R>Z}B&zW!?ShbROmQbr~GWPl<{|1gz!>X5yuC?mn z_hly>32RzR^EZ@N(3YY%@VJ+6tfWw{{=l8Bg}V{v92QSFF>G8|xm0He*trB?0eVIT zPfh-=!+C+-7}mkLF!K{)Fm1Xsup>`rZ^PHYWs`P55EQ{oQi8^{z$&jv-yw~>!hRX6 zM&uqM2zLcLRHbe=qMGKgnga=lDs^AL61DvIALjmLUrKlOw*~_&g;5k?0RM|`7q)5y zpI*Ed?fB!=oRj!{u=udmw8(DXGKnvFqMv$#p?dF&PXT)Nj;{T@zLI(I=-eOm=0_I< z=t86ZACE^6hbv^QD$1ZAq<(>5wSRfrKYz|kN3rbi3eN~`wGd&cPN;WRS_NokvL`h@ zl#A#$8Ve?y@>JWRFO>H@VDqY>kzt{rrdrktiHUT%r5XC+vkobN*KdZ$qvg5w;s!;9 zU|-rpKQ`Vq;8HML=Sowgb%Y$($n3prkWXw*?ktAu7MpbV=0z^wH0fQn5uZ4U`0f z43x((3%U-kGa|+IDFZtlIB@af{^TBMg&_M}4LOo3Y@eox=1>xz*(pZv2)%RnYi(VE zb+RaFj;_vccQ{BG(ROdLicJ zuds@6*ykI>-{1ef@$jv*#aFEsQ61PWsTj;Srre6P+#j0jdH#+}-n`ls8`Fx7DKNF? zM0}KGDaajK(n)-8g?+v{{E~0+3uM)jrAP%XTAv=2-qX~C>v0%#B{wl(B)AEho)Y3u z0kt`StS^y31{xS8{U3Nesx|3iDm%h7BMw-vtdiCx`_ELIVb@X}1H1W@D-v^tQ!lr* z<3u+HQjnjZPq;-PRDmP9yK6gSEFIz@4}F@Q!Pu6WlCcC7+65tkW3RpAh8c3HF{#}} zEpAwUjNnPD#u<7r;EW`{4>G%wa2$D!Via8Cz$Kc!46cRDit^uYJLOv@BH-)*xd(@m zoN{0KE7L-sUe6-^mhudZb6*b3n?MWoXp3UU4^GPyJqNhMR^kmp}Ivwhcn1t5GA_OJg1l>PE1 zcr=N5z#r?JWkKGjg}o@bud^7QfI21kP3kd&UUFjWGY#%FuZ4W7IS=vkS$gE|DNaWT z>mGU+?WJfdy1{SqSNF1V&AI6JO?jTQu;?X;f!(Eo=!^!`yb3@|Rx^#F4o}jx!1wo@ z)(*;j?-z zZa?L7Z#2U4<>ODv{YO2)57)Hph(}oc9X_@3%M8e_VM_45U*1=%?)aH1KLtJHSQm~@ z{u&nOzjjVE|9aW?YUxN1?ws8?}|DtvK~*XJ0yTh@oZWjB-BP^ zLR0!+z`Rk23DTf@1oEECaSUx`WBSgJ`G>sU^@cH8&MJY!zMEohcw?^g8{R%}HpbKY zL52a%u&vSu{n=Og3FRK6jg(X?K>DSG1<$Sbbbnu3^Vf>)0+Hu~IM0xcaie9`N=e1$;XYZ_<84~fSHaBXH-AuH+uv~ASeHsY; z{_0xnkE9={e0%bQ8$ZVt$0(V~8E3^NEpg_;UDCS&mlSYEd6lKXK{!=g$uE$e4t}J&*=W`Y;`6 zr69+=cGvL<@tHq(n@dq7xM>_uBN8+#k|9y#1Q_vy-CAS zq1!j007|nKWFHbh_2O`#J=%Aa2kb!em-EYiTor76b1i~?ubGHCu%1mjDnV>hePzeU z^^LdG56}gS>Y6Q3d78;ZO=_n>_;V+qjInIPEyh}Q5g1VjWcq~aF*{kqFoNkDD|4(; zG7{IH7R%`zpu=a)m82J(F^f*>2c>m~V0zRdg=yP_jHj-WPw9kcN3+<>)4kox9=0cu z@b8~NZ3V=*8AiIDT!RasK-R;((BEyrbNtQr5!ztIDDBcQSXx*N73Bi7t{E!7M+l%O zT&171QvJlS<+W-Ky$yuJw^xNl;n#efv1<+eyV_YBISwOHF>JPXZ`*~N(64Q7(#oCv z4u%y#K5H*C=}eR)wTMptHmHA5;(E_#mRohG*)TSG1c4tNdGYU@6bB!h$Z?v+2(-eT zTAOZh=NVCsp#@_Ljk)9ov$cKS`Rn)?(l29R=k~DMLva@?BR-(2ffscq&=I+VZ}&Wa zesA1&1j4nSZBg^$_Q%NH9$;Sx?7KC|u_LTFP3rbDDmwtJVcn>C&|IoQv*duL5JQQZ z1v?>h6AcU$ZZXFUe5{A$*!xa}!+3mn=vescuQ;+Nk3D9pkZEf}^^l&DhV`m;7ZDSq z2QWJnqaY!9yO%Z_87rk&jZOJzJqy>>ZF)d}Qh55?1)wBrEXXgmCH;?5=0Z_79Q_JHb|Id`AA7#XDnk%mx> z3*N^TrU5b`@fq^gUnGP}9_7aiSe{hK2QIr$vZMPRUJOMvPma4hXFgK_W(GI|q`H@O z9z-91XnA}&f)Ye;UczlCD_rI?-xDO4AOFR~7!AeA8?x^xn5*>4(ra6h4`7A>-MJo@((Uoe9 zhxO<97g=8MF#9OURpa+=`;TYj-?b*4Pp{mh~K%M0H)c-VDfBSST4RbxiV%sQ?}C?hX989Zrk zxpCzL3`WXLQ9oPS&VeVIkH8;R1AR6!{O5GhM!<$W`1bG3l5gWdE9O(pf(KD|qaSCG zz3rukY{Xy0Lja`bZrbIEK_GN%;v$i4ha+Gy#$8HohT+i5TW%(F?1^gvt#fB9$r-bb zyX8<1$;nqvQE)5`n}m6{C@qOWQyVHfK9n7WKidbLd0d)()JVFM*rfukvxzc%v}zZx zrICzrXNMH8CncVZITmZZQ>UjWY5WjN=8?3X#s&Qi3dsUl#e?64NU@f2XEGtGZPtD1 z$##q6Qy?yUJS@Q~Cs@KrJ12YnQ;&>KZ&pZR5eSttE=@A5ADr-7aQE`}2o14Nx5 ze5EjVyO}?$V@bVrbcO`M?Et9EH!(fP9(uiD$7|q7So^i>lcLRm#JCi`H%doSf=L&S z#QF(c7DpwJtTKYZwpDnvX@YH%ZJlj~ZBEs4ytRXIJdHTb(xznD3aLFzTdd}HwYf%3 zQfke--8-5;*J?&l~6 zJ8WN{0)IExe!l0NEc21N+E7MPJ6jWuMi{Xa{#vDdz@~2k?xZe&H*&G{f_rtP>AZh$ zU0raJ=+z#=8lBDFTI4BhRP8cr;dNnb0Bu+U%fe$RbM`Vh|MhYv|Ml>`zwP`7C!>V- z^Uw5E82AwFRiipSKPUu7L8#@ZSl8peZ?wqw$6X&nRJyzb^`I&1zQBT4|`Kt%`! zaZReKCyT6EE%}->8sY(GYf}*~=Q7;mPl6dpBSJx1h-vNxSut#B8wP5)u-0E$()0?l zdjl*iF++s87zh-{sFA$?q<^ji!&*PTq5d2l4d!@xAQNe>&%fRAUf8@~k5ZEpN{o+R zj`G3f$15vGg9#o$q|ipA`T)FT>V6SGG_Pdd%w$gc`}NM~^5Rq=*y=Qs=6!S2cYDrs zAKx^UuTE$61}tVeL*96u{DwOApx>Hix5yvx=6cCHtF#4t;xSHTfWD7TIqxpo_Q{DN(l&8r#Tb*^%Ith?F)DY~;(TK0L zYE$*RO0a^lOZ_Fr!g!t}(0bH3V-`G2h<6$Z;5bY8m0(!7-Wtf_;MtGtSijY@#dbZc zl(UO9O z#HfPQ_GCVOoFc+?P-|DjFtRIt2 zVXB>Jn_BskoXgeD2t00&ZLO3$a=pjab{qF}suYmSBdb;})?t8z7yZ=O2>4f9s8AR< zH&|F7QU!k1@EqkP{voTjt#S{5mVf!x@7nzgr$5tkIXDZ^o;VXsFqb zPhGFp;zEpx&()xBZjKCA(u|>onl>+=F*c^xT%1S^nTHM%`R7U*-?@G=NeT!-9|HxatIUq{R|J7%3FaZD(j=F^`1grg$D=K^!jc$WkR znef%~r-69NCuJJ9f_UDY_>Nqpk4+>SG3CU$QVNpyOuYCTfZ`lPq>^tF@lH&AjsgIG zf`KVS{JMyoD2}A7im2)%#lOo9REdR>cspS=Vwo?|7w3c)KRHC5u3%v)&#@GmXn`}U z{LZm_YZa%j|JenmmHo@*jJRmh4X*>@Xfxt@y(Q{YM|j?~y@0kEacd*^^f~H#@=k>N ztG#2;VOKF`yiDku*?76W-%kJb=k1w4j(e$VF~Rn!BzM<*ti8+s_vMH~*pL@$rQmCP zQBvqR|{?%vQ zq4>Dv2{&c2Vu~{D)Xag$U-c3}`5bIjKexQ4cN z(vWiET+COn|K+B?E%Wi^(GBI3b@I-`<|HFXUwGsZMTsV#hf|0kmB4ks+hpdZj2X6Y zLDk|%->4#?b6NnQGqDL;;_xsbftQ)#{-?>!=PMb`dwQjrug}|=P`+@lzgJxS(24v@ z$>{LNDAmw}P6qS3=32J{TWTqiqWSPT3(`~wEggB-cRjHtn;c?jWjInbEB6c)<)D`iizaCz#oQCCb^^O?-_P7v25?8kYpHkk|y zVFikcsYWEGeN+~w2yWA_QspRS#_5sOw^7^A!dcu0HYHJ8`Ich^1tsS5#dZh1Dr^iQ z90D9&t-1d>R}tg#8`ZlCAOQvERXrJ3zC3Y5oZqrnwrw+_$7_CBR`rjy5zUIV?sF+< z$NufBFk9+MoAdLW)ufI%>t^~YH48}3C=4uS`uf}DHJfu>a z7kSBU4Kyi+SIXgj3VfT6m+y7B`v+8DI@f&)UnvX)g|!Rl=#TmPI2nJyS=D+mN~pB5 zhP6p-;gIQLxw(d5Iz=-E*&C_E&?kyZ)|-n z*sIl}+(v`VpstSQMb0)NlUCH{OEJHLJJ~+9?IiUv2{i06Nue(Es^z1u_S$*6Isxo_ z>GAW=YQCYgy;iP5#&(Nm`m|{CO1(jbs%F!u8Rw-?ch}lyCrQ~a*B*s3m6jIj5b0D- zk;PL)=ZKOO6#g9iIUsHtI!+bOkBTqrN~h+JA_ct#t;Bm^^xML0Me0AFodm`*pXpnK z?nL_M0^1pujH{e{7WQwGmalt@9n&_qk6wyUIHHj{y3nbW8h>k-Y#`wmE8C+>cD6YKbJU^v= zeG2+S9Vb{Wc|^Tftf*? zK@w`rmdowmIc@yoNka04Sb4kM=PT{Gm$y=PL~`A3z70IIxBB-?25{=b0>UQ2x`fAZ zII?KVUdB#3Z_zz>BI6awG4m%i!Q}bc@0B3~BYYbZ-)FVpe{bmz-585+9pn6A)Xb(_ z9?e_k3bu9BGs&KJbCwuCpN5oFx2DIg_&_wevPwnnuu)rH35E!%Ag=EK@@znhWmxQ0 zgP>`$?ZqIr{?MXfA31+^J5+}sf>qIek66$pM5|fK3G>Brb@No&$m@xq@e zs7&){AKMb4n=Bv>MgR&%_fIJ~^ePzb(7)q)UzY7T%&X)7nX}&_YR2OmU`tO@x!PLZ zd<~*ZfVbB)w2bQoSw1}cl^XC8KF&Kqp)$dnCL>M$6{}x7+S|ct1cm-|!Zl2!)TQ%= zo_IRuI@@;gHY&@wikHtrT*tRk8|bv#`Alz%7Yo@7@g?+UXj{BKFpQEw_DihJUBAd`uDb7+U(16b(LV* z^u4xR?{-{PaP$N6HO4xM7!wm0xz4Y2(~=iwrvddfyMvG2 zN^&~mn~B-oeP6Yz*HJl^1#$%q{)*Jb7cBvMpY5pH6^ie?-)>oa{%ap-@i^PO&LaTJ z-|J(-XSU$SmHVv$2tN5gZ_|is^y#vtzmL9;+GnCi=sxIf;lH87lG`SlwuDsCXv?6K z^w4$qW}F|N;e@ti!~a6pR=*sN9i_PbwF0Y;6`n~W@ zs9*5@RXf1Z)s(1->Y;d?xz(j0hVv!;)P7p;5FQ2)y|{g%y`W5>{AFcj(3Vk7Hbytb z*iSlOZ0qQ6RwWi;m!ytOmGKYE6=R9Yu(ksg;`mfn~CDOsfi*CBT8 z$+>W}#F!1!M`4OO`6NAdV*2uu(i6*@HEGDinuoX8*yFaBZ4ymiUYmWCGgHxLP^l!R z5oF&b37Zq(UmISs!Kq&I$8bz{w8 zwvPAyK?>22w1gGg_|M0dgcX)BrKd*Ao{wb$pVpZUUuTQl3(HLX2+I;l-M+WJa9%WsqW?3Yz%EQ@Vp zJN760v-A2Sx3M9uPJ3q0N7w?2CY$t;KXfd5Oxh}X4E^332xDPwY%APz8*-(sxlOrJ zF5LIeu&hG^v`HWPL;QVMQ=h|qq(0!dgCF)sJsu@RB@}Yj_Gw3VioQI?1vMT=q5Ff$ zWglBndTjbJw6nqO`u568Ne^)-TB^tEN%QzTil+L))6+x1#`2WhSuDi?lP5G|77MZU z((-39mpz&DHD`&b!Dd~CkC>|~Xn8hxxlQhwiTS#}9t|Pqw^^h1)uRcL+brL<)I04R z{S5Gl+*j~B^lhx@V2>$v<6?!%Dx@)=++IG<`Dm~#7|?v>JyXgLUDB}Z`u2ZZJv+~n zkQi}6oG)wM&E7;;_O{XPF*}A`R(JaXWyIAtEgCcR#_hciTpYM;cSS~Wj#VwyLbunC zsqUZLvn(a#+$+b-U$=|@M+b0&gBTAXm?^U02R&o$%t4iQzeDyrSXLN|u|OCw*`{ht z2@AE85@uJlFgs>#4}YY^8f~#yt+Ha#!mQ-7Gy5a#4y@2Z*$%&5Wtz>ZX;xJU3sW9p z!!aMNY@R>VW^>4Fhy0K%$!+X=e>^J{)7Qc3z$uS7WQXRrFiS#sr#ZU3MD%G1CMb-5 zck;DdX>p#h(s7N;&*@-@olWJ{4$Ir?y*L_u*U|e zF|o17J@Rf_llO?%L0;x?Mnp!%#Ku{pp;5@ZStHyYs1l0XlbF;)w!|wcTz9m(-JYmJ z;A-)5lppQSJ|yWwj|V#JAvTzj*wFnAmL@(+*teJ^Ugr1Kc_lBV-wy|zQj>>ycp`qA z+wW|0O3sATL+mE@nP}ak(;=>t)$vk8iWm zJ}3Yl2~I8b9_8fh;Jsk+SQI`tG_8|5YEBExiVP-SIJ$j7EwkOee#({OR$h3~(q7)g zjJ)bmtDCoPTJk7U)RB7*WNhEqw)j9pM!yLKJ+hsiKF#Ycetkf$MRH)=*P!Q`G4A83 zC(9Onm$llqCgl9^%WZG_KJ#gs%r22HQZ9;JAE%U9dupoeP3W1R$?h3gCV-C}aHq5M zbO+Sf&8_jIa+R#rVQ1(HKkre0WN0E~`LiT{R$W$8){!hFE5Ya`cu|xy${m#-<&WAL z)f8okO2|B^m>q}Ge$>>=1lxirLZeJSwgQdLPPY8MP%TN5M1zBu<@E5`B9nWh^pLa& zpFQ1Y^MYGBlV*`89Hz98^jWM&qnhT%aSOYkg{eI+$p)4`VUHLQA@qUernIegv*woOyYW4M4!mCzJ&}c>5l$^;F7mpdEY&Y)3#o>>4o`gU)VJB zvFn-RKZ{Si5IMA}aQKv~H(ruHMP1;tkGcDqt7jhx?73#ov{sgUfDLP}IZ?4;Lfr@D zdH3G3_eVFMVjS?MkI zmUP69E?}XI?0&l}sS5P)8~ll~6fMh=BHLB}&?5Cirh#Z5GEAa2cI$zrP!^gHrXG?$ zC0Y8!A4ZB(@hfAMCPh^qmHtj)WgH7AFCX`ivd;FlJS!CW_!spc2oPN<@pl} zlhu*wKR%{BmDH;aD_UBM(c6g8n?UJQ$nF*6_Yl?(wnA57R>so8i&7gx8^RhA8tCQ&SSc(qLlF;W zoLJ9jYAz>H_T(}f++{C5%qmq{)uWoke*OxyHmXXAYPAoYCQLMbg8GVU(dnX_zn{@2l6;sN6Qo z2QBqc!I={$1WWqKMYSb1&RBV7a5rCHbJFlB6s2)uihp+XUDIE<|K2~e5d(| z`pFlv-WT}S%$wIx)VuG5v749FU!Fcx+IwZw)9ZGNNv zk}(U|0cKbzBh7~UY?;D31wHu=+jxw0BelEN?<8AfL)VDK~1Hd{05yWq?1s_MbBm>rCB4w(w)8@>E3jg z-7|}l9ej~$g~=V7f|Y6n9;r58XI99&R7kF*W{a=Q^8NmLizS>4UP$)v6f9g@>ciDj zcwrph$?9jwr+%g~CxI(6-k(N?3YJ)Z`H@#M?_9U#g?Sf0ec$=lzxVWAk4c4*5m`9lpGVafe46gN! zSlyWWb6AsvMQRioN*1mMMHEKxT@lu4S0t+Q4vB~FivT%!W#yd80b{GASJ{cEa>GQHHOGlh*v2K7wZV60{}LaCWB~&WS08bDVH)i4nwq zvoorX-4Tk!iyb2zRnFllV?4EvDb7jJH7Sc6^PLM));JrK4dIQB4bBabSEp=r-R`*E zd27V&DF+<~oxe{!nDV^iIp?2}pG*0x<1Obu9G^NrP5Hs`ALkFrKcwW?9MwsZ3(^IR zM9C>BJ#672Nw(M?aY?aO$&zG^iHJ^$xgf>ibURae^hk|xMn^1*U=dD7czB!itUp3Z ziI$`kSMp9Gqv6`vet+2iVeCx++oZzxyZj_D*2oEe-Jg9s2JYZ$?7xIF_Q;!O7*yMY7u4BGQz zb`P|5vmzl(17YgFZ}$i{KHtrD!~Yl<&i@$B*x-P4JmLt4d4~+SY+APt%Q7?zSigtD zPLCtQKAuC4x~#ty&3@L2Eo4NXDvL#>S1q@-x3z;JFx(;7foUPBM`!+gQMBtL^$i;W z#l_&Y7JxPIpC3o7YPzWFYA@#Wr>TwoIkhp636U-bTcw_RXLBeEwZ;^FSvT)Pk*j1SPP+cqAPt&BtqSd^BAy^S(^l@Ar}UG@`Nzh>8)*be8e%JhU4>Qtc_B!y`+UI{cE>{ zfH|Ut$j}BlD|h5t&>O0NnjIWPzcSN8HNP$4 z-Shx7>AMkik4DJfF~nkio-65(i(h_q7WB1DlwceZR-T z(Q{yfKuYN_5iQr)caIK7qr5L$W8XVG?8{)CVrm(OzK{) z+>r2xQ|pT4>aSgT?}MM3xgoKw^7*^Zf9|R6eOHej{r1M^_ATBlk&}`0F1qETPi{!G z#m1=NPpi3v7(agPWnXcyZ1uD2u6@M!{toG(>v})mPn#glUp@P4lLP9FcmtE1$43eP zMR^MHy^i}M4>=xk9djIaS-1#%0BD@u;JwcGPt@(cFH`ph4^mH4yp^)kWOyYtK$!}h z;EYQU(wmNw5&%yTHEPW<Z>F8Q+h>8IyP#eQrsEnmz_KJ@S6|AZlBR=WM_tS;Dsp_Xz(fn05*~J$r=v z-1mEbApIcxQ-KqmE>Ac@v0ktzcw2-_bBrtz(AbeBn;P@00Xc2A+sHuL=OegKcdrW= za8YyVE|aS^`>SJU>|Lv3NG2?AL-mT;kx7WY@ zANAjS`==iXf#tvt0$^zv@>mnpYm;!sieLiIS5+@x9=bO4CGAo1p!T$Os?2Q+j4&hY zZf-X}&WyABxP3eym!+^8O~_JKjd3~}P)@bmWnSV~G!-i9VO5fp8Ho)E5(#1ugN2L4 z!`VF1EFcFi`5#c_<+6|_9}Y`zg+gJDKge;+!7B3V60E@XvJ|}6n|dF<*UtRGTvl!_ zz)OdN2Nj6wUY96oeP4M58h=!o5b#tBcvb~G)j~88$5S20opC(X@drz%o&HxjRaa<>d(zju|Bj|* z6@M_^uhCvd%3Ewrf7C?IycNq|T~A*cilys4TT*_du=vLM!GvGXFQrC56Gp*@N71D|fX{8xlhf#dGPy-RYJ+Zxwr+M?C0(D>ZsqBl{SE>KVzD>VvexH8d%#WBx znB9lewM(oi@7}H1?cZM;IgdfcRH*s(VN`r2kO!Eeg&I!LCJVzGT*u=JGwm}y& zb9+b}qsY~qm2_(+lQfx<9Oq90D6Id4h{K;Wh$ET65rQP?@r#%&{G1Wn`!HExnm_~q zNg_|iVooEMrRZItw&$n;z7HPy>xN!iA^}p%mj2adR&rX)%u`x_QnZ<6NVwD=ZL#38 zkA57Iz&mSp)XTlA6ZMUks{xmoNVF)|Q^Q8P{_?hgG@AXDP#Zr6wQ&hNge674nO>eJ z1F2w|6ht9FDs6h(P}_Cfh&U3su4zJ?2pkd*1uV^lot8ZoN^Hvq``Sj@?xg>PKGjBB zsaq{mZPZE*&a(LDs0-0Rtc3OR5v-rV5s13i=u282$oWMv%A|9YJsssiR*qQFJVx-8 zMHnL^@)(Yt}`(Xf(Gjs3_i;#EPOu{!O=-yZe&Bk(84p1fHjL z0o^7kp!buj%G+;m%sdqQP#zSrc;Yb)yn&5mH0Q#cCU0nil9FWwE|E@UQcWp}u|nYI zP@P>skp(B4H8&Hs7~BYoy^G*eOf#?~?9B}~1G1uUFdVD+ERrPvK|M(~x3uI)GMe-G zgODb4e%SAi=1NqKfy!cXI7db880$qBs(c)=SfKSGEhxw^GSt2kVYagBMR9Yl6M{XA z0iZBB=SXj---g7~zw6uenLVTT{&{@Oojr2Tg`_QTe%N!>slD}UU%G$eWry$i(du10 zI^1rFf_R|+zy;Tw_?JICSD(5knEh9~H5)a?dQOaW2M z!_nI8TRLXqC_XV7>=CH{BEs;MgRcU7}Eow9>OCdE{ zlBK*FT_#J5)hH=TW;N!PB}t7zHQB7j%CfXbjloff#pBZAMT;yJGnsF04uvGn<&Khi z6uceq!EL=QwyMo&eVXpL0#ps-?S#ncK)SpiloOGL|krJ)j8dT{wAzZA3Ugfn9( zg;5wC!vYE?GdApU_|FhebG8Kb?f__FAFV=Iyto?@)v@7lu0TmaEOX*W7U{NO`0dP# zNi*5ZNgPpyf0(eK#SQ;sOM70(U`m3d^kFHa{_k?BaS3>s+zACzR@2C(SSLY=l+(1C zXSDUnz|8IVt(KXm8?p+%LoS1J0MYi(z|B_}63Q?1Y(IO?yto2iu3x%9cwM>RG)Q|z zf*`Mhv?mj9V%fDr#i&Ka#HZ@%azMSrxxI~(B~p!wvgA^u0a*fSjF%;+8gn_J`r*U? ziRdoCAvz1t=+Z!xAK}KiQyewR0gdb9hB#^)H^rUgD2_&_ahQg=+U(yZ(Y3Hq*TWbv zU80Pr? zoYNXOv+REv`?=X7ulvyO!hy%bp7?<9NA0s;z-@#TXMasO;V8y{3y)&gG8fq9-sT~< z`$zn@Sik9*N|;(GKb6;IU2 zmLuw^uOch|jX@0b21g;HZ;a#g^x$Z<+lUO$;dvn_nXN%oFWirav z7?mbH9$&n^JhNXFhiSxBqFdyConuZEZWRpL%d^?4wY6z5>U73Hf_G_O%=A-?o#`YS>L& zL*8KDsqHFX-}bEeDI50*0=Vd9c}UJ}}h?FI0z2df6~fX2$Y;>vdVnK)^mq|*gt`v!c*~|-ggS;%Gc)|)Z z-I88mY^=l}ZWB#QCI?0mvMi<4SXZf2>H-82wc9+|7+LJ8JvOZtnpxE8jl}@J?b#_7kcQ7UT z{S0GDktVMDZrZMC1$x{BMohp|BRh1fZtJs=<2G=}1~DG_cRg2dV9e>jn#qCnl_LrP z45HcwfWh)1^5D{C&wy_1o(jylr{=&Xgq>q3^#~_6yfK%{jqDO({-1FGM`*AB#|i~M zP}6?63}B8Du>|wC8XjI}BTClrq_%@I zH~j0SnHxHb?s7ec`7J;5?FI7hynG=ii=JyhX0g=NDuX}eR$j5zca%I`cib=ljj5C< zCQIPQ^)(;B$5GKxG5YrUCGKG$Y)wb}F^IQ))#aWiAuM%tU~-6^Qa;G?aKYiqso(t6+~;`F1={q-nN0fC_+N5L#a_;yX0IHHOrEq#uQm0G(smR z;j0w$*d(D{8%nz!U49*)jhDlMWH#7=Qn;A-u5 zVy}3Mc0ch&?NQ?E+JV+XtuOh1AWpUZ(*LS>vUS@3JMnjcQ?2h2|M34+ORNN|{L2el zz<_^a;p6`60xya$XfKN|YrheHquCA5xgtwJHJZm#3!+3$jTydl6-z8+>JY#~hyelw zL=lOr#ah9miGHmh7C-@hcYiPt@RK~p5rn3t(ww#xVw*rAA5|3ffO<$pIO3Gbs1NF` zpcRnl7B<15IGo4}-hu%JoPC5F*CEdbYCvsRs6!HH2onQ7qWI~#1RuB;aYLL(lMtPZ zLWzMBd!&Nku~vbx5h|kStcZfELU3ZmUz5DOF^@R0-; z2pM)xfMgPxxqwf4KH!tB&PfCn3xN-c0A$$!umIyMcpFg5XU<58KCPbCHpYD(`2NCX{x4{Jc=q;lZ`}U= z9R!&D&Ft@>J-n7kfxlv^Tywh%xb^`+>b>QCByfdEkRqGi9q#Mg_mQuYvn1<|MqL83 z45BKs45AdGh?oaaM9k%K0%-5Kq8^tk3Z=nUbw}zTF!MYhr6A|xDLj)_*LtT@5i~&; zC;n z>LpgYwh>!gJBW|Fu6KP2JPMu$M_oSx{{XH(kO0}e1H@<+j6!01k|1XvITCSINfaQ0 zdIuWtZykf=sD~=3dAPBY@a|Zk0+BgtzM?x^6_?LdAq6jd1uD>FeC4pE0&jED*!}IO zr$Xw^Iqh^V(1Pd@Q=^-dc!G5CDJ#!mbj_2Z6vFaOI)|=Xu}y>sk%E+1`T)3&eV8<{ zQ%(XS)FMP?;1xuG@w1I!$6)}Cc4`y73}zn5Nm_FLzu?eS$fH~d!E z|8kw_O2SG=#J^*TYx$z<5%y8@qXK;`*v0Mvx3TmR&Xy)9Z<^u7ZkZ}jBtZ!jDnZaG z6SXRgs3KS`D`7oMhMnC4ukfUUmwA$36>0=9kjs0WFq(bO@O{r!0<;1NW&8(|?xfx7 zY$hZiHUkd}TRszP31(X}2#|2&;=Ij-pY}Er3x_!S87MHMCkPv~GAD-#it*x@6vLlO z_lJtnDG(~!w&Ox9Cr^*$OAopC{OOsPvuYMseBG#6%Vj7 z2Ux{}sKbtVxZ%^p8s7e3bG`adShOW2_ z41nSs@r*wtCeq1_KUoCv5Zt5!O+}E9V#NhxqD%nn+aj_? zQq&k2Lrk8Po(RWk?C*{ahr^t=smA{C@UYi|S=>q;|EL!{x6AkqMTJofJszxaO3SWo%F@D*QNd2@fUkG!FN&A1GaMu&Vg zHH=zo4qyNEllB#6^H;_8NWI8K>T6wHS+86$D5yRentC3^K7%tMfgCFbfqC(v~=b>waelkE0~)&G86({ zS#qdRB9WE|Xkpu-ZH>H7F`djM;_)a6JR}L?2T6rwn=%jMaEu>)T~=WG*ddmhzzM;G zbTCw^fzRoV)^s==A{}-+H2gRhPHx$3B)2Thoe+^x{r0rbX|AB1oLS7oz^4hsey78-QefFGzr6`C?* zg)Fjb0zqMV&V~W5N>FSVEm>SuVU(_hnp+|q#=Z?g~+tkAz)H=7^K{aBYK9576BL)V6y%HB5M|zJ)rem{w!;{ zqJD3^TvTikA(UKO#srR`H2D21C-yz`O&|{4zT@m7cZh%Ph5a{mUP@k10#M)iK{BsC zdd-csWc`L)H(SXsfJZ*Nd%qjv>+#uN(`Gmod;a^P$8OwP7@hZwioo0 zytA_gmg^_mI@*GiL~j$f1-1pZNsP&6vJ*{Ho%Gd~t8G`?cREHQBl1XLMBB^VYT0Ak zW53z4C;JHfNKtUvinfxi94>}S;W7&4H`7W)ku#a*;$pCvtkPOQi)gZ@E-Ec5ue7af z>bGpPZ4x$SHfF;zkV&a1m!-CTu|Los9B93$cv0!1@0OdK~;1kYG1xWCG~6@&hd)DZE3L zB9W)UsHYToz|#b&)oS-xt@f<7$xbJEyklZu23jQP7AlrT83I6$L`wk3DA5JPbfMsU z)=9qZ1d8)<=j%?&StIuxmk&m=0;*(!C&>Hr;Mx2i^0QE^>nqB7{>SiuBJxUJgTkK9 zKLeH%6|fv9svw0tm>q?xcK9_vNcFc`L`Q|z9F?Nxz<_H&(%t29OCZofk}Z*lr=^1m z^DPWi0h7Zmlm}{sKP<>#sQ&k0C<bE0gBUjd_h;kMq(s_J96A$^p56Y}3UMSsX&h z0z@$HbZ!A#$SvV5kt@NKxPmEOU7*UU@8Y`KaF~XCp{f+tC$7M2KvQ z9Ei}7r^qznn|)WeAc^e5ve*ajeni*Hrz2X5)n9Atg&Z~4$GuXaAL_PoWskgnC4tSDrrP5 z7f3zqwP9m!`YVp4#Vudn|11Q@g_-Xlr2NpfbZIr46ijRD&-KSU+uuJkhl**d-93B} zSPW;tGJDGO1e}39IA|a{4Vn#2g_4HzH{*D(_xnPnG}FnfWp+8}L@beNjkTth#g?TW zPO+I(B}MjWS6gmyJdk=e^|vI`Z8x0PvMdGEXcKl}yOFyw290v4U&%z;#y3G5>yMLY zgkj@NY=Geg8tn|Sv;>~#bZdpvA>igTj^vPE+v)Kjor(1)gT2?tXfr|u_?s@RmIV!r zXa}@I+9{3JWCc&Wf+t?V6R$*FuHA01!wuY6=eq6aJ$D4X=MEIk%-e5+b3PtaKY}f| z?BKlP2iKA`LXZ&ft+`;=6YU%n6iGF0cA^?Ml5r$biMU;9CIn~FnrQ|WvnnK-iL@nw z@IAm{!N^ntgOKxyQ6wOwqqIa&q95ZrAdIt$*~h%!@R`2EPBlu@xmgo-ea$=R;lwdM!noE1r zJ`;rBs-_O9Csk9!*&ZV7s$%v9eN8^f$J)>%N_Ge_SWdPhKYMjhn0eua7m)iHd)X!3 zLzsX>IJ|=7uygQa*&mVQ+Uy?P>0=p%V_AszJP@du7zUAg+2=cC9z?s1}1|f|! zJW!~52I(}o7jff%PbxNw%;x_vW*f|cF{Fxkv*@ZgbXSE&{sN)GaqbEP#;+W6SIlWQ z>V4%2M`g}Z9YA$y$9=320hHZ_Nf-_ii)a^68#ywU}(WxFZh+fL`caX0n>rCTwcUN8kT6{kbh3Ic7>E_k7`%6?B(eW zX*jY&{$w-#QTC(U6+E?uUn{RnuPM+2(x$=%8r8@4aa$}D%@Sq^5ktO0Qz#?1uocT( z7%EJ-x;iC|578E}1|!nv9fNzd`25XbZ85X6j;2uCoG zS=>R7#f&1USD zlR~f~R0wli6nT8LLJPyP=$(+(0uNizj4bZejWq?NLM zqqD0-p#>( ztk6Ax9m~ca)F#Nq0QnLzu_vAO*{Tt=Q8c)bMVF;YG(t>+5L|lr5N3o5$yxX&XR-sB zTwd%%Mibd^A{Wm^mAugg2RE45&^wrm-6<4O!eOQP&IW78%IuBh^CF&X{nm8-NA(l& z`X`#Lo@HI&J+a)81D0Q>6=?gq0|9r26yhDFW9)Bz26knNyJuwbolj~0G-ppBedQ(y)1wIC81auu69HTp zD?Cyy>)OTQ#eqJJ&iQZf?@I1U-QnMxVgjZBLlT;o^`;fAPcxZJ@M+Utl2!=?#MyKz zo=)U7Z8^}j3&3V}OJsApPrHh_ioGg*Rnv$z4#t_A*_+ejP2<}BriZ{ocTk*9q%dNo4Q|G(V9^a#LpMklxGHnu(uL7d zyls@*b|yPhM!7AHg&@NRjDalnESP3b>2^q^AdRRLZA9d(pV?H6{}pA020%*{+8WL>}W zyuxZvl3W@o^ezGtFn5RB+8~MMH(oL`Q$IKdvq2BpvAs2BP9$=<_{H@#;HwwsL%9I1 z%_nFS{cwT;rb(9$(I}dYkGO-S4o8Qu)U?`hE4|ltoJX}zd;*+LECc78x6>bChul}w zW9*3gR{AD(-2Eu=sQF>rvqTL%Yp&Tm4gu1tiJ};%i9zWIQQqu7s{eK6JzPA{S3_n3+}4B*G;*dt%?AIySRYMy-U4v5c@;dL5u;x@SB5p zp_O$w%Xg+*c(bt}lCfNX5zsJt=1m=tMQ~!05UeQ7jeJJt+U(z+FydMR(s7f?DF~d? zf=yZ{$pO6Fli|%=xS9u0Q4&6-mVp{IOrHnN-a_Wa_m)-t{X^7c_49`>DSDG3)7tl$ zk#92f`xErbg@NnAdgPT{H9Jl1r5-0*iAB^M3u@_WF{55}QwO77OxKqTU2y zEusjI#pNP56n*Fvc>F7Dyc7|Oc@bk3@wvqci}!3Zc10^Zyd+;FB6KFFm8?1sZ)(-U zVYGF^x2(00VSntCmpeO~zK36$U@={qc;+l!=YeH(Boa%H^w2!G5>xw5Vsi5rWz5_eecC^KP~ zuT!XwS7|=9*0h#crYwuD?bNG#!<^a9DnxV@SYuvgSyf)szNB;2qD_{|Ew}JDn{T!_ z`h7R~NV&SLN)B;FqST$wG?$)+3fxLqXQz(w6>Hj3vEoQcXIX&SkwhwT$Vw@Ax6?{n zyG0ak%2+DB;x=)INEO80A}M|v3N!S?TDRU!!p9y#3zjsO;kebP<+_u$OI0MXv;?v-AB2FaGC)z7SLQae)CK9xsIGrHJ6Cfd=lM+vpO9+j^FRsiLjQBK>aq+L<&3dKzB_Kvm=lHoZsM>1+u ziIPm&Qc(zJ*c~EVZij3OfoQDDR0$CsTuA}tlEoDgLckt{n@*-XL|{KKawjz`$fhP# z>;&Z}l%rsDj2K+9`Eb<*&>|680<&EUe9}D1H4*Ucn7z`jz-Kq)se&s1EtZO?SSo(_ z3L$C_S|Gl+RNB*MZ-#p_-1BhHpNjy_{S6Q(Gg1`kh_zH>-#R*MwQ3OowkC(+d}eB# zZE{$%(A_nTKRirZ8cwQn>DegZZf;qM_O`Zm!(+>M{ho76RiLaDFV5gcIsIP4|I4tA z+HP{iKgHV?ZMz|o`O&+Z)>jirvXD#^4(-4G{H~D8>~{!OZ}-S$EuG+tx!$E4JJ#O( z31{H5A79e4^tz4ly_ZF!xz2oRsd?i>Mm{flOZ^8ob$M7@cgMX;?*@b2f!t7Kveft;m^yM1>U*D(b=wBq^-ud>cC7 zY8CwiP4aGJkT^X$4^Q)W2`Rx_)B$KbBR^&JwXET&#GL+Gc1m~=vOQXE)4<>mDi9RB z1-uSjgRYI3Ovwa+YO9zHB8li9eVxBeqGQb;K@p&hVwe2K* zmyiTsV~#OL+26^uDY?Wp*rp_}p?1=@QhVsHQ{Uv+6)foFJSkg`JK|X?`mF>l`3Pv> zpZg{)vT4FZ4w=SHkDDmdJ60b-h;ge`u=UwSY!fzm9BvNTD8eS#6q^Q{Q?`>f)&}Lr z@$Ry1DDm8yMqL=n9625zA$s80}5qflL{44K+r6Ph=6FZhB$a6 z)2adj7AZu88A)jrsW&_~pZN@A8Js&lHZUL^@e-t3$WK-Vn~{L{aG^^R}$J-pGOh@mDsa5on}QQ7+CFK;iG)8uldc%AgP%nMu$5vbFgAXAgZ#@<42`9MaipsH0Reir1&(XfUUx$lwPGu&}0K zdGBg2P?ovaYJZZ zY)Bjm?G(pCx4Z6gPdF#UuY<3VkH?OH?||>I-wV9Wy%GAIat4SDx!SeKb%%V1G9Eh} zW1R|kX7&`Jz?Tfg5)melnAaff45{NPNvMLV;MCp`bz(tg&S}-AUKW1c0UY1+C3rTB zk`z1@w9`9W75I=A^(EN~dae7cq_rU6tgj(rgqR=>5mUq|f=3-B@z_h3T=Ynnm+>FDSH9e4=@RFr`2Fo=Fcc!58jrNT8Xba9TP?;lw%5yjTI6)+l$`(eolg(bB*@ybpA{1yO{d;Ya0 z*A;PEVzI^B7hUj`y&pNhy#y{g`dz@h{tB?~TbC>(y*uT|>W_ToYws_~??QNK>FgV{ z3CcW~XeP%N;H6{%XMkrI5tATikRv8dLJ9k@2=rML?6O7Fr(l<@g3pG%f71)8mE5 z3sVJFFN_yRqTp-tW;d8NaQ)ePS#~80ltR0Cg?Xd-KKdI?2MX*|;dGW%6hcv-g1ljY znt55b(yLsoTxK3tu2=RG`<2JoC)pR9EJ@Ctvi7(l?xo&v%GVQ$gqOnR3cp6)vjg>_Gg0k{M7C z89552qaH%G@QE7xHm2}gjWf+tI9|Xr(Z~gNK?G2q7q~CyHt{Xr27tlJV8| zp8DH&clAQC8_e2(v)Q5gq-IO~be`$Hw6J;E)wWh{N)f9)$P zLeALe55Ox+M=HHneE)|(LzItJNm@@GB0NNxnp{BnY0d{VtrZo=6L!37RKs~Sod77! zlq3iNZs34o35*)L6J?qaghfg?SyZ1%qSS&(bTx}*Haw4|YqKxoD`4Y?#}U`iEfxzF zHwgXX>M0bI7{ufcfk5HJ)I1Cbd&h|bP{>hpnXdRt7@ug=mBtaN3#`H(Vkv?hV$tGe zH2Zn_tMp--LLbG#M?)N&L}c&r$PxIQs0p7IvIlxvxPx{%?6TYC$Opkg_QXkq9|oTv z9E8?3UQGtF2X>*lwuys*A!5k$GGz)VAqX);6`vle$apb=C96xEj1-TINiki*-Rqn3 zC5Z{}o81@tw)wY+TZ1g1c!uRUtI4~H*-PHZ?6KZ1+!B6>{HA!+{ZsN)$Ipc`Nb8kxq|PN`^kR(Bjgyl*S$Azzx!+a z*UUBUD1XTOJ@U8YDeD=thdapvf<4KSqiB!D4kdsbVj1>E+CykQFZ!x(SH-o>yW6|p z`?{C*dZqtB>nhBiglY+S%nutba($(%g2wnF37{EaU*ddesp9Z~9lqVZeLl)}#^V`B zMKBW_sd4+b*EveybPhfVcZfU1G2CNzFHP)4bVcQKmu5#Rj8KGKuq$@zv>n*dH{sz} z+LuI@G%yo1U)IfxBEU3?65ywyje-}e8ABwM9fJx4*$F$m&`!vrW!%pULWPDGH6}Vb zQ0?WC&65lPNOE)l8#XvBFor!eEc`S}tYX!hD>nGzkRD4T_YB%0S#nr1jwIu~#*x`L zG8;!cKGN-c#VZ6V0mWIdDLB0lWIteG3?Ny-vKFV8sIk8}I_&jYoD#0xcd`~5uli+~ z*Nbx|g`4p=>h%o`=|UPZp(c&6_s_xh?R&P|(ky#_c;CbC{PEZWFV5@%kC=qOrETkP zBD-F?`sz!s^X&aK0I$9S*dIOCxjEjUe+I2&vZ%hC`UOO1UBoJ4fSNH@e0BNyzL>nf zjUt+bt>n(8o$E=WiODk;-l5Rd_TH^K+OJ8DY(=Yk-Q>Sn+*iJR@lDJ2t+}=L9{)Y! z{k=8%Nz*=jhQ1KRpvZqbnYWfDZx~(b^KB`S!EfIkwF0@FE z4HaDQZnuZ$ppolJAb*4l%8mqLB9FC-_PWJosqRlao_IDvC2HWoqnoqiDhj&&O1GhN zUHjF?)n`>oZCr!*@DdfCtBVt>!D_UE>}nl$tKNl0Zw=C;J|JUHk>FNTW0QG z0+!UM7Tp?HZ7u{rUtl~y2EIl9JHZe z_QbX^v27cZOl;e>F|lpiwyn44d(L_H{_uJ4{?U6?S65e8)#|RjcdxEm6>n^X0$6B% zYtXe(vrg*M-SF1gO}hCkNF%}%VZw>3Rr{qkKGV@z6A(KfR_}I-*V}{DH5Xg9q?>}Z z^Vux6hqI8i%?vz_zOO%yv}t z*WKGzi*e+Dx=C|l9on{bhqrmD?S)tp+L{?7>&t|}iJ$K8J7!me^~ZJ_12^Ak zD+AT22!cCO8vNqk*@V#MNG%SJlOy)Vrci@j?oY)Qktl8H%N6&J-|3S$Z9ZQ~cauIv ze>igoFs^jeZ(qzxprLS3{d|KS`Egzy#9C~_{qDz91u4$^c6uYS+-WXaEgI1P+^s=+CAkBZmd)86o- zvmJc0gg_j6O39_&@vjE+D%_zFNszB;j_{^AU?V<&Ju=%@r$UWk^`l9OtzWI7WXM3u z@~u^I(ydvx%|3a6J@) zcfmifL4B!e-wd67$dY7Ub5ksF4`G$T6SZk+b7^Lqf?sWXw2l61B9GTs%)reS;yGiG z;*l$4OP$UYM40D5iaT->6$<|HfqD#=){tjDM!^5p&ZJx`t4A^;h2ME29oN-P|8%A z#c$-x^*?&^>(FsGg%*WLwx4W=rdQf!GUfzpZgk_}4!K!}GUy2g+Di%V*0#zoV=1UG!gGEOK6&!3xatQV#Y#2IrGKuhD_jMjAMAI)ktj#8?1@jR0-01`+R}^;=_<< zv<++d+8$t&dF$Uz26(z4I9Iz;dV9&w$XMFF`BFyyBL#>mnsYxK7z>$sPqx7F7`#DV z;sTQ8SVGv-GfB42!>8?d9;XDl!T8Z9#2P!S#_)rPRi++|De9t^3BC~wGeL7>PAP(% zbEX#hYyBv^FCacC1ilv^hj5Ltg%+0_9DTLuu37{0uc^C^$9q$#!O*I5Wyk8zsistV zsn{Y2P}ZAfa}m#_2weN~U5>Il7wDb~wir!Pp=PR#?G0lih(|Rzy^c=-$#~m8F{pT5 zTvO|DrqH&E3)CE}7qD|&hQ00>|d2fJzf zU>*XBLSR~zQev&Ni$15(3b8L5XcK!RM>ZdQSRA%-6|wPo8r>kinSm!aD2tU}Qj?ng zHw1UjnNkTX#CP`yzFS`5kQdI3xa>YEchdA3xLdOqXf1{mj9*Gc@g}|uv4aEwu<^x2 z8WPCH;>A^L5vr@Jp+?;ntOjE9zIc0;Y~#@LzC8LS*9Z(oID{tTT&%3D1f&+*0T{Ws zqJSspY5KB;R8Ix@#6QI`NPwQdY(DYt0*rfK$%a5D>09t)o_ z;mY9Jr;mN-iZxHgJ>oO;jrEwhVS8yZTz!GW`01=VP_~|{Of!aOcxZ{MIT%70Q0icY2a3M+WrbK5H0_ zzNipwlSL(*6Obr74&rKxlOSTMhR~ExKmJrDV-C^mI*>ECnCNk7LgU8X zXqz0G^D4zVO8DTYSo2@3pjPjomO);fvy9Q@3>AWIr(nwFNB(;9ekV9!kc63Z&6-fd zJ>rB2xr)>lfLvx+M1{%~v?|9`Vyj8W;JqNm%385J(1d7M21;--_(0;yO>}L*nZ$S| z0*DhAU^~@*t`CiQ4`ks3`YQ^%feOFubAdHkh`N0Kg zh;=9t-HCjmFq%?dZ}qtOVkz!~@Dj2AT!y?p$Qdv){0MSLCTiu;#S~H*9d2gkXw?e@ zGaI zFW_hu;hI~H3VCs^_cvXAJY=0!KWK?!cui{b21ixg!6>B z+_yr+B~KR%soKwhHv!8YqdaI}A2J)ab=^nXPWJhm!`xo1;c6{bNA^ z*OJW}CJYU}@|(<`nN^ufM+K9F^bd_Dv{Zh*$wdJP(kU2vx*AtSn}}s@4tan7aj+f` z*j6AD=3gpkuZj>r_1Fdo?65#4jj!GW4C-YZI{pPSH{ZSzz8bP`Nk~<+bp$;->St9z zKKq(3ti645-rnAYK9RlxzJR!68%>DMPbr6mQS8P|@j`dX3*Kg2>`b8v_kHD*Ta2aej%Lv%CpFQBFzNIUen ztx$@M7X3=LVj&im1v3NIjM-ol-Lc*JI@*h|qe%^3*F}eR2*e+j?o(m-UOEWmx%kq8 zJeEAibBmMO%`UR0m6>h8R_{UxIgU$dGuDeHHwWro?oD{6Lb*{c?f05oqXxYTOcz8> zdoEVX`ATaN@4Pw=B^#kvJN-{~dGjcH_+g77(7dMWLgu|leXHkF&M-ezh;Xj51Lwo@ zLOS_#omV7DArjC&aGacE^+As}Y7F}>;pT%P$HUMWW9w@+IOAgl6!<~fPQmO9Q zi%F-5IuTfKqD5XOxei70?;X1AV+(9t1Vw|fe+Fz>+ita^??BAAxI{JU?b$wWG+IKk zv8#=`+t75|M(JK7LA{Stl&O#&6KNCFRi13Uf3Nj=q&2|uLfe)~_dYX|hYiVF)_)gZ z#G$UGfc)IfA0$ddAVd&cgdm6b)k~EcqDC?$E4s!Ui@rQfJJXmt9JZifO1@jI@HnEz zhB9N3V9m4`ANoBQ&fDHf$U_f&&vk)#GIEufb16g&-b2@GIWr1_;`gJ;@fwHGy@o~3CJ6Y&Xb zkbb716kTGQ@-kU5)~cyAs)noS?o`CN^x@p_J(FUWQ3YlqSNQ5YW}KN|aM17q6^7^7 zww1qx?GDPh(|1`;lqoEjGB?wfxwf?_ccmsN;*9;QB9pK^y7d@a4I3yp^jI4`O9!R3 zJk?%UB!pO}g1j~wac$;`lUZxlZZ??+nv`2`wNdtR;J(B#nB=v46W5`yZZJBttPujG zZh_I)4ac8sTb!!=Ko5Q;42cQL-{qT_Gylp+Kg%ZlF^4D zUmoPofFjl=4(h(N)ILzTw6ei#x~;y{8$#ygZfC zgUHJaxxfse)*tzV&1x=BoHm1oMJznX8X>4r!?QALA;j1I3tct>J4-AR@L;9ViotZ> z4h?$nG=w9*{8k{Qlm8TIYL8%R;BwGi-_gD&IG>1PbJ~CH8KwdA$+e%eB9imFF2{FE z4gy)@>m53R;8w3rhft_J=Dt595nHf(kOM35j)LUBg%N*{#8V}I>TX0KlDQ^56fyl2 zRTQFmN(>$)IS8#QO@;Vj6Wy0DWPB+9VwB3Q3?WowSSB6FsY|}gpcRuUP1^Zm)R_2j zq1KKZnOQ4_wzLSJcD9a1xL+guIdrc!rB9#z&D-9^A2c|I!Z%=T>LVqebKgIKX~3>s zV)EWNXj-FbFEw;L7goe505&w)c_%kz7&Z}>-RSXa1MUPF6jg`HQklCi6H z_?=KzkG(ynvZ7BK!ZHJGS2->cnvFWEdyJoR+@AR}_rP6j|LZhJIDCNqI3pNaq~?$& zTbH@w`8+Aq`2QM+xTkmwYXlv?@cB-8E_RQOHJ7KGupfY9wPl_myDzKqAFsL~89^8Dv zNyvgl0lr>h@G#P8`=B6ATqj_!6MX9$@2&&Lr<;$!C(%@^i}iQnJJS~V745dHPxYQk zXyU^nQ=}67FcNem6(J9-?_c&^wx;2EQ5_eYv<$`PmG;IN4w^qF%xhAOZwUVi--E^c2=*VKc{qVPogVx@O|y3_SiGgg8KXYyu7%@Da@FcE|*Z@yHzyf^xtPzeXt7k^M$5sG$AK zf4LGbe0IK)A0n?g5n^HwlDe|K@U084$dWy&)n;ItdO7^bQ@b}u!Oyf1%QFlJnCqPh z{oZ;SqZ_dKO=Q{Al93)CS&;rc?^Q0n4UzR{fJ(2besz2&D`cy~LKSOEWlJ;{UshY# z+QE8aTdHS@clsNb?OZDx2Bc&knZ^|ec$B26mJQSuNVDh$;(nolu;hh|NJwD;O?uIB z`!vKfJCXW*CP-dKqX?T^$_UZjpBH;(V;?c1S{fzA1l|PyA5|a;t>y)mY4f?V3Ekln zv|5w~`iIZATCRvhM|JkYFCJ z`*~4r9kKa4<1F?b&rcz&+NG*BZpE+qRe%{bzJb9)KzwsyM~qN5{aww|!b40Bo1L>1 z;>0%p#;>z_v4lPsh}`nfDyr=3H4=w#R=zDO=o!b1mG;u;$^LQB$mJsE^ETTf$TQPk zVT~h{RW=e;*k<=D+UtB2=cm{9>f&LiMwE?gX3O2{MYgy8=S~}IY4gXR^9TAN2Ws+$ z_!h%rvDl@J@0+UW%i$QG*SW5XRu#=BHjOjth!60m6V+vfFezV*gfNdmzncey3+_On zk4ll{mr-ky6vP;&0G(0DS~5|QY|yh(0a1cEkInXVKK!ltJ4t%GW=9*(Dh=2JVx;gj z>SOj{?9+W$1xEWUNtdVJd{6UOzNPKK)gcxB20ubh7V=Fr@)y+84TA7H^YT`I82(Qv zYMyv1wB-K%{rDUs9ZPaIjM)#I9* z)Py00X5&dj`FkwGGMr#ShAeRY!&@m(-KszkWvR&D{mkg%N0#kYH%*nglVZQ@dwH$v zACq?3(OvzY@%!i3qe|g-=H}ns8tNh8zpJ~X3c3Ix4+`1$j=H^*bm%j&y>IsbUB)B@K3gAC^c;Ivc7+!UEHSO3+eSmrQU#*%tZ4% zt&^eI+BsLaX?uP^Ajq7zaMVsV4F@Z1vu;fsdpS zlUjz!OQvOD^j3SSf2;1@ej=?9JPU|)R*$(W_@1Aj?nVLATp#0XiP)<+{b$2plh&-I z>05J3Jh?G7F(xM`Z>AlMlw&HwA)e1`Nugwtaj$3O7)0o`#oN7iuV;AL?z8lA z1{u2?y!-JKLt^{!M!~YCQ$n%Tn1IcUGTK^ost_3-HuP5VubOxMC^UaT0ZN;b?DOnP z1o4mhX`2f{i>Kfn0#VsR*;YQ6$$g!&_R;p!_B79YVrr7an^D>hE*j4r9SeG%%ANDr zxl*1E&vN~7c+zPv${1wosmJ&39YrVZqJmxX{FI9GqbC@IwI{BpBjG|^I%PUQP)PQ1 zSH7FrLDn#P=FqEdv93&D*g6vow~RUis3j?<`U|34>kpU-)rJDi!8wVs@f3MB>-+ud z^uam%ca!M6{fwGnaeOK@m`~=CMaeOsZiIz*=Dul0SU&XX9Z0DUaXw*Tkyh3%3WhU;q5)+PL6%+11fmVctH#Ul+p3ti~@E1e$XYhpMJwmV-;1NIC zV*>XKC$Q@{;I)61gzZQ>9!U@j3eL9$WI(RafYiM>>NBFlhijK*F=m&WdYx)p@szBt z=xQ{+TmwvuCKG8eYz)18aL9E04^+>5Yh{8OTACo@J%Ljy(u z3fWeaiz}Oy5qBv-$~Etm_lu>fmzd1d=UIg8&Wo}Oby}oJ6D8da{fC96X5YoNw`=X+ zIB)rN$aw^oe4bxobQc{Z@)cDZuZ@{+v^@cqU3OcLY30>x&F$_FQIIH#V9dTlbnijf zCY_LR%KD*)j&ro&=AA6+9_T`(V2HEI!(|0!aa4*I#L4rQ9t~mHIda$}4ro;Ph9>&A zh`)eY#ON}3RnqxZQt@;zFK0c(%CWu?Fp5vE#(5xD1MP;bRAO?lNrGI)6QdTA&NmHg zzhaUSED3@{@M=m6CSk^Zw?9&6>Z&Uv=!S~Pic3|wsB$T__|e#(Nnv&o8#uSON3pMT zJ90y30Q61h785ETz5{v|SIAN~HCtLzdEb1 z5E2gkQd1cx^hQ60c}zW2oE=ZXg$S->P*blOznmv}U58XrVc4xMvX><{G9qm?le@l+ z5CpcLg1-W9E2bw8>#mdB&{fs9ldJ~Hj<*@cuc!{Wrrs$aG)Z8mL5Eh;X!j_$>cE#} zP+a4YEje2dx8fjPgy4(+BsM@Ksm$(|g`@bjI(DFR+$I(@7Q*e@1mkmE@6xWNV=<iw2@9as8>LHw;ReY2 z$J;^hB4COCvJTTfL^W34C{~<1c9JjrsMzcLMSL^v`*rEM7M9}d1AOQ0q?Cg+s=IzC zVu|$odmI&2THH8lOuhtX<|(-xp;z{D%s3KxN&cEP4`E2`{dbHX0q@uZdNWsRaZ+sk zP6KGE(LJI~B>f8Q5R$fubvF?h=3iw`@!2{Z_F`nL4e(XCI8?spb%(6?pfL24G1d%Q z**;&(7)3jui4UYs82DNEciv zLt^GJ_&%PC!%avxy5{kYIr+&saBsznEQK;6Pe+vcnT7s=ko-klO&F;k9~OD#SoS{Y zOHifd`H~>*qTT3rAgN#fNdaMv*t;u=kOf!0gw04|^1~}SCUR9$wi#|sYmzS51>ESOiZfa;q^Qsll^^+^Jk_4A>gjKB75!m6#U@kRqbfdPEsF6p)0#3-;v9M6q$(` zvRtF|5W3&R<}JtFI1azDMU=%60_{MZ-2T+hN~iStet_19F-6KzYYLPEX&_tX-M-9= zPH&Xw{0hu&%jJCmgw{!kw?j7LoLbU&c%eIUt|xQI*-nn!$uNX3x>vS)MR5{Q?zI>u zS^^C(E&`Oj#96d$0-^|n5E2`!K|7;0s=NTle=sxN5w?x5)c=jxG}Fp-`@KHv2uq%j zy{jICW}6M8b=MkP4e_JxCw0e)Rb#W^Q0#ZnJrc})3EuJGftaIgFD)WcjM7-qbs-za z`G@mUVP_mZb?-j!{A`a81||uyDkeeR%|uzIO_{D#QwIQP$jIm_Z&#Jb3M#???h;$3-v#MWu97N0OZGd3i1z_>qZ|5*WYJ{0`be z!8~X8)Hf|JY~xIaaqwdJ`Mp1E00jBl(%IfK=FrVB6H`OR_8?e~vqKB-M#xF4!Z=q@ z7UHxx+VqnhZk9;jguiL_Fh5n8Z@d85iinv`;(_!a;5{(90XhC@IXe{u!34l`+uQ6K zin)P5(#Oz*->gr_f!+P033!2RsDHRcM=eS&io&^d|B}O*!l@?wcrMg}qw?QZ&~(U+ z=)9lYM1A5&5WqJR#|Y36v?fN-d@;}1g3IC=zq+?rR}v?(8%{v6lK(Xq=*ZzoSVulx z7ziqW{EkE0Yo5U;Pq#XtdZTwEeB;EZwm#ctRy(n$qSlw8n<8Yh8Wn}kPoH`We&57v zO3VyTu(7{f6fNI-sGaQ4S3UKXwL{#7H~8INd!UEb`yl#os`p%-7Y=Esv?oSSoT-^R zb%+Y9h9q-I5M#?2PThF(y zk_Q+ua|>@@K!9}9()3ZRXqgg$mO*3QN}*O>4<7#gtl1#N4RHh+FEW{m^dF}HVioA0 zX9XJB7ucW&FSqLV%!*vBvLGi{%V6lb5GQI0ugZ9fvAht#M@rAk1!@%pzx+N$RPJw| zC5*oGWt@5uAn_CE+br(p2;Fy{y8qb0rySqFI6#hHQ%1Xji;U{hDW3AP`s{6+E>D3| zW|^W*ZcBIKGT(X0j-7eS?V}0 zZiE@+r$C|KAm5Qwk(ppWnn1^cg)B2I94T^<-;kX{HIOdSSN--r7w1)ZFp`NL#{?N>O1rMjfFPm6MdHWq7L;*-UgnFJ-?3z z;fXI#MY4Jey>CA-ajJ!;i{oK>#2Pm@&uNPD1geT*rECO_A|H<+3EsK~aDrazCj9j( zCn~K766=C8j>QzO3Og1qe!L6S=3E_N zR;nk86oW7`WDXfkUnsfunhrgxPE#%H0tQ@F;u-}xBgQ6?vNRewX6OeiudM9VKEE}w zBYHd47!4~7*HDXUrZECc(y%Zol^8Q)nu%Gg0V!q}Y45XAiUN9__l`V&R!q)3B$dDq z*-9X!Zh0CFG;CGV>1YKbnaCr? zHjGJadmk^^tiG4JAdI4*k3sf+~FfD7N6eL8m{oWIFTPhMK zf*-NQ3k+rAwC|d9Q8U?JKBSvQ(2QCiBe81nsmgZFTS$c?$JkY!KEgsOp~}hE5iW*k zh9miTn6oU@{m8|Bz0foH)Bq)JfJ zdOJjJFHK{}bx@IymYl6d91l`!muvJKXm4^eecWSa%D+3nr?(Y}DUdxvMg5>`4Yd4b)8)oIS1)j@4a(iagGQ%g@brZkRm}Imni3dC{D3GCOwka z!EVrPbRutp1PMSRCT*yalGafnu1y9B+q8i3SF-6=_pQE9$&O4d)RHIuS=sg_SfwkR zmXX+mWEX@4y|VJFQcTe_2j>A>Dx$lrCt9c|_hu}$Tgc(knkP(bMlE(yuwS;Q)VPAH z2o0DGY*jE{J)m(&i?811Nw)_|8Cr%LMn0kNUfuU=+>Y0)8?7;?^;SAy8B>!-({#uH*)0npZ zJVml_+BTRO3oYn+jA^QTnzrlkuq#TGCb`L^G!~s6TK8boS9b;84xgUU{K-yh`S@c0 zm{{ledKQZ$oP# zR+&5?!43PP`%f97OtIo{S}*55(E$a!R@`Q}dbu+)JuP`AJlnfd9bS`w^b&W0J}L$| zX}?Sm@_1OY4$Xo`{oviy&`({hyecdmPYI6aaNT}d>-Qe|$I8xftG3YN(R95RoFyNO ztW*nBt>$KSd+j&KAqv?Bdi-)xz`L1Jw$8(A9-T}i$}CBY0CUydmdiFC{f{3 zg}+zXugDKhf&dBDpvY@s8%US%8b7t=hadfz5h*T4X~r7d8PF#>!#+J6Z5sbIOeQ#(NUj$#1xZKc5H< z(n>mCg$GHjs#c>xPzOP?L3pZ`$J=^ITX) z4PZne5D`E+m6CkyCEn=El#qdW+3I-_+*)Wcl|Lex%1@<`^N!Tz_^0Y&B#%@(=<(25 z6g9iP!A`#w=4Q*IL*+6c70Da1JsT<` z2C7y?BgTfg5MAQ6V9nM=_9LHYtjpbfCTl= zA@-7W50klyh3*Kh344wzco*6O$vm|KY&Q%&E+U#s_U=b2}$n2WWaBeLHbub5k=X zLM9eYXnFxhLt`5!LN-ojX!^foe=D?1jI7Y~5>EP7=7s_`rdGy;4AAsSPR7=%gd70q zFGo>xD`O@?R={A2|3U}~+PV>H(z3E~5YjR;un{sbu&@#`GB9&$|EpbA-x?r{pqh}V zxDt)BxwWyQtg)-2t+l?5ypoJEfW}JS)RB;x37VJpKdP|*|EU6y@+W{V13(TT31KC7 zM}SxoHYT=&0ELyD?d+_Kt^cY3XqIy@GIlVxF(sswFan^=o!qIQ=@pGl%>f2;C!`br zn9G>z?{NPw6A}J3AwVktdu3ZO31Jz1J3{*Zuz;o))OR%gYk~ihGD^+{PX8Dmz~e9N z-#ftsP5+ZnlbKMHiIqW{kb_W@gPB>IkdYC9V`e4<6hMWAP?MF7nGitn7xB-PiJhI0 zm4V@ZQ~nE9hiOsAb$*H_63=cA?We?U(nS zmVippPS+Zzg9`iS+f#6-Us4l8N6mcCy=Ia}iqDXu-w9WeXiDc&oTc8Y9~tBvMiRF) zUtIx_xt=nHKEzO5H*8iR7&BNB(>S8~EJl%E^@R(AkU?o67L(K}I`%Sdv30KBggxl^ zw8e;}4R-1#%=qxVj^o_FKYU=AnL4(5BBZZa*(0T|xKd(Iyb%B>0=+@8R}f~0Ri6MX z&Wq{phzu7y29jbt?(t#sU?3%q3qpp#iErPEYB-7dP}wM~^r6#HT>heHrS%;_C`zEY zkT?WXmP0Z1$tM}1$NNhdd!!?%tM*%r4B4gI{oP=0!T7WEE0#rAHu1oJH~#FK6|E)6_k>GzgnE1dgyc@p*7D!YOV z!vpPbkfam$gyZukxn1~Ia$6pWnzuh0L_Cj%1;H2uG7jDQ8m@Xz>q@Pt(Onl30rQ9G$7R&scE}oKett;Q zY{u1725Di=Ui;Nk$JJNs=h8yZR?Aeq?UN(@6z8}85XuNuWQwtdv1E=&zUKAllnLR} z!&Dd(Z6+&+4=Z9rve;aw$B5E7KHW}xIE8)geX8upkm0;zDk#1HyTNm*BrW$R0)tI~ zXOX-xdb(7P1OH{NeU7|OT5(r8H5Nkw$6Fo9-fEQ8^SeX2^wCWZ7-KP?$ameTv}Pxh z-grDd(t0+WhhpauY+&ia2c<{QDhAk2H9Rq?!#>fxcr9Y@r91aF-ESYibsMmzrjG z-3Dbj_BtjPaZmq@%%Ef(=a&!U+X6TpdfCC_PNZsa!v!_N>fQe4%dviWZed=k+sgmJ09Y+Vy9Rjl$+ zL3`s#)t@M82%OchJ>QJ!? zQL%w?PkK@0;t~5PyERKSzOUs%vNqyUPf*BV-ge*QCF(BsqS_|MB}6{nl#;&GC4kJJ^vp?&J-Vh z&@vi1YTqaBT=pgVMQ#lxiV@x_)x+Mw5X{^i9^QkJ&KO;JkIM7A^FzE#Psf096?XA= zq`}X+@)hbPKWpPFDbT`}Sub;7Q|`bvH*#GXu6>gixEE04REPYnJ=^J9iE9~-Ke>>v z+R;-+X`!k~JB}oW`jB|t7I?r*KHqFU{d@#0kr!9`ch#}SjGUh%2FjM|C9J5^Cz9$R z)tTRZeF)Wwe^YF25NH+hkbjN8=hPjxJ$kxj`y_uFOEXXmyTQt1(QBU=bq%Twa<(9N zAbwETE63x+qj&MzkG>vyWB$nhSbBM~d{{kLMOy`3&0lq~4t5dWD#dM22l;f^jhA>? z<`goclo9-*FACfqA#V+|88}ji$c=QFx!eB3ek^y7^nsQ=bqrH+{_{1(Cx;nR3B<9M z_*x1)eVERGc?G0N`b%r<(&VYeQys=L2+x4No_(e5oW}(>d+uE9F&>pu2uNcq8@B>JIwE7Q*v|EYS2c>OB<;M|GpupO9%9FtPe z1*B6Fi}Eu4;`5xf8mYE-zdd}zm07U+xcZ|4?Q<6wWs5{P$=C`%+C9>Pk(TWn{rl90 zs5W(aAF_Hwg6d)cBF)BdbM|_Dv5D!+9v!ujpcmS-K0d&|}Ntj+SKxf3*!?RbG$WLoMliej@Ov+$n9v71fmTw=4WH+Bvr|+v8$Ok#YC2@ zqq?ho;z@I`MRQixn(CC;EIn6AzFL;mVO4|s?7Hd#IrDGcQ!J&wZDUO8F;9*-R3sYocMd%clTo>B-xYHO#R!S^d07FpfWcD)lv7NDMJK7wkGu<5xP>5&=|a=J`^ zf5g0{o|b8x2H}&Mh)L^vHjZKTJa)HxTZp-+on<*rU9m!ym`1LvLSXa5`J|f4Eu8)& zIW{+&Gg&XBMtJkS$KK!MI3M7v$EiJokW_Kti43CaNSb|Vd(XZF(ao+k^lI$zSiCQ( zDyyKRp{1gu{ysc4_HbxqYV5I&Rdvr&Ou|aGl9iC6S3fv3Fet2{@rfep=ZhHUcW*i=I` z*_!m3JY`dsK8vt$!4ml7{E&&1l`O^8C-aAOr)uC(qb7dEgYiSOZb9WLVc1NxSR+pB z<5UA#`$HH(<4>E->3tFs$=TWK%G@mWt%Ii8mU&gU#_&Qh*=V_GZl?z`ZBQp|*=B@e z6eirp@p`If$w`q5j5f;v4&w%^_i6ttI&Y&u1JZ>^+lPkLm@H`qT;6R;=L5TwOygZq zYXGM#l9fek&q|%Mk@wO(i@miOKOQAb%bT3}X>^e-a(s&Xuc(mA@LVtm);<*qgQ9Wg zrht~$KPK!Gnf?#r78bb*Qga&dabBK{dkM-%R@h2cl9r{7ZP-PRQkz&}GWkhOWUm>a zM@9Pwmkq*@CXS{?%Gcz*>klTPrfELKrWme5qRz4uC_D~uAQ%lC#hf$o9vBdcRCLVL zrRExBb%3CWT;(yR?|m6bHJwUn-xr8=5^NRL(Ua>>AbacDWPQAC#^?1SdaPgk`YZLK zWIqKxjyng=tVc$WymB801oNUh?(NidE)Ond`LtlZ%OXk>M3#uv2AzV8yKAJWE#Rzq zJ0XG4(ugfW_R6*nZ%TH8*b0TSh!o&L7xqV^QPBudWeybo>F#V3PkFte6_q>cq6}wk zvT<>SssEI{jo^QcnW-Wo8Cv2xODh69av4r>6!g0voov|Fma^LNuu1lJjmtbM-R=*~ zOclxD%@c9i%N97=Ke;GFswf#^F#SRwOYrlv6mrv8^{tg}d#t1^jIST?->@ou%)+^} zmwnE-6k)M&4zI*(nHyS+!q@Fu0=aX&NO@HamGCaUH(yTmYk2LD zCCg%JH2uc1KZA2C z@F8cJ3`*50Z-Zq&$iF_ye_5etL!$Vd*qDF?Isz&d^BE;C?<(cB>OIG{E{Hp`Pnq&H z)H6srs_dmF#cW~LRIbMSJ z8?^la3b8`djSAyOWliQpRhzZOt` zb%^_Z+p$V06?3E6-LvDveP|Qr&4F-N1Y~w{g+Jv9y=NrGcXwpO$9Ua zME)@%)u4Wh83q&e=EG>icsQMM{|WhePm`mg&|FOe^1&5e@BJ424D))AeoUMLWync_ zS9sw7JP|+gl|U3_gDSr@&}wV=1cY?!B&n>_z%@POH%dn>q^5_=fPc^x&u;0vTRa@h zQoSSF3U>oqNPMk^)hPLM=G*Uda=mtUGdUzLfA=<#qrj8bc8Q$Q+v3%`KN$MWX}!I_ z?;6y{BU`g>;c_Ym zJVcCdneuv9f1e)d9lGu_?_16dyVZflQ}sL)Hq}nGa?US zf8%ie6-G~eUUpBb9P}nKH%gwsrkj985CQQZ)ibsDL&p=6@u_$BGPtd?;yG8(+m8=q zPmSqF7V+zflKOc3nFE2ydxpEAU*(B-#G92K^R#*g%0 zC^tYon%|oe=(;9Q3)SBgc}L)>CT3Z8KbP*k0&bzHr&%w$aK3y&Pw)z{copg&T@S2f z;y*RK=-w#C1U)}+zvjif z2wn!2bUqRO{N3=mUgM&63_+9~=!3|lLD*fror$Qs34wQeRR8Wymu=zdx-+#_XhHoW zn|`WTuo>!w&Ix8UJK*t3NE;#i=Ij=UNp@JA=&0r>IPf-Gj%&=;P)>-KyKrnLpM|%f z8n||U~Z>Dk8ew=<=c&lk#728!Uq# z+!2kfHL_A*oFiOd_$pswk5usT#s^k)ym=YKw2uUrCVGqbGlO0l6tWQ%Ojx~bDwbrS zDC+!&cd~Emxa4t_TG2S%$ze5bK*YSw~UIajFlCcS(U5){QkIm zcZ7OpToXzAdoduRW}y-BC%uRks{)pY3kJmAail=HugJ&7T%0q^&ShUsQp6L}HLl1? zz?&@4wp++cuwAtyR9`~=cDa$g*u+zesgM9*&40^Y5#S>n_AK>6LIBZW35vHvZ$(4GL@C*CA z#eAH+3v_vM?k7Oc8BDH*`Ev`rlhl#zh3G7ss^OW${a`9ju!_$WS-8flg?nrvzO>wi zxTt~1{MEx&Yxltql198msiF+UfrL*;KAR%Q$xQIv6`lp1uQQT|Bsavn)VN0xFX4RX zG!r5~d+`ZL_z{gfs6hy88ZVDxiw3#ZE%-6j3*G7m;_OU#A%k-Auu>f4Y zJx~0Ee93w_?vVn_3yU6|C4Zts7bEbp&3nj9`4zm&FoNZMPZm2^UgJgRqU2G91A6jO5v$^=WryD(nJ0S)LO4?ebT? zrXu!>M=!j0>=1Qf-d#h%<(QTi;UqhJ6ba>>bdSg+XT*45hI)o{yo)wRvcjx26*Y-%(_?Mx)T2#xnqqs_R zr;fADf-BMT_P(LgdEZ@G0Xg@+0XbPim|`IKpS}U}zpom-$#56i&BXSaV{}*XHg;=d zT?#+y+8`Sm>&{s^L5{ppcfh<0_Z-6V&Ngi*aNZ;QUi?w*Hro9n??p3eZQ0Z3)N?}r zHcrp6?B_21f$$)b$yPqEc8-{Lt^5Q|VkvTjo41^%pq-x9?AJmbS1$##i`QLiTHTyGPERUg}loa*qXsEs+P|zSM%iRgn3Y*bB8OSc}jI z?%^c}<(lyv(x)08)01cTr|9HHoTv6Llzp2O68*jpEqTW67!AQTp_CWR5RfGTj#20& zSRHsIedr!=ry-2|5A#vNVG8nahbMND%XuEvttgKIrcju178!_s#@H$go-G)C(vV?_ zk+;Wjl$|tEP|Ah8ucd8ykUm^(!rIvRGScZvp%33)J2Su8 z1o0XWzaaUvZ><4Gkj1u%*gQSyF+O*M?zNyZ{`2Wk6-sE-f^TtxJadp@{AMu1-$dNjz@YX9xq?6FL!y5z^`*Z1AN~)JaxZ{f3{Ax;%@_Z!2rL5@LZ^_5D;m>c%iJIfiqh|#A`^kdyQ=ckKRc5p!*=wAi?jo zJ@1IQA!IgJz*c?_J8$UIy8*G~O|WVZe9#%_uMBMK-Ox90(ZA>j&skOiKj4B6i2Z;4 z9nibS0P)>c?u80xYJpmtpNMKsQY4tO6#M19wd>1q%p1^cU5oS1A0Q`^5!_%ra|Gd( zUoF0Zbk063{|-K5plyW#o(77|0GbX)^KE+8J=ud+1M#Ksn|_JC0NqzMK_>xUs2e0+ zRh!0jB;k3;6lUj)vv_qR#8ViDkJgkenYMoVgN_~jvU!GXtn0^Fd``p%=bR#iwN26ORz`h!<;#_L++@6 zpzq$8zGZ)u3*h>H*HYU!)9}WoOv;)zuz3&)kjKBqf); zcj6a~6}+Cp0>1a?rjR&9FIWHCZ{M9P{BNLVU|%{C#h1r5@7z|lmn#?7^oELfY0jAs z&>ccUJ;38A)8-Uic-m@xIbX6wihK6zIj&?z={I4sL+`Djk;-(#IL;*_$&3YYrd;@Ots2S!uUtOa2L=Z7QD6 zgmIB!#d%PvxXZtBfQ;y~m{`#9CnEnDjeH2k)m@iC| z`4j&8JN`S`QB4nc3G{}QJLEICyY3S~5A;B_#gW>Jhz~Z9Cx(eXKZn5irCq>cllzE? zgI+gR7iwBW7zlm#?x#1B*QoD{_-U#8Q8xVU<#QS7Z!g>xbXV*C;AxjP)LF2l$Pik1 z4FCJUayzCMi{A$sgc{h-%__Lyma7|ad+T;=y$!!F`>pU!-J5Xw6f$t9_tx2p{TCSy z$C^!P#~^bA$jbRvcHU(MjY-lD^i0|)zI$%|tBL%?)(qeK>K6^mPxu-Q*ThZ;hYbdJ zvkc<6?8V=r`%Ey)ZF&ZSd75wEdiTDPAwyvr!zlLJ?^`1W!?cGc%$+p@De;G}f!GCc zU}Ho?^(9(I&VKwg=reHJB<>&fi+*#89@I>@1^8`ktUnd~;g=F2-vYg#yTrqd5D@)Y z4Tx^Ye$`zocrlPEJ|GWeKn)`Rt%#{k8OBbc^V^582R7YVzdf`k{EbuaZwdbd?U6Oo zXB^>6(ImS7ZNuaVf@&?4}FO-^@56Z3rpV5grelx3Acl>eG z0()GQ1&2(#J--=*D@GRC?x51^Z;i2W(3_y1XDc8$7bGWuH9%s_lBCxO;|E^#;ZQCA z(wxh74B5xmz9aF3vXo{xuVDQUcO0LQ_uoq03GjO%wdO*jg{(?sQz?IhbR(R>fAMk) zs)NB53#ve!83gVZJ$vKoQXPN<9aB-pq6hqe`jh-(MNsS6u3ah4%RW~fA7x#fyYRD1 z-l_OwaMi0(=`^4d&ay4J;yw7Ke^q{MtJo7LT|sVh@v%nykn4(jM`~H{Ky<@GWw^F} zW96y!f#o`4Izyjz67DUcxrtS`X?RV%xC5tDwg8gHl$M_A2Nt z@N*Zex%mP1!QAo)AK5g>ynd9K>`G_YPe?1j3+uSS-B0Koe&cJG37=eOO($L zKU3S(q3wrK7$+`v;A%lFYIXJ&xW5WaFjQU<4z{jDTnw0b@S@WI>|0|aF>TA=I-(*iV)xBFyY;TJ@PPg$4-Gz5) zx2)f0CPpL19#Pb1ehmNC>tbm zPXLpx|CF>K;TQ4l{Vmtk5$Uc6 zcAq}csMR<`|LkVbu1C6E%T{ULD}kb2k@Sy8s<}kLPpEM7bU#o&a6On@Q*Z1}`^7EJ zfzIG_Rnv-Q6jOC-XhT2xZz~Oh~jaRwOkn6&JAcLHrykIl*RsK~V1;(icdNl%_ z?q)oCF9>`)`jnXj^L)Z9!+F6nQiKlZop7y~j|Yxu8$-HATSkAHj{zLsZ}Gm}oslgl z&Zbvg+=j}ucU!hA$9{i*W%X#%-P*IUJQEzzTUtMFHG(@*-tabD7gJxj5#)k# zM{1h?0J94f!L>ip1h}uaKzu0^y&SL?xRbn;$2fjJ2~^Pcg}f`G7U7?+dBx>HKL$Jl zL-GOQFyetbc$u3+urkcYtns57wzuVfIi*pci-oz<{SinLjk&UZTSu6j(CCr zj(t#ozkBtDUM3I)!~QJm&75JlKzT^flkX;|2j720+?iV@90%zHG>xQlAEDn?@RZxC z>xr!KWrA~GnWT*3-a;%#N@oswg5q-sm>f?;ie^uDkZ!B*nHf}jEZ z9cmZ^Jm|5=U);Z-kLR<*`-YK9C2uMB(~aRg@Et>X0%Ae17OVLas+0sk-Kf_E{%{39 zLvpldws0VX-|)~Tu+jlT03+amYWxn5*~ua{Lc9^CZ};^5{%*k)j>1nMOaC3psC*a` zz8&*@MNZvq*9VvfW(6*L%GEs6`Z51BxY8~ZecQvege0`b>o;knLlitrKFtR)$kDOO zKJun&FsXZ8U0TjHA7HEW*9CDQ;)9+ns$2e z65-uSO)tMCS(|WgtMDl0(lWjtcIT)d%y&sE`L#)W!5PRH6f;aU(1gw@X03=p_(7so zW>biAqr7%j>lH@yNq7*aVxS>xKd{*f>(rs%7C=S`EPr(M9J)eUr0N*6Yem{|-G5FL zqlRP=)bzi)XVKRC17us6(;Dz*qR^j_8c@m{x-cA?1iaKUHs<;kYp)nPsdrs=miSC3T&+_{D33#KaM2DNj9_uQuixrO+{3^Q@%<{U-% z?YvtDx<9Y!6tCW^FzVt*r1LmcJOR2&@Nvh;zs{Cl}SL@~&1;0awXx{&!Q7Z7i(tZTq#ZL2_eb7{b* zY4f+J7q%}<#R&`Gifk$r32T8GPPIjoY`^MAIhZZ|41Vwh{f&+t)=WUoU??B!e4anz zZYK@S?~S(fDhPH(J2e3d9=8{dxVFOb2)x}~T^PLa>`S5V+`M-ig-=-pNKCfLqZde{ z`}vGeH}i7UFHs%V&`#BWkypR2yM6!-j=3p?*iM_B85e~Sm#6`-Tgi?o>Xhms@>s4& zkK!(VO}ZYU*6Ml7Ya#lmFLDuAAu)MSr*kJ9mHshH#Ri)~4#!6%pnil9FAO5jCC)k{ zBA#t1%h@4@E$-qCw>~@}c*}zwgU>e@ERe@IZ{0Ch2c=QGbPuTG2QbH5qCX6M{FI2~ z4X*`!EqbWRDC9Uxx=7ah;9RFDAGBbM2*w9Pi}Jim+>W(IqYwjhw$<{5&Ltb4F}A5k zOO*3RqKk7-XL`I;O1i%D;9iA|QFW^aH(_kyAzwyzkyfmg+3#*rk{GJnsL{=IvrdEf=)J1>D0i|~`&he! z_&zbOu^%bl?OFZa0eoI~#O@YKmss9e9={@mGDHrye%Mj;bC4^`uCz2x{`y=!q8|rI zJTPx+3#C3`oitXSv2Vmy3$zPEC@=GQlg_O8*&D|V)^Ur%l>a`I0}vET(q%inbk2F@ zF;85IlZQ4L_0+UZtZK^f-)_Q}@WW`{w;77@QI;}>_Y3pO40(;B6vqO6)#&d8B6#OP zJySn%(GqwWbNdAtJ;ALt^b-H>Yrxdcacm&##<+8*h(i`lyA_=w71zM`lQ^H9K2qi{ z*z$wB@oHwmaSbG!HvURZVjaB>S zg?k;kiNGWV>I`6jan{|9Wt%Pdp>_Q=EJb5pGH#bu`fJLRJ`(Me+Zbxf{Il+TI%UtS zdGg;S>E`qltQzeN{ZtEq#y2KFg7%oZKh4VRxx{^G$K0o$i8^nnhnL2-~;xuMUuZ$UO?{Wv`$NOqFs;xZ~O&P0~TG=eEltRc^Py| z7sy+XET1x4itrnvP>G{LkSqvz{FIAHGD?>)SAB{VqHm=T{E>jFH?)11EA_SSlnAGI zeTV{>xc)@${>@;t{)KqEuj{9$kv_ouP4Ap$GgFMqMU+IIA!@IYoA*Y@6;NF8!P}nq za#wyy@1DjWrm=uYFYRjAE)_59JiflHoAF**Z8^PbeXpX4^&F7)5 zhgcy9v5`Dts9zR#(EOu$L^Zi58B5XGyItOh`iok?@Kf78Ta$o28ogRvP#Ta}aHzXK zF(0tr;1>ST@K+jVTT7e>H?-$Q&EJ|fWm|AE===Xi_vs4I|-DB8-*vAGC3Mr zb-5SVNG!=-x)N#8f5_jSrOP@?aQ_5a&{ADD1?`^|!`~Jw%bWR^wt=&(R?MrZ6S^6V zErF+(p>MY~8nZuMH`=h=>1sEXnO}qYRzE2;CAe~XUqp~r05OjSPe!le*xY<2aRZGE z4{`Ua7{p~?Sd|9RP_;$YM!yaH2-IV!=g^%29f%|mMSGX-7xXsF1s!6%=)U(XUD`!f zEM+bGDP~fAtclw|fc8*~3{0lq+-UgOr^{Bbvip#Xj`Nq3^oK={?(HknUk}nBi;$#4 zkF70jk8S#n6OkRb6+FZ^ZQByjfhPQoRF@{NYfW<40DD8*R`Iu{Wza_if*>+t$5LAb!%*}#sr6K$>BuOya)C$! zn4dd&jLH}`$F)n6zI>ga7jH?lXxNN6$?wf5Ne1leHVOxfvts)8NzN(zg-T2fxi3vZ zJ!?LaC5P}Ohi6h#4boFz1;&!YfRe+%N=|AOZ7rfyB;*;S9j*1uFZZ19TtYpEFNxWQ z_Bn?^a<_PLw@PImf981>EpyLV9-T71vNY+{B+X7M^x^KUBU|fZbrlB+DbBH$1P2Vp z&If;v7}s7`=PHSJpe~`JoueD^oEE|AN#B@#6y=?c^?iu&ZW~6>*3SZjL*81CG>R zY(^krbM&A(*ZU{HnpSK77;lPBEQ{Ea&GdNnw3jAu2`cJKl(}@nHLy&kiXa5u(6~6~ zcXljZJ4tpVG;w{T%+j&8aCKibG6(aCu9d2dL=XpilZ}vzlH>YOYaKl$mFXIJ;nsM? za>cfR78kB-$j#f-8?Sb{^FN+PznPYv6EKMqg-^Nh;$FRb~OC0 zN;}Xw$sjAOoKJW$Uo-HrV?O-9)6bI7Uxh~+S}aqmJg~~m z{8L)tFpOC=glQSg5Q-Bc7Np1~CB`(|WIf`ecRlpX5hRLqZO1~Q+0!CX{Hc}v(d8L| zMT#v$Tjw3lV&a^a3VRvvs*1Cybb>dB%w{C?E;npvXCSPFAX`L)!Kp15=i1b8m9VFc zs!p(k%p4pVeUjuqNjtaZDrS7ToON^dI}x)VUcY8oS2iP$F7zF>dmu%al}U^~L*jYF%0h z;di|yeJwq9slkSicWkbPfPz0_Yz+5{0XEbWswUuWH8TyeuqICVEcI=WKUVQc!g8nj z@KIKK&4{S54FjJv<0K+H$>5R`(MHZkh#d*nWC_hJBdbJQU-G#-2NVe-Jy>euzrlKI1@qMfzfv``x;CM*&K>Oe(U z|0p5dI^2zjzhdn903(tWBlyXa(2j&s=}ktCfpRAk-_l~g&L9zTcGd#IJDVTd z+rvRudKwi;y$4FFJZm2DGti{&spGtU0-avZG2==28{n9TmRCHsX6xj7q3NgG$?|r! zbo#vg*rf~zyyci+ftI3#>Y0`|MWcJ2I{neT9(t?b#_q#g4`~1gFSQ4T+c2}@rIBJ( znxWi!Q{0+Tk_%+#x_09Bb?SLYPLGwjOvLElUi7Gs0v;>4g*uHIH^ztqLGr+!l!6|> zHGjY|p};0=r|UC;!^S6H@~3pL+*toFdoJ)xqrSHANRs-$-gHK}q>(-e6u$Bx%}Rw3 z$?|UxH0OfFjlFgspPbnV8&7`2i{=RrJD+Y6aZmL5PwWa?F?P;HI2*@e?CrDv--~;G z-x8lbYg0@_y+P$m)^w3y$MTz{nSJVtNBJFK)erJ8NwML_<&o{pgVy^$t_%a09otKb z4#6fWG7a%qRieBmuyi6}=L_cxH(F~=GNw763z+#re2L1u!_%AfU(>TvvS#J{^j~P& z6ZxgGQH)oS&biNOnIzJ#+Sg@9flk9y7KaodI zWfBwJhRN=Rc}gnV_Ixxu?t0BUFwsc=^f+!4S@6Am%uO((Da+rcbM{q`APj5YOS*)nd?InqIpl3XNT&;w@AU| zQ~yxBxo%|bon4Hr5=6bBtfuutSS*qL>!RO%T1x|yx z>69_7wOQ%2Q~0bS%@-&N$=!7>t(3IFVVUaO))>rhs}^n2xROpQ#U>Wg)G*FgH2%Fy z_BV1>-XQ+ZC{#(!^oEQnA%^N9F<@&=%1VS=BKjL{Pcf^F18O(`740%SZ5IWF4zIw;bgwpcK4*d& zoxQg9pmT!PdZMCY47B+`<#BZSWHyNXess3T(|P}4bnJqNc*s84f?#4VIjRC0=S;hS z%uO|bWsHZ?QE5Tv_HFc8@s@UCiketmMAuX^qlL+@;kkQsN->pYoH6Y%W-Kd(jrY=O zPc;)@#P^NV& zo+&00%_cvJqin!1xVj4^{yiGkrj2e3DaCv`ZSi-qYwjr=AQS)cg^ZRqSNc_x?}sW8 zlNK!{Z3#mZJK0wvJww9+mGIvky4LeK*7NI{c^k2fdzMOC9j@i9%~J8rB3>2wd|sYr zmV#QgYvU}rsSES3BGL3cG>58|v}bjx5rNvr9BSa4c|u}0tK${~)MeOe-A-+MTYC0; zwJ7AYTI`7ju+Z)Xu3MY&4EfF5}^7~!nc^Jy{502SOF=A|5pG}j9Hps3Qi2Z7? zALnEz#P0NWKA!@^?b4V%|C$VkX`y7Nug#j!x^Nu^PWuv)|!- z^l}r#;Zgan7eRHhBX*_@O?H2*xFs}c?k38&O=e}}Ek=3PS(T`p)%?yX#+hF-Ws^oU zJ$G$1)xeE^l5{LgOgKl7M>ij#O1>RYPpipYUrbX-<7DK_ zo#a+x5?p0>Z4BuuU9J7*ujpx&!kv_LT+#{|kzvLl8ql`H^Ot9pMmz)0Y%DvO#J6EA z%}PM2+OXBI-mqIx&vM1ef)SUg(@x=g#OkI4=xpZ<_xS`Ijjy15E)OUX@O~+mXRJ0_ zH8l;p&Q+r^#AtD@*6LZK>3zS~sw8sJ3JDC{`v`$fK}IYh{s?ii8xyDNNKXJbNN;|>3rA*>q*c-nr+t(erl7OP@Z1fiDpIJ zbSHU%9-|G^1OJK$KKOb$2==z-*1Hu|l(c+wC9C0WC^(tEhpc65YdW&j zgp_ReE;2;agcNW`vXpbjNyZQUbJV0fh5(K>CuWqtKMl85%?YJawx zu7rzGnl(C@e68$L_x^l8OW;z#Gr>h=WAF~V7Mjp_1l|zrhZ$=h@Y+e2ra$E7*4N(c zA8Q$VMprChntfM3H~Ajrrj)c{{{7OlxoidQ{I4B*8AZ=f8uVnv7aj34!qzrw zFj4H!B(@^XiLj_Pv8GAk$g7T!1l;%6>MR{bRmhmlq(0R`i@IuX={bp*_HLLU z13~rvVE+h&8dj(ZDhmw}`X6?X@D`B2HH>X6_}8b`A1aAZq|q7?@ajHpt zbV0c9K<@^6N};L9@W|0v$KukVlG4&u*$Pfg%L;VuB(!x?b(Iw`{Ml)!#v4io4PALt zK$PVD>V#4V)$a?%%K2=ioR|LE7G)m2GT!nr< zOB$f zo~CJJdS}in)h>}uTn0|+uNZE3cu1BJ4f`?8Q}_yM`>t`uVRW+1WLZpgVjp2|?ksHW}@2%AyUdLv?Y&Wb2L`=F53a#@5HVXcJikY zE2qV-dWXy&-Bgb2e?@nOmcxoyPY^UHV#r-oF|zIG7hSVqrZ`9!T;<$y~9e4yD@tjM7E2Z#eBBVOfTne0cq3u|0NI{@}Loep|Y>DLRd6En`$X zNJ1<|H_e@UD9bFKg_7dVi?XfnXtvm5uWHT-YgA;EWF%WjJkh}BpoN*Ry_0y3yadBS zw1p6%GR^kXuOTF&ijPDWy*^dv(6!r3JPby?O6nEBqlAaXM&(lMMA<=QuX{?8foKX$ zdhn1zSsnasj!8hk#^=(R1Yn%}mX+1cVqBMNLB>HkmR(VILLM7HL3VWhD|ka1q_Gp0i)#SVO{2Psh$qzl@V>P_J&n3G`@7 zZ7tO}?`eiv1lpKmRsXQlC6WymN@QzJ?Mim@H;uYQa+s> z^K7JNW30H#(n-zIFl;$kJ4eeo+cMSf@8xs=qnoYR?uNVQ>=lgIhWI5C$lm*7#xY7m zp~S^*7>6cd!f@eq4yD~jLYh&g(DC|JW%_O$3bQRf2JSvDW0&y&G~vn1YsMc_)g>g* zipVpI&%BzefswG%dByEukTU`C9!)ZQEBgrU<8QR{K;uq>x+sKJjq{Kbu6PF)a zL(?5)RmMdg!zePA^)wbnM=2FEK-nFu!&X90$4F?i4tjXnT|=vJ#!NN|9xJ}QKhPE& zkWQJ<{OXBQ!e9q;ggC^PQMbqP#PRl_ejcvTa-GYMvf4Um+W5P zpfj1S!OBBS%r#K#C|YMaN_I_M*p2CO5IU12IBCjm=fOB#~f0NtoIvx^j3uJPMYU&z7G<1Wg#kf@Xm!Dg$%R)x_Nbb>#$ z#r8U{)pz4zB;&pPER!IE;p%~)?7P-y5zDUJC$#)|>$Pj@{b15NPT4bgC!Ytp7ZQ`S z^gZGsy%D;O%B0w9Xte1W$wkx(zC-VCl_A7}kA(L<=)-8%$?#4ZN6R@BO|KZ}`p3i0 zWYkr5ABdQ!{ScMR3zF$cEYYEa1QXeMG%dp-^x=-vbKtq6zKNP=fi8ULhMg39i_yLq#t%d73DuuRT53*>-R5$2Fd~pZYNawmRCU&D^T=18)WV| z$3v?o%VHHU%C#4TD+@37c*9%W(l!pPDV1J7@E%PMwG2 z>2z7_P0Wi$zn}adB6nht~U17a-grA4tS}#8p0AS=^!^oRM!Z`%q+b1G`F{X&A=K(lr*p-6XnD;pB;Pk zo29ITVG@IlI64fN>+R(i=o^JiZH~b*t$}XacEa?p-jCb|y`Qn6k5q(&}*qX9XwJ5wBN{ zqJ!miinmD#e}qTPaoWj+a#Gr9I4fpMLU$C~BUaa_YmD<)=UY0AG^Uw8_cxpir%7KT z-m?Y_W;5w96l<0-#c!og<)<>F6Z?_vVNRu0?hS2#6)?4l(1tM?vtK?wJI`Si3aU)? zi-WGs>+0Bk9DQa|W8rL)vd-zx1}(7$(OsyT@9np(x7y_TJAeH%c=nTXv||=?VXhP|}hC z4lhpFXfoLv`x5`E)%$icQ#z_OvO~_j9p6v9pp`BrZ+S=AKY*Y7_{y-hu^bIdNzuDq z`deSIOwH3E@aqTtuy}A_5mM5k(LS^k!W}Vip!;a^#f1T8o_;m6Qi) z=ubi&ihfaq)YB^J_Eebb3T;a`VEo1CdX6xOqGaSYbY2@&Oi^u1nHIla5$P~8Mc0_m%GtF*Tltu)myuDRX}8eG1L^PaZ#Hr zoSv$ulVvqcO)dRg8b4t&>Cpk>;AT9BfHZg-R4&&p`03LB2fQ zpAQDpk|u-B;U73%=`hgHQ7I@l7m5puE!t`c`2kreHteNnlu(P9=ys6|Yy0)3;{y)G zW}W*}GBHxt=3(AwqO*L;GL|ZhBwCTvk*$+tzst03v~A~L)}^$gVz_NX!uOg57gK_A zD-4>@2B^u@uOeM9ZZZz!qXsvrkiDuT_-S0t(>9eFn~t-H`3fye6ZUDSXl~H13tcJO zsw+8a+l_9+4{TAhkU(|Yvi+^^Txe63w>&^q5_~(0F8QCI{Y4K=qtaP_u_zbNFRrFA z#jh=r)*-yn6_Ke|x8d)#H9?70M>mky@?}1$htXU(3H$V3|3T(#udX zQ0<%q(VvpicGTqc(Jo!Wu=tVbOE~%8WBNzOC&Gye&;h zk*=vVo}+#P|6pd{zrpv8Z{sW6_9dl_#(coPHXuC zh1m*qe%`{0&k{oqjh`*e_o%9<=r^urhG|@s6T*rd(*9Kxetx_GydN-4AzA%~$*tZA zhCpN-lbH3<`|F7EaF`^(1x+<8<2>*hNMmGC)N)viVXa59pfhET_daV>f`x% zAnIcXUYcab+X(p}nR>DNQ~zMBkhCTLXA9-rS!6*mG^1W{KDUUi0HqPg|e z8@34EK#%O6udL$Q$awL)5z=LnW*Fx@#B5?CkS@$GK5UbYr$5nxd60&6>gGm15a-M( zC*I;3;6hx(AL7gq72sDX7BPO9CEKEsuJ=bnp`hW?($N_}it}?>c~rNS&&1@8j2NP< zIC~MHv`gBA!9MiH*Co+irIt&dLYIk2noduyNg7*u-s>+KTPTe`foXp|J^XRiO=a6G zsv$i6QXQE+j)U!;F=I*{Y<|CbDUpdVmG)1_H4C6^rJav+MWm?SmnSNEG-@B-f#cuhKFRZXDG8}ck%^ZKioh2#r&cmi(g)mGMU@0Za+Tjd zzY-R4eC02fgmgzF>;rW?_ z6$Gcy#WBEpl{58sJsop$GTj{yvq@I464$>Hwy%fv@h+me~e{UkvGIG!{e}RSnrHuFw8|y#Ih%B7!|B?|I|Do?OGB7d! zCmB&$L0U#j@_&~RY5#>V{yUJ!$@U)rt}i_Bzi8P14?^NU@96&xk@!Eh>VE-d|E-kB z_yr992NLkh{Nwzm75Ie|{!1AAmqGZY1%8=>UozpB`uA@b;n#sL{O=zZ{}T)3_!0vD zO(gv1>Hky*zr?{W9`IjhaDH9?#UB2P9Q;Q`|9}I($iXjA@SipOZ`|NND`EO#68{Mg z{zqVt@jrNN|F4b4%*OtIAq*x?*aa~li9UY7($9+q!>`!=WKl}7t3MW&eFcR;{Gr4+ z8ZY|M&5+a{2PuA&gXJXNz4~$G4zoeiu*|_Co^84gN#KA@S10Jv?}QONU2>WE>`Kh$ z!y9RX#iv(>^(t%ut*FZ6r5!nsTjO}U9fq}Y0PWhS^Y!I1GTEx!M3&nDFiIbNwGN|G5-lZB6% zt`i~4h^@wE8gsTm8~dr4_BN6#7Opj`tA+I>+lQE2?soUIRnvKBAZtCY;S}Kzfgzgd z*hE$dm#)N*u*XH3ChrZJOgJ0$f6f#v|MhtKU!C;7Q}+Hj5dSl?_s<^iHAMd1+4~>I z!vDbSF*5)Aulu(?#l+6^HDCRkx5xf9wXprqo$TBP+B;cw>9I{dD^bR5j+;3{l8h)x zOvqm$Q8EP`MpPzVqCAiS4;9BiSW$fmc1434?gE)C5L89ue$gdGRCk>Uu6!k?y`#J; zG2_zj@>T{0bjWAxee?41)pzX5ZyI?2*9p)D$O*vwp=p6Owx3?-U15Fly0sM*?-f4j z(SVWbH{1J4=g|8uPF!s?{o9hcXVj)MdDKoU6VwR_sj8T;YXi~mFgq$$kLjg;X{(Pv z$wK5>be>K#-LtGYqTGRZR~HTgphY2TI~LHBL*Y6d0%s;OkI=m?;s zH|_>K8!J|534dBMS`mvbkz`+{@)Z)@tGJ!CJv!syg6|QC5ga>OCqknfcAX}=tU%@? zMF7>wa$`ge+Do$9y#9*LTIAoa&sFu7EI9aFGJEAjcMzw9*g|fzV(6lBgBls+ z&M>4j1+0x(o5e`7rT3>~$#VjGmcGZ|GKFgD$IkyMV8`S?JCjzIZOteV7JHm#wB<`E*)5qscAjfK$SX)cgjlFsLDE9^ICrL_0D%$Ca{CFk63T6A zK&v}+X%^3!e)!E{P2S%B5+Mqp_=4?pMKa$jJ7$rP<)OhgA$&P)81oeho4PTKZv<#~ zTv2q@A*NJv+)JW{j~A0tF0Lx3FW#$HeHcx-A-&PPvA#hZhi$^lt3E}zw+5Dfz2V+m zcW@&@QgX1nn_pchP`WFE9}O8z-Iq~a{gs%!kQjRuZn@L3HueN zF+M;a>vB=7P4MR#k;N*KLuLd&t7KpibOA-vGpv3|!)1lEE%K+;Rjt6=@bbAeysp?Y zbl21`ujsEBK7hVL`4Cg;S0+yj#bFmam6&;#N--BN&c)2_J-umqDtoGX>c0rOj?UIA zPp4WR+#Z}AG&xqiwZ65#h3=|SrRATt??Lwc#SqAWoXC8rQ^fo^3NVtFIfh3_xk9~nh#OJP=A;~N*X|RV!a2dznZvLJZfsU?A40w6ou)Wz@I5-xwO}0AeKDKV zff@R85!s|Pn-CV!&gC{Rg7OylNb}*U-sVK_1@8KjlJhs#9K}7P`3KTs9#3k1l1#10 z?E|p0znMgZU~xMyMXoB}!7_b4kD5X9=TTS=GpxNd!NBvp(cY%E)VB zQM4t~>&|ySOy6%*x^drVpo+dR&|G0wiV+nF}w2Tf$IKS(cVH85*b@L%7JmVzoC+CLKEhL z6ORwg{yCuOgw*f9aWwRc2@_FGBy$H?ztJUDYg{2DTfWEr9M#`B4HEttfFil`8a2&A z6fy$@Pl~9ya=DK{=@cA741CJz)I4MOWu(GBHH`X36q9K1cfQwI=^NW0sjwgsD;=^) z{J-J#Z?AQ1L$Ws$Jf|y`PkhVcpK{Tn|6;t#CH!SSwY83Gd3_3c3w)QsWFeEVNIxzN zl-Fy^{`bpE`WhF_T2|_blSNy$-`u>iN>Va9#_pc6NdeI#t&VBvf-$F61-Wd@t+jv~ zV~x6lY~}6)B1tajBiHKNpGC&};)SsMj^z2K4s9{krE$6sDV|PAncm#Ft<)qQT~RAb z|J=&OJ?jmFJ*Vcz@jd*Vp7xRXed`O~F>?a^h0NXZay$9Qzt`AJ z6I#vl<}I8tHdWQq(_@wsARDsZ}nC_xR~;PziNPP?xg0-sCE;svicd)8GGatdnc(tZmJf3S@Au;IC3Qd$n@4iRYYy zDi?OkZ>O|;gb_-p&FmOr4HD6$q;Iai69H4SmsTTVb7K~xR2Ao&GMg@(n%v)`T1KZjyt({S>RT`HjG6b)T;o@@%q5 zs?BGDnzU0JNv3foH#N4dF6%a_J!(iibJtp-g&c2l!Sx^VwX3g_^B6mY*rcCm(EHT~b_tb>Fgr4Zd!~4rpu}!`GxU zuViq(!&>(b%x=A}^SIFE zRh|$XtpSi2Xl_qZ{yGMqt9@3jvt<}}O$kHs_T(m{V;51w#@4Mcn;wseP7S->aDq-R zvb~h0L2Z0MQ2yt`lzTFsE}h7q%9@2)R^0$jEjCtvqmoDP5`Q`=O#|MvEzvpOir_xw zm-KYBE<<5|lm)Ce`Pz-y4D1?9lh&QA%pRVslgpvFEH)=T{) z$Wr4TH-Ni2_-7+=i;QB9Nf9T-NWY2uAeaI@@s%VUe*uG_^DacwRQ`ohb4u*~C~o*b z8=m1*e$!qYkF-ypbO}d88Q`}xCr$#5kgT#qAqR52^`P$j=Doi(RIdb z-lRS<*CzYj1i?-PTd7hc1v*AtzIUz#>{%XTpTxZ(GXBk=YF&g!$^a&S<=Avc_8SR& z6=YNpV*Y<+FcJi=+`szIAQlT_db$XOBWr##7SNp{?Ej)kL~$id`0inF08I~`u!P!9 zo)=&JuMGk9h+{*}FOiAp6Sn9KME9<52CosPi+a+5A1}sCmAtkN5Szk5LxNN-Ny@a zkHa`%1b!bHF4(jLi;&{q+&FUzOyw5834_#Lm5YwK<|6zRd1qH+y=gy!Gf3JfHJ{xhQ% zw1xMJa*tCXDOJ9NEBLRi#t&uHHD-i#rgTFZ=GztX19bd!3DgN0evw%s%tuyC6GtC< zzfU%f`JC94izEX4%lmB)78MGVW=6PQ310CUfAozv3`v$S^1;S^y{ueM!33qyA zGIIpTl>Z*gC7MTGgZC%O9|;nc)F0s4CcQ80pTak^J=mj%x!tvd#M6ajbnW$B^aw2q zZWqxM8U(cj(F=O&wTUDFV2Rrj~;a%W_P736#%v#d*W-s zl=lT>(}yvy1l> zuL;8>qxifODWCWNX}r3tU)9a#SjDZlkWn)MKOLarO;=+m*8_N=)R;Q)qL@ZL587bKn9n|*-Ww?}F}60EmUPQ;5p6pviFfS_8@dRT`d+!NLq8&0j%Aa))9Oj9q!NBK~O zmxOVCdo;5N1LaI-XwwZlAoIS#{Lgv^xo}qQQhYa;H3io9)qCU zpPT-6oNCTm`TCTPn+S+r*`r6BRZ2x#K-)xfLDPAos2x8vlb=cJ#)O`m3u0YA=1ccg zCx*D&xW#fE=#t{$ND7ljM7FXdqgYW8ys)Vz05QA1NJQtZR!!-=EAe{Lxz-U`VK>uXtT|2X&_^MYQ~Jql*v4qL~0`$$hv+eUkU z#b>^UC-&gD&lLn~5l&!F{G}%)2^V@~E@WpUGGR~T53ZFwbEEJL1uH%Sh9Cax(f_Sf zv>5!ZiBo{&+q+}-gk{19#jkDEV(gHi;QlHe0NgrBF|tAW(0UEc6bcWt=naLfL%Q@b z?j@1(x;0rQ=?#tvfO=1m8!WG31Zm{K2_U{BypSJLzdX4nALiS5`4#xa zO^S>Qp)q<<~}iB z{cfAIDZJ_DO4Z5ML=d981U=aKmddd5AOxLHt1;)7|B{~v=>YKrp$KI_UyK`_Wkq6{ z1*;My>Ya(tBmO?vr_u*>)b+UbR>0XLnveu;Y5TcW2764WFa~OIb_5Pl zx>y6_y+Dp_;m)BS0!I&W{|aF%-+(Xb@A5zIgcD>%aNe)em17{F6Y(V9!j{^Vq7nJS zDE9&##%$V?;)CdKOlK*C9fSDi`20d>z0b&HLF&`@@u2z#N5d))7pbd3VwnA#2m_Xh5vt3O(}Hv9_?e9$NRjUb*~qwfRvCyf31*XS3_IvnQd!AFFvAfW#t zaef*2rS*#OILcgX#780Lvx@qKofBZbI=}c0^p#<`oW_lWwP(02pXb`>=f5}tuW}t< z%$G0gldsazPCV_VRU_!~!6Fy7;U3S85y3LkKai4#hUL7GaaNl@(4!()3>$NoU*jJ3 zlxW|eHc_Z06bv~gP$7}I)MsNL`nbGu2<8GaE;(H@rd^rj3msFnT_m*otRw>+gq{ZT z;<~5MH|GZ$9x(BIPIDgv7QU`76Te~w+^T}w1yGUm?D8#qfskC1pzi0b;f%-2uSfk) z3?J7gzt@0Ml&d=<&580qgZq-5AEl?o0uO;~FQB5M&(6cT zp}Yy74nT771GYrG+tU@)S(A(w>Z^@s_wO~Z36W0cV%E-*x-!x)f)ZP{1EIKk7<;JC zZy7s~!~WPEm`&rp*{@jvlEc>~c?eE?X_G_L#Blf^;&8V&B8`yXr2&WFABR>1NbEV0 zc|Ny{OQ10S2o?-GgYb54iLgFYQrKl=-M<`5bplFHZ*$3F>ockGzk7tWw%${io>eg2 zH;wJD`W?czX0{?N)ye&9AfF^cw8=(s-1+wIESI9$)pl)pvZ#%>vI|mXwI<+pl^(5#2l}eStqtQbuc7@4d0K|n@w%?h>_TEdze}Y-T#G)g3 z&VSDjten{Izx`HU+QmZZviqE<2o!%S+r_hr45D#@rBAaHHW=rae1AxXGR7n zSVxa*g8y*D*a11z6{olEz}Q4p(2XO2}A z;OQ^C=Nq_1)t`92d(#mx-?*>hGR&j;oc-b2F%8D(kU2&;zgZ&i`LGal+SFRQ@ck_6 z?m6NSxK9jI{&g?9RatLQ>B7>=dPwdou_X%nz66u|zFX=Fth0w|OGVmFN8*hq3xNEo zd!6*jR3oJ(bfiS}tIUujiR-QiHvj% z6q@QW%-5w1U6@J*v=PrGcS_?|juwA=Zr?*-hkD@aG)fVodu~g~wsc_%=hn!==}2pp z=0#nl{fO#>VLrKn>MaSQmJ5=dja^x@hk4 zFS$2j>sY;oNOecBSHVb9IIkjc1-@3;S}Xib7j%DF&@Y4p8bU75;rBD_g}Pk!uC7yD zj%SF=F5&kNn(Am!XROo}ad+qhf*chpy`gs0O07l}i{HxK-&NaMX;3deP@48iCm!zq z8xRnj?@ov<;Pbc6X7hpC$q<~6WBIqlBCrPea*uh9X#2NT$VfI6J8+-}`2l*P zbTs@Eaf>|5C^nyyLcmOr^%XyN%bpSNxsag9kRHI(Q>hv()t zaiN`JPT5^i%jLyR_ysY4!P4kmbcg$yx7;x=#k6YSrk;0a2uwcP!+lQp10c$`Qz0;q z;JQwM<``o=4T@SSxsKDMPNH6+SgGSjqH&OqYwLSz0-c{G1m>Am)gDv3kRlzlRmm+n z(w&BZ!2)m4=Q%25SGi&D*5X}q>cCMy+2MCT%JUi6 zVyqLvQpkj`ditQF783`Z?|2WK=WXd^f_l3GawK>cdv4cHth)C2S4af=ciV!B=T^Jj zs9U3LUCpdxsR7DOX|OMyc@0zUr9yI(lzgZYi~0;-Uk8=fd&jR8akK%xKqW2c1(SEGMo08xaKPdT1^s5z|eyo9NJ-XaxKmN7FrB|_#o&=e&yf4>t0rztm8r{Qf-uFBw zJqJIa77KuK%!~6ay?;xP35fP5LHvR&}(;NkBwb%Q=(8lz0g3EF6qodJGsmO zYO8Qz1GltSC5?=vO|DHUfEl|2I=}vRn&IarR6f^S493piz`Cmkm-b)niI2{PHJ67@ zK-rjU=fd}PZ~WZWI|oN*wo}#_>oz%5=b)p>5H}cMWgL}ZHvzoNU*-N^x@(=#UGK!#O~UPrXaODWCJvMr zZht>Wui@HWawZvf--E;eIUYT*yoj$b*Iv(;`B03qUTqBBV=muG5KFb7c6es5wub)H zh5TU}!3~(a3#*xh#B=Pp*|}@LKLKu7KS8)yrT~4qOR0r>XRnsy5GDbW$WA?IChOHi zR-fAI&5X*QLXAj%S5%@;J|fHW@5DcPJ<2Ef{GZrG$3juSxsCN)&}C;b(6#t&Bj68m zNW2KvOX#l_zI~`;3yAd)B@zjC*L0wR527F{;_;52olp5$Tv58J8%Ez%dR%yp#($qZ zDBcvLy^ul%s8>$k>9k({`y5QT+qhcCgwOIe#ij4HppWiseAUJid3e{4ZPOXN+IP%x z{V}l&R1uvy_3+Cwiar<09XG{!asW`O{T-b2jKr+L8OI?#_fj?^d7Z9Db;MtW>4G47 z6^$9K-S)>C3*YpHJ9g_kgSfZj!MGs_xn;lUQMI#d9N%J^6mT zc-GGqAFLnDQiXV7o>y>zF&@Oz3|aig#vUc;DVTZS3#!kp@a>r|PvsIObSs%aH3t&! z3DP!3`?ygtgo_x7NWGG5YqM1Nlv`%|$*OZpclRk0%Rk+dxERl3Yi-bCdzC@euw7z( zlB!XvQpKv$KOi@!IvoB%DgA{#IA7jm35`!y}8CcFA&G}qUiPI z{M*B9A_*)ha%oT2IdZkf9CX=C=_=L3? z1B>lThn~}`^V{X|c1Q2wnXX}Y5vQOlZ&)COa$%TR}+jFS* z&!@pJg6I~{Si3Qu(+Ldq2_%KCFN2Ftp~Q(5F>K>rn1h##W=W2{kqbXT2}&-mcvSnK z5ioX zFI~@gP7Y%OAJHzF9q+L4Gvsw_w#&cXFCGGI#DAwZ5!RdrX8H)zD_{1LQG(z?)_ahU zAV(n02NnDyMAt{hO89Fg9ix8MU=)RX5rY z^x}ZlsI4G}Vs<;&`&-$*LI%r-7UU*G-vXso|n)} zO3zCv&$+hE!cKq@Og)=xFXSVZRTK#<>^s_N$%fjDyWGAwR(h1)wu67_g&Wdzg&TqS z_3MkK&qAnllluCqnkIfp`rx|d_e~LtyOAN{Agaj<2JYG=cX0shbDKx_u?Oy-a3({< z=j@0MB;xHmCPAo-{TNcr|2iieU?Lm&lK3GE~&vI^iQc-roV;AaCyd;Y9hH` z!TM_EDOT6XW21wK>QiK8+l)wldtIYPADrF##Gp}?%D@jDVJBKPqAr5cDPg`%@LJJO zBG0=20YAAu_9EjrhSDg(HZyYWkwW2zMDKtd&cjVh;gsWAYAdS07HwIObwJpgbc_Y% zgd*JUdBFx=_#{pflw~=DApCsfvY$WyqlK$VGAg*lxRHkQ?@kRS-DN9TSD&1axyR-SUCmx@$J4M_lbFC|H>=A z@W?NQt@(_dcW2zg`V`14Na(Fahtdt?M_qMT6(2s;P_?}cq*k^XY9Mh4%^uZ9<3(=g zN6{Rx0=a+A@g4OxZN0~3-g2E=IT#add|&&S$G_Y4N;ZM>tAz(}U;K)bSQ@xid+0)|?2|w~{Ulzx5J-7!JDIA1zk2?*8jwse> z0$eJB>cG3SZh`z*m3@HNl4aBeaw9xg%d_isrodME>}(0QmPz(sT|K2(~z3PAN5Kti5 zG`cPMM@lf7Ns0OQ7w@sUB5+-MUkBG4&dVb6H(36klYuZN#mRC{?}y`!;NA=pMu)h?*_pZj&x`?EHXHN+Izjd$eS zB476#&j1UqO=;F!jJq*P_Q~c)#^uUW7uVK2bGoqN_P0qIdk{ndmLH-{<{ARYSxb{A zO(QfeO7_Cw^u32$cGO*^+%_R}>!T3xQ-Ss$%pU{!?BU-zdGw?B^dtNDQ22@aset;} zv(FYBk1{v8vY!@38>c7pzH!BBPjcOe zIcrQ9_C#}T14(Tu zxaK-eczOyJOo^ry-U#mgmuU3Xw(9}Y(+9A4cMmy%(yo%9-AW8IS``{jd&|c--7=X@ zXg%E$4zrC7WR-8f7~;n=6%VV(CW=d<^8vGhwi*9FCOZ#SAU+=wlKFox(Ht;dHzZR^It_QX*>hh=3f$G{fZm5 z6(01RjrcR=SW-+r(wqmj2DwT-{73}h>j+Zb*!D;Bk4jDQu0*}CX$~^tzh^BN0p#K$ zDE1?~Q7+@fG%+nzhep8}G?DeFy^;M-Rz^qD;oWbfs1%nK!v)>-hcB2meyH{zpW47Q z1R@uDQ`42mt)}fG9!;NQPc2xz2=`c(+F%9K(EdDRfBgj{ia}Lf?G5c|g=oOxF^p*8C9YoAnY0m>T4~lk0!y zBnzGY!r6XaR*OAZK$2~+>1=9O=J+NNob{}y;V*GZcJ2bZg{3C5ft7Fq+8~L z;b0ER$(2&+6GV2~D95zZBE7s%jeNr2*m67j^ciD_N9aBKjdVx!IG1H8Y8SNLktv~# zV=PEA`(V$j)D7D*y9|C?U6XRrI^MW$4?p>FEDXSh)+@nv_hWG_F*f6Q@#$eu&!m$~ z47&Eg&Y>1zIvkUw!?CGM5nYLR*`Pga6UmmBDC)@$;6aTd}wk7egs3!AWC}8@)w<%vXbV{0wwihnNa9y-);n~OHv-^f` zwgtqJW(KySj`R@4scemY8Qa+k;cAZTlrvc1JCXf&%?cT<9sTBS+Tum zhk?j$0`iGhFkkD0ugE4cA{Iv;d>f{zmlRn|B2yQZ%W-ZKl%yCRdwuvJgjiSQ+|Sw3 zUbSL*FIu9=BesIEN%8s2OwV89Jg0*xgI5*!9)1j-?FHvsNnrsf29n1TPM4DXd$29^ zuMU`|vaQC7&wN@zz9*kxB|E0q_Dp9ZP|U1n#``(OV=s4nc2Pk3QF<3mLNd^YDzA>m z=hUos`z?(or&3fhI1K$=y*Fe&G6O;1w2L7UR*si9i>y}W`Gc-4oE)iR#jDk+$Fs*b zyQfK4T6zdoHMmF z4#S(Fxf_5EFR3hTnTI}~_D6LpWUVT3xRRSgr%jOeXZw(Wl~Td1ZZ15`HYQ}XZgkT-&GORC>rKKPHGgamyB$*HzAlIJC5upyA zdtg3lZi?!0LUlL@H~hF0nqt_&o)`Rt9rl%}R_VEl#U?Qb?w!U``^51>eP> z00}?d3Um8*6SZ$=w^(KjHx~etaf?+AWx5(lgW)gOHy^Nooz)lp#cddm{elb^^?DY^ zDXHuvYL@Mbdf}zyAN#K*atrPP`W1>6SJ7YplVU}TkHor>FG>U01DE(N>;>~6em{6y zyj+}fYyKi5gEjt%A2E0KVna&P+BQcoNN>QD^dk|NAEHkSLcrwH^VtvQ7Mw6>(jxbK z>-omL8=aRV7-oeTt}2;GKWh~rlZ#?w)pIQElQpc~Rl}-mFUhsW@Dky zFVtotn>%Fs5}8_G4At(eUszBB{NhXR>nh>3=erSvU*|undB&q%Vc!;N~zV z!YzUCOx4hr;X1;J3{bfJdIO0WDqXTYB0Yo@JIf*UCf~XnrqPFW+`UMt)hRo(nXjWt z_gm|By2DsMZr6OpnU*QOWL(Ykbd>2q*WP{Tk-$#5JOtCO6i~m)E&U5U3wq`7wlI{%Ofg$|jQc*=4vc3DjjbU$A*%y}d6*<_ji;Pgh|tK~ zy&yXH0!0F2+KGe=piw!T1uG!zAs?Y6A=E-!AkYV*e~BXGo5mriNWpr{!NbmEACkXr5!XF7~DP~%6E&3L(y4=L7$qeE<^AhvLd5Bt}erHkUAmb zR%~L{v|^B%s&U>MDER%E0xmv?F)b`j4ZD48x0PMfG(=e|U(X+&oZr&nK;)ND{JX76xD#G* zJez1IZCfE0Xiw0@Qcu0)wq*ZyR{FJ4a9S_r1e8LUQ6m@0y0VmUo;pR5p=@*5BWGoB zV0dCTJJI@Yh%;CNdtf`oj`$g3PARBpORxDm&|zL&ox{J0oV0W^wa8?mJZtIKIQ;YbFnxYr^Q!EJ7H zk~CJqO;n|riq-oipC5fjLfF51G0L`kzyK@J{NJS;sJJD`{Z!!$lXcOzCARr?fnp{% zT?TF6Z>msh?8sxgC%2-G&~~&Vj!J5LRl=f6U7&W}qngn2kkADq+Ax9XuN0IrQh^g# z7F#icBiw7nqtHCa37k3qahJ!Wn#T0T`qAa~;(*?U@7!n41@M1oK%Yw?>oEa>QnbV!lc|)^uS+l0bll_lenh@h|4Z!F~e`fiYsg{4bmH|F<_Z+h?UiUmKnxesCw^3p1f4@$ zi+-URxc$+-bJv7_4)I%{FTtM;l6?Y&T+^?j74#^h0Fd<)ju z!SGQjAvP!*!OM%lQ1Qljad70&RXQJlH5(1}&=ndM^eU176ZEQ_;1zWHLFxj1AnCPu zx8e?aY2HZp53Hqa=+0D7icb_I&QMU=XMI4GhgEhYsyvEN-c+w$NWoE+dFEFYWrtJz z4Baj+rA|Ed5R5o4X>V!Rf@1oM6wYJ{7S{Q4a17}u{qf|{k#t(5`E@XV(0aAhKH}6R z!W_-dPHf85Be6o`SZx!-iR+=+Al=*vv@tiHJaaU5ofJzd=C!u@l}P7+9}X7DP%|X& z7v|WG{^`&S^Dp8bu17}?7hvz4JR>}ZjT8QuqVS2Gdr5ATLt?iczO{>Y6(;3pl^o_n zZ0@{=8poESbElStCntN!L2U~~5Bn@endfet6{wkMo(pu*OZi4gzNMqrY!9zBF9Lh< zU5+kfOjoAHx z73jQ_I*dlOKI4F(6T11-l9Q6i68dwVm69JSzsuw4W(ZB({}fIonpdvaE>1;hu_k8} zwLOB-dgBQ^oid-Bb>(*y#oLI`17tcrXjmHmGpXcIC#H(c{I$Rf=Bn7h#NXl_cyAlWlrackONrn zChM(Y!{QM-mnG5scpxa>Bir$-BfrHwojpFeWJJ$4&eiC`lX&LvFFV-^Y9b=+13zV< zw?cwkrpN(5-ax6V>_`hmo4La)m-PMRbK(*<&+X5T_7*F1eA zrq!VDAK9cC-ed<+-(40E#2YAcZ9A8ulm0!MbTOSL%kapc-wOlig#reGvYi-c}Z^Q(|l-c}!rsu2xI(24L zWLA_OH_1oU88o0j%mLD0Iiv_w5!EgeR_HR9%AFpqxwa{t{AAd++3 z{Ob`Tw1EUjmC~j3W%R-Ia0>t)^gQlLu=2U>rg7CiKm?u-$z1!xDZWQE1+;dRubk>BD=*R`m5xe6Q|r{ z*Ow(2+dv^E>aWQDBdLu1_t;iNp?5=ErcURFE5RvIWJ^p>yrtYE{B>=kd>L7$rWkv< zkfcgdoQsnAUB#Cf|3}`i7koFWOPGY zm6j%UmY6hPv{jTZJkE)bKzoZPg?`(eaJ0}sNy1ga6`S~nJaCW6Ys;xuMleZsMRJ!$ z$RO3D@{Tqs$*Mw7jdgVBA$_X+YiRlprYzM+eP*cgivE%i60HimAeFD3;!B0 zP;-R#iAw!Nj&v^>z|4{?ZUh2PvQUs$Pn12os~^Q1QYr8?YEXY%n#WAlADZM4sm?l8 zg@{Lwu#cu8@A&oTac#JgKE$3#LopSE2DI*CqfT!yih$XsI z2Ghep2m&G>8Yzp{d1I|r&b%45cck47je(WC!g<5d$3`VylNrl1RVEwm<=Lr=;K zlU}vu%-!pGx^uLkS*$swvdp8UZPTkif81Jlza?*J1WJxW@c%|UyDEiU9g?IM9JzGw zpyE=*bBm5$d9T0uup9TAjXOM*2q;*~%h=eOMsT_lS?@}Kv2Tg^n$W~R z|1RkV_r)?Y1n%LaRM_vG{(T=zj!?>%P)RjA7KV0UqTM|pm~+sHpoJ&7eueZ0{?L4o!macfl%#qvc^BBe(yYDKu6HhF#+F=>@x*A}i%wWwq5^MaE z3YM=l=`vOZ`8HJK5#-P-n<7y$-g5a<`iQCd-r{!Al1QaLX*)Ai8|l!46sYUnS9U$b z#5tC6mRncM;L^1I;fUwa6Scf^lZwRLHKhs*bt&0Vsy$peUA$D$R37C=ogQQ3Io|p_ zXPu61qIBT?3d&Le77jT!wadTO0*Wxk!`@-Mgg5L>PUk9=*3cM6GsJRb_Xm z&28R&XVcA)9L5)mzZ8z2JH`k&e3-i`9yR6RyG7P&kkF*SEiY%uLMK*CK%b**8pk(M zu(4p|Gx?68L)NvL!PjRzm90l^`!Rjte7L7XA3YSzf2c^c0F*iH|I@oXzr4wwmNqv! zv#dX&>HKQHIJTImc`zMKdXBw7a%KyV!NMYXmxTDJHxCG|9ynKw8K78+3$K>DCV>Td zNA=fAkv(HZ{wMGD4PPp{2GuHF0s%N4X5r$hC5P7)htm!&IE;x=j-tC@9+CNpnx2b4 z*@uh#BatAk7lgg;v*1Mln!$H;+<4K^mYDet7-?XtnsT$Ct|O{4+*l{zT77J8<>%d9 zC2)uF7<#sT;WiHiBrF*d`nmR9v9DlUxcD;oE{zyuIeMHE!S}{`Q5t#Jiur4cXJT5I zUz{WNhDCf?pr)WHSs5{!mLQ&(-O2=%V6qnSwH$vM>zeEe7Ykn9OP14dM%knrlX$R{ zXnQpB(FPZvpBJLAh4y321^|2FdXx>Aa0@OXf3Q$(ZH7PW>;e^?^;=nA>~PH<(Uv9Rcf0C|OXWqX!#T1GCCav1>KswUl2fObMDHNZ4wXJ*l?N7HE; zzN^a7sW4!8KdZz7DZt@kS~1)2vSBj#Eu?>RBu(vwb&d#>D{vd^H)pOWvC;s0O?yPl zden!b5SY-TRUnth!;F8(3~Lqzlhc(3wMiuoFa4dJVtaXO^8(uImu2Cc9)@*%NF6?o ziXB_|$&dV&on?vioRnQLOz@R* z|L_YmPPIqQzeL8#NGwnFLVSasAdrv48N%DBpa~rN7Dv@tMYTnAt zrHrD!x7osL`r((=I99E}J5wj)b3uC(DMhcLXS0J?94}4v_7WWDef`jf-IbdpQ+H6t z6=1^txyj{I`)k#(E?}`MTyuRL--Ls(&$@0d=kr?wWo452$XrWH^wV^F=F6WOMl)JY zq#P%z858s)mdLw5e}~&7OK{M{bOrYHKM^c+WS!wHbZSD~pPw(G;GL`HX;y2v^tenH#ju_i#q@x+rX(nbKo+wS z+EFlvQruDQV9ES?=mOFJx&rMrbT^GHqRR3;L^SmnK6~#ow+TU#`&Pqt=aK<`+wJ34 z_S;P~sH@|6rD{sJouU$ym37rL+#Z$rU2-ZV*u~?A&vD3+L;Eo>bMlhs>lIqD%DR18 z*Y{(Y)fwD%Xwe2R2-5NwIlkj*0_9n!s_g4(={v00TD88j zD3`NTMiMV%A5WS43`KD@#@el{48bjuSZR!>J=0V1B^8_YOqdv}I19j0=$rZe)pXvf z8LnBw`OR9y{FuDt?G&|yp8SspD`8PwQdC@2I;NergmsXi;72$)>T6Cfc$#*Rs$J1ZqHpixEcGAFXr@twXc$K6lA5=VBaP4dMNFd4 zxLo~V!;sPWSwuK%8zotki0xMM)`)8g{^ptXYw~Bhz5^3`UmsCrrgZ*Vf}A z{zR?B9mGWo*bpvxwJhg4{<&;wUZG4oNgTVlG1V+2pR10CX69KG^KL1r>)JF(;l)~%P3xnpnxdyoJX}zfF3}ic8LlUNZ7L>d z6pA6>?qQB>N?;;MBdS z5lw?$+MIRO)5PMC50^^?vpRj`;((&^qT%?m;8E5-G^b@nBWoe)-}GtuK5am%Khy*R zM#eu2e^itH4`Xiu9M`Yx3CGOL%*-%mwqs_7n3Cg&eU6{=8ZUex{5e;3H zKXfv#=}nEKW}7weAC9-azByLv>On;cvehLgd1p)mK9Z_L2eh!>qO{~zf^My!E2n5$ zlhuoV=5Goml3NeXFPeBSO&12yvsvy!kJS1oGPZ z&Tp9>`=ScNvwE~FGcwkcYF(l?Y~4%7I{3e8`R>coI$+#SlvE33Sgz*p&BHb}(mQ5A zTx-I1K$ta+$TEh@I1xzqa*9jQjGvj$xS7eUJwKH1?HTREnK`9g(T z3j5r;^2x35?z+FSDCK^r^P!@Ku7MesPq@)fA-5)!-XMdg7Z%Am!cc@M^!`CI#?*7u zxRN|vy{%MHvCb@M$rEV0(#W}dx0a5Q~MADX2~ zii9?v0#;kK!IsFC620VykjAq3mRa60&xY2`R=)er)h)M${_>;rNtaCe5;klTM?Wq$ zKRg1o61@aQ3E;c24OQTZv|N6QFx`%tOl^-ugqgHDbm+YV< zqNjXKMF&J5CudBQB>|X7kJ@&b$=8R@yZR39?&Q?H~NyKf#B zQF?h-iq#xsKli1n+BVLlk~Y}iJwn)XLV<^hd(CAe1h31VUt5SC}BpllvN zC%>OKo`5AKOMa1-GMh5tj0H$xcx)Q2oADU%*vy~3*-WZ_Yn*CZp~85f^)dEU@rCoD z^KE;&c+BwC;6=rxtd>bYQ+}hU4msl}lWR;dZ%>LwctD;sq^~{r`o?EIw<}_odHRxA zRAgM`@yM%Lc!6iRSA*gI9dBz0n#bY*D2ozAv<${hE<&`+rRbN^g6^06g zR2*0%F;)<}-YbW%;AshZYukJd?B#ycb6Ky(V;vxk%SJ{i)>Qne^f3+O^tGGFkCm>! zJ%_qD#qYj*Ncyb?7p+?p4>e{wBGHj-Hj$=wD78#adMa!ERPH}kF8#YXD`d2_PpFG(x1%gmvcd;UU&K357adZc9pwd^_=Y}YQ~@J zO}wu{stU=P$U3qbP1hnpwhSk6AR07Z7fa@Vy@O|-ZZzDs@yyRicRfDTv2leM14VYB zMr&+}^MOAK=6-0JfK#6Fb$WSpNesWNLhL2B=J5>P*dP5Hk86xE$*t#X0_J%wOafJ-6jX~SWkqujE!tQ>Gz_FX?!U{DS~k=^9fNc zhBi8HjW|E97N$q8TeVxxc8wJO>C8i3&|xhCg#Ojjx&9PX7<(&1AJZ-(9{u$+c^EY zE_qd$+!2IrZfd)V|EOscF9jnM-u=u{0DSzRW8(C4t6KpRB^&u(IBPV|-*=sr`wK5u z+x=3doluuL7e4z3mlfqE&3)u)YofHUa4Qzs^o6FZqVq$PaaOy&} z)1xwp;s+0QDk=VbW6s_>iJ`|UexsQM{>4d;W~gmvP1a+qI01C3}PX>zKI(4zV*u1hQ7p#lN z%jOGOnuF}*qE;W4d$!;yYD>rjJXcqfxD)$>0ptOd>N_&mHI|0J2g2fu z{)?H0_ADKPFRK9A`?x?+yue2L&0eA19UkxRI5_h|H@%}%f9dd5qdS4p9_Wju8yJx< z)_hUqH0bf22;XsNb|D3kKpR6X2NY1KQ@W8O?xKn3x%16c3Ot_N`DjFTBlkoYPHg82vFaYZ z_i^xhtbgxg1$*J$T0h)_+T%9HBAc&)$2~m9!Sd zdAF9)XZ_(E-S@gy=GX3$|Eb(mLHGScqwD>N|L8b8@7wJSTNct5SF?>H#cqqQL+XrJp)_Nb_JH6FZ!JVK~@55i685uK58}vruO-_#M2z8!!`Rxd(f_atR1X# zsF%~LjaJ}f%jLj_bHD2sowlI9SvaV(G)$&bUAQ`?`u@3%iCZ800>#PO)$Vnzt=1QE z8lw2p+V7oST}8U^!Yay%!f&4r6bTs=hut7{ zjqTJ2>+!;j8IB%PAg#;se2u9(N3MS#e6FplVk;reTbZnvl{^i9_tZm%Acv2DGGfL& zJM~A=E!{ZCFSr~lHC(c1rnf~#7a`p7Jl3D zdmBJ6bmkLp9MRRU*W}Wvlvg(zjB^$H?P_k59oRN$<4fhd_xZ=ik`^I$^r&%+Vrx(^ zQj-Jf-^&|Cx$|eG2?&=$JV=A&jXi!!Qj!?0vyke z7m~555~*FckF|-U*b<*LvI4PAK2fdv5H%V)n%uK>J?1vw>NV0X0`R{9TK#4azCK;X z?&|~p;#kunP7Kx&FuP=WBIE|jb5+NVNt(n&3(MG8!?(C0xy88%BI-dkqaKH34IKP9 zIMOxHFwwZ%IpQq5{QAjhg?BD67b})_gvl?WtZ4CTq{|aY5_DvK{983X9RJ++#q6&Q z;SoYCgbXs+oLegCQ zv^egz2D8wE`ES?>FQiul5+08rX5HqWuNT2#!{7P1Z@>+ah$Fd(8zNZlb?fKPpzMc55pP6Us9(+^;{ z9;zoo&u8*-TQnq#Y+KbrBtx)B=cw&3N$M$O4Z=gb3e6&gkhcfT_R(H(U`Teueb{*n zifsxFVYob@LX`YL$q?9t{D>xWh$Excccgin?ePXWzd4wZ62nUjB8PAqT(43B3PvJzsBKZ)*?OC%UBQy85{EJvoaC2wP6S{* zF)|Yp$(==9N^T-OTzT($qlWhvglwU6QaF{eQ*}6#h?gtqURQU;WQ{TRlKRtWTnP!U zf+2|^!a|YJ6Kf+>aoj-R=AmgSw9_UCmRUJMR0g=VSLF-b3*W{(sy@Fg+EZQex4*A7 zA^I;t&mQ|nBBPGY$CRuEcFPY!LYgBRr;S>)!s8uHIGtkiwKj8-NWgsGC#v$CaBf*6L5&uf}?EcGZT;W z;Q538B^D5_!aOKl+ZdqyooG4?>B76``gs(r?vsBLsVlF~%VQ!bypE{*EqUdlOk*9F z6W}*%(LK-gSf-Irfcg6n>tins_w(1&i*Z}CHS-glPi$AD*pu{^^xn7Y{&cma2UXPX2<)HtQ?AZN*rp(?wbE3?4?{(C<~)!|eyb}L)g~)vJ10LP zxlX6{76I{}jmKU~rWRodK}zD(3UTz03F(9RnrX=6#EQVq7-cd<>OR-&2t1lv7UZ2w3dZ{61MU%tl-jU8<=`)0baQ&jp z6(K!6s?>E+agq4JIN8L!+cO($k}zWu^kss) zbQy(of_U*Bs_VC)Btfji{qM@qD?4@UeK7-etojbdq$Bhx{^;uGQ1(2A3WK8A;*2Q{kvo@y&+<477(1#4+``~cDb%)%hx@zkQIkBvjf^vEO7_uF zYmB6T%EgGJDLJiKEWX@%8z0q zK;3{H$mOZ#TUhL%QdpAQhl1OeBD)JFv9y&{_?0}1M1yBd$swtK$w7y+i!O03IbOQh zvWf79dBO2fdzNz&{KnaV)qd%?y?36^QCfCC#@yxdo!B5IzhaoHz-IlYFu!*$)n6bWmnOY?w0`#lUvr!FDcEJFLeD z%4^SbFp#^NNN|>*L7XH)lq)1h%uKsalWi9hZ=U8@;j#-Sz+SFD4%U)z`B|~;_|xuM zMas&v`TahXcMMlQ)g_MRfx;Xd-lP3?fHW6QmbO9_jjU&ui3*leS1(GDeC z6r_$i)>X?q^E~Tb`6+g$o=q0w2Z1(jQ7vZ(?%$c=mA42)<0ha0t*wkkG@~b}Un?C5Nuy81W)u!Ko~@I)a&44 z!%$EYc|wdpryps<>*#H5J}xX{COibC=)idY?!c*;K6Em6AgYFGcMt{{4W5pwVq`{< zJI)^r@iE~Odd55Es}%$jio3+Z=ssmH!)zbTjjtlK!#T&nfF;Fx2`9(s9`qTZvk3Z? z_sR8DZ0xamrTDO{28qbel1yRrYOMl1It6}BJMhI#yDikxiGxQK3M3UvdKpecjtdoB zHgk6?i=AvEyylPgu33Sis0*SPPq63D=MH)oB;$kPq$u0RwK_%XnR9^d%M)@DH8p{p zZB92#0e@ClLraLd^Wf<=`!fxDyO9~Wj#y{f@qCpXrcsQ`h*Cnfm-}FH`OjgQm#`jE zT858QA;t>YW~$#XQR6K%3q2Ke3-Odl3-|pyCj74TPaDN0sQ5`OyY~&&f2M9q_iZiJ zStyQ8XqS?Hx(CUx+8Omo0hqOmzr=FSV#V`dN?W0eCpTE2pJKd$Z2!5&{WJPZ*R?TkCi43+vt z3K<3l?JOmI`-0QdSK$?)a2xxA_#)eTIMp`%E*MUn8<{%EDsrR0V)G46f1inC6P}nu)h;0FAa@e1O|0<$02;; z3pks)x&+nm$uUJDf!Xq(gH4Vfq=-Th*@?81I^6LX@j+Z0kVN7kemxhS7`#6(3@qJn z%8UG0L<;k4-LP5B4|kO^0t=6%BfNB8^+PA2ttld`kN(uq};HA;I`eCd1ya`%vS$?h;E64;HZO>VeE-P#3 z7~aN3tj+hR)i1}P=7ECGITCmRxEbfsZa%1fh}LU#Wgn97L0&k`fdVci2d3Z!Mp1An zZZ-C9$83LQvL4fbuR7Y(V4^0f?N`Vkn(%MBl>BIU)z5MQ<-1dDc_~7~C`NQ+i z#Cz2m)WF9La6zp{dW&oNPF!HPoc^SL#S}QCIAra04KDWM<-Gtx->+L#J{AL0Uox<^ zJ7s6BeOJ#!l;{Tyziqe;Ud`&DrPP@9!g7YS-ncRzy`y|tf_H*wo>o_%+P%a$|Dz|j zu|Ai#?mbl~&UFx8ueF!OtaX8C2!`u=mlrlk+R3|u zq`TvOd6CR{XeYr6w+XcP0-{VJb5pa$kFrLqNU0ZDiVB-nS&YwO4!^paiv4|`u#yfk zB!VBZ235c%%gcBwN)c><9d4Akm9&!rM+HRdtc1OZMS4wBwRrFDRxM53)fesE<@tV5 zZhbsGOA3$uvZ703dD(ES&eUvQByq9(*GbYfr+ue$-?riXs_2g9Yv&pnU3J@iDcXR~ zYtO44w%+5SuSU)JPjOw4x^lC1NG!L>9%Bm|Gduk~VFnWFz~?4RK4>~;#^W>EABMaB zRVq|+hSm0O#0X4t9xKRjZ$U%@LbDm@@2*e1n5infG|u!Rj&Y8;SX_c%K(&qx5IZCx z@7Ewq`4iW-HuQ1F31zM&{p+mVAJm^{j8VU0UO-_@3|WDQn^7X z-5Mpt0;H@Dv!yzt#sz8CuU392#!@2~BjhE9iHL)JtCaq6pXNK$DoSY_Bue*po zwt2OA>)3qXQQgU7zK_=d)NRwe5AS_$hd0RhhrQ@?d8BHFz2qSMXYJk+0;S--*?H1G z(0Zx)LG?oUhfbXSA<7^|X&Sj`I+19DbC(X65pD{c`4d=zg<0V;F(SUqPUj z*yrL3^xWs-14)GOA`XIS<3xt{`5iL-30utNY*ZV$M=)C;A`hXne zcpI9(=8foF(kYoYz3s$o*8K?Y-`;{0t?P05TtKQWpVafQ1z?|P-u;*sysLyDr5n;z zhis@GW=7m797kH~GZeHE+-2+drb{0I!vcJFCnm>LIkvYN#}|auJkcv9@!=f0xcU?M ztk^%pJl`rH-rFdY3E2o?vD5h_D)AMG%M|j#W{{D>Nq8c*wiM?QSm$L8Na#-P={$PH zqsF2wnmzI(qDaLxaTBqoWO{iROvfOSk?CFhc^vd&lekA%i*s3~<#BSaDi%7qG4BA0 z08x`^I63j3Yghqn zpeLkbEs8s@mHRlqv2e5gVEpWP4nKSKdDS7j(Ock9ltG;hH&Vhop{nnk+wAox=cCVRZhfg)7#bHI2~3H2}rB)w4161^kC|o zPU_yS(14U^{(NOiV;ZI2nZo0bY^P~Bf|G$l-26EA?b}w)1Q9*;nUl1;seR?!P3ygx zOs0A4fy7b-&>QO^hnt=|jkffw+}d1KU+ZDDPZ_IM#}}>4;!XR1{gm!8_8)tdI8ksr zb*pP&wxMasTqm|IZIy9Xbm#un)OXslze+=7!ho4lFPvSnic9ba!nI#DG+E&A)3)@K znZt08o(FWF+0|EDk@nf{i&zkJL&NInsVqK4ewsMf1hMM(%6aMI$0VsJ^H>LyuG#N= zJ+U1z9822s9iw4u$6ODr!I7olC!WMb#9eOUYA{XZl?^e!?}`I^6^slx%)nD~8p@5p zQ^^=vAVmoE;YYJ~uef9%nMsUb*ZRWbD1i?#$V zh zvRSp0J%2>Z=L%A~2FyW7-x-%0VUZ^J;2t}Au2A>Yrqu#PNxPv&Y^fr`Y{+?`wa$W2 z_Um&84~nkZyp{Uf4kVCAgE)EEDW3wL!T`^MO=~_O)U;_;Zq`2n9o;vd)i7wCg2IhGd2oWaiN} z8;i9qk=SN@dtrtwEJNzj4U0(>s#kfGde_QQ4W^^9@%2@18*7E*G&SSI`Qu(GH70ew zufMg>Y(3dol$6u*l&vAZu`&`tfIanK@cE1VC^CYH_Hg!Hcy^T^Mk;4NB?*vL9`H(6 zF(>rhQkKx@+WsM%K+EA9y6|-(dvcWjytAeR-g=f#rhsYaS0snK!H~>t#&{aF_GAIjXJggf`r5(E8Kw^BP+yyY|D_z}R~z&ds|Y!!gTE{ti)p;$#kI zV0nxMswJFOi+|jC^#?*faZX`v?A&R1Qn}re6{kbDlQH!_ zHh7v#680`?d1VI1K;|H@f5V^3ftUWw@P2Cl=^p6PAVi90B z{d$(7o|or^1vk&bdA{7)FBy@skdLa5APysr%8qCPTJhZDM&yUnk9LjIDVRG2R2J4i zt00rsxMFdH!u6I^rbt`*G@Zmw7$n1%CFhNazh^e=!piA1>`o0rmNr5AD5zd8#M;6oW?`0dJ_$q#=nvQOn zqhc$iMBH?ie9eiozAhW}#|D2#bo#gGyzIUVMeTTe@si180u*<9RFw$t>}kZ8BW*9~ckdBSNdY55!iwUqBldc*MxCB82qyQf!7>Gr#z3k-Z+$9z>v zb^b~9xPGspUzqV405~Gi07t|i#m-vY-daEhu-j4bc<7~;h3G`VdKIVh)at*x?OQow; zRZAw2qO$t-l;@5*hgO=Lr{acEvb2F6PzQwB-Zr(CwcA8aSKU9z1h8PO-v8v69>~Ol z>%;b96gU62JF|ahB>4mD`KF}zN&Tt(QNvgA$Nf<0!#&^dCPEOp7nqlD@r)4=STCH!73)(?;)2HA^l{) zW#a~W8n!uu<5~XP-xpzBgIkArNrPfDYCA1$qB)}&%dAUt*j^}bd8HGYVd;c*7&{-^ zu}{Kpe5A1?M$E6agK!@vncge;7E*!RW1I#H%6Zs`pYB$+zAQo=>XdD@$LYLhAI3QM zK6lK%5!#JEvu%dbLJ+{Bz@Gw`t(~`HfG2h5b~IJPN7}y6-hIRP` zCO-<1grr>Img$-vUV=|5v98E}AzPW2hSFp_6P=(DUn=UF=OyDHWkE_Q<&PNO^ev*b z13)fg((p`N4xj3{zv8gDB#^ZmftNT&tyxHB`t;r+5=RZ`!1ou}UTz!Tk0OL=8qa1e z(|GmcfgC3)f#%j7uvCQj)al>B--n@McKL9n%sleLhwD99{F&pUo|Wi1)`c><_rM8- z?XQWwqQ~YoQiJAp=k74$OJ-o=ck~5}=)a7YEYNI?4Iw=V!(yt8DUYe3cd*Ybsm$xZ zBi-xJ&zaC**l5{2+0!aHR3^rtm3Bl94*`$WWsI9*u)D$ zw)es`m_40*FZ+_QVLoQ=2PFXR=>rW{{BW|`1fy{8(|{muyazsRY@YP}(31())c1Sh zXOg*oZkO{8Mw=J-WYTe?zC%Sp$?d`)@y_wwHilg1t)QPpu}sxWS;>@s8_5ES6j%k8~N5ar;=+V%&#hDa1&nv3(X3)^U79{oWd%S z96nY(8OH2tJsIV9X_8eGz(4QlKHtQJmiN_IkLNSrB4SL6Y@~VRPnr?(r0uU~i}_=8 zX&5CdS={lZ)4IkY4%j2iJ+_VaUf`2_i|!EWUtCC!PaHU86HpykFyl!^_Z~V?hKdIh z70Iy+Bwf{T`%Kv(eK9rQ!6)a~D{7^Ou>V8|w=EHYp{(ciTJ%u?BtX?Qaav6cAf|(F zLpE&gsGGK0b+HjH4BR%{;CO@TidMu<-Pj(Mp3eif4hS9y-Y&k#M2U>1CW};>;Y1K> zIzCer1svnz&qH|x+<=A5^6#TNH#Wfu20hkT5QKcE7nk!z znw{dn?AIS&vdV3y%fZaUiblk%VgRo-W0loXuy0e1nswXIQP@lIQ`CESEi=)6GvG^xa z674w+%ser{L3S$%1uG4w8odH5)HAJk=n+W>JeK)sgZYe8#zw@%Ou-Wa^Fr;*j-&M&=zXO)W(&y^oJkRh$|eS)sWLDa2Ed z9?E3I6<|%-7OvCaCuJp=*#;0vuf%?hsVaX7!9%U{i;Fd;_<3Rn_5oYviK^B*L$?>K zFi`fimFbm29l^Fo&d&J`T(LKk@Ii~oC%#Mj=6gd)4p!aff!;F$miVxCYg{p*Q2A0T zBwTI^>XAey?}I$}Bvfeu=&I}RM1J7^!4x%OS{WTo)=vD2T7 zQN>{P(Q@!f6J`V)tJ_wG5 zA)ZlM1ROI4TQbDU&!hr8Wi{Zi6%HFI;LVMlhUox@{kRYVAd>Jy+!i@!iPA>&fV4MFkLN)-0 zWC1_XN(Ki|viy|cP||CRyhxIBkytl(9v$=8H$mG^REGnu2d9S_*&iUMrIbjfK1S)8 z&Dx7B%;*Q>&BUIW8}>jnX4XaOU|D?a2Z@d|j@v{0iSivQ4{7~WJ;+1%umSA((&c=Y z%}88cSCcn_B{c3yGBCe)qk<8A?~vbMG$Q%fgMO~KvzMG*xAfQK9p^>5>q^Oxj`J}{ z`&14BRZ)gr&?IH@DKq&72kYg@22m&{8Z^iAv9-6+#Vj-5)*W273e~YW%e~HQqbTF= z5Qbv(7ss?RaB72HpKSdvpcLtoUlryw?lkz-^p^zBa2^m|naY^l8Dh62>ss|DY8-2B zYi{-NbQtVVTiaWoKc@Yi&sv{qj<-U?7v0m{2kh}LTi#%NEZ!4%_qaBajH=Z-ZbpBkefxIOW5|zig=mJLz zl}$}e-+%zw+uyzF+cn>#t}XovVBD>e9{{gmI9BbqZ((LY2mKaEoSEt*d>DI?^lKE& zs|q5hKv|e9(DzOL=opmVpiHobg>l*NqrMe*B%|0gmI2{#pefI-@tR#mqhbx_6su7I z{eVwFT&g^IZ`1zZd^SrDX_cF!l=_rGalD#Y;ty+E_{VH<+vVq^YL+qm2T2JvLFMly ze$BL}WFuN$O6qw^-oY6voOBHpXyhMqsX^=;f`&s%*A2N*M4#CAlM|Mb$ zN$IOrlxQ5v*7*f5j?*}_-W^`J)PwadWX5baE#OXI?J#v2&*ij*DeKPa9I4`c;t6kO zzJYt$__JInevg>wD8BaeFg6fQRYRvedSvJ?BXbr#E|yYCzuA_9jLdcB2rE}fUx>cS zJiJ@Yi(Rd;@8|&|SK=X>Y@0z~K&pY(*VDw)#?w=2r}~D}N9bm=L*y%0*2X{wZP#j$)prx_%xcigo%c`Rju3Tbt`KI)*f9U((W65C z&_gf$&76eyzHOV*ncvednw0=2YBpr3o#Nee3B?ib-`2wH{>9z8HK^1Xy&lDmvG@)3U02ryqx7 z%n!3^I@eH?v1L-+E}E3=*Wb2y^@qk-E2OxH=}KMy)%w2tAjpv_N~weGX;W$@r7;@D zXGaHHV0)x@hhLaTFwaqETXZhJam%qTu2n%oXG|2dd=TdTl1d2BEgg~wgj?v@ZC2Nc zUidRyXVBDD+p=x6ZTT7WZv7zouyRIqZhnUOsy2!^4Xx~E(BR3nAFzmQUZFxWHLVpW z({EP~rw!aun$&;<;({$y6%I}x2;~)VaAPpNyE=p!eGe;XyWhyDrl1U)3p-nXQxilJ zz>xq?shrzlznHwO&i{;HID1|(1aZiX2zDa1g`X=R7ZBrM)sWxx3wurndn4N`&&EU< z?FG0&=qKY@SX)(o+$rp690nW;cA){Y+u-@F*xb=!(29lU`%9!b!NqNtshxLd%-5*d z0K!M&I6QnJHdOqVe)JDg@iq?MwM;hUuOL4CL*1Y7S|L#d<(+(q)S}AAHmNxE@tJB0xD?828Hc~X|7-k*1J0`Dk z%Y*g_@(nh^T76iCu4D_9!jLtOSB#L>51oJ0r<~QVZ~{;C3j7Gnkl4ztD;N=M8?1TA z&J|RV-mkBR08`<8_jNGq+_okv_{PiV$R{_QULRXX_sYV_&3rIRv8SMLLq%_;a@r2z zfnI;**WpQ)zZ7LsG}oqxgPFhNxtvRFkJAsi0}`k&Q*&^EuzuB%-cDEJn}K||Q~s3U zMl38O6uWWh)axB$e0EJIGT{m2Uq4aavBd(B-k~J}Bm|d}lx544eJz*_Qr!P8^966rC*ZY+E&93 z`pBtU8c|}(C%$zmoy>2_sci2i(tjc4{dqo!rB}d6E$MI#d)U~q={iSi-V@b3VJ*-% z+Yx=hGwnyZO$BwnjHQ3~_;@gPjT8Kid9vj$DmAvAMfj!%@u4HC#OK4uEYNXT8IICa zAY*B1DRZ;J`SG@yB7vKG&+lfodlrE)Isku&Nj*UBu7j3c}Z{940ceKeK zONKA6k+S#JL2yLfy~_SN*?caSo|vPb$7Dw+DDORKyC~RK+;3MfQwSPvc1L14nImc^ zs&e~PCAXJVaVZ0zP8LJ&1J}001sx1~yhs zVpe8mW?~j*06_O&_40Hnb{KqeOGaHaIi78{p$^| z8n{Tn)XCD$oS0h51XyJ0;zu|EN5_52H5dTg8Lvye&6LSKU z{r$3WasQ+6Fa4K~o1N`nynpj7K&t>iv;GPK0382O1T5qt*7+NDU1ARA|7ru60T%yb z9gvqDsOYZ@Fx4gIWdElENB~Xx>&HL#adQ7F!v%EkFDp<~mzWFa^*=IPoWRiht45cY z`(Mof3D$o#@ed0NE6cz2vN8j?fj;OGv$6u)0(t_Z06^Y<_*nmKC9sSGsQ#~?|0@66 z*x#0cQP9=>@4b!VfAuz5Q#*4P3!uwfz`kK=<6`Or98orgE~a9p#`Y$rf2ICC06nsG zQ>JROn32UF`5-1XM%3!fZBS`&D>}DK=7<32V8}M4#bLxEn4Ygm&qvKY(fE-_G4bZ# z4R76^T(Dm{Hhr>c&sk4iTnHAg_;R!&dw^34wy((k@DUp+llV5te2>szT-=BxVxk=qD)~2b zGL%B?nBj<4qv8MyD)FcYTo&cnBXaR|QmYY3Uf=}&qQ(9ap2?~=y25z<;|T)mS&vsR zym#F%;-OzvoIn0s(RNg#;bk(mXUmMyK3buCOpKihg}8Xzcx2+7?TwL%OO|8|$W|%w zXuz%_y0MUBIVSMOg6?mYY&1X`dA$Uli=#mIXMizVG)ti+{xJ5=h*AuS-nVF$!RR)l zn5$iJU~V%Cm`ldqJ6VckDSRkEH5NM$Rwsxl_q{R#{y-a5JLW4!H-z~L@uvXJM9D^R zA3*L^m+O(r%NoOcd(e!-y;{7`nMrFrqwxmmB;xP( zf8zRIp#48!9SF+*!Ii&&0tC8$A-IVl5TJo5;|v_9f00ue2*IlMYIc@?yDTxw-|h{> zwEr=9eYFG1{YB6JLOuq`|2|x}|81KN@ZMshEFl8C_W+^I!qUZ5(cTgWjylYY+yG_( zF$*yZBQqB_3(y(~Lt9%z;P_``;RcTB|6c;El{0j4vh;uj$^kezIEk4VS-ClZ0bpci z<%DHsWZ?piS!PBKRv@kb%Q%_;RmjEqPY#G!z~;DF*#3@aV%`6`gK+)t0R%opl2CC0 zj$~LSW5d6q%v{j`qWHBJTLJ4(~Oq!oN;n|rv8RxYbwurW{!?hZF3uTp6 zRh3mvSn!*M5O1zTV{pF z#R1Vws^2L~M&kXqJz5Gs&W)N=tzp;(KN74j7UofLuNs;z+m2d6qaCnD685f zpyt@PbXw4GaIk8>R+X%N{n(PCVVeJjOQ9PR0n5-p9gS?VQ2u@rc!QKpPxA;A zt3z={&T6W1ZnvfTonDKoH#jlSAQFqQgeq3q-}Rb}L+xu$v~Q&8cKqNKi4w}X{w@a6 zz~lemHDi97rMwI1o_h4XHuG85tc~^U)Rb*2V~WdDd^ zk}=FREOeY9eKIKJ@hv^m(GedYww1I3&PAA-6?)B*^h*)wBcZtEJ?@;6IBcNBOlo32 z{*^I5$VtFl>@25JDO1X9&8wkc+v7?x^4&SfOmQ*i&R{UQxzEc?OWd_DpO2gAw_rhX z9Y0nDzU-*G!OebCYtP22B`nVNxWx+yI*C8c3?pSZDOh&8C;_5IXQ!%+c_byOl=@0y%6qo4oBIf_SbVI8#@43f$dziALS1fUnfTZeecx7gELoL6I#b5j z7}Q%g!arW6hbGa7BJ4X&9H7xn!icn(od+265N-%29$o!Mh* z^?P%aBe%52>#KgC?8{5ex>h2EiG&YG`WHoI&d? z{5LI&J3)cv-r>BW)$lgmBG`*lbwyO`tygSxTB$grt0c+z)6Y|JaTpt8yMT+{)eY7a zaVyw@Yom{N(sJ)F6+@6qyWch)&ge8C=@)Y}mY*3wd@>~Md034`p$kQ{2sR^-8I$RUE``pK zn$*S#k-C#B@%Qt#njFS0VZ={Mz|9l=h-`6>sxk*58ntS);v6{ zGM2_es+`nTpA<2UEi&)d$`g@#*O<_+DA@BdYqIkylZ%m-A?W61u@N86W3C{h@aFtp z`7+Sv(0656 zY9V$~G;jMaS&SBEETulh_Rr}fp7YI#wuvrtSl3~o`HPh{ugkepFeZZ5h;lxumsW`D zm7+cjVd~xAKhKREPwQ9CPjSL!jz?wdy`HXIEwOF(WjC5XSHH&)w?*#Z(WRt`+1Em-@#B5%2*`5c{8;~pJnZaA77V-sG)s2I?Z^rh1FIxqPY$W6` zsFu=AOg`?@rMo#HOgMW*EkoO-lY(>$m*E@p>KrPI3i4iZzg`TNQU`yz7G{P~8(=zJ zc5fV7wjS3b|30d824e_*r-%jPMe!SV@4#>c*fo9!XyJqen#e6) zIclna(wd1sM)jZ59)X(*0}mYGTqtu<#Bxr_t8;Ee9wzXG4A%b0i@7&5Oqsg!;Hi0s z?e4Ki2_1UZ{Eq`Ab!G;6JG!kxggcS5%s1`_RhjX28N3ZyA$fW4lanEpIye=}7rTLm zf(?(LqZBO}gvi+K{D&e!_9-Nypi0@(5@{p&{sOCD!o$bU!_2`bLq* zvIP|3)MA(l&k4(F*CYA~`-!)$gM%5r%BV~sy#)O|VHL3Rs)rl^GCLs$5 zK`Gl6R`l$X=Jpax%dX68n!GBiS}uhvTzY?W*Y^a9(z#y?jF3n^Og%9bmF>0&?pG&x zhgb+NyGLz*7;xIHe&eyF*8#@b^94xUFoo=JRq1=9aKJ;L#alBBa~oW?)72I(b}GE1 z_pziilBM|QB&|*(3S_C%91*=Z;m=}*vtQuDTNj#(P*+47TTf}aWF(B0X(r{l_g=yU zfVUs$GvXiTMR(s{k?7Y=0E_9u-gDSMD7K$=v;0~&hZU|OlZ4(^%2Znz8ddi^4W#Sv zYrY&F_JV21>d-kG4|(wcz38!~%J0p>)2I?-;S>-2;HSn|!9Ghh4cRm~2J;6(B(iuF z7im|bz`hR>nYO=uO1f-P@P)R+x8ss)n-@ux;jT*gJ9|UNYfKt&kcqPIAKVQ_E{zH; znI*_k=ZE9DwU}a|XK#C@uyc1y9r_q1TY=51;M1VQpU*nJwc|7KY`E3b^tJXhMaqZC zo=Hek zR{yB;tnCz&O9oYbWWG?Wud-Bybt2Lnr+~Dk0+#~WpzSXD&F?I2baN>-UsLIX?g^xcXjW_&a9X?Pm?GYv597d;hRN(E+=1izF4+DB9`4t@`KH?ygb$$lI7N8L^G&Guyrbt8A&Tx*vpSRu|CH$0uvu z=aksnkJbbQJ6*WLeU1`t&?!Svek{R)@Vn*s;OTHPOeT>7E8$;*?8RjV6r3Ci%}xKK zMw(c8{`4Z{BN9iFO*UhVnL5vA?xYubHz`kx8N6QC5@>Y`zp!x#kt#{W6^swtqKK%c zl?;@QmOJm8W+$i-YgGPP{&mj3yra?P`^G_6^V}qMFT1&ZOE7C*N{Ta)8%|1{&B%u;|*%uD`>E~)JDmjs?}iS51`~N+sBGW-AcCvL6{SM zg%aLOix$ya@X5JEt8dML5mS8pnsHreS+%fHz6fflVy^@^6@LYIL0e`((!l8jh0Xqw zGWB&3v2ReNB|6JDq8e1M2m%4F4uD%5V4SF=tf7j;YHMNUM>=(rYweXY7~})!<0qJp zq&U4&c$^tvA|_5L>aD;$!}#LY{B|1qZRAwlZRz3N1L=p=Jlx9684W&+?&)nMPbW3- zn1-zTqJV`%-_J0pu$QBXg$&P09V14pb-Ss6ltDM1Fur6iv*k)xk}}X6 z_9HENLOZO_$vNgJ{c*Y{?W?|#pG%jUmp^*41S9fV**()}-?+8N>cjPKT?;Ur1H#r2 z?+i#X4M4sEqz+(#G#v)0RYN?12J_?rIY>J+b|iZG5bPa^0PF)!5%XQ+vV z$l)CQ03@gF4rEgQwb%Hy*ZxH#e}-WJ>G|JuSU7|RPJzT&MF7Ro-qC2Fi3|Rx@CDkS z9cp;Gc@j*#@b-=nK;uFH8SClk00>@)JWT@sH^jog?y94`H!VL9LW|OOba2K0grl^f zAkYX|2nwzs`x|khjp{dfPpblv)}jw>&@6Jgt`2~jhx{xTAm@R+zkn|Q=MIEw-~n*! z=}apbkmG+9`+tNV!O@8Y0E&t%0K@yWL68W9A_C$B`P)VV2eb|1@yiBBD8YcX{%Hds zARG+{>wnr{NF+?*pbZ97fE~2K;WTXbdn_Cd2k7Jh8v-VOpj{XofdY`|?|w))8hOwU ziI4{{;{iW_Q2)z@1faqJKQtQX^}lQiG5#yozv!4(eH8E6AZn|A;6^CsW{Bu}7me`8Ni0PX{Qr_E;*SAR#^XD#=W ejMKhtKj$gY8&B~5ITL7!kZ2Z3$qNQpmj3{>KvM_+ diff --git a/firmeslink/documents/6/2/9/2/6/62926-2.pdf b/firmeslink/documents/6/2/9/2/6/62926-2.pdf deleted file mode 100644 index dcac6ff82d826e2418210908abe701073ef9a7c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50805 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

w+<1 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 z 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

8Tj?~IR`B6QQ)iuIqlmT7mg6$5a(>s^

A}1pm-2y0zDO+)7!$)6rQaKYP$% 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 diff --git a/firmeslink/documents/6/4/1/9/3/64193-2.pdf b/firmeslink/documents/6/4/1/9/3/64193-2.pdf deleted file mode 100644 index 088398d4ee5ef4b501bca0964ed606e08416d530..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51609 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

~8^MMo;|XV$H>C@9uTC*f5u&{%vFLRI&>p9mW( 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 YvpkZ9145)e?*R)*02A0m?!%>V!Z diff --git a/firmeslink/documents/6/4/2/0/6/64206-2.pdf b/firmeslink/documents/6/4/2/0/6/64206-2.pdf deleted file mode 100644 index ffaa896bed57d86e86e2c7ec4b97b439d0b39aa3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46416 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

=2l)#aMlT+-{cNt3r-MVMM7;PV7XEVA{E;V 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

^@%e7MlER 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 diff --git a/firmeslink/documents/6/4/2/7/7/64277-2.pdf b/firmeslink/documents/6/4/2/7/7/64277-2.pdf deleted file mode 100644 index b4e541252e83f53b734f6eb819b208e72e7b7c95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129724 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

IMgWZ|Ieu*k?tmDM1(Ca0BIRD1se7MS|E6ZmF) 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

%Eq25I1^> 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%0DMiO6Xkt3u#KJ)C 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

^eq_v90kw~y%R&q{zQ`)SXm5( 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

BUn9A7K%d(`LUY-`IHroGAQ){TKr5lIG~>kSHNB zB64z`DGH^vQBn40$;t7P^O7}o1flFUkBRLvv7PW^p#EXjY*l{wI)ZqWFtzMkbkp>-s%fI4yeA(Qz%_u9bHNlx?~YeeT$m`4ejn_4%Ow z)%P^Zw_SeP>eU1DdoAysd2sJ@hn{>A9mOXM*|4mX zwUiP0;EtXMdGL!`ktm8idkdo-P6$N-}vE;d|;`{|n8`kG? z!@=`!*OoqIORPc4ARE^=DVK_Kr32g9KNCo$j>e7E&|B$74Fix~fMDGB|P)99aO89Dm7sOhWA20fPZ zly@127n*I`X4MY-KD*U`tj(kH8W%8HW1RMA{IH?iz=mh?-nTj+h~b>3dLrTwBaD;6 zf$tV>GeRdZqVAsU@?$&w7*c+GOiU+~3lzoq;XQ*CJo}T!(tI^^&)DhFqiQE6zf-s4 zQ22iN$b*i{dgtVeH3HlfAr?v~fSWpZs!^Y?4F*BIx< zC-p5D@aSWYuNvDXHav;CkhU5!bNl>f=B*1vVtJd%*U!oOKG^?kS&u9+!qBn&7g;_u zOzAa*t82jH`R=PJhGr}5|;nDL)NxUJfd*>{42Y4)vOiD%I_-g`RFfRuPA5)x{;3Z zxFdv~o)!%CBY*aXI;9AcGuVpULaRdvVoQT|1$`JK1^Fa};wvLU8?*0Jk69C@A!^ms zwAxDJ3!|pEvySAXT&&%;-(qg!CT-~4J!<##%@EA{-ak;ep=+;!+*t}r$?6#jSrA1L z2Lb*O_-2BFfVyQ0(&*qap)Nplt#}PhS~Zs*>_pK%Z=of4K&`+eB$5;{B`oDR`Ofis z@>d_QDWCu6jh<6>4|!4kerw%3N~L=cFzp%e}olH3k9YjN|TF6TbNXr(x9DgnkJVzrrr4)Ah4tAuzQgChxsh~k;yx&xhY8&5#`^Oo6;x}_UP zn>b;r89P0u;NZ9x=ML_wv%gMRN%hZwsb;Jsrh5PIuJU%Hq(Y276z|XGnryNsEX2ky z8`J-BW)+7J-7JllJQpwuMeNv~>|yQ0y^La;DPN41!eitQ=9q8{Q^(IFHhJ%0<%aG( zMeDY04c7>-Yc6Qm1wKhaKf>hLAajs;a-LrhlY(M{bAt%YB?xFPK;;RKh;U5Ki?9j$ z$!N6!=NgYYki|il2tRkD6bKh=7P6;M(55O-NJQptD$=BQ${v9gr}I!>hGbm$)}sZ3 z);&_Xd*kZbm;={8+x*PquMa+b{gdzh`OegZ#n-eKy7w;anz5l|&b-R1%|%Nxj77)CLpwyTGHI_SA4S$rLOZ0m(hMF~a$#3PU5F^TBuX(1v6>NAGFx@P z9@aInRk&^in&Bem%3wOQKe7`Z7HIlzM|RZQiMjF3+cj$+5LSmyr>h;?O zF{8BBhsbPLFBEr5g6102w2QR2YqSxK(v87d_}@#`u$uS`ho!(t0r2b(4A~ zw@w@446ps`fYc^3^g#C9We<%?!7s5|-gY0d@Hh>8Kct=G^QOqc<1|(DIrk~M^*6mf zWpS)l$2}dQH*TtUly&8*M_Dh9)ttZ%!Y`e`4QOQy?Nt3`?-I#l9*nBk3=QKuO)<7mYb%=n8)Y+T(>_Mz*y-m=a_R%_Db4*=NS0k<1oBSpt zmuP;$KGVpwo;33P>-zAKOMD~Wzpf(;!+kU_@X>5lN2dSMj#(e18MmPl>(EOJd?PDZ z23~$T*<{BS{>8}VKaIS+$<8g*9937N$;jA`5&A9)%|asUFJ!X8$SdGGNav$5u0uPg zy`|78B(VMn^wM+KzozjWc-Xd)hYimm@*>a^72dNeou=9$0r3|8x#B~mNX-m>cJVw$ z9IN@BpIrnz!Pe@o0)dszF22d1SgyQNfwaNC(-^DuY05jncY}o?${4{-#z3nZk`Oco zqys__n4PkD$_U!={KRr9aH?-%1mh8r3Fv4@qcom=fuC4T3!Ym6TIlpQdWn@8kt9*Z zn)}ydN#~o4HTU6TX@mLcSH_yxI2LNP@1sj|fS-GXu6e$(d{T+8(s|BB%2>sGEZaeJ zU*LQhn3GBaHaYj>IQJ+c7W+o*={-xzUh{L05d}K;*lT|7yYuxIy`E;0+|oz<++#HU zBzeej?mwb^kd(#4xuE#~}&+a`%|x44(z zZfgTMkMNPeZ|JSW`7Oz}3kp5NZ^~G6wMBn57O0||OBrkKUyN17`Ar#XUgKDaEU_uS z-PXLx`Ar#Xo^Pzg`|0BRri@k0$D*4nOXat$`}pm)W+vx1WyE6Nh)QY`Ndmr8oZm1a zaS`nl=eG-d2P7q+fG0^)aB+UaX!IoATEuUFxdy)}i>K^^Za>G=f_D+#_j#zg7)(3G zkAfn7fNxGCi6dzQVIC|<{Jj!dddLXf;KAo3@YQ8nlyz&zw_ggdW{K-}JV3JBj_ z`CgM#P>oZADr9g|JFGB0AIVS0EV?H&z47^Q<#VDHbEw9tDdi^{&+}8GtdpW!(K_)+ zAU`$uCOrvbY)OBo^d{t;-mhz8oN^U6GwqoJ$?=0Ur~$H4bL zRmSk~45xzc7M}+j-1>oeV7Gv4uZ(d2>J!qu@@~Fc7y0VHiCv*O4tTNEUBS74Oym(j zzFXiuKF%`bdEBU%_-^5OK8L*uh2H!L<(quBRIb&4#QS#ZO+E(Q%6trbKTH{et3TK+ zHFijnl*YiV3|kp{5$oOW0QpUAI?vI#LevS_0wSVRu4_9TeDY z*qG$|0N4$61yi9pgVVhKQ-8bjil{R!$KJ|#D)DUM1kLr%$2tXX-V&B^sCV!)FNR^< zo0{uFiEat1TL{h14-IJr^lC%ft5kH4YY)sbYNLiaFha7=Oe3U}MD#D_?c3yEM~qp% zWT@e_p~tMlQuRqswLaK9xW1+BOTozdF+u~qxN@N2xU#2qXQD+BkhL4y3QTC z_OJk}xBg44$_>34d7AOUNKdDjQ1^8mtI-|Ry{nUSfuC5}i`FC7b5_X;E?|KuuN8t> zu)qJ(P_`~~SEv}eG-|1Pom;%^W^Q5xY#O*B_5G35&bs+-(4e9MBHb z8#2YyblUr7DF2?E>yGUbnVc3fvEBaUUa{`1$fP#m6FSQMkC}(1`So~g^fL>F>fY3) zMcXamEz)j8Sgg^_+urDyy48bOPVMNd7Q_aB%xaSEG{_AGMno{s82mgM6aJKzKCR!R z-$TxQBv+0E+k#j|OV2w}fJ9J(01@)BQ4FDU36z}+D#aOrL;G*aob7t4YRrHGDZ9H4 z)LgG9&hEH)$x7xNS{&SB5sKj&->VnwLOYL3(CO?ZjmIx22a?}zGDaIysYUG5)=kzu zSkhLs>E}VjNKkPxg{7)g02T;rr_WU4JPJW_(tMAmBBQI}XV**1N;YT}dbBr+Mubco z>C`M)xpE1p@zJ2yVeT=)pd-lV^XSc18*yH|pE<{7vxc=o_$KOrm07KUCS9~H6+7*D z+JBS(9)HQd6}3C`(lqO1bpHWM@{SU;M(8Thl&D0wJCj;hqeq*&L`3 zjS8|w;g^%v&>3w>wPaZ&i{&9?uanqq3GO`bppX2KXH$p`$p_9--$_eFpP~E6N85JJ zi#}GQuv)?v*UO~~E2SBM!~1W}kUvjJ3z^jZK-M6)CnCOe)a0y}lKaNzXm336^qToy z+m+OU16x?56FS_8wnNIWdxPcf0&O&F?d)MR{Y?-hPG9>7*(GTskcq%Zwliuh*cP97j zk(`;Bnqlm`qkE_l-EZ3!MKLGl%%$6ZBb>#kyM&~N#s*2gfMxT0CR?_P-)g(#^I^*8 z!fpH)XzcJ~AUjV0s){hc(~_FajsjkbU$mbHY)kZOwFx01=&vP&m_uSh02Cc!4j`0k zL^2_}xmPzUi(G}=k)`?#)vN_nY9yjXB?Y6Et`7)4cq?Jhvfc}Qqrl#b+L++q?HQ&k zk1S8DO=RmMU=dIoO%>P10ot`muLSapzy>LX0=Guz7x)m?%4Olex%)v|Y z_Vd!G$K@}}C(Yf>+|R+@lmuu(S|pJGXUPrQB-<0Gi*v`hC+EeX5Us=keCV4K{Z2q(hn!9cgP z>)NOLt7a~eKbG&xEtoa_S^sUuSGFfIasQj;EB@uWy}5Q_Ih2IGd&*Bm`bTe@dF2;v z*v9yXh}LU2-}%?G>t@a0vU>5DN!U#&Rouo$eX?)2sA!>LK(QKH`YG@ zI{-vTBmD42qZ1YU0N1wxE~ycx2lqTL*`Y9{qyvNV3r^s{`%KooWPUaBnJ;G=)9RL8 z`Rqsev!5?tHLd+VR|7vz-bpki9ze=gPOZP-t>h7~;aEkP4wip_1#UUDr{d7?=O_P<*)Pdk zZ(geGy|U~aoB8pvYaMsGBIT=cJvvQ!ei+32b&#FfFQc1?VKlzBg_J4Me*Pf~Q%_bW?|3FAREB{$=Zlnsv3$ zpZ=eG>q9o-=A4m6XNm3xyv=R9-brlnj$Co|jcc8Dbw-kv1_&0Xzjt;oo(;W`{HFWS zeatPyd+gCju8%f@Dx^Y%I(QNkQ)G%tUlY$+C^1y_u~ z)E#w8+Jhg;3n2@(_+$aAV0IQ=f8ZUKyzAY!_Wvx+knhMdulvM+{Bgbg5bJm4^0m9m z!PkY516x2*AZWs#O30I!B!8p=5RQsJ_LO=l_>Mb=gI7{>kd4HeBe9xP+on1&5* z$tAxhAGwMIoh9#IW%epI<-6b6yVZAkA7Q^ezwHXW6FY?r9UL0B07NNkun7pOCc*A6 z==C^Mq&+qsDMkE)ml1yC!bSzrg}A5Maa;jzoi5RPuxKCI>Qy_}{I=!9&;WmXr-n+G z)m~=f-hOkyB4*wE$E^#+lPcd}&h?a}^3UoUpl~=S zTm}lGad+i-5*==Le2fs!;==(Ff^-yUtpfAc3NgBHNX2kL2Q(Ff4wn|s5#|)*;)1M) zwras2lsyH8YrL&VRfXP73apB>;0QLOQ4~Z!SIEW1qX%BtbMl3pF;BIhFw&V;xVq@6 zpQ{%f8!HdpR=4)*=TC~m`)wGs_LbSC?UP3JX@<^`vp#!rr@VUN>qT-O@zBi!XBQ;h z-2W6DO=xnC9d=`f15g*~PZ(`zE8apfP?sR9HP?WG2wnsuNl2uGT7KVVd&8-edq%5m zbFt3izvK%I;chW?M#KN2#lW!*xNq+Ct`_}wv3E&NP_yolVT%hB@9&PatbwFT#7ZW` z*)10P}`&i{PfqC>?)Ms6Ox>bWf&>S9jHDI32!mcyZ{NS8G3vHH2@5ob3#)2flFSbQqDQW;8ndReU>~5oC?u zw_woBpqeOALAnt+5S>ofH#Xarn%pHPmT7F3a?UG(QC^hFu2z+tnFj`^sy?^$mr$KYVswvo0)c zaQeErpKp^Bf!;a2%kr-CCz7jOm~`(Joa~epYB>@p=>!Cv)vcwgTPdl=TB$jEY(>T} z*W`r7OM<^S{GEA;bCoH0!Q9k|njUv+b6OQ)Ja4^^U_;hPa*)B_FfGrb)ln{zE<8F{ zhej4U^svyOhXuNb`UA&;S*PVOI{5tNrV0oA!xe2se{i9}Ek|ukMCO2ABB-zsc1;$7 z_s`txu9@_#T@>sGChv3adwj>ZB+;^y-AbG=AyKyPZ1^Dw^Fu5J)vRX(bk%^qW}BP` zm}^P$({aEjCC?P%k>^8!#i$4ikZ1s&@$s#AjDgPxmW)bRm#||!XLN0y+A=1-dj~14 z{-XHy;sz?J@34ZM&CRk^_$PJ5TVbOBoh%yqQKZLc4G6LX2LnO@)yDWcg##33r0fG~ zWrDIyeG^Esj0~~R-OZAcH7tBwy!(DgGE?l+x@fCkrM*~gv3_O~R5Gowqm*_O?-nz` zg#iMp@CX+ZB|C=H0LWSZeWUn`zs&GmTZRh+MJtaMiNNWgBXx{1pu; z;?))6Q4DtvdaqOgf0-M)*BD@{1KQ1`F{1BLJLxD)@nlZu0AQA)ufen zUD#u|f4Sw+37*B-_2RU^6^`-K*;AD}woYv*2WTEvY&EjENH0pnxwVByN4tXk6D5nz z1qmDBvW0>$YNK1CYWFYTI-7<2NHwEgZc8EqadeE&bvoIAa1-hBW4S2lL` zXmH=NdmSO&h{g!ws1S)c?UFxiJb&a5t3pNLC>P99T09L$v-phMNvBN- zzwBB&hc1PrtXw-AeukaW1vNMA+pl>uL9Sm|-|X3SbT14Xt{Z+gXXNi)qvHhskERL zSP9r}ZV@PVMhr9%ZYkj;Dp(VL>OVW{kbL?w(z?#Dz89JPnZX}U+;PBo9qW7e`BiNj ze%$!e({DV#?%UEs=s|m19`ZF5^*|QD4&AC7I{JmJJv!a}Nn^}NuU)>F3Gd0zUVZCt z7ubX=CqAPa1lUACY%Ab1XyXYFaYjX$k@;md3qfeL;|5=uHOUXOra_jo!WtyZscsm; zk`kSL^8l-IajvKS9*wHLRU=mXyt(cYdemGf>{>nW$>l-!ggVrNEiWGGJUV$ey3{^C zb@a|W@xTfBz`-xhQg7OdK7BVVYuDp$uIANF8SBSB(s%AkrB!VO^C$XAzb9P_Idnpt z#};Lalq|0T+VzEafC<~b7oK^q@G`cAwF9PMx|se+fnvY<;cnuf4z0w zK{hw0v_ut~!4av3aj(PxT6oGtcvm#}@4WVryzTVp{KEL^p7!T3tT z7M@b1`dEO+d@oH?h*dNQ4%i1sr1cZX%*Rq@2?MaoMj+1yO2KFgl=Ti|7^lD5la<>y4XMQ)lCp-qC2#!k-OFOio~?7IHuR8ZY3nY^Yvr1W zz#qgzz|){Zk3&U2RnC!GEXp0}-fV598&+j$r@xHtI9Dku-aemLt=8i6dCxAYx9h<`QqCsC=ticfhSZ&Z39^oJ~ zRhlT%? zk$QIN)w8Vcx+n6V7?BpAo|D#Na6-!+y>_n2don*MHp4>^shhZaDXyqvGjS1#LMl9j ziMk|6&SsP;9};A92Z8b7}o)N+tPXd}YJQ)r5U;bW zQ6IvYAr(@QRSY^D+=d-%yztAf9^Vz zLS4v!w0G~LI0>t1Wa@q!!aXU-1`gu$HaSf;q}!sO7VVGfp5?Rl&6#8Wa77hU^{H>@ zW$&AFmq#KdCoX-Org}Uwe#@%f*;&07M8-Exd6m&IznD*TVClYf&Px00{oV-^W*PTC zL$*3SMl;%tnw?tIF9FxWH({RoOX;n|4%`-0u7gamw-@?PzF;V9mFyVQYo72YHZxOS8xO(oZtHhjHk%*+U}i%YH;JK=Tt#QB%+JoV*8c~6YkKl1zE&a8fc zB_4T+2{X&9N6SAy_l3OX+)5_C^c`EZth#)yJp1+=9PgH*v2Q~vIfY8VH$Ka zr8|Yd4CwkZicIN;1`t1TB=Eo<9TCmj;b{wG*V{V|7g+m_W`3Dj`K?+y2E@)>q`A^= z%JjDz7`i0n)UDaQjaBEZ?_LmG6=W<`xlHprbPC?VHqeBwl>SC5)vdv*gAgPZ0G}yk z0X8*^7(%#oIMh6E1>j08t8SFAX{>FIXYGg7>~ zXRq*ZuK=?yd{WfS?2)~*nmeO{Ba++=?~ZtL*?_F99)ss)^a8%j%|1UAWPj0~)s*xL zUGCq!+ud7xR|QvCCl)Tj3f#MeRo}$VS(YcxA66Rt6M|nr-iZNeph`_1lupy zOWEwh-4$}=`i5V2my0f<1(H=-#;f>{e{BjdqD>u91ZaToz`H;hi4>UDBrtMIYmC6E z(n!E#=7r*<@4oo<%)%@7+R@XKM#M;zkL24>ed=UohY;+`jBZTDqrj!=(%5{Ex_3rz|7?F zm|Zks?<4QjUHt*Oa<2}R^cS#F;ka>J+Hie1Y%sl9k4kzFW3kzA0oj}a9LP%5?}Nnf zD~IUe`TNw6i{C9xlG5Wc>zv}9=!SDFH+5EdoG{qaD%26|2*yo9t=#;yfr2f}3Xli?sPHJ!FG{eQ ztzv*=wQ3ze=tOZJ`B1zN1fZ@x-HGHIYrGt7O`Koci-^)Eh2gm4kvBzke7SqmiX%H; z-*@x9og4N{3}KbBe>A}X40-;IyYff##|)GA_N?+On)$?%xadVQMvYv|`U4hVPtdDt zUVjVa$7#*l(mXx~d%1B#L{bf(7{M4)=EF5w&9uA_la>WZ+SUQN+7|w~S}ijpDhv-6 z8A)dqis7sxbY<1Uz)LIPVjxNts&R%@B?_?QE*9*PCe)X>0M@xZnw=RjaP+`_75PKY zT&{j+&$(#%R>N=Nj%{M=@~H=@<7bbBJ6?YJ#*y-dn{az7*bbw?i{VuLD};oiw*w2F zoX40UR5B2-g8>5FyQtg+DvoyP#heidmv6}zBit@7MUZ{C&vGoYqrn>Y79u~LlPjSHH=PP-+Q^QsM^z!3sHjlmcP1tBH_ zn9$$gbsKZX3s)c*K+B+p`x;6#62PveyIwvcH+=E=)XlH1e|h7|)k8|7#kZoQgFn=) zKmA#+>Y-)DkL0msTef)L-Co-r)pHr12$P%n>)dDr8|4=Yx#|pcXafBJo2o}aEY^VQ zF5UtkIIOWjxKP@nT0qrX^mG6a+2#Rf)x`ty%YVINR47{ zOPV-(=T0=(VVCKJJl7;e_7lXS2}(zXPtJkPV!m$y;J#* zlque5aBq+|Hi)9UQ6?`z(!DRy!jWQ58cr$vZ+^G*Mc{%&(3dE5)*|-H^sFz>R}Jw5 zNiMs~6&Bt_YSxVM-z@3gPJQ%E8+=aQZ;teSQ*#L;@oz?Wze)LCjo(Cs$1sY2vloBo zNDV2Lc&Emxels;9H8rtW7bzp-{%;PE7wUp>ViSZ^JgFC2NXQ$*tcJida7X*4@AH1@ z=b6w7$=8+u%aES$Cz|>5gXM+#@Ax>B(}r=hHR|Vf{Utt*@_9e?bNE(t=lSP@lyQh+ z*fLZHvP!=e*$r{Z3{Vd-9T{#SFWFFXLxFTe*@hJDV>;FscQ5|lo0rc0u@!uT=E?~7 z`tcEz+;18I`OuPqkMOhdgnSk>AdAjKYeP?PPY)lXjY`F7g$iG`At9f%=VKr%kf=Zn z9jIuUuZY}Dng`F_WPODL3KdOr9@TkJ?j}ZP;4~ixVWs@0%M1(X`#zqfxK7$lBfBLUy zu(ELmDi{vEMa7GP)&&|=K3xo;P?b-yx|F|<-O)&5XlQ7ZM%xAdm#Ds#v(0_$Mlsn5 zI@%rLV(gAs&*z3OwdY(&>&8#RdPAh|Ed!((cq)u|z}DOrikC>DlPA$C^P!Xb;K==v zAg|=V`>=f!EHJ{k5uTy9vwrM4s0aV@`UsjYM$r{=oEw~D{sg2Lo{*GM2FP7HBLiU_ zB?ymudTL|cv6J&ew~#PB&kaSyo#dCh6A#7Oa)n?^E=2(l0D-0)APH^!bA=Xuxo+6` zer7XN1e;mohiE)OL8vA!Ie3t^qqOvfvkCu_$fn=88UV`yA3n?uZ`e&OX!Hi#$Pz?F zECO!bN~23VGzq%Ry)da~zx|WFv9@UWztPOpu* zk_O2)2^JIKLp<$yG}2@ORaw z3#~S2q1DnqHvp>=5CB64IaelYv=!R1)njwySc552B2sWuDctlbnWVbmAN+{wO(Bh^ zn9$nb1MWxms!V*w6qs-H#v)M*7dAdZ>KZ(UsvnjuetUV=u|DG$#LJ&Xv##xf4UZif zS+--<&)ZH8^Xs-!mYiYLS`E_&8Pk3=uo^0>AC!tkp=KAjk%$;)lz=v$qTPOD3 z9lrkQdE%3MSjeV-?2*6PK4UESg>wV1Gf3wA(pNafIZAD`jVJi}afu0dJCb+*R z4r@>-a#he$66O(n5mf$fwB}AnuP3b*(HBW1S3B&ZRBGQvUJ7!MkW-jrYI?0Xq-dc* ztqKvoO>LjkVOj0Xpq$=$6XMp^t&N}X?BXporp}F6pLef!j(@bzQ!i3z_m$&Ax0bbU z$Dmq?!0)$f1K}$%!_$dAP{0~;O2NUFP(rr}5@2coSu5m1?Mbi&AK??0QOz4*y%!#l}! za`GOznSS>-t7hN1JdH)Nac@jt@Phood8{jVM0=3)GPEA17rF@(l$H19@skdsN#&;j z`VZ3y-Cp55;Kgv`lHbWk;Cc``*VFw%RdX?lyjS+Ui6%sy>t*aeJ<~?HLev|it+!f{ z=`}x!ROtlHR;~^2DBdbX{sdef^n|Zo2PYHthDA7J&1g2DC7shEvdE^ipyH6UvK-|Z z4OOBLEsc0v$~aUx$;SaLh03b^ zmPqRY>A}}!H>X7sTQpf0s%xWl0Z-5~n#=0C_-Ow_d zr5%2EZh65Vceyf2@E_*ldvIq;TQ6XFx%N983X zgawlC(;4RU3k<|f9Owi5gvtS_fooVXf_c^qyq<8FD1i_iFhV(Az3Ktwu7gZA^o4il z7cMSOe{9FdedqV>nOnME{_*AOC7Vyy-FW+@vC-_xt|j@4vsb3Lj&Co2C%IYOnyUXS z&DlNl!rm1-%IUs>uB9#EyGcpubc-BRxYMVfk^ET9@4`On6YZ6|FcHg@LY{T9;D$mv zh6w1WW^)>l%ml$5s6nei64hQ09E2en26*M58r|U$Txs87`P;VD$O75o^6z=O;*IyL z@`p!ZJZM|UAN*EdudVx`r0m4;oDp}%X{!c!z6agZ>xN^2X?kEEM2c)^VH+d9oC2g1 zJ8bzFA%-%mjG8dX2wl=8nlc17O#!XJkl<9S<#^J8{|I@ zyz#e3cNdigW!7byN6KgB%`AF(*H`hJKMEUn!M-q~sTeL_1V$1b67yqj& zW^hg0F3cdyy)*NNH0)WlYR+d%N|t3WeGRN|@0L7;`_FmzP;-#ch~}_RMJ@jRxE7IJ z+7u0tGq=JC#0Oq4zTzF!L(v8V-v}Nw%P>YZ*dnBLiu1gFmbkxXXo)-p0kgJUSCng( z?XI}HL_SblM7GgQc?x;WfdudH*-B1*IvA7RWdOoe5s-b{47ra=`7iMVw}$Y9a*jn` z)hW2SX^lLpA(UEpa9qV{jsu&D?V0G8OjO1=!yfj~@&y0iEJWK%-tbook1% z|VZ z?Y)CkxlilDX=DRLrP@zaU|Q)s5oLT`IAvIucrM>WpO@f4ss?Dh)?TBmrBOOGp{2hR zqSB&VA2d6PbzS0`a3?NL`U#PW#0lhA8Fuwg$fqwh(O963?YZ~1Sb?)+g|>)pIu;?o zY!Jgl#Bhy429LouDvw;RJi`1zoA;H&&W#vVl0qv)nIIagLuFK)z_E1PS^wmAljm2j z9$FmUs{P|5N?2g+sZ391LS~wQoijf%wxpt0m#$MgzA;Dh^_{WV=`C8P#fMCwv)umP z+u9b8^hrVnViGaY5pi*F2FIBrO%cIFS}Ty&ij$W7aMDx}iG%SVg_Ng5u`eCuCYp(& zwU{C|o6_x&zHOO4al!7D!{!m;c_o8`d-fgr{1a+>v2Ifr_blDu(6;H38K0Tv*MiSw z!8$&d*XOa)vB_C|=6$|ZroLiBho+U4_Mg!3X{U~uUb3}S2IhC~Al4goK=9ut!t)tr z4G%%gB^UtgCUbyjaA9^XK0D{bXXgu_|9N&^7xaD8Vg1uOPFz^CX6UT&79D2{np4)q z1)WZ_XqRSa!OqwhkDI@~SC>vRJJytlySNX!zK+u!A3}6X+_P{AeBu^b37rLCK--1Z zDMpykmM}@uM;guT;`HcPCFr@M9#${B^XI;~8`U zH%r*TtCt|1beB}0K^N-A)x1qq8w8h}R&;ZYayXpv?S=MK?*oNH>2yanlrmYm2pu6R zYk5*nlpFP_-(r}*Zj4~{sFczhlfNU7k$FZBWSYH z;(3P)XB3RyGx_epktd5DA3N^FF`9y>7EK+Uex~+Aw2Ce$7*HfPXX_X2l@^UXd*EX> z`rXPM^0#}ZEZ)iDU${|!>>vx*doMnWy0U^OEzFY1;a))*P1C{cMQo`zf1LvXPx@*eQ;Y+iUA)e<=68yGxwHF87<( z?^(Iv_H9Un4fiH!ji4_QmUS0TbeulQPovWz{zopTaHGUnq$gZMB~I2rQcTj`Cqp*; z1C=`BK!r|hjh=i?i45^7o&leTGD_4ID9~(~dY<e308t7+x*27dDby;6ya>w>=&MV~>$kZJcCV;g$+Dy6lhei4?gnT1 zZmGSvxM5jEL;Y^C2J3Sk99W0-F(Vq}_E-!Sy-gED3XmDzIHb%8S?_11eZXC5SOnTe zxX37V0u0AHBeG1lW>1&?F&pJ&m9KY@f7r}^T!&N^@z>7snXMCa_JZn$R~oXISsp3{ zh|gCS$fh4@R{qdJ`r@2tg6pHw(;}L=T`i?%Es+f0%xr>F(B#x0tuj>OAk0`L07~;z ztP5g$qQ$OryHOy|>z9MclZRLz{p*X0;s>69)mVoS5+#b?e15?{%%b)0p53WO=SRy{ z`0JXd1t&SW?(DbVi5^9zQ{R7SZ*_N!bAVP&?k0TTz^ig>ZlMUDW zs61;hPjQCZl4hewX!^5ttIP){;*E{J{n$`TP`B=BeY1y_tuz@14eJ{w?p1OhmPIaK zUD!KvQ{=||qkAuua#pOz%0ioyPQc4-gFYT?HL+-h*gbi<# z?}A=iij_w9vRNywTz&H0F(u@CrSWyMM7NJ?IFYWx>M~g-d zd$N14AurE8a9MT&24=`7t0p{|(rRtHR`0(e&)a?i_aNAw_f@sQCQ1?}d$K~z7UVah zD&CrFfzKR;I%cf}&TzLbHY8S2L^{-{8qx@r@ef-KVtYDXPv_5CoTfF+UY~h$mki4i#(pKZtBM%l_ z6s(CrXcnmfcC*>wuu2BR04Onl9|>FtO4m~I^pm4suUb?HjZ@A(+=<*kq~cdtR@%~q zRjwVW?c{&_^7ZGT(Umcq7S}BncPwt$^U@nBEgA}A{ETZ*tZ;JIm-7Gaesreayoz07 z*M^f~*E`ou>PrBx|S^8=TG*?dUi$EQ^3&IC9O*u=q@^UIQsgRY^FT=+&THmPpxl0w{4rYuArb= zZnvx9S8*?U_wHKJU(np!fxCh5tD|tcr9ijJ^(3~mwz4~s{a^`frH^ejGA}+kNs5kS z&e&LesNi&<{x6!B|M8X2I!l)^L=o3N$Q1V)l%QcD zfg;lu(l$}bz`c>_E@TnIH{98h5c{8v_k^Oqe^AqLT)(nGV>b>d9)4TwJ)t())U#_{ znPbIv+0T$a8sP0AGhTU<4Lze_$K>el6&p^t+ zh@A73c=VHWMoSi;EjZ!macXR+J+!IE%4=?Mue?uX%;bp8HY(l_Ep4q_51_aa4i?vI z=n^8oONKOI!;foT+WP9x%`-v|hx+aK?VEd(-(i*=ca|G^SIRa11uc^ueWQz(1hp`0 zQ_jlUK00&rzwiBTW}gjv?pA!rQknSx8^g3~zPk8FP0N@Ol>Rw?TFX{f;N;~s2!v4S z&7BWH`eBGO&=ehj>Qu^|S3sw^=}31BF{Tn-;6>kL12{sO63uDOKr^Wa%T&wCcC7hr z+sLwJ0o_)}zZyqmr)G?sSrq6AMGVX};*EKeM~|tQXg_=K5}R*X~M|t)|Rh;)(Rniunz@#r!JqgfDBpic;xG z_kb-g&A|E*PA&@W%mC^(n9V_GXe1FI@3WDTnaLtYp?xCK^WI%bUv0Qssg z<2<2uJy*9hDA%`&hJXO8)n7ED2Lx$7O4=$GpoxIz{niu}Ov2HG1Vnn|0k(VJrGq8z zGxENfuNRlT89S@{k^L9s|7Z>{oqT7PY@#$)_Mcr$*WhNEq!+80Ot6LB(7+;Nf{>_; zTrZs{#%WBjKHT9B3ygn@)1b6kP;VNp%{Nj*!T}U`Y2wn24sS-52=r~}X2JVwqKh&P zr?TOvPQN`pdWW3fB(b&F)Gj;cS6iUizk*GbE9rMd{T**+>+|tT*R0xmp(k-X`My(- zdliW|2;@nmDKHj29#Nd`t)JJz8LcHBw5nB+ZquHA0P9fxE%!EPw8{-gk~jphaCCvS z!5Y*fGmCT*R^gZP!o-Sw@(=QbJvQx#5d${#%6#Pwc}L)8RN3Lt;-*we@ z<>7``*5toFe`?;uSH_Ic6ukTD2lB3qV;|cKhsfuZ`{kQE#?F6*MedyOxR)N}M@FL( zmC!VTg|M&~3d;MN!3L0LLLz8VWk?gk8qqZPqAGPaaO-&2_^+@{OtDYSQ|oS81v?)K ztf7&2EaN3N*M^M#3v>;3?XX4mq(hfOo$Q`=@#=E`2dk( zHD^BFB;T#BT$oloZu+5#KujpjTB<4d+v$t)E3cO-V(AqJZlgB){@06({~RwxEhU3Js~oe0sQ9|!s9yjCNZA!2Z_%9FfV zuQ!R4{d#g*$Bf52k8qLgxM6Wx(WL3MllnbBW`6nk!ClvP4IR_#u{j?5lz~&S<~-4J zHkpp;o7z^&zwET<^jk5bY%5#QuUAT1@6K%y>`?9r^39Xq2=`qmxGdBOkS;2IOIz2O`!{Hp71bK19A!dk>|ZE!a8)lH2VR7 z1EL-p@Dy+;e51H6Lc@d2kVj?~LDXZtK|NHl2dP(%yzibP`f<4F!s8{h|0fm$`~t2g z=ex5l$(~{1^7ju1WY|Aq=(A4~m(IQO)1Ofp;=!F|;1++}&9J_7NS@Z|0-#+WRAvqU z?-&EH+}yvQDm}!iN^~X-T{R?LkLgH@vAJW>k6IC1B7}1P343>BX%;l(SN82yK8S_o zCHx`Zdv90WrLw!y`H{WyM)g{ zSsE|26b5=y!kRZvN^m5M%CjUzB#p`oG#bz{*I>|Sf+ARuCL%&`INX8|-L$74?jusq z(GZf%NaZ(#7B70mN@uF*QV_A24hl>Zr6?|*dw{83A>5>y8nQ)1%_|=Ogv-z}H7Prx z{hYburw2K0TfSO>-hbU$;lfg-^WTCqZu!4oqx0XH11SrJ<%T(y^k1@E_mceSuI2Og zewF*g2DJ&`Z>QUBpTxTW-iM(MTZMY;4JB#JD3*-=R9FK6`;;ck@MN1J0;8hR+N8nF z7#eO5AB_$vX#pv@`=Ql+kBlI{$lNs4Eu>j2xj|_#Fw@fF0^@Le661ht7l`Ine~x`} zTQX%N0OY+(M9ZW2EMo4ne(zf>2nsk0;M7pLz-wKyWh{Eg(41uh(;s_j+>+|B#r}G< zW$&8UeqPbx_;#-y`{T1Adpq~uKX}>ZaZ@+D#pTC4=eXS~Q<5GV=2|$kcX;rU{#Tw% z(6m0f=Tw|)PfCkf`9u3|=JMg*_wbSxz(`LLfPWQX=Bm&!GrMJG+8bu38(?Nql$iyZ zF>SLs))9+-!m+?BMAOu!w-v7;LD2^N@?qv9YKIN>s%e>NH19;OAUCZ1OXSOrrVcU?sp+OEidJ!qM4YxKN_uCnbs@y|OjEC73e>Nv*-H-#s zB~voISLoUqjodU>v{NZz6@t+A2%O|^mcS#t;SpC!luMn&6I}{T+a3K$MyXm9tzDLQ zU(X})_tE=Dd7)$O7gzsG{pm7KR9mqlD$ORJ_X5d4MyXITO(fT$&n{Dz+OicN_2}Ic zRz{f{&)EwQk}1-VUDy}xtz)i=f4n6BW5wmQ?znPIBx_O8a2c7ESiSagm?j#07y^45_#%-Ots}_9yMU;+E>wD0GfnVC zRDcmEkf=zb1E0v9H0);DhLXqTr1US?|Hj}DKR;8)F3fYX{^#cDVOgG->MKQS56>Uf zv1HjosYbT0doF(NY|(aS++*FwjTltkHXZ^Soy>5$GjY28aQov_vFSP?wNfM#x-lk2M_E0p1#ARum3KU7=x;dO4j6Ru$L*9?fi0e{K@JTCiSPSzBRS zH*EJJ0$ypN`zE&c&pSN+sdWzVKwisr#W#Sp;!}GMd^&eZ`O0>j9;^b<(;U9P5O=eY zd2Xk}5FU>9N8x5VfPu`wJ*!@tVCF-Q@BzX!YCKIz@>yq@whXD{|03?S_~%z-cka?| zQSt$sl=&BA)}P(K1J0HUQpY@Sn;k3%+;bp`IAGOAnCyjlCVxT}!2vV`S#k}2W{xgm z@}Y|;-c=QZt%*%7HM)9O@#d&4Qw~pGAHBYyc6qmqf}W`xSQc{-Ei&-_QBz6zYr4F&p>oQpt@QIKOoSdHviz`1|9qLSJ8XX_s+hcHxqaPnRVPTTk zy8fRV8+M7KSy*yJR-7f4l8pr;Zd|Hr;g~>zuO=Q0Np@?K8hGv-V=a8e?xSnv9cFKJ zd*(#l>_49B)20X`Qk~3Ij2J0&_rymC&fpNqA)&jl!|XuTw*$Uce`?Y0kFumN0b-s6 zf+Es!6)B>f^e(=!M16QginH4#Vv8hRg3BW_@cly{Xgi-(P9c zX_)<3PtIcS8oUv@w>htULA*vXi+;vw1!A5hG`zWgj7ggq4g=aA?g)b9Cj!0DFx;6% zYyT(N)d&frq(CW8XnJq7E+4d|#5L|Pq*)eKHc^x3WHB)~mNDiqlZon9opjW>IPyU2Lp zVYxA{8h<7K>)h$tou!Ts$%m=G(v{PO+pY%u8YBdJ{2-)*3?@;Jl}aOzqvC93%KkB2 zubP@~F3C0Fp{4u(eVL7j^k1RreYZ|3+Bc>FeZcEipKmQL#F^lESLkD*6Bpr3koA6B zR|2h!P_{>T+FP+5kyfTPT3Mvd3UkV8vgBF=%(+%8Ga9K|nn@%89kitcfDWKvG{KAt zQAt$OCFi~9;8gLdaXdzc)OjwzX(v@s9V*XO0^p1roT?dO)mAi&vd>?4>hFNlxi~Ib ztd5p-S?p7n9N(MWX*gOm4RAUOXOFLbtZ?>MZxNJE)!I$+l}dTH*sOT1f}yjHX=!fx zupYO7=N#}%wD16S!)$gnYX(W&%n!7_ zhv*7&FWEh9Mhzqd?{GM!q!(JVDT(X?D)PKGUE; zPE|te-iX&<%^wzR>F;>1+g`!z*xvB1UjAoWf1wm-1oq8_cJML~KGkYiP1FX+GIDSL zf>zx4S4nQ(f|Md3^~{0!1(Q~;)JP9N<9|r(GB;$qZS{gdJs$_*4pNCdn$a*b^gfeD zM2$wQkWmmtP+C#16Bt4B5DO|FP?-Qs3FuYSA#1c7K^}lbl9EWA$b2W1m(8|3S$ zVPZu^b4IVIZe}tDVjC&Vx<)H*Oubj*FX9pm*^`% zU?oS;y6N-Z7=xdNN_T3d#&WD;+Yxunj02WvYeHN=*ASb~y(`ehBD)$4*c^jZfQr{{ za{$eh1tX8?iCUJJdg*ahLcaq(308pGX8v2K%$U(p%1LPnmf^AY)gyi*MkagC!cnmV zF*2riqIFZv>wS!Wju=GB{xd)(<>@{HMi$G~8pzQ$tRHZ4H1Id*fcb|b(UHzakC(?t z!xSuLzGcWMtDoxKCuwy8G52`2GOMpMe$ePZ>HFw?%u@56BK+!J%NFyJ(qHbLJKU+K zQ0OFq0-{AAHv0M^>KuFq5q7fw0LPHoGCWcw6V~Xa$tjba-O=p8Q%f?2Qc)kesWN(B zl{}s`)uAse?ido36xW(_hataw$Iq(gquj%ycflf=$RXSX__Ca)ARkSLPlzvX1`9L; z{G&rOU`NLdTVwgPbl_IWai$=}T=&QX@9K-33CU9zF7~%?aFsyr^14vd>s zihymt?Hhb4Qxrn~x6<{2j0VL<>9iWOCZlQM7`@RK*Xwug$j=}IMYH@?YN2qG4#A=4 zfrJ4hV0x-mBrT;VY(~U$Yk}$HdlK+f(*J}Izm>+`b>d~~dV~M+vi^Cl!y|IP{$)L1 zFf=YTZ3f*Vs@=$u!d;xcI)6Vza2cF>KOpH~FmBncBOJJsy7Ma#t+>9U0!z9-x7PS| zr`X?b{F15uqYHRu@xWX$hDH27{{8UiB#Pp0fT!~%P?tbhkdSZVYw|K-BTVMd4hJpD zdbpjk9gbnQlmSZW3Hfm=dhK?RWV$;D0rEHP*kD^fv1J1JZrrhPn{4&-H(O)_iGd_7 z`mnELwfOPMP2`xAOaI^G`sF$`lf=)I{`R}KN{V{b(DfMso7+B&(ncwuH!!Glz@P%@ zv+7L%cQd&~2zHTVAS9N~K_hLco=yG2vR^aFfDk2$K}EdQE;)E^%+O$R+4gP5!1b;B zuHOCTQYg6^vSlaPyKXD-`*HSxE*l#&UK@W(`gG6VZjezY8aFzmztYjH!J5%JykXR4 zN}+0@+x)43@QKZ_YEsg ztn~e|YFDIFE#%KP?l3)5+AB`FDfymm8j#0Na_!6O^UYCYq4orAZh&nd4=bYOd`@r* zy%)6uK%PdgAQg}R5T^tJ%V#c3lg?b=M|{7sxu2JhZ~*{Qd#OClPwxL^Kg^|VA4H`r zv=f54=+veVlU@kaD+Bxyn*grM1a#_WiAVu+N1MHFdEe227tYU7VAdz+tuE}Qzl9ag&BHJKm!C_VP{ZPz!@AdhTB zS_7L6;*xEU-Vqb3_4hX_EqWjDHiHi#l)qshZmp0G2KbPe8~VpYJ5flLkk_0AY^zBb z(uE8BsWE5P4)2>WaO9GtEZ&s!kJ0z%xthcu_pJwx)s#u7<3czjAu#Ky7bH>*kOF|s zqZIT^hjWKQFa-_)2Vkh=sg;%HPAGo>Q;FnqKW$R7p z{vb-j?zIgSKE)ndKwq8CuD(F!)BD7981MhMBfIKRy(w^ehB(Uf$y?Rw-NH;nS?!^U*77d=X>_T&RVNnm8V{-Pe zY5hyxV|=A7xwLR~Wz~R0TTK3J_{J*04WP+EbNiNRZf)b_-!b+Wc!gpEBB9MF!W0w6 z1gZ6cKEM_L_7D&j5a!4GK~M9uYIRnT@HBda?_`mYwH}z;sjE;9&&OmagpzEQk)y%e z840jZsbXYL5fUk?FI9^81FrAFDe#lwz~$V&y;mnh4|;#aYiHlx|IyaKgRc#>Dvy;s z|LW*T(}ZJyf8um^j_h7BWYUNcy)vGvd1g(0{eY|&YL~ZuJ7-;HO1hI#3Ea?~IMYBr zb^4eH0%GMLRnjR)HGtMc`p*zm6R#51?7aDpxug4U9ys9Xvs3q7`}wO4{I{9^-Z^Gb za?h%yes68RBHbG9D#s~CZl~}m`axWw(}x(105pZ{u2#wYvsIKP;Pe$A= ziCVw*S)%yk_NofP#ei(D!@@>0f$&PP=rWDWs7wB zHj0dVb&lkH@^4~seY4}i^Y854{KNXUq?MzxV^c;9cBBAH_;1pvuSs{JBT91O@6wI> zE7FUfUcCJ-nfa&le{xj~osg28Rh;UH4hm#7zCU2r68Nh{Emqne@lDH|BZ3V&9Tkhs zaoIY*p4qiJqKl5m*5eyc{m#*9=81vXx}E{qx@b$b4%QSO8~}w5CUzaLGjzbt(CN$w zS*2b(=B;%zWY03V!<+GKe9S`p>%pdtNJJdCA)H-52gG0YgN5!ct#FR7%<{*J;@E|-8XJ03OmHw?JSNy+Ldd8`lAvde zA@ET<5H>E-9>xqOjBi7NkWG2apA3zZMSQq520=LX>@w-hFhkj5=h)sEU)#v~^3i)| zT)Z=E=a;pGqZ0y`%@`mTP)QM%50)0^4_LEVXP_><+Yyo9Twg{^@6R;-PkAY;qS8k9 zj%uFu%=&v9dnZVZkQJlg`JlL9s0in@>L7n0j3Hq17^6b3#-W8!uNQ0rPgPPmsyP5i zbMC2NQE7}eR+|ySPJynnI1N%LHJ(1y|NgP>UJTzJw{b<;I{u6&+I3)3A9LKO(b9v} z)l`aTc<03m8+xI{7HnwG>vup^bQ)<~lRKImLWNM32?#3+Oao^1sKe%1yRM^mO@F<^@a{>30DE3I(V4 z^V5J8{)&^JjGSAQgrtT*{9h+NfUB@r(luF!!uO~Cio4ivgx?rU^0pBE*Gy*b7O9C+ z=iP2T6O0=aXl3IG5CD6suvj#l9BcF|mIJB6Goo-hB8L0>B>!OpB2ig4!r!<5nh!Y+ zg&(3r+V?AN^pFmSWhts`;75U6B;rXjoL##4`THTi(%&~q9|Z|Wuj4E04a1=KhL!>*g7xCOFydoFy=xE~N3VArME%#$096tpLT&!+Hihd`v&SX;L|QBX&S zZQ}QPs_L+m#N-XX!X;$3o)%cdDbA`Y2D9nOrNe%m)H5hH2)?LTLoB49*w}DO zIK(1*xHXViERcLG5YH8UUV42pR1bq!9E40Wz3soA9}Pfo8)anRRnRru7nr5m^)$*x zsh?e*Gcy}K3A302y3mocs7#Y|*I1}pdteBS!JEQg?d0CteERtBsL14+?+FVLj3rwl5D_$csEX#&MZs^B!u3Z6PVewAyVKGSyKAvoj(0+PL3V|V{ z!flJVHYn4R=f-S!Qr;t){T3(PS?-sZPWryMn;J)WCpA!*W8ch6REHUmBYYlijf*)b#W5Ofle)!*QMDfUxvO6)w ztrj2!gh6|D@N){C3=IK^KXgi@NVdHNgpCQ4LAx0~d6YS3H!}^cNs#_0df$+&QHP|@ z0az}Z2+K6SZUk>ktK`ytm+;AC4b z6SfCQ3VM^x1X5r!*`l4@VhlDIhHT~_WF`lhJ+Vi!j?5^WJX4Tg2%y+N*|sMWIuy{s zCb2{kS$6jKm&Ghdo-o$BJ%a5C=5*c>U0}hKt+u4GZoltlqTDM73!j+r+8gDy*N%NX zYt2g~otDH6*)EJ)x-(!3jUisSBJ-&aNZwf%KK##}>gwkg)NF4Uo7%B7ZdmgN8xm6F zcw*9K1^;fv9y_@K&aS7 zAfIM7dmLepVO4gC$sS_{QYZfbBoMPsmJc?yxFX@MBfbXb;2Y{nUe<$oLia5Xo7Q}z z^_y<{D+l-O*K2S=;JtJD4=g?R@0v6*E+?a~Fff4Bo7I!voUnSc1#W0|77)5J&z3P{ z>E{3q5H37^=j;*KYZp|AJ%XFpkO^Gbb;L~qKlcjoqhE%J9SJL`whlR`5O)Va_`%3THD>BpGfX-kdQg= z&+f=ZO-o)oX3UJ7k_DqD`PHSF78p)E#8OD5DCZu5MwS=u8YVA>_|O|D;frRx#z<;rXQ<=3Bh)@Bz*uEHuH z#}cKt;9f)dJkCqyr9%)jz!h+W-PuUglp)_(P#<`a;MQ}0e@SpmYtEFC`kx@l?jJLo z$>)-tBuUp5E%J9NvBiK!u7H*oMI#kM!pvbX`iGeVt-#M#wVNxMR^1*K09R3$4x1$| zKdwEM4W0~nGbTUuSpJ6^>k9Th8$OMOzD+jt&=fUKeXib;truo`oB+~}i7_?hU%G?f z^6Qq&s#`UD zI6$g|(>U<~RNFCVl*ZB8^+c0TH}d$5;6%2KK*jbS$7zDE{n3nn&n9eVg- z(_mkp{tKNmmTE~AuZ&NaaB9EwqF5tc8xh+-ao*hc6!dfiJzao1z(!*|12oE@(I#L0 z26tcb;r>-`jG9sZk)HSTIq>itpMpu7>_ZPNZ0?+%!*P1s4s+qWUGW3%T>uyE^qXlWX6H&nt${bJ@+ttVK{etf z6ElK7LqTf@3@ILJiwP@@ZcUzYmylk4)8n7Az5B-1pj98GC&tF~iH%GSH*fH-6dGHL zo_khN9N#xSGOiB=ePc83E8f8s!P@H7ngVq`dK%4oLaH2Q>xrmk(LadpzL}aFmL6HO zIV`W~*d|T<0`ZP^lkW6psakNZ96}-MI4dayS-FZfO-^rZzRsHteiUnx>ZXVzPN77T z3dD9u2J6wFGkol38*4CjHYwHCYtL*VWv%B|4je|?<6sFzdqG@)Q{$&MRR=!Nq5}eV z=QcaeCC%GZ)?~(q^$Q=jH6*X;s@f5sls4>4AN3U0$+;R*-a4U2aQ}c6p~psD46mm& zWG`7MMxZwx^JZ$1lZKk>oVvj5jVUnt7KZ|xSQxhpSoQ$B1yj39$iF4s=r`o#PHAOJ zQ}#2#LnjQ%+?gU?m0k^;HF({2Axk{r-(`fi$z<5$}kx+Qc0sMoD9uj4eXEn$sy&T->!U zuA$OBijf+*t4j} zRLiuYgY~PXrHvgqZ0yMhp=EC5nx~i64W61la$r^BVY(0HT#D!?MuJD$u43OmBrzcvAwThPcEVi6k(Nk{+CW7?|?Nf$8MlD^i1WHb=PB+D8yu zTj|bqylrS!0BR3;!VdN-E)DgZ0qH(N8Z%q6?|(5-L({FpvV*t2RpJFS^uUD}`hLYm0+Y}=3V3}}7r=jZ9O%JygXH!GFi z-tEt>#j`2w*(I%u!ZhX)OQ0f!nsksXf4k-g;Hldt{ zwIOEmjpfU4U~(-1@s2W^Ux3fQYes*+;4 zp>0Q(Z#u;&KIp%ejj05eZ_)dls2z$~2!X)lWB3lgM$t<}jiv~$u$b##=WHGYf zO1%WrvVt5r)h(!+?$Rx>o*Ym*FjLJjtPq!h+eOI-Qpi*mRTOL>%2~w?gBvH!p3pd; zL2;*W`SQYwzj|2eR@OMd#0u0n;U|IY?i(yfjIV4Nw@@%d%}H=)(Vv&@cq#nU^M!u zL51nO9S+$U$6S7t(6<|FP^U9x%9NsO`vz7F%jsT}I%59SQc^`ecfK-z&wEk5SJ)CN zrk)t(x{KC#LEt#4SdF_K;PmEjh+)?P9gK6t(V84gZ3<_FIQWxQ(tJKZ{H3bXTPiNh zsl!dc9K8`G2Q`h019%C<6ZvJVw){5Ah|u>*eU)&a3Xq0Rw9(aR@U)@F%e!`RO{C^$`DX0?mc5Xvn1zc;Til$|s6!e8T|uQ+?whtd;JCgmN~oy{o(8ee%|z%c)0K_iNGqpa-ckOK2q}$R zm3|<8n2qaeyjKH6X!;&7p;RKZ#U;w`Q5O(Sx$A4PX3C}QWeBufvJGGRo4Ymw8f*61?A|*nlP=rfyCO$4q+D;NA(`QrfG^|;Hc5>(l zI=7<~MZv1nL%iTA!G~B0TL5b(LZMQmL_|nu$SsrWRv4Kf-Hf|4^|Q@uR)G6#;0JPl z5?%nW8Q>c3LL7s1ig%JXg>{^YjC3WtX5f=M_@tVCB9!ts=qE0h^ep$6w&$@6BU+FC z{2J$T3L?zfW{t*d#_9vrvuzWpC&@|^ICDtbEZ{VIA19oiiUSnfxvfC7afcM8xPeC8 zKt-_vCkawVoXkH2CoJ76{XVQ zZ|BnI$+z4gAsy{&fw}8$8SKy3;qUOrgXCM10=U~9(1xYyg1_e z_0DZ5pm`X?c-qJlE!;pGp7+_?f{ndQ-)+W0D&Te?53!dsOpF(t0?)p{zI5N~kr(e3 z&+k(FNLSLEog}bg2UJ$NqziGH1d>Gj6}VK29N2Vt=_me(3(>)7)ORZJt*BnU5j%Yu zGF(4M!zwbwg)l1Y<1Bn~R8fLYo_76#Y6xw4${2oy@(eh)*PCo*(KcL4^@5MB^(W<- zdivIWy!B7T_joJU^&xGCds@MfuJG=vAV)&epwB3@k|8rxcP`(4pfQ9Sh?5fip z)e^1KTbHGEdindSE$S#W->4=t)aB|bwV>9jRzc@0)Nx2eViMlMMD#o!w?Xiuk=ZIcQ--QDh`zL1D9Ijs zz>YSI%jU%P=}+(d73h6qsm+d8whduxOFtRUK2gb^aNUIq+|TS2?=}Qvx!-!?8R;6N z>Oi*yUiW`U;M?%*5Vr)rPJUL_0;puaA6h`W1WsU$%;Yj5kE*cpUBDx}Re`E#m2g0H zQgvVTNF}PyDG1Y%in#@#co5`|TY_K*iHjMJ13x|yJ3#NTf~HBsDJZ@3W$?QE=R@wj zQzCnk8q!r=L8Z)h23K10zfagI{>doNkwXC zb+~&lLdvBHTI#zYRryuHccrV9q!K-}EfjC@la(cm1}Wlk=Hfn}ms?=g&NBXXVO2j@ zld?pbL2P)sMO;W|l`$1GFvThy+>D?Pa6TOtu*#I=o$q=@{`o-QKBdWg@TULjF7)L8 zRZ41m)bFthn3JC2LJz|J*>1g*eY$Ct0NTSgrah>Saq*zNjBFw%PAahSQC2(&tpQv*ux&SNEIO>IH%Km6G>$|&*f_OW zDy0coj>uj~y|tMKGJ~Fx0s|V2$!WwPomssUyV6$*1h+0gzJ=zvQtN5K$SfH2b!tb3 zE!J<^0x@e}U*(`)h!PE)HdY@(hD$fX^iE@A0CsAKw1ZnlHCnEub=}V!Im4T%aSK(J zMm^B20>6}=mEyVHZJ&Xo=CzLbd9?eP^UdDg9nYMX(%T-lt-+m5lOoxD1o{*Q$_Qy< z+281y_*@zYPdoH-GQ4d8ed4z?Z+clgnm2q7qAV|Ay>8-8{K)p+;?yeQIU!6{tXiNF zU;!HM_?#}W0*99d9!r7z?VPFvDJ7w5vb6W!J<6XRN{vLs=t4MTZ>qfg{dGZp@uK&t z5WUW(<6!{;JNhg!=o-!v#AUR_u#}^qm%w1?U`vT)UiWt*s%Z2M?x$wz(cF2X2zcho} zNUafMNb5%I2doC(oz?^>0qruRG*)_^+uybw&*rwS{rL_0tlX|QXx4Ucm`=~8OKZ8R zwym_1iFD=X*Xgr7YnMK|wVCI2I(e%NoLaldb?V-nPhKOdEE@5W9N6ePuuxkk4g z`1eIzU3(u2X4Pn#az@3uHej zG@#y1HEZHG_bRKiKD>ZUI;OvKjKO6k4@d~q9$E|WltFe=RBN6HW4nO9` zoEKDgMb?Sk?X>Oq!FAW%FlSyw=7Ri5-t&}QQXNBmrYP*Gj$9w4O|8tz%FmAo3x;%w zv+v&pUqPilYPV>p-lPT%%<|XPjLnl~7dH(2l{JI3wTds1)yf}WbN6c@@tji^ucfp! z=rcx7nTa+O!JO_e=_neyNLE`ivduQ%*H@dJPuar{DSw!eVl(vYmueofXl5^aK=z=> z{8B1+^;L%O->8nT)kNH@BK|H^Wq2mClulkI*+HMhxaD0qYv>WGZ9QTYM%Y@91PddS zA#1AXxox`-xh0iKc+gOe(sRpsXz)pixXR0Y@s@K4>*01~iDO+|t6X{?SZlYpqLuM4%9 zQ6rL!$^au8R*9lAkiIEHv&ZLzh4e@;m!vfJ?w>hsV3e(U5>Oe$J8>&gm+Aq^po}O@ zS!i}-NWTEZy-?iAXR4+G^~)detQpS8_15jygI2*B{(NL(4_>}@?b+zJb{ihrEmO*w4RZPv-`%4 zNQ;e3Y>LhqJRm$K(SLT@@gBpT>T3m*#M~_LK`-a#d|Qrqn=ev+g7J6f%AF%y!mot?AzY{m-x|Ijxztgo%-77HnuT@dZRP_2E=Qzwv2QWK@j9GBd3yW4PTJ9F-6}E8}4Ip%Ga=F%I*rv^RT? zqMtgfGcykKn~u2kp{JG5(gQ)Su&tr|D_zeLX#3e}?+_koo&`teXDAhc# z^v140Ze(fjfX`2{C{pYymqenh*R7vQw}aldO08#Bt~_&gMMX5_3+}whg<++_c{I!v=aq-g|`alHw3YzQLu^7n7V9kBsZR$ z!7bz}xHa4hTqCy=>)OPf=59L6wZVQGYh*yz7vaC-{vG42MyT9&RT+?S+$??Rl8b5PbWTegCE~xa#Wb(t3IAF7OxW57IIIiO# zXcSOcXwV*gq~jOQ@9aZrXO}e(Ux(pRqTveVC)D^6u7IhIRxT#6ocN;XJT+fL(BJX7 zg4!b-q!(2??OlA`-wEU{*;5wIe)2a7>@W1Z$j{K9ncoB1NpQ$a~`k1HIHP7<=IN2*9owFU^jeoK8Z(nt^OeUqKq|i~~JzEPtZ++Z8EYHs%)n4LBQm7mOE#IeE zqdl*Jvgrt-VVm#@`{Pn40sS&6$#$=B=>VPbqXzKFyRcvQ;BE|b#w;+cGS!(7YIoF|cvCZmx6{XB(FSO{Y5DD1GE=)$ zyG|=;g;ieE5{JtRGY0OU$BaQu3siJ5`+JNF3hGplvl-^v_Pjt18QEj^MG)(NUa}?Q z@VX7p%raa03|gJXOc@E3M_rUsxU9A_@D!-u=4 z1kgdB>d+Z8!v>|q%>c*a8J9eQb=IF?>kMKeFEo9#eWAboWa{F}mgt6ABS)0jszYYY z3eIx$nhrTJ97Z!b20bWF7&5N~K_47qIS;iVz(SkC1rI{FEsa}eYnI|Lqg^}2a70WR z?V`Pp(k`R?tNjYCGkc~5#M)*_hd!E-*i>kyol1_(KMj2PFR=m6*ZPzvk_L=Hn-lLI z1a{kj-OgaUeb^M;)<)(kIDQ~3Y)UdLnyyq0W|`4;47;zRW^r$sqQbN0P_=uyqEamP zYOO0{YiE@@GfHRG#jeb)9aLqSQm}Sy!4y*!j6Q-3d4SwcZI?k|X_g7%yF%=CQ45DC zvo!nkutZ0zeb}^RP-6%Plt^Juk&Gr27#e|z>yD$MpfZ$4=A{-Y=zH`N>B6Fvq|zA` zOJ|lQr7W7cbSZf%!;zZaKQW>I-2MrP{nJw&8R>a>i>FL08!@76+T^m^$$k4KC->OEYNq;l}gh*tcsIQ_5n4>!l)=ShbMN0ZYq*p(x0VQqN`_<=J!a{^2TzhOp1Q* z)Q<~SzI}yCo#Em!#dRueD$+@m5>ZrbUyHZJxr&+K=w5Gj(w4;B$6IXTZ1Fa{64FlT zk3u(C$yJKJ(%ZivYnocqXF*?No^Duj+8&8_6nC(iBl_AK|J+H1I$1J zo(~DtL8D!%lmjs!nJj$q?%kd5r_XboT|fKu@slO*r_PJKs<_uLW99l4QE^c#*FJ~# zTQTl^7`GPwHuW|v0F@lk3)D84(!gWFM2kH#yo-n?yTbh&OeRHF&zJJvmu@fJvXpF4 zIDLQ$)Bf2ryFz^z@ik2q;Tno_z~gSxW|51DfJh7+8@qeb z)Y*T$Bxd!0dRhM|w$v$>iZu~@bXED{k5`NvzGS(dWx(LH@=yz(Kf7>HpAag6bhu#zL-RtnO3x9K)<2|n+kW$ex|Ny z_w;9Lh3_)+&Q|9PJ5#yr{dslImR~Pzz-b9b4~NCOka7_jhHw?MuPam|K%W8&24S(V zNp9m9jhdq2W^zBvH;vV14OG;I%06>vG-RNtXg+-@ARUCG09V(eJbvt}G6#19UxdQ}KXidxCZw^o0g*E`Zwgm1B*bvvy@X=0IcS*ii%4oY{i- zc{&Yx))*|8zbS3PtW#T)#sq70@io^gls)EXMsAo}P{Bu6l-wZ3#MsP1U$*w2;7D2c z#oCphZ$btGUAH81Sn(6IZ6Mz0HLTZo-?2o4eRg2sE+M9!%5!d1M1-HgR-tmAH!`@c zNSBrSY)HSF_ckWk3d=`LQ=z?msX@6fZ$KUKvr_q-v13s-5_Vslh^bh;2+UC5rHJp! zS+wDWe!=kyZY=f)RtWGYd4@*NXt@L0n};yVKTmBO_7dM7b@a;_lR)0soCers7DgmEzuesG31$mjJi!rl_SOPb!FZ=7fQGI zLq+gHdd?xQR1AjAleA4o5BG2`)xZuAy^1&$TUTlebI1B31|eFPuD}!wI_zbDA2NCh+#m@E!(!bsV)1YdpjB@zq?y# zAVa_YTG}Ty{q?Wl0*}ObJZg_p+XFX2wml$b2DS%`u@aVs3((LJ+jvZbqy^dtSF(|8;$)G!A~Fw}0ySbZP;)gLm%3I-yc@oj0`c0iSB!Jc0O)ps86Z(`P`yT|*R z*!8a8xd)6@e@S{oZiv%Siy#!ME^t$k#V`SR96(q>eoL0KCl?rPMBxwx^7(rr9SPB6 z24wu_DRwEE6z3HxZ$Z&h(Nk+ATEu^A-MPe!t0A2wtv!1f;VAAqDIj0v9b6QE^h{-w9O@(@|y<1L3Y#PpU z9vlofpu7T!=!MpJ?%q+8 z`bq3G&V)#QTBR_K>+94-ql#p-ISeS!VOGDBZI7J(-hNp?f~FNAxFgxYN*6;N@YlPt@4Mf;Ur$Y2><`%wFBQ#-xvXt~x!Q zf2nDCQ{O(ZG5G-%vj)bbbW4oa#uUt)hFT#q?tLK|19MCth-Hb(U}NMEu&dW49i6X!F{4^WF()^e4~k^{(j57rMsjrPb9UF>07^8^2X-s&zBt} zhOYktFx`aHtNz@0Q+nr=N|F>Y4bo2s>kn@vWap0alrmt2!+{@Yz?ltp>V1Gs>0?k@ zMdVhiL>xhuU&C_2fh0r8JsS^Y2`VNkcvAVr@OAfUr=OVpd_7?Q&fPh+bOwX@o4RK# z-*iek+oF}aknbZtd5Hr4ece=AEd%}4LX<`NzhoRIX>oP$Iz+mBiXDf7S~nw@yya9yM}CdH=cP<%3@#!p=V(bj;Z~bk3pKwQkjv0#0g!vcktjnE8L>yP$($42!V0~!p{h(`x})o+grC+9wT}Di=mRKh#Z)3 zB;yx=oF+F)Bcy>O8Y7<%UUMD083}uFh>@VulhrR|{2jP|RFDKV_>4&!=q3V+#k=u%)rv@NoG?4X>v%kAs={JVis(e{++^bu1Q zg(af=SVPjt=&*28y>0e{#F@~`VjbfnLu_!l&KMm(0}=;Ugmw4{^tl@%W`YcMeS}X} zdsjYK@1wE=BV#_;%94c;lthLkD9+A#QB)tC2h~`+B-feHg)8@wc!IvI>KyXllm!g(@oX3X+`l`v^Z_vaz1nOY~F7?G)9VhB8~$U3FOuRLkdXFj>=n>k{J&w9~PI?4o;EIN#A`Y z4gV`RVpYn?1?O5I<>B z9NCifuWe)sseS#RWcrEx^!dUK&tx{nt$U%e_EPr)!(87=i=KN{8 zJO`xGF5SBOtK$W0Fp8aZ_f>XR&P9PcTDFymQwD}f!6a-9g$48T<1P^$; zXcC&8u_syy4V)mw$j98#78SnycI>6M?&wC3se7--nP%x`{J(EMuD6R5$38pK?&aJz z|C>~=mt8M4>0tnW{2;YQ(WG-Xg_j>cNKPCz`Tk8|@h=nZ-Pqm#g#&s0KltE{&3&Ds z7ISF3B}FrQWe4bjf1oYgp^nlkdWIw2)E8KfzE%ph>bL|DlmCLTEWl&W292yUHs1de zY59k)D?UEb3V6j2cI}P`iS*ig<^Mule*EImw+gmY?s{g<-QNUVCREN)*g=27fF5o( zT67i^;Imi^VWFY?+%ch|!A}R`NzaEH>V%RX%4aFd`ZF9 zsi)U`6FZwGAeILDXoj9FJaA~!cXjq*{?XCG)jiT5s(vC~H_1GgRfh>K0`l5tp1XVS z;(%N_f^R^xT!Nx)FESN_&slpA#_p1@3PPNB8q=c)weXMRq{LbXKu~@{SWme@w11|S>?m0r53*R#ar7;UR+x=@k-_Nh248?kB>QfXw`*R z=ky;wEjM?5-LhorU$_QNRgLuxhP<2V3=RwqwuV|!(mDX2hlFUnt$rraTZFjh%>+Dm zqAO*tU@Y`nGNUC@xZQk~l^mDVP2kERN`sJaey%03Phv+K9 z?Wy8#&5v)H`5TgzuNIT?#}DzT4w06Oi3?e;?KZBib;SIIf|rYq@-RljV@-K@2a}yv zZyz6C;YVvd@>Z?QVo>XJoK}mH!n8bvdsIlVX9t2(5IROcKQQ{Cf;$|e>KL)v;s#0D z#iySn2TZmu&YlYhAJ`fb$Q$|^qwO|xbmH*-qwTRX6H2l&5^KmOq(~Q&yvEhId^taF zLrjcjT|l3wXFikOJBaG>H9*A9!-@vMkJ;ZD0Y9iJ9EDxORD@GGRe69L5>zT5R1U%- zn?)a55Y|(@mJOY0#0%x4%#N{~=`YIHii1oIS{H^TCW-jPLlT7}O^*t_3O}m+3lR@V z7eD&9^h5baq}y?#*qXIPa@-~AeJ}3#Vb$A;=)=bf@*mv(M0)pi;``47q?VZKinirF zo=hTs+_H1Y7u$A$I8#ij?^!)0JD1dA4WZ>yLQb}Q<}{kJLqY&v!c=+#haCX-XR?>a z{=itzuT2kb4TKHXlfn%_+3&{JJ4v?-#~K~aZ~6Ga#${Cp#^tWsvi8-NnwS0Abnn_N zGU!-(V{hqJ>)NfaZx}YQU~|EqO&k7LM#q-P2YAD%pV_cRcX z7fzm#=}a5fnlBvQ9q!j9wQ@6=BW*_i6idJhv7Y{*&AvLF!p{WcLKLQlg3I}VQ^;aO z1_i*T@rqRHr@hj<+ukjIj1<_UL+`zHtzuA~vR40U-R8+HKv`}bDl`un7-Wr#Ew3f- z)7hG^8&t=R;1XMGfD5vj+m-9COu6p*UzO|sL$P*~!vC&LXXGq>?tfFFYXY{^xOL}P z@Xr+RPdk@D>m>!4bjlE_v~VU9s2+GIq!gVS>e?f%qXv_w#1L2=i#_h!UypL zgb=KZZXb}N+j$x|;7>mNhP|-g$>YA0_sJ31Of$4 zG>S#=1t+~CzK6Q`?k#fl*8Qe6b{kB{mE@aV7azZ>Om^MjBLJ{kx~W7mgOZnE?hc%h z0L*o;GaB{_GpuZ8gBF0)6UTVdh^;tZXp_Fs_p^L`K_A61U;won+B&LXyVX66$bC|j z07XGa7WEQBKgEdwiXm!Edyb6g*!bO+!ny(eVWh++HQJ9wY_x4W?09(ooomwkvWA$v zxaS7W+%sW5fA~CL`O*ih+EM$)8?{2xzrOlBYu`nwu2)(E@!GVZmhRvq+{aS7W5V;; zF;r8QcM#quJ2%Pcw1xwv(HdtRhPWr7G+HT2qm@{J(rBe9jaCw3C0hI^Sb@@LwQBuQ zXc;=VsMcyxby-W<0b{i7@-NfwVqyT-$gmo_(3%OD7gJ)P7BS%$48bEl;NA#_j!F-< zzjL6jdC!G^N#B1+rr-NrV|KN)-UHF7h`u7#fAaS2KD$t74zcotT=)UT7uR|ZG$Zes zCHAT-omFrb%qlo8cv!Fyj9CTKSp}0|%qp19Dwu=>!zzkd1!Gph!8)_agjt!4;Lezp zj*4mj+pHoIySnXv48NLcd$J|CGeQFy*F?12&hM)~Ubtu0zliCkwEf=AEjjDgc&1fz zl`Q!9^zHOl!b7A_q*ee`I{!X=TNWSTnHJ7EaJ%>ll@I(!5l+)qKbUKH^)`qF@ke#% z5arBbqtbz8DA0NRam`neD~P_tAncM_M5xlnOxj8mebGmX1{}}DJ>L9kz!=wp6q~e zx>(GmQLMO;1_KcG3LW z)TmFQ2BM}K^-0vIPl9^5sD^9wRsxL@gu$Nx2GvuQgzYVu9fOAPlp~>oL&z=21+#il z%NI?o6BoK(9V~r%=PG}Te`J#iGf1^fD$61JTBW~E4PYb9*(}|xmtG-5$tToGAA>4G zG2nkOz*-yt47&92e&ff?4=4I?Tlg#CH^c9S|2;k-caHY ztRd=qKy|>>x??#31tK3rS;3_I$3g{KS@5EkOXikt2Uv3RAy5{o<%2D;R8&rZ7B^r7_f`xA-})jUyO**`)YzW7L(|`SLU^ZyqxyW52e+_o_l1)^W%%x?_4tbYB_mWL#{r* zq%OTCY093r$wO)T(wT$%*Ax^ZdJsJKC*dJ%+yT_1ODP8g27?BagF?S{rX1Lw_9gci z@!a%}zg~WE!MbM#KAW@h(6!I^kia*OE_GH3m+PcQTh?y~wlp|CyLgS{Hs#a~2F*?f zSB}DJd1Jj0G0fvI!>$Uevgb&HYhp@5le#C*33gySJ1bn)~9P z7K=H5d;g;J!AmH1u%q?UXZ}IC0!-Mf2a4W1!#Th#h`3!wv3o>zhDZdhNEClZ+OQ)q zTLgTq*d543fc%~>3O<4e=vvXC$;RbXDj{Sm^#sPw_JL7}34&7$*aAFGsI5w?tI{*g z?pym_0i2eNnqEHa6&v}KS+<$eNJjhU%Lf53q>UR$=RiJbAYXM%LuzV}&d`}Kgj3Y= zrPk;H&S-l5LzJKoO3()-=z|jUK?(Xm?GkSDG%9fX$7tzr-8G7g?eu`(=W4jm&k2== z^e5XxrRh231gdib!smlb}XiR%5mG7$AJztqWzK#3y#l<3UjDuWsp2Cs4V~4)BWGXibMW5n8ke z>WAzUp^*==4TxDSmHDH3W%o|b*Z;ZsZkK)1*CF)*qXvt~k3ZS7UEW_YiM4`Q4c<$k z!GU8y>`aNKwj~&=VZ%Z2AmmJ8!p-j{6rH%=JQESA`#*KHlCRUG0>ESV1tcT73eqD1 zndSJati>Kqe=n5^wY6w!t{V6gdJe7(>I0qo zNay-s@aQlR9QLhbfc^;e=cUWuYU|3T`|l7ZFYav;Vv0*$s4&+0kuDej1=P>~lUO7c zVaKeL?r1=FQ05D^HII->4*~OnQ(cI96+6(lDZLeo>ZPCFx`4`^n&z`#O9hKg%v@GF z|KzlCe%BT0%8~CsxK1+n{9{73^r-RqEe+DP=eN*v@-=Q!`LF1!*-c-mIjUVUV}-dq zX2T>ZMz_1;L`I+0X0${qot*M3K^8 zo?FRAU;$SFDwtrHG{)aspi#3ZKHwb~;ORfcFAW1=Vy5T^H8YAXvpfxBQqB^m>f zyv4Cqdbo4N`T<)r`44yp!X~8F{k1C-7M9Fwp0;w)!mZEoZ*XGUCtRS|f_a-^QR@cq z6$c{lL#=gMPP;WA$M6h&6u<55Dv=bXZmw=+0 zP^>a$XCuiGOeIbsAh=&&lJ++{SLCms@ydBJ{8;9S5i4WXw`_7XjOofRifuhx+xALM z7uTj3zIN!Q2it0=O_?))@TP~`w@#TlXF*69X_$4S*dTc&e=&961TA@xLMrLrrMG>j zTn{a+3o;Q?f%%yl0C8%50HGxhUJ1Ava5v!Z0g$%>0{l2X;Mn?^1-(+IgKt)6Rw8&p zX$a>ysQy&ga-S@Zz7On2HpwT1Esxn)X%E9J|3k(i?tlpjrH>lWZV8LmKGzcKyu7yM z(}u^dNlqW6v(by6(t9+l(`mHoQ?7S;`77pd1z}i>HYV0HPRL7muH?+p59%tAbtSOPbTgvkJ}%LTo6>? zF?nG}DPk|D7g1IbAtHK@^^1z)l#Ng~1&vW~AWoRMq1ki{5jf54LqzB^R}vMRAjf2l zUu?ED+hPu9<~{T2)`M4x-&8N#F`L)k*`r?AKC`HL8~^!&S(`WCD(JGJaK+`R$2Sw7 ziBGNQ5w>}ASkxwITH%bXt458l#W9-8N3j?IKiCZPxO~K0&>EZu6e%|_YcsrpH*mnH zW9^BIHD+rO!_{wVm(EywF8pNB=C3xKyTdmP8aQ-BY4zQ+dkDAjYqU>m8d~@$=u9C_ z9|7?D-h$4{3sRbwyaI+xa_hLp2ws(gUgVTeGp}5AD&*~ehOcYR|4DOFyS(z=g}sui z?$7T!hv($3LIf|XU?%LsI;&axdW{I0s6lv)3bK#NEu6~A4l#+$fCpieFwTtMc1i#G zXJO%~`y_hLao2k}TX$TVCPcq;T`GnxOI4%R!22z6q~_tKu*~A58x0jRC z(qQuKQ*RtQ3n;16MB3-u1^sexVz7R_Ko3wK$Y|CPGs^A~)U(ku;nvLuVWn=jgvm4z zQ25{{4A_`~5b?E3S8SR(cKMuf&EHBl_O>*ve&@EbuEqR#Zwk-wr)WQ9fvgkP<=uk zzuPq^E^5q_sx|yYtVs&u-Wx$71E8^_Iz#o|-WsiD(iokVh-MK~(rk9>{IaxWtvM*L zokml41Faz`e}z3iNr9emjUwUIR`^HxdxAcM6uxO**!rau$yUs{zNDo7*_@I-pQ4QE zrUC|y`_~4Grs(*T=Nc>m9BkMjhvHL=CJ;JP9DKu1JG&dyYOPL7xmAQA0?5We5kV0; zV6R!|=qwgGIvt#riSfT4ovi=To8TEH#zq(DH^#|=-59M)Hc}=l|47JkzG-$BHxe(# z|IC!ymB8FxFDI^b$G2XCdhiG7dL~ML+ z(SsM(+p|hIn zjg=!_T7tQMx7nh31zePHu*G77C=Eg6sM?GSKBR_%)0D) z8R)&P@(qKgP2x8_ZlUj2!xC}}@6*U$tx>BLRsMP}y+_!i&Lk#DqP|lSiaSwMFxDvA zrUL6nO)*~a($O~^Zw2tCQN-(5jC#tyFY*&=2G4f&Mpt*2&rdkThr909kN=Sed>}me zxS>1IpErD~ekz5i0MUbT?nMZQHdCIMnkTbMs@SE-6@$Y0i!Pr4exGEu@t*`D@KsqM zq&F^ay^1+-usqXhwiYhkX|pKIR2?uABaEOLUM?rcOf)e@jT&N%F~%4r#?5_h;^r{EO`hv!-K;O0YhN~-b@!iBe*C}H{hJF- z-fq@U4Aif>y1J^my1J@5AR-nXZircqj36s2k$+$@3;3&ORcZVn>Km;*5~&BrexdGyXMQ)1BaLGF5A3f z;}fIu3rg~aRhnZG_l@4Ywx*-8ICmCt{s_3#3=f>%NDB!HiMB|%UB^a4fd*B&dF~M8 zRgBD?5|NWi4ax^{rx^EFj>)&=mJg_JyrcAvgVQEwI1AHrH`RCk`RNUh3}4BL&PDBt zows_!jM!aK^BdlO{;5Bm=oq(q7kGongS-c;MDK-YBlvqE>K+H)^NS*Rk5d`__HVxA zmqCDJ6sME3@i#8rfq1f1gaG-`EV%&9&k&NAv(Jt4IL`!BwCh?{ivss`lAd07@d!E)1xrqD(ilCSsio(;lWhq{oe|pr3bH?hk zRY6U2I?r~l-4k1VuDT8{?Ts=#v?IF!VV2!_$@Sv{q_&=I@*SP{?|ac70xy5U6QRD2 zVVdYtQz#}9Y7PjQ0Y8L~&d>N_Mv_Fnq?!kT$<>{ETlr}EZ41}W9x@;=W7yo?ZBmDP zR(VO;_ja9ahiy0OVtZjL>!ohFOMi+gkjU5h5|Qy76P$K!g+Z?7aaU~BypJ$7y{34k zh`Y+t73H0-lTzB@_O5(~fteCE%bzJ1ej8&pWqQ!+>(8X zawY5cc+M!uiho#GpuR#^ZOUO73MDfo=h1QiMgfTEe$2-Dd602zF{eMa>>LC7Z-het!`gT>~$`e zbnd>Rx6K|g@ej``CoYw5o4xGF+9L;BS2Wgc(w}Hs)7&0qZ=P`9arpynsEO3h77#)+0@}^pXv}qMs1sQ+mW?IYD-mn z$)x*^vy1JBPj4bRS52)&#S`&Qn-5w8kSmOeE22|Z5t@UTJ+F15#j+fvt(uE=O=A8V)2R&1m{_^H~dwBeWR_As7NkrT-N~6C= zv8Ns!(1QbdZ~%ceom3Iz77{9L!pz@Z9DCIyEYX{PwI+Twg z2c*g1HYD9W1};DXFh&5zz?E_ZoO`WY9h`$IY(5{~F=T8IiN{c)>J45 zqS)LaN{9aBb$tgLzm6qg45pEeX`A)u5Rpa>)0em|g7x?^l%aL<*vK4R4abcY19m|^ zPxOY3RYSUPg(;d2Lu_?P$cwk37D$aQ|%7D|9Zc8aMPE?PW!8k9+6r z^DOhRl1;H`XZ_e!pGL@t>nENMFHpSTb>~3NG@l8NwdI`-Z`K z>ER}&wyEn&E_hi?Ub*42(7g||I=$gk`r0zP092QeQHR}2|@Cl^eci0K34A_i_n%GN&zd!?F zl-Gn*2VfCOsPPV@3Jtp{wTjzRy<9#aV|f0ugo|CjkG;2!ov?3;*e74PZrQSl1*mhM z#PNx^p5JUqi`{WO@{Z(9CtjF7sq4~_IkOS&P++InrQu2o=33gq>XcG}4-0exI~RKX zv5GHXyK*$D0)jF+uNdCDbohC;HX5?^!}WW&s4JkW$5$qj0YlK|jQwvA-p&k>OcjAT zGA`=l2b2d2n%qG;ynlgXm$ZC3J9hQ=UF|7KeP^TT?guXEPh9^&4!9m5O+9v9k^VNm zXRb^g!Qa6;AI2ylu-fL&1KC#+3zYOmLj}{j*SDyFw9S z8N8H^eV|)Po7J;f{-H-ZpjDcpab3k+j-}g`+oE8hQIGW^R}|~fmc^7xc|jAUE1@?9}oZjxpTOO z`DncI>DBeynd=G;*^=fWG?8R04w-4#xdXz(YB2`=IC;y9~oZ#w+|kAb;J7f0$og3Y;aA+s{0!n*4{H) zSHEy>$IkO3TzAx+dh@ZZcN|Z4){V9%?%9;$95K3M`?7H}?z(M!ld!7tMNo+@6o_P4 zzK4Y2iS#dVNt;6(Bh&y&;IifD-CpG( zWu5%P4&}k6E!A}ML$>uJj1hoX0QLGYBEKT|%K#RTW2^`d=1Zy$BD&R!3jpeROJgAz zhb^CdGWGWLwN15i>$)!e{lKyBj-9+$dvX5kF(Z^T1@gFY!?ki{EZYYQ7>?1t!)VkA zI>MZG!Hw0IXU&zNRY5popM~FJL=8 z0z%s2HkfW73oC-tc>A{0i%%ZyvbG=UG~P0K(dy_e`V&3P&p)|m%kV0xzGu&{;);p4 z-zjaw2$}FlzQzcs;VKOa4f;HYeFf!YI%Mxu*j3X=PP(d{1=xJ(^b>BNBNd&j=t=<0 znVw=-K0jP|G&&$Qm07x+dRrRPJgF2Nap_v7-CESM2ZI0LgwpDIskZ0Jq6Nh*(gbJ( z<@CKE?UNVly5UhK!A9GhEF{hID7Qm+kg9~*~W$A_M|+pebuVK`O5j~w(y|p_SS*Yu}MRdTN~PU z1Zs!bnugytcFC;d6eX;6_MCjJp=xYK7O49I)a~_B7hUOOQgB#sf}6e?&{rk)NR>EB zHv?O^tRVN5f<}3Tc0p~S6*tBPv;(A&0Q)#+UisYH-}tkj?*6-pI#%eWPIq)tVR~!h zy1NB+Z56Gv`X{n)K-~aPSIMcnA{~=o1$7qeu<%wxs)H&6QJrb1Lb0vbU3ncWk>oBD zR!gpZYOe82`J1h)noliWJu+q8!A^bFZML$-BZdu}vrRg-W#v8p+H&j69@Ct>k~NFY zPZ~DvZ;y45|M&tVQ^Cl|nmpt%;BDWmd|N??!{Nwu$PR~16CR3V0-k}h)mW?L%9Mnh zfFuq0l*emVaZCtB?-a_8YdCM=Ew%DMm%C_=JMMJhE><`{zYyHQ67&0Z;Shj-EDtyG zFh!DS<48+eK=%CdhFcq-n7?$SYgthJ^63k|`PeAcjb6BHwY0e8*5L!PXKd~%+f#D) z&J105UHQDiVO!VV^YzB&`VrMlb$8usvrZU0dQ;JwrEg6rsrt*KJA3|iSsFV$%>@Z~ z6+Aww|BBayfyaT8CM>v0SEj9wa`PB|Iy8iMoI%+({(Hhp?H zIU}&*wA#WN7K4Qt8-^bvwS^)H1#w%l`SjIZM}kd8nki<=JK&JSELn;6NkR8u`o=9Wn9h z`YNif=VN=S>pe2Y<3BC~_uSO#dV1PHGH!oh{<&q#mVR;Bs;wP6Z}q_CVI@mqnKMl~ zcF&HE&#@Zow`Nw>6n8|%OZVP3L)Q_PPUF9W@k_kpi|YOw8lP*PcYHF>Zo2@fQH5q8 z-WVxF0N&~1q0 zZ@nDB`0*G&p6aD6>_i;XJru|EA#skl%s4qNE;!mAQ5C4q30B#WPcAtwyJs|<=Ux`= zmF{2yE&@ahL1amjcbhLY&zv#4eZk$!_O0FVLj6PAx6Un?Q9o+Jz@ZDZ0V9Xa9l5S} zapSSVoQ63|hO`w7$Z?@UT(eU;CVj_gN-MRQ;|$u6ct?CD{Qmf$C|h`qHYZ3}B|%GA z5vK$JQ^)d0q{wwWJBEyJ^B4ckWCu{x){X#6~T(ygl&wKYGr z@D7-%uDBDjtM%;kl1cwKutga?Xj5$RgqfYox2@Un?UqH2*T3Dr8+2`92brQf3Tp-5 z^Xy9FCOk@Gpgd+{ScS%5F-UZzuf$gTVS_k6L0|0NjySCG@ZrN73v%j)q$cO-j`o;N zrw*-1A4U~)uVRZn2%8W>5tYC)osoP&!jxactKfN?d~s)PD3m^VS$X5)iT&dTKm2Le zjNApfqsklb4r+^(FSG?p)!Qq`OMV^ua3Of;!d@@{!wEu z>TFukm}m?{YD?2X{?ygkud6^{aXTN>$-REo;$O6 zm@=GQ7?M)^@GgV~E)+ZKkL_1pk*+mUuLI4iSk--?h&pP7;0d$Hs_;r{HTvLTK`Ayt zMvvP(I*-8XAPYy*MShZM01a42$x$#MD>o@v{1P`h{RYF;i}Zd3Fs5Y1nBgND?kdoA?`YrgO~;~pmCv-p7LOdX z?$*<@hmZa2KuI-b^B(NiIsHs{eblcdBF9o{4y)AU=*8-yx3}oDNg-I(GKeQI5z>)q zaQ6F*(Y8rh&2w~9+l-yl7o@xp`C@HAy6lQx5gb0g-t1yeloy|TZk4hoGb)ZE?wYIM z-*d1AHjUczB(w(p5^1fc=Lt@5+*CuF`PL~$E@ZWbXB#I?>xdh>|DmnH8B1y#mztr( z*@F@%J+g~c^_Z3q8q+*$&>*o_cFSKOR!Uh1u2M^cUB>AmvKntx1?3onF&Jzi>N0sc zH90<3_XUx-$8uj|CF#Cm=f~TVvmSeZlw$sX5p!ncj)l55%a@wWLXi$1-WJe*@%Wjo zmg$s3_nCA|Hx=_sBnuK>ogiuZg$GqeTXHmXqNHIxJwxEAs8ho{y)*XyjglSZ#(Pp> zLgt1vcFi`bCM0AmOvuQC2et$hv`EKx@18ev#31&fl0PgFHiT6x`GXT+L)fq$)4bw= zpy>+ic`oGUHJoZM@&mApIP;j zfsVPWv{z4_nrT@QGkDDS-0+o_?BVyUTlL^_XvSJ-#ufcFoIq1i$KWuJ)5Ry)Y!wM% z5qMzUk&u}nCnRX1gKE%hW{hzBX}3oJPV_&a6QbBylT*k(b8QiM=wgqBwIa27YyF-p zd!Ku>WL9>~!B3N(-Z*+%?);<~sg12OnhRoz7Ti8kf32hKk0pht_nnP)Dx0*!P90d& zbXAG7$KEz${LHnjO~b~JRDTOU&x?S7=+ ztd)lgg0#T{tsfm%7EELFA2}m^skGHjk6xC@w)8j<*TRktUAc_?Etc=-p$S&GLY^W^ za)2Yc#uOA#26;k5r?4V~Y;X!i?u^%|p*;Zl>8`?0M#=`tj>-MH^wi_G-oI++n&Mj~ zCk+`Gm$GsC@1EXqgcUd3TBm$FQGWHF*R$$xo7+~uBrB#MC1GIPtq;#U@%w|WyH~8M z9{E4DNQ}mQz~*bm>Rv_6#D)03G0qTH6>Z9iM6Z87Ws>pVlF=5A%iz?-NfGq`NMtg| zRx0_UU5cF;wR-F7b+ekMj3}v#S+k_I?aNCg)5o`!RHbH`*?cxA;>h~lf1f{Z`pLx; z7nsbu@F|9S8P)dl9ItSxMgf=ZLKllAE%U!nR;iOZNSiiNt29`%0EuCuC(BM zdz>Rr*F9n0bF8`NGv)cb{E(#)jSF8_Zj(l^qWYl4HsX-fJCm)HsaqL(29}zQW`onP z({Kpw_N7`jp8GmrkR5w;3f*M!i`wL_!(9jO%FmlroSc+#OPCJ4^bC|L)V?apHFd^>@7=DiQJk`4GPQtambg zNAHmYO>p-v$yXwzfATLs?;R<=)bcOEk@KkF`A%x(r)1Rj>b0S!iT0eDAhr$(iFhbW z3oLJ-RU&z*!m7}ogKIyW<_6N%j1)WrZ;A_1mcEC-{Lirqo}PA$W>%s&<%gu(LH(D#6R$tZsgHD1 z-#Za=3zcT!w_oA6oF_V!dQB&?-!~!qy+3LR@Rod599q+4>Fg5XhUpDcqAYl=HC3ZQ z9=ArP!!xQn%E-Y*F8x6jq_{vX3Z;x;s>^d{SkVsWvG=OGri~Y8Ho9@;EzyLj(w@E6 zH1z5Ar(X)a^V#;$^Q*Qecb>A`w)wzA%4y|2mv;4?Rd-LAy?fAtXHrdn`bT;Ax#`oN ze`?q*(yX4Na?_=YUZX@&%RrA=RFyz`?BKYE3fTqyR~2xNox^uO;8Jkm}C($ z)>CY;AtA9*QE)`exVDZp$C|?u@Zw%_X2XjnOV)I^a0^5 zMWt_$<-k8GHV(&Xd_ zr_&q}n-CTTw;wZ)NQg*?)C8rXcr*_;(-sXD+C6QNXBJsP_kw)Vm@v&8*2VX2cvxgI zb2rW%Apw`3f&yxmC#LRw5Z|@TA!IYFfk$}F=fUSd!ji8VvV{e z-&fH^f&fo1q4EshK8bRIJGt3A%f4@9lc(ria-2k()c3Hr7_IJ=9oqM4?Ej7ay4Jnc zv9T*sALGwsFIgpR)Q%{?;xdQNi`ZL~JH=A>y!Rryr1zq;m!X(z>Of72roD7*q8VrL zeldkHGp4vSW{VlgL}qhQdZ95hJafhrGs;(__;}Q^hg-r+!w-j_3fBe7h2c2ML`KTV z8ml8BzgSa@yL!r`RI64f7E5)l?$yUjCd489Ade?iaxnZ?q`KSWll`K*S~?(*1JAvZ zL~>0a9pr@>@`p)iX-Z*KVy0e)2Tb`MDF;!jhhrDlZw*YYN?BBSrtWOr$DhsUo}>Km z?5)o%9+%KEB56O$pg~fgg**u?t zlP+XrEh!xlW$C9$4N3*etWGPKh{i)fp{7I=$^jBJvIUNboTx#0QfbiPpi@C$Vo+jG zVqm|1Sq)SAS?uOO3s09&O`+RZ(36K;xbpKk=Tt!>-;^Jw1hY81d^jbz2_DfiuYzN; zl0DG2$hEe)zPoPP-Ur4kdS>x0aVH4y&Ij>7efddDw zSYrlD_L)+WgB1gw`$wCA=YhsLLbT*$MQR2~B_j8rd*Y+SMx<4V(# z%!%Akkj2nMSnzte3~Lb)6%&-AnhP5@7d-FN-4w^iT&OnEQx#3gnkcgs`e1&>N6TWrEa#78<$7nm(><8gg=WWbCw&W4wla|5ZJ{`ONJ zDTiKvVN33_dTt)~D#CDRPrQe_tFy{qcDv0ZEC!rVxfSc5jLJi2G&R$Vj<#4(R)PjH zmN?5{i#AZUI7%HTiwQZ``$}mPAVNaS4yQv3M))~A&Kw@0!4u{@1sTc5blifm%*RE! zM$Lt#<>q^$r)8m!v4EO*tf$Zr>4&o1ltH=ef5pO18*@R(>Tx>SQ1zhs123_1JRNU=~SU+(Mk)gZ{2@As)SI4~j`0=j61$RxUUoh$2%ACPbi=$e~BU$mG)1!~3=FAv3sTkisbG7CO^jWTvVLP=R#2$WsWAJH?x;aYH2|jcBC0oVo+2Ck&1!a5ffY* z85ta`gPjd-4c-}iD7ZIR7lMm8hOMg~>xax`%2y`EQ58xET%WndBUjO@K59ClN7&F1 zAHSEE_{83Dw#D;F# zrECq(8?F45rksUMd=nnUPms4@)P&}hMpL(*WP401{z)(ngqpDXWf_ zD-Vr1dgRd()>L{FSsJygI#ov2EVZ36>h%%*fZ?Co-d>2h?t(A zu0DUaa{btgf0lAvpPaFF<&pRAtUuCwU(n_fX5G}Gym5T{&nJ}c?)js%V&%p4%h&b1 z-L@Ww=H3&%bM=?t{}w|Ia|aj)4Z@lYvP9ZqVltw0@-ss+be7!QEKPh`avF;GT*;Pb zTd56s=r}hs>hgl*8g9tnEy;gR$fNs05hi6ApBm2s6pjq{dl={!I*3a;GA+m{aw{Lg z0XPofBHME+Fz9oUWqi-%BX`6#KeMOji?C#_k5h*}(Dhkt*jgV&TxZfsYdgCqu?1Z{ zFBpTSJTvF6du&K!&bnvim3>MI(sh3uM9LZ4_3!-Z(pqT}SInNrOLC>7(rwBHc4yDt z?6#JjTLvwmcuqL>2NPD1x(eE4LjZLY2?z;AQkDftS-Kz;UgHo?cE(-v$;i<~cM;U+ z=ChR#^xNC=%;H_nU5(u+Mpd-z`n~K$;0=O(O9S30O;%}iM2HDh-eD%-H36^56m2nk zY#FvoU-W*Kiw`1WKz^CHY2f7e1<7mISrT_S?``OAe8KrbssWbB9I?7Be&%5etc<+( z`9b#O@QtbK#Q}IRvAE^Wz&Ri_J|H|I97a|b0V*OuMMOlV-5eGZg}2^m*&&I z-_~z?BllDewVuiB`PQj%S7093K&CHrTMytLIiq6QD#zl3SVr zvC|-GDp1@+tBAxiUPTnoQ*E@ZGd4RrV|aZjngUUEf8hD?Qq~laZNnR@ZJM8ud4VDBh zGcw>o+4!`Q(Ea zuLLwZ=O(o^|J%u4bUZgjN*`b1U@tg(THBvZ=y^48rQF?dWamGXPrrOOFLh_bu0eb5 z9{smPN1S)>xqk8eCyHWr?xCoG(!!$#iJDw`)zfZ{hhG#EgSN9Vh!TWG1ZQyZLHhe4 z4U5B;E>WEwFSMfsVG%g6`(9r0+eaQTpsPoZ6_Drx%RfAjR93(r8*~mTQ3C~IyQ@7R zffWl1qwgqlM+KCYD0+)7K9rYs2lj2H&6nMFlXgw_p_$P>C|K zG^HP^(fdV&qe05La2N(lINXr%5KUYVIxzL;VF4EuM3pMHf{>dlX6hdgpm00Q4Qe9p z>#$bP;$MgZ*zA>Ol#gbXM&Gdr^DP)K*ytR4)ARomv)SCAHYo46ui{hP*7xuaTkk&o zQ*BL#1Ls~xZfOF_=+-4LO@bu>lS&9e=P|VJiZWZ^*M^}zBvme;^9-$)+hZheUCa#* z{JYr1y)gjTan-RUr=84!9M7kk?4B#6(sTU3dXqE%{p>_t?3#s%qr;L13>X|zs9ewW z9R0OfzDNF^Aw@gVF)*^f0QJ zr|&dj_2AWj5fs>2`(`Jcmd=B5!fDxd7*5N}li{(CUGIwLjq2q`vPwrZ?6xmY8p#O_c4iwnrX6UPW8m$-Ei9*7+-2t_Io5*O0xSu&oR z%JL=2kS{lWq@;b)O48_3SEygg7xztgmW@4IKO;*E`vi6i^p5wM6IwvCBD!Rdw%H zE^fG82t81P2e3-|9gu>-=xmfSz?_;NArFkz#G+SPY(yvys_Q}-y4r+77D5v;H3(_? zgmt`HOI{gx;=U|U!#4(cje&cmZsm1fw{zdd$Iap49B<^t);fs@ca;gj?l<#3L}{w` zu0#>luCUJ9eJkPK{7uAg)PPO>^q!xT_cz=wM0}fciefX%KiWyPS&eD;toTF})**5u z=B&-eoYORgrEyM6Vj}jrM2o{53pS(nG(v}3|C=&d4c>Zq?Ok@iiSgNRpBxVd*Ox@E z^$I`}uYh~xPIUqz&|=#|rpQD3?EWQ{Zi0DirFt&(RdnFu_08Gn(U%NzW1NwCEBfk0 zz^+EvsJS%18n6UmwSqKcW`!T(w@z-^B_D+E6kgj(W>)RZb<^m{vW3_u+}h_HG+cE@ z*!UZxCg+rA7AyZyMQuwM_eS&sZxS;(j%00$nZ#*|O5>ut1vH&C4eu_S(PF#lLmLe!p!6UiL&iH|(_&{$LFH2-{^FtRYCogXlP79SUM`K{#S|1OH?#;u!4~S{Y17*;;xxThL^f~3^MLe$(fkrHQ@WAu}ub{Hycsd(2 zU4@)dl*C5)exck|Hk*xM!C`166G6N7jcz56iI7JRk`Oykt+c0T6ULkEb$b`FJ-?5_ zdnG*N(KA~LD#EMPEvn60BbRU5b^U^JWy9^{Sx#SVXVJD4?h$4lKVwxyR z6cjqjXif-*M~EvTTolnY;D6!~!gq)FfW`F9OeFu^ux@CZNO6ZQxC%bZ(L~gB*lZ4bl9@gOsWIzgp@6DH7J#|F(z~&{(^~Q|k zfSD&}Y(2F7`@JvK1>3{J;y2vx8WGyRbaJ%vo=I8L@XC_;b7mi#{aur7OZ@WIsKLW8 zEL%DMweE|o`OOzjPOaO&F)Z-@@Z~=>3}?4I&ti5hTK1Uomo9imd==$av5Lt!iWHT` z_s1sLzdv%L(H7He2|x@OM=f-dxKXOyE}@81^9*h^PmP*C1qF%5vh^! zsJWbwGvc`qcmK5az(M7d@_vGL)t%#ZOsJrD&IkQ@-q|$sAHOYETINhQ#XcPL@oO)z zy4N?YI{O~Ks#Ok)Rn*ORb^mRxbYIIf#n6o7*f|Gk=9dn46|e%S8ef-|s~mJoZD`^?)BT<64o4fD%Pa4BeC)QUlo^vo zA>X6-DCS>>l`POKE*+KVgdQd`O`;_cdYBkCpr8QP)4$G+NMj^Czero4(TFn+#V1Ah zihKUz8p>z(>WK$7B~Dy5Ax8wBKflj&7ug&9m{Q0yOZdeUvUxk0b5dP-$M}M2k2gQ~ zWarxFe*DwSCWl*vgQ~}#tnGN9dEo;tsq@9+a+hmMdfKKnt-E5ix#y0)61mgOkHic% zJw0>j^t!4CAk9NylL{aM>EOb|(oDQ%;LLI24mV2D7Abx|GUpSS3L7> z?0~I1vXbx3O1SQP`H_`N3aDNPe!Y~YqnG=fRE-(wXqpmfHHX2!4T}h-&46BK$U%j@ zuQ*dLFFHo}3oNp3eBUxM))#qX(>3RB-JK%`HkM_l7w+*I&`{UI+Of=r7mS8h=F#4C z9uio>ZAo6KBMeczbzw{sW(fnA!whttWJBR4qBkC1(;-^$8)C#=RWLHepD-(VOlm#= zWw)x2ER9Nax>cv@w&jb@%){$Y?Ir8ouPg-}wg@X9>S7H=53pc#M@o&|OZN=fppyI{ z7jY~G9Sve^3hj&5%2levbG`fQ@qj&?R7umA`6*BwT`@(ikeq?=I^XcC; z78%sNQ%)Rf51M**_WE5mI6~D^b9SsiKd;NQaXP{TOHHv)yt87#&i2wJ;N~81lVXf1 znyS)ti_MJvgD1$C&9T;4FgMl~5oWc*JF%MSta1Z;g>i9*`qg_vKW>wCfxYnS{NUku zOY;(K?E@$8KXS)i?GCm@F~>@Ob|~w1?(O|odwDFEV5Md5w9rJ>R=0lHgz`?7O)VkJ z_qV_NyRa=n$)HD6M{@+Za%!!Tu`;-t*DBSx6RvNTam;hc{SuC)R~M|FabnROrD>ZE zbp~Xu3?H+2#OQ%dn{?gV*53O~XHy;W*Yir(EPAVcSjAr-@1zx{Dyb0|8Rt9x7GV|T zc-K%88}1P(U66-V_|2$$v%yV)q}h4j)n{*;l2kKM&GD9wJ-F)+ED$-~?>r!Kyd}*x zsfFXFOiAf#VSy2nJhX$KIeg3wINw z2-qS81TVka@O}h0v_z5}?R5+(R-b|mo79}0JAP*NGsQ)P(sX(&sfblsvyo`A+%l!S&sr4ow|#=com9da`To8Z&xY*X?Cf z$rDtoSkPVKLwJIej8`w0Aotcu*`0w7V|1m>G6ork8$_Zl_(&22L`bEuniFvW2M)}=9X<;Z8a{p zkE$BJswY!H9!Bq1tX@h-HZ8rT8E)W~C<#HZ?X! z&M7`zJU?ds^gKRR$q06O6>}+9Rw={2#hle@8O#~YZ87Jo$RVY?^hnA}x8N;KYfZ?w zU&~8J+ilgu_03HG^z`u1l!E1D{<-Ntzs5pGFC10O)6*r*5!9;}>EFcdl1-C|o)35e zhn^M6rfNnOP#tbIJIy=IvY8=K{lkXyblcKEnd6WUGIi=j6YrHLGDlgwm}~jrvCWaM z7vxSVN=weuc8KX7XLYOCCuxJr(}y5Kk&!$~NtkIUvcZuG?`{A9*Ys>N`sk=T#GDc0EZtuAk<%7qn$t{fu2?#0;)#aFu=^5JB>ofIq zato@I!>D8zxQQX0BhjL4F&;75!hE#qi^ugb?s4pl50*D4syRgrn9>rxFqaSd>8evS z>Zw(qQLEnG1CX^LSPOdFJDygY|Msa2w_f+ZiT@>D1LAeQn?pNL~b8 z6k$l>8*lxsE=Znmh?;k6xH1tdgkr@vIWvobpYNEicL+HTo6P zKf3-I!alXPIiAWNqHX^9z9I*m6?!jVekH(zx6q$4mIdZ$g%Se~cF7by?_JGKWsx9jF1p`pzls?e3B1HSyjpbCL*sABFRr5r-Q`!(v z`x&UEdJX=@t81J_tBK_LL8G4vy*1Ro z^vrr|2)k&z&2ciVT+)^&_?4bbRdhvhBZ&&su6)bw3%rIv8BZ`&O5R=)B*tp{3~QlP z{`T<6OHp`b8&(6|aP!nnq!IblyD4icTBDSQ zq#Bl5UQ%{zJe#WB=Ba#BLRU6LMNhbeEia!kdm1$CYc^9mLjME2GaLK`2dKoWhOyx$ zO~0yufI!DM^BB7|M<3{xOfrNeALVgVOEpV~f4i)Sp##Do1T5T+N8k{(MBRsMl?yg( z`}WO}1EZAhzB*sBM~Q83TXq+-FWuC!b*b*W{qfDeQ+^CUFYWw+Ec|zNt;glDRW#YMIY66Q$03nf~0t^zHn*@n%HtDUydkYGTA#t|;8P-v8r-OTxntQ%8!o7~q)v9LEFM!OUhq5^?!=HNUC0|g!u4QIc6xliIr>ECxZB+2b=Af+l-DU2 zjz+8rEn6FSD6@nu6*YD{a+2fXDbjTi9_Odf8T4^So=K!7Aj(?f2w^!vdWV!L;eT3l zb%2(t;Dl>IRt{xpRCFN{Sa{DJ?q|4toPl;Vjo^A?WaF^I!&rLh{vplLvn$j}Jl#L5 zS0yQzqqJdd%&A^ z;@H+T)7QTG)uUS%938!;HT4-<9gK}G4M)+}%5v5kSZPrumAVr$^g`n!h%FVP!wlYgIA}IM7p_k3r2bQMV16CnBSAj4LWFZBWVCfTU5%`Ca#z>JCl{Eiaoi zJ32W~`;#NuxHjyhBlSh)Naw2lqu4Ix)~eXyWlL6`=Kfq6ETk6mqUyc?biN`#1-gfE z^=Prfd!tFN*z7NlvxlgE32@75N10? zAFKuoqwZXxD2)q`440^FSV*;$V^Gf&KIq+HWZW7RdWJISrKN?b83m(G21hFGeuHKQ zAb5{$DOaxNklu8+(g7-^0zN|w4^Glz~* zDOofwdBUj1S#609t1WL3s2aj%%Gscb`mW*y%t)ObFDwMx@sAWWPWwGIx|6VgV0aOf z6ZHl37N>>x4e*N#6sRhKfPq!2R=T34B%AWWk~=>%UE6_KYdda#Wqn<1rgAcZB^{W;YC@%Bdv`p+ zs@|V}=%I7U%$L@@_}sjir{w9%zS`;M$ornJGfGMN#ptL={qLemgD;>v+4{&x6Ez3U z&VM%#UH;xf2PU6*UD5zS1*~VX!G)u7VZP12w>YbINCrBsYKCU_Po=+27@t&T(Vo;r z>Y4@&ugx2i@k-vv%q0B#nGvT;!p~7_-rlJg-L8(_kB^QGY`w$rAC9g=fkFg|5{_c< z;{NWz>2Jzgr6t|tH%;ebqg5;)8~=W&^LY5iCvo>J^&CSt_~VG)W@ze4Bcnr&&P0Qh zw#u-@@Ss6XGdM%FRwT)v>wV>HXk7VHXcPWgif0tcHJZqb4y!E^2jlWcyfT2cT@YQo zO2ktym(p%4c3e53U;vd_(zDB=+!6r~GC|bQvmgG@zwL&!)A6bC_`fUNm6wqfFsfjF zTymTv(SiR@y+x@mu|$}H^#OrFcrw-=W(f$5D2yqNa#%wG^@d<;Sg6$)XfSEX3ieLY zUX{vmnzqv^YA^LHwAr2tdO7F<-lL`3fuPa{U;uKEf5COsp+j7_SBlAbdwU(6KB-LB-m{(S5kUXJB_%QKcK}2U-+{qeU!BZ7zkj2_kxL?BR?-3_jzVy;mM&(2gS5Fw;9LgEQl@7A21hjCAc}-vxWjG87E2& zGvMZ92dmWtoRRzMk~QfCfKaO~0Wn&IKsQ%FNEx9j#3W^(_AK72<2W=1saf02-=`|V z&*{xN{w4qUasKm3%7`%)sSdG(xLFMOq=XASVCetuYdOEN0Ey5Qb zO#BPRzmO7rzDP{e={#TTMs}UaupDD2gW43$YKhNJvjX@2G(RcNJwJM7OQ(+qWSM|u zXivlRniV7XEb~3HL>Eds=TwTyha&=0tOpaadXb3tM$yg37qm^;$OsyFZ_9Hv3S0iqzv(n zq0vi4>%?vQ5HBA3X)XP9k}}T=3+$D>aX;RTm6NFQ=roMxx!$L`5r^`wLz6Pki-*2Y z{w2Q1@cAMm!xp0OT0k$!kS@xe3JgD2aArvfu*-me-LmI z;IgtfMm~4QbgN;Q;Grf3F7Xgn%M6;;3?0uQk<8?gS>zynulriiN_v9G1Eil-e@Jk0 zp+|Cwn_T*FD~olkVRO0kvoIBt$k;W|tSbZrVpVHstW^AnQ%^4*j@Q3{|Lo5p#xbM7 zk>I8VIkDRLx)wm-4Fpgz&cyX6%S{CmZFH+R6=?CrsrW`<2zO&Z=V@&=hp1E`_6mqZ zHx+fz!Bu=cfrE4nPb-sbleNm`+KVr_4j$n@7h|T;=Y&zyqInA#Ngm_)pu}$)b%Y@u zFnmPMUn=9m|cR1w6$mg8Fxl-Hnubau2@}shuZmmIcl?wNSSH7a7 zJ^0{2$#c1ma(n@sr4lw*6LChCSQ=#fnZUsEG-6JAL4mN}IObp0{{X!IBD?{c8QM2! zjL!f*UML!uTC8pXx7k^o(&QHC*Ssu4ezYgL*6ufK$!6MPExQ^0fDCbPw~ zpG2tqAPjOWdfp2RfFukYawI!KkXHPP>mK%8FAbdPe+jDfK2)QO+he(VYn2bZ)X^6` zFN-g9K40i`KAaf`yXToFzNl1wD=ejje<5}Ui^XS*5M`d<7?nL6#TSD6;tN0SV}ANq zxqj#Hnbt_Fgp7E0Vd$cM2bbaTDg@kavO@#hR-{(hM{nhVHNe3wfY@ze0Vo$6KgXB+ z=Xh@cGJ-L6r}>z<0wdl|As<5BkW~H8=3`D!Az;4cf51nR?}td?XJh{)J9_5##d(nlO65sKsvXp^4V3caGq` z_(E_$CdOxHE5csrJ4Pk;AKL$!@WaFxiHSaAkj?MpmLiWh6Id>v2k)$>WhoA1k)hyL z6o!IkO)mxw<@+(0PUtJbz?nvQn}LJ3=giA zRXnL4JmkG>;kGcJ_y$Y2mdl*vaO*zR#uanFbs`|(uj2j;8lTQlfLeipJbR7-JGRgi z$*n0Oqn%4FVW2%7R-bTq{Z&x0gG+va3en+D1%K(GmE*WYKxk+#ko*`A9gy%HT=Ic~ zOZaD8!Zom6tz7c)CH-7RvnHaO;JKGT@MQe}Px7o;&c~J$RSswf!#&(vAPi*vfPuV* zXZb7=ycB%srGRUOu<=rak7gi`+2fD(PJ^}d&_-YMye)Le-|zN*p-F-7pTapcP~}uE zr#_&L7h97Jn6 zaEiuU#$|+$88}kL)jsz+iafGLqpsyr!bc4pDdAWnVEC{kkA!Dz0BMxKGYZ=>>8Qkp zs0uZN@TodV8252~5*SBG&?}B{h!-Qx#LW#&3M32MU|3@s? zM}*zf^C|Xz;uKdxP;Oh!fhKWE1t!i# z(2vN`fIvQ^kqVdaHA^|kW7k7CF49ivj|cQXs@Ge#FYqIRx-gNQ$xmfi*U!t%7l z&h@V9j*jMsM{eJif2S2CS0;)E|cl_t^{O2D7XdBnj!F4X?D*{xY^@TBZq zH_5J&?tx0u-emWfA1nL#i{#13!RKS@E^*v#@TBNv@?`!pIkZ`acn3V*J($BMd`!G& z#4(nLG2Q34-flpI^D(Ch2+dn!%y4x~6$hQiI1Ze(-0=a=c}&GZ9yDRmYg+CT7Ru{I zU?$oNoRXm`B~C#}s5<-J66~)|PRVqY5_pL;dvRjHY#32lbBIb!w!q=GO}ul) zE^d7rhz?e{i(|03=khhyW)EL8VBl-BiSy|ytRiYjKtI0YKX>q-e+`@Df#(+HufoCv z``9F;pLuQ4RqSLQO#F)tzy1Y0QuvYXb1;3;8!Wzv^%+AwTZ-r$EU;|h63#6!EKEOG zU<+Oa_O-zz%w*KAlG<6X^bs)0kZ3@W<1xY z0o^WF0G@JNJOzy~!jLe?|GO=2%wVsXa?qa~;Nv@73pGK6lc5413seG2 zymvo#Y)&8P6VqrQ&uMAchC}(@!p9|8&m6kx8+bohSF>5&+DU?np`*vS1Z_|y2;xE3 zEY~eTeIY*3eDbRhkRa?pq?um%@W%lOdQ?D&K}doK;!hqr^oFC4-3;O>ABZ!snKX(Q z#|rF~R=#qnnj`A^PsXebr*SnU)?Wj(ePBN5ohD#n+%V83eU!k%a5KRrU_W0EiG_OB z1DN_iomL)Jp}ebhBd(*08&^LMu4iw+bw+tw#TDm)D&jFg()PR5wSt+XwMulaRbPk? zSmv)nV6FaJa8X>^&`S8@z*_xDK!`zZ266Pu{|n*_sGzm-$MF!?cA5*c{bvC&*saT) zj`cne-G3GkUa7)*>!IzC@^nqtFRynWn47M*Azt8N$9`?S`#}A|diR0)h4tMvfKHTT` zAN>8s-*5H&o@^uZfUm6xX_0&oj%hwHrxj=chY`c5FtW}E=BNT=ej|+ZM<19o%8NIH zksG*_(0mNAjnAtvUb}D$Y)gM1m~LgW3gf*M0)_Jbav8`V`vy#VdS^fbeQn3%H^6+* z+aO?kZHM+NfrnlBHCgHd^$W73OA@%ypOU%lUy>vq^`g}g@iX`yBDN_dxvf!Oh!4{lVMR(vHS=H;_L4y={Bw|Gy+ zeIbr=UsGbg3~}arVHNx#9^l$cbHUE>{{)1%kSB?tQKtDobpJ*`nl+T+ zE(IL%XmX@`EditdT);?n4s%+0gs+msyn8Z1eXBy@{0vNIJWvh~|H(ebaQz!9RdFaE ztqKe@7!1NP4U0r9BjUO@PJWd2yNRyfN0dsF@p zus!_5{p&DiG<(&Nyw+FXA+KG`=rP)>`B-B->){WhH*|wxG*X!d0`^%yoaCIX(3}>W zaogua_liMt`@pz0l%aS|^n?ceGvM3Mx4 zFMLVDAiTUcU^DQ0ab&;A?=J-L-+LnT!W*IQHwp@r2L%OI_Z~wKxAHj(hzrV-0wT%{ zA$Abp;QN%`@WvB-mLAL3_xBfIali%74V|!AM1!z5Z(sn-A;OKn@9!^Y`R_d*m5^=v zp5!0nH}l_nc<{VHvlWn@e{xyl=Uy(sh;#52z?sAE z%<|X`u>Ab%3+p|*^nM-iy}(P}EAaBYkzn5hVB1Jdh-D-Zl3hA5uKkJ32x7_*;F(=YE?X)?bF@{@bs@s(u{tSj1dZ z4iF7K{v4;l4GUSG>rbtZUx$@=*z4C3XUVVQD}hrF$+FkKy8)K_cfPP*Kd<-ez!P3S z4|qMYY#<*s@C;5a9t(?8RNy(UzXxdU?-6Fh5f$3U?*sHUuipn~k1QKjs?a|E-wn{* z|Kqsb&^~@3ptHSxAaHwR*$@NVT$cU3JV<|^FFdmR3tw=*ka9cutpRd6KPL&6#PNu{ z2=W_sEuPdgPaX|CU|1^nm0V_2Z^Ty8;$$zl~Z3+LQ83~wkRYAi*N5aHye-Yj?_E-1+&IuPc8;NHYp)$efo8;m)% zZ=!lAmulp@gG%M~fha9`msh5{YlP^HXEga>^#gM<2j9QcQZh`RRG@n&YtYC+EuB(j z&_Jg?12nMlO0m??+pZyAkD!}D;GTjm32!pJVUOlMXp=@(PeQC(ds$lu?%~E5t0=R> z+HbUN`j1dg8i#mlL1{mYJ~&j5e@yGCup^rnc08rkYqg0{QEB~9TESlmYVdtYhk9eX zP@RMK+NdHhpNgAOlKWOYiQWRz+Vp(;{GwAsZgG{yCg(a9lsw+QDyjU7A-T0hnJKw! zNpVi?u=J!{eO+e$l}u~D)InFA;pxgZ`6z=b%jiF#w06L#3`mpMwMm-p64EIAKDTe- z@xwVBmqvn9y^ouGk245Kk^6i1tu8;y)N^UW_jJ#W<38-ZpYP)Ny(UFq@W4qPson}% z`$2aOv8Ghb7Lqo|l9@{ib4!Y50bsrX407GkiU4PVo<9l*lPXIZV9{$hmUNAX``i?Z z?mLbpeeKP$Y=d{usUwNR<)?;x)urH##6H!&DSrxyG@uH~)E%r{k8ZQsZ$w{t12>#5 zQL5&tUsGjM{-kz7f89xKv@#e%T6F)?P%fm}%Mb2}*m>Zxzo_yNv;|z|X#_cJeW1-V zLLaHOtMzG;!x!;a>E$n!?5pde1W!%97_s2Dn8AD6Q`#;r&55X*#A{zdmOn8u(|WCz z9`VdR|1K)G-fa-YiM+V`rqXNhAqP4r9rqF2q&&CSX6N+JD!zM(X-TM8Vv`4x#J-o5 zU6?ziMH&@2NS_XQqZ8{Nxb@{HR^(Y+?fm<;#F>c1;jYzO9A0Ib4~z`KkJJi z^BltPnt}^8kvk%CF!(KCU#Qo;P-+Xm#%xk@euNDc}&}xRn(U<9crs5N3B~38Y$nn@e>DWxo89 zZpi;sVR#0hS3AsHJ2aA{hx}fFbcLci)zodatq-(nvVSY&7q3@QeIB~}h=#5?g@dB+0>{8ZydyRgzr}SmN_<{6~^(r>XOq z^G>$5Ul8SeL-VD<{Y@uE6uHve##e~)>#5nYF{+<5%Di)Ub$`eXk9}}i=CKi0{YNgz zp4=nxd-5d2@5kX91Cnlc@9-jaLUJr(E3bX1O0k;o>W=1)=dvzfUU$Q&ZY;?j<-Cep zt-HC@pz92mVaXk3xdGw>=Jbb9=R)3uptV-e>WLE(t&4o3%KH!};yGQ#9vvW=MfMPR z8behb_)jM2SA;9gFb$xn0n>TS6D=2LQU9{_v)3GJuaB7G6BTaMG+6;w|(Y(tIFTJI0-DCgpcY{mRFC*XOL~+)HA=tIq#lbnKV8-7{C-4ep zAk!6z66XH-BX|k3gG!j|Phyf@N&?W=z)6%y>jMHp?Z&xAHrdFGj?li8aCL&WkwWHK zcoe=QNu7?FZ`IE(m~{CDf^-3czYo9jj-oOC)PRlB8trAdTJO*VXo61b)??4(lU8SE zm&ev+mV{_e>7uolZ+WyJ;<3AU#GapZ)c78G!_8PT@43(|ffSq5ZKB*QiUV>F4JSve zr8wESzfTeIKVJ-pKiqb7XL|X|1&`Hf zuVKrt$L7OWmFh=_YK&+8KW*Ov5OtOP|GnSGJbBD8!0?7)gb@(|M;IRolNzG3O2m>F zBH@dNk9-mlkxMqKW`>rTn(Ml*5o_ieB3jwQ%*@PO*EMrp*LB-|ZEd-2+qydQ<^Q?& zJ2MQXW&M7Cbl&%SzUQ8M?m6e4d(Szc4{KmXA7xj3OXBk>ko1`uhC9otr2m%i1+1Ra z@?|bvQgH&O`7Mou&O`*U(P~UDlT`oxJF0Y%9t&Drkd`B2IKrvdYxoegRtVNeV4CPm zGmTfa8j*y-=Aeo2%xYVDSxZiPdrn6OeQuF2OOsn1?K>PD9gZFC4j6eoXXMLd58&yz zurAcf)ro2ZKx6ua4WqHcG@k?RZ?QSZp7V~@DHaUCd{humBKjO-4onchtx(<)kzR_b zam#3Ti)n8s(%yPoiVR(}BsmsPNk)CSQgK=F)kLWcFvHOD3#pY_v(6xt12ITR5)K~- zl)eTQ8&8Qtsr$vDvP0yL!pUoi;zb&Y)_bjKqnpX)cclZAOi^*a)r7meE|^ zWLst1WD`nlGi-dUE!{T4CWP9Ep0}Y>&E-kjEUi;3!1T&zNl$6L6{Mb0YEopfa)J(@ zZ4D)2yoL7%ocSY1jTtd=l<)QSyuP33j~Z7vdi1#QLL+@MYTS7F*JBC`$KZ|f4Sot7 z)lg^}BX+%LIfEo5T@ZsoLpmI&{7VOft_lRZ(VAn4uo~@n&`~)A7CCgtH!2uhWn6ea zp9!EExCL57G>AzevfAhbn!hR>mC6ODpnjewV44rT-wq?1)SJ*?p#;bf(2lx-gy+v#UuX*2iXv82u=zXf>DFg z$Ny$Z8%FIwT1WdyEpPTx8ks(G1PkN3X5YU0{TG)$G^2g)6=~w5pDetms^RMuJKE*T@-Mb*evVk5gf!dAJA`o5 zhL6GtO7KWRluC%Cm0`6JhJ@%Wt@mayi>9)Sr{0t@)G+ea(^2wnnP|oxB;Z2&xJWWS zapusfMZaCUsI~ROC&%U`j3~Tsi?wQE)sl>ooZH33^z7#Prw^}P{sI~Nq_NSou}xmn zT-h?Hs9@|}RKBj@NAhmz2CIC@I(P}nn{}G0^;4vPj4s~G4ihF-BCp?(-suBRW&S=W#IIa*-mly3-a-G z#$~ZDu9@3ZSN+Q=Yh#-$o9C4j7E|3H+cORcV15cq<#81H_Ryy){7*0PB{+6c*{sB`Q^Pw zz#-XK0X9?#w3rwR(3DFok1Wkj6N&7a7NpZ-4`GMrtLo?%elvE}8w*++GiTR~eQ-+V zl~@x z20j>oNYy;lhRPTuU>U2o)|Q9qV3wc20O?j2W4r z3R+8Y1{I_ZmX|!b{#W}7TZ;;AuWaT2k)9$ylKT_#RI=w+W-@GJ*TH4-%Vg3g{a@+e zHM`$8MLiJ_=1$QLZX4D4nm+k+sZiw}Hy~8_O7tw4?-YW^$-jj@Z^3%29b?lERSuA& zRl`ZO;;>~q*6;b#zuzQqOj?dI#cH-&>^53w+)laEYCd6oGJakC$fMIWv0t)8#=5c+6sZ*M0}%NJd7&mFM` zt}lVh!P=+>{nx-3K8!1N4#;t&C#LqxicZg}Ezd|dL?_mk$3~mNv_YJ9ZaK&4gMz?_ zK|;75;=%5V3sGc4AZz-{3@M`5%EXr?$%y3%M46IV(jO)gkVz7ZK>bw-JaIMu{MYx? zE?D2P2emTvWbrRnEPJ&^xOimumW7U$x6iI~PMkIVrM72UM%2$6d*{dr|^Ub48fy{CPh5^gGdf?&d?ylxn-kX_yXyjk${Lcs7kYfT|lj}@? zJszZ=QyyVB5k!P%gNPKAsUH^YYeKY$aAY&y~`hb_dcD ziH-#M97%dd{zv+XrmnUfiQ8RWE3%z@_Ib~8!S3>u@;hgEy7`?hzSYw_hR^rVwcKRP zVMLI^T7d0nf_Xc)+#pD}FDnrO$%s@~xDAqGIq)#ioO~7m-|-9nHC*0Zxqr;(4pNZz zcLy1LuRPBxoJ*4D6?`*P-p$Y2F!uvFpNwpq`|gppIY-Ic+qTKCJ~QVe=1sO7u5N_H zrXHN(sOB-mh$;=C#zbSjagy;x<7-A0H^49eCFYF-j04h=(gw~gPYWBGlr&^+d6F0$ zE27|p2w_eOxG*gJB@8qDB`1`GwWzJBLQY6l)FBeqj8bkM<_sAuhOsikNYf?Q2lqo2 zihh_rw9tvVapwL9b7sb9G^+3kJKIx^KJ(0T^6Pii#YFa>KfQJQwbFOVkR9*ItG@WV zd-plho5b>r{NKNny*)m!=&xki`~!2+;u`Zrd9SO$nEz(LW-a%x4+|HaNb`m0dBs;)di z2z4663t0^~tq>X-nUp_dYV|nz%G*n3?Af+GYP)T_dHYCGNQzR|%WW2&Tw=>3>!Qv+lD%waqP!qpOu4UM z{-&SHIHWSaYaUH9FaPnb>0PAXW1g}JPHgxJ$SF~Q%tT?JfdyVLhciCj8fBeZ9+r$p zn4WOXDCFbR8|Rh>Yc+c2?qD5@%8xnDW;g8~QnWczk-RXBqed3ncd#jyHmzy`xsL3{ zyaWTq#D`ek`Tc%UeA2Mo(AiON$EJIhkdDobN9s`e?9k61xYG9VL*&wo74s{%Z?=)> zk9x@SD8n~yoNoNq_`!nboF`|12cE!el`#_I4*Z zp~acBjtUjx60`~G*bo#%p*lQYAfamfPgL{p9>Jd#&SAI)=TpOR>H?^5HflcQ%|2vj zL0};q$BP_GK9*zons)NHt{0xes^DwbgL5HWvbb93DBcuq znp2(?o)H}rJ*Rv?%$o3Dg!7>>lVb4H60;`e7csBJoQSy)(-VVn36BYn3AU!BB+V^P z5%s~;YNSRZ#oxz)U_r)%SXk4qm1oRC#NSZm%Zhz7!=CaV6b$4gT|OZnE=@*Btv1S~ zDz%sq@39O>U9sf1og2>_yO>cGw}0%b3q4=Q^A|@go&C`BLp$Htb2@E${GQvMo6onk zCjT^l+PtEz6JGuGypmS?Px`lxT2MBlXmiPHn`RcbW>17?oM${30v@DUkh7doaYi%v z4e0@$W>dUDW1zeT_ai*|cEj;r?ql!#tjFwoX4nhVu!q3(aUO55y!Fv*Wc(>G-LD$P zH8fv+?Aa;L{xm^;{gDT*to^uU`^E%f`P;wAo^L`YOfWdt=V`9Zk{nwsv1BcOX!E;? zqATho4FMu-?}J*6F)LgLV8uu|I-3n&! z9m6+tO*NRC;LL^zq}6M6YNUZo)V1i==)TnT=v35acc1=Y{RjF#>o4ooI=xPBwk4V} zv&n)Hq^$VVa&i0B@#q|62KGmUOw>Bka`Dbk4Qj?|Gy)eYh*Qf26uzg12DQP^2b6$t zSf~}mH+6pMS&>NIERxF-NryQ8TGu)7{8`6b*GG-oo8qfz#A7MX(Tf(37 z?4zfKBcr`B26;V~Rl}sCtR>BQlgcgr3u`IlD=qtZTlRc~opsdT!hZE=v?F92H$zp) zkHM&9JLC17mJdeqR}_KQaDqX&Pk2~(0x4ZNjUb>rm>KmeGmT-y3|pC?)tz-lCAgjb9@LNP7vxFpxDm5rXH@<)!t=mASw-K0;4V7Zu zwV~pXYfo3=I&+UKc8GMpIl&oZ;&ggWA0B}!ZOl_od*-Y8AYo^MD*4C=$Z)FjRS`yF zUU;&#^;E;G!&|q#&hy+;mzOX9YMqQjAqW3@@sLby#~Iw$Vxd@!cXXG==}g6TfL>6G z>Y!k;nEK(T5kjzED1>S=wfWll+6&q*wUo9~>CE;r7sWxLtqFS&*xh1}8Ny%Pamqt@ z<;f>KL)Wb%GoE~sS_@ksza8Q-$apR7mxMwvoJyycI1Nq6oEg|JyO9uMiUrSG$b00t zdmsN_xmA9IZ{k&+tDfa0I2lMw*b=UdsKg8*9uywnj74TY?20~Ap2Q(?ZW?k$zldGv zFS#D{lI|>cjd(2HL2;wCP1x+d@}v;IUTy(j^HyXPJ*Dcv3OUZH#~5fL&3cI#8OaUD zd&diOR?I4@OrS+zXQ?9i&bIdE{33fwVvsS_VocVn!EM*GHp2qF)hVTcWJ-jcSxOr1EXr(i%lJ6~ z=WEnQ(bCk#V^;}+8#vHDdRfv+&a}0ukA5?OQf4)>fKs>;!&)s$k_tJjam8ToCF~+b zQ+~Bz^VF{u9BtR;QH(&-M0O?kAICev|K9CTuoy-Ro`RIP79bg7@Hu=#zCzzVXEG<(884`TohWL=X+TbD=g2!C6t|lY zWVFHlK5CCm!(Jd9P>g{U%2Ot$at6J=I!ZbyOj)~D-T;P%Za7P4FR-Q(4YcD0_@^;| zYHZ+9KK034KYL>fYxjcHeVqO|6;A^0W*Ssiq4A9*Pdx}Cu9BrTQ<&GF4buudbLIXA#}JK z?g=Ri5CIr7cx<%krmWN{C$@dq#%36$uVhtv&uEL}@Z2b;6_rJTv9YU{^st|%sR&9s zNjJmY?n9oLYQ5NlJ`8_yRygPG0-^YYxG}nL^?*2^^};*5DYb?>5sHqSPZ|wW6?BI{ zH0>gJM}%o)-IquV zZ-Tp6a*!+)$P1_1+@1X5HaVVOEPQ^ozf{2Rhdkm}Q?3VJYPs8-N#G_u9bs@(yF}iR zh)UYcqqYFy=_skFsG-W05lWe1etu%Ij&hV&>L@bLZ3RbBe)7(GE!WQ(D(W>74}(^x z=OqmkB2=p~^SvYNvpFbiVN@Hr=uT<-kO?u#3NePcVY=t4EjJNANh*OZ7ny{ ziNHlpi|u?+={hE&W(m$(^}X5koWx|irxtREaguQUDtr}+W}p&+aT1lu5D+@Oitx&r zfdCSLlL%!=HkXA{F!L`d%tYrKq%4zVOxjQiK~iX8E$BHxF9Zd*YsouWqSEfxkx(7c z5lSGKIT(X)6G-7Bb|(wyL;1*U6^hzqRh#EAatYW=1=rd@9lv&Bvm0C#%&T-dy?=IJ z$4q+4NP!a6E1Fn;e53D^P7wZ{dM2LKM;SXoK=~vJs739=0nRWn7~BM%sE36JrKra~ z3}vf6Qpzh^6{!LF%6JPhLw=gdSf&Y>nB@dT{xNB-MPx~lvww(6W#mYZMiYt+OoLI8 zx9y?iolv3*-5o?ian4dpbj(ilF`7@3fZ15jys`_2VHEogpXq$5Yis+E$u7opa=3Oc z*v_4--AfrSKxea&R5*{SJ4K9L$ACJ@eBYw%b&?ESr<$E{ppON=nE-JHzVT`)N>xaH zY9W9HF^(KT1sEvTzBIM_traWPf>s?Ek*O@EuBpu+S)sQCKU@La9mYogHqu0XZ2#74D>ZlJO=^(ohZ^)kepYvM1g^+)*1* zyBAza1vb^h6c?t8Xdj`A^a4&EV)IF*!rDS1s;XT>-q8@1X1A8m@%C$bI-*|F0(V!& zlj?kGR}j1^){duEI*7S}F%{`?WNZ1gEq)P6tmd829(2Z!yX1v0$lwX(x@;vTkSUFxg$Yh*2AN&d-%hn5CYuCh;IWzR3p%GL9 z1RISiJ}fLe!oUSHYbHqa2?DLxo(c0w0!CbAn0;0;#+%wU^dI9hX5TQ>6rt;v4t~+= zRa9R2>$iLu^-a()abiSpm=0B%A%jg2!r>8;HaM6M3xOmyc%=pvfWJ3>aNT510y=!5DbF5Ow)iSAr z|3buZZnOp$-~(GZ-@G+8O%X%lZT-ElsiyI^=1+TDSI^Do7I6(+6Z|Bth|^nz%3ABVr@2k2uk|bLInw6*H=jIs{G(D`onW<3 za7pzcg9^$Xkmk(`%^Z7olQdtIkUMduG;5YR(J^V2G&^j-s3{Lg3m2NwN8i&TEz-pd zFL_+5uGYtnxND6xJu)?~@@LZ0rDj|Hv{tEM?fQ*dc1YW{t$TXYFP@Wr^{a;Ii)PQS zSGPYuefF<}`ueIFTZNiw_uPGV#pKdScl|<`Frlb;vrsrXf9zQ2ZDSlGHVJn7kf9rd ztaMvuX8(QzV-ueitk$TwCxs-lDKs?P5Tw?x6X4j;JRxwcElo`iKX`vlY2lcxfk{E! z{r7W0NdvRS6qeTL9$9?foH-4P=C4}woZxc({ITuABh&+IH^R?_BS4r@I0OZi@BPDP z`W=3yk01Ssc_zIuZutdnE1dF8@jj%0_v(Q6H~Zck(B_A>Cjr-9|DK(O#qWWyvubO} z7Cg4in&nx8*R3@*Wb3S1CuYr(D{E`z>e^Z{6z{8QYUHZg+7rF4X^U@vdlMM+Ixl4R z>%H%<{j(Py*)l8OPugBh|E5>czbf`OQ+aEgMNEnK-WFAR|aV8BNBL31pHm!5JPi z{(+9Kq>ny|ozV1~e@W-g@q?>(bQ4{d^oKtP_UX@c6TLG+I+HN*@m=3YfBIA6q%|-8 zN4lWOowco-gmg*2`<>b``&Zp06pc6&y&H@t33Hwo*K-hW>| zqW%}%#DqpCQpD_lj^XG5sCg#1;u>n&aJ|}yH`3gsB-1OZldavzW5?@+N#&O ziF&W}Wn{t9wcRA4OM3H7^Vo)Uw_6cSCvk^xHgXWjC3(mMD3JpEvw)|_|m?YflU5B)o*^Yb9ZO=E8XO_E>$~~bs*M=eX8f4d*aCr zo40n8pFqYr2VJpQ@?p!G|CD`D5K=NSEsV+4b`mHFOjEKGpQ;Giv7Cx44^R zq44pfyY9YcS~tnur=l{kbaF*E8Q7&Nbd1O!J+_;q?^991c$;%fH|gJ{%1X4_(lfh> zZJ#POHZG}O|AF14UzaKhTgN7IH?i(hQ4twr2=69Ioht4>*Ln^x=9#cp^{;<@eZ_r% zaL}BEPP6Lr@7uTEUsaeD#a+J4MP(IM-M_v4_quMP>HOoL|N1|lcat&uR3CnL;nF9c zeR+F084F|WTmS=3;#6QrJxXU8NH~c?rNttAgC(R_(kd@~CG9QCMV~Of;RQcR(tanz zKDQa{ZK}v-lq$sujJ^*lkFWoZe*VAwKIOW5(9aaU?FJ7j`)`Dg`37z2^*3uz^}vnb z-0XX*yC^JrpYM95dW5!x4uOEj|C2Q}CzlBD`!DB#2T;Np_h4cq5hNPN zwk#wCMN>0SttE#HBO}S}V^}j8BP2p<9(?|P zVx*%-nHZFWN%Nn2@oVYCiK01=?fkFw-i(%C|2086e7LrG$EUH<+jlKm^U`JM)T!e8 z*6#kd^g&hYFaMk@z46A(hqry4D7|@i!_)gdm(H9iUHnAnKc(MSxSsuEs`Tos_dc@a zqE$M0?I46+EHp_mw8#iDqHFT~8@m4?efS#DKn|vnLIg=jKzi7|sXyO%-X5S-{9Qgd84F)g4^{VT@+N^9atJjP(O2XDV8K(Up8 zWI;?>WT~Pe-~Zho_Cqb^?Hj9l_uW_DIDB+JCG%bt{|Xe|elmm%-HQTj(0Kc)iLrN# z>NmUgbnS;S9kg$>s-xrCU;g^}{R9KFSEbs#b$k1M(vS4t3lI33r=H#q(pdI7RjVF< za{Yc1Lz4F8t5&Xj5c+UGsAJx%(ltHwvq$&CjEUT<3J!)k+z)bw?!8S_KX2jE{cx^^ z>>Ht~tE;G*QL`VU(d<=)+%s+Z?EO@SIiplYBb4Q}o}sD<6HCgj$_~}|@l;vuCu2zA zURBsRXsi8Hv+q?!M0|ev>;0sN6g%UFpyc0gRI7CLArr!`TnU>HQm3={=>Su)5?GEcb-qtnqB99zMkaQpROkzbL;EpvM=lX z7heCl7Z7irJNHaIuA~3?&*|Ok>VA(;^c?`y$#>(Hzo&Ome)GMe4O#*l6oIx(CrQ&u z^1bxgQcWz1g77{c!UCyMKBxSzkk41CY7|veS$WW_jH>-#__Wqx-#3+&@&%vD^6RVK zul%Y?bzD(V)g;OL26x3Dy#)h*kb+jg9-;slFa;0;!T_*~;n!*6z7eO0r-~$dt z&_Gi7UYdjpZi{%@ZNXUl|{o{!OtEXV8Rg` zoMI{xcj5lK!uo=zyHQMN zWoMzfP8;j~PR|z4CI%bri^O#dHky0=bksLUTdRsZ9iDb^-L(?jz7KTcULHI0=!YK@ z7zC;*pzO|T!}yti*UoJdGsHA_#S-a>00XCq;-Zo);X!fAwnqT1Ouj=@N(e`)Bb?<3 zqo=6pkt$Vt!^!)bPBu24Y`XtsLs?aO_4JPFs-4rTI;!{?ji(y%|9<@Xep7WvRaFQ5 zvAP{KdAMq>Oso`3u!j~3zg!~Xl``Rv%ZD#+68vz};DehF|62>^cD7BfD6Xj~oip_Q z`)_-&|9$rjT%1%@)o+HTurR0yTh-ziLsnM!kf^x0A!CYWEPilKh4$fP;}*nRo+dYrOOsPz$3@a&%EL&6dTG@#*fghfy%InD^x&ebi z1}%MPUS(O{ph0QSTL|7Elr zjt<5lbpJDZi<9^MFO(k@1;zYi-}?kU4Ywxe46zTkd0$Q5SF`uk_q+PK&%W<{uh;*6 z{pXbH;QQ_;oUtSJVcn2n!-o9Fk>kj*(vR}c+?<@;7aTb`4!(pwdtzypJARqJt!LMe zVUApD&d{Mb+yuja}N2G!;y0dMTNNR@tc}#=syTJ^dGs zI!+uiC*|^WbI&f4<$YbUJpYVvb;;SfeTZY=_su!ofH{GUaB-*DidoN27K)q@#07;% zXgC9=^zlsJ88j*c;B+_QAU-{O=AQ>?VyjzhIJR`j@rH(D4NH$N5nHb{^P}*-;rNop z`0_X)2i^lQdd{$LPKb*O5;?J7iYCc`Pyu$Y^Y0tp_j8K(cGpcq+YN4Cf(dpnCRoS4 zm~0cjjSGIp57X&HoF0f5k4l`&`D$Sai_1@ShMABHL=_wz6G@NI;tU)D|7p$)c5K#n zx{@6jSB{CBBh||BN*ZvH%U3@&eOBAL8MOuDCd@9lWA^lM6Q}Xb^{bz#nYDI&;jDsL zvkD4l)L_?>?1p@6ggn$EMxr0ivk&L$ohFkiIx!`k3ku3jAD*aEjkql*8+FQ@X(&dY zoja5awcDLqLt+28xIxLG$&-?&B@6asdvc^UQV31NflM4=raODkF)a9nI;0VlV4wPS zy4N_wXYXbT;|tpm&XUBbhk!?LR52XIzqo*&MM}M=4Y6Z`a1t{;*{EuipLSo9pW#V0 zfv6?bQ{)pLoqc*Ev7h;fWP7G$SS%UzK~AMxESZ@WOS_E|eu^W+oVUv ze5&DnJC#|C)2Oha^F*PC6fmAC0q+?JY>WgOK>}IctdM{w(>+{P0_}A|7CAL2f%ZCK zkY`tQ_x|d<32WCC_33p}KqqNu<#PuPSXZoo7AFNgi&P=v2+Wim?mp*8O=zgSUwnK< zN?b;AqAiAxj7&32VY=X8yV?+Bz%n8xF)m4)>qrhx6m(&sI*ruNrslJvA_nwNqiP>w z+J2NSHn1b1oOxD;pYa8K>tzQoOV}e2xPqJ*h+c_61RL`1;9Li6SVYs?5K?c=vFFmv zK)DVxi|qxs+lHhHD@NTubHss+?lQPK4MpAAU4!qQJgRZVE9qSm4QI{-6?dk+GXK8B zRc{yV zj!>GMaE`y%z$CWzM4Z4U}AtVeD9=haYlOUv|8Y3b?A`tJ~AOPLFGiu zUX*gS#y1mu-SyFdbsbL_dT&ZSGmUdmdpBaSuW0i2(m|yhe{R8wT?-mY%huKq92+j8 zqBCW3LsMzlh`a`VRM@tf<{f3FjdQkz>?n}05>)};cK=Vy8uLb$mNn2`lyFy(mv0%O zDu;3fPOBN!7_)4N11-7X2?<>8K$|pdcmfxr2_2X?z}_#TU#KvE#T&5n2XDOvvE#$r zH-Z#z8mQvPwbOIJco`f)=djrvu2v_fV$4|B4$bU=pUi6CkfARkw=NwA+%%Taw@pq< z4h<0vL82HEkzx(`tn{}Fm+WkBx})@&DNW6jCpR^VsFW*)Xf>i}3=Rs39WnhULz1*A z)u<`iUzE&g-nG5){*Lsd#wpX5($>&NBcMk_@dP3d)0~kigWhb6QzcvVX2b$SCr0zp z(MD>RA$ZD84?WOMp(9{B{AV#Z3B1{CaZt^Y<2~sNmC0M8?tN-?0l#eW<{4t~w&g1K z-&IXJCr|0PXW8VLE0&8Vs@flGX&rlS%WGSARBBREs&=jod97vY6jw>Z0R<(l8}_}D!eVjc z2|1V=%0X<$U^5#B5E%ql=hA^-oP?iKZ3%)|EO2*eTn&}E!m!;_7Hxa7V&u$}F#Wa# zi?`lUYKXMejvl{x@zAByMvB?q zWpV^>R!2_Reb0p4$7YnRv02tkzIV;!`Ky@q^xlF*a%L5$PUUR59IqNrG))EaiPCiW>Qjqx!0kx0{Pc;HJ(IKiXTGHvF!-bewvympyQ&=R1ovl{_h5QnV zk{0nc;9^_gS$Ohk(Z)HInZp)3*VPXj*8G$7OmW$aH`aBmZ)|C7*s7CNO;0;ACN45z zCK`H9i?^0a6u2 z#_+r;PKe?-#JY+}796Zil*BmjtS(j?5)_&cA7+Y-j?x92wPu6CtQFL#|EMNaYN8GY zTjNl&QSm<+j+=+khhMbNF46zW3%aJpu@DIlb&i8Q?8X$3z!9M~Iwbrc@<*%WuBxN> zt0Lp+t9(Z8BCkxAHqLdkplVRR#G7!tK3p0>!vIt-)xnUuox>L zPN+b1S_IAsCxnDYgx8kq5ae5nlp_L8l}1E_NnywV5Eh1@0)OdJYTabASW6mziB+_c zfP*Hgq5tSB5)quTZBN{OU)MsCkEl=^aVE;IkL0thp4h7GiTvcQwS1)K?`yl-Trd6}9?nikC( z4GvsNA)JJ$JQfhjFjJE1D5w#Hfd)i?vjiceVRho_IeX`>PIx>O@0vQB9#34&uWpk? z;%?j5hD-==P<(p6@X{uZo8la5HqI$$5zcD$Rx@xln3K$cS?A=!4dDn*3lG=nkOhc_ zed3c&#{~;q43c~xQq>zSh){Kk5{p^K#KQ6P%&7<=w3||~jKzeaQVZD!BB9hBb{$W z_!hg};tGsu2sjrxaKbcNL@whXkUl)zWD;x3VdLucu}FaLyN4~rpfJ}IUsUU{E`Pl$YkslzbQZY&v#Cq*!t?b zKYMBuU*VQh(lcxkn}b3Z&Pg4knj$|gx6ekLZ^h;v&n&6O3P~lGiH+bvieWlVcUjF5 z;h`a1{DAZ%ebUtOU_)4xBq6s`!qjrTfutkz1f*~NTNGCs!ekz%WMe=k3WT^yRvUN^ z`k!VI!{8ztlHFk!tjIG$b0X1!=S_oik!`|8$f`)wdrw?)t-i9p$np7V`LpP7{p~A0 zT@#~uL4Kzn`B`|v%onP6R=&D0Ox(_+IOPZEUb>KpLSIs7DkM-IJtEZTF{xGMTJoecoMhwYIy5ezcls zqQaUx4EtN^96LXG+;c}ff2p-4c4bIpj9koz3>ob#;Y;tF_}8oC-K%SDq?sH>bY7|4 zA~mpRJve6|35Ln7;zVGah?BVCky1>IZfbdq!N?gRBp@mwcYdal?n6m_0qj6k7!cr2 z>Jw4}N4tPmgxo7efzYviQD^CnHq#S#Z+|dp#$GbMb8=8Wqpp1K%txMx+~E0)H1oU5 z2R+enexqzth0AmEmfyalZq16J_W>J<9nH^T;F6tTh9H$7h3Eurm;~09!h~cxg=p## zx~bs91ZOZQ3N#IiaH4JDOC`63So>$w2%F}Y%`Ss}R zs861}a~~PsHF??~Q5-L)$tkRt{1SN)Iyg%%z5{ zLf2aN36C3qAxYLD$LtyC=1?w~@<>>eAubO1#+l4v;er7pV?by<8x{p|DnT&YSWbpq zM;J3-2GiMyEEGtx4{Nk})>vvtw8XnfUuICZW_^0G!YmJ)8$6L?Ip8aH; zl>WNhcILHnpZtT>z6@@uhV(5KD>)ct$nP48)e3bXerOl3fe|E>`3xf`W8Oj2!mjEJMCoERbrsUl>%k~ax8 z#%Zj&_kLKN*u%h>CfwJ-Zj33ya?WAG0Hf3#K~B9(E`BAiGoII}X5^B#18G{-h(sH) zXEv0X$A%{O6-2+{Up`Qqt}-C;V7e$p7CIb;=i&B%(K1M0^W4NQuQ8Ji(5zmSLo zW1E{^_G|0)R<6^jjD~1cgn;SD5YA*WpFLsz=jLKsS_PFgXE4o?rwAYwmh@~j zixmJgC|MIRmTZ2*v+J9pp*1tDrpK4pHEvy%7G$yy(G`|iR%ERbRM)zQTeCv7aLn3g z7f*lS^&#?Rp|rFjdwjyuu}N7}D#1FDF>}>iq!XbsbIVn9ehJ>x7<9lfL1}^l;hg8S zC#dLYGHG}A78WaMfu1B%igSS8C4t;e&NiUE}-y z_(iX@zuNUzdGp?9f;W-y9e=KQ5cpWQ4g5N93?p(c!}mZ_*_w$h1rL7wIM11Jd>VZg zKA$TupBpk)ew5lIJ+DX>(x$G0?hi%&XYd@>KF5c#?7@g{^o<|ZlJ2ME^!$P8`NOjY z=1Uf8B@*ihhhs$UNce&Io{z;QK3+w$>ryzuY62y7{w*9Nrbqo)DHE?dAf7y3E7xty z%b=h#^2AGIL#dYHxA38icW27{HJ*gkz$Q#1&BRzHEA+kzk#(BHoPQpEmO{M&p_mm)(9J_Hn**ix( zH0OV0n$(-v#ht2H2LwyHkcB!8wJfs~ow5FNb+ zgZ?3=nBU4btG;G5Lq7@O z;qp@R>flNISUS0okCY~71{($r1Ub}LbxJP0YkbDgk^;L!oXl@_M;2A)<`z~l&OFR_ z^37`GzQ9P(e7c;F7EGcLr=T7yOk`laaH;MLpdV=g+^(OF%WzPzQn6=-(BT8ib4{d- zA0{1RP?3xFVcJ6>D!6|zAFLLIpZU<83Vg4JJEC#csaF`>JM2TnFwYp_SW%?|=njRB z+#()A6q*^)LB=j`kSXM#QOSUP|7L(!rPA-^ZY*^t&o_*2NJDeQDg3q! zV)2}Kg4k475D792N^^8L}WzH((Kl}t`Rh>NWdSbzK8rf z$bfBsZ?JJ#G{qS?kL)z*kyTBZgymK1Q@)^K={?6&x=I%88Zo$J#K6?SWWjByT`&^0 z3#5;KzA7T?`4Jt1N0$s9J8;0@(HSX2?ilFBOb5(#5ReJn@cmp=&t+#kb`+wbBqP!- zgvKSt@o`yEyQ5x@LN?hDrIy0c!I<&Krv@U&Cd9XKa?s2r$cZAK`xa6m^B%mb+g2&1 z^hN6T%hp9K+Cn*^Z!T}*=@j>HT`D_9Hs~c$co?h|!_uvg$ zu}iv$ou4oazYwH-7;J+}SaghuZt*Hh<4E(adtR=8cj$cE+mF@mL;AZYTgxLqONGk- z+#{YBHcOXaWil9g>0umSjd>3{M$|VE842I4owuN(R7XX3{m~KgtL0DY_DzVn2U?<+$prf*>1>4kgi*vU4dhPg)Z?3cAy@u0`=?^vl9P!u*h;Y9$3$52!f{B zaQK5;6^IrM&DPL4XiT-7)Towc9 z#m}LPtS7OOZ*}qG`Qw$IXZS?{aI}nK3ZL+58f@+5l0Y8GA;8L{V1fCHhI?37FD zaa128+2}dLUz+H-z+31@`ry&XZr{wJtReYm<_8$S8w$-B$SRVFo+5wfr6SKBoFugX zCdxQ?XKNqs@Pni&#=H@1jNbydqg`%XgsG)*@tgT)3q9L-Wb}b<^TDI@z&EPB;1pNB zf98XD$P7h!ZHrvhK-OJxkq|PSf49I>a7EYycvzY-{8StrRgo9f8Z4+`6Mbt`eT){p zlwaVIMvl3*QJh7o28?bnnlxp@caCPkB8(0>&1m;|aZ0xP zykMnx`QT|etJC14lnTj-{KUG^aON;#9g^)WaLHj}ZuKk|Z8`2w_}P?NKMtlc0DI&y zO=Ka7ckyNNZgG6JyP1UX3n->G|Cs(@9$7C}HqJpHfVzaJT*M(CrBIu%3dq{pJH~37O9>Ixl17Uu$EK}Mpn#TCn!r34y5w|u;xh8& zXD+EU?zF!6)0)Om^T*IB=jzV!kCij22?U3LjGF zxZGJq7Lk96SLLp1GN1OO$Um0KJVkaOnnDcg45Cp$eQTb=1Fev!OFmRVHc|d)Bf0Xq zS)>v64b#dugo+GMw*qy8e6EZ^<5B|vl%t}d@Vx}S0 z4Q3kV88r+8w6qaJ!qn=aO0sFCct}1EoG3m%Yfu9%=(CStT1wFM3;0gl5nA)tpgK{&gWVXD!8X+1Luu90{sd5*y zN_<#Siw--S%w`oOurZPmv3eYRpfNoGhVjH#^2=RtcwL(5c|h0@&|3|YD9Ska2-k;u z`o&k2FaC&vAe>5rieMtGK z|EOrXw;9Xtla`fQ;pgF9i!>fS|v*m;)BuL;<-;KEb#o2 zf1;D}E(FsLhpBMLA^9f_q=K3xi{$OX}OJX^GMFtpg`EBX-GalW4Nt3zT{9gBNIT0-#!iQ9`Fx0K|Z)>Kk0Z zyv=8l0OnL`lJw$u9ZdeaVfvvSnbn`GQLVm||v=fQA9u%exx6k@jLDgicsMu&)FFccXBU&W2t| zL~Y+&vPmw=9rH*7wMjg0j^~>Kq4?;o*d#piPJX{la#B7p&u5b)%0Ynmoi+(fl3Rhg zTRx{ig-uc_=L71Gw@IM+z4p^)`AY@rr@|7s5#bNNm*2z{5tmiCsgLOZ`Otl1n_{IXO## zaJ|-}V+#M#cWOOYt;%G2O+HXf>PQO|y}Y4vQPbOt#m`j`@k8;8M2!QoNY(ll)&iqQAPG*rbm#|TGLB;m52!9B~0JkHxGOMu| zBq^l9CBG$X48-yWSef2=+Abd@E3gXWH@jq!**8dW&b0omTA7lfyxx#!RU+VZflEyB z7|3IlvQR}a^Fi}*GW99LqkL<2$^1%$*4DU$7SBQQNTqy*zyB)=6Nfi{tXG&N2eHp8_(pQYZ?xJf`6d_t zMy2Oj@i6UY#dY(6`fI<(_N9tzNd?JViB7JXEuUl>)Zrh|UcWR(0DH6FZI2w2M=oFn zxp2rml0RD{M~P!7UOsp}9md8K`H#QbcJSFF#q$BP(j{cLPf?gUq4v|8!2Et2$7hcK zW;lIi=TA_XD6VfHNo4MJCHT_;W>`ZZb;1v6kNc|1gWB zcmY}Ec2V@InMDFB257EZu}Ay z#dt>dLT$zVR3Oxw`*X1M;8!`F@}Cr_TZF})G1-FKy-lbHz%xYT%qRyqk1d$$VY&)QjGTuqXPnr;4t*cU$331)rq{%T@YaH;y5(z9`%o0 zklP!e6pCEpp<|xPkvuXW1VZwy#=qY#VSK_S)u-~F2DsBkz%21B8p)qgye`+TGJk+w za#G&41O^<2buwA)Sx_k4A(!&w(cd2kGjLFM%O@0=o&06boar%Pp!1*9CuLv~^kw_eeP2fDh)=0ocBbI}-dpOx*6*4`q-otNkxo{Aw zsha=m$5&}h0Y9W$=Mf74dTrMW@}KU(E@K(22WrLEGmniAH=oA;0X*_*52y4NN0zhY zOV!lrDzpY**=Ia&W@oDXlYYzjX^eP$(UlpnSx<>{Z~g~cnaUm^b7u1EDX}lXDfT$zQE}_ib z0f<+Gk6x#}^{w{a?J!9cI04%0R%{Z$7_pKI?g zb+}^b%66Ep$2CxU9g?@VkPm?Cr-IR~$&`xS=afBzzI&Q%Reke4%>XpJ<(HbtyR`Gz z)6A4gd^Snn{W!(L0iP?KwAdi+^`GH9k8kH@89BI;LZL$f>iI@h@v&l5v6F<&7G?R+ z2ZG-wIW3pAkZ!8E4xMp_BZLgOqyXvq9cgB7QcnreU^8^CJGIbjk$f%BY$Tm9EiF3FEKkyl{9@(W0qyEz+YdUs=M1X%u1sDZPL;LDmMFjf4Zq6Ol|Fvc*|A|YSb#3Dq zX(WYk{mBtJru00JZ%BO%q6`4z5H?${$a5RWR#NQ}_FVB46!7no=>+>)-#XdyeLNCi zkzA2CFCtj6!6Na@DCEyEi{yI$x!)r3qj+;3IVo?ghuK=>A{LV2*;B+{l6MQ+Xs>-x zf5dny5P6H|0z8SHGYFkksQ9h%1cR_$?;DP%Vwdb+L=LQ^pbGg*Y+ui}_WJ(0>bEj4 z$|Y0C8ZyO&wbo|24tu`nV()n|-#ITzH&jr$$+$9TOr^rWDZwfe9E%fPa!nn1l;81L z06gF6EXuKT3Mj7p-c4lhM71e0-P2sjU&KC==b1|WI9oAXe=g3)AAom584|!B$K~#7 zvVhEiEyB(VFi%b2b9-JdCWHtL|DjXK&mD9tuFuTG83Ec)=;PB>>?LG#`B7c|C(1(n*B%&6^PVYwPWL$q{}#GQ~~1Q94{g>#5R@8r;>+o z1GP3E`Ia~?Xs;;n6O5@i+nqyCcVFMi+1tu~^H#UtQmaunZ>1jL$LnqmE?fn#!Png} zpjFu|wfgBTwJN<~tD2tA`GbsJk1F))naA)Fc#_eJ7g`DZ0$MqHTSfF~)d$w?H*1Bt zPe(|(&55?NFJm7v7x#?Q;9V>(j0{ zpj}=-J2s9Co-&Sip~`>{zk%P;uH+Wm-5Jns=y$*?4ru4}wS#0Vm7Aq9#CRrg8BTLl zRD>3>{@6YV3qp8jkQjmR`UnKyve0W9e@k-`pu8{~Kgp;ch0wQv@Lw9?iR!|L1fVg( z!p^<&r$e?OCT@d8S8%!Q<#)r5q@H=HZm{Z(NyjqZF-jTo`~PvfrLHdW+e71(Nf0PTxE+XvD*&ebX{GHTy&jlqteSGg)&Fe#{rY%q=fz&Lg+a{!;{P%CF5podXTEoL&uAosxL61f0)zm8K?o26b2Gs* zCKwYI3t3Wh17nOa#u#%Mjjl7A8C^_>gRxBr!HSm5tU$?>wX^ZvSo8v$Q zm&JQhSGDq2E#FaFYdz3=C>u*h_5fhXp2f!gX0n-yY;qxtMef03q zN5A|1=btKnE&aKH`aAo7e&GAAuX?Y1tL4nlB~$*QfAwq5L)-PlZM(kt)VgoBv?V#L z4;|jQ>-5OM`(Jt`So>j1!)y9mf4#sUM~}C@Yr#gann(VF#)zDxgcx_?pV{0nr(2J? zx}JP4Sx+9w2a@a%Gk(k>U&=>5$U2;TSL7cMk1!W_#j=gfl#yzGidlK1zSz^cKPIJZ z+T^UU(_gdqerTqxq|ms3$j#rx?4JAmsY!e4&ySn>$kY{$G4s1k9&+DRnc7qJI7B`8 zceb)WKu(|7zV06Ud-@cqM@q^$1VKI)Wp$p^;)2vdcEadf0XA=9QBmx0eY7fW3l*65 zn*Bbhz#qrVJ@U}@!kCg*_4hiKzNzF)(sRen8VDsUES?_Bn%~4eDLww&U+*s!=-2HOa1z=Mo35#t%5#$&O~GU*xn0^=X_zrgzI?=GuS6-pw!~u zADF~H;v13?Ge7>x1^G)e+RlD+Ytn}Am^FF5Q%#b4{CTiGSZXqOaOawsl(m z-?1h=ZG6#Ay2kD8kJ^wfLydn~Rv&X~#v1TR|ZEU)nYOmgm9!#?`%&HePx*s6_P;MS&G zSd^V|YEkwgmK)02twffUv8wELWny81R3{dB7*M@E#+h0d8lR7S8YX+ zI`x>hc1h{Lk-MK-{T8dpKC*tU=Tj?-))Pq_oYONoAt6yM68-SD5b{rb)aF{I4Boj| ztnG%9!MV|b^|jNpW&PU7teCI7sxOHYoH22hxpwV!>xcS_iWXuy#^&@LHYy2XXR)+; za8Cchqd3ytC?b^S|FWEkKO&h0{ z(@mf{nIk5&UAaGd&~sn-*YS_en40#bNzbKj$QwKR!D%LKGA2E&s`!`D4_+QJV#qVA zYlox{fp@CDu?b37=s`9Q)YArL4KxPk^zX0Py5DEx=;20V&HA#!gB5Oz)>7NMRLfjh z_sU)C^4HZhvwt$UAm+i2b@)kxE9r$-JJn=}^ktg|=xGD8*o!M?2!>Dq>EBmSBa%i%L)7Sm+fD^x_a{Zk*$5^j%r&QF_piYzU`5u*&AlBmo`eC)5tT9 zwS44hxHXg`uG@$FyEFd9dNfa#WZzy@NtR2Ot$1&2>#TJij4n} zHJq=;K7@o1U{>mhoChqHl%x-kwU``DU!&>rUtX7VU(?;)eMk3}?lHHz>zj!g-MbHd zDN&!CsNbKcCl2pV$?q;=uN~G;E?RpEWQ!{LBbpdhKUw0*CS4sAv!jUqVb$!#)wTAo zR1a<$Ryrn&WtG#$-p^Xk2Sry9&e(@0H@xsqDRth=Ctse`rm?sZ6VhSD=g(-zG+Rql zSJ`F5(#x6{n~)QrDOs`suAwChfiAG8>!K931oafVRjAFBZkvjZHM(NlpL+8*6Q--0 zOwiYuHLiZ>*R{mm(a->)4pa@4Y~PJ%!3mqDph>Ji7M*l5&8Iy zK0HbX)=#VE4`HX>7om)X+>C#h9X?fw(rfm=-SnuHs`=ui#dF4IOr@2dPJgUy#+S0i zK7VAJqYsZ8tf-rnlWMV^umspLH0yTGT0(Au(US04f2a}TkM zw>(6LU>P}ZU}hSe#SBZ+ew95DNyO_*k&Ou={?Y?eCMwTrN{rbP-fnkCmRt4@+3`ws zgYo=hrHdE!Y74KN`m@~KFSdmr%w8y6n7Q(JWR~scP1P?f@7I6E#L3gFmHA0eu4!|2 z5y?)iNzq0|T9cVGYSiCsO=_P$>B)C%jjX@!(wYt(ZpT)L;~|TaJGbU$=#Ex=ab?-u z14F*hu`z8+J2ylB*TSl#=bvJu4tVpP<#l)y=?#Z#6LJO*9zHxG2=DPfm<&y%ThkI_ zNAfj+Qnra~jV#V$HqM%G1BtuGBJXx{rN3Z|MD0f0QQ3->Q;!Y*%DmOK7hXHmrH;qp zK<4_aJL))0>Xu|(c3)6jusCJ!><92a@5?QjGjqfQ)9Y&qd&;L~XHV6qWKB1^#Sa;c zC%)vL#0mXhC1?8L4o7PIl}zwfJ2j5F%3W&wZbv`$dS1y;8BE07 zuJWV@ES;)+c5h?fJ@w)@3zg5PIuBxR8K~TQ2z5@^)6@TvI!8wp9qZh_F-By3GtwMi zbg6OMx2G`B`1)EI>5O>b@~C+~m61k!jYlxvnDTt1A)_5z=J%fnbfs`oq_)ZT<)pUY z{`UOGYI_HT#fiGhsEj>qJ4wWY(LqStw2rlIukOTeZtc6_JHP2vXLiy!dh3s|`(h3; zMjVsVe}E;K4|1*j`mrliKTE=WOd0giBYPs5L)-ppW3!>dE&6cXGSuMzcQQ%vfXMFT z#6Cm&FtKXe_Rg8M5$_uL$J=gfeckcqy7?0)OgG!pn~`wy zOxwg?E$P3b@0U;NmyNWWXN>VTS@m&i_pPh871n&HH!UZ1z_1~fl+>YpQ+mbp?qlg~ z>A?_uQE|WCaXpq4$8{WYt9>rpw-jUJD)z_eP&>9imHp(XAiLj5JrZS`4mLoF&Js*x>pR&DQcsGdV${k8W!W|$yPqDNG8k_CicPP2_vSHu^xJJW zzT5T|8wj%MLv{}wXzm-BF-m{$=G>cx@$-#0DgUjTA4m5Ny!Gq0BwIfF4W;lVbz;t- zn7+M|2FAwsj<@!=YCU=kV{g8G-TG<+Z*R4wD#ja(i9$%~#au;SRWrU%htce>Y)%sO zZ{Hb=&4?^Xo8HjpoM{`b_dfKChi`r7?c(^}-IpEEb6-!6d-8`v7QMCp`Q=OZEVY)M z_KOzK`&O&^g4X&e9nD|j}7WIsF&WIIWE1=3&lEnIf<+?U&MH7jBFsO zXdR*RQ1;k_%FMZ>52b4mm&`I$XDcO{F`5{&{bq{iqqYY=GK{xb0vBgFH2mh7B}V*^ zo7dJF6WV$m_|c(Pn_e{*vjo2R*-t+HkDYB(ciaqHE4IE`>Bdgo`tVlBHkh5dCTb6A zU(^=oOnhkcqT;k+1{@!z4V$s3cv$b`X|`#$Ma9#mSyNLdEhbBUPvh$_VLG~t#Ojrz!Wq`;GlXd9u*od>l zrYz`0-=v8X`;1_u77;J&{I{PPxMxw*lz*BrdisJTk7N()H+a&VadX!{x#ZGGeN+F6 zuQ$KhcA)K7!>!e>`CrRh^7WhFUhOz@aK66h*+ZjyUHJ23Nw3uCEkoxNRF-8XykeWP zPPcA5h-}qbV^{;4hm$=5+5B z8*fR_dsw<9M0a0PyDPKH9QzuHPKd#IL(+qLdTmkzAe@2gt+;x~eAe{e1}ezTuXIfmc-hz-&HtPg1Z z(%0T>`@KRy|E(-V`}#q>%GcDKdH9K`BApv}rj zAD=dCY}(kt850LDDmMB7BV}Um5gAL0NAyeS+pYJK;)HI4AYpq;n4OL2nX|G5Vht=Pk@% z`|>klrl%J^KJT$7pMU-74Gv>vpU>Vq)#lqbFnLePa6LWr)i;ycCRz^0&D?tVFK?A# ztY>X~|J;G4D*OY49fP@U7qGBqu)BBTerWW26~rgNLPB1`O`Z zsmOkS4hg(klu9W(K3V&LkBG?{%EK^bXd}3y@u-d#SHD<`!Qpv zF*J4fkX|XNT{vUbTv-}Dg?sEEc#zS9n{M$F%?zhhSWntmOuXz?Mzj=e2 zfZX}_OS;aZgaJrnfTAyo6ZmZ&Cm}A{wDXZ z)$@Ae>$|o#eEsHu^|#({+uqjLy_>OhPUD#tcX+BW*r`CC);zXq?t@ z6-hT3L#~O&EqoJF8;x6eleaS(k6}LjSTt@!`p-w>vDz;FyHzBgI4whOj>fxbqjbi6 zs@!-jN0jmCRw`IZIRBg{0d;lEt2)1KqMJFU>{ z)Fzw%`Z9rYn)WEazDW8i{v&3Z_L#O>dzyKXH0@zhRuSg4Keb+6J;VQJe}=pqoR@Lu z0-m;mH2#nKQ#`$%JnY0)@!Zq=$ITZ>lRK)YL!^Wk`1M(SUCo&{oZ!wpq$am>DO4q{ z=NZW@jhc_6{*&6DGfN)Z>8abfK1Z$6C^d~d*AXrwKdHq!?RnB()RuF;7agQc%lKXH zuOeKkTCt9^v|&9t3N?flX{t?Wv|3W6_R_{QZ6&+E3hmc(kI=-jwD z&e@bBGyf93oC(dOrsEl#MWm>6 z8`p8?3ZAUszNfhF8NTC=JR>xY(4d@JN;}rU4?A~@BtA^-pW>OwRp)0i`Ms;uWh<$> zdmEqXkk>fsvJQHUkLtiPir0}A%tt~WVO+6*I)4$_kL1Zb@U3fLIg)s{KOKFJ<4s&o zEtYriGXKx_9T?UueJUf?EUspe_6Uas{y#^2C5Hv+E+_8but1$E;?*1$cJyQw4*w{$ zK(nyAWTK`UlZ*#6!tNj&&&OEl##EbXmWLb=qV7KL0hZ#ri|y2dzHhKewJHekNwDW{DXWL!TEjK4u~D zJlmsuurk+{uUTvbv0vBp*sZbK`R@{M#Inyr>~~|oM|@B04~QR#JxKgVvF{K+7E7M7 zKaceje=qhl@iTERX?om-xJ{ZR?v-vcHND$I-M*|@x)pU3YFMF=(9F<=Q2(X0beU>} z)Zd`y>ovoA(Rz(@*!o}8_PX^t@f$JN_!tZCJ!N0dM9#@E133?hN!5&)p)tcbr^lp| zG9qRK@sTm3h>wmLLp)QpbbQPN;@L3|kUlwv|4|Y%HD(&|=`quZ&x%=~8MOT|&hu>Z zpum@G3yJ61@`yiSdxChrP$urHv`gwQh(~sUn&s)Lb*r?bXV*RRyq3P|Df?=yp|n!I z(LkDjt;4lYAhyFboh|az?fGZct=6Wh^GtP~{lZi0p4aB7bFMlsf8qHTp4V#Cxj~&@ zCU>3Qr|VhjCOxALmD!4)68O(7lya|BgS**2m%BTL33y?{v<&oOIx;FsH^f7{re7P$|bR`K7(W}exs^3f`` z5*NBPN5k83qh9LYAom#;%0H{h_ADt6S8VVsFTdf8_pEXl&fcDNjyTdQqvxK^ejb-2 z$vMc=;7F<1;o0a&s|tBGJ4SN6q#q=h@?!>73-*@0d-V2UWb) z5l8%OM<#hTJLVBT?#NZS6_Ud#N11cF=d5G4GshDkw;X<5${6Hh#|r0sQdX1yMTfn@ z;koRncIJ7OJKUrE;3uJrbF z>~*f;9=FrsO>(q2*LYLP-*ztcra2B(P4$j+9O0blIOeP+enQ=OsOnR1w!`oAdZ%*F zr{0-locY*Ie(R$`ay7Dt5T$LIIUtae;f9 zD=sN%uZC93qcpFEcgri62zM%%OG_(PDNgz1e#dzgm;9S6u2AkaRqmS=)~ZZ$J`E+C z;X*&}G2)jz;fkZgmr_sSmFtL~sLYbM1D*2vD=XDK=Y&(0F4qF&Goocmo+}$1Gd&wC zH@fn@M&)J|->TxxD!x<2_f+igzOQ8dd__McOWU32&;rAG9cuVoGrW5%_g5L-Pbzo1 zO1yEE2a(24MLWD9=r5A6PxQCqn#%?scQ}W6uU70vYd)7a>AM}XBk2;aJ#;%RnuSb? zd|nrRiSB#b(6W8?Rw&S(UOCG(%iAKq*2l}Q(4kc%7Cs^a@I_?XCvkYE;;sbZ8=NP- zt1C7+PkZeZEs`=PRCrSQjWU+M>2dMeH${8wt*fkjoGcFQ$21)Tzh$?5Y)>$=Wxvsad^Cw)#Jr~tItJFQ~swdTzd6ra9uUm>;rFUqkROznj9MUVR=a7zeK*`FA zJm&#VbM^eX6`qaNd3CFiMtY5ghUy|mTEj-^5gIll2?rXsRxhrzdykN3HP!%%H8cyw z8g^DMb7eH_sa{#<#`4o6H0*aAlD1T@scWKLj=GnL*Qz#pC0)4Y-Q^IjxzR8Bi%4Hq z8HVE*E3Q{%*H3pCE|+IrWtOYKbFuP<^Ll+wmEqc0Kc_0rwV9qp^?Fr3U0c1!%EM58 zIZ}O{vyZ0^RwX%?d1qE0bX9r|R)$Hr=$K8O^Bpr?&CqSOYo~WtRSMSLUb(ZXx<0Qe ztzt)gkz=H5PyJ$YXz&E8MvA^vYG~`ss!Z4Z`ejNZRw{iNCp7UMsmgX8tY20&)z#`f zQhvknxo1^n7Sg_^QhMi$HCvJJKviL#pMENnb_J?tI#TK#((3wJT6e16Tlrb#!TJqC zjrws_vt4KFH#rJjJL|Vd4e4hOp=GppM%q^7m5t?|>Ex19$XLp8^1dp2IJIpwxC zeqM9d9pBjI__XebXGu+^^eHv2s=c0#H4Sws*oskg$I$d;&THPJnvHcQJPkFQx#tG- zPxsEO3AlSVS!+Ia_iKu;x#*nK)Z1Zq5AuX-E+Z`qDkiD;XV8CZ_0ifkBygs4P*XpV z!1{4DVTo5RaLpxt!#%9=NUh->)ikKKr+ZS< zpnHDPB4UE$u>G{1JW`#@7(%|?}OcONFb+I5-#{Ju{VEZekOMPnJ zL^h7s?s9HIr%qSyX%7*q2HSYL$x*x4eXgmtw#9v+$y@%JJJ__r(dNF?w5j$` z#fGLWQQvQ#`%2Sx#}RCDE#)RQXthUN4Gp&1WA1C5Pf){k5r41NUzOdoqcZHi-n6^+ zeUH}gnRt>-`)bcu?!iWV;;}UyfbUz-NAVcfVdt^Kj!d!7#OGqos2h}DLBH9I7q*rThi(Xf`U17Ao$p!bT zUakt&7gfH^`LNRZxT@FcjQXQh+v?)#eUYQG%;{W-@9>Kss13aDOh zR~24Q{e|fHSl!6_VAT;vX8ncAt#z68mz4EzNV~9U?z(K+m5cSRgkp(UyjiZ+`YVnm zR|8h-glh@@Fm|K4O*4oF|)x|^}Yj17Aw?{0QCaUP+2xrt7f<}S$I)5 zl~T?-FEu0z^%|0^R-?tVMYI5~qjy89$}L@Ts~=SLN!{#*40X;@=gC!{x-K@%s0z7U z+Fk*?pQqiV1PkPfy zB|nCon@&qUjVCDaK>hTpT-RsNmU0_sOSz3rQf|{ZC1c~n6KlF49#>P)K~0)2sb^=) z8EvH|OFE^Pc3y` zdCA888vQlnqn8q@T3qQbB}#5DB@0a&o1p*XmuwaB6&o7fcC4;@&2zDO1M!^_r!SWH z@#;+~z6I`_qAfBCqsMGGD=li+dPh8<(mz(|7gZdM#%K6U)e~>#cD#DK^v=~gWHeX3 zTRi9Leab^t0~xV4_7s{oCUuH4hHXp|E;Oc8`y^g{(qS~Fh)aQUa7Ye}Q>TN?L@%r~}(4-<_alCgiox@sSu&yJcUbuHeh zHOuP`d1u$G5=&UKj?wgIRV|(@{33VNr_yU<0h)!6_@ycyovDDfO^0jWhyKV7T6Po- z+TzWu4S5ng>zMKCsb)d74zr+EH47TYEa-Kuo0|DdQ!}3<)Xe87WKY-zQ$>cy6~Ebr+heDoa9pSQ3p-` z;tQAGTYt~2^PjALVh+;K64{QO883a0&VOOh_v(B3|Iy#qnOA48lOHn6d00QJ+4P_4 zKhGt-N-R$;PcP3X&my*f^vU)MRR_tpDqxr#aq ztq)lr*7B^6SRc^}tdCkB)e5citY6Z;Z2c$eKWW9*C#+9sCDt!nzpRy7i><|4nRS`< z8EuiZl1(0-wAQe3-&53M7v+iMDEh9yuFbV4+f(i7_6&O#$7K5q`z-rh`+{{>?fLeS z_1Eo71oq|jRlJT{XRoxo><#vf_5}N8`&N6ieW!hoitmre91^$LZUYG-dG@n}0sF`H zi<~d7zb=Qo)Z-305;-(`B55{(#0830e}z`vJJD*3_H}6W4UWm$8(OnA1&aNMFS35j z@u2n-?T9u*&(Qgg!In9e$Fv;LS@d6L*#Yy{v^Rsd0D9dyO{+Ns_@7C27YL6j=ygHM zgqpo|Cu>^jPS+f&J6Ch0?n2G6x?s(Tx=S_wx+^vB*IlbQUw6Ic6St=B`_yf#3Aqz$ zuDTOzK6fYAw7F9ythKt+YvbJ+wY}Y0wf)?apWWb|Q9H;zt9F=sZtW=dg4%KJ{Mt$G zlG^F+CAB&3*0aIw2V{kF`#vHhNv?#;Dp+*_B-b2qCr zhkIvjt$Rl5 zxppSHFSe%%Z-u^HLT9r3vNP5FnKK=k7I_odCN!^|8OS*@XogDeJ6@v$BA?EzNGLj? z=;HhD_N}HmD0PT}L9ky(2t!o9C_*k#^rJH0dHXtt0PT{s^7!6`FKZwoi1k0}mB1 zO_>mxT;O3>dF+S8^F47QZ(@s0eHFcQmUwzPmw1xYJ2!IrmCY9YkJ?gagJ-I9qi3cm`$8}0X3uQrR?j?VvnN-z&9vbn%lkb`pSt8( zq2&0WXSI@F>g;Uw*qxN`eA`p)JnnHTyDsu5*VLu1pVv`0$Xn|?O)eZA{>qdDu z)Q$6Qs+;89Qa9bZy)MTcsGH;6Q8(YayDrbW&$L(VcEQxgsGc|jp4V!{c4I@8ZIOP) zv^gT5pSoRL`CnJ$sdmlt_N!ZbyL|JRx@F!2bt}DxO&if(zG*)@$fB}$UF_8z_9AL0 zO#9GPzZH+fPDSmZ%k9k*de^P-9$k6K>oaL+)}viFOgcnmr_SL$DY8&k>pflP^_~-m zo+??vzAM`YkHj_!>Na>U)NS$xrEeGcRrf}1xb){@KSfU4c`vq3`fB7=Y>DbSq(2dx zMgGpSo|jczHQ-n&%U-)vl4APhFXwkSp7BRcx|rs^@cM zqowWw@h5<5rl(CHba=YVYZXYnBotXz@+^6ir=pMOsMuP<=gxcM#m2g3dwYuvDdc(w zxl9y#hl#wo%Dkhby(=zz$GMhzC#iO$Z>|;I>C(pb`&WB&Tz2mqSG9M(@LqJ$)#NR5 zz3g4=dd<7+xsl$LO3vu}UE92C1nsnv_LzQ<)Yohy?NV(Je~0uH$Gz8t)^$6)sxKAV zN_ySydQJ6l@~m9%tGB6kM(x5Kd5hc}s83KfN_;BGUu3|P1N;J$->TlypCB8GzU2Sx zzWPMh`^Xz{Mb{3YY0qlA_#39*(KQtR!xgpp5}JBphNgewI$w9m^$Bz`Z9-SSqsz7F zkC=Uj*d6gHRNp1GBx*O?!>EsOFW;lRFU2ob^o;r%?Y1`RgP7N1KU~p1=x(7a6zL1h zu-&e7@k6Aa5P7(lA7ZArhgt3{*H!#xv+wB|ntfc?Q0y>%oU&_#uFvu9(G%t4i{6Nz zFS-*AU2XXM$c`DBeV^&GwA(uw6GY`#>Q!fT@2QI?KV+@0H~tKLi1df1PbZ=3C#Buo zBl2Ij#e1o4J6{JGe9`t`%){z?rU9MCPyhW{khRQ$$ZW?VW;NH zl2%R`<>X!73MBqE=~B2D%r={0`C0OfwprTU6^c$mt0<(+iY^k;W<}$!A#GMPzgH;jmHf<5_)q_N5{3#Sw`7sXXoymS5yIGhO&6Wp@e7 zFLy{2`Gv+xjyr_qpHY68bmXsGWV&k@l|hkrk;OYgQ$D+fA~RB_e>8-rBHN-riqC|i zM@q)KgljjDeuLl5XS#-F9zuU0I;`|7Dl2PqNE6weQ)zP)a!*$o`agZ0Oj&tV-kCg9p(z{4gTsIp*bk8nM;u`@KvxAy zZ_!IfPmmP7CxsCDIMTpKp3UPrpKuM=nIM~Mp^xxvF(LeROa(KEoB9B~9J9eZkV`sc zn>Jiz+EE6U^88A|6_HSEyJIz={I#bE?K~5eLv>AED!9Kw>QT)-v}x^jt{tEjc)^Zhit34@i8O4t*idC_c1A;~v)M-4(@~eDJ{9qu%Qx**#SVVk z&9fQ6%wt$IFA2NKo>?z5>{8Yp_90qtQ)Yxm$}W{e%Bz?Y4fj!x1H_{=Y^Q@+zFAIG zcPkEaFS1Z^6!;>LXWHeYk~lmP{s}5h0_dRncBzxxYv#RXWU9>E*CCVNM zJ)n`up~D@$muum@@Wt^mcnxd=Z-QNsd{v%u-(H^GPuOz%S@j!bi<~+Rfg|7;I05|J z-+UYG`Mghkrt|xG@Co>odv+3rBB8_u;!g-1S0hle{5f%;^ng%g+VmeJPoa<0QTY*4 z*EZsBLpv*okD@oBiGJjj#q}WWrM(ryz^F+6qHh)BB5iHIe-dewQ;`Fpx9DO8Wme>Y zBEU0ic}DvFie(X)?UuHfevqV@ZIpIN8&qFFdPR_Yp>@TjXgi^;++T5p`zYJYui_fd z93+i0g&tk=mV7I&lMWrqTfy7hOZx2F?a>q5Yqj++U(CiD$@DBST`mvLI&5*e8?G8VrYkE{>#6~Fj?;1{y*7xs(($9!| zm|<6+LwtUb9W!k21Ccu=uU$itE0JYMmwb^m@n@tDQT<^Dx+|K{ZgmgORGb4BDp}>g zDj-=cBkM~3uN{Z+-|QCOeivADSsPY#x#+XJiwj2;g%^7BE*5CHpD*+l-6%E|jw_BU z?wR*-aZ+(g-l^i0;8zMGvC)*Sl4?*`zaf`-QXC?dM<~pwnO_CTP74O&QB{^Rf;y8yNga19R-W2qu_e6RfK{Nj>@CyMsv?kvg?6yy|Li-e`ub2l$+6FiY6_3ez} zCB@5&w(#V3+6#}MK@>#?3To9a@@w>tk|RY2;P7Fgiqt@IYp0S)t-li%pDI3UQmktz zzbUE&ia##CSbVudOU)KvxLdlU6@S*bWoAnyy*Mnbi=a5UI5juDcvXH{Zu-JwNaRMv z+m*%Z9zTbK?#xYI_$j|vK7P8`mA89gsHj$WQ?zg4$l`{gO~o5Y-(0-4xVh+P@y^^C zxjXZ>74IqDUwm+3TXE~-r*kuk-!3{SG%P-zn_hZ2cjv;kqNAlpOMRs$OHY>`DB4|m zuJl4_P*Dy3n^Y{lRCKN=XiANgSbF7&J%WY13RXs*mtRY-A(qn8<>_ zq=MukGFYaS9*}3sY(;A%kFtcaM0rN2Q#!vaInP>_T9%5=A@At!=Cbs%jIylU<@ssI zUHIi+*J{L;MAB69kqbaBbC(q*D~$Z$$-a_P#V1Nm>3t|{`VUmT^i zrQXsFrJG8(lx`PYE8S7LyL4aa0i+-kdxQ;wvSJmmK+tDFS$@&(vXY{GdDfz%ly{+Q zN!jwURiv#et1NSsEiXD+)=;*w{cB*W@NExzu zqr@nQD>_|tL2O1zPmok%Jh1?YohwoswIO?+*i({HlJdmmClv#OXfY1Uy`e|R5UeeIZ6sk;;>G8O!+WF$~h{C$V*At!V@KB z)NQHQj^eW=D@=P*vYI$Hq{LoQUE(fjDtWo&wUTWmZVK!pS^o zuo!gvbiGmB!IO{_TS!Y?ux=RJ~9@eoI3h*@wS?5~FI#=qc70!s{ zS2&CKTp;&Lx?llV6~#J2*3znHS$|si--U~31Pz)tV_pPOo{AqM1ce*5oPzBfTZD#% zGYV%w>m3EV3-%QpC^%ejv|v+#ui&KO!8yf)!=xTIIZ<#xcmXHi1)P~xIJaP5;evu| z@CDAOb82Bm!Qp63Qu7P*;bMmaDi~Vt==YXty}bI;GFGiOk5enn2dEY0DQZReV6~P! zO|2py%9oZCv~;y{{C>4&e3bg$aaRN4|b+Wrr+2g#+ykEz>tSFN7zZYS>Cw16E7y{4LhjE2bHIEcznjm>J(8XWih%rPmMig&kaY9e zcx_C6Oa38_BOJ%_PjLA2-_Jj8zIIC`t=-ucI%dQbHYt)})3(A9UdG3vY7c=g?E54B@Jvf3qJklG($u-X|QP3;LV zOzj3RQmy?TrB?lqR_pyU{y)oC*VUUJEYJ*X6YJ~u@lD?<#v*gI4IJyVliF$RGRH~n z8pmbrx}L;Y*X_4L*pp%S|MH)|viZ+r%WehrHMhe0+FJpB4eJ|jh50gd88PnViu?8T zw}RZc_g1U%A~**E;QXyte)DigEIH<4%Tlppsf;pG8E2$we*k}^e)8*_d;B_w9KOST z9yTq8GU9IqjabnAR?yO&|5ek2ybTtpr5e@LO6MF>clx>0&z*km^mAu`I|F=GOHTSx zd4~3l=Fqe=9J=-y2Oli+IjlurqA%f_+hzJPTJ)m+B46IF*VpsqZM|O4m$zH=Eqr-< zL_ea%8{3U$t-G9Gxlk{jDyBOEWjayJtd99#$hedc*l50>tnoYysIU#WwVUf z^z0k*PEP-~5raky8hT^cxuKVbo$IkB(J^{)qNC>}%ZbsaN1sb{^hrx}Bn30H0c8Wq zMxP$AIwL&v#`sC&PsfDDpB_7T{G@TSxZ;{4m=zecZPd1Lvqo(jdZWjd+egn!qZjwQ z6gd(d9S<2K$}wPdpEQ+^m^GJcYY(TgKTqQf>r>OB5*SB#%D z`t-P2<7SOMCx>l@oX1a!)PQ?~awJjj2+Z238kLROHej_NBP@rM+4EAOqsQKU2m5av z;Tk)?$KGDmJ@#4;_B)uEC8^fedR6z|Xq}#zWnD4C)qmrl>$XEzgSN&5$6S(Q;MGCR15R6yN@_~;z^jrn=K8?T z2W{o9<{0b1t0~PX&FbFkW3H3?fy|uD<(U`alLj4#Pm=V^oU!p^F2yI2x_r>JLDy8; zg|UM&bL495p!lS*@hOFwIRm79CTQo-%W{Y;3_GXbvYqe0QCdBI!Gyfb3uCTND4VdI zJhl!vJz|d_J1LtIZL~nuq}67W2?t({Pck9*-oG+4CvIb$uiHxQpxx}2{aW^U1@4wR1o27n<1#N~UXUl_UyeU# zrb{^B^q5Nm`Q5CG+$SY=Z!lBLa8UEucoR~Z)G<=8>}8`~8}*vxC}H>Q-A^aHmf(|X zQv(0du&Z2ly-swDKOKRo9pe|6M}{^b&paX$8Ieqp*?tGLL0Yd{KJ7k`jz#eT{@0M! z02)CPcnKT>K5!gc`3V0jDejifNB{*`uM{u{q=Gas43L*)Bp3xUKqeRmvdE)5CHg7R zuNRWrlVB-$4y?mQS7I0Auy_ezq1Z~Ze%u}4?f`cO^yS#?=Llc86*lX_t|+~3xyaYW zoqq20bEluX{M_LpKNq%9p5qzjh+?QoJZ0`BG=p?KI&BWgXKwic#!71)NM;HL-K@eO7SHU&z z4};I?bqsi61yI0}0D6L6x5Abr!elT28X4_QM2MP3;Ibex4hrCCT_bB?PzmXp$#~`cm zw|v|crqrk2%2H-RF z4nl9Cbr4#ISceq#3y`EBQWR9u@(!)^5x+nQ|BfsRC!>A?GU`J*f=EXYsR$b1<2R9v z9}*q}hd?XWKOsEAy+1_{juO5_c!uyS;dR2l;#r6kh=(DP(1S3ETJ@z?qp4L3v~HnR zE!3)oTJ1(#c2lbsY89YXA!-$%RxQxCg<9>VR;|>km0Gn>s{pmyO|1gds)bs$P^%Vd z6`)qTsg-EiZfYf(7BqfFNQ;f16P_XcEa7#+zf!aKTXy9GB@p5VQOg!;8DQ0rXrE}F zXqb;DOs%=CEn!Lyi>93r@S$8@RNg|9DKB|m0bK$s)svKeI>b6(KewxvZtu; zCd8Yhz5XZ{d{Hj=Db-J@{wNn(X>XYJw$k1(?Q5ldVo6$QUznP;Dvd*i#3Q7Ae#M21 zcGCj1F$N8mz) z1A%*RAfPz#AKd?+;J?6io{4ZnWF{Du8IhNu@>#>ki_|8JJcLzy#Jla^ZYjmyidB@h z2-k00y>L6<#M(){50Z=UO{|<)xQ_N0%Vt_J=K4)*ewy6>O_d+9=E5)GlgXoR5&xgy z1o$2Gvw)Zm^&CS^0a_pyJ)(zV$s_fRSZ?}?cAbpqV}O=MtTuM5o%Yg(d+BAwYMZ(l z>1U*Ukv^ug^`@UO+u1>OBl;O55}-IJloVZoGrSk+jr4Z3p%JSXvC9#wXxe5!w%Lzu z_OmBn3^ooK)J8&q3^11UklBQjz!YrfR|vO&uY;}N8(L635>_URt4It5F6eE0O;>==WSO56lM(KrYAw`2b(QQUpo>&sbd4 zFTrd9y?lsXKEznB6`#V#xGtoZQ&J`N&MavmPsrGC2BSmqfT$f7-lt827Sq8D@Xye3 zGMEZT!>?$;uV}%qXrYWCzC{b=1j*m8I|#81dNt+LaP1;4J(GuYFKG>=y#&4jBE40s zzKQrN+_xFL4z_UrHwmwkegm|@8x0sx#R9Cr^t^_mzq!c9Dy+n6u!j1^w6~m*EPbK$ zfnmm|Q7=V#cq2*40NG#?m;xR|YPvkO>%Kx`oL~E2sivR4V6@L6@ zKmM~H|JiRD1}Mui5{v>FAQOxOS>*q(o#a*KIMUJDsr1xeAe_w|bKu9LU@n+PS}t-e z@}9@_6NLGM1%zmkRz&FKo_f##8bK3y3A{m`&4AutdlT&Bx$ltwF7RDIkEeYP>;eD6 zZ`exhe}H}9UjcoNhUcr%=V(6$*gcItSo;ZO($i``1^6UTu2uUPdH4u_PI#Q~7liL} zFJ7(oEASq`K5D-Pcw8F)^+5X#_$~Md{2R~wJNO;=J;1loZ2*1IdjPyG{XWnK;M?f^ zNgDtLqnkrP2D&_k>rBG2gyRUu6J`-kAj~G5NH~e`0m28-Q|PTf1RepxsKIR zR_$(jn~x1Dz|t{BF%}`qi}8k@B(0K}l@u)BK)5`Ja4=yi;SjSRK{%4| ze!@|NqX{zz#}H-`jwKvNIG!+za01~(Y{dg$3YZ4I03HGl17yYW82A!+94rJ+fCBJk zPz*`|^|er63-z@uA$*DuTWEQja2eqXZ358TqXt zT#L~s)29mGxtu+u^8bdVB!*l8bj+NUfc z^-%qRSVaf9R>7xg;x)iUJYu7R*ytcOI*5%9GMey5?Xw^I?8iR)vCV#La{${Mz%~c4 z%`!%ajD&|`FIHibR)aOvX$>`1qg*u$nNCfoBBfuT4YR>K;#eNEGK@xs(Z(>E7)BEV zXkq|O44{btG%` z0Foa@@&ibI7>Nxbv0)@Ogv5rC*bovMMq)!qY#50RA+cd3HiX26k=PIt8)o^rIWrQm zu|7EHhl3$F7=(jwS2H>I(E(YPE4=x7bq7NwS2C#7W&m#b;bs7C`r&2(Zu;S70B(lh zW(aP|td9?F2H|E9`xa96&6IsSGC1mkqd_?8hob>F>Vu;}IO>C=K{)Dzqd_?8gQGq; z8ib=hI2webJ~$eLqdqtqgrhz<8ib=hI2webJ~$eLqdqtqgrj~q8i1pII2wSXemEL{ zqkcFVfTMmm8i1pII2wSXemEN7+ac4(#iD5?0IQ~zfkglxTE{x-Gr&xc18$ECTV=+b z(U*+K&9R}3eM9VSd2Y;5Fu3)lv}1$F_MS)hH!_ldU< z{($fRvr{tD@FU_s2LBVtOv6w4{VgEW{TcNU3jdt&1i$~1_$lfq^C2DH_!uAY+sEAV z3BXDkA%3U*#udUp6MjbczX|_?{QndD7x*i3rok->U_{DnPpc)CkeMM%H$s_Xk@=OL z0NY|oB*Y()Sqw{m!ep-TNi?fbO-ufuU1%RaC+pwAibf<*_!3gIts*q(A~ZPyBGMG< zB2AIeA!A7;O;Sf2hy&e052R=))-E!8x(n{^MOyX~%EygYetnJAnS(_!q+e0sa-36nKaDF{nY0fFy^ICqXyfU?%DT>k`#WyV6y#L0X?3I7L|{)#cQk1@25F|<#M%#QdNC;J#D`xqzt z7$^G}C;J#D`xqPh7#sT-8~Yd=`xqPh7#sT-8~e12Xjf0r8zh1xK)=Y?SY}7Wf0ef! z0qSnfW%%)qeR#({9Xm=t?ANiEw5yeNwbCx>sRHy=EwryyXAGsd^zYmccMQgXjGui- zrJpvp8dZ!xoLtv|Eu?J&^dHco6|v(7t90m!2-ZomGQWb@wkuixX;4) zl<~Na@wm_8f?gNYXm=!B&H&k95}3lmva^GM--$&o6-I7sT@m;Q0md`~rA>K|H?zo?j5pFM#JKqp1+1 zsSu;75ME#qFEEG~7{m*dk#58be3WtuxqcEX1=~(ip#Bms_#Lt=QHewpC`sLX5aVjJQIKxIzYF4TF)a zk&hjSjHH7`3D>2djDB-5TKgow;mb#DZmW#0@jSwK8(}<+FkVI&4GeC>Na?>?>BY_dt2H`;7q3@F@Z$B#2wuEia|AD5uZ-Zu z>y;6_c)c=$7q3@F@Z$B#2wuEi8NrL!DMuUUHC8Y=}{8h*50F;zF;i z*dBQ|t48G5k1*fhn0_?6rFd!bF47-}hZ0nM!5_6$`h(l^yC&~UehH7Hj}YFt2&Iqc z$|LDBgim6POkQ>DJH#5HUs$2Y`y=T$&Js8Kx(>Xsc_OLif#yNT~bQuh=85jafxPe8<{=DicYqrG?*Nl382-M>D| z^{>JEK)k1OgdYO&xqm}=9*FNvZB;Ld#zQ?n9!C-$M-m=K5*|kq9!HY$!9#=*KU}oK zkLQtu=aGcxk%Z@wgiqe_eQRXIEk5}QeuK-(Z(L3MMWk9hw{^tr{O%yE;dlBJI1r5b z>qf34KDlrrsQmHQxnKM7&0xysLL3emd3>4Gk#I5(|lklcaoh=!%Eq!_)NPY5JmmdjPEsD8C(_ z1y3gl4Gu>A_h8h24=Vp1pB)b<2@fc#i|_7_`tJUy@2>o0Jfnc}TJPijL?lT3cPwty ze-9`xHklsSd}|v(4WP)kNILYeP@9|F7!S}t$j0<^mG`_HqaF$O?R1FB|GPhEK; z@yJNnu;aNg)5FtYXc0!@!?Zih6Sv>I$vjl#`;N!xs}`ZfGr&xc14O!IWFZoMH|dsk zbd>6QNwX=*5$O%wReJx3gp2fEp{%<}uIV$=2Vvg>*z^E4J@5}pu1IY?5NUl0h@{?4 zN;^tuSLtlw8IvC(i9e(KpM$$gUjYBQv-Ew8G<^a(N*(qcizVpjF5EF+vOC^U3?~fEw4!JK~5}F8-}}=!i^bpT_=QPOjiV#Ju)H%C3dxLxSX>$L1(lb6hEPTv z=LiGfJO~0AJ9qf<1iw%yA)~>d^5Ct6GFFZUBH@v55KNyt$mlS{dN1>P5%WzJGji&C z5$Gr1j2H>XwvI0xVwG6*n+3e|5MDZ?G(f+DmmcJ8RtPUWgqI$|OAq0thw#!vcNosInEHCxV-z0 zd<#)V%PVQo955Hm1M|TGkPGraJ}3l5fIbl~mp+$z%2!#^2Ziu;k9TD0MCW_ z#4z)TGP^4?yE3aQv#m12s=i>sE0P&inN5|MRGCE$Gv_8Vs4{yhGp90ZDl?`sTPic9 ze056wd3R5_YUD&-k*|@Qpnrn`+zNPGke1Q?x_dtWaU_WR9KOl|S z7^GCbeNu1yky3es9@c*W{NMv{Rn@-h_fL^8vCJAY)4Dggk8+SwkiHhye`?&g`L#FMUwLrzmlR{#jc6&aGxz>|-1j(mw(+qaYGR>C7Gmm_3v) zXd>SctfV$ox0=z<03MNi$074%Ax6&fJ%La490$;4={*h-M!qodsh;Er&qZ{zS?T5( zu0bhlP9>AzVdg3(oa%fWq-O8 z=gkN04y!K|Bl8D-O8o#_2hITIwzLlbb6Og6TH0^HN6b<60?h5`eL!D8x%wIYZ|fhx z{{q*rsf+L~zE1eh;Je`W;4j)J%S7gc9spCoH1GxR5O^5S2FqjMOW<*^5Ig}2z?VTW zCSALiKehGdB-UDd=z1|n=aIe$* z;K6WeD4-5H-v_`k^#zl>qy0bi?)3KeQ92qeUxApVXld;|+*IoP1==oh@&>@_Y2N~G zf-Z8ys6M3L%#9<=0@+{^c#w9G2P1ac0oSC5TueIzOTbdF3@isLz)JF#?;!aumM3@z zNPil}!vEhPmDxyTHd2|5RAxt|G8?JPMk=$B%50=E`~R3!rkWNWOKyG>D6?s|-}_*> zO?}2vcl-*|{QfU8dw3A5cL=m%rGLUReDOg4Br{|(JLbdc$`_aNwPoZxKZBGoDdFhX zwfA9FJ6c!fdf-ctQCraX5v@k|qn1_K%XZ5uEl^)_VJ~HNR{EP3?4``i-X4j=bJf3? zeM{FF*~q9`=Jr}TSm%~5Bj^_T4f$G8&F6Kpn|Jo>Ymlo`v=BMNZiZQfB0aW~RPiqk z5WnqXMCc&aKjQgDtpD9T+O91@Td@A}C2YiVWt86D&qS<$C~Ez0zo{|b%=D#alJCeP z*1r(iJqgekX1CgV0M^}XMPK=6t62T+d_~raKGDLLLZi`e*{dJ{>o$p<38rW>`DHeG zGyu!~7+&3%IArC}0`?wY0Wx}Dz>%(fnPY^;PVDS}u$Uu*Z|}awnzh$BrZ5w^O`FQx z;|_Fkr}jN^+)Ga|PdmV|fd1eR-*_G7$fF-xr_WOl>x=Y2RV%-$eu?@gJxC8y z3-smsa`jz#-fxLosISyls>k#YJwz?i*XZljVts?YK`qn6^>DRZe@TB?eNW%4Z&pw0 zaeAD3O5d*UR4a6qo~WMYUoibpPu7!FqpsHXsAu#vJx%?Hf78^Y@6&VCkM&&rfclyK zj-ID}uIKCd>KD3J*QyrzTc?HUmwJ(2q<*EB=q0LEFV#!cv+~!bb@F_N@5$dlJ*S`2 zPpMz)m3pOmUO%lH)o*l@Jip*Yd49nLwM)0?U#hg;q&KO(e15?`y+vrcq@i@&b(%{Ro$}m? zPn#)biY_qsm}&YfbFaBy_c620Y~9a%+k9J}Zyqp@>Cc+wrbU;Sjpo<-Yi6r?LEmm( zG%xBq%nq|dPcS=8O5bVrntl3i^NKm3rqub0|9o2Q?!`L>s?v%PI^`Mt*iTd3>p+4gMxlyOmi>?k`* z@3f=sXuZphv19aZJJycXd+aytH+0h8YH!sk`%U{zowm2z+jYj?VJGOl_AYyu-f!== zck7q!6gx$~V(+o{=mYj!@>GrA%I{1*tdB&4qrqC9{?J|PT7-+ip84b{Pz?(m{tS-# zd?%j^sXXdJ#SnT@&JgOqfVz&HM`t5h2HI!HJhGU64S5~; zM{){ipQXNqEaB*L!fF}4h`NHhjJk}v9@N$0Ac?7=o)^|hKPwnh6ZZh>c5)k89qf|$ ziLC9UbCkL*su8~}DiQ9B>ZP9lBP-bdLF!uSKFF;t zj`ndWQY8Akg}u#TZo4_pw#bWL!*y{TdXQE%;xyB*p#KsaJ3jWqa;a^Lnq>|ha3ojK zN^e8FE=9af(J!ap#F;m7+&1QF2qU*~tbEMG=5wq$ob#)U>_n}pq4w;jm6@D_9*igV zvF8pfg&jes0JK}_*Rj<+(DkK%f-FY79)#X(e>k!wfEDzc$Sm1PdNKu?diGh3c#B5TiTTTPs=3R!_3G>10vtb6vbihf8GY*>(ftN5i*W7`Ry zqTHON*0dqFu9CGw$Qht%qb>%6LTtls6lP_|$1z;S7V7n67uWbcXj4OH1t`lXv?~xF zbg|VTj!tb4(0?!X5g9Cj4ta!hmGrlRQ4PtXcQBVdb18y>&~6rLgCn4QkWK@gNzkT~ z&U{dp(?a)ny4hlgzG7FnQpNPVf|Bf}_w;GZ?NTN78=|+J&HfoxKf%Hnm{l`*8ey z(9to_b;1d`y#?noegplGa|`KghGU0=W*>aRytzY+nF zgJvK0IN861-HYYjw_ItHg*iP5SM1R8E?y|#1_5h9n@`nt7leHn>=h`NNlg`7jmuf)h~=Vl8fz5_I0 zha>N@NjSC^+I)c=9mg=f9gci&0Nl^o7pOa8hcWToReywOhQ|GfKCf&KZGy$-Jv7UBuH)p=0en( z;_M2c2W2gT?c^sw)e4$=vWR?)EFk}g-ZW!$XSaM-Xo|=s9OYuhv{9E)mt}863|W?) zK`oSVp&w>U6=tRW0!Ow7_@m+LEU32SG-|h@)_w+#y#h3Ab3`l89-e3XL2?1Pfh;Gh z$yP+_a*p*h99drUP(c4f#?*oKE392fhkKL$6ZJxJIcqOwPWI%MT9zeR4K445gyAyK z9YxPUA=geZ7#@HVa?OU^LhKqu+V7Cu_DmZh^%PL9)zBx$3Kv0}!(;_xHXy@#0`q(U zd_5h$`33cHF4t7DM($|JRRM_addP@RBgPJ3{CFJAzTJ(*lHgA`Q!$2UUr16 z_iEgdV7BlzXxkNR7JZn`VQAe>HqoC7hF62~%UIw|?BR=KC1XAy=YwGfbzkx`ZY280 zoh3WMT_&S^K9n_OXT(m}OPt=&x|ESKK;49xu$(a`$b9%F>#&v=K)WKwuLpx&)RW0! zV0aB$h1HR=;1C@7tvG3G7J>S=%t;Fvej5x%f_4pCwFM7I zKNXBw2u20eL&=NCOF(-7Gm-1z3njiPmrpof4L*`l>bMk3L3u}sOqMeKY&TY71|Wxe ze;{Xkx$`42!4bwkN>+k$cOUx{&oAbS&~o1$&fVmlMnR`wA&`U&NeT{r`w zgO{oA$G&C_C|4bbtYs~)F678Bj$Ba@_ z;Su)#B99@wrm}l_u9C6lGkyVR1~R@Mop-4nD9gJ?m;%*lvJsTyKj_H{P|nU^2c44a z3D$x|bjs)yW!FedF{nB~Q$hbaP@hDkTE~8}aMVX+BbT(9dJ|(dF}|9Stz;cpN~Tyl zkK`FpSF?v2Y-2LR5i;&d&SV1P+Yu@A#E6B=Knlxl_fS_ezK!}S=A@KPJs5lqS(WpY zXuFlpmk{H)t(s4x)^J}iHK^5tK=nKNpJi{3&Zk&=8OOa5l;>_E|IKuYQ7hNs(wqJ~ z{m1Dq1r7J6;63OdKx8Q2-II9v-mApF1IImwTK5pNd}ma&tt8LJOzZ*r+~fRc_;POd4hY>60(uKHGuMYjntZr$Zf#=PR>E1?fd9c^PH}CGcwIq!x0}8vef`M<{H-W zD%zcbma*VpjG4<{^q~JT`ZLTXnGa_u+nyYIZ80d@r%=xOLbU`8=2DY-3u}u=54yf& z27S7P(6T?G)m5O31!o?pcF`}S^AToZw}L%u@IPw!ZGAruxBXQ z0xI75={ZDa7MSg#-tOv@?mA6fDOXGq3HEGvO~MR6so5^aNbzM0lFw*dIcr-;j512z zrOBSotB3^pkxy;lA9Ab6?Ti#HpWPfHrB<{!-N$erpu0XS6?WoYO-}`PH825%4b#Wq(n+@CBnJUF(KcBOCIz0GatzxJ%TY$`Zjit6lUBI86UtI6`StS@WIE!@KR zEsSp=x3G3CwrYuQ6K>BIqks0Wh0c~-Z_QGhq0Z1h3hJNntbG#H&w%b>Tn)N3$alYW9=F;Ug~)38Vtw20-D}rC1=HXhHpWKr#Y)9**1?fVE7vK zaI%`MULbiT?_zz1ZI_YvvX=M69Pb!Myq9Gjf^RuW#QA%!g)pAUg=`hCS*{nyxw*0Q z<2zB;vj^Vuv|MYJYt3@>fOE4Ah;gry+(KLhTkQnRZ6w!)Sx4Oqbn*O;L(5~gK@SF; zo8?ltF^s$nw3|t8A(k0%<*eOHpL32bg^os$95Gl09bQE;ORfvrwbI$b3@^sf#w~`H zElsq|(tm{hBhbMM03&`Q*VsZ^=8_6ta=$qbjJ^&*Hx<}~5^O+4T z*XlycYl&bt^&8|9V95Eq_0)7+%y{Pg;hRb@V4vYzj64mxYWgpb$X*q|0Gqeq? zeVp;Hl3at1z1f{`%xxs|W7bjkVr0B5$Du>cIrPv0=V`e_ZVclKK+84dE~DN|ay?pR z#+AcyZ0q*2mdg@d3LT9gIfq~sbja(skU4Z+a2%J#wNl>z+Kpg>TbJiN{S|P+cpG~g zI^t4CY!xy-Vm^a>)CT=P*9aPJy@ol7IJ#xeHeO%sKj3^U=M%+ib~W1CIG^zv;X0LT zIXUOrM(o9r0&RT0m`%-Zg9N*&-yoj=-Fh&LbxfY8Tz~kc5)9Z+_!c8igRYwXcumcT$s?iV8O?Is zfb+2ptbH7GuaZ2UI`(6C!ZEjz%!64+-HVa&{EtJ2oM-5v1J2EIDcl&w7l1ZCJ6}e< zndG_EG8?WOj$>Q5m$h7q=u+rt1j#uBtDwWHNaoFTK|3ysYo)#cv>QRs8Tu=rL*^=Y z8#?0hMvM;`Dc{l(Kj8O6f_~7h5i~qQ8D=BmxR&P&8?PPqA8;m?Gl}B$xEgJ3oJpQ3 zEZ3k?@a3IJp8BGirR-e~%&bv`Q)b@%Emd4oHETMbASKm3J&eK~fmmzxH*KWdUDIZ$ zLh^hPcN47qm*-ggm&(bA1*)&QfcKld|&f6HBn8K-?4vCzVEqE)yelf8&$JBpK7yuUcDsW**vJ;RPxP1xjWRQ zozC}9DC_pPq_1O{^2=DJ{c@HW|2-*_ZjY~Lne^XhnetDvO#7!;X8a0eq?eWQDkagY zSSI}sSf+df%d~%*WyY_T=#>AVyh=-SBg>?JhGojHVVU+nVwv$x5}o!xmRA{xUduA+ zf5I~5n^~s)Pg!RCI*HEwhm2IquV>9wwg0P({7m}UBjc=Rne;zrnerQ0ru{EiW_*i` zv&a8ZULijlS*H9yvrPL zDgQjnwEqpujNi(PydbZTk!>uK{zaB4znx{;?_innFZ~Z0c~Y%bYt@GTb{p9#{U9T| zSSI~$mMOo7W!fiMW_*enNy{r_B*QZ4_p(g+eJs;{Kg*1NS)!Bv6?ujH9AKIBzh#;B z2U%wPt5PB(hgc^4Yb;a#Fw3-mon^)!VMgANSIEelER+5%mMP!PGVOoIGUJc_A2K4p zvY`&huS6V^=Rlm1=Rp{q=iiookdb37lm0l%lz)e1+P}*(<4-Unzn53Y$Vrw-{|A;S ze~M+=|B+?J%ah3^BY%=t$jEyvlm5>vQ~nIgw11yv#&<|`%KxjpLVo1g6H+GqUs$Gm zC(De_VoCjn@(OwRh-K1$%rfP>Sf+h9%fGkR{QGU>Zy7oD*NpT?50Vl2m=I+$p;@L9 zavYS`>4asONjPLA5y&gaNFrpJOhhbG3C}W}NU+Q#@{p0lC*+l6B$3ZDnfN5jRH7Hl zbmCJiGl|~FNaEA-N-~ltV3|yu#WIyBWSLHUhGixp&mfX{og=R#Gl@PdlZkU#rV@Qw zrsYVjW&WAJ9Vb!&d5yJRR_>a#!b8cPn50|3BqMKI4^hNWPjbCnzsxiz0Qg zDv_gqnS5`*B5|H_?zns3R3?gYsw&ZsszW?^@`==Tn5x8QMZL?o;+(2V^ru3coPVTN z;$)n@^0x$+tD$ms8724ID&^cVOU+jc6BkNMJkmuuRh1Y(g&r=>sj9^1M8zWw%&Drx z=cy2PNlsNIt`hZocU-(7IaQUon(AHguF0vtH=|1>CZ5rtoT^G(Mum|s `!U{Udm zN^+_yaRn9PuFR>b#I>U084b;;s>DA~VMf>GRF$lE%fAs&dVyXb?*^C48p4(#TdR8C LTpRwU?d0D8qPP+; diff --git a/themes/classic/assets/css/199038f07312bfc6f0aabd3ed6a2b64d.woff2 b/themes/classic/assets/css/199038f07312bfc6f0aabd3ed6a2b64d.woff2 deleted file mode 100644 index 3fa1dbd006c09a3b65bda0c5066afe36f6f57d01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160208 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%0A~*fhn6le~WYK_6Ftg`h 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

C$W7QxNPYTuK}XH+6uJq2C%t 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 X4MLk)TZ-)c_a+6jomk8FL8)p0ar{<1 diff --git a/themes/classic/assets/css/22c0528acb6d9cd5bf4c8f96381bc05c.svg b/themes/classic/assets/css/22c0528acb6d9cd5bf4c8f96381bc05c.svg deleted file mode 100644 index 6cf1a7d4..00000000 --- a/themes/classic/assets/css/22c0528acb6d9cd5bf4c8f96381bc05c.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/2fd9c16b805724d590c0cff96da070a4.ttf b/themes/classic/assets/css/2fd9c16b805724d590c0cff96da070a4.ttf deleted file mode 100644 index 9dd10199bc8e8fcfcc5c3a1a394557ed00c567c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414820 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�!PA{ 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

WJ5>YvSr`Ry@8Xk(Nf|7+19&#gk0Wpf>j;!@2w0 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 - - - - - - - - - - - - diff --git a/themes/classic/assets/css/3935e107ea61866e60d7946dc6a962f1.svg b/themes/classic/assets/css/3935e107ea61866e60d7946dc6a962f1.svg deleted file mode 100644 index 79dd127b..00000000 --- a/themes/classic/assets/css/3935e107ea61866e60d7946dc6a962f1.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg b/themes/classic/assets/css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg deleted file mode 100644 index 4211f857..00000000 --- a/themes/classic/assets/css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - Artboard 3 Copy - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/themes/classic/assets/css/3d34be670a7f15086e512282b97ae35e.svg b/themes/classic/assets/css/3d34be670a7f15086e512282b97ae35e.svg deleted file mode 100644 index a17acab1..00000000 --- a/themes/classic/assets/css/3d34be670a7f15086e512282b97ae35e.svg +++ /dev/null @@ -1,19092 +0,0 @@ - - - - -Copyright 2012 Google Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/3d4a907b1b7a232654324a3dd7ae4aa3.eot b/themes/classic/assets/css/3d4a907b1b7a232654324a3dd7ae4aa3.eot deleted file mode 100644 index da2805159fdb53ba9fd89f5780bcc9c10b2e5be5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414994 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 z 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 MkNA22QOo*&0L-j_^#A|> diff --git a/themes/classic/assets/css/3f81521029cc8a9a703419c4a74704a0.woff b/themes/classic/assets/css/3f81521029cc8a9a703419c4a74704a0.woff deleted file mode 100644 index f5ac220e8ff490563c4778a9a6035197c2de287e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 173164 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%0A2Y2)_vO!E&fkt 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

  • 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

    Hz-!<5z_H!3 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 diff --git a/themes/classic/assets/css/8b05d51ede908907d65695558974d86f.svg b/themes/classic/assets/css/8b05d51ede908907d65695558974d86f.svg deleted file mode 100644 index 60566132..00000000 --- a/themes/classic/assets/css/8b05d51ede908907d65695558974d86f.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/99db8adec61e4fcf5586e1afa549b432.svg b/themes/classic/assets/css/99db8adec61e4fcf5586e1afa549b432.svg deleted file mode 100644 index bac31217..00000000 --- a/themes/classic/assets/css/99db8adec61e4fcf5586e1afa549b432.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - Artboard 3 Copy 2 - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/themes/classic/assets/css/a165a42685795361b25593effb32fdb1.ttf b/themes/classic/assets/css/a165a42685795361b25593effb32fdb1.ttf deleted file mode 100644 index 6e00cdce1dac34e409a0111296c90e98c6f40701..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415132 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%0Du4=gPtyp&Tl9Yh|7h{qy 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 ohyj3!`#ee%L;DTjx@8!5k5~VH0QmdE^#A|> diff --git a/themes/classic/assets/css/a67175d1ea11389d9107bd8c08f9d7d7.svg b/themes/classic/assets/css/a67175d1ea11389d9107bd8c08f9d7d7.svg deleted file mode 100644 index 0cf96aa4..00000000 --- a/themes/classic/assets/css/a67175d1ea11389d9107bd8c08f9d7d7.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/a68cfe9d548950edf5df102269877edd.woff2 b/themes/classic/assets/css/a68cfe9d548950edf5df102269877edd.woff2 deleted file mode 100644 index d21ed877685a697a100db4337ecc69c529526763..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126924 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

    4Y+{!!)q`=> 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 a=i0gWHn<3Dh+77>R`Y=y691>| - - - - - - - - - - - - diff --git a/themes/classic/assets/css/b1db819132e64a3e01911a1413c33acf.svg b/themes/classic/assets/css/b1db819132e64a3e01911a1413c33acf.svg deleted file mode 100644 index 16d3ec02..00000000 --- a/themes/classic/assets/css/b1db819132e64a3e01911a1413c33acf.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/b467416c449eb823029e16347b2ea510.eot b/themes/classic/assets/css/b467416c449eb823029e16347b2ea510.eot deleted file mode 100644 index 81f65e426967c2993bd5a8844f8f7e94672f3e87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290642 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

    S?UYw4l%7v4kQRy8*Q&w$* zOkNaw(u5>n{j@smC}_1dSwL|g(O}ZW>fn1qpi$>AH~@rm*e#(31_V)r2*T>jOsuJ9 zup+LEaK+Q%LfjPKd|+ajW!P5NxJ#T=3~5N$8p7y>RFaZF(i7IFZfpWbzTfIW>vlZ; z&47YwB|VDzJP7P0iJyV+#lJhxbb9qks={a2{1$YDRfm629L#f{rMS|P*Fj~zhTj`ZF|V)=fiqnRDvQi?0%)S%mTLnenO=WehV!A+tE%2 z>RcI{{hk~~Ok7#_X-*T$m?c8GvhEg3ic!^*oT}KEYEl9<0wXFy3_UQ~p3Hk_&*v1d zi%APzGCVeND=>C3@1ZY996c!Na!U`4Cn!CX3LBL1EqcfZtXi1^ zyI)EV{mF5q2gOjs7)lR}vRMz5Uq6&>^xRk2r;Odg(YT(X*@m9``dgHe#Tc8!;a6$dijAmFhmD9#W_a5> zNOptKFbSf-XmkWSm{SI+unwfcI^cnEAQjeuR9J+8EWwgW2LqBrz5J=LiUY=9>kU_m z-6CZD;9my40B{8pTwO zpBB65Jo@Bpi+}ddOyg{eWM@$J2J?jKr_w6vS-LrG6E3-vq@~ew$?dgyPmX!~NxM-j z10wQ=4{5Euo!##j8cM6SKHYz;7z;`BK5ldf_X=?j7__q$%DJ@MCY+1(5ZB)n-MO6J z<}^Wq{AbI(XuCL9Q2OZC{It?X3s+!$gmJE*^wEz(31nxhY1_x=oG&PSlr~o@eYEfe z*2h3j-AW&&^mC;TbxR+xVUVv3azP*L_Ok3itZ^ss_Q3Ar_a*qfnhdC7zs1VoVPv;K z8L_|LpY7)(F#Iv1*qtNAfN)o!{tD3FkM74utRGsgLiQhI79Ukemk^7`jX<`C{0q3h zGO7kocaC7cXBp7aoBSp~5ob4{d62TwfZq}ocWhDt;{+mPHfuq@Q&wtixlOo*$O6aQ zJFu0CxdOIIsIE&EM@0z#IIP~LCB_E zS;jSfL?3L%`D{<0pt1^TuHVvUElE4^qgjz@&l8xE(4)DctvW z8T;ibk}+}FM0%nU8Rg`1%!f0@T~u9q@+CTs-4J*zL4y}CAA{iZn2_7AMp+|3R8)GF zq{e+>t=$vg-@w867-EKJ!VgR6`O)`|{dyaqVq23=Hu&a{v(A&Vr5I&D;0k%f zGF>^lK&*yS&0H>zxZNnssO2}d#R|a5u?%#j2QCR9ZqRcQ?J7^^G8BKuPPERy|82*E zUiP~(UW*@*o!r*e@koi9kLL`~d=?}~9`0ER>{zDtsoBFD*r9A%&NJa7VQq!zt>IeP zR7}i9kxj{yaac_s~AI5696Otu`)7Ns=!n4SHjA z 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%0DTuQM>KDI!*j#aTneV|W^;CK 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

    } z7B#b=Ls^n|qGV?Hc_}GI!<6ityy8bjbZp$M1A2g2d?V74k!SfiOuJ)kYVTir;e0X8 zeJ<8p4W09$BWATmt$`QqsPDW-Z!Ou5e)q`nD^W*CotZBoGEkyb!+un&LjZ^Y2eaN9 zBC#}C^!vl*EStfv;`n_Uf{kf9u}rmBssNulefX?C{dVM!U0V*3L%uz9p<&x)dXk@1 z+1ph}zdcW@#bM7r`S|{hG>>sO(5PVYob{*Z?=fgX5#AhGp>$bG_9=;=WSyh+CHVHO z$EGV$rfExX@`9C0r9o}f8$hMO&(T@~`mGd7<|MKvWCK%lf=a=~J1gcq^GrTpOa{^F zJ@n2kZ}X2Nt#Z}n%HrAdhR{HhOAjCW2=J2C*t0;^C&ST z!Xnz*Iopk@NN^hT07ur_6%4UMN$Eip6 zz8IckSC(dUEUuonQZxKdvW`xiRWFMSD=~d)UogEx26^+3Q;sC5E@Z=cvT`<0NHCyd zf^kg1X(h}`*{qQ5TonWuNM)J_#5iC=nq*Hkz0pQ`I}(m5oyx{IL?*Znl@y0{PnmZs2ei-WGr+ZIqwbY}#?Z40-DVv%>=bTW-lL%Taz6GrZSv1W z7^JwzlcbNp;@ucgi{CAwcAIM z@+!s3nLA1LgGeU6OV3M4Lrha8le!OQ*t;S1n$)v^gN@{L*N(7RYi<}hfxeLSh6S!p&zaR`ZztgxDN zFv@jt`Vu`fD?taVT&GhS^h!VpDXlzX@&TI&>y(n>k5ISd4lsc)n}Mu28XQRCLMoOw z6$?VewDC;3oL{j{t6HD3wi2v}48+%}rW9{M(cE-;)J$$t+l8-R*cLkrsU~~rK=%I( zz1y&4Q2t!Z7sDVg2JO)t@YEFH;kF>8ECM{wrq^TX^ljZ*ERrwbsliKyni!{CFmRY}owoOg=Vi_1ed-oY}c+{q-9?_YVe!&AFSW z*4-I-ER5g&pUh{E_bft!>Zbe-WrLQlAi9M19ZWZ3 z*EM8yr2ljH)5(ncEW-}oi#ZAAbgy#?y;_t68S~^ZC`+k~Ju#av^@JgB`2=4@dMu|` z(v(8xYaP6}?AIN9X&zi5#McDrbP4x~guhLz35^WZ3t@Vt&4Nq~$aYEDm*PZBwZqbO zWX@nXzKrY#<^YQgHLG|!IQk~(;Q~ftaFD6U^gTVM(Uf$!O3(8qQmWJt{y!yrF-bwU+$A`aF^W6m0E)Vnm^3*X<(Fi%d7syIh#GwJ)jKT@I4Fu6h!;<7NBO^9e zNMu;OY>1{TzJ4KK?V-IC68R)$)UL`$3 ze+qeIOa|6*ES~osMvdMW$2bKLsdOl!SM$6=L6m}Cvi$r>AvpC&SHv*!M7{^TR8Idx zavDh<8R5N5cJL=?Ioa(+8bWKPYZ!;Ps@Y^T!G<%T@0mr1II#|f9NG)`54Wsu1nkPT z{1`_DjsIg zHu$HzquaT}hXrJVMvtg48WnyNwjjMy5gVd_jN&B+kISEe?zfd#_GZ9NLU6r>Cb>5X zOB+LSlcca=CGK{~Sl*4UYeV0-*)wMJ8a3^QuZpXx>=CJtxP}etImu7v_Nh4w#_rgC zGb_y!*}Esphh#PEY0Uq@YS=LXXo>7K_*8rDAy2A47Dy2sk_0q{Aj60XivR>X*a|^h zkX>s}Y^bo=?Rss97DLgtb>c9Qi%~G0PDU;EkH?LGr$l;dim}B2cUNMPpN9dfR!U$= zOguFC_)zDT#r0{Vk=ipQH_y%wUvTe;H$M07d!N0#F2CrxRb@Hz>W7Rk8aZ*{Wl{<7 zu(9TUJWcJF(}|vByJ^XCEmj^OVPwdYso<$z-KV?IBd|eWi1)e$SkXve*gLsdTINGABLAKd~NiPm*2iA z?s%L2qmOqjf4j%u=9N@bUzzs_d-4H1c_g09urHAu6T;~%ay$zXSc+%KToWlVmAANWD@(pvwEZ?wpJ4su% zYze()?p*kfQ7b0a?#|`^?OpZA<+V2fB8CwqV~=El4~Mnptr%<^$5MUR5tEc1DQ_i^ zYUq#s@D>ByOc1E#!lg?GNas&j8pyc9X-B6W9X_%ES`1P9NDtKc8(HedKj_fg^loPC z-2q^>a=kY49kqBw5?ABt!vZK!vNP~0BV~{kW(Tt zcdQ_Xv^vET6_nDeP-%nI%mR&9s?&=lney4_6=I_jRdV7 zL{8qKUq;JF+IvY?AZdH=R8H*EbMVC8EGo}@HI-5n{zG;$xlFvS!>pUQL>7_O#D{7b zfLlDwnUCTTk&Y+N#_x;gg?L1y;}MaLXAxhebJIDo<*eN*~RgK z!GMUg!NAHISXG1My^%F$rf&RsM4Cw8bcj*8-E6BO!e{lTbY%I9m2i+4-BchMuX@ues08pDF4ruN&h|1K>XP>|b& zaGy__(XI2uOKitsE))#=50&4ZR3q9+841_!&tj8Ep$Ugm3i&jD8k>aD%hncLUQ(T8 zFI0wls?Qv#4concUcD^EWNgOROlfm(NMQW}qB!0^J6y zfn^mlw2OGe5R*c~$5w=LT05YW?Fzldp?5eO>5l#m=<$MMIGXzi4uKcIqFVHI<{$MB z2Ak2JuPCYPZ8j&tp_3U4-FD=qbCXf>*We+$|c?Y>44(uhAdXT6PPOVOoGKk@t3}}baA!j)Q z(hb1{TZ8I3?tnf6(Jwin9_)(bPayuG;o;diYNfp=>EKTi*g`MCVgH9Y#HE$fR*-U* zAaJh|F8kkP5KA>xl0>p|Jv@o3;E>>v6(ZWS3A#MpF&&?xgKW}4HtB+F;o*oqgp;7( z%O+#1VT)Qx2D&Omgsgw~4p>2>0Gp9DW3xwiQwR}`br zV78b?R%p@P!DI``3pp0Tr-XpS5ReG3)bB)^#7J2^R3IB3$L#?L*FvhqK4Aa1k#u?c zQ}%bJm%4)F=-)^@`X8Cp6@IZNRhg=oFVhb0kOHkMzC8?ZOqk6Qnrt*CgIB;%31=C0 zPAS7q>aEy@(P2l(x}abE@|zI;91yJGuhNnxV!NW6F4Gbm?q#dD7^ze!t%Xqm!IPOt+K-^q&lqDFc5LZ2PZy zhH{SNFs7tMKM;$1;;|<>K!1xk{wLXo{%QDKgsx_~6rp=yYOon02l}a!xCdU`XB6#&{j45ce_O3uuEE0^_5JE_a6D(hDqDx z*Wv$Q%~kImHRobKRWWRJS)HPG{yq%HQ*P4QrxP)0!gFQ6=26@ImIwtJ9dSyAOJ9P4AAm>|{8^wZ} z#*Xb1I%Rk^{E(iJ+%4bJP~Fk({XzDvFr0tIF6agc$WIJpklE$l8A0uJDBTP}b61FT zSX%*Kg^cwtO9JQtQUtekByD5?lcatZrGNk_^aY%bZ4)-Pf&5Rmm5?MzgY+>G%yqeS zaBrzQ%EOx&3zqfTHYHum6^T{{Y-hJg&T5m{9g`%f5v|k0`m9;Z=;iA-9e93jlPZwRJ+82C zLz#NS^5VHH*PGs{siBXwnIySMfUs@oQ!L}VTDuOOEH{RcEtnBA?x`!c_D3@GS&;hWt}as-`eMbLd&jd&t5@|+1=yd~I*n3|P9^$J#4 z(U%SgjF)Zkpj!!o9QF6Bu98Egj`dPu#~18~!GWWgRQ|qJm^bluXF9U;Pb6EIH|3`; zbX3=$c%}C~iKW+28Y_KgdNw@Z;t516l32b&bc`(qmV1mf!fw+C38O25{CUZKt%$)> zz#3|eQ3ODbn1(N@%5oxvJLhz}b}1}iv2e3K8%YlvQ%A}fEg9K)>W2L**ICoh8C4D; zKDENrvl*!mU!P|QEuY;vv}e~-LndEAI#4ThSuFpqU5YIQ)TLPCVAaL_mO_cgF=O?= z5h**A{IRf5i0S`IZ?k3q;?0xRJYT6UTtD(piT>5oE|JBbSIwP9f*u~+N_`V)5C8xH z-w5m@q_~9+4p~lu2eH%*=FY_qceZ5LI1v(Nd5eC>bmjH2+5tVL#Fc*ipRZD^smd`8 z6DAr-1Nmpi_^O@T=`L~gUxqg>STs3z0A@*kjst$Wc#kD4SZNEaO--%p2vroIYl%D2f!|!Mi)-7IY+pFufK1(J99>ZOnjW5TDLttmw zJvt!pTc)6C#KNF51-FuAjYfQk9JHp{MTDSMPQ56c^ML z_N=#=4jZ}@3JaR6=|2^73JNPbm-t8AMZAi`VLTFCrqv8mprtx)&x}q)^<`F#lfc64 z{N41h%%~3Kiz5bnec%;+&^Ym`@@mM6`E0 zzf1lxgzTk!iqS4>W?cJ0%OVF{Kk$k%Xabq7z7n!@DVf=P95-Xpd7E^vNY3mD(wkS> z+uV(v(>AwzU^BuxR*qzZrdKSo_xt)Cbr(mvr}yL;nMUPUG8+W1oQG#ji?O?Pd#&S! z7Co1<0NeyCFAfCdETWz7v1$;|wwg*pO~#T?t)XOmD6xi;(4)Q|Ji$RFp`nOlm#GZW z{=@c5PZ`Q;(&dfFG&H9Zs;rzIjdDjsufw}n&U`eD9H#W_f)8G&^A21u7z@z+?8-|# zFg5a?SiVgtqG#C*o+S;6de9MxRSz-2BP?2Vin4G~epU-_MSOrUS2I>62NP;!Kj1rY zBAUT}mzuiw-w78*wNjI-+xx$2b*Jc^-_vRTQK-a_`E|4w&szQLaObm8WF4Kna?l&y zNqzHivTVmNJfGui!eu<)%4S`(4l-$1261I<4Z-Iz>njqK*Ntpw?tV{qNHee?f%)KSg}3>E42_;wNeEiXklywMZ>JF(@x?GM+k2w3cv#6QyyI)bz zC!K<%+4}aK+Q&GmYgSJWGb@rZG7__ttBiAoPFgJf=03>H%vA;MgA7n?DdstbCdX9p zxw`iGxX;jujgQ*Qim#>ntklmMHhC%T!(9?~@OOc3AIc&D#U?@^nL}1E`S>Bk zAu#GNdG0`fL2`D3M3w57v>!6sXADfuUe>U5{mKniVaLVHMTs4v%ujV)G-c+RxUsnZ zDPf0T58Pi**!_vg#D%Dp58j_hcwmzL0ofvtfK=KJzP;m#X?@!DcIB5=4onkvj4#^r z_;a48ZPDFx^E{@DY(*wK`QoP0Xgzro73UEJSLGcW)S9<3~@d|lJdZ)Yh zW%dsJg!cCR;M>Qk#9Q=*dynItM7oYU!0s1i4-A9x3bWbdY_0%E=%Lr|tXV6-)W9%gSO~gn%x{ z5j@A~rVZii9Sx3k;cM}go|wC4&D_RDP}x9F;CXIrEp(v(*$>{3-6K|oYso9&xM(gL z*A>!-Bnd8HXoVcq5)In=y57&i2NPK4c2=MS5FblxE%6)1-{=>ppc)KQkc{Grxp1@Kw+g z1Wt31UyjzSl0gD_O~!ux%XJ7ffIkvoEzcI5kn*e=#9)fzLZU(5nLI7lf#Kr8Y0J$K3ulOX#1k)Ma1q4$MsvgQ7L9DrejLrV+X?Q`61J1kfWyPH9))enME z0=Ae16-Em3GxumxfF1ggy>j@OeIG9y*Y1(N{YOrnIQy$Hqep$FbR_2Nv}KGQ(0^gF z_dNNu>yC+gC5gNp#>P>_BAoLuPY{Q#jrg!2Vwa_}1~Jk@Vx2~`W#NxD&?$VFc)tO3 z1+G$YF&-_>2gVtMLRgeb;M_Cst^Z;iKKW{+OS+z{Z4h=h08sLQd&GNCv>@LDt;X8i zX6S#p55KK}hm-366)mK!K|qkV^&avp;IN~29wb0|%RpF8L3S(~h4*_5q5&OYesdKv z5ky?2fVggR6_gh=vf181)_T8JEc#X1(DrF6=-~#SqpDP*I!J-OX*^RI($n+OTL#V+ zS-ywS$?ig@G$j?w2(u9dZvR;>hlCW)H4i@vLnf5yW~n2-t{VOggAfdCs6FW9*k z>4MSkHO;t_z`#4`EkGA>#CrkP%?1KDyG}s>$;`sJS@Ly60x1%_7s!&4?=?;TH-fdN zX&0iW|AQ-OKCWDVN(59wV-~>aMIawa!78P64`~vx0oe>BxD!+gMF>r|@aeI%iDXjq zXQQvKUosE(L46-LyX}3DzYT>#sxilG4ux)q!!O+@L7`H(6A}O@4@{|SOvM$-J9W^0127Sd&pmfCm>HB_J(=K;hi+R^9kPRMIPpFddI!R zdzd60PAkX@zBO2ff!_FgiR!mboD&PKBmJ5u*YkU(`Hdo`JoX^v5+p3E)g8k73^7uuw}})CghHE^u&l6f=2+7D84|i_+I@B z3e+f=5f;(>uol~0M zRi3!Sbej_BY*u9ouIlG~O1e*#c$0e((o049Q@APctfS&Dq_q>s1ihUODUMw3NTC#Vj&tFRT zgx=?S%UAiY+>U2fD=$H=*|`3m_8}n)f*XUc1q;ERppfEVk5X@OSkf)~EN@yaSm0?^ z+tf*FeiItpANBom1kD50!HR`Ys3Shia-|HdGlIntyhs@;^&nHCb&Js@wTVb*lOI8< zl6Wt+rGFuN<%RwU^dw72bJNdPn6$qAEBm!8&NG zRYz6dtA0_5sy7vQHh5_@Hx;VeQQun!Z4qd#02>}h0xp$0BRka!XsXOhK~H@d`NW{d zqpqJ?M(3jQEA-Ps_>S5AyLz0WNPNhZQ>a+G{eejy@JzA2CxrVLjrrz&~mz)KHc zi0wncf}jxlpAZTyn0Zw+*PbV4 z7!ykxy?=x7j!_xPVe?1V@Wn%f!gQ8Bt7^s+9RoYgwh;FhsT@? zuE!Oq#pAa4zJ~Q21`S)UbLe=T&ZuH#iA))#4sQ0H<7$ynr9Z5Pxuoz*YVevio;szH4jNpLlAD>Qb<^CW_0){M)}1<| zvr_Y+XRt;|G?}}KyBOGApfiTF+$EHSO>>xwQ_ASGDAQ-H5%Z}_IUu!TFPgk~vb8-i z{upB{3jNg1_^Fvr<6iX5hjguNe)QfP&UAoqpng8cwpc(mda{A*O~RfS>AMErWyQJC zm+Qyt`D8s&>%;WCJ_v*LSZ$8tpdi~|^EhD7n~BP7GxKJF?U}l|I&7O1_8nVKG94tR ziB%=B3r1$n$i^v?mp4qE()e_CYD#u>YBp^iw`l(Oaq}0BX`hkNzA^)p*3x{8dR>WBt)N;L>gfh)iFcIx@Nz0Yf z@|}pPl4+fK_Y3Vg;w|+Q)eu)7L$$KX)z>hu=Y%ft&R#FHiwTbyRM^vQEh}UhrN7f; zF;WFE@vsZoNL!Ryxlf~aI~~WJW%ELMH`m;IlFdtSaLcFn9SRPXRA2ei)JA)8-}tuT z)BW)2$xKVu>5zwn8*e?N(-{o%6oQId_~aYxlj8r-WAZ0?KJZDNZ}Z95Xa)BlS>tP- z0gVs$421^A?z!erXsFE=xFD+A`(!wIk-Wfvft>^Wv-xA}oPOwb z{5rn_ewJ^2oqqim>uVqv_}h4=jRwQgQ@r_#*HiBI=675I?`a|_WV|pyemaCTQz3{A z@AIQ;z0Z*AWXd55FNXJ&Z#iEmS>-_o1c;e*=1qrxj4y01cuzQ~G~b)9T#5TZd-Gin z@M4u-?SR6jHgdW)yqG~xvnrz&pC-L1J0nMqT{XiLPIpM$c%^B2<;2A>t(d(L*yZ6K zt&*vpF>s+)gzeUrx5rtp}42(lpXUFTI5)U!$A2TR0)n9J->L>=_EHRm&~( z=hsQ+<9rqj9~=?PMh^3<`hzsifM2xb2k$lO`iYYh3a1Vl5j0sDm+R`I8>MjOy87wp zrpXJ6iw6x#h>3&>jT2&t!&h*QOaIS&I2%Sxs9xXWH$EKVYZkYWMao-~eciVaP5 z<;Rsx8=sMA$>^Ai^Xn^C{K#KYL1Tt}8Kt^{ch*C7>cVtXSW}xNe)oHyrXXJCOO!fk z-+mx{=6!K08LBu!RD7=Y@4n}mCB^(z%wOqKi6{760dKu>_$A6v{ zO6Tb;?M>Vg-vy@z-?hVL^9#iQ;|&UuPdJl`6jh`^c3B3U#&|?A02<~(COTLM%g=M2 z^fH+{V43UZxwP>vuJF0U)qJut4LO`HPxRyFO=f;3u!6bes;w%1mWnX6bWXc3jD#)J zFr66*@hk!@=~v9th-$qgx1_B)P1t8}GN`D={w~SWkS8X&YIqR;p4!g?jz3Si&PDejd93^>EcO2OQ*s6F* z0T}GZjhl?S5E4hE4%(F2VNOS=P@R~l#>A!@S_lJeSrW5~1L8N7XeZnM3xTkSK&i0oNZq|_ESIQbyz6r+yYPeOHs$7&PEBdqMnG_5+y{%?@B(L z{C=`9Gr1vobFz>e7LUJaF}sY1jqe+UnZ^d=W;W256vq^26~ZjV6X+#~8DJwf2YGa% zP!PUMBWVj`*oxF;rKfz@c2$^v@xe9v{Y;?x{txB{i&mD>vvW>lQU_ao{saJh`-or^N9ruPMln@ zz`v(mzVotQ2dz3)Oh;pG9VU{XzuKHCw56K;?b_KcYQB5=^j$8@n}9{Q3d@JpdT0?Z z3Wqik%Ozno+*|=y!ad9l<;HP!@YXEhR&krSXSm()E+6MEcxHw~nu6_#VevUx`Yh5d ztAEz;EMeEtqt6}ecCi0Je#n$5WwkTr&!0A@FgLfT^Al^=E?sR{9kZH$Xv~;C)x`Mp zzI|I?HoP43GT)(nMte{DFWU?8SqE$9bY5L;e7Sx5myOk{JI|>-m=zyvvc@DPIxJ2> zrAGyp2~z^sFgzXdH*^O`Z~X&n2IdleE#-Z*z6iXQe#c?}vejdB8Q#qT^d;tpxnW`z za2TS59#KmR9H>Ncq$IG{cwfQ19WK(*m1QwI;^quL@#Q#oC>stvAJg)Ut0Rq@N{MCt zbI4x>yW5@H+$?`~Fn*3~{!)6ucaU!s9UdNyCJfRa_Om$i;^fJbo0pM7a_%DOcE5DW zrF*2XdC8P1r0|lM!tVA4zK}QFZuW6@9hvENM@B|^pO(JyPqlsZm2_k2qhv&`+s&xN zb&kV$zxme|vI0MYk*md{q+B@=JV19SIOHuA3|&{mM@+@A+ALsm*=SOfl_U-Rz;7ii73s<91CB7Tigrp-!kZ7uX3!H0q^SpPlf3BqYOL7h4{{(mOSLB z?}EpzD}h%<*$A*qLCL%-N>4D$_K88h&vyNO{aa`kuUChu+o}1j@T;hqQ$<*a7;-xE zWx%Pz%-eudg|$i%z=UIrP6=5G;AZm9!Wy4|SB2!Qf4yRAL}`H2Di-bBOZUR5QdkV9 zN_WOj2|Z2ST(R#2>?XruULWj$D}@VZ&wyBK6Fj1)%f^o$F=kv@&FJdUO=V;8wWe&` zm=UAdJ+44DCIiC>7USz`;r_vz?I-?JsJuX%W2tz%_WO-*F6tK(Sc ze6f)5j0QdUQH)22zQy{;DBD{>dVQFU-3rG)!thZRoKnnZh?E1D758-_uMPJm>=7-` zsE>QZveHy;AKxJ_EX`3v_gos6wZGiT9!gz>|LD>8+q5vx3!P_Xk@cV;glO%yH4K#HDJ9)FruX*Bk8% z(i&^(J>BYS)}$@y*VwbcJgRKz(y~$JhMp*g@Ls}wzDDQFP($uFI1@V8HZ|V*oHdeay(|mvg#w$;s*5S^nRp3w8%`+}NzLoZ&S@)OKUabg-Dh;FZ#74Jxx)T!=xlZG1it_B0c! z0kw$*ApP2$6Y2s<=~W-qlzwHy&^I=%*a)v-18^G!1^o;joFlb^G3r!B@2mYcJ7 zmowRk+3~$69#DLWF$BYow{2095@m%FYBN!KxB=W63}m4Ql@gDYFv{@Q7}4fTjExgj zPEJshbTYwpVile87JX;Zhs3BXmZpbn!o1hg6mh?#5$FzaO8zZ`$3Q&R3W83d$d0AU z6nmUEMrhXgkqImzn- z2E~B+rR=E|+#HKJy{cyL#_~B?O6S`3tJUJ5l&r#sE4|&T#&0>= zkd}91?qobO8P9COGf^kZa*S+(5X2dV#6)HU;gJz%UER(yB?jCF(=F}mmWNAWYbWbz z#%3R9erKl<+NhDWyBDt;xxaq${J))Y@CBVaRQ2>s6K9U;)itZL_rR*f3;#NOOx4WC zv>|ytY_V&iQPRl!wxi=Zat1NkI?$lkdKRb}RnNi`vyiVO<%nTNd?v*_Lg6A!YGuq- zCpMnk-X$k3GdHiA&*o3=%E?W3x^PZ-pA)0nj!^|660Ccj4;`Y?VmNZn665cZ8_M0r zJ9WLXWcaY+syE+%b@tkGyXUVGZq7Y4ciNuEKKNzr+>7^NkP)8-_dF{83~iZZpeaoi z+Hwt7$<_r6gGB+PsC-+0MjKNP;Op7)W|^jYr{UqA6C2lPmF;UwE6erb&vbOVxV{@6 zBTjF@qOScXRe6xf;VZ-w7J+IjXF3uRq#9x|O6!h=mllAjDQwaGfp>Y-#p2Y?hU)y&&FNJcxm)@@SM16^IcGA?#C5E6Bj^a@fV5-?-iOL2W#|wR zj77%cygT&w$(wpUkUmM$Pn2njIt{gVIeFov(`iu*nmVLHhZ{DfM)zGapMEY}+_R`> z?c|}kxpjUi%oje=`zoKh85N=Hg0ty)Y! zCrt?neH$0h&-s&!`W3KUR0M+Of-Wh;vQn!lm+AS#3`^1_HY(Yc+-tI}$BB)NA<7{N zPJLK2c?x|Ww`*h^Sci2zfjy~I6fxhsuOIGy3$HcU^@6HWqm(BWW6Y8B0bQZC^oXc8 z&eJ95%8y5h{GEq8k?Gz7{!QAr7PEF3*I&o=t=SmmBEcTVWMOw;bFgd-7qT&uRL-c? z=Xy0=qgR^F_uKWk@C+%tco7|BcU-;kl_{*KY??7*X<$Z@d)CZm87Wykj&6feYCZqH(ytc4<1Zx_{ zC;J=J;9R$MH%O4i8&7KDNqIa$0djJDUOXQWPlDLL#^`6G`Dlzc8sm+|c%w1iXg1#H zebM}cXcEoF8;$WsM+e6H2W=Am>v&Om=r3!7a}vxcpaZcE3aw20&zdRFfBJ{~$6Xb? zI|6v8z9#w$kIH!T#)!t63sQfNSCI3=Y7;wh^&TT1qEN(*s)$icRV-AjQHXGizwgP? zlptp&2oZqv9L^k}k8ngFV=z5pL`8afh*_WPNKQ`{LX>8p2%AX=>K7TbzFgmfx*lkK z{!%skB)wpT+d~7DE-l>}{K)bqR_`Op$2bX2I1#!15Du((8{MuYF`CFH42~~3Qu)f6 z4fNLjzulbw35k4l_0EruZSG&UX;|^9Wg(-;(!BZYqlRUcJlshvUjJ&ps*hiLh5l!a z@74iwl4S2#GU>^uo39;gcxcSBUb*$N#brI+HhW%bToTS-D8eL@6nD5J{vnb8#-JjD zykGb>Ae(|GcIF_IaPW@8nO>|a;}iLZ*k=%7aw5XQdd16)bfq4+zro78jMpisA5KLr zaCo$HR7JGiq&KD@pa9(YV0}{9$ciLZ_$Q-?vkfDa{h{HVzrQ8}nwREAMPlVHn{EN| z>_9k-C9S$i^0NKtu$PijT)T0bJ)SQmAsf%m&Pg1QwEpq3g5Hm&czxRUR4h8Ap?ZKBH$JtGCswsg6);Ti8K@C9T~D((Q;zzB;b!xJTjvF=St z!6jn4rbKiHl^}--O>@wSOjNRVIdZ8CpbF4e3@RUrH5oPqS~W_AT%r{a1@d8rD_(Ku zS^DWaZh9f_%)7@(`Hh1_*XVurjeo9hJo(*o!l@JV(lIL>aJn4Cx&KPK?_GL(+MTx+ zHva3Kd7C7T1??PYk&p*=E)u$r2`C>1gY z&Ja5k4$O-U`6AJ(;K>!LXl+S*WVD5-5Uf{gblAHa; zX7^fEcI16i&<%reLR?l-ua8zAB)ty}`e*5c6Lbyc32tj~3p{nfT$;zKR>R}0R0gB- zIvQQ_=!XV4jkenc(4i)>8&uh>+0|i6qGDky^WWkUX zMTYB$P9PqWG8p6apz{arKB|J(6BuZLO^GBBi1WaGVfEc)n2JJjCKY>=OQY^~`~p>c zr8m%`FZ~Blo({Z{TZ(h=D)#iGnMqBBIW80xEJ4N+bF#nHo>5a`4hkwUn`5=H_DL17 zp<4B%3a#j8e=^UPaI2+$vcJJ-k$z3pso zx*R@lLd8NpVbNRsfQqav+ePQBn##v%@x0yMks19#?E>tQa-61cuGZ5{1GItK3TQM6 z0WHgFD;gCnF*-;Q;tA32(vpo@GFUrK%jar|Rf|kB);f=ojo5G8ZfRjxCmBax0P&(BdTt-;XWlIu2e@PCXdOAmF!EN_n*99+w(D z_yB3=A4zq^0G4+rDA1iecu4SsU>-eW^}(o<1W=bwJFY^dVwtKu-ZO49F_lB-GM-@kU| z7)g0L6MLEUv^oRX5)IB88VRuJNQ21|Y(b-8i&bYwp=fK@dM4}{8B+7_Rx;$-mFVEl zIvmB5dapY=(3JpB)O?ANdDVJV1o3)-!#G?^fBZ@BVk5qW?a; zap2gQ!&mhg{77p1VL*%p@@iQ)_1^e9-TiV3(dX1(ShT3YOqqO>YOTd;?2}aF%q6fS zhyLo}>ILdXwK7PdZZEWNr;l=?leonO6I?H#?WkW8fv-y&hOu_=70i&|yJ}PTJtIux zR;r+q$Sx@(!b0pf?ykI$*0<9mBSiYY*4fuL9s6d)$%9+R{@nX7jg7D(8>N zX_w!t&z0L3ch7xyV}E!5F+D1VRDM%-)f)1$_vherOf2#L^`> zH7C7#Sox#vidH>bHK1R7honB;i8ATeVyD2OsTJnJE%Ch8tg?1UzykP$U zev9`g=-UDMMC=hpU#iC{(>JPuk!E3}VK&t`uC1i~SE^L1P?;)nDJ(B8B{Qk8dO&SL z(VT}XI(1J>?cLq{Q(Ut;fv=@k$#%h%-_i83!_%$U9s7}~+~#e1WiJw1o@E;PTwnt< zO0$;8II|)a`kq3ewOK6Cj4h%ToujoaJz!-8Sz6y1LGmieMsW-WwHiiDgSKlpvR^R-V_FW-HBg?NrO9-nxw;UxWj zBQgH^0$EM0D<|AcN^4Gdeba=x-RmYSW@nq>nJvK1Oyt~0q9V+(5e*fwM}1#-LbWBa z$Sq-x3=JCK0lS6so44}H!nl>@l6fuA8%{DX{0el7p~JjlNF$YYs>pY{PMdd;_#;oe zQ(5)ItF=2SYR6U97xzrAD9P+RqqON1{oee;xeKK4>&}E5d5`^lQT3#8WgR<3wf`X@ z>E*Rw+ySjUV0$EhB{?{BZ_*3loZ6t~vCL|sbqHDVksY`0K;>`gjphb$lFQgz%$kOV>oG^6 zVOf+F)^uFJnwFj^Z*m5p^k0qW7A?1}?Hr!yx1G~cx(#{e`QMn#^M?CPX2a#M&8sC- z8T&m7@{)CBi-jgt=FtR2hDY*|T2q+zC{RS(1?!7Nty#+pVFvt&-jx77R%pX4b`9E* z0tgCd{|xls&-EnQ!@5Zb8LWvqQ(GD5ZgCYknIVk;4)V!knPid8H&c!+ju&KC3453S z`mKMhpuXMPW~f!=!(U#NMDOZy#~#`|^`-xLX6`Px!Z9~*;Nt!R#rk`nd`jPWsXR8R zOAlkzxZwp^HdA=GDf;z2dkH1EYkx)n>w9xbry1YQtQiacDLXIBUkG1Pk(9~g??H{% zec9^(A|k2{P+Zvd^W;bAwFB3qyD0F?QR;!;GdpoNt4-#%v)7VUH=cDG;NFsc&v=Pj zaUQP|;k%OTN|hOB0Fg%zn)V_=9gdq|m7rs82+8S++9>?RlnGAsgk*{l5+ay-6pH-8 zpWjqFGB?s6QMOTYT1jq@_4FM5er4DwHH{(v;`f}QUwVt74;1mo@0apTv&bSZlV8VS zAp+hF@!@!Q%M=;~noOvXy{^`)pt zo=|(S!2lL2qGg+2bcn-6f#C@bWfGIAL2_UB7SJ$wVjvfj;3Q^$S->-t^`EmUz?xXM zAj#(_j$eGc>G|OX2kDng4}{ZC!|RjlcXW9CZ%?28jP@H`8|Tg(T~yz8mE9B*$)~b-tgU*b0ov2S)z?*+{J#d8AC0`@fA8 zIMIGZ*C-pZl2essyteV1Cz34`%cZF=7QcDdw2009(dVGvH|GSxtwz-&)kStxOb_6p_EtLpD6QmG<& zsuC674(iPm-2xOwEDUBbT)A5nqN1!C27&kAl3m5K$5$k#bkx12dwOx#88c>j zlvmz~YZuosf7_14v_!@!=F*+Wmt&luqr@4Ql_Gb19wfbnZ&vl4#7R0yujhd=9A>zd z2syIz)dZz&7|t-NzM02JPY_8n5{7^*1dDnV1F)3&haX^#0odRGLkY{y)(I+spG2Qt z^b?QL=84y$B2?&u9khlh>3s%ENzRgWy{wkZtV|2NfM+#AQZK->^q8goo~%%Gn9^wR z-yTt-v4)pu5{xC9I70~_txG~Rp&Ftz1u26@R4CE)jOa$RG^~-99>NoXoVixnA4!%= zl*vaL3=Vuv+~j@AP2b*mmp>?UNv4ZXy_`a~bp`jjG@>&KDRuOYIPBE@H|akJ(zIzN zivpkzt#Z4hljm`ThyoOKjU8E$(UrW_^<$|2rmpBN+Z9bGx^}g5_D;|#k);x5Q3|5Q z2#Hi-v}#hJ8W}`=drqI|NM!wH6Mxfhw#CO}YX!2CF~5cnl~8O^Tg(dD{VEdURA^a+ zybQljEI!sHp`!ywbv=9(Or>Bp27`4Cx#59L0Qr3ku628}d zp7cny!3YfMD1|Y|Sz@$Al<18lTw#ne7>kX;+7hEt7aAImMvHnKfD!?++%hRFKEk*b zShl3EF_FcjJS*^Lc9|1<59~Tr4t_ZCvkZ;GkKD7r|JJ0fDL2m28ROO@t*J_AC>veS zV?jdQ;Ngqv#9{O1&g^|Or`P^B$-j=0k1BDd~+U^!5fKA_t9u;i?-sRyTslQs_nFh!!wEX4)CJSY*ZntXGEV zMeX_>dW?Qa_x_V4oxkecwdeh*qslh(hv^#>{nf8}yAs{!^JaQuasM>`{TbHQ3{U?s zrAi4%a8*)Li7GC!Bwa-!RYajj>_kvyMVF{jqe@f}5hW^1c!|nwE>UHMmZ)$XRXC0+ z97j}22L)lJg7ji|8xkMz>G}bg*~Qw&B!)G$vcpIAX^>| zIe&^=3XF*UaEkuS^c*&84VblHuA8Tw#2dgnl;9mo5UT{SN)Ri1(}BaMCz@8SA*+yn zh9UEd0I%S;d$<0RA1!l;WZINZz@;Rn(JE{csgOh9>&#*G?ohVP5LReY zVFg*9_9G-+by-Q@p@X+DMo#Y|YMMU?UKbxwHF(yeM~kR?5Wvw!RIn;X38hyE#NLp& zqEwa@ly>P_T4lZV?f31D(G!+ax{6U^?5}SgVJJ*kN8lnc%@OztJQ`an^%9(WAU_}$ ziNbK(xCB7_6QS1IG_35~TVGFml;nbG7m$lCIuacbZas~hgF9@EP`|~qE(Ka{kS9|R z)hdTbv?6h+h*pK7s9*(8f;0|7w1hY`M5`e|BGI531Q!hY{oDrvMRGI4K`!g8EdI`Z zW`M@X`)AbH;IC5U^-JlutM2PT69)XV8(EM<##@`p`3PEP3SkRPNA#A;M(=mH=jkq`bk22qFF$KGxVYsvIK#;${>9*kT z`wf1!aU}Fv7|)UpiC|_MStO>crF75Rm$wn&g||PZRh63uj~-IF@sSby`OEa>*RG%Y zgp|GfnSJFi|A((H0f@59|DWf5=VI<*P8bFT1{iLH0TD$R5s~525D^qn5e4u2icC#W z@xJoNGc`-sZOzQAZA&-pGIL$mZQIt|GAqlqwp`arUjCowd1nCIet$1;c;DywKHuki zJ>TbhY??iL#ob+#9|djQ0H@8woZaOxv-rSD^dQ(x4#T)(yb=Q?$UF(1#vO^9uy53a zna$gFZhqtHPT{{tCv5T8^qhWt>Gy3*9?$(_-se}(3BP+GE`f?+a7CRYPD;I)DjG|K ztdKCh(#k1e9;qcwwQ6-}c&NMyjnf@rU>ACl2#7r9#uABx(Cb2QEBd#XVq$T(3xH@B zI#hE=JU{4Ui|vp-^h>`Zto;j8;Tc{Z=1bExV(<2Po25FRk(ZN+~?9< zV7*RK%%BN_?<&q`#NOaH@8FG1@UBLLcY}c%Ka@0)L?liJXBx!_0AWXAcRZ>4>swdJ zh}Q;vVRJ7<(8m}AeGK86xcs+2+9rH|?B$KLo`3bK@)4D#PYm47q0G4y+9*`U0UPLl z!0u2zK68vCJX#&zR4a+bUrD@L?THh?VCO1^2V5Vph36nhHV6&MqsUQ=Fy2FY#=$7` z;_3t4)hQmbS5DnB`AK?(oKrKsc~bV&Pd1ZtVeLcae=$!Opww}`IEt3}lcuhlU%Wy1 z{>9e%qODc^$?Jn3EtU#fVt-TiXbG91&LCe0thJNO$B>3x2i%r{k6iVI5sIVKb%*M<))uZ*3-~VH^@bif)O*`+s@Rn$g zHH{g*etgqQ+~%U01O3HQ*Ojy{2-;(%gEoKj_D90YFYeoSaQ&+n5=Tyq@9}v?+=FQg zzgj$Utni=r$Bd5%SYjNq)W4UuVF#Tkri2J&cz~>tR&+G6TIFGAR0Nw#9`x7+$(gwY zs1}k^Ker(c44uPLO0Bd51agAqFf%*dcl?^tLBcn}cb9Jx`xI69XYQK%KlgCl47W`b z#&6s{Yxd@KlexpG3oAeV^wq;eIoY=)EotdX#{BZDixy8h(6(rL`N(;X`O)c@#oN$` z1p_P~$VpzU))}oj1?~7KnuCCkT7RNPhk6a8LnYvKBCS#hmoytjx7mgF-6Z?_bDy_& za4_YHO3%Ns9hQ9F?FZvAKJ{Ui1jg^>i|5ld`H02VL}>sgJMCj z^o#}ts`JtolL40j_If5}hn&fY<|NFC&U!SNxTp~;!bwJq@cx}QZz)NZ_VTB{+b;Yd z{P~+VhxHm%^a{Tjb3-cghp-DFSX-3OAcY-*&=7?J_MJj6ryjtdAfXGCqAwl9ze`NY z#D5M69iLQHe(^OHGqe3(-^q_|D&rlmTo$H7>3u)Bb}jTe&UHNc6F@#&X~kCPa|_H? z3+lCo!14&uYiKtrbmQ(OuP_y~shE6Eb&u$Cw0gaqM0i*DmMkqV`sNau{MF47G?k!o z&=7=eSCF52JX&@1H5}$nkUKTi{RU!nWr5WxFemy{FqJpc27J=+$( zkbrWnmC&h^FejyJR{exn6ucCtM=2zcs1;z)0fWdij3(Q@cvJXq3im^zaG&3M<_zAY zy{K;CU36PPH78W4K|NxiO@uKJVE52HEp9rwCn>{&o0E6 z;w2w*>rf(@!CHT5;p8Jb3pYJDT0W##R&mXA@yjnkAM*UT)!UuK!j%{2}6OOMJnz}nvCYmhh`cDK_R<%(*mwOeIIqnLOBCtSie^ zH2`7Yve5xon+doI03iLeUn3v5?d z6_EGTJjX9|5kip?k#Onfw1ANqAt8RxVY*x)9a%9ormzA zO9APNCK+#NTF`z8b8d|~ojTwI*V5jaIDJ&=Chi2x)|FYqVBMVu2QLB?A@CN5BI!gX zrAJ;)Nr*CVN@KE06j}6u7Hsdu9d3_`Z?Z?R*J9zn-?GI21tm7X1=G4*- zLo{AknAJuPWfC)DQEE*lG`*8+#?~sSzGKmEOd3hRc{qS!AG^+7*t)>MizfXm$jv32 ze*EVP^LjknckY^ohS||1QaF&zt&HSab(@yF@NVDpj`Y!^%Zhgr{h2KkzhQtP8+L0V zy=~M=q9KcUd!&7AZA7G11u>;iL8ApLo74NxfZ<5bcyemDF-Gcs&$sZ!#emW|6v z$?W6l*~gK3e&F5}^=lf_EV0SG0B6Tuz_|`^#^A=@fPz9cozuXZsRu@>V@P5KcA#b# z@B{VF0P!%-6FjHD6DtN90GO*xD~}uC>pf=blERkVb*aN_p3JPIapPNOo_}=hE1O7J z?ZB{CVn!`kRAbV=5|-a|=7l+L%{aVh@ejaRdVm^O{}>C0b0qSlm_!yuIRts=jXT^J zk3i4j6#8X&!->77G3g3|+kEf>QW|iX#r%=+*{Gnm262u6??~Yfta;zEF?$c> zwvP~JM1&;OAkYFhZOXAT&;>y)K=lXJ!hG}1^TMX{H}CK{{N4vRW>PO}K%aAR*?xFU ziKGo2m53kFSP&zTnn21{o5{pG%xXP#nXV;)#2_=2G5$%U3%_NJ3 zCSfVCascNvdItl~8*Y9qdKdwEy$tq-ETG`TvpGT0AS$w$lK~M^bg5i=-vu*Q&dK%0 z$L9~Ln(E`8|JUc|`Mvjr$37fse#1EKZ{*ScqA~eis`0s#QiuFFaHplwFRM^OEMH5s zT4^sDu;rIXE2y#IrP24J*u|VD8X0`J=fMF$q2T-4g(nyNo69ApWrCnL$j2?>PJaJA z|KNd?9NxWe(R(Pq%1Ls#ld}8rW6V2T>B|TK2X8>dBSVpv$hE3`1Fk<*M0O0-Z``5q z5$pWLDq>I>;3oFVDs+TFfFl|*iQ$48HG1Y~nDL{LNE|rBGu8%7L8nig*W{K#oOp%v z+kWEq@@|i?A)VBqNL>z@`QY2THAM`@`^T>z7k<1;Xa$e6z(PJC)WLW_cLQI%+-B1| zoPND6!jC&f>UK}4%2_vNVnvPo*mq+Vhsw>bR}Ap zy(L`!i1fL5v;FXI-)WgXVU0{D+z{U6?_X=*{@J;ii`yq*krWIKN7y9IEm~y740C0;JnXD7>Nlg^#$w@m=IG17nMHL1h6j&R^`D z2^6c5VkTsxU?wS@iI&zxV}%NZ5~LtrrgY5&uMcz%{mnB2e>SNT!< z^ZW#&00BNwVxGI)Vd;GNtJv2*zF3DO(&(3j8T?Zu1Q|Qh4F=MJLhd?s$r2lxVWC&`(J1=Sq<-|Y z+YoX1(z4joNu^HS5J5EQ?~kaUql;LuS_=im2si|(MnRL zBr+v+?)izV8+B1Y=#7^saB0xDSE~H9URYRv{iEwuWM$Q-+({bRz~2YuufrUTz_6Lk zVM81N4pM$zC2kwdzGBDM=$srAZDXt8ZCoEA(b2YMMmYH}eC68d+{u<)ZgWmcOHTVV zh;gptb<)OBdecCbp_a{Z8JUM(rZS1Pg6>cL` zlUT216B!|d1xDl>Fe2(epCo=>0{mst95cWZtvLJ9^%G>5hmzrgS5aD;?gIMi9K#6* z-6WNWt1uD}pRq!X*F=&NO}v25@nNUqU9yN|U%k*|jSiIxb3aU$E7Ka!eMk~h`IFrJ z2TJnUl*L64{>7U{d?qCF_uDBg()rw&578{BzQieXNB4=SD~!XK)29Mp$!>;MK9!I zr`t4|96HlnB<02u^GEMav}MZMHw*XV$52`A7S93fucp27;NOrh--B;9fNwPLsYUxt z8?>Yas!LU}#7yRxiQLS0G77tgHHe3O)>7;jF3k+?h{y%6LIr>eX;PyM6Qb@Es;bX zDX|)?E-R0Yp0aR*e~FvSaYH!CI)PyeDz9HAUGralavGREikRZ#kRsPXQb7o z@o^%eW)5}G1ayO&zkcWaJP`U1M~?~_&atxw6eh}+9r=T>oxi_bI6Y=a|GeOAH!vIR zk>K%JjmibeRVY{`k*F3ZRw+1z8kfN$Y0=53jX^0Ps4pQzTt;Y8dLwO19yz`(vA*is zhX_sg&zpGi+l|s&gCChGE;->}la85jjY&;l+VjftrLjEW7> zWtL--Zdy|zY~AysYUMvyX-W%*)Y~9_+NTR^_N?le#4T-Kni-qdf7~n%SMzYta3|%| z#$cTqjP$H#(aHSwfJ*%3S&eFCYDAjok&Q<5@R*yQEyK$0{vE76A{Be~*SVYEV2dN$uBoRDO*+1oboACQB(L-cET#FWNx7)Y_pY7~8bY z@OTg{^m#A<6pKLNX@CQtOb(BQoL&#_G9~ z&HZ}K7_+HWCe5{!_1-ve=A_V6K}se_`Qm~&_Yhh=|4XdlHLM{5d{^VsN0gcjntg`f zVHH*C@{f z)TIX1_AnBrC<{e9B5Gu!pad(_E}k8s-@E1Y2cWT-$*FPkMm;lrRWG?`|DoL>($T5u zBeS#8{ZqNa+n!i)cgyU?2lvO%K00R4xXk>&KfVw)B`89cjd-PGNl!_>WR|Zi(bGpC z{YLbq=`g-TT!#=(bD$mSFx zOOcjt_dM(2JgOx45|Kom3Fcv@3JL*@9tBy?j4^5?&BV9B^ur+$;&HTFNJLMs7kMl3 zASf0R!L|bb?}~>=Ep2qET2=C1?0(~Y@dab zVeQeOy#`!ewh&Zu8xks7eg`KMH-#azLSJN7Z%1OTq6`Iuf0atCEI}U<3rS$zn`T0O zk@Mr{j6K+pTNx*ps(N4kVxLBuG)bFLnUj?^XhtRornU9{y3Bl4W-&4R{MLA{?`X~O zA-x9tWkp_Jz;X)|yB8FzL=0%*$!oYQM~%>b_+qVoUTyS0PAMYFKHG7q_&1 zebvpC6lB&7dsLP^ZODM${o7~m-LUqXrPCXit<~xBODyqw`vB4lfOK&H(sEyBRD{%; z66SwkCA>A(=C_8L{CllLW=&W7t;s6C)f3`JoRh>bczeXNfYud4rG%HYZxZDmm3^I^ zd&HX`6ZM-i%4NaEBE8B%u;k-DlT49Ki+;ZuATL?i_W9r3+@ONox{E;HFhenU7pSshRKc=VH=h8BDA;LCXM zWxQAIk55zi;}b*t@$uS?uKg}Se-T|6<+z^dfYGw}!8 z5Sq&vQM_HGk}l|?%E=aQ6zE|B94LA>xTl&P8QZT<<(wWfp56G&^f|ry9NBebhR@s3 zFK=++z&a@s&OFKSVaIZ&jjo+!mRlc5o3Cp;UwHLc)RRbR3}%ef*V7LsB1ka z{6bem1uH}`sQm-O6X~+0Xf_A z#?@^~m&Yzxv@-ix-^NOK13Afuq@KSI*dyQ%O!qnT5ytK4>}@X#Q9F%;C#dJCx#84l zQZ6Z_hOOB2i@8piU4zpGJVne;Lt9P-+<>sEY+j^*cM5SUU$g(Y*pmm#=H<0Qt!{5=!I_~a{NO{B7v11K&m+Q5K{Uc^}_4Ca>HJ>R_ybufGmo7#LUL6z@4ouwA5HJ zixvV$;CDVwl2qV}lomWscELm;VV++FHl1@1%u0@{51XPY1sH{YerB&uK7LbUqhYFZ zEvYv>r=Lq6bOV3_*ZxB*?J;(ndyYQ_?X1G>6Kd30%9J|F$jlt=%I(fEqd+8cDPv0R zH19}cu_{cel%_J&>4tNDVK)VG6@||UE2_D588G#{b51Ng#5Uo^xApwWRK`E zNp^ATn$6#~X6!fEUSD4@Aj*C;2XlQd&1UN`pb8hSR_G|}(yFq!0H*mEbUaqx(#ju` zUr{y|j4@oX{`CljJS(GbLfeYw*Z#p^ruaB4&BncQxKGdL z#`yFE#ZbcTy1BUgI@6V~D~DST%CCg*l`YM${N+Gf4^-D&3LG!QUZ2KZQ_W5*&XnrQ z)u9oJ!4`%Fv7iziG$`U>=`t$E4%@nG^=nPgVI_^?M5WI$Q|bH$Q!T^(Y{cPdAs>p)XCllm!r;DDq&|v zx-jbMq)-H9bD-TXjktqYCg1h&l}wx1pd8X{UO8%|`@H*ng`6K^-xF6;XX-=dPslxV zc#qI#)qClTpF#qE2+6=Yw&~@@!P*KHl?Z_z*s5>{FnS9oFbNyqMk8I|B9kDg(^f(6DODOZW}@Cl z@H9R1;VWDp*`2p-+3c=Vyo6KSBIm&v&#VAvhHTtBcT#TQYCiq)7*%OOQ$*397(1^Y zJrR)}SQTt&*)q%;C&3L!Ohqgzc}H2)r4FM}!aP)TLYmVn$`Tl90SXb1b5!j;^c^*r z_^O>w`Gn158;o_AM{A0F6CH(ArW8z!5OFYpJ4|IsmY=-J@UU++86f1P#aBJELPUrN z*Gc{?;6m#2OHyU2I^aveW+K@Z=Q?`PXCqhiPUEG|gu2h_FGflE)`VeEWY>fHyi%Ba z0BiGt?rq@JXz;2QCD*N{h%(+}5~YENN#@QKFLo4kW$a=nc&|f+0~1F`WDn1DruC2~ zR}_x#Q8u@<*b|+ap3pn4N5Tu6rmbq=cY7R`=fm;_6y=6JZ;6iU|Acq#Z9lYI2tdc<> zEf`SH(l`iE521L(VjP78o`C7(p+cRq6w)+AIYXl*nJb$6aO2J;bB0Z*-P`OPnOAY; zU(qMl=N6e37zf1<8L=+fomf)imET)B`_a{*hIwNej|{a&3CpB2cdkENRo#BoWS=;E z@pGeUdZ4R? zQ|~uF6PC7+`cp?aK{#Bn)B6}%(O&QoDE>oO=5k<$o=Fi`h4u*Q7+fPcZG*R~pM`@( zDFY4yR%GX8b6`_MM=cC;gquV35 z*j7|uJYsr|ENA$P*{#WO+lmuXEYY#KPyF@|*S9R%bV2C1ylG-~E$+d?igg8 z9Wo9b2g9^lVjCQ3EK@4Vs4}A(h4Cbal2z%Thh5BV!-g=jktle4%Z~Nr?4T9f<}Y9I z$jIihsP&I6-XQ$^_rj*hkM;M3k$N)3^qb{vUrd?*$aCY?hm+>@t^3wq6TVdmr^wyV zb8FFl4JQK9ERABi6;-zsQkz+7wx|u|vQmdAZ~;i?Ehd zxk@$+t1*Or{Dm+lQxO*xk<_=Orp6c{{P$CGDpui)2oH<%$u5kYwiwk{Zwr4+k5L`6 zjhk{-n87uDnVk}Hz=55UcZ?w?_@|hagjh(;bj4z7B5{>u2=F4-o3;gO%CYVF2nN#e z0eKVh`Zw?Al`nVNM;M7)$jt|3p)YEsRy9P1;=GWlzuFfyJ1IOh%2V-JSjm;c`}K+m z+z#$>}NMR9ua@02>h($ zFM^sM&L6~kH#>&oXS6qx_K{#UAFp8Hv$@&$=@%UX9=uFPl~&SG;XA*8jAbd{H-L(x zd`1~>)D5)_4k40|86jK$%OW!##yFhN~acP&U z{>dq;pA@d-`NKSMg_%RLNXa$fW_9j@8{8M$c9k8JO`Y{}-@50@meG6I{(=QP5uX5T zUv&%vY!q@^5b}<(LKMG%{q$Bxtq8d+06C2Tk_(6iOOkjci+p8To72XrrMAq>wB$5L zLv4NVbxTy0{g#B4D9B9Mrd zBFJS)GBkFO1rgE|tU$ydjXA(|BuzJG^}HSmH&TcUB#rKNkcD{m$Z4G?Cf&H`i`T?x zq`f1iIG2(zZR7F-XM_{N1ur*&Mh=d8W%`$+ALSZrcZH?xI@Uc-X>}VnDW~k2wZFe$ zG1JJw8)*qoKFL47fA-j+qZw`AmLjtdXO*6kHNLtkOQU6ug&$~vzd7F0)50szBG{o) zIqde4%E`(WC10W>Vah~hu99Zhs+Bq#Kbh{}HMHeRx{k*kxXz(7MsaS5J84v{TMx}@ zkz{lQTm?eka*Zs12NuXPtYZ7oRd))D=arT8 zAMj|Y`QQfhK%2DbfOO!~Ayc%yKt@sB@tXC~5J{yldWaD|9M)G0Ni z;y|usrEf%nr7E&9a!w>aFp^j!<0E@U@(MUwOtCK4NaJK)6fN8c-xJk3}G=(%?=`LVElF7twG1-<_3SxPeYUhVs;#VAK55&YAku!W*)+W3hez+tDz969?a||~YC7T|Ej~u| zmn_K=-%yJu)-$elPSWzEtx5d&B+@gfD5*M$_au=dolerj(1Q!&{8lhYQ98G z!qkcCTv{|3$7Q)1CYmi)?{JN(bvjT12WSeE>k$KMsF?^HQRBgz9&Wf;kHYw@(Ucg1 z!HdT)7*pL4>@3N8Bz~Mz8sqP=J93C zLk9YCi!_>#Gyaipw*_%EwOlZVeQy~u0!;=eJzd^ZRrUJsGX5Dgq<_Dg!WHEd5SJhq z)}i|UeB|X_g*-|D-}RGB@!2f4@F;0as3)eOHa)dhj?|+G)il(`oko|Oc)ht;9~TwJ z#f64?!f0)3POtZPq7(F7a&nkC+LD!*2j>|SNmn^aiVrkO#TVpwP)f3~q!Sx+dUQIj z6$)A;k(1#LHr|7O(s=qWM0O~wPVg9tFpHjgxlG1XyPPjW;9AkCW<;(?tkUf4e33romma`sA-)6nopYx{DNXm9Y%md^fs#vB?N zw^BK1nD9&}s!rt_X zCKHY7bwQFh`f}}%HVEW)AYDtLx9A&cB~pVFnn)^*j?jhhM>iO7Y{>D7j{Hz8U09XqTM4cNXW45 zNZvfBSh!NL`#=K_5#J+p$AGUGCO%lbUERL2V$&m$@+obcQ{B7Qj$L}RM4X+PDtO6l zWp+Q3VIapYeg5n&_pnTJ5Az1E34LIN(}4`=Bt*E+_m#!#U9KuaqhXGLA7~&}L%gA< zfmh(}-#XGc+1cXcOPnOkndr=Qf^(eU9H%=p)NRG@aEB@ZXvk!7&dFdPPz;R@3NDyp zgGt~3ABm#a%eu@^J3Nqy2wZe=39_fV7>ZDm={oOHJ)gSyNZXwaRL026;bsRIC2HsF z2#ZCylGw#ng!{r6vbuN4!g3~$rL#Xg`-ZUZQc3Ng_47ieZhl(c^d@5`>1#*dxckI^ z=QDxKBuphjUXFqqVkJ|3gIxNsusN#bs;w%1yo&Tx6{)IKya(|@5(5b_IDI2+lWi?F zzQjhtY>Bp9lqlBQfFGL^*Hu7HD1Zx5qEOY8DdNM%W8K{`L0PC% zSuy6}OZvnWq~^@}O?;?RR6pUiLU2i_t=PRiYS&zodD0ga^(N_TweX4I`MvU~TldR^ z*U16-)GbfT$lXhyQyE%>6_!co!<#?FS7b8H;g)k-Iet7xdU8cvHOG4piX}mKONiAs z(lFW3V&F>*B+QU#$TeVn2CUCumC=?t5fRaiv>2Y2g{QGSx6^L3zqUdcZ`fi+_b@{q zS{bgj0uoa}PCLx8UNcn_mWTnuA_gd%XG|H^p?kk)7mveD< zEr+qT%ZNw3kKId?RQggS8oL{Ji7tl=WiqS@X(O#fYb8}_giAvS4QrY;jdwZ>e8{+N z^$cNWf@ZNr_$9{ac8jj0?n=>-3PPk!L10L9wKB)%;oM}i+SoD?qW0q_llKkWb707X ze%mr4hbL{%TCcoz@!bRC*3Qc<^3{yYO6(K1BWn$r`P#dY?)xM9_e$zpZJctWx1-0= z-;e&V3RNciq{2~=`xo2v0;rbrg}%56~*QP6xb%VW02@Z)1h&zPc^>KNV= zLt^xLiHC%EOtG;ewUf0iTE0XJ+b&U?tHtJNv3XjPNfz!4i_oLsC=wJ{P#=rZL?!Wu zRNnt+ytpnmP&XFMfzCsZCKMN8Jj^U~a5mR}?DSpR)@h={O@S>mdv-X_E&pQ%abyZ# z^b2)?fQxQAEuq)lpJqS4JhR_6Mx}q)Qg!>zP2r|;s_?#|Dy)RA9brNIyNF11NuI*} zlL6XlRP7A=68lCwZ>QR<28_QrWJAcl5I)3*@9iP>kU5s+maP_kyoL0%6j`b*ya#5d zJ|Ze&dITR5;TtKNENhYRB{Jj?C(3eVK#mN^k*U=Lx)6DNDEmM_*CJIjmr;;!sUbkg zgAxh~t%{Ofj4t*tmm<1Q!nUMgzqT%t$Myg12RGd$Qm@VFZ{1!%$e_NvgxOy1PO@-Q zZ|K`Qd`HUu6$AQhBrl&N^;~Ly;&s1q>mA_;=k2%mN$2mVrlOS?X)VeqMCGHtlNpvv zl)-Fv$Q&NXUZi&5E(4uXQAt`os#Yn3FlLs_IY1uZPMjy;_JYTQA|L&mK8WXms{`>Z??aTkO zbBmdb6I5P)Z>r#Fd~C9iyl`h#efj)?VO7HS!UunUb=$WaH8aM4c;=p`B9>k%E-(~@F|!|5l^;L34^M@Bj%Dp^=~P8i?IVz66K zsK?|((5|c(D1fKT?frl*0L;zO5^x<33l9IszwkWKA7ODcD~UNeJSYkPM^M1cOPQJ= zY!P*}J5NW{Y7y-=`W=dlQa&G?wejQI(VE%a7ba*XCbTc(*1=f2aZ$+N zRqa=)EcgzL(1N{FOHzE{yh5pffu>9{`ju{jU#ZvnX>=f}JHU%V_Y7XYK)^IL#l=Mb zXmWjb@>8%W8+Rt}tS715-nU^Qe)u*yL&v|!7Dt%h5@PjR0G0({sV(%! z7L`qpq*AR!r9zEpe_rWP32lw6l9{Ct?2VVWoyrxz(Msm)c|e_@>Pl(gin;@R<}fuojJ-?#rE z{JW%f-zwo4|0dRY^o<8oT4y^_hm7I&&z%xxhuy{My2#>ycf=b?2KW-fLgflMOl`FS zi&S8ddPS6iLwOJ*Egc}yB2nCe^#vl*p|#=VeW=8P=o1n500FUdA2=zRQLwepR4nDT z$;m!`OmQaC{$vSPp)1)u9U zU!FZQGy?i)Tx~2-p^d6mu2wbFMq1R^CN;K6jcrn61!}rYYWicf3`vtRNbX=XJ%#;$ z_k>a{yQ3foppd#z`i#;OC8}t|H7TOeXA$x6IHA*slxWx;GUW*EZ-qPizd&p3hU7UF zD}Tt~qB94yB$AJegEPpzj0e?;JKNpOyCT~k%p)JJyt(+>_cGt!Qhf7M{lei-jQaHE z_<2H~)pM-V7h;vD#F)r@I4)?K44*^eH1WtAM(typK`+r+LJ~&RhFB%2031lwXL5uo zOLiO-kH$GU3en|)0O3yg!O^S9haD_^M&>2wjJAhmiH?>MlG-mZSy{2PZ1a)2A^kmD zv?U8Fm>G{K+^eSfv!w?&$j!n(Pt9#8{@d%jg}+V|F21x!R{g|}P%`kV9H)L2!2c6u zrd!fOlH-FZt`5^#EI6T947yn4gIYsiKZU?Ne`p1C6->TEK*C@Ru7U-zfH9Dj4og+^ ziqP(oSV(6|F7;b;XY2A(vq#&VRn)&RYRi!gU$3j2pN-USQyEHf-ke&72D%?Gw?|=% zUtG*GxHzc)WBl7CBO;~^BNKkQAnbl=4|i(u1FUA_?K#IGlY(B4REgi`iGj}}HYP@r z?o4i|b*A}LsDd`GRuiT-fFVK+%#p!SPX?=V9?TJvuoAriD}a^`?{Z)Kiq8TY22(c> zG7zok^jp0DE6$3QoTSpTr4>u>S#OUM1b5J5!JqH$t7u;)EPiPZ-M{A#!Ciqpa-d#2 zt&x%{>4T`iM1=-BqEMLoa)yRluCFg8DlsN8dsJD_sj36&@=Hx-8-6ubYpI-2Ynh zvR;wO;`Kw<99Z{t+lZw;rLenjPDM%nphbhqQ0ZWA=L(DN+=xmf^6Js=jjb>H>l^1t z!}|kAw;PuHuxQAbOuYs zxK~g{&g`Xi?xu5Jr(Ywsbn=4(M+tSG+%^u^5yGX@F-pAOJ%*qom6`Vfw4fy;Mzsq?AgTbT?8X>$fM2 zp+-qV-L_;HB}jq|+1%+(5*h*vm@ir(U%Z2iOKOgM{yvgu>v5PC_i!rK6e~&f*(0LD zqENpw$`Gy(L)z4@pf2F4{$C7sgPy`Hu23rJj?{=<)OhNG6V4x7Hxxev*|WR+lLO}k zTIr5T@t(d&71R{`?r9Nvha*xBXR*WtIc~B_AlJKF3apA0_4Cn!9L!BaWp<}LPy|hc zUw6(hky`>Wd0bZ1l2FY^bYjh!hzjx z(V0+lwVQiIq!ntMGue&0%<=Rv)}2Zysdjgx%=ukhpY9lT?gjw_y(cgK1|N70**T$ok3vaZXO zkiT`z@0zcl+6^vu!;8L>)vovY9NJL8tPPJ>;@qQ*_l4u&8}4AnUP#b7t_X1xj6HK8Unh`CEBiT8s@VHWjrC$Z8( zL{Na_n|T;+qMo!pL`<5R5-z|(HbO=~XLCFuNM zFhN2ab$X2@#QbXl+WSiZ4Nx#S3J4c1st`kn0hZW9c8tgZOdWQk zw9eFL>>1f08eGoy8*VON^g*=0M_#Vz)DI`Qv$x)9A1Z8yQV3X6$3XRNNd~p1Z2AzZ zIy4m4RH#7>Yf5cZgpI33i6Gci-R!|%T2nN@0QPGj048WkA!(I|?ZhtHA6CUu$%2it z*h-yp#VcEmZ2Wrd*mWLd?pJS2FOv^R$r{xD?7$@z<@qqA1_+5yOtYpuv+0?uXWk-B z=c|Tnz-I1s8H-F;9o(rEH#ZF$1w*Q)2DiP`F2qWZxr+8~Y-MKI7H~qcBp2sB)W;rG z8||Qmlz}8_BuXU;@F@)v6yOV#`(z=1|WM;|&sA60b#C*`q03xUH@1l~Fol(_U>%B5aMmMRUtb`(u@U^XOAc z=<-TN%vw!qDA)Y-RS#FO>8q$Uk7Z?TdZNDUhb2G4kxqj70f zP8BYxRq$LTBy24q~@kHE5Znq7|}4OPg*q^Betg^=#w8wk%abj@THs z`!oxg)&B8_Ni1E_gH~FHjs`(rT05t(df<`r;(z|_?B&N+y^j7K_Zq7l!Od5VKK?4< zjvr6uj`t}{%Sw&;xO)A{rd4suUPn)!F)R*le_9H8t!C5QE8t|WkSKFt&PSR!RGNeK#8)(=?7{V^XQ1urzoDwAT8l6&mEF>7a!veL_ z5+0%fO8w<#aHb7vQC>S{`$|@L!j`&`YglO@#F6w!G z!A5nx_etNd)ny|e>HBD1@xF;-$+46)yMoFK3Rg-RIUSp@?32gGjCH5qi%UkWGU4!R z^0^|{P%WAa__87G-4d727>+g@;Z{8ic0Ku}=IVltay1J_3)npHy>!yFcfm$gWk$~) zh1yr+UfCj=JE!6gEe~TCu=m^yW`jdORQtm_;^b^61a^r66?ZW}5MrMp-Ki}vE`&2|(X3Y;IXt5dM60jxoB zUb^wj?okW4y7t-Za6>M2Z7#*y^MI08R*aMQe9?NHMQ3TKl`D0+@K6zjW@Bim5w?I{ z0wXv`Y2B<4JG$Zq%#q-Zi`6LIqT5_1{e`SJ1-y=a`Yg$qv-xlwsS`Y2eqpk(lDLI` z2!AV@A_|EBdS9*H(ktWW{abI{&-&rLH#IE*+#irlle33q(R?Y{`Rz}vxW8)VIG#gT_2}OY z&B(v9ltvlSjJg`kYDb?`M7EdNP?nemQ6Rc7xN)HGZh0*rFN>T!ShIEfYYP`O=EoPM z)y~WBm0jDTnLE67<)+&!v-TM6e_T~Cz!ip&cF4Ik+$6pjGek-fB+))Y6mQbuB2VLx zgq67s8cg?II zjcYYz(y*9wcsLO%Vxy6|hOR^d8%m3K6dqGh<-n5SstrYzqXr)Kw&o`P{oMAwBM(kk zkS~{|L>=f`QP`N7T{^CpywKoTnw&jiqQCUTiNa69rJWmRzusJ3G%KpEseQ=7nVAFj z&B@7!eHh3RLRFT((5fsQ0;%DPUR$60ewk)vl7Q-MJDlD=@Ng8O& zg34pW6CJxl>Ac#eej40BaPuEY@H&$FYd6fcEY?M=e6+r}w>L4Nhf=xSy?t9YsWCjK z%k9VQpOBmP#AEK=w%)19``Y^p0)^!^-03yAH#1AZd}?Dzhz?QhrD9e{erH6xI63CV z8mBLBEKN;~sdEgO5;?j5q9u%rK7fZYPmH zAZA5iQ1PyeN@3twVJ5dS`jt#+9;=;pX)40H?YrWJkF=JOc7e;yz$lZjzPEuz*11+K zmxolyBpl5~fK*_V9;h;b%at55rrAnfu`R8iU={}1mdea|6DH&dzTBp!+-@V8B&EJ| zlTK$u@mUoI{BZGhKL`A9zz;|9!=-Z^hnzx=lN&2&eG57tTxis((}kr#(I{XCSD4Z0 zXRL55Yz&OJ$x#y{MNpz9J14nCaQL6vHc@~!wH;;<@g2KK4L3r56OO_#Xw@`y?$OrO z*ol3*X)!{imdHv~k&y}>=`F>`{>sOl6JTHoU^M2PS{wl?rM?5PU4Xbjs1hk!)s0Wg zc070aaI<}4%&JLM4dkPOKFtV$7B2PHheRj!u#)fU8hGV{`%@N89WH%6FRvS&r_dx z%<{A@EkVj^dZ7jahrWuazhQWpl+@Xu{sVyiBx#UU zLe{5A5Z#|t%B8?3UNPT9OuF*$*w{d>8Zb)pME^HgtqaqNc7FHn`Avyc?LW0HVuIsd zT5Q#>^}-qQCcfFZQ8>eM>!_zfa+5U57GaeM66C|gm7^9AZ4_4;X*P38nk+>rperAS zZaeN9yEa11d8Zze&hOkfK1&np7nav6kiRy1jK1y?&9G~VD4<_`P0qqgcRui{5zI5U zs(AN;@qK(K_2NtRRP9?u^4T|g*D#Tjy94m4NCUGASk{%D$Q@NGASE#r$55O~aYYLIz!Zbd-C6w6kAJ`7!1Y&G?GajfRau1}xLzwK<`SiJ%Rhx5 z4zBo&m=6ib!%I!N`~q_IfO$PajwH89mGo8leN?^*N2Ca>E#sgVn+-YT%5tj%ZH0pL zEK)V57qf~epRr!AAQ{>T)}-TP{ZPdj@vs{yo$Y&h`aKl3lN-^+H1}l)GQarT?1Fp9K z2U>C7`9ECI-0fp~du3R?G4WXghL2VDpE|pzKcReh|2=Eh%^cWN5z{lH_wZ8w=#q`{ z**dRgTWC#Xyp#0ur6q)?q^6JR|LBr}?R{J^&g6*HCcxiu6%zF*EGrAG(50@Ev2-n# z2^DamJtSIta(xFRMaLC|o^vj17?9>l0K>iGm49zJq_2F?uzH^5X-!HJe-yzXL~;Q# z|E7Edvewdk;nv9Qk zQ8R)n`uw4J_GzQ?6Jz4aOa^7s7=Gx4(3K-rME^17%?c@0zwpIl(@dK*RW-v$nmuGi zW1jC57|(2QO0-&Qs19md2eqw3H2@u|0qCH)bvn*a zsu&z5GG!o`g+^^afZ~sMk08e2i+dNa_?XqlibG>-`K85sbjsX00~^Qanxe+{z3lrs z|5E;>D8ZRg74@lJDiw~euPUBDA#-pWNfc0^N%*ksRDDhFgeu_iOTb$Pcv+24Sy)&I z3O?IPC3;HrjN$|jX62W9v?HjSKWBI z$MZI3T+*WlIV@DWJbAhG^&iNb(J&w;jEatX^)$;MM&&==jWyA#s}fnMva22))yk-h z>gMCKv$@oG%f;(t-#_awL`kJz&hiKoPGKEwsE9HHrsorAI zRm|exCu2quWsS~3yQw3{)L;=+Ud}D^y5f`k)eRw5q3xl`vVktIW|L|7Bl@1>1M>2Se#>{aler>8f9vwGNe>4douEwNN!%_ib!sFWD}Sd{SL%r z+7Cc-?1)H#qbEid_eT%4a4E77JTFTOqlB14%Pqtx$lbDfn^ourUD2>1l|2dvKlfzD z;<&6qDCU-tY`+}eJh1astuD*|GnoaN8GH@ zgC5xet#c1_dR6`tY)uPz&+qFIsz*tlo_2p&s@4BKm1AzRe{C3%)`byySWmS-EJKB# zh4@jfRxwByU>Bw!X>EBHBRMnZeqh%wH1M8=Lb<`B%o`7C=cKJ|i_dLc);jN=tQDu>Y9_Y_`@EI+SE$g{Dr-9>8xV{vwD+Gmzp;m`m(q*JH2aOu0z%S zT*vK>qqr$bLGM9(xKR@otKbqBD%un~6?~#1$|yDA66JKqnNvnr@k~$;zV#VG(1}oD zPg!BI+I^bPVms~>yuo7_gt#pitG&FQNn%;8CB_C?YFb(OcDbjErSYHSM zVJTv?%~+trSd5N&X1p{}7L4Zww+&n{b4LFBrLW2oQsb&-Y;V>j%CgZ|?C_3WIWdVb zZ(`QD((~ko9I5(|t_$0mzjL)`zV7CsS9$`-dCz+EKi zXvEuB*xRVI$W6y7s#;10p&%v-00TVsE{TrIu|<;$t!tr=nY@bGFmMJ`#xs1eA|3|ncySo=JvzbqlE1ho>QcMV$j)|A> zT(`GT4%QP#=e~BY8acydvfS1KdnH7;COyVYlHCWV4Dcllk_|^K8F?|f6k_=(q|5mg zwF<5mZRbWuEaIzqE{C2FB{bzsgiK7PfsYB)ZNdWM0H#j3RQ)xHAQ{!Sq{j{%Sk#KY zfc4?oisdz!LN`-XRqURoF=SjrLB^oD4|}32sFsXbD2g2JSaLd;^?`vr#aFY z7Zc?zH=Cat(WdKLpxmyhuNh1BH%y^;zArsZishA5SDsYJ&cNDD&kTQ`R@jL5WQ$CV z7HK5o@1qx-wWV&HTP!_|(`#hYMCYL1DX=ZM_B(**UdQwBN;oBvKCLb!L>l3=siji8 z4N!T#>0ZMJfQ$BmK*G7g4VPlJm*%DAc;hfM{Rk7`!+SBqENen*91|1z*;8B-+jUnP z(| zj3Jd0<%@ixEMAhF4PRRvItU<37EcTeJaGj+H|2|5vN7;Pwooa(fj)a|42gnklzz|p z?V;je*PHBfcnzr#rTs zjErQ^7%BZ^2~Az^({fN9+u}bTr!8 zq(Gs;Gt^0eXSf@{q6(gJv7ezZsU|df{Ej#2gm8S3&?k~ zonr6+@;@-hiH$;z^EI+pL7tc~2~Q$|AqW+o{6Sn}Dt$6FH6$eXq(Z2DXv|9C{U4tI z-iYgT$HtQ`SJ#*hJlTEBO5vaEN$!8f%m(%DRxA?n#;6xztH5-HBub=CS0{Di$#L>z z5l;5x^LSEDD!!t0&iCx3QDATfqjPG6Q>l=_Mk1!bNMfX~Vgp9ykQR(V67Ug| z8?;aFRJnlvCb1{VB_E4pL=>S)$y0Jt{x8ODJ-R_5JH((!4nT219KjMC z0WwQEl|4}!cw&+GggXcYWRvU=+e3^&xk`qw*fA=brZPUon~dAu6}b%@en?SGU#BCY z_sUs}NNF&VO-gs0&bmQSgJL zIIl3M>v_6&9Z5e&Mm8-Z$ z;KzvmYaEdzkOYdPQQ6s|%!V0U$9U`qI;wINxddEmUc#d;k;www3XD_UNn_ZY2X7YD zK;)ra{!XzQPgDe+xG2(^ouQj@eCIA>47SUNo(SwRBA3NC*)D$+!1mJtY_mC`fgWM< z5oP_m$w$=q@1{+t2I?FOI4Z{uQLRM`hHmem6?3_4G;Pg$AjON^*sn@plhKmxH+pB5ic) zTkxX%D#PTEz!Q_i^>;}Tp;CeV;6Mk)V6^dOkTz(PH$KOk?DIR~9$-XqPPmG(_Q7b# z#ON{nA*sXWd?fG$-7Vl;q-t>=<>H(egN=f67x4T(Honx_gWa2w^nra%<@pgOncd~`1hvq5mST17TK{4-ebjl7%7&Kb< z(MyHT#3ut1q3cO1=XWrPkV&x-Qq123zAQK~p%bei)s@;KRhk+Q3ls-bgYRTg0U7M< zc^z;;HMnR{Qkfu*nFBnDV;1ojF=oU`DbE!YV09?4s412dkODR?5Ry&bq9ad~-^5$u z$VD71E65wX3v_nK9jM#EIQTEaAQnjOghcky$E4pef&|z3B$xEsLe<@A*>S)=-Fe8`!ELM1ei_GgH(Q@dI8|WoAmQ82`D|rtOoi# zYxeP%t-5#mYti-569{)Kiy@N^dhj8BF$KH+}BCl*VWEb~KV zc0xzrX@5uLtzXD`X4eJyF%gtf&9K!ofD7@IK^XB<`m`Z4em}!jb>N9swkDDigf$V^ zs+L^S@&hg$gSe9vGuia!;atnZ#^~L8$>|=uqkN9H6_*=n*3^OhRAa^LoI7ss-Zv?DJgq zc@Jp)&gUs52)`34L8631Er=FFp6K2VtVr!)>uwct}9SvaIM;L=A5Y4}CzGgEnv}#&{p?h=Txfb|%+ii>aiy?dx4?ew8nZXB*L}>=4qki` z4uvg2Ps0DB?M(oqs;>X>ci%R9W=$p=NhU)wgb)H5l3~xVhdo3Z39^KMEC~>hHAW1G zh^UAGB?yQV6)B=pgb>i;0*I)Hlv1Qf)vC2BRcc$cki7gq_r5nvg4*xz`~Up{GxKKN zdFP&c?%D2kF2lJV-fAoJR*Wa`Rljwa+qGv(_uunyO zj{RQEen*MAFPM(?W+jg0H>f2tcSvc1uFH)~Uni;%cX-uYQ>vRs*DU6FfbH{&s2EFB9x9M|^ zZZ-U*MT;tjqZauA`8sH378%y(R#;>k&O9fc%^r_tlOu9<0FbI&6>~dLOWJ~3HxZJe za-YIb?#rZjr3#^`3}lQ(YCGgLfM8w(qu5_yW)=~HI-mm_M(iegosL5R{N2u zcqls`qs;JwQVnu%da+iaLyW7s%ogL+b?A_sDyGgU(PHnu9OJG!H-plQ6Y#{)Lwj0dKXREQRPSLu-3)M z;K|!WH81E*5bwA4RUwiz2yPy%z~j=poR8~BP*HI88Rezc2ISfl_zWSGCG`HApbjX9 zG^orl)XlhdhjDqsP&eaxDU2%ug=kBfB;Q5p;$TBS*R#qat=p(J3A}B9Ht2wE5ai-! z*n>X{>w|>kG8wu@lOe4q8y>B05Ai-RG8u}*tSSVRA&LVs^cUJPJW)|lirPaQ(5!Ey zzegd;d*nsYYlLK+K``rQB`{6OsYq4#B`1 z%Bxj8fawL6R};WPm5BVJPHQfDNYley`S6wQ5Ur z2x)VBi1+DYH|n30+d@!2Qyge3jn66y+Eyx#2*d#mA}OS245FU3go0CZaC^hk>uQ(b|`h5RF=j7ortg3?2AM8g~i z!>D1K1|tlQ!n0fX$4}vD1M^ZCrY)W=Oj1;Oo>l&=;fc%$fga)BD42uF+Zs&7N-co@ zsAqD}h5AWmKgKct(8hjGc}fq<0PKf! zT*Ebx;rbbQY6lgOr-=Qy3%D*adFsNm-aCBAi>eQ~Nk(plJ@~V*)c=pC@}!QsAr3)= zM&qtfT+AY~Xo&X-3<8Bn4at;>16GIOfL&^#5+!ITsI;_)IG{m9B6tc>OXW$!vD^Do zIA%scyrji45gZGU<+upv2>39Phv+^^2KeNVf4Ki9n2-$cz7P!hjk;AT9`a=y84&nx z;noGFc2FT15cs?>6vZ`0!`0YE1~BIthN8IILWN{N;B&)J$OJBKV!Drx2dy1}6{Xs* zhSA`2dx-Z5ouvjuctlTypdNzaKwJG&)&58%-X7wB1`!|jA?+d5w&FE1XnVJZP}>S! z>NYrj%XC_$W2|sR3FFv{0VG^s6tGNpK|8mc$imOTg&vQepUh z3?|e{(cYOtJ)=Q^r@$2AKTndw{D)rYjxrtW%fovEO4Tb1M%o4#kW>g3Jv{C#=d+gD z%-}ZjgVlBjj}=1R+d#ZeuB#B?@mm#wwv>wF85%n>ORXZ&^a@xaFbBdg>QM4e!R+RK z{I7Uk3d6L=L%qIA&$HpO28G*9r8xp~kb6ZdYhV}#mRi1pY6MwI?@~E#)hu;-RI9av z3Ab!c2nNv)NdJh0xPtUK`;v%spdX!bSw z{#o?VV4>AvUEEh=c>4T3pa{>aBNys0*iYO)>tI$R)c4lnO8UGS@tyb^yRWJ$|} z$bGeZ67~>kR6_5oUjBqa_dUWcg~$0R#QUs9&!VdX9;7qD!+q5zQ5sNr%7Z^L3PK}MH{CxA4+ILs(YGqw^m$eOPjDEKqY&!E zk4gcwF#>Ux({x%5WheyV;&7jy^Qpal(9(dxM9>=P`?rH*eg6ntWCVc0QT@j#0+&fg z05qs};{fg8Fb)s}7m3?d`Xcx+8W05+HLlPOAI1ct;M(K+BupPh2BP4i#s?U_2pq-- zqTr%N3E(FyVW-(B0p%aK$il#5A#NBQ~`9e9tMMc0d)W5 z=)z6Uu%5;*K10wp;hrm#S=IM7v=Wp8`49JC+e5M*EYa!0kYQa?A*r0fo^X&`9L*hq zYug)b4~ZUa8^}nnltPAkw!n#=Z5zl)50^rQd$@o^54R0uTb$vZE+EmiYIB;4Uk5qX;>5Yoz7!46v z7R$B48x_-`J-A3r2h1#{qw*myLP?P6NNjf#Y(%Ct*hq}mdezt~65|1HM5d|tr7|5A z>)iw$k?EVE(K9p3k(dv-BQjm1;f{*^Zi0@;bO<^s21FfqM`A$WW-%bs7mO-kW*a?* zHWA)kH$A~(!C!bnjR~{j;;j*!eCqa79!C6U+ zU^N5{^0YF8h!;%`pG~tPor@?KlOyeDZ|i8=Y% z)>aZHj^+DFpK-Eo^A8Wj3ny@Ab>v0etGcr~LAOEt7F)Jfc21+aSU$uKnuU3j^XNu9w$~2Z?Itgz ze|A3s1F`4sJ-QPUTO??1lN3I5x)BaKi)^%Fd#>1SP=13aU|wUtXF~3{Vf~T{y{p`H zzseaiv|qEf?}|LA?z@spdvsZ_I;CSu`CZHKu3Rb_Re=3hGt_-wkZd*HpptzrIOJ1f z7pfPm$HRwvObm|c1%=aMmtS~Z>yd?f0<_1pkI6osr}O`;#}-+GNb!g7bI=WFSSUh* zuL_UO;c022)PymwPTVo(&rT?LOmc}`lU%w&QYzM94lTbl7`F82?KrxR^g zCZC|YeA_Aw-7*uvmKlCZ|9(5`oQrHZfkJX-ZT29O__gSi^GElstSdDQHFnL-2`EpO z{HA9tJ>i&@CQe|b#jB+`h{H`wbN@nV$iIaY=X6(2ba6*h``d_|et+Qu?TUMK@C$un zdmkQ1%R3|P!4CdUphp?pxL~iCBCNjQsRrzU4p8yub;HcJnt7@p&q6~)M=&9!$Pu(T ziyV$(H>q~lxq0`>4%Bu)FOYNqS$-B`lbL$t?@y_LyDh8ugBf|IHTIPgyOj*>n=~+O zm8*6V6rlgGg1!y4wn}Sew|?>%f5yDKlRZfj?x;!fB+u#FZR#Dxa(6k~n;n4U(oyzX z=dNJU^v+77;UJYj!2~g zYGoAE@t=e$0MuPfL)6krlpAVk;n7Y?&m8&7aA{lFJOwMQ52J|AsIoQhA29#Xg~~qG z=1*4Fb;N|$b)1ALJit~hst}`FA6Fr)8UzRJ5NoOA!*ek0!tPA;?NOIoaAyO%bGGI0 zRHwKubnY24ab7&hB;Lv~88ljvjLIGqx`}o!_m2^YN8$!#$U=@EwtG}3g++d7{~nI% z3nmoh_#Y(uLn1GgcgW;R`5EJXHLZKbY~!Pv$g|Rz#M2Bp&@ZDE>09DyY1j(-^QGbV zuaL+`7579~5KLoKh|yTh%~si)LlDowpRCq2ri|%DUox0!Oj-EO*_MB{xr6alX*cV^ z`Y8?Ys_Lk(KuX0=#qDx0XqN+fEenI4$BI+216;rk@MKe5W?VrW?~Wt8;~L}Mj1wB- zNaz>jy+O3WwiDCH0vkmmyTq{(vt1;i?%oz=ubLMp{#ERd!(xY`#Vtp*AVU1^M78Uo zU-xBuwu^69KM+NY0Cju9)C~w`kL9QG)x5y3)am{Y$%8V$3*Nk?JZg72Uy(PcdFuK# zWT-|~%Px&j$voq5IEDle3*t#FIi9O9*u z^JBL>Ms1qfQ>HPH+Dl};Lqs2;5zolVUIs~5wlPSpFZ~M`LL;JlzmUADqpGwIz(!Re zMRaxo5*r?SR;ke-IG+kZW1&#LJq&p-=2XgPj}G&HuQLq_#X>w=`a$bf445PhW;KHe z#X>wAlAtg&7FwniUhp+Bm&-oe!zpXxc=# z&X-+Um%nFE{@%Uxy-v9%O{fd(*&W!sH?Vt8pbq#hD%Z#X;4^ZLM#70kQHM?v)Y8$5 z?zRRhFUt4$0_4Dz!0I1M$cWVeaqs2)71yh!PgVp_du0?T%F-}MGR~yH!OdX|Ajb?9iiiJWSR%d~3^hPB-I!}%8W^QwDq0i^E z)sHE;0wQim&r}7Ikk40PABpXq6lWNP+(hB_3Tdw>OhVVj6aZ z3!WE^=TbXM7XCHS`2HZ1S!$d;>$%!Hi99uqUJ%RgDUTUX#B<0IU_8KsE*xm6wu2`& zdpx-;uA-HPkP!vvlyX@bq=>pONRsaX&y+Fb@_2Do@%2=x9ylF<{6<<0%5l~=(j3^N zG)VxvD7S4aV*zCq<@GnmOOKNeg>yGj#ZSlqloEc{M6)Fr!w(CR0Z(HqJ940?Ezh2h z^@MOJi^)SFJjKe@_LxA6$!1D32__Lon^M|sZ%)nw=LBG2bpXC^$U{K$A!rg)iK|!{ zL&*Y9P7AxyZ)wC8upp{2nskCu=J8JXj|RvixgS#1K_V=V_Tn?PoEXOMZ8$Z8--|1$ zvE>?X3%$_F2V|FcRldT@9PO8g+se3p~MBZ{)b z;~$@uMdGta*0)~rzLykw>%32Tg)}emX6Z@1p6I*rK?D^G_?7%lWLe;7#+b>uv`>pq zcGM&7ox5Qyy3ljP%*Q0tDQTB)bCQ=ePM$sA5}=Ux=Z zS)`ee_(vr28nREI5f)NP7E)!WG&r3=aqXHWtxXCBmw64x8sIP@heM2D&`F{QAwzN* zJ(E|OHAOvh0c21k6Y%NW4AIH)b#>I-iH(;pH#TDEBAVkCt^=~NaI(NzY?d^OU=dAW z`FB&^Fm6ZlIw8zzWxK{{u7b}OGO(ft~ItDP-HzAu~_7&ztoIj`S+&*O7mUb$|w zcwK3ItenV?l+XCB^5x@CK75#@ZKQo^ZXz-%d8O0n#dPE*1Up&W)+6rIZho(uY(pwN zo5^0}=8-{8V|2BoQYp$^E`3{uq;V`}$D z&FiI}*`QUvyK`IS#6`1f-rTwAN#*U{Bl9}<9@#~#Z&bc{#Cg0 z+o$zc{0;t2-2GGQSnY0%dKVhg)LJg|;wz!IvDkzu5WT6GhW0ek8mtt~3ljWpoWkhz z`f!51yyGv$dwx(}-uqc;)4#5fJHPk>=QpkR<{MC$2pZmFH2gkXiY-(MHwA`uC!{uo zyEiyK5rdkk9B+{w+(Tt<%8kZUeFlXFDWlneO za3^j#ohf=Q$(DqlQ<5GkOL6Ee50x3Am!Xrn)QtJapO5j;&^0}t5C3tZ0R07qjj$GS z;KT^@9$C6qH+BA@f8>&R-|_WCcwzVIsnc#>`NY~{erR{)Er>^V<&%yi(7oj-*?O+& zRnlw!;4cH89%&Rw?Oz}J{I_4iFAZ#6CyA(88b;r`B8OIHm+X#$$C&BJTv`@q4_aOB z6al-xa(xDahx05g}~iop>gX{lL!OLg&PL|vs0J!Qr_vma`UEsTlx*}J#1_F zjLKtV;M*7haygZkb4y5Z*OouKh9D#bo!=vczPk)=uhSrmUW5k`r2zb`0*qI3aDNnr>7*NC{P?74{-|o{hE` z>+lPOb?+<>3|w>CX`K0}*V`+t)0p9TFt4a=Ps*wSbS%Xa{T!v zo74G)2jA4Ua@Nk%e)WnCwHr+`2zFAFrmws9x!w~SWpScbYpQ%f8V`@38%*%o5|XoM z+av|!V=`l%Xe%5wF3=+y-eU)QVta@`@jax`qUZJHQIfUc8l1d?q-Jbmh$nyyd)k@v z^k7R`En(E2LEoL((LEoB&f{3p@KIo{b7x4iyWM$U50mO^R(ig?b{r`^2yBvaT;S$M z9|i_52}dp-L|l{v#quIv&E{qW`}$moiE-J6&L$mvd}UdBvS{-lYrD%?S=JGWwd-so z)s^e2b_uzzk6honT3w>eWpi2L1cL?JVM0gBFNDV6#7=rDB=vjR6@*mF1W8jj(^WuW={a4ycAit#RS4ubIFmiuY9d@RF-fLmeS!-o2gSK; zf*wcA;XpFgeyDQU3o?mX;}{NbfypN93Edh*Ej=Xh7Z1)Ns=4=i1p&w8u_0L zPfi_O^1vfS6AQ|!#+?6cQ+>rxr!{@76TQW8Mfu+g?l23Yl`1QkU?p5BM zK^DIJ_JAKJ4h&=!_8E5X#9zP3&gRZ8${cb(DX*&@H>#zk1xeD6zrE$N{w?)*t~=L*TNWJLH8(dYHa4Mqj@y}(oK#uXsbiWgxrfYU`@GgvF14~O&kQ44 zmyFS)T&|iEa=DMVZ@E@ZOvWjJJkCTlBKm^J!&~F<>B*{4XtF>Bfl5aBtNH_CES6)N z<^^TBK{Yu+#z}S@Zon%+Rzff0Mfz{#qYTWR9{;iD;Oqa1KhX5omv8s1$lv7IcU1Y( ze(-hWZ}EFP^|~72=~DmdmTeOXR+G3D@+gv>>uA|FIEQS>bYk--lN42A+KA4h>`%FH z<_vk`cU0dyU~H)ZymG;E`Ea&qjKl2WTyrtORtOGk;GX2fvmC+Mgt-9bc!xvBSU}?y z#3&2Z>S|hmn&LzgWP&6(8x@!A7~3(m>qz$p&GX1QGP~tF5|{nOW#zzYRdbcIt5*nq zes#-=jpQFKE8c9`#1{{3`JTrHBSL3p=)PgZB#3;SP~16XHbJ7>)2IqU0Fez18S0Q1 zjlQ5~IA=_U-}vKi4pz=iQ_lML4InOG<6z<`Rdxo1?*ht`S-%^kT;kW%*1V$Re^*tr z@8E*vFOkOyuPDbBFF!&xC`)naF2X-M;GuhRvx5V1W@&=c=A2e$wWZn$ZDVb9whgu? zZ8`(j$<`^Y(}GSbJ4t52hA+NUU+3yFpQ9i(HLtoXRWy6WglT0WG>RT!!>A6QZOYEK z*Ny~de%K|`V9Do|WokC51x3iD3mpwX(m1;d=drL;bn^-jvr=b`)Px1Pi<9=(45>`i z%dulyxo5kaJNn#VWy{c8ovkRd@}D<{`Al0>&~xTt7;y2M%hW^GyEv!;tArt{LS^>JUnsV z338-c*Y%6;m^JM@?b~7jq<8_+l?V&b5k7lUa7vb=x-6JQinCtJdOu4Tn?=&Hx@Ga! ztkf*tAY^5AaCLBZiivZ_RhF4Jx6PgA4!Y5Cce~SEX!0z2E&68tsujL zy_Z5B^87wnJ%p?{deKswS}wSzrY;$&ocgn`M7g}RI<-1}KL46>K7r&UDBqEo4ol}u zd3KzlIK@gb>iH+vXOCI`)N{%*{^I(Yn*4LOwj9I3r~KrkN2q)=sJ7r!Hkl36zzxwsPP@nFb)u;CpEjO?>|N$K6EtC~JbDo=YlZ(Rvr-{2oH zWK?=zMVa*W{_(+vUllg=oYX6rp7(99uJ1l`%gBb@A!)QvO=T|t*`wKsy9V9KNjOy* za^?zK%aa;OwK2R|cjK8P3VAP6*+#<+#&-9NoXM*q=%z~1o4(zVmh z*6iH5KlR|4;tB8UJ7rEK8UMIJUij8He5_;a^^vyboS1$H{w*8%EB9W;xznS!Rg0In$gxJ-9FEEOzd9N(L_87GEB}AYQZx z&Uk0MXm^OZ$}+2fCq!XhnaB(SnnSe?2q|!l#-Vk?Rk(4W>CkhJY7Jx^{A&QqK0E=w zIC=Xc*}{}GW#44WtEqd_KY4|8RhpD9vmdyetE}*f6W3m77u|*-==dg$CF!nzivPNf-(lJLcHrV}dm~P;Iq;jY?m<&dpi8I=aX~qRc z@ew1T0VGB*d85f_a{E%9x!veu%f!=#r$ccOs=!nRDPb2vy8OrmjY`-t+N8#U$O=q* zF(NzxJ!z~XA84cUE~GhBYSTtdw3hk-LvgC_cdR9i%fa@B$@dBY3127 zXO&&Y=j|ie`}UE}&+k(%?AxdO@p=C8u5rVaA+@P@MM{dbjT-#$ww zzDZ%CokB@bFyLR<>GOW&2v}uMdgLh^)Gcvn7 zx?~ClNuXT=dRBv4VHzeQohiaUI63C*=qb%wkPNM2DgBvy3-z?&O5%vm3&-bo3O--H zPDhZMLE5?P(Ygr*lL~5k%`ENQrFX%w(aqapt`wgpYc5VbXXjH&#F`r? zz7-3#vVMO-bu1 zn8+PCOU%G^2wL^J>1BGoz*z-xdYKR#c2e*@*b)rYcjCn_Bst%-xO2&|-pcImWV1Ns z#;(tah0P39wO*4C0I!dC^Jg)Ln#t9Eg_Q){5@AitVY-SeK0#eYhQ7%)`A0}tCb#%w zj=~GHvq>S}Q6YUAByv1orDxdjvN#AB3E9QXkf-p2k&U~1u!D&+@D?5hKE|r&1e>rx zSSdUrNSLt^1QUljnB2*^b_a2@CO|FXFbBbM*2+3hEWfH(|Dw7L8|sSs_Y$sOf6EyEcfbQ*>+aN~HX#b_vrL zT}L<9Dd^x`X1Bp=b-RT4gqTUQG3AN%Z+ z;|lFx&EWne7Kz2UqVrb4U?wI=OoC3-nJr>5otc=5u_(-^Vv%RAq0mrm_{i|Bf%0}T z)oe|;C=DuaotTxud>?zw5I$>8R$sy^k3QPcbJHd=V{}C}`wedRJ_m2_;Z*I1?$sZ>R1`U2o-v zccSArytjVWnqI|zuQ$P%l4?&*koW$_d;I(UxxRdxn3dtDbJ#d7K{_Y|(5Ci7nB-C? zV(kzw2$_J!F-phy-SwD-B^N=*Y~5)uF6uA1hIW#?TUJGpcH%*%YQX{Q8ajW6hUzr*F)s^UL(ah*b6@ z^o^5vUeAsi73yo?5wi0?kgh0_dj*kl~-Q zEW~VeA{5O@CoR#Wpn$gOjrl4DjdKhG21mdFkN`cVEC}&H69`lXLP7cP7~_P-LE74= zg9-X%*I78pVBm4QqD2oZMztn>rl?H!L)0)_j3S0lB}&`~l#DQpSbR^uL*1@2i-X)p zIM2|)iK1Sd3gVMoc=r07e*58p?!?1&Sz&89vt9bdp*+sHE0^P|q}s@)yH9toDqz zIBtL&81&*O91AA8F|3T}X{t;F*(CiO?fww)j5`tP!5>CHxg=a}ZUm$FJ5VsHaQ&!Q z&1#`(H|19EU@G{mL%DEN@En-6+ar>oW&moOE4+~=8(lLu4VU(=tM97VXHJkDXdLdi^lQfGGmOv^akU+|%U@%=Y z;203X>v+l}BN2?e?&pYZ%OplOK`EYmLf<^X`TFLA{Nj401HV|fdcBi0l+h1+#IL7P z54kj8J~s{0WTGt$iP|HPw(5p|%Jk9^1Mwt?#zOo1#JFiZe0wG$#5l;C8J_FQT!NzAsl%z+(Zk|bQYPCGcv zGf)e`B#GK&7zm?DCcL_aB8o-u5rm2)(`Dg2g8WZaVWRp5E6Z#dvo@4NuoMPF3nor5 z31-V419{6pWW#=R&5am$q6|WigEqLCL8=_Fl04uKm7`{_FsfdW>suZopMrX6=#6@C zC+wY=c0-CRylga@!rI+Vm`qfVqAjRqnpk~8tsk;ZF#au7%slB%GjW1}3Rx6zi$;f? zgAUOGX@XBQAwGmtG+|zcid7pc#q1PoXVtzk*@Deb8mNtBo`9KItVU(_k6CL2rrt*d zJH^Pdog-$w-fAEQn_acHd#vOwE0L}H&BTgBcMLe-RV_8jIjDg!tC?oIusBGK@9>@K zOJ#li2h4Ucp;KIjLlC>>bi*Mkcu_u^wWKO})ZM9OtepTFsqo#z*>;u;u7!GbCV?Rl z{C*_N8RSOuQk1K({4_#<2%;T1f^&-CT-)+AI#!?_%LqYaE{nNq8Z$^<_$?ufSAcX| zxe-C1&SHUt7)(5b(q^|zjUhtJ9vyj0hc2_GyXd8}#X}*36Ee(9cfn9qI#pi@*~H2s zDxm}GX?s%f#0AV9jS&rpAf?n`Q%_83VZMmg5x&SIU|l8#f@K*!3zezz9zA(WPh|am z1EK95_V$znEwn)CYJ1YamBtkWpK7$zGDkWF-9Q@(eN)(XkB#-@Lry6_RZ->dxIPe~@@HB}=>t?T z6hCPi3GbydnJgF)M0^LMqeV}W7Cz~xf~z!CQ*927q_lWDimSL(`)g_hs0CEQ6{rOZ zs+h%$M1m*{UPb1?RRfmjV&wr9)@ZA#MQCafG_qu7lYFAZmMj>gvKr-GnC@d?ligr8 z!!=4K$!3=fAsfnTM$|mjLM*Byi>lC1@sw#iGzF4M<%LBmSeJ7W2ptO*zGc=S6#6-&cdP@GxkoY;fz6xXB;6*z?iExb0{iCdsFS9 z|5*Qq#W##J)#!$;L)i3cj!Lt?;mC(^-w6+sEXG3T&5IWjSntfIs96Cja14LDmA#v2p*)b0=BiKWX ziAjhx7%)rf*6}u*WY^i_6RgOU&jKhZc26vMD;6t``TcRk8b{*nbR3(}2b&$mD$o#R zxm8M4e$m#8#nKH*siqyQJ+-!^1c$UlYgg8$*N>{&!fX+Z&G~Pnz0AYdampl)M1$+d z)%wB&>w2ZV*Gr|n{5Rrd_y7)jTj>|pbN+c~Ou7Ck4EFbF;WAjEpSemT|RQ9k-fWi&J7Y-~^clZX4DaJjFdr>VyC0 z)AL5$CskGoUjN9oQdLaXp`~|9^XFT0huvB$Rm&*_V;+!Z&eWv_#y%*`a&#Uz@owpk zJDk~rZmW|P854V#JSHJ<`&pZeQWl)zY$!o44-RE$!O1sbSlb z&q_}{wQTyLS=Cj#J-?Yg>nWkCs(i*yVfNJ9ZoPHVgz;lr8Wp&Z+!BjLYmuYwYqF(ooSPRferm50=K%Zwsz%R z%V&=-8r-c*nweX^oHM6&={C4%{A}aBixz(p{Ip=>G-eTj!`aZ z+}N^OxP0vo-|26-OJD!%Z){vr!|^}s_;w@P2c^q;@AiNrNZZ@+CVtlri{ z+=rxhI#0asXcOTZrLVrqzHRNxO++{(eeD={$L1!I*eJdErgPAuh9;79NIKPZ$^*xm zh}x5`R5_cTyP`i=>(w~fgfgg&0 zK5!%eZj8kDVI-Y&CV8YcGB-$MApUv5F+aF97T*U^js?xfzdiN!J71jr^!!H`Ek{T( z8F%pbsdvtvZz6*Z%NH-ccH*sf-)|zpM)?mfzI6Cy5L0+qe(t$_`wup~(nR_;%6q7- z1GD-ZmY;q0kw>>|-`PZZHp)-etzP@!h9(j?EZ5fFwesHkA8H~!8s+7)s;U<)Ya;%` z^7QF5X3t%)xQTRYl*`B7a_enVn@H|qncBqh6DBp0E{$?gpikkTVNE3auuKhO-{9aT z(y3AImg@Co=Qa`FVHt_V(>iwQ(nLBo%JDjr)#+{`-or9Ak!G8#iKHErxgTz{9%aHa z@{s(`fBx&o=A(pz=PU}kzKi0b<^0ko^&=D(J_H6H|If{yeUAB#8xOJ%_=vN!XTQ(x zHBbEi0Y#ld1k>@EGlku(09s%OExZRUFA8wZ{{ZI3zixW$CnyEhIr#gzcX~(jSj_Wi zev3IN&3i@rFzt8d$<#O1pJ~4{Po}=9zKuCJ&BLj`MpuKH12ln2AYSxY)iNroba)VTf?ox`ki|2 zG465h3GUb2Gu&^u=egfDej!WDX?h~ww`I7rP_Ydyh+<&+h zi~vf+KrF;gVo3t&Ks+RaWRV=4ABmO9q#qeThLGW8G#Muhz)DhbOYqK-RS!Og6%X&A z&t#942$_A?Z~m4joj%RXpd^f~e(c46NoUWFn)}ec|48r7sC(wK6zSy2IV*O5nIye= z%c2c0U6anAFJ7>5|G%a8%UA#U<8+@9Uja!#B9KI@Dyf}XGBM1K>{bADD zCqB%Se)qd+_wM+_D;>LW3`Q>ro}?IFqz~!SIAQsgroT%cyh`-2gIS~q%flrQ-Rtn= z`?p^4Nk>};bb#6Pz%z})jY3k06OGI;mtDv>eD4cm>?RpxF!pgssBJ#@5DULH9INXk zQgE0VeyOPF7|gbfq>yf8G=2{r&MWBMf1osU=l~N~7Y|oA1WT$VxVtrn z*dN|_|IK#=IJOe7%*>ocH#t7;z2E=w2;5@-!^7ma-~Qd}Cr=-tY(6COufX9QAw5XX zL$V~n;~k+P#-YLTb1xidJOXFh_3$8h@7^bV{mgHU5H!#sS>C?$={-kCN7CsKM!+{b z)^G%@@f-@u4?g_p<|8DLq#Z7lA9&y{_`@UMj{A^otiAi5`;H)ti8~})EO3WMz)tI- zzH-(4JC+{7;A+g_K5}K{r1BZFkAOA$LvqY*Q>V{5LVZ{;UbfreEN`^-lt+#!DZQ=) z{B!by#;TZ+jvs$?jEt!= zJ}5uO8{^KNzj%a(Plt=-citgifBVlPG>8hC{qhe#B&MWicJ7Le$svzMy9fUd{F&`d zHyvcaqM9~t=>O`skWXX7xfm?SM{Ix7%OC5{|LK=E7DI+Nzeu|W+<@^#y>#vFOSl(^ z`c1;M2QOW|H#P&GPJDW!UhSX%ulJ+MrgV_@-?g$sbcXQjG`c7~Zj?`7l#bB-P`Tmn z8eXUNDP6dpT^aeSs-*ws(YMN~=)dcag>F?LH)1&*77Bw*>lamsUn3{7plnK zc~w>O*pF4=2it#-AmZKg=3T79bM!xdm6l#v`3HQXS3ppy+=?RqKub~Yg+2iTNKm7= zh-W%Un@-ZF(RWV;@u&_$dq0j2(iG*g`hSvgrCgq^x}qslj%m)QBK$+hYn=@JGG&VL zQOIS5{Z-_ru&a{Ks4l94q-hr@6@Rn{hW;2ut)e|n5i(>dB8G$^U=L#ysFwR)oG4yk zqd)>5wI~8BsGS&lsTDqI_J|jnJy=nKNiXrN7@lvI1YQ;}S17}AP@R_FKe1Q9XIjs10O zlr22WtUfHDR29KUWgEqz6q5=Ci*PXF#jVnFJl!8?KZNz)SpFIrAH!1~JzaGAWeb)s zVF3=-FpUylK=~L;<55G5sI!$HpwR<=yn~;B+yyV(C;@DJ>*w-BaUWovhcVKH{sqr4 zQ=`?r8%}1bXVu@=vZG}i!wvXR;wFY0;MzDH9UG+3@~D=*EqlaGH%d@^8|0RSr`>dr7Hq#oIak5PxH9U$g@vJB%^rc3@xEjcYkCC zTx{PgU2aYHcgTB|om*aeuBPT(?ecTWO3U|DOy65kzHfT@-g16M&G{PqUyi%))mH2+ zFW*aVR_vi05GuG*af(=iIW#NANTeohm9`VV^JqC}OvG}gJlME|Yjksg! zn5FM8{dg%q@Xou3-u?dFAK%UARn9M%zkfbSoH!+Aild}7u5?4`tEFd41-^HGxqoYa zV(i>Crt8wX=T9l^-?eN1(kb)rUaHHS*{vd2!B?brTaZa|GYc~}WD1#d1|#uw?&Q<< zaIehnx1G+z^4jn_yTtP1@DJ)u)j_dwvj6%9Idyr{^O0k~r+qrLPq+3Ny02^ZJ@k9% zv;F<{-!t0b50xie^kc8;rXIa|_4px>AISI8uS(B?{QQFF1Nr#@zJ$KFBn6QBgkKeg zZF!+buRwt}zh}>Ua*6^glL`WX0-(qbY@)EjX1pQQen2@N2;_f?qxs0A0G>#ZEyEi* zQsD31GAKX4=T^Tzz<1Dq6cJbe9Z)V{<078#NwxI=w@&m5*Rdkje#nSbt87&g6JRhf zFAhn8IBzNy)!`b=(U4H|X*7<9Ljc6yK{u5K2Wy|Z-5nPtn~S+?}d5^?p775qS4FFUhj zF@8J)%+Y0F=V#F2;)LX69FQb-%+ROV;<+?d)|K~c?}a5rE3Tay`hKGL5-8X-DA?X< zP_{8Q(}LT$F`X*n^k}+xZV_3-R|rcuGxiK*1|3eBv&fclTu7Hi;;2mvF$m@$j8 z3v6#?XdRwT+XzLMJdXoLHZ#A%oCY0I{=R^1As)A0ZoRFH4&6&*w*}YR`xliBx?l?>@n1v&UyBG8% zJ^lWm!B*5MIk{`PHGORQ)O5k0?oW?1#0l0^EXTz1WjeD5O4-&&Iv|Z5B>u^7W^2JA zzH5^yOfGyqI8Pd<>j4?TQbiZ%&*P$M7AHkk8)C)=yBXYAedv>Gl!oRT%Huq#ATYJ0 zVxn^PPnR0D692_Nk?t)Mb3C3L`XcAEJ)YcLk0-n3%Tb#)j_Ozba#ICgq`=|KYQ9b? zmCe^L5&zc5FI`mLMR%bzH8(dkEhi^U`&3?Cx6XU?DE!ztaB3^#6wQ8+!`%|>!Nqq< zF?V#x`mVWIIb06$Bq14sb*y!&RmjP_mQAeLBs*xa6=hqqtp*{?nq0;g^K4quzDv;Kj+%)KOfIM#guko%?QV1j8_kOp_yFT?b-VY~J@_2fsHTdySAoq#)o9 z<%;n2$Q0HM9B_M|qd85b80xf*YUHK9^))PGe5f!o~eplmjTEv*pqy+lYfXO*2;XUo{2Kk1_WOq_+|Qc_cLQ~0=)xD+`^^9QPH zYeJe3s&0r6tm=3}(`yL~-86%mPMe6u9HUdKCEXRD$zNW$?uCWR#+PoKO|aK^6g8b0 z6PDGEFYVKR89&gmYxauWrQ>Vn?uywxRJl&%p?v-FUzOJM?>D}58LdSLcU^n|wdjI9 zt3!icw@Xaz=1cA3DR8Bva0Oj_Qm@`AT%z9ECAG7^V@^k_(3$NvpouMVPn^JV>JZ(u z9`qlj+ef#675M2oV0`4oQXO`?T{>MlGLP!igm9XX(uJA~brHEu*;wGF_YCSgAuHV) zBihWO7!#Y}jrn@~Z|_*LZ%^%z@sCfeT`^%o?Ftd+(TXt!y(ro(=9r{D(?|D6GsyD5 ziQT^`nY-eJr)!q)%}%SCICUw7hCk{9KO$l?vWLqG#>qC5+ny|^drfZa1V~6t;1d$; zG%%wZ_vmU8HTEMAJN#!maZ-4<+Y`tufaBCwI>Tl1p7?2xtsly-ny`I_SiEbE-29bX zyKln8y|=BJaQnJ7;@R>&57n(6Hm&Z}ox7*#GcwBeZH#%fZt}#nCCiSgG$Ad{Da?5e z3TFDa4yj#rPB)1$_Q>ySvYJv&d{=#{)9cjRt#)Fvo9u}s5j3iTgLgJzAF&i3PoTe$ z57kf?Vh8fvtR29AFdX?GaKR)Aw=;byf?FKg+^Ao>Y)XO9YyZSWyB?j?@AeFbY1hKV zJBN(7#rft88nJzG&!toQiQTK~7I+hTE_-ZLZq1S>?p*W)?;q&v=&RYhv#PYhC+f$H zT(acpym50@Y+YX9qP~A->zC-2)WCmWMYGPCkZ7@C0~ifqXsPr;4}V>I`>Fv|>lQ6rwq)(}(qrphx`2`f zwtgX;2M00Rf5?EfY-~ZIRs@OT+%l)jlF^vp5)zZ#_LW#kql!qPjYb{nHX%*o z{jrp_*lhzT_C>FSCtr@*I(JHLuRDU9s(STWF*-X}Ts7nMO?x-j)YUB8X;kFehCt4k zMNVj*k#xwLLkuinc>6m;cZZrQ;5 zS}u{nb&uXYuG&FfdrVonczb@%s3lJR+5u(OV@tLmBAeM75P9hgo3&pO9AYsz5D-{R zy0}E1cP0z*94F`uVwwjFYf~jL88T~3GQ^mzDIFZnxP*A*H!-+vHn&00AqlvSlIV#r4$DF$yma{i_VU{^z=A-m&K{6(L*!4FD~;u+ z@mEep&`;%}(nwyJplm1oo>U$u!SW}kknhWPmXo2%Cp*a`<((-z$`#|pRpk4fiV-X9 zK1U_CV{ck4)(NM?xME#ZWk}w@S0R0gfK{cju@1?B4W$kTHWg^Q)Z7s%ZwC zY8DUV7SR5&E!amr`!imcOY-Ise}-}=U|oMJ)q*=fJc;FmS*L!VdN*RcN-vSy#c zvhCLIVWwZlu2v_k1hmbdFE8WF7IS%-z0g8ZEhGj@jVu_0ebMkL;w*z~$My~DKwvX@L za&{kR*{ty;iK__qcR0Qj$Oi%`6G%^?2ob5(kcw?Lbp|X`jte&0$g?(*X~Q~xo6W|X zWm}wt6M#9hz$MHn!y22=u6BQ}-H-jMQ?Yd&nl%O4nems01Z93_Cc;0KsT`?=1nNxu z)Vlew6+Hi8cf#QGhP1~QC)w^Ic^i}BhGaIRZC%(QZV-6MZ` z*O5}0N9@9hSJA35klk^??hf#BZW)#WxlAsnQv^}if!ht6Z_AyMx(`<{2#9=5rldJ# zCIJbF!c7f&u{Q@hplMbD#$6Vvd9+>jbo0H0z1_M{9ux7Z^1SlL?emngzuTI%eKgtf z-H$C5=d&&(ta$jTY11AN&HqsT-twcc>J*v($1SI7A6Pv3R?r(mvz3G1Bt#fpgYhs2 z$=sZ>0Q=^={MWhSr6Ni9b}D94HbmkWj=@iub@NUNcyQ6V0|7ov(>*&vVa z|RsYOC@Bhoj z7)#5S5A%*kt}X^or+{8P=uHH@J%UL|9kA_va+#YX#Kmwp*4o@*dYR2=FyqJo(CSBW z0<Ib=48QUacqr*sCa93>@+Xh(&5CtZ*;HR{q$~2Uiaoc zWz#k^Y-$>-l#<<@-^%OHCv6&k^&8TtjQG4|rjYhYuB=oFeaPRC|0`c9m5#B!c^Hg= zKgv+5={fJ9G&AUON%8T<$z}028)uD`IAq+xDGRw8J2l!e{M5umawicF0%gDEU9pep z={3qfO5a##n>%T9c7<}Dj37C_&I9!Qx6F8;!TnLoBcz^RuVqD&U5DQI!|2J+ZW~?& zN+@MdLlSKqPExR$WkHHD3I>M+ag-cFxLN500u+H!As~MXgpKBN5o2C{RJk;1*!dMu z08GZ@ZQV|uAahz?AjXzaWG~Cyf|Qc|&mon|V6EQQn8oWDbXqubtOL7T=|)lPIF6Mu zG*yUtBTt087a9iTc?jA871xTyJ}AGig-lRl4(?i`d{;W^@bVFAWgj(VSoGo)MX%J* z%95vx6!5oYM6abZMLAB6FQq5PBbx99T?QS(kvTBDYRrPv}o*d zX1N?t)jrCl$t@+=;N9{`zOW~&`8$3*8h!6+;qQcdyO~BtIJ3T*o->aUGJ{T50y1J* zSqYP|i5kNUtYSA6fDQb_!*5o;Ep7SU%NHt({QNiBEpL;9ygqLX??ehdgt|7U z9?d4kcR2RhYoz#e^^^VeLy1FqN6}kHF1|nevG)oRjMtXGwfIhqt^b|Gk=I%#SMI+) zV*f3pGKl#7KdUBpBHU5srGxjwaUd>){XHWtf~`OXT(f;fnc0S|Hu#Ej;|u9Q@o2=j zSajxC8XI-9yN-PK5b@>cjD1oY2ke+tc1!P!ME`_bWv@7;rEyKg(|yRidzPnOHO-vf zLU&?wO-OU>m)^n1C3177!b+x!@m8y3a2W++p!@DwPCh$wQeh<6BOp@+O^JYl5q&~a zXk)r`en%S;q;loyI9cDLpYn?GLJmol^|IbG&O{cHm{^0ptmDUnw$3jp38ZxFHnf{C zaLUA|?r-TXH8%gH$9MUYfA1Fj%?%sxCbnPk<|kHm_|7_c0i|;V-FyUIWKxalkUpcV zgDuV?TJ#Q^!OH2u5laAj}tEq#dL^Xtove7&-=}YAm zKS>a=TYPZh7o^CjA26_D+~#?MZtazl(rrvv<#)V(+mY5_%csx;`?*zJUhBulxBTt( z*(V;p@Zw6avUD1>5Ub+RTBkr^BA3Ax2XhCfVP|bxY8r2nENP}BM-uWH#iz#Ot3KZ7 zFd56ssMbK?q1%ER9~Oe=KCJtOK$8UpWF5r z=l9(9+}f(S`+IM=gWuRIyI`DSnm;v@a+`X7FEm@n#Rai}W=@$bV*-KZVW4r6ma>3~ zfpAsf?o*9a4bSn*TGqiZ9R~(4oLwa}R|mOr%4B*OcNY7f(k;U&CM(T!Ue9xxtV5wQM~Bu&(jonI(~=pH{}n{zxLX_OUDnMpZo5MP4695 zHs3aL^SCKxom@9QK1GV2*niKz?y6j3=f&T@^4GUMQ<|Rt!S>LV)d%*277w?D-=ytv zMCNLYP0-Z8ZsNGKYi@pn2=P7IE#mrOgn+r?RS|=rtdfhRMo+9nnL2TX- zFtBq5X)N$GB6A^ngs%Qr@z6fKMvUmyXQ=L2%WeEK%D%#W{R;aQ7E(-m#F>0R{+waL zSw9v5R`ALRy3`oHKYFB(4=A3s?T< zVYQ64@Rs{{GK*h^6u7{T^rI(eph?>*-{XrSmN&Od))Tz zN?I$$crx}dCka7r zC7}hKPJ9n~tv!puZoVD~e`B|iSaAcy%cT69dVm*@DtW8?FK{!4Lza$0Om-0+?*kVs zWBFlJD`{%jTv~G^StF5+;pFVg(+JMb88^HzIAY8y(a*o$oHF*7-UTCZv;fbo=MVBV zI^@j&UUv}twS-RScj$%*V;D}L1V(DWqcBc5TCQ9^UsA*nN=sS_g##)=#5yC$a=t)% zm+16$t-n)Fuzah!Q7qpo{NxVgWf#F`17~m4wwS^q+STmfh^rAHB6AWi#=Y8oUf%uP z=MIzI^S=1v3o;&=y=xFVeS|CI6>roDE3tY8-FA$Xu!izriUM&PQhh2lc(}6r19+G| ziZ(-T`R|omgw)n;SdBVTdG$Yca<<=c#-`Ry2aQIXjU6lxPGoQ^co(!6sl2f79=VNI zlnH`0-Wt0CiQcI0(g1=UfGC}_0>}bkDEJj_$|aZscO{F(z&Df zPbXE49`dVsBT!B*nIvo#j)LPlE;VSA#Cysl3CnP}d&*kTs2EU>DvAaOc&*Cizv|X} zGKc>vhyUc#C8hTAW!SFGIV!$G*6YmJRY%W`m=Nq6fQadwL3?bGGbYZw+e{kF zB-31A=H1u`XD?@2ypex5mEVAlbhW-t&!_3T>38Y{eKL-2@qajZAfxJ={ta7Tn0n_Exn3CqxuuN$u<`+VABN=vEx@p@Z zk(MtXNtdLbqI>giZ=Z!_U}_ZVa}*iYPs>-(hWg*q{TS5F zBEgQhqd7TS_)K=4=19wI@c{R4~X!VI`#h|6}f5;G($B{_#08yURrc z1VlguL`CBT6$LNxvN1-%P$k3=C2A0si^h0CmciJwj^m=9J9}!w!m+{e`{-pUcp1T@bQfQn)(YeF$0zDirI7T2mTE}2B z_8j5isZdoQ9Le8JD%H$ws(*A$`Ol zCN=)U!n0Ol6hti9R_*ahr376P#RDwwt%2Vkp>mS)o6ZG|7^bBCB}g3pBweCQh( zb{_4u$=l=)nSu4UNt@YB8$ygCTHOB-Vy%3ULli$1d)wrR44-ECA405_udxLTUE~%i z&qlqNKg2+I8rYF0=@5=fqoddW3e7%}iDEy3O$hl%z%+Ml%@d^kz-@|`e*`I%R#^uH zV+Dy6z_buD*vBXA$YWJ_hn4E+55T%6xnw35IcC^2f5Q7TYd*L)lrW>|14SNupFEcb zLi`0XYys!u@GW>yAR=xV`b-XTom^YMGT2a?w1X|omz(ewqZL0M4+HNpv7;a1YjjN6 z%S^sBO+EW$J6w@$OTuii$|g=0Kb+n2Q*ntOoFL9IMNh;4+B)vl5`Q>p3|K`fSb@+S z*7&*Yn)pj*ohO&dgQZfyo9N>kMcCjHfUl0>7$?#TjB~#g)OLAs9^3s_o3xd!ES6ts zc>{0KIV5p0G`Ky52)Ci=uRms;01a`P7CYpZ^VlQ@6xU>sKVwe-4!mK``F4`jBD^^V z^e{;_$~muK;{hbOvgI@Jt0^sCiakh@Dm>b!uC^>v4fIy+0Q%{M!ZQvspA7<~@*eT4 ztd<6>i|qlJh~fGm?eKx5fNB2n^wW+V^2#M>T7fokllW#v%T^K5iSTw-g-7i`m1--v zcG>~vA<7l0?`AoFIeYz%jfJv8@#w^siFc$1z{~K$)4>P8wq#Kg5U7zDri1U3s;X$Q z%f!Vt?U)JQZq#5P%rSa^G${bZBc(ZU38aaSm3@`L*^gPGA1KWxdF*OMnz7AaX!3?M ze<5Lz(+V$0=!yN_UQX!{XvxPcpMLm>GmSIrU3sX9O{a#rrKMWaC$0G#v4ps#;`sew zDgtPbC#+^=th-IjmG@{S4{0uE5#nOPw2x1wZ7hfn&qwIUdbwaFt70KGmLthSnx{+H zkc_oXYP)D{shWqiRIhsAgBK>Y>r)%c(1^pEJD<_K>*e9&%Qnr|Qb{0=Tbh|ZSs=c$ zucczgJ=t8uK1Ik|-md5+te^cr;Hg%dn_i9u~a~Ek|1wn0X|KAI$YBi^r*c3L!#fu=N(*e}in9jzA%O4Qb^1G6ga8+d-K#`%aKU^CageJ$Et!hwU zi^-Z`xFPM8`^!@**t);lw9^KDtJ9Db#%duh+sAA9WPrz4urUq*P^F;Swg7HBu)-ZU zP{^D6Y)7XatPds=V1+)E8}r!`_Ah);WN!gmNR(vxWT~`M#5$sIXc#xKKn2u&?X(X9 zlyUa#mEWDo-XQ&`XX*0i#cU<~8{R8F5GvwXJr2|j^5?l6s`!LhA>S@#D_hQiRO1ex1Ute(h#@@Ee-9A9K$xPtPkVe>btYq8xGC8@)y8~@KOECK=gvD ze+1W3i@u%%L5I}_j+VSjlEytjUW_5wlQzwJ7i|npv=tVQwxrr%m}0FKeuxj63eMY7 zTfNmy@Uf^<6-(J_oBXbbjh_Ewn42+$Zerm!mL~4DwcM0o(pzCFG%LOhTuaSEXeR&C z>n!b(-(zpyv`JstTJ(x-Qd>nJM!PEi@R=1 zm6XVP3b5g1CcF~1be6oAdnGECfbwpeY$^xRiPEvuvr ze$)nXi=xOuWn3HWr7ptft`^N?yZ>Snm$07}$vLt?lczxP^<0mM5t+E6*)VaUfo(EC z-3X3qXZ@r}>{pTUQFfm+GhPFV(`=gV&0kCT87&(SCy@yweYVbDngM9-kC3L~k~GOV zuVKRyq`A3ek(4p9<>z8uBk3*-lh4Cc{TvJj9}QE{kay)DEoU>yC0QbGlctYpnZ`zn z8Es&;jxirwL$=BDm$QW|*v4|D*fA|bq-}l>A4{@cpQKTqxtwkM5=~VaHKzHCKPx^7 zO}46|hwmZT>C4#=2OB7jAJei^>JN<6-rjHYz#A6466h?w0&HU~{d|%s<#_q$^+^JU zG%r@#y$a9YHw3@{4V)5cR(=runyM;Xz#Of*B!D@KT#{BC+rbnc4O4CY{tij-z~=tk zA$d5|M`QXxha`C5x9^cd(uyhH9ijLm5{=KP{nPS-R$jLHBtv9ixamuq7GScuPXZqL z^NJAME0>V%S05q>uX8u|&5&6E4<&*qX-noD+C!eI{&}4BnwJ8;f%6G*l z5fMf6yM2<6<$ViOpCmyJ0mMi8BydR{2kIXAa|J4Vl4gu937j#n|FlW|rvmkF z(rfZ;0Od|eEB#8__%5HM72am~9}C!S@=0>!c?6D}67UlXvi;=xI9|yOOi?;CCi%&% zwh~diRSrRfkMt0~2Hr@^D^tX;Y?_Z+J}y=uwD0vurkFo^WUmLWRcTCb%liu0JZ3^i zFK?L1UWa?r$|agFAj?Y-(KBQJ(!;E|kMTaoRjgoX^5-RRT#t$q9}1HKv3@5^pWDh} z;kN$wT)3?VrEEW#N*~6hNqzGJ`!FW?aGZO&7~|E&HjExF&twOiw`sVqgtpPf{$l%Q z5Jd5?zP=AjYjrcF59EU->57zhb zGXs2n=1sYf6|*O7(ni^aF1C$F_&=$ie3Vs{U>GojdtPxG~zY>)#)I!ok_c@H|=C(+h@>W0P&-ICNcq$!hsV z%n~sP0Zi}7UQKD8srw#K7h^JKkPYjkwu_%PYPc_<&ai&>ED1#mqFIuE$flL}CfBE$yUjC)s59nmIP`t|k+0;p zR>L2eVv|;~@a7KzP~L;E2;h5bkLW-1@_7EpNAkO?+0Uto7Oci)A@anP=1ssQ_d&@`?2r$Bgq1XO;{mh_Xji^o+_<6fn+)d=s{K%K`j^*eSvTT}n z|J*WrjEHy+{*cts_;>pyTu*qT`kUOa9Mfq}!Yyf8GDiGNnRRJD%KRRF$;a~U*WkcG ztkaphWpRe|j66-840^vOOn;&7kv~#kHi|b|8Zx9wEeR5qjkUsTSZ0#r19r9-i zJn8k8cLA<>JzkA*Xg|a+`CvKQ?ZEd4wv3gY#ncx=bd<-HtfWfzFIcFAP6aQN@??X& zp@8M`H*hK>J}W|wA;O|d0_K(IrCHlq5h4#OZ+c3DTK@QwxY=ftK5toFAYS_VuE`&# z$Jdb_0O<8yzm(6vgtv^j@E*vEeTC21sJN*;{`b(4Ki(4*Y7wk!i2PLnO}a`|Z8%3h z$#?jf0lr4R`HPo1^Tez>2KcO>XvzWWdwZG6aF9=Cim%J>VhTs3QU3Rx&GdPhpUYVY z$T9|R9$Mh_ZzCzFu)dE^$l>v}dPAOr_XBwA&|4m2!%#f!2SW7oGC##eka#$AM6iw7 zM7(Bc#gcoO0a!W#%M{2&3?P)jQk(f(FEE6SKHzyw(wp-y8{EML)tP z@w%B!GUnt21~vYqc_3c>{$1ntgQoTj7_)K$;*Q83lfFNfKk&Ep;ky`a7;niP-ZK~S{;_#D$C=WD(`?xqQLR%y&lIW0gNXd1mR0%4o#iaRNfx( zSrRO<;cr{~-X0-pEm;wCU4NJ7SFi^1NWRq##CMTf=X=N^sbgPQIE(_ZErDJD-8bFU zo2;e6qPw!w1aO!_bKd=SH2`9G14rwJK=tbvK9_eYP{qmYAK!ieuq~f*8_>l!5^0Ak zhOQ69)xY<8SKek~CxGkUq)yF&gS6SrpDXVS+P>4|*6!i&H2u(Ql7CaqjuP>Br#VQQ zqxvLm-^VF49GG*ZM$5kg&KG?s)6D9dn+kToK~P8};GQZ~WsVh6#fTa&Ta@9$gME@u z(n{vPMjNOJ6m2AEFtl zcqAB7-{-&bnGzpF-)yToH|kTCuVl|^wjchhxR^yWmk-fQ#tI7z+wOlG@9V=J0@Yuv zpUIm|>@&RK|C3nS{BfE_-%`OxVJfD6p60`6h1*E=_p8|%53>_#VtdKSgi1pOXo4Gxc%>b z@YK~=q_NZll&Sm&Xe`%~mh#!+U-2HP<)^d75BZ3p{kk|+KLGE6HpEXqK9rjZuq$Og zd=b80fX~#lUAO1;E@4Cva*o6ESrD?3e!9^_YXpc+^v9p(Gpl?I8?8a7ItKKolh)Zi zv}JlFnTLTOdqV!qz)aF+z)`(I(lGDZ7A9%~w2Ixus}FTCreeF*Sxos$c`eprRoJBc z%@eRZ(GQa9<&!VNFbx-|RoW><(oB_LW%W=1?9AZQ$- zP(}$Mztu?M&`!w$!tkU$pqBozYCY9j>)D6H8sA#$N9}7p@5AdwL;`vkUahrqg*}f^ z>xIXvHSK}5^6_QRzMNlH@Jkmo?iYlWB(kVh+^LSyua5p9b^PHxrPdkH7S0+!IOEki zDQ)YF3Lp+B_`GO+Fg|Pi>f}D8jz63i9#W^o56-j))L9OFdOe^A@LB8Cr}u;eg+pCh zv8GyE{A%eDGvUFt{9!%ST5C{SSeyM|jc=_rq;0L&IqnKxFAAHura*G-@ba&f`&hMJ zc&u8}9$1TXWmdokKKVTl^g{Qd^|3x)6_K3LEBYK?3M%fD8(uU1dL zT8bPAFZ>L<@H|?Bidnx$)XRB9y-gf91>SRh^+vaY=U*?|uU@iR50)@Z&e5*N4%HqQ z{~#PhL~O^oGh#K7QbdHH#r9Neu~jyR^Sv$DdQWmB`rHx;*TX~tVfao@`? zy)d+kTA=ay^o;mv1GDTEXFh!MM#}r-zg?F99nJ=Ze93~I%8t;)HpmzMOT6nvTAnWdm;CQb?_}x6j%h#$ z;gwUdR|xxlHSg#WglHi}7_Ltcl6oZdm^C9QE+jLlLvUtNQb4CpPt2Opi3P-AzcFnv z#MVM}_fUV8)fAMC@1j7|5M}=>T|h)NHC_O|8&112X|E|3+U1)(uea+QdEA&%WtZDhvQyAt5pJ;YU)rdubkK$s_>6?u#GBPTLc7BYeogXnQri(<| zumUt;DC^$ms>3czF*uB53-Y5nNgDl-VHp~ICx-u>i2P1Oey7}+;+SPI(j+K`Pu?-xWA?^K6Jl8B znBFmIF_JEZeG~KV7;#w)n-o(LBgS-XBkxlr@6-PBZk0Bg0Jd2BHYo>ay`t6=1iFFU`(UNM;e{9G4Cy^L_;oJr8MJ4Xbp0=ocNk&~br(GP zk%&VP6&VxWozsgTVMK3atV(Yz)5o${qBoZ4jm?cKj$0NdO+r8@AH8wg<0rj#XNr?O{miH14{GzDd3M;4@y`Xmcs4TY4=I>hkZXa>65ZE$+tx)W*N19C z*`?51p$Pe;)e50a_wMK?U`JqR=idi@5crosX+z+SKyg$cdjg9|0%HQjz%YCySiA>R zQ@dnJL&Gwq0il^vua23LK70{AqG+z`%x*w|IojuDrN$lWkAJfk^Vl}CB1R(cIOZ^7 zK@>i><=Y{MZ?;E+ilGQ5(j&P~RmM}Vfr#syyOwodwQ9$y=jGd@R_bz}nQR#U+|Zac zJ&T`Z+J!n}7TCl$p)cjH(&VnK%$AwM}#aHNqG@Swhn(qChAu=EpC$_rVYMMY3lT$_?)^(26OtJ+v_ob{YH()AlR=pwUn7vc zc-m`CX{5rOQ3K-LtzNUF0Iml1vVhdrQd5cX)Fi~FF{$U$+(y}HSXY9$Zh?v(wH@uC{eC`FXN z@uL=0|1Eh~hw2z(?x1J&!@G{_QPI8p`GJ$hr0a70IPk}`-es%0_3ZXi`ND2V-AJQf z2R~lL-qrwEl;?ggXzv~TU1XPx1gyzm6sof?;&U>6bWPw-1AiSTtpGFL4*Muf3^QA! z)<)u!ijlu1ytTL2&yRYw{tFf3YlJY_gU^@~_;wcJg%^G=#CY+A4UZ>$`vc#2eP|87 zxbSO1S^?#IJK!U{3N%|o)?<6Iv>e-tHFcfX4fF(D@3>f0oR1OCh$PX5*@P?lFU3l1 z0j^;33t;jHV)Dq}4#)tH-4ocz0S62AYlrxw`}v!N5d(js2i7~#*7Eoc;t<69OkStk zh7Sxnu}zycug3gzT-4&98QumaPGGVem;|BK z6DHC&gy3=py%F>uK~hvuub^RgXBvd>^qRj8{_kM%bTIn~43iI&V0Js0l>{#j{w7!o z?${oaW57i6v5MlC?H*Yp8T?B6Op=yKtVF^(W|l0mF0e3BJmxKLaI{bS+^kv0(DceuM`Fh~ z>?vZz(Qnuq+@@>r+cM7JqWMg$ymHE=1oX)dkLxqXatWWgt zXpv4O(aWPhi`GWRHr@O8Z@XlEgqGHH?{E63@XXjjVVSW5Lo;K|q0*#Q8YyA{bsGIs z;ghmK{SoO`8ChT>Ja@&C{KStV-Qgq9fn}9_uo_Af^isAYDkk%7=_A-n-B^hwNQ0nnW^4HR@a^H! z@^BU&fbNc44u}L@-QvX`^417R06Bzay{|3Gx42es>BC#1&)kh{95`ugn(ng$m;IX{ zZ+m}cdBB)7evCc}1G9<2tWWUpV3AIrks^b+`c7Rk!?^qK5d!KELoshU6nf%i(05SZaebw}eY@$qbPg7IzpWG(ALi|t6! zvY=>5gZi?*AUs1r-nZML=o8TwqNQkampDeAqWB^_#f4F9VU#JVHtL^I_oB3kF!vp$ zT#11}(NeO6ku{Sdh*P`;@uo%Y%HlXk5uq6RFFr;(h_;39VHPwITkvriynIkEE+uvv zO5;Y_mX8n)@Ms|YTT{@dD{YPP&hp2vPs`mketpu%e;c~^FR@!Dm210F50_oU&v+$~ zGvm3P+jg@qL*ERJcMkUBQy}b20(Rp4QXh{m%68U=hes#(W?c~3a%$qw$c`j;WnH?m zuF=GxABAK__l(VrWs_oAbZm007=X4HuN{Ogg|iH~(0NhViLeV{Qkc0*BrA?w7Ad|6 zuXAAtTNq*rsSWvO$h{D4B6^&@@!$}wPFvP|*c$)gJ{EyP2;|!*4R)tnYBwZm(&@Pe(=YUT~*f?q&uk~(Aa?Ye#UnaegS+3i4;1fSu#qrNt!;(#d zA4Ky?eMC%RqCcq*rL(&^A!bm_xR{S(G%=h`FzLJLm#Bw;^RBgu&`r5Orkz0EF&?w zQ$&PrT=HAVVp#IRWHDLaDLNy$W1@~x7?VK=Wb!lJTRNRCIhb_`X2rp5Qt*o~D$4u^ zS?$HC3UoAHQGIuj+(0B0|$)Q*FBlW$kSe!GdQ_4c%|#-QR9BYX9tMdMlZF! z1>5h1-WZj=)FCvZ_cJ|S=pjb;NbZr|L(=v@jPJ-Tx$yT8?44C}tIyV#wm?Ebx|JgllS7v~WQEkxt9Hll1xC1&%K z>AZGS9>FY^IijqSVI2F=Ha0bg&+GYg*-K`JNu11WW@}0mruQha=B8p z0Yl`*UGi)4PEo)9%c_Ad7CfE9zRX%J1HL_pSv5BbHS!VWd7jHYq`hi|^4nE=(65flo|?Vmf)& zjOg&7P{WKM|4Cy6QR&2EqGGQf*og3~0ilwLF7}|D;L})3*z#|HhrT$OnP0r}~ z^h*`_Ge-9wlsYxJcv1Dinv&&Zw-Eho;4OJyxqL_7%D$}XC6$kJo-X;VZA#3Y@VN`w zpp&nS>?}91DJ>the1ezSJH;_<6yB)vSiS*If}`PxGCoqDh`2W3BqF8-We4R4Nr=i7 z6w)Ci2F#VT9U?F$qi}@Y8E?cQ9Esqw0vR;mhlN@?3f#*hqNZ@Iui z7&oADcEZty7TKcynh?~~6+|lm+^i%n+V=4BPiud-*QMxa{ z(^%MO#KY|z7S&Z3)I|yk)8NY`n3WHS4y5>qn287Ses4SQ9-f#Aq*9~1055QlD`+1? zs04P1T9ytcnxX&#N6f=Z18aAR*g>Lj&^__L);_;tXkbV}2DZ@TUhWj+7&Uq2k0w9$ z^r~kyOHLkS<(!2TZ=aq#<7akxmu~XTw{KPcdwF)gj z$bxiepkh#z)G;Cm(NihnCV!uUH}Hc7Q4mNP(9l1MlIE2GA|(b;v_wR31=%#u+N(zo zE#5K^sY7);WMKk3KSJ)A4XHPOwfr@Cj{IX0vAFS4JVyGsdAH3}{p#%bnkM;eS+?C1 zC|0#tKjF<+zPu}!Eu8uidd_>-5EpePWHLk;B|I(sQ6Coll(vJmt5yuvJ*6#}@l?~j z4;!L0k^QNmGiCqM&xpu;Dk(H9!3?Z6B5GlL4p}w!#ac;W^{zBTT63T zj=Wob_ci&Gf3lQ?cMCU5U$2xK4$s|^+wuu5L_*xzJ51b&$WDkCECf(g zr6u+!H}IjNgFcb|;?=J<$|thzWJB6XOZOR_wEtETbWEbZQJ^)2~qCrOwhrGEn* zjuQ|my;D?ZRM4y$QQ=`>p`A5xh8dd92$<;C)52-#O|V-7rAJcls(dI#(tJ}RU!5(> zzA)+kxZF8t?Quj%&%WF8nqP=?&FqgZQG9fn_FYhf^!=bN2D`T+BZBDL5Smc*f|{6x zGc*yck?*O&w0S&l?UMR%?S6&8SA&0Awaum2yXAlQ`LEsy8FQP66*VcnswN{)(%zPj za(DhDO)r1!qhIHZ6d!`+3ekocT|38yi?e2ghX*1cGyET7fH%B2Sd8@v+^uL6As(^! zIa{PL4~!6>{a2MUl4kX#WAYHcAn|g!mp92VsnF5 z2Gs;f(=lB(co05V(J`UpppHN5_*O@4#{em@!=es#9i)RDZeZe3na=+Lb59@enM9x) z5YV$vPj4D7-H2TBOl;LN6DjqH)P6I4R|)>@nvQ2jU?s!^$e|m)meIFE$I#erU3GCG zox8+@MRdX^DDX+4xajD(kZ_GQAW|0~ESV7yi-}uh6$ji|{yBI04hbd5iC%q*Shtbf zCo*817%&`xx24_z+5jZBe%o(Gu!JAU)$;G3T;JRN+upzHwztpTDXjY_wy?Kc-;FKk zE!TY&^5+|Jz5JgY1H^elelw(INW%~|TfSY~P;4_alwi3D{)Gt?Yt=_T*Z@zYU%UbB(X>VBv-}Ab+93X7NN5m93fkHpl39NfJ`7>~c^<2Qn~6xZehLLt7}y%4`r-Ic&bdDg4=wFJK|z&Q~sxDy`$E%71n zayb@Da5uqC1T`t3X_ya!ip@aZ{r=drVm%iaCjyT|U{;3Q0Jwx#neYm(Efk7zei)C4 zUZRuguS8zJ=_Ar(%?Wr8@uq}7h47dIEd8%4SQT)*@4uh8aR2?JJ4+$GQP_(y2-q&<+)BYyT6HLe zUw;+9FG5lzz7VCh_b$f-<#N#YDyOzpE9iUftvb;PD;r#*r@h8`v;?}Q=pgZoFdZaJ z^XgSw8p}|#6n8F1y*a2?gdJ7NJ;Y;$2d@E3qPGn4Sc=-Dn@<7zIk-pptL;4l@Oyjh zOXb@4U>fK6!Ab!xW#HE!Z>uQcvQ{X_LVI~ycm^8$JkA5rI!U7?LAZAdsTi90pnnWC z0`Yb$NC?0hxiHvP0dGMB1V0{u@i!)2q5lkUpGLh2pq)YI=Arxwc*)R;u>cF)S&8y0 z9Fnk_VLvQBK>mUtVV~zvfr-P!G(i;8#dL&6A1)5Zl@a17l%Eu*pgdJX#AY#Dd>Q3@ z(SUN1=tS8i)}mY|l?hB*B9$XNuu=0XSkE1rx9~OIJ(}O3+^9K>@_U*SD1WRSC`j5A zZ3?2=4AMS_a*hrw!*m(CX;=mJLcos&7O*~GqaX#m5rBwG0ly6R70NpT{uAYffJT&m z8}JUwhXMdI;Jtw3D1Q`i0_BebZ2}9l2YLi4ur_F{z=FmFy(maQ(}Rc`8gPhsCJG6_ zzW|gPI2DAy2+WrVqUMt37S6Xd{~Ore)!aq7SquBGm9Pp0v8}WbILBza;@nLeFNj(U zi*fFy?S(77wY^bJ*7imD32lFr2XIOUX@{Vks>K>NZMqiUKGTlSjzoEsb`;9vwNvml zv7%R%{h-Sa3^E#U~%W6Jt;CQQ1YlXO5S;jl1Fb>@-7}h14LNwIOXrujY>Y$d;ci2pcC=?sEdgH zi+oHfo{vvikG-b13M}GEq#n43umfnhf)PtOj7dn*g6Nunya5T{G%@0pEl>1&UnDGI zG7j_RqmWYy_x`O%J`pJkDF+D=MU3z(j0U86NQ(sa>l=WNDD%FQjqA(scP`S*ha~85 zo8RbfHI;hHbngNrd~3bkB<3{9WBr8%Wu5Urwj+BDG z>3+iRFw#-)wQOFG>MHdKj)IF)Zx`x)-*f`^oB*7e$WJ4kdtjpH&~M1abLE4p^^UXU z>D3b*7s^LhXE`pHkFU;gTr1D0p6Ad4BaGXLxyW z^)hF4`TT0Vvs-yt^%`eV`HJdFXWw#TwcVLgZmFK=9LCF|${i@{%j-~cV)=SJUGZP<-4mlI%k(R0;ZvSU-cH}yz+z9+ntNbk5un+E-OD)-QZkP zezLj=SI$%)a8{O|uRiRw^E#gLOVvl6>&mZIpKxyE=Pl(os!uz&m*3`Bnyb$_cNs-M zTW1WczUXW)hN9fW?>%6Qs=nepY>cbE?mTKttiI(uVN9;Ri<$#a=d>}^Dmc#>M^tZj z+%b;Dm5as+R-N;TaVa=b!2uC4RO!ui{tC));57(F_{Z zvz5w<6pS;iA4OE7Lmc~P75 zHhx7p@3i*9uNSO&E*U}q)H{e0)WR4%`29ZlS}rt|Z7=SJgxDjTm^^Iajv zL)HxN@O|qPaJ%g}9#@X@>xwK6;pyv8zx8~ImoMWf7a@H}%E-&6!?r}nS<_KlGB8|f zZ3O=}TlYa9pu?{8@`KicuFe;TrreW3{&NaUBZj?{(>!)o4P#)#2L)Z0O+fRZ^ zi@chD61uv`bPf`{X}SnFm8OZdRLE|Rbv?>g&|YquvaA+xAOp`GUw#J9%`iRhMxVroL!W9n)%~Na(oafBbtYuDvIgfPPC{x+gjclDM30JO|y4eCz-en7=viG{f zdBvP>Tk1MuE`}VBRpyYjtekE;?mX9~JeyxP@ayxa)uYwKJ1?3v4lCq-wZ`GxQq_yB zbX7lll5-ce8qeK|L~DGlP;RuXa-B2=S~FZ{6w7Q(ww(eMRHupRcn(x9vU?n7E0@{V zITx9?R!{dFu86W8^c<~RW8dhwSy^e{;x4VUbDOruJ{x6^eY-Qba-Dq_X=(L5&k3^3 zp3`KnJm)I*TBmp}R&KO6I8!RO*qfXU^jy!C%I&sOp6ivn><64#l@0d8zyUpi=T;@P zri+yaz->e2Vc>AF(vL=xrfUjG%{9$jhL*AnPsws!GOw_iT~~2M?_6d!+N`b{W{b_` z%rQHl|F_L`wzaOo=JmD>=vjELX9fbPm1kJfbFyu)U7 zi{{;cxy9UQ+l-!ZtJUZZH1D%*bBCG_+IFIy9<=R23oW+obw-D*xq+1o6p;hy9byrReRj2zu{DkyFvu~-12nWUdM%sK-* z7t8mNju|JAj#Y$K>)kVPp6D*9I#Uy0XRSJ4)2q&946W%`x3=n1&EUEXRaa}$>o!;2 zs2N?it?G8o_`01{%{3Wydn{tjl)Al^z?x}w`z@h0d3A>@Q8oE>?^hkE5y&#zXFC^F z9jnoirLt~yZmc?46M|mseOzxaZLf)-7KHLTvY+l!OI%H{^OhyCW9OS2?5MkDnOU>D?q=0!vRB4KHI2@7 zz<(d_SeKq&qiOc3%=iaM{2!+Y;1jB(yRJ;ma{fj{UXZ+$B6o6Uf+`YdzQ=9 z6YJOD-s$y~rmSjx?KJWv>+OoqX1V4VTkoM3QNIp451UVR9yXu*gwS4KSP^HnxEH`8 zt#>Y}NQTW^R(^z^kJ+xdmsSk0-E^-iKWV$;HXApSuV@Ul4RBj4qHr#)Nag1d&^K4b zSX-!jZ3VD(Z>X3In43)+o9x`e@AANxKp$O^ZSCjYR*{QecUH_qc@J4d_uleLR`hFh zcI{St&WZxN#=XCy)E?|URIvbU{QZih_HgIXidEGo+{Y`-_GtI1@@9KCSY7p;B&+oTg5f>6gd?)ZK0m&6?g0@p4k;qc#1)hdxebtWnQJm zzQ_Z=v^vLmpyI6U0ztD~aD`L`+n0HkRfgldrZO7m%F1r`H6D9ql5MZYQ`y&E=~-8q zVz+xXRt~dfc(zoIvgUibRqAan&-TiRIPa>2SLSI@&hRJE7kI}J=N*$Vf@pSR)93)& zwayrdbCaTV6+5k0>vs_kXR?Af{ekLmN2zmT zb+n_@yMxRKReyyrslQH` zcn%PR`dh%{X8m2lVXaV|WFJ+ZVjO_$r;Q`5@oRM?g|#6Br*^RSeA2PNZKgI}JFU7e z?uxLOagG6p53Y?bzv@`JwpVqEEqiUh>S2ymYX_5mvNpZyye)L?Xn3$R22}Wi@nEg4 z{D}Q%Z3wmB+K9@dD98A`Wg3N{$E=MfifViDaz9=k%**M#Jerrs^Ku6H47F3pXQ-X# zU#>hs-dE*m`w6GL@*H`{l^3b?RbGKz(o|kYZ$)15vf4Zv<-upT#joFm@26bP=cB&^ zyiPHdfe-wR+WDkiwPjTT>PJ`U>=+MLg;ZzNuBeKzjjc8EvW1r&WXEc`-&?!BDhB0E zRq?i^p40sLR+3Kb4qo2P%Z*+?YOuX8S~Nz!wfm~l?R{$xD*Z^SKU{l6ktTV+wa2Jj zdy<#W@bdYp@vw5ksxnCHl(M;u%J6J4Uapz~-Qyl_?ImNBb!+Wa@&syc@bYa_I5c@; z)ilyi@^WjNNl)rTT+hPwJb24TtMcvVP%gG#M0vi=T-yu}d23x@RT+)Jt5(>rDBeO{ zDC|IXT@?3<<9Iodmy>yU0QqKhsbnSUM)2}jUY@|qlX*G2%1C2*JU8BXn#T2YxumOg zGtC*~msVNGFQt)wU4b#xcD$~%%0c7(syb^tFj?PPHu4c`)h58XShbaW;Hn+)Y`id!-Ngq#|HbE*zZIuoX1Q5>Ud$C*#F^sDj7f1) zcYL)eRT|EMr14TF)-}(T=3uMId}%T3DjB8U;5GE`q$c*Fv`^ZHPu*h!1k01oNN3n9 z5<(TR`I>l50{gWlNwb;#hxV2(N$jh8L6;}KsGFrL7H8>R(Jc^5bc=On@fBT_Zj-oL z_eo~*z*6y(z$Jl8#Iu3R0+)&O{l;mS zi)5I4kEeM>(;06%kNlDlXF6j#Z@OfCaDrYLu?9hj@% ziI?jldy8RS9Z|=AgIUfdygk&hKe9gx0qi~Yo)F0X#ExQ@(MRkfp(8uVJ`qCM8Foep zXJ4={u$1#__BCLB!>$UE>^8OxcENVLS|Nt`hxKtxI3t|rltthym@0(=Q>Dpn@|Z9# zG;J|$H|;Vtn3_xnOovTJO(#sJP3Mpk2i-}>6u+Yw_t7yQN4nW! z-eh+0r_`C(o41;Gn0K3x;d&$P*oRsN%|}2B)4U6Ac5b7YTZJ9a%$>r23Qr1+(9fsw z*7t41r+Np+6yaYurZU4@o=al7dx*P<2BqZM9FGAg=c4mIjcIzcQGLts@)r6Kn7)p_kab#vh^*PVq8 zF1aSqt*Hrh2iHWo!)xN)(KU(gZZ*m7q?!TlzC2HLr__va599ZZb&sl<;MUhnc2BIy zc4yV(x^rq~x~JC^xM$atx(zi8-1B&Ose4h)D)%y8HoMo2L9ar?xvbU?gKUNSLZ!29d{qDIpsQAbJlga zO}YU3{L^LEg_>)i?rO6 zob-lYk9OU0baSsE9pX3>kBQE9IoB`0>y9M%IY(c>O@YqQb<#W12_(lbcerB|u8|(n zZ+^K$@4iTXJ0`lXaQP9RNKYvzc_MdYxv%@Kk!*>-?Q%zs`<7$6`>ta)bei;ybQ`() zx5MBbMmnhGr1$=Rb6tdfI_9AbAy@zAIzzaS?mQ}|_CvTXLi>Sk*N}dZe33hrp&dcT z@5|SC1V^Pur{2>(_rV~ZAvqh-hS9!M9dXz_Ar6lx!g1P@=Q!udSFe*UIrk|#_0ara ztIqNI-oKp>$+@nz(efgPInLE!bbU!Rt z`BLMRi7GqiC52B9%T+#d+vk;?DnrVBIzeq0xI5N)VyGQEHhSX8c9Jbt+bgw8#}-d7 zUdL-!s4Y6Sd-^$cc?J_K-Ue}>qrsC-JmGv%+YRLHX!4A99Po_y={`O4uqVTD)HB6# z!ZVHA5U&japXZX9e{Yjw>FcEsujITyqVm zUEsLusUw)K)Y_%45w)vaV{6T>3AI+&ho1Q?*C@rrHGG^HuxV&hGi} zQtg(CpEvi}1=U`tczbh_k!wNiPKVbXx|Y`NAs)C^)$VnfYxk=>RPpfHS@k*I_U}yh zoN-xe4=r6=`#zT&WXJn%(iO7ruzg&wsDFe^oMpAilt^Brzb;qpaUX2z&!HEtwY8@R z7uCk8`sx%s>-lxkPfCFA)Oj}XYpB1_Q{9jHg2jhCTb&`E9nJ{PZfA_A(HZaAM{w18 z&R(8_HRz+A{X9pw%_F-<33V2n@*Hyx_M9ZToTEMG>6&xA=Mvc^U-H&pa@BK{+P5>q zbHh2sbK5!1)68u%*=N7x%&Qfh`L%(*ev^1X_#l-Ws}1F4=(OrTIE!neobzkr2uE&f zsjZT)LOKmyCLN-r@{;E(Y6pv4!dg$7Otx;<#M2QNIWOGkbk85L39nY5{*6|2zXMx z1)FOx6OUcnYOfI<#9Q9}cGlh`_&#``)3vAe4)0HiFYRCxT-V-OnfSqV$qQeVC&^ru zw`+f$(m#{#5iH1x+P?ED^bNRjz4OaedsfrV-%$OI_Br(lPOr_UT-9AQSNja=XPr0P z%hdL*wlmf5X#cl*-Pd=ZU6W7Yvn8tCRCBM7@i5;*?Mt~|O#Jlv8a`XA`XFkKcJ1`` zK@ZAZB7AD_P0dyNqPEfd{`UGK?fnqdKk?<@lPj>*A5r@tH76Uv+h+S5c8vTu>iZ~n zg~GR|_Ch{B<>cp+pW@A3QSK~)sphKhq53Rp`|{z$vE$HyDgKB#S=9lJKvo^@@my?~Jp(>|$v3UePKM$`YZS&+q;1)nAzep#gyl{p;8m_u%Ek%EOO^5(TwBwiB;!&guiS{7 z>SinV@%y)+Ot_ep-ztGmCEbVTRyH9WKpFHrFiphuEF_}OKM{TYiFn|pk7&Fvfj*+q zmp~uUS$SBYh45^jDv#oKqJ?PoODfH3UU>p=y)+Zu?Gxt{epho&Gw~F(b2;MK_vN6O zo=vnrFbBPaFUg+g;0@tOJbGjf{owTOI9$k?>XY7)PH?^0 z<%RKpypr?}*DFZ}4M;?DySx%Q>AOby3m$Vl_RA};1I8^}2OgEsxBGHDhjfti{ed~2 z&-Jr?z6kdaPLG=dSFYR8FD_r?)Q-50x66&2as4iSSMO<`t1yWF#M1$&PwfkBg?Meu zwcM!^kk3S((Ry9|{r`HNgJ(UCjy>=S)r9(ZGt3tpRE3RcJiMLm@%c=;a4wn_=MQyVx1}Pq8(s#RZUsW%Zi8n}U zyCHd3^+Otr>uP(TXQm^KMjEd?Teab&(^XTDrU8Z-d7hHfbE@)DEqvCXLON8Yz%=f}->7dXMOuKg6!k{ncRbs&3UzS5Pqzqf;Odi+x1Df3nTWba@f*>J z`_Bk1vO%Y=(15DECJ&sXoUfWHT|q0RCN&bcOvZp|442~#5=CEkm``u zBW*(3s=%c>yxtDn3%sg!<2qpY5}sYvh_nw0bX6Tu?yEY6`mjrCQtMZp1iWn2JA-r{ z=@RMy-}b5MDt^16)TR2|KI2)u4cu08(rMLysA>ieMAQS0WNUdF^~!_mGU*T{FE4o> z1vrq6B@WL5y;Y#mlIVrK6y;=vcHcb%a4i)HJh6;L0^cl?@hp1I72Hoa09Q*cV4PMG z@tyOq6m`H4;scijXeJtoE~0_tO!X|saeX)PQwko$TdHq4tH4*`5uKI`xCeL=PujyK zxR%Sfj(S{|yzo_da+%iwCgg3o=7j;=c)LYTZJ+dwKd)Wx)6>}s&OU$RVSneK9(d)` z*@yjo5%s_)wSBAY>^t-6Uc9}zYD?PZ zjU#eUVOhJr~ZlbL(SX!9Ng!pXSkGS zsW!!D=dR;^=#}qp@QCX&>0=Yh&}Z^zEH{<1KmYl71N8Gcpv7_s>3z!`8i(=SGXGDH z!|+|%*{$ya4Fy6{Uc8|o@1UX7u)wg?u*zUISPd@2S{yFJ2E*pOeTHp@owIIGnt9H! z)3C>|*RUUTT{w2)*pGwWE;6kS9H4idy)Y6@#=#K5t}m|j!yzF$!T`LtPQlJJE#Da$ zfJg%)u>WQPj*j@6$V4F&Z$UGJFkv!|aO|VY5;_S}gsFII`5gA*LSrx;UM^auqd=Bit>_>(zAvs;3=hPfY2@hXEPui1HaC2 z8J&lmc*?gIS?L!wQ4Qd^6%yV}T;Ui1n#!fe%{hnsxOU&);7W0LaddIF;v|(y{~Xu* z`u|O3TuUh)c0YAQEnP1j#i=6-&lIH=jWDbzaur^OHsUB+TX?HzL*d<`&8TfD+*Py< zx_iE8ry-XnZ(Tqgh@uqhR8FSz}jFW&dk_0SM$>DxxsV8(dNJtNM_31=(*iqIyg58+?r-6 z=1+pQ&g}~*^n@wk=LS3he0=FDxIs@lLI-iCB(Km8eOYf|6! zEumz^j8i4X5=)7rq^<4?&? zr4vdgmu8pdmd-3KD7jHuYM55Kpmb^JD&TH`JtC{q2#OR7biR1{++n4mb4M9A%?dX( z7TOE#bMaaM6o@$}-^WHXBO(8#P}L-9Pc>;ZVLw>1tI*;hf2 zo|RSrVLz!L6x1QD7orN*7HlZkT(GTRXThF=y#@OV4i&tQ(%ORKD4i-eTX3P^a>2EN zo48X%m{}3`YO!;C68iT{tgDlRAE9T~VK;dm*6qx~5sB4eb?g>BiG|{sLcunqok*Jn zp%8mL3$a(V5PMV$={Ky)DcFOw7iqsYr@s#&Z9sY-={V9Uq_apDkmxtMj&(f1ODMR5 zBm*8+#1#f3h2w9)D~v|!<}K58N=Zl)k+P7mAC{M=Bk%hI(rnyA$$*6Cv`O>uH>E{_ zzQBxQRbk(!&lIKb+4y|2b#ooS$=P&Q%;Y=G?~7Tp$(%7K9c=(O)RX6~rM= zM4ntQpdhti#GI@6b!@=|)SO%pir=yeatme_6cm)=I{h6w=PI}!%Gb~eJZ=Ev>t?ll z-E1&lH`|d%42a=T0=n_|0Nr_HfJ7b>Ac;oA=92HIoS8*H_ZsE8p++|TXGq&{JHQ19R`2X|`&QyE@)Nt=2 zTXgR>TYT>fe!b1?_ikflssSa`#b2n;mfX9Dnmh096Bi<#MmmFZ_TE1HR)HD;fS3(i z77sfXk5NWE#u@SWhDE&aH{eIVPJGC(2#3yo0moj4Pb*v$g6~}v1CTo0yC`+Qx4=3A zwkWO;;>A_Kis5{X*F27z$5Hb*Y92?;GpKn6t7-v>9iV$a-xD|l;bR<3xPb!;ma!aG zV)-l|Yiy>5_bt< zVx!my3$Rz*D|8Z@#3ms^d`Emoh!j5%KM-7Ww3y(i2f_0{ zboBtr7j{aB0pKs?GLFN6&3P+NS)?DL|jKBUDs?1 zc|RgwGohnVQRuAGT4KuQMj(rbndzpW5C9-j4D5|DR`O z_TIB2B1lO{h&DHINt}cvXsK$Xnv$ljrJ97g#4R*5ZgD44t^2hpN<>7;p(saCHH4gV zrlG->QjElP7bQkSa?bC)KC}19ajAa$f4%<6Ykk(*Yo2-Lndez+J?nX9&fXi0n7P9S z{2b?k9X4o)dQI!ov+!0!WdD0deP;IjYxvaAYOiUVX1$}K)!xx|8}+`rPftqCEOhG~ zZJKSGS;_4-+HRwUrJKdpXPd>t&Kb74oEZ&2WZ3Fq=SaI~vqi|O8;QOaJ!9$t?n~(_#sC2-#+Jrt|zTsYG?Modf4iLvqm0L8aHyqmTiO2vvZC2 zj)t96Co4N}RztP)&yg#l)2WraZdkgNKk9HJD{Uo=qWed#7XZ6o@UT?W^>ltff-mbytZ4-{V$H?le%U!y6Ij+n6QTMDf-n4aF z{J-)qTId%)uY2Y8i*u^`$@Vkr|A#CaF{}PRx6Rx}&3ZT3#Ov*?*B*Q8L;Z*?=RoH| z=RxN~7eE(6e}!V`NuuWW+N*xl9{XLPeTie6K)s>OpuW&IA?gYSK!c#c(ALnl&`|1F zhbtyrF>(7*+s~m%&{5EdMC)lp$cWh275cG7&3gMNU7>V^(iL|&5&S6lvF%yCEnY;) z>C`)&k_jafN+y&_C^4P-rV}OYJkDXas6b1)aLsvW9^;Nm5K);qAoEXwFMx=)K6mbO z=l(O$^Bk){OQBVqzXMmSaK(!IJvGgS=0J0~i+S)np+@L#=ssux`iG%Mk*U!wgr4K- zA5vS?UZI5*u3q(-uY7)!(LV!zCNvBA28g=-d+42eq5Gi+_}m0hkKYWnQ1*Fv1zHNF z&@$*lXa(gnXeD!x&p3n-cOP_xx@PST>)LkRk@PSH|hFZjXO-a!<6~5z)oKms4Mg4uFwQ;G<6T6 z?m^5{UsE4fE?}o!+G9#(Ts3oNaiy8i#mK*bUjn}rx(xXW_;vJ22|Hbf^SG0I%m7oYQ#`JYcUt2$?^mCPO=d5K0SWt@fq_UF7xWgFvHSE_$u$DDomoZk6VihUY zkovcAEVqa%7Gc(q`VYYuQ0`&u{t@`2@Mqx9!dJmRBd4&Dx7@-;e_ePFTJsHBGmzFa z(!Y(grjgb((waGV#~fPINNcLJrb25P>CZ-5Gl$kR(V8Y&(@1M7v}O+W*+^>|X-y-o zsnD7^w8p$?4y`edO8v*-+@a66iPO3{w603)=FmE`%c;tGy28nPXk8<%tMGS1=4Iw# z=1DPU)IDUaXJlMCGq32dZmb%+THDJBH6+v!b6-u=lDL<#lh+`6+GVmAWfe zYP}tEe+gGfxJpv%?I!Lo?M?D5?8Wjw?k(x) zd1Z*StV+u&wchT?82!oAatgh92KSBS)9Y3LEI1i0ElcV7DlMz}_wm_m;m`1g&@bSe zy!R{rq4z7b-mlbp-)tkT*@oE#-$6zHW!Q!JQpVV4x(CZ&%{%f4XmQk{oweUad2K|? zI>yN&S>DckoGgM_^y(Z}iCXmtC4bMOw2jd#P(D6+q<)aLbn4?Epk1`HqitK#>I$v4 z=$!kOMdiGWc@!q@%g=Hjt8iy|1SSTlpRJFr&0pnfdGxLOTRvCVz2x)6=c6!lMg5*S z*=6o?1siFNkoB7R0Y1P}j_z1y=UA9Ww>-Y)(XAe16Jl&aj7?aL6o^&Wm^Xkr21DEM z*NqME;m`>5qv(+xp`D3`7oocnx(d1)x(2!yx*ocb<4?gCLBujIf&K}-3Nb>S`3m!f z>ke%I;bpEL{xksEfgT@;f9(kEfqoUAS3_;|u15qa;S1|P2h%H~p)t^&&{$|MXdE;i z+6USXIsp19WaW=(kAvf&DbRH8r)&L=nc1t%>{V8JP2>?VtGcQ?iK|ZQbj2TYSGF?T z8M3UWyKFZmUuYy>Xe3`~q@I+Vp^>^$>PXzla3X;_75Oyibm}|<&eb*hoXzob_Op#MWg$f#zFYR0H$jB3iW zxmqU29VNPp{0TB+7BidEK!aF>x!>h=Mc4yWc&9Ob8G0>jSIBNJYG#>dU@O|L4 z!rKqKI{v?C>0pp9`G_oey0AT?l=hm)^|rTe$XY=vIhX*t-py3*F8! z_B6aZp!v`rp?jhGp!=aeLk~br&_lFm0YuK=JpvJl=+!3gaq5ZTPr#pqFN9lEcpBLv zLo?i>Lo3`O#NXh|e%{}q=b#s$7omSZFGChVUV&Q_c@1unz`B}(P03Vx!~4KD zgKrM+3*Q3%P58Iq*ig_PPNWP5!Uw^(gb#*q1>YLJ4SZYp5cp8|cJN{F?IEIgFbdiU z`Zlx+^j*jzDfXvm`UAK{)E~m@QFU)*i>yC}TXg*i+#)RZqA0sR+#>CPaErDF!7bu) ze}UcKMCefH7tj$9>#E>rh?pBp#|PH0N1@NH>TIXYR(AOwTuNllciv8dPlGIbsYi|< z6N&oE=U9zWOH53T-6Y7O-cfLi?-uz^=FC$V&r=!0)A)QkL|#lxPS~-tcw8YKr^Mrw zc$^ZCQ(|#ai^U1CI3X6N#NvcFoDzpq;&4hFPKd)PaoFl%zc{fwXEzoS}R%i}%8#EWX9hwK-0nLa02;B?a z2ayrt@l`y&ipN*+_zaKF@c0amw;7;cFP4ayxsDF z3~#UE?Nz+Jinmws_A1_9#oMcRyX6ZR-k#y@8Qz}Z?HS&l;q4jTp5g5o-k#y@8Qz}Z z?U`e3gtupIefS3O4dFfD-+*rn?*;XN7!|xc!^<2Vl3RUg%}G@YV%oAo6nNk ze3sPavjhuIu)}CPP3D$1& zRZ^R;lG=QgbegY{+I*E@?KWQ}Si8+vNo~GLYV%c6o3E1Ee3fABDb}81?J3rtV(lr` zo?`7OnSX7K#Hz5q7tmzSRakY~u1iu|dE2f_zD_xs_>k|sR9JOa{44p)I>{#nvofsj z3pBC%j#+ufo%RK67sghGwhLqX9*Ix=wcVJiPd4O}3HkZ1Of~ShJJxPrxj%5De6+q^ zxslf5ANI_O-Kd1!sKgQ3-9yj<@}EbrofeJ}sU10)TMQ>sJNAGaw(OQb&vCcU!?9_{ z^Dc*7yQL7hntKWUGIjhD`4!H4mCv>pl|rvW%Q&_i{s#0W$KQg#ja|M&`6{3P1%HqF zKZHKw*vC-DIiJ8kr3ZX^@r!GmBk1iTId&91G8sA!`FM1!^!yW%r$Q$~(>Qi2{51IK z9G?z93pyJjhxX5flSBLG!^xrj3*j@Mi=df&zJhbFfqn=59vyw@{{fkpqa7?_j8A;= zi7oz}9J`Bi8sT@t?_me@Pw4NX{eOlYL~lD>52Je&dJM8rew?y4(oevjqRb-XW~haG zN#Khi#=>VD*!$>s-sqDf`}DU@Eb(85h#~%)`0v}4dl#Z_efrja5B@&<1Ngt;AHhGS z9iKp-LZ4A~4b+aW1Xxu8Dq>k!G`o;ZL0MLoXz#BZWr+X5`f%b=Kz?nzZNbLyp6GfJ zCqte+zU05jQ^0j7u`ZGATh45-ZgaW!RJD^~<97;V<6~oD<6&cA<6vW8eQN!=0Ls0i z`UUUEcR}o4?LO@uS3#fY9;&q8_NUYewRa zLwcn4Bmm1wu&l)YCG-C*YUfV;g-|mi)Pf$*@GB4=Vf*MEyEjF8hJ2NM+?ZZV=%JV% zO1$1*>JJ-3>x=)^57q~?5WC5rGdv6LeDD9^zIhH^o3*)e_7%|}BN}8xg48_?Z=ny! z*XRenYYF}ji1=e8hSyfzyIuocTg7Ybc|?WxavJEXJOe(07LhB|ys^R^Wq6*AZidI% z2xoYljdF&^*+^%MbcVN8{i~?wR_IPX-^J%f_}%c%cl|gP9;15#o_k5YBl&sHuwKcq zezS@U>o?2Du>QJbn01?Vn04DT4YTSB7LsAnRjk?e+|8ORJd=N$JZB5$f&5v*%k&Xm zM_)7%*(_4ouB)CIC=%5pj71SL5xhUe`_r2DC)|te`!?bAb`NH~O?a(&WQs?ocw~z8 zHg$O7I_rYLR)6gmI7m$@1k~E53!;e!AOv8vL91%_6Ec6p*he3h)kW<+6+{w z?Mzpgc`C#s+f}aEt}=Tm+$}TSPrdWW=@N3fgq$w%hC{3)y^(nGD0+dNIxpW5Ojvm& ztUMA{9tkUtgq26a$|Lc9M_D|@BW8LxK=}@#D%x31keOx)qz;;k!CH^7w;Zg8YSkIpZKLh=l z(Ami6LgzylLKi_?M;34=awBvPpV!X%P4s<2Tx-N4VrKnDtRlv*W2`%7)^EfzVyrm9 zf)lLQp2sv|88NedOiZ)qF|lGY{lyqs9JV~kawN--EH_G630PiaIg#Zx>KAuUU01UGCcY`F2j7#`gI}`f!OmzG*0L3{{g`Y&Cfkq6 z_R~(;eq77;<65?#D%)q~CDZ@%?$wRdcQbX|LY=drTOll#jJ`rfUm>H9$>?J;`q-Nf z{Sl%^$>?J;`k0J9CZmtZ=wt888NKaLRXj%7djkF>d?Ea4$`Z#}r^c*NV>0-d3_d1< zkICR;GWeJbJ|=^YS)Zn?O;gsTDH(hErHq{z%UU!hOOMIW<4zfRN`{_x+Hv~oOnnEk zv5{UEw!M244<;bmlZ z8QC2>!`$;~sEuri-+}S-6^QMaRak4sw)*gofFDWxJ`T#Wye6`|j0`U$yR-QvW^Rf7 z^B`7@%q20ITSn%Vk-24LY#A9_=HCw80sRrWi!ygZe?oo?V$Y&BpEr?pWn^6$8J9gH zZ}QozV194%Uxf3fm(P4i_7#(9Wn@}5&&13zG4o4ICYAZ^%p-XQ71!pNxRwJnkvZ8M z6EnxewS1tdwi{Tf?FLqAyMYx}SGF5iVRdD@ffZI)wi{Ssb!EGO6;@Za8(3j=WxIiu z+HPQ_wi{Ssb!EGO6;@XWC zb#su3vP6XnQK7%)rHGj~%* zzCO$|!zRkET^FXx?>lF@Pf`CO>S*RXTX7`Fi=k(c>2IP`OoWPwPBD?G@}+el>un-c zNfW2+f zJSpkqNlDF<65?UruPMB<7nujWjVHZBo#sXVg1^UgK7@aj2d!PhCI8iH)_P1*^BBv3 z&0{PJHjlAPxb88@mptYVSX$jvzU(EIFd`6#rw2WBV*&{5=wwP*}ws}Ots8%|>p@>D7uy$L^m*M}}3zC2x21ef2 z`nebE$c(3Vv|W8YHkVPE2Q@;r{$Ms>*CAyMV(%&CanV-V%V;52^~v>#TPeE_wpWs} z=15s{r0hi4dtJ7kv-f#yZBc*IuNG4{Mi%U|uT2ly&Z5mawsVoPzOdL~@6x37Qc4e{ z>|CV&3W%A~UkR;(KEsRrT098h78ANa)&pIkb)kIynDQ65^>_7Z>r;FFrFZq{H+x^t z=bc5K*?sYO!9{o}yQHimzx-wianD->wLl5P?EkfImF&Si9ZZ{SzjzF^Co~q?3mONF zhxUQK@TLg+Bei$gzSO!ATyZ3xJPN)ev@?1C*R_~@la+7g{T{jjx{>n#>s|C?^ywux zmtO_$$g&C{Dl(#QZ-o8lLF{tW|V9Oz@tPbrdWyZ=b^N67yJ3Jn7lxH~h z#4z(>=t)}tJ-jcXW!MkT8th40M&_H5^=4$e8QE?|rkj!FW@NY-*=tbLw(5%QJLS3LuL3jHF8SpW;lu%P@IV+vnJYq~+*p$(uO&>pnzV6HS88UyVK zjfM7t#zEtueW3jydwyom&M42ywPy9)TmE+L8Ps$pbT4#2rOa=*XI9O%l0*dCi?g>B zGu{KXw~IT!2b__8+Iy+jCm=3sB2Wo{w#9P}YI*ROUwy*Y)?zk+N>wSIMWVf-7= zaSft`y$`(hZMr7p1ss0_S_m~m^wU?ql}2CjZg56~s1hNnL0P?+nOlTW*30?XM4x9YVmKD;@>lTw%BKP@-bxB`UJ8&`V?Bl zaf^E%5xfgKZ|h*`U9}6B66<1R74~-U=iYJDy9jIZX?jsP$8&gS=e*+`^yChV+<(ef zGe$A}+FYcC<1aH3opO+l{DXI`>$wLxSjswx$Vp48wBpPAxVArf1avyod5trZ&v!w# zcCnemW{vtf#d?mB;_7SHAl6$Ys0`KiPx-CzS`RU<_BN)Ct-Uo{e=AdOhB9`U{~$Fz z1b-N+=UD6zFedriu$Eud^U-yX*M+{(+2inq`n%P+=S`tT?wbtN?9blQE@-c6XJ(_F znTdARJF2-w{)QG^#+7Q;#&<_BcX&iqkNHDyV=!OnO^Vy$cqqG1|NV`LrzwLsd90EC z+nW!LR_YA~dX8Nqd#}je6Z-FO0MJHO?e^YIl~udFt7FeS?U`qlReLo!5IP8=E_R21 zzpy`SKee|I7H>-!AZXEQ~}1bu}4_XrR{{ zzQQ6Ju!x2)SVRLB(SSuXU=a;9i)di>UmMx$&&O>yJ%2X7OrxJi@l%M#^~`k+5&AZc z-9rSgXRS@>9zwT(a`p`T8E6&JwhOs*SBNJ9io8CW3{C#_m;U;qBgW;?c5R${hmjyo zDcVLvP5z=p@oqAAkw;nfc#zM6I>)~meC`|r^N9PonAZ{S@`#&1GqQ+lJ)*a&iF+3F z8i{%Kl*s%be?wq0GMST}L(hQQuF-w)KSTNMkUa}%>=bbuHBWuQ@lT=8c)yP~qKSjr z^Iw~Jd?_cee1MsVIG7O!GybO2X8U?(a1Zj@+$8T)i`w~W#af?7ZLLIVcaX0}Y{l^) zXWQ!HVL0Be8TDiM+E!LOMeY3Q@i*un`@5_B=@ov#Zg$7tbJa5${$lkqVgWx>&Yi8p z6RGvE)qwB**^=mC-}2KHn;p(~`i$_t!;#(jo1k9&t?v)$`5*G%{^oWszO`o@-yYDH zZ}!=jGxz6zf9(8VzB}j;{txCo_uuf>-k0-#gm)!-VI%oPpPTrVpPRkgsBxb6N4_cO z9{%se?}FUVU+_M_|MC2u3UB8UHJ{=aa~ARc5U+**KlgZ^#or|@_MYW8QI>cw^EbS2 z^8Yw*rT3Y4ytjt`zx3Lj^QOAM@tgH7a*;R9b>o{1PI28`ckfiUf!l!JukXQMCZFy$ zb{l(VxL&T8H{EUOHucVQ{oEk$EPjtktKXa4;qGwn z5AH~Jly|c`)*b83*53i&>P~Pcdvn}0cZxUPo#syW?sU`Lbg$8!<<9c%=I?`Nc=x!O zZl?EuyVzaqJ?MVxe#@^RUFt6N9&%Ukcf$+ZHSQYk5qF)t&U@7T-reN=#m#neJ)XC_ zJH4k}qr2Nn+`aBzZ?S&!=NZ@J{^C9B9%py)Mfaq8%KL{~#*z=$3e|^D970y=Cqt_p0}%d)+Pbs_qTl&n<3} z|2KcJJKX=fzr-EsKkvWjCj0;J|KX1FU-naXyuZwU!=2>g%Wj&#+F#=?2)v-+X7Dw~ z8@b;GJ%jJM-}9?8d%A_e*kG({3HA#1a;?F*V4UMQUNGMME!a2M*DVhA5B7J@1P2BO zx@Uuff`i=OgP#S5xFx}%!J+Q?;1|I!+zY`G!4a+!92FepUJQ=r7pIo;9n5FC*GfZ5 zL)`10TXS;Q2!3C9pzv73_EEwnVODqwO+U%I2}{CCI0OAA!eUKh=S~mK1NReV!m5rY z;Z*doq1U7E67rmIEZ7vzlHRaMWtzh2$YU8>=Uxr@b_Tb?YVgaodhBSbGO;vqO}?Bm z=N3coG~o-v`-DFcwhLPg-3(!_Z=w|J4!>r6G~T7|2C!xdPrZDyj*R*!;VshqprzhFfVEPs*X+; zPE?yG7JH(fSey;+B+X8y;f_pyv^4wIFxME~QnY*guG-c^NB1@ierIh6eklE9yRN6v zcYCX^_E38sE^cjCl>DsZkJX-bY2KISU1{zUo+jK$`VCcPW@&+1NYB#`c3(%^(O`t+ zAu4&TO1^8dYn5hMkr%J@Unlb$q3 zn&FZ?A}-X1EkqXc&Ko=@Np{> z+-@>nMr*NZ!#xdyRi+OQFbpQBe^Q;bwaOo)_Ut8jw&XW-^cTWW!ku*1zQT#ZNkUK9 zChR8cCH#Z%aN$9Q?qT8EhF&IlOX2NyMYmjdfML*8Z8*e^1{)gspGfYeGOtOqljL(v zcE6Nnf5|gV@2!z$yfhV+d{y$hk{>km*Hf9?=KD%M$a>hND*3!&;SAv|!ZQtno`q?g zdz94>9At8MsPq>K6|w#G)nn>yzpM0D)-1t%?MhkQK>6uzvWjz~uGBfP_yD+-lVs0*RZnh#kIOzM%3@n}^`nKYvj3xn zQ>7Vg-s(@)y^L0mZD{AZp``=3i}S5aaHDMUM%mbny3>Nry-qku{dt!ibr0M9GRhWj z_lSl|v%+Luag3pxE#Ev(=eDbVZa3Mjlzf%SR3uN7{H(4%P%*HFaANUN>ReAPe^lqj zhQT1!xwGAid&}Bcdc-uP?^zASnTCan?P%c))p?)YZ)uuoO8ctJriS4UhrE9G)P3bs0tN4mtrFek)q>mj9Bh&LMk%mX8J^RZ;=j+^eRog&2>K?VT{EJlc z2P(f>CC`)9HR#;^G!~hSqx-(;-Jh&g!R0Emt!g+|XT2c&iJ^N}^clO%uFjHH2e@n&m^y>EU$K6g=Ve zhCz2jf37q=42!P{yGf(*DvUO{v{;%3!%#LEj@7l!Gfi-?T02YfdD8om=NtOR7>4}} zi?da76P1zI2V+e37f3(Duy~@5UTatwXJ?gmR6Pq+&)BePZ758$J2g4@i?FMqe~fUY zVc00#M3@%trRH6Am8qsF?XLE$(9y}N{{YDoOb(Wq9DHa3jYu%X$`@|Z(O4ywDFy#DnY*_7$X)ZPN^KrRHM`LN!tA&?Lj=p2aXmVCK!_ciTP0-h{Fv!qftgD}@G9#tg z(PY23aHw#p>BFkY#TMZM!qW{4(+vG9g)3FVT$9P44QER~*L*XaY;rhVI6?aNtb8!V zIt)G$iJO!AO-+YYSSr6rQp=3%ykHnTGzA z>ML1V(Np<z_hTgB+_?|T0*RV1h8V2VJZNG?|M0kR5PWucrQzUOLjD>s~A7@=D z`B>p@!v4aE!b!rP2+ub3?r-Zs8`c>5N1KMd7t>!V&1jQ@8x8&ab+kq0KN8+0&2r&v zm08y?7%0tHm3dbBUz!|TCH?!7b*(tpRy~O3qfzKWO8quXBSDI_q(r)z3?VP~PW`lYZy+{U|A~@ekBl@2bptIx73|50~aq;jdIC)m5H1xp0^87Sj|?wc3Jx zRPrd(1P7TM{z|p|UHbKf8U=rf^n0`or-eg=fv}IE+t$!~Rhn4XUpPxR%FwNryvG`g zJpF|~lV*3}&)Tj~H8EFf4sfH7rmKk)gkxjxM#ab4O|fzi)bXjn2(u#cIA=!ujV(zecTHuCqQC z-p&&S#~WUt`;%dCxs?pIRSoBAUihV|6{G_PnBj5!$5m1!8mEI z)9UzmmD$}iZ7=%EDf3=o0X@?grr^DWlfc*QC|TwG;27b1rZ4PcvcF7tjPw=BDp`z8 zF68)A)zB!MY8WiB6-0Qp%Iv9g-#08xlH4eqA>1oGgpwm|r#d(_+y;4Gu?N^)nx7ZD z(YNobOm{#vOw!gyfW4Lfyfy|2U;iY`=+u$uUC#%e^hJ{U~ z|DE+b8N2n&euZ<8pE5aUQ9m@ArZC)Of3a||u&-h94~B*N41>SutZRjH3#U-q9;Od9 z7Nxx;&k;^l`6bpK)^6XT%p=x&!H){7z_(2A2i8J=f_n8hl^m)5>>m!I=U*#WZ>+X5 ztV0bCH}w7~pZbSk(AUuAIpHknw-df1Tqex(Jw+I|LYnUyI?Y6`r{up1TXMajr`&*V zV7IGm#4|}OL~>vLy1@mS{oQlY{KYU_YRK2?f-Y>Ek4D!j{=_teJWILO8t~A;8R!q23UjMK(p~*a<;b`%GX%4m6 z5-e2YImR@;VsD{`$ylD%bE%ybj4?SFV{-9)9aa1zgCZLRCRr)z1o!gD68S+hy-s@+TJDbp0UFga{$9|jgp z!+lwsPc{rTGz~Mm$%7^LGIWQijB8tj{IFqgt)c&(aG7wW^iw4NUGhf4zBTzRYk3r-?yWF?x9=RQTHbuoo?vvlty*>yPNE_8V297qebQ3VSe2|tF|TbyMoF7Hp0bL z-ha>JP*#TxSj!Jp`G_KyaPeHeu%H+z#A z$HNTyn>52cg$oUx-?jwJ!R_6_H%;TcWSUTIc1N0~xVOrmV0z*t8h^GlOC?V-BtC;d zV7O*U_y9Ovc(1U@uziN1=Lts>L0$V)$%AyXQ8=Ndxs;<5LU7F->8k<0%sW4zH(J;b z&PE<&&&sKD0yxd~-rK9;KGHOTJ#_9I*G8KM*)w{OHn1mbxVIta@@vWDgoYk-k)hS> zg%#l(A-SU0U}f3{*%OB~sbzF+4Ys4}dBUGse&|iJquw~vv?s#YN_xi?SJ=^-#?I1H z%QijxZg0|Ahv~Pqjw|-$=*7iXRh}N8&Y|E3rIp|~)izFLrrFM+cauGp@J3ta6nfFFyS(ww5>Yagto*IPvNwbS#;e11Xjx=uy`x}Go_c!z>7zU@IPqdN08s8327M@EDg6+Wi^JW29N zlJAs!r^&@_gu|rI4E@!T-xU5@_?lrbM)Cu~7Y(s7tAC)O|FZNNh4Q^7mo>i8VQQOt zsd&E0(PZ7x2`Y1wG~Epg>Z?%i9Tnt3g_Y7rLfvDi_niuvX+p)rqIxM37DCe()rR10 zopp&}Api0&<868NYS_`o-)&Y6mm3x)OWseoi!|p8uQv?38~Sq$!#9Qf4NF}Ni^9SS z(!VBrMfh#Q!iAC_Ff0v}{G#w&;hw_BgpV5rFH1hj&{q}_J|}sC^uIPNspe35MR15| zf~SRJRHm0{zxwwrX z`4|{3ki3QT%6tlW8=f#tX}ro@A$f&i)F}B|h6UYkahPQ3!vjqA)t+#c^v#B$?v5Q= zlTR>Y#b@$7p=Vgg`)X5Zwv%Qz$$1TVo$4$91JnC?kEw-0-ZQGRaIhUMsvnAnOIDph zQD-d|stpC{3u=F;(FrtCVIM0KUM+mju%yw9)MJr)sW?POpD`@vZBrkT3ER2q!}7f* zm(~B#VJfM6DV}d~G+9S)lHA>}pt}fGLl>f zrB_RWw^jZU!$7v$KFj9KP;a~h^7@jZcW{V#bnvv|Krh4MUXm5hgV`n*MoYg+`WvLV z-!M4E(9boRK}y@3rqsrQgo5u$$z(hP+PohW~--ebpJL zZGq*C>(RcBDtS<8irlLhGud6dp)Rn5F%A1f1HEqu=~m~U88oR8FF zk=k4wqB74I7V{RW55v4S)Q4sDc66A^=w6EFn;cCxEZ-!#yJ10h5gsd9Gk9U8 z^0xjAew+7N?%vE_7X^OS~Xl6gEefinm0UiMK|V zizm?)@aAw)bftK6bd`8ZbhUVEbd7itUF-SOavh&qD1E(nbM!m$mS~oEYxH~ZB)Wmp zEzym9YNhl|;?2KK=uCpk*n@`q1_lUPde-dwv z?iEj>`{33i_lq}2e->|v9uRMh9u!ZaCiTcee6k){Al@83EZ!15BHkK3DxO4tQI9;v zC+m^FiZ@4(i?>9vcx&{8coIGNUwY(f?*?yQHdkL?3$NP}q z!Sh|0=ymF`9$6;d94!}biQW)zjouVbqPNr|Z}Z7|ydJSPxMH+ zDBfHyiMNy^@z!!#JSlgv9x1QGCwipZRlK>pu6Rqin|Nz^J@KU6-Fl?FKA-53@&@9~ z&puC#4Unphr!l(%STO`2HVPLh>ts7VvcBareI tjjTx%%cCS&i*~F@6B+kFf9K`73)}^)`YvaL%rdZ6?<0Ri@k@5{{{WcC_$&Yb diff --git a/themes/classic/assets/css/c1a65805f759901a39d10eb854c1dcf2.svg b/themes/classic/assets/css/c1a65805f759901a39d10eb854c1dcf2.svg deleted file mode 100644 index 3ada3efb..00000000 --- a/themes/classic/assets/css/c1a65805f759901a39d10eb854c1dcf2.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/c2183257e7a697769df4200c547551f1.woff b/themes/classic/assets/css/c2183257e7a697769df4200c547551f1.woff deleted file mode 100644 index fe87166b631d66fe589d6e89c19e12a59232ccb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219992 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


    TY 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%0AFb$>}x_earOL5A)-Q@RhC74Ag$OAOsF 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

    yF4O}1x^>s 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 fGZPE%_tx41plg()>u#pI2vmre}kv$d6QWWEH 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

    >aT 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℘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 - - - - - - - - - - diff --git a/themes/classic/assets/css/custom.css b/themes/classic/assets/css/custom.css deleted file mode 100644 index e7e4bf84..00000000 --- a/themes/classic/assets/css/custom.css +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Custom code goes here. - * A template should always ship with an empty custom.css - */ diff --git a/themes/classic/assets/css/custom_rtl.css b/themes/classic/assets/css/custom_rtl.css deleted file mode 100644 index e7e4bf84..00000000 --- a/themes/classic/assets/css/custom_rtl.css +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Custom code goes here. - * A template should always ship with an empty custom.css - */ diff --git a/themes/classic/assets/css/d1a435fd2571e67858a31ee954b52278.svg b/themes/classic/assets/css/d1a435fd2571e67858a31ee954b52278.svg deleted file mode 100644 index 1a770a74..00000000 --- a/themes/classic/assets/css/d1a435fd2571e67858a31ee954b52278.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/d3fbae74a276a9f6cf1d6241f29b61a3.svg b/themes/classic/assets/css/d3fbae74a276a9f6cf1d6241f29b61a3.svg deleted file mode 100644 index 69bd6ab5..00000000 --- a/themes/classic/assets/css/d3fbae74a276a9f6cf1d6241f29b61a3.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/e049aeb07a2ae1627933e8e58d3886d2.svg b/themes/classic/assets/css/e049aeb07a2ae1627933e8e58d3886d2.svg deleted file mode 100644 index 31fe9125..00000000 --- a/themes/classic/assets/css/e049aeb07a2ae1627933e8e58d3886d2.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - Artboard 3 Copy 3 - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/themes/classic/assets/css/e79bfd88537def476913f3ed52f4f4b3.eot b/themes/classic/assets/css/e79bfd88537def476913f3ed52f4f4b3.eot deleted file mode 100644 index 70508ebabc9992e64f1314f866b2d7ab90438c58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143258 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

    ";(0,a.default)("#notifications .container").html(e),d="",f=!1,c&&t.removeClass("disabled")}else!c&&f&&(c=!1,f=!1,(0,a.default)("#notifications .container").html(""),t.removeClass("disabled"))},checkUpdateOpertation:function(t){c=t.hasOwnProperty("hasError");var e=t.errors||"";d=e instanceof Array?e.join(" "):e,f=!0}}},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(){(0,s.default)(".js-terms a").on("click",function(t){t.preventDefault();var e=(0,s.default)(t.target).attr("href");e&&(e+="?content_only=1",s.default.get(e,function(t){(0,s.default)("#modal").find(".js-modal-content").html((0,s.default)(t).find(".page-cms").contents())}).fail(function(t){u.default.emit("handleError",{eventType:"clickTerms",resp:t})})),(0,s.default)("#modal").modal("show")}),(0,s.default)(".js-gift-checkbox").on("click",function(t){(0,s.default)("#gift").collapse("toggle")})}function o(){(0,s.default)(".card-block .cart-summary-products p a").on("click",function(t){t=(0,s.default)(this).find("i.material-icons"),"expand_more"==t.text()?t.text("expand_less"):t.text("expand_more")})}var a=n(0),s=i(a),l=n(1),u=i(l);(0,s.default)(document).ready(function(){1===(0,s.default)("body#checkout").length&&(r(),o()),u.default.on("updatedDeliveryForm",function(t){void 0!==t.deliveryOption&&0!==t.deliveryOption.length&&((0,s.default)(".carrier-extra-content").hide(),t.deliveryOption.next(".carrier-extra-content").slideDown())})})},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}var r=n(1),o=i(r),a=n(0),s=i(a);o.default.blockcart=o.default.blockcart||{},o.default.blockcart.showModal=function(t){function e(){return(0,s.default)("#blockcart-modal")}var n=e();n.length&&n.remove(),(0,s.default)("body").append(t),n=e(),n.modal("show").on("hidden.bs.modal",function(t){o.default.emit("updateProduct",{reason:t.currentTarget.dataset,event:t})})}},function(t,e,n){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n(0,a.default)(".js-modal-mask").height()&&(t.move("down"),(0,a.default)(".js-modal-arrow-up").css("opacity","1"))})}},{key:"move",value:function(t){var e=(0,a.default)(".js-modal-product-images"),n=(0,a.default)(".js-modal-product-images li img").height()+10,i=e.position().top;e.velocity({translateY:"up"===t?i+n:i-n},function(){e.position().top>=0?(0,a.default)(".js-modal-arrow-up").css("opacity",".2"):e.position().top+e.height()<=(0,a.default)(".js-modal-mask").height()&&(0,a.default)(".js-modal-arrow-down").css("opacity",".2")})}}]),t}();e.default=s,t.exports=e.default},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function o(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(t,e){for(var n=0;n0&&this.options.badge&&this.$elementFilestyle.find("label").append(' '+e.length+""),this.$elementFilestyle.find(".group-span-filestyle").removeClass("input-group-btn")}}},size:function(t){if(void 0===t)return this.options.size;var e=this.$elementFilestyle.find("label"),n=this.$elementFilestyle.find("input");e.removeClass("btn-lg btn-sm"),n.removeClass("input-lg input-sm"),"nr"!=t&&(e.addClass("btn-"+t),n.addClass("input-"+t))},placeholder:function(t){if(void 0===t)return this.options.placeholder;this.options.placeholder=t,this.$elementFilestyle.find("input").attr("placeholder",t)},buttonText:function(t){if(void 0===t)return this.options.buttonText;this.options.buttonText=t,this.$elementFilestyle.find("label .buttonText").html(this.options.buttonText)},buttonName:function(t){if(void 0===t)return this.options.buttonName;this.options.buttonName=t,this.$elementFilestyle.find("label").attr({class:"btn "+this.options.buttonName})},iconName:function(t){if(void 0===t)return this.options.iconName;this.$elementFilestyle.find(".icon-span-filestyle").attr({class:"icon-span-filestyle "+this.options.iconName})},htmlIcon:function(){return this.options.icon?' ':""},htmlInput:function(){return this.options.input?' ':""},pushNameFiles:function(){var t="",e=[];void 0===this.$element[0].files?e[0]={name:this.$element[0]&&this.$element[0].value}:e=this.$element[0].files;for(var n=0;n",i=n.options.buttonBefore?o+n.htmlInput():n.htmlInput()+o,n.$elementFilestyle=t('
    '+i+"
    "),n.$elementFilestyle.find(".group-span-filestyle").attr("tabindex","0").keypress(function(t){if(13===t.keyCode||32===t.charCode)return n.$elementFilestyle.find("label").click(),!1}),n.$element.css({position:"absolute",clip:"rect(0px 0px 0px 0px)"}).attr("tabindex","-1").after(n.$elementFilestyle),n.options.disabled&&n.$element.attr("disabled","true"),n.$element.change(function(){var t=n.pushNameFiles();0==n.options.input&&n.options.badge?0==n.$elementFilestyle.find(".badge").length?n.$elementFilestyle.find("label").append(' '+t.length+""):0==t.length?n.$elementFilestyle.find(".badge").remove():n.$elementFilestyle.find(".badge").html(t.length):n.$elementFilestyle.find(".badge").remove()}),window.navigator.userAgent.search(/firefox/i)>-1&&n.$elementFilestyle.find("label").click(function(){return n.$element.click(),!1})}};var i=t.fn.filestyle;t.fn.filestyle=function(e,i){var r="",o=this.each(function(){if("file"===t(this).attr("type")){var o=t(this),a=o.data("filestyle"),s=t.extend({},t.fn.filestyle.defaults,e,"object"==typeof e&&e);a||(o.data("filestyle",a=new n(this,s)),a.constructor()),"string"==typeof e&&(r=a[e](i))}});return void 0!==typeof r?r:o},t.fn.filestyle.defaults={buttonText:"Choose file",iconName:"glyphicon glyphicon-folder-open",buttonName:"btn-default",size:"nr",input:!0,badge:!0,icon:!0,buttonBefore:!1,disabled:!1,placeholder:""},t.fn.filestyle.noConflict=function(){return t.fn.filestyle=i,this},t(function(){t(".filestyle").each(function(){var e=t(this),n={input:"false"!==e.attr("data-input"),icon:"false"!==e.attr("data-icon"),buttonBefore:"true"===e.attr("data-buttonBefore"),disabled:"true"===e.attr("data-disabled"),size:e.attr("data-size"),buttonText:e.attr("data-buttonText"),buttonName:e.attr("data-buttonName"),iconName:e.attr("data-iconName"),badge:"false"!==e.attr("data-badge"),placeholder:e.attr("data-placeholder")};e.filestyle(n)})})}(window.jQuery)},function(t,e,n){"use strict";!function(t){t.fn.scrollbox=function(e){var n={linear:!1,startDelay:2,delay:3,step:5,speed:32,switchItems:1,direction:"vertical",distance:"auto",autoPlay:!0,onMouseOverPause:!0,paused:!1,queue:null,listElement:"ul",listItemElement:"li",infiniteLoop:!0,switchAmount:0,afterForward:null,afterBackward:null,triggerStackable:!1};return e=t.extend(n,e),e.scrollOffset="vertical"===e.direction?"scrollTop":"scrollLeft",e.queue&&(e.queue=t("#"+e.queue)),this.each(function(){var n,i,r,o,a,s,l,u,c,f=t(this),d=null,p=null,h=!1,m=0,g=0;e.onMouseOverPause&&(f.bind("mouseover",function(){h=!0}),f.bind("mouseout",function(){h=!1})),n=f.children(e.listElement+":first-child"),!1===e.infiniteLoop&&0===e.switchAmount&&(e.switchAmount=n.children().length),s=function(){if(!h){var r,a,s,l,u;if(r=n.children(e.listItemElement+":first-child"),l="auto"!==e.distance?e.distance:"vertical"===e.direction?r.outerHeight(!0):r.outerWidth(!0),e.linear?s=Math.min(f[0][e.scrollOffset]+e.step,l):(u=Math.max(3,parseInt(.3*(l-f[0][e.scrollOffset]),10)),s=Math.min(f[0][e.scrollOffset]+u,l)),f[0][e.scrollOffset]=s,s>=l){for(a=0;a0?(n.append(e.queue.find(e.listItemElement)[0]),n.children(e.listItemElement+":first-child").remove()):n.append(n.children(e.listItemElement+":first-child")),++m;if(f[0][e.scrollOffset]=0,clearInterval(d),d=null,t.isFunction(e.afterForward)&&e.afterForward.call(f,{switchCount:m,currentFirstChild:n.children(e.listItemElement+":first-child")}),e.triggerStackable&&0!==g)return void i();if(!1===e.infiniteLoop&&m>=e.switchAmount)return;e.autoPlay&&(p=setTimeout(o,1e3*e.delay))}}},l=function(){if(!h){var r,a,s,l,u;if(0===f[0][e.scrollOffset]){for(a=0;a0?(g--,p=setTimeout(o,0)):(g++,p=setTimeout(r,0)))},o=function(){clearInterval(d),d=setInterval(s,e.speed)},r=function(){clearInterval(d),d=setInterval(l,e.speed)},u=function(){e.autoPlay=!0,h=!1,clearInterval(d),d=setInterval(s,e.speed)},c=function(){h=!0},a=function(t){e.delay=t||e.delay,clearTimeout(p),e.autoPlay&&(p=setTimeout(o,1e3*e.delay))},e.autoPlay&&(p=setTimeout(o,1e3*e.startDelay)),f.bind("resetClock",function(t){a(t)}),f.bind("forward",function(){e.triggerStackable?null!==d?g++:o():(clearTimeout(p),o())}),f.bind("backward",function(){e.triggerStackable?null!==d?g--:r():(clearTimeout(p),r())}),f.bind("pauseHover",function(){c()}),f.bind("forwardHover",function(){u()}),f.bind("speedUp",function(t,n){"undefined"===n&&(n=Math.max(1,parseInt(e.speed/2,10))),e.speed=n}),f.bind("speedDown",function(t,n){"undefined"===n&&(n=2*e.speed),e.speed=n}),f.bind("updateConfig",function(n,i){e=t.extend(e,i)})})}}(jQuery)},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t){(0,a.default)("#search_filters").replaceWith(t.rendered_facets),(0,a.default)("#js-active-search-filters").replaceWith(t.rendered_active_filters),(0,a.default)("#js-product-list-top").replaceWith(t.rendered_products_top),(0,a.default)("#js-product-list").replaceWith(t.rendered_products),(0,a.default)("#js-product-list-bottom").replaceWith(t.rendered_products_bottom),t.rendered_products_header&&(0,a.default)("#js-product-list-header").replaceWith(t.rendered_products_header),(new c.default).init()}var o=n(0),a=i(o),s=n(1),l=i(s);n(4);var u=n(3),c=i(u);(0,a.default)(document).ready(function(){l.default.on("clickQuickView",function(e){var n={action:"quickview",id_product:e.dataset.idProduct,id_product_attribute:e.dataset.idProductAttribute};a.default.post(l.default.urls.pages.product,n,null,"json").then(function(e){(0,a.default)("body").append(e.quickview_html);var n=(0,a.default)("#quickview-modal-"+e.product.id+"-"+e.product.id_product_attribute);n.modal("show"),t(n),n.on("hidden.bs.modal",function(){n.remove()})}).fail(function(t){l.default.emit("handleError",{eventType:"clickQuickView",resp:t})})});var t=function(t){var n=(0,a.default)(".js-arrows"),i=t.find(".js-qv-product-images");(0,a.default)(".js-thumb").on("click",function(t){(0,a.default)(".js-thumb").hasClass("selected")&&(0,a.default)(".js-thumb").removeClass("selected"),(0,a.default)(t.currentTarget).addClass("selected"),(0,a.default)(".js-qv-product-cover").attr("src",(0,a.default)(t.target).data("image-large-src"))}),i.find("li").length<=4?n.hide():n.on("click",function(t){(0,a.default)(t.target).hasClass("arrow-up")&&(0,a.default)(".js-qv-product-images").position().top<0?(e("up"),(0,a.default)(".arrow-down").css("opacity","1")):(0,a.default)(t.target).hasClass("arrow-down")&&i.position().top+i.height()>(0,a.default)(".js-qv-mask").height()&&(e("down"),(0,a.default)(".arrow-up").css("opacity","1"))}),t.find("#quantity_wanted").TouchSpin({verticalbuttons:!0,verticalupclass:"material-icons touchspin-up",verticaldownclass:"material-icons touchspin-down",buttondown_class:"btn btn-touchspin js-touchspin",buttonup_class:"btn btn-touchspin js-touchspin",min:1,max:1e6})},e=function(t){var e=(0,a.default)(".js-qv-product-images"),n=(0,a.default)(".js-qv-product-images li img").height()+20,i=e.position().top;e.velocity({translateY:"up"===t?i+n:i-n},function(){e.position().top>=0?(0,a.default)(".arrow-up").css("opacity",".2"):e.position().top+e.height()<=(0,a.default)(".js-qv-mask").height()&&(0,a.default)(".arrow-down").css("opacity",".2")})};(0,a.default)("body").on("click","#search_filter_toggler",function(){(0,a.default)("#search_filters_wrapper").removeClass("hidden-sm-down"),(0,a.default)("#content-wrapper").addClass("hidden-sm-down"),(0,a.default)("#footer").addClass("hidden-sm-down")}),(0,a.default)("#search_filter_controls .clear").on("click",function(){(0,a.default)("#search_filters_wrapper").addClass("hidden-sm-down"),(0,a.default)("#content-wrapper").removeClass("hidden-sm-down"),(0,a.default)("#footer").removeClass("hidden-sm-down")}),(0,a.default)("#search_filter_controls .ok").on("click",function(){(0,a.default)("#search_filters_wrapper").addClass("hidden-sm-down"),(0,a.default)("#content-wrapper").removeClass("hidden-sm-down"),(0,a.default)("#footer").removeClass("hidden-sm-down")});var n=function(t){if(void 0!==t.target.dataset.searchUrl)return t.target.dataset.searchUrl;if(void 0===(0,a.default)(t.target).parent()[0].dataset.searchUrl)throw new Error("Can not parse search URL");return(0,a.default)(t.target).parent()[0].dataset.searchUrl};(0,a.default)("body").on("change","#search_filters input[data-search-url]",function(t){l.default.emit("updateFacets",n(t))}),(0,a.default)("body").on("click",".js-search-filters-clear-all",function(t){l.default.emit("updateFacets",n(t))}),(0,a.default)("body").on("click",".js-search-link",function(t){t.preventDefault(),l.default.emit("updateFacets",(0,a.default)(t.target).closest("a").get(0).href)}),(0,a.default)("body").on("change","#search_filters select",function(t){var e=(0,a.default)(t.target).closest("form");l.default.emit("updateFacets","?"+e.serialize())}),l.default.on("updateProductList",function(t){r(t),window.scrollTo(0,0)})})},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}var r=n(0),o=i(r),a=n(1),s=i(a);(0,o.default)(document).ready(function(){function t(){(0,o.default)(".js-thumb").on("click",function(t){(0,o.default)(".js-modal-product-cover").attr("src",(0,o.default)(t.target).data("image-large-src")),(0,o.default)(".selected").removeClass("selected"),(0,o.default)(t.target).addClass("selected"),(0,o.default)(".js-qv-product-cover").prop("src",(0,o.default)(t.currentTarget).data("image-large-src"))})}function e(){(0,o.default)("#main .js-qv-product-images li").length>2?((0,o.default)("#main .js-qv-mask").addClass("scroll"),(0,o.default)(".scroll-box-arrows").addClass("scroll"),(0,o.default)("#main .js-qv-mask").scrollbox({direction:"h",distance:113,autoPlay:!1}),(0,o.default)(".scroll-box-arrows .left").click(function(){(0,o.default)("#main .js-qv-mask").trigger("backward")}),(0,o.default)(".scroll-box-arrows .right").click(function(){(0,o.default)("#main .js-qv-mask").trigger("forward")})):((0,o.default)("#main .js-qv-mask").removeClass("scroll"),(0,o.default)(".scroll-box-arrows").removeClass("scroll"))}function n(){(0,o.default)(".js-file-input").on("change",function(t){var e=void 0,n=void 0;(e=(0,o.default)(t.currentTarget)[0])&&(n=e.files[0])&&(0,o.default)(e).prev().text(n.name)})}!function(){var t=(0,o.default)("#quantity_wanted");t.TouchSpin({verticalbuttons:!0,verticalupclass:"material-icons touchspin-up",verticaldownclass:"material-icons touchspin-down",buttondown_class:"btn btn-touchspin js-touchspin",buttonup_class:"btn btn-touchspin js-touchspin",min:parseInt(t.attr("min"),10),max:1e6}),(0,o.default)("body").on("change keyup","#quantity_wanted",function(t){(0,o.default)(t.currentTarget).trigger("touchspin.stopspin"),s.default.emit("updateProduct",{eventType:"updatedProductQuantity",event:t})})}(),n(),t(),e(),s.default.on("updatedProduct",function(i){if(n(),t(),i&&i.product_minimal_quantity){var r=parseInt(i.product_minimal_quantity,10);(0,o.default)("#quantity_wanted").trigger("touchspin.updatesettings",{min:r})}e(),(0,o.default)((0,o.default)(".tabs .nav-link.active").attr("href")).addClass("active").removeClass("fade"),(0,o.default)(".js-product-images-modal").replaceWith(i.product_images_modal)})})},function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t,e){var n=e.children().detach();e.empty().append(t.children().detach()),t.append(n)}function o(){u.default.responsive.mobile?(0,s.default)("*[id^='_desktop_']").each(function(t,e){var n=(0,s.default)("#"+e.id.replace("_desktop_","_mobile_"));n.length&&r((0,s.default)(e),n)}):(0,s.default)("*[id^='_mobile_']").each(function(t,e){var n=(0,s.default)("#"+e.id.replace("_mobile_","_desktop_"));n.length&&r((0,s.default)(e),n)}),u.default.emit("responsive update",{mobile:u.default.responsive.mobile})}var a=n(0),s=i(a),l=n(1),u=i(l);u.default.responsive=u.default.responsive||{},u.default.responsive.current_width=window.innerWidth,u.default.responsive.min_width=768,u.default.responsive.mobile=u.default.responsive.current_width=e&&n=e;u.default.responsive.current_width=n,u.default.responsive.mobile=u.default.responsive.current_width'+T.prefix+"",s=''+T.postfix+"";r.hasClass("input-group-btn")?(n='",r.append(n)):(n='",t(n).insertBefore(L)),o.hasClass("input-group-btn")?(i='",o.prepend(i)):(i='",t(i).insertAfter(L)),t(a).insertBefore(L),t(s).insertAfter(L),A=e}function p(){var e;e=T.verticalbuttons?'
    '+T.prefix+''+T.postfix+'
    ':'
    '+T.prefix+''+T.postfix+'
    ",A=t(e).insertBefore(L),t(".bootstrap-touchspin-prefix",A).after(L),L.hasClass("input-sm")?A.addClass("input-group-sm"):L.hasClass("input-lg")&&A.addClass("input-group-lg")}function h(){I={down:t(".bootstrap-touchspin-down",A),up:t(".bootstrap-touchspin-up",A),input:t("input",A),prefix:t(".bootstrap-touchspin-prefix",A).addClass(T.prefix_extraclass),postfix:t(".bootstrap-touchspin-postfix",A).addClass(T.postfix_extraclass)}}function m(){""===T.prefix&&I.prefix.hide(),""===T.postfix&&I.postfix.hide()}function g(){L.on("keydown",function(t){var e=t.keyCode||t.which;38===e?("up"!==V&&(x(),E()),t.preventDefault()):40===e&&("down"!==V&&(w(),S()),t.preventDefault())}),L.on("keyup",function(t){var e=t.keyCode||t.which;38===e?C():40===e&&C()}),L.on("blur",function(){b()}),I.down.on("keydown",function(t){var e=t.keyCode||t.which;32!==e&&13!==e||("down"!==V&&(w(),S()),t.preventDefault())}),I.down.on("keyup",function(t){var e=t.keyCode||t.which;32!==e&&13!==e||C()}),I.up.on("keydown",function(t){var e=t.keyCode||t.which;32!==e&&13!==e||("up"!==V&&(x(),E()),t.preventDefault())}),I.up.on("keyup",function(t){var e=t.keyCode||t.which;32!==e&&13!==e||C()}),I.down.on("mousedown.touchspin",function(t){I.down.off("touchstart.touchspin"),L.is(":disabled")||(w(),S(),t.preventDefault(),t.stopPropagation())}),I.down.on("touchstart.touchspin",function(t){I.down.off("mousedown.touchspin"),L.is(":disabled")||(w(),S(),t.preventDefault(),t.stopPropagation())}),I.up.on("mousedown.touchspin",function(t){I.up.off("touchstart.touchspin"),L.is(":disabled")||(x(),E(),t.preventDefault(),t.stopPropagation())}),I.up.on("touchstart.touchspin",function(t){I.up.off("mousedown.touchspin"),L.is(":disabled")||(x(),E(),t.preventDefault(),t.stopPropagation())}),I.up.on("mouseout touchleave touchend touchcancel",function(t){V&&(t.stopPropagation(),C())}),I.down.on("mouseout touchleave touchend touchcancel",function(t){V&&(t.stopPropagation(),C())}),I.down.on("mousemove touchmove",function(t){V&&(t.stopPropagation(),t.preventDefault())}),I.up.on("mousemove touchmove",function(t){V&&(t.stopPropagation(),t.preventDefault())}),t(document).on(n(["mouseup","touchend","touchcancel"],i).join(" "),function(t){V&&(t.preventDefault(),C())}),t(document).on(n(["mousemove","touchmove","scroll","scrollstart"],i).join(" "),function(t){V&&(t.preventDefault(),C())}),L.on("mousewheel DOMMouseScroll",function(t){if(T.mousewheel&&L.is(":focus")){var e=t.originalEvent.wheelDelta||-t.originalEvent.deltaY||-t.originalEvent.detail;t.stopPropagation(),t.preventDefault(),e<0?w():x()}})}function v(){L.on("touchspin.uponce",function(){C(),x()}),L.on("touchspin.downonce",function(){C(),w()}),L.on("touchspin.startupspin",function(){E()}),L.on("touchspin.startdownspin",function(){S()}),L.on("touchspin.stopspin",function(){C()}),L.on("touchspin.updatesettings",function(t,e){s(e)})}function y(t){switch(T.forcestepdivisibility){case"round":return(Math.round(t/T.step)*T.step).toFixed(T.decimals);case"floor":return(Math.floor(t/T.step)*T.step).toFixed(T.decimals);case"ceil":return(Math.ceil(t/T.step)*T.step).toFixed(T.decimals);default:return t}}function b(){var t,e,n;if(""===(t=L.val()))return void(""!==T.replacementval&&(L.val(T.replacementval),L.trigger("change")));T.decimals>0&&"."===t||(e=parseFloat(t),isNaN(e)&&(e=""!==T.replacementval?T.replacementval:0),n=e,e.toString()!==t&&(n=e),eT.max&&(n=T.max),n=y(n),Number(t).toString()!==n.toString()&&(L.val(n),L.trigger("change")))}function _(){if(T.booster){var t=Math.pow(2,Math.floor(B/T.boostat))*T.step;return T.maxboostedstep&&t>T.maxboostedstep&&(t=T.maxboostedstep,O=Math.round(O/t)*t),Math.max(T.step,t)}return T.step}function x(){b(),O=parseFloat(I.input.val()),isNaN(O)&&(O=0);var t=O,e=_();O+=e,O>T.max&&(O=T.max,L.trigger("touchspin.on.max"),C()),I.input.val(Number(O).toFixed(T.decimals)),t!==O&&L.trigger("change")}function w(){b(),O=parseFloat(I.input.val()),isNaN(O)&&(O=0);var t=O,e=_();O-=e,O=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}(jQuery),function(){function t(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function e(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(){function t(t,e){for(var n=0;nthis._items.length-1||e<0)){if(this._isSliding)return void t(this._element).one(p.SLID,function(){return n.to(e)});if(i===e)return this.pause(),void this.cycle();var r=e>i?d.NEXT:d.PREVIOUS;this._slide(r,this._items[e])}},l.prototype.dispose=function(){t(this._element).off(s),t.removeData(this._element,a),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},l.prototype._getConfig=function(n){return n=t.extend({},c,n),o.typeCheckConfig(e,n,f),n},l.prototype._addEventListeners=function(){this._config.keyboard&&t(this._element).on(p.KEYDOWN,t.proxy(this._keydown,this)),"hover"!==this._config.pause||"ontouchstart"in document.documentElement||t(this._element).on(p.MOUSEENTER,t.proxy(this.pause,this)).on(p.MOUSELEAVE,t.proxy(this.cycle,this))},l.prototype._keydown=function(t){if(t.preventDefault(),!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}},l.prototype._getItemIndex=function(e){return this._items=t.makeArray(t(e).parent().find(m.ITEM)),this._items.indexOf(e)},l.prototype._getItemByDirection=function(t,e){var n=t===d.NEXT,i=t===d.PREVIOUS,r=this._getItemIndex(e),o=this._items.length-1;if((i&&0===r||n&&r===o)&&!this._config.wrap)return e;var a=t===d.PREVIOUS?-1:1,s=(r+a)%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},l.prototype._triggerSlideEvent=function(e,n){var i=t.Event(p.SLIDE,{relatedTarget:e,direction:n});return t(this._element).trigger(i),i},l.prototype._setActiveIndicatorElement=function(e){if(this._indicatorsElement){t(this._indicatorsElement).find(m.ACTIVE).removeClass(h.ACTIVE);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&t(n).addClass(h.ACTIVE)}},l.prototype._slide=function(e,n){var i=this,r=t(this._element).find(m.ACTIVE_ITEM)[0],a=n||r&&this._getItemByDirection(e,r),s=Boolean(this._interval),l=e===d.NEXT?h.LEFT:h.RIGHT;if(a&&t(a).hasClass(h.ACTIVE))return void(this._isSliding=!1);if(!this._triggerSlideEvent(a,l).isDefaultPrevented()&&r&&a){this._isSliding=!0,s&&this.pause(),this._setActiveIndicatorElement(a);var u=t.Event(p.SLID,{relatedTarget:a,direction:l});o.supportsTransitionEnd()&&t(this._element).hasClass(h.SLIDE)?(t(a).addClass(e),o.reflow(a),t(r).addClass(l),t(a).addClass(l),t(r).one(o.TRANSITION_END,function(){t(a).removeClass(l).removeClass(e),t(a).addClass(h.ACTIVE),t(r).removeClass(h.ACTIVE).removeClass(e).removeClass(l),i._isSliding=!1,setTimeout(function(){return t(i._element).trigger(u)},0)}).emulateTransitionEnd(600)):(t(r).removeClass(h.ACTIVE),t(a).addClass(h.ACTIVE),this._isSliding=!1,t(this._element).trigger(u)),s&&this.cycle()}},l._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(a),r=t.extend({},c,t(this).data());"object"===(void 0===e?"undefined":i(e))&&t.extend(r,e);var o="string"==typeof e?e:r.slide;if(n||(n=new l(this,r),t(this).data(a,n)),"number"==typeof e)n.to(e);else if("string"==typeof o){if(void 0===n[o])throw new Error('No method named "'+o+'"');n[o]()}else r.interval&&(n.pause(),n.cycle())})},l._dataApiClickHandler=function(e){var n=o.getSelectorFromElement(this);if(n){var i=t(n)[0];if(i&&t(i).hasClass(h.CAROUSEL)){var r=t.extend({},t(i).data(),t(this).data()),s=this.getAttribute("data-slide-to");s&&(r.interval=!1),l._jQueryInterface.call(t(i),r),s&&t(i).data(a).to(s),e.preventDefault()}}},r(l,null,[{key:"VERSION",get:function(){return"4.0.0-alpha.5"}},{key:"Default",get:function(){return c}}]),l}();t(document).on(p.CLICK_DATA_API,m.DATA_SLIDE,g._dataApiClickHandler),t(window).on(p.LOAD_DATA_API,function(){t(m.DATA_RIDE).each(function(){var e=t(this);g._jQueryInterface.call(e,e.data())})}),t.fn[e]=g._jQueryInterface,t.fn[e].Constructor=g,t.fn[e].noConflict=function(){return t.fn[e]=u,g._jQueryInterface}}(jQuery),function(t){var e="collapse",a="bs.collapse",s="."+a,l=t.fn[e],u={toggle:!0,parent:""},c={toggle:"boolean",parent:"string"},f={SHOW:"show"+s,SHOWN:"shown"+s,HIDE:"hide"+s,HIDDEN:"hidden"+s,CLICK_DATA_API:"click"+s+".data-api"},d={IN:"in",COLLAPSE:"collapse",COLLAPSING:"collapsing",COLLAPSED:"collapsed"},p={WIDTH:"width",HEIGHT:"height"},h={ACTIVES:".card > .in, .card > .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},m=function(){function s(e,i){n(this,s),this._isTransitioning=!1,this._element=e,this._config=this._getConfig(i),this._triggerArray=t.makeArray(t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]')),this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}return s.prototype.toggle=function(){t(this._element).hasClass(d.IN)?this.hide():this.show()},s.prototype.show=function(){var e=this;if(!this._isTransitioning&&!t(this._element).hasClass(d.IN)){var n=void 0,i=void 0;if(this._parent&&(n=t.makeArray(t(h.ACTIVES)),n.length||(n=null)),!(n&&(i=t(n).data(a))&&i._isTransitioning)){var r=t.Event(f.SHOW);if(t(this._element).trigger(r),!r.isDefaultPrevented()){n&&(s._jQueryInterface.call(t(n),"hide"),i||t(n).data(a,null));var l=this._getDimension();t(this._element).removeClass(d.COLLAPSE).addClass(d.COLLAPSING),this._element.style[l]=0,this._element.setAttribute("aria-expanded",!0),this._triggerArray.length&&t(this._triggerArray).removeClass(d.COLLAPSED).attr("aria-expanded",!0),this.setTransitioning(!0);var u=function(){t(e._element).removeClass(d.COLLAPSING).addClass(d.COLLAPSE).addClass(d.IN),e._element.style[l]="",e.setTransitioning(!1),t(e._element).trigger(f.SHOWN)};if(!o.supportsTransitionEnd())return void u();var c=l[0].toUpperCase()+l.slice(1),p="scroll"+c;t(this._element).one(o.TRANSITION_END,u).emulateTransitionEnd(600),this._element.style[l]=this._element[p]+"px"}}}},s.prototype.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(d.IN)){var n=t.Event(f.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension(),r=i===p.WIDTH?"offsetWidth":"offsetHeight";this._element.style[i]=this._element[r]+"px",o.reflow(this._element),t(this._element).addClass(d.COLLAPSING).removeClass(d.COLLAPSE).removeClass(d.IN),this._element.setAttribute("aria-expanded",!1),this._triggerArray.length&&t(this._triggerArray).addClass(d.COLLAPSED).attr("aria-expanded",!1),this.setTransitioning(!0);var a=function(){e.setTransitioning(!1),t(e._element).removeClass(d.COLLAPSING).addClass(d.COLLAPSE).trigger(f.HIDDEN)};return this._element.style[i]="",o.supportsTransitionEnd()?void t(this._element).one(o.TRANSITION_END,a).emulateTransitionEnd(600):void a()}}},s.prototype.setTransitioning=function(t){this._isTransitioning=t},s.prototype.dispose=function(){t.removeData(this._element,a),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},s.prototype._getConfig=function(n){return n=t.extend({},u,n),n.toggle=Boolean(n.toggle),o.typeCheckConfig(e,n,c),n},s.prototype._getDimension=function(){return t(this._element).hasClass(p.WIDTH)?p.WIDTH:p.HEIGHT},s.prototype._getParent=function(){var e=this,n=t(this._config.parent)[0],i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]';return t(n).find(i).each(function(t,n){e._addAriaAndCollapsedClass(s._getTargetFromElement(n),[n])}),n},s.prototype._addAriaAndCollapsedClass=function(e,n){if(e){var i=t(e).hasClass(d.IN);e.setAttribute("aria-expanded",i),n.length&&t(n).toggleClass(d.COLLAPSED,!i).attr("aria-expanded",i)}},s._getTargetFromElement=function(e){var n=o.getSelectorFromElement(e);return n?t(n)[0]:null},s._jQueryInterface=function(e){return this.each(function(){var n=t(this),r=n.data(a),o=t.extend({},u,n.data(),"object"===(void 0===e?"undefined":i(e))&&e);if(!r&&o.toggle&&/show|hide/.test(e)&&(o.toggle=!1),r||(r=new s(this,o),n.data(a,r)),"string"==typeof e){if(void 0===r[e])throw new Error('No method named "'+e+'"');r[e]()}})},r(s,null,[{key:"VERSION",get:function(){return"4.0.0-alpha.5"}},{key:"Default",get:function(){return u}}]),s}();t(document).on(f.CLICK_DATA_API,h.DATA_TOGGLE,function(e){e.preventDefault();var n=m._getTargetFromElement(this),i=t(n).data(a),r=i?"toggle":t(this).data();m._jQueryInterface.call(t(n),r)}),t.fn[e]=m._jQueryInterface,t.fn[e].Constructor=m,t.fn[e].noConflict=function(){return t.fn[e]=l,m._jQueryInterface}}(jQuery),function(t){var e="dropdown",i="bs.dropdown",a="."+i,s=".data-api",l=t.fn[e],u={HIDE:"hide"+a,HIDDEN:"hidden"+a,SHOW:"show"+a,SHOWN:"shown"+a,CLICK:"click"+a,CLICK_DATA_API:"click"+a+s,KEYDOWN_DATA_API:"keydown"+a+s},c={BACKDROP:"dropdown-backdrop",DISABLED:"disabled",OPEN:"open"},f={BACKDROP:".dropdown-backdrop",DATA_TOGGLE:'[data-toggle="dropdown"]',FORM_CHILD:".dropdown form",ROLE_MENU:'[role="menu"]',ROLE_LISTBOX:'[role="listbox"]',NAVBAR_NAV:".navbar-nav",VISIBLE_ITEMS:'[role="menu"] li:not(.disabled) a, [role="listbox"] li:not(.disabled) a'},d=function(){function e(t){n(this,e),this._element=t,this._addEventListeners()}return e.prototype.toggle=function(){if(this.disabled||t(this).hasClass(c.DISABLED))return!1;var n=e._getParentFromElement(this),i=t(n).hasClass(c.OPEN);if(e._clearMenus(),i)return!1;if("ontouchstart"in document.documentElement&&!t(n).closest(f.NAVBAR_NAV).length){var r=document.createElement("div");r.className=c.BACKDROP,t(r).insertBefore(this),t(r).on("click",e._clearMenus)}var o={relatedTarget:this},a=t.Event(u.SHOW,o);return t(n).trigger(a),!a.isDefaultPrevented()&&(this.focus(),this.setAttribute("aria-expanded","true"),t(n).toggleClass(c.OPEN),t(n).trigger(t.Event(u.SHOWN,o)),!1)},e.prototype.dispose=function(){t.removeData(this._element,i),t(this._element).off(a),this._element=null},e.prototype._addEventListeners=function(){t(this._element).on(u.CLICK,this.toggle)},e._jQueryInterface=function(n){return this.each(function(){var r=t(this).data(i);if(r||t(this).data(i,r=new e(this)),"string"==typeof n){if(void 0===r[n])throw new Error('No method named "'+n+'"');r[n].call(this)}})},e._clearMenus=function(n){if(!n||3!==n.which){var i=t(f.BACKDROP)[0];i&&i.parentNode.removeChild(i);for(var r=t.makeArray(t(f.DATA_TOGGLE)),o=0;o0&&s--,40===n.which&&sdocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},l.prototype._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},l.prototype._checkScrollbar=function(){this._isBodyOverflowing=document.body.clientWidth=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}if(this._activeTarget&&t=this._offsets[r]&&(void 0===this._offsets[r+1]||t .nav-item .fade, > .fade",ACTIVE:".active",ACTIVE_CHILD:"> .nav-item > .active, > .active",DATA_TOGGLE:'[data-toggle="tab"], [data-toggle="pill"]',DROPDOWN_TOGGLE:".dropdown-toggle",DROPDOWN_ACTIVE_CHILD:"> .dropdown-menu .active"},f=function(){function e(t){n(this,e),this._element=t}return e.prototype.show=function(){var e=this;if(!this._element.parentNode||this._element.parentNode.nodeType!==Node.ELEMENT_NODE||!t(this._element).hasClass(u.ACTIVE)){var n=void 0,i=void 0,r=t(this._element).closest(c.UL)[0],a=o.getSelectorFromElement(this._element);r&&(i=t.makeArray(t(r).find(c.ACTIVE)),i=i[i.length-1]);var s=t.Event(l.HIDE,{relatedTarget:this._element}),f=t.Event(l.SHOW,{relatedTarget:i});if(i&&t(i).trigger(s),t(this._element).trigger(f),!f.isDefaultPrevented()&&!s.isDefaultPrevented()){a&&(n=t(a)[0]),this._activate(this._element,r);var d=function(){var n=t.Event(l.HIDDEN,{relatedTarget:e._element}),r=t.Event(l.SHOWN,{relatedTarget:i});t(i).trigger(n),t(e._element).trigger(r)};n?this._activate(n,n.parentNode,d):d()}}},e.prototype.dispose=function(){t.removeClass(this._element,i),this._element=null},e.prototype._activate=function(e,n,i){var r=t(n).find(c.ACTIVE_CHILD)[0],a=i&&o.supportsTransitionEnd()&&(r&&t(r).hasClass(u.FADE)||Boolean(t(n).find(c.FADE_CHILD)[0])),s=t.proxy(this._transitionComplete,this,e,r,a,i);r&&a?t(r).one(o.TRANSITION_END,s).emulateTransitionEnd(150):s(),r&&t(r).removeClass(u.IN)},e.prototype._transitionComplete=function(e,n,i,r){if(n){t(n).removeClass(u.ACTIVE);var a=t(n).find(c.DROPDOWN_ACTIVE_CHILD)[0];a&&t(a).removeClass(u.ACTIVE),n.setAttribute("aria-expanded",!1)}if(t(e).addClass(u.ACTIVE),e.setAttribute("aria-expanded",!0),i?(o.reflow(e),t(e).addClass(u.IN)):t(e).removeClass(u.FADE),e.parentNode&&t(e.parentNode).hasClass(u.DROPDOWN_MENU)){var s=t(e).closest(c.DROPDOWN)[0];s&&t(s).find(c.DROPDOWN_TOGGLE).addClass(u.ACTIVE),e.setAttribute("aria-expanded",!0)}r&&r()},e._jQueryInterface=function(n){return this.each(function(){var r=t(this),o=r.data(i);if(o||(o=o=new e(this),r.data(i,o)),"string"==typeof n){if(void 0===o[n])throw new Error('No method named "'+n+'"');o[n]()}})},r(e,null,[{key:"VERSION",get:function(){return"4.0.0-alpha.5"}}]),e}();t(document).on(l.CLICK_DATA_API,c.DATA_TOGGLE,function(e){e.preventDefault(),f._jQueryInterface.call(t(this),"show")}),t.fn[e]=f._jQueryInterface,t.fn[e].Constructor=f,t.fn[e].noConflict=function(){return t.fn[e]=s,f._jQueryInterface}}(jQuery),function(t){if(void 0===window.Tether)throw new Error("Bootstrap tooltips require Tether (http://tether.io/)");var e="tooltip",a="bs.tooltip",s="."+a,l=t.fn[e],u={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:"0 0",constraints:[]},c={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"string",constraints:"array"},f={TOP:"bottom center",RIGHT:"middle left",BOTTOM:"top center",LEFT:"middle right"},d={IN:"in",OUT:"out"},p={HIDE:"hide"+s,HIDDEN:"hidden"+s,SHOW:"show"+s,SHOWN:"shown"+s,INSERTED:"inserted"+s,CLICK:"click"+s,FOCUSIN:"focusin"+s,FOCUSOUT:"focusout"+s,MOUSEENTER:"mouseenter"+s,MOUSELEAVE:"mouseleave"+s},h={FADE:"fade",IN:"in"},m={TOOLTIP:".tooltip",TOOLTIP_INNER:".tooltip-inner"},g={element:!1,enabled:!1},v={HOVER:"hover",FOCUS:"focus",CLICK:"click",MANUAL:"manual"},y=function(){function l(t,e){n(this,l),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._tether=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}return l.prototype.enable=function(){this._isEnabled=!0},l.prototype.disable=function(){this._isEnabled=!1},l.prototype.toggleEnabled=function(){this._isEnabled=!this._isEnabled},l.prototype.toggle=function(e){if(e){var n=this.constructor.DATA_KEY,i=t(e.currentTarget).data(n);i||(i=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(t(this.getTipElement()).hasClass(h.IN))return void this._leave(null,this);this._enter(null,this)}},l.prototype.dispose=function(){clearTimeout(this._timeout),this.cleanupTether(),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._tether=null,this.element=null,this.config=null,this.tip=null},l.prototype.show=function(){var e=this,n=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(n);var i=t.contains(this.element.ownerDocument.documentElement,this.element);if(n.isDefaultPrevented()||!i)return;var r=this.getTipElement(),a=o.getUID(this.constructor.NAME);r.setAttribute("id",a),this.element.setAttribute("aria-describedby",a),this.setContent(),this.config.animation&&t(r).addClass(h.FADE);var s="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,u=this._getAttachment(s);t(r).data(this.constructor.DATA_KEY,this).appendTo(document.body),t(this.element).trigger(this.constructor.Event.INSERTED),this._tether=new Tether({attachment:u,element:r,target:this.element,classes:g,classPrefix:"bs-tether",offset:this.config.offset,constraints:this.config.constraints,addTargetClasses:!1}),o.reflow(r),this._tether.position(),t(r).addClass(h.IN);var c=function(){var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===d.OUT&&e._leave(null,e)};if(o.supportsTransitionEnd()&&t(this.tip).hasClass(h.FADE))return void t(this.tip).one(o.TRANSITION_END,c).emulateTransitionEnd(l._TRANSITION_DURATION);c()}},l.prototype.hide=function(e){var n=this,i=this.getTipElement(),r=t.Event(this.constructor.Event.HIDE),a=function(){n._hoverState!==d.IN&&i.parentNode&&i.parentNode.removeChild(i),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),n.cleanupTether(),e&&e()};t(this.element).trigger(r),r.isDefaultPrevented()||(t(i).removeClass(h.IN),o.supportsTransitionEnd()&&t(this.tip).hasClass(h.FADE)?t(i).one(o.TRANSITION_END,a).emulateTransitionEnd(150):a(),this._hoverState="")},l.prototype.isWithContent=function(){return Boolean(this.getTitle())},l.prototype.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0]},l.prototype.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(m.TOOLTIP_INNER),this.getTitle()),e.removeClass(h.FADE).removeClass(h.IN),this.cleanupTether()},l.prototype.setElementContent=function(e,n){var r=this.config.html;"object"===(void 0===n?"undefined":i(n))&&(n.nodeType||n.jquery)?r?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text()):e[r?"html":"text"](n)},l.prototype.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},l.prototype.cleanupTether=function(){this._tether&&this._tether.destroy()},l.prototype._getAttachment=function(t){return f[t.toUpperCase()]},l.prototype._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach(function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,t.proxy(e.toggle,e));else if(n!==v.MANUAL){var i=n===v.HOVER?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,r=n===v.HOVER?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(i,e.config.selector,t.proxy(e._enter,e)).on(r,e.config.selector,t.proxy(e._leave,e))}}),this.config.selector?this.config=t.extend({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},l.prototype._fixTitle=function(){var t=i(this.element.getAttribute("data-original-title"));(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},l.prototype._enter=function(e,n){var i=this.constructor.DATA_KEY;return n=n||t(e.currentTarget).data(i),n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusin"===e.type?v.FOCUS:v.HOVER]=!0),t(n.getTipElement()).hasClass(h.IN)||n._hoverState===d.IN?void(n._hoverState=d.IN):(clearTimeout(n._timeout),n._hoverState=d.IN,n.config.delay&&n.config.delay.show?void(n._timeout=setTimeout(function(){n._hoverState===d.IN&&n.show()},n.config.delay.show)):void n.show())},l.prototype._leave=function(e,n){var i=this.constructor.DATA_KEY;if(n=n||t(e.currentTarget).data(i),n||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusout"===e.type?v.FOCUS:v.HOVER]=!1),!n._isWithActiveTrigger())return clearTimeout(n._timeout),n._hoverState=d.OUT,n.config.delay&&n.config.delay.hide?void(n._timeout=setTimeout(function(){n._hoverState===d.OUT&&n.hide()},n.config.delay.hide)):void n.hide()},l.prototype._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},l.prototype._getConfig=function(n){return n=t.extend({},this.constructor.Default,t(this.element).data(),n),n.delay&&"number"==typeof n.delay&&(n.delay={show:n.delay,hide:n.delay}),o.typeCheckConfig(e,n,this.constructor.DefaultType),n},l.prototype._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},l._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(a),r="object"===(void 0===e?"undefined":i(e))?e:null;if((n||!/dispose|hide/.test(e))&&(n||(n=new l(this,r),t(this).data(a,n)),"string"==typeof e)){if(void 0===n[e])throw new Error('No method named "'+e+'"');n[e]()}})},r(l,null,[{key:"VERSION",get:function(){return"4.0.0-alpha.5"}},{key:"Default",get:function(){return u}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return a}},{key:"Event",get:function(){return p}},{key:"EVENT_KEY",get:function(){return s}},{key:"DefaultType",get:function(){return c}}]),l}();return t.fn[e]=y._jQueryInterface,t.fn[e].Constructor=y,t.fn[e].noConflict=function(){return t.fn[e]=l,y._jQueryInterface},y}(jQuery));!function(o){var s="popover",l="bs.popover",u="."+l,c=o.fn[s],f=o.extend({},a.Default,{placement:"right",trigger:"click",content:"",template:''}),d=o.extend({},a.DefaultType,{content:"(string|element|function)"}),p={FADE:"fade",IN:"in"},h={TITLE:".popover-title",CONTENT:".popover-content"},m={HIDE:"hide"+u,HIDDEN:"hidden"+u,SHOW:"show"+u,SHOWN:"shown"+u,INSERTED:"inserted"+u,CLICK:"click"+u,FOCUSIN:"focusin"+u,FOCUSOUT:"focusout"+u,MOUSEENTER:"mouseenter"+u,MOUSELEAVE:"mouseleave"+u},g=function(a){function c(){return n(this,c),t(this,a.apply(this,arguments))}return e(c,a),c.prototype.isWithContent=function(){return this.getTitle()||this._getContent()},c.prototype.getTipElement=function(){return this.tip=this.tip||o(this.config.template)[0]},c.prototype.setContent=function(){var t=o(this.getTipElement());this.setElementContent(t.find(h.TITLE),this.getTitle()),this.setElementContent(t.find(h.CONTENT),this._getContent()),t.removeClass(p.FADE).removeClass(p.IN),this.cleanupTether()},c.prototype._getContent=function(){return this.element.getAttribute("data-content")||("function"==typeof this.config.content?this.config.content.call(this.element):this.config.content)},c._jQueryInterface=function(t){return this.each(function(){var e=o(this).data(l),n="object"===(void 0===t?"undefined":i(t))?t:null;if((e||!/destroy|hide/.test(t))&&(e||(e=new c(this,n),o(this).data(l,e)),"string"==typeof t)){if(void 0===e[t])throw new Error('No method named "'+t+'"');e[t]()}})},r(c,null,[{key:"VERSION",get:function(){return"4.0.0-alpha.5"}},{key:"Default",get:function(){return f}},{key:"NAME",get:function(){return s}},{key:"DATA_KEY",get:function(){return l}},{key:"Event",get:function(){return m}},{key:"EVENT_KEY",get:function(){return u}},{key:"DefaultType",get:function(){return d}}]),c}(a);o.fn[s]=g._jQueryInterface,o.fn[s].Constructor=g,o.fn[s].noConflict=function(){return o.fn[s]=c,g._jQueryInterface}}(jQuery)}()},function(t,e,n){"use strict";function i(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(t){return"function"==typeof t}function o(t){return"number"==typeof t}function a(t){return"object"==typeof t&&null!==t}function s(t){return void 0===t}t.exports=i,i.EventEmitter=i,i.prototype._events=void 0,i.prototype._maxListeners=void 0,i.defaultMaxListeners=10,i.prototype.setMaxListeners=function(t){if(!o(t)||t<0||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},i.prototype.emit=function(t){var e,n,i,o,l,u;if(this._events||(this._events={}),"error"===t&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){if((e=arguments[1])instanceof Error)throw e;var c=new Error('Uncaught, unspecified "error" event. ('+e+")");throw c.context=e,c}if(n=this._events[t],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(a(n))for(o=Array.prototype.slice.call(arguments,1),u=n.slice(),i=u.length,l=0;l0&&this._events[t].length>n&&(this._events[t].warned=!0,console.trace),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(t,e){function n(){this.removeListener(t,n),i||(i=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var i=!1;return n.listener=e,this.on(t,n),this},i.prototype.removeListener=function(t,e){var n,i,o,s;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],o=n.length,i=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(a(n)){for(s=o;s-- >0;)if(n[s]===e||n[s].listener&&n[s].listener===e){i=s;break}if(i<0)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},i.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else if(n)for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},i.prototype.listeners=function(t){return this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},i.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(r(e))return 1;if(e)return e.length}return 0},i.listenerCount=function(t,e){return t.listenerCount(e)}},function(t,e,n){"use strict";var i,i;!function(e){t.exports=e()}(function(){return function t(e,n,r){function o(s,l){if(!n[s]){if(!e[s]){var u="function"==typeof i&&i;if(!l&&u)return i(s,!0);if(a)return a(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[s]={exports:{}};e[s][0].call(f.exports,function(t){var n=e[s][1][t];return o(n||t)},f,f.exports,t,e,n,r)}return n[s].exports}for(var a="function"==typeof i&&i,s=0;s1&&"flex-start"===t.style.alignContent)for(e=0;i=t.lines[++r];)i.crossStart=e,e+=i.cross;else if(t.lines.length>1&&"flex-end"===t.style.alignContent)for(e=t.flexStyle.crossSpace;i=t.lines[++r];)i.crossStart=e,e+=i.cross;else if(t.lines.length>1&&"center"===t.style.alignContent)for(e=t.flexStyle.crossSpace/2;i=t.lines[++r];)i.crossStart=e,e+=i.cross;else if(t.lines.length>1&&"space-between"===t.style.alignContent)for(n=t.flexStyle.crossSpace/(t.lines.length-1),e=0;i=t.lines[++r];)i.crossStart=e,e+=i.cross+n;else if(t.lines.length>1&&"space-around"===t.style.alignContent)for(n=2*t.flexStyle.crossSpace/(2*t.lines.length),e=n/2;i=t.lines[++r];)i.crossStart=e,e+=i.cross+n;else for(n=t.flexStyle.crossSpace/t.lines.length,e=t.flexStyle.crossInnerBefore;i=t.lines[++r];)i.crossStart=e,i.cross+=n,e+=i.cross}},{}],2:[function(t,e,n){e.exports=function(t){for(var e,n=-1;line=t.lines[++n];)for(e=-1;child=line.children[++e];){var i=child.style.alignSelf;"auto"===i&&(i=t.style.alignItems),"flex-start"===i?child.flexStyle.crossStart=line.crossStart:"flex-end"===i?child.flexStyle.crossStart=line.crossStart+line.cross-child.flexStyle.crossOuter:"center"===i?child.flexStyle.crossStart=line.crossStart+(line.cross-child.flexStyle.crossOuter)/2:(child.flexStyle.crossStart=line.crossStart,child.flexStyle.crossOuter=line.cross,child.flexStyle.cross=child.flexStyle.crossOuter-child.flexStyle.crossBefore-child.flexStyle.crossAfter)}}},{}],3:[function(t,e,n){e.exports=function(t,e){var n="row"===e||"row-reverse"===e,i=t.mainAxis;if(i){n&&"inline"===i||!n&&"block"===i||(t.flexStyle={main:t.flexStyle.cross,cross:t.flexStyle.main,mainOffset:t.flexStyle.crossOffset,crossOffset:t.flexStyle.mainOffset,mainBefore:t.flexStyle.crossBefore,mainAfter:t.flexStyle.crossAfter,crossBefore:t.flexStyle.mainBefore,crossAfter:t.flexStyle.mainAfter,mainInnerBefore:t.flexStyle.crossInnerBefore,mainInnerAfter:t.flexStyle.crossInnerAfter,crossInnerBefore:t.flexStyle.mainInnerBefore,crossInnerAfter:t.flexStyle.mainInnerAfter,mainBorderBefore:t.flexStyle.crossBorderBefore,mainBorderAfter:t.flexStyle.crossBorderAfter,crossBorderBefore:t.flexStyle.mainBorderBefore,crossBorderAfter:t.flexStyle.mainBorderAfter})}else t.flexStyle=n?{main:t.style.width,cross:t.style.height,mainOffset:t.style.offsetWidth,crossOffset:t.style.offsetHeight,mainBefore:t.style.marginLeft,mainAfter:t.style.marginRight,crossBefore:t.style.marginTop,crossAfter:t.style.marginBottom,mainInnerBefore:t.style.paddingLeft,mainInnerAfter:t.style.paddingRight,crossInnerBefore:t.style.paddingTop,crossInnerAfter:t.style.paddingBottom,mainBorderBefore:t.style.borderLeftWidth,mainBorderAfter:t.style.borderRightWidth,crossBorderBefore:t.style.borderTopWidth,crossBorderAfter:t.style.borderBottomWidth}:{main:t.style.height,cross:t.style.width,mainOffset:t.style.offsetHeight,crossOffset:t.style.offsetWidth,mainBefore:t.style.marginTop,mainAfter:t.style.marginBottom,crossBefore:t.style.marginLeft,crossAfter:t.style.marginRight,mainInnerBefore:t.style.paddingTop,mainInnerAfter:t.style.paddingBottom,crossInnerBefore:t.style.paddingLeft,crossInnerAfter:t.style.paddingRight,mainBorderBefore:t.style.borderTopWidth,mainBorderAfter:t.style.borderBottomWidth,crossBorderBefore:t.style.borderLeftWidth,crossBorderAfter:t.style.borderRightWidth},"content-box"===t.style.boxSizing&&("number"==typeof t.flexStyle.main&&(t.flexStyle.main+=t.flexStyle.mainInnerBefore+t.flexStyle.mainInnerAfter+t.flexStyle.mainBorderBefore+t.flexStyle.mainBorderAfter),"number"==typeof t.flexStyle.cross&&(t.flexStyle.cross+=t.flexStyle.crossInnerBefore+t.flexStyle.crossInnerAfter+t.flexStyle.crossBorderBefore+t.flexStyle.crossBorderAfter));t.mainAxis=n?"inline":"block",t.crossAxis=n?"block":"inline","number"==typeof t.style.flexBasis&&(t.flexStyle.main=t.style.flexBasis+t.flexStyle.mainInnerBefore+t.flexStyle.mainInnerAfter+t.flexStyle.mainBorderBefore+t.flexStyle.mainBorderAfter),t.flexStyle.mainOuter=t.flexStyle.main,t.flexStyle.crossOuter=t.flexStyle.cross,"auto"===t.flexStyle.mainOuter&&(t.flexStyle.mainOuter=t.flexStyle.mainOffset),"auto"===t.flexStyle.crossOuter&&(t.flexStyle.crossOuter=t.flexStyle.crossOffset),"number"==typeof t.flexStyle.mainBefore&&(t.flexStyle.mainOuter+=t.flexStyle.mainBefore),"number"==typeof t.flexStyle.mainAfter&&(t.flexStyle.mainOuter+=t.flexStyle.mainAfter),"number"==typeof t.flexStyle.crossBefore&&(t.flexStyle.crossOuter+=t.flexStyle.crossBefore),"number"==typeof t.flexStyle.crossAfter&&(t.flexStyle.crossOuter+=t.flexStyle.crossAfter)}},{}],4:[function(t,e,n){var i=t("../reduce");e.exports=function(t){if(t.mainSpace>0){var e=i(t.children,function(t,e){return t+parseFloat(e.style.flexGrow)},0);e>0&&(t.main=i(t.children,function(n,i){return"auto"===i.flexStyle.main?i.flexStyle.main=i.flexStyle.mainOffset+parseFloat(i.style.flexGrow)/e*t.mainSpace:i.flexStyle.main+=parseFloat(i.style.flexGrow)/e*t.mainSpace,i.flexStyle.mainOuter=i.flexStyle.main+i.flexStyle.mainBefore+i.flexStyle.mainAfter,n+i.flexStyle.mainOuter},0),t.mainSpace=0)}}},{"../reduce":12}],5:[function(t,e,n){var i=t("../reduce");e.exports=function(t){if(t.mainSpace<0){var e=i(t.children,function(t,e){return t+parseFloat(e.style.flexShrink)},0);e>0&&(t.main=i(t.children,function(n,i){return i.flexStyle.main+=parseFloat(i.style.flexShrink)/e*t.mainSpace,i.flexStyle.mainOuter=i.flexStyle.main+i.flexStyle.mainBefore+i.flexStyle.mainAfter,n+i.flexStyle.mainOuter},0),t.mainSpace=0)}}},{"../reduce":12}],6:[function(t,e,n){var i=t("../reduce");e.exports=function(t){var e;t.lines=[e={main:0,cross:0,children:[]}];for(var n,r=-1;n=t.children[++r];)"nowrap"===t.style.flexWrap||0===e.children.length||"auto"===t.flexStyle.main||t.flexStyle.main-t.flexStyle.mainInnerBefore-t.flexStyle.mainInnerAfter-t.flexStyle.mainBorderBefore-t.flexStyle.mainBorderAfter>=e.main+n.flexStyle.mainOuter?(e.main+=n.flexStyle.mainOuter,e.cross=Math.max(e.cross,n.flexStyle.crossOuter)):t.lines.push(e={main:n.flexStyle.mainOuter,cross:n.flexStyle.crossOuter,children:[]}),e.children.push(n);t.flexStyle.mainLines=i(t.lines,function(t,e){return Math.max(t,e.main)},0),t.flexStyle.crossLines=i(t.lines,function(t,e){return t+e.cross},0),"auto"===t.flexStyle.main&&(t.flexStyle.main=Math.max(t.flexStyle.mainOffset,t.flexStyle.mainLines+t.flexStyle.mainInnerBefore+t.flexStyle.mainInnerAfter+t.flexStyle.mainBorderBefore+t.flexStyle.mainBorderAfter)),"auto"===t.flexStyle.cross&&(t.flexStyle.cross=Math.max(t.flexStyle.crossOffset,t.flexStyle.crossLines+t.flexStyle.crossInnerBefore+t.flexStyle.crossInnerAfter+t.flexStyle.crossBorderBefore+t.flexStyle.crossBorderAfter)),t.flexStyle.crossSpace=t.flexStyle.cross-t.flexStyle.crossInnerBefore-t.flexStyle.crossInnerAfter-t.flexStyle.crossBorderBefore-t.flexStyle.crossBorderAfter-t.flexStyle.crossLines,t.flexStyle.mainOuter=t.flexStyle.main+t.flexStyle.mainBefore+t.flexStyle.mainAfter,t.flexStyle.crossOuter=t.flexStyle.cross+t.flexStyle.crossBefore+t.flexStyle.crossAfter}},{"../reduce":12}],7:[function(t,e,n){function i(e){for(var n,i=-1;n=e.children[++i];)t("./flex-direction")(n,e.style.flexDirection);t("./flex-direction")(e,e.style.flexDirection),t("./order")(e),t("./flexbox-lines")(e),t("./align-content")(e),i=-1;for(var r;r=e.lines[++i];)r.mainSpace=e.flexStyle.main-e.flexStyle.mainInnerBefore-e.flexStyle.mainInnerAfter-e.flexStyle.mainBorderBefore-e.flexStyle.mainBorderAfter-r.main,t("./flex-grow")(r),t("./flex-shrink")(r),t("./margin-main")(r),t("./margin-cross")(r),t("./justify-content")(r,e.style.justifyContent,e);t("./align-items")(e)}e.exports=i},{"./align-content":1,"./align-items":2,"./flex-direction":3,"./flex-grow":4,"./flex-shrink":5,"./flexbox-lines":6,"./justify-content":8,"./margin-cross":9,"./margin-main":10,"./order":11}],8:[function(t,e,n){e.exports=function(t,e,n){var i,r,o,a=n.flexStyle.mainInnerBefore,s=-1;if("flex-end"===e)for(i=t.mainSpace,i+=a;o=t.children[++s];)o.flexStyle.mainStart=i,i+=o.flexStyle.mainOuter;else if("center"===e)for(i=t.mainSpace/2,i+=a;o=t.children[++s];)o.flexStyle.mainStart=i,i+=o.flexStyle.mainOuter;else if("space-between"===e)for(r=t.mainSpace/(t.children.length-1),i=0,i+=a;o=t.children[++s];)o.flexStyle.mainStart=i,i+=o.flexStyle.mainOuter+r;else if("space-around"===e)for(r=2*t.mainSpace/(2*t.children.length),i=r/2,i+=a;o=t.children[++s];)o.flexStyle.mainStart=i,i+=o.flexStyle.mainOuter+r;else for(i=0,i+=a;o=t.children[++s];)o.flexStyle.mainStart=i,i+=o.flexStyle.mainOuter}},{}],9:[function(t,e,n){e.exports=function(t){for(var e,n=-1;e=t.children[++n];){var i=0;"auto"===e.flexStyle.crossBefore&&++i,"auto"===e.flexStyle.crossAfter&&++i;var r=t.cross-e.flexStyle.crossOuter;"auto"===e.flexStyle.crossBefore&&(e.flexStyle.crossBefore=r/i),"auto"===e.flexStyle.crossAfter&&(e.flexStyle.crossAfter=r/i),"auto"===e.flexStyle.cross?e.flexStyle.crossOuter=e.flexStyle.crossOffset+e.flexStyle.crossBefore+e.flexStyle.crossAfter:e.flexStyle.crossOuter=e.flexStyle.cross+e.flexStyle.crossBefore+e.flexStyle.crossAfter}}},{}],10:[function(t,e,n){e.exports=function(t){for(var e,n=0,i=-1;e=t.children[++i];)"auto"===e.flexStyle.mainBefore&&++n,"auto"===e.flexStyle.mainAfter&&++n;if(n>0){for(i=-1;e=t.children[++i];)"auto"===e.flexStyle.mainBefore&&(e.flexStyle.mainBefore=t.mainSpace/n),"auto"===e.flexStyle.mainAfter&&(e.flexStyle.mainAfter=t.mainSpace/n),"auto"===e.flexStyle.main?e.flexStyle.mainOuter=e.flexStyle.mainOffset+e.flexStyle.mainBefore+e.flexStyle.mainAfter:e.flexStyle.mainOuter=e.flexStyle.main+e.flexStyle.mainBefore+e.flexStyle.mainAfter;t.mainSpace=0}}},{}],11:[function(t,e,n){var i=/^(column|row)-reverse$/;e.exports=function(t){t.children.sort(function(t,e){return t.style.order-e.style.order||t.index-e.index}),i.test(t.style.flexDirection)&&t.children.reverse()}},{}],12:[function(t,e,n){function i(t,e,n){for(var i=t.length,r=-1;++r=0)&&i.push(r)}return i.push(t.ownerDocument.body),t.ownerDocument!==document&&i.push(t.ownerDocument.defaultView),i}function a(){C&&document.body.removeChild(C),C=null}function s(t){var e=void 0;t===document?(e=document,t=document.documentElement):e=t.ownerDocument;var n=e.documentElement,i=r(t),o=I();return i.top-=o.top,i.left-=o.left,void 0===i.width&&(i.width=document.body.scrollWidth-i.left-i.right),void 0===i.height&&(i.height=document.body.scrollHeight-i.top-i.bottom),i.top=i.top-n.clientTop,i.left=i.left-n.clientLeft,i.right=e.body.clientWidth-i.width-i.left,i.bottom=e.body.clientHeight-i.height-i.top,i}function l(t){return t.offsetParent||document.documentElement}function u(){if(O)return O;var t=document.createElement("div");t.style.width="100%",t.style.height="200px";var e=document.createElement("div");c(e.style,{position:"absolute",top:0,left:0,pointerEvents:"none",visibility:"hidden",width:"200px",height:"150px",overflow:"hidden"}),e.appendChild(t),document.body.appendChild(e);var n=t.offsetWidth;e.style.overflow="scroll";var i=t.offsetWidth;n===i&&(i=e.clientWidth),document.body.removeChild(e);var r=n-i;return O={width:r,height:r}}function c(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],e=[];return Array.prototype.push.apply(e,arguments),e.slice(1).forEach(function(e){if(e)for(var n in e)({}).hasOwnProperty.call(e,n)&&(t[n]=e[n])}),t}function f(t,e){if(void 0!==t.classList)e.split(" ").forEach(function(e){e.trim()&&t.classList.remove(e)});else{var n=new RegExp("(^| )"+e.split(" ").join("|")+"( |$)","gi"),i=h(t).replace(n," ");m(t,i)}}function d(t,e){if(void 0!==t.classList)e.split(" ").forEach(function(e){e.trim()&&t.classList.add(e)});else{f(t,e);var n=h(t)+" "+e;m(t,n)}}function p(t,e){if(void 0!==t.classList)return t.classList.contains(e);var n=h(t);return new RegExp("(^| )"+e+"( |$)","gi").test(n)}function h(t){return t.className instanceof t.ownerDocument.defaultView.SVGAnimatedString?t.className.baseVal:t.className}function m(t,e){t.setAttribute("class",e)}function g(t,e,n){n.forEach(function(n){-1===e.indexOf(n)&&p(t,n)&&f(t,n)}),e.forEach(function(e){p(t,e)||d(t,e)})}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function v(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function y(t,e){var n=arguments.length<=2||void 0===arguments[2]?1:arguments[2];return t+n>=e&&e>=t-n}function b(){return"undefined"!=typeof performance&&void 0!==performance.now?performance.now():+new Date}function _(){for(var t={top:0,left:0},e=arguments.length,n=Array(e),i=0;i1?n-1:0),r=1;r16)return e=Math.min(e-16,250),void(n=setTimeout(i,250));void 0!==t&&b()-t<10||(null!=n&&(clearTimeout(n),n=null),t=b(),R(),e=b()-t)};"undefined"!=typeof window&&void 0!==window.addEventListener&&["resize","scroll","touchmove"].forEach(function(t){window.addEventListener(t,i)})}();var M={center:"center",left:"right",right:"left"},H={middle:"middle",top:"bottom",bottom:"top"},W={top:0,left:0,middle:"50%",center:"50%",bottom:"100%",right:"100%"},U=function(t,e){var n=t.left,i=t.top;return"auto"===n&&(n=M[e.left]),"auto"===i&&(i=H[e.top]),{left:n,top:i}},q=function(t){var e=t.left,n=t.top;return void 0!==W[t.left]&&(e=W[t.left]),void 0!==W[t.top]&&(n=W[t.top]),{left:e,top:n}},z=function(t){var e=t.split(" "),n=L(e,2);return{top:n[0],left:n[1]}},$=z,Q=function(t){function e(t){var n=this;i(this,e),j(Object.getPrototypeOf(e.prototype),"constructor",this).call(this),this.position=this.position.bind(this),F.push(this),this.history=[],this.setOptions(t,!1),E.modules.forEach(function(t){void 0!==t.initialize&&t.initialize.call(n)}),this.position()}return v(e,t),S(e,[{key:"getClass",value:function(){var t=arguments.length<=0||void 0===arguments[0]?"":arguments[0],e=this.options.classes;return void 0!==e&&e[t]?this.options.classes[t]:this.options.classPrefix?this.options.classPrefix+"-"+t:t}},{key:"setOptions",value:function(t){var e=this,n=arguments.length<=1||void 0===arguments[1]||arguments[1],i={offset:"0 0",targetOffset:"0 0",targetAttachment:"auto auto",classPrefix:"tether"};this.options=c(i,t);var r=this.options,a=r.element,s=r.target,l=r.targetModifier;if(this.element=a,this.target=s,this.targetModifier=l,"viewport"===this.target?(this.target=document.body,this.targetModifier="visible"):"scroll-handle"===this.target&&(this.target=document.body,this.targetModifier="scroll-handle"),["element","target"].forEach(function(t){if(void 0===e[t])throw new Error("Tether Error: Both element and target must be defined");void 0!==e[t].jquery?e[t]=e[t][0]:"string"==typeof e[t]&&(e[t]=document.querySelector(e[t]))}),d(this.element,this.getClass("element")),!1!==this.options.addTargetClasses&&d(this.target,this.getClass("target")),!this.options.attachment)throw new Error("Tether Error: You must provide an attachment");this.targetAttachment=$(this.options.targetAttachment),this.attachment=$(this.options.attachment),this.offset=z(this.options.offset),this.targetOffset=z(this.options.targetOffset),void 0!==this.scrollParents&&this.disable(),"scroll-handle"===this.targetModifier?this.scrollParents=[this.target]:this.scrollParents=o(this.target),!1!==this.options.enabled&&this.enable(n)}},{key:"getTargetBounds",value:function(){if(void 0===this.targetModifier)return s(this.target);if("visible"===this.targetModifier){if(this.target===document.body)return{top:pageYOffset,left:pageXOffset,height:innerHeight,width:innerWidth};var t=s(this.target),e={height:t.height,width:t.width,top:t.top,left:t.left};return e.height=Math.min(e.height,t.height-(pageYOffset-t.top)),e.height=Math.min(e.height,t.height-(t.top+t.height-(pageYOffset+innerHeight))),e.height=Math.min(innerHeight,e.height),e.height-=2,e.width=Math.min(e.width,t.width-(pageXOffset-t.left)),e.width=Math.min(e.width,t.width-(t.left+t.width-(pageXOffset+innerWidth))),e.width=Math.min(innerWidth,e.width),e.width-=2,e.topn.clientWidth||[i.overflow,i.overflowX].indexOf("scroll")>=0||this.target!==document.body,o=0;r&&(o=15);var a=t.height-parseFloat(i.borderTopWidth)-parseFloat(i.borderBottomWidth)-o,e={width:15,height:.975*a*(a/n.scrollHeight),left:t.left+t.width-parseFloat(i.borderLeftWidth)-15},l=0;a<408&&this.target===document.body&&(l=-11e-5*Math.pow(a,2)-.00727*a+22.58),this.target!==document.body&&(e.height=Math.max(e.height,24));var u=this.target.scrollTop/(n.scrollHeight-a);return e.top=u*(a-e.height-l)+t.top+parseFloat(i.borderTopWidth),this.target===document.body&&(e.height=Math.max(e.height,24)),e}}},{key:"clearCache",value:function(){this._cache={}}},{key:"cache",value:function(t,e){return void 0===this._cache&&(this._cache={}),void 0===this._cache[t]&&(this._cache[t]=e.call(this)),this._cache[t]}},{key:"enable",value:function(){var t=this,e=arguments.length<=0||void 0===arguments[0]||arguments[0];!1!==this.options.addTargetClasses&&d(this.target,this.getClass("enabled")),d(this.element,this.getClass("enabled")),this.enabled=!0,this.scrollParents.forEach(function(e){e!==t.target.ownerDocument&&e.addEventListener("scroll",t.position)}),e&&this.position()}},{key:"disable",value:function(){var t=this;f(this.target,this.getClass("enabled")),f(this.element,this.getClass("enabled")),this.enabled=!1,void 0!==this.scrollParents&&this.scrollParents.forEach(function(e){e.removeEventListener("scroll",t.position)})}},{key:"destroy",value:function(){var t=this;this.disable(),F.forEach(function(e,n){e===t&&F.splice(n,1)}),0===F.length&&a()}},{key:"updateAttachClasses",value:function(t,e){var n=this;t=t||this.attachment,e=e||this.targetAttachment;var i=["left","top","bottom","right","middle","center"];void 0!==this._addAttachClasses&&this._addAttachClasses.length&&this._addAttachClasses.splice(0,this._addAttachClasses.length),void 0===this._addAttachClasses&&(this._addAttachClasses=[]);var r=this._addAttachClasses;t.top&&r.push(this.getClass("element-attached")+"-"+t.top),t.left&&r.push(this.getClass("element-attached")+"-"+t.left),e.top&&r.push(this.getClass("target-attached")+"-"+e.top),e.left&&r.push(this.getClass("target-attached")+"-"+e.left);var o=[];i.forEach(function(t){o.push(n.getClass("element-attached")+"-"+t),o.push(n.getClass("target-attached")+"-"+t)}),D(function(){void 0!==n._addAttachClasses&&(g(n.element,n._addAttachClasses,o),!1!==n.options.addTargetClasses&&g(n.target,n._addAttachClasses,o),delete n._addAttachClasses)})}},{key:"position",value:function(){var t=this,e=arguments.length<=0||void 0===arguments[0]||arguments[0];if(this.enabled){this.clearCache();var n=U(this.targetAttachment,this.attachment);this.updateAttachClasses(this.attachment,n);var i=this.cache("element-bounds",function(){return s(t.element)}),r=i.width,o=i.height;if(0===r&&0===o&&void 0!==this.lastSize){var a=this.lastSize;r=a.width,o=a.height}else this.lastSize={width:r,height:o};var c=this.cache("target-bounds",function(){return t.getTargetBounds()}),f=c,d=x(q(this.attachment),{width:r,height:o}),p=x(q(n),f),h=x(this.offset,{width:r,height:o}),m=x(this.targetOffset,f);d=_(d,h),p=_(p,m);for(var g=c.left+p.left-d.left,v=c.top+p.top-d.top,y=0;yC.documentElement.clientHeight&&(A=this.cache("scrollbar-size",u),S.viewport.bottom-=A.height),T.innerWidth>C.documentElement.clientWidth&&(A=this.cache("scrollbar-size",u),S.viewport.right-=A.width),-1!==["","static"].indexOf(C.body.style.position)&&-1!==["","static"].indexOf(C.body.parentElement.style.position)||(S.page.bottom=C.body.scrollHeight-v-o,S.page.right=C.body.scrollWidth-g-r),void 0!==this.options.optimizations&&!1!==this.options.optimizations.moveElement&&void 0===this.targetModifier&&function(){var e=t.cache("target-offsetparent",function(){return l(t.target)}),n=t.cache("target-offsetparent-bounds",function(){return s(e)}),i=getComputedStyle(e),r=n,o={};if(["Top","Left","Bottom","Right"].forEach(function(t){o[t.toLowerCase()]=parseFloat(i["border"+t+"Width"])}),n.right=C.body.scrollWidth-n.left-r.width+o.right,n.bottom=C.body.scrollHeight-n.top-r.height+o.bottom,S.page.top>=n.top+o.top&&S.page.bottom>=n.bottom&&S.page.left>=n.left+o.left&&S.page.right>=n.right){var a=e.scrollTop,u=e.scrollLeft;S.offset={top:S.page.top-n.top+a-o.top,left:S.page.left-n.left+u-o.left}}}(),this.move(S),this.history.unshift(S),this.history.length>3&&this.history.pop(),e&&N(),!0}}},{key:"move",value:function(t){var e=this;if(void 0!==this.element.parentNode){var n={};for(var i in t){n[i]={};for(var r in t[i]){for(var o=!1,a=0;a=0){var h=s.split(" "),g=L(h,2);f=g[0],c=g[1]}else c=f=s;var b=w(e,o);"target"!==f&&"both"!==f||(nb[3]&&"bottom"===v.top&&(n-=d,v.top="top")),"together"===f&&("top"===v.top&&("bottom"===y.top&&nb[3]&&n-(a-d)>=b[1]&&(n-=a-d,v.top="bottom",y.top="bottom")),"bottom"===v.top&&("top"===y.top&&n+a>b[3]?(n-=d,v.top="top",n-=a,y.top="bottom"):"bottom"===y.top&&nb[3]&&"top"===y.top?(n-=a,y.top="bottom"):nb[2]&&"right"===v.left&&(i-=p,v.left="left")),"together"===c&&(ib[2]&&"right"===v.left?"left"===y.left?(i-=p,v.left="left",i-=l,y.left="right"):"right"===y.left&&(i-=p,v.left="left",i+=l,y.left="left"):"center"===v.left&&(i+l>b[2]&&"left"===y.left?(i-=l,y.left="right"):ib[3]&&"top"===y.top&&(n-=a,y.top="bottom")),"element"!==c&&"both"!==c||(ib[2]&&("left"===y.left?(i-=l,y.left="right"):"center"===y.left&&(i-=l/2,y.left="right"))),"string"==typeof u?u=u.split(",").map(function(t){return t.trim()}):!0===u&&(u=["top","left","right","bottom"]),u=u||[];var _=[],x=[];n=0?(n=b[1],_.push("top")):x.push("top")),n+a>b[3]&&(u.indexOf("bottom")>=0?(n=b[3]-a,_.push("bottom")):x.push("bottom")),i=0?(i=b[0],_.push("left")):x.push("left")),i+l>b[2]&&(u.indexOf("right")>=0?(i=b[2]-l,_.push("right")):x.push("right")),_.length&&function(){var t=void 0;t=void 0!==e.options.pinnedClass?e.options.pinnedClass:e.getClass("pinned"),m.push(t),_.forEach(function(e){m.push(t+"-"+e)})}(),x.length&&function(){var t=void 0;t=void 0!==e.options.outOfBoundsClass?e.options.outOfBoundsClass:e.getClass("out-of-bounds"),m.push(t),x.forEach(function(e){m.push(t+"-"+e)})}(),(_.indexOf("left")>=0||_.indexOf("right")>=0)&&(y.left=v.left=!1),(_.indexOf("top")>=0||_.indexOf("bottom")>=0)&&(y.top=v.top=!1),v.top===r.top&&v.left===r.left&&y.top===e.attachment.top&&y.left===e.attachment.left||(e.updateAttachClasses(y,v),e.trigger("update",{attachment:y,targetAttachment:v}))}),D(function(){!1!==e.options.addTargetClasses&&g(e.target,m,h),g(e.element,m,h)}),{top:n,left:i}}});var B=E.Utils,s=B.getBounds,g=B.updateClasses,D=B.defer;E.modules.push({position:function(t){var e=this,n=t.top,i=t.left,r=this.cache("element-bounds",function(){return s(e.element)}),o=r.height,a=r.width,l=this.getTargetBounds(),u=n+o,c=i+a,f=[];n<=l.bottom&&u>=l.top&&["left","right"].forEach(function(t){var e=l[t];e!==i&&e!==c||f.push(t)}),i<=l.right&&c>=l.left&&["top","bottom"].forEach(function(t){var e=l[t];e!==n&&e!==u||f.push(t)});var d=[],p=[],h=["left","top","right","bottom"];return d.push(this.getClass("abutted")),h.forEach(function(t){d.push(e.getClass("abutted")+"-"+t)}),f.length&&p.push(this.getClass("abutted")),f.forEach(function(t){p.push(e.getClass("abutted")+"-"+t)}),D(function(){!1!==e.options.addTargetClasses&&g(e.target,p,d),g(e.element,p,d)}),!0}});var L=function(){function t(t,e){var n=[],i=!0,r=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(i=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);i=!0);}catch(t){r=!0,o=t}finally{try{!i&&s.return&&s.return()}finally{if(r)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();return E.modules.push({position:function(t){var e=t.top,n=t.left;if(this.options.shift){var i=this.options.shift;"function"==typeof this.options.shift&&(i=this.options.shift.call(this,{top:e,left:n}));var r=void 0,o=void 0;if("string"==typeof i){i=i.split(" "),i[1]=i[1]||i[0];var a=i,s=L(a,2);r=s[0],o=s[1],r=parseFloat(r,10),o=parseFloat(o,10)}else r=i.top,o=i.left;return e+=r,n+=o,{top:e,left:n}}}}),G})},function(t,e,n){"use strict";var i;i=function(){return this}();try{i=i||Function("return this")()||(0,eval)("this")}catch(t){"object"==typeof window&&(i=window)}t.exports=i},function(t,e,n){(function(e){t.exports=e.Tether=n(23)}).call(e,n(24))},function(t,e,n){n(5),t.exports=n(6)}]); \ No newline at end of file diff --git a/themes/classic/config/.htaccess b/themes/classic/config/.htaccess deleted file mode 100644 index 3de9e400..00000000 --- a/themes/classic/config/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order deny,allow - Deny from all - - -# Apache 2.4 - - Require all denied - diff --git a/themes/classic/config/theme.yml b/themes/classic/config/theme.yml deleted file mode 100644 index 91c487d2..00000000 --- a/themes/classic/config/theme.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: classic -display_name: Classic -version: 1.0.0 -author: - name: "PrestaShop Team" - email: "pub@prestashop.com" - url: "http://www.prestashop.com" - -meta: - compatibility: - from: 1.7.0.0 - to: ~ - - available_layouts: - layout-full-width: - name: Full Width - description: No side columns, ideal for distraction-free pages such as product pages. - layout-both-columns: - name: Three Columns - description: One large central column and 2 side columns. - layout-left-column: - name: Two Columns, small left column - description: Two columns with a small left column - layout-right-column: - name: Two Columns, small right column - description: Two columns with a small right column - -assets: - # If you're using this theme as child and you want to load - # the parent theme assets, uncomment this line. -# use_parent_assets: true - - # The following lines are showing how to load assets in your page - # Uncomment and change value to start loading css or js files -# css: -# all: -# - id: custom-lib-style -# path: assets/css/custom-lib.css -# product: -# - id: product-style -# path: assets/css/product.css -# media: all -# priority: 200 -# js: -# cart: -# - id: cat-extra-lib -# path: assets/js/cart-lib.js - - -global_settings: - configuration: - PS_IMAGE_QUALITY: png - modules: - to_enable: - - ps_linklist - hooks: - modules_to_hook: - displayNav1: - - ps_contactinfo - displayNav2: - - ps_languageselector - - ps_currencyselector - - ps_customersignin - - ps_shoppingcart - displayTop: - - ps_mainmenu - - ps_searchbar - displayHome: - - ps_imageslider - - ps_featuredproducts - - ps_banner - - ps_customtext - displayFooterBefore: - - ps_emailsubscription - - ps_socialfollow - displayFooter: - - ps_linklist - - ps_customeraccountlinks - - ps_contactinfo - displayLeftColumn: - - ps_categorytree - - ps_facetedsearch - displaySearch: - - ps_searchbar - displayProductAdditionalInfo: - - ps_sharebuttons - displayReassurance: - - blockreassurance - displayOrderConfirmation2: - - ps_featuredproducts - displayCrossSellingShoppingCart: - - ps_featuredproducts - - image_types: - cart_default: - width: 125 - height: 125 - scope: [products] - small_default: - width: 98 - height: 98 - scope: [products, categories, manufacturers, suppliers] - medium_default: - width: 452 - height: 452 - scope: [products, manufacturers, suppliers] - home_default: - width: 250 - height: 250 - scope: [products] - large_default: - width: 800 - height: 800 - scope: [products, manufacturers, suppliers] - category_default: - width: 141 - height: 180 - scope: [categories] - stores_default: - width: 170 - height: 115 - scope: [stores] - -theme_settings: - default_layout: layout-full-width - layouts: - category: layout-left-column - best-sales: layout-left-column - new-products: layout-left-column - prices-drop: layout-left-column - contact: layout-left-column diff --git a/themes/classic/lang/pl.php b/themes/classic/lang/pl.php deleted file mode 100644 index e69de29b..00000000 diff --git a/themes/classic/modules/blockreassurance/views/templates/hook/blockreassurance.tpl b/themes/classic/modules/blockreassurance/views/templates/hook/blockreassurance.tpl deleted file mode 100644 index 196ea011..00000000 --- a/themes/classic/modules/blockreassurance/views/templates/hook/blockreassurance.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $elements} -
    -
      - {foreach from=$elements item=element} -
    • -
      - {$element.text} - {$element.text} -
      -
    • - {/foreach} -
    -
    -{/if} diff --git a/themes/classic/modules/contactform/views/templates/widget/contactform.tpl b/themes/classic/modules/contactform/views/templates/widget/contactform.tpl deleted file mode 100644 index 18849f01..00000000 --- a/themes/classic/modules/contactform/views/templates/widget/contactform.tpl +++ /dev/null @@ -1,135 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - - {if $notifications} -
    -
      - {foreach $notifications.messages as $notif} -
    • {$notif}
    • - {/foreach} -
    -
    - {/if} - - {if !$notifications || $notifications.nw_error} -
    - -
    -
    -

    {l s='Contact us' d='Shop.Theme.Global'}

    -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - - {if $contact.orders} -
    - -
    - -
    - - {l s='optional' d='Shop.Forms.Help'} - -
    - {/if} - - {if $contact.allow_file_upload} -
    - -
    - -
    - - {l s='optional' d='Shop.Forms.Help'} - -
    - {/if} - -
    - -
    - -
    -
    - - {if isset($id_module)} -
    -
    - {hook h='displayGDPRConsent' id_module=$id_module} -
    -
    - {/if} - -
    - -
    - - - - -
    - {/if} - -
    -
    diff --git a/themes/classic/modules/ps_advertising/index.php b/themes/classic/modules/ps_advertising/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_advertising/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_advertising/ps_advertising.tpl b/themes/classic/modules/ps_advertising/ps_advertising.tpl deleted file mode 100644 index 88537787..00000000 --- a/themes/classic/modules/ps_advertising/ps_advertising.tpl +++ /dev/null @@ -1,28 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    diff --git a/themes/classic/modules/ps_banner/ps_banner.tpl b/themes/classic/modules/ps_banner/ps_banner.tpl deleted file mode 100644 index 04f6ca4d..00000000 --- a/themes/classic/modules/ps_banner/ps_banner.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_bestsellers/views/index.php b/themes/classic/modules/ps_bestsellers/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_bestsellers/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_bestsellers/views/templates/hook/index.php b/themes/classic/modules/ps_bestsellers/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_bestsellers/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_bestsellers/views/templates/hook/ps_bestsellers.tpl b/themes/classic/modules/ps_bestsellers/views/templates/hook/ps_bestsellers.tpl deleted file mode 100644 index 66f12860..00000000 --- a/themes/classic/modules/ps_bestsellers/views/templates/hook/ps_bestsellers.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_bestsellers/views/templates/index.php b/themes/classic/modules/ps_bestsellers/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_bestsellers/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_brandlist/views/index.php b/themes/classic/modules/ps_brandlist/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_brandlist/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_form.tpl b/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_form.tpl deleted file mode 100644 index cbd1fb57..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_form.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    - -
    diff --git a/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_text.tpl b/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_text.tpl deleted file mode 100644 index 23996307..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/_partials/brand_text.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
      - {foreach from=$brands item=brand name=brand_list} - {if $smarty.foreach.brand_list.iteration <= $text_list_nb} -
    • - - {$brand['name']} - -
    • - {/if} - {/foreach} -
    diff --git a/themes/classic/modules/ps_brandlist/views/templates/_partials/index.php b/themes/classic/modules/ps_brandlist/views/templates/_partials/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/_partials/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_brandlist/views/templates/hook/index.php b/themes/classic/modules/ps_brandlist/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_brandlist/views/templates/hook/ps_brandlist.tpl b/themes/classic/modules/ps_brandlist/views/templates/hook/ps_brandlist.tpl deleted file mode 100644 index 624a1743..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/hook/ps_brandlist.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    -
    -

    - {if $display_link_brand}{/if} - {l s='Brands' d='Shop.Theme.Catalog'} - {if $display_link_brand}{/if} -

    -
    - {if $brands} - {include file="module:ps_brandlist/views/templates/_partials/$brand_display_type.tpl" brands=$brands} - {else} -

    {l s='No brand' d='Shop.Theme.Catalog'}

    - {/if} -
    -
    -
    diff --git a/themes/classic/modules/ps_brandlist/views/templates/index.php b/themes/classic/modules/ps_brandlist/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_brandlist/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_categoryproducts/views/index.php b/themes/classic/modules/ps_categoryproducts/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_categoryproducts/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_categoryproducts/views/templates/hook/index.php b/themes/classic/modules/ps_categoryproducts/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_categoryproducts/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_categoryproducts/views/templates/hook/ps_categoryproducts.tpl b/themes/classic/modules/ps_categoryproducts/views/templates/hook/ps_categoryproducts.tpl deleted file mode 100644 index 31394448..00000000 --- a/themes/classic/modules/ps_categoryproducts/views/templates/hook/ps_categoryproducts.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_categoryproducts/views/templates/index.php b/themes/classic/modules/ps_categoryproducts/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_categoryproducts/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_categorytree/views/templates/hook/ps_categorytree.tpl b/themes/classic/modules/ps_categorytree/views/templates/hook/ps_categorytree.tpl deleted file mode 100644 index 90e78c7b..00000000 --- a/themes/classic/modules/ps_categorytree/views/templates/hook/ps_categorytree.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -{function name="categories" nodes=[] depth=0} - {strip} - {if $nodes|count} -
      - {foreach from=$nodes item=node} -
    • - {if $depth===0} - {$node.name} - {if $node.children} - -
      - {categories nodes=$node.children depth=$depth+1} -
      - {/if} - {else} - {$node.name} - {if $node.children} - - - - -
      - {categories nodes=$node.children depth=$depth+1} -
      - {/if} - {/if} -
    • - {/foreach} -
    - {/if} - {/strip} -{/function} - -
    - -
    diff --git a/themes/classic/modules/ps_contactinfo/nav.tpl b/themes/classic/modules/ps_contactinfo/nav.tpl deleted file mode 100644 index c3255174..00000000 --- a/themes/classic/modules/ps_contactinfo/nav.tpl +++ /dev/null @@ -1,42 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_contactinfo/ps_contactinfo-rich.tpl b/themes/classic/modules/ps_contactinfo/ps_contactinfo-rich.tpl deleted file mode 100644 index ae79bc0a..00000000 --- a/themes/classic/modules/ps_contactinfo/ps_contactinfo-rich.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    -

    {l s='Store information' d='Shop.Theme.Global'}

    -
    -
    -
    {$contact_infos.address.formatted nofilter}
    -
    - {if $contact_infos.phone} -
    -
    -
    -
    - {l s='Call us:' d='Shop.Theme.Global'}
    - {$contact_infos.phone} -
    -
    - {/if} - {if $contact_infos.fax} -
    -
    -
    -
    - {l s='Fax:' d='Shop.Theme.Global'}
    - {$contact_infos.fax} -
    -
    - {/if} - {if $contact_infos.email} -
    -
    -
    - - {$contact_infos.email} -
    - {/if} -
    diff --git a/themes/classic/modules/ps_contactinfo/ps_contactinfo.tpl b/themes/classic/modules/ps_contactinfo/ps_contactinfo.tpl deleted file mode 100644 index e7bda1b3..00000000 --- a/themes/classic/modules/ps_contactinfo/ps_contactinfo.tpl +++ /dev/null @@ -1,74 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_crossselling/views/index.php b/themes/classic/modules/ps_crossselling/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_crossselling/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_crossselling/views/templates/hook/index.php b/themes/classic/modules/ps_crossselling/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_crossselling/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_crossselling/views/templates/hook/ps_crossselling.tpl b/themes/classic/modules/ps_crossselling/views/templates/hook/ps_crossselling.tpl deleted file mode 100644 index 020b16d5..00000000 --- a/themes/classic/modules/ps_crossselling/views/templates/hook/ps_crossselling.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_crossselling/views/templates/index.php b/themes/classic/modules/ps_crossselling/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_crossselling/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_currencyselector/ps_currencyselector.tpl b/themes/classic/modules/ps_currencyselector/ps_currencyselector.tpl deleted file mode 100644 index aaf9c7be..00000000 --- a/themes/classic/modules/ps_currencyselector/ps_currencyselector.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    - -
    diff --git a/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl b/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl deleted file mode 100644 index ee8832e8..00000000 --- a/themes/classic/modules/ps_customeraccountlinks/ps_customeraccountlinks.tpl +++ /dev/null @@ -1,51 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_customersignin/ps_customersignin.tpl b/themes/classic/modules/ps_customersignin/ps_customersignin.tpl deleted file mode 100644 index 7e15e4ea..00000000 --- a/themes/classic/modules/ps_customersignin/ps_customersignin.tpl +++ /dev/null @@ -1,56 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_emailalerts/views/index.php b/themes/classic/modules/ps_emailalerts/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_emailalerts/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_emailalerts/views/templates/hook/index.php b/themes/classic/modules/ps_emailalerts/views/templates/hook/index.php deleted file mode 100644 index 96ed9b88..00000000 --- a/themes/classic/modules/ps_emailalerts/views/templates/hook/index.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account-footer.tpl b/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account-footer.tpl deleted file mode 100644 index 12968341..00000000 --- a/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account-footer.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
  • - - {l s='My alerts' d='Shop.Theme.Catalog'} - -
  • diff --git a/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account.tpl b/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account.tpl deleted file mode 100644 index 50369607..00000000 --- a/themes/classic/modules/ps_emailalerts/views/templates/hook/my-account.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - - - - {l s='My alerts' d='Shop.Theme.Catalog'} - - diff --git a/themes/classic/modules/ps_emailalerts/views/templates/index.php b/themes/classic/modules/ps_emailalerts/views/templates/index.php deleted file mode 100644 index 96ed9b88..00000000 --- a/themes/classic/modules/ps_emailalerts/views/templates/index.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl b/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl deleted file mode 100644 index f304091c..00000000 --- a/themes/classic/modules/ps_emailsubscription/views/templates/hook/ps_emailsubscription.tpl +++ /dev/null @@ -1,74 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    -
    -

    {l s='Get our latest news and special sales' d='Shop.Theme.Global'}

    -
    -
    -
    -
    - - -
    - -
    - -
    -
    -
    - {if $conditions} -

    {$conditions}

    - {/if} - {if $msg} -

    - {$msg} -

    - {/if} - {if isset($id_module)} - {hook h='displayGDPRConsent' id_module=$id_module} - {/if} -
    -
    -
    -
    -
    -
    diff --git a/themes/classic/modules/ps_facetedsearch/ps_facetedsearch.tpl b/themes/classic/modules/ps_facetedsearch/ps_facetedsearch.tpl deleted file mode 100644 index f4295286..00000000 --- a/themes/classic/modules/ps_facetedsearch/ps_facetedsearch.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if isset($listing.rendered_facets)} -
    -
    - - -
    - {$listing.rendered_facets nofilter} -
    -{/if} diff --git a/themes/classic/modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl b/themes/classic/modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl deleted file mode 100644 index a3213fbc..00000000 --- a/themes/classic/modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_imageslider/views/templates/hook/slider.tpl b/themes/classic/modules/ps_imageslider/views/templates/hook/slider.tpl deleted file mode 100644 index fd98f815..00000000 --- a/themes/classic/modules/ps_imageslider/views/templates/hook/slider.tpl +++ /dev/null @@ -1,60 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -{if $homeslider.slides} - -{/if} diff --git a/themes/classic/modules/ps_languageselector/ps_languageselector.tpl b/themes/classic/modules/ps_languageselector/ps_languageselector.tpl deleted file mode 100644 index d016e39a..00000000 --- a/themes/classic/modules/ps_languageselector/ps_languageselector.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {l s='Language:' d='Shop.Theme.Global'} - -
    -
    diff --git a/themes/classic/modules/ps_legalcompliance/views/templates/hook/hookDisplayFooter.tpl b/themes/classic/modules/ps_legalcompliance/views/templates/hook/hookDisplayFooter.tpl deleted file mode 100644 index 6f4ca3a6..00000000 --- a/themes/classic/modules/ps_legalcompliance/views/templates/hook/hookDisplayFooter.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_linklist/views/templates/hook/linkblock.tpl b/themes/classic/modules/ps_linklist/views/templates/hook/linkblock.tpl deleted file mode 100644 index 8d538471..00000000 --- a/themes/classic/modules/ps_linklist/views/templates/hook/linkblock.tpl +++ /dev/null @@ -1,58 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_mainmenu/ps_mainmenu.tpl b/themes/classic/modules/ps_mainmenu/ps_mainmenu.tpl deleted file mode 100644 index 3aa86034..00000000 --- a/themes/classic/modules/ps_mainmenu/ps_mainmenu.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{assign var=_counter value=0} -{function name="menu" nodes=[] depth=0 parent=null} - {if $nodes|count} - - {/if} -{/function} - - diff --git a/themes/classic/modules/ps_newproducts/views/index.php b/themes/classic/modules/ps_newproducts/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_newproducts/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_newproducts/views/templates/hook/index.php b/themes/classic/modules/ps_newproducts/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_newproducts/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_newproducts/views/templates/hook/ps_newproducts.tpl b/themes/classic/modules/ps_newproducts/views/templates/hook/ps_newproducts.tpl deleted file mode 100644 index 0bb97794..00000000 --- a/themes/classic/modules/ps_newproducts/views/templates/hook/ps_newproducts.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - - diff --git a/themes/classic/modules/ps_newproducts/views/templates/index.php b/themes/classic/modules/ps_newproducts/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_newproducts/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_productinfo/views/index.php b/themes/classic/modules/ps_productinfo/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_productinfo/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_productinfo/views/templates/hook/index.php b/themes/classic/modules/ps_productinfo/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_productinfo/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_productinfo/views/templates/hook/ps_productinfo.tpl b/themes/classic/modules/ps_productinfo/views/templates/hook/ps_productinfo.tpl deleted file mode 100644 index 471f3bb5..00000000 --- a/themes/classic/modules/ps_productinfo/views/templates/hook/ps_productinfo.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {if isset($vars_nb_people)} -

    - {if $vars_nb_people['%nb_people%'] == 1} - {l s='1 person is currently watching this product.' d='Shop.Theme.Catalog'} - {else} - {l s='%nb_people% people are currently watching this product.' sprintf=$vars_nb_people d='Shop.Theme.Catalog'} - {/if} -

    - {/if} - - {if isset($vars_date_last_order)} -

    {l s='Last time this product was bought: %date_last_order%' sprintf=$vars_date_last_order d='Shop.Theme.Catalog'}

    - {/if} - - {if isset($vars_date_last_cart)} -

    {l s='Last time this product was added to a cart: %date_last_cart%' sprintf=$vars_date_last_cart d='Shop.Theme.Catalog'}

    - {/if} -
    diff --git a/themes/classic/modules/ps_productinfo/views/templates/index.php b/themes/classic/modules/ps_productinfo/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_productinfo/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_rssfeed/views/index.php b/themes/classic/modules/ps_rssfeed/views/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_rssfeed/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_rssfeed/views/templates/hook/index.php b/themes/classic/modules/ps_rssfeed/views/templates/hook/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_rssfeed/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_rssfeed/views/templates/hook/ps_rssfeed.tpl b/themes/classic/modules/ps_rssfeed/views/templates/hook/ps_rssfeed.tpl deleted file mode 100644 index 54dfe8e7..00000000 --- a/themes/classic/modules/ps_rssfeed/views/templates/hook/ps_rssfeed.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_rssfeed/views/templates/index.php b/themes/classic/modules/ps_rssfeed/views/templates/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_rssfeed/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_searchbar/ps_searchbar.tpl b/themes/classic/modules/ps_searchbar/ps_searchbar.tpl deleted file mode 100644 index fb1d5fdd..00000000 --- a/themes/classic/modules/ps_searchbar/ps_searchbar.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    -
    - - - -
    -
    - diff --git a/themes/classic/modules/ps_sharebuttons/views/templates/hook/ps_sharebuttons.tpl b/themes/classic/modules/ps_sharebuttons/views/templates/hook/ps_sharebuttons.tpl deleted file mode 100644 index 7d2127ab..00000000 --- a/themes/classic/modules/ps_sharebuttons/views/templates/hook/ps_sharebuttons.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -{block name='social_sharing'} - {if $social_share_links} - - {/if} -{/block} diff --git a/themes/classic/modules/ps_shoppingcart/modal.tpl b/themes/classic/modules/ps_shoppingcart/modal.tpl deleted file mode 100644 index 8145ec1a..00000000 --- a/themes/classic/modules/ps_shoppingcart/modal.tpl +++ /dev/null @@ -1,83 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_shoppingcart/ps_shoppingcart-product-line.tpl b/themes/classic/modules/ps_shoppingcart/ps_shoppingcart-product-line.tpl deleted file mode 100644 index 49db6716..00000000 --- a/themes/classic/modules/ps_shoppingcart/ps_shoppingcart-product-line.tpl +++ /dev/null @@ -1,59 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{$product.quantity} -{$product.name} -{$product.price} - - {l s='Remove' d='Shop.Theme.Actions'} - -{if $product.customizations|count} -
    -
      - {foreach from=$product.customizations item='customization'} -
    • - {$customization.quantity} - {l s='Remove' d='Shop.Theme.Actions'} -
        - {foreach from=$customization.fields item='field'} -
      • - {$field.label} - {if $field.type == 'text'} - {$field.text nofilter} - {elseif $field.type == 'image'} - - {/if} -
      • - {/foreach} -
      -
    • - {/foreach} -
    -
    -{/if} diff --git a/themes/classic/modules/ps_shoppingcart/ps_shoppingcart.tpl b/themes/classic/modules/ps_shoppingcart/ps_shoppingcart.tpl deleted file mode 100644 index 4274f954..00000000 --- a/themes/classic/modules/ps_shoppingcart/ps_shoppingcart.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_socialfollow/ps_socialfollow.tpl b/themes/classic/modules/ps_socialfollow/ps_socialfollow.tpl deleted file mode 100644 index 5379ffda..00000000 --- a/themes/classic/modules/ps_socialfollow/ps_socialfollow.tpl +++ /dev/null @@ -1,34 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -{block name='block_social'} -
    - -
    -{/block} diff --git a/themes/classic/modules/ps_specials/views/index.php b/themes/classic/modules/ps_specials/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_specials/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_specials/views/templates/hook/index.php b/themes/classic/modules/ps_specials/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_specials/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_specials/views/templates/hook/ps_specials.tpl b/themes/classic/modules/ps_specials/views/templates/hook/ps_specials.tpl deleted file mode 100644 index 0671ada3..00000000 --- a/themes/classic/modules/ps_specials/views/templates/hook/ps_specials.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - diff --git a/themes/classic/modules/ps_specials/views/templates/index.php b/themes/classic/modules/ps_specials/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_specials/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_supplierlist/views/index.php b/themes/classic/modules/ps_supplierlist/views/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_supplierlist/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_supplierlist/views/templates/_partials/index.php b/themes/classic/modules/ps_supplierlist/views/templates/_partials/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/_partials/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_form.tpl b/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_form.tpl deleted file mode 100644 index a1e3da5a..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_form.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    - -
    diff --git a/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_text.tpl b/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_text.tpl deleted file mode 100644 index 9df7c8be..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/_partials/supplier_text.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
      - {foreach from=$suppliers item=supplier name=supplier_list} - {if $smarty.foreach.supplier_list.iteration <= $text_list_nb} -
    • - - {$supplier['name']} - -
    • - {/if} - {/foreach} -
    diff --git a/themes/classic/modules/ps_supplierlist/views/templates/hook/index.php b/themes/classic/modules/ps_supplierlist/views/templates/hook/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_supplierlist/views/templates/hook/ps_supplierlist.tpl b/themes/classic/modules/ps_supplierlist/views/templates/hook/ps_supplierlist.tpl deleted file mode 100644 index 26aabffc..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/hook/ps_supplierlist.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    -
    -

    - {if $display_link_supplier}{/if} - {l s='Suppliers' d='Shop.Theme.Catalog'} - {if $display_link_supplier}{/if} -

    -
    - {if $suppliers} - {include file="module:ps_supplierlist/views/templates/_partials/$supplier_display_type.tpl" suppliers=$suppliers} - {else} -

    {l s='No supplier' d='Shop.Theme.Catalog'}

    - {/if} -
    -
    -
    diff --git a/themes/classic/modules/ps_supplierlist/views/templates/index.php b/themes/classic/modules/ps_supplierlist/views/templates/index.php deleted file mode 100644 index 99e1f250..00000000 --- a/themes/classic/modules/ps_supplierlist/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/themes/classic/modules/ps_viewedproduct/views/index.php b/themes/classic/modules/ps_viewedproduct/views/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_viewedproduct/views/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_viewedproduct/views/templates/hook/index.php b/themes/classic/modules/ps_viewedproduct/views/templates/hook/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_viewedproduct/views/templates/hook/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/modules/ps_viewedproduct/views/templates/hook/ps_viewedproduct.tpl b/themes/classic/modules/ps_viewedproduct/views/templates/hook/ps_viewedproduct.tpl deleted file mode 100644 index a8be2f3d..00000000 --- a/themes/classic/modules/ps_viewedproduct/views/templates/hook/ps_viewedproduct.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/modules/ps_viewedproduct/views/templates/index.php b/themes/classic/modules/ps_viewedproduct/views/templates/index.php deleted file mode 100644 index e261c47d..00000000 --- a/themes/classic/modules/ps_viewedproduct/views/templates/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/themes/classic/preview.png b/themes/classic/preview.png deleted file mode 100644 index b439058c85eb1f9f38526d9123623dea8e2a544a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141698 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%0A$fS+<$oa+y!grEbN=r+t<}O zJ~2j>(#H73wsz18C2M6(hwBpwkmuu?z>J|?ANrlS=Qu#`;fJlwi$o*5XWO$)rGvv9N| zgn}3tRIas?0E$?e{4-9zuVJ&zUegp)qc7Jvb5dR@WfSDKY}tZDt_@F;B)z@8>(;G{ zqR9I9RW(L!=gyt8XU}HlXPoIdisRIXJwG$$w66j@f=dD+M6h{X5mR0M>P#9#CNQrcdp`|@NUKqmK zD>N7%6eJvp2^50X3;Jg3B=HOztpNzY)Zs8`OVJcoUl2e*Mj-}9G=UF^&V)YY!)WV) z@=J&MZoR%NJn~PEb-w8uf5EJ=fuZ&rH%{#7H-lql(d@+c43Y<6Tm=R}x9n1b`^5}& zZVLBiw2UKWZnV6efWGp|D^n#tJto`n#EBC&NjgcA6)RR|G8txGy?S-6FiH#EH4^L7 zR^t#5VPQ`Y3<>xu^Z4PHG9=f}o?jMdQLUfex&Kp#c3sy!<2~2i*d6#kc*QF|{M?gI zY}@_DYj0fC*=ov0B4S9OQbHC$U!c;U%yL6=mR1M#RA-BzCpa)MGG2<=r>g1-NU9{` zz5pt923a8`QH+KSLTp$I6H9>&Fq7s=5+hMtX9s9;_#)wCa7b(WICJw9o&20|7eEx3 zWNRd|Y=MM+WOVz6<)e>o3D+!5=JnvfSoXmU*;j0s0F&9Ul$GaqcPHfv#%A_a>*Kti zuptDEz<_o0VX}hT;n1X}aKAuRsJ8gH>oEp^#%LmP#hz^9<=uDRmC0m9>qJJzh$ zNrjY@CEhTvZ|&lTzOwD5e|YX&zk2)KVJ1jC2-(*PRRSz%YRnNAAk>@^JtfI*B9bWZ zHFvbN`kh`B#ikM&W1OTj%wl<@vPpnIu?PYR3L^U|Ydp(P4qKELC9#Mo0SzE11T;w; z+;noOOjCH0V-a_JWdw}1zj%(;i78i-_I$?!w=hA%CO4xKAHK7aB%x5^c^qlg*Ucn4 zPE>cR2BQ+A3;;u7huUbFmm@a~YPWoVrdg&*jRkk(E*ZjNKwPbELta>}M9h%O1y-C9 z`HYan+|x4?B+=UBTU*M7I5r$)Jx*dHpcCH~2OjF8AH&6Yg4y%4na@4{ zT-Tu^i)LiAfv1z`nf}9V|PhCTrX2p}%l2DN65AOLQXxksCfnU0yAOn+IOtm#l~Qfg7H zn=Vr8R%OrkcWi&@J@0$p!*71u<4-=Ng3Q=>@z4MKuQpwCs~yKDBHzzG`q)#ie&E6P zz4wFLU)mLBTR#7VFTedA@A<&{zxOL&`=&quKmamDRY5L%Nh6>kHp)N}t?ZlirW~-^WpM^vKbl`GsHj&ENXX!g%rM z;iJFu8^8AGKVveW}Cv&0qXNHGf+PdxNfkT!K?B9R<W}JIdxL=TC9czrOisD57 z+OPk{U3cF5mbbp`d+xobSc;!}{)J!r<-h&s5B=>g{L*i4-M(YIRD9t6dw<}EfAG2+ zulw!a`MpG&ef#z;SUCTUZ+Yn9H#~Us*fBrwnWa(iWi3CwPB!2|Toj7wAY9u!tb9%zL_ae#m+j4DL{aswhf+;a7gW66@2ahhBL8MO&2i?QefqCX@TG4}Y{0^FROV zzmJTK9XNEj|LBRqGsFM+k&n)rH}9!uo;f`*bnw8DpZu9$Jb3Uhk|#iu$Dy`Sky2_( zgj)Sgx?)~4dV7`cX{}uePq%a1_v1J&6^r&&Z49n$B_exaKcTg@HcTP{0i5(?sNLx; zQ)`=QimxUR4aIuB%3PzuBe;^kgi$3veP-kpx80g=X>}zMhlYoL_7~oL`zvq#>7V^R zTOg|(6``~9&bw~6I?BI)_`^|L3POMN>SeFE{gxSv){IXKlbS!7%DU4{xC00>2_ptH zJaB5?{)44Las7sk<56kw_>Qa>R!r31*4lsU#O*iV^y2f+KJxtYU14^3bmX0Heb=5B z_k8lppQ1|g!0TVPe$ARvTs22?5U8(K=m{s8WfdC5sntSifQL)G^IE-_p|B+7^TX09Riy z84%L4D$cQ=$z(+2I~m;Fs1ksy>^5`e%(N%CYx!-13v5`w=XpU8+;`u7ma+G|YW1o# z%Ogn=EBcukCMVqM%P^z{_hyhgBGP$)Xwv!exslT5*tuN3SQxb#_Ph7&>*{QcDn$^9 zqq3NUFeC^%a_vb{N#cr<46qWWN~M%UQP#^U^ss@>esO)LB64x709IKB(uNob5oxqs z93CHT4f97&93Pw*-L`jk*pl^(0^grGYv$6PxsN>d)V&Yfd*JxN4}bFG4?Xy%yI=j< zkACX2<*|~llz;)4lta}CK3BxtNqIX?sc*)$Z!t_Ji>736oW+AeAa1fqM|T=Y&P?ufBLs4pL(i$Mo%UaeC!jSK6Ub>A9!KlkBkk+T8E(z zYy<@mh>(a8m0>e5aC+^Uwe#oCW1~|w);(sUYAWtWu7bI%!7x?HnYB?vsj{e4@aSVt zzVqGh{=yf(EWk>6&pp5O5C8a&pMLsz7AB>(@7VjtfBGk1{n|Hy(Dp?Ai@*HqpZ?jO z`N~(nA>smWL?GSi={y!Es*+O5P6hx-o60sFs?CzWldsKEzyBK$arQx-#QC;N=gh93 z{h6OE7AvGecXCDp$N;EF9oTco4|AKYxgG$JkO)r?43;Z;aB#$l ztW$?}6-x1Vu`)JxhCC7!Kgd_g`oNB70ckRc^-`s20uDM7aZNGF(|s931eJw{+=}Ts|ivu6y{3 zrAyr1rX_T!T7o>A&HchJ{L+q>Y~ajJ-w)CW;AFSMp>_fURdTg3OQn+QYBHU00L#Zo z+&63Hz4zSnuD3lrHa33x^y%C0d+i54_`&ag?}LZ?`v(RGH*Q$)o_D|Jr+((A`;Qy} zpj)oL>Z(nfHmqBnB(eJ{1aOm~9tVe>-6oxIw-~w|ZjuqP%?wp&QmtgEujcN|?uOYO z#^3$^x8MK32fR?d_x&GiZ_BM&z2XD!eaFdDgJ1m26W{m2_jR;%{J;k<9T#7^LV7IqwjAmwGL83yTptUAK&-b)8h9z~#i%Y)} zX=`gge*EYQFKoN{mYdyIi9nj<>>l4??$mQ9&Rkbj*I+N*;igDwO;2)|Zv4#Rwx7X) z(|6u^SFSa)dCQi-BOS+?Fk=K5Fq;W=5}^orz7a9@q8e1=j$-KC$~EOC2yJP$2U;X)C zS-5Z}Nae?W?E9~I>Zx3|<+@E*vWf4y>yFto`&#n3t8civvmVC5 z0f7X)c7QY6HXrzx|H#c-wCtfbg!B3a_v{*a@@c=LZN@FPP$n4OwzF+sZ+FkkWNd73 z=ZZi^v|H*hEv%! zq5&zbU81rxzYrlIg6An_c9Y36$~g}_WsI>pd*7_t)rXS$>?9|_v)QcMQJg8pM&Kx= zY7G%nqO_*z{)lI{z_qzbFYVm<4}bG7KlO7zn#pF%6Jx>#0lA6^Ys1D;f~1&%2t=4! z5G@C_Z4)e*&a+}E3`57e@Ef~*TH$Wrxgg2j6zECnB zPyXnkPk*_vch9=_yk%_bi;KVKzTEOv#`8>UJgzQ#g{hY;Wkkd&>`t?D5^Z|mke1tJ z0Yzx<&G*9`vr!5~m=Qt1_Y?>zLIz?$0tGCn6r$%T%j29m^Qw{^1>B(!ogA;lA#ML} zaj@Guvm~e$8mEHB8F;Kk=yrKlbpVH@{97qHRC_8>bHJXkFYJ@8A34Pya@? zFPmSz%1{`DUBjn_gOyBZVqyYBc6%G7j#HTVgkhL^P^Sr1Z<1Y*yCO9@I>ItG ze@>6@d2yU5F92ig-7C){LTv<DYVZ2mqhH>>>!r zP2oP}+0|)iGgRd}lXy(+kc}bX00WQWO2il*7?^nB z+{AC&I7bMDQHl7#>?w*tfEW$J^lgXTxLg$bf{~Vvo*Dk^-tC|G+>DKDGhIF1E7l+R z{AcIhc2{hpzV{!UpYIwS-8J)Vug@-9Os578e*Fm(CBRYd!i7o1zMx_h0YRwkk!Bee zBJJ!mmZl(CX%c}V&eUAhBEy-zJ)imP=U?}l`#t49{nVfR_HX{yyWjQBRjXFN_m_X= z6)Tp$_g(KQ7YcD)0pX}p_7o%_y}dI`Qkm6j+jY#f(!0i8Ely&lI4Gsk?ahURPpkQ0 zN2o&KLdYI|=%J5(_#;aeFWqqEM(c?BlRx>B_y6F}J@~-wtJhqeYYBhnmw)8ffBm=a zx%<{Nt5=>nb^4B5Z?sm**F5klUwIZE*E2rF!HupSpX;*JRM?xs{lYDYY0;8%mNpdx zjffywLj{7ZBgd9@^|l=wDjhhIzh+HEaeI4aeRkH#ky6p%eajYx6m$?2OG$f6ds0b! zJRz8^n4ZCja#s$0RODoPz00n?HWT8svCJR{kf0G$_Hgk-uRs2=FCO~Gf1LN$x3yol zuI0#{7k>Fy*(7~$d!T#4^5fsw90#gvUSD}M%FdqYcjkjlYfq01cg*R@h!F;ZKvf7_ z-l&5q@C~nj{R0oYIurWL@aKQ}NBu_*Ai_;I-SnTo|2sDL zy}h&Jx@)d6Ch6(vdD~ka?&#H8@>Fj9x{tvvrB1TgJarEG;UU&Ch_lwVYHf5h*{h9~vzvB)+%z{ql&FcQC zpZH;*z!;sx6$B^Q(?W9Sv~|m*5mOgoGBkyI(` z>;kWqOWVBq6a1l?P0beiYH3#VMySyup}`E14ybtxdM9BU8}Wn_KK zGkb&h-Afj<5uuTDnt-OW&E2hMu3mUTmV5S@=LSbhT7@T09gB-a4H)Iyl3ZtEP+~5E zh?mixI#nDQ9~*}-8Qiw@ncw)`;o}EQRtXzG~D-da-{#% zsez&45gQ12`s68_RbMC-v`+ROJ^J+CU8rb$e8lGX44oMoJ~K2>C0i1)SS%?;wGEz9 zZ9TZ%koxxyGw6CK5srFh=Yc*jKqcCx994 zS(L787We8(Yz?yQ*^otppkPLXJP;qjfPlypJkG_iNKp0p6F?-2$`i3Jwo>MaN1s@; zZq3H^8=rdes{;c=uX*ijE9HrQ{m_5D>Vf+gFIw=#wjC7doA13%gu}L+tyVA|Gb0!x z<=TZKI)UCOn`~Oe`@4We$2+;&Q}HsJq%bJyN65OZgyws1Ob%(N*2Eu#zwU61XpSAUA4mJV_%}v&~+U z8YeN;FQl|tMa>VKPst?7E7vSm3XphqE+^nqTNq=|o6mDxLh=oYlLsvF9h1(8coA!m z8DpG>(_P!)=9_QPS|?h+>Va1gQK?*9yKaLET=RVYO%J`XHJ`7P$~Fa{_v9qH+{gqmm=~*U@3&7z#1-8C@IHaiwhQ+BrsP*DmeTqFUSvG4<23r!47QdS%nBUs6P&34dK|~`YzzT?{-Y!~uTDtJb&=l^?Q1{7) zz`J*xE}ug*B5Vl3cQIX|XcBE%6sMMefLu_|zp0M|6%nmimAjaBFLe ztK+H^c6D`VOTyVOKm#g~5a6-AZ z<}g>O)>A_SY~pKIthi>y8W3SH%4h^)VMn#rhT695PF=0XVG;#18hGQsJvfMnn-5_S zA|QhR2nl*D8Vs~#0-ZtT97*8E9XUTUqkHL$P8}CpbC~fH5cHrs2H&RyNH`HsAOTn+^&%z;v;sSAK3il?ZtF%!K(#Bd67>rSrC&U6mTB-&ZLyTY5rT(AMgu?s0zd+C&bshtZ5uTY-Vle{{j7mX zdvPRt{Zw>JdbeR1A`pOxD?$XkZUP2n`x%Y8C>js%dH3y&F?z z@*Vgt%HvNS2bUjjnT9wBib#S0EDWFo807qWkF(N{r5X?{)py`?-|%h4;r#Jq?$S;M z>;5Gq=Za$2ok}oZ&?p8lG)9>u64Zpi8bEmlSWv)@9*ThL8xAhvp~_XWw;TdzjsL^m zS*S;j13`G1nHfGjqIcLw+85i`IA(^AmYF8Y@O$b~H%VROd^tP5^{SF+WcVDbMryTM zt(JM{pgvULUZuRH7@G{xnA81h_I^f`l4P95eOvJ(`BgwbF05Ok74hUyLRZhp-Qp$% znL)4S2q)XNZCf;lp6O<)-6l2 zPYccWOjnLyS+kkq`e!h)@x{iMlIpxQC)YmXh_MXrRXmjpm-yu}@sOcHWj7DTT47-Y zXyKs>_lmNG@x+M}DQ$ff6q_6;TihP(d*CKCRK(+gWGADgCEDIB?wpZ~aZS_CdYW#O zyjJuWg-nql+p^DW=wyzrx+N-yBS`|OFqt%)=grOoI|H(Z$aL9NV{s7xjXhRDs;mx8p55jA3Jsoajbb}mobew6x)~FkxzMO!bUP^xpnLI z-Me=g5{U|1Hahq0c1jkqZcIXEn%8L*w8<~O{QT8dUuv5)U09?Z0_UAER)GY=RM=bq4=hB2hbvdE zC;|+wpOC;Ox9CnVTYN#6bPjpQ;-+uD`TEyif98RTS`Kookc7mPZ@)Yw8$i2aQ4_xW z@=K(=CfhfP2OE@tzkSyYqdB6{vBeE!etP-xC2z-JiR|*4heU~os<~H`^@3ERe6^f$ zJ}wm=GO%z@o2EQulp#h64H*6X;>C;Gx9`}tZ7bV^(x8F1Z;<;0PnoLe{5>Zngvyi0 z{5+Y=&Cxxe`63)nojOgd6*cCZLo*6akU4DXY6O!{o_#&QPX9=>-+%udPB781e+vN;yGlnDBv+@c$h!~RtUt|>CE5+v$5Gm$g*gk9nZH z48MN(;Ri-w@W8@7XlSH9_9ab(&YN81kiah=giC`2n4l^sMEmaDyN@0{x@F5YXaG62 zo&%bScHv&JXlhGR%)T*88QJ4}$+(f@%B2KTOdj@#v~^_L_G(P)Q~USt-?wkylWF68 zO8RI5QH}A`%WxXJlIkgI1s_~P*<*Fj;loFeXvhNn3u|gd3in70&XFDSP;gXb?b5-6 z2gL(_a}OWD10~g+6k0+}`!qH9r;{MoHR7>&+wST_N#Sk`JrFjdEmf71shNx3XsK59!ly|q6+s4 zDyTHF3l}aReI(pFoW3hR!JDi7`s=SKL8!O8cI{e)TASTZIuRS{_SC9@JYayW2zdRG z%+D3hZ%jnC0WEex@0cxF=d&5Nwq)Pjtz2{7{8+BZ5V3t*1Mwgdlr|Ys$}dlnh6jE8 zO^BoThBwHvcqow2Nu4Q(_1Q^pptuy&SjHcXo=&mFgc2ReQAS&FfEgON2!e;8Vx>I1 z?TeTy+?biqxpnK-`Sa(8wGn;r!3VsCS3>q0Tc#YfBbC;LkyXevp3VeHnT^umiDaw4 z{OCjquRKFOr&!~B@BJKb-jYtRwaSB)>DEh4;n$l7Z7np*gC1)hT<~z^P9BU^;2|qR z_WH`02caoovwh8!i3L2&?~-aBUg_W!bzGPo9kwiF%X~#axL2U3U%h&jseeY7pM3Jk zB9$#CMVG(0F*D_pm|}0-xWUWN)68BSP=9x(#DnFTmm9j*oc_4-rNs*r*%O3}SV zLP+V>%7gp6G7l-yz))*4WB3x4VTC*d2}K@g3o9>a)!ZvEfM5w>imY5m%VGHvD~@TU zm8*DCqrA)XKcM>%`4o9dJMDOUa(HBUQ|@%)qSIfLTAt8%WeAG?XFSx9zZEjIGwF}> zL$@Agxp;Lseh60HnWNf*&z=rxHNcR`Z}RH zew4psWGL=^anJB#MYEUXdkT%G+t!{Is_e7|X=zD98U6792Is-~0eFa+o7E>Fd8jt` z5yETR-rV8aGQ~veUaUqR`&T$KAWJgNmdhBGp?e;NuPwP6BVaGg{&*lAoCj5js=1Fd zmH=xjaD9<$c2}DMcXe}z_8)4n;?QRJ1aJDIZS}>&SYaM=7Fxki#KX8%Ir|Ga@=rDj zVg$)+VB9>Yyr2sAQNcQzT*bRGKzDd^hob~9RhMwjfs2E~jJq+52e4Epr-&$O^P}e> zi|Hz1&-8Kk^jiOHQ7|4<;ZBMf9S28M^fy{__sx0IDJ_;bi)8X1;yB_6q$i9U;(@4M z*~zi=_w3oT!@pwx)z8xH&Ye3c*$LA7&O7h?*LQHf3-tFuNEoN`UWGe|5&HNGUU^t* zz8AdZdjfmaRduEqCDy%W?`~Eg24N@)zyDhoa8vl`AxL-X${BC-bCZq(P3%z-^_`0E zxp<#a#y0_oURG?t0OW{NZ?mDjx4~L9PlIrZd4S8{ z4#zO!kvvVKj)d?aEyOyw>NYVQ@DFZMn>;V&7U20Oo;9czx~rpIsC?-Wc+Hjs-L#Z@ zEpcrWfFm3{1j5Ev$61`MXgKssBz9IB$n#oKvU9=nlxVP%E^`c4Wx%ikKtAl1kN0J& zw~5J{gpUkT)^k@{n!l36);`4kT)C{4-nRm&kBW+oZ8A}NJGGY;lVGi9vqq;aY>Ik| zZTWki{+JkF8~?-JUEoF%15p6ILUMsHlX&U=VP<9)PfoB;`jW#uz1Wu2^0>?8s_$Rr zo=L}UauC&}{#oYLa(#V0H8tgs0q@2sc;ioz&Xn<%n2&dlL)+Tgvh}WZg_!-k98wXU zIj~}9XUAP)jtA42*9}!}Zf^GW_9C;gvT}NQnltL?)R?Q$H#Rn$RN$pFx0G^Fa*>Q} z8XXE@JL2Yk(~K$xIBCHs_8GRQxNppbBuf6U|EIIuosqZwkrW zEfe7!zJf+rTHSkJu@CbAM4`PY!xLh~WmjI{IRHx#i9T_W+zrWa zTix|;5OEod2_l$_yE{P?%_?=Nll!B$XzVv&$991vn6U@Luvub~>C{nH=EATXsD_&=r*z7Z*`q2vM#h z9?N%>&}juyVGkP^Q^mJYp~x_SB#A5HQ=JzEWfB2LFL}QLVnK-vtFm+v1{zP9Iy*aS zsngC=m9qC4Jf$;#&IJ^|;6FDvrviB$y}@Fqww9I_fCEQg9l1O-G-T_A&CN}gfW|2tOlC-1qBd*nb%KgFlz}Sk_jSi3Jn`5fgL^y?@AB>DnaDh-QAss2Dj*8 z63u!&1ffpuH3T^h6lokck;eyTbg1AKHj82LnbV4qPcVCwz@!|DtRs@;WMnOK?!b+(3UDMEInH7k_gUz*OLsZwD*pMKT;S}H zJdvqL=(=d9+$fY7QM4zmfJKhTKqiGkcNLg$zq*}}%?OW7Wm{Vtz%wZX6iK=#qbpYSm#%|Tm7sSr6entekP z3mWRtru#2=4D#&49UCqgI>ca@StvhDp(}eBoRxt4{3SzJm`Kwlh_e43N5~V_(OkP~ z)Dobu!jgb6>assVmbZFjb~fmeAaXSXowtuNb*X=IFJ}UXF{w(j5Sh}J2Z3Zagu`ak zk&Jvqpu{RMxpi!8O!$d3ABo9Ro-u`iApG&;hi6*^6%y1&8zr7bk)9Gmi)49FN4JcQ z$NDB~cz%)ZsAXIEdLh4vXKLk5jfP7$B-X5#f~k^pxR#;CkILZSpvWx$%*l(K&Chpx zXOgkl#5OE)+8LM)F2rQVRo*)_>9p$5tfs9+C38_#>%a<=-(11=% zpzU!GWgl!2ksx{^3hG~+O;zLHExbb!xuYC<_O2qcgXo36k8ZtH#sjHHNPBZjbcz$X zz{94D0|$=4!JzNOK?F+f^3-SS`IwlN&*K0Azh4lt1#B$^LvwpRH?$n{O5H?=U{ z&|&fiil=Gw=s7p>4g_n)XQnU2cr`kdd^PzKg2eN)wdRLLiGfd`8>{2gDsr?7d|){EKVh z3Xz=3tFv*twTe3+;M=Sw6pq6YDF%lYJ+ruT`q|?Co;tbO4&vUGlGvnV>x(-bD;%DE z%m@zFxxXI=b~t>NxX-^|c=P}Wj~e366}iM65b*Ec4EB3}D@us_m%TgSh%AcY0M34t zzCi*MfFJ;Z0E$QiKqRPugiwMc5+GHfF=J+iVKC;4?0487hbQ~A*|qQBzIXB5x%chc z?s@n8@44sv&%5H@Edlo*EeV_|37JsA{3F)+d>)hr*cz1}R$603z>vdCviMh-qmGsY zX`}QhM&}x=Z2_@hrgIG~77Ja_7Uoj*{I{Po8B{E;0Mx+AAz1L_5ck+j1WA;)M6XJz zau8C+*A!I_E~)6N3cUz{V0mhECs|P+jp_+<=%|ndl)Om{(@#!L7)R!Auh$!mMi6{= zcUQZ6qe7v~0(Bjo!Utb4<-Y)9l;bA(Ry58R2CUDi0 zSNc#2DsXdiLl*$I`A-76uCA`ML~aCqApzQPd3i}<35O+hXQ+1Nujlc2JeE^)baaFh zhBtTGaJaU%mU(WZYmT`J%TV9&L_yf*<|aq~+uIw4Ul5#E zR#pHy`9S~R1%|#Av)+dsyyer=)BXMZrKP2?UU@}6K0dJeY*vhVb#)cq`DvbDbGjC( z6!s;AAgK-Wbz@_L-NTBvh4r1`;58x*<8-1nvgj#DIr!UI?q#TSJa&0`8KqYYlQBYF zP3Sl(fh8Nch@yJDjSfm^uA0MN8bK0PLTmDI-NL@4J!^1#g=hZ=Nn0gp207RoQfqaLb!a*@QY-W*=z>W$;w8DIp4G# zLjIovs#+4Fh^+PaVnlqDB8cIBni3rD3|PZgXU0PO2s1WXSQunp1yn;I333Pro&V7a z7m=9Y>X-xOC!af@_mecV=xsWn>Rp(P9b2YAa8D)%e0zTaxL0hMM#24`DGIphphz24ivW51NcXQil<-)j$SN(kk60z0=%e5SQk1p$NQj%QYL%e1R7 z)x&Z(6Ka-wiwbj<n{ml*M5KHVV*!MxX^vX3VO zE;fqQlGz|*=TAJKm-CEjFCY(w~kYTj*5X_`BFY*N$pgop!l(go>Gy5@NPJZ>hu zB{~pQpJ3>s=Okqlf$US>O8mr)YTlWh9OoxG@rHx@%ZAH#R*Ha-v*Ek@Ii-yg6G}ch zuzV5+xD7gtrRb28Ty%&COZ?&Wj@UcqM~Bq8ya+7bK+Ns)%>4@Zyn`h&_F(LthpJ3& zbeNolIvgF|@AxUg(cydwc|o&(@+8As4T_{P$|caugN65`)0b6hA0yjw|c$#jvWeiOJ@BoNaEqIrmWV`mEYnh^I}*{KCz?A2ID6RVkTpG*J@-1DZU({~Aj$sNI|I&y;wXv( zs4Ap_5D_Q^g$U`}2BLsOQK_n=R6+ps38Dt}|daIHK> zX~;SbS(s>Z)jk>WAi1YZqEDa<=J(Ma2C>E>Dv?Mqut%d&*(7Ng-)^_V;czq> zF`oDP{oQVdCoq}uc+8B?bG2F}lS%X%9Y@nCxL&V=!2o+H`UJ+g*rj$l9eP0UbG$kn z4#c+EGsc(@$9BvP(Qa%snAu6PZ(+WcVHVbyl}aU($uNea_>D$`pjNA;)9K}MNm;Aa zqVnYpCilzbLK&y%7UgoeP$=YbIovq{7ujmHN++PBgf+Zd+>J5bwllNi;M#09+wC@! zJL=57MP7g?Z!8wuY&J-9KA(?7BFJ&6RAOmEWxZbK<9t4+GMmjZn=|G!#TSdk>2!*G z(-QXkJ#8Z%kMpDx=;s!T1?rzlrHDCen>}NU3B^-_JqZ&!TXKX57~#=ww&X0#fR=W@2TCl_vlxIDH~W5(FPX$T@ecLXwR{*SmDV~nvuwlT&S|0|?1#u$tH$GeB#eS$yoieNj#tgZK)A^ZnEyFebyMSW&L+*JV8-Kd3lD4 zMMJU$iW;(BrZgO=c&9|gq6w9CM~$CZy9sOl7AOZ6Sa7NLL;xF`T;r&ZBD$(s33ls9oWbzCSq>0vzxJSk?eNEj*} zx*}zw%&E30Gn7+&MS(HOemlbQoS{Im9nWHUXeflvD^ljUPGu8yi1G@@DCY>pnPOuG zs1D`LTGz~hV)Ow;bcafTqB5%chK(iga=kfVL z^<95z|7NeO5*&wtD0u(F4VX!6qA>h#Me=ZtuwiiZYgRu_aa#2KKzY-mmfFxgv`bd& z*R1Y_iSG?7QOWW$iZehcW8Lj`1F9Nz zIUQ-ZQkvJaw%tJgv16jF?1qt5R8-A-oT3HjscQix0(C5fd3j2ewby!3QtA8sCX~s_ z1|eFy(GE)5E;yVNwRRnr>qdTR38nc(D4SQ}JEfrfzDV*)yEafn1js9&Z`Z4FU7S~( zXk4jW2URP_R546gYm^~&sSGMXtNNhuBv7b8p$K*Qpok(+L5mm}OKKOTB?CzY$OAbn zgb5DULQzaSw62Xdt#qS?DaxKx)kfW*d|Z!5nwQjlUe`wtOf!{5mnvtq+CSFcNoq^y zu+IBofC^e!Ua=bH#Z&VS>hM7k@)fFw%7Ye>?fsbm#qUsb-Fq(LQZDQ6b~)L$i?WJo zq`RPkR+1L%DNmLCFy1$+fnt>rCgBkB*;8@4Y4Ks67fkV&bsd*+F$f?yMhFKtFpF^{ z5c0`~nm4M2IxXu86%_&sBMb%9;c#T9LIo|TFk*yE;Dk?I zmpiwA?3{&PqFMX@?_YPv)7{m%_yNK699>o+EF-0%(>W@y`dfRRkQ{`78 zeNisEUm}$Z&f}Wa+%@(*vpTb+{$rQJ9z~JEQc8Y#JMMm1ZhjRnxS;XK?OwO;L@-qT zrJ&?@i>0#R1yJIy(HB_^as~T;y&38snIDl#{oTEU_n&8$)ipmzqwns!wjHk2#-97d z(w8*(og!(IY7*4I)Phe+CApIG`L`o{!g9h>OJDI#y8Jk;h#~MHRqr^QTXtt^W4BL< zGze6&l-;QY)i2Wo#l#bjkYV}gmJYK)+ z=-9Neb0@iiR^R-pU-BCPDUfw9BLIaB3F$L{mT@Q+-$qn7ms@-|uOQKWj z#MfVB{q}A=>=h76{_k&w=F?cg*-U|I7?ff}i@7~7mj{$e!>Zd?En6q2r(uOnxs^QM zi2R@5iVaOJc^plKpJWu*y~t)yzJDz`G^I2! zj`Dxs3Qa4li7#rX6sSNA%&huS<$-1L$5h!aWbk! z7%;PJ#$X5n2z+pM6%WgK?J)&)aXD3=x*YyIj`A|G=o{}whNP6Hl{RHmH+v})Cia*r z#U%Ycq-gy1grdgO!kYj0R@k#RN?1zi_pU`hjxD4xgdqiuP}iDe8%ppil|3()Jt&bX zhBcu0?ZZLYjP#<~|9>eA3WOSeb}QB|GC!}98%|-JoSv7QJ zZ+I@;15WZzU^;~%@Xuht4L0`n!x`;@-WeP?kl+8A-2VobXS3}&_MHbuMvD!};%-Qe zxP2&u(J?r)dVJzOai3bZc1i5MYROP`Nu5tb{|4-!B#qmxu}g=s=A-t*?8R0d0u z%k5(*#vRTBP_9Ezv&oI!JV_U138bBv)ko{vb2tY^)$hN^qSXq^TZYJj!L7Z0XyfSk zST&}Ns_EiMd$70Fa;0YLCYB5e>xMr2N7UDXGE1ttRPi81G_<|94{aPCpQy%kku{w{ zW&eB6(wQ8obz|#77K{zsP0lR%M-}9kH`d5TQkr@!Tf3McY&|l+7Ru=0EBkNZoeciE z(E{qwE6cv`oS0tliy~(h)i9((DXd;lC#P74+SMzSa z%;YNvF~d>Knm5Ei?ZOZ+M_yS&Ky)D}$b!#clHL&8VzOIdN|CZZqNcNBTnAHv+S+pz z2nVU+ff73BT2K~TXxF~~ku11M4M%e6Q7W7V%kP|AL?jsu23%bJUjM%if5*vv2TLnz zlw>kndM4&^*xcUPBi@WGZ)iO@JEwFlzYxtW*bY_=7J|5^>>R{~zihNsi#ii%{OD3n zUY!K{KMtEnRm5wd)cTf#Qx6p+o?F;BST%yWgJkES3|2;SSA01yqL`Ic)1n+y<9>ix zdGkqTWDeu#?3_8Ie=3|EUAJ%U*om(^MiK`F_pO)qCRGTcO1W7z&5D7kBljtS?y;>~p9CaK(+G#kc{LN?C2PbEODf1&Q zg9qoC;@N++aXW%`6baEmRWB`=`+oO{zk>b9COS z8X$=K%c}+q7@J!vY?Q^6apTH)RIc)Znw$o8b40B%Ioy%0nly!O@AzESIZS*kU{!Cz zfYG_75{@FWgdJ7FE@3P1BOW5-6aUj+(LJ(ze4eV%0R%ogHIG+e8W@0=Q#ncqiluTP zbZl2{M z!I47=I z;?^Nl3Kezrk7K~1-U2hlm3cxeySAl$X!_V2EWh_lODwE|ap4$&!r2Lf1IIPu;{j~3 zH&}4YYVAq%h8WDf0IOo)x>neiAC2`LR!`M(c@zjB4@iRC?FQ^qR?Lux`#RuI1OY z{vont$zVAJSEvW7>e@SMhLe=Vj=-Z#Exv_jUxioSy1_Vdu93#x?H z@Sme=C7Nxk(@kny{MMtqkuf!%SMu9mk11;#oW$0mw`?rwO)PoecY_L5L(}*zUnKwc zAyswbmJQcw*?{5SKQ5HFb>lg&ZSa?2#W+YV8_bZkxMpgS_WmTK2)^#ggWMM4MS0_d z6;x@T{=YvhR;qgO9MuNQN8B;IV(`eqe_J|7eic^CZ5#Atw9bM5{e)7~yAFyqWg}kF z8dzdH?--f+aY#{vq#N-JSt|y!xMK(uThWi-wyApm<0EoOpMJyTZkVwChfq34AjR{} zk=btt6*ftG5YLdcYP6~br{0P!FXMVbbZm0wdyjHc6grF3EnC?6AF=h6vRXW!T3G!> zXfcha)GX^E3;I{~PrMmhhCJm-bK~mI`eb;heYa#`=hF$S@~S30pIlh|aWDm%)UFy} zFHrpx^RRnrr4ZXc`Vg-L<^&0*^?N6MtB!AFh!ZoZ*gIE@wm(Ic=G3&z>Q*6Z-DK+? zo4HG(r&S5@PTk_l&wNr}3e@n8zBR}9vRcyeDsgB9^-2^KUNpC~4q5AF+vu$BSzi6~ z{07(2367t4LUV7{4C%HGrz{7rmZ$=w^Y)#tja|pJ#9%lC3)~D20OeDwnm(JzmM-kT(8+S`XCGvYO?bkgl&yF(t{g4_6GIl9 zq@1fjAgHx#_-#RH&Bx-K6bl;`lL3|YzsUsn&*a|RH#@8`z??`Km*Q!2E5?awE%6!u zdY)7w@4WgvGdimh_2P(9PNTF3!;G7DVc&d%NxYtf6MTxwChd#OPO}nQ0NfljB6N}$_p5;6| zA~(t?jZ#n>d#;v2O?|t%e|F7{AGdekNvs&2U0T9P=d->Q^&aX;V#$r*oc)8ttlCy8 zM*(Wn?rI&>)U{1^Oe~?mf%|4~VPkX8xD98Pp9kiavt-JyBr@Z(??j?7-5~GB;q=&j zvgbNdjOrk(V{+Mbe2Sa#-@FzbpGOCkkAwUVJ(RR>5}6D0IXpSV+-lnpYzKQ_O7HGyW`+CfI{pIwKnmca$vp3@uE@|-#e^n5!w=V2TL zR3)g-_${p(hh`RUrO|EMyRgx~>>BKa(vV@p4oc8I^pe7YtmJ~4S01Ie$~zl)Qpg%X zyVGEOCAw@`Z^p1Otr5Nf54oV&^1hHF7W^k6ulmiWBoD=x5nu2hotoFInUP$uDPq{T z&e*6@bGl}hOk4P|dvxYDiLv8w(VJR`t5IS}2d}w}`1w<*YQVZ}e=D9gF~5XiGb>hB z=QOu_cF{|<4NStR_M8V*jV+&gH%ct+;DY*bASm2d-iW6mtz+2Ss;#L*jeq7=t@sfs z{>^xrX>(W7-cS5A5P|^ypLZgwn_5u?yG^QA4NYO#qHzm?nmVUvywv#IB7()bW0$n| z!975UBpt-%$ZD1ZZKPYC1U-vkm>3q-pqiS{neZc2^hR7cf(1$=KJVYamqQ`1KPDxU znfr%F!4ww9yT|J{_5^)%P~*7P=snAuUX7tH8EwN8v&5%;pukpn*PkAeP*8$7u<7Gm zf?))J!}K>&>BF;&i>n6W(|(l=%`kL8Y~kI|Jeb21ENlfR+pe>DKvS<$ zgE|GZxqT&`Hm+IGE$eY{5i5GkCey}0ll$Lda>vs8r?eTYp7-*_JI>?oVKqVAKyOMU z?dt3w>mHa;bPOQ#5^scEkD}np#!yUL$q`Bh=6a_V)0?{A$rJCoj@$dkK_%uhM6#~V zJ}=cdfLbu|=iqy>B}fz1^6~3raZBHH&x95w^*?6t4Vw;}N^q%snL_2as5*K_LA7-a zGTD+J-AVj6HxuB0l40#{NjyRKbiaD3NI3AzG_G-LU#(fjwKp`aoOeMDPPTOoF<7nN zyB+_v2dQY8!c$+#6!5#IdM9-Z*~l-`c(ZF82FoV#U;Q3Ls1kG!Oscwv5n5ND zWfDJqj;hY^g7JqboQC!Z$f8R}zMIUM*Kgs#Mf?vx->3qX2#56%$ZGdeSDs}Mzj?X6 z=Rnf@RT{6ceH^ly+Q)xQ;`L6iq2EjVG3?DJBovo09u(#YxdAa0;@|jU2h|$4zMssg zY#o6tG?0Ii!Wo#;Z`=2YU%!0oNydlN1SE3AZGKS&xclQAr_pczio~myj`U7y1>Ne` zvxLIFxx*9pkNinrzY$yA)S~Pf0tH$8Ruu}q(9-y<&a~r%4hseSkR|My{(U;Hc~FBr z=yUgyzjG@ddV|iPjgCGK6_Q#8i$KGsZReje_(j70?g?#c|IDp|=1R#Z@`Zm=8S#gp z@>(Ih0``Kf#j-9WCW5#w?-|`YaKBG(PHXJyom`X-&RxwFRmsLr&d%?}mk_Un!i(fy z3VsDYNzAWC?obU(?7B|idl^mLU1JN1p*b`&NsZl*m0r#!z7RmE;>g}#zQVj%gw_dC| zbe{#5%VL=As!WVA1zsbI_YO|H!E!Sxp8?ff zgc#HUl@fmm@kyXUT@})?cXCD2!Fi}LwV~@ex!Hc`mUWLH#IUW3j!d-5HzFqvrn4s}yqz7h#iBFsVgpw%nTZ=& z&l4zUOr4&c?K)hj;?3h&zO{$b=!xX4n*%4{f1>K5= z+IOMMs#!ImT#maZdNp+%3GqgB9;X|FZT7<%lN}${Y`a7N#Wx~vVp@aCro(l(VzPn4 z@d}4nbgsm*&W~M-3n^>GQDXPN{Q+g&B_0>~eMs5=N^OHec~RKf@!#H!4WmhLz1?vg ztBsiX`Ih70CsFjb1JnD4CXY`}a9mw8Z(>~+UxPvS30eM^_mkcsH93#mF8A5A(SCC7 zp?(}$b?Hf3|M27qUVeD&p;kVkj?jVlwNLW(OctuzIOeMjd(NX%oX79vaDH|#34w=> z0-97Pi$m6$dBX|J?H(LeVZ@6|(>Gew>L!nFGO6+m|QY@DaZP@3m+O)lf)abrF0I;GMEzD7}_7~pb?G4s+bnE;x z(R`z{Hz=+EMH19Hi&%2MtQr&z(P%~A336L|JjcDk@tK#gd5zt3H@UN+&2zym+J@Gi zkVFdVIiL!gWT29~R8$Ek0Dtt1c`6B`Gr@7>rk=TLtm$~E<^gY((?0q*JZDvJ!37o_ zC!Y)^T2&a1&KTa%r07T8W=^*f7@5QFoVv%Kk7$_-5NcR$qk&PmYeowaB^rYmnLzu1 z!W&rfepE>2v@1^{vN>H-H`y}@Qq2wa45v%|G%|ZevxHVGM>*h=$;5b2VDScgw+|Hq zy~*}0I*+9sek9U_H_zSW&$Bw!fuI(aaSZ1u2Qf0{Lke$zbhJ{}jn>Bz+3dDqU*2rI zM1$2e_RNPQko$(!ST$O8&^)vUD!EeVpH)L{l){eq9!_XdQGIh)Xsb3v?9n8s;JEz$ zQ7_f!p(0Ayu-65JRw1a(?Y-cHLTEcktchx!ht(L}+JsDMv!WN)L<>DIzaI7ll}Z;q z%&A3>7rPN^UrD)@bhb26u7hvDLzvy#xO6J452|~7?nz!(QhIC6@OjWR+ESYj3irqgv*I#PbcU z-608-tsOh|n}S9ejGIykswKi3VzRyooGtoB)WNZN?EZzo7HzytOH!>0lmkI=WXOWs z=haKDr&QJd3;X7bei2i8}bw*QkKx+J^5jx!- z+UAYw?S6a-(drimJAWD+#E6b1Qok6ywccbyHGkb<>+YhAj=~Il zlM4#f7@+0m0G-X{(b0^|JLG*g)$I0mSUnhO(Y0EG@Z+T}I^P;W<)i{Sl9vBAIthO- zs*fF6rK+{YFB+(hqI=_CjlM`Mg~nn--lbA)H-%pyHfxU86y57nZa%4juJ@Ku%+Fa+3i6v$zQyFGH0A z4<&OXfKwSR+4d2|WU--wlGY4G-e>=sT~H)!FG|`?k);2j<_okCE0RqzizefOFS@(4 zutrWwC5lL`dbc-B(e)+@B__&$>qN!lm;8!;iW;}YU0rOMkcw1?N>S8**&^NX4DHL- zf7b}TejiPRQmr(Jy*f)x=`6(xI-W>B^`*v>F3o4tSAP>Oy7mcfas+(oO)ndq0X9Ia z+oUaTnRE9*_05ldxP1HVw?6vT=Rfbb;?WOS;dV#UmwvKsf9dx>t#r;kUkf_Sp0DK| zwM6f^;OkHnj}8&q>a3^Ek$mxU`ck+&L?FjS9Xd%|9^%czQc6U7-P!l)0gnzD*U?6O zXzDNp#n;K`V$0)bz_ZPqgca-h`(C~8nGdeI>B;NvdHL(#wA&tf4@V$OdoTQGef@WV zmHU>>{ahW~+ua_!<19wW*T1~x_UAP=-whvVbgua3(?fHb1WkulvZmB5j2H%B7`XqQ zouTY6>C_~0nCZ}x_XI`C>uQv9bf}qwVwo90#udw-eet#$XZ0F1E^k(lWz@u22 zZU64>X4l=7dvUuG+$=ys2oN*O;_mKdK-}Hk-Q9IJX1M)wX8Y3LzHHc+XEOPwkZfjp zdU|?yPgS3)>KdOwPU3D&>%6jt^C1Okl^rnuQBsxep~N#09I60!@8~R-h^(4cZtXAT zawYWqqcX9&b1vx1ZWS@JMi4;+SxG|i9j;^hunYv$dd1|FHFn_;T)XcdGqLlF1#Ohm z&XSmT2ylYsK0GD@A8iqoxXr*9J}wZ5=61dtozt^>=P9=?h#-QjRB(sys%L0yd~&+A zd(br^L&3looI8#?dxoyEO-k>0lElP6coX8>#bPip&HWMw=D_Hdt3Jq;Xm0NzomBQ zf5au__JhYIH7$hfyJ{O45ucTuRovA(xPrl55J3cRADg*(J-4B#zS|+TbcaLo% z_36B&Z%AZnQF+~{ki^7Oa7Pl;;KTyW|0c&AH1u8SnmV|wdTf0+GC`xPRwT3wB8VW= zY(w7c!1P_b=o*>+gO-=ld3%I@B61YDd&6QRG4VDOQb=O5%kFe68cNA6Q@i2}k2yB< zuntW|;*zd&SWbE4inQDX5k!!`Q_Fqfo>pqtm5gqu5~NwwDe2kFBU#|VL$}B*Brzd} zZd3?`62PnFL_p4{SK@n^vP>mzY}K zzVa-0K?D(mr9KUgicsvy$Ug83B?A-^Nz5+WuJ3~_Xs}D5cWRAmQpM=lr~vMKb*N%f zFzjL5J1~r`eUIqbmDaVZdS|6qwl5&H>7ih`3nIu06^YG;H99uO>+;oLqE3MBX4Q=MP(ra&%LlWt5vjuEO(Y! z{-1AyQ~!N~VfXsKoQ?mj8$oz5)a4Im#n3V+yyp;>VG@vt@=w^x2Zyj1CQ(3f**GM* z6m;;p5|aS#UH!w@#t6k_4w?mG_fhy%QCsIrx6HVfsp&h9R*dh6E<#zh_mXWOayA%& z$eyCTE&tojlHlcm1v@S)@*6B~AhJ6F$U!m4lE?p}(+*)-@5}0kjqT}g3Ogu&B9{3S z_)ShHGIPa}`1uX)SfJN;^mXz`9FbBa?H@?Y$^ck(g1~-P5-MEO$13{E&wDCEKt)RoFr47YwNw(Eq21 zPPTKC%)R8vGH)&aloYJXJkIhuT;?Ux4RE8y7vlVK9+N4F|K7!uY#-=$`4hfK#qv51 z68k4tc8p}!baxI<;#X|>x&D%O*RYr?kwy-ouB=ETBr)-pbI+-4Jr|g(>XmWt(Lb@3 zE+L92!V(gZf*Q lgB%__C3stb2TFp{2_;eVYK^&;-o%cP&xR*fS(D{pPJZY|A~A(+H2v2ntKW?rW@1`N)p&q@2PkN3RGyV=sN{ zfEzKH=v)f*zWOh}xW+d)_C{11{Tm*W?jIVDq7&@a<<-sJfiY4IGW+vEb zv&h-&hEHHjKxlkuc(Qj;j89OEljn_;%wqN=sCk6SVoZ_I&PyvB@W!F?IGe7CsoB6A zNtko5fN1YP?yrk?I39sbINsu<%wjzwk7K&_R?eZB`4tN{Z_^(6`|TK=Uhqz-N-JwI z4J+IyDaVG*NB{z;-{cb-kD_2g5)*GLF^R;ZGm=fx+lRlS=8hyLY(fpdLIHeK0z!3s zz9(ql`;QtUFMpv&$QnXEB4i68yU2TII(vtt7ux+p<8N#~Psmn6))BIokPV)}@$6d- zNZNYLh`aWkQ|Kh{Mlw4Um6%HiiBBt(&oi+0D7&GkZA-{bLRJ&9mXOUD&oiH$?dlt* zD8n#x&nXMZ*)Irro{%>Qd5(~0dk02YSI{(sd`if6NrTrUZAg7{7i+L2vZv>k6Y}Ld zyDxbM#i3x(ch+eUvJC~;7MZ9>WIK7z0Ue?}9T@)7t>rK|_|CJtEHUjAyUVzGa^#hh zW{$zZVM&+Gy-_+9l{wihcAhj-z2GQoO5-fmnzrsY2w8vPtV3{EvZYffChFxc&kc`? zr8TRiTbQDbowkwJ>)S72Rsp-(MxMJ)Sw<)4)80Tcl2=t7y}}p0K}R%gl=bY`at;4i z*0$o!J*a7;q3?d?va9L^XSJ*DQ!{h44Whq~>)K(qEu2DvZX~H)awgHasKB%y)J~$%nZH2Rh?6Y#c&f1_>nS!z@F#WiWO=)$r zsbdIvS($vIJ}R1|J%q((5%S`Vn2g%yE&$dEJ$pa~j@LAHKxer5$FMufx7kILGjH#_ zNWOdMPaCxZZX}mfHu{DpKDR}ikb}x+9gq{qU<+2{+fX)ds+c+iW#^ZtWfiAn6ry_H zL$r|yVjFg-n35NiE}D5~<#7#CGmFx*OA+=UI}&yT#wH;jgvVv0cM2h7M@>TqI|ao?esxsysw*AIB1P)z7qjVz0RU-{HXRxj6SBX& zrdgWwhs8}+smG@lNFT(?;OFbLu&!Ei>Vm^lq5E4q``PiC*#%t7_avtAg?p$lr5e}j zR5*}d*|bmH0u|vOKK=*Nmr!5ZCq7q5V&bLDN;VGT3iij8uRm==i?IAg%_*s%3PF&J z80D`p?9M5wL1_YtP^T`!=GuM5!iND(bW$FSz8|d7XqM1WjVKWO+oR+K<+`R${EC{c zO1ic%*#Hw`;wd1`aUEL#!tC5l^3Lhi`>)(WO(^vI82v9TjBb&bqI<|EYNb`p>@0Kx z`PmWjhHCG?2rHq`)Ye1(aEy=x7{ih)03aRufiat3QY)WOW?y6Rj`Q6y%C#%rHr)kP6h1Bu9K$bjvU!L%)CYx0sZ`OEPN39}492Y2!Qj&m?ztLs_` zdB@KEI?U6{<~~popjl+^^;9^1?=*~bpU?!_m=;|_9aJ17zdzd8(#60%C94GJ^U4=z zr>5tn`(Zp1Rw3L~ADl*P@^S)isAY;vV4+i(V^;Re+yeRiaqo~sX`Tus^($YVo1MSC z{e+2EP#o*ztg+_>Q?DhTmmNWSfcwPM9KDfr#S)kcwExV!3i3@w%Aqgva${9-NF5}* z1D=-69wo=?ux=oqRyVZMq9&)XnjV1@kNo;5c|)b6i(7-kPDJ~Ir_E5U239t>@8a@?w45@$$SSC6 zZ0)gd4t4O3fH5dPup}lq5Bvc6Sgn6>jFrxjfO`vo33hsGM=wJwd(Uuy`@YlW;NnNd zCI*Ja@IQqihFMTZn-1$EvAj2BS}Iph-!>MlmE%P%)*N5p5#q4kjv^P_c|Hg4DD&xV~x7}UlisV8E6LS4bu z&d4oiN7xJKKSI`3*0n7HcW$vozHII2V@H_94H{?HNwfB@{`SuPwvImh?d>1YxAId^ zGKRKh;EoBzyAu+b*3&Kfq`H-7i+NQqPe$dl2ZvQCW;J;Fc>I^Z66#F zl~y(G*RfrtWQ>>@+t>>8h~oaS34r?)Pxo^dEO*rN&97;loa4e6s_R+^IqsiOgx7^# zleL4hE1(h+GYpeKGW za5EN^HvoMcy(1GdN+b@?eVmo8aDHlbUQUpug;Owyh+{f-j25Rblv7m2aW!wMLOn1a zprV#Fc}4j*YctPVvQd*fe*z9e^l(7k8V*Ll@`0xp6#qN=X-2?Fj0?JnKPQhdvXf|43J z3IP2pD4W=Oge_U~v!JvNo@6LpS#Yo5RypfH6DwGB5?NyF~MYLqme)&R1|Rt7`$jcEmi;DmeMk z-~TZ@CO&WItRGYDT0Y)4b%*cZ&d>q&CI{K%V6+6_7?8yzYTso_5kNcxV}Zgu zRZKzF(<4>&ZQ$0)Gs=kPt8MC9d*JHslcsImgMZkd^|Q5_aI%>@1Od_Nn>(LYej0(5 zYL{JbBTMHHR{E8m@(zy2?a==ef(|7zGCuLmHJaaDb>@@37r!`exKqXWHygELQ}S8o zX!-Vz3*>#(k9S{?G%)$yMyYRl7QT30Tn;Yi0CT-Ac_XL+Le|TY=`!l%P*#2=Ya^|P64MG9-zCM^aLqy^ z(*VI306oRRMh$HO4yai|`Oz7WqQXX?7ZG?mGj|i}ZA>(UscY%z$5JUZyHuLZ_q&$# z%vN386dwclz2P>X0k8D->{-Xe)0a3p?mc)TRtC6F%`GGs))dvW#AKH%Sp{G5in(+D z!OZOZIRl6D*Gocc$3)|T<<47h?-&%%-MP=vtoc=2ulU@3^tcI&+>b9*G_>O^`+V~k z+3}qR!w$qDKT-sdvMBfR8iyBK535@uf`W3d`_(Lg2#Btc&RD@&@zg9#PKi@=&ET*| z;`DpT%`cj>${m9N?hQ`|_nWuw?o+dZJ?P{WM%y6PkOq)|Edjw|Y!^r!c~qB>Un;`h ztf+0psu`R(VliQrv(DQ(`^hs(U~*tf!pz56{JnSofgEs$BLOo2qgWQ)Ln2Z!FoXuN z)eN*0T(2}FMq*0W0*k@XAuRp<-Iu^-$hlEjB^1C~0O(TTG}0`}7mI9j);=aN2MZBk zF;fPNi{E?N{E)gOojUdoVg}yXalyqmN`~Q~-1=S#x6Xv>IR(riYle#u7HMGZznqWL z!$*JDGju2KpMn2||Kto8;W{`m-_kFhzIm6MvC76bbzJ7}-0K@0CBIdxZ0r=%Bqlz3 zR0YmGB&~9fbBbF+1>V}+$|kZ)-^4l8(9Yk=?HUVz=C5G_u!g4;-~~|V>K$Gx#4Q;n z?LjrmJ9jw^2PZ1|s}k(fY^VW7?80o6NMbsS%D+)oCx~OcU(d>~0O)+FWI}#<6v;tP z19t$TmcBcd4v3YO-bfiFFL_Z3S_f`bhOKbx!Iocp@CpKQmc$qE(NI5s*{m}zo|3(n z%q5IdR=_fa#<1fnO^x*F*#!jZT;^hjSYvLL^WLtD_wIi+PM{dP4$zATM}ZQOkA1aV zc<2XZRdgNjh}PO)q)t%5k^EU1N{c=+GoPiNZe3^3AYDnYs2u9~@C*ER8oP8LETc?<4HV!C6QA zutn7|=8~mPXmtA2^c+61x9&Z_wvfDDa^efDe#I5G+b4T2O2nOR!SLM>61NsGAuz`&~{Z@c;M+9L-ZJPu)cY+pJ(spJ? zu0^MVZTR{sH2^x+{^R0lyddwN#@!8U0?;R0D8QKsZFJt$3qT_s{vnN7Kx#x}LLn_` zz(h7DX!l98ReLYZE!<|O?mv74a}`E3e2h?hhidlpOQ&?B1GSkJNc$kD~SKzoo9_KqwTkW|Qno9AMQU54ev| zYGvmM=lH8Oe!kZdMH5qaFogN?HHk?8_sPi#{p9AvmWig0Uh?I68fu+i-Ky^$t7sXV zT2#l!k1yk54QvAe$DG&kqch)Lbq4l0xDN2k$oQuQEdEE30Quc<@|z>?Y(M|!%{m|i z$Zw7#x?IX^{|d97|4i?7h4V0VrAYjDk&J#+%Nj43rT;W|MGxx^=>tT_ua5j~gBFG) z$x~H;`k9@-#jXWpY&mKOk_Rj>y;c^c0qb}QYuD@lA(t{D2npE)W}~8}1>rYvA@1g4 zKsQtOAj3YOC;3nvHa;Da6p^wE4y#CGKStpqa=dxMR5CJn}l^QHcSm>-11{TgfQRL+l z_=Yp`1c~XISKUB-e|L>0(x4bSEN4it*3F$lSM9k(-a7T%7M&BicEAW~isEworFQFv zgIE5#K@+25I3?W)8038bXtkqM@JP zU8{v}IPIJ{gyB|IIBvu?hmoIEkdasM=C*U3HvOYA(x48hThA}tWH$I#Mg4XAF8+M2 z#!uI3{BeUO`MnaISav&@)tH%=zBmhX=6d*8-8~={%bg{6b2GLLxN7N(Ulv*P9o+*6 zjG^=nI>tfjEB@JfEwDzc8I3D_d5bnu8NTtU`ion2p~H|L%X;hV9{AA)ZStpov3C`~ zjWbu+(++j0I9wPiGcz;%%*@OeW@ct)W@aLX$?;v7BRk-59FFblXX{R*^ERr^MP>HQ zCi52FuE1KY-oE#}=VhOIUiRTNZmtqR&&s^xP#|BxM4!}ko(rw&dIs% zdEa#Z^h#!Z6Nas~oR}m?R4ucXTT=Vkzr1JblQ6TSdM!8`*pNom^Z2q`PG`&TtaN|D z(B&Q;9%*?AS++z+Oo&jz%r2^6ECFQ#dCFMhV{XFBkE`M|>C37Ob}cU+TM?5KY^b3c zIypHbpd!)d`GNLOt38Cm8d;K1js^z@hfofS_af#af5B)3+XI-U&8qOnDxJ}}UT1!Z zj!#Z->DZQHP7@ZNOUyb3!dsAM$71SVtHq7L_2d$J1;`%YVuMZ&O;`Rh^BXOy;W0}P z7U?(H!rhWQNZjK@LaX!p`FEZsdCLFLd!vl4gnG~-B=!} zLvSpv0Z7bwS$0h@G!jVQ07P5?%Lg(LB-n$ft8rK5WQm9{9YS|a!scWrr-;B*+pXwR z&Tg3&b3>!!vM;^ipHT;XL9Z!Z|v-sw)D02k7d_%KIfMnm{|?u8SG5hxrKX|4kiyUSh`C!SO=Zlm)5ql zrx*A(&##mJ%{k%RaFcan8k<_!-PyTGi4vu&OZXJg>>a_8@!Jh8C8rq)PQEkm7{lB;^|3#m-59W;VL_9#B`q`P-y*4vI@E`iBF6O;1B5nY<` zp=-f|IG(FA4-piy(O%q`{mgB2$LsczjEe7PkH#o+4#Wxm{djHY?tbE^`e`icTw0uW8QV*8qcLX_`V(68}mjAtZ%(GD}JN zzY{#{r#hp7Z<&1J{n#q^kd&a<+$CleHco)YV5I8AM4gy6Hk>My4U=04J16_@o2-jU z*XX2oYQ?=SiRCT*^hp-AZOHvcLJ`3TCJ@nBI7?KSZS8_#jX`0?&O#LIYY$<63E)XM z*8{s47K(sx1jDt54L*zOi~r!!8*A$cuv~a7gJ-b{uqDI!?rOI8CTEvm7f)Oe-hm09 zESdB~tz}8vUN?RH@12}`G|oO;psbzPTm-uHFWwm#8Atih_`FkmNpw*Y;0NgBE=eaQ z&Bprn(V2bm@Hd|G+1)#U-t8%`RL|rx+-AJA*&xxBE+fPL_kuk>que(lySS>IjW+eN zZFqTo7wp_&@%F&$esIX-fG{zM|K@2|xO##|W)reh?$G*RUp zo@MKk_<>v8(ux{cTkk}lh%7{~BSx3ZJ)&xv8I87kaR;XRA&pbAM?BQ4>)23zJ0!<0 zx&Wx|yZZ;M6O$CDKN=u=t+2e|lYe^8$}4_Rt$8sZYw(8AacOjR)ibxVbwt>Si7tEq zU%uGX*4x=V)Gi<7QV08=Wdu{lCI9(MJ5f$nb#@QpFjT7>{QG6?nUJ1e%Q_Hc71i5% zCk-m5z&CdcykryBH$1`l{y+owvR%YAk9fFhz3UeL!nF_f+2A^7-TCynic#Z_(4z+j06Ov?A%;`&D>z}L6-JpN7~z~VUs z0;u3TLNZ&rhGjo`3us?bLiQz_ z(Bzyd#6{wdF0Fe+f4zW^>KLA^m5*W)fF~o0dIl7-PrvG!QiIy1P0opFUvflO?&~$} z{o%QF54k0!l((_5@U2|JA{&%8^>a$qzKF@4Zm3?m`N`W|1cSuSir!Gw6SagmcNl!| zEMVaRp_g5~uBg`9y9O~S!vqRoFVJSRb`G%NCRn@|gw6o0`NZ@*5byz&1q2%wD!ryr z4xBZ%&+(~wEcCE9qa2?xA#*J>we~2KQ?#c`N)>b;dwEld|vI zDyA0qcK2>lx(bi6D6|~1N@Nx+CFvRkz=>&befRM6952I?rruxM#U7pOj1dYy`|jYx zJR&h^B&wF7I`_D;?t6nPb6XTfHEY-KcV6{_|H5-0_*;9$wR8{G zi~$4|$t*ZEx7y`L&_+X3A=k!8V0it5rzBNt8D?|;^@Ik`tk!3vY7=V)QPMRs`MDRo zgA)qwec3&&pqe@{NjMVI;qfU<9usPYoRjOk!_xy|a~76WSjfY6!;e{`06NZRz=5<(nuc<$1h|EMYChRKPkZFUDX53;ZCuEO$ z!aNtdZtzWgB`{Mtv$V6f&oIm;jl?9;NKDOb-M@O;(Jwmt`0N5sOw}Dmz1!-xHm7B5 zU}EVCuiPn7qLVwEn4(e&t7@8FunK(JH5!(YHnGKk|3%ft?qP=#kz=V7lVmqk`v%7l z(Kt4}O!oWtpLdDDdpo;j?9s5QvaaiM%*GXVVxmNes%5r!_v_pG5L6bf3^8e?AHCo9 z=db%Ccye{$^e_F&nuey-)D%*>rjXN1*bd*j&>L`@GxDotf3^=PG`+XAXX@RPo3~@L zu|~vqMy|O7_tlKKEu|-<3`U+8tLz_1fhVQF-)?+|ltEAm#2*X9N$J^^Vx++FrSt+) zXk#{(fj^dB#1V>?;-5SJF7WYqNhyQb5t35GSiDo#6L(yAEL4e+B7amYLpCO)kP(yu z@uiR~7>hTY1xE)G5qX8H?P)AE~!STYgc1mqP^}+Eebz+jR6H{7Q(|h50FZgA2j!fWYS2xL>ykly|m?z4nhDaQHKG+k6hv7g8zLqo zWdmg7-`#!O-L1zBt=IkKWi@iz>fUkr_T$U`z zNs6)(lxq2cYGaP!CudIzquOy!-zd`dJ6A8`vTmqHDbC7{oW1FzR-!bp@r=*vu@(&w~8G?NV=<-KBy$G;KIg^^%usfYI-cigRL3q z->LIwMfYL|QL`1x0~Kc#T)>=hUeRmP4)0XmkBoX$>?g&BK=U}oCQYALHC$kK-S=;} zC?^nzio6CjG3rh-U#O?18}h0RmtpnQlZg4U31jaw0IO>DU2bZCc-Z}%HF6RAk%i3VG#t@M|c2% zfD0%DGf|-M_GL6w^iH7xCl3-t)pWO%s_G6+MNCp(RCM8u8qhU#@I6`3@o8Q$2zgo8 zZO5yY=|(hJ?0d;%6zL~WNK6)@2w>{Yf&s^{gMtN!M(T_8s5sjx2IE+=z)F@ZFc%hM z@DH7G6-QC^Yy6*1Um1pavEVrUeI zy9-W`;O_2H+V^*pZ9mVyu)b|_bHDe@oH=9X%$-@;+{Lc$sD#)NHZX^ci>)0!#G7%Q z!?W|V(?7k$^nLZYr}K1IOXRM8(t@j+jFAPr$~xJ<9uK{nSR9!~Cq4^59!Oz})Tffm zaopnU@_KT$@fuZri>AC@sxWj6!TL%Cn)s5sZ_D|_UtPKxQy58M5TAs78I)cnP@YMx zK-)C4xSm>Lyj&y=D3Rg7mqu$Z>|0`N3&^Z0t8OO#@!Exmyy$f1u`{v%aq@n(MEhkN zePntbmYOH9UM`je)0I~qQ+%!SJe^~7Cc*OX<7{l(wr$(Cv#~d}ZRd$?+s?+eZET#p zx%a;3fBM6mGjn>Trn|aly1J@;_W2SKqFRBi$~?kSi+T?)EF;Y!t|tSGi2-?1gK8 z>Lt+!6a)7wHug%Ho1XNg=}vwn4>f)Xz)W|g^?ToFGv7_)DXZgl|8_9;x&g>8?@TM9-0{TYcq^I@X~{Tgb+RG%>Q! z6JfC^$qLv8PwD@FSp42Hy+b=mnuN9W0a&}{00?0+r_eOhR$Avqy;J&j!xv|AqTXjz znBrZznB!jFX<+paws`GwCg5Y(HoWqkPZ4e4cLF~}W=DLm6vA@zxKSSRO0Px2(uf~? zR2A7}%IyFAnppN~7DeAp2|@k|vlSz8rLS&CtmQ>Y6!S(6RfZ3zBmTN~;%_9XZ|Z5& z2cKBvaw=4Hj4JUDA-#uXk-3Qajbouqy(;{)(vLMXnyf_~SB#UcE0`4A4JA`iECi*xU))!xx_&i;yf08gcGP%ZK?-F?Y*}bxc#f`z zrC8CXRS{k`3oB1&cXhQhalmA4M*1{S?LhEkzk+hFsfAW>7&$UnSjawexaIWpWW3gF ztYz8W;bRCLCryoEp%K3SP!ay!=F3w~N*f~Hg^QV}DO{UEgmrohNr5py!-@#zC6(H4b&UbF@n8n%cEAnUyHt89SV47r*p zPD|nAiHtJ7%9tQDw<|}jUn5tcQZ%E$Kd}<7hdT6}w)r^#`Bb-m%?6d`?pcFD;YIrdbk7`nMfX`PL03?S7Ht zP~Ll~b@dgJns&t6Puwkx7G@V}#MK{Rox=IYM1yQiyS}f*cyQ#!`3dW0#ix;Bu=f50 z?cX)YtyT6{g6QI%A;dZXtMp2l`rU|eIgN~1Yd*qsLCS&3nAziOPfzfu#{>p~Cfi1ac49Tw<%M+h#O6N!GH^g%8y-P`F}yauS7wRJ|*0<6jcSe#+_p*vrMSv+MfHZ&63 zK>nmOu;mtxo?^ZRk`J4^YZl9!*nWSQLpMu@+gkYM&S&b~=*kIS15S#p2S4tyP4gFJ zb40#eQkLg@$e0N630eg-F zA*Mi==XhPnDGF4^96Fu$^QxaFjblF+MLM5@6)S02`yZ!h5-M4S=I8YFt7|;bn-rxX zs|J5%&yf?ie^Od~cg<__Df(kQxG6hZ9AHQQ0OGEPBv?p*DIt@G$M0{>4&1SG0y3)d z<}Bs09&9~-(gakfx3c<9s-`hkY)aE2AH#t(hBC4y;RV1Ar5O}cm;XEf%s-B1lD0V9 zi;EfK9NMt#$u_8mnw`B7bwKq2E@x5tD=h%^vKux;pxk&>O`tj6nT{Gk>_9;ylPAna z4Hi6Yh((oJ+XDm~0-D=-vgFw&lp+PZk|Op;scfzoAym-~&<2Mt^ix`NulH}wZghz% zF>T<~_q-y`yw>_YACXn^OLiLTK=XivbW;>%?J<%p;He`e<+cdQnWIwzJKa_G*aExNQRRC7MsWs8BzDK9)oYI0Xb6b*Is zB;*y++TuXQF{|R6!eI@mpS4jgXgYu^rFXj=iJ3T%*Sdt+RxnbY+8eQVs4xxMyEC;Q<%@Vb3Gxdf71Cx(| zfw8u3`c2lBAkWKMPL~~r);Sqmg^JXXw9NbMA?>-f*NvjM8i_aa0t}6VEQNV$PXdJs zd<`7kO@7KNDe35zi1H%$QF}6UO0$oLacI$7C{;>glGN0hSnw_Zsm0vRc-r`Tno-qV zWdHL(q#Qa1B`aLs$SfK6$?nVJ>Xi3$A7!)rofU2MijD}hRW`=Li}y2f8Q9V6Z=xM- z8#?_7C*Ih-!jW!OqnM8cOzhOpcvY(BVpU(g(T~LupEB1_ zGpD4cdvw**5no%U$T}7RzDG+^xp8J`?dBBA{~o52X2cjXkF<3)GFNxl1hA5hin37)Bf`+JtXtdPE2|Y5K)&+6a;@Y%1i9{s?r4 zn%fQ5Iu-AQIC#c7f;3R;oal$2G*pVUU7z9y)AIJZdw9bxQc_-oJxd>@x_zwEu5{xM zk1fZ^RTHqf&~?co9jdIg!QXJfiw>Fl>g6hp1Ln~6&=HF$IcV9ecVk?*r)T(=JyyuHCF(XhGTO4(RhzUd3 z`h6R^{kf8r{$t(VR_$(S<7wyNByM|gD^vN>A`V~CYJa;BZ}UhTB;$47-^}rV=9r9p z$pIztu$Js39Rh}G8Y4Rm2;fT6g+Bv$zCpz8jKdwe!_i)^k8t#uVu~2wYjm+x0eJ0D zo40{)?iV-57OTpeDHy|WWKIfUvNLlZU?%?^G`s!1UL|K2Fi8(Id063KXF`D<+Y?Pf zoeC(5rnCFDkyp<6RlPcNIMqIDBM@8p+pW{t?VWe@4?nGill8yby+W{1AVB#rA2S;V zHy$sFAfEI{`ZK?rpMXL<~pd5B&qH{rQs){ zS6;<2kTQl0aZ_kKVZvUNwaX`b{6P9|TI#6kL5<;cPsoLd;oEUTMOOz0M49{^HNY%v zH5}~~c*N$Yh|}Af6ttK(QMIz|P4Ig6qM~&BuSoEad~t8jGp`+LRZyB!-5VLcn=tf( zQz6G<@^p#9ezwDE<6rst4Y+ZI2p-)Ze}>f@|KaHu%#dhKF#-+W8c9^=r-yF(Xb2ruNp$7P(l{y*Y`mV40HDj> zyl^Ro>Hu2u<=h_Rrly8a!jt013N+@n&$40A3D5{0NQrcbFpTAaKhWnly^+$T_fzN+ zF_IC$4AVkacsb$%97lX)Xr4f3m)JTxM5VvDvdyi7ps{%{GEp+8MSC@Alu*8XoK3wU z~NqijOA6sc(@+H@i=pIYAz+YmR`K&1;hU(PQthV!;%Z+SVn2h2of z9-CmGJduYfTaayc(yXlS2|XTEsczki`D#F$r?kJ2}#<*4Y|C^z> zA@K;JQ?fUA_PM#1W3VmLfdm$&>{;h|S0GQTwYwT)W#9i){PmL}@cST5QHy4n78)Tr zL)#Gt8A50RU9s}T+UkNYL$#-+n?_A1VkIa=JF4IGo0*e@z7r%Pq%?QQvd>l#L=~7# znC>NVZiJ$qwMt@$h+0uEX+9iyHsW^k5QH5SXB4r4K&33*sdQB02{xus(L8lo7thCG zzpyUa+(MH1YAUBH2ogc&B~w?P1%0Q=_NFjgX}Ck;SkTB7X#IJ6jw&5dwxC7{^r210 z=q==Az|g_YnqJ}@?)>^E%ZvQiBl5!Y$_ad$ZjNM#h+8J;KrpvWD(L z2?z-cp=?poFck({<;>fTV1SfJHR{Jr#%eEb+AkfB_R*b^U+w4YDU||^+mBi;mVbWt z+IxVg%uMSj}e=wJ$sMfE3p^GuL)Wwz|-!X7}5ic1d;Ij(&Ttt(3f4$y{^pvpeoZsi);WR80_Y|!*4Xq@VX-@KmU0l+w=)o4iHqj ztwT2kLY-XgO%XhMohwa`gCQ{#F0eC3f)d_{Usi(Hxd>FV`Ko52g;4lLxN-hpP>UO9 zq#>xn#L63N+zQG!!M-jmF(b%C5}c^t(*A?_f)p-VY~_D*DH&EkqnnQoTi z3;fY)G&5TOTpk?AZXvI+G+A4tl}X`5X@JhDwd?zC6t1IZwG_DY))%`N;09ML>^Uzj z@%!rVb04|~AO(X*oU;jW);-0XOp^U{$^l{-iJ7W?c6xx*VMx&oF<krJb|y0Guk)|C(cn8<*54d2949FgYe&i)Pp+_wEh$|kHj?z9H74J<;-4U7 ziZb^?vpu0~aT?W3SI%O z)vOR5LqH{LfnAX+j@ifRVzp{SpxG#U{P-Qe{TNCOs{j|ce>n7h4GIdWSjQL~hZ`|! zwg=w<@AutqjpJ)D{d|f9EKCfb$AF6M2t0{Wein=J3VsR-#&6}0d3gl=efF*>bAG`q z={9o&+45s$L~t%XH~m8s@cd2i(}*0-CxR4~h&#^@0NMEdE0;NLf|L-C2`uuN|7 z1hMo<4WSn5Uq|p)%9<@pYf#WM54$_|N7_B)3CF( zzbbdw9~| zlyGo)w$qVu`{P5zgaGWVlIKA$*;Qe|glXV^6L-Y_I(!xOj)gRY~!~@(4*ZB_m~paGArwNE(}{`x)}2$7~tjsiSHm zxs5>%T|4*yfR6Hzqq|Wx*hso^o0p}92ykHD`+^Y1bT1iS!CUoux$sbq2)&gL z0pEyc8r3qY7c>T@PgbXIeRF#wqkwGy?ATr?`ZCv6(eF40Hc~Sd><#josCSX9x4jnh zF*&4i)@UQ8FvRB0lt~%-G{S3CbyWuk4GR0jWQrNq=`^exQdASZ z_x(3@-)3IMGz^IYirJ8a;ivxBrC;oU^I97N`!I*Lgzxd44C5s zqL`*;%8blWS-PG03`N6$Su0L<^o94nmK|Xa1AFfGoviR&O&|WrA+k2Bw0s9KRg(ld zvZ68NKsJHbtowTCU2O84@&VTYp#i`5D;m!+g73@#qLFv1S~G5PA*vWTD7Z6^>K`TlW^?dpL$wCVUxGYN8S~-v`KAM ztYqnUffppKu6AzmI~~VFu#@`;?@Qez(-Gzdzc5JQswfK7yDEnhAnlu%xuN_ld7H#9 zrc+A#8@W;PPIkjsOarRvz}TOo331T~DS|nrJExd^Y&(j+{1~njbY$I~e4mxfj zh`R5~Vk9igH(bdv@=1PClF?$yLgH8}!t?qrSVdXOMDJdRbI>{Y2hraSxhYokTs9K; zvE6z_Byi3@d)2pzu%ultCTtD{whZCFEmNi>ak!uY>A?lj0qB@M^T@=@8RvkGaH4em zW+_FNe;f$5x2L}iwU2vG@vSP=E7!cY1(4>ljuzKP-k)!9uLV01(ykG;Ewl7q3{WQW;Q|!PL7YvGTP(zAlVrjOiwgb0w{M z>d?i})pFpZ3>Tvng_M}{KwQDps{%_$Nf9+*F6f|Ax}B9St(iBnByRd@(Ea$ga6C=2 zor`!_FB{g+j3$Nz9%J|=%o-^LCe6hW2+-1vwo&N)=$&=v+GS>DtnWbRD_U1yg)YAW z>|D4+PLNxf0ydgGzT#|Ph_zGY_+e&l#%Gn%q^&p<`bN6rK&OXi%nK(-(obNjjK%UP z`mL;Db+Y>Mvv!rQp95}hDvFg$OgRi>J8nlLS9RW9SfF`W+5Roxq27VWf%;CO%Tj zMfn)z50q@+y(lh}HG%0A-9fxiFpE}aY_M76bPE<}P)5)l+iS+qfL(0&7D#f>&~GJr zSQD8mLIcKE3#JziHbRf^bn&GghgqJIecFHl$F;MSs6w##tl$W=KoP@)5o4xF-|Gh* z4Ag$2x=I`!Fsuo}7$GHxmb)YQBrq}Ms#t*1eIhw!kK|?<_l|jD8nPAgIYLaU_GeML zs0wK^^yuIS#Du>wfHXdoJ~FsSg>iBmw)hk-`pmZfahbvGFSU>zAwEv0X^o zDy|C;yelt2Y_1YJ5fXBSsNfsn+V7Bt#d&(JlR3kw`s=vu7el^23_p1BVwzOtlEAez z3QHl!;+@*>6uFf9y92otxpEbK0jkIRgRK@eE2S7ra_d?z;cU^;jEV{6yjoo)xX})JYwl`PwVNuAjMCc(nY+(n zqpXHX8n0V_5*gWOktrI>5Oa0WLuppjk+0CRlDtax6#XXhu8*#M$(UEoEDs4S&x&K| zktb3dI7E{k+MtGZaa{~pB69yH`H})5P=E*+5*QJTqvj?mbwmZ=1u#{fnFhYqMT>ds zsa-Gn7eGt-H5@tIknE+k-b|~AS#SK*Z2VNvL-~M9doO|i`9-j~(#pVsqJ|{2TTiIY z7WF2-Xwr@CuE7$bt(ZvZb5WczpWeT7>1u5*9R!`@{kBBK*OjXn*R{CpIlMN>+)Q&( zz^byBReqZyheaMobA-3ZmeF0%Nzt9t1s~$_wj(BXRCF)LO6esJj=B}JJ}zYS&r_Js z0KL?$>ZS;hSHC`N5?R0Dp!RZ0Oqhld2yAx!6JZh?hCK^7v!nYtq>V6W&{ZtYVRQio z@fv6V4`|Oex^5mQTL!h48@vPDg* zwSdsOe*MLo@+q51Pj~0>#=|$!;2S+(!_yN&yBC;>W{xVqIE+5VfxVs`r=1^@pa(KN5IzGgJ@WPc$A}?tL%I8VHR{rb z@bt0W8Dae&T8wZL_($R&)|fgB=lkwQmA~a> zYWu7JnrZ&#^8K#m$~nk*?&{>exVVs$lRG##*xA|n{rmS1OqlfM`uh0z_?Ml%y^fAf zXJ=<^ZEa~u$=ll-IR(WJW0`XIe1G5A#DpZJ>ge(I*1^Fco?w~iN9gODo8Gpzcs+Iw z4jyjqlG4(Rjg8jURt5%!_VxMsh9B^PcV=f{U)U32p={UZw_BO^DrbfU};p73&e zZB6R<=qLmhrdaJY2Wb6(TBi)Jx2MOlxu?hXhn$#x^x=G05f&EqN69ba2K)MdC4PEh z0@_VORkf?Tdw6s-NcCQE`|n>kSx5+o<;6uo=Wt#g9vpmpJ0qjH*;$~?tgI|OU0pz3 zZ?B({5>n+)>Yo>o32kFaSzZ>F!d-c|jE|3x?ry$YTT|1a>%-U8Bnw7aSy@q0Q9+Aq z8yg#3G_+y4UFOM~o160dnaxdIPeK$742o*#H8?o9%8H6~*5n_EWWrCBLv&0G_;WIo z)mUC$p7Vqg#7JI9XXt+m`TNO9=?~GjPBS(-8uk|rZES4pv7WP=+x69z8u-J*0~Hk& zn73m8QGb6xT}ry~slB10zb3hsqT=r9Y1>c8Fs=RP`#aAMYKX}pE+RsxF)CbK*UQ5r zI5>E7b8}3*yu5tuPxHUKySedkD|dGcZVL;Gq=5S=G%EAeqS8{C?4%^neKnax(MuNg zbeb;8bwy7D0zbt6-=3#hKRWPOH9mx>S4L(sEDRC?bc&9ie&l@5USA*oL(RXW?}z1S$^QdwHa1R7O%3%pd3<_8Lnj$g zqkw{fGBGg$>+S6YabGq!Gn-S>)64ng+>*3EKd+ok7QvJ-F){J)`PoW`+3DNgAE?F9 z-2bVUc7tv6f2AL{28LK$*7i$yW_?{7q$+xM*N_&;k&%~=Z|(s4TG`&(Iw#TcGp??# zGKv9OB%Ms#U?E}?5|G^8-M#(D1JcqkvKlbVewxGhsBqIU!y&be?&?$PsAliK1tA}& zOQfq108Dc_^wQGUIGEipyR)_y5b-k_RtbfKgg6-kl>$0>=Up5e0O@1}&sadbiegWo z>OJVm$;l3Hwav!n<`A1^9*RM{qYqkodc!qF+qigm38+?aeglL^M>WgjWMr=|FRJS5 ziBz<-F0QUe@BmzIlgZ%FP;qf_a&q!WoWb-25L|D3{Eue=FL!_zA4;&}hxztO&&*Uwz@79@i5g?o0`?eKlzz_3Y^ zO8Y}G^+&i?8FI9Q{{sB`{N#h8)(YrfGpo#PuyTs@WQg|l@yW1kbX8~a4YZo%oF0io z@8(%L;aarhRs5ByHqW&x+~~2KnF#KQ--O1kX^b0le zhH;&eLDa+5tU>;4UY^I^{m{-JpOH)BhjShBbGavLHF0C#IPUbzPegrRx|(hq zR)|Vho^AyhHer5hus%=B<@ByBv*&dQ@eN<_UVK*2j;o!SUHbmr@={`ux0f5^AE#ij zs`aiFcZ(4Zo0$me`+3YJjC)2bvv{J(*T)Af_-v5JpFask`xo>r`RDe`qqc}Cj3y^Y z%|IFh1)``@k+P~iJv|d#jqN&=GApciLUEb}w&Zf=aZaL}nlbfscS8+wAPgLp zmQwIj&2scrnM$)_6qOxHlT(LA_Lv&h<)2YAZyn2(?nj2f5)sQPeb@}o47pJga285Q zBvc#j;t%=AMQ09qb0yoMiWL5$&}(`%r`nX$gnpjj7{I%k<=P#TP7bzj8?scfiC(x; z4J0)76kog_2X=6Q^(*f01x7A`@wYuyFmL1c!6>sY&k}Pa43-L(jFkQ z#)el_0itpcM06DvG!=?jD8`J4wqIaU2Fwtc8ne0{!o`CVn8$)-`VZ!od)Y=k#f708 zo6vJ_-g3xSNMZj(|>)T!Y{h_$1st>91-Es`zQlQhaUNH6jOFcZulwr-1_}7qeBL`Sk zqp{7VbaT7u?7<;z%$v9s|Cla^J4_~O$TXDu!opGizN_ZUArqJ0kAG7|qctTg=ufLf z81ARFd;Np|6eQ9N%YfV{{g1enrY92gjhmeJEL!M~v4?%&0S6BWRkD?h(n(REZb_!P3<;o*bie+8FW@%w~~m zKAyE>?x?raPg2o${l(dx$#Q(FB?46QjpSG5R|Ae1I$=AR_}MdFSp`K zXqXU3@17Z;)l`*|sox+vBYhg)_a@tb9)XmrvQ3%4PtqPO*>@Q5sBKOh5i11?Jw3Mn zU`d}3Nd(cx0C5Q3!B|qbWY?adcFsSU2(^Nj18d5HIig-vd0WOB#(wd@O5yT#eu2PA z2Vw>Sk%canATam#ibq6)P=|@NDV4vOVvFE*HBBqo?6}8tu?ie5kH{UB`Ui12Q{f$7 zw=Wm|MF7pr!5|xEDU>YDZ`o;oPcn8X5tso(JY*h1weIAKn|=cqv%Dv@U0b43cSbVh zd;>y)L^|XX9-kjy-9(OQSw*^Py?xw6(O}q9pn-O-n#{fJ5B`22!ghKcy(^xkM^iM7 zt>C__NV1Ei#UhSnIlGKky?~xerYdLdayTJ#qN8YQmz5?lEWm$eMsfVmlUqulnP@dO z5~c~5-UA;)HFfEWM`2wZ6Em;J;G5=tav9#GwR#KDC!eIT#za%!Wb7y4P*{N5TPRqf z#h<-Zm2jCpG4nzi6>Tum6qOuZv(z;BLe1PpyLP|*4kG73lM^yG>FNv*YHREqI56!PmZQ3)x-YK=HYpl1^u z#mmR!UU%-@*}35eHGR5AfhFsBmpnlv|Ek%8WX;KPCtgHsbF9~$I1o8~cny}$sgn?i z91!=PDmxlN_3P2Eb<4EFBHQXzoW-f=kd&gF*|g($g5q>IMghAVfW#!SWa5ksa;{^8 zUeOk&oH30Z$jI9RF+)W8TMxZG>>5rbt{`n31uE^CY0T>2qQMsC0MFN+5XBo~eL4h< zn{^~g!^Rsxi*d&oo-a;Q)=Kh=taB=`4)dNRhsvgdA}+&>K5Vv#C*NTZ5|R&lkCwMN z)RFnj#)fD}QKVGnrEN|T%0Cem7gN$gLHdUrY}%i36%svf)x;pOKZcu|AKk7cDl&h! zxExPs!!*RzrWL7KktBLemIKeM5@?mRPoiI>GyaH3B%Z3Umwq`A)&f4~vb{@FiH9fX z%)dwWdi$L?dkvOBCF%|oQ<)$|{TWi#__siin>o~SMqMu#$cI>Zv3ISV!NK6$IZdHL zI97Ty9@UwOa-6%JKBX8hJt@I|2E-7dfIvKWu|NCJE~;X8Dd=y)qZ-07HQiYy(swE_ zoWeq@ZJ{9KBOj9xL}R$hL%DTl5&T|MppZBjW>L$Ad(wUu$}{ba|=5Iy`ht{iz- zd$s{A^~3_(9Kpe>oO=seKr6(fHHO^@TtWHzeW8%i1r3d|xH<`Xi6VjyuThdb3R9_6 zr|%2A)=LHN61Yst{6H7Lomcn`yem=L+IC%7-fOF+*+QO zNw5Sl5iqlOM{;bwd^dO8&@b=ljdGz5|IA@x;fU0Lw`QcqdfZ)N8KkEQJbhy;CS-8w z)Ec@$TrsSnVZ2IVs@RGM7ujHC3m9G@Uc&K=#y+2bcLf458Ur&T59oZ-?E5l#)IT?j zM3wG|fP}whw!hTaCaj>=J1e89q3Xzd(CP-*O}W)W4W*sb@GcemN&snV-JXa{$COsa zi|R0rGT~HA_U?t8ccO+o2%K-%wWZy;PoQsL9GJu`(qxj*3jteCp2HO>5ISx|f}uh9 z=*_u~4b8!xmq(R<{-Ar`+5ASpI9+%*S_i+dSIYN~n3@qcEJCqnWYH?=W3$T_c>af1 z<|l0^hR*L|jzlw+sUwRtX`Q1sV%1Nk79wl}g29SqfPEr7q4?+d=Z{TC_eA`8s*3?MW;TOs^1I>^Oc^O_u z55PXOP9Gr76%7&)sWZ+5!QioWp|LT*lch32YVCWT$N4h=hJWi*=I(}_A||z%`f&VZ za-*+^6JZ1dyVFrhDJYXayKoID@T+k;SPMi42mui{Zab9~U&}UqKu>-E^6+k(q#B%# zks6#rbE9zE-EpssR=g$GPt`C<+F~h?7QNABLTu+_2nfBwaLk5_@$DoiIB8SC>4e@{ z&evcjb{3UXNPiBJuoSXu9*X8M#jw~GLp-Llz`o>e_R`sw(V;r2(gvi*@bqUbR~6_g zRvH$cJcrW+bD>suui^S{2*2kzY;nTnaP7>6rjE-eW>?;NcJSPeU13@+Cwxquc~O4v zbx;3+$2%JPvWQE^`7{*E;go__(poe9sR&qCN207m&1>*$98ReZfEUM?r4%$026cdpIEonL%)>T} zKrEb=7%%jh#@Ee8SUqM{UFG97)gnPvo=em|6i=@4JxQ^%G!C;^iGv5(d&r4b53Sha zXFTKMEmMyV=~Tfj>UXOjWI;z{+GqjVTvKLC`J}`GNzLDGZrQg`UgbubsHNM+4e;|y z22V|{Tz&O_C;n{+%%D{d(F+-(sPhIgrOdHV9mE1gMmx+*B!@vbn(f>VXI>~4rayd` z;B2fXa|om1`AZrRuG7|9MYlP|0@f&)M~Gx|vTY?aRGnE^NKKScgJyq*g*AH2^729# z__;E*I-GWfS%($w=!m95g`dD*%}HFCBb+BV_5uuuOQ>`o)vec|XwN(R@;K-N$HSsJ z=Q2=kJ6uC^UP4iedH>#WN-e0y0{THk^MZ@64QWJ3sg5B*C!b2jUaR-p;McqrLbnNx zrVO`RlV^gYTWItRW7pglKOc4V;^PomP}Ix|k4-#w?d*Pj;_;L^_Z?Ch$vVZM6PI&p z^b{p5uyiD|@{}wvD21%h&HauhTvo(A$``b0t()Bje9_#i#7|k5EdJz+=O&yp{ZqB% ztoM20rd~}n8r7T0CO4NLH>GjSA#%(Va{4r$OI?@A$1Omr5aLCPsTiRJuFi&Dt_(3Q zH4tigofZdRWDdCa`8%FN3?g2P!;{$;<3Te`RE4Rr7iG)14R4DwRQu94;8r)|emEo& zi9<2Sxu{@%{=O((0!yQw%b{`kNGCa>ShUDCm!xET;Er733k)0vk?qILqETK$zD10D z&~I%Z^)t~KPe{Q;6lycvG*fmz8wQy#zydX0Yl$W>JNIBGg|(VXkUG+h8sI;AL>7b8k%->#9SZaMje7zgnup)CTg7s zSahh`5aD?3A+gA>QQrc-oBJ>sTFbu&u^jhKUTCX;0Y!^H53`2azOYp2VY< z!7om$Vih@G`l^TgWqSMgV3jg3#7goQDNBe4LX^A5%|ed9N(vV`o__G6pAQeN@zphJ zLA5>nJJ?+ElQBtm`RzaRPq!Un9&ekzIQ{UIlb!yChSe5D=baP02JEe{p>|@3v7A$n z^v)4@ge;|#<=hed33}dXRG2i`?8S8Gn9ot*s}KPXgQ)+KD#ggTv}nst<-@8VBKN)} zy0ELJmoC=W@YN=8xanO`V3{BR8_N^*7?N`C74nu+sE!U3H^{2Seb)0DUB4EED^DA0 zemRqopz*ogSzD~{y+|5%^l$6b&W+jr^SX6Tm?o%{;~~Zb|0Q#Hf7_6z&Z)BUnsZ?2 z2Hp}vtH_4v(59O) zojwpl&lRu;ex}=M<_Hf;)ymq0Po9V?v)_b7#F7{lMBtSKEoNBqYMB3a?`{V{%;e3s zlivUHd19!QzH)v#*Wd~3e{<#EICE)DZ@nq=fFneOlHsmw?5s_3!RoaZw^B0v)%d!V z=g)QB1UndM9qh&SPZJ)ZL z@sM)dD{z?;g5)oV2>M=&4b#)eS%`tVy+tqTqXFiOgsQgxby2kM_L)9b=}_x>-QNDz zi+|EFNfIzsP7YQiz)CEREgYy`c*o*w&as;W2EHlKo9{`IpWPf@T2pYbWs%*Fh*V8G z^6U7Y$x5nh7G6GNp7bx3`rwUM8HnTr>0?MZOxsl9o3GF3j zH}uhj5P_J#j`Ny3t&JIf=VhGCB-(XT9`1fEyT;de`b~7RTIBf42(?5j7?jLtJ1KBK zSC^0va;pd-2U%`VH|mx4s4kjP&`qj1X~o7`(6M{55M;gB#nwoiIriS2*`)Xez3=vT z(r;=39ANi<64Ga5ZYBHtBjgG}p#c&huGLVGr>f2Bok$k>CwLR8+tv}(uF5r<^T24W zTte?@RN3$2K(MK?Pr$Eb1zpF!p9(5u)L@0`Z!-|XKO>a4tkfiF7O3PPRhKLv0k>W5DX#tOF=mqFx>;& zJcxQ|=?NdZGP2f|+j3oW;H~kV6bO+6RVCAnhylKqU^Tt?AO&jShFP`i(JRS z#OT0@(i^8JDu#NhU}gNSMTUat?r2eD7180}y*&Ujq_>HsbwZx~m$Z2OX%Skq)S72oJ~+^5+DiI}r1NvZSGOsxSy+4jl^y z5X3SPxsly?E9g1Ms|87!42kQTO66iJxYAKu&NS2g%*=I)p zD1D6WlHz0&SbTS#xyBcC^$x}V%mxPN;GTl~|D^k`po9Tl(&Ngl&l20>TrGbo|Ayht zJVSm&knNF|`4Zn7qy$S;!=!u*8m#g_Vy0^dDRa4=FP1yoC)QHCR$4#=36(D7U*Fhjoj=FHy)8rx z7<{yUhuwd}*%=sh2+*4zRQIc}e+{}&DIdO(hX^1_Z(X^Kek17j#2mfl3U0ck?fi3C z{bzV;{3qHDy>W8AsY6SGZ{$mH)veTzd51Wl@!nrNk~dW=L3iw0)+TKT3F!s&yKl?p zS}maBV7;cu27xN?;hexxpu~H#&~K{R?@{T<1V7rGK@Qa#x?8hM4!qDo5F>w}wX$ZNbmqpMdj@=tt| zcF~?$D#Kss*;@yDoU=5G1F=2bTNTNiCR7Dgv-hgph9x`l+SVFT}B}yegk($q(x0mpH|*TvNCM z+k}am&$ZWecN`!0lGlY-S-{-43Zq}$YHs=C*X7I>YPqbMmq4zZ zz)nq_5&{*?8d2J4Yia_b6jy(CsqZK;g-+ zZk}*y*Ojl*J`xMrcuwKbxquw>lc1cwH&rY z*twXanB4lkSa8*|tC!$Z#0Sgv)|)v)tKQMOOD^k`ej05Tt@`gsN4xR+GvY-CuOhfJ znJp@qrz;3g5ak??%L!~q(E68{1}nDMoGTwLya?{EDB@U7FmEHi3*cx_aTFAk7ZCz$ z$w)!le=C$g@MFlhszi_o_+UM-VEU9*z?bEFPg7H{OhhEWR>(qqr<;-)3 zholiqJTS1Dq?}R>*}D)Zf1mti!xbpiVLa=16+kGnoQ~z;88O;WQlCZ0i^7Qit;FY$ z>vf^vN7l3cp}gxr)Ql_j*jo&|Ih?sLuF`b;V|ob|aLKAgQ+5qH_L5*vpQZA+IG4+;V_qS2r-Z*RNgx;=iigMi+PMaD-iUfsuWw$+UIK*$6 zUd{g(-6SI0%o@%9e6{CDH-P(Wsq^gvQBG{$E8#9h!hIbF?%)ReL0ISmT!1O;7DwJd zA25M1_VRSWDU9MgMC{xJbj02nu8Fa@;S80S0#p$he=NAMHlVO|#UCT{k^nJLU?oF9 z9sv>149l2{*@=t}(+Q40O_0g~3o8?8Fa;LK$h_k01$5$%50Az~OoyNooGvEX6u65I z739pk*qMk-Fp3ixUWM4s3lV2fSn#I{ogoY-e{#dZn`Eq5EvWIQmzU3D(!_@$#3z&8 z33oQv9G(9oT!7J6YsFvAXN=Z>J^L5;MfT^KYNLO5yvnJIzuLPwQvTs|D$*L<8m(Nd z6t7T<_}`nXYmNTj!-a)%mtFtggZVpS)o8Q-mxT;r-|t={+@(m7A5=HcwXFglq2A`j zlec9yf9KAZPfp&y>@%KWS0M67J^JgM>Wdue`(4_Xy$0V%@%gIHc&=SRhu5F=>fDfF z_$wUhr^nYH$14OiIu6{i`I^u8j7NW~{GcjjeIlH@oVZ2%w;1wpj`qHoX;TioX1uD8*bz7y_}s3gN(Iss5< zm5IJLTv>MaP)P@cyELrx8OUpLfMk8Yn5>zqu}Q9*-$Q<8_7o;br!w4?=WL$x+4|{_ z&1VMks{rY-fnAR*ogMBn*=zRh2DNnHcz%#B%$1$_XVKGL)-%lq})TD@#Ch#A7|Payu>!1u9Z=DS}! z5G6{6D{a0#eyxG;3^2{$ePzKN0RT!Iya;#{Fx$W~AI&0BKxq))4%Qm< zXNYc~KOBqgIanUfww*w*(55%Q|cpyDCG$JOlhiJmkKk#xDK|oY%TmYyV5b1=Q zF*l(75jK=(!`H1is*2_l_{PJdLca2%+0jr&^g)W3f(xVe zgrzYwk3C+hQXyaVd<_9(gv~`9l_W1sY!Jdq%92up4f}qsem!l!Fb;+*@O@>$eP!_- zID#Z71{1*<^n}HbOBcLDaRa2lA7CZe${-*@G>FDMB!yYI^95n}c{JQYNl2#wWZ^aO zAOUmI2?%q!qsIY%!eU`_3;XQO6p*DL!6<;1krFxs)6i4dx)eiL0%atc<%Qj9P>C!t ztQnW$4aCz+RpRtQ?JBGqbYb!l>hX9;K_8hVWh8XkO5!VQY|pA?3Hs#{R(5d|tOhQ( z+f7M~-Ab)XWbU4(SAhGwz7!9htN5iRk#Rjs_ z&GP^#v*#Z5W?;ua1Iz`=4D_<;NN%@a8cIS^4f;?OjDkf$pe>EIAlizAo{AA9fR6f2 z_Lzsg)QiTECGq^wWq`f-Gv@9#mQZm-;9@LZ%ptF8p?M7ZG(fqRdM?uW3!-6Ak)3&k z@6n|^zfA0MeuP&t(RqazHrhB1Rb7YgD+}%`E5k!@bbv;$y6_G{jdG6lI0{lDeU0Lf z95d*|k4ZGXqsb=N1)5_#a#Vatt8y%+_5RLpJaofn;o>G#LBTbCT(|hDHa=ydzxUeI$0R8RSDfum% zWL6g3S60l-v@PWH?cUsiNtI8?WftN;@-Pnyt7??7^Up18eS5gz*GfDII!WrSm}B|o zK-vyFJlW>>({1%DD;I$K%1*^Jmkl>t!u$7q#RUen^H&Mk5V$9y}*Ng|7)=C$cv ztDI#g|4Bz%_s%cXf4+AWh4UjDcfIh+H~OwqCbzP{59{1*w)s z;kz#Oz_HDgBG~=nO6VErYEL8=Z_1WWJ9*q9WIJs-=@53iw!hGuyL9!^NTCvOM4-`S zAkLUIK!8qZl~@YPzmke(2!^IS0X>9Zy@y9TDY@%n=@!as7^&e{Mz-;W@o#?tUs-Tp zS#XDjHh};~7zgq?h8w!s3exMdUH}ShwL9$(!ZKhF5Zm6~Rd2fz-CAsfl5JFPT7$mx zvf(~un*!T{DIjCGsY@Js4GWJd)DWt}3xTp4*t5|9?$DfG?;LS1g)3hv)XdlmzPEl2 z8QW{$U}3$Xv7v<5o+aRZHm6he7=!N>ETi8$IcL3MH)vHV`+I&g#Cml1(Qd>i`092zyuBD(? zOu1fro2cQdU1SZ2%#6sw%wL4g@4nyf+RBiZS-WC#)R3Zy8qwG^e3pjOX|Wo5KiIni z)r4Uv3ZQBA|36sl-b#xhRO8!V>#92kkY^jys&D}j?m@#H;SOt9uc4W$adym#+OJzr0WCHw!T=&K*#_F(^MvRfT8?blkM z=l_+)ZQC`I7w%n3m)~A`wq3BpTk9{*%k8FVie0SNx?CzV7WjhQY4uPSZ5cv+w)k zI4%|o?B^8|u?=iS*L5(y7}fVZSP+E!4i!bg0rNbkC<-&629xkS55S!0256cliXziA z!RhUKHw|EukQf#cMKQ~=3%hoqQV9?RV3^v6@I8D3@d2b20l`2(#m4ULPV8>iZfQXb z8U#TQ1bhGkB=%zmmWCCS@?JpZ&Yd_h=Rao#CnqPbuC6{lJ{XM|3H<#0d~$Mfcz9^{ zFfkZ5>^MC=P576Wm!+kp%gf8Rx3}MaKVdHMIE6K?udnSw?AzO0>dep2pP!#I#s95_FtYRG9tgWq8RaIfo>FKG?{{H^s<6~q2CKC$_ z3-JhahK7bjm+($XO6u(FlqxiYAL4v@P=(bXGAAbo0`l|ov8=DJPYi2xb#*0SiOt_VzZw-QV9|TwIXQ`1JI2WQR!jOG`@&`R_a69zMCbxm#OXudlBR zNH1Wmsj0zhzPP!$A$fUux${HFj*bo{HHB@3B`#sWGmWM3|m^C$@48yg$!yu7^3 zQ^Ui<@<(t-dwaWK_Tpj-YB;4v+D=0+8h^ zI!sMXm6er=J>gVbTpY^t-rio}7b;nB1jJBA=|>!MwZlg=hGC*hJcn@d_seA_Dl%$F zNQygRD;SlxKqd-S(<|qh(ze@Xl8zVljJx)XdBbfw3$lB_))%Sf7!RAv4*R zrpFE!#<5Y->{&L0ag?dRa<7 zOGrq7S5hr3ERfkxQW}CozaA&bFgoJ(-Q6AglR@o2Iyx#n$Hc_oKIlujN^;i2eS;-+ zIug~~a8t29pRTX3hm$DXhFLK~~as#@N0a0yciCE~boVZLEr8iOCRA_;!g1@x16ym*L0F9EViTB5NBsUNt|>H zz6dt}`3zpIrbsuEf)Wycd9l%nfZqZ4u%N+;1DOVwi9r{gL}gNRb__IVq)2C8Du?GR zoxajenQxe{Uebbj{pA#5E5@Z;WS2_W-yw83d0E2%H!bPVEC%6d9>IFsv55tZ2@g2_ zMn^|GCqEJHkxvBfViGCBSLhK5Xd>zqVrp9fDS$;9d;m}=f)Gb(tWXLs*Uin%;!qnR zy$=AE@RlLIwPJz{;z5|A*c%HLdsDJCz){B)J`{1`YNB|D1K>u4KkVHB3fnLYh2i_( zXuuA)4}J(^UcFLil6Ddh6vuI7w|-XSXNR@?biSU>&v?$J7x@A&MKI)qCKT@|o+5KD zaKU$t13h1>mk^NW=E!?L$c+WT#vYgGQWVSi^;;Y>7H&E6H(b@Q>PRSrZ(Cv|^q}MP ztzj9D&Ws*fjfAZ#C!5uX!t%o3OqJs2X#UnE_m;m2hFVy9)z=g z^cQ}nk&yxS9RrV~uh@~k9?wVi~3BKOCa*O!I`!8ZYS;cQ`aQhBB>c|+Z%|caRo6}es*S0f6*3Ni18l3TtI7rxg*h*R$%@G=^mplf5ni`8nhNz_~ z2u58(=0Q-wfRtF_S9$I|TAQOtxeK!hfeP=)DlN^9YjheUS|pOqBFWG9l$|^msZ2JpckxbSPDB?2)?a3V84cCv&?whc!6#&Gw4@Ab=UX?V|p(u*Md77M{-AV zL{T^1Sli56)lrKpVSQv|z#SConNUU-Sk+cA{z&YnuvQg}M&r4U47gt=I%gA)d~*=5 zZ*$v;bT|S~bkvsEI290(E*qZ_^w0q)Mc+OXC>iOYIpZJ_0@m4LlQI^vk$Nwha&XN_!2j52q-0y`o zk5-H9R}7K!&0Y;&YjN8(V&pqKcN8Eqy@E~+rDXkqN*rV#8F0T0C11Yxe4C%F(Pn3b z3vFJ9$t3w8aA&QZd#L9U+%bP}d-(4#Jubf#ux_5ilrMgyqii;GG(98d zdEh=WGGAiSClja7OCLX?Bxf#h0*GY8yk=Y9^l(g1BIcjWc|WW|OhPO{l`#!qLfGsy zRu5;EE?pwG7bbFhKLy<7SE(l3*>CjXo&#|ZA00?#dF~Y1uxL!$p9JnBBeUhNzK0Ty z5(8_X3}&7#s-r?ic!U*$bO>}La=T=UC@BNdq!iuNoGLs*ebbY5;NHRCO@+)KL?2`` zJ3TkrjC8_0Ic){5QaF*!#@7TuY8t;#HQ7uDrssfrmek;u6nJiYc3(}h6FpZ~doqb4 z+Xs2>tr08Q-l|&MDtd{fklcv#hSiag@!X+|RVN~(j!*{HSY?APZcU0nD&Ph;FjQz2 z6asoj-Wdf3xhsw~BDt;$zmx{Bz}CALF+pmO0lt~dU@5^OU${kBh9!uvIshG>LVRn2 zc$5qlH#ok`$<2f~mHbwlJw>CDh9Ab~)oM@2pr6ggE%tx##$g*dbAn-HWWXJ`02;m| z1wL{fTP+C|+kpUF!bG5x!yX>VBSS$3DKMQc3~;5F=S>8O3T&A^f1C|q(Tf7hjWl3U z3gf+Jh%zxxb$~lCl|eR_n5r%l+r0Oe-OB9#$Mp)t0>K= zUwmw2u5)leJQF(C5AM81Gk-GwUS2CRWwoEavDWd1Ja-5#GA8h1%36q~83owgo^HZl zVr7mpJBsf~_3yO>7S9ljMnSkL*N-edZSy=x$b2dHL83 zV0ZT1Iq9Y`+QS{qRD6cwRFn+X(_^L(%%qjz}*;sN$y}1^`KPsCjX3 z44R;U<^HUoh*K@#YR?T(QGjKoX3aSy5mj_1o?GcUO6pVJ-GE4Uw0O;;2kE?Xq6m{$@Uu!6EgBp#Oji&Sn z_tDv!m{Z1u%MNrLK zfjdjIgP}-dNsX*-)A+3#Q@ff)>uI;bP%SZ2-^Mfbb$ih&zk<8y4a07fs5GbQ?$rC1 zzooleZHV_{N#~S z;Xi)-fd2e$BXqA*9x4x5mu?Iw+U7yZk;nj7VK)yzilJ9)Gq^1x+*`yfB9NoRyCeI^ zfcwZ*FC58!ugyK-=WbL;&N$E4t4#akcxUR}h?^WmGGCbD6ud%ks9M}lVqf2Nms`Mh z`>FA!p*Cq1u|&fL2zCjw6F0(Wg9Olr!Ub@8-Hb|4m*`j&jw82vWV9nFN;?eDE!!~Bjtm%OJ$d`NE=Wjo-=LO!szJcaC)UC%y zr~9vf?H978?ANJno|yf69^`=jc{1QW$d0`bL4p(K&An+!$J_S6gD@lV&?$qf2+y&U z6)sl{9XX(XsEQ*4?%%mhu`sC6s&Hxy3X^Gqsy7Gsc3&}TCpK-SPN3OQgjck>P_MeE z1-;0%IIjq`i9UK`z{tqRH-r0tJ7n*Z7b&okfWmu%`@zh?(1>-{?#hrIaI@SrquD>> z6MPp(HUPBH$s8lzNK8SZkYDWGfo3E@6h`6qf1n^R5FrpDFA#t{LcsKXTn4+lZ5P|B zC+8q)s%ru`Q>y>EHzJbzJu`P(=41w=&SmeI++N)I`N5P$l-wY6il4?K)5>GA83xXp z?AEDYo=>*KN*}j~NbYgQm#b5ue&%7|ii8AcMFcOe-uRW&nkkT>|GCs;dS~CR~&A7^>5WKJWRgkxtrkb!`s772;B3_=- zO3UOaw}?2BA271kbgHh zUG}ZC-lQ4-M+1H_`9n|kBO3o% zs?a#DxiwrJjLmpDlXI*;gNRs>>yePVr#@~Gu@uQYxeK!kG8%|NO0N^W0J}J&0hJ3%3aY=pzRog@ zJFN6eATcR7=_@WM`8`mzyLV1>2`XlcO6p z7nm`iexkQ+ckfAU_vPds5y?HAz!0=#I;T&%5e80O+)AbL5xTL`0#0M*D>n7U^K^@d zqe<>jiQtGx?&aLE)2ZV(Pa|Skl6z*yw=;D_B=-(jPV*ZO5y?HXdrc}8quis{r{0&E z+_}6O5pfQ=CwFmmQAk&lC|>IE^Yc^8QQ%!5^6l--BR89*VwCokr4fZRuz2$er*1RZ#ZR}5sX*YY zM*bZZxUK5x^YgRIP3_zx;skO}@pB6a`z@^<&hYyw->F7KaxV~xnb~_35pfQ=XZDDQ zdzE`!|G*XzaW1*nAY1%V+I@?NxEr~bmihSjkY^`%C49wW6#iBIS8_&vhV+HpP0B}} ztPyrZB=>git}Htl=H?h?|g6Swf_Id!fiQE=$13Y z8JjwIpGRv#d{u~i%g#sUzc?h)OAmJvk)2mr*Uh576RA}_=CPYsb=7j?`vG_KXb%GN zx-OBIJH4x=fF~!E$C>Y`qCz_Ow>kLJ5oda2o!OC_7XKy1DFQY@vZ}@wZq3o56^dcnp1X0hC^<`# z<7WjjASNP1O)eSa1ba>Ou)y}^B|VAY zP9nHpd+hg-Ekr4xmXsANdYnxQ_K_J3Ja%qJ$7a~|m>48)pUEIT9KyUzZ#;h=m`6t7 zB>B8xi(#^-`@rax8!t%C^w63dTBlZc;Y3p-Yhq~O2)$uha%M)>i4`tM?u8w#D=s<* zEO0=;VUU34VD5(Ettsw-5ljuO1<{!tn0=qE$Sy7p{AA#>HQ7D2BUmn-_{Xk(pa-~) zD}N3x#6(^cjCAM}vw}S@IXkMia#I_s!mUl!L+~BlUlnXt)^md0^B6ppD3!wWyN>3AzGsd}2iaE};Ky z*ZA;KMGfn!_g&Zcxo=u5N6+}aX8`f22N(M{++R`LZ@N0hZNUBOD@}16pKNRXWZ!H+ALS+YJP(QV zQo@}?a0iqz0uER-T3#Op+zaCV~os2RRf?p%P`VzDlSmij)1ZKK=Ylnz_5%l z8PLacEQTqZL2Wz9(3dzud;0s`)s+0hIz)PvDz zA-ID7(Pl2~2%(EZvX%Q07*qoM6N<$f`w)5F8}}l diff --git a/themes/classic/preview.webp b/themes/classic/preview.webp deleted file mode 100644 index 3e9758ff2694ed2f56183d85a551befbe50c3fe0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31008 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 diff --git a/themes/classic/templates/_partials/breadcrumb.tpl b/themes/classic/templates/_partials/breadcrumb.tpl deleted file mode 100644 index c3431e46..00000000 --- a/themes/classic/templates/_partials/breadcrumb.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/templates/_partials/footer.tpl b/themes/classic/templates/_partials/footer.tpl deleted file mode 100644 index 7508b286..00000000 --- a/themes/classic/templates/_partials/footer.tpl +++ /dev/null @@ -1,56 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {block name='hook_footer_before'} - {hook h='displayFooterBefore'} - {/block} -
    -
    - diff --git a/themes/classic/templates/_partials/form-errors.tpl b/themes/classic/templates/_partials/form-errors.tpl deleted file mode 100644 index 73e39484..00000000 --- a/themes/classic/templates/_partials/form-errors.tpl +++ /dev/null @@ -1,35 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $errors|count} -
    - {block name='form_errors'} -
      - {foreach $errors as $error} -
    • {$error|nl2br nofilter}
    • - {/foreach} -
    - {/block} -
    -{/if} diff --git a/themes/classic/templates/_partials/form-fields.tpl b/themes/classic/templates/_partials/form-fields.tpl deleted file mode 100644 index 32ffe5a0..00000000 --- a/themes/classic/templates/_partials/form-fields.tpl +++ /dev/null @@ -1,195 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $field.type == 'hidden'} - - {block name='form_field_item_hidden'} - - {/block} - -{else} - -
    - -
    - - {if $field.type === 'select'} - - {block name='form_field_item_select'} - - {/block} - - {elseif $field.type === 'countrySelect'} - - {block name='form_field_item_country'} - - {/block} - - {elseif $field.type === 'radio-buttons'} - - {block name='form_field_item_radio'} - {foreach from=$field.availableValues item="label" key="value"} - - {/foreach} - {/block} - - {elseif $field.type === 'checkbox'} - - {block name='form_field_item_checkbox'} - - - - {/block} - - {elseif $field.type === 'date'} - - {block name='form_field_item_date'} - - {if isset($field.availableValues.comment)} - - {$field.availableValues.comment} - - {/if} - {/block} - - {elseif $field.type === 'birthday'} - - {block name='form_field_item_birthday'} -
    - {html_select_date - field_order=DMY - time={$field.value} - field_array={$field.name} - prefix=false - reverse_years=true - field_separator='
    ' - day_extra='class="form-control form-control-select"' - month_extra='class="form-control form-control-select"' - year_extra='class="form-control form-control-select"' - day_empty={l s='-- day --' d='Shop.Forms.Labels'} - month_empty={l s='-- month --' d='Shop.Forms.Labels'} - year_empty={l s='-- year --' d='Shop.Forms.Labels'} - start_year={'Y'|date}-100 end_year={'Y'|date} - } -
    - {/block} - - {elseif $field.type === 'password'} - - {block name='form_field_item_password'} -
    - - - - -
    - {/block} - - {else} - - {block name='form_field_item_other'} - - {if isset($field.availableValues.comment)} - - {$field.availableValues.comment} - - {/if} - {/block} - - {/if} - - {block name='form_field_errors'} - {include file='_partials/form-errors.tpl' errors=$field.errors} - {/block} - -
    - -
    - {block name='form_field_comment'} - {if (!$field.required && !in_array($field.type, ['radio-buttons', 'checkbox']))} - {l s='Optional' d='Shop.Forms.Labels'} - {/if} - {/block} -
    -
    - -{/if} diff --git a/themes/classic/templates/_partials/head.tpl b/themes/classic/templates/_partials/head.tpl deleted file mode 100644 index ceb262a4..00000000 --- a/themes/classic/templates/_partials/head.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='head_charset'} - -{/block} -{block name='head_ie_compatibility'} - -{/block} - -{block name='head_seo'} - {block name='head_seo_title'}{$page.meta.title}{/block} - - - {if $page.meta.robots !== 'index'} - - {/if} - {if $page.canonical} - - {/if} - {block name='head_hreflang'} - {foreach from=$urls.alternative_langs item=pageUrl key=code} - - {/foreach} - {/block} -{/block} - -{block name='head_viewport'} - -{/block} - -{block name='head_icons'} - - -{/block} - -{block name='stylesheets'} - {include file="_partials/stylesheets.tpl" stylesheets=$stylesheets} -{/block} - -{block name='javascript_head'} - {include file="_partials/javascript.tpl" javascript=$javascript.head vars=$js_custom_vars} -{/block} - -{block name='hook_header'} - {$HOOK_HEADER nofilter} -{/block} - -{block name='hook_extra'}{/block} diff --git a/themes/classic/templates/_partials/header.tpl b/themes/classic/templates/_partials/header.tpl deleted file mode 100644 index 8f41c9b7..00000000 --- a/themes/classic/templates/_partials/header.tpl +++ /dev/null @@ -1,90 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='header_banner'} -
    - {hook h='displayBanner'} -
    -{/block} - -{block name='header_nav'} - -{/block} - -{block name='header_top'} -
    -
    -
    - -
    - {hook h='displayTop'} -
    -
    -
    - -
    -
    - {hook h='displayNavFullWidth'} -{/block} diff --git a/themes/classic/templates/_partials/javascript.tpl b/themes/classic/templates/_partials/javascript.tpl deleted file mode 100644 index 49c65619..00000000 --- a/themes/classic/templates/_partials/javascript.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{foreach $javascript.external as $js} - -{/foreach} - -{foreach $javascript.inline as $js} - -{/foreach} - -{if isset($vars) && $vars|@count} - -{/if} diff --git a/themes/classic/templates/_partials/notifications.tpl b/themes/classic/templates/_partials/notifications.tpl deleted file mode 100644 index 10392bf9..00000000 --- a/themes/classic/templates/_partials/notifications.tpl +++ /dev/null @@ -1,78 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -{if isset($notifications)} - -{/if} diff --git a/themes/classic/templates/_partials/pagination.tpl b/themes/classic/templates/_partials/pagination.tpl deleted file mode 100644 index 717115e1..00000000 --- a/themes/classic/templates/_partials/pagination.tpl +++ /dev/null @@ -1,64 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/templates/_partials/stylesheets.tpl b/themes/classic/templates/_partials/stylesheets.tpl deleted file mode 100644 index 5886bc76..00000000 --- a/themes/classic/templates/_partials/stylesheets.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{foreach $stylesheets.external as $stylesheet} - -{/foreach} - -{foreach $stylesheets.inline as $stylesheet} - -{/foreach} diff --git a/themes/classic/templates/catalog/_partials/active_filters.tpl b/themes/classic/templates/catalog/_partials/active_filters.tpl deleted file mode 100644 index 40dd5536..00000000 --- a/themes/classic/templates/catalog/_partials/active_filters.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {block name='active_filters_title'} -

    {l s='Active filters' d='Shop.Theme.Global'}

    - {/block} - - {if $activeFilters|count} -
      - {foreach from=$activeFilters item="filter"} - {block name='active_filters_item'} -
    • - {l s='%1$s: ' d='Shop.Theme.Catalog' sprintf=[$filter.facetLabel]} - {$filter.label} - -
    • - {/block} - {/foreach} -
    - {/if} -
    diff --git a/themes/classic/templates/catalog/_partials/category-header.tpl b/themes/classic/templates/catalog/_partials/category-header.tpl deleted file mode 100644 index 554b82c4..00000000 --- a/themes/classic/templates/catalog/_partials/category-header.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {if $listing.pagination.items_shown_from == 1} -
    -

    {$category.name}

    -
    - {if $category.description} -
    {$category.description nofilter}
    - {/if} - {if $category.image.large.url} -
    - {if !empty($category.image.legend)}{$category.image.legend}{else}{$category.name}{/if} -
    - {/if} -
    -
    - {/if} -
    diff --git a/themes/classic/templates/catalog/_partials/facets.tpl b/themes/classic/templates/catalog/_partials/facets.tpl deleted file mode 100644 index 413047b6..00000000 --- a/themes/classic/templates/catalog/_partials/facets.tpl +++ /dev/null @@ -1,168 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $facets|count} -
    - {block name='facets_title'} -

    {l s='Filter By' d='Shop.Theme.Actions'}

    - {/block} - - {block name='facets_clearall_button'} - {if $activeFilters|count} -
    - -
    - {/if} - {/block} - - {foreach from=$facets item="facet"} - {if !$facet.displayed} - {continue} - {/if} - -
    -

    {$facet.label}

    - {assign var=_expand_id value=10|mt_rand:100000} - {assign var=_collapse value=true} - {foreach from=$facet.filters item="filter"} - {if $filter.active}{assign var=_collapse value=false}{/if} - {/foreach} - -
    -

    {$facet.label}

    - - - - - - -
    - - {if $facet.widgetType !== 'dropdown'} - {block name='facet_item_other'} -
      - {foreach from=$facet.filters key=filter_key item="filter"} - {if !$filter.displayed} - {continue} - {/if} - -
    • - -
    • - {/foreach} -
    - {/block} - - {else} - - {block name='facet_item_dropdown'} - - {/block} - {/if} -
    - {/foreach} -
    -{/if} diff --git a/themes/classic/templates/catalog/_partials/miniatures/brand.tpl b/themes/classic/templates/catalog/_partials/miniatures/brand.tpl deleted file mode 100644 index ff272fda..00000000 --- a/themes/classic/templates/catalog/_partials/miniatures/brand.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='brand_miniature_item'} -
  • -
    {$brand.name}
    -
    -

    {$brand.name}

    - {$brand.text nofilter} -
    - -
  • -{/block} diff --git a/themes/classic/templates/catalog/_partials/miniatures/category.tpl b/themes/classic/templates/catalog/_partials/miniatures/category.tpl deleted file mode 100644 index e925ad0e..00000000 --- a/themes/classic/templates/catalog/_partials/miniatures/category.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='category_miniature_item'} -
    - - {$category.image.legend} - - -

    - {$category.name} -

    - -
    {$category.description nofilter}
    -
    -{/block} diff --git a/themes/classic/templates/catalog/_partials/miniatures/pack-product.tpl b/themes/classic/templates/catalog/_partials/miniatures/pack-product.tpl deleted file mode 100644 index 854c47e7..00000000 --- a/themes/classic/templates/catalog/_partials/miniatures/pack-product.tpl +++ /dev/null @@ -1,54 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='pack_miniature_item'} - -{/block} diff --git a/themes/classic/templates/catalog/_partials/miniatures/product.tpl b/themes/classic/templates/catalog/_partials/miniatures/product.tpl deleted file mode 100644 index d1428d5a..00000000 --- a/themes/classic/templates/catalog/_partials/miniatures/product.tpl +++ /dev/null @@ -1,109 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='product_miniature_item'} -
    -
    - {block name='product_thumbnail'} - {if $product.cover} - - {if !empty($product.cover.legend)}{$product.cover.legend}{else}{$product.name}{/if} - - {else} - - - - {/if} - {/block} - -
    - {block name='product_name'} - {if $page.page_name == 'index'} -

    {$product.name}

    - {else} -

    {$product.name}

    - {/if} - {/block} - - {block name='product_price_and_shipping'} - {if $product.show_price} -
    - {if $product.has_discount} - {hook h='displayProductPriceBlock' product=$product type="old_price"} - - {l s='Regular price' d='Shop.Theme.Catalog'} - {$product.regular_price} - {if $product.discount_type === 'percentage'} - {$product.discount_percentage} - {elseif $product.discount_type === 'amount'} - {$product.discount_amount_to_display} - {/if} - {/if} - - {hook h='displayProductPriceBlock' product=$product type="before_price"} - - {l s='Price' d='Shop.Theme.Catalog'} - {$product.price} - - {hook h='displayProductPriceBlock' product=$product type='unit_price'} - - {hook h='displayProductPriceBlock' product=$product type='weight'} -
    - {/if} - {/block} - - {block name='product_reviews'} - {hook h='displayProductListReviews' product=$product} - {/block} -
    - - - {block name='product_flags'} -
      - {foreach from=$product.flags item=flag} -
    • {$flag.label}
    • - {/foreach} -
    - {/block} - -
    - {block name='quick_view'} - - {l s='Quick view' d='Shop.Theme.Actions'} - - {/block} - - {block name='product_variants'} - {if $product.main_variants} - {include file='catalog/_partials/variant-links.tpl' variants=$product.main_variants} - {/if} - {/block} -
    -
    -
    -{/block} diff --git a/themes/classic/templates/catalog/_partials/product-activation.tpl b/themes/classic/templates/catalog/_partials/product-activation.tpl deleted file mode 100644 index 0732958c..00000000 --- a/themes/classic/templates/catalog/_partials/product-activation.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $page.admin_notifications} - -{/if} diff --git a/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl b/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl deleted file mode 100644 index 279e7003..00000000 --- a/themes/classic/templates/catalog/_partials/product-add-to-cart.tpl +++ /dev/null @@ -1,88 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {if !$configuration.is_catalog} - {l s='Quantity' d='Shop.Theme.Catalog'} - - {block name='product_quantity'} -
    -
    - -
    - -
    - -
    - - {hook h='displayProductActions' product=$product} -
    - {/block} - - {block name='product_availability'} - - {if $product.show_availability && $product.availability_message} - {if $product.availability == 'available'} - - {elseif $product.availability == 'last_remaining_items'} - - {else} - - {/if} - {$product.availability_message} - {/if} - - {/block} - - {block name='product_minimal_quantity'} -

    - {if $product.minimal_quantity > 1} - {l - s='The minimum purchase order quantity for the product is %quantity%.' - d='Shop.Theme.Checkout' - sprintf=['%quantity%' => $product.minimal_quantity] - } - {/if} -

    - {/block} - {/if} -
    diff --git a/themes/classic/templates/catalog/_partials/product-additional-info.tpl b/themes/classic/templates/catalog/_partials/product-additional-info.tpl deleted file mode 100644 index f4fd6b5d..00000000 --- a/themes/classic/templates/catalog/_partials/product-additional-info.tpl +++ /dev/null @@ -1,27 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {hook h='displayProductAdditionalInfo' product=$product} -
    diff --git a/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl b/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl deleted file mode 100644 index b6553cd3..00000000 --- a/themes/classic/templates/catalog/_partials/product-cover-thumbnails.tpl +++ /dev/null @@ -1,60 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {block name='product_cover'} -
    - {if $product.cover} - {$product.cover.legend} -
    - -
    - {else} - - {/if} -
    - {/block} - - {block name='product_images'} -
    -
      - {foreach from=$product.images item=image} -
    • - {$image.legend} -
    • - {/foreach} -
    -
    - {/block} -
    -{hook h='displayAfterProductThumbs'} diff --git a/themes/classic/templates/catalog/_partials/product-customization.tpl b/themes/classic/templates/catalog/_partials/product-customization.tpl deleted file mode 100644 index efda2b5f..00000000 --- a/themes/classic/templates/catalog/_partials/product-customization.tpl +++ /dev/null @@ -1,69 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {if !$configuration.is_catalog} -
    -

    {l s='Product customization' d='Shop.Theme.Catalog'}

    - {l s='Don\'t forget to save your customization to be able to add to cart' d='Shop.Forms.Help'} - - {block name='product_customization_form'} -
    -
      - {foreach from=$customizations.fields item="field"} -
    • - - {if $field.type == 'text'} - - {l s='250 char. max' d='Shop.Forms.Help'} - {if $field.text !== ''} -
      {l s='Your customization:' d='Shop.Theme.Catalog'} - -
      - {/if} - {elseif $field.type == 'image'} - {if $field.is_customized} -
      - - {l s='Remove Image' d='Shop.Theme.Actions'} - {/if} - - {l s='No selected file' d='Shop.Forms.Help'} - - - - {l s='.png .jpg .gif' d='Shop.Forms.Help'} - {/if} -
    • - {/foreach} -
    -
    - -
    -
    - {/block} - -
    - {/if} -
    diff --git a/themes/classic/templates/catalog/_partials/product-details.tpl b/themes/classic/templates/catalog/_partials/product-details.tpl deleted file mode 100644 index 0e5b62dd..00000000 --- a/themes/classic/templates/catalog/_partials/product-details.tpl +++ /dev/null @@ -1,91 +0,0 @@ -
    - {block name='product_reference'} - {if isset($product_manufacturer->id)} -
    - {if isset($manufacturer_image_url)} - - - - {else} - - - {$product_manufacturer->name} - - {/if} -
    - {/if} - {if isset($product.reference_to_display) && $product.reference_to_display neq ''} -
    - - {$product.reference_to_display} -
    - {/if} - {/block} - - {block name='product_quantities'} - {if $product.show_quantities} -
    - - {$product.quantity} {$product.quantity_label} -
    - {/if} - {/block} - - {block name='product_availability_date'} - {if $product.availability_date} -
    - - {$product.availability_date} -
    - {/if} - {/block} - - {block name='product_out_of_stock'} -
    - {hook h='actionProductOutOfStock' product=$product} -
    - {/block} - - {block name='product_features'} - {if $product.grouped_features} -
    -

    {l s='Data sheet' d='Shop.Theme.Catalog'}

    -
    - {foreach from=$product.grouped_features item=feature} -
    {$feature.name}
    -
    {$feature.value|escape:'htmlall'|nl2br nofilter}
    - {/foreach} -
    -
    - {/if} - {/block} - - {* if product have specific references, a table will be added to product details section *} - {block name='product_specific_references'} - {if !empty($product.specific_references)} -
    -

    {l s='Specific References' d='Shop.Theme.Catalog'}

    -
    - {foreach from=$product.specific_references item=reference key=key} -
    {$key}
    -
    {$reference}
    - {/foreach} -
    -
    - {/if} - {/block} - - {block name='product_condition'} - {if $product.condition} -
    - - - {$product.condition.label} -
    - {/if} - {/block} -
    diff --git a/themes/classic/templates/catalog/_partials/product-discounts.tpl b/themes/classic/templates/catalog/_partials/product-discounts.tpl deleted file mode 100644 index 4e5153e1..00000000 --- a/themes/classic/templates/catalog/_partials/product-discounts.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {if $product.quantity_discounts} -

    {l s='Volume discounts' d='Shop.Theme.Catalog'}

    - {block name='product_discount_table'} - - - - - - - - - - {foreach from=$product.quantity_discounts item='quantity_discount' name='quantity_discounts'} - - - - - - {/foreach} - -
    {l s='Quantity' d='Shop.Theme.Catalog'}{$configuration.quantity_discount.label}{l s='You Save' d='Shop.Theme.Catalog'}
    {$quantity_discount.quantity}{$quantity_discount.discount}{l s='Up to %discount%' d='Shop.Theme.Catalog' sprintf=['%discount%' => $quantity_discount.save]}
    - {/block} - {/if} -
    diff --git a/themes/classic/templates/catalog/_partials/product-flags.tpl b/themes/classic/templates/catalog/_partials/product-flags.tpl deleted file mode 100644 index 2f5b14cb..00000000 --- a/themes/classic/templates/catalog/_partials/product-flags.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='product_flags'} -
      - {foreach from=$product.flags item=flag} -
    • {$flag.label}
    • - {/foreach} -
    -{/block} diff --git a/themes/classic/templates/catalog/_partials/product-images-modal.tpl b/themes/classic/templates/catalog/_partials/product-images-modal.tpl deleted file mode 100644 index 2500cc79..00000000 --- a/themes/classic/templates/catalog/_partials/product-images-modal.tpl +++ /dev/null @@ -1,60 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/templates/catalog/_partials/product-prices.tpl b/themes/classic/templates/catalog/_partials/product-prices.tpl deleted file mode 100644 index 7b6c0b50..00000000 --- a/themes/classic/templates/catalog/_partials/product-prices.tpl +++ /dev/null @@ -1,114 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $product.show_price} -
    - {block name='product_discount'} - {if $product.has_discount} -
    - {hook h='displayProductPriceBlock' product=$product type="old_price"} - {$product.regular_price} -
    - {/if} - {/block} - - {block name='product_price'} -
    - - - -
    - {$product.price} - - {if $product.has_discount} - {if $product.discount_type === 'percentage'} - {l s='Save %percentage%' d='Shop.Theme.Catalog' sprintf=['%percentage%' => $product.discount_percentage_absolute]} - {else} - - {l s='Save %amount%' d='Shop.Theme.Catalog' sprintf=['%amount%' => $product.discount_to_display]} - - {/if} - {/if} -
    - - {block name='product_unit_price'} - {if $displayUnitPrice} -

    {l s='(%unit_price%)' d='Shop.Theme.Catalog' sprintf=['%unit_price%' => $product.unit_price_full]}

    - {/if} - {/block} -
    - {/block} - - {block name='product_without_taxes'} - {if $priceDisplay == 2} -

    {l s='%price% tax excl.' d='Shop.Theme.Catalog' sprintf=['%price%' => $product.price_tax_exc]}

    - {/if} - {/block} - - {block name='product_pack_price'} - {if $displayPackPrice} -

    {l s='Instead of %price%' d='Shop.Theme.Catalog' sprintf=['%price%' => $noPackPrice]}

    - {/if} - {/block} - - {block name='product_ecotax'} - {if $product.ecotax.amount > 0} -

    {l s='Including %amount% for ecotax' d='Shop.Theme.Catalog' sprintf=['%amount%' => $product.ecotax.value]} - {if $product.has_discount} - {l s='(not impacted by the discount)' d='Shop.Theme.Catalog'} - {/if} -

    - {/if} - {/block} - - {hook h='displayProductPriceBlock' product=$product type="weight" hook_origin='product_sheet'} - -
    - {if !$configuration.taxes_enabled} - {l s='No tax' d='Shop.Theme.Catalog'} - {elseif $configuration.display_taxes_label} - {$product.labels.tax_long} - {/if} - {hook h='displayProductPriceBlock' product=$product type="price"} - {hook h='displayProductPriceBlock' product=$product type="after_price"} - {if $product.additional_delivery_times == 1} - {if $product.delivery_information} - {$product.delivery_information} - {/if} - {elseif $product.additional_delivery_times == 2} - {if $product.quantity > 0} - {$product.delivery_in_stock} - {* Out of stock message should not be displayed if customer can't order the product. *} - {elseif $product.quantity <= 0 && $product.add_to_cart_url} - {$product.delivery_out_stock} - {/if} - {/if} -
    -
    -{/if} diff --git a/themes/classic/templates/catalog/_partials/product-variants.tpl b/themes/classic/templates/catalog/_partials/product-variants.tpl deleted file mode 100644 index fd0bdada..00000000 --- a/themes/classic/templates/catalog/_partials/product-variants.tpl +++ /dev/null @@ -1,69 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {foreach from=$groups key=id_attribute_group item=group} - {if !empty($group.attributes)} -
    - {$group.name} - {if $group.group_type == 'select'} - - {elseif $group.group_type == 'color'} -
      - {foreach from=$group.attributes key=id_attribute item=group_attribute} -
    • - -
    • - {/foreach} -
    - {elseif $group.group_type == 'radio'} -
      - {foreach from=$group.attributes key=id_attribute item=group_attribute} -
    • - -
    • - {/foreach} -
    - {/if} -
    - {/if} - {/foreach} -
    diff --git a/themes/classic/templates/catalog/_partials/products-bottom.tpl b/themes/classic/templates/catalog/_partials/products-bottom.tpl deleted file mode 100644 index 9188f7f5..00000000 --- a/themes/classic/templates/catalog/_partials/products-bottom.tpl +++ /dev/null @@ -1,6 +0,0 @@ -{* - * Classic theme doesn't use this subtemplate, feel free to do whatever you need here. - * This template is generated at each ajax calls. - * See ProductListingFrontController::getAjaxProductSearchVariables() - *} -
    diff --git a/themes/classic/templates/catalog/_partials/products-top.tpl b/themes/classic/templates/catalog/_partials/products-top.tpl deleted file mode 100644 index 6ef70677..00000000 --- a/themes/classic/templates/catalog/_partials/products-top.tpl +++ /dev/null @@ -1,56 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {if $listing.pagination.total_items > 1} -

    {l s='There are %product_count% products.' d='Shop.Theme.Catalog' sprintf=['%product_count%' => $listing.pagination.total_items]}

    - {elseif $listing.pagination.total_items > 0} -

    {l s='There is 1 product.' d='Shop.Theme.Catalog'}

    - {/if} -
    -
    -
    - - {block name='sort_by'} - {include file='catalog/_partials/sort-orders.tpl' sort_orders=$listing.sort_orders} - {/block} - - {if !empty($listing.rendered_facets)} -
    - -
    - {/if} -
    -
    -
    - {l s='Showing %from%-%to% of %total% item(s)' d='Shop.Theme.Catalog' sprintf=[ - '%from%' => $listing.pagination.items_shown_from , - '%to%' => $listing.pagination.items_shown_to, - '%total%' => $listing.pagination.total_items - ]} -
    -
    diff --git a/themes/classic/templates/catalog/_partials/products.tpl b/themes/classic/templates/catalog/_partials/products.tpl deleted file mode 100644 index 6089cf71..00000000 --- a/themes/classic/templates/catalog/_partials/products.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {foreach from=$listing.products item="product"} - {block name='product_miniature'} - {include file='catalog/_partials/miniatures/product.tpl' product=$product} - {/block} - {/foreach} -
    - - {block name='pagination'} - {include file='_partials/pagination.tpl' pagination=$listing.pagination} - {/block} - - -
    diff --git a/themes/classic/templates/catalog/_partials/quickview.tpl b/themes/classic/templates/catalog/_partials/quickview.tpl deleted file mode 100644 index 43fbb8ef..00000000 --- a/themes/classic/templates/catalog/_partials/quickview.tpl +++ /dev/null @@ -1,79 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - diff --git a/themes/classic/templates/catalog/_partials/sort-orders.tpl b/themes/classic/templates/catalog/_partials/sort-orders.tpl deleted file mode 100644 index b9c40e87..00000000 --- a/themes/classic/templates/catalog/_partials/sort-orders.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{l s='Sort by:' d='Shop.Theme.Global'} - diff --git a/themes/classic/templates/catalog/_partials/variant-links.tpl b/themes/classic/templates/catalog/_partials/variant-links.tpl deleted file mode 100644 index 54f52638..00000000 --- a/themes/classic/templates/catalog/_partials/variant-links.tpl +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/themes/classic/templates/catalog/brands.tpl b/themes/classic/templates/catalog/brands.tpl deleted file mode 100644 index 62783347..00000000 --- a/themes/classic/templates/catalog/brands.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='content'} -
    - - {block name='brand_header'} -

    {l s='Brands' d='Shop.Theme.Catalog'}

    - {/block} - - {block name='brand_miniature'} -
      - {foreach from=$brands item=brand} - {include file='catalog/_partials/miniatures/brand.tpl' brand=$brand} - {/foreach} -
    - {/block} - -
    - -{/block} diff --git a/themes/classic/templates/catalog/listing/best-sales.tpl b/themes/classic/templates/catalog/listing/best-sales.tpl deleted file mode 100644 index 3b34af8f..00000000 --- a/themes/classic/templates/catalog/listing/best-sales.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{* - * This file allows you to customize your best-sales page. - * You can safely remove it if you want it to appear exactly like all other product listing pages - *} -{extends file='catalog/listing/product-list.tpl'} diff --git a/themes/classic/templates/catalog/listing/category.tpl b/themes/classic/templates/catalog/listing/category.tpl deleted file mode 100644 index 37eb25b9..00000000 --- a/themes/classic/templates/catalog/listing/category.tpl +++ /dev/null @@ -1,29 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='catalog/listing/product-list.tpl'} - -{block name='product_list_header'} - {include file='catalog/_partials/category-header.tpl' listing=$listing category=$category} -{/block} diff --git a/themes/classic/templates/catalog/listing/manufacturer.tpl b/themes/classic/templates/catalog/listing/manufacturer.tpl deleted file mode 100644 index acfa00c9..00000000 --- a/themes/classic/templates/catalog/listing/manufacturer.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='catalog/listing/product-list.tpl'} - -{block name='product_list_header'} -

    {l s='List of products by brand %brand_name%' sprintf=['%brand_name%' => $manufacturer.name] d='Shop.Theme.Catalog'}

    -
    {$manufacturer.short_description nofilter}
    -
    {$manufacturer.description nofilter}
    -{/block} diff --git a/themes/classic/templates/catalog/listing/new-products.tpl b/themes/classic/templates/catalog/listing/new-products.tpl deleted file mode 100644 index b42d05c5..00000000 --- a/themes/classic/templates/catalog/listing/new-products.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{* - * This file allows you to customize your new-product page. - * You can safely remove it if you want it to appear exactly like all other product listing pages - *} -{extends file='catalog/listing/product-list.tpl'} diff --git a/themes/classic/templates/catalog/listing/prices-drop.tpl b/themes/classic/templates/catalog/listing/prices-drop.tpl deleted file mode 100644 index 21639402..00000000 --- a/themes/classic/templates/catalog/listing/prices-drop.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{* - * This file allows you to customize your price-drop page. - * You can safely remove it if you want it to appear exactly like all other product listing pages - *} -{extends file='catalog/listing/product-list.tpl'} diff --git a/themes/classic/templates/catalog/listing/product-list.tpl b/themes/classic/templates/catalog/listing/product-list.tpl deleted file mode 100644 index 4ebfbf6c..00000000 --- a/themes/classic/templates/catalog/listing/product-list.tpl +++ /dev/null @@ -1,73 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='content'} -
    - - {block name='product_list_header'} -

    {$listing.label}

    - {/block} - -
    - {if $listing.products|count} - -
    - {block name='product_list_top'} - {include file='catalog/_partials/products-top.tpl' listing=$listing} - {/block} -
    - - {block name='product_list_active_filters'} -
    - {$listing.rendered_active_filters nofilter} -
    - {/block} - -
    - {block name='product_list'} - {include file='catalog/_partials/products.tpl' listing=$listing} - {/block} -
    - -
    - {block name='product_list_bottom'} - {include file='catalog/_partials/products-bottom.tpl' listing=$listing} - {/block} -
    - - {else} -
    - -
    - {include file='errors/not-found.tpl'} -
    - -
    - {/if} -
    - -
    -{/block} diff --git a/themes/classic/templates/catalog/listing/search.tpl b/themes/classic/templates/catalog/listing/search.tpl deleted file mode 100644 index d745e42f..00000000 --- a/themes/classic/templates/catalog/listing/search.tpl +++ /dev/null @@ -1,5 +0,0 @@ -{* - * This file allows you to customize your search page. - * You can safely remove it if you want it to appear exactly like all other product listing pages - *} -{extends file='catalog/listing/product-list.tpl'} diff --git a/themes/classic/templates/catalog/listing/supplier.tpl b/themes/classic/templates/catalog/listing/supplier.tpl deleted file mode 100644 index ec63ada1..00000000 --- a/themes/classic/templates/catalog/listing/supplier.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='catalog/listing/product-list.tpl'} - -{block name='product_list_header'} -

    {l s='List of products by supplier %s' sprintf=[$supplier.name] d='Shop.Theme.Catalog'}

    -
    {$supplier.description nofilter}
    -{/block} diff --git a/themes/classic/templates/catalog/manufacturers.tpl b/themes/classic/templates/catalog/manufacturers.tpl deleted file mode 100644 index c85bab0e..00000000 --- a/themes/classic/templates/catalog/manufacturers.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='catalog/brands.tpl'} diff --git a/themes/classic/templates/catalog/product.tpl b/themes/classic/templates/catalog/product.tpl deleted file mode 100644 index e3eb87a0..00000000 --- a/themes/classic/templates/catalog/product.tpl +++ /dev/null @@ -1,268 +0,0 @@ -{** - * 2007-2020 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2020 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='head_seo' prepend} - -{/block} - -{block name='head' append} - - - - - - - {if $product.show_price} - - - - - {/if} - {if isset($product.weight) && ($product.weight != 0)} - - - {/if} -{/block} - -{block name='content'} - -
    - - -
    -
    - {block name='page_content_container'} -
    - {block name='page_content'} - - {block name='product_flags'} -
      - {foreach from=$product.flags item=flag} -
    • {$flag.label}
    • - {/foreach} -
    - {/block} - - {block name='product_cover_thumbnails'} - {include file='catalog/_partials/product-cover-thumbnails.tpl'} - {/block} -
    - - -
    - - {/block} -
    - {/block} -
    -
    - {block name='page_header_container'} - {block name='page_header'} -

    {block name='page_title'}{$product.name}{/block}

    - {/block} - {/block} - {block name='product_prices'} - {include file='catalog/_partials/product-prices.tpl'} - {/block} - -
    - {block name='product_description_short'} -
    {$product.description_short nofilter}
    - {/block} - - {if $product.is_customizable && count($product.customizations.fields)} - {block name='product_customization'} - {include file="catalog/_partials/product-customization.tpl" customizations=$product.customizations} - {/block} - {/if} - -
    - {block name='product_buy'} -
    - - - - - {block name='product_variants'} - {include file='catalog/_partials/product-variants.tpl'} - {/block} - - {block name='product_pack'} - {if $packItems} -
    -

    {l s='This pack contains' d='Shop.Theme.Catalog'}

    - {foreach from=$packItems item="product_pack"} - {block name='product_miniature'} - {include file='catalog/_partials/miniatures/pack-product.tpl' product=$product_pack} - {/block} - {/foreach} -
    - {/if} - {/block} - - {block name='product_discounts'} - {include file='catalog/_partials/product-discounts.tpl'} - {/block} - - {block name='product_add_to_cart'} - {include file='catalog/_partials/product-add-to-cart.tpl'} - {/block} - - {block name='product_additional_info'} - {include file='catalog/_partials/product-additional-info.tpl'} - {/block} - - {* Input to refresh product HTML removed, block kept for compatibility with themes *} - {block name='product_refresh'}{/block} -
    - {/block} - -
    - - {block name='hook_display_reassurance'} - {hook h='displayReassurance'} - {/block} - - {block name='product_tabs'} -
    - - -
    -
    - {block name='product_description'} -
    {$product.description nofilter}
    - {/block} -
    - - {block name='product_details'} - {include file='catalog/_partials/product-details.tpl'} - {/block} - - {block name='product_attachments'} - {if $product.attachments} -
    -
    -

    {l s='Download' d='Shop.Theme.Actions'}

    - {foreach from=$product.attachments item=attachment} -
    -

    {$attachment.name}

    -

    {$attachment.description}

    - {l s='Download' d='Shop.Theme.Actions'} ({$attachment.file_size_formatted}) - -
    - {/foreach} -
    -
    - {/if} - {/block} - - {foreach from=$product.extraContent item=extra key=extraKey} -
    $val} {$key}="{$val}"{/foreach}> - {$extra.content nofilter} -
    - {/foreach} -
    -
    - {/block} -
    -
    -
    - - {block name='product_accessories'} - {if $accessories} -
    -

    {l s='You might also like' d='Shop.Theme.Catalog'}

    -
    - {foreach from=$accessories item="product_accessory"} - {block name='product_miniature'} - {include file='catalog/_partials/miniatures/product.tpl' product=$product_accessory} - {/block} - {/foreach} -
    -
    - {/if} - {/block} - - {block name='product_footer'} - {hook h='displayFooterProduct' product=$product category=$category} - {/block} - - {block name='product_images_modal'} - {include file='catalog/_partials/product-images-modal.tpl'} - {/block} - - {block name='page_footer_container'} -
    - {block name='page_footer'} - - {/block} -
    - {/block} -
    - -{/block} diff --git a/themes/classic/templates/catalog/suppliers.tpl b/themes/classic/templates/catalog/suppliers.tpl deleted file mode 100644 index 84992fcd..00000000 --- a/themes/classic/templates/catalog/suppliers.tpl +++ /dev/null @@ -1,29 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='catalog/brands.tpl'} - -{block name='brand_header'} -

    {l s='Suppliers' d='Shop.Theme.Catalog'}

    -{/block} diff --git a/themes/classic/templates/checkout/_partials/address-form.tpl b/themes/classic/templates/checkout/_partials/address-form.tpl deleted file mode 100644 index 435d5f45..00000000 --- a/themes/classic/templates/checkout/_partials/address-form.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{extends file='customer/_partials/address-form.tpl'} - -{block name='form_field'} - {if $field.name eq "alias"} - {* we don't ask for alias here *} - {else} - {$smarty.block.parent} - {/if} -{/block} - -{block name="address_form_url"} -
    -{/block} - -{block name='form_fields' append} - - {if $type === "delivery"} -
    -
    - - -
    -
    - {/if} -{/block} - -{block name='form_buttons'} - {if !$form_has_continue_button} - - {l s='Cancel' d='Shop.Theme.Actions'} - {else} - - - {if $customer.addresses|count > 0} - {l s='Cancel' d='Shop.Theme.Actions'} - {/if} -
    - {/if} -{/block} diff --git a/themes/classic/templates/checkout/_partials/address-selector-block.tpl b/themes/classic/templates/checkout/_partials/address-selector-block.tpl deleted file mode 100644 index d46347e6..00000000 --- a/themes/classic/templates/checkout/_partials/address-selector-block.tpl +++ /dev/null @@ -1,72 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='address_selector_blocks'} - {foreach $addresses as $address} - - {/foreach} - {if $interactive} -

    - -

    - {/if} -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl b/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl deleted file mode 100644 index 130410ce..00000000 --- a/themes/classic/templates/checkout/_partials/cart-detailed-actions.tpl +++ /dev/null @@ -1,45 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='cart_detailed_actions'} -
    - {if $cart.minimalPurchaseRequired} - -
    - -
    - {elseif empty($cart.products) } -
    - -
    - {else} -
    - {l s='Proceed to checkout' d='Shop.Theme.Actions'} - {hook h='displayExpressCheckout'} -
    - {/if} -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl b/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl deleted file mode 100644 index 2761364f..00000000 --- a/themes/classic/templates/checkout/_partials/cart-detailed-product-line.tpl +++ /dev/null @@ -1,175 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - -
    - - {$product.name|escape:'quotes'} - -
    - - -
    - - -
    - {if $product.has_discount} -
    - {$product.regular_price} - {if $product.discount_type === 'percentage'} - - -{$product.discount_percentage_absolute} - - {else} - - -{$product.discount_to_display} - - {/if} -
    - {/if} -
    - {$product.price} - {if $product.unit_price_full} -
    {$product.unit_price_full}
    - {/if} -
    -
    - -
    - - {foreach from=$product.attributes key="attribute" item="value"} -
    - {$attribute}: - {$value} -
    - {/foreach} - - {if is_array($product.customizations) && $product.customizations|count} -
    - {block name='cart_detailed_product_line_customization'} - {foreach from=$product.customizations item="customization"} - {l s='Product customization' d='Shop.Theme.Catalog'} - - {/foreach} - {/block} - {/if} -
    - - -
    -
    -
    -
    -
    -
    - {if isset($product.is_gift) && $product.is_gift} - {$product.quantity} - {else} - - {/if} -
    -
    - - - {if isset($product.is_gift) && $product.is_gift} - {l s='Gift' d='Shop.Theme.Checkout'} - {else} - {$product.total} - {/if} - - -
    -
    -
    -
    -
    - - {if !isset($product.is_gift) || !$product.is_gift} - delete - {/if} - - - {block name='hook_cart_extra_product_actions'} - {hook h='displayCartExtraProductActions' product=$product} - {/block} - -
    -
    -
    -
    - -
    -
    diff --git a/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl b/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl deleted file mode 100644 index b15aaae1..00000000 --- a/themes/classic/templates/checkout/_partials/cart-detailed-totals.tpl +++ /dev/null @@ -1,58 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='cart_detailed_totals'} -
    - -
    - {foreach from=$cart.subtotals item="subtotal"} - {if $subtotal.value && $subtotal.type !== 'tax'} -
    - - {if 'products' == $subtotal.type} - {$cart.summary_string} - {else} - {$subtotal.label} - {/if} - - - {if 'discount' == $subtotal.type}- {/if}{$subtotal.value} - - {if $subtotal.type === 'shipping'} -
    {hook h='displayCheckoutSubtotalDetails' subtotal=$subtotal}
    - {/if} -
    - {/if} - {/foreach} -
    - - {block name='cart_summary_totals'} - {include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart} - {/block} - - {block name='cart_voucher'} - {include file='checkout/_partials/cart-voucher.tpl'} - {/block} -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-detailed.tpl b/themes/classic/templates/checkout/_partials/cart-detailed.tpl deleted file mode 100644 index f04ca4b5..00000000 --- a/themes/classic/templates/checkout/_partials/cart-detailed.tpl +++ /dev/null @@ -1,42 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='cart_detailed_product'} -
    - {if $cart.products} -
      - {foreach from=$cart.products item=product} -
    • - {block name='cart_detailed_product_line'} - {include file='checkout/_partials/cart-detailed-product-line.tpl' product=$product} - {/block} -
    • - {if is_array($product.customizations) && $product.customizations|count >1}
      {/if} - {/foreach} -
    - {else} - {l s='There are no more items in your cart' d='Shop.Theme.Checkout'} - {/if} -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-summary-items-subtotal.tpl b/themes/classic/templates/checkout/_partials/cart-summary-items-subtotal.tpl deleted file mode 100644 index 4f3d99da..00000000 --- a/themes/classic/templates/checkout/_partials/cart-summary-items-subtotal.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='cart_summary_items_subtotal'} -
    - {$cart.summary_string} - {$cart.subtotals.products.amount} -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-summary-product-line.tpl b/themes/classic/templates/checkout/_partials/cart-summary-product-line.tpl deleted file mode 100644 index bea5fa0d..00000000 --- a/themes/classic/templates/checkout/_partials/cart-summary-product-line.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='cart_summary_product_line'} -
    - - {$product.name} - -
    -
    - {$product.name} - x{$product.quantity} - {$product.price} - {hook h='displayProductPriceBlock' product=$product type="unit_price"} - {foreach from=$product.attributes key="attribute" item="value"} -
    - {$attribute}: - {$value} -
    - {/foreach} -
    -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/cart-summary-subtotals.tpl b/themes/classic/templates/checkout/_partials/cart-summary-subtotals.tpl deleted file mode 100644 index f1fab19a..00000000 --- a/themes/classic/templates/checkout/_partials/cart-summary-subtotals.tpl +++ /dev/null @@ -1,44 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - -
    - - {foreach from=$cart.subtotals item="subtotal"} - {if $subtotal.value && $subtotal.type !== 'tax'} -
    - - - {$subtotal.label} - - - - {$subtotal.value} - -
    - {/if} - {/foreach} - -
    - diff --git a/themes/classic/templates/checkout/_partials/cart-summary-totals.tpl b/themes/classic/templates/checkout/_partials/cart-summary-totals.tpl deleted file mode 100644 index 903817c8..00000000 --- a/themes/classic/templates/checkout/_partials/cart-summary-totals.tpl +++ /dev/null @@ -1,54 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - - {block name='cart_summary_total'} - {if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled} -
    - {$cart.totals.total.label} {$cart.labels.tax_short} - {$cart.totals.total.value} -
    -
    - {$cart.totals.total_including_tax.label} - {$cart.totals.total_including_tax.value} -
    - {else} -
    - {$cart.totals.total.label} {if $configuration.taxes_enabled}{$cart.labels.tax_short}{/if} - {$cart.totals.total.value} -
    - {/if} - {/block} - - {block name='cart_summary_tax'} - {if $cart.subtotals.tax} -
    - {l s='%label%:' sprintf=['%label%' => $cart.subtotals.tax.label] d='Shop.Theme.Global'} - {$cart.subtotals.tax.value} -
    - {/if} - {/block} - -
    diff --git a/themes/classic/templates/checkout/_partials/cart-summary.tpl b/themes/classic/templates/checkout/_partials/cart-summary.tpl deleted file mode 100644 index 6c07ff69..00000000 --- a/themes/classic/templates/checkout/_partials/cart-summary.tpl +++ /dev/null @@ -1,69 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {block name='hook_checkout_summary_top'} - {hook h='displayCheckoutSummaryTop'} - {/block} - - {block name='cart_summary_products'} -
    - -

    {$cart.summary_string}

    - -

    - - {l s='show details' d='Shop.Theme.Actions'} - expand_more - -

    - - {block name='cart_summary_product_list'} -
    -
      - {foreach from=$cart.products item=product} -
    • {include file='checkout/_partials/cart-summary-product-line.tpl' product=$product}
    • - {/foreach} -
    -
    - {/block} -
    - {/block} - - {block name='cart_summary_subtotals'} - {include file='checkout/_partials/cart-summary-subtotals.tpl' cart=$cart} - {/block} - -
    - - {block name='cart_summary_totals'} - {include file='checkout/_partials/cart-summary-totals.tpl' cart=$cart} - {/block} - - {block name='cart_summary_voucher'} - {include file='checkout/_partials/cart-voucher.tpl'} - {/block} - -
    diff --git a/themes/classic/templates/checkout/_partials/cart-voucher.tpl b/themes/classic/templates/checkout/_partials/cart-voucher.tpl deleted file mode 100644 index f1f95ad6..00000000 --- a/themes/classic/templates/checkout/_partials/cart-voucher.tpl +++ /dev/null @@ -1,91 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{if $cart.vouchers.allowed} - {block name='cart_voucher'} -
    -
    - {if $cart.vouchers.added} - {block name='cart_voucher_list'} -
      - {foreach from=$cart.vouchers.added item=voucher} -
    • - {$voucher.name} -
      - {$voucher.reduction_formatted} - -
      -
    • - {/foreach} -
    - {/block} - {/if} - -

    - - {l s='Have a promo code?' d='Shop.Theme.Checkout'} - -

    - -
    -
    - {block name='cart_voucher_form'} -
    - - - - -
    - {/block} - - {block name='cart_voucher_notifications'} - - {/block} - - - {l s='Close' d='Shop.Theme.Checkout'} - -
    -
    - - {if $cart.discounts|count > 0} -

    - {l s='Take advantage of our exclusive offers:' d='Shop.Theme.Actions'} -

    -
      - {foreach from=$cart.discounts item=discount} -
    • - - {$discount.code} - {$discount.name} - -
    • - {/foreach} -
    - {/if} -
    -
    - {/block} -{/if} diff --git a/themes/classic/templates/checkout/_partials/customer-form.tpl b/themes/classic/templates/checkout/_partials/customer-form.tpl deleted file mode 100644 index cbd7b4fc..00000000 --- a/themes/classic/templates/checkout/_partials/customer-form.tpl +++ /dev/null @@ -1,50 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends "customer/_partials/customer-form.tpl"} - -{block "form_field"} - {if $field.name === 'password' and $guest_allowed} -

    - {l s='Create an account' d='Shop.Theme.Checkout'} {l s='(optional)' d='Shop.Theme.Checkout'} -
    - {l s='And save time on your next order!' d='Shop.Theme.Checkout'} -

    - {$smarty.block.parent} - {else} - {$smarty.block.parent} - {/if} -{/block} - -{block "form_buttons"} - -{/block} diff --git a/themes/classic/templates/checkout/_partials/footer.tpl b/themes/classic/templates/checkout/_partials/footer.tpl deleted file mode 100644 index 853c4d11..00000000 --- a/themes/classic/templates/checkout/_partials/footer.tpl +++ /dev/null @@ -1,29 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='footer'} -
    - {l s='%copyright% %year% - Ecommerce software by %prestashop%' sprintf=['%prestashop%' => 'PrestaShop™', '%year%' => 'Y'|date, '%copyright%' => '©'] d='Shop.Theme.Global'} -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/header.tpl b/themes/classic/templates/checkout/_partials/header.tpl deleted file mode 100644 index 54df9a1e..00000000 --- a/themes/classic/templates/checkout/_partials/header.tpl +++ /dev/null @@ -1,76 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='header'} - {block name='header_nav'} - - {/block} - - {block name='header_top'} -
    -
    -
    -
    -
    - {hook h='displayTop'} -
    -
    -
    -
    - -
    -
    - {hook h='displayNavFullWidth'} - {/block} -{/block} diff --git a/themes/classic/templates/checkout/_partials/login-form.tpl b/themes/classic/templates/checkout/_partials/login-form.tpl deleted file mode 100644 index 45b49d6e..00000000 --- a/themes/classic/templates/checkout/_partials/login-form.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/_partials/login-form.tpl'} - -{block name='form_buttons'} - -{/block} diff --git a/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl b/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl deleted file mode 100644 index 8708cea5..00000000 --- a/themes/classic/templates/checkout/_partials/order-confirmation-table.tpl +++ /dev/null @@ -1,136 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    - {block name='order_items_table_head'} -

    {l s='Order items' d='Shop.Theme.Checkout'}

    -

    {l s='Unit price' d='Shop.Theme.Checkout'}

    -

    {l s='Quantity' d='Shop.Theme.Checkout'}

    -

    {l s='Total products' d='Shop.Theme.Checkout'}

    - {/block} -
    - -
    - - {block name='order_confirmation_table'} - {foreach from=$products item=product} -
    -
    - - - -
    -
    - {if $add_product_link}{/if} - {$product.name} - {if $add_product_link}{/if} - {if is_array($product.customizations) && $product.customizations|count} - {foreach from=$product.customizations item="customization"} - - - {/foreach} - {/if} - {hook h='displayProductPriceBlock' product=$product type="unit_price"} -
    -
    -
    -
    {$product.price}
    -
    {$product.quantity}
    -
    {$product.total}
    -
    -
    -
    - {/foreach} - -
    - - - {foreach $subtotals as $subtotal} - {if $subtotal.type !== 'tax' && $subtotal.label !== null} - - - - - {/if} - {/foreach} - - {if !$configuration.display_prices_tax_incl && $configuration.taxes_enabled} - - - - - - - - - {else} - - - - - {/if} - {if $subtotals.tax.label !== null} - - - - {/if} -
    {$subtotal.label}{if 'discount' == $subtotal.type}- {/if}{$subtotal.value}
    {$totals.total.label} {$labels.tax_short}{$totals.total.value}
    {$totals.total_including_tax.label}{$totals.total_including_tax.value}
    {$totals.total.label} {if $configuration.taxes_enabled}{$labels.tax_short}{/if}{$totals.total.value}
    {l s='%label%:' sprintf=['%label%' => $subtotals.tax.label] d='Shop.Theme.Global'} {$subtotals.tax.value}
    - {/block} - -
    -
    diff --git a/themes/classic/templates/checkout/_partials/order-final-summary-table.tpl b/themes/classic/templates/checkout/_partials/order-final-summary-table.tpl deleted file mode 100644 index a1cf3185..00000000 --- a/themes/classic/templates/checkout/_partials/order-final-summary-table.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='checkout/_partials/order-confirmation-table.tpl'} - -{block name='order-items-table-head'} -
    -

    - {if $products_count == 1} - {l s='%product_count% item in your cart' sprintf=['%product_count%' => $products_count] d='Shop.Theme.Checkout'} - {else} - {l s='%products_count% items in your cart' sprintf=['%products_count%' => $products_count] d='Shop.Theme.Checkout'} - {/if} - mode_edit {l s='edit' d='Shop.Theme.Actions'} -

    -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/order-final-summary.tpl b/themes/classic/templates/checkout/_partials/order-final-summary.tpl deleted file mode 100644 index e67a4a51..00000000 --- a/themes/classic/templates/checkout/_partials/order-final-summary.tpl +++ /dev/null @@ -1,103 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    -
    -
    -

    {l s='Please check your order before payment' d='Shop.Theme.Checkout'}

    -
    -
    - -
    -
    -

    - {l s='Addresses' d='Shop.Theme.Checkout'} - mode_edit {l s='edit' d='Shop.Theme.Actions'} -

    -
    -
    -
    -
    -
    -
    -

    {l s='Your Delivery Address' d='Shop.Theme.Checkout'}

    - {$customer.addresses[$cart.id_address_delivery]['formatted'] nofilter} -
    -
    -
    -
    -
    -
    -

    {l s='Your Invoice Address' d='Shop.Theme.Checkout'}

    - {$customer.addresses[$cart.id_address_invoice]['formatted'] nofilter} -
    -
    -
    -
    - -
    -
    -

    - {l s='Shipping Method' d='Shop.Theme.Checkout'} - mode_edit {l s='edit' d='Shop.Theme.Actions'} -

    - -
    -
    -
    -
    - {if $selected_delivery_option.logo} - {$selected_delivery_option.name} - {else} -   - {/if} -
    -
    -
    - {$selected_delivery_option.name} -
    -
    - {$selected_delivery_option.delay} -
    -
    - {$selected_delivery_option.price} -
    -
    -
    -
    -
    - -
    - {block name='order_confirmation_table'} - {include file='checkout/_partials/order-final-summary-table.tpl' - products=$cart.products - products_count=$cart.products_count - subtotals=$cart.subtotals - totals=$cart.totals - labels=$cart.labels - add_product_link=true - } - {/block} -
    -
    diff --git a/themes/classic/templates/checkout/_partials/steps/addresses.tpl b/themes/classic/templates/checkout/_partials/steps/addresses.tpl deleted file mode 100644 index 2dc14b61..00000000 --- a/themes/classic/templates/checkout/_partials/steps/addresses.tpl +++ /dev/null @@ -1,137 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='checkout/_partials/steps/checkout-step.tpl'} - -{block name='step_content'} -
    -
    - - {if !$use_same_address} -

    {l s='Shipping Address' d='Shop.Theme.Checkout'}

    - {/if} - - {if $use_same_address && !$cart.is_virtual} -

    - {l s='The selected address will be used both as your personal address (for invoice) and as your delivery address.' d='Shop.Theme.Checkout'} -

    - {elseif $use_same_address && $cart.is_virtual} -

    - {l s='The selected address will be used as your personal address (for invoice).' d='Shop.Theme.Checkout'} -

    - {/if} - - {if $show_delivery_address_form} -
    - {render file = 'checkout/_partials/address-form.tpl' - ui = $address_form - use_same_address = $use_same_address - type = "delivery" - form_has_continue_button = $form_has_continue_button - } -
    - {elseif $customer.addresses|count > 0} -
    - {include file = 'checkout/_partials/address-selector-block.tpl' - addresses = $customer.addresses - name = "id_address_delivery" - selected = $id_address_delivery - type = "delivery" - interactive = !$show_delivery_address_form and !$show_invoice_address_form - } -
    - - {if isset($delivery_address_error)} -

    {$delivery_address_error.exception}

    - {else} - - {/if} - -

    - {l s='add new address' d='Shop.Theme.Actions'} -

    - - {if $use_same_address && !$cart.is_virtual} -

    - - {l s='Billing address differs from shipping address' d='Shop.Theme.Checkout'} - -

    - {/if} - - {/if} - - {if !$use_same_address} - -

    {l s='Your Invoice Address' d='Shop.Theme.Checkout'}

    - - {if $show_invoice_address_form} -
    - {render file = 'checkout/_partials/address-form.tpl' - ui = $address_form - use_same_address = $use_same_address - type = "invoice" - form_has_continue_button = $form_has_continue_button - } -
    - {else} -
    - {include file = 'checkout/_partials/address-selector-block.tpl' - addresses = $customer.addresses - name = "id_address_invoice" - selected = $id_address_invoice - type = "invoice" - interactive = !$show_delivery_address_form and !$show_invoice_address_form - } -
    - - {if isset($invoice_address_error)} -

    {$invoice_address_error.exception}

    - {else} - - {/if} - -

    - {l s='add new address' d='Shop.Theme.Actions'} -

    - {/if} - - {/if} - - {if !$form_has_continue_button} -
    - - -
    - {/if} - -
    -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/steps/checkout-step.tpl b/themes/classic/templates/checkout/_partials/steps/checkout-step.tpl deleted file mode 100644 index 47773c82..00000000 --- a/themes/classic/templates/checkout/_partials/steps/checkout-step.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='step'} -
    -

    - - {$position} - {$title} - mode_edit {l s='Edit' d='Shop.Theme.Actions'} -

    - -
    - {block name='step_content'}DUMMY STEP CONTENT{/block} -
    -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/steps/payment.tpl b/themes/classic/templates/checkout/_partials/steps/payment.tpl deleted file mode 100644 index 2f14dfda..00000000 --- a/themes/classic/templates/checkout/_partials/steps/payment.tpl +++ /dev/null @@ -1,167 +0,0 @@ -{extends file='checkout/_partials/steps/checkout-step.tpl'} - -{block name='step_content'} - - {hook h='displayPaymentTop'} - - {* used by javascript to correctly handle cart updates when we are on payment step (eg vouchers added) *} - - - {if !empty($display_transaction_updated_info)} -

    - {l s='Transaction amount has been correctly updated' d='Shop.Theme.Checkout'} -

    - {/if} - - {if $is_free} -

    {l s='No payment needed for this order' d='Shop.Theme.Checkout'}

    - {/if} -
    - {foreach from=$payment_options item="module_options"} - {foreach from=$module_options item="option"} -
    -
    - {* This is the way an option should be selected when Javascript is enabled *} - - - - - {* This is the way an option should be selected when Javascript is disabled *} -
    - {if $option.id === $selected_payment_option} - {l s='Selected' d='Shop.Theme.Checkout'} - {else} - - {/if} -
    - - - -
    -
    - - {if $option.additionalInformation} -
    - {$option.additionalInformation nofilter} -
    - {/if} - -
    - {if $option.form} - {$option.form nofilter} - {else} -
    - {foreach from=$option.inputs item=input} - - {/foreach} - -
    - {/if} -
    - {/foreach} - {foreachelse} -

    {l s='Unfortunately, there are no payment method available.' d='Shop.Theme.Checkout'}

    - {/foreach} -
    - - {if $conditions_to_approve|count} -

    - {* At the moment, we're not showing the checkboxes when JS is disabled - because it makes ensuring they were checked very tricky and overcomplicates - the template. Might change later. - *} - {l s='By confirming the order, you certify that you have read and agree with all of the conditions below:' d='Shop.Theme.Checkout'} -

    - -
    -
      - {foreach from=$conditions_to_approve item="condition" key="condition_name"} -
    • -
      - - - - -
      -
      - -
      -
    • - {/foreach} -
    -
    - {/if} - - {if $show_final_summary} - {include file='checkout/_partials/order-final-summary.tpl'} - {/if} - -
    -
    - - {if $show_final_summary} - - {/if} -
    -
    - {if $selected_payment_option and $all_conditions_approved} - - {/if} -
    -
    - - {hook h='displayPaymentByBinaries'} - - -{/block} diff --git a/themes/classic/templates/checkout/_partials/steps/personal-information.tpl b/themes/classic/templates/checkout/_partials/steps/personal-information.tpl deleted file mode 100644 index 13b6b101..00000000 --- a/themes/classic/templates/checkout/_partials/steps/personal-information.tpl +++ /dev/null @@ -1,98 +0,0 @@ -{extends file='checkout/_partials/steps/checkout-step.tpl'} - -{block name='step_content'} - {hook h='displayPersonalInformationTop' customer=$customer} - - {if $customer.is_logged && !$customer.is_guest} - -

    - {* [1][/1] is for a HTML tag. *} - {l s='Connected as [1]%firstname% %lastname%[/1].' - d='Shop.Theme.Customeraccount' - sprintf=[ - '[1]' => "", - '[/1]' => "", - '%firstname%' => $customer.firstname, - '%lastname%' => $customer.lastname - ] - } -

    -

    - {* [1][/1] is for a HTML tag. *} - {l - s='Not you? [1]Log out[/1]' - d='Shop.Theme.Customeraccount' - sprintf=[ - '[1]' => "", - '[/1]' => "" - ] - } -

    - {if !isset($empty_cart_on_logout) || $empty_cart_on_logout} -

    {l s='If you sign out now, your cart will be emptied.' d='Shop.Theme.Checkout'}

    - {/if} - -
    -
    - -
    - -
    - - {else} - - -
    - - -
    - - - {/if} -{/block} diff --git a/themes/classic/templates/checkout/_partials/steps/shipping.tpl b/themes/classic/templates/checkout/_partials/steps/shipping.tpl deleted file mode 100644 index d6b5182c..00000000 --- a/themes/classic/templates/checkout/_partials/steps/shipping.tpl +++ /dev/null @@ -1,124 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='checkout/_partials/steps/checkout-step.tpl'} - -{block name='step_content'} -
    - {$hookDisplayBeforeCarrier nofilter} -
    - -
    - {if $delivery_options|count} -
    -
    - {block name='delivery_options'} -
    - {foreach from=$delivery_options item=carrier key=carrier_id} -
    -
    - - - - -
    - -
    - -
    - {/foreach} -
    - {/block} -
    -
    - - -
    - - {if $recyclablePackAllowed} - - - - - - {/if} - - {if $gift.allowed} - - - - - - -
    - - -
    - {/if} - -
    -
    - -
    - {else} -

    {l s='Unfortunately, there are no carriers available for your delivery address.' d='Shop.Theme.Checkout'}

    - {/if} -
    - -
    - {$hookDisplayAfterCarrier nofilter} -
    - -
    -{/block} diff --git a/themes/classic/templates/checkout/_partials/steps/unreachable.tpl b/themes/classic/templates/checkout/_partials/steps/unreachable.tpl deleted file mode 100644 index 158efa3e..00000000 --- a/themes/classic/templates/checkout/_partials/steps/unreachable.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='step'} -
    -

    - {$position} {$title} -

    -
    -{/block} diff --git a/themes/classic/templates/checkout/cart-empty.tpl b/themes/classic/templates/checkout/cart-empty.tpl deleted file mode 100644 index 70d0d7d0..00000000 --- a/themes/classic/templates/checkout/cart-empty.tpl +++ /dev/null @@ -1,45 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='checkout/cart.tpl'} - -{block name='content' append} - {hook h='displayCrossSellingShoppingCart'} -{/block} - -{block name='continue_shopping' append} - - chevron_left{l s='Continue shopping' d='Shop.Theme.Actions'} - -{/block} - -{block name='cart_actions'} -
    - -
    -{/block} - -{block name='continue_shopping'}{/block} -{block name='cart_voucher'}{/block} -{block name='display_reassurance'}{/block} diff --git a/themes/classic/templates/checkout/cart.tpl b/themes/classic/templates/checkout/cart.tpl deleted file mode 100644 index fb0a4d5c..00000000 --- a/themes/classic/templates/checkout/cart.tpl +++ /dev/null @@ -1,87 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='content'} - -
    -
    - - -
    - - -
    -
    -

    {l s='Shopping Cart' d='Shop.Theme.Checkout'}

    -
    -
    - {block name='cart_overview'} - {include file='checkout/_partials/cart-detailed.tpl' cart=$cart} - {/block} -
    - - {block name='continue_shopping'} - - chevron_left{l s='Continue shopping' d='Shop.Theme.Actions'} - - {/block} - - - {block name='hook_shopping_cart_footer'} - {hook h='displayShoppingCartFooter'} - {/block} -
    - - -
    - - {block name='cart_summary'} -
    - - {block name='hook_shopping_cart'} - {hook h='displayShoppingCart'} - {/block} - - {block name='cart_totals'} - {include file='checkout/_partials/cart-detailed-totals.tpl' cart=$cart} - {/block} - - {block name='cart_actions'} - {include file='checkout/_partials/cart-detailed-actions.tpl' cart=$cart} - {/block} - -
    - {/block} - - {block name='hook_reassurance'} - {hook h='displayReassurance'} - {/block} - -
    - -
    -
    -{/block} diff --git a/themes/classic/templates/checkout/checkout-process.tpl b/themes/classic/templates/checkout/checkout-process.tpl deleted file mode 100644 index 98065b20..00000000 --- a/themes/classic/templates/checkout/checkout-process.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{foreach from=$steps item="step" key="index"} - {render identifier = $step.identifier - position = ($index + 1) - ui = $step.ui - } -{/foreach} diff --git a/themes/classic/templates/checkout/checkout.tpl b/themes/classic/templates/checkout/checkout.tpl deleted file mode 100644 index ed0134ab..00000000 --- a/themes/classic/templates/checkout/checkout.tpl +++ /dev/null @@ -1,94 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - - - - {block name='head'} - {include file='_partials/head.tpl'} - {/block} - - - - - {block name='hook_after_body_opening_tag'} - {hook h='displayAfterBodyOpeningTag'} - {/block} - - - - {block name='notifications'} - {include file='_partials/notifications.tpl'} - {/block} - -
    - {hook h="displayWrapperTop"} -
    - - {block name='content'} -
    -
    -
    - {block name='cart_summary'} - {render file='checkout/checkout-process.tpl' ui=$checkout_process} - {/block} -
    - -
    - - {block name='cart_summary'} - {include file='checkout/_partials/cart-summary.tpl' cart = $cart} - {/block} - - {hook h='displayReassurance'} -
    -
    -
    - {/block} -
    - {hook h="displayWrapperBottom"} -
    - -
    - {block name='footer'} - {include file='checkout/_partials/footer.tpl'} - {/block} -
    - - {block name='javascript_bottom'} - {include file="_partials/javascript.tpl" javascript=$javascript.bottom} - {/block} - - {block name='hook_before_body_closing_tag'} - {hook h='displayBeforeBodyClosingTag'} - {/block} - - - - diff --git a/themes/classic/templates/checkout/order-confirmation.tpl b/themes/classic/templates/checkout/order-confirmation.tpl deleted file mode 100644 index d73a9707..00000000 --- a/themes/classic/templates/checkout/order-confirmation.tpl +++ /dev/null @@ -1,110 +0,0 @@ -{extends file='page.tpl'} - -{block name='page_content_container' prepend} -
    -
    -
    -
    - - {block name='order_confirmation_header'} -

    - {l s='Your order is confirmed' d='Shop.Theme.Checkout'} -

    - {/block} - -

    - {l s='An email has been sent to your mail address %email%.' d='Shop.Theme.Checkout' sprintf=['%email%' => $customer.email]} - {if $order.details.invoice_url} - {* [1][/1] is for a HTML tag. *} - {l - s='You can also [1]download your invoice[/1]' - d='Shop.Theme.Checkout' - sprintf=[ - '[1]' => "", - '[/1]' => "" - ] - } - {/if} -

    - - {block name='hook_order_confirmation'} - {$HOOK_ORDER_CONFIRMATION nofilter} - {/block} - -
    -
    -
    -
    -{/block} - -{block name='page_content_container'} -
    -
    -
    - - {block name='order_confirmation_table'} - {include - file='checkout/_partials/order-confirmation-table.tpl' - products=$order.products - subtotals=$order.subtotals - totals=$order.totals - labels=$order.labels - add_product_link=false - } - {/block} - - {block name='order_details'} -
    -

    {l s='Order details' d='Shop.Theme.Checkout'}:

    -
      -
    • {l s='Order reference: %reference%' d='Shop.Theme.Checkout' sprintf=['%reference%' => $order.details.reference]}
    • -
    • {l s='Payment method: %method%' d='Shop.Theme.Checkout' sprintf=['%method%' => $order.details.payment]}
    • - {if !$order.details.is_virtual} -
    • - {l s='Shipping method: %method%' d='Shop.Theme.Checkout' sprintf=['%method%' => $order.carrier.name]}
      - {$order.carrier.delay} -
    • - {/if} -
    -
    - {/block} - -
    -
    -
    - - {block name='hook_payment_return'} - {if ! empty($HOOK_PAYMENT_RETURN)} -
    -
    -
    -
    - {$HOOK_PAYMENT_RETURN nofilter} -
    -
    -
    -
    - {/if} - {/block} - - {block name='customer_registration_form'} - {if $customer.is_guest} -
    -
    -

    {l s='Save time on your next order, sign up now' d='Shop.Theme.Checkout'}

    - {render file='customer/_partials/customer-form.tpl' ui=$register_form} -
    -
    - {/if} - {/block} - - {block name='hook_order_confirmation_1'} - {hook h='displayOrderConfirmation1'} - {/block} - - {block name='hook_order_confirmation_2'} - - {/block} -{/block} diff --git a/themes/classic/templates/cms/_partials/sitemap-nested-list.tpl b/themes/classic/templates/cms/_partials/sitemap-nested-list.tpl deleted file mode 100644 index cf6044f3..00000000 --- a/themes/classic/templates/cms/_partials/sitemap-nested-list.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='sitemap_item'} - - {foreach $links as $link} -
  • - - {$link.label} - - {if isset($link.children) && $link.children|@count > 0} - {include file='cms/_partials/sitemap-nested-list.tpl' links=$link.children is_nested=true} - {/if} -
  • - {/foreach} - -{/block} diff --git a/themes/classic/templates/cms/category.tpl b/themes/classic/templates/cms/category.tpl deleted file mode 100644 index d62e1b2b..00000000 --- a/themes/classic/templates/cms/category.tpl +++ /dev/null @@ -1,53 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {$cms_category.name} -{/block} - -{block name='page_content'} - {block name='cms_sub_categories'} - {if $sub_categories} -

    {l s='List of sub categories in %name%:' d='Shop.Theme.Global' sprintf=['%name%' => $cms_category.name]}

    - - {/if} - {/block} - - {block name='cms_sub_pages'} - {if $cms_pages} -

    {l s='List of pages in %category_name%:' d='Shop.Theme.Global' sprintf=['%category_name%' => $cms_category.name]}

    - - {/if} - {/block} -{/block} diff --git a/themes/classic/templates/cms/page.tpl b/themes/classic/templates/cms/page.tpl deleted file mode 100644 index 4839ab7a..00000000 --- a/themes/classic/templates/cms/page.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {$cms.meta_title} -{/block} - -{block name='page_content_container'} -
    - - {block name='cms_content'} - {$cms.content nofilter} - {/block} - - {block name='hook_cms_dispute_information'} - {hook h='displayCMSDisputeInformation'} - {/block} - - {block name='hook_cms_print_button'} - {hook h='displayCMSPrintButton'} - {/block} - -
    -{/block} diff --git a/themes/classic/templates/cms/sitemap.tpl b/themes/classic/templates/cms/sitemap.tpl deleted file mode 100644 index 1a924724..00000000 --- a/themes/classic/templates/cms/sitemap.tpl +++ /dev/null @@ -1,52 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Sitemap' d='Shop.Theme.Global'} -{/block} - -{block name='page_content_container'} -
    -
    -
    -

    {$our_offers}

    - {include file='cms/_partials/sitemap-nested-list.tpl' links=$links.offers} -
    -
    -

    {$categories}

    - {include file='cms/_partials/sitemap-nested-list.tpl' links=$links.categories} -
    -
    -

    {$your_account}

    - {include file='cms/_partials/sitemap-nested-list.tpl' links=$links.user_account} -
    -
    -

    {$pages}

    - {include file='cms/_partials/sitemap-nested-list.tpl' links=$links.pages} -
    -
    -
    -{/block} diff --git a/themes/classic/templates/cms/stores.tpl b/themes/classic/templates/cms/stores.tpl deleted file mode 100644 index bb3c9923..00000000 --- a/themes/classic/templates/cms/stores.tpl +++ /dev/null @@ -1,88 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Our stores' d='Shop.Theme.Global'} -{/block} - -{block name='page_content_container'} -
    - - {foreach $stores as $store} -
    -
    -
    - {$store.image.legend} -
    -
    -

    {$store.name}

    -
    {$store.address.formatted nofilter}
    - {if $store.note || $store.phone || $store.fax || $store.email} - - {/if} -
    -
    - - {foreach $store.business_hours as $day} - - - - - {/foreach} -
    {$day.day|truncate:4:'.'} -
      - {foreach $day.hours as $h} -
    • {$h}
    • - {/foreach} -
    -
    -
    -
    -
    - -
    -
    - {/foreach} - -
    -{/block} diff --git a/themes/classic/templates/contact.tpl b/themes/classic/templates/contact.tpl deleted file mode 100644 index fc228c09..00000000 --- a/themes/classic/templates/contact.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_header_container'}{/block} - -{block name='left_column'} -
    - {widget name="ps_contactinfo" hook='displayLeftColumn'} -
    -{/block} - -{block name='page_content'} - {widget name="contactform"} -{/block} diff --git a/themes/classic/templates/customer/_partials/address-form.tpl b/themes/classic/templates/customer/_partials/address-form.tpl deleted file mode 100644 index 3f30e0f7..00000000 --- a/themes/classic/templates/customer/_partials/address-form.tpl +++ /dev/null @@ -1,63 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name="address_form"} -
    - {include file='_partials/form-errors.tpl' errors=$errors['']} - - {block name="address_form_url"} -
    - {/block} - - {block name="address_form_fields"} -
    - {block name='form_fields'} - {foreach from=$formFields item="field"} - {block name='form_field'} - {form_field field=$field} - {/block} - {/foreach} - {/block} -
    - {/block} - - {block name="address_form_footer"} -
    - - {block name='form_buttons'} - - {/block} -
    - {/block} - -
    -
    -{/block} diff --git a/themes/classic/templates/customer/_partials/block-address.tpl b/themes/classic/templates/customer/_partials/block-address.tpl deleted file mode 100644 index 433672db..00000000 --- a/themes/classic/templates/customer/_partials/block-address.tpl +++ /dev/null @@ -1,45 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='address_block_item'} - -{/block} diff --git a/themes/classic/templates/customer/_partials/customer-form.tpl b/themes/classic/templates/customer/_partials/customer-form.tpl deleted file mode 100644 index dba04d00..00000000 --- a/themes/classic/templates/customer/_partials/customer-form.tpl +++ /dev/null @@ -1,54 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='customer_form'} - {block name='customer_form_errors'} - {include file='_partials/form-errors.tpl' errors=$errors['']} - {/block} - -
    -
    - {block "form_fields"} - {foreach from=$formFields item="field"} - {block "form_field"} - {form_field field=$field} - {/block} - {/foreach} - {$hook_create_account_form nofilter} - {/block} -
    - - {block name='customer_form_footer'} -
    - - {block "form_buttons"} - - {/block} -
    - {/block} - -
    -{/block} diff --git a/themes/classic/templates/customer/_partials/login-form.tpl b/themes/classic/templates/customer/_partials/login-form.tpl deleted file mode 100644 index 932480e4..00000000 --- a/themes/classic/templates/customer/_partials/login-form.tpl +++ /dev/null @@ -1,60 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='login_form'} - - {block name='login_form_errors'} - {include file='_partials/form-errors.tpl' errors=$errors['']} - {/block} - -
    - -
    - {block name='login_form_fields'} - {foreach from=$formFields item="field"} - {block name='form_field'} - {form_field field=$field} - {/block} - {/foreach} - {/block} - -
    - - {block name='login_form_footer'} -
    - - {block name='form_buttons'} - - {/block} -
    - {/block} - -
    -{/block} diff --git a/themes/classic/templates/customer/_partials/my-account-links.tpl b/themes/classic/templates/customer/_partials/my-account-links.tpl deleted file mode 100644 index 18920171..00000000 --- a/themes/classic/templates/customer/_partials/my-account-links.tpl +++ /dev/null @@ -1,34 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='my_account_links'} - - -{/block} diff --git a/themes/classic/templates/customer/_partials/order-detail-no-return.tpl b/themes/classic/templates/customer/_partials/order-detail-no-return.tpl deleted file mode 100644 index 005af9b4..00000000 --- a/themes/classic/templates/customer/_partials/order-detail-no-return.tpl +++ /dev/null @@ -1,175 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='order_products_table'} -
    - - - - - - - - - - {foreach from=$order.products item=product} - - - - - - - {/foreach} - - {foreach $order.subtotals as $line} - {if $line.value} - - - - - {/if} - {/foreach} - - - - - -
    {l s='Product' d='Shop.Theme.Catalog'}{l s='Quantity' d='Shop.Theme.Catalog'}{l s='Unit price' d='Shop.Theme.Catalog'}{l s='Total price' d='Shop.Theme.Catalog'}
    - - - {$product.name} - -
    - {if $product.reference} - {l s='Reference' d='Shop.Theme.Catalog'}: {$product.reference}
    - {/if} - {if $product.customizations} - {foreach from=$product.customizations item="customization"} - -
    - -
    - {/foreach} - {/if} -
    - {if $product.customizations} - {foreach $product.customizations as $customization} - {$customization.quantity} - {/foreach} - {else} - {$product.quantity} - {/if} - {$product.price}{$product.total}
    {$line.label}{$line.value}
    {$order.totals.total.label}{$order.totals.total.value}
    -
    - -
    - {foreach from=$order.products item=product} -
    -
    -
    -
    {$product.name}
    - {if $product.reference} -
    {l s='Reference' d='Shop.Theme.Catalog'}: {$product.reference}
    - {/if} - {if $product.customizations} - {foreach $product.customizations as $customization} - -
    -
    - {/foreach} - {/if} -
    -
    -
    -
    - {$product.price} -
    -
    - {if $product.customizations} - {foreach $product.customizations as $customization} - {$customization.quantity} - {/foreach} - {else} - {$product.quantity} - {/if} -
    -
    - {$product.total} -
    -
    -
    -
    -
    - {/foreach} -
    -
    - {foreach $order.subtotals as $line} - {if $line.value} -
    -
    {$line.label}
    -
    {$line.value}
    -
    - {/if} - {/foreach} -
    -
    {$order.totals.total.label}
    -
    {$order.totals.total.value}
    -
    -
    -{/block} diff --git a/themes/classic/templates/customer/_partials/order-detail-return.tpl b/themes/classic/templates/customer/_partials/order-detail-return.tpl deleted file mode 100644 index 1156ec37..00000000 --- a/themes/classic/templates/customer/_partials/order-detail-return.tpl +++ /dev/null @@ -1,253 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='order_products_table'} -
    - -
    - - - - - - - - - - - - {foreach from=$order.products item=product name=products} - - - - - - - - - {/foreach} - - {foreach $order.subtotals as $line} - {if $line.value} - - - - - {/if} - {/foreach} - - - - - -
    {l s='Product' d='Shop.Theme.Catalog'}{l s='Quantity' d='Shop.Theme.Catalog'}{l s='Returned' d='Shop.Theme.Customeraccount'}{l s='Unit price' d='Shop.Theme.Catalog'}{l s='Total price' d='Shop.Theme.Catalog'}
    - {if !$product.customizations} - - - - {else} - {foreach $product.customizations as $customization} - - - - {/foreach} - {/if} - - {$product.name}
    - {if $product.reference} - {l s='Reference' d='Shop.Theme.Catalog'}: {$product.reference}
    - {/if} - {if $product.customizations} - {foreach from=$product.customizations item="customization"} - -
    - -
    - {/foreach} - {/if} -
    - {if !$product.customizations} -
    - {$product.quantity} -
    - {if $product.quantity > $product.qty_returned} -
    - -
    - {/if} - {else} - {foreach $product.customizations as $customization} -
    - {$customization.quantity} -
    -
    - -
    - {/foreach} -
    - {/if} -
    {$product.qty_returned}{$product.price}{$product.total}
    {$line.label}{$line.value}
    {$order.totals.total.label}{$order.totals.total.value}
    -
    - -
    - {foreach from=$order.products item=product} -
    -
    -
    - {if !$product.customizations} - - {else} - {foreach $product.customizations as $customization} - - {/foreach} - {/if} -
    -
    -
    -
    -
    {$product.name}
    - {if $product.reference} -
    {l s='Reference' d='Shop.Theme.Catalog'}: {$product.reference}
    - {/if} - {if $product.customizations} - {foreach $product.customizations as $customization} - -
    -
    - {/foreach} - {/if} -
    -
    -
    -
    - {$product.price} -
    -
    - {if $product.customizations} - {foreach $product.customizations as $customization} -
    {l s='Quantity' d='Shop.Theme.Catalog'}: {$customization.quantity}
    -
    - {/foreach} - {else} -
    {l s='Quantity' d='Shop.Theme.Catalog'}: {$product.quantity}
    - {if $product.quantity > $product.qty_returned} -
    - {/if} - {/if} - {if $product.qty_returned > 0} -
    {l s='Returned' d='Shop.Theme.Customeraccount'}: {$product.qty_returned}
    - {/if} -
    -
    - {$product.total} -
    -
    -
    -
    -
    -
    -
    - {/foreach} -
    -
    - {foreach $order.subtotals as $line} - {if $line.value} -
    -
    {$line.label}
    -
    {$line.value}
    -
    - {/if} - {/foreach} -
    -
    {$order.totals.total.label}
    -
    {$order.totals.total.value}
    -
    -
    - -
    -
    -

    {l s='Merchandise return' d='Shop.Theme.Customeraccount'}

    -

    {l s='If you wish to return one or more products, please mark the corresponding boxes and provide an explanation for the return. When complete, click the button below.' d='Shop.Theme.Customeraccount'}

    -
    -
    -
    - -
    -
    -
    - - -
    -
    - -
    -{/block} diff --git a/themes/classic/templates/customer/_partials/order-messages.tpl b/themes/classic/templates/customer/_partials/order-messages.tpl deleted file mode 100644 index daf71a57..00000000 --- a/themes/classic/templates/customer/_partials/order-messages.tpl +++ /dev/null @@ -1,85 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{block name='order_messages_table'} - {if $order.messages} -
    -

    {l s='Messages' d='Shop.Theme.Customeraccount'}

    - {foreach from=$order.messages item=message} -
    -
    - {$message.name}
    - {$message.message_date} -
    -
    - {$message.message nofilter} -
    -
    - {/foreach} -
    - {/if} -{/block} - -{block name='order_message_form'} -
    -
    - -
    -

    {l s='Add a message' d='Shop.Theme.Customeraccount'}

    -

    {l s='If you would like to add a comment about your order, please write it in the field below.' d='Shop.Theme.Customeraccount'}

    -
    - -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - - -
    - -
    -
    -{/block} diff --git a/themes/classic/templates/customer/address.tpl b/themes/classic/templates/customer/address.tpl deleted file mode 100644 index c97eb94e..00000000 --- a/themes/classic/templates/customer/address.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {if $editing} - {l s='Update your address' d='Shop.Theme.Customeraccount'} - {else} - {l s='New address' d='Shop.Theme.Customeraccount'} - {/if} -{/block} - -{block name='page_content'} -
    - {render template="customer/_partials/address-form.tpl" ui=$address_form} -
    -{/block} diff --git a/themes/classic/templates/customer/addresses.tpl b/themes/classic/templates/customer/addresses.tpl deleted file mode 100644 index 8d59bc7e..00000000 --- a/themes/classic/templates/customer/addresses.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Your addresses' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {foreach $customer.addresses as $address} -
    - {block name='customer_address'} - {include file='customer/_partials/block-address.tpl' address=$address} - {/block} -
    - {/foreach} -
    - -{/block} diff --git a/themes/classic/templates/customer/authentication.tpl b/themes/classic/templates/customer/authentication.tpl deleted file mode 100644 index 3d940b92..00000000 --- a/themes/classic/templates/customer/authentication.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Log in to your account' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {block name='login_form_container'} - -
    - {block name='display_after_login_form'} - {hook h='displayCustomerLoginFormAfter'} - {/block} - - {/block} -{/block} diff --git a/themes/classic/templates/customer/discount.tpl b/themes/classic/templates/customer/discount.tpl deleted file mode 100644 index c434a52f..00000000 --- a/themes/classic/templates/customer/discount.tpl +++ /dev/null @@ -1,96 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Your vouchers' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {if $cart_rules} - - - - - - - - - - - - - - {foreach from=$cart_rules item=cart_rule} - - - - - - - - - - {/foreach} - -
    {l s='Code' d='Shop.Theme.Checkout'}{l s='Description' d='Shop.Theme.Checkout'}{l s='Quantity' d='Shop.Theme.Checkout'}{l s='Value' d='Shop.Theme.Checkout'}{l s='Minimum' d='Shop.Theme.Checkout'}{l s='Cumulative' d='Shop.Theme.Checkout'}{l s='Expiration date' d='Shop.Theme.Checkout'}
    {$cart_rule.code}{$cart_rule.name}{$cart_rule.quantity_for_user}{$cart_rule.value}{$cart_rule.voucher_minimal}{$cart_rule.voucher_cumulable}{$cart_rule.voucher_date}
    -
    - {foreach from=$cart_rules item=cart_rule} -
    -
      -
    • - {l s='Code' d='Shop.Theme.Checkout'} - {$cart_rule.code} -
    • -
    • - {l s='Description' d='Shop.Theme.Checkout'} - {$cart_rule.name} -
    • -
    • - {l s='Quantity' d='Shop.Theme.Checkout'} - {$cart_rule.quantity_for_user} -
    • -
    • - {l s='Value' d='Shop.Theme.Checkout'} - {$cart_rule.value} -
    • -
    • - {l s='Minimum' d='Shop.Theme.Checkout'} - {$cart_rule.voucher_minimal} -
    • -
    • - {l s='Cumulative' d='Shop.Theme.Checkout'} - {$cart_rule.voucher_cumulable} -
    • -
    • - {l s='Expiration date' d='Shop.Theme.Checkout'} - {$cart_rule.voucher_date} -
    • -
    -
    - {/foreach} -
    - {/if} -{/block} diff --git a/themes/classic/templates/customer/guest-login.tpl b/themes/classic/templates/customer/guest-login.tpl deleted file mode 100644 index 356e81b7..00000000 --- a/themes/classic/templates/customer/guest-login.tpl +++ /dev/null @@ -1,79 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Guest Order Tracking' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    -
    -

    {l s='To track your order, please enter the following information:' d='Shop.Theme.Customeraccount'}

    -
    - -
    - -
    - -
    - -
    - {l s='For example: QIIXJXNUI or QIIXJXNUI#1' d='Shop.Theme.Customeraccount'} -
    -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    -{/block} diff --git a/themes/classic/templates/customer/guest-tracking.tpl b/themes/classic/templates/customer/guest-tracking.tpl deleted file mode 100644 index 52a149bd..00000000 --- a/themes/classic/templates/customer/guest-tracking.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/order-detail.tpl'} - -{block name='page_title'} - {l s='Guest Tracking' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='order_detail'} - {include file='customer/_partials/order-detail-no-return.tpl'} -{/block} - -{block name='order_messages'} -{/block} - -{block name='page_content' append} - {block name='guest_to_customer'} -
    -
    -

    {l s='Transform your guest account into a customer account and enjoy:' d='Shop.Theme.Customeraccount'}

    -
      -
    • -{l s='Personalized and secure access' d='Shop.Theme.Customeraccount'}
    • -
    • -{l s='Fast and easy checkout' d='Shop.Theme.Customeraccount'}
    • -
    • -{l s='Easier merchandise return' d='Shop.Theme.Customeraccount'}
    • -
    -
    - -
    - - - -
    - -
    - - - - - - -
    - -
    - {/block} -{/block} diff --git a/themes/classic/templates/customer/history.tpl b/themes/classic/templates/customer/history.tpl deleted file mode 100644 index 422757f9..00000000 --- a/themes/classic/templates/customer/history.tpl +++ /dev/null @@ -1,119 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Order history' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    {l s='Here are the orders you\'ve placed since your account was created.' d='Shop.Theme.Customeraccount'}
    - - {if $orders} - - - - - - - - - - - - - - {foreach from=$orders item=order} - - - - - - - - - - {/foreach} - -
    {l s='Order reference' d='Shop.Theme.Checkout'}{l s='Date' d='Shop.Theme.Checkout'}{l s='Total price' d='Shop.Theme.Checkout'}{l s='Payment' d='Shop.Theme.Checkout'}{l s='Status' d='Shop.Theme.Checkout'}{l s='Invoice' d='Shop.Theme.Checkout'} 
    {$order.details.reference}{$order.details.order_date}{$order.totals.total.value}{$order.details.payment} - - {$order.history.current.ostate_name} - - - {if $order.details.invoice_url} - - {else} - - - {/if} - - - {l s='Details' d='Shop.Theme.Customeraccount'} - - {if $order.details.reorder_url} - {l s='Reorder' d='Shop.Theme.Actions'} - {/if} -
    - -
    - {foreach from=$orders item=order} -
    -
    -
    -

    {$order.details.reference}

    -
    {$order.details.order_date}
    -
    {$order.totals.total.value}
    -
    - - {$order.history.current.ostate_name} - -
    -
    -
    - - {if $order.details.reorder_url} - - {/if} -
    -
    -
    - {/foreach} -
    - - {/if} -{/block} diff --git a/themes/classic/templates/customer/identity.tpl b/themes/classic/templates/customer/identity.tpl deleted file mode 100644 index 646668bb..00000000 --- a/themes/classic/templates/customer/identity.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends 'customer/page.tpl'} - -{block name='page_title'} - {l s='Your personal information' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {render file='customer/_partials/customer-form.tpl' ui=$customer_form} -{/block} diff --git a/themes/classic/templates/customer/my-account.tpl b/themes/classic/templates/customer/my-account.tpl deleted file mode 100644 index 7ef5e760..00000000 --- a/themes/classic/templates/customer/my-account.tpl +++ /dev/null @@ -1,111 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Your account' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    - -
    -{/block} - - -{block name='page_footer'} - {block name='my_account_links'} - - {/block} -{/block} diff --git a/themes/classic/templates/customer/order-detail.tpl b/themes/classic/templates/customer/order-detail.tpl deleted file mode 100644 index 44b9afc2..00000000 --- a/themes/classic/templates/customer/order-detail.tpl +++ /dev/null @@ -1,213 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Order details' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {block name='order_infos'} -
    -
    -
    -
    - - {l - s='Order Reference %reference% - placed on %date%' - d='Shop.Theme.Customeraccount' - sprintf=['%reference%' => $order.details.reference, '%date%' => $order.details.order_date] - } - -
    - {if $order.details.reorder_url} - - {/if} -
    -
    -
    - -
    -
      -
    • {l s='Carrier' d='Shop.Theme.Checkout'} {$order.carrier.name}
    • -
    • {l s='Payment method' d='Shop.Theme.Checkout'} {$order.details.payment}
    • - - {if $order.details.invoice_url} -
    • - - {l s='Download your invoice as a PDF file.' d='Shop.Theme.Customeraccount'} - -
    • - {/if} - - {if $order.details.recyclable} -
    • - {l s='You have given permission to receive your order in recycled packaging.' d='Shop.Theme.Customeraccount'} -
    • - {/if} - - {if $order.details.gift_message} -
    • {l s='You have requested gift wrapping for this order.' d='Shop.Theme.Customeraccount'}
    • -
    • {l s='Message' d='Shop.Theme.Customeraccount'} {$order.details.gift_message nofilter}
    • - {/if} -
    -
    -
    - {/block} - - {block name='order_history'} -
    -

    {l s='Follow your order\'s status step-by-step' d='Shop.Theme.Customeraccount'}

    - - - - - - - - - {foreach from=$order.history item=state} - - - - - {/foreach} - -
    {l s='Date' d='Shop.Theme.Global'}{l s='Status' d='Shop.Theme.Global'}
    {$state.history_date} - - {$state.ostate_name} - -
    -
    - {foreach from=$order.history item=state} -
    -
    {$state.history_date}
    -
    - - {$state.ostate_name} - -
    -
    - {/foreach} -
    -
    - {/block} - - {if $order.follow_up} -
    -

    {l s='Click the following link to track the delivery of your order' d='Shop.Theme.Customeraccount'}

    - {$order.follow_up} -
    - {/if} - - {block name='addresses'} -
    - {if $order.addresses.delivery} -
    -
    -

    {l s='Delivery address %alias%' d='Shop.Theme.Checkout' sprintf=['%alias%' => $order.addresses.delivery.alias]}

    -
    {$order.addresses.delivery.formatted nofilter}
    -
    -
    - {/if} - -
    -
    -

    {l s='Invoice address %alias%' d='Shop.Theme.Checkout' sprintf=['%alias%' => $order.addresses.invoice.alias]}

    -
    {$order.addresses.invoice.formatted nofilter}
    -
    -
    -
    -
    - {/block} - - {$HOOK_DISPLAYORDERDETAIL nofilter} - - {block name='order_detail'} - {if $order.details.is_returnable} - {include file='customer/_partials/order-detail-return.tpl'} - {else} - {include file='customer/_partials/order-detail-no-return.tpl'} - {/if} - {/block} - - {block name='order_carriers'} - {if $order.shipping} -
    - - - - - - - - - - - - {foreach from=$order.shipping item=line} - - - - - - - - {/foreach} - -
    {l s='Date' d='Shop.Theme.Global'}{l s='Carrier' d='Shop.Theme.Checkout'}{l s='Weight' d='Shop.Theme.Checkout'}{l s='Shipping cost' d='Shop.Theme.Checkout'}{l s='Tracking number' d='Shop.Theme.Checkout'}
    {$line.shipping_date}{$line.carrier_name}{$line.shipping_weight}{$line.shipping_cost}{$line.tracking nofilter}
    -
    - {foreach from=$order.shipping item=line} -
    -
      -
    • - {l s='Date' d='Shop.Theme.Global'} {$line.shipping_date} -
    • -
    • - {l s='Carrier' d='Shop.Theme.Checkout'} {$line.carrier_name} -
    • -
    • - {l s='Weight' d='Shop.Theme.Checkout'} {$line.shipping_weight} -
    • -
    • - {l s='Shipping cost' d='Shop.Theme.Checkout'} {$line.shipping_cost} -
    • -
    • - {l s='Tracking number' d='Shop.Theme.Checkout'} {$line.tracking nofilter} -
    • -
    -
    - {/foreach} -
    -
    - {/if} - {/block} - - {block name='order_messages'} - {include file='customer/_partials/order-messages.tpl'} - {/block} -{/block} diff --git a/themes/classic/templates/customer/order-follow.tpl b/themes/classic/templates/customer/order-follow.tpl deleted file mode 100644 index 9006b891..00000000 --- a/themes/classic/templates/customer/order-follow.tpl +++ /dev/null @@ -1,98 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Merchandise returns' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - - {if $ordersReturn && count($ordersReturn)} - -
    {l s='Here is a list of pending merchandise returns' d='Shop.Theme.Customeraccount'}
    - - - - - - - - - - - - - {foreach from=$ordersReturn item=return} - - - - - - - - {/foreach} - -
    {l s='Order' d='Shop.Theme.Customeraccount'}{l s='Return' d='Shop.Theme.Customeraccount'}{l s='Package status' d='Shop.Theme.Customeraccount'}{l s='Date issued' d='Shop.Theme.Customeraccount'}{l s='Returns form' d='Shop.Theme.Customeraccount'}
    {$return.reference}{$return.return_number}{$return.state_name}{$return.return_date} - {if $return.print_url} - {l s='Print out' d='Shop.Theme.Actions'} - {else} - - - {/if} -
    -
    - {foreach from=$ordersReturn item=return} -
    -
      -
    • - {l s='Order' d='Shop.Theme.Customeraccount'} - {$return.reference} -
    • -
    • - {l s='Return' d='Shop.Theme.Customeraccount'} - {$return.return_number} -
    • -
    • - {l s='Package status' d='Shop.Theme.Customeraccount'} - {$return.state_name} -
    • -
    • - {l s='Date issued' d='Shop.Theme.Customeraccount'} - {$return.return_date} -
    • - {if $return.print_url} -
    • - {l s='Returns form' d='Shop.Theme.Customeraccount'} - {l s='Print out' d='Shop.Theme.Actions'} -
    • - {/if} -
    -
    - {/foreach} -
    - - {/if} - -{/block} diff --git a/themes/classic/templates/customer/order-return.tpl b/themes/classic/templates/customer/order-return.tpl deleted file mode 100644 index 6aa23651..00000000 --- a/themes/classic/templates/customer/order-return.tpl +++ /dev/null @@ -1,151 +0,0 @@ -{extends file='customer/page.tpl'} - -{block name='page_title'} -

    {l s='Return details' d='Shop.Theme.Customeraccount'}

    -{/block} - -{block name='page_content'} - {block name='order_return_infos'} -
    -
    -

    - {l - s='%number% on %date%' - d='Shop.Theme.Customeraccount' - sprintf=['%number%' => $return.return_number, '%date%' => $return.return_date]} - -

    -

    {l s='We have logged your return request.' d='Shop.Theme.Customeraccount'}

    -

    {l - s='Your package must be returned to us within %number% days of receiving your order.' - d='Shop.Theme.Customeraccount' - sprintf=['%number%' => $configuration.number_of_days_for_return]}

    -

    - {* [1][/1] is for a HTML tag. *} - {l - s='The current status of your merchandise return is: [1] %status% [/1]' - d='Shop.Theme.Customeraccount' - sprintf=[ - '[1]' => '', - '[/1]' => '', - '%status%' => $return.state_name - ] - } -

    -

    {l s='List of items to be returned:' d='Shop.Theme.Customeraccount'}

    - - - - - - - - - {foreach from=$products item=product} - - - - - {/foreach} - -
    {l s='Product' d='Shop.Theme.Catalog'}{l s='Quantity' d='Shop.Theme.Checkout'}
    - {$product.product_name} - {if $product.product_reference} -
    - {l s='Reference' d='Shop.Theme.Catalog'}: {$product.product_reference} - {/if} - {if $product.customizations} - {foreach from=$product.customizations item="customization"} - - - {/foreach} - {/if} -
    - {$product.product_quantity} -
    -
    -
    - {/block} - - {if $return.state == 2} -
    -
    -

    {l s='Reminder' d='Shop.Theme.Customeraccount'}

    -

    - {l - s='All merchandise must be returned in its original packaging and in its original state.' - d='Shop.Theme.Customeraccount' - }
    - {* [1][/1] is for a HTML tag. *} - {l - s='Please print out the [1]returns form[/1] and include it with your package.' - d='Shop.Theme.Customeraccount' - sprintf=[ - '[1]' => '', - '[/1]' => '' - ] - } -
    - {* [1][/1] is for a HTML tag. *} - {l - s='Please check the [1]returns form[/1] for the correct address.' - d='Shop.Theme.Customeraccount' - sprintf=[ - '[1]' => '', - '[/1]' => '' - ] - } -

    -

    - {l - s='When we receive your package, we will notify you by email. We will then begin processing order reimbursement.' - d='Shop.Theme.Customeraccount' - }
    - - {l - s='Please let us know if you have any questions.' - d='Shop.Theme.Customeraccount' - } -
    - {l - s='If the conditions of return listed above are not respected, we reserve the right to refuse your package and/or reimbursement.' - d='Shop.Theme.Customeraccount' - } -

    -
    -
    - {/if} -{/block} diff --git a/themes/classic/templates/customer/order-slip.tpl b/themes/classic/templates/customer/order-slip.tpl deleted file mode 100644 index feb56629..00000000 --- a/themes/classic/templates/customer/order-slip.tpl +++ /dev/null @@ -1,80 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='customer/page.tpl'} - -{block name='page_title'} - {l s='Credit slips' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    {l s='Credit slips you have received after canceled orders.' d='Shop.Theme.Customeraccount'}
    - {if $credit_slips} - - - - - - - - - - - {foreach from=$credit_slips item=slip} - - - - - - - {/foreach} - -
    {l s='Order' d='Shop.Theme.Customeraccount'}{l s='Credit slip' d='Shop.Theme.Customeraccount'}{l s='Date issued' d='Shop.Theme.Customeraccount'}{l s='View credit slip' d='Shop.Theme.Customeraccount'}
    {$slip.order_reference}{$slip.credit_slip_number}{$slip.credit_slip_date} - -
    -
    - {foreach from=$credit_slips item=slip} -
    - -
    - {/foreach} -
    - {/if} -{/block} diff --git a/themes/classic/templates/customer/page.tpl b/themes/classic/templates/customer/page.tpl deleted file mode 100644 index 099c1f82..00000000 --- a/themes/classic/templates/customer/page.tpl +++ /dev/null @@ -1,46 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='notifications'}{/block} - -{block name='page_content_container'} -
    - {block name='page_content_top'} - {block name='customer_notifications'} - {include file='_partials/notifications.tpl'} - {/block} - {/block} - {block name='page_content'} - - {/block} -
    -{/block} - -{block name='page_footer'} - {block name='my_account_links'} - {include file='customer/_partials/my-account-links.tpl'} - {/block} -{/block} diff --git a/themes/classic/templates/customer/password-email.tpl b/themes/classic/templates/customer/password-email.tpl deleted file mode 100644 index dcfbc605..00000000 --- a/themes/classic/templates/customer/password-email.tpl +++ /dev/null @@ -1,74 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Forgot your password?' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    - -
      - {foreach $errors as $error} -
    • - - - - - -

      {$error}

      -
    • - {/foreach} -
    - -
    - -
    - -
    -
    - - - - -
    -
    - -
    -{/block} - -{block name='page_footer'} - -{/block} diff --git a/themes/classic/templates/customer/password-infos.tpl b/themes/classic/templates/customer/password-infos.tpl deleted file mode 100644 index d829349e..00000000 --- a/themes/classic/templates/customer/password-infos.tpl +++ /dev/null @@ -1,50 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Forgot your password?' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
      - {foreach $successes as $success} -
    • - - - - - -

      {$success}

      -
    • - {/foreach} -
    -{/block} - -{block name='page_footer'} - -{/block} diff --git a/themes/classic/templates/customer/password-new.tpl b/themes/classic/templates/customer/password-new.tpl deleted file mode 100644 index fc376407..00000000 --- a/themes/classic/templates/customer/password-new.tpl +++ /dev/null @@ -1,90 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Reset your password' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} -
    -
      - {foreach $errors as $error} -
    • - - - - - -

      {$error}

      -
    • - {/foreach} -
    -
    - - - -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - - - - - -
    -
    - -
    -
    -
    - -
    -
    -{/block} - -{block name='page_footer'} - -{/block} diff --git a/themes/classic/templates/customer/registration.tpl b/themes/classic/templates/customer/registration.tpl deleted file mode 100644 index 9f717033..00000000 --- a/themes/classic/templates/customer/registration.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {l s='Create an account' d='Shop.Theme.Customeraccount'} -{/block} - -{block name='page_content'} - {block name='register_form_container'} - {$hook_create_account_top nofilter} -
    -

    {l s='Already have an account?' d='Shop.Theme.Customeraccount'} {l s='Log in instead!' d='Shop.Theme.Customeraccount'}

    - {render file='customer/_partials/customer-form.tpl' ui=$register_form} -
    - {/block} -{/block} diff --git a/themes/classic/templates/errors/404.tpl b/themes/classic/templates/errors/404.tpl deleted file mode 100644 index 022157f2..00000000 --- a/themes/classic/templates/errors/404.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - -{block name='page_title'} - {$page.title} -{/block} - -{block name='page_content_container'} - {include file='errors/not-found.tpl'} -{/block} diff --git a/themes/classic/templates/errors/forbidden.tpl b/themes/classic/templates/errors/forbidden.tpl deleted file mode 100644 index 90dacff4..00000000 --- a/themes/classic/templates/errors/forbidden.tpl +++ /dev/null @@ -1,30 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='content'} -
    -
    -{/block} diff --git a/themes/classic/templates/errors/maintenance.tpl b/themes/classic/templates/errors/maintenance.tpl deleted file mode 100644 index de7bea89..00000000 --- a/themes/classic/templates/errors/maintenance.tpl +++ /dev/null @@ -1,61 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-error.tpl'} - -{block name='content'} - -
    - - {block name='page_header_container'} - - {/block} - - {block name='page_content_container'} -
    - {block name='page_content'} - {$maintenance_text nofilter} - {/block} -
    - {/block} - - {block name='page_footer_container'} - - {/block} - -
    - -{/block} diff --git a/themes/classic/templates/errors/not-found.tpl b/themes/classic/templates/errors/not-found.tpl deleted file mode 100644 index 8a932e81..00000000 --- a/themes/classic/templates/errors/not-found.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -
    - {block name='page_content'} - -

    {l s='Sorry for the inconvenience.' d='Shop.Theme.Global'}

    -

    {l s='Search again what you are looking for' d='Shop.Theme.Global'}

    - - {block name='search'} - {hook h='displaySearch'} - {/block} - - {block name='hook_not_found'} - {hook h='displayNotFound'} - {/block} - - {/block} -
    diff --git a/themes/classic/templates/errors/restricted-country.tpl b/themes/classic/templates/errors/restricted-country.tpl deleted file mode 100644 index beb1095e..00000000 --- a/themes/classic/templates/errors/restricted-country.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-error.tpl'} - -{block name='content'} - -
    - - {block name='page_header_container'} - - {/block} - - {block name='page_content_container'} -
    - {block name='page_content'} -

    {l s='403 Forbidden' d='Shop.Theme.Global'}

    -

    {l s='You cannot access this store from your country. We apologize for the inconvenience.' d='Shop.Theme.Global'}

    - {/block} -
    - {/block} - - {block name='page_footer_container'} - - {/block} - -
    - -{/block} diff --git a/themes/classic/templates/errors/static/500.html b/themes/classic/templates/errors/static/500.html deleted file mode 100644 index e69de29b..00000000 diff --git a/themes/classic/templates/errors/static/503.html b/themes/classic/templates/errors/static/503.html deleted file mode 100644 index e69de29b..00000000 diff --git a/themes/classic/templates/index.tpl b/themes/classic/templates/index.tpl deleted file mode 100644 index 5a8535d2..00000000 --- a/themes/classic/templates/index.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='page.tpl'} - - {block name='page_content_container'} -
    - {block name='page_content_top'}{/block} - - {block name='page_content'} - {block name='hook_home'} - {$HOOK_HOME nofilter} - {/block} - {/block} -
    - {/block} diff --git a/themes/classic/templates/layouts/layout-both-columns.tpl b/themes/classic/templates/layouts/layout-both-columns.tpl deleted file mode 100644 index 4a2ddfbb..00000000 --- a/themes/classic/templates/layouts/layout-both-columns.tpl +++ /dev/null @@ -1,112 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - - - - {block name='head'} - {include file='_partials/head.tpl'} - {/block} - - - - - {block name='hook_after_body_opening_tag'} - {hook h='displayAfterBodyOpeningTag'} - {/block} - -
    - {block name='product_activation'} - {include file='catalog/_partials/product-activation.tpl'} - {/block} - - - - {block name='notifications'} - {include file='_partials/notifications.tpl'} - {/block} - -
    - {hook h="displayWrapperTop"} -
    - {block name='breadcrumb'} - {include file='_partials/breadcrumb.tpl'} - {/block} - - {block name="left_column"} -
    - {if $page.page_name == 'product'} - {hook h='displayLeftColumnProduct'} - {else} - {hook h="displayLeftColumn"} - {/if} -
    - {/block} - - {block name="content_wrapper"} -
    - {hook h="displayContentWrapperTop"} - {block name="content"} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} - {hook h="displayContentWrapperBottom"} -
    - {/block} - - {block name="right_column"} -
    - {if $page.page_name == 'product'} - {hook h='displayRightColumnProduct'} - {else} - {hook h="displayRightColumn"} - {/if} -
    - {/block} -
    - {hook h="displayWrapperBottom"} -
    - -
    - {block name="footer"} - {include file="_partials/footer.tpl"} - {/block} -
    - -
    - - {block name='javascript_bottom'} - {include file="_partials/javascript.tpl" javascript=$javascript.bottom} - {/block} - - {block name='hook_before_body_closing_tag'} - {hook h='displayBeforeBodyClosingTag'} - {/block} - - - diff --git a/themes/classic/templates/layouts/layout-content-only.tpl b/themes/classic/templates/layouts/layout-content-only.tpl deleted file mode 100644 index a3f38dc4..00000000 --- a/themes/classic/templates/layouts/layout-content-only.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-both-columns.tpl'} - -{block name='header'}{/block} -{block name='left_column'}{/block} -{block name='right_column'}{/block} - -{block name='content_wrapper'} -
    - {hook h="displayContentWrapperTop"} - {block name='content'} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} - {hook h="displayContentWrapperBottom"} -
    -{/block} - -{block name='footer'}{/block} diff --git a/themes/classic/templates/layouts/layout-error.tpl b/themes/classic/templates/layouts/layout-error.tpl deleted file mode 100644 index 35f221ea..00000000 --- a/themes/classic/templates/layouts/layout-error.tpl +++ /dev/null @@ -1,55 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} - - - - - - - - {block name='head_seo'} - {block name='head_seo_title'}{/block} - - - {/block} - - - {block name='stylesheets'} - {include file="_partials/stylesheets.tpl" stylesheets=$stylesheets} - {/block} - - - - - -
    - {block name='content'} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} -
    - - - - diff --git a/themes/classic/templates/layouts/layout-full-width.tpl b/themes/classic/templates/layouts/layout-full-width.tpl deleted file mode 100644 index bb0d0273..00000000 --- a/themes/classic/templates/layouts/layout-full-width.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-both-columns.tpl'} - -{block name='left_column'}{/block} -{block name='right_column'}{/block} - -{block name='content_wrapper'} -
    - {hook h="displayContentWrapperTop"} - {block name='content'} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} - {hook h="displayContentWrapperBottom"} -
    -{/block} diff --git a/themes/classic/templates/layouts/layout-left-column.tpl b/themes/classic/templates/layouts/layout-left-column.tpl deleted file mode 100644 index 242d95c8..00000000 --- a/themes/classic/templates/layouts/layout-left-column.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-both-columns.tpl'} - -{block name='right_column'}{/block} - -{block name='content_wrapper'} -
    - {hook h="displayContentWrapperTop"} - {block name='content'} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} - {hook h="displayContentWrapperBottom"} -
    -{/block} diff --git a/themes/classic/templates/layouts/layout-right-column.tpl b/themes/classic/templates/layouts/layout-right-column.tpl deleted file mode 100644 index e1fdb524..00000000 --- a/themes/classic/templates/layouts/layout-right-column.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file='layouts/layout-both-columns.tpl'} - -{block name='left_column'}{/block} - -{block name='content_wrapper'} -
    - {hook h="displayContentWrapperTop"} - {block name='content'} -

    Hello world! This is HTML5 Boilerplate.

    - {/block} - {hook h="displayContentWrapperBottom"} -
    -{/block} diff --git a/themes/classic/templates/page.tpl b/themes/classic/templates/page.tpl deleted file mode 100644 index 0438a397..00000000 --- a/themes/classic/templates/page.tpl +++ /dev/null @@ -1,58 +0,0 @@ -{** - * 2007-2019 PrestaShop and Contributors - * - * NOTICE OF LICENSE - * - * This source file is subject to the Academic Free License 3.0 (AFL-3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/AFL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://www.prestashop.com for more information. - * - * @author PrestaShop SA - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) - * International Registered Trademark & Property of PrestaShop SA - *} -{extends file=$layout} - -{block name='content'} - -
    - - {block name='page_header_container'} - {block name='page_title' hide} - - {/block} - {/block} - - {block name='page_content_container'} -
    - {block name='page_content_top'}{/block} - {block name='page_content'} - - {/block} -
    - {/block} - - {block name='page_footer_container'} -
    - {block name='page_footer'} - - {/block} -
    - {/block} - -
    - -{/block} diff --git a/tools/.htaccess b/tools/.htaccess deleted file mode 100644 index 228b4239..00000000 --- a/tools/.htaccess +++ /dev/null @@ -1,9 +0,0 @@ - -RewriteEngine on - -RewriteCond %{REQUEST_FILENAME} -s [OR] -RewriteCond %{REQUEST_FILENAME} -l [OR] -RewriteCond %{REQUEST_FILENAME} -d -RewriteRule ^.*$ - [NC,L] -RewriteRule ^.*$ ../index.php [NC,L] - diff --git a/tools/index.php b/tools/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/tools/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/tools/profiling/.htaccess b/tools/profiling/.htaccess deleted file mode 100644 index 3de9e400..00000000 --- a/tools/profiling/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order deny,allow - Deny from all - - -# Apache 2.4 - - Require all denied - diff --git a/tools/profiling/Controller.php b/tools/profiling/Controller.php deleted file mode 100644 index 872bab5f..00000000 --- a/tools/profiling/Controller.php +++ /dev/null @@ -1,759 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -abstract class Controller extends ControllerCore -{ - protected $total_filesize = 0; - protected $total_query_time = 0; - protected $total_global_var_size = 0; - protected $total_modules_time = 0; - protected $total_modules_memory = 0; - protected $global_var_size = array(); - - protected $modules_perfs = array(); - protected $hooks_perfs = array(); - - protected $array_queries = array(); - - protected $profiler = array(); - - private function getMemoryColor($n) - { - $n /= 1048576; - if ($n > 3) { - return ''.sprintf('%0.2f', $n).''; - } elseif ($n > 1) { - return ''.sprintf('%0.2f', $n).''; - } elseif (round($n, 2) > 0) { - return ''.sprintf('%0.2f', $n).''; - } - - return '-'; - } - - private function getPeakMemoryColor($n) - { - $n /= 1048576; - if ($n > 16) { - return ''.sprintf('%0.1f', $n).''; - } - if ($n > 12) { - return ''.sprintf('%0.1f', $n).''; - } - - return ''.sprintf('%0.1f', $n).''; - } - - private function displaySQLQueries($n) - { - if ($n > 150) { - return ''.$n.' queries'; - } - if ($n > 100) { - return ''.$n.' queries'; - } - - return ''.$n.' quer'.($n == 1 ? 'y' : 'ies').''; - } - - private function displayRowsBrowsed($n) - { - if ($n > 400) { - return ''.$n.' rows browsed'; - } - if ($n > 100) { - return ''.$n.' rows browsed'; - } - - return ''.$n.' row'.($n == 1 ? '' : 's').' browsed'; - } - - private function getPhpVersionColor($version) - { - if (version_compare($version, '5.6') < 0) { - return ''.$version.' (Upgrade strongly recommended)'; - } elseif (version_compare($version, '7.1') < 0) { - return ''.$version.' (Consider upgrading)'; - } - - return ''.$version.' (OK)'; - } - - private function getMySQLVersionColor($version) - { - if (version_compare($version, '5.5') < 0) { - return ''.$version.' (Upgrade strongly recommended)'; - } elseif (version_compare($version, '5.6') < 0) { - return ''.$version.' (Consider upgrading)'; - } - - return ''.$version.' (OK)'; - } - - private function getLoadTimeColor($n, $kikoo = false) - { - if ($n > 1.6) { - return ''.round($n * 1000).''.($kikoo ? ' ms - You\'d better run your shop on a toaster' : ''); - } elseif ($n > 0.8) { - return ''.round($n * 1000).''.($kikoo ? ' ms - OK... for a shared hosting' : ''); - } elseif ($n > 0) { - return ''.round($n * 1000).''.($kikoo ? ' ms - Unicorn powered webserver!' : ''); - } - - return '-'.($kikoo ? ' ms - Faster than light' : ''); - } - - private function getTotalQueriyingTimeColor($n) - { - if ($n >= 100) { - return ''.$n.''; - } elseif ($n >= 50) { - return ''.$n.''; - } - - return ''.$n.''; - } - - private function getNbQueriesColor($n) - { - if ($n >= 100) { - return ''.$n.''; - } elseif ($n >= 50) { - return ''.$n.''; - } - - return ''.$n.''; - } - - private function getTimeColor($n) - { - if ($n > 4) { - return 'style="color:red"'; - } - if ($n > 2) { - return 'style="color:#EF8B00"'; - } - - return 'style="color:green"'; - } - - private function getQueryColor($n) - { - if ($n > 5) { - return 'style="color:red"'; - } - if ($n > 2) { - return 'style="color:#EF8B00"'; - } - - return 'style="color:green"'; - } - - private function getTableColor($n) - { - if ($n > 30) { - return 'style="color:red"'; - } - if ($n > 20) { - return 'style="color:#EF8B00"'; - } - - return 'style="color:green"'; - } - - private function getObjectModelColor($n) - { - if ($n > 50) { - return 'style="color:red"'; - } - if ($n > 10) { - return 'style="color:#EF8B00"'; - } - - return 'style="color:green"'; - } - - protected function stamp($block) - { - return array('block' => $block, 'memory_usage' => memory_get_usage(), 'peak_memory_usage' => memory_get_peak_usage(), 'time' => microtime(true)); - } - - public function __construct() - { - $this->profiler[] = $this->stamp('config'); - - parent::__construct(); - $this->profiler[] = $this->stamp('__construct'); - } - - public function run() - { - $this->init(); - $this->profiler[] = $this->stamp('init'); - - if ($this->checkAccess()) { - $this->profiler[] = $this->stamp('checkAccess'); - - if (!$this->content_only && ($this->display_header || (isset($this->className) && $this->className))) { - $this->setMedia(); - $this->profiler[] = $this->stamp('setMedia'); - } - - $this->postProcess(); - $this->profiler[] = $this->stamp('postProcess'); - - if (!$this->content_only && ($this->display_header || (isset($this->className) && $this->className))) { - $this->initHeader(); - $this->profiler[] = $this->stamp('initHeader'); - } - - $this->initContent(); - $this->profiler[] = $this->stamp('initContent'); - - if (!$this->content_only && ($this->display_footer || (isset($this->className) && $this->className))) { - $this->initFooter(); - $this->profiler[] = $this->stamp('initFooter'); - } - - if ($this->ajax) { - $action = Tools::toCamelCase(Tools::getValue('action'), true); - if (!empty($action) && method_exists($this, 'displayAjax'.$action)) { - $this->{'displayAjax'.$action}(); - } elseif (method_exists($this, 'displayAjax')) { - $this->displayAjax(); - } - - return; - } - } else { - $this->initCursedPage(); - } - - $this->displayProfiling(); - } - - private function getVarSize($var) - { - $start_memory = memory_get_usage(); - - try { - $tmp = Tools::unSerialize(serialize($var)); - } catch (Exception $e) { - $tmp = $this->getVarData($var); - } - $size = memory_get_usage() - $start_memory; - - return $size; - } - - private function getVarData($var) - { - if (is_object($var)) { - return $var; - } - - return (string)$var; - } - - protected function processProfilingData() - { - global $start_time; - - // Including a lot of files uses memory - foreach (get_included_files() as $file) { - $this->total_filesize += filesize($file); - } - - // Sum querying time - foreach (Db::getInstance()->queries as $data) { - $this->total_query_time += $data['time']; - } - - foreach ($GLOBALS as $key => $value) { - if ($key != 'GLOBALS') { - $this->total_global_var_size += ($size = $this->getVarSize($value)); - if ($size > 1024) { - $this->global_var_size[$key] = round($size / 1024); - } - } - } - arsort($this->global_var_size); - - $cache = Cache::retrieveAll(); - $this->total_cache_size = $this->getVarSize($cache); - - $queries = Db::getInstance()->queries; - uasort($queries, 'prestashop_querytime_sort'); - foreach ($queries as $data) { - $query_row = array( - 'time' => $data['time'], - 'query' => $data['query'], - 'location' => str_replace('\\', '/', substr($data['stack'][0]['file'], strlen(_PS_ROOT_DIR_))).':'.$data['stack'][0]['line'], - 'filesort' => false, - 'rows' => 1, - 'group_by' => false, - 'stack' => array(), - ); - if (preg_match('/^\s*select\s+/i', $data['query'])) { - $explain = Db::getInstance()->executeS('explain '.$data['query']); - if (stristr($explain[0]['Extra'], 'filesort')) { - $query_row['filesort'] = true; - } - foreach ($explain as $row) { - $query_row['rows'] *= $row['rows']; - } - if (stristr($data['query'], 'group by') && !preg_match('/(avg|count|min|max|group_concat|sum)\s*\(/i', $data['query'])) { - $query_row['group_by'] = true; - } - } - - array_shift($data['stack']); - foreach ($data['stack'] as $call) { - $query_row['stack'][] = str_replace('\\', '/', substr($call['file'], strlen(_PS_ROOT_DIR_))).':'.$call['line']; - } - - $this->array_queries[] = $query_row; - } - - uasort(ObjectModel::$debug_list, function ($a, $b) { return (count($a) < count($b)) ? 1 : -1; }); - arsort(Db::getInstance()->tables); - arsort(Db::getInstance()->uniqQueries); - } - - protected function displayProfilingLinks() - { - echo ' -
    -
      -
    1. Stopwatch SQL
    2. -
    3. Doubles
    4. -
    5. Tables stress
    6. - '.(isset(ObjectModel::$debug_list) ? '
    7. ObjectModel instances
    8. ' : '').' -
    9. Included Files
    10. -
    -
    '; - } - - protected function displayProfilingStyle() - { - echo ' - - '; - } - - protected function displayProfilingSummary() - { - global $start_time; - - echo ' -
    - - - - - - - '; - foreach ($this->global_var_size as $global => $size) { - echo ''; - } - echo ' -
    Load Time'.$this->getLoadTimeColor($this->profiler[count($this->profiler) - 1]['time'] - $start_time, true).'
    Querying Time'.$this->getTotalQueriyingTimeColor(round(1000 * $this->total_query_time)).' ms -
    Queries'.$this->getNbQueriesColor(count($this->array_queries)).'
    Memory Peak Usage'.$this->getPeakMemoryColor($this->profiler[count($this->profiler) - 1]['peak_memory_usage']).' Mb
    Included Files'.count(get_included_files()).' files - '.$this->getMemoryColor($this->total_filesize).' Mb
    PrestaShop Cache'.$this->getMemoryColor($this->total_cache_size).' Mb
    Global vars'.$this->getMemoryColor($this->total_global_var_size).' Mb
    -
    '; - } - - protected function displayProfilingConfiguration() - { - echo ' -
    - - - - - - - - -
    PrestaShop Version'._PS_VERSION_.'
    PHP Version'.$this->getPhpVersionColor(PHP_VERSION).'
    MySQL Version'.$this->getMySQLVersionColor(Db::getInstance()->getVersion()).'
    Memory Limit'.ini_get('memory_limit').'
    Max Execution Time'.ini_get('max_execution_time').'s
    Smarty Cacheenabled' : 'red">disabled').'
    Smarty Compilationnever recompile' : (Configuration::get('PS_SMARTY_FORCE_COMPILE') == 1 ? '#EF8B00">auto' : 'red">force compile')).'
    -
    '; - } - - protected function displayProfilingRun() - { - global $start_time; - - echo ' -
    - - '; - $last = array('time' => $start_time, 'memory_usage' => 0); - foreach ($this->profiler as $row) { - if ($row['block'] == 'checkAccess' && $row['time'] == $last['time']) { - continue; - } - echo ' - - - - - - '; - $last = $row; - } - echo ' -
     TimeCumulated TimeMemory UsageMemory Peak Usage
    '.$row['block'].''.$this->getLoadTimeColor($row['time'] - $last['time']).' ms'.$this->getLoadTimeColor($row['time'] - $start_time).' ms'.$this->getMemoryColor($row['memory_usage'] - $last['memory_usage']).' Mb'.$this->getMemoryColor($row['peak_memory_usage']).' Mb
    -
    '; - } - - protected function displayProfilingHooks() - { - $count_hooks = count($this->hooks_perfs); - - echo ' -
    - - - - - - '; - foreach ($this->hooks_perfs as $hook => $hooks_perfs) { - echo ' - - - - - '; - foreach ($hooks_perfs['modules'] as $module => $perfs) { - echo ' - - - - - '; - } - } - echo ' - - - - -
    HookTimeMemory Usage
    - '.$hook.' - - '.$this->getLoadTimeColor($hooks_perfs['time']).' ms - - '.$this->getMemoryColor($hooks_perfs['memory']).' Mb -
    '.($count_hooks == 1 ? '1 hook' : (int)$count_hooks.' hooks').''.$this->getLoadTimeColor($this->total_modules_time).' ms'.$this->getMemoryColor($this->total_modules_memory).' Mb
    -
    '; - } - - protected function displayProfilingModules() - { - $count_modules = count($this->modules_perfs); - - echo ' -
    - - - - - - '; - foreach ($this->modules_perfs as $module => $modules_perfs) { - echo ' - - - - - '; - foreach ($modules_perfs['methods'] as $hook => $perfs) { - echo ' - - - - - '; - } - } - echo ' - - - - -
    ModuleTimeMemory Usage
    - '.$module.' - - '.$this->getLoadTimeColor($modules_perfs['time']).' ms - - '.$this->getMemoryColor($modules_perfs['memory']).' Mb -
    '.($count_modules == 1 ? '1 module' : (int)$count_modules.' modules').''.$this->getLoadTimeColor($this->total_modules_time).' ms'.$this->getMemoryColor($this->total_modules_memory).' Mb
    -
    '; - } - - protected function displayProfilingStopwatch() - { - echo ' -
    -

    Stopwatch SQL - '.count($this->array_queries).' queries

    - - - - - - - - - - - - '; - foreach ($this->array_queries as $data) { - $callstack = implode('
    ', $data['stack']); - $callstack_md5 = md5($callstack); - - echo ' - - - - - - - - '; - } - echo '
    QueryTime (ms)RowsFilesortGroup ByLocation
    '.preg_replace("/(^[\s]*)/m", "", htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false)).'
    getTimeColor($data['time'] * 1000).'>'.(round($data['time'] * 1000, 1) < 0.1 ? '< 1' : round($data['time'] * 1000, 1)).''.(int)$data['rows'].''.($data['filesort'] ? 'Yes' : '').''.($data['group_by'] ? 'Yes' : '').' - '.$data['location'].' - -
    -
    '; - } - - protected function displayProfilingDoubles() - { - echo '
    -

    Doubles

    - '; - foreach (Db::getInstance()->uniqQueries as $q => $nb) { - if ($nb > 1) { - echo ''; - } - } - echo '
    getQueryColor($nb).'>'.$nb.'
    '.$q.'
    -
    '; - } - - protected function displayProfilingTableStress() - { - echo '
    -

    Tables stress

    - '; - foreach (Db::getInstance()->tables as $table => $nb) { - echo ''; - } - echo '
    getTableColor($nb).'>'.$nb.' '.$table.'
    -
    '; - } - - protected function displayProfilingObjectModel() - { - echo ' -
    -

    ObjectModel instances

    - - '; - foreach (ObjectModel::$debug_list as $class => $info) { - echo ' - - - - '; - } - echo '
    NameInstancesSource
    '.$class.'getObjectModelColor(count($info)).'>'.count($info).''; - foreach ($info as $trace) { - echo str_replace(array(_PS_ROOT_DIR_, '\\'), array('', '/'), $trace['file']).' ['.$trace['line'].']
    '; - } - echo '
    -
    '; - } - - protected function displayProfilingFiles() - { - $i = 0; - - echo '
    -

    Included Files

    - - '; - foreach (get_included_files() as $file) { - $file = str_replace('\\', '/', str_replace(_PS_ROOT_DIR_, '', $file)); - if (strpos($file, '/tools/profiling/') === 0) { - continue; - } - echo ''; - } - echo '
    #Filename
    '.(++$i).''.$file.'
    -
    '; - } - - public function displayProfiling() - { - if (!empty($this->redirect_after)) { - echo ' - - - - - - - - -
    -
    - -
    '; - } else { - // Call original display method - $this->display(); - $this->profiler[] = $this->stamp('display'); - } - - // Process all profiling data - $this->processProfilingData(); - - // Add some specific style for profiling information - $this->displayProfilingStyle(); - - echo '
    '; - - echo '
    '; - $this->displayProfilingSummary(); - $this->displayProfilingConfiguration(); - $this->displayProfilingRun(); - echo '
    '; - $this->displayProfilingHooks(); - $this->displayProfilingModules(); - $this->displayProfilingLinks(); - echo '
    '; - - $this->displayProfilingStopwatch(); - $this->displayProfilingDoubles(); - $this->displayProfilingTableStress(); - if (isset(ObjectModel::$debug_list)) { - $this->displayProfilingObjectModel(); - } - $this->displayProfilingFiles(); - - if (!empty($this->redirect_after)) { - echo '
    '; - } - } -} - -function prestashop_querytime_sort($a, $b) -{ - if ($a['time'] == $b['time']) { - return 0; - } - - return ($a['time'] > $b['time']) ? -1 : 1; -} diff --git a/tools/profiling/Db.php b/tools/profiling/Db.php deleted file mode 100644 index 2872d71c..00000000 --- a/tools/profiling/Db.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -abstract class Db extends DbCore -{ - /** - * Add SQL_NO_CACHE in SELECT queries - * - * @var bool - */ - public $disableCache = true; - - /** - * Total of queries - * - * @var int - */ - public $count = 0; - - /** - * List of queries - * - * @var array - */ - public $queries = array(); - - /** - * List of uniq queries (replace numbers by XX) - * - * @var array - */ - public $uniqQueries = array(); - - /** - * List of tables - * - * @var array - */ - public $tables = array(); - - /** - * Execute the query and log some informations - * - * @see DbCore::query() - */ - public function query($sql) - { - $explain = false; - if (preg_match('/^\s*explain\s+/i', $sql)) { - $explain = true; - } - - if (!$explain) { - $uniqSql = preg_replace('/[\'"][a-f0-9]{32}[\'"]/', 'XX', $sql); - $uniqSql = preg_replace('/[0-9]+/', 'XX', $uniqSql); - if (!isset($this->uniqQueries[$uniqSql])) { - $this->uniqQueries[$uniqSql] = 0; - } - $this->uniqQueries[$uniqSql]++; - - // No cache for query - if ($this->disableCache && !stripos($sql, 'SQL_NO_CACHE')) { - $sql = preg_replace('/^\s*select\s+/i', 'SELECT SQL_NO_CACHE ', trim($sql)); - } - - // Get tables in query - preg_match_all('/(from|join)\s+`?'._DB_PREFIX_.'([a-z0-9_-]+)/ui', $sql, $matches); - foreach ($matches[2] as $table) { - if (!isset($this->tables[$table])) { - $this->tables[$table] = 0; - } - $this->tables[$table]++; - } - - $start = microtime(true); - } - - // Execute query - $result = parent::query($sql); - - if (!$explain) { - $end = microtime(true); - - $stack = debug_backtrace(false); - while (preg_match('@[/\\\\]classes[/\\\\]db[/\\\\]@i', $stack[0]['file'])) { - array_shift($stack); - } - $stack_light = array(); - foreach ($stack as $call) { - $stack_light[] = array('file' => isset($call['file']) ? $call['file'] : 'undefined', 'line' => isset($call['line']) ? $call['line'] : 'undefined'); - } - - $this->queries[] = array( - 'query' => $sql, - 'time' => $end - $start, - 'stack' => $stack_light, - ); - } - - return $result; - } -} diff --git a/tools/profiling/ObjectModel.php b/tools/profiling/ObjectModel.php deleted file mode 100644 index ec5a2bb0..00000000 --- a/tools/profiling/ObjectModel.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -abstract class ObjectModel extends ObjectModelCore -{ - public static $debug_list = array(); - - public function __construct($id = null, $id_lang = null, $id_shop = null) - { - parent::__construct($id, $id_lang, $id_shop); - - $classname = get_class($this); - if (!isset(self::$debug_list[$classname])) { - self::$debug_list[$classname] = array(); - } - - $class_list = array('ObjectModel', 'ObjectModelCore', $classname, $classname.'Core'); - $backtrace = debug_backtrace(); - foreach ($backtrace as $trace_id => $row) { - if (!isset($backtrace[$trace_id]['class']) || !in_array($backtrace[$trace_id]['class'], $class_list)) { - break; - } - } - $trace_id--; - - self::$debug_list[$classname][] = array( - 'file' => @$backtrace[$trace_id]['file'], - 'line' => @$backtrace[$trace_id]['line'], - ); - } -} diff --git a/tools/profiling/Tools.php b/tools/profiling/Tools.php deleted file mode 100644 index d2ad7ed0..00000000 --- a/tools/profiling/Tools.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -class Tools extends ToolsCore -{ - public static function redirect($url, $base_uri = __PS_BASE_URI__, Link $link = null, $headers = null) - { - if (!$link) { - $link = Context::getContext()->link; - } - - if (strpos($url, 'http://') === false && strpos($url, 'https://') === false && $link) { - if (strpos($url, $base_uri) === 0) { - $url = substr($url, strlen($base_uri)); - } - if (strpos($url, 'index.php?controller=') !== false && strpos($url, 'index.php/') == 0) { - $url = substr($url, strlen('index.php?controller=')); - if (Configuration::get('PS_REWRITING_SETTINGS')) { - $url = static::strReplaceFirst('&', '?', $url); - } - } - - $explode = explode('?', $url); - // don't use ssl if url is home page - // used when logout for example - $use_ssl = !empty($url); - $url = $link->getPageLink($explode[0], $use_ssl); - if (isset($explode[1])) { - $url .= '?'.$explode[1]; - } - } - - // Send additional headers - if ($headers) { - if (!is_array($headers)) { - $headers = array($headers); - } - - foreach ($headers as $header) { - header($header); - } - } - - Context::getContext()->controller->setRedirectAfter($url); - } - - public static function getDefaultControllerClass() - { - if (isset(Context::getContext()->employee) && Validate::isLoadedObject(Context::getContext()->employee) && isset(Context::getContext()->employee->default_tab)) { - $default_controller = Tab::getClassNameById((int)Context::getContext()->employee->default_tab); - } - if (empty($default_controller)) { - $default_controller = 'AdminDashboard'; - } - $controllers = Dispatcher::getControllers(array(_PS_ADMIN_DIR_.'/tabs/', _PS_ADMIN_CONTROLLER_DIR_, _PS_OVERRIDE_DIR_.'controllers/admin/')); - if (!isset($controllers[strtolower($default_controller)])) { - $default_controller = 'adminnotfound'; - } - $controller_class = $controllers[strtolower($default_controller)]; - - return $controller_class; - } - - public static function redirectLink($url) - { - if (!preg_match('@^https?://@i', $url)) { - if (strpos($url, __PS_BASE_URI__) !== false && strpos($url, __PS_BASE_URI__) == 0) { - $url = substr($url, strlen(__PS_BASE_URI__)); - } - $explode = explode('?', $url); - $url = Context::getContext()->link->getPageLink($explode[0]); - if (isset($explode[1])) { - $url .= '?'.$explode[1]; - } - } - } - - public static function redirectAdmin($url) - { - if (!is_object(Context::getContext()->controller)) { - try { - $controller = Controller::getController(static::getDefaultControllerClass()); - $controller->setRedirectAfter($url); - $controller->run(); - Context::getContext()->controller = $controller; - die(); - } catch (PrestaShopException $e) { - $e->displayMessage(); - } - } else { - Context::getContext()->controller->setRedirectAfter($url); - } - } -} diff --git a/tools/profiling/index.php b/tools/profiling/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/tools/profiling/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/translations/.DS_Store b/translations/.DS_Store deleted file mode 100644 index de70136faad045e2b01187dba5f7d1687efd4a14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyH3ME5S$ARGNMUIc{N@BzywoJM?#`Qi6IoWY(;=l`h)lnev8@Lld;X46tX5r00q@8Ux0FG0-s}-v>_>%p$gm;nTq( z907<4%|SR1|8_(#24WVmRiuUDG?l2SE*>$Qrqk|YTo$oa)O5H|nd`*LE}l?as7|{N z;c%IvjmCg6Fl69FFK5#KZ;qe;he>v23>X7{iUF78%Y4CGioJDobJA-)^?@oPajjyP j!bxbwjFnb=K@CE?mkBY8*ecROu^)jzgAK;Ok23HH{P#n> diff --git a/translations/cldr/.htaccess b/translations/cldr/.htaccess deleted file mode 100644 index ec2b13ce..00000000 --- a/translations/cldr/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -# Apache 2.2 - - Order deny,allow - Allow from all - - -# Apache 2.4 - - Require all granted - diff --git a/translations/export/index.php b/translations/export/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/translations/export/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/translations/index.php b/translations/index.php deleted file mode 100644 index 76cd9dd3..00000000 --- a/translations/index.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; diff --git a/translations/sf-en-GB.zip b/translations/sf-en-GB.zip deleted file mode 100644 index 09526331d241630e238b0f1777ab5cc36281ef7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544346 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 % zx$Bpyolir|Nt+0YNvi;P47dPLED&>Sl3(gJ>OcIf`m+X~lHgNFN)Bub ze$-USe?{|CZS!1ASSs3j1XEYA@{fpEm?=ApyiC5O4H$ZMMGyL2f&l-yQzKr zt4Iw;Q7?R?U)Dt^6FCQ~cydK_)FGCIb_5iE=pLT{Zi3h#ZPZLOk3`BEE`sogk^?Fr z&Er{x%l7E?$@qxWHX0$5SE8xFb-;MEh?5K;tAl7cx5^lJZ`RC(p!FvtR4yUMt~0Mu zyy)IQuWh`DrBr%OAJMPJrb*rh?kgn$0w|%_J^zmmA7ZFK4H6kmn+$3(aBQu|d!TUD zR%@Tw&na8|RLKWT!0*r5sS`~$X{u$Eng}vp3h^L8A{igZW#U{Tfw())hOPlaBWLhQ z7;;XSwQ8>M&y9RL(e_H+WiLHDs~LuQ<4^{z007G&{$BtZsLbx7fxyCdwD~QOG^vD> zQ|oIf1!DCuwfqjudXr{ymp_t{BTQ((2_18@k1>7=5_K%hD#u*_(%wI@38Uz}HfnCD zFll(b;T?$fn?r8fTV3qvb9ucbMgyWH{YwAjL=7|v1sy2680QG-9}ZzCPe5PG-t5b( z{D?zQ@2)7C6B4B;N;yjmT}SzNSO1^fW9~H(6c}p>3S!xiwB(d#{o6Ve4jhQwZBsr` z11;^;Cl;Y)0Z1sU!kMx{bj`F`dLn^G1`!!yYyowf zt_JWw5}UWMVkeIDdBS;nU=J~%MZ#EhoNKP1=r5~SN6x>>GOLd=ZX0xT9C9Es7Ju*{ zpv{TXWe2&(d!`%|7D!)J_}YDqUJy4&cXDM;=<9!VCLstk{l_@T2^~RnbP#4S8^}=f z5dLA3T@zSoQ0nK)e2)0Dyl~nF161@2Pnu8U&tCKEuy8z(WH^lB*zHbJj+r=yN+*wi zIfG5TqijBYpnCy1-v<8R3=ad;wN2q|=F7By%79kV_M}Bie zkVGJhK!JZm80*4Ms8E-9-IDOF>_7e74(%rZc%P?nKHW2yjsnt2X;V9FI5;n8)!7u$ zJ?yF6oR6n^>`Tm0M=IdaPjTXJx`lz`6w;@nX#s*m5u;lomZL4GYRZVj3X`A74CDKu z3QPQ&!^Tet++Q%KMtAd^gZ1TqLq+!Lggq}go#&uq$riL35TaucXg@5AVj2Ph5J5xM z0s?#jZGT?8o}MLjwd-HIll}2X!3tsEc^s*F9%ekA(0&_f#-eX42}R$fANbb z5SpXtIw9tOQNE&qfL*P}9*B5-!lI9gT`CnKt?OX039d2chdhqD*#}e0&GWvNY^AXk zkvTbr^M}o-JkK%KS1H|8axpH0TmFiaSnT;@2Sx~DML~4(5Z}bUjFt|L8U%$2Dcerd z$VR&ON7Pj@9wCawB;yq6TMugwvN7B~#ygwSGScW18apIluMUc*UB`)S zY^~{RhD-xIOwQU>6?%wh^QjZY3ltWHbLIh;MqBHTHQ3Bm*dz?+Soctd%=2^%VOEFy zdGu%z89JGOaxptaKRMPFWcou>myzTf7e)U_Du`$c90rfM9dn!XWH}IoW`NmV%IY6N z)t8QKCTNr`_JYnR+f|_;0)&_MrLM4`?@RdC&+}S~twm6yY!e;J42F*S$aDY^kN`Va zMFc2p8J0QK<2G{D4vgW($VU#z+gCGeGVAGwF?$O_$xVI50d3bTX>si zYPV#^%VHJSE}vu1f7gj?Tb}|j!f>;07^)>HB`oLqe)sa0(Z327+G?6BINAm$mQVGf z(gi*iS96GwYDM+C>5|}xd!HtVW%7?sDW8^p9q<2*odt;T2i&Cu09gC}ugv!UMtCKnqglbL?Z5~w;T+Jn_T{9ynNWj zjiuw^w&u=NHOa|pndeIgbwcK~4HMd*%aEfLXI@p^XBC&{vuSvI^~oDvxUAt$Kd)i^ zhAOzvcDbmZlj~*u-S4lQu8;js{_gj7oujS!*_W&~_00mmp3rH-$IdWRTfMmZ=cn&g z3*0v9tI^f3ly8-^)-DL zVif!jp3W5 zFuGf|BhOG_H>MhPx4qXlp`w3f!GT>Z8VW#nj4u8>eoQ~>jRh^`_-=%i7_I2d`_yU}L02c82u7U&X>Yy9(?_OLIrtJQR^_SY<{I(XC zeEE{GYf(@~M}q~B&t}vMawzbCq6a~p%Knr!V_48%%Qh+(QcF4GqfMHy??v*-?uvdG zz2n)W!+k7)uIYYzdf0q!VG16Sf;*50%CeFECj5Q0Ye!eNmXgEA)#y( zZ+S3(OCa9)_FS`Ve&h2A@Vg#%1|_?Gp51DHOc-|m7OZ%pM`Ul?JY>t_6C)9U1dK1( zZJC8-dyUg-Eb&R&<`e0`4tct7C&1$ojnTgU5xDAtrDKfMxE@t4G)0_CBSuJy4G^an zjU}UoqXN%>6-&@WslW^P-O{emJ{|gC-;PA0v=F$&rx)4pZr3E4I+oz5a}<*KleDCE zYFxdn1{G;K;)Ph1@aAIILn+Dw9Eiy|JIN)lz)EK`coy`s!!;t~8em|&z;Ii_bn4=# z?s@@^@sX%#(4pyu@<{~uU77`?uU_RHlCOE)(XR7NquabSuNICqAT^#8l-`oO9yYbm zv_ub5SO(Ff?aRy9BXPt-V%D^6B!Q%rCg4~T_{@ZvLV`>Q5fxg_qjnXFG`iQD%)SjZ zy6LikXzmUlMH)=17r!$*mZ7@CZVetS$zT#bNX1YtQ{3IJYE0!`!&@0CBAI<}+JKo* zekjZd$cV(bKJ20a2XWpTl{}!{F7MJ#R3dePZQoQelTZIp&51DW(ffoUQo&IOsi_SC znRB2dKEb3FWPoD**8{;%%TEY`ZS6KqPRB~vyWG3MIwWXjIlD;k4u?mseR5xsN;)W- zA}lyRNtuYsiYHA>@dFl>@8zc1HezlON-7Y;ehZGb^n&ZGJ6rSE2m00#MX`GsD5UVr zFo~6i0jf_ZDd{NE-|Gn6m`cm(uZg(UR(#$fAHkuZ-%$*FK_OP6+W9O_$Ui!!YHx6%9as4m6uG=ALf@3#yPNS|wfJJqTjD4tSr zIJ6>JK;pCPO>^rQsn zj2Hlk)CD(6XI5oCQ^@tpNMk`P!*eC)ON=&QN*=zgRFV#zr#@V-3vifl5!w--cVEcR zY58=}EAPBJOq{*ANe+g;8Si zOd^Wor_YC^tk3E2DqEm`^BsT+Y|Cgyn&(%wc73Rt&%?Ylkx6-D{~jh+iOtFkK@{lI zqr$JlX^%stQ5=?BMFon|;gQ(#*s@d>e}vWkrw-)CXLi}y{C%|%ni|)%QS_NpwYgj> zu8)R;!>w)Mf!pDCTNrJx#&!+(hfOzy6pms#GCMTHDlDvZPWc?9B*Yib!d9@^6 z@g5>orev6auR^}NyF~}uPuqIvFCpDS=jX}6$5(Z`2aOEy^GvEq8Ra*riAN#`I6{X5 z3=^2#@TAF%gT|YM$%_!5672_!nAvQn9>I`z%GO}JDI$PDRcbCsPh(t0pw3L?mc~q4A0O znl&E+FDD_n@>PZF1SX)9Wd>D(Y~fXyr$QaOnbfv+;{>#f6?GlDlGF4H881#NWG;*^-b4|y-LIbj!k31D1|D}go*)%3#Q&MPS0P|RJ zqQvlc;uO!_SR%q-wCvcCbrnr5*(ly?J)Di+G~>URgpZc&_2vpd>B~D+1c;h!m@TWJ zPGZL;PN+R`ec9RU&cAolL_SVP9FuI7`0o`+th?(r5FAqEN_gSKT5wvFlN2w(SHZ&Q z!rSdb!h$?7QHLG_hT@-@P?u%LQ}Uh7+1Hm$^TbS(f(U(o$BbG99S8~Bb&Y--&5^Lm z*p`rEPNJImiOu!C!8XlISQ0yGm`4<;Vii61qm_1`z#5dkB=aiH+AA?QEi2a2O4Fk-@ z69W*h?Q2c%_N1LDca+HJdc7;B+m5%6ffxLM*PH3Vk4H10&t6aU^QN_Vvf6u&q)cJ| zXo=CWQq8e>I0_l*&JfxcD8=hh3ufIX(!QMuM3sLXl=4r#U7^^m#kM$}4p>0UuHTt! z%+PTL5IT&67=XFtH_9`p&5!#2FUsDrNfaPRux;D6Z5y|3+qP}nwr%USZQHhOy}KLp zCUz$F!|ZRUs>saB%yZlfdsb-QpHB1E&wL^SMG9CH;Ey!0Msf@k81{W0*qC%P!sEV! zjm}_%BmAr`C3q4UtD3Diu}r8G4Q}NfB!*+9pH9P3{M(VhghN6efzm2IO`(#3e|$PI z=)^ho-tM|GVPkPr?)68z;QE;@vWrm$=OjYB8|azE?ilP@WPuM5rJA*( z+d9df{5>{Ti{{9@THp7v920~WGSsA}!GUam z=x0wza~MU}aTs#82a2P8Hje5w+F63;a^l!gQYs;AfIooORL2RL`cQ_*_C$mQuWTd8zQZeh}3)z)ncjcpJpXkp8X^jE(YWE)}1 z{>WQAOHf?xxXkS=~onr;4C z2t0nYO=U7C6%k9C&zVt$H6Q+~sWK0GU`ti~H1|8Um~EFn#^dtlTaHU>P3K1ds7%aI zllU|u%5g}&FB@w+&I3xMId#rSJ^4P)FmbhPn<$b~rN}*+c{ENaY^fRW2t&$EhMhML zTirL{N^pDNC1%g+_>r7Ne?z^e6V1pR07aoV!$z5~l(K{fsIjp7h7LD2pRaDe*k+z%$Td^c)n!0f zWTettRgD}NHaxC{hjN%{*T*MZ;7ltKgysMFqpfFR1f-h6x9Bc1aD2cE_c}TW9Hxc& z$=Q|IwzCTClriO@tPD)GSE8@{3)-9;9#^zCHnAE#*X*Tuz1>zssRx&=nPA3XVbGUJ zg;zRhQTs$DF&P*cn+=|b9<4SFp0`CuIP((+JBa(pbkbsLFc@G_kuYY2iIo&hME+-D zz-k&+UBRK=YhfWci9HfO$UcBy*3=S z_o~|kly_@Scq{JMLeqM}!olaH9OWNP%Cem}zMEP?Nip7eo#CVvL_FYF=o z8uS){gW6R0HFfo^I1woWA;F!0k*;AX#sLK^7(fQ}fi&lyJ37i+@5ZsuvSYcS$=HK% z;AUX-CKcS{5oHyd>okqu0FQCIUXNxuOqGgMI-JtNGPJ-GLyDAy~!N5@CX6q6cjQ!7g&H8osun9)h7Dpu=QfG zeY?(=-X_zoYITSD>ul}esqn0!vAdM*On%K`$d2Yd#wr^ru|Eg3=f2ervgb|d$a&Xp zl+N#)^cfEw?QLMADwq+*cW5Xxa)@KBQjaSe#i*kQO|CAcx}$l9DG$aA$2><&xi*is zN5<5;fX~VTxMFevQ3HBH4Wk0FimkSlutmu*$s_40TW1t)T<9e>8F4R-1sdQg(}f`= z$fz|>3J@u25OhQzgz|=1a$za5tDxZIr*fR#0txVq7uw(6F2D6j!3&d_!U3(qaClW_ z^f6?PMH&mo7#wd3r!O*cjf{}E(**iG%u|!;!a0^PI~8&1Bw}Ie^1s9@l`&K6{(!@Q zHB(Iv-B87&&Wevn;!ERMuMw$q7*Y!&vx!Pfnr6h%;($vZim#9}R9ye&0*c?B*ej^h z-qkjj@9RGfK2D+>Ob@v3!?yUBzBPH=qVgxI4QlYZzDK(81z4qP9G3q_t_7wQ{)sc>*u1dH( z%!s50L13fcD2C-{z@S==6gh$JSxeeQV5%F*_*nS#fFd3nPZZ2OzcqklZTqTY36w{~ zxtSk|AyC7!)vhY&=OuZ5I)UHD`MK|`d$@?*(eM`?-3ZB-fB=}qVg)rPf8si|DQv8hct2^aA_N%4C9(K;cluURU*&VZz{fO+7PFj$ICf z8+nG$Z!Rt>FDh@P0yzj{iuyy4#?D4V_gBL6c4Lg!+jjH38zuQo>`$C!Qt2EkeSli?yorlFYWbuQ0vAM3j`hSn3%%EV8?>$Duqj48a_O|NJaGmrF&j?AZR*vdMmC|8DxU|vk2_n`P4;3QzfLjBLz(e ziFe#dIZ9OO`>958Xzx@!iwjdt45+&1PYU)O?ytEH_`t!+%&vz)tdjl2E%Qf^AjPiN^4 z=R6EWjp2$SAr#zi)SS8q0}X8p2xwI|%=mUopZU!6G?7VK{UoEgNzuJZD)3W0Z@pX~ zb3gN2H+{}CJ+%E^Uiw@9?!bh|Td zy5ne_`rL|%-!a-@$@fHd{j!`7%EX~YLetgGXmnTy8sjnV1c+b54((}|1!no@rEa$E zG#<&E?|Pi=CtT!YLc8XLkTYIjcm&QX5^=7I4xk;cqm%=8ou72rGWObXRmY7R`6v&F zR~U+*g^Rq*xb@AA%bF@Ib#*pJ$XMs&3Tyox>!P=DTYBq@h&T|L{t<6 zC|?$B=by-K)*;>pejEeOIpjVmPzitEn}v)7tw|pXPBH=1AOf6!{LMz!9p3Hzte>C4 z${mR+R`Or7gt3aiu~=Llo2NXmG(4(WoUR^ItIYIq$G+n>vu;yx>%H0ahRA~WeU`lW z_BKf?WOmkIw*-;MIKx`hlRKpg4p5*2mpocQX)dWNXS=3q8xXc7W4X;P60myoI9l0n zrTKvAI>?Ymuq)7c4^JB%)3A_iR2gXcLB3dl_e(*7xWt=vs$iod8yV*mD3;hJ#l_tz zb{w?ST>$h)Zn9Ql?`mJ~D^Z%jS-=c67R*SF#%0 z-~C!5>y)V8GMC>V{M4$v({pH!gDm{qgcopWE;R_2JtVeFPuc9n(0K|{_DYyir<4xe zIlNakGWB|&^n45UMkNxs)j?(B(~5YYKrSm6gxGor-^u}M+Jg9^vSRa#=`IsWVc#Z0 zyu)v?&`{;RKwcGYzu^2^p$?E5jk1?4x2h*@^TSzN*3pUXlh3SoqFmOrsr0fP6J(*6 zV5oF2=**02M3%Qi-P)&7)+q|}@#U*c$4AH4ivAFNR%f4i<^+}`3CuaF#2_?DDayoq zs(7F@Cc0kjeOw_e#dn+Rn$xs%IT=Q=p`ti=_-B$=)K9L}f5yKqU0vP4?n~H%DvVth zf!8n-u`q92BM9*Pa8dOU1l@_#v4oUJC5vR16%_aG-mh*kkWZJ^>mh-n=RvBH_0QSI zORM^al1UY+YjF|Y@r!QT^_ETif1IhS$*}nhG;un~a^&y z$F#ko>dbXLQ$MeHzWHJ}oeH@Q4|LxkJ0@3^-;YZ@N!DX(@B97uD-vzB*OZ58u-?Oi zZ$sa0osgRmmyt7)Q}J#~z=Lks6?vlI)B%J7R&vmk0)ARIbrRaMJ-VMwm4&ipZ%)c} zB|68uokxl zJ?&Lt_Y77wVNVtN$vZSQsKVcE+fI^AG*0!PTo1z(zJPua_h>osqHc*f{~8gVU|_?y zv?jGEk+9k?6F9w=VU4u6^QJCMUDsCzrR76RJ$r`4+Q7HuT(h+7$I!|@HD%dWHpT>a zjD=FF)O4FoH#gb-d0Nb~y7;~TydGA@R)t+#lsPj!(mnN%jUJNz8C6_LK z3#v5ly{{BuPogjWyLhT=Yrr_bFb$vD9)XWKYtJ-nHNw4!KXoZ4?TP3 zqK4`4SN-mBpr!9!hnb~{QZxwc^hg5k#0?2bmQ>u#I>d}G-F}xQ_8km@Yzr#(<%xiR ztZae316+QF0(083NBaz16$8q?ppt@aOdEC*zP&YR?P@zubb7-Mp-js^BlLb40Y5qw zzwVTm?W^@`;>oG{zvf6PpvfRAx|D}7^hU~q$5g%<;4&!7EG7;G!NO{&Z4W@$x3na1 zL~yFjX-4TpB1@1pGUfFl;dkF+rv(X^G5VIH9+`49uC zmtUgF%9ZD!yh}e0ic)Lf0|;`|tB>Oa(9`Ef!QEk!djGy4tfuSymjmwt@k6PqKy&T4mr=oZgnj@uZRNlTcEn z)o*1C7i(5#73~Ldh!VW=fXrm|UlG2D2JDX{=>vxN{HyI>5vUo|UTqw_gbL~frxAYo@_6>KO{zbD$ z*E!SK{Zg$FWSjY}=!vnz{U#I*%Ny7o$<((px4$hn>mzWaPEgn~?L+-zQmR{VokuY9 zgyIr=dgz5OWSV6@2ot6%5HcHtBQ$Q+TCit;?u+>`ypFhvl&`@ZiwreX!SF)!OZvHp zSsqjKrc(VdXD}PcD*8yVmd4513;C{^wrjFC%MZuafoB5$2tZuYuMZCj14nlg8c$ZCJV)nM5WLJj`Tw1lBWHhcx|+ZgfEe zOe^!M&Q5cO@Ofoo{`nrzi$A~cm;O;T>xy~bC z{DyB-ZD2?XB^W`9M2p5HjVuJzkqEM2SQOs#lm2fm58BXN7JH zVF0=y@SOMN`kuy+V|1}cR2?cj1$wLkNA|E5u$<+pa0!zUlA4sGOn@$Tu?<5UGR4Ih zZS>C9s2?EAigXTZi`5ceph7f_{DD5CWM=jpi1exbtwCddN$y_}mK3z4d%K{*&Iqvk z@{Aag!9e*T#Xzzbh8~QyQ54UsyIRJvB$6H>40ZDv5E~;TIAQh@HnYYlLODmj;XmCQfrh zyLVfkjF~kX^i(egeHx06=r;U@j4CA$^r)>+17-!f4~G=cRrM(aAh&p&<6gi2G+rz1 z1RipvsCLV~jM1nBGs754mxAo?a8V_*DU6Jn5J?y73sZ(I8Oa_<@JuJLSWcghCqGSD zg~2@1Xb3bp1yJ8{x6gE;gx=3P^*%yV?YD##!^#SyGKH;hK3K;jW`Il=ld?b|`v9m# zZCGHK43~W~zav(HC6Ot~Hk}429B>FFYm?KE;t{E*s8gjE`04f&>27O#((no)^`{Sf zEztJC%+#$+U&-xueVz20*@CL-H>mrb(@m~&d+zhdMXh+=TQ?8bb8;YHj zg0*ltVb(;CQz1e)DP~S#K5Ag*Hqrjwy9J-`_Ovtkfe3d7)IB&Fch{b|yD67Qd@HwJ zN~Q`0kr~5J%Ndte2)9Y5JU?=G63=&j+bG|sbx;iZj5xIy$vRNLXXG(sB_#|1Uz4UA z{B43kM4WAxXY{WV5|#zE7+XxAvn{un%)CM0+xG@7^_lRBDgL(ngU?&GSJSB&3<>L# zQJtVsJ_nYVEJx^tn5>LYB~foX-(Vinz;YH?-eULDIf?R$5_-du$7*87!<*Y&a|6=Ci;F^;OsQdC>|>&06k4w`H$ z%KYQflirT+-)>p6V1)RI58;M%Z6WFXM%gKI^u#3`p2Ebrg9L9~tB+V2s8+#|3E2_& zR3(}{-Gt@PtB&*Dx1Uy_xBgzA7gO8oMo{(@usjaXMN*|wlJOzPFRFq4wZWK;z|8Fm zk1TaAW|0GZ(#LTEQ!2HWyw$%7S?u*Jr?+FtE1vzFjAT|92;X#MBgIOoVgClfcdja6 zKZef?gC0)WNAZ3uSF7KD&{n8E_o>Wk zO!6baicp*|UGW@}F~d7pIG{-920>fxJY^gkh6L2YvSIQ{eXU%{j~}gPjtsmU;Wrr_ zsc-|?G}mgUtfsx2Lqd>h;D6?xZBS7kQ6hrW_{ax4JK9=*CAZ}>p@Tau@vacQ@sfn6 zK?|F7_J*Y&AO3Ao-8+7p{G4ms6i$JJTSAfwV@~|to02dxe&F;}iKjmYBr)K&S?4GV zl*8lW4yU_!{svT9g^m^rnjaheMr&fG*ZbGl)ikl!Dp{HbuK{|L#h{HKA}yP!>IU2D z4jq&MevxSsy1hYofb(*P$41seTNTOuP!gk?>jBF-za!??r7P0P){?m^P}k{AQ_@f-$p|^h@U>g>k@igRg@`5;K5i{{c9?z2$z7*m9w5{ zP8zWn1T`y>pZLLKi`j+izk5k9g)wU5g(*(wx=v=iOH#BUxps+az1M2`(HPR0 z0b%Sh5Qm$&PJWe2vo7*jmHxx=+7qEcaW$&QNkI}DCo7SLoSm{{l?%N-fPaIYc?w*z zdqlAPgmqcOcfcbqtEB2(M_9+6Q@4rUyO#dz>`E?S&!Jp`vVje;?x?s&jA`nkuTHO> zsK8@4UbIydMG8vb9(5|+l1!0Pswy=N^>|f6tY@T?8 z0LYjM1=A-t*+XLk9LnC$-t)OPXSs|Z4Lu%YG7<>`SA>*JRKcrKew~Y{D~__DJIZ>^ z7|bEB?*7-+ulPaz29c1z_k%(6L(xGi#6y6vf|(Ez%R@ZYcr;sbgd*Hd>PA#+27pBh8s@F34h?Y6R>7LgcKmBD zkL@%b2EIFHAmc zYQ%`NNim4_5K1)>lNgk*vBI!H8luKDH_Z&1(fx-fbt|0tPx8F6j7#=xu+QJheg2G4`ItD74@wl zmUjdn^@%si$~?Mmo$e0WSf!7(+rv{0&D7+=0ZGd)=Di;Yv!r5yz8kQ%e)OdpJA)?n zeRf&q6`vZnPNdBjC2%v3<-&c?HVAg{)H#v!ZBh zmn7*3^)3(!12DZ7Xf7*THodJ$T7s+blZ_eebMrT zB@RKw($T5O(reQ?_No}?A1<%X9mBO7+;O-cW9FIC#>@wrx(B-iHp@2cuiuke(>5Cn zu-#Xb_9xZqM3HY;A-PRkuRsF|iU=$qkm>khtIrqWoMM^z6_x0|G1dr+B;}(xe*Bgx zw*?eVkA<;R}g|5a}1jP_^&^4llz^wb@0LzsQQLdfs$S7O z{bAm7kDA{;Wj9AsJxB7+Kv0}aqI1Heo{|ZXusg&o^20sd)wlO@YOhuAc-Sv0+Wn#2 zpjifk^M_W~l05*0^|mF3P*;SD4VOM92SYi@kC?7<-hLRIv7 zI&A707y^Q-tcu3nhJh5A-{mfM0EzFxAf#gqgblm1$$5QKSG$PyZHK8P3D3>_iZ9AKC2QY|UQ_*jl z#sr$OrQjSt!FNud%WNS6^*gpW)vVKWN-h5wpkS#}f@-Og?V3byp04+w`ES=#MGXAx zrLU8UMc`cBU^tyX3xi{|K(#_~NA#i96PiQIJKI+5f3Lkp_2A6=d8oG--u1_N8l!|> z(laHV8V13$Z_Y$U>8X9VRW-;uHwiGu8VoA5EMp8q^r?jctxyd+Gy&UOt!o{#RZ>l*RZ8*FX60@IMeM?SHc4{saE2|*5n|H5J|Ntt%sBtRIw^?(ZPwDAEz!dlNbnbY+&FS`b&spps)6DO8O z>h)>Rk=x1`O4!U&U+aBo>!i8C=J^aJTwR^i0I(FVJ}@>g!8d}FcF|vf$nH0E^et6T8Oi~)kr*p;mxW)+c>2zH3Nr$0QH1SSPb9PfnsV}a;Yrxex z`e&9);v8k?B#Hbl_CaoR`R6+~^Ft@X zgU`^k+Gzt}m$lmHafb7AFV{sAy(W`+oO1{#bj{}>zyDK z3e7V?Q+vIpLux~u2j0SyID6^k0txXcBNO^H?x|I>#}E7}?P+zqs<^QRZKL9nsy>on zDXM+KF>`1PBO$BGsUS%=={;hEC$&4$=iy1*ps@@u2A&H1A#BrG@2?ZD$5qi$OV#6& zty-8H39n?;VO3N6C+vT{pdPg6C(HjXXbbfJ=_369>C^^J=61HmCe{|NCXOEei?Z=Q z8*!dam9fkEgAjWAj!Ip;g9SVZ1l@>RQL$hJe_c>!?&?;ra8GBF#`5!u%N>!(7GsSy zd;tjf$(ZZ0lZHD>Z_AF`+27wbLs#gWDhyNOTG~=2^7K5p+#XGrYWBEUYl9_fRih_- zsBZ<{^V|{w`@wbQ$*+f9HVV5TU&f5b8#7UKjA`^(dL7?hpwoiZA=2z%dNnuN-Mg~4 zI)inkxzXao$8@>sGt`9*9&?JjwhTe7Eo@GVrmt@BW^?zo7#5BRfzZke`-I!fwr8_u zCg4F~*6J4bgalUqtI3)G46ZDT2>C zR3PqlPRl=-T0z@c43yq z+F!FSTU6%bzI4>9jz77N z4P#|SdY_Z@!rtDStCOG*aNbHEu|bqa5!e%M8%k6Jdb~~)(8p{5z;!YkK62b zxR_p)3vuFV5Azwv#85c{i(-*yzDpWZ%$jPjJ&{NWsB(~^ZmX})c0CT!Ctvg=0?f*F zl_P!-Y(>*^v(NU1w){jc3-`E_Vt@ReW$SKr~N9k<6uvARrAr>%@vYPF=H&zs-is} ziDAFdTsaqa6%*og=c5xjyLr*7zLc~x?mMZ-TT+XIX)jCt&_u$LuFT6A@AlV(e%AND z5%{gG&km>l5#8s}|1a-G-oVVn$=1%<^dHmR_hbI9DikF08 zWHH6Oy`u5p3Mxcsp$y|yLfW8uIgMxG*3hr7SmGjy4*8^LJ?!8Pi7wo%8{IDF(ZTa~ zB~e~Mgh@Gl;!`#mh$XhR#;z_2zMU@@b>eCodDLg+Q|{gdmo7%Fw+}jH z90Jo4bsvVU*nZj^<i1H@YTMHuoinke8@C(6j0xSW)JXWxMVxwX`i@N@0&pyuNCXS(U z9Enk@P?I+1Sxr=uIQO;NA}BQe=CMQylpVe=i4FRw*K8w|ZaWJQ9IZ}VIIwTRm~pQy zrv~_ox^>UuR0djB4k{60teTW(XS;I^Ru2H&u9fO4q3RC~ z53;PFp(mKfsKMS5;h*KqTfZ9HIkxGU&sjx`p!^k4E^kEmqSrv6YHKcEPUa@_=i=+_ zCo|c_&)>B+ApE{IOR0J<2w`j6$BM@#;&eAaKtM>>TpH?HTxBJ1X1q>HI?*M(fdw`D z9KD|My_VEoPc&KHPOTu| z{Q1Jq>=!+oSC;s}9&0{wA&@v>QyFbfB>^*Ty7Z_rUvm<2x^H&B)+(UdR>7_rh0Bki zdsWHENqT@o--SbeA9_Nk6hKi_Ceu(zQUgwz!piyL-M7!qEg%~3FU(oaUyVAUpzhuG zMqKahGFZ>Ewc=Sc1KPp>G~hRqWuVw>L<4;hmd2T_~zX^73Cw`O(;x0$~arO}@aZ;&Af=8m*z*xakns7XzXmkg2 zHsDXduNpVb)q800!xHfo1YByJ#%dNZMly>xGd2;hC-%LL&joIE%s~fGEVxOCiC|qv5NYx*(c+wTsp7y z;9*`r3xA}Z86Mf87M8{~sd7wAOkoHanWn ztQvx6Cg8~SR+{K$fDu6k03?Dm($o><-z`nlw8~)3j%`2wHpz=&S;fK$S$+OB#R%hj z?VV$s#Gapr?OL+7ihl+Mk9GreXCX!84Ruy_dUpQbr)TKS_lITl)!Pdyvp}1ypJUUj z%qp~x%3e$Tw2vx6?de{$t z;G4sDa^rTWZ<-4GAx@JUmbh+mlBh=ZstaCNK2~8RbXHx9VGXVnN!&Ka-NJ70fP-LY zAvaNW@Cc@LyXCfPFUb9F>Brz*0{IZbdt<)s&7ZDbE4Y_jyu^IZkTxzxZ94OEw_VIp zfWq!8Pv+{ZHUow#r3}nFKcf_j{CXbsG_6dAD~5Y|ydh36C(lJhJdRr>-M&eEN46OD z;1S$ZoG>@Y)YyqX$O=0!UY>W89G#a2oZ?5IP0|mQ!_G<`c%rhIPs?&1)5hz?ta;m| za7Pv~1TQ{$R-Snwbp+Gz9dM1L=E_Ohnu_)$pDi#P##AXlPs)GEdV_q$aRU%G8ZaY^>h$yFVs;Em*`Z)M zl2cK7CCUPe`mM5pA8(}VG>=gx%bR)dQ305Dh!|2yNl5#MGf_NbXGqBpEtL6tPV421 zl19k&XhS?KlZSy^naaKaZ7-MwRmMc?Lr?XKoR-v6W9DT~0w2ChZ9*$CqpF^iKKVzO zzGES8F76o#^^8`!iL8>YBP;QkQ(TEmH8yZU#^QtLsZ242N}aX;*?!Wvhx9MhGg}6vYKZS_d#G zSvqP`DA5o;>k^QG?=8~5OorC1ANzw&mcP)~@rhi)?Z`cY#(mcYqyxs$Y@?daM|(`h zZB0dRmmwETjA@ublR-^9!Vz5%^QEU6g-?3O&Zd@aw-R(V2$OzWYF#Fa1n<28H*LSyQbCK_BCj}Ydsj`~xKR)g7N_h}@qr`k|B`adNxq}-}0@o?Wb5I~} zq-1_jkVv`^%^lZkw6}ku_ODFm$m0k#<3rK+@93sXL(W@FMpttVL1M)`)-sO~D$Jr4Yi@grVfgRjVVK`1SBH^u~i0uDV*D@mopvYZE^He}~6wxTpJDH*G8 zpGGiT;1kCd2)UBe0=VG*OOLh>UxV&Yj!I3b63Y@WK5<5a0xFDJ(iRS4O{G3g`=hj* zcHnN_9WGRd5DU@ISmneL?*U>Xui zPAag6bx-(EPF(Q2b$mHjjLUjD%o1_y5ySp^ayk8)LzkSrs5eiu?m+)pBvJGQ{(2~T zdbLgTfX57F6y_uoD7`=~*n%`_4a#W4JySGl3c10y0}V!A!qUGb0y7v#0L+>tNtClA z_Q#5`YJH#2SY?k|OgEKYA1>w$$*UeAvh`pw9kuH{GTh0x1}OYWXU6T1Cwg7BTPVbH z86I<+%cevwQQDB0SSQn()&c^1c#4ABS?0+t1H@Qu1yu9900;Rc_Y`M&NY;ia31i^Q zQKXZ1TE`}ah6oQ6d%_QLTtA-gzd@#apXHhIarfuy*4wSCyX! z7;fKjKmnkB9K?r(Z-)r-uEEGk!_%E6WD65nC*<*i>ggh{sv$c3{l6Wzu!skBq{v#i z-`}Req4j!}6?wJ_$sEN2YH+dDfVu}!I6R)N09&WhYUa!56=617ai#0-o1u!x0e0^{8nh)4+9esi~OYt z@fz{Z+rlAoq)jZ-4xcJ!%`O;(Cai8qG_>TgiAA@0EkrplxMm7RZJeb7p3TW!N z+5NeP+gtnwBgkUk79P&`>&(DgrTsT2nOB-bo&HKZ-qp_S)a_bLTv63_Jj&p=YR$LV z0W{B`EkhY^;+~T9vTk8qgmd5=tkK8WgA2E5d$;wPOVw|^{p<6){f=rn+&B5tBWS@4 zC@67CF}p)CrXCFH#z?KaqfJdAJ|n}C*4VphlF?kZ268{*QBpJtBCFsObSMdJsvPUj zKL)hG=Tz?7(b$?JDeyTKeXH~inui=jgXdK{HYRzLj{5+Tha>$e0AvhT-j}>eu?#Jb z&-s9IbH}kBS5jmK*D*D*x|P_lMV^^r=-aV;4%{*hjaWGNAS;v*n8h)W9WcSV)~vijGTVMbj-G zJ^C=Y`9@>y4Ea;CG*r1D?&QUX_rv7qWJQMe>&em8W1)1#pY=-Kyy`4V-Og6)(-bX1 z?%M%xCqKN)dR@Wg>2u1gEB+Ljootk04Jvf`B^eJLRa*x>Na)qpxf#W68Z-3E)~d9* zu77-!*6tyz+RJ=So$YEe5v{r`fW?ri+SMDZ8FG1<$QjnvIo@`T@6FdFqK+9CH|nl> z&A*Kodroa0{F-~0?rpq7Nwp3t+&XF|YRQN#N|8HY@&clSh6hX7*sKa{7zE>TP;Hv5 z&*XpBxy{KtPxq2qPr5xiDRjKpI{Cf2x>=je=V@4|p3lg+_piHo_bYGqraK!0J^I6W zvTSDD$Y$|uewZ;BE%PwQDFY)0>`f}zgxiyom2%HvFg6j4f!8D81q+_sDMTG={Jk(? zB8C#rf(#d;#z0Upa;+(bMY^?V^Jk}t6?o@yz{cXhA%MD~={!O8h2sSz%?QZGlYl6P z4g7y;)S9ZWWc2b&5FO`v6);0ti9kzYg{k`DF$Gc%v^{K^VW&uIi)F(MbdtAq=u&I0 z7$A6of|r#+t3sCdY8nNhGM)DltmJaSF$peQmRa99Tn`52ukPi89j73%1oM=mAq*&V zBZMhp%Zk!K*&PUm>|Tu9~tK{x(oskX(J}e!PVGZQhLQ(2L>5L zt39JZq$nYaSb&HEnGzui@^uD?ui*yYDqei3b#Q}DDrOkU5v_E=XEDtU3kQ}3i{>Ue z0Td1c6{gIFPFCCSqb$3h=8gn6Rx!X>4Cg6iD}XD3LF1>KKqolTf}=pBGRMz~ZacHQ zXG!mdn#E~e=s<-y5;DR5=y{RQYFcI~q+G}wqF+wf zCUnE(Ucj_xB_fhi1yh(i2kcLnit1lz(c&iX5j7n};)6Z=tUI&chdXwbF-Vh%u?U1_ zN4=)?xOWTRv1;85!+S6~uYrEGmwE1aA{XwLetl|)chHfAQ zE(c9B4eIUsjiERdH6DiV_p^UkjNT~>4(4r+8Z|!b_lrDv*&%Kc1!isQr*6Q=_ic)M zs1xJ%8`z52$5B5oQ75E4Hj3OdCE1_jGTsQo^f|bY61CO!7aeZ`*g#bJTmUkgIvJ#d z5|oPcg+~;&NSw8LBK@nDfvn91xoQ0>=nDbO13^l5K);rrQP1AeoPnM1#jFXAA!t6| z743%E{ACmB)`;EK%p9FXX~}|7Xk*c~#hnxmDW?z&2Exu-o+?10Pveg&QUFxy{BEXa z#`Zc}<80?|;SL5bf4i{SOceUvp0~8nJRin%kXtg@fQj@(V_!+Vc16BMs8H$R!9i(l z1Db4Ed#p$0qa~c;0cets63HZk)`~;-+3dV7dWX#Pm-2v3r`e7TCgOh2*kwr<#1vuL zqW@y)oH$OPD;r`ZX^FTJGu5n|7QQKbF84h;`DU)vH7PQOIKq_Hc}?pOqKpR1z&*@M zQ^idPx9#8~ykyX^^Uxk9qgd^j!ea#+hRdhk`v4ETMTt)qDD z{El&sK_UT8B?ulEb>UO+5RBw&k6!aw3KEOIHn~^&PtgVf6R+vv3fOG9sw%QkHfyeC zEpZ8pVSzCj@cJfP+RwBC_ktIekUPzLsEW<<517wKo7HY;srK{JbJRm<$=9nHX<318 zb=vYJDz{|}i=ge?SegWTafDr7x`e-(L zvi()@nksRi5)^fSKTmG+(2t)JPQF-*fjF_NJuU%ye4r<}abH8Q|KcBew9~i2@Tov& z@LEo|`JfSod_*taH6h4Qp@%;oP%R%s&$cA6DDvuk(hQ;0m7)}VN-zrmn z{8;o9hDjK(A&4UlxKroB1AsyCfIlXwSLX~{{}Gq#(v%~?X&NOI@QCBsD*vcB zYgzzPa-}vvw4-sC+$ZQdRoPXo;^p%lN$_%c}iFS@)w9i(jORq0{lV~@8 zXD#4H4n+6>@nVN(vMoT{>M$TFgAvIvMZ03q%-)7#N@EX~(kW*1Fa5$c!PQPi_9|vp zQIhBjE&mI z$3H1HhoL&Q-K3`jVz<}lc6(&59$%JUx#TIvbxmhfx!q+(SnZW5Yju4VDD!6ZY&H8g z)Fs1V5=n<0YXn^$Bb%E^$W+^LVRb=Acyyi6WmV*hOn>c!=ZE3j*Z5}7z|HdLvP6?L z(aL)dtGlj1_nAQeI^qf<^c)?7x8vj2XBuJ?0zox)$Go!q3Lt-Q4D?a(i);6{1bRV8 z2lwqIQ~iRjFcRS`VH~GnrV(NCfdd({5lto0jLA^Gg{EIjvs;W#bDL0V>y1uNrKHnv z>KYMru8ME}geOzpjp}Wy9j+N}yM$~9A;J79oZagVxAv!h8hSQU^GvXo6S0%+R^84)s@9FBgXereO8cDI1}bYe~GJDZW(-=6y# zULzsRJjS!Zg|?(|^N*2D?jiHi+)R190#ChKtliL2GS>NQat~AHJq<&rL6-t3K&%p> z>uOHfi%X~ip%wNN@Ja6&Yh+9a71 z;Nk1GqV-=Wc)nyZMI5OlKT&k2;r_L$d}diIGkG8qDl}Czf~oMA7jBRT5PRbZR9Mf)wE@=Zm?MSgj14xGB3M z46Oya>UlnV=&#!{xc!N^gO7=rf}+qr9eWL4f~lvPfn;QnBuNodCE|px9z-c@M6+Tr z$34)#Dmz44@DZZu*YRcs66eaU)q_wn1Qi2an{IY1h4<8%HmOMQP%dtXg03Sh%kT30 zn_eTYB+4sh)^TY9Hm?U}_3r4`ke>kr*8>u>qMn-Q>W5i9fiH(eI+tqJ4BrEqdT!RB z*Qj8T8JMLIm~OO0R{5~3zC5hD#$Wt_4&{jpWh>HvPwy+skC8l{SCI?x7P2iuv@-=m zFe+62fDz<)>5p%{~u@X{GDmobcx2cZQHhO+v?a>r(@f;ZL5tyE4nswf9%@6aPweJ7muBxkc)vmp_hHv%7+@s}JH^>(?qhqsK5PK&-h?hsw zCc!h~J6QkF!<`1WE}O^G0CRI{l-h?7cy$CZW4!o3i|zwCR*s#Bk8%@-pkaGRZ7l>T z*iNMI$L?S96P#e`iE0OZ;Zd93=Gr_O>D?{tCt?l3Cg>QO(6gwBDU4Dd%tP(LlsrK7 zbX;l{ssHnT7bSIyP+A^I-40R$!jPe|E_Q>-CWGb|+3-t^D%f}Ew8f&S!QGY*3++Dd z_|7>mdO{qnE5(fXw|y5hkWH8m zd*_bGIK%VAsuB~k>zLCV+lTPHVOs}2!%v~$!5$}(Lbkl1%IlQZ!*7|+sE>QqibrG6 zQRJ&4F({@iHK0WVap9}}Ufttgd$crc<^55QGvbG8T63H_3j(Q32GW$;)hKRmZH&1x z-g+DgkdoD7%_pp_t7N~2Z)LI#It$74qYFS-1`o)jTeo;ADpMx5LQsZPJfTm<)n%^$cfyN!noKJ#K6E8_qPXE>v>j~e$-WgM-2NfISpnB zqhj@#wc6Vi#x?-TjxENc=!R9ypw|Af=ZU;|$1gqe7X-aSb2nc@YT7V-EW-r#;Jiu- z&nBVrWqH`Kr>R!vZvFinbx~M`vrW!%ep|b~>o=sNuet_xj}_yCi&F+Lmy4&OPksINM9Jcwsox|s>Jo>OWd2Pw4vgc=oCnBd59 z?3Gg$WI7HQIL%HhE^dy85m}+kro{k(Mi;@ zec<82V;ig>=OK{gh|2rVAU{EwV^J^w!6Y^`(EjlXAHQoD3PP4>B}AW z_BLuf-;JZqzT}3Z9SFe?6Z>>cHDAuq3sfww;8iq2zPa#`3XwXs{$v_@iN^w65-YJ4 z4<@Vdk_^hO-T4JD=~GCq-rKN(rT5{!JtQ(QFEZc5!~Frj%b#57-*IT9!b|6rJLtJi zc`z~XS^}%W2)K5IK|hXcqZrn?aBi669bM-iA6yI`UArs*+m14Jn z{_}qlsPBD1{jeB;asR*0OaH4VX<9p*I~sf0ncKVmH&|lY`VOS*Xns3}#^OXmg;Oss z7nSrTghEn*PrxBaA}NBk8^}pcSc>aMJ1+dvR?5T~7w)9Rm6vk1&$&JqE;DY7ecpP_ z2Lx}M#aA{GGga6@(`B=+ZJJGa0dGfgGrgVuF0ZQ`%qVyphgEBp*9?hM^1UY)Aa^6X zjH5G*B6n5bu0!DbmQBZ1jcbp%A`GSrAkuy=8?LQAne-}JE%CGArX7Fh-frD#DTS)-A?;sX8!0`1s<2&ISysO=LIb+_-k&a`!FX4VdxkLq z%N$!kaYI-z5c?`x4*nxy1#S8Qx^7cKnU3sL=xKV8HtBUjTJ|0Jxo z3;esQ><4T1_&7o^raJGlW)+&lg^Y|f~x<5B?k}u4+IoZa{TK=n7c!B{0ZB zK{q;FzC3axiXQS5x=LoiL;5gaJ4V~#J#F&8^kI)xUo+ZQ4d#a>$u4_?!uSY{f}{y< z_Pdh5(s$_W1ld}rx{_QMT$vB=jn{HR#r_tSCs#BtDyV^g)Ce(S78*^iq;SdoTZw8u z3$38Ll(;SmY7k}X9wzRo!E+1MNWhI{DvY4f`EhC)DCUdamsFEWBx%@ALz4DB$w$i6}4$ks;Ka6 zL#`S)SZ11^xjd?(p(&?j*-};@Fu7Lu^4oSkhv&|kfnb0V406b|&dDfYg~47;=BT7# z;vEW|Jpo{31-CAxEeoAwE+~pQMuYn9T6?qM=;2iSaIJmZqDXDkoH5~ih-InP6sg0= z^*G;T^e1nZ#eDe_!XR2r#ml9Yrf@;l)j=|AIy&h}p#DMgaGV4nXB-G4{+`U0PpmmS zlp7bj++xN%*%FJdu|hj#U$VjY{<0>BR__avrYGM>rv_hVN$)iQ(H+(kpEIX=X)7G% zQh)yDqRQF>k>?n**WuFyAEWB6v@*q>n-Jpx3>UU257Jj}W%BFQR}D6Tt`IWXzeysHZhHP>vZYy?DI%v-@a+?G@sKnRGCs1RIH}3 zHCrpICe#`?TX_f(?%(ZXh`;rVy~k$vPyV?D>stmN`tntQ13-O4i&|@@)2HD(Ar3j& z(%;#)L1l8R3z|q`4n;He;Gb#X;L3@vBJe_cRrAUv=g7$!MXd8V^f6pHBfcoI?X5T&S zx0eG#F|Ua%kIAn&N`(>XrO;F8+1S=Hz0_F+5=Z=6&P4kbwV&8XU+3UYu4!M&K9%46 z^)=q}dJ9IPr8#1(m`Ek-aVM>DWlguT1-{uY zQEE!*crpWf`flj6R@`G&67!>yh*gj1h6n4Iv+7@+V&CTSNZ8}lU9a16q3!v8C6;#| z6ia9OjWeWE!o$BCKjUBm_uYlyNvqojHJxe)Bpsa<5SX3~F2)V@23QL#;_0pzZ2(x- z?6oT5jWhpwtA3CPmN$G`%|n*3y^(q#qf+80#C+4#hG76re1deTUm9np22b9u06vl# z98LP?EjyzMqhB|Ex9pEp?LfmaI=ULvWHhrLTQX;hbtO*qt_p^fyFTF+(Z&@qMw!c< zw4~>G9-(6qGM7!xH%i)lm_yvC|k+Sd3qt)y1QW)6zPEHs&P1WH?JzqnH z;QT9PXmR4EhMTk;XbEzE1;`YZwOR#>^%utwVN8S+$r8jTxOTktiA!z%g&9Q7>~BYe ze;0cH(z3a*5&gya(yhoeiwnrjgKbQx7djIlqL;Wq8I-yaiS?@==d2^q_Z|9fz-&LvwV#Y}KwURfl7b0#RE$8*anP<&NK z^veT$XM9?r@ZsfpFm$55IlT`wZ;>vA)iJ~RyZ3%D&Qg%0yf{akNhmAJCa@|9n{$uA zMZu^_c&Woi?4+Kw)&F+zord3rEwk3qWW!R>mai@~{k3OK3QftLlI;jO3By(Pr&sCh zBGdbjQ@XZSq$!fdK$e=jG}NS0JL0bZ417gM$-ij(+p_M+4cazq8_g37>KZQ6%!7Af zBrBYnKUQ>_6DIa@ULE$=bG!GK1j=7S8WIPfk-xn!j;{aG@S{8NX&66eQ^GvefA;*t zCrSUMx-S^SL9Of}{*+Mq4-AWz);8RD6eJB}WmF^B$aMMyD`3p04cC24D6RDv;`+}5 zTMcdPE?-PKij}z9G@tVCgqUggVH;(qKTFun0v3}+7+qyjl0m%@iA#2S29Z81EI){LU>ZRTyt`iD1IKy&+_@4}TyDY}}ECMySD(t!}c6$A@>DQ)? zOx&1ssPnbXS8Px0F56dnTYbZN5ejoZT3k(53*g;Y6xT!-lkFIQG-PnWR?ana?U&`a zaJ?-s}W}tP)XN;w?7*auW zpL@4SM)DV0TH=ZDl(coMyRhz}bAd}X0*M2J!4M}Ncexvm`Kg&gmH@9@ z6q?6oK$Vq>v@Wjm6{QgKYhc@7i|Ln@N>6Drmo2#qefSBIsOo68*;wpCA^|dL>IvxL zOJ*I_#fdEb28A2jUWmLha=QJZD@D&#K^XXnI}kKvj*T&hwp;j6$3xLDze!H`Gxx^` z`EXoN3f&amxP1kf`{e$;ct^G`pv{@)Lj(evya$l+*pI04NE9|Fn4z1S*P>)^4OKlG z57z!Yk{@fORz{2z9>~*FfiHCrXrUGAaY(07I&h(z{*}4(GL`C0fINioxn#$d$W?8| zD$nv@Bi;5@G3eS#QaKtqFNv-aL-WdDV9iY_Hm&r`K2Rq~pj4+eWHRbKuP?FSGM7=E zZhyidAn!i(DNf5i`b~(-W{V8>4BVJrdT=|E`StFXht{SgKzT*Oqj;yzWLOCa^UYtngIM~yD~ z2S7Fceu~c*LJ${#c~G0Ynx+XMuN6{}{IOhfO=M<1X#(BeD?oDIEe9=CdXxwXDER;ZF3u9bFGKiM@+&Ms{=2GP3%1nA=W z7)=r0={Y_V^>5BLs=GURNX=5t;1f5O&pU&r%v+|M`UdP9&c9Bb%Z-!nERqBTdwW;? zHr0y(?;N|Y5Sfnz%bwcCstE+^>`#dHxqV+fB*@+;4(^Ae_MmPH`)Oa{`9?R~+u2|A zn0~PG9=#4{xr?`rDxo$pn+5l9NhKQ0jNHXSF=}&Jk^S~7M~YgxJp;9!Q>rXEyZSx6 z|0r~$+2c`t8!NKT?OR^nhW*B%`A%ULLD=wZRN%?E_`l_YDV{waOYI${lXdB1)7mC6 zo)`UxIaKUx!ZXG3K|Iwmeb7VlPZF@96`MXUf$B&(y%gW%h$K`vsoQiokeiDU$5wChC2v#FGt9f)v+%bb=~^nU9-^S7!V_#m;! zjVqKD1DnjR52J;kVEFEa>L5yNh!(|S-J8C;$UHj5+t2yu6k3xYm|>GKSWJ?DsxPxx z$3$?*q|z15iC3a5O*j(dQG7jZby4$d^9#tCOX%7R0bmAA;AF6_I@lnJpy+r8I+E(wmfV z>0|yFSt02Wz)%z~iqtF1fBRoMMSdZQKv0ikUsltx5|MfEq4Or{sVGP;4#3LCB)XpA z?G*ZL<9%}im~OE*6s>)Zm8_667?;85X?2yf2SG$(VI+|Pa_+r<_Ys6>$CkV@S)`+7 ziC1!goJO-nGfQSTLaP}cMd}05lvR4cdc5_%6`>6!kKj3|$(070P@o)3M}bk9FS2HUBpUnJDacDTFq<-bHNnec~fyihy%1~EeI#xFx@r#f3*6~J9Os_oT-#wl>dcK28 z$}?u1V51m~;wtC%%!DoOsu8~kDTh;dIQ-WP*KR(#a1k2uYIY$j5w?j$cw zaY(AUp5}s#+pr>_wg>j)B_lA+Eax3MK=tD}>!HR~;)|_713!C0uc)GGEcvo6m?>hk zHRzt07*`Y;F=aJlvL2L0MAo9bN|w$vd1sWff&drI-?d5Yg!tkW>CZSr^vYePj04xW z+p#2^Dp(RBs+|nxp|t6k|6zT1c({V~ZAB6BMrD=09Bq*@NnI;KoZ`uC_G>S4&9w4? zRtSjaRm>&q*(=eXa*FAZvMqDz-_x%p8>bg{cehp@yuN1roKM*QEN*NfouqQ`KtLDr z|CIrxW@TePDKM7(E?%!+Y`-PY9-+(&A6y7E zJ(-<=QR*JCRbuzJ@=QlAQ$0l&)-1+9yk~B~z0=`;JQ-8Q@O=>@8}numDn`}pZ)vwsJZ zwU;f3N|~jIPRZC;Re9WzYr5qAD8AMIF(REUx??IBWyk7z=^MLs;U-yUxYZNT+OC(a z=GS#Wk~>wLrN6SAhDc}*D`82S&x%4t!og}77WXEZR$=F ziY?&Wt3nmtPFOpw;MSzw>P(~a~l2u7B^HC%b8EIsKv!P84u*`VKz7npE z$XcmvnJ(2hqRIN5FG|yE-E--9$`*b!;2WrpNh=nF(mD61{}##BSD3g%BXxC0+mI~eZT+%iJf)p-ZKUP{Z1sf5yD%CkW5sGFbLh}y%fqGc; zeC2>5`Y<{)HF%5N5t-1dl-c9fth?fnn!LLX)C5ho^$2UnpIw}gv5dvUCh9RtyQJMt zu0NZxxhPFWyiKDkLd}mN&N&&7IpM#-qF9(s;hd1BY=IB``-c4y$vlS23h;I}4uBGH zEAYXo>Pk|^=sjeRGSEZ&FGKHOOD!0ga8W7tZa~xNJD4*kP5!BULQSQJ7l=pdXzz!( zl6N?-U6y2a-7XkCd>Iuc2PHzp`)4;YgQHSwfy)M^!=l32#H{G|Kqfz)SQ9}G>toU_ zWb@+kosyTPOUb6QIfmk>Y{DPlBY|#$PJF&dGX)bW`H&$@(h`UD0YAP2q1cHZrlla67ToI8wu;55h3_Lwr}5*=mgHYljudPS8c`=oi@zl1 zAQBZoU(3BC= zkw6I5@Zib5;Lw8C@Yek1IP<_2u~d?UCVY-1@lNvF2|?Nk!HCSkR7AucIyx#PDzRr# z+6(>eonshA1oXi59Khns@v~Z!JfH`2_p*&6Ikiuat<1l0R;PXa+pqgB*PEk<-o71n z`&I;9@%0EB4)X)aaY4yBOTa1H;?xL!m!8Lavv1pOi)DSJrT zPZHGiNJuHg6O6QqXvikOIo^H7MDKx}d93hf!aBr5QM_E4*j&hBJ8Ngvu%PKDahOT?6H> z3WXIbf84fNg_)=E5b|7rLS8yyJ|2qwRzQg zj0|%&d%CL(%F@Xa8X_A9M%}wm74}+5!T8v#5x3flFXB)xRF$>t9wW62up|`9cMXM! zXoHO4n3O&PVSdIROQg@6lNP@GNmDg==u*>p4k+QdWefY1*+i>OGjhKfa1K+{*Tn7A zHi7SedD5|e!Woph{Cy zCMJV$8>PzV(71Wwot7YjuiY(8HCCB7P;gqxHPuO~jTL@hYV5itZ7^=Z%de!BJ^!1U9W!@! zAQnVC;H$u)9KG-VLAJ#M1p6bP&P`vzR60SX$}U1<3|z>rd=`As8oBx&xR%b;5#tVo zGqI@lQQ1Iv+!!8dBbCS9lxbtaAPx*Lyd+mEGIiBtTC}^xm`RODs!7c`Apq>f9iPuh zU8*YOn~`0a(Q%;{-;2Ctr_;}lu3uFJ+<#{?NSL_3U1NXG^xEGqJxDY11X3#L#|oyT$986329jBLnpP!k%ICId z5*B1>+bOeI8!c&NCGXHl4OfB7q2!Gef9*3uPuOkfNvJ|5Rn6kLl8Y)-Rv1*?E4UIJ zGPokHh<)&Mt8L9M)fS!`sxVDWUL(~ETQ9?ENM}rV4Gq};UPLnGq-bti&PF#;^@t4c z1I<_!+4l7q zc9$f%qD%)y8ZRt1SqQ#Rn$e-B}cWvs47_1h*;Rtl2g9C?{B zp9Y&E2quc7<$3AH zZ|My?HDwBfz24f=G|<79Oze(VcbBFoXBWp;xj_xQ1TT-B;(<&9Jm9YWDjIlm8PRf% zlg&EPl6OSNt|^nB#LR`S1^ojrOEs9<=zY-`xZEw$o%XB!vJ=J-%`VJ4Y{iewsIM{R z<8cjDRf3V$Dqwep#AXtuI-SiMb$60SVhme2d%!8+t(mUu8+|&1IsFBa5T>{vbmFL= z!@y&r!qho#-H?L+_A<`%jd}lMB3fhmd_ejofk<>o;Pfu-NJ7g1VVaDp5<%2r zRD4Y3f-_@_t{19P)7`1>bsJO8Xo268!Cn##ha5&qGXN5&!;;$%Mle^DC=(_|j)1-{ zhaO*Zo%N)VdRWHEQ6@)NEzrvPV8@x=vag?OYCmitNZ|f268XH4ht*Oo8L!8kMUtc! zd`e%3<4?xF4^Kh=`8UGful7>kDEndV+_vH0D0}7X1)Sq%L2Bk^fbavGMFAdg3h_~2 zs@*U%fsyBP`%#5fD-V`LhoqOJY^ptJnuG8}TygR?fCTUy#W-DpV_E%&*tloZsjxz# z9N$TS&m_f}RB6d?OAQ|RFFbP~rAcit=eM5e1vSI$0PYvOscU|#c`m{`yh-={3kUmP z{27jxeHM}-s}4@(*W1yd9FPB*fI%5#2D=(Vjm=jrlVQ}9sqd3Xr>pNEj_CQSd zRn=ZzYDb!Yygv?)=Rc19XuTq<4m2f<)YZ<|Ur*&sogWP$*G!H~qIuFTwNp=zwabBo zWy`wK{X9CKyvEe(!&9qelgGc->afnW2Z7H>pWKogCv+K9`p0s_uFWFHWB)#ogD(Ux zK4Atc)BGUdq{Cp|{)B`xLdS#2Nr?X9Bo`4@+QR$gccp%X?Ku_z?oVA)724cSd8 zQkov`zg^dmoM2AdU+oaqT}f88vy8E%2o8Edad*zeBte15tf#AqxUW7c=m9Uv6189`nHllDl#m<3ZiDB9S+o{QE)NL>< zQXAhMO<^YWUIw18l#h0K8vwytQ6oi~k*NQTpc#%QeotKR?Mti>vl{K&6jp za#*!b>3XtZE3MTzuX+PNO}OmtDgTbzIcbi&TR@aI%A3&$$i6)E`2H_el55{TTeY9d z-z(bxg94Daow2p8i<^mysk61CtF?pue`5^Q^K-PZIfndmw7~=l=G9Q#YY4VBZLzP9 zrRDj13|A0hX=@3kfz(;Z+3fsUH9NspJC#d*{WglN&1SjcipQ<8YsSE@TSs$c_0esk zTkF=ewX#0Kt}-hMvr2IL)A>N7&Om_oy}j0@_M}bz+oa_(a{=S6Q_yY~=6&IZgxD)6 zZ?|b+%=&W++0ZFisnz4Fp>Ek>@W0U7+sIj^{093IW!6`pC-`IMPN;zUqXkiwq#)n6 zp1p?pj(u0SvSljn(Q(;7(Y)-j|z`m4NF1f!8>3-;A0DA3r&yxSt*}q zgWeIuPn>5X@*R06BzSa9m^{IlaCD zL~*dT?ed=Z)&l4#-Ua6D8tA)peeM)wRXggO`Bjq1oCMN*;4}?y2Jmm{{42rCFMAQ0 zTR&qKaA_K5!bA;eGlj#jtbBG+>f#lnIU^W`0s**Fzb^eUeAVi6K_|0Ff-EsQS@E9} zo6RYS7TR|7gD^E+Ifb2%^om)h(Z!EdaO)VYa)6I9}pM8fq#;6nBz8=>?t?+}Xbnb|sM7aS7qf6M6DKu| znoJ{igVNJu8A*f>aqZ|Y`>}H%FNI~YY4kfqmN&H*%;VP!V=+i4?~!Jv_~Wz=F^NJ3 zfShqay#XsHV)+Slf#t5AG}zDbu?!z6qug(^fZIwa7ZMqK-*fWJqkEuK%_#Zq-Cr zXN4K#aOy{v{R``IGqV2(#)mTpMHP{tC2ovPAkS-@n~$q8WdY|EP|L(5`?7L3$h|cI zZVNKg&~@m5(O{))EC!)R_d~Mk*2+J-;+Db*IT*ETo!nk|nfL-)2Y*kGAfFBOQd>Nf z%wc2qlY*P(K568S4cl(r*wY0LU>*jZgyqU{%EdE&q|p_2j+S+hO0+^va??mrt83-f zQE4T}#P4r4o1tMrA(Y8amL?kz)-uX4Cx{mf@x|Kc%g4=3cyl2*HU*x9B%PJ}XTjBc zJNBBm9C8+DA%xB|3+5e)Ko4fqmn273NVO{C*U2;}9`;_iYCQag^Zd}gRz#}p6?NUE z{%;L2JGM+O9w+&^*tlejyQDgqgu!S|DmCcKMiptMENzA^eq`^%j}>oe3Uej{cXlX2 zFFw2&UKlk32j#Cx8*zV8a)z~8pb-p;Q?*;3#&|Y}*UX8~D7}?uNQuo}2uAT6J1T<{ zHrAs6gvez6=LPya-Tr)?1olLPg>cSf=v`2jVdvEaVY3bJ4&2L=6yU4O_GJR}EtLK6i`m z>@r_T6(ywV!6ii$h#J(1f)pFKGr3B87 zHX^uzIMw;5`InQVRmrXA@C{HexHz+TJcrUXQj;37wM_|297$O@f4fpY`E|hC^9H9w z0DsMP9DP97fW^-Cik}ZmswtVP;FYT|LSwtou!AGYUz|;MnN28?TiX{DB{(1BNjM!%8y{8*zR~Rz_MWM`LGWJ9F0`J8ubdV^=q4^Z&b9 z`GuZc92$4x*L0oKqfIfdb^hm9u#pBFlZzF$Q2*q%zlbsKW=>}1MDHY>_nVsF*P!~A z5NrIQ42}ekUDZTRih0+^YHT>=p!@dwJ0U>)9^<{>QsX)91>b#fm&Uz9KW9_$?eS5u zZEJ2Ppxx~{PCUy+)Jt>dv&gNlb7No@!9%ltc<&19+P<$ZtFztUpG`O5I=l$+7rLb2 zrcI_#hrZFm~r6u{k$cW-0=7OkRiKLmR@>L+v$*FYrrVz+EAx<-O+cmz(n z9@iXwBcqz`m_0t7vo^73FeImDYu>}#Fzb1=hoHBAGFF*YBp`UdC95sq>$Y5)Y0%S2 zg7d_3eJMO3dILfQRWyykJ?+8x!kB&2pl-dvdf}6Fq!<-hY?sIKkRRd?kMn4X5;2ee zV*i@PaVvkZkV6MMVQVJ9PYYt(5cGi*Ibi5uPz}qs5SmjcwSS`@4I7?%WRE)Hl536nN z$c$yKRWCxR%6vx6enTK+6Si8TY5F)8Q2TQx>5@6)Ntx)K$ z9t{?47GVQ?XjJmvb?N2ac)k*+%d#VUFMof zS3d^+mfVd#VV0AUsKO)l&dmR_+e|2a#c?hSrfy!J6ru&uLLv}a#}kK>F{8(q1Q0_S z77zpsm=mGTyLwrc?t5c(kw5X`8^U@S(yO*_!M(DH`4K@CiO5JrHB*M-#mtu5nIOeHWZ))%KoQW6 zT}6Qp22OcX$s0tQzd#MZyyYI;2j8)QiV!MRz3&CWICOGWs})ap8bz!Dom7KNm6-Pz z#}`ALSr2X`2Y01CZt-cJFq2Xj%jR871@232@84XO2V?M2%gsp; zCr(R*N}(wn&=LLKs}FF@tw!lUtx8%K_R0%L#F}Kv*oF|E(okk?%m6kAp$G(@W=TV) zl{=E1dCmaySk>F7vI^8{K#8i^C)VbyAm_^!#M z(tuEu-Hb^hnIch%5@POTqrx_5*Bcu3^5H7`*s%Q9@>#OVp4vf5wJZ}jsjh@`(N=+? z-Q0Gn2K!Sn3TGYR`CU8WB>vHcf(aM<{hg}ubxMGOF`G*w|yhE4jYT&dK%5`r;5sP(pHW zW2QwL^cwG8R7Tkob#D8$`s?22;@|b-#UstPSzeSbV%MQNcbV7i+0+80pn(6|(RdSQ zoq=G$OB^Sofk42+`Or#Trv1_|BJZ{QDdt&GeLwadL`H^(bXPbVn|9Wu>tJzn^MU;> z%;Sv-qj zBz6wSijcc(FU45pKM4W71P&grPr|Av-WlTzPVZd@b5ripDALsE4?r&H+?>=jE8E?Vf*n9)d&kR_NzFT9K@V)|J%6L>Kcb{?eBFwGpib&k+ zWDi8D;>ik`1~g960!%>pIh-)v_4L@zS?AsUjM|wplx=B)RxM_?MTw)h}_xZRpGz8~nB1V^FF$lKh#9AM~$ z#~yFgb>6z7o*WO3P^iQ_P>f}*)?iwv)pAtGAIf9m_c*Rn9I93@xE-ElC%PF5kPa`% zkKV(79#A}QIVY{~&wcp2z*KZ=Cc_=-Ge8+jx2BamP}@Uoa&XSgCclRvW4`-a< z?rEpu*XTVYDvj-{vzlA2pIdJS$&J+jboMH;cF(B8Nc%o|?s8m+d_r8QHWd|yR{V~4 z$u=JElXVq4)URtc6r1xW2h(HQQcAkA*tB0bl4M9ni^H$39Pk*>G zZ^m7=&An5|vlB#euDt!pf$eU6x)SBVuSWa#JNNB>eAlI42XFV$p32GNt5|{2vdvh( zH6%d2kyYZSbz64^KdN*&Wr;@Hah8q4{bWCo#@clC*#NazMx?5M93WgS8zcCkR?B}9`uceuLxsk(270px&!?n=`y>~URdHWpTkWpreN5=;&(ja zl4i6(I+_C|$KI8OJH+DDEeCK-^AxzT(DdB0>-nSMAU3JLTtKJ7Z(WxpG9QyOPR<)o zNw~vB3)(mMNsh5X-K!z|jY^VwSWFF-)%a{c34Oy#W7(ray9VNqDvjyc@$=oS2?Po?fj6Ysh*6 zDtRy_gUYQ{&*WTKaYS@r{lIzW5Irql*|_TqlV9gWj02Csb}^<<2UxkoE*b3ald$4JsmfZrV*a9gi@rOZ1wJ(Y~syPxBR{} zyX;r}*h2%l;Ls&-JdgnMKv4|0Wnv}Vq&dBFc&A9C`z7zl(?Rq4q8=kFw9U6fh+=dS z8Fdu*ix?Sfh5{cMveMs^p45)uwQrC|mKFf7ADb;ixDof7_Z5}|ZX##o@xK~#MTIu! z?m_#n5CEu=-eK;tCuifvtBZt-57=2Y@!bsw4e2J2`Cwf5gYZsEjSn|s5VWG z-XFUTz6O_F;JhrsURrL<;8!A*JK^(mHyCB^qVYe(`zkI5Rey)TPm4s7bbXGq0g>Zm zhbZIlO~}m{p=zNf>4hF7>cb<1m+r(@2ukqs9vV8j{Cat`{8L*NFTc1c%%QDP2Pr~T zkSzM;eA&63`Dq6`(-3YQSA&}3WaXRMxFO?YSO54740Kuf8flA=6(+?)qS{EEE{h5v zEkCj>Gl4WcrFrIfb&yOlHxHQi?f`d1rnztW5)lnvycfKeF7(G)H5F4R2yGq--H^FK5 z4Ve^16n&A~lTN>qKv3`+&LoC0z)G0Ttm;&Kiz0>{mOz-%GcC#LbdMQ`9r z4!_V|$V10$vKkY?ec*PnN9nlV?OxWSf+%LB8Nh=uXN<=#drYCY3NZ_H6&uqDYJ_f| z4rhQuLMOWgpNe_A2kx3&2&1&HU3}7WA}G2a8iSz~+xB7qy?U54 z%rul(i9{NSqWlz{O`jHwA&0#e(SoafzZeMVpm>Fpb$U)1rv?Lt<^Pv|ePybiUS_@+ zMvtNdoJxuU_KtU~oT`ySN3*_nenvh(3+kw{9}P#)G?d$6JP(pgNdzD#M#*$-4q>Vv zTG>Qm-tbMtMVOk7@qyi{?7ZI`{pTP)#A@CofjTS^%1h|lW;%s&{Y{lIEu$=F6MKKK z8-gHtSTC22L>j#4z=~gWo?Hz*%1m%jiJzpadx6NpQT~$4RKtsa_0%xY?VusM8G!~B zl@*1jx8f(Wf*8z9u}unAS7{}Fw~-}#tl%D*%;>9 zW?m_#-}cvK+6Zg9OF(_2obe-Je2hI$I9*O`8ir4N}5h6ESo&^ek9TV)8amRY%*2@1K#4vyag717QghO{4YgDQ!Y=;b1^|P@yvM z(OA=h@NK+bc;(>di&IxpJHgcZ$AWH`rI=98UhZnjgfdJ`3iA)Cu8BlT!BiD>$Ui7K z(F!l{SSP_+iWMzHJiirlX*Z~wS~J%kl!eBcUK*onwyJK&PUv&@_4m}}##EKNm&Da= zqwJE_`B|pHPL{D=ql^a9Mp*h-%5B2P39}a{MloB1h2fyhdwcxb{YBbZnW!vlaPK5< z8i2X?VE4PcYkj-j9{*DlVg%y^W=~Gm?WghjR%Ajg z!&#NT6K0Xn*&3x_2_!&TD#^J-T9(Z=18QQcgwcJhrSywJESV^U>nKqP4UuN-TC)m? zLkCS)vJzcM-Yl#}cenkmo}f-O#lb5a>crTE`K{{!5v@OPAtgg=4Hj*dYdzS4IExtP zb#R@1nc?giC86mxdR@Lj+?}xVpg8Rv6l0(z|z?-}?PP?!ra@ z^lKFlX9&U&pTHKR+!zS+plLrOsOl^Xw>vh@$-yv}HSNBS?##V8;D=n(J8^XE|A(@3 z2oeS8((EhSwr$(CZQHhO+qSJ&Rj+K@wymzeXQCr|H?zrgM#fD<+%M0mOyc02*Fl|4 zzyZ}*HM%@RAc3eW&Kn~0G}}}P^F_iz74+&X4kzWbknkW8)AhrD6F&PZv74r*(5?9DEAYPW826PTKxAj@n+MRHPz0_R#0J5PBdKK_yA5CvE4dBr zO#Yg8fdY2-jFTpJ&1UBoB_#5lqObG{xl;du#m70+?4G5EjjN6;Ve;mU3`=-Bqvv4n z1erKXw-RBPcpt1h&HJ9mY4cg{dwZ-%DP4}|HbBtn7?GJD^DvRA5CnU~L1P6|W*6BTvvgYQ z;qtr6O}NSo0m#9{i4w&kdyQVEEGljZLG~u-lj4`#nlZ?HC0n40*Ch68rrT;^%){E6 z*2A*zHE&TQfXGRlURB2*KaH8!{Rchk#PxLH*wfwKovv!wFz}T1^|p_tncp84Dk>s$B)0n2KIFMM_%#DB_4(5UJ^PZr!IYlb z;J_xaSl!QqZ|06#vA_-@FTq8V7WLatR9n^+Z_UIWt$h@gH`|x%DWa&Zh^Ab=$vIIV z+i|9b1FFfO!CizZJ13X5ZCK5e+ zjTEu+c(JV-o<3k19qLN@PkD*$;5Ud*56$-s$rliI3u;aQ8&dYxty|tU*?a%OPe?~A znnSSD5DAtE{AP5&KS5M%Bf4P4`boZ5BuL$AMcLJ-Z>mb4n|ar%KK`OI3xqi|S|No= zwQ^v!Hz~5Ls$Sy8@)GHhyWq*#%UOG?J<#h=31uQtwT6ny*w_H}8!<&&0Aokk`O^{y zKmZ7SQ=g296I00N=POxXaFv4cJ)Dz6f5Mg9m{o=aLa2CIX5-Igol)J)>VbvoJ12zg?+yCNL}s_7=-QbqSdW~@&oqSxOu4bP@5iiI44tBr2} z8w!ZkC2?9y7W|+P>Ggl-_=)tozs8FUyO)nEMkj6WQvDZb>nOHG+65^Ro%ut7^572e za0OuJa=2n~Ecy7*lrf)4~VxPj?yGCADR} zx7gV>-q_1^>{t_1f3H&{xKiS{WpR9~SmWJjMdJ%kO`Kd=^Nt;Jyj)w|mRRPT2|(yh z@Wy;#kY?clh*?F_Aj!;F?#w*epQk!FG4-{co9k$c(09>nfAWU$Vrhe6#%hfX=~gK; zycE))C85dqZ|_EVy_u>^c+Y>00(Y#X;OR9~L!|U`SXM;DDa8;xJQi^exw%Dn5~W2u z>>j>hROg)auRwIRW=?UzkYmokc_f|xs&z@L&XvY=SE0#`<=&6F{zq9*DTgUa3jy7)T^yVP57UFuNB?Imi@Q4p$PO76*6P zXjJ+R{MQ3C03)Gew{e5K6cnlKpJl5Gnd_SCXXR6-ZMNKuO8A61SVf&pHZn zoHbZGHR$BOMrz)=gR$l0t#t>xfw8&#{oA5*{A_9t@P`Do3<877KGC_g0n$><;jH`L z{X%W_eOS^rUeU}nn_Zqz42muPWfI6iWRo$NkxGhv35y{ASwM?Y>-r4eWcUI$t{vb; zfRG$+4=F!w!fv&is3w&VXx=RNjnQRzos3e}kg}tfFjhI7z9vEli48Q0@SiXOiNtX; z6zls#3^((Jg(*`%nScc!^lMnp&4_leFc2gwd^yUE^p>`9lt~t^`#TclC6Nzt_4lVU zx)H8{BinQ56839n320||iQ1I8#8BHypeOV!z zc{z^ylD6?Q3FNvn>WXfU4|*&N;;L0dg2wG{pUbU&6$uY2q{73^C3et=F-!0gXM;PK zKzuSjwXcG_ZhWD!npr4;k#QkYw(jud?p7!?@ymG8Iz$K*0eqQbr>hnl$*Ge8k?RCQ zFbVG@s`+|+hW?<+<;7S=zB1Uq@@ln~))XZ4F$$5CNUWn;wU8*lOsqdS_Rid--ag?H z%8Z==kAaL(WI%EzBsyt+87B?VHNyuQuo3YLXHxyD(RtmQ0Gss3XarI)!Qx)mLTDrd~ z61MBDcmoiv)E-^7lsCtB&!34W>ji)iI94{g?0EML`LF=f%ZlH6yT97dIN58WGe0qa z_WxzG%qr+RH(#ndQX&*b1m`C!5P$l&+b!H9G~$Y}f#B?|N)yi zAJ7Zcx~Xx0d`+1a`>fI(@(^VK#vXoB;zdR<0tFkhEU+$cChk-6LW*}r&6?x}`79r4 zW+f;}lY{cqpm30mOP!6GF7e-nXEzaR!>Jveg=4v{-?(RlT_ob7Fl<`qk?Dpjpvg>! zEM|Y*#1uCbS^yciVmhV)4H4XHTrW)dAEV)Q3^(Rtd(~1j@)BK9{EDl|!7)7sOT3s2 z&%246g3iMPt}53PW|I;*@H@+SENo=SQBf49P=NZoahttX4Zd)%_s(3QeTrq2Tv3dL z5k|L>?W%~GCL}6Zjc!|kjAfL#kg>dj=(fAnz56!()V<@ZXxH9S0A3#d^}SeKe50}Q zjmV1;XF!D~bLX_|6Tdjp$bujhF#=0?*80a%=(DXk{4}WV<@&vD7{0Kgn68m^e?38G zW`47^@{NjfmuX(P0A8826oQ8LvkRIGi$-s|rC;gI`*xfN<|Yl%Wj$q`o#@Wp;B7!_ z#vp@}({PjuZBwCgf(kl`_E4fX#Yw*Ac0F6nq{8%*XL6iq;-ocdXP3_|}C6BNWMo+M9d;W*ZhmdiGQf^fVt@bc}T&d%S`>2iK@{}{LYi%q(h{XnU; z=Ve(%=fEbEcrmiE*MV)6~ffJZ7_3ut{m`gUO6 z!9fMNu?#UeWw@vjGLmH*q=bvVf9>tab$MQ!@8|Hz2U@TMHe#6!T@Sx25x$9zLE^~s z9@KZ8)-2rd$yqBNVI5jFGL`Wa+d>CY8hZ|$m7zp7FxMY&C4Cb9==iObo(P!(KPmiB z?L2&%WZh~y@gqA*oJ4X50oT)oLo7;%XA9L>7{`i8JA$-)V8{xXJLSFvJ{J~1=*r^6 zxpxhla;Pn;f=bCxcC|-n1Hz7Ik_#mXux8ae@j$zqu~T_6)oYo2!)eFSDmMu@$}TlU ztR^)?$+1g{ol|%5`4bcwJRem$6C=Y{TuRf1swXyr)k?YKWb@1ZltOgY%>!EYCid{h z?snC_3rq5;r|J#iaukNw*b%PC2_xrkA`nIhIkXKhO1fU>LRKCr_e2g~tT_}j{83_V z_H%fEJ~E9JNR<$M2`Qk$9}PDKh8;pj9X&^(RRY-6ssb4VF~V8Kkzxt95=E79UJ!_B zq;D3@1cb{w0J!M1KU%a38gtU9j?4Q#+|4*(SOgjPMCpY@o#N-b-jyJEqQFIezpdh$D2%!In2p0 zZ>Hs+a9I?f_T2+P^%8GeFSvHR*T04mZ)j`d+sKjr+qY@vLbTWE?YW12vn+WD;(4E8 zo=6sDv?`Hf^eERHs_r)cj?1hMAA&Yk_Uz5(j(kLHL$i>9`f3ozI?mniVYrH7!xF5o z9y9Z95&MiFZS1{dlbFqN|grR~>E0r$UV` zI7;Q1RfIy5;-5p}eRoC0ni!;}ewLU=c<<$zIqvA~UR(z@Ql_A#plb$9fiXKyI7qkV z+q&oWJQ_J)-L~^vXxQ(XV5z=69QNUCSN?=^c{@%_4bSt;XgvdbqkKL*ec_23REe(E zmeo&!1{EOCisP3$s#e>cvTq+3i0qJEd8(%?%EfJv?n~7AruN{Or%1^_*HF#EN$L|c zIKPj`7jzERe$~Qr58yE8FblDb^VFWZyakk5eJnt7mgeyFnA+;(dXv*WV68!K@$G1F z6jg=~!4As|PNgl-M`c3kt{#50*TU6Gf25s%I;PsMIhS~HQouZy})P2ZD1ox8s<-gc&*XM%L$B9q9(66COO}5z2}9M zoM@OdWcq{~e0`22Df7`;8pHh!G9^)E-f>>p*!^o=Ds&+ch~gAMQ*OZdC!odhj0vs1 z*xiKoh(*OP8zc9@D+-3G;-{LmU5-p%;?v|PwQmI*e%hi$`yPo?f1RLFxB7!E^ucuy zO~pqxCPUVGSF1q!sEYx|F|2MCn~L0g-ExA|SC!kLzew35WM=+-ihp1^<6h9Bi~dtX z*&BE-o9Ij-VYRB9bvq{83?ZlDZJh3~WY&GhF_i!nN-pQaQnJiQe6UJfdDwk3*0??G z;nI*_z-=ycve4W^$5Fcr?F4#>Q{v)2R&jRv8&;0Dixz}RxTzrOmnY;mJ!7yoXYT@w&}jGs-EIiD zmfm1~5j2#YUte%__TH6svQhBFoQv42rQ;TM5C)*j5-yGBfh|2Ppd_OR=Uq!M zidI-@-%J+S+kPsoN2Nva$cx9G?5ZhUh2V$JS-YQ&c8B>#vpk|`UzMl5I;MhEoT#>3 z8qEDQpcO(x>FGn=cGGLxT@*jGC%3H~g0oDS=_invE0&Xh>w>e=(6^-Oq2O5;-8zlE zp!B9-bB@Q1mInMO4FzYO?ju##P919u^WRd4dIAJbFCW9`Ds!SeBKwGcSV zrd{A_!FadQo*_WJL2XHBck!P{QTll+!`z=x7>8i3m@_}S5dZ{P+H(ema)2!QOWO*h zC_Ins@ji8nQr`;{)oug_Hdc*CL$SUFO`Qc?nXuk@?-U2Lr{sq(O>HB!C2LzS_fePU z1W2DAKJqsG9Qao}L)4GNvP{({I0{8}*bA~&SFB}a8)Vx9X83|hDiNoILEGb^kb5u}Lt|AzHH)_JcXVv7*PRf|V`Dy!dSNX{51Y`|1$Y2KqNIf#yy ztJE%TjM*qcwaJ+?5ZT9ycuFv&8+98=yHdtCBQ{|BF6k?cNR9hieciA?cgQKV9sc*c zGCe)_^N9d7smGCHxv~|<{qI0hE-WBB@(yCKvMM)m`W3EpS(SGE+kBfe_PS177B5q+ zA{v4XA*@nC1IN(h6pxf4UAf^u`Q1fM63?i}H5C{69#^n%lW|~5O;alG7?e`}5>(9c zZ$M-7E*m;Kb%up~Omn~VjAD@UO6-UYV=Vc=I%U#oWLYCN&>gadt>>oJ!$*)$4jadbyFdDmk)`IHh{>r3hI}O zR+ME%9;8++v53*@!Tfmn_=xIB|ekbulf4%B{Jyf}E?D#(U)!7E|bXaU!K3P^R@3@P3KUv;Qp;Wz;ed)n= z_MXdHabBCn`c|Bo@T?XXJ#=qRXaO}a*MzpA7__UkH1Ngbw^Y^wS%31w)XuO9t((2D zJOLFL>3t`(B=SKJtieP6E6yxNcL=ADgP&bkaV#&+DqZx+n4{W|1D$DV+p=1hb^Q`6 zFxU07{M|ak{uW;&JWw}dM>Of29$h{?KiAGqzRz37U-wr`Do=#yj2MxsL*ygvV*ee5Zow-zYMOaVURnm;CB%Yn^ zZgxS2N)Mz_F4*dysZ4eK3xQN)AaGIH0Nr*BFd07s|>L+AaCF9N2#Mxwg$i4Z8vzY!mGjFLPDe7*5 zo3C!pLUMGDR>Uw_krEs2Jb*d04>n4I8pB%Wp{KFvsgXmf z>+o|%Y@;yVnxBR&H5TICW6D)!^aTGaJa$A{Rntt4k#l5nl4}Jt#^DX zJJ$5&IAz~mg`{HaSL{xQ&b%va^QD~(^%^6zNC4d4B-$kzKY`&Xhv)X#m7zpIOdQt2 zP8geq?%(9}0D$9bDS_%u|5`oS@1>eNE5xal2jXE9BN{Sl#c1{qRZW?;?H z5u8hnhh#?}LFgj(r*lR0_+8RbxcG|-EV&M~dN?!%eVTjol)$Iewk7*LXX^_Y6#Az8 z!%0+NC|ao;-zu4Pk;2n_`gK#99DVGt++_x2A8Y?F7HbuOXGg|4AnmR4_x1OE9u3|0 z(?~FrC@u&-6Jlzn^Cm^BBQti^Y!eDpfdryGs$d`lmlYfW34pVt=<>n+k7C<#+}}8z z-d(4lcyZ0@syI{}78B|)-x^a9k`+mwxJNdJ4HB;}4Be;N-3B8fY7&dsIQ~}ZDl@I% zWCqYjQ7ssqCzP&~40&k>A_wd8zr*BjZyCf zW5&1``^!HA>xU6fl&6dile6{Y75}6`T%b!2rVdP7!Cv5#oi7wPU05Q za;ndA#Mo8Nz8!D$%}P7Vq;7UWV#RSf8tO`8FqEi+!;Io1*~mn7_RXE6R1?uI-_*+o z6?u%Ee5TrVAa&hz^VD_h<&Z*A96~W;$}%CGjGnem`|1H5+mA>=(buUnX;2&pAUEW) zcIC1!_3bsa(|J5tF!+c6!bg#1c#YG##R|FQ(WxcI!2BIEayK z-?KR~m)8xYmkJ0M7W@>WXE|zC5)WQ)zGB9&rFd#;Z#!J~#99WrblBD7=?E%BTJ~4p zK*a>qS{F_$RD~%CP!)Aj$hdr?SK2<&`DO@L+3Ei_D3LnJ8&iS6&XV8NNwO(fw&n_S zH&zI3XxT<9X?}VlC&q|@VX`#m)s4PA*xZ?HWLtMAEzk7KNHq;9svK&%q-t7W$dI>c z#sSEX;f%z-m3SrGOmI&j^R0ODR+FvLnCXlK-9#X}2WH&5SKx>35Mc{MU|x-V>j#6gh*MU;wQlPf(H_z2{=E0FawmmKzgM-Qdt|DdvKY=J|K5BUKgUjmP0J z(UX?{8Rfi}+cWm*^o*-7MG8LAn>WQoM`Mrzi84~V;$S{*GM7&&wi(fy)te5>v(u98 zdAmE=KKfL*b*3;&_gldZs;VZS5Es!+8?!>vHs|p8jn}GILc0*)dSsD9nz;0=$$FGK zCvS|l1#%US=xXFjoaYM*0R{9vx@l{}d`_O+Z}{N#-k|;nL6v`w*nCjn2K8lDO+EL@ z4pbhAl8kr7FJ;l%89vsAfGyc<)}1pNPzRGae`uX&GG@_ZUs) zBPcs06QCEu3b&aYZG+!L#v)BDwjgecEij) zA#?QLmav$NGTeBe9b}6J6>WIkSip0mpvJFzTjPk{ow8N?hpP_fh}t&cZ*bCoF#{e3z=R9PXvE3 z7E%0RI>pk0fc2>y1He;~?2xZaR*Fqj4#KhU`8fXj@l4fzgUNk0Z0sDbP-8|czDE3S zCN@!}GISJOvS17qvCc}q_e8+^Mg0CmYB=uk$@5NaZ}O+h`XR&n*oY`*8-J>NVb5NG zVKtmqRSimG30^1V^1V9d-e+z9#muL-lFVx0f~tRYBloDOFCfT>=PKjlFYaH$NiPs+ zgWKd3mGYF`# zD4f(_!>h0#BvORq(hO=ZCb2Q>mJO6dALxhT{3<5$EtNK`4VqU42e1mM_Ak!#0js;J zhpQ2$2?r{KNR?yj2pj4+j!^614qeY3Md0sKS$UtBnsW2G@}V445s~^b}n!Y%Z1tNegUH2(sMH zOoSe>FXhbQ97y$I%C-Z?6OW^`G~1MJPb3I4e?`;x-f=d$)bbFKFsbs&+}@FPvBD_z zYQ*YLINC%5>YN4xb_PIuy|kuiK%k3rX$bvWCM7k(jMek@b6jiF5`!Mz`$F{zh9Oaf zl`Lq1hbjIy{t>7+VUc!=c=xa%Z>Pvb5C_w)Inp93rXQ~9vYyNASX_)rRl*{ECNnNu zB~2BVX(Nl8lEV{L1|Ka*6;eVr%%2Z1FS@Z3HjlAEfY|r#!@+vG?W(c$MAZ(-=j#m3 zycjFlILCOD8W668m8oI@Ld4v1=F!5Ix{JeogY}8UVq1jUwD%D_YvV@*sY6zJ z!L!R$=1pD3snj&8bG$m4Awz=yV&0IUDGnS5SAy&WS}IkA68G{6^Q2<>Ii=;&t)!u4 zF&v#Y$%+v zsau58ruWzqgawjHETU*_J-v)o?6bITz>ff*9l;DH9*c}tB7J@MAlOyC6Wzsu~5P&QUs;8oeR)yd)Nr~#1012;ZKluD4 zFtajwAd{YXa7{8H0%kH&7|+bANjU(wo*;sAuJXr+1ri);)na2J>t)`Iw3F}o;a{7Y z+ob0kCK;KS%0zk05+!g67^*u<^{8xFf5ObBBjeLq=tcX>2e%B*G;foRYa@_0sJ#m@ zoDe5~t|0%OWS~MjBY=jFR|nHgdEx11jZKTMdHW=QmuDzxo*;^irsR5+wYSK;c}Y-^ zHKr;Pl}h^B%(0Qpdq*Lx`DCsTm{!Z+rD*jaHJ=3jU;W7K zbo=Lbh(Dr0uo51O4^=dbJG9b~dY8jFGu{CS^uYU(xy+xUR^fR>mC(Y&#yJX_DCQOE znh8;YBoSSBcptuYv*=#3$HPQ2)69*HFZVNy%;hmYmwQ9srz|c|ypO1@Gp0ZH1eUIz zNG3Xex765R6lrjYdLe7`RgbD=OIIiUj$Qow36f{l7-KW8m(|@ zgnAV!8%*9x@gNPDy{r)66f;&D)6I9b?>djA>PWhf?4(<*BFeNqODY$|ZK8dv>?8Yr zhNlH)S?UYa5?A0hDA4rjic6istjAVToaI8w)H_CUOfm&rIn|lJLJoJ}jGhvzKT_LI z;QPr2=sde?vP#}m9&S%h=eMQ70JcK#=#ZdY)5C?@P2}~B@xj?q-OtHEchJ6;WZ`my z>Id+@t8P`4NV-k`&mT-`z(45!Q*|~bPEH19CjXCq>`m>9I4rirpI$$a9c;%mkbUSK zxIx+7CbllnePT2&fIxikNaML8sW{KpuA{q4J-?w;W;j00WX6oKtuS_?h#}Jk-9Adx zkGV8Exs79(=fOfPUf%t@rXtX^2C1l{ixDxt?)UQmuJ`+>K5owqT1Q*+OGkI_=JPZ- zE_BqvL6YqKTl;9ZvK_oq+FDr$4&K9G@Zm*MWD(u>JagQA;ZW%XS{<5{IUb$>rw%n9 zv9}XHN^U z+&leqJvMH2YE*+p@ran>A9Q;G_tFw5+{VR3BKyN#rBN}M?3|}9tl|bVc5IuIf{f*f zkA0MGo9}1V)~evMxx3?uDus(DR-l^L<Mn%7SI>rjVKMu0 zv1M@^Pk4F^w+y-2Pms=mhuDMv1R4*4oi;TP(oNMz79Nhixpn3y?}?vJBDiqVcJDhdEBP)6j!`d9}kMX^J>EjOY_pT)C_XRI`8GA(VvqB;00 zwHvEd23wY*GB-+wNHE*J3N%)xE0QWhf&1G07oLni|tOOG*qJfo5G;=|cG|drJMM zqPJQUvvaHbe8NKtInzP4PswNJy*#KH)1D$Wb-fEP^dL2;)Q6jsVPuqSJ&(~|KNnLLTI7~v+DgGS1TiPKE3iNCO4A% zcihf>&Uu2doz5=|_MN%n0LvV$q8vkm-x}?%t&xxU{!~Iz%&#V8D9?JXNzvs)Y6#OL8j&S+dA+M4@;PgkJP!Mfqev4V z!uua>9BqF31QLVhSV$3K8`C*3VPiyBsKd3;i=SnV!&G+zj(co~ zvXfwQ!SP{GQb&>I)!O@y8uXXr8_px@AjRt$eOS`7zco<5E@5f$3k;@yOxcb+i7t%K zS`y$eD>}Z8SD5R;!i=LZtAy|Jb@JyN7hfaTTW0d2)_&62Z8QB{6f*@2q~;mYl1OI@ z)1j6wdafbv39gi{xx3cdyVLeX17AM@QbD=do}VZ0JGudYk-_svxo z*6gTwp16pUOD44eVI>3vKV6y#q4oYpshV)x_{j+2%ji45aN%LS4;85ca!It74lave zbOA;C>3QKX>><#i;FWAF-Cb9aa^GAmZ9#K}nx;CoEy~jNrT;8wu&Kp%Tw=xK1QSKM$oUz!b(PT3S?mg#X zx$y47`(*MO^YQgDFh%0av}8Huv|L_kZY=}uKM*1{B?7~eCI~rAjGe$4j!ycu-qlq+ zI#p1BN7H5W!$~gJ!6n3uLjjh+4I{x#OT%7@TYIm-8%_6TQ-CvNe%G=V6z0HJ;8UQX z@Y#dKJW3quBP|XID)@av@Leb+vq$p9n2%e;nK0zmWZNG=hmDxS*U5q26?p=khzf43 zLupq(H?s2BF|_L1irxTIHWHyQN6w7%oy_) zY56@uFLX)#gEh&VOlgftz!m?81B${jQD(!YtTk(TTP?KV;qSac*rByUD#VJ|{lcJd zex0l-zXe#J?;nS<22~4LzqRrlHje34CxG zOy6Bfe)m{RL_=AIilw32^uoJGO??QKT+idd8mK%;iPc?#9A?rl9t*3zEAN!}f|#~+ z(sA2&;Y%Alp<)lihU1(Ps4T{2f`>o}SdNIV zp5R@hrkw8U+fcr(%IFZK&-=l3%(e>vagJcBO+p2AhyAlIJeGk^p~Bv&@`|^4FnVwK z$<6elFtMiI-$Mx22w%gER!*KKH}7u*od^|5LEu~~e&k0@7Ss%33@Fs1zDd#kKru}zFHNS1P_11Wm&*|2Q$(JXM?H^+d4jH{d zA-x69r~w)X9IrH>uOfmd-kO!UP+Mlr;#}ndHoNdEs%{Nfm@iSQb75hcO5K3-?>u!^ zE^h=+2A;^r78}3JS!RUf$8~+s+v)DCQdz>m=L5u~Af2Lc8ed*3rbj%s*EU5BiAK4g zTl#8^;%D`cT&;&#rA}?OXKb?s$;mTPwb&vEJD(Kc&wre2$nNL74^GY#P9r(UR%=%3 z#{X$#FFNWCa8=>tn$fT0J&aqJNn3Yg{0QTk^a9uC#G)lijPw+VXn;<|cXUM+0KKuw zJZ7`O2C1m+0-lhpg)Io*>UQrrU&)bOvfGg=1Nj;CB^Q`i~^vc-y}fS4COHfaqW zq%U$RbUq`+Qjk~GD!4RxQ@d2YcjC z(TkMhA;!`n73cL-mAG$ZBl1;5lzmh(J=t=tpf*6OM=tQn`mR1G6E9axQ+xcyEA>-M zxFHV+7*Snn*&{xBwNWS?-rI&WTzDOWOutXh|C9#L0tkx-h}qyf88HW_m4g2j?H3Y3 zczk1|F+98AKARpROhelsXG(d^?5+00N-R}p&UUV1m2o7@ou+3wArt2}4GiDFQW)x8 zamy!#?u$-RhS*H***)T2j1k-P78J+@h6y_kPUINKda7~yA#=}A3-lsCX~Rj_`tmtK zhLF&w$Ba2jW>o66W&t7Z7m4pJ-G9S@9^~jhv7B__@I|G@{!<^bP_bzUqsoCF1if2b z_5;py6kQRRmKQmmZG+0LG7pqUx!s-MC8*Uma-9>MS% zRZf;AuEnva0IWeK!BB0OR36fJV6t|g9>d99&NJ&3Vy4UUBDczOwb+`;@r9Y)$zfL> z9{|Hhav)C<8Ukb#PfT7k(OocA%cPN==&5%}slZl&IRd;X#2lZVx;3-v*%`NhYPxBZ z0y2UwpJgH|g67;v7d{I?9>B!0%y-MM&ucCFJyat80hmW&$ic6v`)4By80SR8Fwo0> z>yGHVIz0?(tOuoBoobMK|HW`po(C%d0vaj4i-a&9i?@Q(w3?x`%u8zv==FPYd2sB; zf8rFte(95W#Qpl@k!j^?(sU$siXKm%ltZF^?x#K7I2BkYWS@Oxdzqg5ECf zc*1H!jz%P@OVzpwc*|~{26v?l00BaAeHwIB(y3D&rV3nR9O7{f)N`^28Q?X)WBJF` zeU&l?e328HuCj~jG&&mOtZA|5bI+m^uf8oZXU$$=7w#QqEz9^GPl)f9EMd9`sS}Ev zp#bR-oGeeN_7EAUwpCi<5OI>_;=2r;Y=CmPMw7M>@?)FB;G-5u-u+u$nPe0xD-8VF zdIIEaaZp7I^-P)Rf2mu=oRnP@UJ+1Hh{=>ZZPe-?9YG?qOnLZUUW$l z$g3oQqqAWX$y5R2at9hccx}cgN@hr*2%yF>VF1TRY1n`n z3D3xbA+39P>ds0hYUpLtmcXK`d>M3^dA`IIzpXuCL@Z{nQm=+GTUg|>(8eCc1!+lw zn$cP7es3nhZLjyn-ldhJ?rmt>j9xhC>yhgN5Xs#hyyXW2@ANKJA+1G_?qCMgeR&Ll8KwJdEt351tf%lopJs_|Ma5IXxx00vHdg-G2xfVoS!epx#&Mu-N zMbTJwlQM5qdAzlphe1zb!2D?BaZ6q6c{7^QjpEe3%ikU(9GO1_97>UQrwAEyN93ew zHz;)-rBDT!2gwCZov!?Z5E)=M_$FB~O#Kw|UHQqvq{8*`1Q}(`!z(%-Q<^-j?S<_& z?H3?W=+2V(?)s3$#gpn5QXIaM09Lxj%@iO@cpBCtGxv_-4Tab%W$86Bn`zs$2Tbkfys`P3w3$v&GW8pPUu5^SM354hD=*Af&V? z4JV$6eAureMY0?aX;Et@Oix)PkS8lA#zxyLPu7S;4*;PN%4d&Ee!MX_Snl98;|c2i~LtW2yVA{ zb*!27<$w9H*aiaxp$89`99?W%D38l6C!3HBU;&j+n6CqQYIlKl8Smao>K2~P$2d_v zg`0mwQ6yj@Pb^Uo)C~`SEH@qDg*7pBvE^-t)>+2o8E2i^By`;gArzl5TPv^|>!dGg zqGHQ;^iOH(0zJ2SIH|Vo_|);0nhcEJW4JJRnnF_ET6t_7T}OG7G^==l1VWHX(&;r$k)Bq<;7K!wXiDN8h2^BO7-68MF=yXSao&f z9X z3FhEHCI{c~+ZZw8!m{Qh>ijf0?E^mLF~^t)S^CsqrTGPMKs~xKP0)8J+~~|M#ULuk zwn9+cOh$^Tn^2Us;pLS=$sHk^B}BwKy~bR7mj@1X6XqZ8q%VFwg)KGA@(NXZ?M>dS z;KbP93`3e@bE~$q8hlIM@{rlo$7Lk{OR(h;U1 zgXlStRn#9FYjVFQuCF@5HBC_9s_a1zg)rrfcf8VcsVsu+LMaRkXA9j!S`{fLrGhx~ z-v4j}+rV@l(3Ky%)tiS6%@e(Jc$vDs#OtV!p2ge=Gb$GgW@g1 zwK*SOXnL;XihjE5-(2z*JnBrY)TPhW%&N|k(5nF>n@P%Me&)z0)^B!!-puFiLi_Ph zRUNHevVP9%etaG7ZXZ@LjBS%k7|-?QGYFd~vqDYV2z=qucZYx|Kw9B*p6B0R!sx*{6WD}FU-2c#76?=GdvoRz zhB0%YqG);}s!QEnylgCn1$_zo16NITPa34DI`e(v0-*|@Cn5D5KIDKWA z{(L#ZWq0nPx=5r>OKA)L7XVK{u)pw>?*`WJoC5VCfFK)k-MXyS*?iNy9Qz}Bb74p5 zOW~72L#yy)3#ku7+|V)-s{qmqdPGaPP4m(`(2Ir9)yi#;gq( zgnCvvkLGmF(Mi()3vTm2$4&Hu!+U`r8{_3EvM}p27;m`p20x`?Ih7nyJ*Cj#{b&zv zJQvj%WBtcKt#p#gE*8*$8&c{}f)#}`L_7@%98{bTmzPwXux~p&mD_bV`|%{4pU(a= zpuO7Y+xM>2m=bN!0Tr*$K6y05OD-m$v=5f2tYv8k*MD87(K_+n)l<&{Hz-F_%So@L z4-UYUC{U&oJNR+$J5YX|TxkQk^TR^XC*CLn>=8KD-Bh?N^~@eU9S1rXEg zf8h#BQ)LZWT|9u&01|}s1&T((Ew#8+WH3ZFqYOscHiL(YXZN0P}2yMFZV`}I~fbcD?%59J(oWr6TG?fmcP*8A} zyMC*My8QNS1%KBu=RxPr`%Fu_=8$VxUBRl^)BY=-z|=0aS@zVD`iBfB1ae_0~PQTrG~u@`B3FVY3kjzsHw-|Naj%Ja2Hm9$+p#cbBP?-V_tuC6ul>TW7L~!j}w6Xde>7 z&<3O9-L_Dw+oJ>w@r>NTM4ZN6;mAGSv!^Pf?kcIaRaUnJRn2C~E56XwE~`Lvcfvc$ zLpFk}b>$hv%nYRLcmrVkW_kYkmQ9G73UnoE%@L{(jqaW22(JW_Oe>3MGO82>LKg&* zK4`?rXt_Jv(z26SX0M=Y+Wf=v8h=`r$JWVjX21LSVnMW^^}4%X?||}tT~8IL%PZUyS9_A2I&@bZ-c?jlzoE1FFExgT1L>g7sK|MJK#sXpt=Yl_peG*8 z;^iF0{*Fm~wpiYT#pb5o^DO+_-KVQ0>{#vRSMyD?TjF1BReJa32!q@zNWPRreE$wn zPv)L8qod*mA!!Q<`@6fc(b4vI|2=w*)De!*$aJ=XE5Yy|C(#6QT$C(>kI8u6Qu{!4 zh{wwf6@6X|q~>{gY_F*|!Zj!gr~)jYEQO$WstK|-rg^RD9b>#paLs zcwn#DG-7tqWF>?I!%&5npiq<+YXNkzT=~?}qhfx1K7a(}_VQkH_SwDo@vNrWUhD{; zezaL#5q1h#zq0|*FxTpFXpV9tkVJmn~-P`IE&%#Z8{|a35mhhf(sP?8>vjd(ealeKg z1t)4BSZ%sBp*?ly0k6N!nN0IF;*;6sc}Ac`P5uxWU7pu~R#?n8b2JKOKcTSCSMzoE zYI_Sm-(~{MJI_LuOkGf{&S%G2xZ~q%7smg`mtkr!kYeoy9i8Kj`Qk#9GHZrkIn2) zLniiM(A0imu2iv9;f2aSdY(hdkp&f!_0fWDsC0UJPvW8ZPIhi3MZ6Vwbb2DOex4u0 zYI)fiG@WcD4vmvJ%BAy%`@GBKj3J%o<#L7RC}jN4_S(h#{1pGTz6fUrGuWg<)XC@n z^N;`D%n;?SZVtMG85VTh@P{q&OhAcU`$IQNfPd1-_3n}p@pH|x^nia5aPj1I=ETgD zOmvhJP#UU=?&RXZmLi2%R4xz@Ze`PYSvEKUIH;tWijaZYdR!Wf!%P z+9-p_!)u`fbv2Q)B^Q8-`>%J1isrCbE>AlSsQKA^5mvXpxaIkWshen%zFW-GX>BrF zSBwa<;V~+t9o+n(KGoaxey1@tbXw!l@j_y_fc5=srUp~Dojh>xeJ3w< z;U?QClHw{;Zx-zhwO+Ia?U)iUzDNeF2BZhu!%3W}wMQ^yVj&B;Sit4-ea+%)jdD^t#W+kmM^g+KfwRV*A7pmuuq! z*U5meWUaRMSzmX|d_$GW&|d7LAJc2jkKr)3A(eu-A%iw()hO~f+MtxPg;>L$U%3yd zQ`%z*Me<^K{A60^Al?7MhfM9@F;**3)}zkWDyCdi0jd%cv8ZfwgA2aO_T$P`O_=~E zcs-o2yCxy`jxJf+`!t%HlNIF(*O@=HM-HCgk^PczZN2qgn$N6+`JyWW-D23<;H1ij z$Jy3{bk;xByry73y3k) zZp(%_>zvJzS;MV|hQv>Tp7a@Zl8s6RhrrgyV_!x^@|rMqTR#7aQ9;CKqTr4bJ`!W1 zcR5FHDA1t-j}0P;bW^x%Z+quY|Lo2Bvx8aKo!#q`IjXKLI3Qqw1}$Zj)e}|^;%@Ro zwBpoHp88nxppC|}933KI8Krd6N?syJDidK1Pl3()1MKYgl&o-Ir}Ia)4b9j7(8`KDsv1>F&dD>o_7JcH?@~tSfADmuPXV&DeOar zNhHm$=Y3yR*Z+ikvfx7SrI>=)0|AJ15G5Kx!ZPh-L$v#k%N0-pUbQG!K;Q{>XOUKh z^3lMbJ|H2#@pU@6b$MBV7pcI zYkc$G?>izdhG(d?ht4XWqlVygKsYHGi_D9bhO2#h|2AszBG>8^r*Nt_>4n21G(xet zNNX6`$65v(bSy@K)Y@3v#C+D~bZ$>VZ@pdbN_;{l{th(P=WSymuLhR6~24@7pd+dv8Cqfz$n=FQZ=icpvEkU-k9AOXLjAXHZ#5Spszpj)FR_ z5PLmZo-Jt@ooAqn#jQ`~7ZirOniF$HsJ$tx+D6#9yx(zW7u9XHx?lX9seSc=g%X1Y zZ8EULbC6kc=Q!ut3g1HJ`aNOxZC4`52c1^CYh3ifhC@4Vb$cZ5{lVQt+^T_Odn5_A{RRH@ zU`GEvJpP4#IR2$Q&h>Gg{W4(llvm$+D0FVPDKT>wSWH|3uD6p-p4&fPP(tjT!>Wet zw#LNS#pMQ8?Jj_pTTNXxr=xPjT5P4xqWEZKa79A0NjZ&DrJ16OzS}^Gu5QTG^;TXK z1a*k@P^!C7vIQ%-Fj0$`lWJ)b`|f19B>QpDoE{9Cn)bsPsemc(iI)_dHo{nmDl701 z@e{W1)IE!9;KsZ+vN!2$L@HAe%+%tkqH&6aYF(0&EC*$P^OmHux1?N;S0O(jn5l*& zMY4BR`xbIEGlq@0@zjZ4**fnGLOO|9FK20^k~IrkP#!8Ytj=Hp#8%S7F&$?kPt;`r z4{DNNT_K-_@reWxr8u(cmQg z!<@22%g}bZkA_Xnuwl7lQae*nUOL7V$KxX-QHHCKatrF;QXvlM+q^fTch`-uW`pER zM~emvWE2pTbB0sfLH9ErigsT1W61;C6%Hw0$oHFTmU%H z01Ll(vz}eyqOF^IbnK7lJ^mxMlrSz)TX5^8K&`_fqqH}P(-f@8*dW+;Z#Q^4A7M68 z2TP5>c_?V*+H4WGBYrnR=_Hz%V84NNTFozpRQ%o>(tG4bnC~_ilLb#j2PL)gQhLXV z!D*p!mfx{?{iK>F1A#G^t0&z(>dGVu+kX-8H& z4E#JC)i*CcrU|JrN*E#`E{OqtHx$oBfr~EUcWbH2{*O5#vzIVs_S~R%w$CPfy@E*Z zz~1W#b&nw2_{@DYR!6jmn06&A`iM+t(eSyhT0hIxOB0Mf-tuokJnDWvTHwpP-trfr z95qW+nHoidcgm6Hyf~EN4q@pFxMm5BRjRuUasJlW3Ypj!UDvBo2~5N8-wSVl6(4(j z^tv4xa?TE*nBoln6PPVVL==*aGs}5t0I}cgcXe!UdU9{j)EQBfHK}AS0no_coD3*V zP6w0oNx&#z!V;bKb@dQr6z zG2b1g<=K!loratBChLE?Q25csay_rn`r7+sckEv8#5u`Or3pM}(L3CyB1b@ck4I4A zVQk@g{%)5~UDG$q@{)MhmaEQ}d$L@%Cn&busn^T)JVEsIACmI3>#KgXqyBikBEyoj z%EfS>vb0_#{DMrE7&wt=wG`6*xMeKqCPVp$q|4^(HPvR-8t|*In77B^+wa#KY9AAl z;ntyT$3iS7aA_RaU?n6LGAa<)kbJW%4yYZkR&X^Zz6tU#4y`VD;s#SY<}`vJD@A53 z2pgnG+2j8zpd9x`rG~)mzb|*Mno&x|WoYNVdvfT@to7-SWhF;le|40X>9Wh`e!Zdz zr(-e}Hy$n`-{?JbNx!?7Z%+SsG;V6*1{WpRh<0l>QYBRWE}#qw zDkTBd@rI4}9^d*R+|cWhaBtT0kH_@~Tt+dmq|B)+fY(e~jX+d^Kp~4pI@*A#p*V>G zC-l@IftK$2-pPnjzI&jwj_gbnS_Gw%(X^~Uf&xh9@DT<(oqM+OG(`E zps2O6V^LX-dbTCY^*gw3Z=`Yk%nUxEYT0h1S9XY?HZeRamWAY+>VjQKj`094qTFg} z-Tr0;1@Y<;#i8EJzMSp;9?mFR?oI2rdGezMX;X&Ru#({K-OsI z#g6aO{f+y3_e+lKnUS=%wujwrNeSRsV^#GuySm7SEb`&-`R{wU-mP};@BiB%?Ubi6 z`O1syeA`qb>&0$4Ip@k-jf$+ZEg_~@qTm7j*YS46{U+{B7!~I{GuoqVR7ML=w?89o z%a&9v^q=LPqAi;OE-(so*d++*a{cb2!e)1%yE{m6=LnzJ#^rn<;_Hoq_!($XqvyVa zS^1hnXo_CPtW&BUOLJa=7XP$rxa6~tUvKGBy3S!_I8l(BQCdMX^N*`8c4-b{$K9A2Z)S~& zHl>2>K$9O`b)+2&rl%SLAK6R%m|L)4hBxx+w#B~gjL~_9Bfg`WzQn5={`>6;-wpqJN}a8YapV{o&k0*PIzkf-dbdV< zBOyP3#TR5l!z7D)q^D2czNQZ+jUtYqoxjldLHmr8cJzhZ`OGXcu69$&UF^^xMwLR3 zNyI?99?Fw|rMYgfX%`1HIEfkk;R}qONUIt7=+%{wG9s3qFgqq90d~q7iQ5W@TCtz* zmJjo|OmwcaAI={ac8;Q}f%(Y^j&v8I(Lkt>eyBEkQgxC>x<3xLCO>+*8$T+{oD`k_ z9y_-$2WO1Q0iif()x}UV_bZSH!wCGOHYc=d|6tm<7F9F+YT9~)+lx;0UTU3MEVc$i zh`vT0=^d3W)C}1^n6|uZj+<2WT#zXsAhl2c!Lm1(XeUbez+NyD?bT%2KAN_?Y$-(R ztdFsS?$%Zypl?8D?`&zt3t~I}f$zC}j993<@#E5*Kh}I;hdE6kt`^^`0;5vPu0!k| ztWvF1L3H6~*x==QzZC=3dlSYL#xp<@CWIjy{LA+5SGV|tjq?-xl--mI`=~Rk=y(vi^-OC`NC`!Q)Yb z8KFs}#~+Gwj!8jnsmZg)K}*z{3WVhZ4)^|sX}iRp)ZO?|Va_vkKEi%E-rBP|y_OJj zsI{3$8mp#G?f`1-la4tdZ5_cu&VFbxuw$SPwf7h^l)gwE0xeB6hx0Zd9 zR3FY-ygGw3CbU=4_yp0XYJm%xLW>o9Pm-|taZ_E8LxUTp3Y@Ab?#~>RZ%)u5DHn~U z{YL7qMQ|ZoON*Ck;D$#6Dv+Nq*H^fOD^4z2$%Xr9+R{OOZ^$^22w)uiLvV9mlD#Z-PrW`P3P!+G2P{+tE9aBHg)}UswdVC56t|ulHrH!6}?m4>qNe`?Vvg- zjD#&IA1X8K2<+7#z82dj9{O9$89t7of9k8(`wd>f`}O`QGux0hNkQ^Hqk=*>G&e^! zM|XyHWPSvJ;{P0OSzO?J9Q|pp(xWZJGrBnB6>wb~f=gaC2gLB zz{FHJBZKg@89HAf0fC~m#Q=gB&a3s%^zPnWesStgSMRv62AYtMS?!NpSYO@Iq77I0 zXQXIvZq}RKf$#pnf;80iYf0W1t zvx4)B7bL=;hd1ZV`+=Z(Sa@+W&wo07G+H*N?7AlJpjZN0L18V%`Cc+px2M{iBqH;} z6#^|3fAN7&c;NZLy5AgF$YDG5;5m`i4t-}?u!Gh;OktkeL!-j`4KE%l>iy!=xpjX- zH~eX_&yQC#snTP~5iBROv;<&s&IB-nhT-NzlbiXR zyV~e;c!r~r4=~aC=1|pk{QC*dO8A@#V#|b%9FkuE8g22Kw0FTIIgdNitR2zyL~^#< zS>xHSGfYqk1q}D$2njv;*dZ!~t{JjG$*LqULEHdfNOPNnj6R$-3dUz_K-3{a>KM4K zHQEp}IO9q;QHKCg;8c8rSGb!a+5;0uVc(2ZBdY*pEzqUts`E;7AV^1Bo2{xhL0sz_ z+^$|QJi?7@egoYyv+gg~xGHJv2$B^Zejd~tGP55SEJlIAyBL5Cx78lHzi;;g*LmO1;{l&>;iZd_gR!7mx8MpXhzbc+su`OG6-xm@ zegF&6X|>ny7%(5I;(xdO{lz=(%s{tuubU@bh~9!LdCA7SYcCzn%}%w*xnN!yPz2Tz z7DMn`WmPy!QIu(PO%i-{@wa2E)1l2N?c5C>dIgecU%jE1eV|_H+#u@EG@E;Uo$$2y zwOZ=imIfF=3NmD6nJ@WALZtR*Mab2&9`umA6V{&#oCyZ`dy z6*p$O-VYHdwiYWgoBQpd_WCVc?Qwf>(}s4D_g%Pq7yaF-?a!Zwm*%sBVdl))&Eek< z2=23sH+a4Oy?Ar~#)TM-I?Zq%Y@t^_DyY^pgl3@Ih)~GmYlWP80Vw+(-rzlv=^{?yA2J4RA_5%g$ZR0J5 zKn1q)rJr@_@e-yPdf(9NP-`jVgsFtpnc70I#$u>J1p&tRc6GhlUW&=OkE6#c6rKSK z^EVtj9{nRCzW1A7p7wOElwKkiYWHNb@(gW=nl&9q__=Teu;Viy;ED4Y3|ls=?$|wXWW9j3ZP7 z(Bx7zZv{AWx0cGlBS-Il1{P6OSxulr8{J&5OqkBisElh$WsQPkvlraXcW8(z zKbN?hu{7?_v2@c)CBKjy-@w(P2vxgWnrWguiyv;e330PpPbgacVA|3?U$DL#O=?($ z2Bx`+rdsby&#pm00cyOx#lInl>qI`7v~;$Jtq_3Q>{$TSs*jEx*$_iCw!|#Z1GhK$ zevVY{A4RInvFz+JxilC8DDpjNOQ}*7)U2a`di19~*%xtw@oDtvQH-9`p06iw2yg|h zywhZ7=oR!}Oz#l5&O*XwJVlVx=*0!`F*74rR~dZc=x-bn*U5yM;*}&4_KF;$36k6n zUtE-!1L0pw_OqMpZM3MPPR?{2O(5X}p;9VCc*(nRPQ>yNJdcQUxxC zWF%SBuP*nSNlSA(esN){wME;3y)e00TL~4&2F03zJ0J?o>9?EJ1W`_-7Z)UzsJzxG zmQ3qXTWz#T*gR;3Tw*QIV6fY7rs%NS@rw(?$r#a~tIelUYzE66MGV0m*D*_Y^GU%@ z(8cFOm~oEPo8c~Ffb^$Y0|Pgf!^ZjFUZY?=Udr3@ygb*AXO;+tU~z5iN~+X>kiKH0 z=v*r?)e;4%XQWdnsNY8r!IKMSvMD+wa$8hXEhDXfkG@BzB}Jh>%b8++K1UKWO9a}( zNPdcKy)q}ZtD#u%o&ZbkRcQf?B=tE#(>{U-P=n^&Dp$yuBX~%LP=D+t=R)4FzyOlk zoSq2qtTC7ZH6Um?+o@FU2nJ%QLR-ECEzfUYY7T zpQX^Iu(@<+=<%BZw38(b4&*!eF;;+^6}bpWV+m;UP+0Gwf=k#yOLBI9mKXY-wFff< zV3xED35)ZsS+B_)R5i5!tX%3LVa5}mFupo-x;RUK4pGMfI+8K2ErzTJ^(pQj#jMFz zAi%d`pZnW0j`qA2@V=1JN1sc8z#Y>ek%QV@s@^I|e$P)J*Q1XhKnmUGm|8CMz>Vu( z9GB|wz4@wpj8g0xVb1Hm!Dw^%k) zWVsu^xG)_odQw9*DAG`g%v_6DOKv1hbdnO%mrO}2HV}uwi;H1q1auK`=Bykl^KnAk=v$bk6Qb zDce{pc|Kr@s*Zf=O7Mehbq-lVaq->$T5RqPW0zlt;%(;cSL8o?WowQ-H0z9}#h}+q z;D&y;zmlt}VeH~UI9(vBlr`;$ZnHJ9rOH|Kxk7DxNItD@-B*t));d21p4ZG`sI{`xf{Q@FeHlAwA<;8f?5Cx zrxc@<>%m#wLEx-@gLRTHcjK3T$wHz<>BgeMY%^4Z7+SUDG*zXG;2?ki)C8<`PJ|g} zoH!6Zc&BP@p5Ru<^cm@gW@}4M@NyAungFpLL4-(FyU`VD!-^+7He6vIdEgDV!Yq5o#SRER{ET}Hj&@y0Sm_too;7D96g zVy*!R9%|a+lDr;*N*5Dg)x~27QCy*|pp7B(-Fz{YFe3Kk8b@kTkb&`?Jh=be`QZMn zWaY%f5CJ;?v%9d<)Le`jG6GgXAcv6B1W@$|A{f&(a7I#4w3WS&1Z|DV)sRkgMbsQ_ zFK*v83|(A=uE_#mnSi4nK?I*&L6uT6HIa|!v6qZk zg6URSa-2j6Y65zC1QD#W7_yHAW30ir2;?oLrW%QnN|W$zuEj0ohoOs$(2R=3p(+)f zfz-A4Z+sTMDk^TnniqT8xrG#pFPsRR4Tk*K*E^)9BHB)j3BMoNvy+0y^m= zqicpA#=eU6Gbt>Vo&@|B}rNFA2;j$jkp5mGQVC3y?n-O`lamGPK*NuUVB^0Ant9{JFd z@ZyHHF?X=}@=I|E-$OG;?S`2{VMyK_nQ;gKz=I>35vq+o_Wx(@+LqfmlI*V_CahRH zLYC`(*_R22?HMa}teLUo*_bCr)=k6;1T+9CS^KnKvmdr!vYFK&NXk+(y9q&l5XDPX zqq3{=TA6uJ;(C=i1YT`>FP-ak^6jkm=Zz9Krx|_>;A%BVG*Pv2Sz1U+qGKMVv#3!R zdFcDaQIE~5Rq4$*31tv=my58-=dgv`0S8x`^-F$h!HG{DeKBSRe`=f+OlU!g6p=$g zHyykLjXq|Rob=ph_3h*xzdL7~sCm{Lf&UiJ6#yJWZxz8B`WACboT{DPTWfnU{V4xt z-Y9Wy#!*(ZJ*|R~WEN38Rnf(xDb5#{6@yRzeBH5SDs>;2I7*(Mb9`~f zihr#=j2$OpMy(5KI4EAEnl$+8Q71I?jS3_@at=6Z;m;d>nbk0MoQN42;whBua}ZHS zieYMxjs#?s5xFY#?-*$ke}Z(i+FY?6?wj%B#LR&pmKCKnl~KheV+Eg4MF-Kmqckta z=?*d+`2!m-@*uW)75GHH`Pf57$u={%NmlgAV=6VNred=u2sAD!eqLkBoNKXXo45SP z;oEz>5H}|T9aVI;svN)rDxxeY#W{-z=;As~Hrw|bevZg6cASVArM<{P2Hg|%%VR?~ zP)I|`2|+0#tg{>h?0vJ?7fXKJ=gyQ-lKh;EbMK0&%{JZ8{`D%QhUQ^#)}r%bIaQ@o zXyFhs2Sdo(YDLU0`f73pQDu=%fDd$q%)t=)5&z>7F^nB2Vony7ibA1y$U0C1LCU?= z=r0;;v=fz;mbY9_0D8P0Jx<7pBkYHW!`VxUhnz0%ke##^P^9MEd^EWz5TfNw#fU*D zMhQ<3;7o$nx;B}&Zcwvci~7t`2O!oJEODXJtx#>&Al%*;pZZZ`Mb3Z6JhdUK@O20!+Mty4@k z=zW}Nwq*{-X~nX(ZNYWod#@0 zC75F?t#BeTzpQtYDY`pnR1nW_B2$dPgEEv4=9_6XxF(ybx=2B2wG6{|xx-Vzc7_kb zN5$?8PZDKTR5H<#Q$7N^VGfOVK*LKJ=>@}7+}0g((3iWfxU}4wFh=oS*F1g*$~7OeHH#*7M~c!qp=e!h9Tc>edlEdF&>`2|Yv&l)An z&8hFPc*=|Qg78nIZPmFNY?c*TteKOA`oph;5k^Oi*7*~xkpbCW-bW^nlIdr}c8rO- z28BY^36Fx*S{bPGTs6Y`7&&Er1fbMS?g@K$m@%H-GsE*hE|bm!p!Lc><=`lazR;9(IMoN!SZ|24P!@lWDZi0Rj#-Yn)VQ=6o76Pil6`- zo-WVn?9jnICLw{`=aQcYee~Mo*!L$rJD46Pv^nso5LlX1=+mKWYSp72Z2^R|u~kO# z(oe(UC#lW5b4K}MMkH5dqZF7Jo6td_1g7HzD1=eNl%N>78R%2*_hbPF5aeqMW{2*? zaq5 zH><1Ob(i}Vm=8O40%QzeRYuZd>xDZ)qBTVpwMJRvI2Aijk&;?3I+obJG4gr{xm@7t z3*o5@bli~9ds6q#${qD|`;L89j`U&Um-BP(Mrum{s%a+#x{3;fmIQNar4G$A)c*G! z$(7Fh`qiGeo752W9R9fY3%-o2-Qv}H^OlW~I`ygJxB8z^=;IHtI$>-nY28w@6;M{@ zS|SPuwqNAg;llcn=~X!|??nCrghj2av#f+qOv_?JowZGdV8Bm`a2 ztqnSYN3Sq|_ldD#UsA*O`fFZ2VFzfw{KvO14pT;zw3=awXC#T7T4$_mly9#DWn;8P zrIo@l?)84cJwoQ$Z28w>w`LqWt=o!Hl|}^{9b_s5D$-YKbm;`$)Ns_qyg~TjmbD?t(HjCAO1;TL25^t;81C5~dHUZjuV2go z32d=x11)(ExHYvw`JL zc-?HgD8@z=oAOmkC$$#R8T5R0GLqAX5x47l`Fn|VbGr9lDgWA#^Q=(|Vopm8i)JkP z_acW>NaBTr^3F(=W6pvTT>bfa&421^=G(0AO?#M$`di9^Y+9x0nsdsf5M8JaL^BXm zu8z}DW`B`Oe6-&Wl9X?|YqVOv>JXRcBHe7-d%MNv@gscDI7iRvZWt4Ks<~;ImCn(a zByCFqeV*cg)5X5;>*CpjY@gdR9(KumTmeNw^RvViL(hD1O2!x+bwMf+oGmg7FFXn< zMyVHS3>Gq;{4<>+>jlk$c@YV~UQl#QCSWe;me#QK{&RY{6CW()`7gw)W z8_MYU2L209D6HsKGgy@pgqT`TQiZImv}oKJD1wprMrF)I^=`r*+?_KT?3$wxt2aPB zjDu4UgIAhL5OoVKl%PFB0AH_f21%cUqU;N0@3~l#LO)7JD@p)L!z!w3%?L;S(vR2h z(%I>WcjkZqZfB z7EpzH305ZhYKAq%dOFne1qFgG&tZ+KV?h4i^$5h~5>`(Z`$V^Guf9iVaj_3w)J5JG zckid9+UP-03WX2}P<^wmd@$QnuWCHgX~xDRMIn5P;>@XDNomnC14UkdbD7gdVCZl# z>8RbAGEUOH7wDfz)$Eo8oqNL0CXsf)fJhk}0W>Q|_#&+sVKs^Zj`NE&@0R~P!S_8( z7}fSO3J>rkrRq}Arbgvs%_{pOH55wQ5|JUmh_O0HZ7ZNPTsoI@|6}w2AC+>k*(MF4E_*;P-J_eXG+D5Mk-PEZvefIHVAq=8nKMe$oMu77Wju{8fGeRz zw3t$&)(j#St8L{#$MzS$+}%246Hn;-b4O`Bk%>MCj8mp=xtNSozO;yGU-xfsUVq+Pyxy!Sp?uHd-_Tz+?`l0O+s*5OhTQ44MVEm4(kKxjLG!wK>1`vN zF@;_^2loD-l$V4&^P>ZQbE-cgr^?jPsxtvC10o!i9z=npd%rVi8^&UmU}${pG@AHdDcTL@%}y#(fgiBIg9jtj~BsIenW%o4Idsd`KDVNu2n9PwYFC zoxH33Lg$$eKXyfvb=jzbf}Ii%61xAzR%KJRI@8?}!#>@IjIZz?EK1$Iy4<{8&~d)H ztXnd!3Hx)myCLoI;%a@lToHxH>#r|sFY6xO#nd|SqkZbbZrnd$n-!xYS~E4*l$BCd zwwmxXRv~N_z=&GEIEVEs%6Xb_q;6)67gK&dsrIic^t;Z6%{gIJO4AC^W~qP%jo01= zQHqzjpnNMjGi1TvY2Ax&`?|UNad*zBo|$o9)x7l)kXJnk{N>1S~Yn~la= z<6@AtxoQO}HYiml6h8$x`B%?}t}S2ICoiA;JGm6)DpQhoL-%`~QBUVRh)kC&|Mx%t z%f3CB^W;%IIR_6```~j+5+q@YxF|rO7lVg5TT?2dx7H764!(O!!3cKGky|q!mectG zJEl61_KGJ@jC#N~Wwgto1d%~_P8<0DJcr93R-yFm)n@aG5(ebp+{nbW5;z4_p9pkPUU-|MiB_C}km@_!(>ECW9jZ!s7^1Gx=G)jjST8u7R#U zM1?D@nii7qEen%ltjZgOiZ=+);Tl@l1g1F*KQ<+)NlzEoxc=(FYLT5M_<&+%(XB9K z^}hGU#0E~szh6X=B{YPTgDgHcn?n^wR4+r#J}8D=Ff477ZE$DG(J5*c4LTQ8*5I58 zUJ%SyGa;KK3hLq zKPF9p+qO0ad-U#A7w>v~;iQgNhdHC$ak5ZvPYXEVEmbZ_Hm!w$ zGQ&20B)`}#HtWR-U)17}`l6@7cfud(FZc-&_dMk@RPudbb57lFST!mLGeu?aHCR_- zH34OnLc!YvtC=T-lZUPiy@N)g+p@C6-wc)B)D5M#CL8Jx`Bx+pAA4;3hLkDFX_X9` z(#;o>EnT!36GhZ4ur3Y>ef2k;01tgzCnUo>=tGXJ=~@+J{N+G(xmIi2&_0xqGx|MJ zXAVT~Jp>(SINB?^{ltf9%nxXO@G=Kc&^#_4ZGTbq-X| zQ`ZaR@r$iZbH-Ybkvi`hG*n}0+UdqQ^HkHtKhHG!9x`S)-Lg_Q?iwU= zt#u(%n`Cq#Q2cofg#)rg-GSLu><5ohF{kAz?n5H%`RGDGOCzQ#=odj$2hlL7=r&uI z37tnKnR>UUjZ!wl!7HjLAw=^HoOX~)@Uj`5MX)GJ3M1q_aQ@+LWm{jO30}7k6C{Vn zku16O$O)ok4pgWIRnaMo1l^5ZuWeF7gPd$lK?A1@=DXW>OzdO({;W~D=CpD%!J6o7 zB%J$9QStw;?%I0fxN`IR{)!F|TM6J;=YByp24u;K4OnYor9~bDVR0@znvO@^gYF(_ zC%-;qb@yCbRjeaLM*Lup#>G+SCI zCVBd8qvOzFI9*Fw`l>5#XyaSV1jcdznNm?LF%0Kl5lZhjn1lL?h@!P=K2? zNeXr_H2d2H`ZBQCUJm#A?ULW;=b_-Jc3nLyLMahICta1UT1Np^7%i2mXlXd@SvG)Q zJv3;b&2+gMQU-VH#rgW(zPx+!q*fx9J(hUyxefR1&UmoGYPU@1dxqTMm%pI1w^`w6 zl=W&gle+6`ea+}RbYK;qGi8Q0^i?am7m$;!K{rsTIh+~B>2OFv*wcF+G7x5_FWi$I z)$#wPu;oMm;cJ(+6e2SbE^F_o2Sp7ynga# z`0x+Q?Q(Zqz(>Didn8pkG!MC2+!j3qi zx8E(^t%vqe^sbjj0^sf9hsBFqPw!Ix{_WczxD)XINTDyi8gxj?7g0PkpM(Xeq2X_0 z0BU5f8KLMG_tfU6lirsb)vW{X$42D#%E}7KYj12Uv1tWfm*f*Ck>)vqjV+YR&2o1| z93oo;W#0`4@q1hs3&db+G<)YbW5fJDUan9_A|fAH0NDq?Xa6;ySC-8|LFGJAy6o_>3&?sW?i{ zJx47-^}NDFN6e-P6bNN($=;f(8Heysb;*X#`)5a$nC=+;Pzi%)1W_-j;;U57S(7Vz zW{MJ0oa89+>x|Y_zfQKSa??GEPe1@bXIX3SYP7PnA!Zp{%?J%BUw{$d8)A?Zc4>J& zuPM{D%y<~5BjjHbgoG+$742Ka3zH%azy`< zXdDfq|0*kD7~`5iPn5xE3M<$owCHR`(;IYJnlNV(8hX~z3Y=YP$joqQuK3woSJPyZ9XQ9ggszM8#W<0zNs4&4OcYvVZ6b$g zYsKyjx|-+>+NVIpjZkpts}u@1dvGe)Y+F-!WFdCruzb&r<6+2mvzU6ThPBY40gFC@l3I?;#lGg=rExXBMW2hcu0~d}k~edV zIp&z}lW4sJSUtaOFbtLSmv!@}ef1G8_QqZa@{J`>9s^3io0KVBiv;7SA?x+0`5x~y)d1p9O&L`r804ptTIBF`J*ku6GlPHtP_p0Tg; zsrW>_4o&Ym9=ekrL|il|qFp*k2C&gmbcsD11be9Thme4z0&oSXVyccS-R zV{;MJJuIf~1SaaCuN$p_0i%t=4Mis4dKB0ert zsbyDVlTRCeg9=#CyYV98j+|Wp34W$l7C)syVK3_VpG{LFkKfwg^#L z*U+(nQRApUO9shSjtN>i_-gQ4sRlK{^g+){&Y5qBAumQg>YhAJ!cYo!-Danzdq-Ht zkoOy`z4^O<_=&Qjl8lPuzAF#gMf{v9ZLyUqo*j%4?pT4)vWnGlwBkYFwc+jBL(WrZ zhUgKh5_k>#=h9Dp@y~7+Srw}5N6~Ih-rO@6y&vsU&|zpe{_BzrIJT4dk|kWp^7?+X z7+RLJj>~ z%RNBBBPT0DC5BGFB&M8;QdOilDf-C#{aK+9Kw#oU+)y|_?_Wc?4$Jk{84YM-4QIg$ zk+=nfTV{3^_a5>!@ACW1NzR)g4kYjWH|LhMV&zd$$x>A%lA$Hapz$qb@+9$un}N1F z@S*jPwTHi(?Iyr<6HgJHd2u1Xz2OZg`vy}1L04*XY6wxHLhof}Y(4Oc)^~jP^#zI4 zdO?>S=NFFbxGJ*$+`V`{l#m6=;X&G;Pym7ygaPA1MS+ecXe3Q_tT?73H^w8Li`%ILwfv$}?Xc+W z)D+k16J*c=XX+=3C<@2A?&g?C-Uo5z#n*Gf_(ihPFLh(_7>r_gZH!-8)`>aIAb2Jn z2D32c^57qbt^>O#aQDQ`k5B6m%3mT7y4YY{!c%26s7>UR!gUZOb|h8?T;NJW;BfgU zFUN06Q)Lu-4RctpLuw0z%)9#QK(CBlldQ8K2rQ61=oIPNGO#42YiPw$11ZrBR_%XL z2FQ=h`y{h>j5vyK=Eh;gB}yo3Be~1KyL$dvDjBFD6;xL>dP)W_F+M^2-!I#1J$s$j zDjTb#)!Msuor_cL<1Y-auKX&EQXnHW9(zHpV=kxf#I9L5aLkf>qVFD zPw?FJxcB-g)nlk0GMi$z9TbjsGs!EIT4XXRLPQeW%MG~gB)0#l;rm+qzDJmN>p4{G zMyyXWne@3jIaj7rG_mw&Gp#&~`1?f6Q8!xd^#0V$`m2;WRW|Sn?eNbEL(ed>|c4>vw;O0)2*YEfDJG=w* zP&<*|0hi35p^vYVr=1Vv*9L^aY;`NPEsK#1=t(#y8&wu`-x?=VFq_S6gqqvwSQ-_e z7Kar!^Vk|a(n*}t3ynfs$*B}0MaQ159juIt=A9#;9x@h8d0oRAx8FEdFFD6Ozv2;P z6lw$83(Vq2ixBH`gu3m4Pu3wcN>yXMw#Tp`+64Ti_vw?I(zubNZ`Iz-a{#CPxV)3r zccQO!diNFhL+*W8*Sl}Lb6!o%WtWx3YDy9N*^n0%dck8>QkGtzU<=ywIoU}qd{Y-K zMwnnbC|DZhLwPu^^2m@r^kKvFCn1G8Z-#<@F2#(<*z_FIQ+`jjd+?^^@s0akd3wnx z{FvmJNWza1ch|VgBD)4khShDr$XhM9B8Y$@HX-dW==XXqv%pYpGu1gN#E70pV^O`K z02aEWSDjH%G$b6G)WZWFt@WsMJ{TK5I<`M&+nHZRM%6C%EZoE<49U>C24l%n|IW8d zn26|-WjR6mh1|Xneq06jBYlBu==l$xwa3zK17j;nEHtUqwT4znhtP6(gQYEaS@tV_ zj%W03({H>xkMOq=OvXv{_`E*LB+ifzPjpC_p;Jq$^}?uDg(*fI%oEmOQ(bwb(>e+} zx?Z~`=rCqc31`Wskzurx8*k$DbH$`nSRnZA+ISNqhd-H01_*nqDl84vT;wWhiOg_U zES5CshqTO6ZvnMak*=OT)s`HC+R0Ny=MX30ui3cYvmJE3DE=GQ%5PUjc#9Ktrc_S< zgR~Aq5`PGWx1&;vPk#Rio@>v)>qGT&)Jh8hoU9yG;fT_>0i(*g*Rx`rYT8^)SOymG zzG>awi5DqF?cq145LrGIZ*atZ5Qcid+_@-lF!|~>88GhWw5$dF2q>amHk+67vWPCB z6Z|9$Zp3?u@{M@J|6cJSVrPHlL%Z?}Wd|rxIT=$6+!qdEs{oBG~is zzuqn{k$Ae?D-ib3wnks*;E15mrzV_VSZqbe^}=R(O;s*j!&LZ)7;Dz{4t}cALh3v< zG+}5{!gQ?^a~~0b3PJ|=>D->BN$>OWN2_?;MT>A}rhfD)^u(`)Vu!6A0Cr;M3};|8 zberh2UlZVsm+;<=bfvJ_bRB>e0>XD`CN>)nujr&TF~hGg!nnDEwOE|MGabd>jW;1q zrI3x*$NkHyJ?~~9CK_dk%lAG=O!?_G;~>x);O=YAjgg_Ej=rF(BzVV~e+T724z2;e zA34p`+*iY2z@vwGL}#a5Nap1pzAUwH_fT;1-l^EC%PdEv7;H^#ZW*Q#HvVIBJj{Pr z{g!?D`sjJ=IL2Tdc#@%!J}y^6tLTT$j%(AO9U1{bsoh&PN)Xd*7G|W=VD%#}6;HFK z;uDrVE>?(E(7aePov1vk9#mTtJXtd}J`+0}f3Q>>ExS{}2WAuC|C#V$W+U)<_TNDW z@@Hm*t^d#)H{?J-H2)Wb@PF_dqDHP}4(6t2wpQ+D&R+im2uE+0oWtL7EC|Qq*nCxW9lgs&L|dT)qlPks?TdF z7z28CIF|9BMYdWsaQz3^(c2nj+)3oe<|Fav9S?_&I z6TJRMZ{{gwY^Ow=liBgt{#bSN9OH5s1viof049N$g;b>h_P*2LoaaII{X>dEADqv> zw-spRWSG%Eba3-C6B39m?OJ0nVq;_hguJU2!AA_4yD%Oq*WTJDYKUrE+d?YkT0ZBo zPm`9R`w#1DSS(3*SG&j`Eflo=`n5YN3o1wzTVBWtPL$ z6Raj1mpS2M63`f=E9oD4xmUp#1z8R=RpeZB10jD=`;_Ofv`>HFEnVmaSkqqmXzO7f zG~QTM;x9k4PRv#&3(&uamS>#s=G(ZmxbsUCW;9UH{%RHs&uS|vIAr9KFtMA5<;t_( zI4A4dbF)jIow2~?m6kQsiVf1i?*+CKZsO-8OwLaFktdcy6~x&G#_X#PM73{9mHmY!5Qz{Ntu%9 ze7Z}YBvEDM$3LhnK8rs{jSg>&A(Wn&aqIvH&HVZkK`rWr#xF(OE2)arB#&0P;7y$C zoog5z(FYemKk~rqeblO=q*K5QrXZUbX{OFJ+X7~m2u|omlukFh!Iu)x{pcB(CyliX z=$bjWaz#sPFlg}jePw@@OPX#<8=Gw68vH&HT9E?_!25j=vi8h%uF@6beO6nqcGknDX_@5#MF!dEBSx@~jWieXJHo*e~rl6~RBG*~)`#hwp_#ya{}&JCYT z-#-1*py5^3>_1RO0gfmxW$ARzL5W!t7;e*ol+YnK{tcsoO9e8TdK>+u??GF)neyYMamx~jKUCP7*r|_nS!9VJ zMFb?Nyg?r(T6RymPA8;ZR^9BFon#JVb|I{TGIp$Fj1|xg)HDU7K($n-p!_oB4kMG;)PN>%JpEQI9F~$0^bfaSd0kG(m}pPZQcZ0NL<>cg=Q@| zV>xWa*0oBdbRZrBuUZ@K*DC8Q;WnsRC@frMqBQv=;qQdzsmTb3uG}+4(PYNaYFD-d z0qi=tqsdE3R~@oT2S|{*P)98<+~hLRWXhPTNc0YGh?U;FL=^>c%Q|;sC(3{w*GBeI zG3!+=$Jpu`a#FuRVGJ#Z$p%38xSUYlm&KNUMV2>~OlA+0W_F-gTL01Wn_tG%)ua9F zS=A+ZZa0nq!Y1-dM7TdzTf5$i5pMj!S}W#3;oDD7V+e%>sc0f^Tp4B} z(Izs{CvXsoRMD?huBcks)XbCpc6>iGZGQLoP&LUfw3#O7$5#ByG+pQ_TXAKodi^6? z1JnEY@qJ?7MQt==Z@a5I%WlJad#&#BxK&Sx5Zgs!}{V%pPK)#dwN4!0e4wXmj6`0A$FeE6T8{r3PfP2r#Y zi}0zZEAMo-nX)HGrFHLr_eMLig!rbsH}_X=_;sL^?Nuw0P&T0n&=BF*13>>vr3p**dUyA;4HOfnk(gUz#mGqJB z>9nLdV)Lr6RPZ$;#OmsinQnK(*g~#Pwh^)j zN^h9kn1cQJ`@G(^ZtBr?-TZq(c%7Kiwz+AvwP};IOO|b1q|fY+qZsp+qbdZcU1BPe z1vm?WE7Uf6ks}S%aWcGx$m^Fo&x?%sOxY`T%Q(DtJb)TbMM*JSs}xqgg&4sXxO~Rl z1y&PP<&Mxj;o)OqSnDw2zI8l;BwO3=Up3rgeO{6*N_EwV84h-A6$udigvH8HCtJMJ zQT0Z_z5y4n%#cmMVz4F7r2tSd4I-XlRE&Byii=I6&hx?+PF?;|_SAT8*Wx$~u66&j zL4LA$<|5ws(?)cmoln@^<|pv0PwOf+xi7R%cjaxjK(Fx=^$Nc+SR8!zt%823#}L^? z-@CfAAm}XA8pZ<^_EgD`^=U@xJRn0ud)%PiOpv3%_-Nk$sJ`YV+ug@?!s%*ikyJUX zXanL_^DgSP|1K&CiK?}vVSKWj@8Q_2N+vwFuj}Ct9!Xj#&-LJZj+X;gyL4deKSzY6 z_m*azmQcwh%9tY&kSn#Nx_jKmfN$farxl-31P#?fI#PHvcqe|DInan!g9H5s2k`w_m0C@ z&S((Fcocmla(F~Zndm)Uvrfhq)L2S52>PyRg-|yIOS~0qSsD6c(B~B3j-@OXZARYAOa5z9Rzh9LO~GA zjt3jI$p16eglKY3s5)K2s|KYgB_%274i&v2Y+|mo9|IOE zlHfDCyvSFnq#HnVdF{^8^hU3Gu@~7?#Fl+CUps>yN7OB zi;A_Ux0I$*XPxjNfosalH>r9nh)pV*F$kumX(*VHxJ^wB^2;idmE2{N8Ouvt%&e_{ zvbdN9ED#nOF8=#8DiSrO7+PdfrlLT>eg>g?%;prkR2)k+-*O}j0zVW8hgdV(B^n9u zBeccJY%CFgK3j@&y}Z+V(Zl(e;T$!^QYo??n@m?UDJLNs<=XB`zO3PZ+5 za8<9+N;b5u$0+9H4$+yZ+N^b>_EfF$_{EXmhWm`%{o6h}BCKN%HeAlS&|V!eCgA&a zwN%IV;r04^scbfLVWTWS^RoN64&HBThs`MFYb)_OzHdh;`&q{}oX3e2v)&^uX3QgY z>%=>x=IUH+D|BYacyrJ{SQ@3$t zGe<1lqu$*C8hxuN=FtL7x=VMx4`iz=;E$09{+1=`p0R-4s%ywgB+ZQ%k?xUrbfhhI zxZ&}yE3d7o5K5?;{xV0GJqstV>?M`@HmeO_!oGUk9+Qpj9RkLDrS0GSpKOOoWg&^YRMRFsz0+>N5X07+5@N>$~tC@%|Am? zQKaJy5n1v8dGgCEi!ml`KfY0E7c&-2-N0#@kMZ1Cgn6E%&=6PbgB={@#AG6A`XNCs zQs{GP6>_DETV!gNn(b?0oNvwf1_WLHH?rEhyHv>E$&O0FnQ-?f42eNMjUUP0TWQ-Z|u^hDN>a5az#^y zEy-Gu&}{y7@xMi9*q_qf%c6^%X{5#5L3G@%{KwK|Xoj5+Jl6^9S!8gF%uXp&KC*l5 zV<(~w=EyiQHyEIV-p5j2be+>!oHWB=T5=UT2_c$rRUsTCzZJTN%$N9|{`F>V%UW(C z3ul6asCj+8BK0+NWfkNPJGjw{h%RR*rSizrNWkD!ZA&BOK{wlaOuYHO=Yk1ls(SdV z36x8FlJQEDq&dSFXp+(>g^E^A7%iRzEa2QyxZ(Knj6y+}39ifTeVwwE4v)PL0Xln? z%Vx+Vo}fWK`f4j>C7lVJz;7=`J0(v_Yw?XrR$xTfxaR~h4-~wA+|QTMm))1si({v6 zd9{_7R^x} zax=3NnplgAp(b|73|)s4cfZ_S`icDv=4O)Z`LHcRE?8%h;?Oxq(Sb^b-i z{i|mjSxhzS0*eCa<@XkchzAxANKgZzzbK%YO%Ahr9=`N-%IVc(({5Mwl5xo9^wt$4 zTG`BcTZ8KFYNQz}w7K|B!5#Ssl=fPI9yxQTtX4l>j%uLO;IHVHkGkT$Jx7{41GNIw z)5o4y_?i!Zh3v^kyZ;qc>+(NVHx3*}8jvz~)|8nUY8r>!MWD9mM0rN)QbY%}nA#+j z`=dx@`U#^aSiG*}C)YJC-3%tIp>D(oTo+3LAUGmY9h$hK8G9TfiPr}u4La@fW$w#;r&+~k%#zp%{oCw6{an27m_{migrI46{S1X2F9+Tk^7u7L!TC>p!Y zK;%dXI00w;XsU+XQKIsh#)xRK?zBaNV+Pjo*q5x$(l0(!wrdGVuk>G`W{KVD%I)cb zjbH%7fj(h%MFqt&q?8g*EYUE?Y0y~!(h7e~?v-yz6z+)~>L^oLUc|{r5XNkgDt?e7 zFXXewNkwTDDo$_LlspPiG!ST460YHY z9yd=|AYd>nARr(x$A7Qhbh(73{}6w_(9>`1E`8aRHpGbNDLIKa9feVS{%VuCN9JB1 z?;NysZv?kkcQ??AIp=t8_dLY%N&C6%w3nr~SZQFN&a3IGM!cl87+=o6Ml%|FSK%x@#U^T>VMO6SisM>pv@|>0 zE{OGh1mT}zXyf(7gtGZJ*kyD`!W*Fk-3pD_<7E^7sQSE1T>&bv#QIFZ8F_~VsQ}0J&R7E(_^bl(H+R?VweRNO=!Vr zWw9|&NfUFD&%cCh8ENtq7AJ5Eomo13@xg(ee6&DGauv9UMoe86EH}jyr1Op7vk)=7 z!rL$BA@Nl^!*MGyuN=IG@R4cH*n{3g_kg*KGVuzv1m=PX03VD&H$bLjtRKsC(H~w* zl}bWeqf$2qDE03XQ6$Q^5u9LtvK2j$`D)S98#+Y7bu7#t1Y$Z2H3RCQ806-Hs*A^p zbtOI!T*Ru^t$JLN#u!{73H2Rnzp&kw@Io7k?_A7=eno`cY_^~AP)n0@rO@S&r8${O zk4ouErZt|$>GrsZ5hA>9E;BQFCIc&&fsm;2PE7Gi zm6+1~;-W!2x!?@j+ahiZYuG9s`Q$n8(|8OuO>4N&(M~@eHwL3B)IB!Ngi0y_9~DD6 zDUD_Xdhpr_p;#pD+%&d4>h3)#8<9cgBmC)V&~G@qIK9 zI;Z^aI#+S{57*kk1>&|Rxsh27ZEOqP+k;PFe8imOKvl9 zDZ&5khh84FC4A+k?X4qK-*UqeV$Ryd-=>$lUsQ5ZLdVo~c+sJqn(x3s+0~<& zH$#}k9ZF(j(oPk@K8xb&#u3vnYQNIG?(TP-g1dtCfz4-e^j%q_n}bu8IcReML}KohQWVuJvwhojkO;DSEsiD z27&h}A%~aok|4g1?`b-nHEb5d2s!{tQ7y-1qz9Ug$^-96Wi@VOO&XDe$%{MqIZs>gD#%Dac$WG}6b744 zx|)|S{+11%BV?oztNuQO3S9snyh0-n+0OTtVh7>a1*W4x6dZITc6?M#x>^@{JI-wV z3~|u$IlM>qoCQ?N!x4`|`b!)d%;R3juu_#w1bEn$DTL zw}_n+hqpqO9ppr&ca#<5sQmR`vJtsLAwi-Ee-G1kp^S76#(~$Rg3od(4hfD{8;?IY%-<>Mi#M@ye-B~0w~j{?Eyhyu&{Nt(A$9tCfTO|KBP09 z8X{^Yf~k>bmPyfiI`t3j2bKi#9J8af760n5_BHu1;T<=kKi@gRJI!|Igzm z!WiySn7++Nhgo$!mxZq1*NiwG@LwZH45NJp!|XM6h1d+IwC-(;X}Mpoa%#QuPasuo z)r=RT^xHX|o_ZXNq1s=@uC1!SI% zs$4)}es=XCtA6Xb0qZm9x^z1Kx;=)=YPNRVB8SWOd%a)n%Trr`x9`x~|2Ll0 zg}s|#ghw2|(0=FsMfweJtvfTQ%kr)`e?69kWrSa#9!{idCQ32lc7_-wC&}cj{_DKn z$`QEJ8}@BW3rSuZ@p3R{RNUT2amYxRwBU9?^3MQhQTqIcp#o=#tVGt!Ebn>M2 ziWXOhAC(G}a{UKS&FUX(jTp_XwrXpofKY48YA9I2m%%q(9~G9}(+Abj&((!x_PQ69 zO7y(fWU1%hfFth!hydPs=*od*8Ht8YGaUMP`w*FD!owNcey(qV9YpUa$K@G z55%QWnMJgNjhLK{dbw<)cgCCoRs#%{;jP11umw~K)}X+H%a#RB%Mn9G5Jhq4LgkS| z*zORFG|6)xB6qyt;vJAU2hIKB}g63o{UO=Itf$X-?_33S$v&_gv$QE4^beQx;9^?&NJG>P|$cAmXHfddG;HW4opzm1e$hN`DK zU8L#SX6P1FD2yvs;BbTDr=j*x9dY>>(5otAlElg6DbVI)BG5bapN1l6JwOeHq#?r; zHlk2{q=%ac2H(5~1PI5W7nJrZ<|iTPsn&pmeBdsrn|9p>hI<`y3}RL7QsSPS4m`4f z(x-&bmDyS}+)@gkUPfFv48Bd3L}tgKp&*LWla$PZ!3X1vv9N)I6>zkY8AU>~&o!3I zWL>*!X|fk0p1nIO@E89oJUO<0kLqV^^7^8g^De+r&QzKgNE3$44hXY|ZY&}NE1`2G z{8}(sK?eu=s88HLXp0X*bLu0y9nzE-zxZ%Dsr=9lK5yqwO;WAu_V1u-J*(W|w$kJa z`E7E1EDc5>)sTm6$|%UyKm_DPRt)a=wWY6j1k)L=tCzFek_fmfokU4(NFmyjexA2Y)c zk=5sd>W@r_;%0)*F$E_8-m9t%(NRrIIUDhhg?ee(&_OzqzYpb*4dw?F-%GH{CE;4* zGYh7rCR2tEM2089-X>4(Fjm)1Ela(oiIK99ln;R;+c$op0jI5`1#-U_*e7$la(f=g znV-ykT^Lg^$aVywt~!M13`boL=u8%tfV16bO15V6-gmdgNQ{25z2;-D-4OciXuuY6 zMne|tipTlylA(p2pny1{d|p;CTNm)S<@atDp5T}Lz=#_X{<#g_wzJ;H6_L@OUhN;V zC@|8w4eLyqJvBZ&op#Q3opM@y77}6M!>I6*4Q~f0J3{5V5vv(A=r>ZMoA-3@mdcV@h*H(3RpgD~f`H5+9M{Q9-9}Ze zq#K6tjW!eGxsaTtM^hIkXCtX6sa%n)TjTl3@k=n$0fS(2+9j%r-`#UMcbj?|5}Xh) z{}#m3jzX4u2oPbLWF%$C;#?<&MXDlWlmJKew1VKqo~As~cJqVH%qiAh&r!swOl5+U z{#ZNb6f_rEFIFHoWIoCUBJ>bJsrX@XKRh1UKEjU`9Tqj+I2AAWRXYzI`tu9!8}kc$8Qvv$-7U}_!2_Hz*N0{JS{fn97Z*Wi43fowCNj_2YNoB;GB*U(51GA z+B@mk7E|^ZEgFx`YVsl_k-b;g0S2gNNEz}DHKhaTWY$5FV@v!u`#YkXJ7=8vUL?>U z+yU1`M|FD572_jd*^RB#WK3yzp+H#FDG=u%6k@ZwiL%)!2@?%?;nnQdZOfzTz04?w zNBPKq+x~V3)ghm(2CV2m1|MLyZ=x}ReeZ{#hkds7G`v5JF>9reTSHI~^A?mQ2}zk1 z6$m;tN>9;^edeapkgJc`e6`kkuW7URs;T6sLZ?HH(Ji`-xquMGqZ)$oy*9LdU!RY3 z*||;?{#Lz~Z!|{5r*>Uri1a!x5gvjDEvcm2C^3l*=3yf6!X4j*G1kmGa!bXxhdt&3 zsq!at$tU;Uh&WDNVl|HTCC9kYOx?L3YeW;>@?wo zoCXFsQ6!a{KTrSjtzxT2$j?*5BU|^FsrpSjCr#u9!0ZjzKWjMirc$q8P zAP-XM?rD>{0-@f5b0c6QPV0}8<`a*R&DsJHD2LgV$fZ&6DKHCWg7%~PLnWD4A<}J3POIo4^a9FPGyMDo`jDXj5;G|ou$??g+(6I+ zkfJ|b1*$AvYWVqwX&woL7pd;zD9;<9zy3%?WUSsvVudSMJL)Nu-IAAFtU{vsXUU|G zXP4w3?v6?)NnGOx;UZ4gDhSl@HUF?62w9HeCkr9RaZq3(GYx3P7ewhy`qEhXi-CIB z=wG;#4^-E%#}~L5X}&0Ixjn{Fbh>wPLAhwG)~0jf9$f`f`fMHY<7BG@$J0U8Q}2b7 zlY~I)YstmQ|D7*M;86fjJnX@oS=n>w&~q%mL$=EtUpC@X2W)7v1d9@_WS>^-1#XW; zIg#9OdS@|7TkG`4{e&IFUvd6*oyr|84a*F11&p=}GQ*@B$iBTVyEQ#6HqA_j=tw2H=K%Psc zJwMP%c&5g;P9dRC!*J0?t2r*fleZ!gO8)D9iQKKE3$J>w8VJvRu$7DI9le+UovH3K zDvPT7EDIefC`~@ifefvt+7GpyI+|PzmW_Op*ot}nv#3$~V=#R+X3bA*;jDJS^)aWe zB?}oVk)}WhQ9_gWug83B5E}}Pf86cY&K~+#9E;btv z{ir-e{-I8aG?`1yjvSo$ls+BzC=n>=DA;*6QYx^cYZna_BxsZH8Pd0%@i$jY>*foB z1`@xz+s4Jm=or$X9=wlM;T+FDdY04`2}v+5|K}r~NG9)^jJYAcNlPq5P%pY9PsrFM z*fvBIYDm8U=KNKTDX!)!VAQU8YHF*oo^g(Lte(xWl6TD1Eh*T(P9CB2Rx{_wQDzBTO_f3Mb?L6*nhUcEJWkd-= zWv;z{bMtQ!uo!5ANhu#kkaoiHpE_sjSLqO7G|y_ z9im~WJw9a_rUJvi3wu>Wy?mj)V?e6{zo*$3?l$~Hz5C8b5y+=y3~G))=MQ4MN`z(b z2GOH8B0v?4;RBw>DJeY>%*85DN(P^T=jkU>6ULD*YLZfe&|3|D%d96qFa|@HC#CwmVJmYKV9gE!-VW3Dbv=ra7R`#hm1L6;@Kxc})l(lT2Qn;0~ zd{t?Je}z&&Po(LxGS`k?vlpsto(K&r9cLzOCS9Hs`IRuuE)g_u)jVxT5m=aBE-3{; zC>ls6&s152Axf;kyGWOb^N4Hj=z%@Oe@{4|F?;ne!+JozWS;F3k0E*8E`=tgZ!K7)QB4iYwI z4Itc=k70BlWSPK?XZ?d}0N9!r2qE;s_i`_(5N)BOnZ!;c(qbgZ1sBU4)!TR-2 zzJtQ1?ZD8x3}Zx_9`8l%9sA9qBnBz0Iu)2bH8b<}JrFmc0o__fkKLf!D*MyV(OUM+ z&4y|~z1|D5A~I%l0&&_zR$jA;tkw>AsEa+9VEfs`-_M(!g-M46JU3r?LCOsHAaVy( z_&gfB3`z#6n-;;(T9|j_?Q4ASI40W-SlpJ2I^1r#?$PR}AA`?Lo~sF+jV-vN zU_Khznq7M^GkI~!yzOQ;ng$34C-; z&$TlYFLhu$rVe;@`le#d$N)m@8`O2WXJen4Ujn%zCpo~Z%9`2EjC_T`qo%#ap&vgE z|8CCXcE{cN1cWv8lXyY(^cVye31+jOf{4M`cKbntgy11?h}%x29g>~a-`wVq>fCRj zA(Ha|Cu`o-g+~l=xg2n?sPo|a%Af`kAI^{tgGeOaK-`&2GYDAs-S<^*Y85`xbxCNG z^&~pKdPFWsygvd9=-IW^R}v$Y!e9lr!9^DnXGF;}=gGd6+A!rJrWthan%>%-2_5Xu zY?1^z?6{^TsYR*9j9qF0{Kn$X51hZ=Bg7nVQ=|$C+vQarOSzU7e1v|e9O0>dLw@rQ zCtGmUkshAIr_3Jr1~h9QbQ61Ww)EE9dp0+e)&||qG9N3M&CFMe3N^{Dzom1rqwbnl zcvG!B-L_^7PHADP$sL{_IqDNfv&GEg=Bp|5`~+}=^S#a} z0moQ(RS@UYivvVq5Al@O#qr5K&SxxK_{w)sG^|wnC++~YXkTawH7O0PKTF_STDx>b zk*DGI+NY=zu*l=EPSR|q^m*$NT^q3kr*B%SlzL`L3I>@K|7eP7Wh&`nBZ+@~$pdkn zXEXuuNU3_M(NkyZg!Xs>h(XjSq_7QEC(4XZ)|r?WhN{rM=pNh2)i-It$gD5E{neV@ zn>fjRb9kH#2GXfjsTXdJ_<4TuL4SqnOO(k3R~qS z0NU76GExmIIOTNb>2*-_S*8w%31)jaFx6eMX>NQh1O5M~@@c=Ng@_xO&-+=+cZ`mq z;?NnIAE(~H>YU=N?FesxYN+f z7E^?0z!Gc7K>J19hlS}w;JM5)(=5Th`H7*s_qUp}Cvf(>-5eo(Ws|ohL}%49RjsAc zb;}UZZm@>SnnHR}3G;k6jVHK=tq|^LvRx(UQ5|QKP@DT9MZ9--NZEv=k&BoL8*Pq3 z)8DMQ%5J1t#>V18cyN6PiM2-3pIimO=FEi8n4GVHGG(X>*t9gw$uQxQADl8ZF0Qtc zpI!YlD>CcE6?buD0-nVrtpZEKE=F8OSrXmLYn05i736YK2Aq=SwaPpGY_rU>L+5Hf zD^-c-T$qGuk2d0iP(=Vs@y*c2C)YHI=F?An>XKZ7Zezq6R|fdE>S`ti(;|^j=7WWy z&6Xy^0Mt88m1P)gf9@R`{7)9*-I@&MmSXgll1P9gvL~0T(b=<1qqH_OkKxG5aWo&C zqWZSu+Y4W5cdzE>KVx~VO9WE1^oYCXfY9QyO4!mfmC=lZb^##=aJsPLUxZ7wKFEhg z+|vk_$q~Hn94WthBM8iO1%x~qJiIAJS!&U%3Y3e8RD&PInY@<-VMK`29L7I+eMbE2 zGQPa}$B~V=k2{}2m7*77FtIy{YhsP|w#6KR>G5Y4qA&_BcCL3KK6>$jd1ilIW^^vf zdM%AnKDTY;Mp*Cm{iR3E%njxv`(+IfSo-PByV~QzHEMEOur_Z}g|kHqRQ8tm_7?Fr z@3IZR4X;FXm@CsfS*qPGd}1wqf({l`126@ZTE@lBN-JXo1!FPjP}E)K`G3BJ8evgN z9MlA%KSZjp8*}H#9>lg*^<%?HMam9z0%a9DXK=nTU5(K508KR{#Eg7g^%`_&BQ(@I zF`Y1#nm#H zm8Tv7m($j?`Q}MALxSGY({vo_SScohmmMOGSzK_smUC`0`Iim|W6PHco2j2eT8rFSCHKjq& zXs<%n2dWnMpuZx}KpR;ZvX5N@IQ$x^tSy$FstK%M&=#~l)>?)74}S{J@kP8L=aVi~ zdV&-g{xPoxrC1?0&OdMR+fwcEEQ{H;Q|se5sW!8;Bsub(@$vquSe$CIA|Yiu37bNe zu%(VlIz=?Jf%|p0$AysehkVJ#d3wJsNq5ZV72kcn#SJo)c>1X*(&T3d6HF~9rPmm` zvO*@AqWukpP-FJ`IWi2)+w*3lAio~FwOch!5J0!}p~loUpyQvfj|iHk6vMU9tj_|y z!2U7xavm%jM#;pw=`e13WQ_qVc0~kvS+e5o0v^DS&|xf$ilS)M90|{ zF;wFJpu_PmtkoOs;^Xc7r z@N+8@@4W-y03KT02C3%P^}e>$IyS);z618JZCYso`ZQHi-#T+67n9L8xNzRxas8@QYRTx`>UHMoVShp@4 zHnh6mxR~{mh_OPu?C48dsx;;&jzq*IT7h)N4*&voJl-B zMcyc}j9?3Rc|BS|TUeeF(w*DFW{IS5QIO>%Q*pS0Z%4W{9#%h5&XJz%UuO-wmn-n- zr6V zwF+XMJT1e@XN)%Oc^SAl$dRajYmG-YjoR=Onv@M}&6uES7+2DK!?F#A%U2da{OIk- z$X4=x+^)*}Bj^cb)WoiP9wS7G)wJA*`V8fOB07b8_X1SP?SHZoL6M*~6>B56dA_<< zL|_74gXUads6NJ6dV0TCaqc>%mB|Ipn;!=ujH{97M+7cOM-ER2Ax@_zLd}@CUK4a@ z5-9lm8wf-on1@w+)07ahgZCn{)H!;`ihINl2!#TFo?E#J6Lr6HJR5A8a%;1@>$J}Y zR2Ya^rUHi3IZTbBGdGoQA2#2nHU#~;)B7P`FO?{4LB^?^$#sAz41OA;fi{M|Y&+P; zXpVtj-8=ReU9WFbSX6Cy)RuylzjE)e<8ha_9S$fW*OtolnumWXx134?q2=^FiSaUG z`*VyNN3T{br6O+9K@&?wXZ8*0DNNMk)R(yr~XEd{o?0Hi~aRj$4yPY#?a4c zfHNB#NY9At9m{BUHrv-rT!}S$#T{<-%7QkY7CWsNn>0W+j_7PU=9bA=@o1aK9%l2| zOuG7_>S|i~mH$mm-<9*(-{_^1XG?Rt|2b~3t?T^{H$eUt$T#+mNPuc^ojT@++z2J12#w~AS+`U| z4Q<@YT|qucgifN+`h3jQyQk%H^H>&30)m9ajgf@&-0V)%`o5*RUqtB&{+rwRH2oJT zkb#?Qy)|?Bw0@qS+a^7)Q%el;yJ}`I5cRd)6w$Ui`K)a;-N~DEg*@lmQg5Hb9CqDd zT>=wv8wccSZ60rsMCFAw0j##3`m1eTO$~l}tMPogwC`wyg{9$!?P`6OMm?1_h%#%- zzCcwpW$iB4c3q*?$gx7pweva0zDo2G>$ck9vDDhR_GjEY+5-KAown0?e~0@!gFY=J zdvBnD?JWd2FhH5Z>D$mLa^;Sw*vw#~m72 z+H@=fr0$KD8OXg>jd?mZmxRTJ-{s%Kh)n~f2~$l~lAtBc9$bxhjl=EikL6Q$ix=L| z^pfG$qiErj9V774W93u(vp6Mx%EHTc)7f&6jO5eLFXA?i+1iU~(|C+>=!-Y~`o1RF z=sRS}=SA`59XB(B0%!Y=cvZv_zyjWBX}df~LP>D;~aCQ)_o z+vIQi(0M@($(nV}pe->Pe6{_-J{U;lZ|oiQ<~PKf6U(#ikX4TO zYBYHlLzUPd%0$3N)=0gkvxGvX^NVnSLiwR=^N#ONSztvUKQRS&8+K-h1597AQ3{BJ z-?82$_U)%MrwNK{xGL;!CH`j6%xa1Fct+o6OtAWy1X!j5=uw)&$ezpo`CY)ZZI3)B zjA)yp&T14*)Bqd2e#_qH`Z@kiVp>K(dN1RG!CSGn)m6Rkj&is`I16dX&PPsT98JlM z`hGA55MmrDDCx>GT#Y;*T}1#~ys|JjDO=y~AAVzJip%fVWYxv!x=j5W{o*)051)eO zQk!)?r(0Q8xnKdOKcy8Ms7ckoZtumAia%Oh^;H#K^0G*ua4o(Ey9eru=Z-=06K4sviV01#SHF9`rSu%V(O-_JwOxqAFlvt6^T-N(ZoJ=&Wv`qV z)$}_~I;Cm-6gKZtlvb`1)CtQ7ps{<=8Q5sEEtJpe9yJ6e+S)SMXl)b)y%??5f($v` zzq#N6^bOi7qRM)Rk@=DZ7~;A{)`nO4-)_1ti2-@}lGom7$?5~kxfvs|go(nF_gWv` zZP)zaMlcQ;nW$=7AV$C4w=A!6Tf_tl@@FLF1=vf5Vb%*7?5qVe68n0swQoQ0A-{=B zOXrB*kra32;mSAxC@KyVSPYDu)`##Wc72!m_8c%Figi37u8|JzNK~D=LOn8L;OxDb zVG@`j-&OZ?sv0m6ZFpek2XK1Sc%GWY3VTT^2s_(sUF+OJ<+eXy#cza}!T?UJKKMkO z(W*){l!@2L%lKr_mxtVZP?zH)AHQ$IO??-CJe!v)bhsDlNk0y99+$FVzH>cI)70j& z`iVc+>n)A$NzvQ1hC=iy)5}qzhd#BZ?|!)s+tq2AK&Azqe|-2ceo7flTs{vjb}9}S z!-)FOXY8Q_7qW`OAuh`#?glpKe|gk5z0ut-6>Z|^381SLwx(g0H%$HbpM{?wqi5x}1Y92K;gaR_ez*RELX(9y%o);kW{2mfWp>h0|`fE`YhzhvT=JzIGqHF5;Ij+E(WO3bEl7k@) zO#`op9(0nmxz*Hfj%p_mJ8ynO;>O45W5e;;@dy(d-z%?VnoeZEOCeDz5ap-5p1sHU ztR42q&ZE5zJfslwm7I&q%)u$N#V?uPWCVHiunr#e0GKI;M{v{O-a$7xv21;?FNH@x z1xUz6DMo-hQLLs+>(u8Q?y-QfD~>(zT4V+yu{2y})|%w>+Duu?a*%SGG8J9?a!T>t z_^g_YKEH|Z-H2TcEY&APDs@!!^sKkeKgx2@? z=?B&IPDQ*DYx}-l8|@P#TYo8LlSRyHyN_!ncninhx`b@gf&t_9?iAbDwDIhL6-5~~ z(RFE@?CTfMksq!QrL_c%<{GxkY}Z8kksmF)vFAk5GxnMTOJq)3uhFOd+&@irzfx!W zj&2=Q4WV4eB@v~@MOwTrgJ+$v0dqE+$3Zs@o)A!iVp59~mW5lG0Kow6JgNgi-U-tV zj~Y#Y(?q2g|Fmu#6EQxh8geB0Q0 zVP3r_l*U{NmWqee*~t=!GwRIHQyjxwYk3lzG>M+jZ6gn??c1;9;Pupen6{9bbqj7m z47YgR8cnnk9t1wkTNB_=chH819@{{EBGS4j`(6el;s=SP3N_$U{tPXz7{?VtpiHJ2 zJCAXDvuLZw)_ph}L+%p8+Fzg~=MYUh5OnW=+?Luuf^JdL9SADS9O70m=NCifM--eo? zfQC)5(!q}@D;R?W#Gq4S=w|tdvmDR*UQ+J70tjEq1~XLgKJB4HhcI~YaIc;3Z@FU= z1;&nqz=Rp$a=6pYr6+k&9jB0t!4zV{uzD&h3a-km7$M#YMNnu;%81l-&uw`Ab?&5j z!tfL?ysueHM{ju<)5uJpfic)HGAqTw1zDIM%0AMknk6TL#DO)rf`e5FT)0zVhq-+ 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

    u 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 H_!0gKi^w(; diff --git a/translations/sf-pl-PL.zip b/translations/sf-pl-PL.zip deleted file mode 100644 index 3a08f473bdae59e6b4fcb5eac20520bff984b46a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 668930 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

    3GdNCxGr=^GU&h9Zdu`vBS!1d0 zieJgt)4K&vw@+HJ8%a_ZOKLW51TQo{SjR%tGWwQSYgM`IB9R&b)r=p+)19w0XKWPX zAZeWMOgC>S*H#2hiyUS;us?#XqqF$;863_}`5P{NbMe3|{^kII1#{mIkWx!XJJe;B z*W>|tSPO547EY=o?Bxjh5GwO*5_!NV{RCZHut0laQJZ6d18dVHSHqAA_8(jdL!w** zX;@MxrFQHU>yb$q;)C;%n0{gk<4@eb$DqR8oz1Knx&YeS-RlojZvqFGgZr<}0-f2_ zmtNtRe8#WlNB<}L%elESIIcnj^u23bvWh)@2B}~KZL^&OP$CmLaegxU*Uh`&s6oi_ zr1r8=*LQApQ574>OzSb&#pH%E%6%gm{ z<~1|xY2$saZ1@iNPfD?05ZSBm@dFU@XpH00zY?_t2bm0dq$vLMoO!2NyS&kx^|&FI zaS5kTjr|z%qS_SZKWe<=3(69MC93kphYt7D1!bWqtBLx}!~wg{9 zCY~wMu_o%=q-Z{n{l&w9p{5CBWD+2WhG@kw3!6AHmgG|*5}qZI6%8;^jOC!D?gVr|5#h|08l89AI=PtUD4)7p{M!E(nmG+oTe;Xf# zK58#>%NN#(XQ)tsu0l>Z(te+^Oi<5)7~`4tIVzd0pH35gbzTc=#qyQMj9}{QQ}@`{ zF6|!oPkJP5(aBQ^AygL=^7^xn@uorS<(dqx#rbZf#pJ8(>gDrZ^YQ!#Pi(iltsBp` zve)aL@BeB-9V}!kHYNao=NA9~hW}{7|B-%jj>f-o(8$Hf+0N$oL)OmO!qmdZz}dp? z|EUUxv^QgkM-zNr)KEML`@lpOJ$hlB8&n(h`>iyf$orY{YX>~ znu4ml1oN7rmsK@J#rZ0s;1@eWifkvVnH;C$>$bH~RlN{%cV5*3qIX2cZ<(&^xYldZ z>wu>f)OM8W(m9k&?q$|?cZDAR;qz1-X#F{L_^YdnV$*E_)Ya>}ygZ`QABHZkgOX!a zo6qIJ)XUT{*f`TQlL;wpm4*EJ_;Z$hFJ`H!Gm zN|`~bdvV+gT38pww%hi?%)f41z{^1!Tn&qNQ!H;)W?m=FreP!|*`Uc;29eE1tuCLk zHq*1oSGhWiiC?P?EKFsg?i(37j<*{I&KrG!$e2G;Si0rmWRfr(N)FmZr(2im75Zy2w(d- zF0M~|huEp_`T=4KJZ*iz&i0}s;;pxrINt%eqnG}^sEe43`j?Uv2@V=7Dh0Wii%D+& zNansjdi@!u?ux+!t_9CU@cSkErc@8$JL6#ZST$)hrBnTyFqe&@cJ zr%j&)Ie`JQge(E!q+-c+Ye{cqxXBZ_meK!jEv;gA#ewpsPsGUjp<2BdczM*Ysg7FK zYE}r+ebxH$>VZzauESxq@;IOo70_xR$#4z;ZU`p(0=al;r>9bL)*!l;nu~}UI^77N z_)kN>*@W%O{ckzX7@BT+L)`6uw~W~jT{Uh!MT0ZLMpu35yfIaO?d%2;K# zxhdy%uc5MuQSW=9Ex zF}Yz=n^2UImLiTk6cN;k0*22qK41DZBLCp_n@6FZI0OUtpUn*KNA+L5>;ze*gzO%d z&GAsN2ZsE?hc*(41eiY`D@moKswp{v!IamS95ANo`NJWU*Rlf=EJqkNA`K#%v`oE( zbNolJURSdUmXHcljsT%HyhXd*0VLP-V6CHcqGE?uEBd?xYEIc^p4pTUHL%P@;jd0p z*k&H#C`clpZ^+WzHIvEJHdGVmMVliG*u=~zp#w4tD+cy|QFczvl`zn@jj?0fHaoU$ z+qP|I$LQF$ZQHh!j@>~gx!=RBTXpW+`4wxI=siuZOSV_@ij1JLZFqmzXP@?WNWZ+Chj>Lm~)!PUP=6dVh^kAq{A|Q^^5jr~Pz-U7- z@S9j_kn?hK@T|5gk^L7vE@(Nmmh71S-lCl41ZLy9el;S}zKXZ&9u9Rd)&RT&`{%EM zRgXii%nv#WK&GfFa}$gpPFaoCl9p&fN`}XRKWhRCRCOv47Yej&m6cAZT%8D5_%++@ zJQ=zaFbTC#>}0X7Rue;^3NG!rNk!n<&W}mOjsP%KNVh#ei3Z}9rc}CM?+rz#it=&{ zbtjB~kQ_(c3l4cmXP3>?QqJ2q%Ng!Z`=@Ee!Wk{Ob)vC36k{lw5u3>%*b+2?)}lP( z2iEBCBub^5+()6O<6CfgxRGOkD2ymP!H~MA%xj)0WvI&v2}-zgtM=Ih&2E87^MHPf zFDJ}48A@ldiN9$>89IX$ialJU%gH0t`@SG)`^xO?!-vn80sy69=_$xM*-9bDe8$x} z3O0Tm#BV3SP;Gvv37CP_4jq@s(2zOfe9?9_Wj})$f9eyM7f0%L!lTF z%^R5Lnc#cJ|LXj(it6HN6B?Lg9$&AW4oB^G6Nt3mv5MPCxl%oe%pYzuF&ZhigB8ZV zo5S^fd~~&)@5wm~$3kWz98?|F)Zx5(hc%%*?V&7Sz$9s$t4an@Te&6_g%WICWu=DC z94gC5fRJJXF_5-!ZB83{h3CI&ak|)vyxRnD53Nf(eE?@!(Oivs#@TC|MBMIQW=w;_ z@~B8aLWqjYY20};$tUUg@=%g_^IX3fJ7_-fd&}?uO)^n-IzoV3Q>hFd4HC9qMeqAZ zv?8>Ai?h>;4dArvk%Gyj^C8&0b~(FZrW-tH%*;sSh|p|HVfm-)Aifg-*Dm;4g&~je zyH1P!)L`skdf%)aU)+A z{i?k6_{5<+ka!?AAE7}H5&gra_!+;uCWy%XI_TD5BqiQcO=Ag6Q1eT(7S|KmH{hq? zMvV;Uf=Ni_mM9B}a13x==OdD!eDHiAUJK}-$<$tbSt~e#HfuERzd(yYgD7`6xDH0Z zI{kNS92#+i!;-mQKrrC7gO{-Bv9rviNvQ`Pfnjb&0 zO@xVJ7C9M9phThdNmR5bzgd**0gVR#`THyia9QM$p?jW=c8t@V{FhJ8E2hdyx1vIr z>|_OTJPrMHLzetd40gwp9!}A7hjo7)rj(u*hOv60byGa^yAU)1?_c2t6@gu@j|e;~Xs|!BkhW|vG~}1?RhFYI&dx&(dyYtF^ThZbKi!qxKR2-8H@n8;7vPZy zKMrQYek*W$K_MSw@AV5g2qchLEBekii!-Vu-JU7muQJ;aK15unX{KI(3N~jBz z&S<;$qs+@3Y;WH4>g0K=hiG!^Fg~WETo5%^!f@G>yaFc{iz&O2epTl~+$T@O3{^M6 zQ?_!3gM280@+ns^&rr%bo*aliX0u1kk^KPmGg_lJ`0Q`ysq@9MYlmqUU#moT`O+nR z>X(QF^sDIe3YA$Llr-X;mBk`aT6>kpJXRF`b`@seitEu+DL6kp-Bk4@*D<>gbM@aY zm*Gi*rFRGYHh*o%)m`erE9K0=ZRy1VDH%#!C;=6bOj1C}_+=6bYvJJc^GNKTh#n&0 z{aEdp=AX8KFtJ`Rc4zSlWpd`Bnm7$;5h{zT?(cB|Hs92R*guC)BJD5Xq%J`JnVe!B zQn24kK?V4+6od~~AX39>%%>X=XyvHsjb8QTyHMYaG}&ydi(L{QgZTs&aUOJ@r&WzQ z+H>5CNTi<)BpN=Bu$mF3Wh4ciELzNztcASH?7NFUkL1T+9qQ`|@sJZOx*qGIoPEJ9 zm2=V))NA=a3-f%%jYz}l34rs(^G2g>_3Xm<9mni0yutAd9PJ6N=y=BgV=LbJ8idIp zFhDSlA6KDWKonBbURD0fzrY~N#@g<4!5In5G3Uk+;5953y>b>X4jXR_Kz|)pDm(#u zaS|K>&Y&j@DKFsYH0&l0cbNg+5RkrIo+F)+@^N*Y!m-E(kMuR*~o|`Vk_BE<+75o z6CGr1-kSOpe>3S5UM0*ZFwNv)-8zKRc(sS6eAb)VpK_~YnA(ITf`yBPw~xuPw}RBS zHiT4LgNs7H_##ONtOdH_#~*JG!=zo6uM+}W`imx6G{iT#muZnnC{Qud>ywg#baa$W zQ%JKQ=KqDodgSMn4WSYE%K@4ZkBLq~+;gFqvPAz{8jUX&d$AOk+(%FzMWK(l9AjTx zpzOp|qs3nUUwVfn*^w#zMEHwgVZI6GKij1f(l_FOG#k?WswKph%sKE<-knCo-$=S!RXTj%(*+TKpt=1%>~^^v5VJp_`{Z)L>^7+R89 zocy0w%=rlZL0Ej=`jb%Wknt7i39{HXm&KzfhYDZ|IYo{#>5U1&BWPnL_odtzP1$EU z6v=shX7@e+o}REbg(ePed>-~Nuva%b}m zzvV)11vcgA3{|>n)E68GXkT2>!0}G@kmN`0AuTR1x z#?R~Y&QgN9{u3vGrrbiL{HqS~dC6viJDKNDydiXWBMhRRGP(HbFo54V3D<9@mIO6n zgHgt**9WVKCXXY`1&0N<1xreOWUiFEjN~V!pSBFj|MChx^71}qR?bK{ZvJ!euhN-Q zRNSpYF8!{t>*h8f2Dxy{zS_AQg^l@L@T|^GvhH}|TV@b^2zP+o)$o}zi44hDN;EqR za^qgKu2y9|LT9Ba0KFgq`5(?x6=%xNFBH$p((cM^PTvO@)K$3dDn~Q3Yv=gp9Fz%k z|0PUPQgF)DgLU*2rv#Hf@q5D3gp%aFZ9pt(c{_R%EK=0%o}H?RUk{|%3;0+JWGz;5 z?`FMFO(FZ5@Gp0DSEjCdlPeXuG&J{a@m92DUWTqw4mTL=-|1Htm zV)s^Eud@#=Thss#2CX~4;A)5oI$U0GUB77?J%|f$=Afa#VvpR2R>d4txtDSccJ^A{ z4er$Kh+R2>iL~PiA-iu@)@8V|b*fsAT3o5@&sO}zh@==g{pG6>I?bTAV#j1=yO7}0 zkVZ)-Qqv*~H3$QXc?2vOD=8S=;B)2H`1!WnhgafCmB=Rg zSP@JSb3qGh3W^F%Do>tCYd*lrd`5nIT1VL}5#!f@PUZmQ9FFwfpvkS&0 zin>WSW$!=J7@p|NVFDzXWz>CO&uX~Z{v-TZ z^4jcqjV^IA={bw(-LIbubC&yrei2n4H4~wzRv{e`Pj8Y+5=lJcLr5Lh`xU-k`c;83 z>&50E{bL>(>RrLUe0ua99yE5#kqd10#7;~s`i02LTNyW!sL3W;vBE-oMjS7nzKJ@q zQfQyD%rY8D#Ld^qA<7+BHQ2F~K5Hp#`MORsxE7lKV z;TuE-DgUR6s&e=jb-yeX>z@N_q*;-L#4@WUhsVOF!V41p!e3`&J`B+h1q7*5s1y~l zuWQF=K~qUsJlCQ>&(5u<_LBv$)m!)rLz1Mz3?UYYI3gW%81vfPrw|Wa3j~p;JHsjL z45gCkqxoCyfPEwe+{G*t+~^$$*&-A^t77m6SYSvM5 z`u8{!J)Sz`#g)d8H&IblDx-UPwhv7)fy9fnve`I|#CFIgLuvelvGhRzJ0qr$02K({501DSJPTPn zH7FcLMZQYot&*Yow{$}iQ#O?C7kN1CNc#o#1;ipN7o`ipi5ol)tmFu+6mtDib zo3mn6|5o!WHkoQx+ALbh98F_2j1=tKcLd~x#B_OxePa#&j}1ZXoC*$x>r@s+j;eyr zHg)ehMQf-sDvyMDkqwO0S_0XRThQd+(Rl$%8TKLnu23oDIS&52o5 z#28%!&SaG%`6t1$5qI+p9S+3sJjGNN{Fkl3j!z%-+{$)FKE4^P>NL0({{#h)41fwi zMYrr|!7HW5EBnJgl)avEK2N1T;3~za&=+n;zdQ?->c4Y_@b8&s3vjzX@cYB7VuM$$ z5Jgz2#xce^$A?(O7o3KFy|Q5ce)f?#7JUDZ+S5tIOKa`Co(5@{%=}Oq$Rm+= z;7pU0V@q~e^k@fo2FYu_5}hlnmWNAm$&Vz!&#$Q%X@J1Q;|nUI#D=!X4?_Tu3PpP@ zhFd>bwCl{iN{$8)*WOClLPr|f&^r}K6@qK>*p|C{@F@|wL6L0fZK3e^UgKSvA&3mR zEwt5*pkvAuO+?@NzI9$Yz@VF_#;IwXem9@|dp)#xo3>f2>Tb zga?6IaPuytYUVOdQ^{9;mZg5y?t3=8(7p3vRCwh>bb0iTv0jv{4@IrmI8fY@P8smP zHEt?FrlF9H14d~I<vWXEe6@&hBE3Fj20MT@#wI@q0ktM=qyDTlaLmt z$W-pA!ORC88GG==ijr$^3Sc9=Crx(P`1?JC$zx6ien?dJjGgXpx0AU+>>^?GDYFwK z70K%)#0H(mVJtR)wQ8ht_o!W6_Oh~x&$Ab7uDfQ}uHzsmOBLJn*vwa97DAFZ;W-ba zhd6i^usMAoze{VI5I>)^Jd9$nYM}g@ z?XbuQUpJ9rQNrg1fR_RJ)tf-?Z@dX;ZnMm=MPk3_Fi2<~TzWn_Q&^XIRF4PIun4G@ zge8Ie9-Fo;j;}C3{&4EGMmUe)!q8hz-T%aYMm>_+tp)lg1L^ zyj5TE%9(8AxmzQ-E*yyk$UBCjbG$K`SB%bi=#Kd!1(Ae<2*GU=U1ZQShYv(YVD@XE zbwFMF@c z+|CMk62+-I6|5JF?l$eFzI^)`2MY>G>9kor2N#S<31({^?w_u`)st-KRTVL)0vIYn z99Ff6LnxRe>FOKsXn@KDnX*;`MZ7cVlS(>&r#F8llBRA02ElK%+ohxLoMY3MXWI#d z{c`S#1&&|&J^JNDLQFrGYpVDvJAR$nb4SZ***H%t-F7Auc}k#1?FGe?xWb`Ko1(IU zb!8piJ$iC^X?WSyU*X#wuT%j~5LyUSCeL!@vt}w#sWB%7;Y%tpW<7us;wj*CHKYf7 zR^y_jb5rizvSqf(Bd{ZT?W?{0Cv#-(x0OB^*3dm!ubuE z@#E;Ud(&;TZRzpZq}?IAToHZg48Kwnfx4@G5LYH_K?R$%<*dZW;i4;*qPv&}}X|_#woYy}eQL@9T?ZWa!mgZMWleIV(ycUd+s3fMvBc z`CcNjc07+)KEG-BOyEy^+e8NL&wY^ZpT%CCx@FlYhjS)F|44Vx1~@^vV`-^>U6bg2 z4#XG#y_HAHwE{4bo1_{=XW|ds+miOoWYLlK(pKp92irz6`+N@X88s6@oo_7*5N|)0 z4d(X>9bMPaCK6xel)GxYVWluxG-GDH*#L-sxeB}b{gpOgI=9C%u5sx3VDx)4e|%U! z`CCA??D5VlcX%9&bEI91mLA1>G8bXca+qzOAw}TFXBdGb*pAiz4jyT zbB3GTGOaPn^GKv8ICuhYfVMPft2XFg9xSS@g#l6a%-4OA!>I;o!+)x0O9uV`ldk8I zicD}=+T&e>Y`BVl0=u;L;4a|YU{q~+e}vX=3l&>#M2!5~2i$V8rZSIa)Lh5jIkHuT zXh9<^ayfcmDYD_NK{3J6NtNkdcDHH(>W?D9R$_j*yJq`g+o9!)b}2eFQ(&eB!)Gi{?)anVFI!^wlAhSkG?-vM_U*i^y4zJQMM~7pl~(`dV1Gu)>`T#zLS@NSP3q_9$>B)Q)ps zA?$9PEk*BY;md>d4GT3`*<6H01=RqzL5L0#xf_kn7|vOo5@l&&3i=03(za*YBtLRu zUtHR4G&R3q)o3@iUU>uFO}Ui^T>AbS>f?-3f^VX%z-PJ$=7S7j=5jh}E4>X87m{Ff*yN7_~No2=t- zPv(ePgiqX*`*unBdfL)jB)FG1a0`zT>9GIc5Nn>v!}{MaXM}?fv+r%wVUvG=@(}%i z4P_e%@e=DB#9tAZI<@AdoFWxrI+&!(NL^eBKA?R3i7K2E^iw3R@NMP;{;grUu*Jq< z@2R8<#NE;dw3H!Ye!rvDP5$0$BsM9yh!L7BhXkse$hh43l=TI5V4`ps%J{B&-;U4cGdN&}2DS4qjnf&# zZT5hm789!ZKieRJ#7eT8JCKWgew|64R(8KuJf`QS^#Uv7w z*xlgEKrcCbyJKtlq$RFs0}U0g1?I)sjGKF7eI~sC7$e6Ee;9!t{!?e6@qa6}T2lRxB~8=H4&Jp~+DJC1RE5LlIwp?`gtcz$8q}EUdO@o3;;WSW z>TDmvi9%D6=w&jSSR^q;aG-wFR<>2{t1xx8I!U4h9I%N`McMw~AIU9L`0c}XVsuA& z9)siIZb8MC-rUk9M}!6LvSb|zBie`sp=-;3GVE8L&^309b>~@-^)?-*J`ro~3 zKY{npc_|gcOfOL*y%R~QEIY9?w3PS6c5}E-)Ps!%jG@G=YY)F#Bv*>>`HNZv5ymyC zSv5k{GE9g3FCjDy%_+Rm*Mf(!W@H(Ad&U(8ahwjH$}x2Q2Anpj{z8sm9K}vW&7`DD zD+SFI4s&8%5E8zUVAMW_Uvh|Dv~M>4dN0|L$$RW}FW61YH^T7A5+I6lsjM{aM^=lK zqka;0u5Xzg5jn%GY|atwQQk1IyHlC=Teq-tpGfyCvn%)B;u4dkwIRNtfMq?mDvI5c zCIW-N<2xBC2GyQK-PkyrDAFB=j_uiVXYz__LcDc#r=!Hv=}2sgAW)@?yx$R{s7*D^ z4D#_B*D}eWRAC+7R5X3XI{iMh^3~J{4vOTBIY~Uhnl7=3(1#GEMnyqV#2Qm%TkX{ga}|q494?E1I*Kw_R`je-PdUSVvEsl^L2$U$SeY4&MVn4> zR+cJleq5upC6}Kg6Y>mR^79!CfS?+2bl5NqzxwjXD9p(^9NV)8H7X8b%N_I~7sHsq zVN{;k@j5(A0dtGMLqBb2CK#Okm-}6u?(vB}(kST=_8SlPqkeOv3HKk+Dc%(>BGi`7 zx-860k$|O&ocE8|V!7kr&F!mECo_z`Jx|C|Wj?4DY1dGam6(4y_$k- zpc#gsdbnznc9g~VV;s@1<5Z*93c@cN%jv$oGX?oiV<9CBYvfS!G#cTK_IN<4d@74e zCJY)4w(?ZPb7jYK@X%85mTjD&xs1 zVbmQwlpWu&f>sHp*7al)mx2v8OIp?no$>?37`ydYscGscmNu`l3B;7yvl>)*GIjad z+bET54*7f)RyI0vM3W*NAoeT>rxZQvaO<3mxcOlMfcb=JMIQn5XwhG^3Is_f1f`#>e(Lksnq?U&HhJ}=Q%#2(h^Lz@=Q3S? z`b+(>dsx?3i;K^l*vb`{S5Xe91AWkUz~{w=?UZdA$dyDQJ1%aDn6 zE^6}n8Y z{J_8wWw)XZ9?;*8vA*>NEt`7?k%gi}B6O2bYWvK(v)Xg;Un;)I#up{h5+NOfqk|2FLBE0!}75O+0=(RV+`OPfC0AK>P4>Hqr1pSK(Rd(%i!%)R& zWF`B36J)c_+4!Y=vppOaCT=B*tN3wwo;uQMGG{RHX!jX8Ur7zhqN>!pq(VO^+}C`JaC`eZ)YT2b+0p7empi~69DMdP(q zF0fDxGTe`#*k!u*K8+yRs~~X6_S^Ew1)=FVfp|Vf$}7GLpdma(oMzNhq(dtK!AgBf zzE{ha@7G%~fAnL@bo9Amz5{VT5RgER+^2lHcZ6KevrbcgLd5Eog2otEdm zCa{zhqY#%J$!mNSH;pW?6LjLlQ#~Hj(uUH-4#6H|@pxPBMNyj90v!gKm!i$4TS|c{ z{eol0k}K_3sSQR0cj)^I-8UOvfIGq1$GS2034hYxU3F1Z|Lq5y6YJ(s+VC<~2j#{1 zC@}URSxNFNXLEX3KJdl&1fOtKYukn$l;Qqv=@Y2`x(==8?Y_vA>AtpIo&CjG9eaoM z4qte+HOIkReME<y~hdJg;f+zmW#zZ7ONo{(4St7TW3K)SB~dl z)0+#Q(?ZkluepA&i;u@=I3OB_R$-Y`Y1)5U;;@?T#*s3EcO8g?_KDtmw8B)!ycB&3 zrt8TW&{{F;=Ja+5+Gxa`V9De8{a7$R3Q36^LK=e6(Xweh=zf0yADzT*R`;iuAdCfp zH-Q=f?DgeDK?#WVbLc6U?O?D1mA1GwC;G5_O?E-}T)~!Fe^iU#DlkgK@n(#UPkAnf z3(2j04`xE7uCbKP^^l>ev=I*e8oE6v%Xp*(!CgL zf6dDdCPh^Dk68wVIhC&hF$3VDA8HN_}OaT4(T z9;Jy-HkVBcbUh}_UOIHs)Xs@`zm zrVzuep@(HCsg6N*I)`o_gE7fC9o_5dB zA?A5*Lxn_&7lO(Bg`P%B5o>M22z>T9KPLwLJz%MS%&8ee^j*HJ^fxWCfi`I!g4 z09t6*HY@*-K|u(sgfSo|H^Hkc`B05Apz6bY~*2l7cCItJ>39i zh*lwW5nv)xM>ijBet%CA&x~{2ZutFvQ@zf#*Wo;ju24U4xC{fAMEa9Ydb|G{hJ4d3)bvXT(ZKS($c+1M=qz zjFP{u+at#IxLaCf2?g8Idv_r9%YWm*Q3W_C^5K`Y*K_5aq&PqJE}rj2dKCY$37t3= z@8zkG_(T<Lt?!eW|LxwRcDTy7q>8sDp0^tRq}yNr@oXu#amahLJuzW;L|P*Y1pO3 zP^J%p(VdJf)LOnhP1D+ERj1!=S*1%Kj`mwuAQCkHnQQhkLAo>dPOyO@G*P>%=y3== z9AyncAGx@tF2{JqQtDlA+?)TNbW8p+k#6(}>1T1;d%6qMx!M7Wt7pvVqawsx#YTqs zvpJZ>aWFlp=_nCbBkbHF#7O>>y{^ ze5_=9KM8oTSrTbv->JqN@GYGX+}#f>5uK;(eZi;`s6Dr8-J)Ju66Epe&RH9do!tI zN>JtfifxyixKG5%9}B)p8A0E5%-^o#Z`28V!yp`WDbuw>^#kYqnh^Y$yuz1I*h#K~ zB&22-pqm1@O?oOiDDaSj(Pd2%#dvLuf)NNVRPvDLs}3S(^+5g!2FKDgT#QmK6SvRrYqXHvQkQ%A-27 z4m%SleV;VAu9M>FZ$HIpz0B8kM)b-01FV?YvP!%9Ie!in(aco!9?@Y~UUA?BBOHSr ztG$!>q^r2ebR%*wEHU%2S=q_6XOA@14gJ-NV;uu&;5@?RtKDAA4)b{6BGMLA)TgOp z*MINxD`4&m_`5yG7B&GFx2pV`F0wB5M60)+05W#-aa{Rz`LYaMsC2Hkc|Nh--9EA9 z3E15eYQb`xHkGv0dGs<2-C*0zU0>rWSLVS&<nM;=65*0$Tr{c;}7mhBOSIX8@cI-S2VTFpo{ ze`~X28g@8#U(flcalAcu<{6y*Tl5S&hm4)oKpV-swrIvE;WCP@C}K>3;Vtbs42Kf|4!Z^{pL=ISnt; z`o8g>moRE&Z0+!V3O^5IVDkR-rIEk^aKh(s3GW|1ADidld0Eqn$Ti;^Gx6IlfX#0? z{4H#cCt+G-qZMhPz9qS5_}r{hb*o%pVC^2Oagq^QGZHpP^nh+wxj~Fv?lkZfKwM+^ z^_pg3LeW5wc}i&;eS3Je&ZPBJwZ_kH9+$Eime}bn>p=OFz0;*G@@t{KQIpegY}e8v z!llXHHSYA!`jd4-zhcV5DeJ?aJKrBDfg-$V_Bj}I zwD6fzgBKC@dl=M`HR#v*NY}^xqRMV5;6@Oc#D&-+l~~e)`bcO}tR!YRDEqvF!^{R- zZ|dr0cteF;S+zl1z4_Ybb6|sZ{;ddd0qip6oIlS@HnI#mkYa%K@EDl>>l!Xwy>ls8Mfe)udI*SK?X+;r?2}qVN*@t(p1VK1s^em$( zS}9@16qpmIxd(q`{iP{6>WT{(L}R}7ycAJ zc?NE5?<8Lq)k^xn))0SRz9lig+N6nIq}p?&lHWvRg~E(CKGC7C#(6AshRpd)?`VXe zHlOZ7?sE}|n*OS=oSEs#x- z$Ju31)W1;r->U^KXeUUFUsxhcLP=xRM-ghL zJ0oZTL3t2P7EYsW8rm^8Hr%l7ZD=K3TQzhshs=#aqcO?mCA3i4w#iGKe+rbyCfhF$ zwfL|H-hyCCa7T+XpoK5Q_@Ge4rKtyD^`h|iVJ)n}G_Bwvb*C#r0&6q^A*R;dq!#}( z_1U9rlW_YXo(^MN8&Ri#e~8Z~HI9o@gRp@uK2+)g7r+&C)<~xI(5AY@uM-ZXXJo7@ zt&0hgw>Uh(DSG&K?S*SAsQu)njw6YCxw>;z^l~;EC-a_C=)(PdC2s8OKkHxN%_^(d z3ajN9x-FLK%g5rS`@V%By)VOp&!wp%5}&w`cRY{9ER2tgjs);w1p_%?jMS#?0h4ib zcK3K|b#9symx|rNgH#3Q5hMHbqjcNa4%1~?*4!$KIa`5+eT5en7~vA(*`76OQosIg z=0^ToM9%zE`E(FO56qpQQa=IYyY4G;jetghgl@!rUcokIzJ{W_l21#qsd z`MAcJ)I6W%DlNYd;4hy@+doXWiA#n-_xkKAi3g!sU>uy`!jIl&)i(YzGwANTO}D`X zTE&~-I{4w5()f_@LTxivltmJ-g&-}kv$~2_k!E5+P8?I8Dxg}fh<7EL$N!$o2>56A z!jtS(zJbhPLTAiS)MX7-y>-XEJJuEy!*GW{9~fvLovFNzo`bQ>7n;AY zTXb=4^yTLu)Q7z~yRD~P?Aq8S;W!+2c$~nrvL6V(O`s&WAWx?F_%EpzQn14g>F_O%E}Wg*#6{|bBm-pfe@}Aad@+ky z@lVo;?SW9?Jhje(#R|b;*qDyKh}y7ss-p&9VQ&p=O|xk>zIM@3fGnW%Zyzr5NeEf+7W>QF7r1Z=X(6ccONYoosQ- zZ}@c9nJXjvZ+56**Mt=1xB3tShh(MiF9=6K2$h62R(afwqF6)>+YEd*l=&|mb%IUd zt}LwyP&{rP_#0OA6uF2u&1qyQR(4x-?l!87huwoT=9G|1HO<6{h|z>Gl}wi&b2VN? zD5uU<;Lleatmm3nVxA9`+2QT4N}e=}_Gz`OP^7>tO}L7Tzw}0Beagv<$Ex1WCm9Fs zHno$qn(;#LmS^{=rKlUQ!fWa7|n>UT4wdXi@|a1Qtie zcLI)yHCyfn-6W))o{^rWN^`Fh`<3OSpfAQ*c$X>GgbIX}t!b5<{e&n}7s9BWf+d|? z+25#Ve~N#={%2C;<|%tKMgjqWlLP^w|NoPsh@GRUt&6#_tE;<kHU**=MeJ2y=oFm3YpwQ`X5ex%?9y=-I>!V z``7n|Mke=mq}f6`ns<{pV%4Te>%6@0$-g`%;C`?@HmfJ3u72z65SF);3IcaOqKZ4v z>+y8Dzt1qo@BX3}dVftF2vKkU5lK~D*SWvdcX`L@0s8edxK9)qDA*Fv8f4Kiukb#3 zqx?Qu{1?U>xf)k$Tm4+!^eU1nmZQezVqS0e!yCHoPBYh@ujgU(k4qaLiGTMcUytGT znV03%|7HA*A80-PM9v(+`!rO3A@!z}pEE{5V zFRvnXSV(N~Oz`Pix*nxB{pS$2QFSg7kIw5Y&7gIM0>Mr~XvwYFo5d7$!4|lSiP}j) zuI-=4v&-EQ>4fGH?y-}&6iK2X5AERnq1F8lhf7Xd=W)E(JIQe-62G5bJj87 zh7D-&MsN#@NTjrwg%Z8AWK~ zb&G0!_zh0B%|oEZPTzjJ)t-_y(bc;H98d@eqJ(MQP*bAe6J;(nW~&z%umw7AjwO8O?7INy3X`?+V4!#%`d zTl`#f-veUAgSi8%BNZ!sl@_O9z7pJKJ%9wmHEaiM&B<(;?Gzd?439ZtKT*Szzxrk= zmDo8fbYY-QSWOr3_-Cnfw`9vFVFWSgx!I<3B=+u53mo(0n=p9LlIbtj@W(h&7X#@_ z(G5x^Q~$Vle@t5?eI+ud@gCE*g?lj3r$@j$L1)9$>*d|=AJGp2p1P0f_3Ecj!9vSW zv>qS(NT~Y9Ret)x-6H+txWZAYdZzw<$+oLH0*(?~RN7t!3m^ds`+1Ctb$uLN2PZ0M zYk>hTBa67`p_zobC{^**BzDF#=%AxiDtoVG6jwIA!9nN9 z5_^e3`X6mv)LRTA0doCvfo8p6h7&OHj^7%KY?M?H)xIr(twmz0N4R>*Pz z%~4{r+~!bPu*E8g+uByV8%S5(jg(fLI}uy?*#^w=>rLMXSOp+vEO5{%`^UiOu45p&LeBh7*_}Z&^0_K`qwj!`*+4r}X zFK6fEHbpWt-Vm{3bZN9Q%BiV%^F4?<5VwPL7N$W!))(*YYehvx>D{)cyp>ga2iBSw zE%z=zEWb`Xn_ljE7Bst%p2A+qx^Gy=v&mGpjl(&ZHR{tex?c>z%>%^`8Q{s1vYiPy zO0OrDVm|pGTJU_N9tnW5y?=i=iI>eb8I{sjmBX~p(Raeq? zs0(EZ8@nXw_>`C+)Amx8@E0cDj@CI@1tzV{m^rM^Lz}P8W<#4-qDBhh!_~bO%_F! zdMpcnTs~mU3k19>JLm}nK0LVb4e_Pj+dU>;rKfl$P&R7PftJ^ zZ3#;#9`~nQZ;poi)6L%!OZv8_wpBt?eMhTbz8?0!yP1ZQJ z&`R<-Z4e`I-dxOrUB?%eaYI1|1VSd^#Q<<>#N$+$V_&2@@SS`z-NyG~poqy8prszW z$Z>pUR+a0$vM)7uw;ECsZ@NfU!JgQ6x8uwn){-wg`BMb4q5H(RcIJ&Y5hpHo0Pl!R zy~;?Gzl%KUztd#|Xt%_DUlhaq+dF-BlV7~saZ2ZKf0-ocG`i>R&e5UT$R;|^YW81@ zY{0ruQ@$_p3dLS&Z0nPVnE|YGAyv`!riP*~km*VoxtPJT%$;%3e~UVV^|#q>BNWf& zJN=-*&!(9h)BoP0H7)`wT}+TdqbP-SB?fycRug`;PcjXB-rj{VNG>2u_s}YBI6EW; z6!*amgat*Jbb*u*;JBG~Lij3af7y)JPyt!`hr5Kt#u5Z^+$5`qfA3*Q$#=37%SKL@ zj6e>;QBY-n!o{cJH-2kMs9FE~GA}XHl%NO9#!|eohum!HfO&?1kCF~nw1Cd=E4`zK({e{OAS0%OVUAIVNw*V%l3n&O_@ z42{3VpmRY;sWfwS@PbmX2Y3?KbfT$@1PkZFcr@tR;;EGPzb*1d#uXfTFRkCj8Lf-j zNa_GAA4iDMzL|4DQvd2dVPx~CTS4u%#%vPrX`FM%FR10AaS7Z_5n?GplR#9Ca6q&{ zio8V(PdVc;`$Ptt9^}ehC)(`pX3D{1`Uz%wvy^n%D|`;x6fj57Gnz-R>NKp-%k$Re zScqxVsl<}`Gh1zt_ka5Nad7Dn-i`Vf4eVaJo$?V`&LYHen`8mdhe12|As4sF(Z_Fm zO|sdqr)o3nfptOlJp62}3OL?M!%cfbUOe_~?O#t2JJfF-RskDczh66GTm2u+AI~mg zp+Ef#k~yH$EUHR>q29j3`_4AFt9%_m%muww-vunk6!?@KE~nu z@fzIrJO5@mck#s}b=0Y_*&yd+Cp8^QkJVvNIcd2LvGIXh1`$iFvO%|)yN@Hp%s`5< zzJ`&T5rkI@M?EBFGL|KW17K-+#mA`h(qf8(fXSASnFU{>v$-s8#ocu>Oj1xFf%iGDS^OAuSt= z-W+Qkk-yA5i;AdP4`#fl!O$16W>qth)6=cm zHg$NjjohBzCs5V26t%SNoa52(`!QJv)ci2v zwFuNMbR$4mCTTwdX=NG8djpH8n6=I45qVJ?1u&Qs4JC3s9bv3|payJJ`-+q|L%nPK@f|OFw;2J?0;lY8X3Oo*qQ>gjFMo#nQnQ<5YUrK24 zTzO@rsZjdFDU0QH4nOj)DO|!LT58iAr0=F`DLuAL-;MFY;5^wi313mgo@8m4vYvtO zpknD?m=)A8r(76Qa7dCuUTzbaL*oxd&GIp3#-~M`e=;&;TlrhbD`-kFk-^%vVKeoI z?&8cd9?-4|A^55XD6%QwxyxjXYFj2~ezga=x1`KKlgdOf2jEb$bfFoP4kP>V>f%Ri z=|y?0mD8nw6kY0v~&e*|IcfX?&45yLDV6Ym5iDmhFr@9^Yr;iG*<^jgDijZl%46IT%} zE7_=*sf5KzQ##LW%ni%~R-M9(DArfqc~AOVqY3>tM*prmM|$)W%zf@2bzdk$pO=mb z@IqKj1$1q}G7VL_no^bPc}qT+be%h?ny@Q};h=@eHy~BCsCwGaH}^Eir(tJv5-6o}7722*4j{F5N-}ya21q783$(CN z1V4RA&@AuBy&rs^w{`?Ce7>*#c(&5Ee0(%aW4YE550#dF!Pn;Z29u(hrC@MD1Q`YX zP9H}}Cs3gaAv<>&dfhm1n6z~jVZUuX7~6os=;v#atPPZAmD5)3R|RF{gv3r|4^ql~ zSVLX8ei!V{YY*RWlO;C9X|0FXgqF53RaC-8WVJ*ypdmTWXuGVZ=fCHW-teWF87BRh=}1>bNBk4Aw{jwEKB3}Qq;En_a9G{wKS+ok1C2Z9kh^FHWH}M z1-nzK3gSODVy#_e#(reVNmRD+h9pRf!+yPov)*s;|M`qJ7oqwq2n7UmkNJNgd{oSA z%)C4toK625!lzdgV2?YA{1Zd=hyv9FOy+chDU@_T)SYeG+t!#=c$#%%-86deX!?8X zFjIn5yl?QY%s(T8uN3lc+EtbkQGk>rjUbTF{$sCvF1OkarotYB%QFORv8xl8(|iu} zaF9)5)aLQg)9g$6-SP zFb)(gq)-B3jL88Pq6{XgY3Y6;96({F?RsJAShJoUsj82BMWWh7+jxJ5eHY_qvz|8wjeSeE>B1g}<-S{cyveVKWO=#WU3objixuI8MZXbKQ zY<{el{3|&{=?I_jZl`@gJhI3`bE!Wd^UC4Bp8+3`W>5!n4eoUlH?@Pd2o4FyR2#Tv zsgDyuQO z=vRjRP_o*n>A8t{v_TFWc><}R6(&bgMUqPPZlvdB|K5HGiqRh81R(C`gM~&U;gd!g zi(#-l2q;-<)+bv7f8OjlMm%j`R3o~rVm?>*QsOae_=k@_Z6E%PjFbWqrhFb=kts!$ zjw+dupq%lHA$mS^VbKU%%%`AhF@3_@RL;(F>eamnYEAQAkzdnEHEuY@jID8H$yWKX zArs7W3y@w5m-LDVr##gJ@a)#}XKX!UaH&`qv%uN|*OX&#(9)qT(WEkPn~RmxG*IO2 zHWFx7t`pLth5m7ip2pwDv_@pqn-?H>1qw+9+nz+>NJ^@(dV`8X^+td^_YOy0F8Uq+ zyK&kE;wy^ly;$)tOla>$0UIOq^t44F$!*N{g3|6V1pdQV=2NiN~{RzC(gc_$V(MOdlysDnkgT zyz&w_^AeKe8P!jaq$f97dLZpXJ@2kM$AkGUpFg4v9bI&WU>Pp9-ruh;wOy$9gp=*j zTQ_XT*lP@e9Iu*;r_PXE^~C5MI#_sPgE+YcNBOl8hFr{I&?$nnjVQ?vnVAxC_?r90 zNv^Q;B6#>*BDBb)86NxZTv*cTXtw$uvIeA-uJ6X;$m$1bw2%ze_U>*Hf7%qQ$AqA& zX(G5ua1a*MidH$+0|9Z+;!HMfnatF;9O=lTjAyqj9~=pr@+G<4sV}Rp79U)yO?Rkj!IDG z!lCifXfPOL>Gc;*^iar>-F*Gt&$pA!Xx!&N$Fm-%Yn1DnYaKIG`n=;$3LA*p^EDQy zTX2JNLi%px_yPA9XPVCE1~@el2Q|OgBMl4$_M)Jc0&l&TqD0-Y0*SxZwNFJ}0d+ch zO3we((Rm$4G@)WjH*Ra@p|O}fRr>4^Tp5WJUDFUCWhO2G76QCH7VTvIno4LK!G)`v zy_KpCtAZfnZ2Y4%NFpV(qen6#G$xtCTpD~xWr|FuhZvGU9kbo7`e#qw=Aa?wX|_G# zsOFpP|G2cWH?K$rx1mGp?$_~bS2Rj5^S)V zGRsun7?v;51Z!S+H`ESUU8h!oTZTa6#-q@u_##2~?@= z7dldWxE`r0+~(%tdDa?!B245bjqzbDIl?aV9YH40oBj1yY(`{Ht_QU4c%G`2UJ9J; zRE{l05pr)JHMb%y!NFnU>B3iv?VrI57EVaK=Rl;fz}+xs+P?JODUc~=hZWYVshekj zf=7)mC1@1v(8vj4FTsgE-d(G99S)_t>*jN0 zzbFa!R0o$NUH_E+SCF#8Oo>j4+Mb4UVc z86d3;PHZoxXCkfw?NX9ix45=D^i`PaR|1jda8;Lv(p{4a=b|!M(mhNm<9wOineY__ zvK_R^-*-cx9a3&;Zm%}_N>|Xo7&kt+U4QNLc^SxF7k~U*4>eTDH_CyY zIad^L5LrwZGV&KhH8CARe|Swa9|Ev8%35Ah%_4>9*H^!y8Uhe5Hhl#)mYLcw32!ZY z+#3CzEtzLhRyf&mGH!+D>%Orc;WtGwyQ-rL2a6p-HU^&B#R6oK$Tcv#0UwnHcqjk9 z_Z#SDZ7Gz=b1*ssbg7Q5V5Eob{z0?j8FuZk$TiJf$bJ0zzh8QqbdA>L_xlIEQ z+ZIftBVaY*3p7qi8Dm~8~G zshV+cY5V19{FW-Je00a8zGjd&B$$6cyY%k&me_7v@VLE;uQ}{m%2phZ#4Cjs$m6g` zX`wz1=$xna=w!`0)yJx15$VJ~y@nr~6aH>F1Px;6V}T{||Hd7R0xPT!2m5yat11#o z-sGSKc2q(~h{~PXcUw)5CCBb@YrhAu3r`Fs4(D?KGDx7YzqIoY4LKm2ix8J@|Bc0H z&&ocob*)7}%*q$IkfTClm3AB_HAdDdZ7J6{R3)n@Gs;=GSKCUT6{mVv-&Qdo7hjD4 zs`2s`es}v%N6fU`{?CrTy*~jgekOjrY9|`=IG;i-tGbR@Z`qKAe%X*S#B!oB)c!se zDwqg~J=3~l370IyzY9c9ss4AF0k~Zx%=T#KNDlOs!%VVO=*$sinOtS&QMw>i z=QPd>=js$WzO_>5%*W5_ri}2sIMlVi_v>`I1-={jNH?L~tG|dsz@!l@?!pz`ifPpI zvGdJj?{LF|Z-V zISK2(SD-w7b-{9w9%Re;r(G|KcSKm2?(WGg}No+ zO7_Uh=E0;%Z5!}uBsf!SqiL-rps>zyL2SS#>L2A}A$Nz~LZH}=_&RqAE2q5<91uj{ zBhr-MAO8u7Wio?a1I?7WsVqQI>uTCps$Zr97I^|=012!TUPZ69qZO5BkKUDskAl12 z5~?&vVq9jt(AV^l>aQqARpn^ET?db%Tdsx<*Ph<2t@~whfv~EvVe~4zqHfY3!8;9gDuolMYRxY8~jDEcDZRgy;>85$S#-hy+6hcvOZnc)Y*zS+tCP z@1f`w$(7y^U@BJsd!w;}#n7cMv+8J)J{ngtc>Q=(GYvxRjrHe&xA6!qk2fq~vQu8= zJa&cQP%?4y*J47SZP4|H=1p;z!Fkzy^G|&IZ~SVA?M)H3t+!WxRGT8&oTs;*JBuTq z&b-4@?wNAt*IA~SfrVQUoAlC*yu}rd+byrauo@ok3f&i$D@Skvw$D?llSeQMJ14}` z$aa_tj>?tH~dymz_EqmZ4eZbL}M1`b)arp3DXhJ;yS!O~m3lU*-|DDy^}IP>a; z*EQl5&1Y}n??*Lo0-6E-%MU|-%5b%9v@;4(hLS>t5{*v6GaRvj&= zRrMOfpDIC~#Tz-$I?Z;_1%^ibkPV$?$V-3mt!{(vSp6c7&2vXxlkV7V@Ua=o_irH$ z006Ofa5&d0Ul8#u%~2i!lEM_%N%{-O+cJ0O*~9l4zBBC5!~Iu`K-GhnUr?*LJkPOZ zQH-i)I@n>PTg5Y)NN;@#55@XBYgdk}0LA33%aJo&9xnkwfu0nXx{ibkq%sUS7&neZ zpc$2IToC3<*a_qL1FO`(cd+mKg<*@oRj8^wj`XP4y=l}g(5PoBEyxgjFk6^2uO@eW zWA70ccK1C%9$hZ=(Pb6dSjUzQ4kh+kA4Fq#yjWYy+J7|h_A2(e> zS|sQrsae~s{a?!07iiW1O~g~CMTROYdjTI;U2YWQpi@fCRWe9BENwM$m2)sC5qe0Q zg=(i?VljTWr!L!)jx0^|!kR*AsMVlr4xT-MqitM{oNocT=}vJuAwk>w?&!8caP~;; zw@%}k=@oTFi^Edu!_duv@pA|glBkpk6cx$aQlv>MEUWqTAG>qff@=d{%Ux;)Xm|s5i`FeU+e(+s>&;Jpu-j%Xnat;gx zGzAI-MD?G0f{LY)vzf7*tE+?ke}iP?s!ZDhn2>r-X)$S)tOenlA$pW9y*dq6=F%>nDkSL!bk|bc)Qhqbgj5Ekh-VFt zC-tX-cE~}@_&V08T9W9h+E3e8;hS65zOZ8+!<@}ub?tgThhB&Nh(A1+RIoi=d(x*9 zx(=)Y18;$H~OiMa9y=@&8|GQ)<#+Ts9L@*sT}L^vej6 zWEzp-s*HjfK%|<0w%$Uv77KS%1n2quG9i{dytb{^Yph>l4|16|4{}-_tLSgt@f*b< zT<*Q0?%w_F9)BI}zm3|gW;X5S6t~7>701@}#gVO_JaxG${TrJ*Yn%n8T!*$#zl$^v z+A$nEI%YyyhnyCALS9*nVyr`j*rc)mrmz(iw9(1^TPmpVMQQ0wgI&Ts7<95Dg# zP#ao3fk^_LxHy)iLWwRL{Ujo(C0>S9*0?)aSe+v8dnSYU${$squEHD=%Yt)&v|8y1 z$cj-r;8w^Ck;}BAm4+q2ly*GCbtonG*F7MI^?Yj0HxuOJ9b_jW{lw-1X4<$&#`gU_ z(DOxW%)&JKBJo6ASHz<}hw_RaJDd%`&uUEV0P#odz(E}vf3;(7ybuXZnZmLY+DAO)zdB$i4|r#~s$E8tng>r>43E_$immxF(74+0k5M*nsg zTB|o>=W$lxHPmDk?!0wU;UUd11L)ovDN;ve00J_I7TTptg+_kKjpm!DE}dA{@28+5CDRaJkFL2Pdbot6N%3 zNBD1P9vivmE={$t>a9$-^7Gdq*^`cTT`uZY(aZUzL%&3eCmX)E|6uI`y%Dq}M)+zF zQ8ea@C+0gcMl9Q=n1iuQiL?>^#Jxjc-QhjHK~L!tW}3K^-hyZe3ZpZM%uIBT1>m{mWOX$x*!6C2{evpc zDgMTX}-G*PBfs{oLwNt_6B(sl7{LT7yzM;$o>4b}dZekX5P^#}svAXZ%ZvhKymyRN(B^k)@p{j2^Id7;hX$?!3$VWDMvm+(F zogs|>s+9vKbVGrxgh7N`%5UbF6^Br3^TdM&J^n=rrt~pTJ3r)$%ozUgH4y;|x@vZaX&i zRoy*wF*WKu2!?+?Dw?t~A{DycO}~n{MjxW@TcDv+`+GSTz_ELCj;HSvzxK;{S>Blr zuT(cgD9g-m093ZyJe%C9!{B$novRyty9D42hlu%IkN{^KljL%;A6!2=`=}V`ZcX2J zo2e;0fwfbDp^0t?D_JlmD1eeTdYMzsSv0GB$TH=M@(5ZED1+r9T0)Pcu34eFs8fFM zn#y@LnXlTFk4NY9dKo@3MQb(mNV3@2J-oBzYD$N(8y}&*9Q7hwBOeU8VqKNCtB?95 z%T-~!j$eZ+<;Y#C)nSh2;)Ibo$(zq48>@kjgf*^}l)xe_CmbY#l8Ai&0scv17k1i577CfmSR@yNJ%pa)>?8 zDIJZ}fU=}t1JeAEY1 z>&avCU4J8^-JOo7&4=V)&kpK*T-`+{SdT&}8>cM1phwToXu8A>E}eD+Rdg&1BAOit zo!77I0Vs@C(&>2Z9y_{HC`{A_D6 z-+oGdeelpVX~&1Z2k)EP&F9Pkseq-89W$rjPFa_|Y9`Ono=sPFcs&CtGrjTJEby?T z5FuH9c=MOQ{4@1LB0x2`DH1+wS=KC0=Q`wp1PXjiGXEKr-=&TsK$&A?tV!sgC@>+D z(HDFa)E0z-0jFt5?MObdB(j9-rG&gzN$jaJQn53+5al;AzOH9e*fhX@P|x1}&OP(c zo00wY`h+jCnK3_V$)oy)?A*Ay$p-KFXqH+3RcjkMoo*6O+JLTaPT(B5W6NM)S`!k5 z%0o!$heVHDAM{42gP+>)3luOmjpH~~^k$~$=W@zyAvB+6PhZ~l2Q zU0nO8dYHwj@5>OycU1?v=?*zDJ^-83vYJLVr|6Ii3#&i}Vk4d938K5XHfaCKnDL37 zJ5S$*FZ1p0`idZ~p*F^Ls)!<=s$PC7N>960s5UdidR~m;x-XrHq$@>Hg#tE9fS+)9 z!C}DE7}FpNi~C@pxUN4UX}1Bz>WrTChCH6ib0}Sa^$&nl!46^?q<{bczeItEf`m|) znh8|J1M|nsM3lHSen?lC);I1HaH>|$dJ}DwwKyBnHbj`Rr9dBJD)trlTU|X@^%AdH zALaSs^k9V9pgmi+GkRkFP?-K0&_$7|D>V*>&Z;D@a}AEEt2~8WER}^<1n4ml&}{^@ zLZqT0W6?H|qgf2m8^cb-VMNp0Mc9Sa}XP_YBF-trmq-tvTdsZ9DLL3TsT+ z$jng}k*dttYuzmohRcr-?!7D0g($sI_s@Ow=LmjR-zEjNH?zIBfz8L8Ud=O2+!eu9Q)NY;#r-YM4nR+_1X-mv`zv%?(V zrt~Sgt@q6@dwe76Pkx8e3k59sue=$Wc!g`3znSp%HtvBYl#g}@y4TXcyly)MlSU6N z=nevyZ_c>7-P?^Da>Fb&llOf^0q)bc?7w4TWNPB+5n8P63jhnK%|q8)iPOK~EqB`U zc>?ln{srLCHGYqvaR1Hx#aoP5BGuZaW!`|eD)K&0=yhMu<4njXFtF6B!5%EiOw#}> z%QoGlYIV3!{!7nlb^c@NK;7gXQTvbLNV>flBM|0w)ii(8ZVV6poRFm@G@X-w$h*Ry(j#CF1!ElycRWcv9hrL@7u+$bpiI<;%&b38Y@;Y3D88< zUj0yQka04vPaC5=J6Eu`hI_jGCq(0 zN+9}6CUcr|a?ldWU6An1dS#}RV;fZ6x1f~2f2d?e|E_GhSmAA?_$by+9w+?u%p|Wo zdQXx`j;%l_*P%EX^At*I1K&)CkgB4!b3?)UpXCsB^UazS}oClDhE*Eyc8dt zxYfz`57(~|{bX=WDyvDdG3n5COlB;T&Qq5!$G!Zf&W;#Vo12;?K}IaUe)0x2_bMguPc^+r={y*&{MYP%bbgb`6D{kV z%$t*R>emmOOb(}bArg_~eXmC}G@%?=DGd1aMfI#(if08g?@?k@;h1upv5$><>ZMPk zer#K~62*43^qjaK*Au{z95aYut5y+BR`1k7Z4`m}e6NdsahNo?f2yfv3x9fGp`3f@ zqn{h|^tJxBs-tGV(G>~f_r|zwSsfΠ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

    =@nsnrIv!7nAtVM<% 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 Hzx)3OGG_Ot diff --git a/themes/classic/assets/css/eeb9224f85430652fd070e4e64129aa4.eot b/themes/classic/assets/css/eeb9224f85430652fd070e4e64129aa4.eot deleted file mode 100644 index fe764f866c3dc960e73dfdb57ee62a82d490d600..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415310 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 z 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⋘̸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 z%0D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 P7Z>Bl;>Y7B;wS$<>UyNf diff --git a/themes/classic/assets/css/error.css b/themes/classic/assets/css/error.css deleted file mode 100644 index 93566a85..00000000 --- a/themes/classic/assets/css/error.css +++ /dev/null @@ -1,50 +0,0 @@ -#body { - background-color: #F7F7F7; } - -#layout-error { - text-align: center; - margin: 50px 0 0 0; - background-color: #fff; - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); } -@media (min-width: 1200px) { - #layout-error { - margin: 126px 0 0 0; - padding: 50px; } } -#layout-error .logo { - margin: 0 0 31px 0; - text-align: center; } -#layout-error h1 { - font: 24px sans-serif; - color: #333; - padding: 0 0 14px 0; - margin: 0 0 19px 0; } -#layout-error h2 { - font: 20px sans-serif; - color: #333; - padding: 0 0 14px 0; - margin: 0 0 19px 0; } -#layout-error .page-content { - font: 16px sans-serif; - color: #555454; - text-align: center; } - -#layout-error { - padding: 50px 15px; - margin-right: auto; - margin-left: auto; } - -@media (min-width: 768px) { - #layout-error { - width: 500px; } } -@media (min-width: 992px) { - #layout-error { - width: 500px; } } -@media (min-width: 1200px) { - #layout-error { - width: 500px; } } -@media only screen and (min-width: 1200px) { - #layout-error { - padding-left: 0; - padding-right: 0; } } diff --git a/themes/classic/assets/css/error_rtl.css b/themes/classic/assets/css/error_rtl.css deleted file mode 100644 index 8d149b93..00000000 --- a/themes/classic/assets/css/error_rtl.css +++ /dev/null @@ -1,50 +0,0 @@ -#body { - background-color: #F7F7F7; } - -#layout-error { - text-align: center; - margin: 50px 0 0 0; - background-color: #fff; - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); } -@media (min-width: 1200px) { - #layout-error { - margin: 126px 0 0 0; - padding: 50px; } } -#layout-error .logo { - margin: 0 0 31px 0; - text-align: center; } -#layout-error h1 { - font: 24px sans-serif; - color: #333; - padding: 0 0 14px 0; - margin: 0 0 19px 0; } -#layout-error h2 { - font: 20px sans-serif; - color: #333; - padding: 0 0 14px 0; - margin: 0 0 19px 0; } -#layout-error .page-content { - font: 16px sans-serif; - color: #555454; - text-align: center; } - -#layout-error { - padding: 50px 15px; - margin-left: auto; - margin-right: auto; } - -@media (min-width: 768px) { - #layout-error { - width: 500px; } } -@media (min-width: 992px) { - #layout-error { - width: 500px; } } -@media (min-width: 1200px) { - #layout-error { - width: 500px; } } -@media only screen and (min-width: 1200px) { - #layout-error { - padding-right: 0; - padding-left: 0; } } diff --git a/themes/classic/assets/css/f255af0bbbe837e79f7821827f9c6f10.svg b/themes/classic/assets/css/f255af0bbbe837e79f7821827f9c6f10.svg deleted file mode 100644 index 6cc507f6..00000000 --- a/themes/classic/assets/css/f255af0bbbe837e79f7821827f9c6f10.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/ffddcb3736980b23405b31142a324b62.svg b/themes/classic/assets/css/ffddcb3736980b23405b31142a324b62.svg deleted file mode 100644 index acc23889..00000000 --- a/themes/classic/assets/css/ffddcb3736980b23405b31142a324b62.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/theme.css b/themes/classic/assets/css/theme.css deleted file mode 100644 index 8193e1c1..00000000 --- a/themes/classic/assets/css/theme.css +++ /dev/null @@ -1,7 +0,0 @@ -.bootstrap-touchspin .input-group-btn-vertical{position:relative;white-space:nowrap;width:1%;vertical-align:middle;display:table-cell}.bootstrap-touchspin .input-group-btn-vertical>.btn{display:block;float:none;width:100%;max-width:100%;padding:8px 10px;margin-left:-1px;position:relative}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0;border-top-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{margin-top:-2px;border-radius:0;border-bottom-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical i{position:absolute;top:3px;left:5px;font-size:9px;font-weight:400}/*! - * Bootstrap v4.0.0-alpha.5 (https://getbootstrap.com) - * Copyright 2011-2016 The Bootstrap Authors - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}[hidden],template{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:700}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}@media print{*,:after,:before,:first-letter,blockquote:first-line,div:first-line,li:first-line,p:first-line{text-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.tag{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}@-ms-viewport{width:device-width}html{font-size:16px;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.5;color:#363a42;background-color:#fff}[tabindex="-1"]:focus{outline:none!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #f1f1f1}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#2fb5d2;text-decoration:none}a:focus,a:hover{color:#208094;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:not([href]):not([tabindex]),a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:none}pre{overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#7a7a7a;caption-side:bottom}caption,th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:700;line-height:1.1;color:inherit}.h1,h1{font-size:1.375rem}.h2,h2{font-size:1.25rem}.h3,.h4,h3,h4{font-size:1.125rem}.h5,h5{font-size:1rem}.h6,h6{font-size:.9375rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:3.125rem;font-weight:600}.display-2{font-size:2.188rem;font-weight:400}.display-3{font-size:1.563rem;font-weight:400}.display-4{font-size:1.25rem;font-weight:400}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:5px}.initialism{font-size:90%;text-transform:uppercase}.blockquote{padding:.5rem 1rem;margin-bottom:1rem;font-size:1.25rem;border-left:.25rem solid #f6f6f6}.blockquote-footer{display:block;font-size:80%;color:#f1f1f1}.blockquote-footer:before{content:"\2014 \A0"}.blockquote-reverse{padding-right:1rem;padding-left:0;text-align:right;border-right:.25rem solid #f6f6f6;border-left:0}.blockquote-reverse .blockquote-footer:before{content:""}.blockquote-reverse .blockquote-footer:after{content:"\A0 \2014"}dl.row>dd+dt{clear:left}.carousel-inner>.carousel-item>a>img,.carousel-inner>.carousel-item>img,.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #ddd;border-radius:0;transition:all .2s ease-in-out}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#f1f1f1}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}code{color:#bd4147;background-color:#f7f7f9;border-radius:0}code,kbd{padding:.2rem .4rem;font-size:90%}kbd{color:#fff;background-color:#333;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;margin-top:0;margin-bottom:1rem;font-size:90%;color:#363a42}pre code{padding:0;font-size:inherit;color:inherit;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.container:after{content:"";display:table;clear:both}@media (min-width:576px){.container{width:540px;max-width:100%}}@media (min-width:768px){.container{width:720px;max-width:100%}}@media (min-width:992px){.container{width:960px;max-width:100%}}@media (min-width:1200px){.container{width:1140px;max-width:100%}}.container-fluid{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.container-fluid:after{content:"";display:table;clear:both}.row{margin-right:-15px;margin-left:-15px}.row:after{content:"";display:table;clear:both}@media (min-width:576px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:768px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:992px){.row{margin-right:-15px;margin-left:-15px}}@media (min-width:1200px){.row{margin-right:-15px;margin-left:-15px}}.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}@media (min-width:576px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-right:15px;padding-left:15px}}@media (min-width:768px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-right:15px;padding-left:15px}}@media (min-width:992px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-right:15px;padding-left:15px}}@media (min-width:1200px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-right:15px;padding-left:15px}}.col-xs-1{float:left;width:8.33333%}.col-xs-2{float:left;width:16.66667%}.col-xs-3{float:left;width:25%}.col-xs-4{float:left;width:33.33333%}.col-xs-5{float:left;width:41.66667%}.col-xs-6{float:left;width:50%}.col-xs-7{float:left;width:58.33333%}.col-xs-8{float:left;width:66.66667%}.col-xs-9{float:left;width:75%}.col-xs-10{float:left;width:83.33333%}.col-xs-11{float:left;width:91.66667%}.col-xs-12{float:left;width:100%}.pull-xs-0{right:auto}.pull-xs-1{right:8.33333%}.pull-xs-2{right:16.66667%}.pull-xs-3{right:25%}.pull-xs-4{right:33.33333%}.pull-xs-5{right:41.66667%}.pull-xs-6{right:50%}.pull-xs-7{right:58.33333%}.pull-xs-8{right:66.66667%}.pull-xs-9{right:75%}.pull-xs-10{right:83.33333%}.pull-xs-11{right:91.66667%}.pull-xs-12{right:100%}.push-xs-0{left:auto}.push-xs-1{left:8.33333%}.push-xs-2{left:16.66667%}.push-xs-3{left:25%}.push-xs-4{left:33.33333%}.push-xs-5{left:41.66667%}.push-xs-6{left:50%}.push-xs-7{left:58.33333%}.push-xs-8{left:66.66667%}.push-xs-9{left:75%}.push-xs-10{left:83.33333%}.push-xs-11{left:91.66667%}.push-xs-12{left:100%}.offset-xs-1{margin-left:8.33333%}.offset-xs-2{margin-left:16.66667%}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:33.33333%}.offset-xs-5{margin-left:41.66667%}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:58.33333%}.offset-xs-8{margin-left:66.66667%}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:83.33333%}.offset-xs-11{margin-left:91.66667%}@media (min-width:576px){.col-sm-1{float:left;width:8.33333%}.col-sm-2{float:left;width:16.66667%}.col-sm-3{float:left;width:25%}.col-sm-4{float:left;width:33.33333%}.col-sm-5{float:left;width:41.66667%}.col-sm-6{float:left;width:50%}.col-sm-7{float:left;width:58.33333%}.col-sm-8{float:left;width:66.66667%}.col-sm-9{float:left;width:75%}.col-sm-10{float:left;width:83.33333%}.col-sm-11{float:left;width:91.66667%}.col-sm-12{float:left;width:100%}.pull-sm-0{right:auto}.pull-sm-1{right:8.33333%}.pull-sm-2{right:16.66667%}.pull-sm-3{right:25%}.pull-sm-4{right:33.33333%}.pull-sm-5{right:41.66667%}.pull-sm-6{right:50%}.pull-sm-7{right:58.33333%}.pull-sm-8{right:66.66667%}.pull-sm-9{right:75%}.pull-sm-10{right:83.33333%}.pull-sm-11{right:91.66667%}.pull-sm-12{right:100%}.push-sm-0{left:auto}.push-sm-1{left:8.33333%}.push-sm-2{left:16.66667%}.push-sm-3{left:25%}.push-sm-4{left:33.33333%}.push-sm-5{left:41.66667%}.push-sm-6{left:50%}.push-sm-7{left:58.33333%}.push-sm-8{left:66.66667%}.push-sm-9{left:75%}.push-sm-10{left:83.33333%}.push-sm-11{left:91.66667%}.push-sm-12{left:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md-1{float:left;width:8.33333%}.col-md-2{float:left;width:16.66667%}.col-md-3{float:left;width:25%}.col-md-4{float:left;width:33.33333%}.col-md-5{float:left;width:41.66667%}.col-md-6{float:left;width:50%}.col-md-7{float:left;width:58.33333%}.col-md-8{float:left;width:66.66667%}.col-md-9{float:left;width:75%}.col-md-10{float:left;width:83.33333%}.col-md-11{float:left;width:91.66667%}.col-md-12{float:left;width:100%}.pull-md-0{right:auto}.pull-md-1{right:8.33333%}.pull-md-2{right:16.66667%}.pull-md-3{right:25%}.pull-md-4{right:33.33333%}.pull-md-5{right:41.66667%}.pull-md-6{right:50%}.pull-md-7{right:58.33333%}.pull-md-8{right:66.66667%}.pull-md-9{right:75%}.pull-md-10{right:83.33333%}.pull-md-11{right:91.66667%}.pull-md-12{right:100%}.push-md-0{left:auto}.push-md-1{left:8.33333%}.push-md-2{left:16.66667%}.push-md-3{left:25%}.push-md-4{left:33.33333%}.push-md-5{left:41.66667%}.push-md-6{left:50%}.push-md-7{left:58.33333%}.push-md-8{left:66.66667%}.push-md-9{left:75%}.push-md-10{left:83.33333%}.push-md-11{left:91.66667%}.push-md-12{left:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg-1{float:left;width:8.33333%}.col-lg-2{float:left;width:16.66667%}.col-lg-3{float:left;width:25%}.col-lg-4{float:left;width:33.33333%}.col-lg-5{float:left;width:41.66667%}.col-lg-6{float:left;width:50%}.col-lg-7{float:left;width:58.33333%}.col-lg-8{float:left;width:66.66667%}.col-lg-9{float:left;width:75%}.col-lg-10{float:left;width:83.33333%}.col-lg-11{float:left;width:91.66667%}.col-lg-12{float:left;width:100%}.pull-lg-0{right:auto}.pull-lg-1{right:8.33333%}.pull-lg-2{right:16.66667%}.pull-lg-3{right:25%}.pull-lg-4{right:33.33333%}.pull-lg-5{right:41.66667%}.pull-lg-6{right:50%}.pull-lg-7{right:58.33333%}.pull-lg-8{right:66.66667%}.pull-lg-9{right:75%}.pull-lg-10{right:83.33333%}.pull-lg-11{right:91.66667%}.pull-lg-12{right:100%}.push-lg-0{left:auto}.push-lg-1{left:8.33333%}.push-lg-2{left:16.66667%}.push-lg-3{left:25%}.push-lg-4{left:33.33333%}.push-lg-5{left:41.66667%}.push-lg-6{left:50%}.push-lg-7{left:58.33333%}.push-lg-8{left:66.66667%}.push-lg-9{left:75%}.push-lg-10{left:83.33333%}.push-lg-11{left:91.66667%}.push-lg-12{left:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl-1{float:left;width:8.33333%}.col-xl-2{float:left;width:16.66667%}.col-xl-3{float:left;width:25%}.col-xl-4{float:left;width:33.33333%}.col-xl-5{float:left;width:41.66667%}.col-xl-6{float:left;width:50%}.col-xl-7{float:left;width:58.33333%}.col-xl-8{float:left;width:66.66667%}.col-xl-9{float:left;width:75%}.col-xl-10{float:left;width:83.33333%}.col-xl-11{float:left;width:91.66667%}.col-xl-12{float:left;width:100%}.pull-xl-0{right:auto}.pull-xl-1{right:8.33333%}.pull-xl-2{right:16.66667%}.pull-xl-3{right:25%}.pull-xl-4{right:33.33333%}.pull-xl-5{right:41.66667%}.pull-xl-6{right:50%}.pull-xl-7{right:58.33333%}.pull-xl-8{right:66.66667%}.pull-xl-9{right:75%}.pull-xl-10{right:83.33333%}.pull-xl-11{right:91.66667%}.pull-xl-12{right:100%}.push-xl-0{left:auto}.push-xl-1{left:8.33333%}.push-xl-2{left:16.66667%}.push-xl-3{left:25%}.push-xl-4{left:33.33333%}.push-xl-5{left:41.66667%}.push-xl-6{left:50%}.push-xl-7{left:58.33333%}.push-xl-8{left:66.66667%}.push-xl-9{left:75%}.push-xl-10{left:83.33333%}.push-xl-11{left:91.66667%}.push-xl-12{left:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;max-width:100%;margin-bottom:1rem}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #f6f6f6}.table thead th{vertical-align:bottom;border-bottom:2px solid #f6f6f6}.table tbody+tbody{border-top:2px solid #f6f6f6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #f6f6f6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th,.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-success,.table-success>td,.table-success>th{background-color:#dff0d8}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#d0e9c6}.table-info,.table-info>td,.table-info>th{background-color:#d9edf7}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c4e3f3}.table-warning,.table-warning>td,.table-warning>th{background-color:#fcf8e3}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#faf2cc}.table-danger,.table-danger>td,.table-danger>th{background-color:#f2dede}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#ebcccc}.thead-inverse th{color:#fff;background-color:#363a42}.thead-default th{color:#7a7a7a;background-color:#f6f6f6}.table-inverse{color:#f6f6f6;background-color:#363a42}.table-inverse td,.table-inverse th,.table-inverse thead th{border-color:#7a7a7a}.table-inverse.table-bordered{border:0}.table-responsive{display:block;width:100%;min-height:0;overflow-x:auto}.table-reflow thead{float:left}.table-reflow tbody{display:block;white-space:nowrap}.table-reflow td,.table-reflow th{border-top:1px solid #f6f6f6;border-left:1px solid #f6f6f6}.table-reflow td:last-child,.table-reflow th:last-child{border-right:1px solid #f6f6f6}.table-reflow tbody:last-child tr:last-child td,.table-reflow tbody:last-child tr:last-child th,.table-reflow tfoot:last-child tr:last-child td,.table-reflow tfoot:last-child tr:last-child th,.table-reflow thead:last-child tr:last-child td,.table-reflow thead:last-child tr:last-child th{border-bottom:1px solid #f6f6f6}.table-reflow tr{float:left}.table-reflow tr td,.table-reflow tr th{display:block!important;border:1px solid #f6f6f6}.form-control{display:block;width:100%;padding:.5rem .75rem;font-size:1rem;line-height:1.25;background-color:#fff;background-image:none;background-clip:padding-box;border-radius:0}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#7a7a7a;border-color:#66afe9;outline:none}.form-control::-webkit-input-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999;opacity:1}.form-control::placeholder{color:#999;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#f6f6f6;opacity:1}.form-control:disabled{cursor:not-allowed}select.form-control:not([size]):not([multiple]){height:calc(2.5rem - 2px)}select.form-control:focus::-ms-value{color:#7a7a7a;background-color:#fff}.form-control-file,.form-control-range{display:block}.col-form-label{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0}.col-form-label-lg{padding-top:.75rem;padding-bottom:.75rem;font-size:.9375rem}.col-form-label-sm{padding-top:.25rem;padding-bottom:.25rem;font-size:.875rem}.col-form-legend{margin-bottom:0;font-size:1rem}.col-form-legend,.form-control-static{padding-top:.5rem;padding-bottom:.5rem}.form-control-static{line-height:1.25;border:solid transparent;border-width:1px 0}.form-control-static.form-control-lg,.form-control-static.form-control-sm,.input-group-lg>.form-control-static.form-control,.input-group-lg>.form-control-static.input-group-addon,.input-group-lg>.input-group-btn>.form-control-static.btn,.input-group-sm>.form-control-static.form-control,.input-group-sm>.form-control-static.input-group-addon,.input-group-sm>.input-group-btn>.form-control-static.btn{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-sm>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>select.input-group-addon:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:1.8125rem}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.input-group-lg>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>select.input-group-addon:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:2.75rem}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-check{position:relative;display:block;margin-bottom:.75rem}.form-check+.form-check{margin-top:-.25rem}.form-check.disabled .form-check-label{color:#7a7a7a;cursor:not-allowed}.form-check-label{padding-left:1.25rem;margin-bottom:0;cursor:pointer}.form-check-input{position:absolute;margin-top:.25rem;margin-left:-1.25rem}.form-check-input:only-child{position:static}.form-check-inline{position:relative;display:inline-block;padding-left:1.25rem;margin-bottom:0;vertical-align:middle;cursor:pointer}.form-check-inline+.form-check-inline{margin-left:.75rem}.form-check-inline.disabled{color:#7a7a7a;cursor:not-allowed}.form-control-feedback{margin-top:.25rem}.form-control-danger,.form-control-success,.form-control-warning{padding-right:2.25rem;background-repeat:no-repeat;background-position:center right .625rem;background-size:1.25rem 1.25rem}.has-success .custom-control,.has-success .form-check-inline,.has-success .form-check-label,.has-success .form-control-feedback,.has-success .form-control-label{color:#4cbb6c}.has-success .form-control{border-color:#4cbb6c}.has-success .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #96d7a9}.has-success .input-group-addon{color:#4cbb6c;border-color:#4cbb6c;background-color:#e0f3e5}.has-success .form-control-success{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#4cbb6c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E")}.has-warning .custom-control,.has-warning .form-check-inline,.has-warning .form-check-label,.has-warning .form-control-feedback,.has-warning .form-control-label{color:#ff9a52}.has-warning .form-control{border-color:#ff9a52}.has-warning .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ffd6b8}.has-warning .input-group-addon{color:#ff9a52;border-color:#ff9a52;background-color:#fff}.has-warning .form-control-warning{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#ff9a52' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E")}.has-danger .custom-control,.has-danger .form-check-inline,.has-danger .form-check-label,.has-danger .form-control-feedback,.has-danger .form-control-label{color:#ff4c4c}.has-danger .form-control{border-color:#ff4c4c}.has-danger .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ffb2b2}.has-danger .input-group-addon{color:#ff4c4c;border-color:#ff4c4c;background-color:#fff}.has-danger .form-control-danger{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#ff4c4c' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E")}@media (min-width:576px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;width:auto;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .form-check,.form-inline .form-control-label{margin-bottom:0;vertical-align:middle}.form-inline .form-check{display:inline-block;margin-top:0}.form-inline .form-check-label{padding-left:0}.form-inline .form-check-input{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.btn{display:inline-block;font-weight:400;line-height:1.25;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.5rem 1rem;font-size:1rem;border-radius:0}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0}.btn.disabled,.btn:disabled{cursor:not-allowed;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#2fb5d2;border-color:transparent}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#2592a9;border-color:transparent}.btn-primary.active,.btn-primary:active,.open>.btn-primary.dropdown-toggle{color:#fff;background-color:#2592a9;border-color:transparent;background-image:none}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.btn-primary.dropdown-toggle.focus,.open>.btn-primary.dropdown-toggle:focus,.open>.btn-primary.dropdown-toggle:hover{color:#fff;background-color:#1e788c;border-color:transparent}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary:disabled.focus,.btn-primary:disabled:focus,.btn-primary:disabled:hover{background-color:#2fb5d2;border-color:transparent}.btn-secondary,.btn-tertiary{color:#232323;background-color:#f6f6f6;border-color:transparent}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover,.btn-tertiary:focus,.btn-tertiary:hover,.focus.btn-tertiary{color:#232323;background-color:#ddd;border-color:transparent}.active.btn-tertiary,.btn-secondary.active,.btn-secondary:active,.btn-tertiary:active,.open>.btn-secondary.dropdown-toggle,.open>.dropdown-toggle.btn-tertiary{color:#232323;background-color:#ddd;border-color:transparent;background-image:none}.active.btn-tertiary:focus,.active.btn-tertiary:hover,.active.focus.btn-tertiary,.btn-secondary.active.focus,.btn-secondary.active:focus,.btn-secondary.active:hover,.btn-secondary:active.focus,.btn-secondary:active:focus,.btn-secondary:active:hover,.btn-tertiary:active.focus,.btn-tertiary:active:focus,.btn-tertiary:active:hover,.open>.btn-secondary.dropdown-toggle.focus,.open>.btn-secondary.dropdown-toggle:focus,.open>.btn-secondary.dropdown-toggle:hover,.open>.dropdown-toggle.btn-tertiary:focus,.open>.dropdown-toggle.btn-tertiary:hover,.open>.dropdown-toggle.focus.btn-tertiary{color:#232323;background-color:#cbcbcb;border-color:transparent}.btn-secondary.disabled.focus,.btn-secondary.disabled:focus,.btn-secondary.disabled:hover,.btn-secondary:disabled.focus,.btn-secondary:disabled:focus,.btn-secondary:disabled:hover,.btn-tertiary:disabled.focus,.btn-tertiary:disabled:focus,.btn-tertiary:disabled:hover,.disabled.btn-tertiary:focus,.disabled.btn-tertiary:hover,.disabled.focus.btn-tertiary{background-color:#f6f6f6;border-color:transparent}.btn-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#2aabd2}.btn-info.active,.btn-info:active,.open>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;border-color:#2aabd2;background-image:none}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.btn-info.dropdown-toggle.focus,.open>.btn-info.dropdown-toggle:focus,.open>.btn-info.dropdown-toggle:hover{color:#fff;background-color:#269abc;border-color:#1f7e9a}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info:disabled.focus,.btn-info:disabled:focus,.btn-info:disabled:hover{background-color:#5bc0de;border-color:#5bc0de}.btn-success{color:#fff;background-color:#4cbb6c;border-color:#4cbb6c}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#3a9a56;border-color:#389252}.btn-success.active,.btn-success:active,.open>.btn-success.dropdown-toggle{color:#fff;background-color:#3a9a56;border-color:#389252;background-image:none}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.btn-success.dropdown-toggle.focus,.open>.btn-success.dropdown-toggle:focus,.open>.btn-success.dropdown-toggle:hover{color:#fff;background-color:#318047;border-color:#256237}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success:disabled.focus,.btn-success:disabled:focus,.btn-success:disabled:hover{background-color:#4cbb6c;border-color:#4cbb6c}.btn-warning{color:#fff;background-color:#ff9a52;border-color:#ff9a52}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#fff;background-color:#ff7c1f;border-color:#ff7615}.btn-warning.active,.btn-warning:active,.open>.btn-warning.dropdown-toggle{color:#fff;background-color:#ff7c1f;border-color:#ff7615;background-image:none}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.btn-warning.dropdown-toggle.focus,.open>.btn-warning.dropdown-toggle:focus,.open>.btn-warning.dropdown-toggle:hover{color:#fff;background-color:#fa6800;border-color:#d25700}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning:disabled.focus,.btn-warning:disabled:focus,.btn-warning:disabled:hover{background-color:#ff9a52;border-color:#ff9a52}.btn-danger{color:#fff;background-color:#ff4c4c;border-color:#ff4c4c}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff1919;border-color:#ff0f0f}.btn-danger.active,.btn-danger:active,.open>.btn-danger.dropdown-toggle{color:#fff;background-color:#ff1919;border-color:#ff0f0f;background-image:none}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.btn-danger.dropdown-toggle.focus,.open>.btn-danger.dropdown-toggle:focus,.open>.btn-danger.dropdown-toggle:hover{color:#fff;background-color:#f40000;border-color:#c00}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger:disabled.focus,.btn-danger:disabled:focus,.btn-danger:disabled:hover{background-color:#ff4c4c;border-color:#ff4c4c}.btn-outline-primary{color:#2fb5d2;background-image:none;background-color:transparent;border-color:#2fb5d2}.btn-outline-primary.active,.btn-outline-primary.focus,.btn-outline-primary:active,.btn-outline-primary:focus,.btn-outline-primary:hover,.open>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#2fb5d2;border-color:#2fb5d2}.btn-outline-primary.active.focus,.btn-outline-primary.active:focus,.btn-outline-primary.active:hover,.btn-outline-primary:active.focus,.btn-outline-primary:active:focus,.btn-outline-primary:active:hover,.open>.btn-outline-primary.dropdown-toggle.focus,.open>.btn-outline-primary.dropdown-toggle:focus,.open>.btn-outline-primary.dropdown-toggle:hover{color:#fff;background-color:#1e788c;border-color:#175c6a}.btn-outline-primary.disabled.focus,.btn-outline-primary.disabled:focus,.btn-outline-primary.disabled:hover,.btn-outline-primary:disabled.focus,.btn-outline-primary:disabled:focus,.btn-outline-primary:disabled:hover{border-color:#83d3e4}.btn-outline-secondary{color:transparent;background-image:none;background-color:transparent;border-color:transparent}.btn-outline-secondary.active,.btn-outline-secondary.active.focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.active:hover,.btn-outline-secondary.focus,.btn-outline-secondary:active,.btn-outline-secondary:active.focus,.btn-outline-secondary:active:focus,.btn-outline-secondary:active:hover,.btn-outline-secondary:focus,.btn-outline-secondary:hover,.open>.btn-outline-secondary.dropdown-toggle,.open>.btn-outline-secondary.dropdown-toggle.focus,.open>.btn-outline-secondary.dropdown-toggle:focus,.open>.btn-outline-secondary.dropdown-toggle:hover{color:#fff;background-color:transparent;border-color:transparent}.btn-outline-secondary.disabled.focus,.btn-outline-secondary.disabled:focus,.btn-outline-secondary.disabled:hover,.btn-outline-secondary:disabled.focus,.btn-outline-secondary:disabled:focus,.btn-outline-secondary:disabled:hover{border-color:rgba(51,51,51,0)}.btn-outline-info{color:#5bc0de;background-image:none;background-color:transparent;border-color:#5bc0de}.btn-outline-info.active,.btn-outline-info.focus,.btn-outline-info:active,.btn-outline-info:focus,.btn-outline-info:hover,.open>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-info.active.focus,.btn-outline-info.active:focus,.btn-outline-info.active:hover,.btn-outline-info:active.focus,.btn-outline-info:active:focus,.btn-outline-info:active:hover,.open>.btn-outline-info.dropdown-toggle.focus,.open>.btn-outline-info.dropdown-toggle:focus,.open>.btn-outline-info.dropdown-toggle:hover{color:#fff;background-color:#269abc;border-color:#1f7e9a}.btn-outline-info.disabled.focus,.btn-outline-info.disabled:focus,.btn-outline-info.disabled:hover,.btn-outline-info:disabled.focus,.btn-outline-info:disabled:focus,.btn-outline-info:disabled:hover{border-color:#b0e1ef}.btn-outline-success{color:#4cbb6c;background-image:none;background-color:transparent;border-color:#4cbb6c}.btn-outline-success.active,.btn-outline-success.focus,.btn-outline-success:active,.btn-outline-success:focus,.btn-outline-success:hover,.open>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#4cbb6c;border-color:#4cbb6c}.btn-outline-success.active.focus,.btn-outline-success.active:focus,.btn-outline-success.active:hover,.btn-outline-success:active.focus,.btn-outline-success:active:focus,.btn-outline-success:active:hover,.open>.btn-outline-success.dropdown-toggle.focus,.open>.btn-outline-success.dropdown-toggle:focus,.open>.btn-outline-success.dropdown-toggle:hover{color:#fff;background-color:#318047;border-color:#256237}.btn-outline-success.disabled.focus,.btn-outline-success.disabled:focus,.btn-outline-success.disabled:hover,.btn-outline-success:disabled.focus,.btn-outline-success:disabled:focus,.btn-outline-success:disabled:hover{border-color:#96d7a9}.btn-outline-warning{color:#ff9a52;background-image:none;background-color:transparent;border-color:#ff9a52}.btn-outline-warning.active,.btn-outline-warning.focus,.btn-outline-warning:active,.btn-outline-warning:focus,.btn-outline-warning:hover,.open>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#ff9a52;border-color:#ff9a52}.btn-outline-warning.active.focus,.btn-outline-warning.active:focus,.btn-outline-warning.active:hover,.btn-outline-warning:active.focus,.btn-outline-warning:active:focus,.btn-outline-warning:active:hover,.open>.btn-outline-warning.dropdown-toggle.focus,.open>.btn-outline-warning.dropdown-toggle:focus,.open>.btn-outline-warning.dropdown-toggle:hover{color:#fff;background-color:#fa6800;border-color:#d25700}.btn-outline-warning.disabled.focus,.btn-outline-warning.disabled:focus,.btn-outline-warning.disabled:hover,.btn-outline-warning:disabled.focus,.btn-outline-warning:disabled:focus,.btn-outline-warning:disabled:hover{border-color:#ffd6b8}.btn-outline-danger{color:#ff4c4c;background-image:none;background-color:transparent;border-color:#ff4c4c}.btn-outline-danger.active,.btn-outline-danger.focus,.btn-outline-danger:active,.btn-outline-danger:focus,.btn-outline-danger:hover,.open>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#ff4c4c;border-color:#ff4c4c}.btn-outline-danger.active.focus,.btn-outline-danger.active:focus,.btn-outline-danger.active:hover,.btn-outline-danger:active.focus,.btn-outline-danger:active:focus,.btn-outline-danger:active:hover,.open>.btn-outline-danger.dropdown-toggle.focus,.open>.btn-outline-danger.dropdown-toggle:focus,.open>.btn-outline-danger.dropdown-toggle:hover{color:#fff;background-color:#f40000;border-color:#c00}.btn-outline-danger.disabled.focus,.btn-outline-danger.disabled:focus,.btn-outline-danger.disabled:hover,.btn-outline-danger:disabled.focus,.btn-outline-danger:disabled:focus,.btn-outline-danger:disabled:hover{border-color:#ffb2b2}.btn-link{font-weight:400;color:#2fb5d2;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link:disabled{background-color:transparent}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#208094;text-decoration:underline;background-color:transparent}.btn-link:disabled:focus,.btn-link:disabled:hover{color:#f1f1f1;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{height:0;overflow:hidden;transition-timing-function:ease;transition-duration:.35s;transition-property:height}.collapsing,.dropdown,.dropup{position:relative}.dropdown-toggle:after{display:inline-block;width:0;height:0;margin-left:.3em;vertical-align:middle;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-left:.3em solid transparent}.dropdown-toggle:focus{outline:0}.dropup .dropdown-toggle:after{border-top:0;border-bottom:.3em solid}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#363a42;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:0}.dropdown-divider{height:1px;margin:.5rem 0;overflow:hidden;background-color:#e5e5e5}.dropdown-item{display:block;width:100%;padding:3px 1.5rem;clear:both;font-weight:400;color:#363a42;text-align:inherit;white-space:nowrap;background:none;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#2b2e34;background-color:#f5f5f5}.dropdown-item.active,.dropdown-item.active:focus,.dropdown-item.active:hover{color:#fff;text-decoration:none;background-color:#2fb5d2;outline:0}.dropdown-item.disabled,.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{color:#f1f1f1}.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:"progid:DXImageTransform.Microsoft.gradient(enabled = false)"}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#f1f1f1;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:.3em solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:.125rem}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left;margin-bottom:0}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-.5rem}.btn-toolbar:after{content:"";display:table;clear:both}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:.5rem}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn+.dropdown-toggle-split:after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:1.125rem;padding-left:1.125rem}.btn .caret{margin-left:0}.btn-group-lg>.btn .caret,.btn-lg .caret{border-width:.3em .3em 0;border-bottom-width:0}.dropup .btn-group-lg>.btn .caret,.dropup .btn-lg .caret{border-width:0 .3em .3em}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:after{content:"";display:table;clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;width:100%;display:table;border-collapse:separate}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:active,.input-group .form-control:focus,.input-group .form-control:hover{z-index:3}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#7a7a7a;text-align:center;background-color:#f6f6f6;border:1px solid rgba(0,0,0,.25);border-radius:0}.input-group-addon.form-control-sm,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.input-group-addon.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-addon.form-control-lg,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.input-group-addon.btn{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group-addon:not(:last-child),.input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group>.btn,.input-group-btn:not(:last-child)>.dropdown-toggle,.input-group .form-control:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:not(:last-child){border-right:0}.input-group-addon:not(:first-child),.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group>.btn,.input-group-btn:not(:first-child)>.dropdown-toggle,.input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.input-group-btn:not(:last-child)>.btn:not(:first-child),.input-group .form-control:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.form-control+.input-group-addon:not(:first-child){border-left:0}.input-group-btn{font-size:0;white-space:nowrap}.input-group-btn,.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:3}.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group{margin-right:-1px}.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-left:-1px}.input-group-btn:not(:first-child)>.btn-group:active,.input-group-btn:not(:first-child)>.btn-group:focus,.input-group-btn:not(:first-child)>.btn-group:hover,.input-group-btn:not(:first-child)>.btn:active,.input-group-btn:not(:first-child)>.btn:focus,.input-group-btn:not(:first-child)>.btn:hover{z-index:3}.custom-control{position:relative;display:inline-block;padding-left:1.5rem;cursor:pointer}.custom-control+.custom-control{margin-left:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-indicator{color:#fff;background-color:#0074d9}.custom-control-input:focus~.custom-control-indicator{box-shadow:0 0 0 .075rem #fff,0 0 0 .2rem #0074d9}.custom-control-input:active~.custom-control-indicator{color:#fff;background-color:#84c6ff}.custom-control-input:disabled~.custom-control-indicator{cursor:not-allowed;background-color:#eee}.custom-control-input:disabled~.custom-control-description{color:#767676;cursor:not-allowed}.custom-control-indicator{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#ddd;background-repeat:no-repeat;background-position:50%;background-size:50% 50%}.custom-checkbox .custom-control-indicator{border-radius:0}.custom-checkbox .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-indicator{background-color:#0074d9;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-radio .custom-control-indicator{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#fff'/%3E%3C/svg%3E")}.custom-controls-stacked .custom-control{float:left;clear:left}.custom-controls-stacked .custom-control+.custom-control{margin-left:0}.custom-select{display:inline-block;max-width:100%;height:calc(2.5rem - 2px);padding:.375rem 1.75rem .375rem .75rem;padding-right:.75rem\9;color:#7a7a7a;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-image:none\9;background-size:8px 10px;border:1px solid rgba(0,0,0,.25);border-radius:0;-moz-appearance:none;-webkit-appearance:none}.custom-select:focus{border-color:#51a7e8;outline:none}.custom-select:focus::-ms-value{color:#7a7a7a;background-color:#fff}.custom-select:disabled{color:#f1f1f1;cursor:not-allowed;background-color:#f6f6f6}.custom-select::-ms-expand{opacity:0}.custom-select-sm{padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-file{position:relative;display:inline-block;max-width:100%;height:2.5rem;cursor:pointer}.custom-file-input{min-width:14rem;max-width:100%;margin:0;filter:alpha(opacity=0);opacity:0}.custom-file-control{position:absolute;top:0;right:0;left:0;z-index:5;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#555;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;border:1px solid #ddd;border-radius:0}.custom-file-control:lang(en):after{content:"Choose file..."}.custom-file-control:before{position:absolute;top:-1px;right:-1px;bottom:-1px;z-index:6;display:block;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#555;background-color:#eee;border:1px solid #ddd;border-radius:0 0 0 0}.custom-file-control:lang(en):before{content:"Browse"}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:inline-block}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#f1f1f1}.nav-link.disabled,.nav-link.disabled:focus,.nav-link.disabled:hover{color:#f1f1f1;cursor:not-allowed;background-color:transparent}.nav-inline .nav-item{display:inline-block}.nav-inline .nav-item+.nav-item,.nav-inline .nav-link+.nav-link{margin-left:1rem}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs:after{content:"";display:table;clear:both}.nav-tabs .nav-item{float:left;margin-bottom:-1px}.nav-tabs .nav-item+.nav-item{margin-left:.2rem}.nav-tabs .nav-link{display:block;padding:.5em 1em;border:1px solid transparent;border-top-right-radius:0;border-top-left-radius:0}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#f6f6f6 #f6f6f6 #ddd}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link.disabled:focus,.nav-tabs .nav-link.disabled:hover{color:#f1f1f1;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#7a7a7a;background-color:#fff;border-color:#ddd #ddd transparent}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.nav-pills:after{content:"";display:table;clear:both}.nav-pills .nav-item{float:left}.nav-pills .nav-item+.nav-item{margin-left:.2rem}.nav-pills .nav-link{display:block;padding:.5em 1em;border-radius:0}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover{color:#fff;cursor:default;background-color:#2fb5d2}.nav-stacked .nav-item{display:block;float:none}.nav-stacked .nav-item+.nav-item{margin-top:.2rem;margin-left:0}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem 1rem}.navbar:after{content:"";display:table;clear:both}@media (min-width:576px){.navbar{border-radius:0}}.navbar-full{z-index:1000}@media (min-width:576px){.navbar-full{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:576px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0}.navbar-fixed-bottom{bottom:0}.navbar-sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1030;width:100%}@media (min-width:576px){.navbar-sticky-top{border-radius:0}}.navbar-brand{float:left;padding-top:.25rem;padding-bottom:.25rem;margin-right:1rem;font-size:.9375rem;line-height:inherit}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-divider{float:left;width:1px;padding-top:.425rem;padding-bottom:.425rem;margin-right:1rem;margin-left:1rem;overflow:hidden}.navbar-divider:before{content:"\A0"}.navbar-text{display:inline-block;padding-top:.425rem;padding-bottom:.425rem}.navbar-toggler{width:2.5em;height:2em;padding:.5rem .75rem;font-size:.9375rem;line-height:1;background:transparent no-repeat 50%;background-size:24px 24px;border:1px solid transparent;border-radius:0}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}@media (max-width:575px){.navbar-toggleable-xs .navbar-brand{display:block;float:none;margin-top:.5rem;margin-right:0}.navbar-toggleable-xs .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-xs .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:576px){.navbar-toggleable-xs{display:block}}@media (max-width:767px){.navbar-toggleable-sm .navbar-brand{display:block;float:none;margin-top:.5rem;margin-right:0}.navbar-toggleable-sm .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-sm .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:768px){.navbar-toggleable-sm{display:block}}@media (max-width:991px){.navbar-toggleable-md .navbar-brand{display:block;float:none;margin-top:.5rem;margin-right:0}.navbar-toggleable-md .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-md .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:992px){.navbar-toggleable-md{display:block}}.navbar-toggleable-lg:after{content:"";display:table;clear:both}@media (max-width:1199px){.navbar-toggleable-lg .navbar-brand{display:block;float:none;margin-top:.5rem;margin-right:0}.navbar-toggleable-lg .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-lg .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:1200px){.navbar-toggleable-lg{display:block}}.navbar-toggleable-xl{display:block}.navbar-toggleable-xl:after{content:"";display:table;clear:both}.navbar-toggleable-xl .navbar-brand{display:block;float:none;margin-top:.5rem;margin-right:0}.navbar-toggleable-xl .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-xl .navbar-nav .dropdown-menu{position:static;float:none}.navbar-nav .nav-item{float:left}.navbar-nav .nav-link{display:block;padding-top:.425rem;padding-bottom:.425rem}.navbar-nav .nav-item+.nav-item,.navbar-nav .nav-link+.nav-link{margin-left:1rem}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover,.navbar-light .navbar-toggler,.navbar-light .navbar-toggler:focus,.navbar-light .navbar-toggler:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .active>.nav-link:focus,.navbar-light .navbar-nav .active>.nav-link:hover,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.active:focus,.navbar-light .navbar-nav .nav-link.active:hover,.navbar-light .navbar-nav .nav-link.open,.navbar-light .navbar-nav .nav-link.open:focus,.navbar-light .navbar-nav .nav-link.open:hover,.navbar-light .navbar-nav .open>.nav-link,.navbar-light .navbar-nav .open>.nav-link:focus,.navbar-light .navbar-nav .open>.nav-link:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");border-color:rgba(0,0,0,.1)}.navbar-light .navbar-divider{background-color:rgba(0,0,0,.075)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-toggler,.navbar-dark .navbar-toggler:focus,.navbar-dark .navbar-toggler:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .active>.nav-link:focus,.navbar-dark .navbar-nav .active>.nav-link:hover,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.active:focus,.navbar-dark .navbar-nav .nav-link.active:hover,.navbar-dark .navbar-nav .nav-link.open,.navbar-dark .navbar-nav .nav-link.open:focus,.navbar-dark .navbar-nav .nav-link.open:hover,.navbar-dark .navbar-nav .open>.nav-link,.navbar-dark .navbar-nav .open>.nav-link:focus,.navbar-dark .navbar-nav .open>.nav-link:hover{color:#fff}.navbar-dark .navbar-toggler{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-divider{background-color:hsla(0,0%,100%,.075)}.navbar-toggleable-xs:after{content:"";display:table;clear:both}@media (max-width:575px){.navbar-toggleable-xs .navbar-nav .nav-item{float:none;margin-left:0}}@media (min-width:576px){.navbar-toggleable-xs{display:block!important}}.navbar-toggleable-sm:after{content:"";display:table;clear:both}@media (max-width:767px){.navbar-toggleable-sm .navbar-nav .nav-item{float:none;margin-left:0}}@media (min-width:768px){.navbar-toggleable-sm{display:block!important}}.navbar-toggleable-md:after{content:"";display:table;clear:both}@media (max-width:991px){.navbar-toggleable-md .navbar-nav .nav-item{float:none;margin-left:0}}@media (min-width:992px){.navbar-toggleable-md{display:block!important}}.card{position:relative;display:block;margin-bottom:.75rem;background-color:#fff;border-radius:0;border:1px solid rgba(0,0,0,.125)}.card-block{padding:1.25rem}.card-block:after{content:"";display:table;clear:both}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card>.list-group:first-child .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#f5f5f5;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:after{content:"";display:table;clear:both}.card-header:first-child{border-radius:-1px -1px 0 0}.card-footer{padding:.75rem 1.25rem;background-color:#f5f5f5;border-top:1px solid rgba(0,0,0,.125)}.card-footer:after{content:"";display:table;clear:both}.card-footer:last-child{border-radius:0 0 -1px -1px}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-primary{background-color:#2fb5d2;border-color:#2fb5d2}.card-primary .card-footer,.card-primary .card-header{background-color:transparent}.card-success{background-color:#4cbb6c;border-color:#4cbb6c}.card-success .card-footer,.card-success .card-header{background-color:transparent}.card-info{background-color:#5bc0de;border-color:#5bc0de}.card-info .card-footer,.card-info .card-header{background-color:transparent}.card-warning{background-color:#ff9a52;border-color:#ff9a52}.card-warning .card-footer,.card-warning .card-header{background-color:transparent}.card-danger{background-color:#ff4c4c;border-color:#ff4c4c}.card-danger .card-footer,.card-danger .card-header,.card-outline-primary{background-color:transparent}.card-outline-primary{border-color:#2fb5d2}.card-outline-secondary{background-color:transparent;border-color:transparent}.card-outline-info{background-color:transparent;border-color:#5bc0de}.card-outline-success{background-color:transparent;border-color:#4cbb6c}.card-outline-warning{background-color:transparent;border-color:#ff9a52}.card-outline-danger{background-color:transparent;border-color:#ff4c4c}.card-inverse .card-footer,.card-inverse .card-header{border-color:hsla(0,0%,100%,.2)}.card-inverse .card-blockquote,.card-inverse .card-footer,.card-inverse .card-header,.card-inverse .card-title{color:#fff}.card-inverse .card-blockquote .blockquote-footer,.card-inverse .card-link,.card-inverse .card-subtitle,.card-inverse .card-text{color:hsla(0,0%,100%,.65)}.card-inverse .card-link:focus,.card-inverse .card-link:hover{color:#fff}.card-blockquote{padding:0;margin-bottom:0;border-left:0}.card-img{border-radius:-1px}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img-top{border-top-right-radius:-1px;border-top-left-radius:-1px}.card-img-bottom{border-bottom-right-radius:-1px;border-bottom-left-radius:-1px}@media (min-width:576px){.card-deck{display:table;width:100%;margin-bottom:.75rem;table-layout:fixed;border-spacing:1.25rem 0}.card-deck .card{display:table-cell;margin-bottom:0;vertical-align:top}.card-deck-wrapper{margin-right:-1.25rem;margin-left:-1.25rem}}@media (min-width:576px){.card-group{display:table;width:100%;table-layout:fixed}.card-group .card{display:table-cell;vertical-align:top}.card-group .card+.card{margin-left:0;border-left:0}.card-group .card:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.card-group .card:first-child .card-img-top{border-top-right-radius:0}.card-group .card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group .card:last-child{border-bottom-left-radius:0;border-top-left-radius:0}.card-group .card:last-child .card-img-top{border-top-left-radius:0}.card-group .card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group .card:not(:first-child):not(:last-child),.card-group .card:not(:first-child):not(:last-child) .card-img-bottom,.card-group .card:not(:first-child):not(:last-child) .card-img-top{border-radius:0}}@media (min-width:576px){.card-columns{-webkit-column-count:3;column-count:3;-webkit-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#f6f6f6;border-radius:0}.breadcrumb:after{content:"";display:table;clear:both}.breadcrumb-item{float:left}.breadcrumb-item+.breadcrumb-item:before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#f1f1f1;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#f1f1f1}.pagination{display:inline-block;padding-left:0;margin-top:1rem;margin-bottom:1rem;border-radius:0}.page-item{display:inline}.page-item:first-child .page-link{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.page-item:last-child .page-link{border-bottom-right-radius:0;border-top-right-radius:0}.page-item.active .page-link,.page-item.active .page-link:focus,.page-item.active .page-link:hover{z-index:2;color:#fff;cursor:default;background-color:#2fb5d2;border-color:#2fb5d2}.page-item.disabled .page-link,.page-item.disabled .page-link:focus,.page-item.disabled .page-link:hover{color:#f1f1f1;pointer-events:none;cursor:not-allowed;background-color:#fff;border-color:#ddd}.page-link{position:relative;float:left;padding:.5rem .75rem;margin-left:-1px;color:#2fb5d2;text-decoration:none;background-color:#fff;border:1px solid #ddd}.page-link:focus,.page-link:hover{color:#208094;background-color:#f6f6f6;border-color:#ddd}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.pagination-sm .page-link{padding:.275rem .75rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.tag{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:0}.tag:empty{display:none}.btn .tag{position:relative;top:-1px}a.tag:focus,a.tag:hover{color:#fff;text-decoration:none;cursor:pointer}.tag-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.tag-default{background-color:#f1f1f1}.tag-default[href]:focus,.tag-default[href]:hover{background-color:#d8d8d8}.tag-primary{background-color:#2fb5d2}.tag-primary[href]:focus,.tag-primary[href]:hover{background-color:#2592a9}.tag-success{background-color:#4cbb6c}.tag-success[href]:focus,.tag-success[href]:hover{background-color:#3a9a56}.tag-info{background-color:#5bc0de}.tag-info[href]:focus,.tag-info[href]:hover{background-color:#31b0d5}.tag-warning{background-color:#ff9a52}.tag-warning[href]:focus,.tag-warning[href]:hover{background-color:#ff7c1f}.tag-danger{background-color:#ff4c4c}.tag-danger[href]:focus,.tag-danger[href]:hover{background-color:#ff1919}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#f6f6f6;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-hr{border-top-color:#ddd}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:2.5rem}.alert-dismissible .close{position:relative;top:-.125rem;right:-1.25rem;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d0e9c6;color:#3c763d}.alert-success hr{border-top-color:#c1e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bcdff1;color:#31708f}.alert-info hr{border-top-color:#a6d5ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:rgba(255,154,82,.3);border-color:#ff9a52;color:#232323}.alert-warning hr{border-top-color:#ff8b39}.alert-warning .alert-link{color:#0a0a0a}.alert-danger{background-color:#f2dede;border-color:#ebcccc;color:#a94442}.alert-danger hr{border-top-color:#e4b9b9}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{display:block;width:100%;height:1rem;margin-bottom:1rem}.progress[value]{background-color:#eee;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}.progress[value]::-ms-fill{background-color:#0074d9;border:0}.progress[value]::-moz-progress-bar{background-color:#0074d9;border-bottom-left-radius:0;border-top-left-radius:0}.progress[value]::-webkit-progress-value{background-color:#0074d9;border-bottom-left-radius:0;border-top-left-radius:0}.progress[value="100"]::-moz-progress-bar{border-bottom-right-radius:0;border-top-right-radius:0}.progress[value="100"]::-webkit-progress-value{border-bottom-right-radius:0;border-top-right-radius:0}.progress[value]::-webkit-progress-bar{background-color:#eee;border-radius:0}.progress[value],base::-moz-progress-bar{background-color:#eee;border-radius:0}@media screen and (min-width:0\0){.progress{background-color:#eee;border-radius:0}.progress-bar{display:inline-block;height:1rem;text-indent:-999rem;background-color:#0074d9;border-bottom-left-radius:0;border-top-left-radius:0}.progress[width="100%"]{border-bottom-right-radius:0;border-top-right-radius:0}}.progress-striped[value]::-webkit-progress-value{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-striped[value]::-moz-progress-bar{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-striped[value]::-ms-fill{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}@media screen and (min-width:0\0){.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}}.progress-animated[value]::-webkit-progress-value{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-animated[value]::-moz-progress-bar{animation:progress-bar-stripes 2s linear infinite}@media screen and (min-width:0\0){.progress-animated .progress-bar-striped{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}}.progress-success[value]::-webkit-progress-value{background-color:#4cbb6c}.progress-success[value]::-moz-progress-bar{background-color:#4cbb6c}.progress-success[value]::-ms-fill{background-color:#4cbb6c}@media screen and (min-width:0\0){.progress-success .progress-bar{background-color:#4cbb6c}}.progress-info[value]::-webkit-progress-value{background-color:#5bc0de}.progress-info[value]::-moz-progress-bar{background-color:#5bc0de}.progress-info[value]::-ms-fill{background-color:#5bc0de}@media screen and (min-width:0\0){.progress-info .progress-bar{background-color:#5bc0de}}.progress-warning[value]::-webkit-progress-value{background-color:#ff9a52}.progress-warning[value]::-moz-progress-bar{background-color:#ff9a52}.progress-warning[value]::-ms-fill{background-color:#ff9a52}@media screen and (min-width:0\0){.progress-warning .progress-bar{background-color:#ff9a52}}.progress-danger[value]::-webkit-progress-value{background-color:#ff4c4c}.progress-danger[value]::-moz-progress-bar{background-color:#ff4c4c}.progress-danger[value]::-ms-fill{background-color:#ff4c4c}@media screen and (min-width:0\0){.progress-danger .progress-bar{background-color:#ff4c4c}}.media,.media-body{overflow:hidden}.media-body{width:10000px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right{padding-left:10px}.media-left{padding-right:10px}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:0}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#f1f1f1;cursor:not-allowed;background-color:#f6f6f6}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#f1f1f1}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;text-decoration:none;background-color:#2fb5d2;border-color:#2fb5d2}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#d7f1f6}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-item-action{width:100%;color:#555;text-align:inherit}.list-group-item-action .list-group-item-heading{color:#333}.list-group-item-action:focus,.list-group-item-action:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9{padding-bottom:42.85714%}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.embed-responsive-1by1{padding-bottom:100%}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal,.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;outline:0}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translateY(-25%);transform:translateY(-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header:after{content:"";display:table;clear:both}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.5}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer:after{content:"";display:table;clear:both}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:600px;margin:30px auto}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.in{opacity:.9}.tooltip.bs-tether-element-attached-bottom,.tooltip.tooltip-top{padding:5px 0;margin-top:-3px}.tooltip.bs-tether-element-attached-bottom .tooltip-inner:before,.tooltip.tooltip-top .tooltip-inner:before{bottom:0;left:50%;margin-left:-5px;content:"";border-width:5px 5px 0;border-top-color:#ff4c4c}.tooltip.bs-tether-element-attached-left,.tooltip.tooltip-right{padding:0 5px;margin-left:3px}.tooltip.bs-tether-element-attached-left .tooltip-inner:before,.tooltip.tooltip-right .tooltip-inner:before{top:50%;left:0;margin-top:-5px;content:"";border-width:5px 5px 5px 0;border-right-color:#ff4c4c}.tooltip.bs-tether-element-attached-top,.tooltip.tooltip-bottom{padding:5px 0;margin-top:3px}.tooltip.bs-tether-element-attached-top .tooltip-inner:before,.tooltip.tooltip-bottom .tooltip-inner:before{top:0;left:50%;margin-left:-5px;content:"";border-width:0 5px 5px;border-bottom-color:#ff4c4c}.tooltip.bs-tether-element-attached-right,.tooltip.tooltip-left{padding:0 5px;margin-left:-3px}.tooltip.bs-tether-element-attached-right .tooltip-inner:before,.tooltip.tooltip-left .tooltip-inner:before{top:50%;right:0;margin-top:-5px;content:"";border-width:5px 0 5px 5px;border-left-color:#ff4c4c}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#ff4c4c;border-radius:0}.tooltip-inner:before{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;padding:1px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover.bs-tether-element-attached-bottom,.popover.popover-top{margin-top:-10px}.popover.bs-tether-element-attached-bottom:after,.popover.bs-tether-element-attached-bottom:before,.popover.popover-top:after,.popover.popover-top:before{left:50%;border-bottom-width:0}.popover.bs-tether-element-attached-bottom:before,.popover.popover-top:before{bottom:-11px;margin-left:-11px;border-top-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-bottom:after,.popover.popover-top:after{bottom:-10px;margin-left:-10px;border-top-color:#fff}.popover.bs-tether-element-attached-left,.popover.popover-right{margin-left:10px}.popover.bs-tether-element-attached-left:after,.popover.bs-tether-element-attached-left:before,.popover.popover-right:after,.popover.popover-right:before{top:50%;border-left-width:0}.popover.bs-tether-element-attached-left:before,.popover.popover-right:before{left:-11px;margin-top:-11px;border-right-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-left:after,.popover.popover-right:after{left:-10px;margin-top:-10px;border-right-color:#fff}.popover.bs-tether-element-attached-top,.popover.popover-bottom{margin-top:10px}.popover.bs-tether-element-attached-top:after,.popover.bs-tether-element-attached-top:before,.popover.popover-bottom:after,.popover.popover-bottom:before{left:50%;border-top-width:0}.popover.bs-tether-element-attached-top:before,.popover.popover-bottom:before{top:-11px;margin-left:-11px;border-bottom-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-top:after,.popover.popover-bottom:after{top:-10px;margin-left:-10px;border-bottom-color:#f7f7f7}.popover.bs-tether-element-attached-top .popover-title:before,.popover.popover-bottom .popover-title:before{position:absolute;top:0;left:50%;display:block;width:20px;margin-left:-10px;content:"";border-bottom:1px solid #f7f7f7}.popover.bs-tether-element-attached-right,.popover.popover-left{margin-left:-10px}.popover.bs-tether-element-attached-right:after,.popover.bs-tether-element-attached-right:before,.popover.popover-left:after,.popover.popover-left:before{top:50%;border-right-width:0}.popover.bs-tether-element-attached-right:before,.popover.popover-left:before{right:-11px;margin-top:-11px;border-left-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-right:after,.popover.popover-left:after{right:-10px;margin-top:-10px;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:.2375rem .2375rem 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover:after,.popover:before{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover:before{content:"";border-width:11px}.popover:after{content:"";border-width:10px}.carousel,.carousel-inner{position:relative}.carousel-inner{width:100%;overflow:hidden}.carousel-inner>.carousel-item{position:relative;display:none;transition:left .6s ease-in-out}.carousel-inner>.carousel-item>a>img,.carousel-inner>.carousel-item>img{line-height:1}@media (-webkit-transform-3d),(transform-3d){.carousel-inner>.carousel-item{transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.carousel-item.active.right,.carousel-inner>.carousel-item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.carousel-item.active.left,.carousel-inner>.carousel-item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.carousel-item.active,.carousel-inner>.carousel-item.next.left,.carousel-inner>.carousel-item.prev.right{left:0;-webkit-transform:translateZ(0);transform:translateZ(0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5}.carousel-control.left{background-image:linear-gradient(90deg,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001));background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80000000",endColorstr="#00000000",GradientType=1)}.carousel-control.right{right:0;left:auto;background-image:linear-gradient(90deg,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5));background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#80000000",GradientType=1)}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203A"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:transparent;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media (min-width:576px){.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .icon-prev{margin-left:-15px}.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-faded{background-color:#f7f7f9}.bg-primary{background-color:#2fb5d2!important}a.bg-primary:focus,a.bg-primary:hover{background-color:#2592a9!important}.bg-success{background-color:#4cbb6c!important}a.bg-success:focus,a.bg-success:hover{background-color:#3a9a56!important}.bg-info{background-color:#5bc0de!important}a.bg-info:focus,a.bg-info:hover{background-color:#31b0d5!important}.bg-warning{background-color:#ff9a52!important}a.bg-warning:focus,a.bg-warning:hover{background-color:#ff7c1f!important}.bg-danger{background-color:#ff4c4c!important}a.bg-danger:focus,a.bg-danger:hover{background-color:#ff1919!important}.bg-inverse{background-color:#363a42!important}a.bg-inverse:focus,a.bg-inverse:hover{background-color:#1f2126!important}.rounded{border-radius:0}.rounded-top{border-top-right-radius:0;border-top-left-radius:0}.rounded-right{border-bottom-right-radius:0;border-top-right-radius:0}.rounded-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.rounded-left{border-bottom-left-radius:0;border-top-left-radius:0}.rounded-circle{border-radius:50%}.clearfix:after{content:"";display:table;clear:both}.d-block{display:block!important}.d-inline-block{display:inline-block!important}.d-inline{display:inline!important}.float-xs-left{float:left!important}.float-xs-right{float:right!important}.float-xs-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.w-100{width:100%!important}.h-100{height:100%!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.mx-0{margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:1rem!important}.mt-1{margin-top:1rem!important}.mr-1{margin-right:1rem!important}.mb-1{margin-bottom:1rem!important}.ml-1,.mx-1{margin-left:1rem!important}.mx-1{margin-right:1rem!important}.my-1{margin-top:1rem!important;margin-bottom:1rem!important}.m-2{margin:1.5rem!important}.mt-2{margin-top:1.5rem!important}.mr-2{margin-right:1.5rem!important}.mb-2{margin-bottom:1.5rem!important}.ml-2,.mx-2{margin-left:1.5rem!important}.mx-2{margin-right:1.5rem!important}.my-2{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-3{margin:3rem!important}.mt-3{margin-top:3rem!important}.mr-3{margin-right:3rem!important}.mb-3{margin-bottom:3rem!important}.ml-3,.mx-3{margin-left:3rem!important}.mx-3{margin-right:3rem!important}.my-3{margin-top:3rem!important;margin-bottom:3rem!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.px-0{padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:1rem!important}.pt-1{padding-top:1rem!important}.pr-1{padding-right:1rem!important}.pb-1{padding-bottom:1rem!important}.pl-1,.px-1{padding-left:1rem!important}.px-1{padding-right:1rem!important}.py-1{padding-top:1rem!important;padding-bottom:1rem!important}.p-2{padding:1.5rem!important}.pt-2{padding-top:1.5rem!important}.pr-2{padding-right:1.5rem!important}.pb-2{padding-bottom:1.5rem!important}.pl-2,.px-2{padding-left:1.5rem!important}.px-2{padding-right:1.5rem!important}.py-2{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-3{padding:3rem!important}.pt-3{padding-top:3rem!important}.pr-3{padding-right:3rem!important}.pb-3{padding-bottom:3rem!important}.pl-3,.px-3{padding-left:3rem!important}.px-3{padding-right:3rem!important}.py-3{padding-top:3rem!important;padding-bottom:3rem!important}.pos-f-t{position:fixed;top:0;right:0;left:0;z-index:1030}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-xs-left{text-align:left!important}.text-xs-right{text-align:right!important}.text-xs-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:700}.font-italic{font-style:italic}.text-white{color:#fff!important}.text-muted{color:#7a7a7a!important}a.text-muted:focus,a.text-muted:hover{color:#616161!important}.text-primary{color:#2fb5d2!important}a.text-primary:focus,a.text-primary:hover{color:#2592a9!important}.text-success{color:#4cbb6c!important}a.text-success:focus,a.text-success:hover{color:#3a9a56!important}.text-info{color:#5bc0de!important}a.text-info:focus,a.text-info:hover{color:#31b0d5!important}.text-warning{color:#ff9a52!important}a.text-warning:focus,a.text-warning:hover{color:#ff7c1f!important}.text-danger{color:#ff4c4c!important}a.text-danger:focus,a.text-danger:hover{color:#ff1919!important}.text-gray-dark{color:#363a42!important}a.text-gray-dark:focus,a.text-gray-dark:hover{color:#1f2126!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.invisible{visibility:hidden!important}.hidden-xs-up{display:none!important}@media (max-width:575px){.hidden-xs-down{display:none!important}}@media (min-width:576px){.hidden-sm-up{display:none!important}}@media (max-width:767px){.hidden-sm-down{display:none!important}}@media (min-width:768px){.hidden-md-up{display:none!important}}@media (max-width:991px){.hidden-md-down{display:none!important}}@media (min-width:992px){.hidden-lg-up{display:none!important}}@media (max-width:1199px){.hidden-lg-down{display:none!important}}@media (min-width:1200px){.hidden-xl-up{display:none!important}}.hidden-xl-down,.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}@font-face{font-family:Noto Sans;src:url(../css/3d4a907b1b7a232654324a3dd7ae4aa3.eot);src:local("Noto Sans Regular"),local("NotoSans-Regular"),url(../css/3d4a907b1b7a232654324a3dd7ae4aa3.eot) format("embedded-opentype"),url(../css/19c1b868764c0e4d15a45d3f61250488.woff2) format("woff2"),url(../css/846c191efd3d0aacde5a916cf2ebf1a4.woff) format("woff"),url(../css/2fd9c16b805724d590c0cff96da070a4.ttf) format("truetype"),url(../css/5ea9fdf2293930126fa9c544968009ae.svg) format("svg");font-weight:400;font-style:normal}@font-face{font-family:Noto Sans;src:url(../css/eeb9224f85430652fd070e4e64129aa4.eot);src:local("Noto Sans Bold"),local("NotoSans-Bold"),url(../css/eeb9224f85430652fd070e4e64129aa4.eot) format("embedded-opentype"),url(../css/199038f07312bfc6f0aabd3ed6a2b64d.woff2) format("woff2"),url(../css/c2183257e7a697769df4200c547551f1.woff) format("woff"),url(../css/a165a42685795361b25593effb32fdb1.ttf) format("truetype"),url(../css/5dc400bcedda37b13f35cb44623193cf.svg) format("svg");font-weight:700;font-style:normal}@font-face{font-family:Noto Sans;src:url(../css/a77ade19de3d3762dfbf1fe553b293cc.eot);src:local("Noto Sans Italic"),local("NotoSans-Italic"),url(../css/a77ade19de3d3762dfbf1fe553b293cc.eot) format("embedded-opentype"),url(../css/7a3ebca0cba2e2c6090e84e1d77e0f94.woff2) format("woff2"),url(../css/332f555bb44cdc394d6c799df0c03389.woff) format("woff"),url(../css/154da4697acc779b55af0a67f1241e4e.ttf) format("truetype"),url(../css/3d34be670a7f15086e512282b97ae35e.svg) format("svg");font-weight:400;font-style:italic}@font-face{font-family:Noto Sans;src:url(../css/b467416c449eb823029e16347b2ea510.eot);src:local("Noto Sans BoldItalic"),local("NotoSans-BoldItalic"),url(../css/b467416c449eb823029e16347b2ea510.eot) format("embedded-opentype"),url(../css/a68cfe9d548950edf5df102269877edd.woff2) format("woff2"),url(../css/3f81521029cc8a9a703419c4a74704a0.woff) format("woff"),url(../css/4f6ff3639c1e5728b905b650c1a06e75.ttf) format("truetype"),url(../css/80e74ff9406650e53bbec1e292c2c094.svg) format("svg");font-weight:700;font-style:italic}@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(../css/e79bfd88537def476913f3ed52f4f4b3.eot);src:local("Material Icons"),local("MaterialIcons-Regular"),url(../css/570eb83859dc23dd0eec423a49e147fe.woff2) format("woff2"),url(../css/012cf6a10129e2275d79d6adac7f3b02.woff) format("woff"),url(../css/a37b0c01c0baf1888ca812cc0508f6e2.ttf) format("truetype")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;vertical-align:middle;width:1em;height:1em;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;-webkit-font-feature-settings:"liga";font-feature-settings:"liga"}body,html{height:100%}body{direction:ltr;font-family:Noto Sans,sans-serif;font-size:1rem;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#232323;line-height:1.25em}ul{list-style:none;padding-left:0}a:hover{color:#2fb5d2;text-decoration:none}p{font-size:.9375rem;color:#7a7a7a;font-weight:400}.color,.custom-checkbox input[type=checkbox]+span.color{width:1.25rem;height:1.25rem;display:inline-block;margin:.3125rem;box-shadow:2px 2px 4px 0 rgba(0,0,0,.2);border:1px solid rgba(0,0,0,.05);cursor:pointer;background-size:contain}.color.active,.color:hover,.custom-checkbox input[type=checkbox]+span.color.active,.custom-checkbox input[type=checkbox]+span.color:hover,.facet-label.active .custom-checkbox span.color,.facet-label:hover .custom-checkbox span.color{border:2px solid #232323}.h1,.h2,.h3{text-transform:uppercase;color:#232323}.h4{font-weight:700;color:#232323}.btn-primary,.btn-secondary,.btn-tertiary{box-shadow:2px 2px 4px 0 rgba(0,0,0,.2);text-transform:uppercase;font-weight:600;padding:.5rem 1.25rem}.btn-primary .material-icons,.btn-secondary .material-icons,.btn-tertiary .material-icons{margin-right:.625rem}.btn-tertiary{background-color:#f7f7f7;text-transform:lowercase;color:#7a7a7a;box-shadow:.0625rem .0625rem .0625rem 0 rgba(0,0,0,.1);padding:.25rem;margin:.25rem 0;font-weight:400;font-size:.875rem}.btn-tertiary .material-icons{font-size:1rem}.btn-tertiary:hover{box-shadow:.0625rem .0625rem .0625rem 0 rgba(0,0,0,.2);border:1px solid rgba(35,35,35,.2)}.btn-unstyle{background-color:transparent;border:none;padding:0;text-align:inherit}.btn-unstyle:focus{outline:0}.btn-unstyle:focus .expand-more{color:#2fb5d2}.card{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.label,label{color:#232323;text-align:right;font-size:.875rem}small.label,small.value{font-size:.8125rem}.form-control-label{padding-top:.625rem}.form-control{background:#f1f1f1;color:#7a7a7a;border:1px solid rgba(0,0,0,.25);padding:.5rem 1rem}.form-control:focus{background-color:#fff;color:#232323}.form-control:focus,.input-group.focus{outline:.1875rem solid #2fb5d2}.input-group .form-control:focus{outline:none}.input-group .input-group-btn{height:100%}.input-group .input-group-btn>.btn{border:0;box-shadow:none;color:#fff;font-size:.6875rem;font-weight:400;margin-left:0;padding:.625rem 1rem;text-transform:uppercase}.input-group .input-group-btn>.btn[data-action=show-password]{background:#7a7a7a;padding:.78rem 1rem}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#7a7a7a}input::-moz-placeholder,textarea::-moz-placeholder{color:#7a7a7a}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#7a7a7a}input:-moz-placeholder,textarea:-moz-placeholder{color:#7a7a7a}input:active::-webkit-input-placeholder,textarea:active::-webkit-input-placeholder{color:#232323}input:active::-moz-placeholder,textarea:active::-moz-placeholder{color:#232323}input:active:-ms-input-placeholder,textarea:active:-ms-input-placeholder{color:#232323}input:active:-moz-placeholder,textarea:active:-moz-placeholder{color:#232323}.form-control-select{height:2.625rem;-moz-appearance:none;-webkit-appearance:none;background:#f1f1f1 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAAAPklEQVR4Ae3TwREAEBQD0V/6do4SXPZg7EsBhsQ8IEmSMOsiuEfg3gL3oXC7wK0bd1G4o8X9F4yIkyQfSrIByQBjp7QuND8AAAAASUVORK5CYII=") no-repeat scroll right .5rem center/1.25rem 1.25rem;padding:0 .5rem}.form-control-valign{padding-top:.5rem}.form-control-comment{font-size:.875rem;padding-top:.5rem;color:#7a7a7a}.form-control-submit.disabled{background:#5bc0de;color:#fff}.form-group.has-error input,.form-group.has-error select{outline:.1875rem solid #ff4c4c}.form-group.has-error .help-block{color:#ff4c4c}.group-span-filestyle label{margin:0}.bootstrap-touchspin .group-span-filestyle .btn-touchspin,.group-span-filestyle .bootstrap-touchspin .btn-touchspin,.group-span-filestyle .btn-default{background:#2fb5d2;color:#fff;text-transform:uppercase;border-radius:0;font-size:.875rem;padding:.5rem 1rem}.bootstrap-touchspin{width:auto;float:left;display:inline-block;box-shadow:2px 2px 4px 0 rgba(0,0,0,.2)}.bootstrap-touchspin input:focus{outline:none}.bootstrap-touchspin input.form-control,.bootstrap-touchspin input.input-group{color:#232323;background-color:#fff;height:2.5rem;padding:.175rem .5rem;width:3rem;border:1px solid rgba(0,0,0,.25);float:left}.bootstrap-touchspin .btn-touchspin{background-color:#fff;border:1px solid rgba(0,0,0,.25);height:1.3125rem}.bootstrap-touchspin .btn-touchspin:hover{background-color:#f1f1f1}.bootstrap-touchspin .input-group-btn-vertical{color:#232323;width:auto;float:left}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down,.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0}.bootstrap-touchspin .input-group-btn-vertical .touchspin-up:after{content:"\E5CE"}.bootstrap-touchspin .input-group-btn-vertical .touchspin-down:after{content:"\E5CF"}.bootstrap-touchspin .input-group-btn-vertical i{top:.0625rem;left:.1875rem;font-size:.9375rem}.custom-radio{display:inline-block;position:relative;width:20px;height:20px;vertical-align:middle;cursor:pointer;border-radius:50%;border:2px solid #7a7a7a;background:#fff;margin-right:1.25rem}.custom-radio input[type=radio]{opacity:0;cursor:pointer}.custom-radio input[type=radio]:checked+span{display:block;background-color:#2fb5d2;width:12px;height:12px;border-radius:50%;position:absolute;left:.125rem;top:.125rem}.custom-radio input[type=radio]:focus+span{border-color:#7a7a7a}.custom-checkbox{position:relative}.custom-checkbox input[type=checkbox]{margin-top:.25rem;opacity:0;cursor:pointer;position:absolute}.custom-checkbox input[type=checkbox]+span{margin-right:3px;display:inline-block;width:.9375rem;height:.9375rem;vertical-align:middle;cursor:pointer;border:2px solid #232323}.custom-checkbox input[type=checkbox]+span .checkbox-checked{display:none;margin:-.25rem -.125rem;font-size:1.1rem;color:#232323}.custom-checkbox input[type=checkbox]:checked+span .checkbox-checked{display:block}.custom-checkbox input[type=checkbox]:focus+span{border-color:#7a7a7a}.custom-checkbox label{text-align:left}.text-muted{font-size:.875rem}.done{color:#4cbb6c;display:inline-block;padding:0 .8125rem;margin-right:1.563rem}.thumb-mask>.mask{position:relative;width:3.438rem;height:3.438rem;overflow:hidden;border:1px solid #f1f1f1;margin:.625rem 0}.thumb-mask>.mask img{width:55px;height:55px}.definition-list dl{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.definition-list dl dt{font-weight:400}.definition-list dl dd,.definition-list dl dt{-webkit-box-flex:0;-ms-flex:0 0 45%;flex:0 0 45%;background:#f1f1f1;padding:.625rem;margin:.125rem}.definition-list dl dd:nth-of-type(2n),.definition-list dl dt:nth-of-type(2n){background:#f6f6f6}.help-block{margin-top:.625rem}.btn.disabled,.btn.disabled:hover{background:#7a7a7a}.alert-warning .material-icons{color:#ff9a52;font-size:2rem;margin-right:.625rem;padding-top:.3125rem}.alert-warning .alert-text{font-size:.9375rem;padding-top:.625rem}.alert-warning .alert-link{border-radius:2px;border-width:2px;margin-left:.625rem;padding:.3125rem 1.25rem;font-weight:600;font-size:.8125rem;color:#6c868e}.alert-warning ul li:last-child .alert-link{color:#fff}.alert-warning .warning-buttons{margin-top:.3125rem}.btn-tertiary-outline{color:#6c868e;background-image:none;background-color:transparent;border-color:#6c868e;border:.15rem solid #6c868e}.btn-tertiary-outline:hover{border-color:#bbcdd2;color:#bbcdd2}.alert{font-size:.8125rem}.nav-item .nav-link,.nav-item .nav-separtor{color:#7a7a7a;font-weight:700}.nav-item .nav-link.active,.nav-item .nav-separtor.active{color:#232323}.separator{margin:0;border-color:rgba(0,0,0,.25)}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - 60px)}.ps-alert-error{margin-bottom:0}.ps-alert-error .item,.ps-alert-success .item{-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:2px solid #ff4c4c;display:-webkit-box;display:-ms-flexbox;display:flex;background-color:#ff4c4c;margin-bottom:1rem}.ps-alert-error .item i,.ps-alert-success .item i{border:15px solid #ff4c4c;display:-webkit-box;display:-ms-flexbox;display:flex}.ps-alert-error .item i svg,.ps-alert-success .item i svg{background-color:#ff4c4c;width:24px;height:24px}.ps-alert-error .item p,.ps-alert-success .item p{background-color:#fff;margin:0;padding:18px 20px;width:100%}.ps-alert-success{padding:.25rem .25rem 2.75rem}.ps-alert-success .item{border-color:#4cbb6c;background-color:#4cbb6c}.ps-alert-success .item i{border-color:#4cbb6c}.ps-alert-success .item i svg{background-color:#4cbb6c}.dropdown{color:#7a7a7a}.dropdown:hover .expand-more{color:#2fb5d2}.dropdown .expand-more{color:#232323;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dropdown .active{max-height:200px;overflow-y:hidden;visibility:visible}.dropdown select{-moz-appearance:none;border:0 none;outline:0 none;color:#232323;background:#fff}.dropdown-item:focus,.dropdown-item:hover{background:none;text-decoration:none;color:#2fb5d2}.search-widget{display:inline-block}.search-widget form{position:relative}.search-widget form input[type=text]{border:none;padding:10px;min-width:255px;color:#7a7a7a;border:1px solid rgba(0,0,0,.25)}.search-widget form input[type=text]:focus{outline:3px solid #2fb5d2;color:#232323;background:#fff}.search-widget form input[type=text]:focus+button .search{color:#2fb5d2}.search-widget form button[type=submit]{position:absolute;background:none;border:none;bottom:.3125rem;right:.125rem;color:#7a7a7a}.search-widget form button[type=submit] .search:hover{color:#2fb5d2}.header-top .search-widget form input[type=text]{min-width:inherit;width:100%}#checkout #search_widget{display:none}#pagenotfound .page-content #search_widget{width:100%}.page-not-found .search-widget form{display:inline-block}@media (max-width:767px){.header-top .search-widget{float:none}.header-top .search-widget form{margin:0 auto}.header-top .search-widget form input[type=text]{min-width:inherit;background:#fff}}@media (min-width:768px){.search-widget{min-width:15.63rem}}.top-menu[data-depth="1"]{margin:.625rem}.top-menu a:not([data-depth="0"]){display:block;padding:.625rem;color:#7a7a7a;font-weight:400}.top-menu a.dropdown-submenu{color:#232323;text-transform:uppercase;font-weight:600}.top-menu a[data-depth="0"]{font-weight:600;padding:.1875rem .625rem .375rem}#header .top-menu a[data-depth="0"]:hover{color:#2fb5d2;text-decoration:none}.top-menu a[data-depth="1"],.top-menu a[data-depth="2"]{padding:0 .625rem .625rem 0}.top-menu .collapse{display:inherit}.top-menu .sub-menu{box-shadow:2px 1px 11px 2px rgba(0,0,0,.1);border:none;margin-left:.9375rem;width:calc(100% - 30px);min-width:calc(100% - 30px);z-index:18;display:none}.top-menu .sub-menu.collapse{display:none}.top-menu .sub-menu ul[data-depth="1"]>li{float:left;margin:0 1.25rem}.top-menu .sub-menu a:hover{color:#2fb5d2}.top-menu .popover{max-width:inherit;border-radius:0}.popover.bs-tether-element-attached-top{margin-top:0}#_desktop_top_menu .top-menu[data-depth="0"] li:hover .sub-menu{display:block!important}#mobile_top_menu_wrapper{padding:15px;background:#fff}#mobile_top_menu_wrapper #top-menu{margin-bottom:.625rem}#mobile_top_menu_wrapper .top-menu{color:#232323}#mobile_top_menu_wrapper .top-menu .collapse-icons[aria-expanded=true] .add{display:none}#mobile_top_menu_wrapper .top-menu .collapse-icons[aria-expanded=true] .remove{display:block}#mobile_top_menu_wrapper .top-menu .collapse-icons .remove{display:none}#mobile_top_menu_wrapper .top-menu .navbar-toggler{display:inline-block;padding:0}#mobile_top_menu_wrapper .top-menu a[data-depth="0"]{padding:.625rem;border-bottom:1px solid #f6f6f6}#mobile_top_menu_wrapper .top-menu .collapse{display:none}#mobile_top_menu_wrapper .top-menu .collapse.in{display:block}#mobile_top_menu_wrapper .top-menu .sub-menu{box-shadow:none;z-index:inherit;display:block;position:static;overflow:hidden;margin-left:0;width:100%;min-width:100%;background:#fff}#mobile_top_menu_wrapper .top-menu .sub-menu.collapse{display:none}#mobile_top_menu_wrapper .top-menu .sub-menu.collapse.in{display:block}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="0"]>li{border-bottom:1px solid #7a7a7a}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]{margin:0}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]>li{float:none;margin:0}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]>li a{text-transform:none}#mobile_top_menu_wrapper .top-menu .sub-menu ul{padding:0}#mobile_top_menu_wrapper .top-menu .sub-menu li>a{padding:.625rem;border-bottom:1px solid #fff;font-weight:700}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="2"] li a{padding-left:1.25rem}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="3"] li a{padding-left:2.5rem}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="4"] li a{padding-left:3.75rem}#mobile_top_menu_wrapper .js-top-menu-bottom a{color:#7a7a7a}#mobile_top_menu_wrapper .js-top-menu-bottom .language-selector-wrapper{padding:.625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .language-selector-wrapper .language-selector{display:inline}#mobile_top_menu_wrapper .js-top-menu-bottom #contact-link,#mobile_top_menu_wrapper .js-top-menu-bottom .currency-selector{padding:.625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .user-info{padding:0 .625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .user-info a{padding:.625rem 0;display:block;width:100%}body#checkout{color:#232323}body#checkout #header .header-nav{max-height:none;padding:.9375rem 0;border:none;margin-bottom:0;box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}body#checkout #header .header-nav .logo{max-height:4.375rem;width:auto}body#checkout #header .header-nav #_desktop_contact_link #contact-link{margin-top:0}body#checkout .custom-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex}body#checkout .custom-checkbox span{-webkit-box-flex:0;-ms-flex:0 0 15px;flex:0 0 15px;margin-top:.1875rem}body#checkout a:hover{color:#1a8196}body#checkout section#content{margin-bottom:1.563rem}body#checkout .container{min-height:100%}body#checkout section.checkout-step{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background-color:#fff;border-bottom:1px solid rgba(0,0,0,.25);padding:.9375rem}body#checkout section.checkout-step:last-child{border:0}body#checkout section.checkout-step .step-title{text-transform:uppercase;cursor:pointer;margin-bottom:0}body#checkout section.checkout-step .content{padding:0 2.313rem}body#checkout section.checkout-step .step-edit{text-transform:lowercase;font-weight:400}body#checkout section.checkout-step .step-edit .edit{font-size:1rem}body#checkout section.checkout-step .not-allowed{cursor:not-allowed;opacity:.5}body#checkout section.checkout-step .content,body#checkout section.checkout-step .done,body#checkout section.checkout-step .step-edit{display:none}body#checkout section.checkout-step.-unreachable .step-title{cursor:not-allowed;opacity:.5}body#checkout section.checkout-step.-current .step-title{cursor:default}body#checkout section.checkout-step.-current .content{display:block}body#checkout section.checkout-step.-current.-reachable.-complete .done,body#checkout section.checkout-step.-current.-reachable.-complete .step-edit{display:none}body#checkout section.checkout-step.-current.-reachable.-complete .step-number{display:inline-block}body#checkout section.checkout-step.-current.-reachable.-complete .content{display:block}body#checkout section.checkout-step.-reachable.-complete h1 .done{display:inline-block}body#checkout section.checkout-step.-reachable.-complete h1 .step-number{display:none}body#checkout section.checkout-step.-reachable.-complete h1 .step-edit{cursor:pointer;display:block;float:right;margin-right:.125rem;color:#7a7a7a}body#checkout section.checkout-step.-reachable.-complete .content{display:none}body#checkout section.checkout-step small{color:#7a7a7a}body#checkout section.checkout-step .default-input{min-width:40%}body#checkout section.checkout-step .default-input[name=address1],body#checkout section.checkout-step .default-input[name=address2]{min-width:60%}body#checkout section.checkout-step .radio-field{margin-top:1.875rem}body#checkout section.checkout-step .radio-field label{display:inline}body#checkout section.checkout-step .checkbox-field div{margin-top:3.75rem}body#checkout section.checkout-step .checkbox-field+.checkbox-field div{margin-top:0}body#checkout section.checkout-step .select-field div{background:#f6f6f6;padding:.625rem 3.125rem}body#checkout section.checkout-step .form-footer{text-align:center}body#checkout section.checkout-step #conditions-to-approve{padding-top:1rem}body#checkout section.checkout-step .payment-options label{display:table-cell}body#checkout section.checkout-step .payment-options .custom-radio{margin-right:1.25rem}body#checkout section.checkout-step .payment-options .payment-option{margin-bottom:.5rem}body#checkout section.checkout-step .step-number{display:inline-block;padding:.625rem}body#checkout section.checkout-step .address-selector{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-ms-flex-wrap:wrap;flex-wrap:wrap}body#checkout section.checkout-step .address-item{background:#f6f6f6;-webkit-box-flex:0;-ms-flex:0 0 49%;flex:0 0 49%;margin-bottom:.625rem;border:3px solid transparent}body#checkout section.checkout-step .address-item.selected{background:#fff;border:3px solid #2fb5d2}body#checkout section.checkout-step .address-alias{display:inline-block;font-weight:600;margin-bottom:.625rem}body#checkout section.checkout-step .address{margin-left:1.563rem;font-weight:400}body#checkout section.checkout-step .radio-block{padding:.9375rem;text-align:left;cursor:pointer}body#checkout section.checkout-step .custom-radio{margin-right:0}body#checkout section.checkout-step .custom-radio input[type=radio]{height:1.25rem;width:1.25rem}body#checkout section.checkout-step .delete-address,body#checkout section.checkout-step .edit-address{color:#7a7a7a;display:inline-block;margin:0 .3125rem}body#checkout section.checkout-step .delete-address .delete,body#checkout section.checkout-step .delete-address .edit,body#checkout section.checkout-step .edit-address .delete,body#checkout section.checkout-step .edit-address .edit{font-size:1rem}body#checkout section.checkout-step hr{margin:0}body#checkout section.checkout-step .address-footer{text-align:center;padding:.625rem}body#checkout section.checkout-step #delivery-addresses,body#checkout section.checkout-step #invoice-addresses,body#checkout section.checkout-step .add-address{margin-top:1.25rem}body#checkout section.checkout-step .add-address a{color:#232323}body#checkout section.checkout-step .add-address a i{font-size:.9375rem}body#checkout section.checkout-step .delivery-option{background:#f6f6f6;padding:.9375rem 0;margin-bottom:.9375rem}body#checkout section.checkout-step .delivery-option label{text-align:inherit}body#checkout section.checkout-step .delivery-option img{width:3.125rem}body#checkout section.checkout-step .carrier-delay,body#checkout section.checkout-step .carrier-name{display:inline-block;word-break:break-word;text-align:left}body#checkout section.checkout-step #customer-form,body#checkout section.checkout-step #delivery-address,body#checkout section.checkout-step #invoice-address,body#checkout section.checkout-step #login-form{margin-left:.3125rem;margin-top:1.563rem}body#checkout section.checkout-step #customer-form .form-control-label,body#checkout section.checkout-step #delivery-address .form-control-label,body#checkout section.checkout-step #invoice-address .form-control-label,body#checkout section.checkout-step #login-form .form-control-label{text-align:left}body#checkout section.checkout-step #customer-form .radio-inline,body#checkout section.checkout-step #delivery-address .radio-inline,body#checkout section.checkout-step #invoice-address .radio-inline,body#checkout section.checkout-step #login-form .radio-inline{padding:0}body#checkout section.checkout-step .sign-in{font-size:.875rem}body#checkout section.checkout-step .forgot-password{margin-left:14.38rem}body#checkout .additional-information{font-size:.875rem;margin-left:2.875rem;margin-top:1.25rem}body#checkout .condition-label{margin-left:2.5rem;margin-top:.625rem}body#checkout .condition-label label{text-align:inherit}body#checkout .cancel-address{margin:.625rem;display:block;color:#7a7a7a;text-decoration:underline}body#checkout .modal-content{padding:1.25rem;background-color:#f1f1f1}body#checkout #cart-summary-product-list{font-size:.875rem}body#checkout #cart-summary-product-list img{border:1px solid #f1f1f1;width:3.125rem}body#checkout #cart-summary-product-list .media-body{vertical-align:middle}body#checkout #order-summary-content{padding-top:.9375rem}body#checkout #order-summary-content h4.h4{margin-top:.625rem;margin-bottom:1.25rem;color:#232323}body#checkout #order-summary-content h4.black{color:#000}body#checkout #order-summary-content h4.addresshead{margin-top:.1875rem}body#checkout #order-summary-content .noshadow{box-shadow:none}body#checkout #order-summary-content #order-items{border-right:0}body#checkout #order-summary-content #order-items h3.h3{color:#232323;margin-top:1.25rem}body#checkout #order-summary-content #order-items table tr:first-child td{border-top:0}body#checkout #order-summary-content .order-confirmation-table{padding:1rem;margin-bottom:2rem;background-color:#fff;border:3px solid #e5e5e5;border-radius:0}body#checkout #order-summary-content .summary-selected-carrier{margin-bottom:.75rem;background-color:#fff;border:1px solid #e5e5e5;border-radius:0;padding:1rem}body#checkout #order-summary-content .summary-selected-carrier .logo-container{text-align:center}body#checkout #order-summary-content .summary-selected-carrier .logo-container img{width:3.125rem}body#checkout #order-summary-content .step-edit{display:inline;color:#7a7a7a}body#checkout #order-summary-content .step-edit:hover{cursor:pointer}body#checkout #order-summary-content a .step-edit{color:#7a7a7a}body#checkout #delivery,body#checkout #gift_message{max-width:100%;border-color:#232323}body#checkout #delivery textarea,body#checkout #gift_message textarea{max-width:100%;margin-bottom:10px}body#checkout #footer{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);padding:.9375rem;background:#fff;color:#7a7a7a}#order-details{padding-left:1.3rem;margin-top:1.25rem}#order-details>.card-title{margin-bottom:1.875rem}#order-details ul{margin-bottom:1.25rem}#order-details ul li{margin-bottom:.625rem}#order-items{border-right:1px solid #f1f1f1}#order-items .h3{font-size:1rem}@media (max-width:991px){#order-items .h3._desktop-title{display:none}}#order-items hr{border-top-color:#232323}#order-items table{width:100%}#order-items table tr{height:1.875rem}#order-items table tr td:last-child{text-align:right}#order-items table tr td{padding:.5rem;font-size:.875rem}#order-items table tr.total-value{background-color:#f1f1f1}#order-items table tr.taxes td{text-align:left}#order-items table tr.taxes td .value{padding-top:0}#order-items .order-line{margin-top:1rem}#order-items .image img{width:100%;border:1px solid gray-lighter;margin-bottom:1rem}#order-items .details{margin-bottom:1rem}#order-items .details .customizations{margin-top:.625rem}#order-items .qty{margin-bottom:1rem}#order-confirmation #registration-form{width:50%;margin:0 auto 1rem}@media (max-width:991px){.done{margin-right:.625rem;padding:0}body#checkout section.checkout-step .address-item{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}body#checkout section.checkout-step .delivery-option-2{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.delivery-option{display:-webkit-box;display:-ms-flexbox;display:flex;margin:auto}.delivery-option .custom-radio{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto}.condition-label label[for="conditions_to_approve[terms-and-conditions]"]{text-align:left}#order-confirmation #registration-form{width:100%}}@media (max-width:767px){body#checkout section.checkout-step.-reachable.-complete h1 .step-edit{float:none;margin-top:.25rem;margin-left:1.25rem}body#checkout #header .header-nav{max-height:none;padding:0}body#checkout section.checkout-step .content{padding:.9375rem}body#checkout .form-group{margin-bottom:.5rem}#order-items{border-right:0;margin-bottom:2.5rem}#order-items .card-title{border-bottom:1px solid #f1f1f1;margin-bottom:1rem;padding-bottom:1rem}#order-items hr{border-top-color:#f1f1f1}.bold{font-weight:700}#order-details{padding-left:.9375rem}#order-details .card-title{border-bottom:1px solid #f1f1f1;margin-bottom:1rem;padding-bottom:1rem}}@media (max-width:575px){body#checkout section.checkout-step .content{padding:.9375rem 0}#payment-confirmation button{font-size:.875rem}#payment-confirmation button.btn{white-space:normal}}.js-payment-binary,.js-payment-binary .accept-cgv{display:none}.js-payment-binary.disabled{opacity:.6;cursor:not-allowed}.js-payment-binary.disabled:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}.js-payment-binary.disabled .accept-cgv{display:block}.table-labeled td,.table-labeled th{vertical-align:middle}.table-labeled .label{font-weight:400;border-radius:3px;font-size:inherit;padding:.25rem .375rem;margin:.125rem;color:#fff;white-space:nowrap}.page-order .table{margin-bottom:0}.page-order table td,.page-order table th{padding:.5rem}.page-order table thead th{text-align:center}#authentication .tooltip.tooltip-bottom{padding:0;margin:0}#authentication .custom-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex}#authentication .custom-checkbox span{-webkit-box-flex:0;-ms-flex:0 0 0.9375rem;flex:0 0 0.9375rem}#authentication .custom-checkbox label{padding-left:.625rem}#authentication .radio-inline,#identity .radio-inline{padding:0}#authentication .radio-inline .custom-radio,#identity .radio-inline .custom-radio{margin-right:0}.page-customer-account #content{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;font-size:.875rem;color:#7a7a7a}.page-customer-account #content .order-actions a{padding:0 .125rem}.page-customer-account #content .forgot-password{text-align:center;font-size:.875rem;margin-top:1rem;padding-bottom:.9375rem}.page-customer-account #content .no-account{text-align:center;font-size:1rem}.page-authentication #content{padding:1rem;max-width:640px;margin:0 auto}.page-addresses .address,.page-authentication #content{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}.page-addresses .address{margin-bottom:1.875rem;font-size:.875rem;color:#232323}.page-addresses .address .address-body{padding:1rem}.page-addresses .address .address-body h4{font-size:1rem;font-weight:700}.page-addresses .address .address-body address{min-height:9rem}.page-addresses .address .address-footer{border-top:1px solid #7a7a7a;padding:.5rem 1rem}.page-addresses .address .address-footer a{color:#7a7a7a;margin-right:.5rem}.page-addresses .address .address-footer a:hover{color:#232323}.page-addresses .address .address-footer a i{font-size:1rem}.page-addresses .address .address-footer a span{font-size:.9375rem;vertical-align:middle}.page-addresses .addresses-footer{margin:0 .9375rem}.page-addresses .addresses-footer a,.page-addresses .addresses-footer a:hover{color:#232323}.page-addresses .addresses-footer a i{font-size:1rem}.page-addresses .addresses-footer a span{font-size:1rem;vertical-align:middle;margin-top:.625rem}.page-order-detail{font-size:.875rem;color:#7a7a7a}.page-order-detail .box{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;margin-bottom:1rem}.page-order-detail h3{font-size:1rem;font-weight:700;text-transform:uppercase;color:#232323;margin-bottom:1rem}.page-order-detail #order-infos ul{margin:0}.page-order-detail #order-history .history-lines .history-line{padding:.5rem 0;border-bottom:1px solid #f6f6f6}.page-order-detail #order-history .history-lines .history-line:last-child{border-bottom:0}.page-order-detail #order-history .history-lines .history-line .label{display:inline-block;margin:.25rem 0;padding:.25rem .375rem;color:#fff;border-radius:3px}.page-order-detail .addresses{margin:0 -.9375rem}.page-order-detail .addresses h4{font-size:1rem;font-weight:700}.page-order-detail #order-products.return{margin-bottom:1rem}.page-order-detail #order-products.return th.head-checkbox{width:30px}.page-order-detail #order-products.return td{padding:1.375rem .75rem}.page-order-detail #order-products.return td.qty{min-width:125px}.page-order-detail #order-products.return td.qty .current{width:30%;float:left;text-align:right;padding-right:.5rem}.page-order-detail #order-products.return td.qty .select{width:70%;float:left;margin:-.625rem 0;padding-left:.25rem}.page-order-detail #order-products.return td.qty .select select{text-align:center}.page-order-detail .order-items{padding:0!important}.page-order-detail .order-items .order-item{padding:1rem 1rem 0;border-bottom:1px solid #f6f6f6}.page-order-detail .order-items .order-item .checkbox{width:30px;float:left;padding:0 .9375rem}.page-order-detail .order-items .order-item .content{width:calc(100% - 30px);float:left;padding:0 .9375rem}.page-order-detail .order-items .order-item .desc{margin-bottom:1rem}.page-order-detail .order-items .order-item .desc .name{font-weight:700}.page-order-detail .order-items .order-item .qty{margin-bottom:1rem}.page-order-detail .order-items .order-item .qty .q,.page-order-detail .order-items .order-item .qty .s{margin-bottom:.25rem}.page-order-detail .messages .message{margin-top:.5rem;border-bottom:1px solid #f6f6f6}.page-order-detail .messages .message:last-child{border-bottom:0}.page-order-detail .messages .message>div{margin-bottom:.5rem}.page-order-detail .customization{margin-top:.75rem}#order-return-infos .thead-default th{color:#232323}#order-return-infos .customization{margin-top:.75rem}.page-my-account #content .links{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.page-my-account #content .links a{text-align:center;display:inline-block;font-size:1rem;font-weight:700;text-transform:uppercase;color:#7a7a7a;padding:0 .9375rem;margin-bottom:1.875rem}.page-my-account #content .links a span.link-item{display:block;height:100%;box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem}.page-my-account #content .links a i{display:block;font-size:2.6rem;width:100%;color:#232323;padding-bottom:3.4rem}.page-my-account #content .links a:hover{color:#232323}.page-my-account #content .links a:hover i{color:#2fb5d2}#history .orders{margin:0 -1rem}#history .orders .order{padding:.75rem 1rem;border-bottom:1px solid #f6f6f6}#history .orders .order a h3{color:#7a7a7a}#history .orders .order .label{display:inline-block;margin:.25rem 0;padding:.25rem .375rem;color:#fff;border-radius:3px}#history .orders .order:last-child{border-bottom:0}.page-footer .account-link{margin-right:1rem}.page-footer .account-link i{font-size:1rem}.page-footer .account-link span{font-size:.875rem;vertical-align:middle}.login-form{margin-top:15px}.forgotten-password{padding:4px}.forgotten-password .form-fields .center-email-fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}@media (max-width:767px){.forgotten-password .form-fields .center-email-fields{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.forgotten-password .form-fields .center-email-fields button{margin:10px;width:calc(100% - 20px)}}.forgotten-password .form-fields .center-email-fields button{height:38px}.forgotten-password .form-fields .email{padding-left:0;padding-right:0;width:430px}@media (max-width:767px){.forgotten-password .form-fields .email{padding-left:10px;padding-right:10px;width:100%}}.forgotten-password .form-fields .email input{height:38px}.forgotten-password .form-fields label.required{width:130px}.send-renew-password-link{padding-left:10px;padding-right:10px}.renew-password{margin-left:10px}.renew-password .email{padding-bottom:30px}.renew-password [type=submit]{margin-left:50px}.carousel{box-shadow:1px 1px 7px 0 rgba(0,0,0,.15);margin-bottom:1.5rem}.carousel .direction{z-index:auto}.carousel .carousel-inner{height:340px}.carousel .carousel-item{height:100%}.carousel .carousel-item img{width:100%;max-width:100%;height:auto}.carousel .carousel-item .caption{position:absolute;bottom:28px;left:90px;color:#fff;max-width:340px}.carousel .carousel-item .caption .caption-description p{color:#fff}.carousel .carousel-item figure{margin:0}.carousel .carousel-control{opacity:1}.carousel .carousel-control .icon-next:before,.carousel .carousel-control .icon-prev:before{content:""}.carousel .carousel-control .icon-next i,.carousel .carousel-control .icon-prev i{font-size:3.125rem;color:#fff}.carousel .carousel-control .icon-next:hover i,.carousel .carousel-control .icon-prev:hover i{color:#2fb5d2}.carousel .carousel-control .icon-prev{left:1rem}.carousel .carousel-control .icon-next{right:2rem}.carousel .carousel-control.left,.carousel .carousel-control.right{background:none}@media (max-width:1199px){.carousel .carousel-inner{height:auto}}@media (max-width:991px){.carousel .carousel-item .caption{bottom:calc(50% - 2rem);left:10%}.carousel .carousel-item .caption .display-1{font-size:2rem}.carousel .carousel-item .caption-description{display:none}}@media (max-width:767px){.carousel .carousel-item .caption{bottom:calc(50% - 1.5rem)}.carousel .carousel-item .caption .display-1{font-size:1.5rem}.carousel .carousel-control .icon-next i,.carousel .carousel-control .icon-prev i{font-size:2rem}}#products .products,.featured-products .products,.product-accessories .products,.product-miniature .products{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}#products .product-thumbnail,.featured-products .product-thumbnail,.product-accessories .product-thumbnail,.product-miniature .product-thumbnail{display:block}#products .product-title a,.featured-products .product-title a,.product-accessories .product-title a,.product-miniature .product-title a{color:#7a7a7a;font-size:.875rem;text-decoration:none;text-align:center;font-weight:400}#products .thumbnail-container,.featured-products .thumbnail-container,.product-accessories .thumbnail-container,.product-miniature .thumbnail-container{position:relative;margin-bottom:1.563rem;height:318px;width:250px;background:#fff;box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}#products .thumbnail-container:focus .highlighted-informations,#products .thumbnail-container:hover .highlighted-informations,.featured-products .thumbnail-container:focus .highlighted-informations,.featured-products .thumbnail-container:hover .highlighted-informations,.product-accessories .thumbnail-container:focus .highlighted-informations,.product-accessories .thumbnail-container:hover .highlighted-informations,.product-miniature .thumbnail-container:focus .highlighted-informations,.product-miniature .thumbnail-container:hover .highlighted-informations{bottom:5.5rem}#products .thumbnail-container:focus .highlighted-informations:after,#products .thumbnail-container:hover .highlighted-informations:after,.featured-products .thumbnail-container:focus .highlighted-informations:after,.featured-products .thumbnail-container:hover .highlighted-informations:after,.product-accessories .thumbnail-container:focus .highlighted-informations:after,.product-accessories .thumbnail-container:hover .highlighted-informations:after,.product-miniature .thumbnail-container:focus .highlighted-informations:after,.product-miniature .thumbnail-container:hover .highlighted-informations:after{opacity:1}#products .thumbnail-container:focus .highlighted-informations.no-variants,#products .thumbnail-container:hover .highlighted-informations.no-variants,.featured-products .thumbnail-container:focus .highlighted-informations.no-variants,.featured-products .thumbnail-container:hover .highlighted-informations.no-variants,.product-accessories .thumbnail-container:focus .highlighted-informations.no-variants,.product-accessories .thumbnail-container:hover .highlighted-informations.no-variants,.product-miniature .thumbnail-container:focus .highlighted-informations.no-variants,.product-miniature .thumbnail-container:hover .highlighted-informations.no-variants{bottom:4.2rem}#products .thumbnail-container:focus .product-description:after,#products .thumbnail-container:hover .product-description:after,.featured-products .thumbnail-container:focus .product-description:after,.featured-products .thumbnail-container:hover .product-description:after,.product-accessories .thumbnail-container:focus .product-description:after,.product-accessories .thumbnail-container:hover .product-description:after,.product-miniature .thumbnail-container:focus .product-description:after,.product-miniature .thumbnail-container:hover .product-description:after{content:"";border-top:1px solid #7a7a7a;position:absolute;width:80%;top:0;left:10%;opacity:.25}#products .thumbnail-container .product-thumbnail,.featured-products .thumbnail-container .product-thumbnail,.product-accessories .thumbnail-container .product-thumbnail,.product-miniature .thumbnail-container .product-thumbnail{position:relative;height:calc(100% - 70px)}#products .thumbnail-container .product-thumbnail img,.featured-products .thumbnail-container .product-thumbnail img,.product-accessories .thumbnail-container .product-thumbnail img,.product-miniature .thumbnail-container .product-thumbnail img{max-width:100%;position:absolute;top:0;bottom:0;left:0;right:0;margin:auto}#products .products-section-title,.featured-products .products-section-title,.product-accessories .products-section-title,.product-miniature .products-section-title{text-align:center;margin-bottom:1.5rem}#products .product-title,.featured-products .product-title,.product-accessories .product-title,.product-miniature .product-title{text-align:center;text-transform:capitalize;margin-top:.7rem}#products .product-price-and-shipping,.featured-products .product-price-and-shipping,.product-accessories .product-price-and-shipping,.product-miniature .product-price-and-shipping{color:#232323;font-weight:700;text-align:center}#products .product-price-and-shipping .discount-product,.featured-products .product-price-and-shipping .discount-product,.product-accessories .product-price-and-shipping .discount-product,.product-miniature .product-price-and-shipping .discount-product{display:none}#products .variant-links,.featured-products .variant-links,.product-accessories .variant-links,.product-miniature .variant-links{position:relative;text-align:center;width:100%;top:-.25em;padding-top:.1875rem;min-height:2.5rem;background:#fff}#products .highlighted-informations,.featured-products .highlighted-informations,.product-accessories .highlighted-informations,.product-miniature .highlighted-informations{position:absolute;bottom:1.25rem;padding-top:.625rem;z-index:2;background:#fff;text-align:center;width:250px;height:3.125rem;box-shadow:0 -5px 10px -5px rgba(0,0,0,.2);transition:bottom .3s}#products .highlighted-informations .quick-view,.featured-products .highlighted-informations .quick-view,.product-accessories .highlighted-informations .quick-view,.product-miniature .highlighted-informations .quick-view{color:#7a7a7a;font-size:1rem}#products .highlighted-informations .quick-view:hover,.featured-products .highlighted-informations .quick-view:hover,.product-accessories .highlighted-informations .quick-view:hover,.product-miniature .highlighted-informations .quick-view:hover{color:#2fb5d2}#products .product-description,.featured-products .product-description,.product-accessories .product-description,.product-miniature .product-description{position:absolute;z-index:3;background:#fff;width:250px;bottom:0;height:70px}#products .product-miniature,.featured-products .product-miniature,.product-accessories .product-miniature,.product-miniature .product-miniature{margin:0 .8125rem}#products .product-miniature .product-flags li.product-flag,.featured-products .product-miniature .product-flags li.product-flag,.product-accessories .product-miniature .product-flags li.product-flag,.product-miniature .product-miniature .product-flags li.product-flag{min-width:3.125rem;min-height:1.875rem;font-weight:600}#products .product-miniature .product-flags li.product-flag.online-only,.featured-products .product-miniature .product-flags li.product-flag.online-only,.product-accessories .product-miniature .product-flags li.product-flag.online-only,.product-miniature .product-miniature .product-flags li.product-flag.online-only{top:13.1rem}#products .comments_note,.featured-products .comments_note,.product-accessories .comments_note,.product-miniature .comments_note{text-align:center;color:#7a7a7a}#products .regular-price,.featured-products .regular-price,.product-accessories .regular-price,.product-miniature .regular-price{color:#7a7a7a;text-decoration:line-through;font-size:.875rem}#products .count,.featured-products .count,.product-accessories .count,.product-miniature .count{color:#7a7a7a;font-weight:700;position:relative;bottom:.5rem}#products .all-product-link,.featured-products .all-product-link,.product-accessories .all-product-link,.product-miniature .all-product-link{clear:both;color:#7a7a7a;font-weight:700;margin-top:1.5rem;margin-bottom:1.5rem}@media (max-width:767px){#products .thumbnail-container,.featured-products .thumbnail-container,.product-accessories .thumbnail-container{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}#products .thumbnail-container .product-description,.featured-products .thumbnail-container .product-description,.product-accessories .thumbnail-container .product-description{box-shadow:0 -5px 10px -5px rgba(0,0,0,.2)}}#custom-text{background:#fff;border-radius:2px;margin-bottom:1.5rem;padding:3.125rem;text-align:center}#custom-text h2{text-transform:uppercase;color:#232323;font-size:1.563rem;font-weight:700}#custom-text p{color:#232323;font-weight:400;font-size:1.1em}#custom-text p .dark{color:#7a7a7a;font-weight:400}.page-content.page-cms{background:#fff;padding:1.25rem;text-align:justify}.page-content.page-cms .cms-box img{max-width:100%}@media (max-width:991px){#block-cmsinfo{padding:1.25rem 1.875rem}}#products{color:#7a7a7a}#products .products-select{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#products .up{margin-bottom:1rem}#products .up .btn-secondary,#products .up .btn-tertiary{color:#7a7a7a;text-transform:inherit}#products .up .btn-secondary .material-icons,#products .up .btn-tertiary .material-icons{margin-right:0}.block-category{min-height:13.75rem;margin-bottom:1.563rem}.block-category .block-category-inner{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.block-category .block-category-inner #category-description p,.block-category .block-category-inner #category-description strong{font-weight:400;color:#7a7a7a}.block-category .block-category-inner #category-description p{color:#232323;margin-bottom:0;word-break:break-word}.block-category .block-category-inner #category-description p:first-child{margin-bottom:1.25rem}.block-category .block-category-inner .category-cover img{width:141px;height:180px}.products-selection .sort-by-row{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.products-selection .sort-by{white-space:normal;word-break:break-word;margin-right:-.9375rem;margin-left:.9375rem;text-align:right}.products-selection .total-products,.products-selection h1{padding-top:.625rem}.products-sort-order{color:#7a7a7a}.products-sort-order .select-title{display:inline-block;width:100%;color:#232323;background:#fff;padding:.625rem;cursor:pointer;border:1px solid rgba(0,0,0,.25);box-shadow:2px 2px 4px 0 rgba(0,0,0,.2)}.products-sort-order .select-list{display:block;color:#232323;padding:.625rem 1.25rem}.products-sort-order .select-list:hover{background:#2fb5d2;color:#fff;text-decoration:none}.products-sort-order .dropdown-menu{left:auto;width:16.88rem;background:#f6f6f6;border:none;border-radius:0;box-shadow:2px 2px 4px 0 rgba(0,0,0,.1);margin:0}.facet-dropdown{color:#7a7a7a;padding-left:0;padding-right:0;background:#f1f1f1;border:3px solid transparent;box-sizing:border-box;box-shadow:1px 1px 1px 1px #f1f1f1}.facet-dropdown.open{border:0}.facet-dropdown.open>.select-title{border:3px solid #2fb5d2;background:#f6f6f6}.facet-dropdown .select-title{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-left:0;width:100%;color:#232323;background:#f1f1f1;padding:.625rem .625rem .625rem 1.25rem;cursor:pointer}.facet-dropdown .select-title>i{margin-left:auto}.facet-dropdown .select-list{display:block;color:#232323;background:#f6f6f6;padding:.625rem 1.25rem}.facet-dropdown .select-list:hover{background:#2fb5d2;color:#fff;text-decoration:none}.facet-dropdown .dropdown-menu{padding:0;margin-top:3px;left:auto;width:100%;background:#f6f6f6;border:none;box-shadow:1px 1px 1px 1px #f1f1f1}#search_filters,#search_filters_brands,#search_filters_suppliers{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);margin-bottom:1.563rem;background:#fff;padding:1.563rem 1.25rem}#search_filters .facet,#search_filters_brands .facet,#search_filters_suppliers .facet{padding-top:.625rem}#search_filters .facet .collapse,#search_filters_brands .facet .collapse,#search_filters_suppliers .facet .collapse{display:block}#search_filters .facet .facet-title,#search_filters_brands .facet .facet-title,#search_filters_suppliers .facet .facet-title{color:#7a7a7a}#search_filters .facet .facet-label,#search_filters_brands .facet .facet-label,#search_filters_suppliers .facet .facet-label{margin-bottom:0}#search_filters .facet .facet-label a,#search_filters_brands .facet .facet-label a,#search_filters_suppliers .facet .facet-label a{margin-top:.4375rem;color:#232323;display:inline-block;font-size:.9375rem}#search_filters_brands .facet,#search_filters_suppliers .facet{padding-top:0}#search_filters_brands .facet .facet-label,#search_filters_suppliers .facet .facet-label{margin-bottom:.3125rem}.pagination{width:100%}.pagination>div:first-child{line-height:2.5rem}.pagination .page-list{background:#fff;padding:.375rem;margin-bottom:0;box-shadow:2px 2px 4px 0 rgba(0,0,0,.2)}.pagination .page-list li{display:inline}.pagination a{color:#000;font-weight:600}.pagination a:not(.previous):not(.next){letter-spacing:.125rem}.pagination .previous{float:left}.pagination .next{float:right}.pagination .disabled{color:#7a7a7a}.pagination .current a{color:#2fb5d2;text-decoration:none;font-size:1.25rem}.active_filters{background:#dededd;padding:.625rem 1.875rem 0;margin-bottom:1.25rem}.active_filters .active-filter-title{display:inline;margin-right:.625rem;font-weight:600}.active_filters ul{display:inline}.active_filters .filter-block{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);color:#232323;margin-right:.625rem;margin-bottom:.625rem;background:#fff;padding:.625rem;display:inline-block;font-size:.8125rem}.active_filters .filter-block .close{color:#232323;font-size:.9375rem;opacity:1;margin-top:.1875rem;margin-left:.3125rem}.block-categories{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1.563rem 1.25rem;margin-bottom:1.563rem}.block-categories .category-sub-menu{margin-top:.625rem}.block-categories .category-sub-menu .category-sub-link{font-size:.875rem}.block-categories .category-sub-menu li{position:relative}.block-categories .category-sub-menu li[data-depth="1"]{margin-bottom:.625rem}.block-categories .category-sub-menu li[data-depth="0"]>a{font-weight:600;border-bottom:1px solid rgba(0,0,0,.25);width:100%;display:inline-block;margin:.3125rem 0 0;padding-bottom:.1875rem}.block-categories .category-sub-menu li:not([data-depth="0"]):not([data-depth="1"]){padding-left:.3125rem}.block-categories .category-sub-menu li:not([data-depth="0"]):not([data-depth="1"]):before{content:"-";margin-right:.3125rem}.block-categories a{color:#232323}.block-categories .collapse-icons{position:absolute;right:0;top:0;padding:0;cursor:pointer}.block-categories .collapse-icons[aria-expanded=true] .add{display:none}.block-categories .collapse-icons[aria-expanded=true] .remove{display:block}.block-categories .collapse-icons .add:hover,.block-categories .collapse-icons .remove:hover{color:#2fb5d2}.block-categories .collapse-icons .remove{display:none}.block-categories .arrows .arrow-down,.block-categories .arrows .arrow-right{font-size:.875rem;cursor:pointer;margin-left:2px}.block-categories .arrows .arrow-down:hover,.block-categories .arrows .arrow-right:hover{color:#2fb5d2}.block-categories .arrows .arrow-down,.block-categories .arrows[aria-expanded=true] .arrow-right{display:none}.block-categories .arrows[aria-expanded=true] .arrow-down{display:inline-block}.facets-title{color:#232323}.products-selection .filter-button .btn-secondary,.products-selection .filter-button .btn-tertiary{padding:.75rem .5rem .6875rem}.advertising-block{margin-bottom:1.563rem}.advertising-block img{width:100%}@media (max-width:767px){#category #left-column{width:100%}#category #left-column #search_filters_wrapper{margin-left:-30px;margin-right:-30px}#category #left-column #search_filter_controls{text-align:center;margin-bottom:1rem}#category #left-column #search_filter_controls button{margin:0 .5rem}#category #left-column #search_filters{margin-bottom:0;box-shadow:none;padding:0;border-top:1px solid #f6f6f6}#category #left-column #search_filters .facet{padding-top:0;border-bottom:1px solid #f6f6f6}#category #left-column #search_filters .facet .title{cursor:pointer}#category #left-column #search_filters .facet .title .collapse-icons .remove,#category #left-column #search_filters .facet .title[aria-expanded=true] .collapse-icons .add{display:none}#category #left-column #search_filters .facet .title[aria-expanded=true] .collapse-icons .remove{display:block}#category #left-column #search_filters .facet .facet-title{color:#232323;text-transform:uppercase}#category #left-column #search_filters .facet .h6{margin-bottom:0;padding:.625rem;display:inline-block}#category #left-column #search_filters .facet .navbar-toggler{display:inline-block;padding:.625rem .625rem 0 0}#category #left-column #search_filters .facet .collapse{display:none}#category #left-column #search_filters .facet .collapse.in{display:block}#category #left-column #search_filters .facet .facet-label a{margin-top:0}#category #left-column #search_filters .facet ul{margin-bottom:0}#category #left-column #search_filters .facet ul li{border-top:1px solid #f6f6f6;padding:.625rem}#category #content-wrapper,#category #search_filter_toggler{width:100%}.products-sort-order .select-title{margin-left:0}.products-selection h1{padding-top:0;text-align:center;margin-bottom:1rem}.products-selection .showing{padding-top:1rem}#best-sales #content-wrapper,#new-products #content-wrapper,#prices-drop #content-wrapper{width:100%}}@media (max-width:575px){.products-selection .filter-button{padding-left:0}#category #left-column #search_filters_wrapper{margin-left:-15px;margin-right:-15px}}@media screen and (max-width:767px){.category-cover{display:none}.block-category{min-height:0;margin-bottom:0}.card-block{padding:0}.card{box-shadow:none;background-color:inherit;border:none}}#product #content{position:relative;max-width:452px;margin:0 auto}.product-price{color:#2fb5d2;display:inline-block}#product-description-short{color:#232323}.product-information{font-size:.9375rem;color:#232323}.product-information .manufacturer-logo{height:35px}.product-information .product-description img{max-width:100%;height:auto}.input-color{position:absolute;opacity:0;cursor:pointer;height:1.25rem;width:1.25rem}.input-container{position:relative}.input-radio{position:absolute;top:0;cursor:pointer;opacity:0;width:100%;height:100%}.input-color:checked+span,.input-color:hover+span,.input-radio:checked+span,.input-radio:hover+span{border:2px solid #232323}.radio-label{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;display:inline-block;padding:.125rem .625rem;font-weight:600;border:2px solid #fff}.product-actions .control-label{margin-bottom:.375rem;display:block;width:100%}.product-actions .add-to-cart{height:2.75rem;line-height:inherit;padding-top:.625rem}.product-actions .add-to-cart .material-icons{line-height:inherit}.product-quantity{display:-webkit-box;display:-ms-flexbox;display:flex}.product-quantity .add,.product-quantity .qty{float:left;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-bottom:.5rem}.product-quantity .qty{margin-right:.4rem}.product-quantity #quantity_wanted{color:#232323;background-color:#fff;height:2.75rem;padding:.175rem .5rem;width:3rem}.product-quantity .input-group-btn-vertical{width:auto}.product-quantity .input-group-btn-vertical .btn{padding:.5rem .6875rem}.product-quantity .input-group-btn-vertical .btn i{font-size:1rem;top:.125rem;left:.1875rem}.product-quantity .btn-touchspin{height:1.438rem}.product-discounts{margin-bottom:1.5rem}.product-discounts>.product-discounts-title{font-weight:400;font-size:.875rem}.product-discounts>.table-product-discounts thead tr th{width:33%;padding:.625rem 1.25rem;background:#fff;border:.3125rem solid #f1f1f1;text-align:center}.product-discounts>.table-product-discounts tbody tr{background:#f6f6f6}.product-discounts>.table-product-discounts tbody tr:nth-of-type(2n){background:#fff}.product-discounts>.table-product-discounts tbody tr td{padding:.625rem 1.25rem;text-align:center;border:.3125rem solid #f1f1f1}.product-prices{margin-top:1.25rem}.product-prices div{margin-bottom:.625rem}.product-prices .tax-shipping-delivery-label{font-size:.8125rem;color:#7a7a7a}.product-prices .tax-shipping-delivery-label .delivery-information{padding:0 0 0 2px}.product-prices .tax-shipping-delivery-label .delivery-information:before{content:"-";padding:0 2px 0 0}.product-discount{color:#7a7a7a}.product-discount .regular-price{text-decoration:line-through;font-weight:400;margin-right:.625rem}.has-discount.product-price,.has-discount p{color:#f39d72}.has-discount .discount{background:#f39d72;color:#fff;font-weight:600;padding:.3125rem .625rem;font-size:1rem;margin-left:.625rem;text-transform:uppercase;display:inline-block}.product-unit-price{font-size:.8125rem;margin-bottom:0}.tabs{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);margin-top:2rem;background:#fff;padding:1.25rem 1.875rem}.tabs .tab-pane{padding-top:1.25rem}.tabs .nav-tabs{border:none;border-bottom:2px solid #f1f1f1}.tabs .nav-tabs .nav-link{color:#7a7a7a;border:0 solid transparent}.tabs .nav-tabs .nav-link.active{color:#2fb5d2}.tabs .nav-tabs .nav-link.active,.tabs .nav-tabs .nav-link:hover{border:none;border-bottom:3px solid #2fb5d2}.tabs .nav-tabs .nav-item{float:left;margin-bottom:-.125rem}.product-cover{margin-bottom:1.25rem;position:relative}.product-cover img{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}.product-cover .layer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;background:#fff;position:absolute;left:0;top:0;opacity:0;background:hsla(0,0%,100%,.7);text-align:center;cursor:pointer}.product-cover .layer:hover{opacity:1}.product-cover .layer .zoom-in{font-size:6.25rem;color:#7a7a7a}#product-modal .modal-content{background:transparent;border:none;padding:0}#product-modal .modal-content .modal-body{display:-webkit-box;display:-ms-flexbox;display:flex;margin-left:-30%}#product-modal .modal-content .modal-body .product-cover-modal{background:#fff}#product-modal .modal-content .modal-body .image-caption{background:#fff;width:800px;padding:.625rem 1.25rem;border-top:1px solid #f1f1f1}#product-modal .modal-content .modal-body .image-caption p{margin-bottom:0}#product-modal .modal-content .modal-body .thumbnails{position:relative}#product-modal .modal-content .modal-body .mask{position:relative;overflow:hidden;max-height:49.38rem;margin-top:2.188rem;z-index:1}#product-modal .modal-content .modal-body .mask.nomargin{margin-top:0}#product-modal .modal-content .modal-body .product-images{margin-left:2.5rem}#product-modal .modal-content .modal-body .product-images img{width:9.25rem;cursor:pointer;background:#fff}#product-modal .modal-content .modal-body .product-images img:hover{border:3px solid #2fb5d2}#product-modal .modal-content .modal-body .arrows{height:100%;width:100%;text-align:center;position:absolute;top:0;color:#fff;right:1.875rem;z-index:0;cursor:pointer}#product-modal .modal-content .modal-body .arrows .arrow-up{position:absolute;top:-2rem;opacity:.2}#product-modal .modal-content .modal-body .arrows .arrow-down{position:absolute;bottom:-2rem}#product-modal .modal-content .modal-body .arrows i{font-size:6.25rem;display:inline}#blockcart-modal{color:#232323}#blockcart-modal .modal-header{background:#fff}#blockcart-modal .modal-header .close{opacity:1}#blockcart-modal .modal-header .close .material-icons{color:#363a42}#blockcart-modal .modal-body{background:#fff;padding:3.125rem 1.875rem}#blockcart-modal .modal-body .divide-right span{display:inline-block;margin-bottom:.3125rem}@media (max-width:767px){#blockcart-modal .modal-body .divide-right span{display:block;padding:0 .5rem}}#blockcart-modal .modal-dialog{max-width:1140px;width:100%}#blockcart-modal .product-image{width:100%;max-width:9.375rem;display:block;margin:0 0 0 auto}#blockcart-modal .modal-title{color:#353943;font-size:1rem;font-weight:400}#blockcart-modal .modal-title i.material-icons{margin-right:1.875rem;color:#4cbb6c}#blockcart-modal .product-name{color:#2fb5d2;font-size:1.125rem}@media (max-width:767px){#blockcart-modal .product-name{padding:0 .5rem}}#blockcart-modal .product-price{color:#363a42;display:block}@media (max-width:767px){#blockcart-modal .product-price{padding:0 .5rem}}#blockcart-modal .cart-content{padding-left:2.5rem}#blockcart-modal .cart-content p{color:#363a42;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0 .5rem}#blockcart-modal .cart-content p.product-total{background-color:#f1f1f1;padding:.5rem}#blockcart-modal .cart-content p.cart-products-count{font-size:1rem;color:#6c868e;font-weight:600}#blockcart-modal .cart-content p.product-tax{display:inherit;font-size:.875rem}#blockcart-modal .cart-content p .label,#blockcart-modal .cart-content p .value{font-weight:600}#blockcart-modal .cart-content .cart-content-btn{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}#blockcart-modal .cart-content .cart-content-btn button{margin-right:.9rem}#blockcart-modal .cart-content .cart-content-btn .btn{white-space:inherit}#blockcart-modal .divide-right{border-right:1px solid #dbdbdb}.product-images>li.thumb-container{display:inline}.product-images>li.thumb-container>.thumb{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);cursor:pointer;margin-bottom:.625rem}.images-container .product-images>li.thumb-container>.thumb{margin-right:.8125rem}.product-images>li.thumb-container>.thumb.selected,.product-images>li.thumb-container>.thumb:hover{border:3px solid #2fb5d2}#main .images-container .js-qv-mask{white-space:nowrap;overflow:hidden}#main .images-container .js-qv-mask.scroll{width:calc(100% - 60px);margin:0 auto}.scroll-box-arrows{display:none}.scroll-box-arrows.scroll{display:block}.scroll-box-arrows i{position:absolute;bottom:1.625rem;height:100px;line-height:100px;cursor:pointer}.scroll-box-arrows .left{left:0}.scroll-box-arrows .right{right:0}#product-availability{margin-top:.625rem;display:inline-block;font-weight:700}#product-availability .material-icons{line-height:inherit}#product-availability .product-available{color:#4cbb6c}#product-availability .product-last-items,#product-availability .product-unavailable{color:#ff9a52}#product-details .label{font-size:1rem;color:#232323;font-weight:700}.product-features{margin-top:1.25rem;margin-left:.3125rem}.product-features>dl.data-sheet{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.product-features>dl.data-sheet dd.value,.product-features>dl.data-sheet dt.name{-webkit-box-flex:1;-ms-flex:1 0 40%;flex:1 0 40%;font-weight:400;background:#f1f1f1;padding:.625rem;margin-right:.625rem;min-height:2.5rem;word-break:normal;text-transform:capitalize;margin-bottom:.5rem}.product-features>dl.data-sheet dd.value:nth-of-type(2n),.product-features>dl.data-sheet dt.name:nth-of-type(2n){background:#f6f6f6}.product-variants>.product-variants-item{margin:1.25rem 0}.product-variants>.product-variants-item select{background-color:#fff;width:auto;padding-right:1.875rem;box-shadow:2px 2px 4px 0 rgba(0,0,0,.2)}.product-variants>.product-variants-item ul li{margin-right:.625rem}.product-variants>.product-variants-item .color{margin-left:0;margin-top:0}.product-flags{pointer-events:none;position:absolute;width:100%;top:0;left:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:2}.product-flags li.product-flag{pointer-events:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;background:#2fb5d2;font-weight:700;padding:.3125rem .4375rem;text-transform:uppercase;color:#fff;margin-top:.625rem;font-size:1rem;box-shadow:2px 2px 4px 0 rgba(0,0,0,.2)}.product-flags li.product-flag.online-only{position:absolute;top:25rem;right:0;z-index:1;font-size:.8125rem;margin-top:0}.product-flags li.product-flag.online-only:before{content:"\E30A";font-family:Material Icons;vertical-align:middle;margin:.3125rem}.product-flags li.product-flag.discount,.product-flags li.product-flag.discount-amount,.product-flags li.product-flag.discount-percentage{background-color:#f39d72}.product-flags li.product-flag.on-sale{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1;background:#f39d72;width:100%;text-align:center;margin-top:0!important}.product-customization{margin:2.5rem 0}.product-customization .product-customization-item{margin:1.25rem 0}.product-customization .product-message{background:#f1f1f1;border:none;width:100%;height:3.125rem;resize:none;padding:.625rem}.product-customization .product-message:focus{background-color:#fff;outline:.1875rem solid #2fb5d2}.product-customization .file-input{width:100%;opacity:0;left:0;z-index:1;cursor:pointer;height:2.625rem;overflow:hidden;position:absolute}.product-customization .customization-message{margin-top:20px}.product-customization .custom-file{position:relative;background:#f1f1f1;width:100%;height:2.625rem;line-height:2.625rem;text-indent:.625rem;display:block;color:#7a7a7a;margin-top:1.25rem}.product-customization .custom-file button{z-index:0;position:absolute;right:0;top:0}.product-customization small{color:#7a7a7a}.product-pack{margin-top:2.5rem}.product-pack .pack-product-container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around}.product-pack .pack-product-container .pack-product-name{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;font-size:.875rem;color:#7a7a7a}.product-pack .pack-product-container .pack-product-quantity{border-left:2px solid #f1f1f1;padding-left:.625rem}.product-pack .pack-product-container .pack-product-name,.product-pack .pack-product-container .pack-product-price,.product-pack .pack-product-container .pack-product-quantity{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.product-refresh{margin-top:1.25rem}.social-sharing{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-top:1.5rem}.social-sharing ul{margin-bottom:0}.social-sharing li{box-shadow:2px 2px 4px 0 rgba(0,0,0,.2);height:2.5rem;width:2.5rem;border-radius:50%;display:inline-block;background-color:#fff;background-repeat:no-repeat;background-size:2rem 2rem;background-position:.25rem .25rem;cursor:pointer;margin-left:.5rem}.social-sharing li a{display:block;width:100%;height:100%;white-space:nowrap;text-indent:100%;overflow:hidden}.social-sharing li a:hover{color:transparent}.products-selection{margin-bottom:1.25rem}.products-selection .title{color:#7a7a7a}#blockcart-modal .cart-content .btn{margin-bottom:.625rem}@media (max-width:991px){.product-cover img{width:100%}#product-modal .modal-content .modal-body{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-left:0}#product-modal .modal-content .modal-body img.product-cover-modal{width:100%}#product-modal .modal-content .modal-body .arrows{display:none}#product-modal .modal-content .modal-body .image-caption{width:100%}#blockcart-modal .modal-dialog{width:calc(100% - 20px)}#blockcart-modal .modal-body{padding:1.875rem}}@media (max-width:767px){#blockcart-modal .divide-right{border-right:none}#blockcart-modal .modal-body{padding:1rem}}.cart-grid{margin-bottom:1rem}.cart-items{margin-bottom:0}.cart-item{padding:1rem 0}.card-block{padding:1.25rem 1.25rem .5rem}.card-block.checkout{padding-bottom:1.75rem;padding-top:0;margin-top:1rem}.card-block.cart-summary-totals{padding:0 1rem 1rem}.card-block.cart-summary-totals .cart-summary-line{padding:.5rem .2rem 0}.card-block.cart-summary-totals .cart-summary-line:last-child{margin-bottom:0}.card-block.cart-summary-totals .cart-summary-line.cart-total{background-color:#f1f1f1;padding:.5rem}.card-block.cart-summary-totals .cart-summary-line.cart-total .label,.card-block.cart-summary-totals .cart-summary-line.cart-total .value{font-weight:700}.card-block.cart-summary-totals .cart-summary-line.cart-total .label{font-size:1rem}.card-block.cart-summary-totals .cart-summary-line.cart-total .value{font-size:1.125rem}.card-block.cart-summary-totals .cart-summary-line span.sub{text-align:left;font-size:.88rem;float:none}.cart-summary-line{clear:both;margin-bottom:.315rem}.cart-summary-line:after{content:"";display:table;clear:both}.cart-summary-line .label{padding-left:0;font-weight:400;white-space:inherit;color:#363a42}.cart-summary-line .value{color:#232323;float:right}.cart-summary-line.cart-summary-subtotals .label,.cart-summary-line.cart-summary-subtotals .value{font-weight:400}.cart-grid-body{margin-bottom:.75rem}.cart-grid-body a.label:hover{color:#2fb5d2}.cart-grid-body .card-block{padding:1rem}.cart-grid-body .card-block h1{margin-bottom:0}.cart-grid-body .cart-overview{padding:1rem}.cart-grid-right .promo-discounts{margin-bottom:0;text-align:center;padding-top:.5rem;padding-bottom:.5rem}.cart-grid-right .promo-discounts .cart-summary-line .label{font-size:1rem;color:#7a7a7a}.cart-grid-right .promo-discounts .cart-summary-line .label .code{color:#f49d6e;cursor:pointer}.cart-grid-right .cart-summary-line.cart-subtotal-products .label,.cart-grid-right .cart-summary-line.cart-subtotal-products .value{font-weight:600}.cart-grid-right .cart-summary-line.cart-subtotal-products .value{font-size:1rem}.block-promo{margin-bottom:1rem}.block-promo .promo-code{padding:1rem}.block-promo .promo-code .alert-danger{position:relative;margin-top:1.25rem;background:#ff4c4c;color:#fff;display:none}.block-promo .promo-code .alert-danger:after{bottom:100%;left:10%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none;border-bottom-color:#ff4c4c;border-width:10px;margin-left:-10px}.block-promo .promo-code form{text-align:center}.block-promo .promo-input{color:#232323;border:1px solid #7a7a7a;height:2.5rem;text-indent:.625rem;width:50%;margin-right:-.24rem}.block-promo .promo-input+button{margin-top:-4px;margin-left:-1px;text-transform:capitalize;border:2px solid #2fb5d2}.block-promo .cart-summary-line .label,.block-promo .promo-name{color:#ff9a52;font-weight:600;margin-bottom:0}.block-promo .cart-summary-line .label a,.block-promo .promo-name a{font-weight:400;color:#232323;display:inline-block}.block-promo .promo-name .cart-summary-line .label{font-weight:400;color:#363a42}.block-promo .promo-name .cart-summary-line span{color:#f49d6e}.block-promo .promo-name .material-icons{font-size:1.2rem;margin-left:.4rem}.block-promo .promo-code-button{display:block;text-align:center;padding:0 0 1rem}.block-promo .promo-code-button.with-discounts{display:none}.block-promo .promo-code-button.cancel-promo{color:#2fb5d2;margin-bottom:0}.block-promo .promo-code-button.cancel-promo[aria-expanded=true]{display:block;padding:0;margin-top:1rem}.block-promo.promo-highlighted{padding:0 1rem;margin-bottom:0;text-align:center}.block-promo p{margin-bottom:0}.product-line-grid-left img{max-width:100%}.product-line-grid-body>.product-line-info>.label{padding:0;line-height:inherit;text-align:left;white-space:inherit}.product-line-grid-body>.product-line-info>.out-of-stock{color:red}.product-line-grid-body>.product-line-info>.available{color:#4cbb6c}.product-line-grid-body>.product-line-info>.unit-price-cart{padding-left:.3125rem;font-size:.875rem;color:#7a7a7a}.product-line-grid-right .cart-line-product-actions,.product-line-grid-right .product-price{color:#232323;line-height:36px}.product-line-grid-right .cart-line-product-actions .remove-from-cart,.product-line-grid-right .product-price .remove-from-cart{color:#232323;display:inline-block;margin-top:.3125rem}@media (max-width:767px){.product-line-grid-body{margin-bottom:1rem}}@media (max-width:575px){.cart-items{padding:1rem 0}.cart-item{border-bottom:1px solid #f1f1f1}.cart-item:last-child{border-bottom:0}.cart-grid-body .cart-overview{padding:0}.cart-grid-body .no-items{padding:1rem;display:inline-block}.product-line-grid-left{padding-right:0!important}}@media (max-width:360px){.product-line-grid-right .price,.product-line-grid-right .qty{width:100%}}#block-reassurance{margin-top:2rem}#block-reassurance img{width:1.563rem;margin-right:.625rem}#block-reassurance li{border-bottom:1px solid rgba(0,0,0,.25)}#block-reassurance li:last-child{border:0}#block-reassurance li .block-reassurance-item{padding:1rem 1.5rem}#product #block-reassurance{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}#product #block-reassurance span{font-weight:700}.quickview .modal-dialog{width:calc(100% - 30px);max-width:64rem}.quickview .modal-content{background:#f1f1f1;min-height:28.13rem}.quickview .modal-header{border:none;padding:.625rem}.quickview .modal-body{min-height:23.75rem}.quickview .modal-footer{border-top:1px solid hsla(0,0%,48%,.3)}.quickview .layer{display:none}.quickview .product-cover img{width:95%}.quickview .images-container{display:-webkit-box;display:-ms-flexbox;display:flex;z-index:1;min-height:21.88rem}.quickview .images-container .product-images>li.thumb-container>.thumb{width:100%;max-width:4.938rem;margin-bottom:.8125rem;background:#fff}.quickview .mask{width:35%;max-height:22.5rem;overflow:hidden;margin-left:.625rem}.quickview .arrows{position:absolute;top:0;bottom:0;max-height:22.5rem;right:5rem;z-index:0}.quickview .arrows .arrow-up{margin-top:-3.125rem;cursor:pointer;opacity:.2}.quickview .arrows .arrow-down{position:absolute;bottom:-1.875rem;cursor:pointer}.quickview .social-sharing{margin-top:0;margin-left:2.5rem}#stores .page-stores{width:85%;margin:0 auto}#stores .page-stores .store-item{padding-left:.75rem;padding-right:.75rem}#stores .page-stores .store-picture img{max-width:100%}#stores .page-stores .store-item-container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:1.875rem 0}#stores .page-stores .store-item-container ul{margin-bottom:0;font-size:.9375rem}#stores .page-stores .store-item-container .divide-left{border-left:1px solid #f1f1f1}#stores .page-stores .store-item-container .divide-left tr{height:1.563rem}#stores .page-stores .store-item-container .divide-left td{padding-left:.375rem}#stores .page-stores .store-item-container .divide-left th{text-align:right}#stores .page-stores .store-item-container .store-description{font-size:1rem}#stores .page-stores .store-item-footer{margin-top:.5rem;padding-top:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around}#stores .page-stores .store-item-footer.divide-top{border-top:1px solid #f1f1f1}#stores .page-stores .store-item-footer div:first-child{-webkit-box-flex:0;-ms-flex:0 0 65%;flex:0 0 65%}#stores .page-stores .store-item-footer i.material-icons{margin-right:.625rem;color:#7a7a7a;font-size:1rem}#stores .page-stores .store-item-footer li{margin-bottom:.625rem}@media (max-width:767px){#stores .page-stores{width:100%}#stores .page-stores .store-item-container{padding:1rem 0}}@media (max-width:575px){#stores .page-stores .store-item-container{display:block}#stores .page-stores .store-item-container .divide-left{border-left:none}#stores .page-stores .store-item-container .store-description a,#stores .page-stores .store-item-container .store-description address{margin-bottom:.5rem}#stores .page-stores .store-item-footer{display:block}#stores .page-stores .store-item-footer.divide-top{border-top:1px solid #f1f1f1}#stores .page-stores .store-item-footer li{margin-bottom:.625rem}#stores .page-stores .store-item-footer .card-block{padding:.75rem .75rem 0}}.block_newsletter{font-size:.875rem;margin-bottom:.625rem}.block_newsletter form{position:relative}.block_newsletter form input[type=text]{border:none;padding:10px;min-width:255px;color:#7a7a7a;border:1px solid rgba(0,0,0,.25)}.block_newsletter form input[type=text]:focus{outline:3px solid #2fb5d2;color:#232323;background:#fff}.block_newsletter form input[type=text]:focus+button .search{color:#2fb5d2}.block_newsletter form button[type=submit]{position:absolute;background:none;border:none;bottom:.3125rem;right:.125rem;color:#7a7a7a}.block_newsletter form button[type=submit] .search:hover{color:#2fb5d2}.block_newsletter p{padding-top:.625rem}.block_newsletter form .input-wrapper{overflow:hidden}.block_newsletter form input[type=email]{padding:11px;width:100%}.block_newsletter form input[type=email]:focus{border:3px solid #2fb5d2;padding:8px 8px 9px;outline:0}.block_newsletter form input{height:42px;box-shadow:none}.block-contact{color:#7a7a7a}.block-contact .block-contact-title,.linklist .blockcms-title a{color:#232323}.account-list a{color:#7a7a7a}.account-list a:hover{color:#2fb5d2}.block-contact-title,.blockcms-title,.myaccount-title,.myaccount-title a{font-weight:700;font-size:1rem}.block-social{text-align:right}.block-social ul{display:-webkit-box;display:-ms-flexbox;display:flex}@media (max-width:767px){.block-social ul{-ms-flex-flow:wrap;flex-flow:wrap}}.block-social ul li{height:2.5rem;width:2.5rem;background-color:#f1f1f1;background-repeat:no-repeat;display:inline-block;margin:.125rem;cursor:pointer}@media (max-width:767px){.block-social ul li{height:2rem;width:2rem;margin-right:1.3rem;margin-bottom:1.3rem;background-size:contain}}.block-social ul li:hover{background-color:#2fb5d2}.block-social ul li a{display:block;height:100%;white-space:nowrap;text-indent:100%;overflow:hidden}.block-social ul li a:hover{color:transparent}.facebook{background-image:url(../css/3935e107ea61866e60d7946dc6a962f1.svg)}.facebook:before{content:"";background-image:url(../css/8b05d51ede908907d65695558974d86f.svg)}.facebook.icon-gray{background-image:url(../css/082a71677e756fb75817e8f262a07cb4.svg)}.facebook.icon-gray:hover{background-image:url(../css/8b05d51ede908907d65695558974d86f.svg)}.twitter{background-image:url(../css/a67175d1ea11389d9107bd8c08f9d7d7.svg)}.twitter:before{content:"";background-image:url(../css/ffddcb3736980b23405b31142a324b62.svg)}.twitter.icon-gray{background-image:url(../css/e049aeb07a2ae1627933e8e58d3886d2.svg)}.twitter.icon-gray:hover{background-image:url(../css/ffddcb3736980b23405b31142a324b62.svg)}.rss{background-image:url(../css/cf2f3c1d5c7cb02c29f61964313148e1.svg)}.youtube{background-image:url(../css/22c0528acb6d9cd5bf4c8f96381bc05c.svg)}.googleplus{background-image:url(../css/36bff72dcba3098b4b70b482b22c29ab.svg)}.googleplus:before{content:"";background-image:url(../css/c1a65805f759901a39d10eb854c1dcf2.svg)}.googleplus.icon-gray{background-image:url(../css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg)}.googleplus.icon-gray:hover{background-image:url(../css/c1a65805f759901a39d10eb854c1dcf2.svg)}#block_myaccount_infos .myaccount-title a{color:#232323}.pinterest{background-image:url(../css/afb2ed6d67613a724a420a39b4fe5b0d.svg)}.pinterest:before{content:"";background-image:url(../css/b1db819132e64a3e01911a1413c33acf.svg)}.pinterest.icon-gray{background-image:url(../css/99db8adec61e4fcf5586e1afa549b432.svg)}.pinterest.icon-gray:hover{background-image:url(../css/b1db819132e64a3e01911a1413c33acf.svg)}.vimeo{background-image:url(../css/f255af0bbbe837e79f7821827f9c6f10.svg)}.instagram{background-image:url(../css/0266b05265f317a7409560b751cd61e8.svg)}.footer-container{margin-top:1.25rem;padding-top:1.25rem;overflow:hidden;box-shadow:2px 2px 11px 0 rgba(0,0,0,.3)}.footer-container li{margin-bottom:.3125rem}.footer-container li a{color:#7a7a7a;cursor:pointer;font-size:.875rem}.footer-container li a:hover{color:#2fb5d2}.links .collapse{display:inherit}@media (max-width:767px){.block_newsletter{padding-bottom:.625rem;border-bottom:1px solid #f6f6f6}.footer-container{box-shadow:none;margin-top:0}.footer-container .wrapper{padding-left:0!important;padding-right:0!important}.footer-container .links .h3{line-height:1.5;font-size:1rem}.footer-container .links ul{background-color:#f6f6f6;margin-bottom:0}.footer-container .links ul>li{padding:.625rem;border-bottom:1px solid #fff;font-weight:700}.footer-container .links ul>li a{color:#232323}.links .collapse{display:none}.links .collapse.in{display:block}.links .title{padding:.625rem;border-bottom:1px solid #f6f6f6;cursor:pointer}.links .title .collapse-icons .remove,.links .title[aria-expanded=true] .collapse-icons .add{display:none}.links .title[aria-expanded=true] .collapse-icons .remove{display:block}.links .navbar-toggler{display:inline-block;padding:0}}@media (max-width:991px){.block-social{text-align:center}.block-contact{padding-left:1.5rem}}.contact-rich{color:#7a7a7a;margin-bottom:2rem;word-wrap:break-word}.contact-rich h4{text-transform:uppercase;color:#232323;margin-bottom:2rem}.contact-rich .block{height:auto;overflow:hidden}.contact-rich .block .icon{float:left;width:3.5rem}.contact-rich .block .icon i{font-size:2rem}.contact-rich .block .data{color:#232323;font-size:.875rem;width:auto;overflow:hidden}.contact-rich .block .data.email{padding-top:.375rem}.contact-rich .block a[href^="mailto:"]{clear:both;margin-top:1rem}@media (min-width:576px){.contact-rich .block a[href^="mailto:"]{font-size:.815rem}}.contact-form{background:#fff;padding:1rem;color:#7a7a7a;width:100%}.contact-form h3{text-transform:uppercase;color:#232323}#pagenotfound #main .page-header,#products #main .page-header{margin:2rem 0 3rem}#pagenotfound #main .page-content,#products #main .page-content{margin-bottom:10rem}#pagenotfound .page-not-found,#products .page-not-found{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;font-size:.875rem;color:#7a7a7a;max-width:570px;margin:0 auto}#pagenotfound .page-not-found h4,#products .page-not-found h4{font-size:1rem;font-weight:700;margin:.5rem 0 1rem}#pagenotfound .page-not-found .search-widget,#products .page-not-found .search-widget{float:none}#pagenotfound .page-not-found .search-widget input,#products .page-not-found .search-widget input{width:100%}.customization-modal .modal-content{border-radius:0;border:1px solid #f6f6f6}.customization-modal .modal-content .modal-body{padding-top:0}.customization-modal .modal-content .modal-body .product-customization-line{padding-bottom:.9375rem;padding-top:.9375rem;border-bottom:1px solid #f6f6f6}.customization-modal .modal-content .modal-body .product-customization-line .label{font-weight:700;text-align:right}.customization-modal .modal-content .modal-body .product-customization-line:last-child{padding-bottom:0;border-bottom:0}.sitemap-title{text-transform:capitalize}.sitemap{margin-top:.9375rem}.sitemap h2{color:#232323;text-transform:uppercase;font-size:1.1rem;font-weight:600;border-bottom:1px solid #7a7a7a;margin-left:-15px;width:100%;height:35px}.sitemap ul{margin-left:-15px;margin-top:20px}.sitemap ul.nested{margin-left:20px}.sitemap ul li{font-size:.9rem;margin-bottom:1rem}@media (max-width:575px){.sitemap{margin-top:0}}#header{background:#fff;color:#7a7a7a}#header .logo{max-width:100%}#header a{color:#232323}#header a:hover{text-decoration:none;color:#2fb5d2}#header .menu,#header .menu>ul>li{display:inline-block}#header .header-nav{border-bottom:2px solid #f1f1f1;max-height:50px;margin-bottom:30px}#header .header-nav #menu-icon{vertical-align:middle;cursor:pointer;margin:0 1rem}#header .header-nav #menu-icon .material-icons{line-height:50px}#header .header-nav .right-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}#header .header-nav .currency-selector{margin-top:.9375rem;margin-left:.9375rem;white-space:nowrap}#header .header-nav .user-info{margin-left:2.5rem;margin-top:.9375rem;text-align:right;white-space:nowrap}#header .header-nav .user-info .account{margin-left:.625rem}#header .header-nav .language-selector{margin-top:.9375rem;white-space:nowrap}#header .header-nav .cart-preview.active{background:#2fb5d2}#header .header-nav .cart-preview.active a,#header .header-nav .cart-preview.active i{color:#fff}#header .header-nav .cart-preview .shopping-cart{vertical-align:middle;color:#7a7a7a}#header .header-nav .cart-preview .body{display:none}#header .header-nav .blockcart{background:#f1f1f1;height:3rem;padding:.75rem;margin-left:.9375rem;text-align:center;white-space:nowrap}#header .header-nav .blockcart a{color:#7a7a7a}#header .header-nav .blockcart a:hover{color:#2fb5d2}#header .header-nav .blockcart.active a:hover{color:#fff}#header .header-nav .blockcart .header{margin-top:.125rem}#header .header-nav #_desktop_contact_link{display:inline-block}#header .header-nav #_desktop_contact_link #contact-link{margin-top:.9375rem}#header .header-nav .search-widget{margin-top:.2rem}#header .header-nav .material-icons{line-height:inherit}#header .header-nav .material-icons.expand-more{margin-left:-.375rem}#header .header-top{padding-bottom:1.25rem}#header .header-top>.container{position:relative}#header .header-top .menu{padding-left:15px;margin-bottom:.375rem}#header .header-top .position-static{position:static}#header .header-top a[data-depth="0"]{color:#7a7a7a;text-transform:uppercase}#header .header-top .search-widget{float:right}#header .top-menu-link{margin-left:1.25rem}.popover{font-family:inherit}#wrapper{background:#f1f1f1;box-shadow:inset 0 2px 5px 0 rgba(0,0,0,.11);padding-top:1.563rem}#wrapper .banner{margin-bottom:1.5rem;display:block}#wrapper .banner img{box-shadow:1px 1px 7px 0 rgba(0,0,0,.15)}#wrapper .breadcrumb{background:transparent;padding:0}#wrapper .breadcrumb[data-depth="1"]{display:none}#wrapper .breadcrumb ol{padding-left:0;margin-bottom:0}#wrapper .breadcrumb li{display:inline}#wrapper .breadcrumb li:after{content:"/";color:#7a7a7a;margin:.3125rem}#wrapper .breadcrumb li:last-child{content:"/";color:#7a7a7a;margin:0}#wrapper .breadcrumb li:last-child:after{content:""}#wrapper .breadcrumb li a{color:#232323}#main .page-content,#main .page-header{margin-bottom:1.563rem}#main .page-content h6{margin-bottom:1.125rem}#main .page-content #notifications{margin-left:-15px;margin-right:-15px}#main .page-footer{margin-bottom:1.563rem}#notifications ul{margin-bottom:0}#footer{padding-top:2.5rem}@media (max-width:1199px){#header .header-nav{max-height:inherit}#header .header-nav .search-widget{float:none;width:15.63rem}}@media (max-width:991px){.container{max-width:100%}#header .logo{width:auto}#header .header-top .search-widget{min-width:inherit}#products .product-miniature,.featured-products .product-miniature{margin:0 auto}.sub-menu{left:0;min-width:100%}#blockcart-modal .product-image{width:100%;display:block;max-width:15.63rem;margin:0 auto .9375rem}#blockcart-modal .cart-content{padding-left:0}#blockcart-modal .product-name,#product-availability{margin-top:.625rem}#search_filters .facet .facet-label{text-align:left}.block-category .category-cover{position:relative;text-align:center}.block-category{padding-bottom:0}}@media (max-width:767px){#wrapper{box-shadow:none}#checkout-cart-summary{float:none;width:100%;margin-top:1rem}#header{background:#f1f1f1}#header .header-nav{background:#fff;margin-bottom:.625rem;color:#232323}#header .header-nav .top-logo{padding-top:11px}#header .header-nav .top-logo a img{max-height:50px;max-width:100%}#header .header-nav .right-nav{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#header .header-nav .user-info{text-align:left;margin-left:0}#header .header-nav .user-info .logged{color:#2fb5d2}#header .header-nav .blockcart{margin-left:0;background:inherit}#header .header-nav .blockcart.active{margin-left:.5rem}#header .header-nav .blockcart.inactive .cart-products-count{display:none}#header .header-top{background:#f1f1f1;padding-bottom:0}#header .header-top a[data-depth="0"]{color:#232323}#header .header-top .search-widget{width:100%}#header.is-open,#header.is-open .header-top{background-color:#fff}section.checkout-step{width:100%}.default-input{min-width:100%}label{clear:both}#products .product-miniature,.featured-products .product-miniature{margin:0 auto}.block-contact{padding-left:.9375rem;border:none}.dropdown-item,.menu{padding-left:0}#footer{padding-top:.5rem}}@media (max-width:575px){#content-wrapper,#left-column{padding-left:0!important;padding-right:0!important}}input[type=number]{-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0} \ No newline at end of file diff --git a/themes/classic/assets/css/theme.rtlfix b/themes/classic/assets/css/theme.rtlfix deleted file mode 100644 index d7e46956..00000000 --- a/themes/classic/assets/css/theme.rtlfix +++ /dev/null @@ -1,41 +0,0 @@ -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir.ttf') format('truetype'); - font-weight: normal; -} - -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.ttf') format('truetype'); - font-weight: bold; -} - -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.ttf') format('truetype'); - font-weight: 300; -} -body.lang-fa{ - font-family: "Vazir",sans-serif; -} -.rtl-flip:not(.rtl-no-flip), .material-icons:not(.rtl-no-flip) { - -moz-transform: scaleX(-1); - -o-transform: scaleX(-1); - -webkit-transform: scaleX(-1); - transform: scaleX(-1); - filter: FlipH; - -ms-filter: "FlipH"; -} -.magnitude:before { - content: "?"; - opacity: 0; -} diff --git a/themes/classic/assets/css/theme_rtl.css b/themes/classic/assets/css/theme_rtl.css deleted file mode 100644 index e9d83a92..00000000 --- a/themes/classic/assets/css/theme_rtl.css +++ /dev/null @@ -1,48 +0,0 @@ -.bootstrap-touchspin .input-group-btn-vertical{position:relative;white-space:nowrap;width:1%;vertical-align:middle;display:table-cell}.bootstrap-touchspin .input-group-btn-vertical>.btn{display:block;float:none;width:100%;max-width:100%;padding:8px 10px;margin-right:-1px;position:relative}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0;border-top-left-radius:4px}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{margin-top:-2px;border-radius:0;border-bottom-left-radius:4px}.bootstrap-touchspin .input-group-btn-vertical i{position:absolute;top:3px;right:5px;font-size:9px;font-weight:400}/*! - * Bootstrap v4.0.0-alpha.5 (https://getbootstrap.com) - * Copyright 2011-2016 The Bootstrap Authors - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}[hidden],template{display:none}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,optgroup,select,textarea{font:inherit;margin:0}optgroup{font-weight:700}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}@media print{*,:after,:before,:first-letter,blockquote:first-line,div:first-line,li:first-line,p:first-line{text-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.tag{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}@-ms-viewport{width:device-width}html{font-size:16px;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;line-height:1.5;color:#363a42;background-color:#fff}[tabindex="-1"]:focus{outline:none!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #f1f1f1}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}a{color:#2fb5d2;text-decoration:none}a:focus,a:hover{color:#208094;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:not([href]):not([tabindex]),a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:none}pre{overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#7a7a7a;caption-side:bottom}caption,th{text-align:right}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:700;line-height:1.1;color:inherit}.h1,h1{font-size:1.375rem}.h2,h2{font-size:1.25rem}.h3,.h4,h3,h4{font-size:1.125rem}.h5,h5{font-size:1rem}.h6,h6{font-size:.9375rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:3.125rem;font-weight:600}.display-2{font-size:2.188rem;font-weight:400}.display-3{font-size:1.563rem;font-weight:400}.display-4{font-size:1.25rem;font-weight:400}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-right:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-left:5px}.initialism{font-size:90%;text-transform:uppercase}.blockquote{padding:.5rem 1rem;margin-bottom:1rem;font-size:1.25rem;border-right:.25rem solid #f6f6f6}.blockquote-footer{display:block;font-size:80%;color:#f1f1f1}.blockquote-footer:before{content:"\2014 \A0"}.blockquote-reverse{padding-left:1rem;padding-right:0;text-align:left;border-left:.25rem solid #f6f6f6;border-right:0}.blockquote-reverse .blockquote-footer:before{content:""}.blockquote-reverse .blockquote-footer:after{content:"\A0 \2014"}dl.row>dd+dt{clear:right}.carousel-inner>.carousel-item>a>img,.carousel-inner>.carousel-item>img,.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #ddd;border-radius:0;transition:all .2s ease-in-out}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#f1f1f1}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}code{color:#bd4147;background-color:#f7f7f9;border-radius:0}code,kbd{padding:.2rem .4rem;font-size:90%}kbd{color:#fff;background-color:#333;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;margin-top:0;margin-bottom:1rem;font-size:90%;color:#363a42}pre code{padding:0;font-size:inherit;color:inherit;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-right:15px;padding-left:15px}.container:after{content:"";display:table;clear:both}@media (min-width:576px){.container{width:540px;max-width:100%}}@media (min-width:768px){.container{width:720px;max-width:100%}}@media (min-width:992px){.container{width:960px;max-width:100%}}@media (min-width:1200px){.container{width:1140px;max-width:100%}}.container-fluid{margin-right:auto;margin-left:auto;padding-right:15px;padding-left:15px}.container-fluid:after{content:"";display:table;clear:both}.row{margin-left:-15px;margin-right:-15px}.row:after{content:"";display:table;clear:both}@media (min-width:576px){.row{margin-left:-15px;margin-right:-15px}}@media (min-width:768px){.row{margin-left:-15px;margin-right:-15px}}@media (min-width:992px){.row{margin-left:-15px;margin-right:-15px}}@media (min-width:1200px){.row{margin-left:-15px;margin-right:-15px}}.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}@media (min-width:576px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-left:15px;padding-right:15px}}@media (min-width:768px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-left:15px;padding-right:15px}}@media (min-width:992px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-left:15px;padding-right:15px}}@media (min-width:1200px){.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{padding-left:15px;padding-right:15px}}.col-xs-1{float:right;width:8.33333%}.col-xs-2{float:right;width:16.66667%}.col-xs-3{float:right;width:25%}.col-xs-4{float:right;width:33.33333%}.col-xs-5{float:right;width:41.66667%}.col-xs-6{float:right;width:50%}.col-xs-7{float:right;width:58.33333%}.col-xs-8{float:right;width:66.66667%}.col-xs-9{float:right;width:75%}.col-xs-10{float:right;width:83.33333%}.col-xs-11{float:right;width:91.66667%}.col-xs-12{float:right;width:100%}.pull-xs-0{left:auto}.pull-xs-1{left:8.33333%}.pull-xs-2{left:16.66667%}.pull-xs-3{left:25%}.pull-xs-4{left:33.33333%}.pull-xs-5{left:41.66667%}.pull-xs-6{left:50%}.pull-xs-7{left:58.33333%}.pull-xs-8{left:66.66667%}.pull-xs-9{left:75%}.pull-xs-10{left:83.33333%}.pull-xs-11{left:91.66667%}.pull-xs-12{left:100%}.push-xs-0{right:auto}.push-xs-1{right:8.33333%}.push-xs-2{right:16.66667%}.push-xs-3{right:25%}.push-xs-4{right:33.33333%}.push-xs-5{right:41.66667%}.push-xs-6{right:50%}.push-xs-7{right:58.33333%}.push-xs-8{right:66.66667%}.push-xs-9{right:75%}.push-xs-10{right:83.33333%}.push-xs-11{right:91.66667%}.push-xs-12{right:100%}.offset-xs-1{margin-right:8.33333%}.offset-xs-2{margin-right:16.66667%}.offset-xs-3{margin-right:25%}.offset-xs-4{margin-right:33.33333%}.offset-xs-5{margin-right:41.66667%}.offset-xs-6{margin-right:50%}.offset-xs-7{margin-right:58.33333%}.offset-xs-8{margin-right:66.66667%}.offset-xs-9{margin-right:75%}.offset-xs-10{margin-right:83.33333%}.offset-xs-11{margin-right:91.66667%}@media (min-width:576px){.col-sm-1{float:right;width:8.33333%}.col-sm-2{float:right;width:16.66667%}.col-sm-3{float:right;width:25%}.col-sm-4{float:right;width:33.33333%}.col-sm-5{float:right;width:41.66667%}.col-sm-6{float:right;width:50%}.col-sm-7{float:right;width:58.33333%}.col-sm-8{float:right;width:66.66667%}.col-sm-9{float:right;width:75%}.col-sm-10{float:right;width:83.33333%}.col-sm-11{float:right;width:91.66667%}.col-sm-12{float:right;width:100%}.pull-sm-0{left:auto}.pull-sm-1{left:8.33333%}.pull-sm-2{left:16.66667%}.pull-sm-3{left:25%}.pull-sm-4{left:33.33333%}.pull-sm-5{left:41.66667%}.pull-sm-6{left:50%}.pull-sm-7{left:58.33333%}.pull-sm-8{left:66.66667%}.pull-sm-9{left:75%}.pull-sm-10{left:83.33333%}.pull-sm-11{left:91.66667%}.pull-sm-12{left:100%}.push-sm-0{right:auto}.push-sm-1{right:8.33333%}.push-sm-2{right:16.66667%}.push-sm-3{right:25%}.push-sm-4{right:33.33333%}.push-sm-5{right:41.66667%}.push-sm-6{right:50%}.push-sm-7{right:58.33333%}.push-sm-8{right:66.66667%}.push-sm-9{right:75%}.push-sm-10{right:83.33333%}.push-sm-11{right:91.66667%}.push-sm-12{right:100%}.offset-sm-0{margin-right:0}.offset-sm-1{margin-right:8.33333%}.offset-sm-2{margin-right:16.66667%}.offset-sm-3{margin-right:25%}.offset-sm-4{margin-right:33.33333%}.offset-sm-5{margin-right:41.66667%}.offset-sm-6{margin-right:50%}.offset-sm-7{margin-right:58.33333%}.offset-sm-8{margin-right:66.66667%}.offset-sm-9{margin-right:75%}.offset-sm-10{margin-right:83.33333%}.offset-sm-11{margin-right:91.66667%}}@media (min-width:768px){.col-md-1{float:right;width:8.33333%}.col-md-2{float:right;width:16.66667%}.col-md-3{float:right;width:25%}.col-md-4{float:right;width:33.33333%}.col-md-5{float:right;width:41.66667%}.col-md-6{float:right;width:50%}.col-md-7{float:right;width:58.33333%}.col-md-8{float:right;width:66.66667%}.col-md-9{float:right;width:75%}.col-md-10{float:right;width:83.33333%}.col-md-11{float:right;width:91.66667%}.col-md-12{float:right;width:100%}.pull-md-0{left:auto}.pull-md-1{left:8.33333%}.pull-md-2{left:16.66667%}.pull-md-3{left:25%}.pull-md-4{left:33.33333%}.pull-md-5{left:41.66667%}.pull-md-6{left:50%}.pull-md-7{left:58.33333%}.pull-md-8{left:66.66667%}.pull-md-9{left:75%}.pull-md-10{left:83.33333%}.pull-md-11{left:91.66667%}.pull-md-12{left:100%}.push-md-0{right:auto}.push-md-1{right:8.33333%}.push-md-2{right:16.66667%}.push-md-3{right:25%}.push-md-4{right:33.33333%}.push-md-5{right:41.66667%}.push-md-6{right:50%}.push-md-7{right:58.33333%}.push-md-8{right:66.66667%}.push-md-9{right:75%}.push-md-10{right:83.33333%}.push-md-11{right:91.66667%}.push-md-12{right:100%}.offset-md-0{margin-right:0}.offset-md-1{margin-right:8.33333%}.offset-md-2{margin-right:16.66667%}.offset-md-3{margin-right:25%}.offset-md-4{margin-right:33.33333%}.offset-md-5{margin-right:41.66667%}.offset-md-6{margin-right:50%}.offset-md-7{margin-right:58.33333%}.offset-md-8{margin-right:66.66667%}.offset-md-9{margin-right:75%}.offset-md-10{margin-right:83.33333%}.offset-md-11{margin-right:91.66667%}}@media (min-width:992px){.col-lg-1{float:right;width:8.33333%}.col-lg-2{float:right;width:16.66667%}.col-lg-3{float:right;width:25%}.col-lg-4{float:right;width:33.33333%}.col-lg-5{float:right;width:41.66667%}.col-lg-6{float:right;width:50%}.col-lg-7{float:right;width:58.33333%}.col-lg-8{float:right;width:66.66667%}.col-lg-9{float:right;width:75%}.col-lg-10{float:right;width:83.33333%}.col-lg-11{float:right;width:91.66667%}.col-lg-12{float:right;width:100%}.pull-lg-0{left:auto}.pull-lg-1{left:8.33333%}.pull-lg-2{left:16.66667%}.pull-lg-3{left:25%}.pull-lg-4{left:33.33333%}.pull-lg-5{left:41.66667%}.pull-lg-6{left:50%}.pull-lg-7{left:58.33333%}.pull-lg-8{left:66.66667%}.pull-lg-9{left:75%}.pull-lg-10{left:83.33333%}.pull-lg-11{left:91.66667%}.pull-lg-12{left:100%}.push-lg-0{right:auto}.push-lg-1{right:8.33333%}.push-lg-2{right:16.66667%}.push-lg-3{right:25%}.push-lg-4{right:33.33333%}.push-lg-5{right:41.66667%}.push-lg-6{right:50%}.push-lg-7{right:58.33333%}.push-lg-8{right:66.66667%}.push-lg-9{right:75%}.push-lg-10{right:83.33333%}.push-lg-11{right:91.66667%}.push-lg-12{right:100%}.offset-lg-0{margin-right:0}.offset-lg-1{margin-right:8.33333%}.offset-lg-2{margin-right:16.66667%}.offset-lg-3{margin-right:25%}.offset-lg-4{margin-right:33.33333%}.offset-lg-5{margin-right:41.66667%}.offset-lg-6{margin-right:50%}.offset-lg-7{margin-right:58.33333%}.offset-lg-8{margin-right:66.66667%}.offset-lg-9{margin-right:75%}.offset-lg-10{margin-right:83.33333%}.offset-lg-11{margin-right:91.66667%}}@media (min-width:1200px){.col-xl-1{float:right;width:8.33333%}.col-xl-2{float:right;width:16.66667%}.col-xl-3{float:right;width:25%}.col-xl-4{float:right;width:33.33333%}.col-xl-5{float:right;width:41.66667%}.col-xl-6{float:right;width:50%}.col-xl-7{float:right;width:58.33333%}.col-xl-8{float:right;width:66.66667%}.col-xl-9{float:right;width:75%}.col-xl-10{float:right;width:83.33333%}.col-xl-11{float:right;width:91.66667%}.col-xl-12{float:right;width:100%}.pull-xl-0{left:auto}.pull-xl-1{left:8.33333%}.pull-xl-2{left:16.66667%}.pull-xl-3{left:25%}.pull-xl-4{left:33.33333%}.pull-xl-5{left:41.66667%}.pull-xl-6{left:50%}.pull-xl-7{left:58.33333%}.pull-xl-8{left:66.66667%}.pull-xl-9{left:75%}.pull-xl-10{left:83.33333%}.pull-xl-11{left:91.66667%}.pull-xl-12{left:100%}.push-xl-0{right:auto}.push-xl-1{right:8.33333%}.push-xl-2{right:16.66667%}.push-xl-3{right:25%}.push-xl-4{right:33.33333%}.push-xl-5{right:41.66667%}.push-xl-6{right:50%}.push-xl-7{right:58.33333%}.push-xl-8{right:66.66667%}.push-xl-9{right:75%}.push-xl-10{right:83.33333%}.push-xl-11{right:91.66667%}.push-xl-12{right:100%}.offset-xl-0{margin-right:0}.offset-xl-1{margin-right:8.33333%}.offset-xl-2{margin-right:16.66667%}.offset-xl-3{margin-right:25%}.offset-xl-4{margin-right:33.33333%}.offset-xl-5{margin-right:41.66667%}.offset-xl-6{margin-right:50%}.offset-xl-7{margin-right:58.33333%}.offset-xl-8{margin-right:66.66667%}.offset-xl-9{margin-right:75%}.offset-xl-10{margin-right:83.33333%}.offset-xl-11{margin-right:91.66667%}}.table{width:100%;max-width:100%;margin-bottom:1rem}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #f6f6f6}.table thead th{vertical-align:bottom;border-bottom:2px solid #f6f6f6}.table tbody+tbody{border-top:2px solid #f6f6f6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #f6f6f6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th,.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-success,.table-success>td,.table-success>th{background-color:#dff0d8}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#d0e9c6}.table-info,.table-info>td,.table-info>th{background-color:#d9edf7}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#c4e3f3}.table-warning,.table-warning>td,.table-warning>th{background-color:#fcf8e3}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#faf2cc}.table-danger,.table-danger>td,.table-danger>th{background-color:#f2dede}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#ebcccc}.thead-inverse th{color:#fff;background-color:#363a42}.thead-default th{color:#7a7a7a;background-color:#f6f6f6}.table-inverse{color:#f6f6f6;background-color:#363a42}.table-inverse td,.table-inverse th,.table-inverse thead th{border-color:#7a7a7a}.table-inverse.table-bordered{border:0}.table-responsive{display:block;width:100%;min-height:0;overflow-x:auto}.table-reflow thead{float:right}.table-reflow tbody{display:block;white-space:nowrap}.table-reflow td,.table-reflow th{border-top:1px solid #f6f6f6;border-right:1px solid #f6f6f6}.table-reflow td:last-child,.table-reflow th:last-child{border-left:1px solid #f6f6f6}.table-reflow tbody:last-child tr:last-child td,.table-reflow tbody:last-child tr:last-child th,.table-reflow tfoot:last-child tr:last-child td,.table-reflow tfoot:last-child tr:last-child th,.table-reflow thead:last-child tr:last-child td,.table-reflow thead:last-child tr:last-child th{border-bottom:1px solid #f6f6f6}.table-reflow tr{float:right}.table-reflow tr td,.table-reflow tr th{display:block!important;border:1px solid #f6f6f6}.form-control{display:block;width:100%;padding:.5rem .75rem;font-size:1rem;line-height:1.25;background-color:#fff;background-image:none;background-clip:padding-box;border-radius:0}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#7a7a7a;border-color:#66afe9;outline:none}.form-control::-webkit-input-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999;opacity:1}.form-control::placeholder{color:#999;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#f6f6f6;opacity:1}.form-control:disabled{cursor:not-allowed}select.form-control:not([size]):not([multiple]){height:calc(2.5rem - 2px)}select.form-control:focus::-ms-value{color:#7a7a7a;background-color:#fff}.form-control-file,.form-control-range{display:block}.col-form-label{padding-top:.5rem;padding-bottom:.5rem;margin-bottom:0}.col-form-label-lg{padding-top:.75rem;padding-bottom:.75rem;font-size:.9375rem}.col-form-label-sm{padding-top:.25rem;padding-bottom:.25rem;font-size:.875rem}.col-form-legend{margin-bottom:0;font-size:1rem}.col-form-legend,.form-control-static{padding-top:.5rem;padding-bottom:.5rem}.form-control-static{line-height:1.25;border:solid transparent;border-width:1px 0}.form-control-static.form-control-lg,.form-control-static.form-control-sm,.input-group-lg>.form-control-static.form-control,.input-group-lg>.form-control-static.input-group-addon,.input-group-lg>.input-group-btn>.form-control-static.btn,.input-group-sm>.form-control-static.form-control,.input-group-sm>.form-control-static.input-group-addon,.input-group-sm>.input-group-btn>.form-control-static.btn{padding-left:0;padding-right:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-sm>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),.input-group-sm>select.input-group-addon:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:1.8125rem}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.input-group-lg>.input-group-btn>select.btn:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),.input-group-lg>select.input-group-addon:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:2.75rem}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-check{position:relative;display:block;margin-bottom:.75rem}.form-check+.form-check{margin-top:-.25rem}.form-check.disabled .form-check-label{color:#7a7a7a;cursor:not-allowed}.form-check-label{padding-right:1.25rem;margin-bottom:0;cursor:pointer}.form-check-input{position:absolute;margin-top:.25rem;margin-right:-1.25rem}.form-check-input:only-child{position:static}.form-check-inline{position:relative;display:inline-block;padding-right:1.25rem;margin-bottom:0;vertical-align:middle;cursor:pointer}.form-check-inline+.form-check-inline{margin-right:.75rem}.form-check-inline.disabled{color:#7a7a7a;cursor:not-allowed}.form-control-feedback{margin-top:.25rem}.form-control-danger,.form-control-success,.form-control-warning{padding-left:2.25rem;background-repeat:no-repeat;background-position:center left .625rem;background-size:1.25rem 1.25rem}.has-success .custom-control,.has-success .form-check-inline,.has-success .form-check-label,.has-success .form-control-feedback,.has-success .form-control-label{color:#4cbb6c}.has-success .form-control{border-color:#4cbb6c}.has-success .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #96d7a9}.has-success .input-group-addon{color:#4cbb6c;border-color:#4cbb6c;background-color:#e0f3e5}.has-success .form-control-success{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#4cbb6c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E")}.has-warning .custom-control,.has-warning .form-check-inline,.has-warning .form-check-label,.has-warning .form-control-feedback,.has-warning .form-control-label{color:#ff9a52}.has-warning .form-control{border-color:#ff9a52}.has-warning .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ffd6b8}.has-warning .input-group-addon{color:#ff9a52;border-color:#ff9a52;background-color:#fff}.has-warning .form-control-warning{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#ff9a52' d='M4.4 5.324h-.8v-2.46h.8zm0 1.42h-.8V5.89h.8zM3.76.63L.04 7.075c-.115.2.016.425.26.426h7.397c.242 0 .372-.226.258-.426C6.726 4.924 5.47 2.79 4.253.63c-.113-.174-.39-.174-.494 0z'/%3E%3C/svg%3E")}.has-danger .custom-control,.has-danger .form-check-inline,.has-danger .form-check-label,.has-danger .form-control-feedback,.has-danger .form-control-label{color:#ff4c4c}.has-danger .form-control{border-color:#ff4c4c}.has-danger .form-control:focus{box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ffb2b2}.has-danger .input-group-addon{color:#ff4c4c;border-color:#ff4c4c;background-color:#fff}.has-danger .form-control-danger{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#ff4c4c' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E")}@media (min-width:576px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;width:auto;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .form-check,.form-inline .form-control-label{margin-bottom:0;vertical-align:middle}.form-inline .form-check{display:inline-block;margin-top:0}.form-inline .form-check-label{padding-right:0}.form-inline .form-check-input{position:relative;margin-right:0}.form-inline .has-feedback .form-control-feedback{top:0}}.btn{display:inline-block;font-weight:400;line-height:1.25;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.5rem 1rem;font-size:1rem;border-radius:0}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0}.btn.disabled,.btn:disabled{cursor:not-allowed;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#2fb5d2;border-color:transparent}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#2592a9;border-color:transparent}.btn-primary.active,.btn-primary:active,.open>.btn-primary.dropdown-toggle{color:#fff;background-color:#2592a9;border-color:transparent;background-image:none}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.btn-primary.dropdown-toggle.focus,.open>.btn-primary.dropdown-toggle:focus,.open>.btn-primary.dropdown-toggle:hover{color:#fff;background-color:#1e788c;border-color:transparent}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary:disabled.focus,.btn-primary:disabled:focus,.btn-primary:disabled:hover{background-color:#2fb5d2;border-color:transparent}.btn-secondary,.btn-tertiary{color:#232323;background-color:#f6f6f6;border-color:transparent}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover,.btn-tertiary:focus,.btn-tertiary:hover,.focus.btn-tertiary{color:#232323;background-color:#ddd;border-color:transparent}.active.btn-tertiary,.btn-secondary.active,.btn-secondary:active,.btn-tertiary:active,.open>.btn-secondary.dropdown-toggle,.open>.dropdown-toggle.btn-tertiary{color:#232323;background-color:#ddd;border-color:transparent;background-image:none}.active.btn-tertiary:focus,.active.btn-tertiary:hover,.active.focus.btn-tertiary,.btn-secondary.active.focus,.btn-secondary.active:focus,.btn-secondary.active:hover,.btn-secondary:active.focus,.btn-secondary:active:focus,.btn-secondary:active:hover,.btn-tertiary:active.focus,.btn-tertiary:active:focus,.btn-tertiary:active:hover,.open>.btn-secondary.dropdown-toggle.focus,.open>.btn-secondary.dropdown-toggle:focus,.open>.btn-secondary.dropdown-toggle:hover,.open>.dropdown-toggle.btn-tertiary:focus,.open>.dropdown-toggle.btn-tertiary:hover,.open>.dropdown-toggle.focus.btn-tertiary{color:#232323;background-color:#cbcbcb;border-color:transparent}.btn-secondary.disabled.focus,.btn-secondary.disabled:focus,.btn-secondary.disabled:hover,.btn-secondary:disabled.focus,.btn-secondary:disabled:focus,.btn-secondary:disabled:hover,.btn-tertiary:disabled.focus,.btn-tertiary:disabled:focus,.btn-tertiary:disabled:hover,.disabled.btn-tertiary:focus,.disabled.btn-tertiary:hover,.disabled.focus.btn-tertiary{background-color:#f6f6f6;border-color:transparent}.btn-info{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#2aabd2}.btn-info.active,.btn-info:active,.open>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;border-color:#2aabd2;background-image:none}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.btn-info.dropdown-toggle.focus,.open>.btn-info.dropdown-toggle:focus,.open>.btn-info.dropdown-toggle:hover{color:#fff;background-color:#269abc;border-color:#1f7e9a}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info:disabled.focus,.btn-info:disabled:focus,.btn-info:disabled:hover{background-color:#5bc0de;border-color:#5bc0de}.btn-success{color:#fff;background-color:#4cbb6c;border-color:#4cbb6c}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#3a9a56;border-color:#389252}.btn-success.active,.btn-success:active,.open>.btn-success.dropdown-toggle{color:#fff;background-color:#3a9a56;border-color:#389252;background-image:none}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.btn-success.dropdown-toggle.focus,.open>.btn-success.dropdown-toggle:focus,.open>.btn-success.dropdown-toggle:hover{color:#fff;background-color:#318047;border-color:#256237}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success:disabled.focus,.btn-success:disabled:focus,.btn-success:disabled:hover{background-color:#4cbb6c;border-color:#4cbb6c}.btn-warning{color:#fff;background-color:#ff9a52;border-color:#ff9a52}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#fff;background-color:#ff7c1f;border-color:#ff7615}.btn-warning.active,.btn-warning:active,.open>.btn-warning.dropdown-toggle{color:#fff;background-color:#ff7c1f;border-color:#ff7615;background-image:none}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.btn-warning.dropdown-toggle.focus,.open>.btn-warning.dropdown-toggle:focus,.open>.btn-warning.dropdown-toggle:hover{color:#fff;background-color:#fa6800;border-color:#d25700}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning:disabled.focus,.btn-warning:disabled:focus,.btn-warning:disabled:hover{background-color:#ff9a52;border-color:#ff9a52}.btn-danger{color:#fff;background-color:#ff4c4c;border-color:#ff4c4c}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff1919;border-color:#ff0f0f}.btn-danger.active,.btn-danger:active,.open>.btn-danger.dropdown-toggle{color:#fff;background-color:#ff1919;border-color:#ff0f0f;background-image:none}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.btn-danger.dropdown-toggle.focus,.open>.btn-danger.dropdown-toggle:focus,.open>.btn-danger.dropdown-toggle:hover{color:#fff;background-color:#f40000;border-color:#c00}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger:disabled.focus,.btn-danger:disabled:focus,.btn-danger:disabled:hover{background-color:#ff4c4c;border-color:#ff4c4c}.btn-outline-primary{color:#2fb5d2;background-image:none;background-color:transparent;border-color:#2fb5d2}.btn-outline-primary.active,.btn-outline-primary.focus,.btn-outline-primary:active,.btn-outline-primary:focus,.btn-outline-primary:hover,.open>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#2fb5d2;border-color:#2fb5d2}.btn-outline-primary.active.focus,.btn-outline-primary.active:focus,.btn-outline-primary.active:hover,.btn-outline-primary:active.focus,.btn-outline-primary:active:focus,.btn-outline-primary:active:hover,.open>.btn-outline-primary.dropdown-toggle.focus,.open>.btn-outline-primary.dropdown-toggle:focus,.open>.btn-outline-primary.dropdown-toggle:hover{color:#fff;background-color:#1e788c;border-color:#175c6a}.btn-outline-primary.disabled.focus,.btn-outline-primary.disabled:focus,.btn-outline-primary.disabled:hover,.btn-outline-primary:disabled.focus,.btn-outline-primary:disabled:focus,.btn-outline-primary:disabled:hover{border-color:#83d3e4}.btn-outline-secondary{color:transparent;background-image:none;background-color:transparent;border-color:transparent}.btn-outline-secondary.active,.btn-outline-secondary.active.focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.active:hover,.btn-outline-secondary.focus,.btn-outline-secondary:active,.btn-outline-secondary:active.focus,.btn-outline-secondary:active:focus,.btn-outline-secondary:active:hover,.btn-outline-secondary:focus,.btn-outline-secondary:hover,.open>.btn-outline-secondary.dropdown-toggle,.open>.btn-outline-secondary.dropdown-toggle.focus,.open>.btn-outline-secondary.dropdown-toggle:focus,.open>.btn-outline-secondary.dropdown-toggle:hover{color:#fff;background-color:transparent;border-color:transparent}.btn-outline-secondary.disabled.focus,.btn-outline-secondary.disabled:focus,.btn-outline-secondary.disabled:hover,.btn-outline-secondary:disabled.focus,.btn-outline-secondary:disabled:focus,.btn-outline-secondary:disabled:hover{border-color:rgba(51,51,51,0)}.btn-outline-info{color:#5bc0de;background-image:none;background-color:transparent;border-color:#5bc0de}.btn-outline-info.active,.btn-outline-info.focus,.btn-outline-info:active,.btn-outline-info:focus,.btn-outline-info:hover,.open>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.btn-outline-info.active.focus,.btn-outline-info.active:focus,.btn-outline-info.active:hover,.btn-outline-info:active.focus,.btn-outline-info:active:focus,.btn-outline-info:active:hover,.open>.btn-outline-info.dropdown-toggle.focus,.open>.btn-outline-info.dropdown-toggle:focus,.open>.btn-outline-info.dropdown-toggle:hover{color:#fff;background-color:#269abc;border-color:#1f7e9a}.btn-outline-info.disabled.focus,.btn-outline-info.disabled:focus,.btn-outline-info.disabled:hover,.btn-outline-info:disabled.focus,.btn-outline-info:disabled:focus,.btn-outline-info:disabled:hover{border-color:#b0e1ef}.btn-outline-success{color:#4cbb6c;background-image:none;background-color:transparent;border-color:#4cbb6c}.btn-outline-success.active,.btn-outline-success.focus,.btn-outline-success:active,.btn-outline-success:focus,.btn-outline-success:hover,.open>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#4cbb6c;border-color:#4cbb6c}.btn-outline-success.active.focus,.btn-outline-success.active:focus,.btn-outline-success.active:hover,.btn-outline-success:active.focus,.btn-outline-success:active:focus,.btn-outline-success:active:hover,.open>.btn-outline-success.dropdown-toggle.focus,.open>.btn-outline-success.dropdown-toggle:focus,.open>.btn-outline-success.dropdown-toggle:hover{color:#fff;background-color:#318047;border-color:#256237}.btn-outline-success.disabled.focus,.btn-outline-success.disabled:focus,.btn-outline-success.disabled:hover,.btn-outline-success:disabled.focus,.btn-outline-success:disabled:focus,.btn-outline-success:disabled:hover{border-color:#96d7a9}.btn-outline-warning{color:#ff9a52;background-image:none;background-color:transparent;border-color:#ff9a52}.btn-outline-warning.active,.btn-outline-warning.focus,.btn-outline-warning:active,.btn-outline-warning:focus,.btn-outline-warning:hover,.open>.btn-outline-warning.dropdown-toggle{color:#fff;background-color:#ff9a52;border-color:#ff9a52}.btn-outline-warning.active.focus,.btn-outline-warning.active:focus,.btn-outline-warning.active:hover,.btn-outline-warning:active.focus,.btn-outline-warning:active:focus,.btn-outline-warning:active:hover,.open>.btn-outline-warning.dropdown-toggle.focus,.open>.btn-outline-warning.dropdown-toggle:focus,.open>.btn-outline-warning.dropdown-toggle:hover{color:#fff;background-color:#fa6800;border-color:#d25700}.btn-outline-warning.disabled.focus,.btn-outline-warning.disabled:focus,.btn-outline-warning.disabled:hover,.btn-outline-warning:disabled.focus,.btn-outline-warning:disabled:focus,.btn-outline-warning:disabled:hover{border-color:#ffd6b8}.btn-outline-danger{color:#ff4c4c;background-image:none;background-color:transparent;border-color:#ff4c4c}.btn-outline-danger.active,.btn-outline-danger.focus,.btn-outline-danger:active,.btn-outline-danger:focus,.btn-outline-danger:hover,.open>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#ff4c4c;border-color:#ff4c4c}.btn-outline-danger.active.focus,.btn-outline-danger.active:focus,.btn-outline-danger.active:hover,.btn-outline-danger:active.focus,.btn-outline-danger:active:focus,.btn-outline-danger:active:hover,.open>.btn-outline-danger.dropdown-toggle.focus,.open>.btn-outline-danger.dropdown-toggle:focus,.open>.btn-outline-danger.dropdown-toggle:hover{color:#fff;background-color:#f40000;border-color:#c00}.btn-outline-danger.disabled.focus,.btn-outline-danger.disabled:focus,.btn-outline-danger.disabled:hover,.btn-outline-danger:disabled.focus,.btn-outline-danger:disabled:focus,.btn-outline-danger:disabled:hover{border-color:#ffb2b2}.btn-link{font-weight:400;color:#2fb5d2;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link:disabled{background-color:transparent}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#208094;text-decoration:underline;background-color:transparent}.btn-link:disabled:focus,.btn-link:disabled:hover{color:#f1f1f1;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{height:0;overflow:hidden;transition-timing-function:ease;transition-duration:.35s;transition-property:height}.collapsing,.dropdown,.dropup{position:relative}.dropdown-toggle:after{display:inline-block;width:0;height:0;margin-right:.3em;vertical-align:middle;content:"";border-top:.3em solid;border-left:.3em solid transparent;border-right:.3em solid transparent}.dropdown-toggle:focus{outline:0}.dropup .dropdown-toggle:after{border-top:0;border-bottom:.3em solid}.dropdown-menu{position:absolute;top:100%;right:0;z-index:1000;display:none;float:right;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#363a42;text-align:right;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:0}.dropdown-divider{height:1px;margin:.5rem 0;overflow:hidden;background-color:#e5e5e5}.dropdown-item{display:block;width:100%;padding:3px 1.5rem;clear:both;font-weight:400;color:#363a42;text-align:inherit;white-space:nowrap;background:none;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#2b2e34;background-color:#f5f5f5}.dropdown-item.active,.dropdown-item.active:focus,.dropdown-item.active:hover{color:#fff;text-decoration:none;background-color:#2fb5d2;outline:0}.dropdown-item.disabled,.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{color:#f1f1f1}.dropdown-item.disabled:focus,.dropdown-item.disabled:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:"progid:DXImageTransform.Microsoft.gradient(enabled = false)"}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:0;right:auto}.dropdown-menu-left{left:auto;right:0}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#f1f1f1;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;left:0;bottom:0;right:0;z-index:990}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:.3em solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:.125rem}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:right;margin-bottom:0}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-right:-1px}.btn-toolbar{margin-right:-.5rem}.btn-toolbar:after{content:"";display:table;clear:both}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:right}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-right:.5rem}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-right:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group{float:right}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn+.dropdown-toggle-split{padding-left:.75rem;padding-right:.75rem}.btn+.dropdown-toggle-split:after{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-left:.375rem;padding-right:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-left:1.125rem;padding-right:1.125rem}.btn .caret{margin-right:0}.btn-group-lg>.btn .caret,.btn-lg .caret{border-width:.3em .3em 0;border-bottom-width:0}.dropup .btn-group-lg>.btn .caret,.dropup .btn-lg .caret{border-width:0 .3em .3em}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group:after{content:"";display:table;clear:both}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-right:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-left-radius:0;border-bottom-right-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;width:100%;display:table;border-collapse:separate}.input-group .form-control{position:relative;z-index:2;float:right;width:100%;margin-bottom:0}.input-group .form-control:active,.input-group .form-control:focus,.input-group .form-control:hover{z-index:3}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#7a7a7a;text-align:center;background-color:#f6f6f6;border:1px solid rgba(0,0,0,.25);border-radius:0}.input-group-addon.form-control-sm,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.input-group-addon.btn{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-addon.form-control-lg,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.input-group-addon.btn{padding:.75rem 1.5rem;font-size:.9375rem;border-radius:.3rem}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group-addon:not(:last-child),.input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group>.btn,.input-group-btn:not(:last-child)>.dropdown-toggle,.input-group .form-control:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:not(:last-child){border-left:0}.input-group-addon:not(:first-child),.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group>.btn,.input-group-btn:not(:first-child)>.dropdown-toggle,.input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.input-group-btn:not(:last-child)>.btn:not(:first-child),.input-group .form-control:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0}.form-control+.input-group-addon:not(:first-child){border-right:0}.input-group-btn{font-size:0;white-space:nowrap}.input-group-btn,.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-right:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:3}.input-group-btn:not(:last-child)>.btn,.input-group-btn:not(:last-child)>.btn-group{margin-left:-1px}.input-group-btn:not(:first-child)>.btn,.input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-right:-1px}.input-group-btn:not(:first-child)>.btn-group:active,.input-group-btn:not(:first-child)>.btn-group:focus,.input-group-btn:not(:first-child)>.btn-group:hover,.input-group-btn:not(:first-child)>.btn:active,.input-group-btn:not(:first-child)>.btn:focus,.input-group-btn:not(:first-child)>.btn:hover{z-index:3}.custom-control{position:relative;display:inline-block;padding-right:1.5rem;cursor:pointer}.custom-control+.custom-control{margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-indicator{color:#fff;background-color:#0074d9}.custom-control-input:focus~.custom-control-indicator{box-shadow:0 0 0 .075rem #fff,0 0 0 .2rem #0074d9}.custom-control-input:active~.custom-control-indicator{color:#fff;background-color:#84c6ff}.custom-control-input:disabled~.custom-control-indicator{cursor:not-allowed;background-color:#eee}.custom-control-input:disabled~.custom-control-description{color:#767676;cursor:not-allowed}.custom-control-indicator{position:absolute;top:.25rem;right:0;display:block;width:1rem;height:1rem;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#ddd;background-repeat:no-repeat;background-position:50%;background-size:50% 50%}.custom-checkbox .custom-control-indicator{border-radius:0}.custom-checkbox .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-indicator{background-color:#0074d9;background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-radio .custom-control-indicator{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-indicator{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#fff'/%3E%3C/svg%3E")}.custom-controls-stacked .custom-control{float:right;clear:right}.custom-controls-stacked .custom-control+.custom-control{margin-right:0}.custom-select{display:inline-block;max-width:100%;height:calc(2.5rem - 2px);padding:.375rem .75rem .375rem 1.75rem;padding-left:.75rem\9;color:#7a7a7a;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat left .75rem center;background-image:none\9;background-size:8px 10px;border:1px solid rgba(0,0,0,.25);border-radius:0;-moz-appearance:none;-webkit-appearance:none}.custom-select:focus{border-color:#51a7e8;outline:none}.custom-select:focus::-ms-value{color:#7a7a7a;background-color:#fff}.custom-select:disabled{color:#f1f1f1;cursor:not-allowed;background-color:#f6f6f6}.custom-select::-ms-expand{opacity:0}.custom-select-sm{padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-file{position:relative;display:inline-block;max-width:100%;height:2.5rem;cursor:pointer}.custom-file-input{min-width:14rem;max-width:100%;margin:0;filter:alpha(opacity=0);opacity:0}.custom-file-control{position:absolute;top:0;left:0;right:0;z-index:5;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#555;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;border:1px solid #ddd;border-radius:0}.custom-file-control:lang(en):after{content:"Choose file..."}.custom-file-control:before{position:absolute;top:-1px;left:-1px;bottom:-1px;z-index:6;display:block;height:2.5rem;padding:.5rem 1rem;line-height:1.5;color:#555;background-color:#eee;border:1px solid #ddd;border-radius:0 0 0 0}.custom-file-control:lang(en):before{content:"Browse"}.nav{padding-right:0;margin-bottom:0;list-style:none}.nav-link{display:inline-block}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#f1f1f1}.nav-link.disabled,.nav-link.disabled:focus,.nav-link.disabled:hover{color:#f1f1f1;cursor:not-allowed;background-color:transparent}.nav-inline .nav-item{display:inline-block}.nav-inline .nav-item+.nav-item,.nav-inline .nav-link+.nav-link{margin-right:1rem}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs:after{content:"";display:table;clear:both}.nav-tabs .nav-item{float:right;margin-bottom:-1px}.nav-tabs .nav-item+.nav-item{margin-right:.2rem}.nav-tabs .nav-link{display:block;padding:.5em 1em;border:1px solid transparent;border-top-left-radius:0;border-top-right-radius:0}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#f6f6f6 #f6f6f6 #ddd}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link.disabled:focus,.nav-tabs .nav-link.disabled:hover{color:#f1f1f1;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.open .nav-link,.nav-tabs .nav-item.open .nav-link:focus,.nav-tabs .nav-item.open .nav-link:hover,.nav-tabs .nav-link.active,.nav-tabs .nav-link.active:focus,.nav-tabs .nav-link.active:hover{color:#7a7a7a;background-color:#fff;border-color:#ddd #ddd transparent}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills:after{content:"";display:table;clear:both}.nav-pills .nav-item{float:right}.nav-pills .nav-item+.nav-item{margin-right:.2rem}.nav-pills .nav-link{display:block;padding:.5em 1em;border-radius:0}.nav-pills .nav-item.open .nav-link,.nav-pills .nav-item.open .nav-link:focus,.nav-pills .nav-item.open .nav-link:hover,.nav-pills .nav-link.active,.nav-pills .nav-link.active:focus,.nav-pills .nav-link.active:hover{color:#fff;cursor:default;background-color:#2fb5d2}.nav-stacked .nav-item{display:block;float:none}.nav-stacked .nav-item+.nav-item{margin-top:.2rem;margin-right:0}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem 1rem}.navbar:after{content:"";display:table;clear:both}@media (min-width:576px){.navbar{border-radius:0}}.navbar-full{z-index:1000}@media (min-width:576px){.navbar-full{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;left:0;right:0;z-index:1030}@media (min-width:576px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0}.navbar-fixed-bottom{bottom:0}.navbar-sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1030;width:100%}@media (min-width:576px){.navbar-sticky-top{border-radius:0}}.navbar-brand{float:right;padding-top:.25rem;padding-bottom:.25rem;margin-left:1rem;font-size:.9375rem;line-height:inherit}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-divider{float:right;width:1px;padding-top:.425rem;padding-bottom:.425rem;margin-left:1rem;margin-right:1rem;overflow:hidden}.navbar-divider:before{content:"\A0"}.navbar-text{display:inline-block;padding-top:.425rem;padding-bottom:.425rem}.navbar-toggler{width:2.5em;height:2em;padding:.5rem .75rem;font-size:.9375rem;line-height:1;background:transparent no-repeat 50%;background-size:24px 24px;border:1px solid transparent;border-radius:0}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}@media (max-width:575px){.navbar-toggleable-xs .navbar-brand{display:block;float:none;margin-top:.5rem;margin-left:0}.navbar-toggleable-xs .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-xs .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:576px){.navbar-toggleable-xs{display:block}}@media (max-width:767px){.navbar-toggleable-sm .navbar-brand{display:block;float:none;margin-top:.5rem;margin-left:0}.navbar-toggleable-sm .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-sm .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:768px){.navbar-toggleable-sm{display:block}}@media (max-width:991px){.navbar-toggleable-md .navbar-brand{display:block;float:none;margin-top:.5rem;margin-left:0}.navbar-toggleable-md .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-md .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:992px){.navbar-toggleable-md{display:block}}.navbar-toggleable-lg:after{content:"";display:table;clear:both}@media (max-width:1199px){.navbar-toggleable-lg .navbar-brand{display:block;float:none;margin-top:.5rem;margin-left:0}.navbar-toggleable-lg .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-lg .navbar-nav .dropdown-menu{position:static;float:none}}@media (min-width:1200px){.navbar-toggleable-lg{display:block}}.navbar-toggleable-xl{display:block}.navbar-toggleable-xl:after{content:"";display:table;clear:both}.navbar-toggleable-xl .navbar-brand{display:block;float:none;margin-top:.5rem;margin-left:0}.navbar-toggleable-xl .navbar-nav{margin-top:.5rem;margin-bottom:.5rem}.navbar-toggleable-xl .navbar-nav .dropdown-menu{position:static;float:none}.navbar-nav .nav-item{float:right}.navbar-nav .nav-link{display:block;padding-top:.425rem;padding-bottom:.425rem}.navbar-nav .nav-item+.nav-item,.navbar-nav .nav-link+.nav-link{margin-right:1rem}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover,.navbar-light .navbar-toggler,.navbar-light .navbar-toggler:focus,.navbar-light .navbar-toggler:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .active>.nav-link:focus,.navbar-light .navbar-nav .active>.nav-link:hover,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.active:focus,.navbar-light .navbar-nav .nav-link.active:hover,.navbar-light .navbar-nav .nav-link.open,.navbar-light .navbar-nav .nav-link.open:focus,.navbar-light .navbar-nav .nav-link.open:hover,.navbar-light .navbar-nav .open>.nav-link,.navbar-light .navbar-nav .open>.nav-link:focus,.navbar-light .navbar-nav .open>.nav-link:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");border-color:rgba(0,0,0,.1)}.navbar-light .navbar-divider{background-color:rgba(0,0,0,.075)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-toggler,.navbar-dark .navbar-toggler:focus,.navbar-dark .navbar-toggler:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .active>.nav-link:focus,.navbar-dark .navbar-nav .active>.nav-link:hover,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.active:focus,.navbar-dark .navbar-nav .nav-link.active:hover,.navbar-dark .navbar-nav .nav-link.open,.navbar-dark .navbar-nav .nav-link.open:focus,.navbar-dark .navbar-nav .nav-link.open:hover,.navbar-dark .navbar-nav .open>.nav-link,.navbar-dark .navbar-nav .open>.nav-link:focus,.navbar-dark .navbar-nav .open>.nav-link:hover{color:#fff}.navbar-dark .navbar-toggler{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-divider{background-color:hsla(0,0%,100%,.075)}.navbar-toggleable-xs:after{content:"";display:table;clear:both}@media (max-width:575px){.navbar-toggleable-xs .navbar-nav .nav-item{float:none;margin-right:0}}@media (min-width:576px){.navbar-toggleable-xs{display:block!important}}.navbar-toggleable-sm:after{content:"";display:table;clear:both}@media (max-width:767px){.navbar-toggleable-sm .navbar-nav .nav-item{float:none;margin-right:0}}@media (min-width:768px){.navbar-toggleable-sm{display:block!important}}.navbar-toggleable-md:after{content:"";display:table;clear:both}@media (max-width:991px){.navbar-toggleable-md .navbar-nav .nav-item{float:none;margin-right:0}}@media (min-width:992px){.navbar-toggleable-md{display:block!important}}.card{position:relative;display:block;margin-bottom:.75rem;background-color:#fff;border-radius:0;border:1px solid rgba(0,0,0,.125)}.card-block{padding:1.25rem}.card-block:after{content:"";display:table;clear:both}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-right:1.25rem}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child .list-group-item:last-child{border-bottom-left-radius:0;border-bottom-right-radius:0}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:#f5f5f5;border-bottom:1px solid rgba(0,0,0,.125)}.card-header:after{content:"";display:table;clear:both}.card-header:first-child{border-radius:-1px -1px 0 0}.card-footer{padding:.75rem 1.25rem;background-color:#f5f5f5;border-top:1px solid rgba(0,0,0,.125)}.card-footer:after{content:"";display:table;clear:both}.card-footer:last-child{border-radius:0 0 -1px -1px}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-left:-.625rem;margin-right:-.625rem}.card-primary{background-color:#2fb5d2;border-color:#2fb5d2}.card-primary .card-footer,.card-primary .card-header{background-color:transparent}.card-success{background-color:#4cbb6c;border-color:#4cbb6c}.card-success .card-footer,.card-success .card-header{background-color:transparent}.card-info{background-color:#5bc0de;border-color:#5bc0de}.card-info .card-footer,.card-info .card-header{background-color:transparent}.card-warning{background-color:#ff9a52;border-color:#ff9a52}.card-warning .card-footer,.card-warning .card-header{background-color:transparent}.card-danger{background-color:#ff4c4c;border-color:#ff4c4c}.card-danger .card-footer,.card-danger .card-header,.card-outline-primary{background-color:transparent}.card-outline-primary{border-color:#2fb5d2}.card-outline-secondary{background-color:transparent;border-color:transparent}.card-outline-info{background-color:transparent;border-color:#5bc0de}.card-outline-success{background-color:transparent;border-color:#4cbb6c}.card-outline-warning{background-color:transparent;border-color:#ff9a52}.card-outline-danger{background-color:transparent;border-color:#ff4c4c}.card-inverse .card-footer,.card-inverse .card-header{border-color:hsla(0,0%,100%,.2)}.card-inverse .card-blockquote,.card-inverse .card-footer,.card-inverse .card-header,.card-inverse .card-title{color:#fff}.card-inverse .card-blockquote .blockquote-footer,.card-inverse .card-link,.card-inverse .card-subtitle,.card-inverse .card-text{color:hsla(0,0%,100%,.65)}.card-inverse .card-link:focus,.card-inverse .card-link:hover{color:#fff}.card-blockquote{padding:0;margin-bottom:0;border-right:0}.card-img{border-radius:-1px}.card-img-overlay{position:absolute;top:0;left:0;bottom:0;right:0;padding:1.25rem}.card-img-top{border-top-left-radius:-1px;border-top-right-radius:-1px}.card-img-bottom{border-bottom-left-radius:-1px;border-bottom-right-radius:-1px}@media (min-width:576px){.card-deck{display:table;width:100%;margin-bottom:.75rem;table-layout:fixed;border-spacing:1.25rem 0}.card-deck .card{display:table-cell;margin-bottom:0;vertical-align:top}.card-deck-wrapper{margin-left:-1.25rem;margin-right:-1.25rem}}@media (min-width:576px){.card-group{display:table;width:100%;table-layout:fixed}.card-group .card{display:table-cell;vertical-align:top}.card-group .card+.card{margin-right:0;border-right:0}.card-group .card:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.card-group .card:first-child .card-img-top{border-top-left-radius:0}.card-group .card:first-child .card-img-bottom{border-bottom-left-radius:0}.card-group .card:last-child{border-bottom-right-radius:0;border-top-right-radius:0}.card-group .card:last-child .card-img-top{border-top-right-radius:0}.card-group .card:last-child .card-img-bottom{border-bottom-right-radius:0}.card-group .card:not(:first-child):not(:last-child),.card-group .card:not(:first-child):not(:last-child) .card-img-bottom,.card-group .card:not(:first-child):not(:last-child) .card-img-top{border-radius:0}}@media (min-width:576px){.card-columns{-webkit-column-count:3;column-count:3;-webkit-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#f6f6f6;border-radius:0}.breadcrumb:after{content:"";display:table;clear:both}.breadcrumb-item{float:right}.breadcrumb-item+.breadcrumb-item:before{display:inline-block;padding-left:.5rem;padding-right:.5rem;color:#f1f1f1;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#f1f1f1}.pagination{display:inline-block;padding-right:0;margin-top:1rem;margin-bottom:1rem;border-radius:0}.page-item{display:inline}.page-item:first-child .page-link{margin-right:0;border-bottom-right-radius:0;border-top-right-radius:0}.page-item:last-child .page-link{border-bottom-left-radius:0;border-top-left-radius:0}.page-item.active .page-link,.page-item.active .page-link:focus,.page-item.active .page-link:hover{z-index:2;color:#fff;cursor:default;background-color:#2fb5d2;border-color:#2fb5d2}.page-item.disabled .page-link,.page-item.disabled .page-link:focus,.page-item.disabled .page-link:hover{color:#f1f1f1;pointer-events:none;cursor:not-allowed;background-color:#fff;border-color:#ddd}.page-link{position:relative;float:right;padding:.5rem .75rem;margin-right:-1px;color:#2fb5d2;text-decoration:none;background-color:#fff;border:1px solid #ddd}.page-link:focus,.page-link:hover{color:#208094;background-color:#f6f6f6;border-color:#ddd}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:.9375rem}.pagination-lg .page-item:first-child .page-link{border-bottom-right-radius:.3rem;border-top-right-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-bottom-left-radius:.3rem;border-top-left-radius:.3rem}.pagination-sm .page-link{padding:.275rem .75rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-bottom-right-radius:.2rem;border-top-right-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-bottom-left-radius:.2rem;border-top-left-radius:.2rem}.tag{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:0}.tag:empty{display:none}.btn .tag{position:relative;top:-1px}a.tag:focus,a.tag:hover{color:#fff;text-decoration:none;cursor:pointer}.tag-pill{padding-left:.6em;padding-right:.6em;border-radius:10rem}.tag-default{background-color:#f1f1f1}.tag-default[href]:focus,.tag-default[href]:hover{background-color:#d8d8d8}.tag-primary{background-color:#2fb5d2}.tag-primary[href]:focus,.tag-primary[href]:hover{background-color:#2592a9}.tag-success{background-color:#4cbb6c}.tag-success[href]:focus,.tag-success[href]:hover{background-color:#3a9a56}.tag-info{background-color:#5bc0de}.tag-info[href]:focus,.tag-info[href]:hover{background-color:#31b0d5}.tag-warning{background-color:#ff9a52}.tag-warning[href]:focus,.tag-warning[href]:hover{background-color:#ff7c1f}.tag-danger{background-color:#ff4c4c}.tag-danger[href]:focus,.tag-danger[href]:hover{background-color:#ff1919}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#f6f6f6;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-hr{border-top-color:#ddd}.jumbotron-fluid{padding-left:0;padding-right:0;border-radius:0}.alert{padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:0}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-left:2.5rem}.alert-dismissible .close{position:relative;top:-.125rem;left:-1.25rem;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d0e9c6;color:#3c763d}.alert-success hr{border-top-color:#c1e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bcdff1;color:#31708f}.alert-info hr{border-top-color:#a6d5ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:rgba(255,154,82,.3);border-color:#ff9a52;color:#232323}.alert-warning hr{border-top-color:#ff8b39}.alert-warning .alert-link{color:#0a0a0a}.alert-danger{background-color:#f2dede;border-color:#ebcccc;color:#a94442}.alert-danger hr{border-top-color:#e4b9b9}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{display:block;width:100%;height:1rem;margin-bottom:1rem}.progress[value]{background-color:#eee;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:0}.progress[value]::-ms-fill{background-color:#0074d9;border:0}.progress[value]::-moz-progress-bar{background-color:#0074d9;border-bottom-right-radius:0;border-top-right-radius:0}.progress[value]::-webkit-progress-value{background-color:#0074d9;border-bottom-right-radius:0;border-top-right-radius:0}.progress[value="100"]::-moz-progress-bar{border-bottom-left-radius:0;border-top-left-radius:0}.progress[value="100"]::-webkit-progress-value{border-bottom-left-radius:0;border-top-left-radius:0}.progress[value]::-webkit-progress-bar{background-color:#eee;border-radius:0}.progress[value],base::-moz-progress-bar{background-color:#eee;border-radius:0}@media screen and (min-width:0\0){.progress{background-color:#eee;border-radius:0}.progress-bar{display:inline-block;height:1rem;text-indent:-999rem;background-color:#0074d9;border-bottom-right-radius:0;border-top-right-radius:0}.progress[width="100%"]{border-bottom-left-radius:0;border-top-left-radius:0}}.progress-striped[value]::-webkit-progress-value{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-striped[value]::-moz-progress-bar{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-striped[value]::-ms-fill{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}@media screen and (min-width:0\0){.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}}.progress-animated[value]::-webkit-progress-value{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-animated[value]::-moz-progress-bar{animation:progress-bar-stripes 2s linear infinite}@media screen and (min-width:0\0){.progress-animated .progress-bar-striped{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}}.progress-success[value]::-webkit-progress-value{background-color:#4cbb6c}.progress-success[value]::-moz-progress-bar{background-color:#4cbb6c}.progress-success[value]::-ms-fill{background-color:#4cbb6c}@media screen and (min-width:0\0){.progress-success .progress-bar{background-color:#4cbb6c}}.progress-info[value]::-webkit-progress-value{background-color:#5bc0de}.progress-info[value]::-moz-progress-bar{background-color:#5bc0de}.progress-info[value]::-ms-fill{background-color:#5bc0de}@media screen and (min-width:0\0){.progress-info .progress-bar{background-color:#5bc0de}}.progress-warning[value]::-webkit-progress-value{background-color:#ff9a52}.progress-warning[value]::-moz-progress-bar{background-color:#ff9a52}.progress-warning[value]::-ms-fill{background-color:#ff9a52}@media screen and (min-width:0\0){.progress-warning .progress-bar{background-color:#ff9a52}}.progress-danger[value]::-webkit-progress-value{background-color:#ff4c4c}.progress-danger[value]::-moz-progress-bar{background-color:#ff4c4c}.progress-danger[value]::-ms-fill{background-color:#ff4c4c}@media screen and (min-width:0\0){.progress-danger .progress-bar{background-color:#ff4c4c}}.media,.media-body{overflow:hidden}.media-body{width:10000px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right{padding-right:10px}.media-left{padding-left:10px}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-right:0;list-style:none}.list-group{padding-right:0;margin-bottom:0}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#f1f1f1;cursor:not-allowed;background-color:#f6f6f6}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#f1f1f1}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;text-decoration:none;background-color:#2fb5d2;border-color:#2fb5d2}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#d7f1f6}.list-group-flush .list-group-item{border-left:0;border-right:0;border-radius:0}.list-group-item-action{width:100%;color:#555;text-align:inherit}.list-group-item-action .list-group-item-heading{color:#333}.list-group-item-action:focus,.list-group-item-action:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;right:0;width:100%;height:100%;border:0}.embed-responsive-21by9{padding-bottom:42.85714%}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.embed-responsive-1by1{padding-bottom:100%}.close{float:left;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal,.modal-open{overflow:hidden}.modal{position:fixed;top:0;left:0;bottom:0;right:0;z-index:1050;display:none;outline:0}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translateY(-25%);transform:translateY(-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;bottom:0;right:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header:after{content:"";display:table;clear:both}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.5}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:left;border-top:1px solid #e5e5e5}.modal-footer:after{content:"";display:table;clear:both}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:600px;margin:30px auto}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:right;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.in{opacity:.9}.tooltip.bs-tether-element-attached-bottom,.tooltip.tooltip-top{padding:5px 0;margin-top:-3px}.tooltip.bs-tether-element-attached-bottom .tooltip-inner:before,.tooltip.tooltip-top .tooltip-inner:before{bottom:0;right:50%;margin-right:-5px;content:"";border-width:5px 5px 0;border-top-color:#ff4c4c}.tooltip.bs-tether-element-attached-left,.tooltip.tooltip-right{padding:0 5px;margin-right:3px}.tooltip.bs-tether-element-attached-left .tooltip-inner:before,.tooltip.tooltip-right .tooltip-inner:before{top:50%;right:0;margin-top:-5px;content:"";border-width:5px 0 5px 5px;border-left-color:#ff4c4c}.tooltip.bs-tether-element-attached-top,.tooltip.tooltip-bottom{padding:5px 0;margin-top:3px}.tooltip.bs-tether-element-attached-top .tooltip-inner:before,.tooltip.tooltip-bottom .tooltip-inner:before{top:0;right:50%;margin-right:-5px;content:"";border-width:0 5px 5px;border-bottom-color:#ff4c4c}.tooltip.bs-tether-element-attached-right,.tooltip.tooltip-left{padding:0 5px;margin-right:-3px}.tooltip.bs-tether-element-attached-right .tooltip-inner:before,.tooltip.tooltip-left .tooltip-inner:before{top:50%;left:0;margin-top:-5px;content:"";border-width:5px 5px 5px 0;border-right-color:#ff4c4c}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#ff4c4c;border-radius:0}.tooltip-inner:before{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;right:0;z-index:1060;display:block;max-width:276px;padding:1px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.5;text-align:right;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover.bs-tether-element-attached-bottom,.popover.popover-top{margin-top:-10px}.popover.bs-tether-element-attached-bottom:after,.popover.bs-tether-element-attached-bottom:before,.popover.popover-top:after,.popover.popover-top:before{right:50%;border-bottom-width:0}.popover.bs-tether-element-attached-bottom:before,.popover.popover-top:before{bottom:-11px;margin-right:-11px;border-top-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-bottom:after,.popover.popover-top:after{bottom:-10px;margin-right:-10px;border-top-color:#fff}.popover.bs-tether-element-attached-left,.popover.popover-right{margin-right:10px}.popover.bs-tether-element-attached-left:after,.popover.bs-tether-element-attached-left:before,.popover.popover-right:after,.popover.popover-right:before{top:50%;border-right-width:0}.popover.bs-tether-element-attached-left:before,.popover.popover-right:before{right:-11px;margin-top:-11px;border-left-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-left:after,.popover.popover-right:after{right:-10px;margin-top:-10px;border-left-color:#fff}.popover.bs-tether-element-attached-top,.popover.popover-bottom{margin-top:10px}.popover.bs-tether-element-attached-top:after,.popover.bs-tether-element-attached-top:before,.popover.popover-bottom:after,.popover.popover-bottom:before{right:50%;border-top-width:0}.popover.bs-tether-element-attached-top:before,.popover.popover-bottom:before{top:-11px;margin-right:-11px;border-bottom-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-top:after,.popover.popover-bottom:after{top:-10px;margin-right:-10px;border-bottom-color:#f7f7f7}.popover.bs-tether-element-attached-top .popover-title:before,.popover.popover-bottom .popover-title:before{position:absolute;top:0;right:50%;display:block;width:20px;margin-right:-10px;content:"";border-bottom:1px solid #f7f7f7}.popover.bs-tether-element-attached-right,.popover.popover-left{margin-right:-10px}.popover.bs-tether-element-attached-right:after,.popover.bs-tether-element-attached-right:before,.popover.popover-left:after,.popover.popover-left:before{top:50%;border-left-width:0}.popover.bs-tether-element-attached-right:before,.popover.popover-left:before{left:-11px;margin-top:-11px;border-right-color:rgba(0,0,0,.25)}.popover.bs-tether-element-attached-right:after,.popover.popover-left:after{left:-10px;margin-top:-10px;border-right-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:.2375rem .2375rem 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover:after,.popover:before{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover:before{content:"";border-width:11px}.popover:after{content:"";border-width:10px}.carousel,.carousel-inner{position:relative}.carousel-inner{width:100%;overflow:hidden}.carousel-inner>.carousel-item{position:relative;display:none;transition:right .6s ease-in-out}.carousel-inner>.carousel-item>a>img,.carousel-inner>.carousel-item>img{line-height:1}@media (-webkit-transform-3d),(transform-3d){.carousel-inner>.carousel-item{transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.carousel-item.active.right,.carousel-inner>.carousel-item.next{right:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.carousel-item.active.left,.carousel-inner>.carousel-item.prev{right:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.carousel-item.active,.carousel-inner>.carousel-item.next.left,.carousel-inner>.carousel-item.prev.right{right:0;-webkit-transform:translateZ(0);transform:translateZ(0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{right:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{right:100%}.carousel-inner>.prev{right:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{right:0}.carousel-inner>.active.left{right:-100%}.carousel-inner>.active.right{right:100%}.carousel-control{position:absolute;top:0;bottom:0;right:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);opacity:.5}.carousel-control.left{background-image:linear-gradient(90deg,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001));background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80000000",endColorstr="#00000000",GradientType=1)}.carousel-control.right{left:0;right:auto;background-image:linear-gradient(90deg,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5));background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#80000000",GradientType=1)}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev{right:50%;margin-right:-10px}.carousel-control .icon-next{left:50%;margin-left:-10px}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203A"}.carousel-indicators{position:absolute;bottom:10px;right:50%;z-index:15;width:60%;padding-right:0;margin-right:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:transparent;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;left:15%;bottom:20px;right:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media (min-width:576px){.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .icon-prev{margin-right:-15px}.carousel-control .icon-next{margin-left:-15px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-faded{background-color:#f7f7f9}.bg-primary{background-color:#2fb5d2!important}a.bg-primary:focus,a.bg-primary:hover{background-color:#2592a9!important}.bg-success{background-color:#4cbb6c!important}a.bg-success:focus,a.bg-success:hover{background-color:#3a9a56!important}.bg-info{background-color:#5bc0de!important}a.bg-info:focus,a.bg-info:hover{background-color:#31b0d5!important}.bg-warning{background-color:#ff9a52!important}a.bg-warning:focus,a.bg-warning:hover{background-color:#ff7c1f!important}.bg-danger{background-color:#ff4c4c!important}a.bg-danger:focus,a.bg-danger:hover{background-color:#ff1919!important}.bg-inverse{background-color:#363a42!important}a.bg-inverse:focus,a.bg-inverse:hover{background-color:#1f2126!important}.rounded{border-radius:0}.rounded-top{border-top-left-radius:0;border-top-right-radius:0}.rounded-right{border-bottom-left-radius:0;border-top-left-radius:0}.rounded-bottom{border-bottom-left-radius:0;border-bottom-right-radius:0}.rounded-left{border-bottom-right-radius:0;border-top-right-radius:0}.rounded-circle{border-radius:50%}.clearfix:after{content:"";display:table;clear:both}.d-block{display:block!important}.d-inline-block{display:inline-block!important}.d-inline{display:inline!important}.float-xs-left{float:right!important}.float-xs-right{float:left!important}.float-xs-none{float:none!important}@media (min-width:576px){.float-sm-left{float:right!important}.float-sm-right{float:left!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:right!important}.float-md-right{float:left!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:right!important}.float-lg-right{float:left!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:right!important}.float-xl-right{float:left!important}.float-xl-none{float:none!important}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.w-100{width:100%!important}.h-100{height:100%!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-left:0!important}.mb-0{margin-bottom:0!important}.ml-0,.mx-0{margin-right:0!important}.mx-0{margin-left:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:1rem!important}.mt-1{margin-top:1rem!important}.mr-1{margin-left:1rem!important}.mb-1{margin-bottom:1rem!important}.ml-1,.mx-1{margin-right:1rem!important}.mx-1{margin-left:1rem!important}.my-1{margin-top:1rem!important;margin-bottom:1rem!important}.m-2{margin:1.5rem!important}.mt-2{margin-top:1.5rem!important}.mr-2{margin-left:1.5rem!important}.mb-2{margin-bottom:1.5rem!important}.ml-2,.mx-2{margin-right:1.5rem!important}.mx-2{margin-left:1.5rem!important}.my-2{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-3{margin:3rem!important}.mt-3{margin-top:3rem!important}.mr-3{margin-left:3rem!important}.mb-3{margin-bottom:3rem!important}.ml-3,.mx-3{margin-right:3rem!important}.mx-3{margin-left:3rem!important}.my-3{margin-top:3rem!important;margin-bottom:3rem!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-left:0!important}.pb-0{padding-bottom:0!important}.pl-0,.px-0{padding-right:0!important}.px-0{padding-left:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:1rem!important}.pt-1{padding-top:1rem!important}.pr-1{padding-left:1rem!important}.pb-1{padding-bottom:1rem!important}.pl-1,.px-1{padding-right:1rem!important}.px-1{padding-left:1rem!important}.py-1{padding-top:1rem!important;padding-bottom:1rem!important}.p-2{padding:1.5rem!important}.pt-2{padding-top:1.5rem!important}.pr-2{padding-left:1.5rem!important}.pb-2{padding-bottom:1.5rem!important}.pl-2,.px-2{padding-right:1.5rem!important}.px-2{padding-left:1.5rem!important}.py-2{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-3{padding:3rem!important}.pt-3{padding-top:3rem!important}.pr-3{padding-left:3rem!important}.pb-3{padding-bottom:3rem!important}.pl-3,.px-3{padding-right:3rem!important}.px-3{padding-left:3rem!important}.py-3{padding-top:3rem!important;padding-bottom:3rem!important}.pos-f-t{position:fixed;top:0;left:0;right:0;z-index:1030}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-xs-left{text-align:right!important}.text-xs-right{text-align:left!important}.text-xs-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:right!important}.text-sm-right{text-align:left!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:right!important}.text-md-right{text-align:left!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:right!important}.text-lg-right{text-align:left!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:right!important}.text-xl-right{text-align:left!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-normal{font-weight:400}.font-weight-bold{font-weight:700}.font-italic{font-style:italic}.text-white{color:#fff!important}.text-muted{color:#7a7a7a!important}a.text-muted:focus,a.text-muted:hover{color:#616161!important}.text-primary{color:#2fb5d2!important}a.text-primary:focus,a.text-primary:hover{color:#2592a9!important}.text-success{color:#4cbb6c!important}a.text-success:focus,a.text-success:hover{color:#3a9a56!important}.text-info{color:#5bc0de!important}a.text-info:focus,a.text-info:hover{color:#31b0d5!important}.text-warning{color:#ff9a52!important}a.text-warning:focus,a.text-warning:hover{color:#ff7c1f!important}.text-danger{color:#ff4c4c!important}a.text-danger:focus,a.text-danger:hover{color:#ff1919!important}.text-gray-dark{color:#363a42!important}a.text-gray-dark:focus,a.text-gray-dark:hover{color:#1f2126!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.invisible{visibility:hidden!important}.hidden-xs-up{display:none!important}@media (max-width:575px){.hidden-xs-down{display:none!important}}@media (min-width:576px){.hidden-sm-up{display:none!important}}@media (max-width:767px){.hidden-sm-down{display:none!important}}@media (min-width:768px){.hidden-md-up{display:none!important}}@media (max-width:991px){.hidden-md-down{display:none!important}}@media (min-width:992px){.hidden-lg-up{display:none!important}}@media (max-width:1199px){.hidden-lg-down{display:none!important}}@media (min-width:1200px){.hidden-xl-up{display:none!important}}.hidden-xl-down,.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}@font-face{font-family:Noto Sans;src:url(../css/3d4a907b1b7a232654324a3dd7ae4aa3.eot);src:local("Noto Sans Regular"),local("NotoSans-Regular"),url(../css/3d4a907b1b7a232654324a3dd7ae4aa3.eot) format("embedded-opentype"),url(../css/19c1b868764c0e4d15a45d3f61250488.woff2) format("woff2"),url(../css/846c191efd3d0aacde5a916cf2ebf1a4.woff) format("woff"),url(../css/2fd9c16b805724d590c0cff96da070a4.ttf) format("truetype"),url(../css/5ea9fdf2293930126fa9c544968009ae.svg) format("svg");font-weight:400;font-style:normal}@font-face{font-family:Noto Sans;src:url(../css/eeb9224f85430652fd070e4e64129aa4.eot);src:local("Noto Sans Bold"),local("NotoSans-Bold"),url(../css/eeb9224f85430652fd070e4e64129aa4.eot) format("embedded-opentype"),url(../css/199038f07312bfc6f0aabd3ed6a2b64d.woff2) format("woff2"),url(../css/c2183257e7a697769df4200c547551f1.woff) format("woff"),url(../css/a165a42685795361b25593effb32fdb1.ttf) format("truetype"),url(../css/5dc400bcedda37b13f35cb44623193cf.svg) format("svg");font-weight:700;font-style:normal}@font-face{font-family:Noto Sans;src:url(../css/a77ade19de3d3762dfbf1fe553b293cc.eot);src:local("Noto Sans Italic"),local("NotoSans-Italic"),url(../css/a77ade19de3d3762dfbf1fe553b293cc.eot) format("embedded-opentype"),url(../css/7a3ebca0cba2e2c6090e84e1d77e0f94.woff2) format("woff2"),url(../css/332f555bb44cdc394d6c799df0c03389.woff) format("woff"),url(../css/154da4697acc779b55af0a67f1241e4e.ttf) format("truetype"),url(../css/3d34be670a7f15086e512282b97ae35e.svg) format("svg");font-weight:400;font-style:italic}@font-face{font-family:Noto Sans;src:url(../css/b467416c449eb823029e16347b2ea510.eot);src:local("Noto Sans BoldItalic"),local("NotoSans-BoldItalic"),url(../css/b467416c449eb823029e16347b2ea510.eot) format("embedded-opentype"),url(../css/a68cfe9d548950edf5df102269877edd.woff2) format("woff2"),url(../css/3f81521029cc8a9a703419c4a74704a0.woff) format("woff"),url(../css/4f6ff3639c1e5728b905b650c1a06e75.ttf) format("truetype"),url(../css/80e74ff9406650e53bbec1e292c2c094.svg) format("svg");font-weight:700;font-style:italic}@font-face{font-family:Material Icons;font-style:normal;font-weight:400;src:url(../css/e79bfd88537def476913f3ed52f4f4b3.eot);src:local("Material Icons"),local("MaterialIcons-Regular"),url(../css/570eb83859dc23dd0eec423a49e147fe.woff2) format("woff2"),url(../css/012cf6a10129e2275d79d6adac7f3b02.woff) format("woff"),url(../css/a37b0c01c0baf1888ca812cc0508f6e2.ttf) format("truetype")}.material-icons{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;vertical-align:middle;width:1em;height:1em;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:rtl;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;-webkit-font-feature-settings:"liga";font-feature-settings:"liga"}body,html{height:100%}body{direction:rtl;font-family:Noto Sans,sans-serif;font-size:1rem;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#232323;line-height:1.25em}ul{list-style:none;padding-right:0}a:hover{color:#2fb5d2;text-decoration:none}p{font-size:.9375rem;color:#7a7a7a;font-weight:400}.color,.custom-checkbox input[type=checkbox]+span.color{width:1.25rem;height:1.25rem;display:inline-block;margin:.3125rem;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2);border:1px solid rgba(0,0,0,.05);cursor:pointer;background-size:contain}.color.active,.color:hover,.custom-checkbox input[type=checkbox]+span.color.active,.custom-checkbox input[type=checkbox]+span.color:hover,.facet-label.active .custom-checkbox span.color,.facet-label:hover .custom-checkbox span.color{border:2px solid #232323}.h1,.h2,.h3{text-transform:uppercase;color:#232323}.h4{font-weight:700;color:#232323}.btn-primary,.btn-secondary,.btn-tertiary{box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2);text-transform:uppercase;font-weight:600;padding:.5rem 1.25rem}.btn-primary .material-icons,.btn-secondary .material-icons,.btn-tertiary .material-icons{margin-left:.625rem}.btn-tertiary{background-color:#f7f7f7;text-transform:lowercase;color:#7a7a7a;box-shadow:-.0625rem .0625rem .0625rem 0 rgba(0,0,0,.1);padding:.25rem;margin:.25rem 0;font-weight:400;font-size:.875rem}.btn-tertiary .material-icons{font-size:1rem}.btn-tertiary:hover{box-shadow:-.0625rem .0625rem .0625rem 0 rgba(0,0,0,.2);border:1px solid rgba(35,35,35,.2)}.btn-unstyle{background-color:transparent;border:none;padding:0;text-align:inherit}.btn-unstyle:focus{outline:0}.btn-unstyle:focus .expand-more{color:#2fb5d2}.card{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2)}.label,label{color:#232323;text-align:left;font-size:.875rem}small.label,small.value{font-size:.8125rem}.form-control-label{padding-top:.625rem}.form-control{background:#f1f1f1;color:#7a7a7a;border:1px solid rgba(0,0,0,.25);padding:.5rem 1rem}.form-control:focus{background-color:#fff;color:#232323}.form-control:focus,.input-group.focus{outline:.1875rem solid #2fb5d2}.input-group .form-control:focus{outline:none}.input-group .input-group-btn{height:100%}.input-group .input-group-btn>.btn{border:0;box-shadow:none;color:#fff;font-size:.6875rem;font-weight:400;margin-right:0;padding:.625rem 1rem;text-transform:uppercase}.input-group .input-group-btn>.btn[data-action=show-password]{background:#7a7a7a;padding:.78rem 1rem}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#7a7a7a}input::-moz-placeholder,textarea::-moz-placeholder{color:#7a7a7a}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#7a7a7a}input:-moz-placeholder,textarea:-moz-placeholder{color:#7a7a7a}input:active::-webkit-input-placeholder,textarea:active::-webkit-input-placeholder{color:#232323}input:active::-moz-placeholder,textarea:active::-moz-placeholder{color:#232323}input:active:-ms-input-placeholder,textarea:active:-ms-input-placeholder{color:#232323}input:active:-moz-placeholder,textarea:active:-moz-placeholder{color:#232323}.form-control-select{height:2.625rem;-moz-appearance:none;-webkit-appearance:none;background:#f1f1f1 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAQAAAD9CzEMAAAAPklEQVR4Ae3TwREAEBQD0V/6do4SXPZg7EsBhsQ8IEmSMOsiuEfg3gL3oXC7wK0bd1G4o8X9F4yIkyQfSrIByQBjp7QuND8AAAAASUVORK5CYII=") no-repeat scroll left .5rem center/1.25rem 1.25rem;padding:0 .5rem}.form-control-valign{padding-top:.5rem}.form-control-comment{font-size:.875rem;padding-top:.5rem;color:#7a7a7a}.form-control-submit.disabled{background:#5bc0de;color:#fff}.form-group.has-error input,.form-group.has-error select{outline:.1875rem solid #ff4c4c}.form-group.has-error .help-block{color:#ff4c4c}.group-span-filestyle label{margin:0}.bootstrap-touchspin .group-span-filestyle .btn-touchspin,.group-span-filestyle .bootstrap-touchspin .btn-touchspin,.group-span-filestyle .btn-default{background:#2fb5d2;color:#fff;text-transform:uppercase;border-radius:0;font-size:.875rem;padding:.5rem 1rem}.bootstrap-touchspin{width:auto;float:right;display:inline-block;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2)}.bootstrap-touchspin input:focus{outline:none}.bootstrap-touchspin input.form-control,.bootstrap-touchspin input.input-group{color:#232323;background-color:#fff;height:2.5rem;padding:.175rem .5rem;width:3rem;border:1px solid rgba(0,0,0,.25);float:right}.bootstrap-touchspin .btn-touchspin{background-color:#fff;border:1px solid rgba(0,0,0,.25);height:1.3125rem}.bootstrap-touchspin .btn-touchspin:hover{background-color:#f1f1f1}.bootstrap-touchspin .input-group-btn-vertical{color:#232323;width:auto;float:right}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down,.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0}.bootstrap-touchspin .input-group-btn-vertical .touchspin-up:after{content:"\E5CE"}.bootstrap-touchspin .input-group-btn-vertical .touchspin-down:after{content:"\E5CF"}.bootstrap-touchspin .input-group-btn-vertical i{top:.0625rem;right:.1875rem;font-size:.9375rem}.custom-radio{display:inline-block;position:relative;width:20px;height:20px;vertical-align:middle;cursor:pointer;border-radius:50%;border:2px solid #7a7a7a;background:#fff;margin-left:1.25rem}.custom-radio input[type=radio]{opacity:0;cursor:pointer}.custom-radio input[type=radio]:checked+span{display:block;background-color:#2fb5d2;width:12px;height:12px;border-radius:50%;position:absolute;right:.125rem;top:.125rem}.custom-radio input[type=radio]:focus+span{border-color:#7a7a7a}.custom-checkbox{position:relative}.custom-checkbox input[type=checkbox]{margin-top:.25rem;opacity:0;cursor:pointer;position:absolute}.custom-checkbox input[type=checkbox]+span{margin-left:3px;display:inline-block;width:.9375rem;height:.9375rem;vertical-align:middle;cursor:pointer;border:2px solid #232323}.custom-checkbox input[type=checkbox]+span .checkbox-checked{display:none;margin:-.25rem -.125rem;font-size:1.1rem;color:#232323}.custom-checkbox input[type=checkbox]:checked+span .checkbox-checked{display:block}.custom-checkbox input[type=checkbox]:focus+span{border-color:#7a7a7a}.custom-checkbox label{text-align:right}.text-muted{font-size:.875rem}.done{color:#4cbb6c;display:inline-block;padding:0 .8125rem;margin-left:1.563rem}.thumb-mask>.mask{position:relative;width:3.438rem;height:3.438rem;overflow:hidden;border:1px solid #f1f1f1;margin:.625rem 0}.thumb-mask>.mask img{width:55px;height:55px}.definition-list dl{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.definition-list dl dt{font-weight:400}.definition-list dl dd,.definition-list dl dt{-webkit-box-flex:0;-ms-flex:0 0 45%;flex:0 0 45%;background:#f1f1f1;padding:.625rem;margin:.125rem}.definition-list dl dd:nth-of-type(2n),.definition-list dl dt:nth-of-type(2n){background:#f6f6f6}.help-block{margin-top:.625rem}.btn.disabled,.btn.disabled:hover{background:#7a7a7a}.alert-warning .material-icons{color:#ff9a52;font-size:2rem;margin-left:.625rem;padding-top:.3125rem}.alert-warning .alert-text{font-size:.9375rem;padding-top:.625rem}.alert-warning .alert-link{border-radius:2px;border-width:2px;margin-right:.625rem;padding:.3125rem 1.25rem;font-weight:600;font-size:.8125rem;color:#6c868e}.alert-warning ul li:last-child .alert-link{color:#fff}.alert-warning .warning-buttons{margin-top:.3125rem}.btn-tertiary-outline{color:#6c868e;background-image:none;background-color:transparent;border-color:#6c868e;border:.15rem solid #6c868e}.btn-tertiary-outline:hover{border-color:#bbcdd2;color:#bbcdd2}.alert{font-size:.8125rem}.nav-item .nav-link,.nav-item .nav-separtor{color:#7a7a7a;font-weight:700}.nav-item .nav-link.active,.nav-item .nav-separtor.active{color:#232323}.separator{margin:0;border-color:rgba(0,0,0,.25)}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - 60px)}.ps-alert-error{margin-bottom:0}.ps-alert-error .item,.ps-alert-success .item{-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:2px solid #ff4c4c;display:-webkit-box;display:-ms-flexbox;display:flex;background-color:#ff4c4c;margin-bottom:1rem}.ps-alert-error .item i,.ps-alert-success .item i{border:15px solid #ff4c4c;display:-webkit-box;display:-ms-flexbox;display:flex}.ps-alert-error .item i svg,.ps-alert-success .item i svg{background-color:#ff4c4c;width:24px;height:24px}.ps-alert-error .item p,.ps-alert-success .item p{background-color:#fff;margin:0;padding:18px 20px;width:100%}.ps-alert-success{padding:.25rem .25rem 2.75rem}.ps-alert-success .item{border-color:#4cbb6c;background-color:#4cbb6c}.ps-alert-success .item i{border-color:#4cbb6c}.ps-alert-success .item i svg{background-color:#4cbb6c}.dropdown{color:#7a7a7a}.dropdown:hover .expand-more{color:#2fb5d2}.dropdown .expand-more{color:#232323;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dropdown .active{max-height:200px;overflow-y:hidden;visibility:visible}.dropdown select{-moz-appearance:none;border:0 none;outline:0 none;color:#232323;background:#fff}.dropdown-item:focus,.dropdown-item:hover{background:none;text-decoration:none;color:#2fb5d2}.search-widget{display:inline-block}.search-widget form{position:relative}.search-widget form input[type=text]{border:none;padding:10px;min-width:255px;color:#7a7a7a;border:1px solid rgba(0,0,0,.25)}.search-widget form input[type=text]:focus{outline:3px solid #2fb5d2;color:#232323;background:#fff}.search-widget form input[type=text]:focus+button .search{color:#2fb5d2}.search-widget form button[type=submit]{position:absolute;background:none;border:none;bottom:.3125rem;left:.125rem;color:#7a7a7a}.search-widget form button[type=submit] .search:hover{color:#2fb5d2}.header-top .search-widget form input[type=text]{min-width:inherit;width:100%}#checkout #search_widget{display:none}#pagenotfound .page-content #search_widget{width:100%}.page-not-found .search-widget form{display:inline-block}@media (max-width:767px){.header-top .search-widget{float:none}.header-top .search-widget form{margin:0 auto}.header-top .search-widget form input[type=text]{min-width:inherit;background:#fff}}@media (min-width:768px){.search-widget{min-width:15.63rem}}.top-menu[data-depth="1"]{margin:.625rem}.top-menu a:not([data-depth="0"]){display:block;padding:.625rem;color:#7a7a7a;font-weight:400}.top-menu a.dropdown-submenu{color:#232323;text-transform:uppercase;font-weight:600}.top-menu a[data-depth="0"]{font-weight:600;padding:.1875rem .625rem .375rem}#header .top-menu a[data-depth="0"]:hover{color:#2fb5d2;text-decoration:none}.top-menu a[data-depth="1"],.top-menu a[data-depth="2"]{padding:0 0 .625rem .625rem}.top-menu .collapse{display:inherit}.top-menu .sub-menu{box-shadow:-2px 1px 11px 2px rgba(0,0,0,.1);border:none;margin-right:.9375rem;width:calc(100% - 30px);min-width:calc(100% - 30px);z-index:18;display:none}.top-menu .sub-menu.collapse{display:none}.top-menu .sub-menu ul[data-depth="1"]>li{float:right;margin:0 1.25rem}.top-menu .sub-menu a:hover{color:#2fb5d2}.top-menu .popover{max-width:inherit;border-radius:0}.popover.bs-tether-element-attached-top{margin-top:0}#_desktop_top_menu .top-menu[data-depth="0"] li:hover .sub-menu{display:block!important}#mobile_top_menu_wrapper{padding:15px;background:#fff}#mobile_top_menu_wrapper #top-menu{margin-bottom:.625rem}#mobile_top_menu_wrapper .top-menu{color:#232323}#mobile_top_menu_wrapper .top-menu .collapse-icons[aria-expanded=true] .add{display:none}#mobile_top_menu_wrapper .top-menu .collapse-icons[aria-expanded=true] .remove{display:block}#mobile_top_menu_wrapper .top-menu .collapse-icons .remove{display:none}#mobile_top_menu_wrapper .top-menu .navbar-toggler{display:inline-block;padding:0}#mobile_top_menu_wrapper .top-menu a[data-depth="0"]{padding:.625rem;border-bottom:1px solid #f6f6f6}#mobile_top_menu_wrapper .top-menu .collapse{display:none}#mobile_top_menu_wrapper .top-menu .collapse.in{display:block}#mobile_top_menu_wrapper .top-menu .sub-menu{box-shadow:none;z-index:inherit;display:block;position:static;overflow:hidden;margin-right:0;width:100%;min-width:100%;background:#fff}#mobile_top_menu_wrapper .top-menu .sub-menu.collapse{display:none}#mobile_top_menu_wrapper .top-menu .sub-menu.collapse.in{display:block}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="0"]>li{border-bottom:1px solid #7a7a7a}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]{margin:0}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]>li{float:none;margin:0}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="1"]>li a{text-transform:none}#mobile_top_menu_wrapper .top-menu .sub-menu ul{padding:0}#mobile_top_menu_wrapper .top-menu .sub-menu li>a{padding:.625rem;border-bottom:1px solid #fff;font-weight:700}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="2"] li a{padding-right:1.25rem}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="3"] li a{padding-right:2.5rem}#mobile_top_menu_wrapper .top-menu .sub-menu ul[data-depth="4"] li a{padding-right:3.75rem}#mobile_top_menu_wrapper .js-top-menu-bottom a{color:#7a7a7a}#mobile_top_menu_wrapper .js-top-menu-bottom .language-selector-wrapper{padding:.625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .language-selector-wrapper .language-selector{display:inline}#mobile_top_menu_wrapper .js-top-menu-bottom #contact-link,#mobile_top_menu_wrapper .js-top-menu-bottom .currency-selector{padding:.625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .user-info{padding:0 .625rem}#mobile_top_menu_wrapper .js-top-menu-bottom .user-info a{padding:.625rem 0;display:block;width:100%}body#checkout{color:#232323}body#checkout #header .header-nav{max-height:none;padding:.9375rem 0;border:none;margin-bottom:0;box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2)}body#checkout #header .header-nav .logo{max-height:4.375rem;width:auto}body#checkout #header .header-nav #_desktop_contact_link #contact-link{margin-top:0}body#checkout .custom-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex}body#checkout .custom-checkbox span{-webkit-box-flex:0;-ms-flex:0 0 15px;flex:0 0 15px;margin-top:.1875rem}body#checkout a:hover{color:#1a8196}body#checkout section#content{margin-bottom:1.563rem}body#checkout .container{min-height:100%}body#checkout section.checkout-step{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background-color:#fff;border-bottom:1px solid rgba(0,0,0,.25);padding:.9375rem}body#checkout section.checkout-step:last-child{border:0}body#checkout section.checkout-step .step-title{text-transform:uppercase;cursor:pointer;margin-bottom:0}body#checkout section.checkout-step .content{padding:0 2.313rem}body#checkout section.checkout-step .step-edit{text-transform:lowercase;font-weight:400}body#checkout section.checkout-step .step-edit .edit{font-size:1rem}body#checkout section.checkout-step .not-allowed{cursor:not-allowed;opacity:.5}body#checkout section.checkout-step .content,body#checkout section.checkout-step .done,body#checkout section.checkout-step .step-edit{display:none}body#checkout section.checkout-step.-unreachable .step-title{cursor:not-allowed;opacity:.5}body#checkout section.checkout-step.-current .step-title{cursor:default}body#checkout section.checkout-step.-current .content{display:block}body#checkout section.checkout-step.-current.-reachable.-complete .done,body#checkout section.checkout-step.-current.-reachable.-complete .step-edit{display:none}body#checkout section.checkout-step.-current.-reachable.-complete .step-number{display:inline-block}body#checkout section.checkout-step.-current.-reachable.-complete .content{display:block}body#checkout section.checkout-step.-reachable.-complete h1 .done{display:inline-block}body#checkout section.checkout-step.-reachable.-complete h1 .step-number{display:none}body#checkout section.checkout-step.-reachable.-complete h1 .step-edit{cursor:pointer;display:block;float:left;margin-left:.125rem;color:#7a7a7a}body#checkout section.checkout-step.-reachable.-complete .content{display:none}body#checkout section.checkout-step small{color:#7a7a7a}body#checkout section.checkout-step .default-input{min-width:40%}body#checkout section.checkout-step .default-input[name=address1],body#checkout section.checkout-step .default-input[name=address2]{min-width:60%}body#checkout section.checkout-step .radio-field{margin-top:1.875rem}body#checkout section.checkout-step .radio-field label{display:inline}body#checkout section.checkout-step .checkbox-field div{margin-top:3.75rem}body#checkout section.checkout-step .checkbox-field+.checkbox-field div{margin-top:0}body#checkout section.checkout-step .select-field div{background:#f6f6f6;padding:.625rem 3.125rem}body#checkout section.checkout-step .form-footer{text-align:center}body#checkout section.checkout-step #conditions-to-approve{padding-top:1rem}body#checkout section.checkout-step .payment-options label{display:table-cell}body#checkout section.checkout-step .payment-options .custom-radio{margin-left:1.25rem}body#checkout section.checkout-step .payment-options .payment-option{margin-bottom:.5rem}body#checkout section.checkout-step .step-number{display:inline-block;padding:.625rem}body#checkout section.checkout-step .address-selector{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-ms-flex-wrap:wrap;flex-wrap:wrap}body#checkout section.checkout-step .address-item{background:#f6f6f6;-webkit-box-flex:0;-ms-flex:0 0 49%;flex:0 0 49%;margin-bottom:.625rem;border:3px solid transparent}body#checkout section.checkout-step .address-item.selected{background:#fff;border:3px solid #2fb5d2}body#checkout section.checkout-step .address-alias{display:inline-block;font-weight:600;margin-bottom:.625rem}body#checkout section.checkout-step .address{margin-right:1.563rem;font-weight:400}body#checkout section.checkout-step .radio-block{padding:.9375rem;text-align:right;cursor:pointer}body#checkout section.checkout-step .custom-radio{margin-left:0}body#checkout section.checkout-step .custom-radio input[type=radio]{height:1.25rem;width:1.25rem}body#checkout section.checkout-step .delete-address,body#checkout section.checkout-step .edit-address{color:#7a7a7a;display:inline-block;margin:0 .3125rem}body#checkout section.checkout-step .delete-address .delete,body#checkout section.checkout-step .delete-address .edit,body#checkout section.checkout-step .edit-address .delete,body#checkout section.checkout-step .edit-address .edit{font-size:1rem}body#checkout section.checkout-step hr{margin:0}body#checkout section.checkout-step .address-footer{text-align:center;padding:.625rem}body#checkout section.checkout-step #delivery-addresses,body#checkout section.checkout-step #invoice-addresses,body#checkout section.checkout-step .add-address{margin-top:1.25rem}body#checkout section.checkout-step .add-address a{color:#232323}body#checkout section.checkout-step .add-address a i{font-size:.9375rem}body#checkout section.checkout-step .delivery-option{background:#f6f6f6;padding:.9375rem 0;margin-bottom:.9375rem}body#checkout section.checkout-step .delivery-option label{text-align:inherit}body#checkout section.checkout-step .delivery-option img{width:3.125rem}body#checkout section.checkout-step .carrier-delay,body#checkout section.checkout-step .carrier-name{display:inline-block;word-break:break-word;text-align:right}body#checkout section.checkout-step #customer-form,body#checkout section.checkout-step #delivery-address,body#checkout section.checkout-step #invoice-address,body#checkout section.checkout-step #login-form{margin-right:.3125rem;margin-top:1.563rem}body#checkout section.checkout-step #customer-form .form-control-label,body#checkout section.checkout-step #delivery-address .form-control-label,body#checkout section.checkout-step #invoice-address .form-control-label,body#checkout section.checkout-step #login-form .form-control-label{text-align:right}body#checkout section.checkout-step #customer-form .radio-inline,body#checkout section.checkout-step #delivery-address .radio-inline,body#checkout section.checkout-step #invoice-address .radio-inline,body#checkout section.checkout-step #login-form .radio-inline{padding:0}body#checkout section.checkout-step .sign-in{font-size:.875rem}body#checkout section.checkout-step .forgot-password{margin-right:14.38rem}body#checkout .additional-information{font-size:.875rem;margin-right:2.875rem;margin-top:1.25rem}body#checkout .condition-label{margin-right:2.5rem;margin-top:.625rem}body#checkout .condition-label label{text-align:inherit}body#checkout .cancel-address{margin:.625rem;display:block;color:#7a7a7a;text-decoration:underline}body#checkout .modal-content{padding:1.25rem;background-color:#f1f1f1}body#checkout #cart-summary-product-list{font-size:.875rem}body#checkout #cart-summary-product-list img{border:1px solid #f1f1f1;width:3.125rem}body#checkout #cart-summary-product-list .media-body{vertical-align:middle}body#checkout #order-summary-content{padding-top:.9375rem}body#checkout #order-summary-content h4.h4{margin-top:.625rem;margin-bottom:1.25rem;color:#232323}body#checkout #order-summary-content h4.black{color:#000}body#checkout #order-summary-content h4.addresshead{margin-top:.1875rem}body#checkout #order-summary-content .noshadow{box-shadow:none}body#checkout #order-summary-content #order-items{border-left:0}body#checkout #order-summary-content #order-items h3.h3{color:#232323;margin-top:1.25rem}body#checkout #order-summary-content #order-items table tr:first-child td{border-top:0}body#checkout #order-summary-content .order-confirmation-table{padding:1rem;margin-bottom:2rem;background-color:#fff;border:3px solid #e5e5e5;border-radius:0}body#checkout #order-summary-content .summary-selected-carrier{margin-bottom:.75rem;background-color:#fff;border:1px solid #e5e5e5;border-radius:0;padding:1rem}body#checkout #order-summary-content .summary-selected-carrier .logo-container{text-align:center}body#checkout #order-summary-content .summary-selected-carrier .logo-container img{width:3.125rem}body#checkout #order-summary-content .step-edit{display:inline;color:#7a7a7a}body#checkout #order-summary-content .step-edit:hover{cursor:pointer}body#checkout #order-summary-content a .step-edit{color:#7a7a7a}body#checkout #delivery,body#checkout #gift_message{max-width:100%;border-color:#232323}body#checkout #delivery textarea,body#checkout #gift_message textarea{max-width:100%;margin-bottom:10px}body#checkout #footer{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);padding:.9375rem;background:#fff;color:#7a7a7a}#order-details{padding-right:1.3rem;margin-top:1.25rem}#order-details>.card-title{margin-bottom:1.875rem}#order-details ul{margin-bottom:1.25rem}#order-details ul li{margin-bottom:.625rem}#order-items{border-left:1px solid #f1f1f1}#order-items .h3{font-size:1rem}@media (max-width:991px){#order-items .h3._desktop-title{display:none}}#order-items hr{border-top-color:#232323}#order-items table{width:100%}#order-items table tr{height:1.875rem}#order-items table tr td:last-child{text-align:left}#order-items table tr td{padding:.5rem;font-size:.875rem}#order-items table tr.total-value{background-color:#f1f1f1}#order-items table tr.taxes td{text-align:right}#order-items table tr.taxes td .value{padding-top:0}#order-items .order-line{margin-top:1rem}#order-items .image img{width:100%;border:1px solid gray-lighter;margin-bottom:1rem}#order-items .details{margin-bottom:1rem}#order-items .details .customizations{margin-top:.625rem}#order-items .qty{margin-bottom:1rem}#order-confirmation #registration-form{width:50%;margin:0 auto 1rem}@media (max-width:991px){.done{margin-left:.625rem;padding:0}body#checkout section.checkout-step .address-item{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}body#checkout section.checkout-step .delivery-option-2{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.delivery-option{display:-webkit-box;display:-ms-flexbox;display:flex;margin:auto}.delivery-option .custom-radio{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto}.condition-label label[for="conditions_to_approve[terms-and-conditions]"]{text-align:right}#order-confirmation #registration-form{width:100%}}@media (max-width:767px){body#checkout section.checkout-step.-reachable.-complete h1 .step-edit{float:none;margin-top:.25rem;margin-right:1.25rem}body#checkout #header .header-nav{max-height:none;padding:0}body#checkout section.checkout-step .content{padding:.9375rem}body#checkout .form-group{margin-bottom:.5rem}#order-items{border-left:0;margin-bottom:2.5rem}#order-items .card-title{border-bottom:1px solid #f1f1f1;margin-bottom:1rem;padding-bottom:1rem}#order-items hr{border-top-color:#f1f1f1}.bold{font-weight:700}#order-details{padding-right:.9375rem}#order-details .card-title{border-bottom:1px solid #f1f1f1;margin-bottom:1rem;padding-bottom:1rem}}@media (max-width:575px){body#checkout section.checkout-step .content{padding:.9375rem 0}#payment-confirmation button{font-size:.875rem}#payment-confirmation button.btn{white-space:normal}}.js-payment-binary,.js-payment-binary .accept-cgv{display:none}.js-payment-binary.disabled{opacity:.6;cursor:not-allowed}.js-payment-binary.disabled:before{content:"";position:absolute;top:0;left:0;bottom:0;right:0;pointer-events:none}.js-payment-binary.disabled .accept-cgv{display:block}.table-labeled td,.table-labeled th{vertical-align:middle}.table-labeled .label{font-weight:400;border-radius:3px;font-size:inherit;padding:.25rem .375rem;margin:.125rem;color:#fff;white-space:nowrap}.page-order .table{margin-bottom:0}.page-order table td,.page-order table th{padding:.5rem}.page-order table thead th{text-align:center}#authentication .tooltip.tooltip-bottom{padding:0;margin:0}#authentication .custom-checkbox{display:-webkit-box;display:-ms-flexbox;display:flex}#authentication .custom-checkbox span{-webkit-box-flex:0;-ms-flex:0 0 0.9375rem;flex:0 0 0.9375rem}#authentication .custom-checkbox label{padding-right:.625rem}#authentication .radio-inline,#identity .radio-inline{padding:0}#authentication .radio-inline .custom-radio,#identity .radio-inline .custom-radio{margin-left:0}.page-customer-account #content{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;font-size:.875rem;color:#7a7a7a}.page-customer-account #content .order-actions a{padding:0 .125rem}.page-customer-account #content .forgot-password{text-align:center;font-size:.875rem;margin-top:1rem;padding-bottom:.9375rem}.page-customer-account #content .no-account{text-align:center;font-size:1rem}.page-authentication #content{padding:1rem;max-width:640px;margin:0 auto}.page-addresses .address,.page-authentication #content{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}.page-addresses .address{margin-bottom:1.875rem;font-size:.875rem;color:#232323}.page-addresses .address .address-body{padding:1rem}.page-addresses .address .address-body h4{font-size:1rem;font-weight:700}.page-addresses .address .address-body address{min-height:9rem}.page-addresses .address .address-footer{border-top:1px solid #7a7a7a;padding:.5rem 1rem}.page-addresses .address .address-footer a{color:#7a7a7a;margin-left:.5rem}.page-addresses .address .address-footer a:hover{color:#232323}.page-addresses .address .address-footer a i{font-size:1rem}.page-addresses .address .address-footer a span{font-size:.9375rem;vertical-align:middle}.page-addresses .addresses-footer{margin:0 .9375rem}.page-addresses .addresses-footer a,.page-addresses .addresses-footer a:hover{color:#232323}.page-addresses .addresses-footer a i{font-size:1rem}.page-addresses .addresses-footer a span{font-size:1rem;vertical-align:middle;margin-top:.625rem}.page-order-detail{font-size:.875rem;color:#7a7a7a}.page-order-detail .box{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;margin-bottom:1rem}.page-order-detail h3{font-size:1rem;font-weight:700;text-transform:uppercase;color:#232323;margin-bottom:1rem}.page-order-detail #order-infos ul{margin:0}.page-order-detail #order-history .history-lines .history-line{padding:.5rem 0;border-bottom:1px solid #f6f6f6}.page-order-detail #order-history .history-lines .history-line:last-child{border-bottom:0}.page-order-detail #order-history .history-lines .history-line .label{display:inline-block;margin:.25rem 0;padding:.25rem .375rem;color:#fff;border-radius:3px}.page-order-detail .addresses{margin:0 -.9375rem}.page-order-detail .addresses h4{font-size:1rem;font-weight:700}.page-order-detail #order-products.return{margin-bottom:1rem}.page-order-detail #order-products.return th.head-checkbox{width:30px}.page-order-detail #order-products.return td{padding:1.375rem .75rem}.page-order-detail #order-products.return td.qty{min-width:125px}.page-order-detail #order-products.return td.qty .current{width:30%;float:right;text-align:left;padding-left:.5rem}.page-order-detail #order-products.return td.qty .select{width:70%;float:right;margin:-.625rem 0;padding-right:.25rem}.page-order-detail #order-products.return td.qty .select select{text-align:center}.page-order-detail .order-items{padding:0!important}.page-order-detail .order-items .order-item{padding:1rem 1rem 0;border-bottom:1px solid #f6f6f6}.page-order-detail .order-items .order-item .checkbox{width:30px;float:right;padding:0 .9375rem}.page-order-detail .order-items .order-item .content{width:calc(100% - 30px);float:right;padding:0 .9375rem}.page-order-detail .order-items .order-item .desc{margin-bottom:1rem}.page-order-detail .order-items .order-item .desc .name{font-weight:700}.page-order-detail .order-items .order-item .qty{margin-bottom:1rem}.page-order-detail .order-items .order-item .qty .q,.page-order-detail .order-items .order-item .qty .s{margin-bottom:.25rem}.page-order-detail .messages .message{margin-top:.5rem;border-bottom:1px solid #f6f6f6}.page-order-detail .messages .message:last-child{border-bottom:0}.page-order-detail .messages .message>div{margin-bottom:.5rem}.page-order-detail .customization{margin-top:.75rem}#order-return-infos .thead-default th{color:#232323}#order-return-infos .customization{margin-top:.75rem}.page-my-account #content .links{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.page-my-account #content .links a{text-align:center;display:inline-block;font-size:1rem;font-weight:700;text-transform:uppercase;color:#7a7a7a;padding:0 .9375rem;margin-bottom:1.875rem}.page-my-account #content .links a span.link-item{display:block;height:100%;box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem}.page-my-account #content .links a i{display:block;font-size:2.6rem;width:100%;color:#232323;padding-bottom:3.4rem}.page-my-account #content .links a:hover{color:#232323}.page-my-account #content .links a:hover i{color:#2fb5d2}#history .orders{margin:0 -1rem}#history .orders .order{padding:.75rem 1rem;border-bottom:1px solid #f6f6f6}#history .orders .order a h3{color:#7a7a7a}#history .orders .order .label{display:inline-block;margin:.25rem 0;padding:.25rem .375rem;color:#fff;border-radius:3px}#history .orders .order:last-child{border-bottom:0}.page-footer .account-link{margin-left:1rem}.page-footer .account-link i{font-size:1rem}.page-footer .account-link span{font-size:.875rem;vertical-align:middle}.login-form{margin-top:15px}.forgotten-password{padding:4px}.forgotten-password .form-fields .center-email-fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}@media (max-width:767px){.forgotten-password .form-fields .center-email-fields{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.forgotten-password .form-fields .center-email-fields button{margin:10px;width:calc(100% - 20px)}}.forgotten-password .form-fields .center-email-fields button{height:38px}.forgotten-password .form-fields .email{padding-right:0;padding-left:0;width:430px}@media (max-width:767px){.forgotten-password .form-fields .email{padding-right:10px;padding-left:10px;width:100%}}.forgotten-password .form-fields .email input{height:38px}.forgotten-password .form-fields label.required{width:130px}.send-renew-password-link{padding-right:10px;padding-left:10px}.renew-password{margin-right:10px}.renew-password .email{padding-bottom:30px}.renew-password [type=submit]{margin-right:50px}.carousel{box-shadow:-1px 1px 7px 0 rgba(0,0,0,.15);margin-bottom:1.5rem}.carousel .direction{z-index:auto}.carousel .carousel-inner{height:340px}.carousel .carousel-item{height:100%}.carousel .carousel-item img{width:100%;max-width:100%;height:auto}.carousel .carousel-item .caption{position:absolute;bottom:28px;right:90px;color:#fff;max-width:340px}.carousel .carousel-item .caption .caption-description p{color:#fff}.carousel .carousel-item figure{margin:0}.carousel .carousel-control{opacity:1}.carousel .carousel-control .icon-next:before,.carousel .carousel-control .icon-prev:before{content:""}.carousel .carousel-control .icon-next i,.carousel .carousel-control .icon-prev i{font-size:3.125rem;color:#fff}.carousel .carousel-control .icon-next:hover i,.carousel .carousel-control .icon-prev:hover i{color:#2fb5d2}.carousel .carousel-control .icon-prev{right:1rem}.carousel .carousel-control .icon-next{left:2rem}.carousel .carousel-control.left,.carousel .carousel-control.right{background:none}@media (max-width:1199px){.carousel .carousel-inner{height:auto}}@media (max-width:991px){.carousel .carousel-item .caption{bottom:calc(50% - 2rem);right:10%}.carousel .carousel-item .caption .display-1{font-size:2rem}.carousel .carousel-item .caption-description{display:none}}@media (max-width:767px){.carousel .carousel-item .caption{bottom:calc(50% - 1.5rem)}.carousel .carousel-item .caption .display-1{font-size:1.5rem}.carousel .carousel-control .icon-next i,.carousel .carousel-control .icon-prev i{font-size:2rem}}#products .products,.featured-products .products,.product-accessories .products,.product-miniature .products{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}#products .product-thumbnail,.featured-products .product-thumbnail,.product-accessories .product-thumbnail,.product-miniature .product-thumbnail{display:block}#products .product-title a,.featured-products .product-title a,.product-accessories .product-title a,.product-miniature .product-title a{color:#7a7a7a;font-size:.875rem;text-decoration:none;text-align:center;font-weight:400}#products .thumbnail-container,.featured-products .thumbnail-container,.product-accessories .thumbnail-container,.product-miniature .thumbnail-container{position:relative;margin-bottom:1.563rem;height:318px;width:250px;background:#fff;box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2)}#products .thumbnail-container:focus .highlighted-informations,#products .thumbnail-container:hover .highlighted-informations,.featured-products .thumbnail-container:focus .highlighted-informations,.featured-products .thumbnail-container:hover .highlighted-informations,.product-accessories .thumbnail-container:focus .highlighted-informations,.product-accessories .thumbnail-container:hover .highlighted-informations,.product-miniature .thumbnail-container:focus .highlighted-informations,.product-miniature .thumbnail-container:hover .highlighted-informations{bottom:5.5rem}#products .thumbnail-container:focus .highlighted-informations:after,#products .thumbnail-container:hover .highlighted-informations:after,.featured-products .thumbnail-container:focus .highlighted-informations:after,.featured-products .thumbnail-container:hover .highlighted-informations:after,.product-accessories .thumbnail-container:focus .highlighted-informations:after,.product-accessories .thumbnail-container:hover .highlighted-informations:after,.product-miniature .thumbnail-container:focus .highlighted-informations:after,.product-miniature .thumbnail-container:hover .highlighted-informations:after{opacity:1}#products .thumbnail-container:focus .highlighted-informations.no-variants,#products .thumbnail-container:hover .highlighted-informations.no-variants,.featured-products .thumbnail-container:focus .highlighted-informations.no-variants,.featured-products .thumbnail-container:hover .highlighted-informations.no-variants,.product-accessories .thumbnail-container:focus .highlighted-informations.no-variants,.product-accessories .thumbnail-container:hover .highlighted-informations.no-variants,.product-miniature .thumbnail-container:focus .highlighted-informations.no-variants,.product-miniature .thumbnail-container:hover .highlighted-informations.no-variants{bottom:4.2rem}#products .thumbnail-container:focus .product-description:after,#products .thumbnail-container:hover .product-description:after,.featured-products .thumbnail-container:focus .product-description:after,.featured-products .thumbnail-container:hover .product-description:after,.product-accessories .thumbnail-container:focus .product-description:after,.product-accessories .thumbnail-container:hover .product-description:after,.product-miniature .thumbnail-container:focus .product-description:after,.product-miniature .thumbnail-container:hover .product-description:after{content:"";border-top:1px solid #7a7a7a;position:absolute;width:80%;top:0;right:10%;opacity:.25}#products .thumbnail-container .product-thumbnail,.featured-products .thumbnail-container .product-thumbnail,.product-accessories .thumbnail-container .product-thumbnail,.product-miniature .thumbnail-container .product-thumbnail{position:relative;height:calc(100% - 70px)}#products .thumbnail-container .product-thumbnail img,.featured-products .thumbnail-container .product-thumbnail img,.product-accessories .thumbnail-container .product-thumbnail img,.product-miniature .thumbnail-container .product-thumbnail img{max-width:100%;position:absolute;top:0;bottom:0;right:0;left:0;margin:auto}#products .products-section-title,.featured-products .products-section-title,.product-accessories .products-section-title,.product-miniature .products-section-title{text-align:center;margin-bottom:1.5rem}#products .product-title,.featured-products .product-title,.product-accessories .product-title,.product-miniature .product-title{text-align:center;text-transform:capitalize;margin-top:.7rem}#products .product-price-and-shipping,.featured-products .product-price-and-shipping,.product-accessories .product-price-and-shipping,.product-miniature .product-price-and-shipping{color:#232323;font-weight:700;text-align:center}#products .product-price-and-shipping .discount-product,.featured-products .product-price-and-shipping .discount-product,.product-accessories .product-price-and-shipping .discount-product,.product-miniature .product-price-and-shipping .discount-product{display:none}#products .variant-links,.featured-products .variant-links,.product-accessories .variant-links,.product-miniature .variant-links{position:relative;text-align:center;width:100%;top:-.25em;padding-top:.1875rem;min-height:2.5rem;background:#fff}#products .highlighted-informations,.featured-products .highlighted-informations,.product-accessories .highlighted-informations,.product-miniature .highlighted-informations{position:absolute;bottom:1.25rem;padding-top:.625rem;z-index:2;background:#fff;text-align:center;width:250px;height:3.125rem;box-shadow:0 -5px 10px -5px rgba(0,0,0,.2);transition:bottom .3s}#products .highlighted-informations .quick-view,.featured-products .highlighted-informations .quick-view,.product-accessories .highlighted-informations .quick-view,.product-miniature .highlighted-informations .quick-view{color:#7a7a7a;font-size:1rem}#products .highlighted-informations .quick-view:hover,.featured-products .highlighted-informations .quick-view:hover,.product-accessories .highlighted-informations .quick-view:hover,.product-miniature .highlighted-informations .quick-view:hover{color:#2fb5d2}#products .product-description,.featured-products .product-description,.product-accessories .product-description,.product-miniature .product-description{position:absolute;z-index:3;background:#fff;width:250px;bottom:0;height:70px}#products .product-miniature,.featured-products .product-miniature,.product-accessories .product-miniature,.product-miniature .product-miniature{margin:0 .8125rem}#products .product-miniature .product-flags li.product-flag,.featured-products .product-miniature .product-flags li.product-flag,.product-accessories .product-miniature .product-flags li.product-flag,.product-miniature .product-miniature .product-flags li.product-flag{min-width:3.125rem;min-height:1.875rem;font-weight:600}#products .product-miniature .product-flags li.product-flag.online-only,.featured-products .product-miniature .product-flags li.product-flag.online-only,.product-accessories .product-miniature .product-flags li.product-flag.online-only,.product-miniature .product-miniature .product-flags li.product-flag.online-only{top:13.1rem}#products .comments_note,.featured-products .comments_note,.product-accessories .comments_note,.product-miniature .comments_note{text-align:center;color:#7a7a7a}#products .regular-price,.featured-products .regular-price,.product-accessories .regular-price,.product-miniature .regular-price{color:#7a7a7a;text-decoration:line-through;font-size:.875rem}#products .count,.featured-products .count,.product-accessories .count,.product-miniature .count{color:#7a7a7a;font-weight:700;position:relative;bottom:.5rem}#products .all-product-link,.featured-products .all-product-link,.product-accessories .all-product-link,.product-miniature .all-product-link{clear:both;color:#7a7a7a;font-weight:700;margin-top:1.5rem;margin-bottom:1.5rem}@media (max-width:767px){#products .thumbnail-container,.featured-products .thumbnail-container,.product-accessories .thumbnail-container{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2)}#products .thumbnail-container .product-description,.featured-products .thumbnail-container .product-description,.product-accessories .thumbnail-container .product-description{box-shadow:0 -5px 10px -5px rgba(0,0,0,.2)}}#custom-text{background:#fff;border-radius:2px;margin-bottom:1.5rem;padding:3.125rem;text-align:center}#custom-text h2{text-transform:uppercase;color:#232323;font-size:1.563rem;font-weight:700}#custom-text p{color:#232323;font-weight:400;font-size:1.1em}#custom-text p .dark{color:#7a7a7a;font-weight:400}.page-content.page-cms{background:#fff;padding:1.25rem;text-align:justify}.page-content.page-cms .cms-box img{max-width:100%}@media (max-width:991px){#block-cmsinfo{padding:1.25rem 1.875rem}}#products{color:#7a7a7a}#products .products-select{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}#products .up{margin-bottom:1rem}#products .up .btn-secondary,#products .up .btn-tertiary{color:#7a7a7a;text-transform:inherit}#products .up .btn-secondary .material-icons,#products .up .btn-tertiary .material-icons{margin-left:0}.block-category{min-height:13.75rem;margin-bottom:1.563rem}.block-category .block-category-inner{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.block-category .block-category-inner #category-description p,.block-category .block-category-inner #category-description strong{font-weight:400;color:#7a7a7a}.block-category .block-category-inner #category-description p{color:#232323;margin-bottom:0;word-break:break-word}.block-category .block-category-inner #category-description p:first-child{margin-bottom:1.25rem}.block-category .block-category-inner .category-cover img{width:141px;height:180px}.products-selection .sort-by-row{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.products-selection .sort-by{white-space:normal;word-break:break-word;margin-left:-.9375rem;margin-right:.9375rem;text-align:left}.products-selection .total-products,.products-selection h1{padding-top:.625rem}.products-sort-order{color:#7a7a7a}.products-sort-order .select-title{display:inline-block;width:100%;color:#232323;background:#fff;padding:.625rem;cursor:pointer;border:1px solid rgba(0,0,0,.25);box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2)}.products-sort-order .select-list{display:block;color:#232323;padding:.625rem 1.25rem}.products-sort-order .select-list:hover{background:#2fb5d2;color:#fff;text-decoration:none}.products-sort-order .dropdown-menu{right:auto;width:16.88rem;background:#f6f6f6;border:none;border-radius:0;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.1);margin:0}.facet-dropdown{color:#7a7a7a;padding-right:0;padding-left:0;background:#f1f1f1;border:3px solid transparent;box-sizing:border-box;box-shadow:-1px 1px 1px 1px #f1f1f1}.facet-dropdown.open{border:0}.facet-dropdown.open>.select-title{border:3px solid #2fb5d2;background:#f6f6f6}.facet-dropdown .select-title{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-right:0;width:100%;color:#232323;background:#f1f1f1;padding:.625rem 1.25rem .625rem .625rem;cursor:pointer}.facet-dropdown .select-title>i{margin-right:auto}.facet-dropdown .select-list{display:block;color:#232323;background:#f6f6f6;padding:.625rem 1.25rem}.facet-dropdown .select-list:hover{background:#2fb5d2;color:#fff;text-decoration:none}.facet-dropdown .dropdown-menu{padding:0;margin-top:3px;right:auto;width:100%;background:#f6f6f6;border:none;box-shadow:-1px 1px 1px 1px #f1f1f1}#search_filters,#search_filters_brands,#search_filters_suppliers{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);margin-bottom:1.563rem;background:#fff;padding:1.563rem 1.25rem}#search_filters .facet,#search_filters_brands .facet,#search_filters_suppliers .facet{padding-top:.625rem}#search_filters .facet .collapse,#search_filters_brands .facet .collapse,#search_filters_suppliers .facet .collapse{display:block}#search_filters .facet .facet-title,#search_filters_brands .facet .facet-title,#search_filters_suppliers .facet .facet-title{color:#7a7a7a}#search_filters .facet .facet-label,#search_filters_brands .facet .facet-label,#search_filters_suppliers .facet .facet-label{margin-bottom:0}#search_filters .facet .facet-label a,#search_filters_brands .facet .facet-label a,#search_filters_suppliers .facet .facet-label a{margin-top:.4375rem;color:#232323;display:inline-block;font-size:.9375rem}#search_filters_brands .facet,#search_filters_suppliers .facet{padding-top:0}#search_filters_brands .facet .facet-label,#search_filters_suppliers .facet .facet-label{margin-bottom:.3125rem}.pagination{width:100%}.pagination>div:first-child{line-height:2.5rem}.pagination .page-list{background:#fff;padding:.375rem;margin-bottom:0;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2)}.pagination .page-list li{display:inline}.pagination a{color:#000;font-weight:600}.pagination a:not(.previous):not(.next){letter-spacing:.125rem}.pagination .previous{float:right}.pagination .next{float:left}.pagination .disabled{color:#7a7a7a}.pagination .current a{color:#2fb5d2;text-decoration:none;font-size:1.25rem}.active_filters{background:#dededd;padding:.625rem 1.875rem 0;margin-bottom:1.25rem}.active_filters .active-filter-title{display:inline;margin-left:.625rem;font-weight:600}.active_filters ul{display:inline}.active_filters .filter-block{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);color:#232323;margin-left:.625rem;margin-bottom:.625rem;background:#fff;padding:.625rem;display:inline-block;font-size:.8125rem}.active_filters .filter-block .close{color:#232323;font-size:.9375rem;opacity:1;margin-top:.1875rem;margin-right:.3125rem}.block-categories{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1.563rem 1.25rem;margin-bottom:1.563rem}.block-categories .category-sub-menu{margin-top:.625rem}.block-categories .category-sub-menu .category-sub-link{font-size:.875rem}.block-categories .category-sub-menu li{position:relative}.block-categories .category-sub-menu li[data-depth="1"]{margin-bottom:.625rem}.block-categories .category-sub-menu li[data-depth="0"]>a{font-weight:600;border-bottom:1px solid rgba(0,0,0,.25);width:100%;display:inline-block;margin:.3125rem 0 0;padding-bottom:.1875rem}.block-categories .category-sub-menu li:not([data-depth="0"]):not([data-depth="1"]){padding-right:.3125rem}.block-categories .category-sub-menu li:not([data-depth="0"]):not([data-depth="1"]):before{content:"-";margin-left:.3125rem}.block-categories a{color:#232323}.block-categories .collapse-icons{position:absolute;left:0;top:0;padding:0;cursor:pointer}.block-categories .collapse-icons[aria-expanded=true] .add{display:none}.block-categories .collapse-icons[aria-expanded=true] .remove{display:block}.block-categories .collapse-icons .add:hover,.block-categories .collapse-icons .remove:hover{color:#2fb5d2}.block-categories .collapse-icons .remove{display:none}.block-categories .arrows .arrow-down,.block-categories .arrows .arrow-right{font-size:.875rem;cursor:pointer;margin-right:2px}.block-categories .arrows .arrow-down:hover,.block-categories .arrows .arrow-right:hover{color:#2fb5d2}.block-categories .arrows .arrow-down,.block-categories .arrows[aria-expanded=true] .arrow-right{display:none}.block-categories .arrows[aria-expanded=true] .arrow-down{display:inline-block}.facets-title{color:#232323}.products-selection .filter-button .btn-secondary,.products-selection .filter-button .btn-tertiary{padding:.75rem .5rem .6875rem}.advertising-block{margin-bottom:1.563rem}.advertising-block img{width:100%}@media (max-width:767px){#category #left-column{width:100%}#category #left-column #search_filters_wrapper{margin-right:-30px;margin-left:-30px}#category #left-column #search_filter_controls{text-align:center;margin-bottom:1rem}#category #left-column #search_filter_controls button{margin:0 .5rem}#category #left-column #search_filters{margin-bottom:0;box-shadow:none;padding:0;border-top:1px solid #f6f6f6}#category #left-column #search_filters .facet{padding-top:0;border-bottom:1px solid #f6f6f6}#category #left-column #search_filters .facet .title{cursor:pointer}#category #left-column #search_filters .facet .title .collapse-icons .remove,#category #left-column #search_filters .facet .title[aria-expanded=true] .collapse-icons .add{display:none}#category #left-column #search_filters .facet .title[aria-expanded=true] .collapse-icons .remove{display:block}#category #left-column #search_filters .facet .facet-title{color:#232323;text-transform:uppercase}#category #left-column #search_filters .facet .h6{margin-bottom:0;padding:.625rem;display:inline-block}#category #left-column #search_filters .facet .navbar-toggler{display:inline-block;padding:.625rem 0 0 .625rem}#category #left-column #search_filters .facet .collapse{display:none}#category #left-column #search_filters .facet .collapse.in{display:block}#category #left-column #search_filters .facet .facet-label a{margin-top:0}#category #left-column #search_filters .facet ul{margin-bottom:0}#category #left-column #search_filters .facet ul li{border-top:1px solid #f6f6f6;padding:.625rem}#category #content-wrapper,#category #search_filter_toggler{width:100%}.products-sort-order .select-title{margin-right:0}.products-selection h1{padding-top:0;text-align:center;margin-bottom:1rem}.products-selection .showing{padding-top:1rem}#best-sales #content-wrapper,#new-products #content-wrapper,#prices-drop #content-wrapper{width:100%}}@media (max-width:575px){.products-selection .filter-button{padding-right:0}#category #left-column #search_filters_wrapper{margin-right:-15px;margin-left:-15px}}@media screen and (max-width:767px){.category-cover{display:none}.block-category{min-height:0;margin-bottom:0}.card-block{padding:0}.card{box-shadow:none;background-color:inherit;border:none}}#product #content{position:relative;max-width:452px;margin:0 auto}.product-price{color:#2fb5d2;display:inline-block}#product-description-short{color:#232323}.product-information{font-size:.9375rem;color:#232323}.product-information .manufacturer-logo{height:35px}.product-information .product-description img{max-width:100%;height:auto}.input-color{position:absolute;opacity:0;cursor:pointer;height:1.25rem;width:1.25rem}.input-container{position:relative}.input-radio{position:absolute;top:0;cursor:pointer;opacity:0;width:100%;height:100%}.input-color:checked+span,.input-color:hover+span,.input-radio:checked+span,.input-radio:hover+span{border:2px solid #232323}.radio-label{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;display:inline-block;padding:.125rem .625rem;font-weight:600;border:2px solid #fff}.product-actions .control-label{margin-bottom:.375rem;display:block;width:100%}.product-actions .add-to-cart{height:2.75rem;line-height:inherit;padding-top:.625rem}.product-actions .add-to-cart .material-icons{line-height:inherit}.product-quantity{display:-webkit-box;display:-ms-flexbox;display:flex}.product-quantity .add,.product-quantity .qty{float:right;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-bottom:.5rem}.product-quantity .qty{margin-left:.4rem}.product-quantity #quantity_wanted{color:#232323;background-color:#fff;height:2.75rem;padding:.175rem .5rem;width:3rem}.product-quantity .input-group-btn-vertical{width:auto}.product-quantity .input-group-btn-vertical .btn{padding:.5rem .6875rem}.product-quantity .input-group-btn-vertical .btn i{font-size:1rem;top:.125rem;right:.1875rem}.product-quantity .btn-touchspin{height:1.438rem}.product-discounts{margin-bottom:1.5rem}.product-discounts>.product-discounts-title{font-weight:400;font-size:.875rem}.product-discounts>.table-product-discounts thead tr th{width:33%;padding:.625rem 1.25rem;background:#fff;border:.3125rem solid #f1f1f1;text-align:center}.product-discounts>.table-product-discounts tbody tr{background:#f6f6f6}.product-discounts>.table-product-discounts tbody tr:nth-of-type(2n){background:#fff}.product-discounts>.table-product-discounts tbody tr td{padding:.625rem 1.25rem;text-align:center;border:.3125rem solid #f1f1f1}.product-prices{margin-top:1.25rem}.product-prices div{margin-bottom:.625rem}.product-prices .tax-shipping-delivery-label{font-size:.8125rem;color:#7a7a7a}.product-prices .tax-shipping-delivery-label .delivery-information{padding:0 2px 0 0}.product-prices .tax-shipping-delivery-label .delivery-information:before{content:"-";padding:0 0 0 2px}.product-discount{color:#7a7a7a}.product-discount .regular-price{text-decoration:line-through;font-weight:400;margin-left:.625rem}.has-discount.product-price,.has-discount p{color:#f39d72}.has-discount .discount{background:#f39d72;color:#fff;font-weight:600;padding:.3125rem .625rem;font-size:1rem;margin-right:.625rem;text-transform:uppercase;display:inline-block}.product-unit-price{font-size:.8125rem;margin-bottom:0}.tabs{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);margin-top:2rem;background:#fff;padding:1.25rem 1.875rem}.tabs .tab-pane{padding-top:1.25rem}.tabs .nav-tabs{border:none;border-bottom:2px solid #f1f1f1}.tabs .nav-tabs .nav-link{color:#7a7a7a;border:0 solid transparent}.tabs .nav-tabs .nav-link.active{color:#2fb5d2}.tabs .nav-tabs .nav-link.active,.tabs .nav-tabs .nav-link:hover{border:none;border-bottom:3px solid #2fb5d2}.tabs .nav-tabs .nav-item{float:right;margin-bottom:-.125rem}.product-cover{margin-bottom:1.25rem;position:relative}.product-cover img{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}.product-cover .layer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;background:#fff;position:absolute;right:0;top:0;opacity:0;background:hsla(0,0%,100%,.7);text-align:center;cursor:pointer}.product-cover .layer:hover{opacity:1}.product-cover .layer .zoom-in{font-size:6.25rem;color:#7a7a7a}#product-modal .modal-content{background:transparent;border:none;padding:0}#product-modal .modal-content .modal-body{display:-webkit-box;display:-ms-flexbox;display:flex;margin-right:-30%}#product-modal .modal-content .modal-body .product-cover-modal{background:#fff}#product-modal .modal-content .modal-body .image-caption{background:#fff;width:800px;padding:.625rem 1.25rem;border-top:1px solid #f1f1f1}#product-modal .modal-content .modal-body .image-caption p{margin-bottom:0}#product-modal .modal-content .modal-body .thumbnails{position:relative}#product-modal .modal-content .modal-body .mask{position:relative;overflow:hidden;max-height:49.38rem;margin-top:2.188rem;z-index:1}#product-modal .modal-content .modal-body .mask.nomargin{margin-top:0}#product-modal .modal-content .modal-body .product-images{margin-right:2.5rem}#product-modal .modal-content .modal-body .product-images img{width:9.25rem;cursor:pointer;background:#fff}#product-modal .modal-content .modal-body .product-images img:hover{border:3px solid #2fb5d2}#product-modal .modal-content .modal-body .arrows{height:100%;width:100%;text-align:center;position:absolute;top:0;color:#fff;left:1.875rem;z-index:0;cursor:pointer}#product-modal .modal-content .modal-body .arrows .arrow-up{position:absolute;top:-2rem;opacity:.2}#product-modal .modal-content .modal-body .arrows .arrow-down{position:absolute;bottom:-2rem}#product-modal .modal-content .modal-body .arrows i{font-size:6.25rem;display:inline}#blockcart-modal{color:#232323}#blockcart-modal .modal-header{background:#fff}#blockcart-modal .modal-header .close{opacity:1}#blockcart-modal .modal-header .close .material-icons{color:#363a42}#blockcart-modal .modal-body{background:#fff;padding:3.125rem 1.875rem}#blockcart-modal .modal-body .divide-right span{display:inline-block;margin-bottom:.3125rem}@media (max-width:767px){#blockcart-modal .modal-body .divide-right span{display:block;padding:0 .5rem}}#blockcart-modal .modal-dialog{max-width:1140px;width:100%}#blockcart-modal .product-image{width:100%;max-width:9.375rem;display:block;margin:0 auto 0 0}#blockcart-modal .modal-title{color:#353943;font-size:1rem;font-weight:400}#blockcart-modal .modal-title i.material-icons{margin-left:1.875rem;color:#4cbb6c}#blockcart-modal .product-name{color:#2fb5d2;font-size:1.125rem}@media (max-width:767px){#blockcart-modal .product-name{padding:0 .5rem}}#blockcart-modal .product-price{color:#363a42;display:block}@media (max-width:767px){#blockcart-modal .product-price{padding:0 .5rem}}#blockcart-modal .cart-content{padding-right:2.5rem}#blockcart-modal .cart-content p{color:#363a42;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0 .5rem}#blockcart-modal .cart-content p.product-total{background-color:#f1f1f1;padding:.5rem}#blockcart-modal .cart-content p.cart-products-count{font-size:1rem;color:#6c868e;font-weight:600}#blockcart-modal .cart-content p.product-tax{display:inherit;font-size:.875rem}#blockcart-modal .cart-content p .label,#blockcart-modal .cart-content p .value{font-weight:600}#blockcart-modal .cart-content .cart-content-btn{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}#blockcart-modal .cart-content .cart-content-btn button{margin-left:.9rem}#blockcart-modal .cart-content .cart-content-btn .btn{white-space:inherit}#blockcart-modal .divide-right{border-left:1px solid #dbdbdb}.product-images>li.thumb-container{display:inline}.product-images>li.thumb-container>.thumb{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);cursor:pointer;margin-bottom:.625rem}.images-container .product-images>li.thumb-container>.thumb{margin-left:.8125rem}.product-images>li.thumb-container>.thumb.selected,.product-images>li.thumb-container>.thumb:hover{border:3px solid #2fb5d2}#main .images-container .js-qv-mask{white-space:nowrap;overflow:hidden}#main .images-container .js-qv-mask.scroll{width:calc(100% - 60px);margin:0 auto}.scroll-box-arrows{display:none}.scroll-box-arrows.scroll{display:block}.scroll-box-arrows i{position:absolute;bottom:1.625rem;height:100px;line-height:100px;cursor:pointer}.scroll-box-arrows .left{right:0}.scroll-box-arrows .right{left:0}#product-availability{margin-top:.625rem;display:inline-block;font-weight:700}#product-availability .material-icons{line-height:inherit}#product-availability .product-available{color:#4cbb6c}#product-availability .product-last-items,#product-availability .product-unavailable{color:#ff9a52}#product-details .label{font-size:1rem;color:#232323;font-weight:700}.product-features{margin-top:1.25rem;margin-right:.3125rem}.product-features>dl.data-sheet{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.product-features>dl.data-sheet dd.value,.product-features>dl.data-sheet dt.name{-webkit-box-flex:1;-ms-flex:1 0 40%;flex:1 0 40%;font-weight:400;background:#f1f1f1;padding:.625rem;margin-left:.625rem;min-height:2.5rem;word-break:normal;text-transform:capitalize;margin-bottom:.5rem}.product-features>dl.data-sheet dd.value:nth-of-type(2n),.product-features>dl.data-sheet dt.name:nth-of-type(2n){background:#f6f6f6}.product-variants>.product-variants-item{margin:1.25rem 0}.product-variants>.product-variants-item select{background-color:#fff;width:auto;padding-left:1.875rem;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2)}.product-variants>.product-variants-item ul li{margin-left:.625rem}.product-variants>.product-variants-item .color{margin-right:0;margin-top:0}.product-flags{pointer-events:none;position:absolute;width:100%;top:0;right:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:2}.product-flags li.product-flag{pointer-events:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;background:#2fb5d2;font-weight:700;padding:.3125rem .4375rem;text-transform:uppercase;color:#fff;margin-top:.625rem;font-size:1rem;box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2)}.product-flags li.product-flag.online-only{position:absolute;top:25rem;left:0;z-index:1;font-size:.8125rem;margin-top:0}.product-flags li.product-flag.online-only:before{content:"\E30A";font-family:Material Icons;vertical-align:middle;margin:.3125rem}.product-flags li.product-flag.discount,.product-flags li.product-flag.discount-amount,.product-flags li.product-flag.discount-percentage{background-color:#f39d72}.product-flags li.product-flag.on-sale{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1;background:#f39d72;width:100%;text-align:center;margin-top:0!important}.product-customization{margin:2.5rem 0}.product-customization .product-customization-item{margin:1.25rem 0}.product-customization .product-message{background:#f1f1f1;border:none;width:100%;height:3.125rem;resize:none;padding:.625rem}.product-customization .product-message:focus{background-color:#fff;outline:.1875rem solid #2fb5d2}.product-customization .file-input{width:100%;opacity:0;right:0;z-index:1;cursor:pointer;height:2.625rem;overflow:hidden;position:absolute}.product-customization .customization-message{margin-top:20px}.product-customization .custom-file{position:relative;background:#f1f1f1;width:100%;height:2.625rem;line-height:2.625rem;text-indent:.625rem;display:block;color:#7a7a7a;margin-top:1.25rem}.product-customization .custom-file button{z-index:0;position:absolute;left:0;top:0}.product-customization small{color:#7a7a7a}.product-pack{margin-top:2.5rem}.product-pack .pack-product-container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around}.product-pack .pack-product-container .pack-product-name{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;font-size:.875rem;color:#7a7a7a}.product-pack .pack-product-container .pack-product-quantity{border-right:2px solid #f1f1f1;padding-right:.625rem}.product-pack .pack-product-container .pack-product-name,.product-pack .pack-product-container .pack-product-price,.product-pack .pack-product-container .pack-product-quantity{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.product-refresh{margin-top:1.25rem}.social-sharing{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-top:1.5rem}.social-sharing ul{margin-bottom:0}.social-sharing li{box-shadow:-2px 2px 4px 0 rgba(0,0,0,.2);height:2.5rem;width:2.5rem;border-radius:50%;display:inline-block;background-color:#fff;background-repeat:no-repeat;background-size:2rem 2rem;background-position:.25rem .25rem;cursor:pointer;margin-right:.5rem}.social-sharing li a{display:block;width:100%;height:100%;white-space:nowrap;text-indent:100%;overflow:hidden}.social-sharing li a:hover{color:transparent}.products-selection{margin-bottom:1.25rem}.products-selection .title{color:#7a7a7a}#blockcart-modal .cart-content .btn{margin-bottom:.625rem}@media (max-width:991px){.product-cover img{width:100%}#product-modal .modal-content .modal-body{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:0}#product-modal .modal-content .modal-body img.product-cover-modal{width:100%}#product-modal .modal-content .modal-body .arrows{display:none}#product-modal .modal-content .modal-body .image-caption{width:100%}#blockcart-modal .modal-dialog{width:calc(100% - 20px)}#blockcart-modal .modal-body{padding:1.875rem}}@media (max-width:767px){#blockcart-modal .divide-right{border-left:none}#blockcart-modal .modal-body{padding:1rem}}.cart-grid{margin-bottom:1rem}.cart-items{margin-bottom:0}.cart-item{padding:1rem 0}.card-block{padding:1.25rem 1.25rem .5rem}.card-block.checkout{padding-bottom:1.75rem;padding-top:0;margin-top:1rem}.card-block.cart-summary-totals{padding:0 1rem 1rem}.card-block.cart-summary-totals .cart-summary-line{padding:.5rem .2rem 0}.card-block.cart-summary-totals .cart-summary-line:last-child{margin-bottom:0}.card-block.cart-summary-totals .cart-summary-line.cart-total{background-color:#f1f1f1;padding:.5rem}.card-block.cart-summary-totals .cart-summary-line.cart-total .label,.card-block.cart-summary-totals .cart-summary-line.cart-total .value{font-weight:700}.card-block.cart-summary-totals .cart-summary-line.cart-total .label{font-size:1rem}.card-block.cart-summary-totals .cart-summary-line.cart-total .value{font-size:1.125rem}.card-block.cart-summary-totals .cart-summary-line span.sub{text-align:right;font-size:.88rem;float:none}.cart-summary-line{clear:both;margin-bottom:.315rem}.cart-summary-line:after{content:"";display:table;clear:both}.cart-summary-line .label{padding-right:0;font-weight:400;white-space:inherit;color:#363a42}.cart-summary-line .value{color:#232323;float:left}.cart-summary-line.cart-summary-subtotals .label,.cart-summary-line.cart-summary-subtotals .value{font-weight:400}.cart-grid-body{margin-bottom:.75rem}.cart-grid-body a.label:hover{color:#2fb5d2}.cart-grid-body .card-block{padding:1rem}.cart-grid-body .card-block h1{margin-bottom:0}.cart-grid-body .cart-overview{padding:1rem}.cart-grid-right .promo-discounts{margin-bottom:0;text-align:center;padding-top:.5rem;padding-bottom:.5rem}.cart-grid-right .promo-discounts .cart-summary-line .label{font-size:1rem;color:#7a7a7a}.cart-grid-right .promo-discounts .cart-summary-line .label .code{color:#f49d6e;cursor:pointer}.cart-grid-right .cart-summary-line.cart-subtotal-products .label,.cart-grid-right .cart-summary-line.cart-subtotal-products .value{font-weight:600}.cart-grid-right .cart-summary-line.cart-subtotal-products .value{font-size:1rem}.block-promo{margin-bottom:1rem}.block-promo .promo-code{padding:1rem}.block-promo .promo-code .alert-danger{position:relative;margin-top:1.25rem;background:#ff4c4c;color:#fff;display:none}.block-promo .promo-code .alert-danger:after{bottom:100%;right:10%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none;border-bottom-color:#ff4c4c;border-width:10px;margin-right:-10px}.block-promo .promo-code form{text-align:center}.block-promo .promo-input{color:#232323;border:1px solid #7a7a7a;height:2.5rem;text-indent:.625rem;width:50%;margin-left:-.24rem}.block-promo .promo-input+button{margin-top:-4px;margin-right:-1px;text-transform:capitalize;border:2px solid #2fb5d2}.block-promo .cart-summary-line .label,.block-promo .promo-name{color:#ff9a52;font-weight:600;margin-bottom:0}.block-promo .cart-summary-line .label a,.block-promo .promo-name a{font-weight:400;color:#232323;display:inline-block}.block-promo .promo-name .cart-summary-line .label{font-weight:400;color:#363a42}.block-promo .promo-name .cart-summary-line span{color:#f49d6e}.block-promo .promo-name .material-icons{font-size:1.2rem;margin-right:.4rem}.block-promo .promo-code-button{display:block;text-align:center;padding:0 0 1rem}.block-promo .promo-code-button.with-discounts{display:none}.block-promo .promo-code-button.cancel-promo{color:#2fb5d2;margin-bottom:0}.block-promo .promo-code-button.cancel-promo[aria-expanded=true]{display:block;padding:0;margin-top:1rem}.block-promo.promo-highlighted{padding:0 1rem;margin-bottom:0;text-align:center}.block-promo p{margin-bottom:0}.product-line-grid-left img{max-width:100%}.product-line-grid-body>.product-line-info>.label{padding:0;line-height:inherit;text-align:right;white-space:inherit}.product-line-grid-body>.product-line-info>.out-of-stock{color:red}.product-line-grid-body>.product-line-info>.available{color:#4cbb6c}.product-line-grid-body>.product-line-info>.unit-price-cart{padding-right:.3125rem;font-size:.875rem;color:#7a7a7a}.product-line-grid-right .cart-line-product-actions,.product-line-grid-right .product-price{color:#232323;line-height:36px}.product-line-grid-right .cart-line-product-actions .remove-from-cart,.product-line-grid-right .product-price .remove-from-cart{color:#232323;display:inline-block;margin-top:.3125rem}@media (max-width:767px){.product-line-grid-body{margin-bottom:1rem}}@media (max-width:575px){.cart-items{padding:1rem 0}.cart-item{border-bottom:1px solid #f1f1f1}.cart-item:last-child{border-bottom:0}.cart-grid-body .cart-overview{padding:0}.cart-grid-body .no-items{padding:1rem;display:inline-block}.product-line-grid-left{padding-left:0!important}}@media (max-width:360px){.product-line-grid-right .price,.product-line-grid-right .qty{width:100%}}#block-reassurance{margin-top:2rem}#block-reassurance img{width:1.563rem;margin-left:.625rem}#block-reassurance li{border-bottom:1px solid rgba(0,0,0,.25)}#block-reassurance li:last-child{border:0}#block-reassurance li .block-reassurance-item{padding:1rem 1.5rem}#product #block-reassurance{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff}#product #block-reassurance span{font-weight:700}.quickview .modal-dialog{width:calc(100% - 30px);max-width:64rem}.quickview .modal-content{background:#f1f1f1;min-height:28.13rem}.quickview .modal-header{border:none;padding:.625rem}.quickview .modal-body{min-height:23.75rem}.quickview .modal-footer{border-top:1px solid hsla(0,0%,48%,.3)}.quickview .layer{display:none}.quickview .product-cover img{width:95%}.quickview .images-container{display:-webkit-box;display:-ms-flexbox;display:flex;z-index:1;min-height:21.88rem}.quickview .images-container .product-images>li.thumb-container>.thumb{width:100%;max-width:4.938rem;margin-bottom:.8125rem;background:#fff}.quickview .mask{width:35%;max-height:22.5rem;overflow:hidden;margin-right:.625rem}.quickview .arrows{position:absolute;top:0;bottom:0;max-height:22.5rem;left:5rem;z-index:0}.quickview .arrows .arrow-up{margin-top:-3.125rem;cursor:pointer;opacity:.2}.quickview .arrows .arrow-down{position:absolute;bottom:-1.875rem;cursor:pointer}.quickview .social-sharing{margin-top:0;margin-right:2.5rem}#stores .page-stores{width:85%;margin:0 auto}#stores .page-stores .store-item{padding-right:.75rem;padding-left:.75rem}#stores .page-stores .store-picture img{max-width:100%}#stores .page-stores .store-item-container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:1.875rem 0}#stores .page-stores .store-item-container ul{margin-bottom:0;font-size:.9375rem}#stores .page-stores .store-item-container .divide-left{border-right:1px solid #f1f1f1}#stores .page-stores .store-item-container .divide-left tr{height:1.563rem}#stores .page-stores .store-item-container .divide-left td{padding-right:.375rem}#stores .page-stores .store-item-container .divide-left th{text-align:left}#stores .page-stores .store-item-container .store-description{font-size:1rem}#stores .page-stores .store-item-footer{margin-top:.5rem;padding-top:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around}#stores .page-stores .store-item-footer.divide-top{border-top:1px solid #f1f1f1}#stores .page-stores .store-item-footer div:first-child{-webkit-box-flex:0;-ms-flex:0 0 65%;flex:0 0 65%}#stores .page-stores .store-item-footer i.material-icons{margin-left:.625rem;color:#7a7a7a;font-size:1rem}#stores .page-stores .store-item-footer li{margin-bottom:.625rem}@media (max-width:767px){#stores .page-stores{width:100%}#stores .page-stores .store-item-container{padding:1rem 0}}@media (max-width:575px){#stores .page-stores .store-item-container{display:block}#stores .page-stores .store-item-container .divide-left{border-right:none}#stores .page-stores .store-item-container .store-description a,#stores .page-stores .store-item-container .store-description address{margin-bottom:.5rem}#stores .page-stores .store-item-footer{display:block}#stores .page-stores .store-item-footer.divide-top{border-top:1px solid #f1f1f1}#stores .page-stores .store-item-footer li{margin-bottom:.625rem}#stores .page-stores .store-item-footer .card-block{padding:.75rem .75rem 0}}.block_newsletter{font-size:.875rem;margin-bottom:.625rem}.block_newsletter form{position:relative}.block_newsletter form input[type=text]{border:none;padding:10px;min-width:255px;color:#7a7a7a;border:1px solid rgba(0,0,0,.25)}.block_newsletter form input[type=text]:focus{outline:3px solid #2fb5d2;color:#232323;background:#fff}.block_newsletter form input[type=text]:focus+button .search{color:#2fb5d2}.block_newsletter form button[type=submit]{position:absolute;background:none;border:none;bottom:.3125rem;left:.125rem;color:#7a7a7a}.block_newsletter form button[type=submit] .search:hover{color:#2fb5d2}.block_newsletter p{padding-top:.625rem}.block_newsletter form .input-wrapper{overflow:hidden}.block_newsletter form input[type=email]{padding:11px;width:100%}.block_newsletter form input[type=email]:focus{border:3px solid #2fb5d2;padding:8px 8px 9px;outline:0}.block_newsletter form input{height:42px;box-shadow:none}.block-contact{color:#7a7a7a}.block-contact .block-contact-title,.linklist .blockcms-title a{color:#232323}.account-list a{color:#7a7a7a}.account-list a:hover{color:#2fb5d2}.block-contact-title,.blockcms-title,.myaccount-title,.myaccount-title a{font-weight:700;font-size:1rem}.block-social{text-align:left}.block-social ul{display:-webkit-box;display:-ms-flexbox;display:flex}@media (max-width:767px){.block-social ul{-ms-flex-flow:wrap;flex-flow:wrap}}.block-social ul li{height:2.5rem;width:2.5rem;background-color:#f1f1f1;background-repeat:no-repeat;display:inline-block;margin:.125rem;cursor:pointer}@media (max-width:767px){.block-social ul li{height:2rem;width:2rem;margin-left:1.3rem;margin-bottom:1.3rem;background-size:contain}}.block-social ul li:hover{background-color:#2fb5d2}.block-social ul li a{display:block;height:100%;white-space:nowrap;text-indent:100%;overflow:hidden}.block-social ul li a:hover{color:transparent}.facebook{background-image:url(../css/3935e107ea61866e60d7946dc6a962f1.svg)}.facebook:before{content:"";background-image:url(../css/8b05d51ede908907d65695558974d86f.svg)}.facebook.icon-gray{background-image:url(../css/082a71677e756fb75817e8f262a07cb4.svg)}.facebook.icon-gray:hover{background-image:url(../css/8b05d51ede908907d65695558974d86f.svg)}.twitter{background-image:url(../css/a67175d1ea11389d9107bd8c08f9d7d7.svg)}.twitter:before{content:"";background-image:url(../css/ffddcb3736980b23405b31142a324b62.svg)}.twitter.icon-gray{background-image:url(../css/e049aeb07a2ae1627933e8e58d3886d2.svg)}.twitter.icon-gray:hover{background-image:url(../css/ffddcb3736980b23405b31142a324b62.svg)}.rss{background-image:url(../css/cf2f3c1d5c7cb02c29f61964313148e1.svg)}.youtube{background-image:url(../css/22c0528acb6d9cd5bf4c8f96381bc05c.svg)}.googleplus{background-image:url(../css/36bff72dcba3098b4b70b482b22c29ab.svg)}.googleplus:before{content:"";background-image:url(../css/c1a65805f759901a39d10eb854c1dcf2.svg)}.googleplus.icon-gray{background-image:url(../css/3a2aeeba930cc29e4d31ebfa1b7cdaa2.svg)}.googleplus.icon-gray:hover{background-image:url(../css/c1a65805f759901a39d10eb854c1dcf2.svg)}#block_myaccount_infos .myaccount-title a{color:#232323}.pinterest{background-image:url(../css/afb2ed6d67613a724a420a39b4fe5b0d.svg)}.pinterest:before{content:"";background-image:url(../css/b1db819132e64a3e01911a1413c33acf.svg)}.pinterest.icon-gray{background-image:url(../css/99db8adec61e4fcf5586e1afa549b432.svg)}.pinterest.icon-gray:hover{background-image:url(../css/b1db819132e64a3e01911a1413c33acf.svg)}.vimeo{background-image:url(../css/f255af0bbbe837e79f7821827f9c6f10.svg)}.instagram{background-image:url(../css/0266b05265f317a7409560b751cd61e8.svg)}.footer-container{margin-top:1.25rem;padding-top:1.25rem;overflow:hidden;box-shadow:-2px 2px 11px 0 rgba(0,0,0,.3)}.footer-container li{margin-bottom:.3125rem}.footer-container li a{color:#7a7a7a;cursor:pointer;font-size:.875rem}.footer-container li a:hover{color:#2fb5d2}.links .collapse{display:inherit}@media (max-width:767px){.block_newsletter{padding-bottom:.625rem;border-bottom:1px solid #f6f6f6}.footer-container{box-shadow:none;margin-top:0}.footer-container .wrapper{padding-right:0!important;padding-left:0!important}.footer-container .links .h3{line-height:1.5;font-size:1rem}.footer-container .links ul{background-color:#f6f6f6;margin-bottom:0}.footer-container .links ul>li{padding:.625rem;border-bottom:1px solid #fff;font-weight:700}.footer-container .links ul>li a{color:#232323}.links .collapse{display:none}.links .collapse.in{display:block}.links .title{padding:.625rem;border-bottom:1px solid #f6f6f6;cursor:pointer}.links .title .collapse-icons .remove,.links .title[aria-expanded=true] .collapse-icons .add{display:none}.links .title[aria-expanded=true] .collapse-icons .remove{display:block}.links .navbar-toggler{display:inline-block;padding:0}}@media (max-width:991px){.block-social{text-align:center}.block-contact{padding-right:1.5rem}}.contact-rich{color:#7a7a7a;margin-bottom:2rem;word-wrap:break-word}.contact-rich h4{text-transform:uppercase;color:#232323;margin-bottom:2rem}.contact-rich .block{height:auto;overflow:hidden}.contact-rich .block .icon{float:right;width:3.5rem}.contact-rich .block .icon i{font-size:2rem}.contact-rich .block .data{color:#232323;font-size:.875rem;width:auto;overflow:hidden}.contact-rich .block .data.email{padding-top:.375rem}.contact-rich .block a[href^="mailto:"]{clear:both;margin-top:1rem}@media (min-width:576px){.contact-rich .block a[href^="mailto:"]{font-size:.815rem}}.contact-form{background:#fff;padding:1rem;color:#7a7a7a;width:100%}.contact-form h3{text-transform:uppercase;color:#232323}#pagenotfound #main .page-header,#products #main .page-header{margin:2rem 0 3rem}#pagenotfound #main .page-content,#products #main .page-content{margin-bottom:10rem}#pagenotfound .page-not-found,#products .page-not-found{box-shadow:-2px 2px 8px 0 rgba(0,0,0,.2);background:#fff;padding:1rem;font-size:.875rem;color:#7a7a7a;max-width:570px;margin:0 auto}#pagenotfound .page-not-found h4,#products .page-not-found h4{font-size:1rem;font-weight:700;margin:.5rem 0 1rem}#pagenotfound .page-not-found .search-widget,#products .page-not-found .search-widget{float:none}#pagenotfound .page-not-found .search-widget input,#products .page-not-found .search-widget input{width:100%}.customization-modal .modal-content{border-radius:0;border:1px solid #f6f6f6}.customization-modal .modal-content .modal-body{padding-top:0}.customization-modal .modal-content .modal-body .product-customization-line{padding-bottom:.9375rem;padding-top:.9375rem;border-bottom:1px solid #f6f6f6}.customization-modal .modal-content .modal-body .product-customization-line .label{font-weight:700;text-align:left}.customization-modal .modal-content .modal-body .product-customization-line:last-child{padding-bottom:0;border-bottom:0}.sitemap-title{text-transform:capitalize}.sitemap{margin-top:.9375rem}.sitemap h2{color:#232323;text-transform:uppercase;font-size:1.1rem;font-weight:600;border-bottom:1px solid #7a7a7a;margin-right:-15px;width:100%;height:35px}.sitemap ul{margin-right:-15px;margin-top:20px}.sitemap ul.nested{margin-right:20px}.sitemap ul li{font-size:.9rem;margin-bottom:1rem}@media (max-width:575px){.sitemap{margin-top:0}}#header{background:#fff;color:#7a7a7a}#header .logo{max-width:100%}#header a{color:#232323}#header a:hover{text-decoration:none;color:#2fb5d2}#header .menu,#header .menu>ul>li{display:inline-block}#header .header-nav{border-bottom:2px solid #f1f1f1;max-height:50px;margin-bottom:30px}#header .header-nav #menu-icon{vertical-align:middle;cursor:pointer;margin:0 1rem}#header .header-nav #menu-icon .material-icons{line-height:50px}#header .header-nav .right-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}#header .header-nav .currency-selector{margin-top:.9375rem;margin-right:.9375rem;white-space:nowrap}#header .header-nav .user-info{margin-right:2.5rem;margin-top:.9375rem;text-align:left;white-space:nowrap}#header .header-nav .user-info .account{margin-right:.625rem}#header .header-nav .language-selector{margin-top:.9375rem;white-space:nowrap}#header .header-nav .cart-preview.active{background:#2fb5d2}#header .header-nav .cart-preview.active a,#header .header-nav .cart-preview.active i{color:#fff}#header .header-nav .cart-preview .shopping-cart{vertical-align:middle;color:#7a7a7a}#header .header-nav .cart-preview .body{display:none}#header .header-nav .blockcart{background:#f1f1f1;height:3rem;padding:.75rem;margin-right:.9375rem;text-align:center;white-space:nowrap}#header .header-nav .blockcart a{color:#7a7a7a}#header .header-nav .blockcart a:hover{color:#2fb5d2}#header .header-nav .blockcart.active a:hover{color:#fff}#header .header-nav .blockcart .header{margin-top:.125rem}#header .header-nav #_desktop_contact_link{display:inline-block}#header .header-nav #_desktop_contact_link #contact-link{margin-top:.9375rem}#header .header-nav .search-widget{margin-top:.2rem}#header .header-nav .material-icons{line-height:inherit}#header .header-nav .material-icons.expand-more{margin-right:-.375rem}#header .header-top{padding-bottom:1.25rem}#header .header-top>.container{position:relative}#header .header-top .menu{padding-right:15px;margin-bottom:.375rem}#header .header-top .position-static{position:static}#header .header-top a[data-depth="0"]{color:#7a7a7a;text-transform:uppercase}#header .header-top .search-widget{float:left}#header .top-menu-link{margin-right:1.25rem}.popover{font-family:inherit}#wrapper{background:#f1f1f1;box-shadow:inset 0 2px 5px 0 rgba(0,0,0,.11);padding-top:1.563rem}#wrapper .banner{margin-bottom:1.5rem;display:block}#wrapper .banner img{box-shadow:-1px 1px 7px 0 rgba(0,0,0,.15)}#wrapper .breadcrumb{background:transparent;padding:0}#wrapper .breadcrumb[data-depth="1"]{display:none}#wrapper .breadcrumb ol{padding-right:0;margin-bottom:0}#wrapper .breadcrumb li{display:inline}#wrapper .breadcrumb li:after{content:"/";color:#7a7a7a;margin:.3125rem}#wrapper .breadcrumb li:last-child{content:"/";color:#7a7a7a;margin:0}#wrapper .breadcrumb li:last-child:after{content:""}#wrapper .breadcrumb li a{color:#232323}#main .page-content,#main .page-header{margin-bottom:1.563rem}#main .page-content h6{margin-bottom:1.125rem}#main .page-content #notifications{margin-right:-15px;margin-left:-15px}#main .page-footer{margin-bottom:1.563rem}#notifications ul{margin-bottom:0}#footer{padding-top:2.5rem}@media (max-width:1199px){#header .header-nav{max-height:inherit}#header .header-nav .search-widget{float:none;width:15.63rem}}@media (max-width:991px){.container{max-width:100%}#header .logo{width:auto}#header .header-top .search-widget{min-width:inherit}#products .product-miniature,.featured-products .product-miniature{margin:0 auto}.sub-menu{right:0;min-width:100%}#blockcart-modal .product-image{width:100%;display:block;max-width:15.63rem;margin:0 auto .9375rem}#blockcart-modal .cart-content{padding-right:0}#blockcart-modal .product-name,#product-availability{margin-top:.625rem}#search_filters .facet .facet-label{text-align:right}.block-category .category-cover{position:relative;text-align:center}.block-category{padding-bottom:0}}@media (max-width:767px){#wrapper{box-shadow:none}#checkout-cart-summary{float:none;width:100%;margin-top:1rem}#header{background:#f1f1f1}#header .header-nav{background:#fff;margin-bottom:.625rem;color:#232323}#header .header-nav .top-logo{padding-top:11px}#header .header-nav .top-logo a img{max-height:50px;max-width:100%}#header .header-nav .right-nav{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#header .header-nav .user-info{text-align:right;margin-right:0}#header .header-nav .user-info .logged{color:#2fb5d2}#header .header-nav .blockcart{margin-right:0;background:inherit}#header .header-nav .blockcart.active{margin-right:.5rem}#header .header-nav .blockcart.inactive .cart-products-count{display:none}#header .header-top{background:#f1f1f1;padding-bottom:0}#header .header-top a[data-depth="0"]{color:#232323}#header .header-top .search-widget{width:100%}#header.is-open,#header.is-open .header-top{background-color:#fff}section.checkout-step{width:100%}.default-input{min-width:100%}label{clear:both}#products .product-miniature,.featured-products .product-miniature{margin:0 auto}.block-contact{padding-right:.9375rem;border:none}.dropdown-item,.menu{padding-right:0}#footer{padding-top:.5rem}}@media (max-width:575px){#content-wrapper,#left-column{padding-right:0!important;padding-left:0!important}}input[type=number]{-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0} -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir.ttf') format('truetype'); - font-weight: normal; -} - -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045380/vazir_v18.0.0/Vazir.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522045523/vazir_v18.0.0/Vazir-Bold.ttf') format('truetype'); - font-weight: bold; -} - -@font-face { - font-family: Vazir; - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.eot'); - src: url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.eot?#iefix') format('embedded-opentype'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.woff') format('woff'), - url('https://res.cloudinary.com/ipresta/raw/upload/v1522044764/vazir_v18.0.0/Vazir-Light.ttf') format('truetype'); - font-weight: 300; -} -body.lang-fa{ - font-family: "Vazir",sans-serif; -} -.rtl-flip:not(.rtl-no-flip), .material-icons:not(.rtl-no-flip) { - -moz-transform: scaleX(-1); - -o-transform: scaleX(-1); - -webkit-transform: scaleX(-1); - transform: scaleX(-1); - filter: FlipH; - -ms-filter: "FlipH"; -} -.magnitude:before { - content: "?"; - opacity: 0; -} diff --git a/themes/classic/assets/img/modules/index.php b/themes/classic/assets/img/modules/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-1.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-1.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-2.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-2.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-3.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-3.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-4.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-4.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-5.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-5.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-6.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-6.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/b-blog-7.jpg b/themes/classic/assets/img/modules/leoblog/1/b/b-blog-7.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/b/index.php b/themes/classic/assets/img/modules/leoblog/1/b/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/1/b/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/1/c/[themeforest]_Floral_banner.jpg b/themes/classic/assets/img/modules/leoblog/1/c/[themeforest]_Floral_banner.jpg deleted file mode 100644 index 47c4d677f827331d7141b3ee018a15e73b64ebef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46252 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/c/category-1.jpg b/themes/classic/assets/img/modules/leoblog/1/c/category-1.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 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%0A2Wn}<(%e%7uq4l2 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/c/category-2.jpg b/themes/classic/assets/img/modules/leoblog/1/c/category-2.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 zcmbq(1#}%tuHZE@L(I$+Gcz+YGegXFOffSvGc&UtGc#k%%oMZNdGr3v{N4R?&YrE- ztyW2@Qgz=hwWO|(<&P}@qNJ#VC;$iu008xeK*6BEz@Sj!VBk>ypUX!t00|O^23QsZhzJ0T1O$Qv^wAH%1pojLK!2|Fp9Ki` zbB>>LgZgA+e{w)R+5g7>iwzF(u?m0%0RjLcf*^k0C%1X8Y+%$_%M?OOY+Ib4tXV~+ z)wNWc*vNBP(+SVzv_(v-iUSIJ$CDBY1Q`Ot!%%3QIy@65%&Da0GBOg{8l)uWs(MlZ z76IqC^k6rD2mm4^A|%j!3IG5O8Zk^LDG|o(%OAx*3=KsvZOkqcbD|{;1&)F#&E=T{ z6l83W#t)m0XR^36LeR=889BAMHtM5m?wH@{nIJ*6B2G3(xQtBs{b8RPcLdrrZCKg0 zppcQ|c4oa%J8tE8a?4s1T>{vT-N=0ZD=J5)dE^0aD`>N8;hi&|=I+;?-G&!(Xk^x2acN&3STD5++BvhblTp zzK2RY$lRxdyncA@)_3x^C1QEelOsH++z0V9eUk)t?(Y3~QF!(c`N0_iN85*p-`W2n zcyN4&bw8UDh}d^LI5Oh0#{yyR=EHq?up4mEbbElY@Nkoa0?L&@1|ZKx3K!aNfGe*) z94f{sI$M{~95=OM#-Jh_{1C*Em^}_BV!4T$zZk-oi&QJKX!UNNw3x0eVl=Vp;J$Sf z>SABxb)8JE36yMsq$Gy|HoE(=HHyYij;L-K+cZkC*0K}UXZ?84Wq)Z$=k43)Ai z327`DL^$?w3HI5+35X^bvIY8`bR@Hc(O`dlr&TB?RtOLibTT*;u{K>J_P)i3+Set$ zuZwS_RZpu0Z{P)2wS7nJ9{_e4J~6RLF+=b0=*+3b4}jp*;oe!}@0zQPL4`9Ie8T0$ ztTeGqy=t)nv_rJj^yeCK(#~b~1@K2*&!}vfMfZXFSx3)~`q>KiRf(h2E~j+WYK+D-o_r20aB{g6L z^s~ERo?`qZ$KvTQ7suTk2wvAc$KKu%?mO8U;j6-pkR|^SFIw2AjsgzdM2d~VxFd%q z<)8wShHyw#oDEhr7Bx>E)udS3RwoH*+b02&BOOf664FBJs7{Bt)kEDx@no{61*$id zM&dnyoOoL+b*o z7~!;;twOaK@s&L2X|_-3t^2xsO$#uTaE;9SKj)QFKwP=YHp$x@{UBH3lS8*onWMQc z8ZWP;HX1709t&I&l@~KLnbotU) zlrzw3PSw`Vf8&J^w=bHaW~C>mHnb;M4Vqnz(>7U_P!cmIo8L@jJi(rWh$(Sen`XQF z@~USy1MIJJ81@this$FRWZN|IG-1ePU-2`gVA81gKrS0y;oO~P@PNZ0E777OQU!RE zV_&+dz|1|#IlgvvXEe%;?zd!xE|z$ub7Woc(K>|PLx=8j(b|xgc3LxS;PC#h+2(h# zRZkx|>4}DnhuG2wPXvTx_f9-_-Y~9w`=*6X&(+R_FA57o$ii44llOIbNglEg4SGXu z+2D(t#FwCY%*;)3a-yCoD|rS-H^jeKM7=ucEs6=NkD@uAnfkL_H!a2DxsqKv?IZ3y zz0%=^Alwg~o#N_SbTF)9-PyjoKbsNOW;ivkcqcDJ|EMgZdnk-3Nm_9NC+W`dbIEp#L~OKE${m#?7qYEaC5N-<+<@qJ@>^@ zdz4<|#a1x!lv*Zt`jAnI*sW`PnE`foVe-_Ao0^9K(E^sL=Tliimz{M|v6bn%y*=f( zMKIuS0E&dNtE3_L2O#)ZH#pTX;F&!5Xur1a{wq(W2PgW9)E4eybGF<25Y=ndTy*gm z>*nh1(Cq7jhs4SadgSelxB4BNlTYR)@h{l=ymP!PJI+I1|J(i7i--`5op@PB*46Y- zTWJY#t!cDoo)n40cAFNmh~C<&F+HKj!)0C3y%(!fEKHoN3`#o5G1G)o23l*k#p1c4 z-kVH2?4^MQwci_h*&89Ycpkqz9$yjM#XPc_nR2BMPMuazJBD&c3x8?ihC(Z>VoOzy z6mW(RBm|&0M*X^+I_cQWEIZpCEj7MDysTokog|;;#G@?D&m(hKm2Ex1V~UN`lV*FE zGM=rQU@G3tFRSe2^{8svI^DGzPaAB?n&OAl%9Q4Wl#vQWH`T@rF+mV+=4m^wbUbn+ zsc++Wp*m_V@N_+svh;Edk3ADUl%rhxZlJL?q4377gr^pGD%k1iv{VP$;S95C#&XTq z@SOH?_j=Qw+cf6wry^bD-Rg(A_~1}>U}i;$XkzA0Wz&yhTXfZ{jUE#Ftm&cBFc3+p zGHf}YGOmEUqnN-sW?x9hEoviCteeRs(}+9y`fR6?%~uV!JAa>i+nyd_TIKE>W<4hn zb_WE!E(<1l0brAyOTW>fO|GmJ3V)`BZD|}s9 zjz~p0j&?qj2+KoYb$lmBW=EwD)_a)*fjEwQpwX;zUxmtMr>I2Tq>rL2Uz8Y})4Hi;xC zHXue6SpY2@9q2at=-q;0JO4KzIr!j38Ux(!%&BiE@&(f@bk`$5s&D85;O4Qppb5*~ z4)16D?Kav;D&-JDoK$V-$dB`;r!-`a1}lZJr_}%N6ZLE%WHaZIEaR{6%sD7W#jnC8 zDaW83=3XVCQ|68D-uFKpcz#24na{l*qsgg_-;lPRT6i;reUBHq8fuM%llo>MM`I#a z5#hjp^_SN^HW4XPB;i6atrz7P71)MMx94c=l%EPA&EdeAg1S(|7$$5wPZ1fHS$Rq(0P^GuNd&f}to|nZ75C?fzo#a^*}C&px_nvBJv<-Yea8W3nKn-TYStDd?pS}SYUG0 zaH1(iu=?g%;6duaY%xU>(u7D`iV6H8^7+PKNEtU}!V1c*2r>XsTV@fFYlW# zO^^ocdk>x@rYVo_nLU3TkDpSZ5JSp53!IVsaHM`uK#3`;a87KjAJ`ESX2hV;U%D~R z#*v=>t7&#{x7_Uv0u2gd;1$u43UWu*RrsZ7%Af>mu=a!z)L2NK>3*ICgx(73nWoHBv?)rKDz?Puf_puX4p!MuoB0w z;h$(wg9G%;+`a#wewrL$=Eu)H!_;B~6}WurpRGRwE=CDya=@AIspQA1!Ha0)`@+r! zn(8V+L7XtcJc!d4K8#Z@c)(H^{AOOorb)dF*C^#=3lQsvd)$FQWcTfdC$I+z!QuZ` z!~4Gx*>*#)ue<-|f1cg79`;)EI^&-`iy-S(yA8n_I$EE`-r7;obE#%d98b#u>O1}8 z*M(`SZmSc-l{9zGnK`Fg42wxWt}D|d$!J=#Zc_#qisi6YVyUrKNW!r-Fr71tylhNL z)i(#omsmlnDj;;!;ah8P9rZa6emXDwI86uoce1lSN<>9O+hD(QVu%NZMh&LQSOwBr zDy8ZOEgQ$$4vc2tXCE3fPJ!CT<|lx;Nto6Q1**0YGOQR3iPa-?a7iB@wix zov+4u-R-3P6$Q14u{y>cY~x5itt*KW9o>0ai`T(8M4Y;igMQFSa3UJ+0FQgvjaG|5@QX(^$M2P%F~#P z;$PRFdL;~AHh~{D=pBjCij#yZz{kX~((gs@RT~n;S_W@>$-)n{*=Qs@l*oW zRLDxI-@(Fu7?>O8H0=x(;0;PlA$KInGTGCs^J+q5asRK?Ys!QfSi%fDNOK=q5R?!} ziG|EeVlF-%+b+IAf+7w&3dHy$2@$au#C{svoOJ|rh#(0Wsvr^ylf;Yo7+;)GTu~7Y z3OpckRrH)#P=Jt-LR=CVISxt!G!}FZhEU&RY~_wXpfOs1wv#*jfwln+jf%9O+(22#PI{{Awm%R-~a`hyWgsLbBE9Vf!~|RD3x0hETjM*n1`{{=T>X= z5DQGe?+c1(?JtZaZUF>|1yq1BZuMzpN=#vU&IvxX6OuvpP*|ZXy`qmzn?jMXV1jGk zR4+G?)bo(Q5fU_|^zy+S@L3-0v!F~ckhBEWgcvh|LL!P=Gh@PmA`Vl~Pz>f)SYh=$ zkQ=Wsu0e;{ROE|E)vWbB&=tCUAE{}%WXyx2PXv}H{WM=`-P;X5k^*q<=-q;9<+ko$ z&a(9*!(OAOd#o7(c+oD=^=x*pB`x5OWpEc#xTvY z1O3+KS|iEkt3@z6Ty{a-tuGXUr|oCl*|5b4h7)IvU~HNXn$L;jj!86KH~Sqa z>N!8^F9|6>k7{6wuK#H|h2#UO4-HLxcxhZ!v-Bus)wM4W9TPJ=R7kXH%BhN1T!;f| zJHW3=vYJhPsLj-SYvP40?ZjjHS2$+*(7Y)3SFQX3xq8t0;hx{guz`qLXbwy5| zQS;BMh7j3|3h%`I@|~0JPR+ohX!SVVV2<@?%|ex#gf)tUUE0+`X;~n&6`X7$(J<-K zEOQxYCpB%SL7}6+U54tK932byI7zxTm-CsF6qKQ4&Xl9_U=rdMslU3W-#DhfssKr2 zq^4|Mr=yAmOzJv0{CEoWS(+uOlQ$6#CY8xL7zS2r}$dSz*cS5SMK>Y;66!Y2V)9q`m+jpn%J>o7f0{2SYW9v13d%{Ja z*)|rrY5Xibnz_JT|5Xq2m{FxVMi`=js7@-1P5X3$2W;41mOlhpoFIh2-xOP3u!kMa zKoS|XbAu1X_+At_P(6{WppdXMG}BBg7_W2yRy+}SAz#L5pD@KoSZhfFeo;g@Xj;Nq zy=g?zgwh>i&zPLk3bpJ55H`;O%w)s*wM=;i+$u)TV%8qiyM#O4fD@4gtb7LI2y)Pf zdzhw^>5i`?p^_NF6CUr83AS>em2@EoDK`F+mLNeCy%D9HJ8pJD_$7>g+z&^igTT{3 z{d>J>(x&C~s2DpFbn|%e)NYUvfdmvm%nyI4&j(b09(JG#D;YT-+%Um#*zU*%qpu$m zeQKyot3-u27JcM-=v(2#53A8ud)>Hm(7JGRu=Lu~3RBcp`0`mP-@#jd;dmXZ#2ajA ziJZ#{9Dmunz|N-p#YT$p*+mZo!?)Noe!t*5Ej~1}cBQOBzYl<(Txc>{;YRv&G-_4I z+>S|GA0FWvMam$n6x>ef9%q@lEOp%WJx)NNp#(<~d6IC17zr_wB!g_dLu#FVWYZ3Y zu$!n&Eu7>!|MZ-KOkOk$iD*zkI)h^6JWf0wS-dHpY#yT)@u$yI!d{)n8?dwkt>H%W z`^%1BcA&m+Q1HH(196op1Fnu$7Pi3)_%4-p(`G?M)?Ul`WJ0d@&d#E6Omf^#CrJwN zBplQSU?@F6%H7iQT63mgx577{Agy`bU*dY4n6|jqdw4Cm}7}BCyQ59nP@sMHXmRFq3mV{CL<)-y+O-}3K^cPpSEc|x6COiSabIvhbrpMw6%a6 zP|D8Q<6l=Et2+VWzDREIxdecKxyN3he=k=TY|x7Mb?cf6#nQC)4{)xpz_EuP#uZiT zYHBnqh7^34PLLsMhv=r`++heZUhGB*sdrluv2=-PySPQYB7Km5%3+fkDX#u=1X~ z3)X)wfluy?+VV|&T)%s1dN!*@7?X^h5}IVbniq{GUBcS8l2Qg+X1v8zc^ofjw)KLN zVTa$Pr&U_6jx~o)-J*$M0XEzK_-_xmqxeMK68)y)YJaa`@TVeT z(n0#d*HaTWHH4vlW_kKfYsfPHu8>9S+KQwL+*YNAd8Jjjn#x}xlVa5kD*5D?;8_|! zGME#!gK<=Ib`Y-wv2DN#fwH!UP+ibXU7+EQ6H8;2G2h@f66co(JmB(OgH~Z{x9hLn5NTykndx|c+fW5Fn8e^$S-cWGXje+7-aAherJ~QdR zz~vyp`ucMRp>&y6W*B@+E}GFIB2LlV?3Ayl1@n?*AfvE-Hbv#W$`^>)93M3Je9Z#C zKpe5yp~0=7(bY!E&pBKtxXw6IUQh;>!n3)(I)4daOhoVQFF_$)n)Ef|k(7dLzQ*f< zY#m5yF8i8G9p_H()A#d$30@0DG@Zh+>nR#E-^6qYyR$EB3%IJMs;A)&p3$)r|-oAW{Iv$ox()C~CVStu#r z(oPacDF)|iY zfaN9ql#va{U@ZI@O0h%Yh#ILRW18ntVS7@>Kc}z%`CgPCH-+tu5c>d>3RZ8^k165B z20*pg(|4pJDo<5*!M!1H*M$rETyvaFnHur5^*kr|*a$J4ruF56ytfCxBl#rtLfYip zSPyMfhP*Vg;8Ki@2wmOdBS(X4L0#GBL0tvL;pXeR#QLs^0=dce0AJO{fo+GA!1RfV zyKKa+C5hQ;; z^G@%Gwp7=Z6T$InKeZd>gX8$PqjTm+&83<^yG~AOKw)NBT*Ex4Sz}U)ouauCQzpfX zQo<^8d8hblnLclfTu*OuM=(B{dyi=>%;QVJd{~yj1ZqHjml_PK@3Tbz0qFhuW$#cO zz8Y7bv)?)76lh_$0zxgS23MaxqlycD-cv{z8!q6ySC25f+Y);oZU-1PsUnU!79pP$ zOA*e3Hp=_UP@-*)<#3*~rK8jUtm@=xSUm~@sb{HKq}4b_WcmCWdlhi{N!rW;S}qe- zCf>K&4}dN3xAd%1pPl-CtHK&t@~x2$6^sF|9n%P#cWE~9KwJm$;f15`5G8`B@t9}! z2Kb>Ixw>0@vi|U}aL@Y?y&UiJzrZY!G5#E+o+uoh5FZ!y|E;; z?9^noR`7ZK`f~GByhOy#vh749s^t($-{=1s~Pv!*R(!tht8A4 zC^Ckk__mW31I~$z)MIErwT`;Wz7Y*(7F)ZL8y;?lW^SmUwbpdySja4D)@v`)WzC<` zaNwpw`D@`CvN+ohSb`bqP_;GUNUrwAnjs|^JcmX#D(=T}D$Pqef;P3H=){!V=!D!C zq~4gum|>1o+J-rdxD}bcz|OqNj{BCxpnnf8nKe>~Qh;B2P2o<=B@@X(N1hL`FLgyM*RzCtmCLmj5?g${PQ%G8edJdH9%hQgO>9`Sc&}D8U zT%c`*Pq%Jq21kB^)p=1JZIO}2Nev8~qaR76u@1wMX;p}uW#xD@Jo2>R>31axXk+V# zhjBsZ?~UY~A4LwOIJsqyMeFQB>ZjH>5&fA_1h3_7>BjOm|>I(>=0!Dhcw}+0lWgF1(s-R!Dkgy z5cUDMN9SnrgBu*bZ(xgrj4U!Pe6(TqGbYsEBP0&v7n-1HY+(632zISFms2$EC3L#~qd08!zU==}!O zV8HnhQL~N=)AubyPD+rVf>^hX8%jQ>8opFo>gpgB*c+ufidI9~^=gn(7rEJPaHJn* z2sOZM1GSgivYcTvOd!Hjw!9z15h(csK>6p+|8@KStHJ~$5r%iu<3G(T@7ry3^K_|3 zh+5dbUajCo=pEF4#;9q5mb`ik@6vm!XZ|Ap@U3;j3he?VRS9w9S=#yr0%wJ{P=L<>I8 zirQo&=AhTU9AeG=XF}Q(Ob_QM$@$k7gB^NBl34pV2y6oT8wh*?M<|dKah#s(@d9`g z0!I#z)M1=i@dF3pV(lbzebN{ixaEz={{+))MlSyV{0LdpQDt_TZ=>_cR~5xtM~P7( z>PIHVfIxsiAwVI)Kli!(DWAJtK#)L@2^IdNnh6*b!331-KU2+2v9&W-#LR+12EP2c zJ^Fv;n?G~Yd_XF*4E!??z$M}BEkSV^K11N410b8-340tCknq5v)o9FfuK@oNiq?{R z#tw#(2in4h&dq33@i{@kjXG1rvnM7P{doGOF9%IfOpp(r!5y?~WCpe?OfW7ZDOyd^ zy`Mtp=kfH-)~SK*#^e7Rvq2-%tngABNfqCF-o(C8jzpZSQ03o?GF4#5S*Fj?8~SaX zvrqn=!uUuUK4ytd;j`Dby|9|5xJCv2N)*;9yqbU^h#GF!Q;cCM}8y>pqsch{e&r(ENX)eJrcB>$JOt@>S`iS*-nY(vk~ev*=~KF^vj$fo0JJ z1cMR$Gs?^WKTFFzLM54Pt&&kN)!Iy{YzXTY={eaipzt9)W88kFDk@YZiz(DiRXORJ z-^EeUtQFU1Tsd6I;jU8~~%D(X zBiSV~Guj*la7kYoQ-|SiggO*hb-@Wjm5!mxr|(XMi>B0oBwrGkb8_z_3kpaH^6gV0 zFIuJ5s?&{^WIj}R&4JoWTQw})Ygc|}zj@B5$z3oG@RUF2GS+KV9#c+gCw=1B`~YOo zV&p~z?Nm&*^z1bc#8-H#KGiu#hy7xet-aRT8Cm3|_E_N@8nCmXeCxT^>>&Up%gy;- zr=pyZ5FCApzOHY(dQZ+crC0cq#VuVrP;EP+P6|ij_BBGqssK9l(}#RGLH~*LcBcZ zJ=}S|mrh#jEi8Wk;_=LWbOz{8WrfpMvJ>sv&xqT zAW$SMO06(4#f%FbTe8E1K zdXm8dKefNcu+TD7fY5qkiOd_LQ50>k`UIA=3DbIwibX5b>Pzn8$7pCq<(V-po2|Ss zioYRMdU^u3Na&IQ#Uwp!rPU-!{eh-#jHYhIdVWH>NhJAq7u4hA7z@17V18LOg{S46 zv(L-|pP2F+uF{?J*O~clF~v7rsXJ%6e^7CF$r*TGszydutedoGf2)t6;Dijz@o-t9 zV>_8=S8XEnO}-f3dP|BBC3zrl;z$Vh2leL>aTLGEy^9+ekaSi1-^;oXsi!sZ3GOg3 zWITF`+2?j1ZvtvgCrJlJSin zHS|Z{VQDZpD2&|l{kGk_;ps3CTnwu#win-GFG7N3E;uk!;&kDQk@$!P)1QbbyW=zN z%@G#9pqTfFN^hjr&Pz!D}t59YtL>R%9HxMGRbN(&U57SdZbuwswpWoyXyOVfaYZ zYs(Y_dPm3BKGS!^j7gd(o%j2I?R$@iDa_Ru#?Farb4Lkrz$)YkiNJX^;?%r`%v;j^ zvWlBL)43dx$ml-W_YtGwjgt1lNqOdAxO2!q+83J{3!?(#FF`{&=8Yq=K(8~c7R^`d zDJPS#iK9)66wOz#qsT> zB9dg2n8fC;#lrZKwouQ(?j5E4rDrTUKM_HU3NI2#4^&ZaTlLp&_vZ>xLj2=kfPlh* zLqmOT4F>y{gMq@pC;)~?#Kg>^U|=5`7e9kaK18y9USMc|zZg4)}M_#*NE*)MI%?25lYy2L$pL65YnR31?Xw_G{SIM5M z`By3&AAo3iPh7d|tn5MRE6j(X_dbRx#h<;;Ad&~yiXf(5#9l*u6y^w)r4ct~9Fyaq z!2_H|W{#Sx^IzKXPX(Dw9C5TfRfW=*_j}%UJJcY4M_p^ra;x0^FCqV|Ka!sU|D%fkruBas z=8rDbT-=PIcmvvGirtXo$1Oaou8_A}_KjJVZ}XDyPePiG7Ofl$&a;VpFxgX6*TB8s zxWiOodx>}p_9ku2^(CObT4W*wDN$CH6#W5}&|ZOCwbtz`)DpPuT{10H{i$s7xyt zq$51jAlb;#-07&$h4fU+`&KmRA5=eeo|K05#nTHm$qBq`caLy3&$z9t`O^M{bGKIXVRU7}Cw3U5&c#UXZoPz6 zb`sp{d@NG`i~|BUp+4DR-Jx`ant@Mre~?x8d@RDcb1nJL1n3y*e%oprnOv;5432HI z+D9h0JM3bAb@?B~N?0X7<&5f7|BOPDxfTPz!o`Z&41X>AL+gyrsNoc)S<2C>Cd`3V z4oz&02CU;ee&E|0f~g$pc-625)}pBuu`}mi*G{gfV^`l=6OjwdW+W~D4n%%;@iMX6 zG=d#YV*J%ndqxosHBNkK(lc&S0}XC=_j^Hl3l7S~@+C{{uXeXhyl_gTAdtPgqM8*f zjNit)Y1gg9zu93qVA@HoE0U6)OsZgX1)9vbeNj0>a9%r3h?XZxTO~9{j7b;Z#z!Oe zc7WbhEJBksDxxqhtP;bbY`wI~PBhGz$WAXTq7rCx$31UdA(ViX3L3?=aaJ#)N6FRX zSKT9Yz33tLEsb2riW%0v8MHm?D@E*qJ2+&vRK-zTeUq~)^CFIvlU)Fi;|R&1Of0c- zwdgv#+%#v$cV@j;N!rwtmMa?J7qFgx0Qf%uZK`}f@t*dLX@=Q#W9PACw0XyVv3z@B z^IYgV+qhNUTBQ-zWcww)v57jsHo_`60J^1ZUF9Jw({?B3ELNjGt07e-@)gm4MnrM-DY$MD-1{YlGsh${>6%_8#1O`ETDTWQP=Yq4;f?SA!# zp>uxGV}OAW$u>s%YR+@Ix}X%*~( zgtbD4W8grIiyC_0d`lBvA#J-6NInD1R8S+R)jN#&Gn-eIiCBN?DLxboqSn`6)_$k?`AqNP z>>81CA?1EsRjy?MYQ{mLTro8j{T|#;Z(?3qwp97s)CWw94j$lxL!vE_kB@ZJ!SBU4 z+G+@IVtXxB_|MTJ_S!lhfW04YU(n>9KLBynN5l1VKCcO`)(i_zonQAtSTU~pyk3)m z%-o;IYSfKNnSb$-3K`Zf@xFV00jd9e*u%-Dp5O879>EViZag)P(RRVOUyjl9=bUa~ zoVA@(H$9v4dV8oaTtph4ljcJbyBRzxp>cpBrr22@+(p4b8(ZzfEW8cfU9Kp{ z0-Ff9<8Wwh&ZI>uvkpnSFi_!ioja6+KXxjUrW4T&XyL>pqZvX#-5V3{mHO*3?{kyn zU@*(MG1^m0_6WALU04i9M7wrRWWV!*7>Tj5DRcL&Y+)Oz8J!)WQXksb4V#1B4>dA_ z$o1!k6B%IBgedQD;x8FqVbSis>v0W@QufE#xX7sx1^6n#HOHYSTugl>Fz2 zp+e!I@G2`D$cIE5CkMSI84`y{jPtp*c+6Jcg_+@WsPHjbvN4DGMJWmXZqUwC zOb4n#tP9j10A+VF2{s!Jo-arhrZRD}+c7^d_rDG{jB}ir7dDBQ-=r%)P#Pr8%zu%j z9E+kYR;*oV5;%Bm6*mE0nE834)A_cR6OLg1^cYy110^aQP;e<;8 zWVkSC79<56j+l3CGSX)|!jb*_q^hi9ueVTJeue7iTVy&7pgJkvbvs5Hk!sS!!mfx-HY;U`B&9CM~%Ra6ZV?uy7g zLI#XZ@gcXZ7{9Vb`*f8Y3^|0-nhH;b^bB@-u6F~uqDjH%^f9pc*uYz zkBSB7q<0zxZLAtK9z6bND)GQ@NF{s&g$N3PIT5%a9KHQod|cSXiA~E%UY08`V>I26 zMYTbn`o4^ZBfFY;c0g5aGlEptg26LkBZ1dgH`%ew2ul^qU{zk3tvJKut{M#_g?!yX z+o5Pe8C$8YF{8mJvrtXZ%XaTwV%4Ye>o1C7OevxCZzI~2(-9SZr&(7|uA0h2@X|`f z4F1Hs?PQ!{N{J2x-DH?*I85`|7I|*gY*??k%0WUzAN3u9|eR>pF%A zTofyQ4h&!TS1Q~EZNQ_4_*~dAa-_|Kk}Jjy)kZs^Bl*U*aOwe#H`@~6m@BkABiAW% zCwYaCDJzuI7(IdiRowA^zL@K|9~n|eT=P+ZbLc=mPWo?tg)AK?Q~D_HGV%dVtaa4ARdl($oy*kKS#vsl~E#USv) z`NDTd1u?o`RU5Axr)DBm>I4heS6|($Y7={)v5~Xr5Dlsn5p!|vP;+f9!Wo&gzGaII z3~jEog{SHCrvloOp>2@JMsifVW8%5&173yqVcCF&yzs{pscaJk)sfeFpnLQ)dj_7- z3f4AD?h%3XiPfz1pBoU|#deOiv^mwcn;q2TT$EK^C(*@;!pS*>fj!~CI*LegslAr$ z3AJZmD#k1LJ-WnE+u-jS^GF*OM?GP{6eR{XqLxnM5CN{T7U8K%8_q+os!`;Uk(x#? z=fA#?s5B^m-NB3q23``kuM2&va9*&u#=6PzqL6s=^$& zUH@Fx4Wh>y7KWGXRVa7biXeJ1IuM1ShExhr-*WE-KCUK3r{U2xmVO!x9S5YLLNzoN z?7D=`=^8EnO0!>$etEwZnx+r)m;Rn86Nj~wse7X?`o(q*Om61EbH0k|Fs>&BW?mMq zR`92c`wVywxb?O!5-a|`shuzU2(PXApoznHh#6E<0BvRKtN zQDD9n+AyrZy!ok8*;DRF1HU*#Z`Hkn!$aMuJ0i1vylD$HoO@O4gR>uAWm?QJj2F@z z$@e?yB=$pi9J^0iDpl-TsqjkV;&!Tui(m4xD0wWK2e20nA8u;=GL9>5eh&VaKE}}G zZ8YSV`VvXnZ-{#o{T8MYB@H` zoho0ANJX?l3`cZQ5w@OE&`iUc&s$T@Y;HEOK=3^s$ByEcN%$<}^j=n9TrOg@+cZ-~3mXC5I4W;68xzOFycF7gG zs?~E^ERRS>q6ed|lhihOsg+j>YRT(ZhE|@dov8*7bheqzHK_K3@47!k__R=y%o<3f zQkR$J6p5MDcaHllvE+R@z&1ob{G_C*`XQQSBGd?zik`ZmcLfHGF$wgZ?#STtU(~Az~6{ z8r*+qI9Cm3Q@59CxxCf;f)k9~_W>w!Pgp#a4qC7vyB)jtmgKTVNz!y!(g8eWb5&}5 zo!_*e>kNdGL|HtFiU2Mx66Hv)MO&QIA9h4ojhBVNvcxII)%N)Z#po~J<`g6 zbDaUy>6B$j;28m(=>Q6sKNFpbQhTaqOq9*US@T31mz45G(yZYeZCjOTK5D+s1X5}G zrB)F=ZkFb0sA_@2BhHEvl=pXNa7WCj(R(Z~2dU5F9lh zY)jJ7qS$0ybXKqef$OEXu(06P@||T9S(2!9$v*dl(5qUJ4UeFFjTY8C*+QkQv*}x=>18PtE4YH;+$l8LOf;u4ohC*vs{=jh~m(}aj+v|r5kt`A4NmUqIOH!)}!z~DVRT0t3(e9HXEsT+R2HH!5|JmoZW4s z8WpvQdXej|?E$Y*P9Tl!z3v&GS1UBW{+`3Z;TxS<^@Lyw#yf-UAngV>(ogC91$-a( zb=wx}s4H?n2)38QLC$J**T0!ukLt%Np(jwm!m2>yl3$#gjlA5^>heX0K1=Z!aUYny z;{*V*u79o$8O~;XXsLQRoIGO)%#9m6>D@97^+1n3|6Dcuxcky{{(4(LP@>nbgyYOK zwYOuXYoOI4a!HPIu=P3Vpy5!p`uwFwqf?I!f!*j(wF*ts zO2SOzmX@@jLQm9t?i%N}`y%^Y1?#2FCUDfg`c4P{*2=HbNkzvq+QZu_LtIV%Kza34 z^;ig-bd7$!t>G8(p2+M9lh3h)TvNF#S{`0_ozG5Hmw@XBpw++k22akS-r!a*?qy!2 zW@Mj*k4U?ES+dcD*y%f`U^WHy*YZQdnn!pQzxumRb8SS1F~Sfb1-!{KtTogM@o#D$nwAjfnMc~h$z+OGs>*F0T$z!7qa z`0Yxx*R)L9p3yO;x5Gr3 zT=ecjc>vi5bpB}R)%~e$@Kv9VKKYYD`pLlbsA(D0{afE}vAHs6!uRok1irNypX zQmf^NJsVfUIm@CH%i24X)6Dozgv6r`$aHZ$5dg^)~@d_EcgiEe{v8ydfI&VhNB7_S(E`%dN%DK2J69 zrU&eu7MA9kUuZp*ok5RPa5iUb1K+Id47#ZOwLIXiwXxQg?ZW;|xP0$VM`ec&_Qt1@ z2GSEv&c7JCg}LO4T*;*w9Oxq}Y1f#} zDYlvEUJ-fQmbL9^x1S&3wL+74q3;4_iEXQKZsW1d|eme#&L3x4=r~C$3c(CqVVtj$uM#Us=NvWVZ zOg2*QwE?s^tLPV@%KydNUq{99L~nyQ4#6FQTL>-zf(Cbo5Zr>hy9P**;O@aCXmEFT zcfue6f)4IOwujI6eRt39@1Nf}dv>&|tGnvL)Pw=Zp#4)nB7@>3!QuL|6d zYC`++-IF_i`1F6gaPPWM>dVQZPp8-u(Z)&c5@}-&2=q|Rz%_VX`V(JDwo$5o8jU{i zLb|%%a3YMywRojHXS6n#kT6TSj9FrD`AEZSmoh-WpbEa=-ESEocly)<Pve?9(l(EPRR8UYKuJ7^Nyf%UDeKxMvubZHI=9g1-UG5b z%f(7{Z~fTe)|177ryx*F5qiGX_yIiTK@xFe*|=2Ek~vbfpQk9zyQd*?dB&%jm`)Kh zc3yv5u75Bt8T7|#^n}9)q|);S#XObB4Kj%-df?cVt60*i0DUMHNS z8L<<(rb$En!(6s519#Xb{?C=hFjPD#au^+aUX~W&pvYjf=)crcZVlh8z z{>5Le;~z|n9bTmFB58EMq5Pa{!Q3absqwtw zdUO5heVmj1ha`~HU1jQXE+j}G{clD5(zTut&nWs2#V*&xQu&PBGBm=#zo32gA z6}H#5EnULOZEMp<*wysE$EYxI6^jDiH|23~e!2uF%SnN(;E*EDJM zy|~P**E(9&9GS2bB4=6cdp^5U+&?=F?OAqUKbqYQ+rh$%(iI=V5Qb14vJ<4fkK8$+ z7K#PBsS7On`b=T@&h+?1FFE3VTN2%}Or9UZ%ZHTyd+%G0uL@zzI#jL2@-yWyU_B7D zbbrGhaV*G6^RXtz(8^(?!ar-z*ML}Ihmf-HC`OR>T@ScEX7eWuVEi4XS{Do+XX3Gd zaWSryM&qapRp-kZLQDJT;<{5QdpFYYcP%GQO?OrL$o00j&ZpA>(NgE8nT&i{9~1MK z4bk#6c+<)AvlE|SZZmmKD_XGF?{7U+r@bwtB!lqzGomlvR{19LJ`xK_a=*pKU$KNl6(Ha@Q|Jpx4QrQ-#oH*(KuY;8K6-h^7N!p za8;CMHj+309DDy$a;Db96Xb23I}sXa^Y&^W)sR~#&Al{xmos?tmG$I287t1HZF-x7 zCPP(o!j`zO^1eV_$92Dcpz;b^M?o~|J6%goj=xA~lb#>=@itlfQiWCZ)*xkGJ9XxY z-XjTrtyFv)1vK^T_xTbWVl-fv4-O%2d?g`fUT*g7XEtauOtvHrCQfB--*{BtR>lX@ z%CwG+sjNyz*0Q+XJ0cLX=-^fDgd*}MtYrPoS}Xqh8y%CePRG27h*xTPo{=tvR5U?C zi+?8TQ(n>1@*d|}eA)(@>G~b5Ya~|+rg}5?hh=>dieokmEDs`tkhT{nx;IaIH{)LL zsX1f2j;|ZAZ6otdiOO^$m(47fvMQ}OuQy8W2`TnuecOi0GqC>@H=1bJ+KehbzLJLlX~rG+i&ghYe!KR zO;R~@d^%vz#Kk$5O8Bs~^I=E6d}3lua)`U(xOm4s68l|Gss|5@#t)Z@85L7BQWtBZWGBOFnHE`rV|qTtrrTPi_sXT6qPE zQ#a2Ec)2qx$*(|YJ1>P!;(;NF$7ntB!+^Kj?AKk0)(iUK#Wr*FU7f&V)tK0)$EAQSAMg^`-~n>fWz^w$bXx@pxCT{kv|ay~wP>pqQ1D&# zD1I+brw~lYn%b^it14~sh6m->?hll_4w`a3Dxs#u$VZzP+u`dJBxC+}k#2816(fmv z!GyQKoN2~S81-0}tb=-MG|ACFttc55lx$-NC-;XETQ3#axpV4{^x6>9moad+VjBAY z0b`p$_=4EBJc2Bl`;6vk(tsIR0>lu%mo1-dmW=EAY|LhV=fzjHh4kF7kC}F;^gl_f z=$$G1=B8Xms}wPNrFQ)P{T^Z2Y$PtA&dsRetn;kY7ns^;a2giuZr1;>sn0~Q{QudT zo^4q=5zv^^M{;V#%@X_HM6krT=ekKtSjiXO?{5U>pH%wI$gc0avjVL3ruF7DFBUp@ ze>$=r>dpD2Tx}G!H@zgrd{Qp{C!zO$**^S#B>sP%^1lxIs&pvhgdgorta+?@vN*j( zmUU9ypiV#geov@P6jt4xnIL`Dd60ST99vh`X+kQJR(PR2&iW9Vxys*x6%>g zNUu*|@oZyugLGA|&u0nQ(b~zwBjs#z)^Q(WQSN}wA;Q&(vRmbhW$fK}-OC5{KbU&JSo&cYv4QE8uy6># zWXu0qZ44F$hniCi8<+wS6ra~Kb4FEjzQrN>zi#Ijp(Ym3=&5|O-s0*tKVIg2Ci*df zo}XkilM~;TaZ$Y?6lTEUCds+XC=7RZKA$j&S4)-;meb>X^5@_T{k}%>y_V!z;#8t< zV_PnJEncZ?`YkS-W8aI$UbeP}U^ff<$m#7&G35ed>S|i}X2xU*l-?(a&(Im8lTL6q z1$2@A{7eClx`)6Ko!^PdD8t4yL1r|i-!-_~v*ofomdcVM4?IRk`oZeVmpENd4tBjBEJu>Nd~A+>~-N+7S}GCGyN1T%-Cn3cQUlkFwmp2r51l`nx= zH|RC>dPm3$=XZZ$1@I`WD6L_SRE+suBsZd8oaON?T!jLDa1YtSK*q&VD=SZ9EVa0f z8xDp^yZGWRoW`Qk!pyzaphjOGkH6G=U_Hfe44-5`rO$L=Ww5Yz=QS5XT8cOdU1Igu zgjqo9-U0+(*{T?Qz=y8h7M6je1cb%^qusfMrh;0 zv^PnX&v9^dtwLnH*=I*j)ZH}8QIoSPE}J0j+)zc5lTmuY@B8LwBq2y-Y*?h*-EY6< z?N|IPK`(1c7$dd7rTe-UW9%3acbh+L(F?wwo-x&E3vur z+^VD0vl%|adL9df&1E0it%={kWqr40%r#}7odw+81XpxFdEnrO=9)b_c`-YCdeKus z$?qD{>Zzb`nX-@JRkl1Ns%`wURRS<6C!Jn>L!|T-WLZwJP%i^F5f(=uRJ`S^v;M)%x?>v6@)~qE zS=scjtSl65taT3~;+qJh=ZSj~&&O&DXu@l-)d6F=X@c*}Tb-vW)U`u^3-x2uSFb_g z*yJc=We=7A&bZk8?%^*E6t_q)y*q6BxGcx`T;=X6~Tig>82rXH}hZo(vPVY`5$uRsigXNg; z7GcKVF;JFiW6x^CC{XE#UpHVT{JtmG>30(GHw%bh zhsgbn!@&OCY}7%cGd!F(Y@6l2wjpr5_Vi)M<@cr`$*SpE`R0UDq*{_e2`dpeU3YF83 zEd(UwtmCmVJd(rNU^j*cMOprCa4chPu5I{InYi11+As=4I@#xT0uO!f2!kVGX*~Ac z$1(dg?a-=!IizaKCFxFVwQpI`_6`i6DVO=zd#Grm{U3}~25A{2 z{~*6^ye62K_e61=de6mFxlSE(#&7YDIWHB8HWx-c9BjtT!8>2Mr*+2HwgpIiNPfHd z;=>dUKV_k;?(!>ShmBDagOUA7GJ@*8vzcc*zMt0F zcmW9iV2E?JRG(|~qz|*lg2Po|VW06uzEk$RyUQ15??J)#Vvr#=4ibL#>_fEq?d}aJ zEh#N$&QYw6+4NxiLRPH;CHI19gugjZF`rk+ERIRE#TYwZjPfgl9paOBhx*|vVyzX= z)!U(#PkfD?inu{%DNh_auAe=;>TcFwQ$94sds9YJ^?l2NMHiBgIh)U*=iI`T@B)1) z8rx>r+0^P`WEBo<;WRJK5MyK!ie7Tl~$Lp;z=%9ZB7*EPB}HtYK2jp^Cfm^WhoW7-OmU zrEROIZ2BCw=G*c5&SZ~l&R3$9NnFS1xVFix_OY`#QSWtUvamGD)z6ucW(|vOXV@y` z%m18Et_*T0HW8%dO$*45T5pAdT{27%wy}TN*lux3RgJb@%fNnTm$IE;m0(yeBeo!e z-}&MeQ(2TNI6ERq-Jm%elbD{%n_FoZuStgi=hkEu%vh+kewIR$uqvxSU*Ze zuSA>O#qA+DnulMgS1DfGs0Q2d{z$Mh`#R}Wi$jo8t=XitrcUH8fBb_&@$L{aCK^IZ z`4_E}gp*l)0;Ry&>3YR0OU$}EAas5TOnNpN4P@UHUIB|FUVMG0B^@>xh;X0NBW&E4 zH`;0b!N};A*JEF^ecQ{tt*Em`vHT(Y70c=`CTa4EwPt&Ciz@Q>UQ*uSDTptIco~(I>mS&*E!+zq~yIJ zzGJaI36^n&_H&Z!p$mZ8b47Ko zMfWQ_vofbQiRecu<6vH$s2YL<*Q`Xn^Dm16^2{MBa2pi)<>Sx4xH@xrA@ZMhcwjxY zAs3@$NXzj<{PCBhgnFr;9k-+|!%x4AdT0vJ+UGGBXepMS$0!%4b3~8H2wObode_6xdi!uAjAK|oQ+UrKf_Z@exDM=c}0IdX3P9~oQ)(p2Azm|V9 zsl$~_+AfnSjg~cymnF#f9}G(5NWNQo$?D~)w^H0V>;~gR*zr4!Hyjb;z%TCHY9G+w zx@aE$gLxD0!Uij_?j~0M#U@`{O&}MRZ+7={uX4sMvy|C>&pEG}aLVUUlBV#lQ$Zs) z@03H1D>h90A6b_6A?k(s&1jPR_2weXSi%-qi_src~BK&dnjDv1d;mev;e#E#c#5MXz$~1Qf6oh87%s=5IA29AJ=#L-n3I>esPL-&xX6m zH8V(*ro07Ih;ev=6ddgpiRAXs*LfUJ8!Il|ME_##aQngJK zP@wLZxRK-DU!}j>`NE0-p~sO+nD;qCocnZrxcFM&%6g1#FJne$xeY?Kn4*PlZRL=P zyY5w2z;~TQYUDtCAv9(2tD>aw^J%txlK9sWG|atl$D-2=U}Z8SVN6XFYh*l@IMZql z<5~xvcS?G4Nw%15@s*Kj;%m}6O2(^}Qp%@upMT(+etASPa_U~E(k&~aCcF+IH_kof zQlE(;7;Y2Xennb&h{YdE)|T@|jJ9DsSpmbntgYTNbv18Ui(wvN+hhXdU&T>i6IEXh zZlB2A{4`_KIu28a%piYPmhQHd61hE#1{p){rTyFt%f(|qno#@y%+#j7 zZ~t`DhxQO=yZe!&!oHYaKx%;-1!v#4EDZytEj}X% z6vtvnqT&&o($CvkYaVceGfnF(j`rEECB60O+ZIh#aMY%J@4 z({CAR`mR@T{D(wbjxI4MAH}H?ojX$6_4Q?jc7gqaxa;${1d*=!QsdH+fyvXrSh2az zKbTi4B;c4Gi~t*AQiMI7-Ph7mC)zX>hGh< zPuX=jiXuR@`B^1h?(JY2AFnJfIm;JgRYOwx+OZa^JQE#fySZrF98IyE`WVd^aeBY?M8;JlXqiGeMkck0 z^@}pmuRG4diippOoWJvpxm-X_7b%+`EAktTm~&ZpQ2RxZg4fx8*}#@heqiQs4M|tZ zCuni2vlc^P50;}1*=1*uJYq7@mZw5d7vQ|?v^u?*T?x85kTtAH5G9}2yyc2vW@SZx zPNAyh6fh}JV7w5lM}=`856GJu%KoADTd&*eJ0C@S58Osy+;JGQ1dFCpfX~B!YC~^^45cdc+v9+=hE(QMYr^ZTXyj(Tpe#8shRe zhDC((Z*oP}eoG|f8xgWZ&Qbrsa}Ez%Ez}?OKtOh0xh@}o2h+-yON%|qC}1f#DOS3X zk2vcRp(m3>|HX;;4h6SJKFV|;TD&M5`%w|gIvl%hQVh%zzAzod=AeNy$J2f`Ye@-q z75b^_CtI)F?o!2_@`(;?%s{q%YpKPupK?}ejqLoZl8VHaWa~!>e>)Lsn>$(4D4Kq~ z_FsNDRsDRMm9Rn$ips=|d&b9xBm>VHNSVnDYR2382Y(&!tqN=*o_A4ki&3vDX1;2; zWzg>O_HGjv*FO|fA|ZGc%^aym6n1ilYE9Co2&CXZtJyoh7-s>U6RweP0(b8uA z`Lvj6b(*5-eP|(!CNuIQLgb$=EdHz#4y=^Az~Q}LfBvLC?UYT-eA3~0&#IJMeio~z zTgknI08gZA3(A2L91vgi0q^)x{Yi;3zh)}aS&rI?+iJ|Pnr&>)0^P%)ccbur0(&|V zy-tmTMo%Sri?Td*ve#J~O=;l+RSy zCkiUEw1~+ZB~7Sn)#A{$;-U+RN{4cB>lw3`1$BfdKAcEfC`mmP6NUgdVi&r5R-rU=}**B)(N;&w`IQ!tzS zHJ2uJ!(ua_#)c8?#{I;&nUgWgyxF5WDNS4UMpsJcaa7&@F^?{%sgl!~0>F+ez7PixRh#$wNTd@oCz9!W1)@}Sy zEHG%9#qs#1>{Mzh_Lqkq>xjiA6-}(_%~(g38+J?XNJqD~6Nn|qe!!2yABzFpnfy^A z_>_%#ByR_yUO}K-<(ZQ?g`3*Ywb{F=RYp@Xco1jtOsKeOnmL6(tBurGMV_ zJ+>(}2QAf3R4>l}mI6!^d1V-J<%xn)XB zdQ-13v#QMOC7h(ae=_CN=9TwKcT@A?{an-@E|33xq&dJ68NObma*_SOXR63|taGWNgBk_V!0tMVKH8q&t7{Kf zI}ccp4-NrsAcSK<+{!g!|D2NRJ~rL5`#!~wJ^d+ld^bSkw4M4HZ7-1EQsn!6&Vb+4 zp0G*lg%KChIh^TL* zzkSR2i-=$siAbWpfVN75h;GPRqn0=PwuV>1v9Pq&$m+BnZ|L23+d-}ve-#F?+Q`9Z z&g8GvxWwkBOri);3a_FpIMde54Zc-}y-Joy<0Hm9bvxHN!^29^vSEd z-}rMpgvgw-j}Qrqt`{+lzWlMRt6=W6ZmXUbtJ!=n5UPET~Z7T>F{be)Ac3s(n{@E^D<6{5zU+_7pA?v5B={!C!l^F)P*7 zH+mHjxyb}0LQu?tgst@|W&L-d-C4(jJrUJ$k;$_3IyDpXVv1Ug8UGtXm@scfH%Z%k z6Dg9sG9m?Kw3K(rfWRo@UdQl2NMlPjGsBsr?IL7vz4@q->7lWYDO=Jw_qXX@+F^v35M~s z*9917W9DYW>v36FLyJtvsx&hoDhzq0tIP$)LnsUeMDo3qi20f*!e)MMUv>0QG(LLj zFGw;IEQ$RYN9RXX<#<&9n@~Wzvq{Uwmr$P9sEj{tW-l+NxqWU-p&7yxqQjlRnX(K< zzbMo%R3$^b-?QxTDxLh2qRAOvyi@N@oL;6PO;GRV{<#3Bi-9FEVXH~j;PWyZitXfb zuE~iq3jR^NJn@Fkq?|JyXeW1$ti>~2lI2Ji5>t&pZq8JW9UDHnsTZR5lVBm>shFwn zcGVww74aHE)1@_ww5+mZeNB1De(<31M@gM`I>&p|zl6WAMTdvCLcFM(CwXp^KCT;4 z7cYg2P-w-9p>Lo-jAo<)4Xo2dL_mh6=a68wdB#RZ>x&=(Ol&} zR+ad~KARgCRaZOImJn--H&{f(uT4I+T!)(IN{G~{Y}Poj;$U!%CENROwvUwMPQYeG z@%pFSW#u2day86AD{YI9vr%k#FTiZ2-K*K8cf#}sShYSt_&cFVrh*aEDxzK48#Q39 z^ANb`X~iT&YtFs$t@+aK0<|rkvoL2z9z@NtVp#i`GLpSRIF_hpp_a4sS`y~MN%W*R z+^ATt8utVv6XB9sJH8GCovLJROy*(F58+Y^2%tvVq0s@n@kK=IMv!@?z3`zVEB5C~ z>%xK+OTtgii+Eg2K}Edn>gi2{l&Uv5+BabvBI<)5!K3~ntNx%>N)?DgKv&5ge2;OU zHdS~>>-00xv-#9wwe6j{zIU*!+w* zb%wLvYt(A54cdWs*#BVO!PcuUr(Dp>E0(@*exJ!1xp&|pIOy&sl83vpM=5N`tzW}C zpj%Q_)o$9&^G#Rl@7J*RrA#fMuVTgY`V8aS;Msx&Cn^)lF`ssuzj5)*`U?JdFNP2o z*bTciLAi)Co?w)@&pvUPy4Ray2Ui{e^EZ?0UH>98&G(5E2p_@*$?w^xl>j?nWWi6^ z;iGj|;HwfyJ5}Rlk*|u$WpR^y`zKI6jN{3%%Ug-5Y%F0nq5J8}{r~$W-K`N03hw!D zCYw$l+mHd6^jyo&8L4TXsA2un>y*yz3E!PimB(Y|!?$p08}dJVqWVNWBfWfJOC}^% zQ`lt4KqNsrhec?UGffq`cDO+5zNkBfnHt-CKO=m8I;@5m?Dx!af|tLlvoXAxMH?E} z3%m7=QVI7qY|?0~s`cQPE0#jtrO#1Wrd`7&H+pNwHn&j|-w9>Y2;xj<`_?t(`lC_% z|C=vRJ9F{Lg|r_c%%0e0guZ|w-!G7~C>IHoC@y!1oY z2iM+DO944K4B`A$>u`7SSes#KTg=vq+#1g6pVR^gMUo25nRGdA0#GzlL?&#+lfD@f zTzs=K#7UG5i&AIHvA-AA9igi$*;FPp0y8kD)3*vitH4_e(Y=? zNnsbHh^NeOE$wy(gr|~He8|iz^EM(7G24+X_t=aKr$sbJ60I)T7 zv8PY4M$dyeV_>JcVlhB2Ia(K;N+K zxOKdZ;kO6CtCC+^RGVANlTikySt1As zK7<&V?$mJK;wSf`Pz5nxR72oh5^8}{6XG_LyEmQq0)gSwm%nj>fv(YjZLRW%m>Q^d zT^o}ksKVOi;LSe{CSnV?q`W;Uh=%P*4V!Dw({N_L zmM>QNowqmqRP{fY$I;WW$f{G&Bxv{I^u&x57~$<+(3TAR2V>t>)iq}%bh)&~T63t9 zoI@e9R;s-P{B=yx7W>BiyNieNPWgvXGzW5l-?vd;LUkU$d^}}RW%(+)KfiM29scg_ zZf?)R@gK}yQ10zvg^iRsMb!y>p%;Q?0wcS$`(@ z=4~^i7l(tyb9p$hEpmj|3t;Ht0U7{_zgSsxbI6Y<`z;>CPrPw7Rf4q&BQj~2J zR0K~Kg;SO3DML3Bj3pPl!aN7)d@C#DXi_|RMSq3WGy%1@T&+ zXr??SJPn}wA7T2;$0ZBE|JI1w%q2MWZky8<`3Iv{KJUO2t*|Tc=@^;!qG!q+^muXG z>e>rmoifaSDPwSLDcl>}`41+Km(Ivbt8wbC-}`ckdr4?NmiYD;vyjl`l*pQr^Vr1w zKKiAS(A<=e>jZbAve4WJ#~Cb&Q#XsV0ydtZg)W+qnu^fH1kB6;1Jxk$`5;FhGP)}| zI%gmLj!2jtD=ljM`(v@V8Bwh1&RtcbtBmM+mZ_ZLd^f_|=w zsJ;;{nTLl67d`&y`uHoLSm;`~GC0-Ea^M~x6Yr&yI&)E5s|Jj`{ zhH;i8|Av&=+>vrUpK+&UzZZ>W*JSObp3SaCX*oJ7isRtjw> zrU!DI`KvRIpKw73&y$vg`##E+g?s<=;R$TXL>verz(+4X$!Le*W{37fNs<^J>n0(p zx{p5v2Z)JKWr9T`XDGy2Lr9k~f`Zj)Ee7Pn$@d`-;a_Jk*7kf#)L+FND~04fCKSm8 zYfk4Edlan%;i@f@qB$+==C}Fq?i6u;bAYUzMf9@hQ=+ufKWLX$VFW9y!JU14fBkgz z)Av)f3G$i=d+$+xF=2GERLdBrgl;2xZKDQGobsy;K2jSCnK$Ddo@~L< zuOR5OlMDLE`U_Lmr@LG0xE>g%{vJLt-@0fsy6U2U#;dr1UTrMds)UkcXUuE9w~fS2 zp;%1tE~G(Bw2gWKevsQdB<+{6$7b&-Ayq-&AhL}@AIrU~BES%{Iqwy#;`4vcYzzstWtVz9|>lTpXj6#!QAl58a zRQrvGZAJr zk{hpYgCyS%kyJ;A4l=|k&=-AO;@IN*5Yc1q81jZ`oZ>={c|~i<-F1iU?U;?d#;jq_ zuYTR2l9J@!Y!$ko?|71u99r$ORWU!IuS zIBbDe_T_!cN&d2w(>YNwImJ0yF_F13_AxTy2V^eGje_njk~G+ZaqzPB8U{49&2G45 z^-~6>dbZ(|9E-8v-!_eN<=eaK6O{Meo7$l=;YO*5`{FFDM7va>TZJBlG%Vk}MY?`S z+RnaLo_h+~j@#W8cgc>r}LvMr<+J_KPLuPl@}gjORp%yfg2T4?uVtmYs$ngBK?^EC*%r+}u$Ry4v>a zYsC%urscr4uKjMUx&#ZBkVmMubnoNlmP}$|XoIU*y z#~<)@mmXa{X-x8c4#5+h#IG}>(b3R^9s{fQ-IhPFX<+@<-Tn97cAn^9Z1oP8ESS26 zk@;M|Pge1tWDq;XUozke!u&bs)&8o7GQKI;O(+N;v2-fm?7=>wVS%?TA9z!-dk8zGsmhWOzv3Sn%;N3BJH zl11dMMdXl59*GJVg7d)bqPTxBnJ@GVG~loZu)s1h|3l9(usGD%oB%yjImhSCY;gqD z^qi@lztA&up(Sj&8Wdm^ewc)aNau9znfwUznYN&C1sXI&_WbAM8CK&1w2XcwbTW(U z&5^@f>d%sY>*BGEN*s%0r#nyz6y@yR2mmo)X z<*b-wf6&+?Kb(ec8#QpoRG4iu~JwMyCb+^n~Y7YJIx={7;1^xI~hN zvq?U@TGF?9O9f9xIn^I%^S_R#Am^`oaa!}44jNiY$dwKz*nhgYIb-JP2yI|`0GWZq zYSc+%iq~&eSo%}vZQLE7aV&SH*SY+oJ20BpIZ-%<*@j*9A}izfwpQ!g3K#AOu-s}% zB_x*L`Jtj);Gkz1*!GI;`SjA6fVJ&0y2r2keAcl&nPD=@7h-=#4)vRVXQiSUF)p2u)hRm3^t542w5l1j&OIgb6TIHGkD+A4r`fv z0I#<$A4bFm{3yG55%r0Bj`8w;ti6^T6r6&W97#*8g(=?p*8JQ*cy=YW^=sBxe$4a} zQK)(c4Q{Kp=*KvCf-i9uuF=m_Gy$r(M)Oui6%y z%5j<>xvKdY5|MX{kE&F?Hqk%KCZ5jYmG(T)O*7*EX4IA0Pz<( zN7r_P+E|F=ea`iFJT?*9ReK>RZA*B%`A{5DX|mtr2mA7HCUte5=%!K|K}A9bFN zi%+;m3V=Hc8RPjJ{iTU~bbP>FL&wc;FNTUQmstq1daKFy2 zDYu=5VE;W)&GrO6*shL&nnm1hYHv>`hk+I zp8J;CWrYu~&1ZcNa^@Q0yqOCWa3+!*a%el9L#YTOE?+XZ{Q?(~8p&>OOLW=}$lfZm z2mJ!357`c+Ry{tI|DT`L+Ylh9^L%@3$^SN%&~bMyjO5(X;8vs$dQ8p&R8m*dm+htU z|6O2nmpk-?fi6PBHZX)4njLv-$a2(q(c%Hs;1*W?66xKunJ^UQ<0950TvjLT|V+phXWTjCCY6690{r*sK)CqBD*q&@VO^7}K zjy^;^`hx8e7gDu(P=6z6+JRb5+OpMg*j32${Np7S|$pZVq0ygPw3^ z55Uso(hffeNbnEFAIR-`gvz%5uEKohPlqQ+UB)!k!1Gwg-{0Ez2Gj7&7xV}h;tT*{ zEmaUUDaUR7%DE`pb3>6^*I*Hlaq1Q-Y3s9XXbK?eGjL@A`+>H+m&OM}3z_$kp1otB zh7YY?fE5t!5K*vnJZ{ZP^`9@H+aMxiE_FGz`5Cs|I0E8W zkKCa(fEO`^fjm$(ITV{NqnB$8sMdv^2j&(OfEIHc_j>WgTr)hY&B1Gn3u!r%&7N#E zuXmRM`T&cAgq#5Kfogm(pa`~$1ONqYP}-09-uNv=vj+?V#&mmpFK6OpGY0DL{iwaU zklN)E00GP*DW8t4Tw%$-+bzRwP65;yP0jXVA{bY|8F(3y*MOy{2-41_``+wo&+vJG zM(Ul27LKYO3)WsVHrNPM*a@1wJ*C`-f_e!+V=UhP1Qh-E0MN4MZ-E4uwn}z=2HlaE zE&*`s^HXY<>71tkc#Sep01PT&2LKk;5io)(B-Up@2D1pfGOX(P2D}Q~feTo1pEO!E z)N!U^$5Nqgf_(qtmrp>oZOR5OvVvYz=Cj`lfa1k}{i0N4-W=fMttlYu_L#r@XvO!o zZ!iF`w?|(nc3zN!6F{$je2)P8ul;a+0!Tq|1+@<+{&uMQH;eh(Ld_~9CmULV(1v@T z0#G{^FOUS>KkKptY6)3G*)RC)bDlxZbuHfl3R+p(e}Pw^{iTlc$0g{YIgT&lAJe{w zpGpGM(Mqy(1T7S^&{+h)@a#7f5H~qYEL*^Nd8#AX1J-3QO_5N7{Ib{sk0k?yth;`6 zK39N-e=KZIJViVMhAWJ@0bJ9MRzIDt^rI!f!%k<90Gia&$KVs1c>3j71UL$#&lH}5 z0JyorznTc-KV9cl+z#-^ImPW7v~uZH+$?%_gU6_?5M>gbu6WZn3Lr(FjDShrbVw%aaLM}1S3zJPpT!0o>PQs?DIt6qQ_b8VrH1zt8a{LkA+2FHMdVhOXLme4BV z-uDx*e_!V+Jb<@Dv?1>70e_arYzG1MKna67=04+vEYRuzMRg_I9((8h=cfBymA-(6 zL{-+HJQJ`4az)XjBOk3*;$FGltCP)sBeXp-oPIxLvn2 zY63XeUlx4NdpQtaRY&f=OoQ88 z@B;|=kx1ZrzT;8g>d(PEz{Yc!@k2_0`y5`EGyt%>=l7eXQ_ZP^9t(K6=M z=bpViv4{cOwOa)az`n~Vls2|}DPSHlmF;Bf&mMS4z3aXM@NNtUV1TCk?c3*)02a`2 z`!m$9p`l7wHu=R1)-R1r*Co_I_bO8y{{+4`z{oz(F!0=e<}gV*~albNeh|a36IZCHIIjlzz*QR@R-sDS|`Ajzke#JgXG!?T!--UeSz- zR4JJa$28Mm7{TKsbAtJz4P%Dy*h%R>_Mji7mgjBY-SKp3-P?YRXXtJ($Y+M1M{=_- zQ;p$M{zHu6RRKHW5PExKSkxShsArtzt@HVD_tRMMLi!IEoLqbscf5VmJQqQuD)~S z*K1Vb$!c!^VwolXxx5&j7dj?kuPz6$3V8{qHn4!kr|Pk0E&2tcUBRQnF;L5RH8S9U zr(A+i+*Yob0VsMfV77p-X>fAped1{1WiaHSE|8Y~dGA>rYblcVBB%A-;@KxVK4C zyj&L`m|1^`GP|6T@1T(lg=y@__vC6k+>4l^njrdVRk7`N<6na$!V!}sjpHeZl_)JU zlGR@u(#fFo{P^*WArGehjg)cwA%Af;1#xTJh{x4Q0vWwrXN#Fq7|YI4R90OTu7Ar< zc3^rs2q8Hb!%+0k9Xl0ApeRp5NQ0S%(yXxtWZEBO@gjB;Ekz<%zHX-4`6335N&jQhQ`*X zA}^8dW_1Tt_s*UA(1@o6;sZ_m7o;tRgU|q@Ag8@3r0aOpeTj^k9)P%M9q{X`jA(=yr-=zGtrCZrI zd7fZ}{u!Qx5_q(tug>w81Cy##u-$n$bn(22tgiEgBcI`3X%QJ1jmTvTZ}H{2BOr87 ze0I7~tp7Z^B2drqvFi0C<2qYk@avtAZ-nT`+Oodx?5lh$_Mxfp8_et~M~Z3gxnpr~ zb;bCrUvsDE@VUmRCiS!2S28&z=U7x4Nh7UyR5Zr2RdE(8P7=hw!b2EI=Hm6d!z1Wa zzZWEJlFOc=JT1BP+c4~yi%cBM*P$VcwSwLfP zG&ZKURiCr_XNSzfiID}H$rgh{?hyvw1Kr|$@jZ-WVXa%O;k(;7X~SHn_WBVN z{5b5EB7IAnLr|+@9}Dgmww@{~@3;NRM_&?SYz#X!-3fm1W8S_IjYZF!sTJfh_C=sm zC`UKT&$QtcU1~zl51uB0?=_iot9VYm-4acwMlUKD`D7j+#f{t%+sZIZ6 z!bBj(3D<1CLJ`I5F}3^R_1%Sz6n7Otg%0C%Da}k)8=d(!RLV0xFCvu({i|{ys(7EC zYS+a<3?du{el6V(+|SwGi7?nf&Nv9viL{v8n|w5-(&G2`8Xxf!^Cc}xEV%`VarzKw z&9cP$;R?+)%5z~C>D?ZjJw9wD)OnjP_()SzYb0+U&Ztnz;lbjiXv^B7vu63*MLm zV1Z-;&_4?CLA!bDFM;5GBtU`xQRPd7`WO|<4DA@5=7d3WP?k=PJ07D+bk2cjUeBNR zV$&j20~HkykLMo@&icBQ>D77ZG!%_Xr>rm3rFiP^;-w;oXOrntzEn^(;n%~# zlX((XCR*Z&`58!g~h$nDfTw@TRg%c%vf`fX8%BUI5)y;;l5IE8l_@}(r{gJe>4R&JK?)B~#6 zhokW{^&844wQ|8J)^r70MaCDz(M`dB+gdh9(W!MYTt2-M9jP#-n_d2JR3%;jU*Y1F z8j^q)dbh-SlMU^ZHvxWmd$I=YXr7!wQF$Kv)A1-zRX7CJ zU;4DR(v@VWAK>|%Awm?%dx`D5*pYev+yDe7kw64EYQH-11l%W|{jwyNEzmjP2l@&? z-ve534iI>}qX3mc_j)cPmkxQMlQO-)@Wo!%=3`g*~y}C_K|a7u9<+3a{0F(*Fk_u%{{Xo0vZS+xutw z%KfmDca*MzovVA|m(HzRJK_>H5aoliuVouiqxLbK=Po zh|hcE`LXvakIDOLHHV}dE>YAdrIX&H(iO3Hm0{VlJW>KIB6iZRf6c`jYXpeJxc>pv zi*=ft_~su9m{>avPoV8{5`f<8#@!5O19C@%TOL&|+5^Pa8~v=(EM|W(xHzP)#A!v7 ziVNZ`Y;qq-86P&|uHIa|l*b>xm2IHGIz{C`B&T|`q8kjbp9h-bGE~+zf}6D$mZzB$ zyM!2<{mYN`PX;^kqgKT6Drlo(>uC4}Q@(oPkBI;0LD|_zA@pG$4FA{g`7W0UU#EzaemNYO+b<-xZa6yEF)Xt>#C%#iZ`Y^!DpIXod z5#>@WODT@7VPY0}cp2hZYj1E?J}FUXzHvjJ)XiijF)yH_S75(Ge~{dM3?CRQY&+mi zp@{l!20wc%Ul;d|=^?^z-$SX+wMw}RY640!8(^}3zQ z=|IP9G$d0p~16F7X~`8*!dCYKc`5L*0JpV7|5($ zljH6bs*lJwMJHZ&IKMzq?Q{pwqpuq(D|qYF!aqoSOriLqc4O&AXLI5yC?62r9RX3U zM`~p25h+M`c+M$vZ*3*90Y2BEttXx95tA|O1kvUF>H5z1K7qd9mR6-?63ga0$?|yn zB3v5;qrMkaB@wEj5T3Z^tHO&kz$3&nC)}dZfg-yO+ZwfSO=V7A7RYZhq(ZMJkR&V- zEJj0!t2gE{&cR|^ugvw$WG#TuwWO*F0m_>Ms3pKOQ+lQtKkTW+#+Bt`t-k!*m6!#d z%7YktL39T+a?-7O8>G*11G)H?QiWP2)P3vq`Pa7n^R_5#MdGU!Df`Su|Ru16}}XjU8Zk;Z1=Ad*u+>OT{a= zG1blk8B&-NCRHvK${b^jo>vX5GyKGh%od~J&ss1&H!6k^42=74>+8SY!s2U>&qdDe{skMj(7&W-al-PiS$g|_ z4YTjWa(_)mDc?60zjt^p;Y4Hmdf0BjGVkT<*-^3wn=TB@w_5Bk_E-nsI`#OB1Ml~~37jsapUzovp1J93C~0x>sh87^HO$j>Lr1QyJSpHOndz;M(;%=ier zj+$S_#ESQF%*wH4V?TpW_y{>9d_@g?ye;mg;hUvs2Aa#dd6~b5Xq3nd=yZ^D(7EDa z68#k3qN=h@0$4vT@JJp`9zGaK4R+{k8hK`U8_|8|EoPhc39<;EO1lmUG8qfx0kO3$ zVIS(SaPaV8uSKZQmAUG(q*KFOv==%Qn9Xyby{Pvx(J}VrU`n9Z0HK$|oL){7F6&ng zf3VA6<*OcDt0|nW59kMXm|@&S19?LpY>xzn&~JVvSeI8L2UjlERhj(@8JAV*ZO#x9 zF)+k_nwWSf-@6iMCl&o>{K0Yt=A?iEw+7wpOsbQ#;>J>4{IRgRy^Usm^6Q_4da7VY zDH*N#ZJg>0qdw%x)^p$6XOGX#j>#X6n4j#A%|1DK#P%M4Jk57ucx1Mv_iwr4)5IhL zS$JiRh~|3r0V0c$tkIFcOxS+R}Zqw4QoEj-*{;nkMq3;|vpt zl~s>{ZFss=#wl#hp(ZvE6NNb}y${Bw;lUVIP{`$$5f3(Yie>As(v?!;YRf9COT^<0 z(QPP5^CQ%{g+;=ml4xO{1A#|M-?f-o~)DltB+(w}4 zE{+9?LWfwWyY54?INf-^DoW?18gfbbV@x1`aV|j)7lU(h(`dgeS0~^Ud4XJJulyn< zuYyp~0W`5B_;dcp#%`Yl*b}Ixo&$7a?*n8tJVgt+$qC_ROrB=8%$Bt>XqAZjt?Y5i zHK=Ohq!h(u!?qYie1j8VFk1J1@D2`c%Car~CQ8agOIB+| z2&)DEa5;_jgGEVfeGbHX@4r5Na(9-oh~H98kESCR)!WtQ?oC+yW$Z$OqeM(+p93o< z9tggsVoQK8ie&xB(MF44_1KQCl(>tE(Xc1$4gkgI)ydNI)+;#Y!727w8bQ5c@!M() z3Y4SMA0)L!E+Z+<>0~`R=t;nGoI0C+anl44v34(`OELtK&YXIsblKzeICDsF2#={u zJ+xa~u?WHIW^$$513H|=m7ra?W=*GEoQ@?0ekkYkE9h4#Mi3qsgOecPs)b50S%{=U zxKs$N=c4ES>9&>BXXR$du){m=Yl4NVHtIXkzGW)X&^RDkvbOF;8H^x1<`7bC$m9fZ zHMt3p?Zk%=Q@lic)ybw=G{sI8J&bjtg~C!;eS>Lj4Qr!O2s#mEXiGU#?imkO2kA>2 zM7V8YBsqK*Z&b}Yov(;38y5;T`k6(_)`htL^a%XMF{b0z$pH#?)APwC)6M-7_!fPa zJmN1yFb}fF3|5R(`Cg=QG}j`{I58@G=#)^*d|uocQh$f^KR1dZaRS z%F;;ADqJH#rAE)o#4poGVJ@s*Y0&{S(bF)5)&usi6v*_81o~iOKzwNCCm$`^GJQbHx}}TH%ym4-GR3Hus$iPR|^VBNlp-+!Ry96DF@f z(~#GU%A{fP2>7(Ut*y6lRa}K{i-B?H<77A@$Xo<}i`|S^RYS6rZ)|&^ZIOuSpn9h8 z>v6+(LLvw^>VPt%s5^J{oOAx+%+07Bw*(XP?2V;BYvY(&KAarjpf`mh4GMAqS_Q7F#PHSfsF6?&A z?lE0rf7w|m%V2rPTYFvmlFzq~uixkVIT@v*ewo3)dA_T;2;yMvK# z^9MN&W&H=X7i#bkb~4j=FAoLt$CX!eJ884mVGyg;DzN%tA-JQrpqv|@Vg^wCG(PW) z6o^8$O^8@}mWum|pS&;gzM+9_My5vIJ^HL!C5ca8JSC(jo==OKlTUl%&3eTSP^P$% zx8K7)*2d9rtP4~#mUNM+H^W{4xROvxLBS_A39*Fte6BXOVMCFz(EnAW762Alg31X^?EF-g@Lf0GGj9$hfiS)E2XH19IWyQ3L{!vxPb8m1 zEx+R>VwZdPhkDm2Opj#nD77)Ub;~~2tg1@DGq-dw=%Y*=Cq#0FJy`R#?KdW+5wKj` z^`+6>7Xn-)exo|UZnn$~<&|i;WMzZR25UP2VFwpjToB|nXfb@wA?N`yhi1r*-C z6b!3Cm0{f^#WDMqFK_1z0r>!`Bg|*?d6JkuPCjz=c`(vvuK%I%NqEril6^F8=t;lo z-1td8%@U9h+u(;(x}OyI$UoZO+V6~TeLrM_^K4U8alJg&$&abvV;?(}0P|~5vY$!i zierQMPjM2!-Y9N0ZFKbIuE=&m_b1P^Qx1Zl2FAzIBCb)+YwA*a0}`wP?lG zIK*cQA;Nozw!Fgj8@UYqR6vB;pt95l*y7Hd1H<)8Nr zO@Cg&oF8B&q|N51q-53mM${sBL0J)VhV+_x`vA=su25#h~NQKmXOa*X_73!M3;X~ zGXy)FVFM(9bnr$4^*mTkwuMELlE7&$5+5Em$uN4wfu;9cSjxH1VBNdM=3-(9!S zV)pTCY{IU+sz1O8(hVg`HBI|}a*TPTFfMJV7XTI>4oALflee@S9l#mXq6hWp0g z=jkinsKLgBmah))Aqcrfq!iGfCCm(jfP5ZTm92HRB1a#o=z5Q5L#cr0A}`Q*1RIrCUSy4)dOz?#l4>^BxVjPPQvLsyw-V zw(aHdg+0%SQx~|#U?ihlZ+Vq-C@EI^UA~i`N|8srO=D2A!Z5xk)V_`2TaP?$j8o#D zhW1agn`*nKTj`&VhZb97_msM}$f|kSsay+WqQk8ZDKgT4FWn-R3GzL57^h_QI&5d*7TGtso+v|U&b1aK&EN9;*) ziY1KetXW{(au|MR(&o_;FIb&4e^=W=^uy>TUu7cms7z=;Omeh{p$D90Mn=(q6b%bi z%#%v;Dpq$x>`#0kb4qv)`Eu(B=Y2W*9%$ZMG*Z8G{s6xQwd`R z_`^kd{qv`LKjfb%tUt={ayKix+`~|jsOj-d#fbPAThi&`#@UjRHz$F$2{b)em~*o_ z>u0d7M~az@;E+~Bx_?6Uu={v%7~YedL}NEdvX;u@lBQNLcO+#aMqkW8Z58SqE%ZH+ z+>nwtz9ND4dV0gmkQ}zwy`8nC6?J!1H$@nkKz9yOTO2UY=%%0A2Wn}<(%e%7uq4l2 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/c/category-3.jpg b/themes/classic/assets/img/modules/leoblog/1/c/category-3.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 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%0A2Wn}<(%e%7uq4l2 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 diff --git a/themes/classic/assets/img/modules/leoblog/1/c/index.php b/themes/classic/assets/img/modules/leoblog/1/c/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/1/c/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/1/index.php b/themes/classic/assets/img/modules/leoblog/1/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/1/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/index.php b/themes/classic/assets/img/modules/leoblog/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-1.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-1.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-2.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-2.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-3.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-3.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-4.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-4.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-5.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-5.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-6.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-6.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 zcmbrlbyyrvvnaf{1rpp{7uOB$y7=NO5-j-Q!Gi>M77r5K7uSS9f=eLC;)LJ?4H7Ka z$M3!8J?Gr#x##|Izp8oWnVGJxuAZr`?y9MNTzFguP$>C1z6Jo))Hngyfd7KWLja+o zkBzfG00n^l^jHl5cw9&0a`5(c7w6-HdGT7=x>?)t+PJy$`B}O13Gnjs0VHMo+^uY! z?YtSR?d%<4QcS-;^)N9w+Db7QiD>d`x+~Z@II0GC+UW&o>DvT2+lbjR$w)Iu`ic9w zy1UwWTQT^#y1=}|{iK-w#a#U9`k%*qObq`b@phJClKZDs24hVf1_d`yI|dP6ejXcs zkN^Wnm{&lUUrbnxn?aCYfS*r5kdOZ*j{v{8$V+j40fzqorl;0CZC{H+6qWy@t*1LF zrvK=audgq!uMn@Br#+v5n3xzJzaXEWAkPy8kC#8p+scmz=EeMP4vKbOHlB{|-i~fC zhJQF(S-bgoOEEo3`oFs1>i(Z>|BvtLzY%I`{@+PmUH^Fj|6=Rq4YB(#dH;`$z4ZOv z?f4*eUT!{~Hg-?s%>Pt&7gzAKv+{QH)OT}p`S)AYad7i?^Kx)=XHd`+;T2#oa)jBs z`Fj0}UQ<(C4d&%-1+%eJQ7&C7vRwf&!E5&R$P@;wQ|_s@s@Zy);KkDj#WpUeML+ozlVRD3(wleT+4srBPA zfZ$)s3b6h1G<;AVmjMv~bW~JSG*omnG;|C!G&BrM^e4c?!u$uYaImnko(>!wTs%BH zT%2eBg6IDL;eP_k6Fn9t7CsIRJ~0740WrxxCI348C&~Z);_(ZB5F3RXRSOM;5P(XE zf<}n)*bf+ck`EmX1?9g+KjxE!SO8RP6dV))>Ql*oFGEFnD#XOXegQyv>cmrTFrGSs zhK`Acf{KO?AjDuK!W6)g(`6#IBEj|u6O?C8ErO8ZG=81379u(*K{h7KB+m) zDswHUKQDaxWdkK=r_`HtxN^7k&^mb0dQy6=N9}HtX(278jR(%xYU34sga)?E3GW=? zm*`l*5*YB(ve_vN|5=3xIP$)5Xs^ipH^>M%da=iGmSSPiHOAG4V`&L?0ohO{Uf6bAa~=hN4f=-0CpIYZjg-!<0~lSs)MX&W+aYMwE0a zYZFa6-2ji}t}2@S>g)#RR*~%jg+`>ePLZjT%V)U((bq;6WUpou^6W+ga*i2Ce#EkJ z#R?L)>HLBy7s)206`=>WR!PQq8_o0tm+Tak)64^g`BP}f(SE4T_|d(!uFO->klD%q zwZ6cXp0!m5A=`Nu3fq?L zuu&(^*+#}1X{TiiGV|3uEjcsr3-UFxj7zS?>^+WEJNaR^sm1&m`}TYBl==Y$KQ6Dc zXQ!gP%+ZYH@GMKMNW<<{eT1q8NIjvLB))gWG_MsJxh`ta2xAH6;D&7{ddzs$7+!|) z!gC>m&iBkJ+3A%;$PFD@_2cT*sJcSFHSPR6AWi%xNj!V&BS15MV{5!fm$8NzW5!F+ zDHws%xq!V|6s&SNEw&b`#&ma7G5H(2ud363mQO-Nx|rrq3+cRK9O7HmB7AGmTwTf~i^vODs}vnA z2!^H}17%qp1COPpK~;6bqWew5@y5(sU;H!sw%&fw?2`+LwD)kfMB)FMWOE@iB#JZ= zaB1l(fJiNys+5&ddqa{cj_HE~lJH=qi$6B>fN~%&OaGg0Xs(@1wz_M%xg#q+Ybp97 zISWfcsdL$Ha|(6L&eKfc71S?hd2M*yD;-JI5~uT>oZ31n*)m;Jo%>eK&$uS8cvjU? zg^d1ciAG?(AP7^_jMcouuQw2R=S!!K*>Lu}O}nirys;%c*NjR}*WpcIQ_@-GM&S3d zj=~hkJD(LFtkE3qbQ613d-$k30a-KVGY=+b+afUYIX*VaLEx;R$ux`gZimEZVC3*O zAs#gzWh})+K#!*Q98gQ|bwTz38bwmjhmgP|QlN^Cri_}Q!n2oL3Tq@Oawne+C%2;1 z({G=lrqzXKFe>I`ZbbzCk}lJ?wIlS7TD2{grImC@Q!Je%9V=!mt86K9p2E($`1PzQ znl^>VXRZZc8QNRO$l_CNCpbLN5S9Ru#jppLHT{VYOoghyjWe_TNcG}?3`^5-Bg&20 z01ULuaIH0w6IQqKVtE1gMsTWt{>pQl!CTDqJ85dH-pz9PK(?&mM5b=?);J{8vs15< z$>x6}2x;+uxS2K*i3EQPiyDxrHA9gFp+1GrhEKm8(&QxsRo1nGaKT$m#GRU@EF4u(7yuBi2@qdf!OQZZQ=G#~ zl(WzSGIDuvx0N!m;wO$mlSE64aL}qV3#CQyL)$ryhIqbgm)LCcBj*L3IEG~6QYPdj zducA)h60#=$j|mn>k$0OCqXG;d1W=?x9W_NpB6RNP-!CRRq(CyfT5}afL>(CVrDT| znwkM1JUJ$eo7iL@^kQvL6Bi-9-?ib#(v4$t3&(0DjvQ-^|bbgU`y zrP&Rxim*8@RMH7#s>gVM-8ft6F^w^lO{>YA%a^D|t+X-Iw1|R*jm-O2mV#o{e)C_0BO?OW zcE-&a!N50MX|@{_0)fBF3AlG@JVENok90OYyv?({;5oNKiHwWT}t_V0pD*)+J%#ga2Tc6lqH+WQr!C^ymB z*YlplTwA*NIwEvlQ??jr)-oZzh=A-(b~2LnX8f*c{pXe|LDl6A-p=pgJkrBgFgNmV zC7yBX((;y0e+hS_nR|-_UF)mJuDk;Su`jZ=s4at$g85J0gQ9&{}{9^%? zl^1h;R|a~aBXMVRYod3htWEO7b49X(gdQ-DkK)jMSN&0p)KpOYt`Ifn>piS8-WZn@ zF*8gLtrwpMFRUGG6B~nExhu(4SAu|cLYm%fgesTCAep8rH?}ehERM|cjgje^w6ER_ z0f)Xs@pUmxubUJ`In+y`2(uhZ*Ai1%*O#soHw8WuBYy-;$4%EG>Tu@@(;6GAYXew-^3-2g;mg}HGczfh zxAX5dbvy|)H^fdhCwBCgi2mp+t3k(kP!vg10Isse8F-2K`oH6x_+8P?{`eFtTp4A(Y4S*x-IPx_}y^B z4Hgw8cIuMpWNSy?9yq16ifyT&cyG_D1&_I>eeH-Txh=yz^7!-Z#LQ4piHOIh33%Ca}0Ui>eLETM3ie$DDA z86~#Y1$4goufDv`&$=A%Rr~1?5?PbdX|z0)F@|Hc z?zir@D{((mljXX0+Ig~}UJcQb(i`2|_Y0Pym3baLkRQzNx*Sms;>v2{Ep1N-E_(Z! zEEnm^J}XXtJ%32O_ot>Nud4?B2*^SCzS;DQKf1tb&Lq%q#RC^?w7JJ(d_TLGn40D& zyd;^C7syBoR4To6m6WmK3)|$+-xTu4RMWakU?(Kaw5j6o*u!gF{;X!K3fBByI;W+= z3H~+v%ts`1b>yvz(Ys~mEV2oM@jr5vWi;$S8N&i1)6W!b_OVu*3Ip3v_&G(;j24i~ z1Lca+zogZ*#;uKnZ_1F~j+JJN6*xET_0A%;Vspd%+mWylE=K3=JSp#B zv!cO2{iuNNxj3f~rDm!pP-RSlGQ5nayG+eA&9;;T9y0z)SVYNu!dF?V!okU=QS-zlrEuYOAX9Z}Su!^CgJwN`~QaCfS z!MKx{NHhI%I!gBuAQad1&x-PuFH2JLk>#I#S#?3N+H+>R#;u>%B}h{N#prWpihdJO`o7xa^R`ef z*v`G~WpWfb^S5EPH)@TKfIoM^1#ce#JB>@pt+x85V?~OkUh|%BI|E}2OxI5{35TpY z_wZb9o6?`>W;TWF(FcQKW(l|r|AtH2H2&B*M*o@$pLrM?U8#-I1>Rb*pTk_^uLgwsDZ#hU9OWdb`WV6`|dd3pFB= zlonZy_;wd3sf(91B0;2bqZLPw+gO`(kQ@KZ{l>N6 zep;FL@B5nmY^yOsiy5I1&GSJ9eZgh9=m8hh6{@2s3*~K?Cgl$RPfCB;jiGVZi^ej7 z)iGH72vyXTtBYemf=wBs!JmPpnFNu3xP>auK_q*(H6WEdcWL?TB-vJ4F%s`KQeeI8 zbU8nl*B;~9f~AAm1LtSO`dzyey%!CtmAc3ovIY^D;OH@iMXBCv9BfWKC$zzQ$?S6C z^-@w641-jA&TC?9M+rBh0SZ=Pl1VAft+*40b1H)vOt)qYH1?%J%gsy}*b5jXX?5rsr{6k$QzNa#V@ zV8zke#+*hNrf!s4da7jCEt}Gbkdw0=S%ffN==}63(hg&8Z}vx{Nu@#Pl`s)|nEDXq zyMkBYS*C#YBOs$M+IJsbZ+5B(^Y_Q}l-oZIrDnJNY;TQCx>PvY$aM6MU()KB@EzSL ztng%U`&>AoOcxTEWCWBZSFL7 zLb#b@;}!@-a~Wsl$8Xow_)yo|L{AB`zt_`6d!jo$fk7ccv%xCRiVlTb`hXf5c1k`C z$Dp(=Ub5X-*_BZc5iz$ab_pF)!8JIFS=Wzxq zh`yB}?jziwG>dYMJ&O{o7Zc;@CtkWrH#q8A-5`m7phu~Q%CHx#obusqDXG^g(5PuS ztKD(GN$u8hR6yA65}7QI9TSfxJ2(3ECqDv+GdyOY+PztNHoMdB5rGN!3_VtsTt5y; zL*nKh0R%0tJ%EpZttdjni)ZiF=)-t_-f|Q@0?x=nKK8uwGJ1+Q423+Xh0F#1#OM+u zkQSfy9vV~uL&Qr){$zy8>i$WqTh&U58Fq;l}5;&fc8Sj zpPHpdfUb1gBj6qw$ov;&`Jl;P=xJs|)`g1jK7|B5LxuHbDW9fB9aNYqYPh>dYN{*h zfkBlSoKB>TX{kw%+G7|2)M$dx`aPh#eQu{mDVnQ!L&Yo)jcZRDDsxaj7E6V%F$$Eh z{0x!h*?bC_m}P>vla}vku0jeVkr6g3bo~z|#9?X++M(hfx*q{eHD0oZs(Wvz?@`{= zCzN%Xv~a;~39U7f)d6=e#P9zGJ;kVVOc%Y1pObBNtgS9wcX&*L+EOy7(^tPl!~^)s zCO%MUj$YB*ur>;$e;k9c;-UZOCs`;{Vr8KxyuIU-#oqSo$N636`FWr%ly`3P2u`pD z4loO`Q|)DTjZl0yFI%Rn5XP!RjA>T6{)qmMxh15P0V0 z`f4uxQ33aSYj!)n*8lU~Y9Q^WLSE+;@@LR(qU7c>{7&_Ee&v7_>Q{z6yN+Cr`{lQP zvtnwS%^V|e3YP9Ee5s|H41H8Lv#$s)SieILdh}ZS-VgY?N4%NM_?|)9Rw4Ihcdw*% zMXg1Q3^4p%mONJyi!?;I@UN1m+xDV;5@Dv%sN7!$78Kh*Wb`OoTzK;3Fs9T>bOQ~S z0#32+!uQHrni{&>s+5ufY1^{4j+woRx%k7s+p?6lIN$;y=%C$;{Z)QZ`9}#<2b@bd?vqcs~*4U@l zvzoM`W9;(xqE`bEWi)Q$4IP3qn$a{!kU{xO$Y_WUPP(~K9NF)7NBh&=M?k?E^%bKy z;ugYply>8~6(nQ73}1r#pRj#0%aoLZiTyy&?DL#G5>2%(cz=J9|D~DP!g19hp^v-I zJu9O~=cFpp8mweKa$A%!EcJJSUMqabFk9bnN60N*+rKbfv`BL%ERFTV#1Vf15fcAp zT3gRf?~CQTf~6jv6oYk>@}vw1o7FCRP%i{!8C=+4x<$Ue&g%(Ll_AzCwr`px@@Xa` zl4=sEK|T{|9FG3hK<^cNFWe7&6&*-17PllKoJg*Gh`;p(ChqF$_=fg-<+nEiLuRYW z>HDt(Swq90F@;L<7|Lby__I=aFrcR)oZs<}<3_|AMnI-Y5aI8=IYut4LTzvL0h5J+ z;h~)3uLMH{LvcQd=3X&VN%MVJr0p}CIDZ6`efaSR5R@XHR+pNnzwX&e{b8vc|1_Ry zM+onDCuG`)L)Oibrk|`vX7JOgWa?hO=f;%2ROVsOYY51;u)dp`d>bqC!%Uj*iP^{R zZYz&~Tg!*xhnXVjOnt&WG3uT#r62BUYv-LC_Y9Jc8aKLIO|~Yxe-ep40`?{Uo@}mj zJ=v()51LO_MP~gGP?>yz6(F(rLDGxy@C6dQg-b(GaKwPa-`Ok$au_A@2Umc# z4hh%|u79FYSE!DuNw3q?H|S8bCo3qoU^|_4O0_}l0%skDuhEDm`y#Vgs)kGXqfy^f z^9!a;#o&hLo>&^&9?*!2?y=c`%dOWrq`}leg`|uy&LuPp*vGJ1f1LSFC$tgtbyqI8NNwFV~SL3U(4ec!3cP=^q=&iiMY=hN@K7F!qVq zNJpVGM?Ylt1!x(E^N1X0?6Y-v$W)e`i4{Ct1&a9o7`C5l za*6msxP*R`ZrI94yRyGR)DGV@``>> z87lU3I(|9)vOe5HG}Zd- zs}999nNkNp1g7>J{0%gpC6Y~^mD&^l(MGFZIYA_!78s@eI$TVhA(Vag4T1tWWW;RT zZDU$(b#YjS$QM57P6Q>Uv)YVb%forfJ?wqDb34gi!ZpG$8sVXE{jud`H3(@X_$#n! zNMS7??vL=5_>zgAeeuTSa;M0JvN#F7;D+8wCu`HWlS`4J$*V|~i>0Dn^EiZ_i3(cQ zK!#wSG2!OTtcttvMs56GwG)|jO^$e_j;W|?$ps0i<4gR;qeHEC!U8X+QSCfma@~*# zIjXZe*cLJnys0eh+(q3ozG|1Ap4zMgF@MvW8cs+xZ|Mk|5$Mn5Qwo#A57GE?UCPV8J*Ke4(~qz==haYb#|B5STy zDP3SXhUvl@1#7BI01XGbisZHK-{Mf<(!VAq8mn_k8VjYW6Iy}oA(pl^6vGvGT5%ZW zTIzJo$80DTPHnkm|MucwD-^ny{w5?VHsBI^kjvVCovD|!+pss*n58}-Wc884r>tYB zTdt{J4GLjL<_lI=+I2bzO*@#5*I z9~R=fZX3G(584IeYR|V>>P)AC!whj`rR0fnSu9pjKT5vk@#dC$weIyPnK_5IrhIFD z?Q^^>b5y^r=VDBD2YwFmnRY7y7jS>`J2xoed8{sK3&lj-@o%cl73TK%Lwo8`oAq%A zr3qiWl&w5HR|!^ix9wMLRIc;5kk+DCtaK5fWrV)?hFv3eXenM88ji*`=1WOr)k!$<70>z~UbO-+BWO0-4I2D=)V zVA#Rv97|Nlu9T*lDfgT#-;J1^K5Kumd6Sl_{#*NvAla*49ulq zE61z()Vl)Z+j)#+*><)qggr$KwR}2SG6LOxX=8PH?3Z6Jly3)Iz2EDd{VYQmMg76< zWO7S>kTs0Ra7)}GX({vEw)*R|Tz4GP56;_;7azfT6GmwPG799+yUqI|YRXi~O(h3; zMx0Omk5#^InHXyidossb3CXD+qBCkBSbjRaH-=zil?`STPe`)C;S->@GD$mB5|PMJ zt@cQnSS!&Ut*ne>9$~^!yE95083BRm+ajPV%K~~4(}+A#3MvFk7Ne@VTBKIViqzBJ z(35@EW^7O@)&;)Er$}%A_#ei!hNH9JSpJrHcjY*tjPaBe2*pu^1`Y&R^A(75HX(P|o zXhfO<$n1qZt7vAa>oHy9`8wt+&pY0wH};)*-Fl7JN%*t<=~2ry?<}f8W@H(IM0-e(NGLI5ljAL ziKPEX6VdrRo<9kg7>-&(G~(uKGfMY zbD3YJ-GDF9*0{N(Rz4p5*cbj?*K~F?KV=E%jZoXt=1cvq8S8AgiFRLIXa0H6^V(Y( zPpm0(iR@D7dE8*1hDOlqR|9T}jg%-Y&pUi>5Abr`xCfWrxV=NMz=EpHZ>mPHJ;y6) zyeG*Dy?GZ&5^MtvTEsw3E^KYrbpj*DkS1X zh)2ElPZ`Qb=FPKHxCL)&YVT;%a|6Of80J(jNDDaYFOzGxhuZ@RPv-RP|Xu2(qebLLz;ihw- zS`yX_7vy92=FTCo^v$VousspU$+Pq9QT@5W;Vf4?5=76i@D8zG#n_~(2;ZvkWif!n zOy!6r#?CQ0PVNHV)#ipcdwDEmvBtZVTZ$$ERGy{`M_fma3>> zxkmuf1V{S_MCEsbua%+KFhxbQ;z5j0>4{2GAt*>jd{i#3rgi&4Gd(xW+0TC#rnE20 zbNu6;)wenK$T&O+81;4lrV38&ury#T29L<>$h7sQjx(CU#f4fv$lh0Pa>8I%t)7za zxr-0S0+Vl@yK5q7H8jEr`qDqSka;Gyg@)SBd19(&o1&ugICrop{%Il4T zS{U`{f$E%KIBxn#Cob^E<_7lU3?|Mus0q5VTHXdtP?^Mi>5;4s8SBfrp}O{4N7;F< z+`dg_Ub8)X1*`N7p53{pkk&Q4>;<4OJ(pv3|32i+horLME^offEj{l@W$6{+8jJcD z;EM-<%3zt|3;}n+Uz+8W0C+0(2(U744ey9!+lZX)t+EF`D8YQur{b(jTBL++C6eIqWmP&cqEPfX#F|O;azU` zH;3ZmqIl7@y`r{v2$zSUVuCl4tlc8kTH7Q)Q<(=BHaqk5ekFY$tHNFGsN&^z^se!Q zJzu~%Lj-{xw)ByPGB1yYTP^1+MTYYeqkQ^pX%*d9Kh3$2Na6~5oMVCX&UI}KrYdo2_Zcc| z87@=;9CuZ_Un)NJ44tWst0s#fDm>6l*WOJg^E-cg1i0*_?r}AN6y(!)f=i&=T78oj ziw~F|y**D$_&r7aX8~ebVoW$Z!}4`$h{2Mhx(IH_!p=lH?I75-KY5zUAcq+92=V4# z!3Lsw#%rN~i=#ALHK;nmz1)ct#)u+Y9WhN$i6iQ(&BG`L^f7_ad1L63n* zSh!J3zH^P^>uJX+bfw74h!bpHTKr;o62Q4l62~f;uxqVT78rX{>A{g%oHF;~N6emX zLo6N+eJ=-uR@NZdyOP?pfSX?eDB-llOs%TbvL*z)*Oev75H0^drOdXI{F86!XCO;}0ADRb5&0x1O6Vy|tEsG}OR4sha)h!H6lu5P%JYf+%iobU27Ia8)*J5~Ut;?> z;?$c3}01tXcA{Ig(T!xLK(#Z{~jyINf*V?J_aH zv!n6GB@?7f>Pl|T4W_mrKMsjZ~( zv+QefR<-Y2Oq(<#ML78=xoRHU#e1CckYI_KS1@lW$-NRh{n8y|!2D;@-}ZD|V_YFj z!+JKZpM^STnLjN?@Ry6`iC9}B7)w&}irc|_Rxr{G^4No4q4EQ<0deN2d7bs2Gq(jxcqtgnR7K=bL@3kwcC zFnau7{j^z5I)>@@>=-OQca(Y1k9VY95rR=?3B{vo%%0?~P^0(SVUK`*Lkn$M0Gi7KGPELUIVcVWgb<#lSF;zo1pqeT5?3-9L9;H>Z%D zc9ohH2e-b+s8H9tizF(0twz~MG+!i53XS=!pg3r8fP9sZL}6vrh@`T6LH{yLA#nv? zlVy!<@W^AUq_RwhooxqIN8GelHL9OhGg2I-G*v@(IC+i)MP(-Lf6v7B{}?LCS@;~c z5)JYZ@UOV4)|1f-c>2|ce1`)Zh4V8Urn8u(0HJgOF0knB(ZI!+=?~s}t*DOx+Mwa2hWo*4&)3;=Ddx*E6?FSv{@7aNBP&voLvEK7d8^R-aYNlxI||*;&)#j7AZN9vbByl@QrCa9u1ji@ zF|T`^HtL#aS7|bGOfg-VPJEUeXM=LOHkz3AGFh0Jx%k?TVVh3p$GJ8^iWjNVvDVGQ z>)ZNF`Q@rM?>@2Z97ar`G8%gjT9;y=@BK1)iMgq8nHr2*IZT{={bEg7f&18~Ep!1| z&1KP_W}8vH&tR#ZCWjIHBc!_f+ljE~svc)-C)=@1mQ76XQQukZyGE?Fl8{JT*2!YX zBF)f`o_*StZ&#hqV^!SZHdj8PhX*f$u|`ad?{nY&^=@#fk0tFc3+xXh|5@;B8&gSl zdsKaN#dEO?$P<5|=lJyRwmQ}1czfRP@S|aGi{*X8UyLy-&8YY;quyM$Jzf|7l- z58?6qxH&UrisEp40L9>d>=IR6Xqa0p)%)#Hm^RPW2;1sL4O$;K zVu08Hq-gDgnahGxh1QSU!kWD9hA3F=f@I^$&|`^7sMR<@D2$3kYKRtho_4#)ov%zP z$){R8`CrvC!bjM-4}H~9)j2W6S7dR4^3i2#61600&hu)Qc9SRPe8X8}?Gyv+Ile>{ zwh^1mAeZ(X+E6G0?jtf5jXPBPd0>|Z!Lbx5l;OZ)OQ~xb-aFp~0{l{` z{N?JFDD){&enu$G;@Ifp#nAGF;P))jwvE2Dvu}Bo5cf*_Aw>~RmzUfzjy?pyc2f^0 z)FJhFC+R-z``=7^^7;tz;9rjbUQc9Ni2Zf?-7?!ua%Rn!u#k>C^2qPd#BoDq^%y<1 zej8*3)yIp4jX8s^(p(IJZUcL=%F|tB!NEE-_~s{_9rARA&g%-5Qu>#dSx0~{>%e+; zf2bKY2JefaPDb#oY>H;}ukse-@IS)JoD$q0q5-reUdOh6R8p(*{I|@tdmCq3Djjq)X9;~}>oitH zqQ#}RSFAv`OEAulim1(yw#r;pL7G<*a)YN5=KfgBEFt@!ujQ`U)!**-xolq%r^N85 z7cw%i;!FWmQJ4?Wz(Xurnxr(93qB&yBvnZZ{zm}$ah3Pq(2-xG;20^T*YG|RR)Lc; za#XEB@H9j@Dghpcw_m?EKv@Ypb0Ma`GZcTRp0qHh?nocY;N!s%g3K2WeeTufOAtN9 z)1%-^_VB^y&?8!KWA%8Kn!fI5)(-vVwnbBC))~jX2{i1R}}a-OJQw#O^u8~uzyjfCi~c6tA{;hQ;pMmldl%O&xO+Me!~PVH|tN(9eB1c<1U1ifexPb z>~QAigF0J@`_^;4&Cy35hr z+Cz~k0_n1trI;)q{B$rFwSfP%*KcS4pUqjw>VFJ1KFP;__Gh6wdzLV;v~vP9waUX9 zm=62dhb$RYcT#PgUCwA+(sw}(p%F{lL)c*1Q{v6AJ8#ru zfcSm5V4}UYW$x17r@v%e4Y$ln!q<-Kr^)?0p_;&7hGJOX;})RoLx_v_uT4 zS?yN>NAjPr?zm4c`>3CG4`IIcGSp3jGh3^kDuhIYxavwYv{H3U%+HW!{i2asv3Qx} zBENYm?cvZwM4_sncCwEJ-hr;zv;^-2@UqX4jrf=$$?F~gp)wL5gDz^TQE6Qn4I##k zIHo~u`7a$O56o`P>mVmmtTLJ>=Gwqp=+Fs|pU(SlR_mi9g5~*o(DaFImghbUJhQPe5~w6; zjiOylhM|StO>?;&J&EHzV|v9Ry)g<9y|xbu=1W`qus0!Yl%Yo%-FCCAYBFCY=P&n+ z5xcz-P6Hn}1(x-SC9M7gFFw#7jl2lS-&$_GS;;1NQ7`=Rn)vo0#}_nmy-sns1y;(- z{wBPj;D{}+6b|7A(4&~$kWh(D*Vy12ff?e{U-TpK#Tko@5>MHi)?rvFW16%zXvm$9 z$=X9-=2arU1SNEpW^HgW>5Uu4dYG%r%{C8>=I^ zby`w)0@q1l(BM|ja`%8tYb>}^M^3oA7WRid@208TsHIFec#BDtY+r#Yz&Un;0FMTY zFA}C)Gb+NL9X?(gkOL)ISn3nVR2+BQnMSk7lQ-Wdrwxnlb~67_fZM4!m=EPDr5Ben zeI1AKxGv#tn6KvLM(SR*svC6qT>JK&-wD3@An=*&0qxCeTXGBv=X%tlG? zy9m1pb%_@hQ@EzRIaWMf;NYf|5FLQ)w&6U55e4gSQTwvb!fz=~Z^!vJE6eiTan39p zN6#VYNxEr<;&ex&VYtKWeq0}Q#Q$6nPyPzFc;9A{cJ*_4!91Ld*{y#l%SuVZwbJO5 z)CKMF%PvA&;_@tT+SIFsWZa1Nrc9c-8TkInbm7tGodA`GlSPgWRTK%imp~bxZeg(j z$=^q)A*4$Wx~Z)G_Jf?v@w`E~;*~I#lotfZgSzr7mSsJYijgzGa-4geK%_e_xA*N_ zW6IUOxb|JY5ql{UR#m~gd=GX)Agtf@tyIz_HyGATn( zk*-?#eT8LPv|EuVWp@UToyuU-_;wUJjl2@Wi>~JPr*FlQJYlb$DSmy6uNom>1%&J{ zAJ=e}zmZh3b@)1F9eSKK|B_1HJbHjB4}PJV%MUDtlB& zT()4_%_cw-`-P?*#0V@Cimg)l!wE;Vf&3-gXHxgQIQ1{TSm0l9#yaNKsx;V|+q3aCvBKc<#NJVBCVzENg;;e*WyyC+$G^ z2E#3-&uTju~@yaYL(! z=ma+F_NXf!MUoVeTh33WWQG?m#^yciLR5B~rno2v9%i}aG2#BtayLDesN<9lm~#*U zVj2yT4QSx7m=Q21NVSs0`ka$tHI!)=ls<{B@df52n~=3BOSpS)bvcQ_{O`%*e@z_c zJ^&|8fKvqqfTg_>g;fHK75AplinSZF6lt45lbDy|)e1nUd~sIYfl@(1TA)Bg*}SS% z23`9Fv^>1V%VmlRj&mE*d)BE@m>kh3F-&jLM8jyswDE&mIok5H)bq<>SD^j9OsAIl z+|Ie!J9-*;PwM{%=Rg?0iUCmEcMvVGxGmO_fS*hpa(q14MyHC==cO1<130!?@G#rI1p%#d|M)iXI2=u5Uk$J5uTV z4_WlrcB6*mty}FZXYL^Q_hxxalptkaMm9JbOKhbj#SVv2;(Tpt%};Kz{BH};>~nsq zYf}of$cP+}?YWOeV#N#z3;2xA3h;L0I2D zGWblkb20Fp9l`r8+Wrp#3~{_u5MCA^G^B?ls@^5VT#vf2a&B^3vmC9I_Xq+L)aram ztU{WpZKtWIU^IUr7%N~q)_Ns6pV%oeoq%a0A`ts*s1&;T!)R>&BBSAMqwlQuPBpZo z@Y}{be*(x?DQu5@)D@`;x>k}>q@4&L*n&P4EedKxBd@33+z{kU@%ZkykmM5I!@vzY4ofrS51o|B^|ox+l8v^X3uJdj_i4POKo>xbk6Rwt;}%zP?+!NrOdumB|~xs#5fXe5^Zl; zt17B7_+yu+y)Aa}_WGJ@$DN$ZP`a zUIP=1W7)^YZXzvWP(5lN=2`V0?5yp#xDG>9pl*igz+Iq6LPh%8fE7Y10NgeyS{U@T zRkQ+YXIl+P@E$cxkieI6yS>|P3kh;LHd;PCNa+|YE0Ck$kbrb2z#VC-;#q6NR!4<0 zmdNIw>i+;xJk;XkJ`0Z+*yiaOEQl&}k2cyHPyTJcVXn^~vPElS&!RV1!b{>g{{WZs zepSe3Dt>bzBP%SDQskA~BL4vWS_P1g`arJTRKm50tRq^AiqJ~{-X+-EWE2;i_eIy$ zD@~NqAe7w-H%f|bw2P2BUgRSTdw0M&zcI-<3ya|#$tBXoq@h2e(PX5BA>{&7(`t%J zuAjx~x~gy^oMWqG&w0L)`;WkQk$nw`O~)3A zuaOzN9P`Wg!lO8;45rPK>qz{k{3^&xCO%Ier&X~Nh{`(=`yEh!5dQjUESc)FrH5Dy z&{#^6uTazx<5aYDYoAg&SLr|MNz4T1@Og)du~JkLg)HCMS@Hh>l=%MIjn)dTt2(0f z?%oDu%z837lfDy#IOnu_1rEAsQg8Pf<8pXvyvjQpIGnWCOt&HN5MPd#-Eq(!T0%-} zQWdvQ7i;)*Q0ZJNxlztAX>e`ieV=9|$lltBOO^mDP1hX~uqo@a#M8%;hPVRM#KDpF z9BX}v8!SlLd_Ex8SBc4#UWFX`>$PMekJ&aSHrt42*=<7hwy7t>?5|_T=Dw4}ayYn{ zQGxAdCmPTzNK%vHsx0NU5v@d(P=OxJqQcr~SS89?+-{^bo>o$J4z+5QOA{iVfa`~H z`cn)wlO3kV#+ZUCXi+A@!hj-Xq*&g7A|~~z0xDqC&;tUI?~k^CDGG5+pbrV44=4l8 z)B)j8pbZqd0MTop1YCBM1Xk@C7)9ABPg81E#*A`k%g;!3Ho{8Qu7Fi;W$~-bc-9F; zK*?EA)AZUmKVer&t;o7DNH^{GV!MaQRvW`(RK#ZujJMOYTK5NW)cw?sNfO#c``Ztp z4mlZ3%jHrPlzbh=Iz24{bvN^>rC^R_^Tl|V3FB}+Ul$dKO|n7?8A?*4@wv6f#`dZu zYAlZ$a%?w{2!XSg$NH(kngOy6WAQ%Gg$4-L3is;Ml_4&SNcnifU}56~EJrk~Og%Pv2ad`>ds;G%?xB zZ*2?fj&a-u1_B{rVX=#f*xDP4fQ>#RYHOP-9G+XrmA3aJQo9c-6o|o#n$kL*dJ1&% z1Bj95PPm52T6z~2Y>L}gAFpMQ#toznCk8jUl8~A1m254vup3H;B+^By0z)w&qp8Dfue zuR6<5E^Nl4zTyie3^a|qQhh0PLcsb@Pxq zm&CJ;Y^t$hQF{LM===u?W~T;oMKEeGDXD1DfISV+2IxfqEQHbkqi9l zn6gTwNm+4v>TFLz@D>%)NhO7$sVr5yz za>V6wAyMLOKbZwXbA#f9?f(EUsZngA%i#^#)ZL=~n_aoUrK$YI_42%mEWefs_MxR- zL9k8#0O~3~8n!Sw_VU}?LjM55@vJ5n9+)_&O=IG;0#ej;1PukXw^M3;4315Vd1fO6 zmBh%zWms-p9E)mU_|E`Ch)~p9&Y`qSTTdqd{Z#!oPwoEzCRebPOyij{rQ>EOUg_#s zboBQSKl2Yz{J}KIVV!DiR!38tc}E>`6oR(F_EvO0N66K&mP|Z~Iv$${;BziUbRlQZ zPKWqS5{VSs(!#@o4Qc~tUCH!oH3kq!{sVg_K6>r>ptIcxzI#SBm>2SG9 ze-`2$v+d74pE(mIg*MBUD^sMM!|XrXS5@1bmyq0^Y$C9Wb06D`EK-+VLRRSf>H_uD zqlp@k#J`y-3uJOQ*iGzBt~vovZ!$1BmRy0%mTF9e5P`KOx%P7x2P z_?mjFl$kM$W971jm;rvGE45TwMyR4XT9&YOi&f}iDqCP*an_g!nak_oC;}d6z32iW zXzO|aiU3Q7K^1=YymB zdGxp2?l{6`PGvJ+Xay8OnSt?_CgH9!7BX~~JZ9-O(ol-#qMbxnt5KoQ5zWZTv zkYf$I7RrcG7PsM0>MwE$xwl@VR(DpuhSkmKTWj|FX^+QI^x6D>64%a3b-1m^3MI!E zu^89+}8>r18(1aAa_TUEfX@p zU?98d_hwwYq@UnyYx{Jp7k4V*qScE&RAaWK-NgQzdn?=Aa(Tj<-Mh?rjzLCLy0L@kEdVltW)haKZSl{XB&gR?q=PT)F86ouh<3*a#JsEQzmmu(2=Nl2rJ=Gw zREJ4WN?R8K{ZvQ^2CaoWyI|!Mlki&W`j^)lVJ~}c7E!#1`j8@VR1&4d$F_wOJN}Gi ztaLzWJDpg!=2$;vSpJvi^I_9}Bjwlq5nryl{$_q(dajTCFCE=KSC7AM+*JId>od8z zr&gR~wxBfXhzgE{IO>4WAaC^mZ{#Y@KhWK`i>%`*`pfuX8hF$19ORS~A)f_|{{Yt@ zPF{bxS=ZL)YcD=XQN5Jz^=LG*O6~`inpa+l@Ho0x1s`NmI`;nnrQQDkn6oKCzbQ_C zqKki!&FMUM80tnyW!f$c-r++#EpRSYhkhdW>2Z4R@vMdLbFH~3?~e~^@bvTWJSTbj z2fX(CV_zaQR_E}!Idsd}E{2<4D|q;%Pw+nKaBLn~GhnJ(Wo<2$Is#R-RwP_3tM++Q z!S`@c3F3RN`x6tVeAF)l95{Yhe;?uHi|9rvZLDJ3w&E@~0;2X3n$ z6Z{{2>W<^guG%FQ^nQMOn7bePU*3CPHXMft;u&-4oL{+&OWn_xud`eola3c?d_{P+ zeH3;ZsY2k{E$dE&1^Mr6BIji{K0Bfe#{Du@5LfQDk)hg~613XM^BQ?t`t9i%&| z(2woGWOnbjiQ?Gzqls=zGSrtGN`OmASQfi!@VLm7!>o`qXC1*oMJl)dG)21Pzsdege4#Wa&BrcN<}Z- zf3E(^@g+MC4(hp{VWLo2#i)F$77eWIvI;akLt$$30=8AavU})_b@1mc^hYxHYwI(; zyy-5(RN==kuU#h_hTO_jli>5W_gwgbt*7`!bm`$&Uxr_)zOF1G>dK``Qj}DpRHM~I z-2U3wX)(6ewS*uQEc8ehGy!vVi|B8?e9^Y2&5Dj6f^-E8hHNRNtt4LTM$y&jsJKc` z@l!^(BQ3nRL)5ikcAv2Qr_07^j2r#J&jLUA#&2q3wB?BgJU|LXt)W%aKaRCWjB~8# zN_%LDtVh%*a~b6AHzoGd47IIB>u8Ro*t~A){;EkSeWxr^q=0S@LM>V4EEXuXM)IuM1K-S9-0@is3#!RL z@g6l~D@|lsO|1&Ym2<2IBabtUb5_01Ka#pVz?&{BgYZaccF>@oBlqf(N(Hq~r&YPh zefI3WQ-|_5u~Sl+P^2f{gEgW0GUF>$JlO<~`Gx%_%vhQlac5RCjj<^V{t@^Rh_NVE zs8^W(01;P4Svi+f;Kw{~I^!-SrK_jlC;JU7qFF`Q&_3gQf!19^?5L$^An1A;siUPA z)Q-;jQ~HC(a!4%k?m)D;J(Ps7XQA;ot{uGj&utNgcQ!MNgr7BGKr3pxtyGn9=VKNy zawMAL(Bh|aq%C94yA*I#cQit*8opGaW>a7^xfZUBV3Be|7vrG-mkrHYktA&OjY36- zoiYL%X#|th(*Y4VH@yHvOw#^T0Sl3RDF&pR5E(pzQVzOQ6M_|4rv7mv{w9FIQIl2` zo)u6ArBngoRVg?$D->j$8kJJybrV$+O5|A@@@QL8q;oHgCX0@$t;oGrkk(TQ0FmKM z8I{{th}D-;my%V`8nNnQ*y|6ae&yo^9yA3kY-}Z^1$9D(mp=pl03J1#$c>Ysve{cHHtVO4 zz}l#VIC;s?a(>}<`-m{~?5yS>ZuPnDEN)TS27|7lBjH*OVvMD+MfX4Y zfHHvOUKs?)P`X6vw?ltwQTUJiYez|@9A7ey&2rB4_eUx1NP2E;x~(HN6qv~W0HHpg zy;n4|wlG<529I*JDrvmezcnlS}i^CHf8GJYNUdXjAd)59E0s z>A4vfzv?AxKx=)qDDO6Jo5_%jY&c-y z=CY)``tP+X-ckaJPvKHdx_mXgWbW45mrOH<>HAFGf|^{qr;M*(+2SYLE)^pK#M_aS zFGNXDP>T_J&a1MPw2uy+XZKZ|zl$g?xi+)l9q*Y;=kn`{c>ZVm{>Y5y-%LC!n)2D% z45(WYayW(K#EfEuY=VNE3rPx9(v_sA(6tXwz+U?KJXqf2)%>qN!`ONH?QqUKN~4qi z08PwaDdRYw_NH{dvil$o|1x|CdJ zT9=dicm$oE{+0g#PyAyq{MS76zHu$0KxZa^(*a+^<7iP*kNtKdz}H5*=LeMa_9G3> z6G%=5}I#U5LmvzpqrGG07=tZ*Au&N z-O!ZQdbjqUM*jd$zN!Axn_nLMe5t;i04vOKopgO!)5`}KJkk)IO46I(a9*O` zVBWkmWs~(KwWzJyUU~iEGuIR4OKT}w+!k#LwaK@D@x6P0^!~10o!+I#T4xr2Peb^W zy+3jDPxWGbwS7H$<~6oz{-tX89C5SG?`$`n0KB#nBv=w6A%-3fB`r4NNlRB3x=2E9 z4!$~Rt$mZ~520zfboD+pm|q)Zr~s z-`(5JGW7Az+aFAE=&}Zu_*a)caFFpLr4VkBRw7N(nskH&GkvejxtfsoAIg6s$L76x zSi!WcDdgM-nhHvSR6>pIw1cQRkwWW^R9+L@^;{pQ>xBwDivDct{{X|5aqj;BOuW*@ zo9U)BM28dY9|*uDD`GI4EjpPpz*4W~l=Ku=Ok!c~UsCgVnNpWbf2KNqVKuHk&Xsw= zGi3m3q}1R;QrM^gk0Z`;{y&UfM?E?|8VhMFQ}Y}Rjiadm>P1S6lfp#CE?Xm1mkJMLqJBa$v zE6cei3x?wr45~B~j{sUpCCh*Is#n6*(yNaO{uFJhxYx1-*^-46pd_cj0nk;&%2_v3 zz)2(3x2OaU+DQO?=7Elc?LYMP?lxu%8NPctjtPN$CB!uE>dtiv>9wFi7wAHYNa`*r z)o&SQJ9)8=i&k_$4(&H&J4-4oel>#kvko=yr;%omnJOKHyhjmR(#B@UJ2;(+$HDnxtumu zxD6^iSm`Q55D*gCPuP*K{M0BZY#mtK7~#BYnxhWnu17J}o}YCH=~aplZ(*p>L|XnM z!_J~yMJ#6}a-MW6zTveRW=&93=zOp)6yvTfV%k}L;XhzM-&V^FV3@}Q_a5VLIWKQh z!ntzVZXrq@z-3ajIOZ|;?ixeMxKL%n3U#pXze0>tN$72+#|M*{`?uP>&mPXqz~JA?QuA21HveDZk4fQZa zgoj9yw@^_Py`X57s98O2T`1O(a)^`g+eO@cTh;ODR$vI}lJ0i2nGW^4A?X(pqv_&QsitNT$)zLQ8QsQjzzJo*)i5?r!wfk zRk%d>Rc>X?yIiO8)>M@*>u((t&g%)bIg!8|!zN{erXG$%T8e$=eFcbGQEhNZfKFktdNp ztefJ>EH~+BA0m8fm3MNJ(mEJz=C|MORSp2v>J?;kOV3Q87$3VLa( zPfK}QN@PIoc-W2*?!^21RFJSW2~h-uo}*AGYak1A%&#TlxK&Bxcype5I9s18mrH6r zRzOg`swc!+{cJU=Epmi&6_bB&<5kGHLd!l{f6a{Gskl$q?-rfQQ;X%1&j*r+J*64S z-x)*24m<$%ln+9*?Ee5T>0ItVc7*5CHPZc0ao&H^o>vZ)Z8BHEt>dHoJXf*j&@=A0 z)~{r^Ypq0+k{LM?+V_CQv}PbBNxDLdO1G#GM}@8DTQ28QR`NXGZ2DKY^K$F0#V5S7 zzbt1@Ve@ynJjv-ftd2lF!ajOSug7jO0#cN%Wk6XWJ8Tb4zioNWHxY6yZZX2k$@Z@Q z0QD@pPYyA*g?! zCdR#&YVJIa*FL&ehP^8(uPH_0{u%q3@lJIWcgLCE(=7ZKw!i*4#Y#VPlpmK~tRdm2 zG01r$FnFd4v#&UoRRK!g-s^$56yMMRz0!W_`zLGq!;8t|K1NdMT~dqm^3U7NA2;s5 zPv61hK0V7+`f{=NYOFb?l*w&NEoEC9A#MwdTgeWl`T&=LWm9#y2(8? zug@P!v?}wLHYxUVbrc=xk%u<9#}= z%KI)WTH|THqGZ*`i)}lJ3Qg^CODdd5$>K!`0lGyxLYsl(Opq7_IVRg~Y&x0*2m6WL zKHP9TV&`)F%v>XAPVmdC213V%)`8t)=Bp2lSqf!0qAZ0{o6#J@-S6saDbIEXYw-Tc zH9*bgM!q9+O#cAk_Aa+oz+cSG)$o6*oX^htgU>m(QCSXOmzAH8rEdt5v-0RZ8yN>~ zo&{T#@vYE=VeqUQp$NxhLdZ(g(MokE`zpd-!=4+#InOW3{{SuGc!`{fXjavx14YK$ zHocs8@Fd&7o!<%@NjCOHQhhs@{{U%!r+*}t8_D+%B8)^!1%E7pqFhkxwQgN10G$uv zx0SD6GoAHn!~Whne_Zrma^KVTtUPLkIC}m?#mv5wdl}1ne&-G1SZLfglt6Fhxc*Pv zEBU8FeR1Tjz!bS}0qH)Z+g;tB(cfw3trtu3&ySbx^Er1;$}Pn8U$BDuH}C#JHes&9 z_h|}+lEX<5xa6FG1x-BB+MH9$SD4Z&@2In2{{W_yck7#4F*#Hwy5sisEPm*Aub$+2 zqmQwWTAOGDxVOr7u*lTidTF<%{5q3cCDXaggT{d0BJ7?_*a;z`vuxK^HGt5#!74$-uJ3-kE3$-7U@ipoTf)JoiGWDQ8%RFY1h`21^2l1QV( zioC&>x%+(RTJ2jO=DJ&GF#tSQicOfcLS}OMf5=h(=zgq*h;d-URT$U*WPVx48 zvBA;D^8qn=rXi#L-^o9x&9aem4nnoR`4#v701#bshD{uM+#b6eyWB1XIxNW;>Fh2X z=uR!Aw(54Rw-RimsC~6eUK!A~wPbWFc~N9Tlu)oxw$JP}der2!;=(>L$WDn-^$)~6 z{vxZCP1IeI&h4jg@|=4&A0q+c)2t{hDoOpI`Gevry^T_ek~^=m9pS)p&N|EMC=;Uq zm)R#&D31>`n`!?5gWh14Bc&NO_H67wuJSd2P)k``()CaZERL#8q6S3!EJQZ9=h#N+ZEPzgcSve|M)(Fkx|yptipyloYZ zT)gaBSbSHuc=(_=wu6cv#ZTD+eC1&$N_y0n)JYdD5?P%IWF>yU~S#lz?S6 zl%@8@gm{l5S?KQG`p(9vaqx;4Eer)I3LgsfHCfcMQ#!#M%y(luaeb#yYg}cMmvvn% zR~^rCaq-K?7Z1w1w7ImO!ldcAecfrKvL#aKWY#w@A4nwKV^i_?)e=Wqx#b-X^uOLn z=nZjIK(fr8hh>{Yt0uF|_%^bElLzI{SM7Ss; zCgIUbf=z?97y}fbp=yxG`y0wRBnZDP5=lcM;VD`|w%_;()P2UbQ`|19Ju!L=nXV6( zXRwKMFdCH1hgBiwWFQc=r~ppkWdoq``>FWd#@cg@Q+d>!hM26hSy<-s(G<3mAxhkb zMyXm2l#8msjdUWtXBUwhprnRclWk=gM%0yicOWBnpxgs%kG8atfzxs!$v|}jdAUeX z>7oAs9Vh~t@2Al3ZMo@@nZ;j=a%a-F7V{$TuHbg>JHz?&{7)=cPC_Gr4!;F$ z$Y^SJ@frb;L*iW;d}PYXq<7;{`dI5 z72=yT$Y8j9em-#d=q;jiVaMU+SsT+SMF*%-O3>j7)Gx$bE2X_Ujda5rMkx4P?B#bJ zR&}=PAGN>X>I-r18S?Nq{LB90id42xt2V8w+yPHRUQ3_er8zi7E`#(B(m&~iTw1H; zT{%8PT9zXH*#7{B)nk0?>)=>Dr|!2T;2Ae3;G;p59#~YCCoqRM5G{7z7I6pQ6>Igb zV&u;q4o?T7@83f9{_UF_I&ATjUM2fuFJ#llgNfK5Po4M0cPkYjK*i66lg1${n$pr9 zU~V@37tx~p>{69{2-dbySI&#*O|*O;>c6Bp9gb0RoM#FAEom?Kqp#x`NqOU9%*A9H z`HiIQI-x;Y5Pmo5V^d0Tp1K}AlBpVB!1S%D5P2a@hE$bxP|$pQ>1=5%F-EBdvm^%T z6yR=zsY(e*Dkq>Cng9gu*VMOVyKaXO$#V^_CfEM}lw*oy%qspBr6eJ<{{Y@8C&(Jp zR~~cO7S}}QvN>zJ-_(b>+0g6`3lY8@j9t<5t3LGgr1<-UCuRQt$Ph=Fu7zAE$9+xJ z@S`1Gr#$Ae`HapzCf;kD1zkfK*Cwj_)Tr-r?aA>Vy}B#3vEN;K1T|R+H^F6B^KI zTL*z!bwAl${zcQC(!x3Owo-X)j-3ZIvDP%_E(vgWsGlkMQZ#!6Z1x? z_X{ObtYTb}+=WP5_Ba$4l^|>=QhE?YtZ(C1PE+f0n@Rd4ze6@(iv+%=dlehJoNZi> zj-f60Q;bIjLre|7&Ed7tJCkAa2>g~iygC%y(r`J;kh)*SzcuIk&759OL+N`mTj;y$ zaz}D;=;9onXUO*}kF;4tnE-$Bs4VE9>J@9qYTv4!q`fKU;wg8iQAyJjWaQzPb|l4duxe#oO~u%Bodbi^(|{&w^ffq zO+0JD$gWv0(fveAz+yc z(M7T@c91$~G`(!&*BocW%Y3Drcn?|Sn7J)&byrIIuH*A{wa><{lJP|-LCKi3$5KOx zkb-W4HMjmAeiW`=V<`C*$35dvWXSj1LKA!KDm#aOuqLZ`EsJ22UAvtj0hVJefH7I_2q{vMllRc&U@FC(W%vB})ih%IG9X2~sF07Z$nltG79t#f6+_J`|7%u<;&8{3@wL=+kyfZ?iqx%yBM2 z#ORJ4pn&6K`c{HVEL~aVsuB1ls{3ht0^kAiWl}($>inP2Nq7U z+q*&|ptO$_ukl;_e%f-gccC%>QvFLGnDwAiFDW&ql63%3P5@40+#FUtwHF;oBKlsJ zBdBDkIj4D+`j*^NWb3Ufk#uV-?58A~F~X&+s{a5QjE{mj#7I~w)}tb}Hd9L~w_0>a zv}{|>9+b#N$6v`kKN^uT3KSZa$~ue&Xa>%evTJ6xP zx~Aof5m_#Jx$=VdZ6nCnFO`{|mX6-kGDc_fd3mT2nY*QW0G&-`;_;VIlaEL}ob87s z80F+v!h#StFGG8I*Q(*z(!tNU#k~siH;qe(Q%f57S6&h_Szl5DGLc@4`jD%F5ALlg zi)t zckfetqYg3i+ygZQ1Khc>eX*c)4?pAmwdeVqUzYN=XCsxz=y_Wfvu|8nS3RQ;s$8gO z4Z`RHV6#hrH%iS$1{6uCzzS^Kn^a(O8=2+%i;Cj%*Tdu`yptp5Sd8;w=G|H~C_gk zc-hK8_hJ&4A`omyNjKPUs2Yn4Y15&_?($QAGgQy8_x}L&-kH%K?C}{xInVQXXUX_y zZFTbqG9O;qTqk!|I~Lk9yd4M(%ZA_Ss#2Un74vMD5|ts;ej6)AfOlC$6g2zSP19>Yfl6&%9|SMi^Idp$w9Hgc_$|23CCq( zfc{-db&h9?f8Bv3B-v72c&plbQk}>?)TF6@tLw9Ls??TZ{{Z2CY@Q;75u+#&#C_a zrk(!)w08MQ9Ehl0C+^!Xhab}a0HYuFUyEKm`y1V6LYh_EQjLmMEww|ygI-F-roIR0 zUL~C}!haFa{{TsUMyck+@{V&E*qmX;)FQ=8jxzMO4vBOrJ4ix)-G0jM_P*8gS5==6 zf<9CA=hv%&Cr1+>KR)!daf^PFBXE{D;k9t3Q=__Yajx(twgCx zAPcEPoh#H)L@AF<77_4n>D{?K#_yfTo1DLAl1oIrgMMQE2``4!kg4lVhOIDR&gN9WFSc zlxF^DgLd98N?-M3em2Z@R2-{a4Fl z%?Z&TYR#+8^SKnI?kAtf*I#dy%iLdn%lMCY&moPN$1{+M7TjmjqEO)4Qly=x*0}0C z4PmO@scEr;lS8J?hV@&HU&chpFs>xttg-@AHy~- zr29@3^uM6)K_g<>UGSMl0fw>MEhuI1RugL zbpkZ=xu@jQbmRV8N?xWvn3BQ)xilE;WzJ31e=m1=eIF(Y5}O?^1(SOlX{}jJbBq$3 zQkRRy0x#56&u=w~Tg@MvaR_zSRDfG~w6*{$Qj%?Q4ZvTd>uZoehNGNpKDY+Bd};h= zl)aK`J1$leBt5w}$J!1AkPgM~O3;w7bP7vpxVlyOY2gAH@f!6GKal?^YT zDJXPY2U}Z9xA~CZN{8MBD`cXy=Z?1DC5i}Pg%|ww;bwk<6r!& zL8eCYF6Llx@s#A52y7<$6R+JyLNIKjdyDli@2za(KMteZKix{?XpJ6aO`GP~Y?JC+ z&Z%Wb#L~7~(vZo9CCOF5Bp(__G=!9r9$IT`m{{MF6mMD1`nIhGmYv&xcp8syJI-SA=5 zh&-!~tw&|*BRn34uHP23f;4>k6}cft?7d8-7IdM+l3NN6TQ?ZAKCq_Llj&bgY3r>^ zV~Nk>IBtR{J=Kvr8)u$bNll0zpnUEq_oFOi<;#fNdXmtu`D-wYr9B;2ZNg65Sfu$^ zcZGYB!`$b}3=!lQbjo0qi#VN9f4aJ`k&60ykQpJT7BDygOt`8J;t-@3JF>D z4HP`bol_{AD7dgVUogpGa`Cd5=Zi8UEI8W7PlzML5up{9+SHRw+bF55GqL+e-0W8| z<4w3H1NWDl8#{d%IsrU%!;|D38ga*YLD|)+XreStp5P60O%b2#D0Bz zYRThteYgEQ`i1hUd@E;(!GD+jC@tgdirXK{=hAboa(+e3U||X-tjOXDw4xd6U(>apu|Ce?(tXU4r3!Y6lPG7^HEGfPA=lKyQ08pVcUGVu3C$X=RAW zOD!~j07?=p00T~y&`S#l@wQnjB$osHV=#Qi*Qju(RFJU154 za7KBA$cf5xL_UU{=uq56B`9gcC=q3++(Lm$j^IUO=W=C2T`|slPER9|V|aQ5x$aY* z%RZIQkhwzV^hi4Zw?w5n4Sp5C@QwV$H+L4An8MbOTL^Hj@1UtRQWs?nHj7@lT%JOmuUxMK(s4M>rS0GCJ; z5wv3Qc`W`-Ol30h7bawBVM&`BPQ?qPsVW5uDcm=0J4j8{*0FrGDLnoK_1!+F4vZzV zyfOR9jsxB#<6^59jezz_JX!wUNyR0`DosPH8Nn+#2k`ycMk_X#Sz1(8>2-wyq&(WREv%45lstx&#;dq|t5Z+-mMFB! zW4@ia%yxsE(XK0uNRc_GQrf;zBJYq1186n|rgP9($5E#* zpOwQ*OTNfnHM=j|MvDb!Zq0Mm7nw1o8u3QCY| zeRU?e*Yj(y;&?io9?{C>>r@<&(5 zr_-+YQZ|F;lyo0`>g5~>kcM_DGqFoWAf$_0m=ict>r3f9&MT68l=0aA0RI4v%yRN$ zwlswD&ww2oSw5fPSEr#!s%0D0zfI&hJWnTK-e#RWx*Kvn8j%d-uxt-Z9v4-Q3H<;VZcbSMevx zgzyuoNR7|;8<6Itsp+y7@|JI@HvN=jl>~;78ks3}NGc|zhDkw#8KO()^&3zdJjGEq z{0b)Dfh`6k`Hp*W8X>c#{vR5M*XC8z<`UvKB2WX8&gFSk@j|&13C2ZbyCEO}Rv`iI zPci{C10{kAEG53OO)zI7=Ma6+JP-I(WH1Q00H~4V{$msO05wY$$%(w^weMB5 zCs2xIsH(uyG)VEOP6Ul=iJ@ZkALDX`D*;;8J62AY8%L69sf@UfGhA*=aD5}`*6e1B zEt8sdHlid-HT zIm&Pz;tYn9>rdhX#Cg`pNaS*8@j$Xx>kkDc=_xgC3<=?dd}};~pe07Y^#}5w@HI^0 zbZEOJquK81Ww?JOYJ75BjJr27HS~F+bszH%sXldwlR~mMF1nRuaCR>o=DdF?jEyoh zl&PtROO5XIs>&C#f#^qwuQfH(EIrIGwDNjf{#?3Ojsk3N%Bdu-#PtO9wGqdO&T9gW zFqJw>DJ28TrRij{^dQ+REOi8ZqLHD6nq<_HI%SjPQGy3du}qM|Z2tfm$7OL(z?#Y> zM3~x{eU}B&v?y4l{{Z3lQ=K8b6i^IE)Te?MpC*&jjtf9gjA#hsI! zpX_mIYX=#G%%RsFC_;85#&dS)?brcrt45k5#=Q@3jj@iePbPe8>mFYM+uDS4JiN*{ z^YQSL``5JSo(J8YDakTYaLu~Bek@wx0LJWbBkI0 zPAs0a=O-Jv5^5>GHhr^;Z*A=rM$4rXmXME@JWVI^VeKDi4xXo6^ra)oBDQh6CykHp zN1X3J>W5Nr;lnNe06g@H{{VJ7{+^7}F_`8VoE&uJB+s9O#;Gylvms8Z6H6sZNJunSMetl_Kgn{<;`sa- zS-g|0_M43Xvg(S@M4M<2!uR-4g_ahr;J-LG^vmwt&M_xF%(5`Jn`}o^hB3~pDfb8) zf?QE4OMALqMI|SyYfl=woss#?#u@jqz7BUInABg(T~hE8{>TVskv)3856$xzd^CdL@07Tc3K_^Li5;SL@^Ea1eS=gK_neUq!4dY2&EMl_VXGyPPdq7zz$c~&M?ER z&BwuI=fl3@Q;~6NWwmuDVr);Iq~E1ARjBKO(su6QJ5!AJKwlzrI~O|h{F!*{#yWdm z#K`{uE*)_Vl1I44?HhF+TRyK3utLI?UZ&fj^CG%(nt5Nx(3s<_P0L|e0Z*m1FHBmYsbG9_UJvK|8Oq`symqo~4ffoy|wDr(fyu^(`*iVe%LyL&xV_{$Uh0 zKkl0s`DGwnB}yNOqBI1Hq}%e}Ztfo!-dS1o@;F_}nxy_@eb>8Qf5-J5cN@ALu9e3! zxcDK*$X=(RD z2^*TXRE?ui{gw0EDU~y6>=Li0PhAO4Cz(edn=TGfk(c7x*1l6QiFq5FdOE>MlmQ@b zP5nN7G|-LRznd;Sjq8WH`*^S54n8QU^N@LW(#Lrt^4=;{$vacc6R|CoU8#^%N|g!n zeJPU0;#qKk;tq;&C)w9x!jxW9HYXlLF!x3Gm{tcn$6#{~DgD%22Cbq2aou}ylMS=8&3OdCgUGg&A7$!`3#AH13S8H^yai1{8?wW1+OSGPze!*pC@E zDsOltN=VQRI+{t#L86V|@cCR>aT?^9sSL(a0SHm{O2>+lqLPw))2G^=wd48qy6GNZQJhvJv7LQZ`uXa;xWGZeni(GGz;}(sax`Y7wxSj5N?S>?)J~&R z>$k(q^`nKE@?z>uEdE|2_k|j}Y~#slQgL|y0DHsmem|ko?@EgnF?IE!lqT0&$VeB{ zQfu2I;|v{Na-u(*PB#}4PFZ2kYD3Y|15DU}t;OzpTEEK6K2SNxm44xVD+v>;ZmVa;g3gp8=Mbi( z81A3q1Mrjhlkp0wB^(`EZc|$Bb5AJas)+G*q53L4KZN;xo>gRJlP4mMmzA)`6_Rp0 zp(K!-{?CmwMRm^shAS!^K)LmQZB)_Fgz^w!9fYT?Cw9UJ1s42X7rg^8yAH-fB1C*# zauTatpdPldBKNR9H4T)@O~VW)Y~#mBe=6uJ8v9`0-)&PXqKYMFkoI}wF+XHA6xgjG9 zBis}LS$q41OphSoBJ$0urb39$M1_qhS!`;^-7-iws@Z4A$od@Km#QSeaakhEsW#dx zC9LW2xNXY}mdEd~ze?oa7bEEXma6E+qlcuSw4XY~@{e^#B{iWDK3bGXCasM{^5hXx zo;NkB6rB6HNfEPmxRL^QU&7V4njTI!GnpJbiQ=(2LbG5(59RAypB6IQ^YP|NFHM4M z4{Et?ZF^wEb^ic00c4N0M@rFEY8x4Ez0X!da?Tr-!%lJ(_Ef{{ovT8JO1&9(E52FB ziz_d*pVLwG0r^k(RnV4BXCj`LltRLm>{$Urr$Ri%Gg&i2eJnfSoQbr^VQRCU(vso= zx+o;yY5vN~Y%-cVTuatdI%kac{{VnHjb=NmFr8Z4NcRw-?Obgjl!BEcU&G78TJrYx z+jY}Er@x1O<0y4ytS^TLLGjR$j9`0#??O)Wn}q@{2qUN?p{(s-`8P7vWwMf3O}CFA znj>w7k`eewz5MF<;~EqTxXKjK3;aHQN5Y9Ltw3(mLbG6z(=Alsk>q&AM#&dH3UwTS z@w|JaSf<}?TB~CMUE%EZ3!8Bn7(A*hhljZyLJ}0X@1z}%H-8k~#CW8X_|(c8VV!=* z-mmR^nBP;?XxD_J;}`bP;rJXu%KI_T@jT&NJK0GQW9*d0xp}2-n~a};agX|KNYd@FRZ?*;Pd11c*)`~JxL`N z{{T|_&GP;+hKc;cIg(=>g$t<5aVS_8y}h&QzxhC}oTj6zcs_YY8p~fradLi(Cl&o> zeNOQXd&=?c@T9pJ?lza=E0Hkjns!SMSe8nsc$^;oOQ)G(iuDh+s{{X2f9s;_(32rr?2P96VfVAA z#Ele1TW+oVF<-Rj&dhK>sQzoppTTiN#chmaC*N{MsVpS4g((sDAc7RNXf*M)P4uWn zDsz*@k=JiwqOR{`r6&kNDetEK3pm_>o6ftDfP!Ai6=E|mpCV2&OVXH@mjiZCASpzB zmIqLJYg7G~ijiXaf=Oakrv1OMsTX%@JKey3p!iBVLC?gjA24afuY+P(hek+5xq zRREo1Lk)BayzUG$6JJl6;0&iy@i zX)DEitgn*ebLA^Y64reXRI{Os`5?wuKu@>$RN7Hg>r-7UtCd2sJ#jh%JA;)RyB14c z)QIaKC>;qlu@~wHu1%Cm5qVxGCm14_b@rVM$WGP%MOx`U8p|B586$}hntC#j=t{!D zw(Ujy58QmJuAjdm#Q(5qLk zr-6!m%lQ~kPugiRK5s1*adJCy4DH$Su?m}vi)rd!g+ktD^{P`*SWE6i$BSKWs`+L4 zEyylO#B!L}jJp-Ip|@FdZEY6~tqSyuA5q+sqRsjqnpZoJo5pwYI#ly3vN&s|DebWH ziMHe@fIQiCm7oQk6{@{K#EzogBl~S!nekMl2)Ol`gp#V=xwqQM)9^mdf#N&pQs92*eR=x`*eU_w}q5~4y@2mm;n zgZNc{8(UgfRT%7&9^OTk{Bm;kw*LT8;LnF_^fG>Lvrlbb4T}bL^0(KpG_M8qDQ83G=R3z>Q=FR@86)|YH4d!|NGK>SH+>XS z;BD60U!_x=9b9!SO6xg=awLLNa?-y7zqtHr=*uTE>YN$27bLb^N)&8750woQU6>4U zGt%G(#B~*0M%65rXJmPPEpYz;ls*!}>;C{rbInIG|oX76DYtT4FlBDWVuBeE<3CZ z$Tss8WMm|uCe+0^t0-92g*zT8N9K~B6MyWZ0g|I-(?prXmmFAvp;XC~{EQ9cM$)Tt zE`=jxL?z0uQ#V77J&%nh)~wU8-Nxa$J&AZY;sC5RT6#J=O5BhiqSceumMiEeVoBNYt z*Ae<_&rb<)_WoV2q^xWED^jlr<LIKZ0oWCEwOKtJ-1wTj+W9ud{! z_UAR3Fr}u$YCAER(?9R zg24ATHc#MjeJ(sJtH+F#eeKUX%d!%&xGY4Vb2xKlw(2xD1RpBBJQ<{vmJ0ik;M|8K z*b>^cLHK!9@p(BnRN%(gjGE&-0VE)s{fEw?QOOk9(!;DCXWncb-n8`|e;UsyoqFu* zM@{`Ecjyw&4$eQ<(}|Gj`~F!({{ZwqWpTOuPv?)`VCHfE0GWN~OG1|5Y;0Gjt*elv z(ajzQ-E;t>r;rw*$*>n?6$t?GgbHMaB{A&nZ*{d__6pNnaDaH)D%=t%rVzAkP`&DL zkRs8JVkTeb(!w27WGN-}B|DiyzY>zQejkpauHxRPvpb>s<-zy`ilCk<-Ov`$BOPICMzEq zWl-VAL6J3N_^C;{x^)|rKFZB(BWAK%BfZ=1yNKGRZAwcX?~mLA=6iL{F-7;j$!C1fhy>Ry}&=zrT(40OrcR) z;jnh&n{gdOfD^l=tg=;phO*0@$AeLFO}_+UpEh%SFhL{#09xE52O!}%W+4zTk(L<( zI#9!V6J+l6jmlNL%CF~C(a5&j8~$G};yk!cE2`OH`3>Fvpjh-}S04w){$ZvL$0g*J z;89v^rGKNPl$-5V&@bjIs|c?XBZGSc81JggS9bUoONe4+JKN50n_)5Vvlj4r42cCp zYfZ^QHz2r2x3SjJR8G_tn~Gat+**snHumY&Pa+e#J$0w=FHhie4(J91rBzAKR%-55@p&A{{{U&FPYx@^ zX{yJx>_4Zj+i(uta5lL25_uUR5lU)&_W&=uARkz8bxyi~ZGN@Sw~;AJEP6Q6QNZ84 zeVXk*a3?VDGUGVx!jQ_C{&M?>jUqBHbhej4ZDlt)C)^_E@O7n!B5P;&4QCp+j-{vO zS9uSlFQz797x0)=$1zqL`K)y5EVve%DJlzXN$Frhhun0~mp16V{{SK5z@kfHL+TUh z;T`GVa$LqR;(Lw3S`ng4m11*n17Ts8+zCi7>OfV8tNf}UZR2ts*-dJ{Gaa?AD~nGt zm*SY)=>zH}M{+SEwtVfyGu*x`+la)>no1qY#*7GYhxck_FcbQK>a>q@QXSfIc+tHq z{88A!%;Kf*$70lRmkOL=*3{aYB??P}UFrL8V_c@*TE-4;O=9B}F|edMsP6?4?Ky6@ zwSlqM?XA7Ks;&6b>d9>%E^FS(W|>Y8ALbZdRcn-@R2gKFpcIe^x>9Z9;bWzGMEX*S zST@rNTlZts{{Y0u?8LZHuO1>V)Tg3{udBmj*YXpIKH9}haJt{cx?k23s`M6d9Q!YkfwGdUM2mqtA*5b=+y8Y8xl zT`iCbT-RQNf9$GkqcV7SNc0>IH8X@IEnC+<@t^>c+L#N;e>CI|NaXUp@n=iXn3KtYJ!rmph;3qy-6bA z=xbcL8sQn;f(ypWbmC+|PE+wk!5BcZ*>KH~S6 zxBMd(sXT`$#1yuhggCM8FHJ0wuC=c?MwnG8Y;wPOKd9{4W!O9xAGFcBMn+)Nk2E5y zc6l4C;r{?p&3wJW zskMuP`@SNC@Kt0KmH|olx1vZXP}B0O%vI^+<=I<{AK>z9ZDA@pj+gQHR5V#tm<>4o zX~tYbtth0VgQ4hZyc)BVTpWLvH_33KEQJrBU|l!=0MrBf>bb)uNp!M3=nk^^+zLhP zLHJUslHj*Ne;-U&amn_82G&0VK;p8I?TdA#84;2k0^wdX=t&5qM;fNrtBkS|QBTYz zURVCgaWYh_MmMS@BS-ebw&I&sc}Pid5$d584wY1{i&P1jox4B8~4Xv9W8&=3ugO6>= zyp{(N>?=wsT(PH8D@1EEOOnecjrRACV$z+hAtgOjK)qU`W|hs7*$!F8aWTks#3ZC! zXtuv~4G|XdSGnGLiSyKqBm*Vo9Tj71pBoCu_^@v{I?(PG#yH8gKeL_5@e>Km{2H?%8C|(6bem>R1L+C zm^GeJI+1Ef?9ZkS{58yQgB6r$9s;?r+G#H%0kR+!UOD=+b9OO3VAF)tl@npb-wk_ zrFkvOv$Z{#?Y0{r)F_B!5F7-rAtfH`ic&?!<(t@_0&n)$8eFS6GsTm_{Etw(bv?eP zDr)PO=lnjFc%mqb}DW)RSOR52zl5c!OBuCtULvs(N7SPN?5bERGbG zsrVGMJ|Moxce4YZ=G*zPEF(a@_6ht)X$R6mZ>Uwed4pbxF^m#X zFiLWp%(Y>cZ~GnGu2!azjE0D~+lO4p%}Rn?LdaFp1&O%vNw-}*D;@mE!Q*yxc-$$? zXJzUU=DwB_8Od0uXK%^Lj2*^HY^`b%!3kf!%V0RBho^eey?c6HR!v}B`z2yaO?5ht zw^bUX_ju5|IH%Sh5n^M!PrUf)J+Vs+Q=^9A zL_>&_;7dicC8mi{w&S+f`)Z3X>(_Gl(Hhnkm?FD1^@G}(j?Ckkz@8bD!A=-Z?AZ)E z8hgQh+8mDiM)p|RY~oS@J8r99y#*7Bic3r*fy?ce>t-^ZKo74ErF@d*p7eIyJ&xrV zM;o7+XC3K%N??T}BOD|j)o$OYE$dHEY(chB&Zwh_$X^7u3jUnFpfMfo;0AKNn7zc~ ztu~HDjc3xCEsv>xRr9lbz98o(#BqVv8 z3xTecfybqFHe&T;zBI+2$crt-snlI<5WTCnO~@z2Us2=ZeQUMBYHL|OrR(5muIVj? zS+3uE?y3EZI^(LcmaqeWZQH6(q@N3dKFaGUGp)z&-3t=V2V75&%Yun=rn6}ZR>m)< z>4botLFi3Y6!P9ZhAwX*TQ$?LCEPCU<1v$@VPZuSr8%@cbstNKH!0db6};<(-23f( zdAg$>sd%2Fu>Bu*K9zlw`EYw_t6pR*UQLbUnf4&%VJi`nkP#j{l(<_Utevf`N*bV( z=}OX|6iu~NXXAIO@3BV6xJl@rhq3<5r}>(>-%Ij16uWr#D`2&f#=36&pRO?R<{xl> zrTi{4AmrS%wa;6`E7(BT-;d(4H#+&){{RTCnx%N^d5&Loo$yh@SS-v|6A_JL*?}FX zt$}MakT3R;tz41Kl-##@9&a8MB9wpDhth5@yPQAg@rY_SIKniujFPJ*GMm*(g!;dQ zNAMH)Rq!T~aLK2Q$oX$witp$%>c=4Lg!XT^?mG{Y;nt`)Nm&b}*Mk=d$4M*K-)Ilg zQU3r@0>{>yxUiRlF6Ht60G>M?XI7XG37`aJHp|SZr$Ae47E(`$rIb{b9>g_}3%R}d z?FVf!idKIp%vTx*Y*Z*YB}c7-0k|gj*3^-NYgk2gU*=?8rmgTK5`N)AMRS^n zE6sQ`_!D2oQxETo#bJe=u8#gf=e znv$Ri)OGmMv|U|+pBm4<7DI0`vXYVrB9Oi6T2Ql5b9j$=0DR+V{X`C@;wfA*Ri2V- zhQ@snRJCZ89Ra0qBj#XRGdV3UY1Gm${5SB%e4*nHWi)O0QLxx~n=qeRiG^^4iAz`0zfRvqS<3N+; zlh~dN`|1T^!mo{3G1}K zvv}Ne)V1=cZ5RBY3YS@1wX)I2a~x8c9^TMx(xJx!b!2|uCWiA0N^Bjm+7C<8k_+-~ zPXV~EH#ckOSSctYLKG}gZ*WCVLj^5#IXCJHwGpwCPGb;~<{o;9MYSxiscBwT@beW+ zql2eKy-Nih$~gLEGHfjJFSPmm4NPT%Z>Oz#fU;O|hln7gq}yFAMO<>4X_MSzKBTB6 zM&xLr<~;t|s&O{)?kqkJ%<{M_+)TzT^B!C^hgoqyybT}fR`a~JbBDX7f8uu z2F4P6(AYZs3W@lpx>a`fyq*p9a9j9}e&qc7zWv-iIEYW3=u02v}E6tV<3Hog2*`1H&3UE-B zV`bTL6g~+al;6zX?5@ujvD;>|_gCh4?&tNd8jQx3^CkF4_?C|p?U!pfbf#Htq{zy> zqF<6d$5cmKUqOE%_X_kpZU-NZ(o0w7crN4LdHndfN>8D9EfO4e-?AJ-x_!Kp#j}VF zhZFB(=Aj_F4oX4x-fyQ)icjWE$Hux6j#0v@*9m1Dd-UJl9!>Q5-AVnP?wUg!K5V<9 zQ{JXAlAb@OkYP&}`B&}>z6e+9dVgDW82(qW(Y~d0dgHjuzx|ob@a}Ie8^K=WmmQlD zUectz+Q}(#B!0yY194+}S27kpEZk(WnW|N;Toj`4(67@s5a9f?xxx=JkUnL$lKv+g zgSIq+*(Jm#{{WbNBH8fiR$s{LNyp)TuaLBHx;nbPC93krpX0gGPVvSe@+b0GYzsKR z+7l7UF78jb(g+r4GO~*h2V3i@P3s++BYir(UZj60}zSsvltJrvb<5QeLxr)QQ+i1$Uk_{$L%1LQK zDFWmJy(MW?kEmOy6{CX&?RfIk=l5<#IO{%o7O&IaVtCJKyJr`N;@@*B+b_8`OsOFt zy!*rzsHGqzT#p2b?#4Jgl1W7{zR;{LxyH$NSy~Qk9e)7R_b>& z#Dq4qDWxG^khLb(w%yv-54hKKA5>zbn_ilD_;2Ol&w1GUj~-OUy{4Ale!7gYzgXST z#_=IGmkXy%snp8eC&0Q8bhdBbXrr?=%sibwM|tyVJ%LVBZo|7InAY&wsDVC zz&=09CcoWPa>*FXbJ-MS24#5MijfXHlH&IjGIpf^?orUM@h{R3O5aZpke^eIo(CtN z+&FTJs=FRB_Q~`=w_Vo9a^5)BdLT;;tqDxHi&o~@Qjip;ij2!tb|e6d1s&QB>%xf~H|U@_>3X=uNK@Pel*Ns}zuSDKPZa z8>qEg9*OQ={3p5`L%H3!XSf_#n9-a*#&;4<=kc?W0dc1`{$Eg1R1;;SrDH`}u=477 z>W#asgHz2F3R?LE=EgyQd z@UI=*yLHO>T}sN6&NThHHTLyBk=eea;7^SnFC#EeSWzt5gY#~WIHYlYE0ZBK#(zK}}<7*NUN4YdL_cwzwwmFsU19(0L!Fw7d~cyHVIO-QS0YG z7AI_entPqh3vaOu;_+)E{{H|X3rHic>7dz4)2D~VnMJax+ZdO>8~SGLX9UGJlgZnZ zWzYIv@knQPno-aXj;G^RbYWzw4tC26L`U}rxxAJf#72OmKy9Y%rWru?{ar17qZFQ8+gxok4zI#^U!UkGVCL(%&b=BqMf-`NqO`Y*&)TyHEFDZLpV8IQ;%6 z_S4g6`5gPoIKzo?ZLI~j+9ftnAc75wR1TwBvM&cR+WL?#SaFAJeI+KWFl@=JE=Y?4 ze$h(Nd?p)lE=2q}NO84V#A)D1l>^IC;p1F}9OwyKR!XhvPm!YrX)Fllp*r)WX*UL| zltjosl8)k4w2Fj*4Aj5^;^5Tebc76(?g8UK#9L9R98I4zbj(E_f|1rbw*&Z?m8^{_ zepx>_n#S?e5(o zD4UaW^;{rdr7{Na5W>S_q5!3&DPC&Uog$|)UKT(yeCDxP1*eZ;CuN%g1kf#L^^ zJS1l1(Vb8xl{mw}Nj6eVTe;6q3@hUq^r;~WHc9Fa56{{YQcs_n^qPbONp3wbiBIDYQ;8z^T^a#l#bZmF3CtTk^i6>^|FG(T-$XC|IH z$K;Pe!R+^4{{V*^FE^qr&fNVa!*ytTB8PLY4XRRY?ZiMT3A(%p1o)L#F3#t5x>T^d z{{V^VDC}HbGV0_@sri2oAH2A692U;C)9xa$y5Svd zmS2)O(Z1QG9yAnV{ZiBLUvJuJJKf}Y2BGo%M$pC5+i{V(&8oG7%N9Le;V-TlE@>0%&;sE>Wt;Oszdf4&k zk15>#x`Z8;A{n~@c@vH0yb%BGP!tW$R^7`_Ow!4 z-=1}=BhvTqH`<+V=0k4~KP$$wn4hVf7Z}7gwz&i>%Ntr)+hW>xxNmC&sR3TC0)ndo z<4IQ}mZpgFBlBY?@U8y+&c@8l_HeJcJuX9x!%KcjoVrlb8&379OCFGvfJry1CmF?R znXaBiN?lQsD@^Bgcs?_VPR&FtW+AlTCAJoot!`Sw^nnUG4;xlAr1OMmv$#_Q)aUqa zR$adD?|O52nb@pGdkw&lr<|VjsZ1qKsQ?m`f7~Rb*(Tdc?Qg<7YU+6tgmGRMn`Z6@ zBePvpr^`~EyG9zuDn1W6FYeU+O7Se`1TV~z{M@D;(~OqtT0%tEnn?cuxoEfO32=I> z0I~eGu8;oXTp+ssFC)j<#QB!X2*1OvbFS{Qo{3?8r$dXuRY^}dk~t%|{{T<1p>}hRaxN&!Gjo}gG1=(>{f)Hx z$Usw#yfklk(1Z9^Gzt~h<8$h%N=bXZ&3%PDwRa**u1(AGEspr`Tq`*42h5mdE%97p zc4U}sDSftIaJIHk>9JR|9ZQY%9;Itypbi;x?1c_hEcHJh09;s3-kUVXk$!gbDaW~g z7-K1qAVY4=Dg$T@A~L|ZK|(;%-+=TZ>^9rP@W#VW}XqlGCA%3BAt9aZ?LQN=h3WiZ>e#$xlJ? zHB|15R(Hpcu1Oo>@~V*HkQ&&~D)yF(>?sDq_W*)^&-_xW+}qPnF=H%`ihvh70a^+i)k}Jvcvpz@y+JqRNRcH{B)GXU z95-99D6MKg5_PC8Jq`G%?fZJrMo)L7ei5&kpp(?4N>Cb=EZHDxNj?A#O#+t3YCewp zz06SD=`nxW_(fQm`BapxN%L)u6itqst$zw-2FfSMiqUGzXSG~2>6?f0kL9g2=Og4X zZk1&6$g^pAKb59P8+GZRH8sjDwd8B$_U=R}R!OWs1>_~&4(0MD`S;7E;$b$HR3a!P zOdwq+b7}my7V#FWmd;Ae4?)^EbW4YsEp^w&_=k<+;=tnx$h{dE8FRo=(BQIA73v8Z zk)^G3e>&*n2=cb_9IV24NT_?Ekx%obM0*^VC`Q*>2vWfTV)p{%YvXUWx%W$4VD){b zG5LLcP3Lib*UrZW07l1<4ZlHYCet>^{TU4-)cX>&@8`xvt4%so5OpMk!k8dFu z{{Y`GfupGdN1L}(ZolF+(0Rzq9>bq`2Om3%k}R?N#WY!6u+F3-NO6}h(2B6hu|I~% zbOh2gT^R=)LzF)a^pva8bWrmZAtjQ>g_vesbhv|Xp;3Z{gmMhF;z{xIrIbND5OYzm znyn(tkxEec)cIWh0A)S|$h3GjBJ}+u^^$PlAX?(1q@J=;BzDj!z;%)gzLbwhqXE=8 zX>uIUXbmG|bq^yzNg%A=sg%WXBp8gqPTLBl*hf&B66^_K*8c$0Cr~Q*Pa~(0mLgin zG?k?F8rG?jjpRc$oZwnZ7F%D1>Gn&h`2mR1`etUdWY!||n)EQkukiIC)t zE_5~ogXmCDAf$o~$AS2C(zD5Ay*v*kBOS{iy@1H2ES0HF<0Kx8Jgt4Qe}PB#8mdsx z(N(T2qIs_o$YHXt!I;ry))Y{rsCbH@tQ}a%Nfoax zFDqga9JgaXxOC{D<|&%VniJ_^uN}=H_EOnZ&AkWAd3~a&luor4_nV!=mlhp9hh zg>9-A-=r27;Bomj@VHr>(#)Tpug^u{sC~qKnc*^#Gn2|P3P$zDj!IFWxe8a}R)fOT z*W-35t!#Nbr*it<$$PwY(!Ac`z9v=&84VElraiZkqy;kMbb!J2B`Q%`bT;*F0Pncf zKBV8fRWPk$D+h<<^DVwzR!PbFlXwL3)Ju@8tC80g;M(H0%1B#Ex9TBBqJ{qe3G3(A zOH8D$<(`@kGe8&zo~D33pa$rN2{JwA+DUfAZ?Mo4asm5%sxVGoG2nWcaaSO*?xjy8 z0;bYM#qVqVwlz5nJZHe=@9F{cj^`xDx!nF1!rSF|bfx^PXk?+;Y_Vk~QzaHqkjBtK z8kCI=9HnvvSS{eZEY`mK-DLy`~o;Ab6i}YnJ0=V86 z&O3#ieH>NXWEJ3BLyx_Ym-0=?YC?)iQlJ*3fUQ%d!M>*C9=9KdU09W|Z>wFuQtII6 z9ri3f&TuXr!ucayZ7{3aQ=JS`MgJwvSnkkDbad+j65|%?4QcCD^Nu@O2!7R#|dQ| zYuV1^bC0C{`b+KSI(5k%yv{x!GQw0^Xe@*`mW(y@*aXXHYo_7qNDfq=OT#)=!Ezzh z9sb%K-wtd^aN3m>)Jcsc33Zp6P+M*`vAHWklW;)>;EKHEU}4HQ+04a6Wz3NZI91+m zDuO-ak!^}qw~sNkLs|g$AII6nxQop5q zryS*Ht2)Q|lEcyCXRok$<39F&;bcOI9?!nvb=Ja?9dP=#EZ=Fhu0Gny#_d(rHDsHd z6OKEv#iP42?USmKKTldYa5rvruES7Sm?O-$C1JY6!nkT^nobjx&OZM<_}@ zCL}cc?AMd-GTOb@ltXQV-*S{jfg{BDUs|TFGK2 zwyu#A8bM_$@>|-E{I~mR=QOrARm7aV5y(C4`r_}WaZ9lmJN>zWcH{YWFqXoSd>mc( zEAJ=aRk^lwYU08ktfz=loGvJr9a*}TvQ(uL;z`ufnoYgCYNKz5jRa)(cp4yE;(E|Y zvrW46gfh}p^Y17jwwp;>)}x>aN^VJ@QrY1jNPON_F&XZ2GB<8G(Hs6_E=SHfjS2Q+ z1G@hJ^M1;@t~}=SMmzb{*Wz@yVEZZ9JWl}s0Cx7?D;(b{!CDnNCF_&!HKNdzr~ul> zP>_+hebsH8c~tP$rb_ur_wP#!(2UG|L&N@dS<66rQ<2^IM-DS_TzzZ;k!^=x!Z%eB zy>(#pANw5RO0h|5vX`16Id>D|JgbmF&0*B*($s~AEXiRi*i&NXxDr7JrlU*KTNL#Y zi=_y-&FEJ=`y)3U$zO78M;7+Pu=8q4x2YhI6qP3T)5L-eWsH|re0@&MeNd$+=1}vF zxciGsf_FOx?;m659FodF3HGE%D6jxnCd7?Ft+BNpcag%MQ@|_FIG$@ckeikfUQ-T| zVeLWO8|o~Oq=BdLe#*~mI-YQJIDEMA(B@gTms(xgqCrEjX>w-AQb;tA7Ep zAf%0HdU{Z{-nkZZ=Lp*+&ogczGa3bk8C`+ecB{=Qzfo?q^~t@=e6BPh@Vxngy~5z^ zPsa{Ji)6PNMa-4}{{TtP5}!1a{{S9WVCQvV;Hq2 zWTiry62k<AZMRmxqPC}AJiEURXSD60* z8on~g$hxNnH^gLD74QkN3BCM}okW&Gt2$V9gvzEvK;QKf*W>Z5@<(E;GIaOR2XS~* zu1e1o<{zqGAvkAWU+Hi0j^H{Q{!9Ipllux~XH#088#~u3x;|Vbgufre?thS6Y*JB# zX@-<65|xW2C#IWi(z;NBio!gtw@$~IJh8kEB>Rqg`FULA00m#}Y0}9dxrqluFx=-Q#rhqcT^Bv#WKpvGQ z#^+BO0AU9Qhlwr8F_{8G*WTxy_3KKYlgdStx^jw(c}rp1U2SVA_X3ojsY&TfR&h7h zZ_~#q?Kf~^_q(;KRw^Sh#JP>dPp2I*!ctt=EDUJ@MGhnI`ieA4z^Z2)Jfo+^xmg~G z9SijT0N<`P-TvFN$?<_O^Dy?tswKTLSq@Y!M9evnOqdvj*jw)5gaP2#nDBAvFaQEgq zNE@!=?m$r&*gZGs1$qO)WVLq+0QY))=mNF+p89m-UEl5FxOsabXCQ@0!esW{QRG|j ztHidy!nFBo)KbbhE~4jLv*2^T(LdCGBki9wUtxQu7mRK+uaUq?l&?%FD_5ohmUJ=R zBp9pcl^<{LsR>1JmNaJ0O)6`yCuwg_om_KIH_!uIw7fJ(rgllzV#bMeszjBgv^F{t zRH6VB0@UZ;_kU6j&~XoY9mSHaVVZ8}9>viSweZ=~0Ti|NBSdp@>9Hpz#9EaWi z0INRx_fI4sR9Cs#DV~;T;O-g=;^XA9lOw)45!g zNR^nk8pf{5P*&GwC@ZDq;WE8O0e9u=^pE3$q z#(c(5Va=UAxG-3Dbmww+#GLmGdZ7{=Bmi5e2ch*Wf1FENby1)0^oGg zyR^|xJ!^E-TQ zhCEiqynb7*UWK3a0ovc0_PeRu$G5}Dggu#NIXe{FiUD%Aj{*Mxte*lmTk%(g5)g|GbKLPJ(c_5Q4Lzd#6 zODZL>rQX8801~ecv!~x$DV8vEyW7_>@ehQlkmMKFHEuQzh)@9`9sqPA-+!0ce_jtY zjQ9gw&nLw5F_#tf519N-Jc|V(X}K0r{==mrvO5}=3h1u9Y;D3gRu*0jr(cu&0Y^Ky z#M!%&5}{-zKSa;V(nATmN=2`6ZiIOeRvDVXN%u#$ zUm+<^#!l#NleXIIKf-^ylLe8MO2;jSQ%fWZ3S`Qs5u|l3wbY84Ig7{so{l+Mv2)1e~tG$@Wmrld4&_{N~qLc!wCFj?mtQHJ`g zMu{f2*D_}uk7Ytqfm%r+Ri#BUJ0PaGrXSL**bvhq>K|`iN0*fm21#*#MD{rWBI-cX zQ{hn9D1`BOiXTUyUC$$OKX$c5q*|g&#>~2{s6rB4uqr2Z&oVaw{i2tso{~waEjb?U zq#;(+5(xW^MneFPDaRQZ2G@;jnP^y0b+Kz(%+#q2R{sD|eS*j<6aMRi6t(UPlNj6eclW;*D2t6u>uyrFP zBz*ehij$4WvfSK!_Lm+^ zSChH78gV5mLc!_?H8>SKJfnmAiNty5(pS_BZd=8W?n{Gal%|s%#Sqk}YF6iQvQ?-{ zt^Ot*J~mdP+-%U(gF3L1K<2zz@8%dh+kWJA5oI#qB`aa%-0g7- z1q(^&phYv=CpK_#czc7~qmR4E;H?=4mjz`i3`$Ch9B7gGK(Qd$Tz`FHlcCY3iPSowxEhW_?*z0mC zp3}zpP-;>4v-tTMJC7&kNjSYQO7>U!O7ncX%unu)bNM_57FNzD5TfLgJUz(^9*f$_ zLKE=|uC!pH@{!Jz+gN8w=RTNo*!+rRaU7sSC{ENOT9${93U;V_s01hwNU;M>x34>Y zVw#^-GRLFv`_G{8ezmGps`+)fHT==T&OGAwe#h)cl~?ru?$WyuhbwX`=B zw9pClElOF|$^Dh1w{~|#{$$=|;9>fM>ebDszPBjqyA230;Y2isFm7YHU}C(^Y3 zH&g2uP;$`;_%ZoBY(A*$&wJVZPJ4ZWFJpKNMRJ^yE{~mh?ZZLy9TcJaKFTF$kX6Bx z)><5u-LI(b^7kfUoaFhJmk^R$$HgV6=m)?d79BeI)lN;F3h9J4K<@ye}h14_hXJjjKt#wIw5y+h3TX0#D@H@;B#~O6virUDpW2mPvSpyx(_Poal2ji@BUnV-*3an+s5rS*{k;vKytqE z_n*1hwBndlxvof8=;83~sa;QsTOYKV?{Rx=G<+*B&7JN)0-id`TKTZA5%iag<1kT} z?^h&^!6B#z6M}}cO3XejaFUQpTPE6G_13SCDY7o-#ye_EL;8l}Jb5VNeTCx9;N)Z$ zA|p95znjZTQuG^Cuu5;&{JwSE<94`XGG_;q+-#G;ha2s;bRX{CGbh}5FY?x$eM^?i z$5SZ_D{WyrlG4^L6>B8;*4Jfms$VW^DShTHnK`bwycQ-Sw-^jQc1)ai&0y!|8AywR z*r^36bbH^VQ+EIs1YE1`wW|%ByLlCKwVt2m+wt%;MwnG*Q^tG(ekH^+#uM>mN=A1U zwe6XXleyMXyL4Ml*-bbB(P`ST;Ht+N&beh}GeneTu=PM6bvtZ0-cc)zm8%&v6~-=V zq!IX!(l2{#U*sd~ zw@dhI=#rM3A42V1-ZHKH$mV~JQBSwQd9>a^@}eP;^6CNkD^d1V4yMYz)%O~Il$shm z?~yFUygv^wXluu@6F7D{XS*0oM$;rqWjmJM(Pbgj^{^W5Nb|i%%V}Vvm&}hMN$u!C zFP3tQ^NI`s><~`nkPro~I@tY|7pkKfWZOUOV_uuHe&2B1g8I_Om}mnqtl&HV{u*~j=}q?V3O>EcS$-Q8(XH8d{z!cvvYYJ+F{Zm zH40sxZ$}ZXm8zRZM7|3=Bu4g}Kd6yodg)g(s~|U@j7r`vYpq?9q#(`}*PH+iDC)sD z98TkIHxTX8!>FpIA<`po>`pRDE^L#fzwoR)jz>Y%;P4&HEyWCi7KABE0bMWu0F7ja zGcQx6cV=;pR;7u?`*SK=NpeESLcA-Z1(VNBVc;{u@H`wVA89IB{K^+KYDHNeXSm)s zBZ_t#&85bjK|+$C2q23PMK%di!NT8EzfaP*e;{&HHq@+4wJA)h*VuZN)%JLNDw#(I zR*Slk&%CFPCQ~GY+2-%G`TPwLmIIMbTJ-^>GUG0kkWxYMtBzAxWbYZysS62Fxf(2a zk3Y7noK3uY%OAJg>o>-^6g=h{N}|qy;$C6o9}(0jc%?%{4-r*tZ<10+(m$sj{{Ue7 znZg;#M=4_=93`BLJKan_ZF>GybxH9Rd}Wkz?y14xHO=KS%|6_GY&6I(Axim|S7zH# z=oFEu>#n^zZa$h~kxVRX(^3~Ee7|%)E+Yhut@Jhob+Nd=h_&_BfFHj-rkPvL5YtU0 zt!r7(B_ibg!k7lw&P9oxIryxst@vaILXtq&rH@XQHvSTobW%wGf9{|UDgf8t2k?vh zd?*7h58^lYPzR3^rixInZAYTKr~$4n7>1Ps^OD?IB&oxGruO@(BCs^&)boVBgimz4 zYsI^R!RK*qM#z61l5C_D+uUK%t8cWTG+GXz{l?&tQr1bXZVxEpuGn*aZ}hX?>AV-4 zdy_kT$Q?_P*4k92%S-(>a}f|OcO@wZeF^m`DYvO@p*2ePUK!G|F}@v9-F>ijHXDIr z@(FJuyok!8NflJfSAC^VC6aHnH!MoywD44{P}v0xGhQDNa%w}qA{)Mhd9-3>6&a3CZs z>J|cxv2}fMZld=G%Byzy8>-;9 ztd2eAT(>>TIZi{7XIw;_u4&^YTH8QE6tV!m(WgKvm#NW=R8|ojhQ+LrU_7)GV4Rz6 zKiFs zXSbY}!gRN9dr#VoCl;T@xMUNd&8D z`0Teo;eFAYh~_e1%H+2h5wee|OHA17QQG@uS_|}2N8whL*W= zT}-%f7BJ%FsfP+&hvt@rhuf%9Vq%6*lQa{^=A+tD<|z$0TTX=@;8m88eMtnHcxza> z5=u@me&%#E(-(y)FMGs}?&cmQe}c?QAuE#=CHC!O>uUOod5eQh!@K2LrS`ybE9-+t zEM;XK=H8#Sy=9Y097sX7T0c)6>55tZ0A+H8B2Fq-=|OT$l#~^J=sCOcllV`8)9mwH z`c$7%J3L!lbPl=B75rO`rY_bo?~sjiP0h~49TTsDY$&jB86Wua-k`X3N{#W5+A z&nx3DMUb>9I(Q!fDN8euPFyuMvrJacBRo*510=i*fk_(BF)*Cr`9%xsr}oncf%JN% zlY&YUl#L3>SgvR(8UgcGAX4BH6-zs)=`W0jQJ4VJs1K4tJ;2jSo`4oo+_t8wnk6Ad zh$C9ZI>?eRt7@%Otr=L0tUDd?C7lKRLbugCjkrmM_9w>+{KKfNk&#TJf=P%3dRj)e zwe3>KM4EWS=}c@1)mnX&jSPnoJ5ILP_Y!|otzqPG+|JK#=PF*KxI8ByWTW38HiOsU zSmVQ!dYzj)wQ4ULhw(Ek#EO<$NpWZZSvA;#!aRl3>Xt?E^D}Qt3vi{DQmbq_l@B}k zRfS;&@w8AVCEZTnVYy!$k&c?!aSxz?ZK_q^q@OWR)=Mj!i#P+lou|ui?oRv(NIL;4 zX}~O%pq&&dmauiJu}KvdE#tvyRF;RRelR?|>ER6QxDjE&jlFzmWFln@7yRQk;yU8lMcCCPM`3lm21VC&1E0;J(__ z;K+Q;G^X;AP|PJ~v3@^R-E7ltdAd_4l)8GG=>n6 z5|Drr0!KuEIsxD)0dTaPPpHra-tYs;fHg9QM2*MyPzRgI{6^!*bf5&XDU|Frw-wPD z&B-E~T8(6sq}o_tZ@1}% zpabLr9v34Ckt0?gBUCJneWxq}$Jnl-qEX5oi=A@xIrHeJ>Nh*v zeq!%rdzJ2E<04^)g??GL^7)Hj{^YeC3lFH>g7+Af8s+ek|qGhZf^HP;ifec@J| z<2~U(4WEY7q#&zoZHjGizyS&eq0>-BbNQXW`@|$dv5{(XXu6yq|w$@c` z6{4H)N|V#3hME-3ytj|sR-*SJx!-j=VcYyl=JHIOTuUfOA-7xw#RT7ILw$Y&OIC=& zFh$kW<)TL}cc1#7Pm%9qyJwB|Th#+GlNyoyO|||v_!@_2k zl;vdRr8swg+$}}4`E5n*rB>T!=*2~7h@`ei&{z-IP&w_8I{J_9pbrYvN01+~fF*c0 zZ~50W%BLN~@ltb=RIQ3sbRT60{O+Gf`!9NwvLxoBvfd7l?U(fN!{h#2A>Ew7yY3|j z!Qx7SO4X`R^TS_PLHK=EPNacN(w62cIiJvuis7(0e-y>16~i$xc>Xz|w(K^aae7;F zmuuYB=_Fv3+_h|yU(2mU#}r*z)Tu<=-|g0{MN%6`T7uH!M`O(>DGN!l1avgTZINB; z?GGI97jM;$ow6Sz#sxi%oD=G0>v;Hcfx-1Sa#^1+d4n4vhXrXCC$hk^^9SA)S!m&4#N=GU499+n}hFn5| zkkiWuxay6^X&(z$ZE`xIj2|luZ;ipqQ-M|@#`R2|OA*k0rsn?u&M*Uy=N0csZ64b% zIn~qwYa9MxKWMIf^y5@&s>6Jj8O{uXqQ`7D%6dFHDL!?Dr;}ou-1Kp&aogJz7v!qj z-Cg#IF@RFYrc;PHE(%M^2$GR;ZBu^{;iXZ1J!sp)<~n7c0tL=3nigeh9@2CNb@Z%@ zjXjR6yNz3|$!M*$0uov(>F45Wp;S6n4i6^pnI^__FEhe3C8Y~`g~&Aord8SON}6>^BE(QR0`nybphI>fDJFm%iHF)E^u&gZ04kA( zan)r|DpK2XrBba~z|SPCNYPnH39z+WlD5Yz z&tWUD7wNCtOY;!99XXX{v|VZm1J13;$phS@x_n~~9ZpP=+eriSC<=zhj2k(t>NlU@ zIr}3Wg~z)(YiqkQlACSUPzO>7s^s!+rVbmN-N?A~{Cu|~OKD8H*(q8U2q5_oX$^Ty z0_7Zhu;F>3`bzL0l=*#?bY+v9$fu>{5b)%=8STTTLOjJYMtDo5hJ1T4ms?5-u5IW( zW6SQUB@?Snxko|$A$?0q?e``a%%iGb7|S@3B_xs~I&=~eJiHbMhQ1XrmIdTf*0Q%d z;~AHYIwNvpsV*||LeSy}P*PMb2qQuWtp_Qr4QKNR49hUsLz3rNL^OmGVn2wRTl_WY zK?6Y#m1SbA&XN434iHkzdo4jA-pVQ(+!79y0XGc$FC?Y zLB6Ut_;^qT-s(W|pbRn-&}wJ{&E)kuc?tk;lye{s!Je# zrTtDId!C{lAcV7^+^RZ#<+0KJ=&MX-d!m2?d!_XQ+MeFPRGv+iVk3zMY*Z*M^^y5f z*w+653P&V|uBlICa;JHJsYf=<`?&t!!5A1Sx<8rB^+-_ZbR+WlgQZsN@;BGQOXAe$ z9!1DG4gamyy^ zHc0c(PyrWh`$gQ&f00Z+C5V3_6l|$#Np30y>{O=+u>;3#>J(cNc19bsrMp@EJ@`Hy zO-}AsOy}o<75twbcE&=rJ6upVRgamm@~c&TW-B?Z{5luDF<5Rtjz%ktW8&a(?Ia-# z!a`7OeF0Fhr$#w8^?H%{kf|_VW=i(ACABo7p>lT%Tzp4bB^4ysn3=&93ne2R37CdT zr%2kAsY=yfgadQ-k18vJipFvymRYdn^S3Fc(1kjk3t)n)9}t_|{nYMBZtyau#=5#* z2kFhoOKqvfy}+;y+dD|PwwKU>Q|W!uClJ|pa=%3|ua2Y#Tt zJBaQ_8%}==(hZd4d6~Ow1$vU*6emXO&xH#;gs}-&< zL4ICJb1&T7CNmXCn}6h6Orn*%lz_D-Ku?`>rHtrmj>nG%k~9DcL9#_3q5G{$PDV~L+EiAeR0jEWYj~NyeGQ`C_&23alMyNv~(W8e|ZyK+0q_9n6aOkkTPeGP) zCtyNhur#JnDQx#MhGJYoEvOnAd;)kPIM!}PCnNH&lkJmXdXzg^ENo_7r&CLHq?S@It5W|8|0nvzg) z{nbOhCb-omv_M?`^5+)+0LtQ9Mk*=OWKm_2{$~!qveiYLjSVz#eoJ`b*IrE z)bgUOo(agLA7R6@4JFln5`X+MiSR%Af3wP-67VweY0tclvT9pvKI%ZZ7Ao<#m0WYi zGdW~Hl{X9i{#Z(i8Er$)0RsSnEwFh2LbnS^Wi>; z*>>RiU19VnDLEEE2lEfr7XJV-1Qk^?kBT?(ugd6#hF)3UoU4q;qW3UlK9jQijM(osgcn*(ncXXF6`VGS;VDKYEF`-AHO$Y-$@PQ=s!S z228pKLAd#v117FGke$m_hsQxc1^uz?FLpbDDJ}85OR9=U-;kCIF^~_A~jHLSI>9L*LIqjl4 z2e%Ve(`v`Z!?TIQ1OUn-HV}lAi)~l&f;@Wv0CIMY<;djDU2w#FAD5w)_$A|(G3EHz z@oxTtNrfR-ZFjjsx|AsO`#i;Z3>mUPrcxBEZXoJD>JT2JiV zQ>0fWR4~4x;ZNl5MToYskQjYTHzG@FaJ;tHw5$~Cr}ueQTlo$fESq@TMLpgGGrWhA zV>v8G;>>Px5Tc!{K~z_MVMq8BH`jZ z@;*2roPdt=vrym5!Y&6wT(W}FmHM>wTV26A3#ahcM}-;I`epFFzjxb12R5ZB{K&05 zMLAARDy1S$5w{~Q4&^z;X5u{wco z{guMzTk@dfwP$m-ahD?K!dfO1$m8-e*q2v9=L)upS(#Dwh@Ae(9XtIkH-rAk$L$sl>Y$BtUBCx6jai8YoP1*Ub?&}ES16*1zph8b*GC~YArA8@XQP7tc(CfZbrHIpD(fFg1sm9Kh|l`S{1Bc)d? z<3dpxDbduQx~WySs~f0^$Ye+)4JzRXS@{3~+^&@=1_A8HA&$yT)CDp_Bnjp@D%~VE z)6Se^hzU)z7pv>7S-H{UUmBOF`-Sq{#5{{~W0fUsC@lpV>MGY# zgUT$Gv9&bNTih-r#%~HaPBDYR zD1DU_DI_Qqn-r)Uf(YnA=~T6YqZuh9xIU5or4!6>BLkaxBa!190If#GQz_6oKg>ET zef4Z5lby(?rR8j0QIQ3uDaIOYwJfP>T0jJqYNOM~#;h|4qLVErGQ`;CDN_RIRm+mgt~C`=|nN&+r$WOo~GJatGeCPsh-5V6$o4d8oT}ts- z^+Cp7&Sa+#X_SG~jn=syU21WrUWlf5#s@?8)9DYhd^t_b&Xsdq>vmO_bi{3coW$h0?X>IeC)-)I?vy9>2)Np-B<OH5xRdwP#J*1E?ddZI2=irJOgi@hRzG7Gnu37b#4-y~sB$I0d(( z&+Q%}uM`|ie1nKvh-|pbU>5SyeMlGlM0K^rSW?QPy8WHQJ;gF|cz{+Lktclk-olER zaY?(2X-FiCF6!HF!mC?NDydT!xqLYjkBLCY`h(^Y_*$@1Ww{na$Cz&->LawZIKz8( zxDMoc#?k3FN~{z%sFf5|q+L6lwedO+iQ(e#?5`YlTd}8MGKy)bIXJF4u`(QQ^jruk z*rcp&+OVQOE~9BR*-WyYc4mjn>x+&zMbPdtVj@|jHu6sp+6ahRrz~ZFJr{pNM%A;ZpMwYF2Cf}7`y0>xe&X01NYsRR8#CFFsm}O1uEU@ZSg*ZS0$^;&w-3?o1 zv5w+G4T^Tt=--0ziD{oT*K-*J+@))~NJ%&RDM7#Qu0^p^O+A^?qS;p^D7-WhPVD;$ zc>5C6mQ;TN(g_0hwZRwZT$y&oogRm$uj)y3`_WC3_$*c{kHsvut?sB59X)E=FJK42 zbgjI8JZe}+7oE?aCRvfYxeSc4cK-nFT0In@brIpA>DT+KNzXTo>R4yn3sUW^)Nj}O zsf7`fJP#TGi<^)ZI@F9q?;O^{58N%u7Oi zXvmF@8_EIWQII!tIE1Fu=( z+_m)cHAL$yjEM-G+|87x{lR9<(_?LIRZ18hFCzKL7?~KAs!H1uP%eiChwrMKbFq9T z;#HY{eojosx>Sw(LV@(!{cBxuQAA3|CR!b~;z5X88TKDiz&3dxr673gSa}v@n`nc^ zUcrmXhk}S+U$Zf}2`s$JNC7S&k5Y8&r^2YA$`V*M%B5^tmY$_q-5vzg7mW#vjQkS>OZtL3J zE;Xhr6v*;yY$5*uaPSN08%^#{QJ~g<84RZ+$m~>5G0{{mqVi7ik`z5YL=Zg3$M}FI zBg%EQ5QkhZIFJIDZM%r^u<1Y>{L+t8VL%>2#7CT24x(Pl#~ zc!Q`Q_$ed;k~$H3mW7O*UQxjv_w2T3w*1x1RD!8kxm%ybPq(G^FVLQWXy~;4{RlNo zql2wgs%s<8)crK~C!I%cAr+)zuq)K%CmoFxgJN6iSJK{)X=Kz^Tf!oD#yWVH?{2=F z`zylKi4L%NhH1MWnw*MeR4HR0+MU<5R>PT8vji=N_ zleIg09G>xAdPClSkddwX3CA*6Q30hlC2^xE1rA2sw;n3oRH9U(r6`hmtL^w!PFF6w zqNeAFwXA$|_S^CF2*sz24PNC>qB>ZBff1I*)U8%iyH&4Vg5ZAY=g*%g#YUylmyYt+ z^!@{=EamDlRN@`^f~5zLqJ7m8RtVH9cB0o6jkcd&URRHgwk+#x}>tK6h}ktE>Jf~ zN!}X@9viN0V`6%WnQRGblJVkM{zTMd2Xaj*h{{TKr*LefB;Lh9+>aF6-{z`xMcpmz z8NkRpHSe0#wno$wlwuM2`AH7Ag`h@^E|9XXU)yUDZ@=OVET*Ee z!D=HCBzVadDtW**mt0omTd!00RHu+MlQ9VwQm=0T(uVLWV;6G%q5!gbUZG1YjErYx z(2z-0S~xMtdCoc-331R5fWD{f6$Ge&dG6%QlA?&WLQb2HS_V-enqwt7&F&IG{K_>c z6Pyl_jf}{;zfoVhtWXuPIS$xZXg(D90yrTwl0UQ5R8F;> zR8o?3dZS%1^{~N$@nO;JU~utR1(+dA<{sadvW8*UPZ-4P7fi+O*tQ zgKbizojwMxPbV@_ad>0AZZ8`MT>(!xRlK{yL&ePts+0zo9) z+xtxbW+#xxoWXUJxY|-}XHrm3m%Wev&~!F50N~F9#(+He)t?=s_s|ETP#+WLKpvU4 z7besJug=`u4SdZ2Hgi7>5|YA{rMj&^v9_IU;B8TroCizBdy01}ONsLy3QvgpjSXaK>~MKUId&tv6Z>V%C-&Q#I+4cSmbOdbdz;5gQor|v zE5V0Ni=GKSy+2a=_mI)Fvu5W(2(sY2NEW_~SB10>wZ6R9~3FO>U95 zhtp-yjI>Rp%`owCvi-%(neyedm2Dv1Lf7>5zt{!-73HFpjk!qrU6OowsMQTV+y3yM zv{`uvF1QbW+_09)(4uaX6p%FdA1di~+ozWX@{c|B7Y?NbY*rUgpoPr3&0ZsT>jUfpd#9xiXjfE&FtPPD8B4!kdQt9jSpEPM#*S(hI#GI`(d z_7*w$3@79r2WmAz(A%i1T5CnIQ^_47ViF3RR<^PIwJIK9kUPlv?jst}_gzXz=#kX@ zfK#P`)Jo@*cXD*KDY$oO2TjLSe}JbgP{25qWal_tc}HrsD{$%i>M#yT6BvAUF(55U z4=c~YokXSDNXb%CpGV>NRgnb7PdiLV%1g-|O#m@?B}&{X0M~w$xfIcEiZTLD8URag zs(>9d-DkmbW5~$0GDU5Y5rr^}eATT`Nx34_0FjZf^{E(LoSnRC0C1eh9yE-c9xpbt zpfrt)kb{%lQS~cIs!|;xKb=VU)iRjr2tPf?SFtA5o>mT`DAY#EZlkSbovg7$@z^bR z8&WG+-6n}j0!kLEgQZ|^$-h$C+((iLqcqv!sJrpsauC} zPM~~iHIO=-dxHEPYGjrB1qwyQldv7yd0MkNux@uR5bus-;Y5rENnzKNH@4EX7uMZv zV|tZJ+{te(y&?{BEJWEe6zgb2LWO%tP`C?704Gt>iB_3!7ntjMj#Gg-jx;ejRUw(} zD5o5^O`HlnSzY`U`D;ZM{{Sl}=A|ih$L}iK?iNfbjz*Az+l?rpNl?@gp%tvfoPrtL zH?rrr*!?wru4h>^O7}Bzb=y!&)NnE!FieQ>=fQeC{l&6oA=%z0AIis{?Sj zP`$yc%nWZA8xaT}G_y6}cl(a&Zc0hFkR>TL>2Z5rpn>d+%vk8$^QmPgrsHCM$^egN zntS;#mWLg3S{C0V8z5_CbsCYO7VGCg62~Bs)X)c?K2Jko=4b;1!F!W)@t_Y?kV;ZX zRe;o!&`+f>Gl+% zsc4gOFVHJ>uhd(nhrz^m)S-7g&u@403VxeA$n3bt?awN7vyy>!a1!L)EA+*T7k6qD zfIm;oBX3lvef4#_Gw5k^*|r zpcyrCcA6R*160fwwffX_fufxR+#6E5vPMrge1B~pC^BJMJXNRPOsYYV?h`bue6Mk% zy$aF91Nevdj|$ntz0o|ayik*mQYLc@Mx4-{9N%(ou%FBajl9Kr>aA0XYi44UNZ7c? zk#$`xT%_+!bXL69q8!mi- z2H$ma?CsUb=VQIc`h$^NdR`^%-|g)b#kIw_+EmnY?n+tOpr2c$?c4#i$kU~0qm2rd zh8|~dx03TW_YN13&SVi~pXJe3lX8V!>)-f>fLqJQTliLk0Hz^`5Qf$gR<&xkm8nv# zYm$6u0rQiz>p%^jo$;Us67r}(B%6J-04>UUlZD1MqWj4U9S{xG`zRejva{tq>B-Gf zn}9ur&YRETKjBM~)m{OSA2X3zdG!#3s+@F?KYcV}*f}I@SBr!_1LmC{omwCo(Ha?3 zvm-f~WlL>I4}PH4C{Bs{Dcx8qaudPk=QRGpqEa*<_*HL06mk||juY-%N~w&ESMOC4EJmo^eQP|+5#)RP#uHNR9_-(k` ze(ieR{{XtFxBMmiZ-wV!9{zu~{%SwBZ|2(v&3k`_*7WYayT7`(Ri2fd%u(M>imHFh z`wRDNvfAFQM9&!17Ju6J4%^!LRp&X5aX#+<08RGaPq*Pn%WB9?7k!g|$8Bv@o0d+a z`dj}1eE$HjQ~c8Z0Lyp(0PwGJ{_nHnd;UxQ3V4{W$5w@tKl#VY{{Y#0e)Y%tx3#=_ zQv^ER=wSyqqlF4+jai{8UWT`^FNkf%We6M zr)Rl+yRD`E7oY?%-|lNU{KsYeJ2qRc(Z1IFyT1+f^PmTEKbZRq_BQ+5Pq*%0ZtH2f z+S>F1&Yw}={{Yh8t@C@o+n@gcX1>c`^ZsjJ@ZZ-}%O=WxU)}|FZ~p+2zdS#m`@hZi zfBBdCUgn*C{{Z6kRrGwn=G>>1^Re#j=wDI4_cZ*UxAJxyK3d-0ygGkb_%cmB`SrNc_$9rO*vm@7P+@FcV+%EBbcZ?*96n0QJx2Hyt+H!lhsjQ}Y(rckZds z2G4#iH*eDWZ-4%c8URbfznkq|>-?{V?z_GpcUtXsp1psk_LNw8w=3lRzk1``y|-Uq@4c<3mXrYP zTdsHB*V6qc19bb^^!Qu*=mSSR>Huvc-?6m-0CzY2`||4kRkz#m*?so^0FNq$TMT%V zreFEr%`4|O``7h*x4*{JhJt5}{{XlCU&H6WFU)=${4Gx$6;CF)Kjyp7%>EC_xBWle zTj=RB%OLJ^`M2l)087JXPu*H1LfDRp^IquNd)}yIGC^N4?v0=7Th(f&WXB|yE9W-r v_fx2}mmcq0lsYv#X~s1@C}1G}0OG3H4PE?H5+|+dP#)`Qau5I6+)fc8 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-7.jpg b/themes/classic/assets/img/modules/leoblog/sample/b/b-blog-7.jpg deleted file mode 100644 index b805fa698bb7a4748425fcefe29356e6840f7240..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65725 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/b/index.php b/themes/classic/assets/img/modules/leoblog/sample/b/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/sample/b/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/sample/c/[themeforest]_Floral_banner.jpg b/themes/classic/assets/img/modules/leoblog/sample/c/[themeforest]_Floral_banner.jpg deleted file mode 100644 index 47c4d677f827331d7141b3ee018a15e73b64ebef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46252 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/c/category-1.jpg b/themes/classic/assets/img/modules/leoblog/sample/c/category-1.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 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%0A2Wn}<(%e%7uq4l2 zHQ_HMQJh{wQ)gJx3i#wRuJxm!p@UFpd>bER2d(7%`r`Lh12{T=`rOM27g>rx;bz_= z0RX#o%o|qgfGQm|5G#@{dBmwuiXFv&}o)FjjbG{%&YI$!8z zF*TIz{AVO8&*7C8I!`9)*h5L;`r-4A8f=}hK^tv}4p$?$CfyV27tR+RltbBctids|& z-Suo~Da**6n%qTuy+Q7;R`kWIt2|AH)*3E^f1#3$HMv!XTpEoG8|1Dc9eGji>B5F2XT3-OJ^W{}T+qNMk zvW40go)}<=RQjNFbGxd(nPk3@#~Bd}UvX6arJY2j%j`@k8_Nu>WDIkk)QOI}TagDc z6=@~rH<)x4yO`e(K#oi0aem0=V&*FEMb&zAZ?VMg_xuyBL01xW4m#)qW2Ag~;KwkBCqoT9g7L**5++mk?i$F4C-U?n* z8*}{6gJj1N%*c0#?8U09>?O}d1`WSLLkkK_ccS}SH6R&)LD&#Wx3M}i$qRr->zQWD zxHpo>+QzLd$w>swU7%Xq&u8APOPwsxcTb11TfSQS0Yvarg%_4sw4*N(7Q9|OMP6Z`K6F;=s~d`qncuC5QeRlZ{sBbs z`rJ&&y&`)+3%0Jb^}x9ECa4>>5<|nSI*w1}$!C!f?bDZx+?5B%FsKVDo&Mg@wkKDx z6;p^N4gg6RFl1miJTm;^m;Z=Ph^cb3%{t``sX2{WB&8h9YlW=ssSJ%X6c(lq5P)9q zXpFCM<8GNAh^zw;LieueJn;MjNQ`}Owq|l`D7`YkvmH{R#K}5!Q%7%Cpj&}>1hvVK zZiwS4K8dQpLK><-Lig~?3B3v|I%GH!&Z0SL+0@K2kwNVFy^|o^jMT_qdQ z1fI+fyjpD(8~hZl@~-7>J}H%9|EjfmoY9~<&zSb11P`F77@?&GIL4))KG@aazG^X3 z`y@Qd{3Ih+3N&3uGM>~uoP|hc9z?{55!b}CVa1%%ny!~J$E8KuxfSoNxJrZ@2?h8tzxZA56ayo zo_Y+7oX$BvomD;RdKk1Cps`5#FQPB?%U=5D_W5VC#crg?!_KQWj|T5`sdc9o?~%{6 zud<&H8DsTdEmoL)r|Qu4Fz`4)<4*QokFa zpR>$lj;{B>XgaL<8NF(_i&qM&Ktl@LGwXwp9j>4Wp_IhTOe!}strbsBDM~(R=W^BygzB(0H=3oqKsVV1+qgFPnRIBZPCYs95{{RTz$F z+T%PWbk2(Dsj&J_)-cDyYcb42j?P|R_=GHZl{~;})O>{jij;_|m4;G^nDN$yxR|g` z7P7ZSq0+;MeanXtHgu}E)Pk!v(7>A+zVuCYqQ+9|C%tevZP$rIq6vfyFoQPPe=kg#x zo5IC8cqp%fB8NZ!#heu6>=M3x?V%dLH9FYJyrWGU8M(FA#&HVX(f`-k_4PY+8jE1t z5Zo+-*NVkYl?KeR?!I6>Wqw)((w5I2KK5qtSqy~cp=PQ>>CoRvT1|xIk(jLVZSpv> zX)RiEn|$g<%dk%EOkN)Npueg>ih-mc02X6zXSzZDQt<(mg?K+yEOSZT1(Y_WOg1U> zGMd0k{`*Mf%-w!h3ET~0a;AiKHUQj~vJb^nG3E;LS)A1n88o{c-w-Kxlb@xWdv>kV z?U(zv>}SxAp-fIPAr7!mRf2H{&Mkv4y0$*ce1uc-tdcU3rPrNed$l;)lms%0tJ2}+ zYAR#D40OMO6y&EeSpacVoh)2$AqH`=sVp(~?Pw<~9;xM@mE9=pv`v%mP7ABPm}g#l zGB=g3y+U-C8Pod0u&Hn2y}y?cV`f@!vzL_U23Vei+;B{!+@{f%DK=w5QKb$37xxYd zZg0M$6d}v;K>S4THIU9omnVwjAs5gX%PVeeofOO(3S@$M@~gZKe6q0i4A@>r_*ilC zrRqKnK~~r0Qc5q!FqN6*kUhlb?{;v4n9Y%yp~LJ!FTtDEEIDaXdEPfjREXj+L+Xjh zo}w4Fd!mZz9AoA?G^{5kM%KC<$$PMofoed-mEk=lHF9E2&cGBqL&wmL=FpR3&LzWk7d z;`QGYhrXDnWpDs5RwXl|eKN$o^-ebzI+>N<9TOfqsW?&>X)|<1z;?+@_rY7TI8acK zx=!BvFW7Y{FzhWdEOxR*RhqcXYS9kFIlFuF zX`kyn89DD~<#VNI<%z8Nj)e)WjfsR3P!x_)kPvR9TN)|U z4N4(Ef(G&@jL+-4K8eU3k;qo^>>CaXO1ZsR#pfd1+T~~>mhEkiF~*pnA0RX%F!Zi81WDdz=E)S?0;AM&RE zbYe>YSernsfgoov>1KZ)RL}?6Sa~6*(*0NlJAKV|l2w<6xek;axS}v02Di*jb)!Nb zD;e-1;CkX1XGoFq()9H1n`S=YQXEXEPQ)89|I3(;+MJ=T#t~hI`vn?x^I!=Q?w&Sp zE)}I9dq_+bk9+X3DOem6WEiPmgSHD*2&2;B*+$JxdWmcRZ}vt7MR2SHNI0-Eb7mcZ zhJvHlitXJl49yYFFdHX;bMPfG{7)!$e33Y*VeP5{gT`$E*ttrE34o7~kV#2s_dtnB zo{{2ZRv~R8CLr2CL3b5JohK0huBPS6EfipUT7o%mplx=e#;4b^(XEd#io!2TOKwP? zzEvI+H#JAp%h^BRWQ!^Ej|8P*##XCzUp5h-M+wZg;ls@yk$?R{DPC;5qTPT8Vh{9LA$n zz-ETkxbW`E)alCh>B{fZrKcQ{dhp!pX<6Q{IYtl(GqCGqaw^zPQSho$UIW)7SB}u@ z+ifXc+T^EJ6v?>myj74kY>ssgyJXuVkfJPy<-Me+rCoIzCASH`dAr(-QfW z%xV)u5(Em_(~Y}7;I0JEM-z`*H!sB;2&*pArRcWO@HCW z!i%1uiI>M#x!f*WlfhKEp>ef2zHGX_;B_6ig<@=x4uZc{j$GJ+Y>Xx1FDOII!*RVmu=(}a~yFKA7LG#|4(`}Y)t$`j?GdqHsfvgXrgU8d~~hO#c99bZktk#14rDqd!v%~SC6AAqY(q9E&1 zkQ|Mjc-Keko>=LhKoym$EcAWfsXax!Hgp_Yu(iwsHJXl(*NxDqYeP9Sk& z6K{n=xCm?w;D=^IBc_RwnYw1smy_JQ0*F&v;@`s^wom#FXlpHvItIu>jBjXkE}X$( znfp{3U2netWC#TM(T+*^Xf@@{7FdL>{qmmpoXvmTMy^xYnc>Bi#cyn!s!P+q(b|e{ zqzi`=86sc9J!GS9jT|DVYVksmd886~&1gAR!y@RnXHegi*r>bCt>F{z@b9OBm*J|^ zgIw8m-J{g+T(IBX8t1Z)a(@jVj$}>-jnVyLqe~L&Vk@xI;rafS%A@#O>%na&Q7ejH zO4{I~<73L9gx?-FWqe36^V7=dWT3wBXn1-pX4fJEdt*T(@NOMDi*2B6+I2#0%oTpp zLZcPrw>EdIQe|v#w}EaR)AcfjA<23?d{Ml)36d%WJ5Eu>EhLvhx!+u92>orZaJ}WX zM^BXe?ZXDszh>@r?CH=y0Gzs^;mMf9QIulc$<_*{>-BGs-rdTBLY-U7akE8+DTwtC zp+#qTE<3?vx5W+_2@D+RhDT~w>xI&N_}%@7LxiRB+9$@on5{dAUipmS6%>`4T^k6c zTNH>8=$#jr?(Qn7rdB#}%g5^3=_u28a2ko-!LTEGC!X9BBn5cx9j{Sp``RW}$30k~ zd;_4pU}nLdZV)6CKYkxQV+A{7^b1_O)`G;9jES=_SZ~IF5&HxaiSh1Us`A*tCDqy% zf#Mv$St$*HczLI_rJvLV`sTi<2A+$`K`9@Sk6aO{Y!r}}7dxsjFcjY(TuZwctno~^ zS>x~7@=`ouDH#6;fHDX~{_=8?mXln6I1}9EzZUsvyAs;_qkrw8lA)OYO=G|>dhs(& z((Lc@x?ajNyihYo;l%O0nd|N^?RcSf!NrWt%#Q=cd}K1dmmQcv6lBrPAS!aipy-Ut r@43HMruDz~kW956|4>J&L-#5c90kAh<{phv5cb^F4Unj%KcD^=kTf1{ diff --git a/themes/classic/assets/img/modules/leoblog/sample/c/category-2.jpg b/themes/classic/assets/img/modules/leoblog/sample/c/category-2.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 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%0A2Wn}<(%e%7uq4l2 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/c/category-3.jpg b/themes/classic/assets/img/modules/leoblog/sample/c/category-3.jpg deleted file mode 100644 index 82fd1c1a047b9346d7d68ef7c571a6166fcff657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45193 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%0A2Wn}<(%e%7uq4l2 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 diff --git a/themes/classic/assets/img/modules/leoblog/sample/c/index.php b/themes/classic/assets/img/modules/leoblog/sample/c/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/sample/c/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/img/modules/leoblog/sample/index.php b/themes/classic/assets/img/modules/leoblog/sample/index.php deleted file mode 100644 index 6bf70e95..00000000 --- a/themes/classic/assets/img/modules/leoblog/sample/index.php +++ /dev/null @@ -1,36 +0,0 @@ - -* @copyright 2007-2012 PrestaShop SA -* @version Release: $Revision: 13573 $ -* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); -header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); - -header("Cache-Control: no-store, no-cache, must-revalidate"); -header("Cache-Control: post-check=0, pre-check=0", false); -header("Pragma: no-cache"); - -header("Location: ../"); -exit; \ No newline at end of file diff --git a/themes/classic/assets/js/custom.js b/themes/classic/assets/js/custom.js deleted file mode 100644 index f4c0bc88..00000000 --- a/themes/classic/assets/js/custom.js +++ /dev/null @@ -1,4 +0,0 @@ -/* - * Custom code goes here. - * A template should always ship with an empty custom.js - */ diff --git a/themes/classic/assets/js/theme.js b/themes/classic/assets/js/theme.js deleted file mode 100644 index d1b0e878..00000000 --- a/themes/classic/assets/js/theme.js +++ /dev/null @@ -1 +0,0 @@ -!function(t){function e(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=26)}([function(t,e){t.exports=jQuery},function(t,e){t.exports=prestashop},function(t,e,n){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n5&&function(){var t=0;(0,a.default)(e).find(".color").each(function(e,n){e>4&&((0,a.default)(n).hide(),t++)}),(0,a.default)(e).find(".js-count").append("+"+t)}()})}}]),t}();e.default=s,t.exports=e.default},function(t,e,n){"use strict";var i,r;!function(t){function e(t){var e=t.length,i=n.type(t);return"function"!==i&&!n.isWindow(t)&&(!(1!==t.nodeType||!e)||("array"===i||0===e||"number"==typeof e&&e>0&&e-1 in t))}if(!t.jQuery){var n=function t(e,n){return new t.fn.init(e,n)};n.isWindow=function(t){return t&&t===t.window},n.type=function(t){return t?"object"==typeof t||"function"==typeof t?r[a.call(t)]||"object":typeof t:t+""},n.isArray=Array.isArray||function(t){return"array"===n.type(t)},n.isPlainObject=function(t){var e;if(!t||"object"!==n.type(t)||t.nodeType||n.isWindow(t))return!1;try{if(t.constructor&&!o.call(t,"constructor")&&!o.call(t.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}for(e in t);return void 0===e||o.call(t,e)},n.each=function(t,n,i){var r=0,o=t.length,a=e(t);if(i){if(a)for(;r0?r=a:n=a}while(Math.abs(o)>v&&++s=g?c(e,s):0===l?s:d(e,n,n+_)}function h(){E=!0,t===n&&i===r||f()}var m=4,g=.001,v=1e-7,y=10,b=11,_=1/(b-1),x="Float32Array"in e;if(4!==arguments.length)return!1;for(var w=0;w<4;++w)if("number"!=typeof arguments[w]||isNaN(arguments[w])||!isFinite(arguments[w]))return!1;t=Math.min(t,1),i=Math.min(i,1),t=Math.max(t,0),i=Math.max(i,0);var S=x?new Float32Array(b):new Array(b),E=!1,C=function(e){return E||h(),t===n&&i===r?e:0===e?0:1===e?1:l(p(e),n,r)};C.getControlPoints=function(){return[{x:t,y:n},{x:i,y:r}]};var T="generateBezier("+[t,n,i,r]+")";return C.toString=function(){return T},C}function f(t,e){var n=t;return _.isString(t)?E.Easings[t]||(n=!1):n=_.isArray(t)&&1===t.length?u.apply(null,t):_.isArray(t)&&2===t.length?C.apply(null,t.concat([e])):!(!_.isArray(t)||4!==t.length)&&c.apply(null,t),!1===n&&(n=E.Easings[E.defaults.easing]?E.defaults.easing:S),n}function d(t){if(t){var e=E.timestamp&&!0!==t?t:v.now(),n=E.State.calls.length;n>1e4&&(E.State.calls=r(E.State.calls),n=E.State.calls.length);for(var o=0;o4;t--){var e=n.createElement("div");if(e.innerHTML="\x3c!--[if IE "+t+"]>=0?e:Math.max(0,i+e),s=n<0?i+n:Math.min(n,i),l=s-a;if(l>0)if(o=new Array(l),this.charAt)for(r=0;r=0}:function(t,e){for(var n=0;n1e-4&&Math.abs(s.v)>1e-4))break;return o?function(t){return u[t*(u.length-1)|0]}:c}}();E.Easings={linear:function(t){return t},swing:function(t){return.5-Math.cos(t*Math.PI)/2},spring:function(t){return 1-Math.cos(4.5*t*Math.PI)*Math.exp(6*-t)}},h.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(t,e){E.Easings[e[0]]=c.apply(null,e[1])});var T=E.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"],units:["%","em","ex","ch","rem","vw","vh","vmin","vmax","cm","mm","Q","in","pc","pt","px","deg","grad","rad","turn","s","ms"],colorNames:{aliceblue:"240,248,255",antiquewhite:"250,235,215",aquamarine:"127,255,212",aqua:"0,255,255",azure:"240,255,255",beige:"245,245,220",bisque:"255,228,196",black:"0,0,0",blanchedalmond:"255,235,205",blueviolet:"138,43,226",blue:"0,0,255",brown:"165,42,42",burlywood:"222,184,135",cadetblue:"95,158,160",chartreuse:"127,255,0",chocolate:"210,105,30",coral:"255,127,80",cornflowerblue:"100,149,237",cornsilk:"255,248,220",crimson:"220,20,60",cyan:"0,255,255",darkblue:"0,0,139",darkcyan:"0,139,139",darkgoldenrod:"184,134,11",darkgray:"169,169,169",darkgrey:"169,169,169",darkgreen:"0,100,0",darkkhaki:"189,183,107",darkmagenta:"139,0,139",darkolivegreen:"85,107,47",darkorange:"255,140,0",darkorchid:"153,50,204",darkred:"139,0,0",darksalmon:"233,150,122",darkseagreen:"143,188,143",darkslateblue:"72,61,139",darkslategray:"47,79,79",darkturquoise:"0,206,209",darkviolet:"148,0,211",deeppink:"255,20,147",deepskyblue:"0,191,255",dimgray:"105,105,105",dimgrey:"105,105,105",dodgerblue:"30,144,255",firebrick:"178,34,34",floralwhite:"255,250,240",forestgreen:"34,139,34",fuchsia:"255,0,255",gainsboro:"220,220,220",ghostwhite:"248,248,255",gold:"255,215,0",goldenrod:"218,165,32",gray:"128,128,128",grey:"128,128,128",greenyellow:"173,255,47",green:"0,128,0",honeydew:"240,255,240",hotpink:"255,105,180",indianred:"205,92,92",indigo:"75,0,130",ivory:"255,255,240",khaki:"240,230,140",lavenderblush:"255,240,245",lavender:"230,230,250",lawngreen:"124,252,0",lemonchiffon:"255,250,205",lightblue:"173,216,230",lightcoral:"240,128,128",lightcyan:"224,255,255",lightgoldenrodyellow:"250,250,210",lightgray:"211,211,211",lightgrey:"211,211,211",lightgreen:"144,238,144",lightpink:"255,182,193",lightsalmon:"255,160,122",lightseagreen:"32,178,170",lightskyblue:"135,206,250",lightslategray:"119,136,153",lightsteelblue:"176,196,222",lightyellow:"255,255,224",limegreen:"50,205,50",lime:"0,255,0",linen:"250,240,230",magenta:"255,0,255",maroon:"128,0,0",mediumaquamarine:"102,205,170",mediumblue:"0,0,205",mediumorchid:"186,85,211",mediumpurple:"147,112,219",mediumseagreen:"60,179,113",mediumslateblue:"123,104,238",mediumspringgreen:"0,250,154",mediumturquoise:"72,209,204",mediumvioletred:"199,21,133",midnightblue:"25,25,112",mintcream:"245,255,250",mistyrose:"255,228,225",moccasin:"255,228,181",navajowhite:"255,222,173",navy:"0,0,128",oldlace:"253,245,230",olivedrab:"107,142,35",olive:"128,128,0",orangered:"255,69,0",orange:"255,165,0",orchid:"218,112,214",palegoldenrod:"238,232,170",palegreen:"152,251,152",paleturquoise:"175,238,238",palevioletred:"219,112,147",papayawhip:"255,239,213",peachpuff:"255,218,185",peru:"205,133,63",pink:"255,192,203",plum:"221,160,221",powderblue:"176,224,230",purple:"128,0,128",red:"255,0,0",rosybrown:"188,143,143",royalblue:"65,105,225",saddlebrown:"139,69,19",salmon:"250,128,114",sandybrown:"244,164,96",seagreen:"46,139,87",seashell:"255,245,238",sienna:"160,82,45",silver:"192,192,192",skyblue:"135,206,235",slateblue:"106,90,205",slategray:"112,128,144",snow:"255,250,250",springgreen:"0,255,127",steelblue:"70,130,180",tan:"210,180,140",teal:"0,128,128",thistle:"216,191,216",tomato:"255,99,71",turquoise:"64,224,208",violet:"238,130,238",wheat:"245,222,179",whitesmoke:"245,245,245",white:"255,255,255",yellowgreen:"154,205,50",yellow:"255,255,0"}},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var t=0;t=1?"":"alpha(opacity="+parseInt(100*parseFloat(n),10)+")"}else switch(t){case"name":return"opacity";case"extract":case"inject":return n}}},register:function(){function t(t,e,n){if("border-box"===T.getPropertyValue(e,"boxSizing").toString().toLowerCase()===(n||!1)){var i,r,o=0,a="width"===t?["Left","Right"]:["Top","Bottom"],s=["padding"+a[0],"padding"+a[1],"border"+a[0]+"Width","border"+a[1]+"Width"];for(i=0;i9)||E.State.isGingerbread||(T.Lists.transformsBase=T.Lists.transformsBase.concat(T.Lists.transforms3D));for(var n=0;n8)&&3===o.split(" ").length&&(o+=" 1"),o;case"inject":return/^rgb/.test(r)?r:(m<=8?4===r.split(" ").length&&(r=r.split(/\s+/).slice(0,3).join(" ")):3===r.split(" ").length&&(r+=" 1"),(m<=8?"rgb":"rgba")+"("+r.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")")}}}();T.Normalizations.registered.innerWidth=e("width",!0),T.Normalizations.registered.innerHeight=e("height",!0),T.Normalizations.registered.outerWidth=e("width"),T.Normalizations.registered.outerHeight=e("height")}},Names:{camelCase:function(t){return t.replace(/-(\w)/g,function(t,e){return e.toUpperCase()})},SVGAttribute:function(t){var e="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(m||E.State.isAndroid&&!E.State.isChrome)&&(e+="|transform"),new RegExp("^("+e+")$","i").test(t)},prefixCheck:function(t){if(E.State.prefixMatches[t])return[E.State.prefixMatches[t],!0];for(var e=["","Webkit","Moz","ms","O"],n=0,i=e.length;n=4&&"("===P?k++:(k&&k<5||k>=4&&")"===P&&--k<5)&&(k=0),0===D&&"r"===P||1===D&&"g"===P||2===D&&"b"===P||3===D&&"a"===P||D>=3&&"("===P?(3===D&&"a"===P&&(N=1),D++):N&&","===P?++N>3&&(D=N=0):(N&&D<(N?5:4)||D>=(N?4:3)&&")"===P&&--D<(N?5:4))&&(D=N=0)}}C===v.length&&A===m.length||(E.debug,a=i),a&&(I.length?(E.debug,v=I,m=O,b=x=""):a=i)}a||(y=S(r,v),v=y[0],x=y[1],y=S(r,m),m=y[0].replace(/^([+-\/*])=/,function(t,e){return w=e,""}),b=y[1],v=parseFloat(v)||0,m=parseFloat(m)||0,"%"===b&&(/^(fontSize|lineHeight)$/.test(r)?(m/=100,b="em"):/^scale/.test(r)?(m/=100,b=""):/(Red|Green|Blue)$/i.test(r)&&(m=m/100*255,b="")));if(/[\/*]/.test(w))b=x;else if(x!==b&&0!==v)if(0===m)b=x;else{s=s||function(){var i={myParent:t.parentNode||n.body,position:T.getPropertyValue(t,"position"),fontSize:T.getPropertyValue(t,"fontSize")},r=i.position===F.lastPosition&&i.myParent===F.lastParent,o=i.fontSize===F.lastFontSize;F.lastParent=i.myParent,F.lastPosition=i.position,F.lastFontSize=i.fontSize;var a={};if(o&&r)a.emToPx=F.lastEmToPx,a.percentToPxWidth=F.lastPercentToPxWidth,a.percentToPxHeight=F.lastPercentToPxHeight;else{var s=c&&c.isSVG?n.createElementNS("http://www.w3.org/2000/svg","rect"):n.createElement("div");E.init(s),i.myParent.appendChild(s),h.each(["overflow","overflowX","overflowY"],function(t,e){E.CSS.setPropertyValue(s,e,"hidden")}),E.CSS.setPropertyValue(s,"position",i.position),E.CSS.setPropertyValue(s,"fontSize",i.fontSize),E.CSS.setPropertyValue(s,"boxSizing","content-box"),h.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(t,e){E.CSS.setPropertyValue(s,e,"100%")}),E.CSS.setPropertyValue(s,"paddingLeft","100em"),a.percentToPxWidth=F.lastPercentToPxWidth=(parseFloat(T.getPropertyValue(s,"width",null,!0))||1)/100,a.percentToPxHeight=F.lastPercentToPxHeight=(parseFloat(T.getPropertyValue(s,"height",null,!0))||1)/100,a.emToPx=F.lastEmToPx=(parseFloat(T.getPropertyValue(s,"paddingLeft"))||1)/100,i.myParent.removeChild(s)}return null===F.remToPx&&(F.remToPx=parseFloat(T.getPropertyValue(n.body,"fontSize"))||16),null===F.vwToPx&&(F.vwToPx=parseFloat(e.innerWidth)/100,F.vhToPx=parseFloat(e.innerHeight)/100),a.remToPx=F.remToPx,a.vwToPx=F.vwToPx,a.vhToPx=F.vhToPx,E.debug,a}();var q=/margin|padding|left|right|width|text|word|letter/i.test(r)||/X$/.test(r)||"x"===r?"x":"y";switch(x){case"%":v*="x"===q?s.percentToPxWidth:s.percentToPxHeight;break;case"px":break;default:v*=s[x+"ToPx"]}switch(b){case"%":v*=1/("x"===q?s.percentToPxWidth:s.percentToPxHeight);break;case"px":break;default:v*=1/s[b+"ToPx"]}}switch(w){case"+":m=v+m;break;case"-":m=v-m;break;case"*":m*=v;break;case"/":m=v/m}u[r]={rootPropertyValue:d,startValue:v,currentValue:v,endValue:m,unitType:b,easing:g},a&&(u[r].pattern=a),E.debug};for(var L in x)if(x.hasOwnProperty(L)){var j=T.Names.camelCase(L),B=function(e,n){var i,o,a;return _.isFunction(e)&&(e=e.call(t,r,I)),_.isArray(e)?(i=e[0],!_.isArray(e[1])&&/^[\d-]/.test(e[1])||_.isFunction(e[1])||T.RegEx.isHex.test(e[1])?a=e[1]:_.isString(e[1])&&!T.RegEx.isHex.test(e[1])&&E.Easings[e[1]]||_.isArray(e[1])?(o=n?e[1]:f(e[1],l.duration),a=e[2]):a=e[1]||e[2]):i=e,n||(o=o||l.easing),_.isFunction(i)&&(i=i.call(t,r,I)),_.isFunction(a)&&(a=a.call(t,r,I)),[i||0,o,a]}(x[L]);if(b(T.Lists.colors,j)){var V=B[0],M=B[1],H=B[2];if(T.RegEx.isHex.test(V)){for(var W=["Red","Green","Blue"],U=T.Values.hexToRgb(V),q=H?T.Values.hexToRgb(H):i,z=0;z0?"up":"down"}function d(t){var e=(0,a.default)(t.currentTarget),n=e.data("update-url"),i=e.attr("value"),r=e.val();if(r!=parseInt(r)||r<0||isNaN(r))return void e.val(i);var o=r-i;0!==o&&(e.attr("value",r),s(n,c(o),e))}var h=".js-cart-line-product-quantity",m=[];l.default.on("updateCart",function(){(0,a.default)(".quickview").modal("hide")}),l.default.on("updatedCart",function(){r()}),r();var g=(0,a.default)("body"),v=function(){for(var t;m.length>0;)t=m.pop(),t.abort()},y=function(t){return(0,a.default)(t.parents(".bootstrap-touchspin").find("input"))},b=function(t){t.preventDefault();var e=(0,a.default)(t.currentTarget),n=t.currentTarget.dataset,i=o(e,t.namespace),r={ajax:"1",action:"update"};void 0!==i&&(v(),a.default.ajax({url:i.url,method:"POST",data:r,dataType:"json",beforeSend:function(t){m.push(t)}}).then(function(t){p.checkUpdateOpertation(t),y(e).val(t.quantity),l.default.emit("updateCart",{reason:n})}).fail(function(t){l.default.emit("handleError",{eventType:"updateProductInCart",resp:t,cartAction:i.type})}))};g.on("click",'[data-link-action="delete-from-cart"], [data-link-action="remove-voucher"]',b),g.on("touchspin.on.startdownspin",u,b),g.on("touchspin.on.startupspin",u,b),g.on("focusout keyup",h,function(t){if("keyup"===t.type)return 13===t.keyCode&&d(t),!1;d(t)});g.on("hidden.bs.collapse","#promo-code",function(){(0,a.default)(".display-promo").show(400)}),g.on("click",".promo-code-button",function(t){t.preventDefault(),(0,a.default)("#promo-code").collapse("toggle")}),g.on("click",".display-promo",function(t){(0,a.default)(t.currentTarget).hide(400)}),g.on("click",".js-discount .code",function(t){t.stopPropagation();var e=(0,a.default)(t.currentTarget);return(0,a.default)("[name=discount_name]").val(e.text()),(0,a.default)("#promo-code").collapse("show"),(0,a.default)(".display-promo").hide(400),!1})});var p={switchErrorStat:function(){var t=(0,a.default)(".checkout a");if(((0,a.default)("#notifications article.alert-danger").length||""!==d&&!c)&&t.addClass("disabled"),""!==d){var e='

    j6?p3-%S@px&Fre z4Olf3FDSck0x^T*&7%YulPLZ?VZKw2D>7WY!o`{)QhXCn_I<{w`TCRY52<>PZpfN4wPTFnvfOlM) zFF9SW&v&L8iGGUtKQ?C6Ns2fhx96yYA3r$j=`z3F237QafR$A-zu#gxH%Rw!Hx;Se z_~BUEx1}K0Jj+FcDmDPFNYymS^g4l$LS|;QScp*FxzaF8_Wz99QyYi%irUTB++>%?T< z&f%%+Jn5BoG2K0^Q0y*}^4s8-=heF=wW>o+w90qrx|2nIW^u%@Q%?@7k$f zeCImFe$d$u>niVdV_146yS>Yy==;0qCsVJtL@fdmYzL$hXoCm%u*R|;te0(NQ>H}w zJCw+;%dqPZcQp0tXGp9e#BoM0l-z%qAL%OYPxrA-H04RRe?}!^x=lOxaBq2(^=5Ck zpFi9|yGfnEkLl9)s$vo;H3ts^Pkf{tbuht6z;~qvaZ^k5EQMy$l+|Qm27jrgtwNl; zYpw|#&Pig`;l&nK3N}*re|z)qn?MW3AtYl(1Y%q7|Nmm!Q)gD2^9f0(=&ug+VMbK@ z#b_pU9A(0k{gXb8Tqi21E{O#-so4T#L#KILON36()K#(pA-(%8cMF_ZP$0t z&GOG5oUWn+b>U2wrkP}c&fZd!lI#~LG&H3kl+5tM=r;^Qw`_lz#j+dN*(!isYV?4r z0!HZ#S$JkJQ&AA( zBeq%1MBBuxx6W)B-1M(Iu9j%-bwoQ~1VMEX93^W8lmMUh))AN zt?{7zYb6U1HP1cSCs=J%Hg}0;A%2Boc*%h#$6KLW@d|O%Nv$*&A-Cwat1#9Ri3*o_=g>Fg-sz8s+U`75lhH@0Kcd zupbS4e##(SN4CG*^M5=~o8Nr_>u%a<2hmVFH1p5&XzY*W=cx+3RItvU0g(CYfBVCXiY5 z+L$ciU6D-qk1N7K9qH`*h0Z5bNX8D@V-zuS3{edz1^jzXET=n(v*gh05ugVN(ufA1 zSA^G|!I95@0;NXQ#Kq*e7=C=VrDLxv(J|ob$>gJ3LnAR%6*XI3@5sE--}O(*p%vSo zzEC!jM1^ELQnV|%W0B9RkZ5brr)2A(1E*g^?>-Y`?qlXW05D*6ZyfNx=~)71fejKz-eLO%9T>vU5K!&wngF<5gQ1|k`K-3WH@C_&=7C<#Y zF5`7_cW~rRc!J?~OB~mMTGd?LKi) z7v{Umb=)J+;2MvlD<;E@E~`w}Fh){j%SY{{{i~5lGmqFag-43)AfeF{=7G^&wfZvI zk0|$QZCV~KGZ&qQ8K6B$dH)WJW~Crt(Y;r6qU;OGr)39;B`rpEq3k1}l*T+RJRK3n z0&7t8LPlpZwx~3O#@^tPuSxBI>K{>0QNtv*q$r5(>Eh33ANzk%glr<#e6{<3{*7P3isSF)#}DBTs{CCpsUffL%LskGabup3@RVU=OCC;>9ap2uSB%q6(liyyo!6 zwU=7&hG^IY=2m09x(61zgZKFzd=|Bnrdk4|aaA7sSRMe4N#_<_5!q5{jYe}(Gb)8M zNAcb&KttZlsB5+3u&nHj2j$XL8wOBn6J5u*5XX69drj;enxDMJ!PuA3x_5 zrI~c6f zCv4o-0{rVV<;%<>P+G(Y$mRSRhpgbroJImo32Q)Js1gkzrBVS0;M(4!w%=NiqQ9#l zT34<}N&U^aj~>ET(BT%tYZLs!a~;8d#qJ!`7@|z%g1SzCdc@+`k$8W5e@t0vZ%kF? zNZcA1h%ht52ckA+3JFoKot|j%`_L;(=oPG{OuiS5WvwRQJorf<8pCw50dt_TEV@90 z;*tYsMs>Jci{foLONr9f(9qCEQ>Q?OiU3nJe32XC@px?kt`D8}SoS$p0Z?eD)3?ky zxy4LHoS?$aGMs{n9ctT9LTGR|ThCaogz)O3tb#Ocg~ug+6|16)$!!u=^@weKWndyK zNqfN9&6*r`eSD1hTg!B;=cPxaWKxX=L#d(z!8mP7U1FQFM;!Vp4$A}4AtX?OnRZZ3 zOh-(Y6-*3bK=!hk5%$;7Jc~jbQ)0hW4NndkK|vgWXc;|z42ymzq#C{3CN}Mfe|k)1 zi%Xrsh&idPo&MdSE}^m~as+HfkNL+WJy`Im;?dCo1Hv2(-BE4sGUzKD1(#&w`+fv- zmA&91M?vuax0kjeo=xXXMA*D#Kn;i4u5bJ8#wOG3w4{kB8^y+~zO=RFx0}eUTX?ef z=C%)~{g)rb4u2CvtEA=Gi4^L!%Mj!c=jmzlijeX`8#L_Z* zbC}`^Yh=VOg_4No$mL8M^uU3i7p@i~Lm7x~s#{u%7GuTL2TpNe=JeZAf5c_Z zO4*U{NNX~_Jo^QGm+rGN_&*3X?h&=WJ(BzXs=f6{9-tk(6-l@%HZyi;Iq$lHu)O#R zeG`oKbl=-x)EfX+AJJvj;LZ_njR$p&c1Kv6xNE`vtii0xoM)wGbtetYVb>rt0y7XT zt1?X*V3Zek{jtzieEEkEd|Ag0uaRU%J!F5F>3@=hRu~gf))U?!|EZwR(uFAXLh#1$ zquCGn9_&)cv`X1QEb6HM*?ct09^*r+#~IDOjJQHe9@4p2uM?M<81HnmGo#ktV%FAw z7d6hU2XY`$2{3**4LJH=V0a84eXL+~tg1okrj!K$iOQP-D$HOCGW(JG3*PMFOUL%gUs{RCSc5p=a+Jde7Nywy{{Q7dd(l0PGq z4sPv9j_I<#)3mR`YR<&f=_V2V%63OLSmC1B0|W%1FSF1rpwy0wbR3%!-O|J2m%MLG-#I4<2E_ZLk|(7|ys7J-%Ww zJ`74(Tt_Q4S6O9tN&R8z!!vmJD!VIsiw%n}m=!iBeZ|L_NWtN_x(59Wfjzc?$J|{h zPP*0;nBb%x8C1ZMk3-LD@)vB>JLWgK&*lTvYPH>6V`>@Lr21!wgAZ zjaDMDqf^Xwa@IuU8Oce~8#{v(#r#dLa!Jky$JC>5K263q$gdcs!NHLt_B^_#<6)HjlI z1Lw-($!bBqBeB8r_Ek0K{x|bK7YmO&-bN-pMBV?((p0sTimBe@SoW*#18RTMUEkC% zhFXghp3^ka<3U~Hv^3acUdYB_*gsTJTEyvNjRN@=9A<_n@`Q3-+6H2L0)Dk}k0SA# zX1kr{Uy?frDT;?wy0x*vq+hwOpIeK3y29Mf@pm#FWC(=HkFt+-|mZ?f<=r_%X-J_9L9C6)o+crR5$2 zcxYGa8^)TBh9^=|{}}6k!VFI`?IHRF>`B%RY~s>_j(=+_5`8h>fv4aR-@TKfr9=qwtG#OOwcfxK>8k@mpzj$X#Deqa?0Umc5cg_Ak$JCK=7inZhaZw5 zkn>NRJ^479(V>kX0(S?JyTUJ>2R08~Z8Q}+9v)5XkvS|P%*A?Q^93}eau2*xN_xg- z*UG!ars1i>Z<>?H0xC|KfBK!4uZmn?X(__o`SXZ_!TaIA4=<;#H=FY`XQm6L^bcSx zf*dnVRi>7$8n=4d&Aqes;h^`zCg7DdExHkVWqTLI%-@!*v=&j6PmHw+mt>g?^x9U=&%10y?u1BUOzm zUokT0QWTiqU5&Q?gmrjM!@}1i9lKYaPDhL+OiyfZIi$2wWbD>eZL@b8AG;XP)v zgX7e9ykcLPqt78>lgHhU`kK9m0|uH`n;N_a5)iJC)%)*OHX1yW_79{@L3qiUr&!`S zuMJVkI|<akYbDeH!Gt*BCzws2)Om-Wj-u``;nY-cJgPhkp)?l}K>SyhHTz~6;mBxBONizGihsZyH6ayd zB<_5X%_(|w=&t=&Hf^;<*+i{Groag4CvSf~-%WSf)x5PlL;(m-%L}CH1Gj+=xf#eN zpG8LPoZ_H;T+My0&;0*wmi|Al;!D(KdOJ<(FOd$p{v9ELXJPT;V)>if@zVfh~tNVJ{a0+BgV>&q>D^d8Y}EJb~dciH@i=*E~Cf zS*cG4IDucQ_iMe3eHBLcpv(5ldvtATa_F|s=%#uBXBGTnX@kb@>+#zeF|YE_7xQcm zld{)h&5Kk*0*Ov*OFkH=&~q5&9f1N!(s|eQ(Z;u#iEb@brBkw#IgV`;TQ9d4N__x> z9bOY~TB_=Z{9XufH{yaCqY5bT@3v37a&%;Mqjj3*Ma*7jk$mcub;o7WU-rfx_cYzu zYYQ8CUSO<8LMdy#dugaSc|H+b6m{tI4fp$qSANYo+KUR!5eNc*dV`P&{p<2X7dZ9E!N;Svi}Rhv#T@ij^!}Dw!Sn z)tZ94Mj2M<_cie)twBm+;0{<;DW$)U49>;y4b!zW?<#`!*(V2#+ zjpI6<;HeDr_c%;ZjYhp9#q>>?x3MuIx!-MFyzO7<@vbe^Ws@=!B~A?!J6F52CBA@x zR=07OTbkmCtsMfisW&~B>*lQgRkv`k2;iq2O6-A>g zo}d5C?!o-7RnrK~*#Y(CH#X6r5{kSXd#YRLXi!PGunq|AoxzmbZ9bcnl+!;G6^6F- z`q+l?p;qSPu5JyHW++8UprG3)+@%&0`nZ9u@xDg={Yjsa&Q@J#<1?+SW3H}iPu}vQ zWz!u8w6hr9xYLoPw+n~qZXV}*w%yuFD!<#(J2yo(s8==6Uc~WPMpnfz<-N(&EICW_ z4rRseZPd(+@}IF6gj>os5YqCB zqAU5;>e}(FkY=`3387OC>3Gu-OX=Kmxncd|tj!V#Rf5x(*{fR~$T1Fs73vP)v4RW*#$P58fCYLKDu zmu?olv0&TVkq6!?BKv1ngRZ~1gcm8~`C=MV1SY>x*cjMNCkk>(|FWLHpcUEsp6@O% zifGv#ly>UiC!qu0{E`~qMqzgCi@*dx0}FX{IX~bY;L)msw!0rkooRHaY6sWHdqP_c zggCWLpj1DqI!z_OCeNmMSU4**>tsRy^WDpJARvohzSCu}xu{gj8V-HVUcp;erKts2 zdq1q1Bec#t=Ua6YWE&C2bNAt~2(4(Ag2`{OZ`KnE0)-=Jrf@cT+`U8q*7D}kPUn>9 zmWDTXqpH)?0^xZ@x~E0A_#Zm5I9-U>P{?POZ=0hZKJJt9ntKNww*N#X)ZYg`6b(T8 zKhqW_T+Lhq0zCM>xqFRw+R?E&Uqq|Z&S^bGO(SE3F$_zKL?d#IO5$Z}%7 zyx?kqO_H|=TpI;9^U26xgGrJP_|@gbcmG^G@6IHg``sw)k~wH^;F*|(wZN5JDxr`Q zSgr=Nag+%9K-M-co|Qm8;E}lu>^In68mA_AraWCPm6RbsSko{J93{^cZOc4YK%1-S ztVp$|4aOF^paq&F8l*H+%!Mj>v=r)xA)I4Ho0eMdYM!ysLJNZJsfXAI*vNcyN%ur| zaMih4|J>ohhM2a|&k)9ST8Vvl>hT1I{YmIhH}YWp14J=d*gDzH1LYptxM$Stb^b+cjPmCN+$98=U!m1^@jTy@Doc2kwDl*e!$z%1 zpv_A8?_pg5w^M^1xk=XyQ;D1aQ9!Q0Lg^i!eZ+UqXy@%E)a-R2{Np~&4e#c^K0)*U zG6C>^?)A_fqiZ9}FT4=_5$gB4&k*^ST;ZqRf>%GG@cuy9154B{ON>`4BJk^1iw)|M zs4v@93jcI;ww4BY`Gv^rg6WUVOW6@6ElN!;)x5?{IxGdKb}SRp(0r1T;F}rKXEv%* z^rtPCwj9LRxF-VFPb>1}P#jrl5SqZZ$bxK}ox;wy_xWF5~DbF-B#eKIQERoRu0MSlSpF zD@Lev^w%XR3wH$(toE&8x@!@sdZ#`2C*;E+CsJqMh202NL}yjxnMoBE9A1bx4()T~ z_RAc^`D3DT@0iuuD|HCxhmCNpP`S}X^T$;}2B?R|&uH*3Abnk>V63)tL*MtjGD|qe zdY>l!!wau>K6PN8$FY~p*LxWjlnTk1fe%t!Qujx{m!x5TSaDlrP6W0F(LJ<=n4XYo zB6$TK^pW%8Y~karAo4p%wQ&DOCUJQHxSXrWj6r{<-AwA4@Xg5IK6C4hVC5`-I;p^%HSDLx&^SZsv>z4km7{p5Q^0ty%-i_XqcQ32z0)J_3DO%UiH&q)%WD1^^o@SKs zvk>1b5LXWf3Qn4ck{?q^Sy7dBYdn(ob$rMb@zeL6QsEgPse=#DgFrAVd`Cu}p2N1b zr#wySNNW5!wqOs;*_}iY=?cTEd!xfJJz*ewy5atpU!?30D-W^e>7Kq`ro}>`|H{m> zwBM_Eph=}3JrQ`x+4U2kx+zd%V-EIG#Cj#y=Wvy_O5@mga{q(k`?r`qE%JU@tJ+M} zRT-rL*5GE#=VVvm;)F#!CM9K&F~unKXYt~njg|$L1e4@yOSOKS(|4aU!KsI-0Dg(C z#Kmz9_4j`zq|54gLBfgXBn8U0-AdXQceWwA zb}}W!@qKO9(_Aq^;03f+Wab7uq7~w1se~R4otA`vFf<@{?? zKD7H|w&d0O8dP>mZHQMUP6V@W4V!84#}f|=L?q-pdxN3IR3Kezi47H7sFSj(#R3bPA6fXzOBr1Bx>NZq~P2=$a#2b~95v0W@;idQhbz^-vgNr~o>tbRDQ#nS7Iy4d|e$A&*`QLkQ@|t+;{)e~jLCP9Y@=`J}^ZPu(who{(lViWu71@+~W z+M4u&r_YB9S_cVrw1(4b=`H!0c(>n2Md3}w@cecIdUzJE?s$%J9wj%M7yrK16BFk+ zMIiXzjK&POPz*hEu{W8o>>jt2I-^0bB}9!Yxb!C5==1GHx}HS)-ORxkaab&@xTjC1 zq&oavm*avLqhRui>A_0mZ(FqU_8nB|UJ;$}-g?N{ZstvThRcgeknx4Tuh2@iTTBXV zh)d`!3n}iE3E6~&^vpqy&*^2!0`NxA>Cs1ylQ;y2M=9OHQLIe5PDurH(AJX2uFY~O ztS_Yn3q$?IB9CSrp1}gRlrP+RILY*D=(>jLTpIaS*AWLtnKhRhPzg4+rF>ZmY9)_e zi+3{Bm!bpRG>5nBC%X|G2B~ZvN2Lnoy4~a&oI|6OeZg5;1fTl@1c*Mq^c9HXKTBBS zpaRy&)&cjyjrTigk(=d39QwGgWapaoX=Z#Dg-dr}xvVna{HzG3PBn{^)*)Wi)r#}$ zi+2^6)^S;6y~`_!$GF-CFhKF@|B|M3I)$S!^#AeR%-!%@NCwbKaghSrxl(pEg$nRMYF#7~~ zRqdAK9II}`u+gM9Qw{kB30t{O!){3E7&|;2ud2nzjCC&;-cT2Gxm%cMRh)go8jm5T zowQ>Jdl;KqlhZ?=B_;NRibU!y&Li$o+|u}E*~!suBb8Y%9)O=wP}wDKyn>p}WaW`b zk*>JNtrfFCV?c6H>yHYrGa=S4d&mi~N9yObgA|2<wQvmlemJGcDaO|D26Ta);(@1U)D7`>K3K|xW$ip;scz;OaYmMKH) zvmS2{UU4_stuD~94HncQWu4t@k=3aSx-_IvgW96o#jU6ShulB8h8CB3Dy_>0Koyri z>T73@?%Ij^ECnp z!ILnfV-WQQxrx@%qJnvL1U;oZl}Xt?>ejS#g|C5_UVbJcp6Pt2L<_~;Em0USUNa8S zR7k3+w$VUwx!$oW5iK|Z#-FKx@@r<0oydsGsMuE)U%5(@;V2-~kr&Z=e>HqwYt z%?!co6n$VfZc)g;g|f(-UbW;&T~fiROUec$x~C5*!E` zeU-mV<)Whr&kKth>KPX!NE*dykfqO;$R!n5LhBbc)58^0rxy5~#N;cVKGFFd~eL>0_i=U&qL;uiOpCrG(azjB2G+GIbbVPI4z*wC7B zcc&%8BAl_ErW34G>G(qRf<`2hxkd5xTy%u#Sh z!GlRgN-3pRkD$FQgno$@5>&g3rXb20QBw<{{<5!*yZlRG5BNv&%jA?p2I)IAIw+)~ zS7sz!ob*eBc+`PAObUNeKf2R}227nq&Bnl^I%SPtQgwPg+C@x63)Fl^@OLHUQc1w| zDq>cnNbXOBv(((AFN~=Sq%;INkbr8lt&(fv-RhO{0Pa9)bA;HTR2=^{7M(%#NQvYj zK!rdcesJ{`hJ0bclHxqffRixE1duTXoNSTxcv7>^C$zjG6nPzPT%PEgInSPt%Csln z<=)O@CnA&v=oDmWIM|H+QTwtgFSJLxK38kt);}x%bMa+kR{00Goe)@@tCj9wX6RW1 zbiJb4y^@22FtiY0nfxaW=xgu9?I4AYef4r?&f6V?Hu97BBP`SiU%fgmJ%=B@v|xDMD$8>^r#&s2pDp1B>W`ib3jmt z36|$^b6U%|@_4Im%o+@rF z$-}6R*SeQ9ev=tYQOGsg&Ox%-=vyhNzr_gDO>-Q$1uPYO*@%g-S6@%^50qX}&o)OpADdx175d&Z;a58EQA+8Cb_ zz$3~iKwLz*C9%2B$68>L$E_HbC*$#P1vy)4+i^&!JIP}FgANvU zkyWL{AEtw*d`kz-=%7Ys{Y)py=O~J4Dy7`2X$8Z#!vY%fsjv3}@zReH!=S)UdK_%J zRR7om;Y^;B!C9K_$F_Oui87+AxhEU{;R_3QTHjW{I5cAEYEZQj@w)xQ*nuanbS1b} z#YIZ$q7K@shr$_t$^@6d(a6_Hy_jB{Uz~%Xz8L?9&B%t`wPk(|ja;&hvs@`3C{oE< z&_RVWN{na4{%f{qfe<41AJ@2!g9otl#8qWB0V;{DH&bs_gG}JR!*Wx-TCK7)K^k#YEv&ynJ%Z5*Cp@Bu;pPKKXsMe_T=6j zPvQmuv?d7qb|DvXv@;bOaCJMRo|eMDqQxGe?d(cj{CWQ+tt;*>#ZMOAaM0zJnoNWk z-KqRp!#hlZY!i?Pnj^fp$=1TQ+)5caSeic`kKj*y%Awk}@r=#2n} zoY>2s7mspT`7=CfSP7N{tiZ7LMx%4IbCg}>2A3??s^rlzGrGr}x|3y9#sdFlY9B~Sq zCXh4gw)jn=+v6yp6au4&o+OLlf!3+V_Nv1j-laL-hu$2{;*+x%5CzGYl=eUaQ!A2b z!=x?SlUL!l` zJN5&{qpVq|S5Yd1kM3!@ap*N>8dboo;}cnIF0H0`LLKGChrhIt#Qy+oNAl`Y(q6LE zG+eg`e)ZXH2RPXC1T0%kDGvZt(t%acogx4=Ym50%YIJsdUeuqb|4_)!Jepusn~=Np zP=&WR?zXuhJ)2&iQk7YmLdhppLQ~j@mEbAfIDgE9Bw!>i>F;E-4ZO#7W8w(Y zx`;Jq8@?q&wU7M2>L#w`eocl3*g7D$k|QCl*BZC$4y#U5y@}TC9%;Rfrn)bPE;!r` z9FPdYqN{|Ern<7%tfbeaf4d3XqP^w1|XcId0a`+GT;;mBoXl=^RV zf2P-7yfbe;D#P){^DmB10FQUu%G4u39uEK<%?$pMfx*BR0`>s}1*B@AWI;b9)452vFKe6buN z#Z&XPG3D9 z?r6y(WT8Q0Awz|GtenmeD~XUFJR(tKZ&AbmJ3Bkk=LDZK%zIGJ?;iqntgH^k6S5q1 za{z5_8Zp%vWF190{}*UKl~tCaCX4AoXPzr7a(41FY{XfXWb~gU42_fq$Q4@nx1{b) z?m%x?#>R}?3`#w2@scX$yu>}#s?n?MT=+^MM?WUT10+2{zKfhCz%T)@ssV0fmaVOf zEy1rreGbi717qqN7s6stXHJe>ilaY}$l;9L$S$;@aY-;(mE&stOpZ1`IQn94<2CYv zmx$$NgeCI;xbf-XTLSM(_mmAiH`#MrUOQX-bicCna6*+{Irrk&5U7hPGQ7J3rB_6$ zvc5HQVZJ)k^DisRF{}bsajHnT=ZxXKo{$wdFBH={GwwjU%5V0Wp^+yM8w6spR`6@J z-7ggxgjA>+8F=*a-!ievhRI*TJqesN{MT@j=rfPxRa_f6L!Et0d-IcU%7%nZ`K?GS zY|+qGL(F{`s3nF`ng>(;pN{~ID)xccDhP{b7Nc$M$8Z^*e?H_~@ecQRgr6)a=q#zs z8SqFrf{QoXM1?q1g7Q(+SQ?rtX66=Zjuy3*bfnXN%Wj25``KYfQY=%f5DQu3B7KEeUjVSJL5O z*a3+DmfA6SMMXuq&lUR~8@z6M{X@04CGpzqNw|>%(pGQOMUUt$oJH4^wiKJ(s#y*Gp3TJeUyif! zXnNd0<$SC}{+Om`z4|_a!(Yy1%f0-6#}1J1FEKea7e}rD8bR5F7e+EL8Q&jxi2*sD zO;MD!P!{U%mAE@i*@XEJ%%oCccfbY4A$KmS|#aakB> z)MEj_set&2z{neD`6w;&vrGQg>*pk6+(baal)vqx8vJ89JWkz;4e=FGiLF=p_=#0Z zASk6KO7wHOVkofK-L@z2==svZa0cl^y49$riky=ks>E3t{4VPa&*!>F^XyHxqu8aW z8$xDeCMl(cChOB1b4+XOjja@mxdzZcY6v_7!d;O4_wDp@N%d8-ONk%42(I-i8Fh~M zc+T^)Z}QhK)?YmXzg`aibOlbupeOQqn%jqdvC@YFHmn&P;mE}iIMNDpUdGqW~0rE)DW^AKGg3|tq1NkTX{K7-})UN#Zc-~4>9kruC3AR z>U3$OTfj2_c4&pbh8;s7lu_VC8h97xyBkboyh0jTrfT$P5*Z# zA^qw*M-_>^$x^XfK=XCczTn;MA9f~9N1@(HnrGVR&te{!PH0TZo4>2S4i!nkukxLl zoc4%8L^mYNy%BKS^HQ&8-Zl}opu|DkTr~I-pV$H7<ahccn z;SXI_HW9Ib-r|YQQe=@#p|^*~h&hhqX>NwNAJ+Mne>ATeVAa@%hAY$@W!9pBYl{}_(D+F#E9=h*&7T~2ww$OV}V_D>T!Xp^pQtOB}Ts`Uj@sN{*eZZnY-gJ6zwa< zQ@ksmnlpBRug4!KGYJYs>x=J>@$PP9>h;1k`qzwIoZ=|n8)L=$#SMbH$PVz!j}&`w zFG$Fsc4Ium1^>Y(!re&TI6pm6%U8Gz66ewvh0Hbl&IFU&CCUrjQg#W969QG|tT2|V zc(@lA_%sshw2NQhccJ?-E;c7$;MTc8>qzS_GqI;234i1K9phIDblVeg9#cH{vScGf z{HxK3rc_;Uj8VYjJd)!RrwRbXZR1&*pf4IuODYL@^(bJKi8zI%^6>OgQ537#grWx_ zw{5&Y{Ht{4`vONM#!oXuf*%OvxAvmYGo)Pk9K#D7rU%hR;Vb;1xcrr&#A~^%y=8N( za*VH-qzV*H_?4=2pek^KOYp|`)*U3{=4FfE4R_iZ`!fW(-`<$N-EH-52!FXjo^1kY zWNRGv?NLbDYJX+hQY(d1r4p|NWM3Pc12(c-@Q65;6+p-EFoH4M-}yyRoD)2bNUZNk zUZ=EZg>7>!6fR34j@MvU#!tL7xLB>HW(k@|{2HM5C3oL%vvwxaK85*meZ$&H)TK7oZbIej-J%%C9SUD0=~{ zf+8t~2`2nz(R!|pX{tP|v?II^RZS8p|3zw1&v`(lWjR2RlbBm^0qf%{l9`f!WuZ)2 ztl%g+995%wP*)b^_tT!^L?YUCp|#mW>IV5t>ikp#xR4@vb5g~pIU&c@6F0A)nmJu?0S&q!vns8-~vZG0QcYY3KQp=P7 zANplN**!uklxp!jL5ls0`(G=NO8NMtKo-f>Mv&r4IEoNmEsye69-R=Uj!;f);{D*> zMXro11y5d`IFBd(ch&74+e66i38aKn`~1emBsn3!EAVDo=)cDW3k%%3P&&GbgdydH zvU6R)tF?)i0g=%1$R52^fH_VS2zZ$+z-MB-yi0YP#ZQQDIQB)9lG66I&6KKu0l z0rQ3M*TDVD?IfGN&Hau4TCLbghzYy5Uw;B$kgcM3tLkSy(eD<^u#PKx2$~jKi3awb zbl>z^aYM&1-6|H%FI!(SGAyO#Mjcr{Fgz^frL9VCamt9?*5)7~Y|Rz4dTn}&?O`Fm zRgl|kH^jK4Pf6kJ?d$qgwJo}tPqeco=Cs{es~+wq z{Q6&P$>4t}JG^7>6pp4O#C$`kIKknUcOdx1<~Ti`wL`2)?!x2X%pYkf+mv0`CF?+oj2Pzj2VVEv_xs?q@4YVGle$PWCO-CCd!cISC4uS5gmSj?;&NzK z-DTij4#_|#PPS8?aTy%P@Muk$b$)JZYnTwAzo3;b^luFc2z1*!$pneZuKOEg`)X{a zsU@Si9wp;A7Ym)uVseTZB_g6XuCoe@*aCfNYU#Mgf5?JI5mP*#Xj2G-anvM z6p)X<06tpt68aR zb}>Mq4_L#DTM9C>V(Fdt7^e1ETA@$cJE80eU-@|M#~ z($qH=X%-5f&8e%KsSC!|A@m|b+2VZoD!=;H?8*?TDLjm;TIhUhoy#$2w=0zorMbvQ zf>ND8=SZ;9G?MBpR~+~2&+3WaVS@|5(aK*E=jvCZ!>3Fp5PqIXE4nfL_X30B8xwTR zt0ui0T8r!&vakh>_0_Y#en*WLdFS?`yqjzI8IOg1+-YsA^Bro7#V)%bYr`bGF(bIY z43oP8<>_>AFgHF9cL%J5H-@B6E0YqBEm{bTdF*xWM$&nQ_C>pIiw+%&4h&-gd)C&N zecrBZ(c#;o6{h{W*6jC?!=b>bE?D0)@6TdBpT%K);`+^^sD5$G42k59DF5qjRR1Hm zj6M8lIjpbT{SQ>^AH}G?VxFTVu)dN|I5Z2s2G*yNy{ybNik4`d=58#h2#$FZB}9(3 zHL;*09trjEUSgb#lJ6$D^Aw9&t~8fm1RwXTaE?z@v}{lP?Xu+}GFxYK4_#Ad6JbGT zaDm@MjjyK#8)SM|ICHm}8vBk*qs?$S_|?+?@s$CAklvnb5`T27igr!3v?zS#ZZ)$C_zdv_Wmrv<3q40yP{2_DCtZ|SglX(oK zNhvv4+<@yr#;x(%e7waqN2ApG4}Y2rE@d;&b0?>!1RQVTH0e<^VU628yES zJ$V4o=iCPcAUQu#QPz~k*(Ksw%*H9qimuJ7OjH{cO)WKTUk?CCXOya)ZW;bl7*|1+ z$7A0gfvvn`P$T6iWcd#OTdFZ&(sX_NZBMs9HBn7S-lDb&n2epNYQ_2WqXjtx%6D}NZ!43Q*{}13cIJuliO!^i zkT=m*sRLtgM%P13%MR;z2z!ZmP+fPLNnn>j{7f2Iipex|W_Q#Uj4 z7$pp13a#A>u5^qF2Gjd0KH_+i&tUS>z*oX1ew5N-D+L`~u+oqt4)tl3@#hW15|#s2 zMK~iOEa?RLwXgN_v>4~ZkOuWV$Gn0hW4*QDK$K#L&1$3y+l(XT4qt+o2jc=eh;2U? ze)?AAsrX}iGFIaw*#lUA?Mbe zBO1%0^p1YgEi{!ho(CEkCMh=_uYPT@)a>U#3F6i@z*N+OT`al-lDa#iAhZ>S`OIkQ z(eccDrp#R?AU*Ih{|P2HRt@f4sd?i`T|?k$-k`uZApKDv>N2yt1|5QcYasTKOO3v# zd4hw07qFE!8dRSP1Y%YWn^oTpK*d))Jj_zfI%FN%=Lg)}h)Fi+FIs3E9CCFOTfw%V zfnS+oV<147NRP4Er^;?JFqtSxAH>qMAFkR7I^Aj`i93z%Tlz+peZ@x`9ysUBU9~yk zs^a;AbC+LOQ0ic1b*!q00Zu=t*dn;#`AaV^29OCvvRWOXtLI_h!!nI%vXoo)mIpD5 zbb!zSD{VyK>{2LweCWrI9*-`ZnO8?m3ymqcCCm?B7RedFM6k&YErIHxf?e>?^rRhT zW3HCZjlIQRfDS8Rw~6@^K%JQLg)wKfbKw!l5|CQz46Cs<>dC)wcqIN5^{JxRHJCBo zqy?Dh$=jX%8TRV0AXo@Ragqo2Y5Sla<7Qas+#d+0A)#F%ah|@dFs9xBAqgD{bdswv z!fDKDg@j7D%=he`IYyd^sU?EbMfP(@wA-4tBeiLtZhvDrY!v6Kn-*kle?LR7PW)S3 zhix#`*x&T5IIU~~ieJ1soQXtnt1B4W4pZco9xLV(b>Fbgb*OEbkSeqbWr1_XN~olH zZ4f;Z9wI$6gN3IK&d4JKDae#I_kSx?Zi)*pCzD5!E2Ga5M&R_pXJ?j-m`9bz1t=TS znW<0Y$}2ui?5AOlU_z#<98B@aVX{7MZ?{W>xw_23fWtEBfw~G*YEWy^LfBdWqw%j@ z+6lW;N~FT3QM09@CA_5^802dplZi%CVi75@E5@|A2YAoki*UX?} z^-0|4Xk!SP7*voms0~lx8UU5 zW_cBCr;8LepueeWuZ{$jk2LwD9|9B$wJvaj69O6*lz;Ff)Si!olg0&1`FXUu5^WUV zyow)3mhUWAO7v2b#xfokQD)WzEi?heFIgSV%w{M=mp!%}2IQ614mv8CdyTKbIb|(|K=4Foo-gHI7LhO|sJkFNv*xjqLg|vqutbN{|pHT#d}is%$0= zmz;t04<_vduEKMMp@|>NuqlDT4k7j#Cia=>g8&c63+5@+K0uME{sX@i^_Ka{^Q|j? z!psLMKa#~wM;c3}YS&RQrC`Fyg&GlcmMR7-{tSp-8uf4j#?m`n( zM3(a!(N_wlRo>1TD^uYAgECbOOk@{Z9VhO+ANEBqp4oD5oGE;bUfR2-1+zf&hel8(6YU$k7!4|Mr_1%ksv| zS6=4vyuU|mA5H2Af;!eSz7^!+OyqzfB(t)|;N(SFn$iY^4;(9Sz)4`bWv6|LN9r1L zzT+_ZnPfjBOnYK|ITMppDI@LVUzvqDe$Zblr*D|%7+{k>V_|V}zM)-w#vVFS`@p&V z=(A9U7%6g}X%!c5uKUW=vAeU!F?knj7b7BNGHr&h?7dgvRxz~P0uLbCfw4iF$dX7) zO=)`x<)YhO5Qq&=vMfNyWss1qzw%)YfuYd!Bo{mu6IY-FpW0b~HJd>6+w zvZV1cfHlm+m*zdz-{;Qf3ayGq!oxPzI;`-=-;jl)zM*&~K?Yb=v_5tn%P1q{s$UjVtcXbWTIZj&o2<0V%)xoM-eQ6eQLq4!OGn^z6P_Jgz zSu@s;loQb7F$5pW{9xhoN8E-&SnC1`_Yr`$rfWDl#2Q6PRDAgRz5O zvoXu#IEm6+yJ)k9+5Ng^|P72ySNqiE~(1uvG5Ls9sS zn9!b*EckeqQ3FfBVK$j*OaZUORWyMPR&iT4Gc+4V3$2Ib%TY9;JB2m1rBR;6iFxfE zLxcx+fbyH|QYa(lluZNG^!KjX!Y7HLp{OL)sKUQ+RCj7dgrtyp-`|h*^O3WTd8K&C zj*W^T`kFIKklgdE<0^%@!B;1WoQTKFd`hpnsDz#p`_K@x6yv%B=R@%EOcS41zq1oE zMVPqYzNNBs!LcgsA-?e}lgPR(7N5(^yM?AP1zh3V4!AC*Y*a-U%&R>_&;{Vj5jVcC z&obwx9+rjj3Ic@J4zOe{t%8qbc?5pFuY(b)Zun6W2o_n?*Sm3DN3fKh#bR+O*d7sa zMo{z8)Xa|+?20tm97>gWA|11avNw`crN^-NHb=;{G*3{WKuiCLv*SnXIL-dc5GiX8 zDbKteUUtkC?VP23wbC$L_TF;xV|oZ}X8P8i1s}_VJx)aJb&tW(_MFkdj>fXGS_ZP> z-Z(K9pKgvd5?>kAh^O!7Em}xFR$q{olmNJ2 zWpcz?qzv}YXgeV1F|{pQ_pUMK|N5dc9Iy7($6dUXl(|Gg_aI43pxJux4 zsH($lNy7hf^UfKQn$Wbc;vlxn>ah_Odg%Ru%2h&FNigea$OvNAun;vcO+=A8BOdBN zDPn4tDm6yGq-KfiNqccw2H%abC=U&br#HS&sZ7@=i+R(e|6ADikk*eYu z2|MBZliz>QHWUtws~uzR^S zGX^pzFYA=fFH3*s_O!bMO#CD@qtA0c8g-tC)~)DAqX$c1FI`-&;-2E;L;_bvdd4Ig!K)EZ!7Bh^QUe1;0y2TI zG)0W%vSkVn0h*eD44DcHatt(IW^0})L8U21HDwZ>5$9y5@QC!2v~7Qqc-MKK1<1I| z%J(5_u4Zh_S#J$jM83-6H!{vWy<)MJYwLpi)5o5+Vt4E`65&EWg0RsIWM)e43Erdr zwA^)GJOSjbUOH#Vnkz+}68sb#iq@#Djk8l;MMvV7FnmW;Y(#H*)I!##!8oF=uka2Lb?m4y@$3!Hu7T`WR(Ite{7ioX#BHh_v8lRa(@bzo z)2Gz^25}PQDioI&9MR!q#xmH{o!WaAjti_Gi6}PnT^38xwS4=@*AM&FNY?%~Xndw>H#nu=AXLhT+ zhb=AONU_fYa4U7HsN^*wO~>0vl*BHGH79dn+#mRRE3#9jK!dPjBTj4d^$&klRkI8sc$Sa28cW3 z8^cg&moAztY*OqSqBa%vCF-Fz4R@Dljco>^OAH*_QbFt-n^!OdjIkhOQXCU9L%D~b zHcrCZ51g9(3nv#J#&rr-^lN8E(HWqV<-;EQxQ;0pCW+x5b*5aR@17Rh07(bq#i?B@yKQ96vs*n^Dc9NRUN_6aJbzKUa zft2i*=`NwmC)5iG<neLa#jQg+#jJB{taDnm}&A>b0MTVRP+y$ygm39ao(Hk_dgfh(AN3cdt z5=Rh23I;^b3QhE6V%j;&^}3cslBaLxIj~(q{CE1f3$E&X8-y=9;q0@?ok3K>-fb24 zMW;^I9P^4%aYL`}6}fqzK~%dEh#J|zn8hf@pO-K$>t+|^FE*Kc-pMomp^t}ut3Xm# zj@ND`-vS%B%W+6S>~s;4==fSa?+ww*<$v^n6keyUuKtqbuzuTGsbJejJUNI=3gepI zQS?pY6`>L~MHuI3%Jr}J2zi<*4_IDVAat#pmU+AN|3ZHwL7wyn;QYeTln zkn_n<&)qqx+_e03iSfYwVF>1a0^f<4UiKZw%KEsEFC`p8&u8PWVIF(*eHhIr_7lI= zbhI6PYT!iJ`b3K;wN4kDj);1d+ia(T?VOBsog21Yk}=!GQ(e~*+tp{fZt=p6&QaP? zZ=i_(qexl+?ou)m7E#VKPmCy4!TC_$-XU!kW(+GABn8zFlZ5rnqyM~ESe*tp%rgF zX*xC?n@$5K!YI)pr+HC1p4^htes&~hV$>hBA`JDbRhJPF?uz?{10mcJWpikQX<6E^ye7z$8QTpH7Wj1q&UFGv)(tt`*B;|MQ^!7e{ev?u>iVv}9fCObtl z1RgDtYpW(PIof^6Pgp|Y21et3nqaXD}%y?bA!S;d*dOn zYw#^XqB)!zFt0iMbr?Ik1z3ksu3CoUikd{O#JSIeP{K3tjCMxnS>us(O2M`ZzpkZ6 z=vea{gI9qxp>u)LD7a2yW-bN;id45V62%og`Z9<&sb8W>%XUI_?!gC!O8mrNM{~fO z^tTOVHEu7#jV*gO1h+QueN)IlcO>YJmW0JDW336GB=Me0NMWRwkTCi;kf;rtu)`T= z+{RXF?9<5V<}8&Es8uIyllQ9B^@C?GBZ(J+RF)!eKODREFjczq|Y6tarm zvtS#wqB|~Il}=^=j$AMKh{_WA9*i>rV+!PG2iI-MI2Ep=#baCPs*^Ko)aoE`DG5db zs#=3#E2X;iCgNAH*AZ3_lq5Lz5F8;slD+jcW{U-DH6zPCt|sG$Jw53<-EdUXlN5q% zFgnyTNUp|bHIzp7gt24V6Z%oBSy<7n%Z7w-mY*l+)2?n(<~`*C~kf|C2vv=C>Y(A=mp8zA}iTh%gkA6O5V3{ z<+yDjecRflZELC8HtycUMtUoofWK_~;J|jDJQMXSA=C{UmuiKn=dd6c>$Zl>VFxVK z?X-jVua!k&A&^@m#x0KARSq5lkLmCe&b<$T6)Ma~rq1Hgm!0_3OpYDSy!B9O-x(rZ z)!iHw1!KB1)}ybY##>d#_$iKR8vWd1$l@q)kUJ1Q@z<66=A1=lfm(M~&y{Z)D=Q9w z98>+liv=LV6v$~I_^bHT++`dk2prqLp;F!S!z=WOBzGC?9G}D1qva=bR^mkBgg^{# zPLTg0BTrHf)%ZJ*75XPh8s}X@0mijcrXMkFGWZ+vyV3SRqT3&uPT`vFBaKT6h9Y;y zvbl9!ljgnV@E@<4|QIX{}J-;A)UpDghi~bcNBIc0@_xKvxM3nZ2zw$3~ z-+9y^hk6t>DB0=6ZGRD7gcspOco81p6)$T?5fLE*tK1%LUn9uEjlDfwP1Hv8(}3e| z;#2t7ZW-X2p5^)!V#m8!SVYvXVt{r`5HaAe17v4}hA8JtzFI&J_`#&Z&Q5(UICa25JI^v=a{kT!)|eQSOp zf2d=SR3B;_yY@CHtr3^I{dn>J`eo9_y0}uVdo4!4BeMHq&Ua*Q9dQ>hcwX~Hcfvgo z=wHN$8(~CPEAFB-D&%!*H#uua%QB~=idxTa(8zko| za<7M>-vv4JyKrj03p@83cWYcFEpcxJp;){kE+~fTznxm*QP4+07IVs4I5aiqxen^X zP*e>c>kqG*eUZIfkB6gVH`n9goL91ooef1qJ0hvIxPysBMEoiC(QU_K^riy35m?OO zdFakAJLb7GovRwb^BNA3kVu|nhxvVPEM77<2}lF zhAE(}vH-QTl)FCVeY-FGhkh|fvH+{=r(d?e+r7p#(Ap0P)EZRB1e$f;@C|HxQfZtv zH)YqYw+a+#r{mHig#X{<3W&w2CAZeS8KVuDbJKfPPI+F2Ac}s>!VR&~a7w?2O*3%G zxXx5NrIF%z4apEUfQ&JnO{1o9)5Jc8E!zR-2B@|e_!n>``pga>zm?-uOrJ|48ij z`A*_FPVs{+T!|5LbCclXXR)_zJZGvt+L?7k70B|zy^Ogdb!g} zUq{&gPx{vWH_5a0NZe3MBS z!B^cIE+(myV_p-_d*_?77z9myn4o!^g`r1-+XZ3~V)*h989su{AdPGtI841=LzO;^ z{a|m=z82eD0{u0(d$cNjJhl>|Q>G^T#@eyjl9=Tad}-{>&_@Hi(5;1`G33;F80#Ds zP5M38&q>S4ljN^^>w47@>Kiw3a=mDZZs}q&DX7p#-QNiiUsAonQuOKpX@QsllUuVS z8NsLyHCk>#C=D^hPZ;5qeaeBdXOtwRu&N^M@G-ygd{q0&d`J+fZme_69?C;% zuLt^3+ja)Hx__xaEKIY(qkviB40st)o=9E!F{x6&wbI{rD3Yq0REc%}9A8+!2mW_eN30+I^q8nasl#rxaoGaptG>5D-pLkWX3B!=>feynHoiIME%bW)r#MoL!VkSGm6?YTDF`%X&DpJXoaoZeQz3# z4oQ*`mkIl^W#>|nwjQYuPGAt@j5r&8(|gyaBewd_st5xk#h|6P}g2+n2jO!;+5tV9iB)azst)nmH~maLTOqBAS=ddGSUYW2{$1qBT>o<$`@L~vO(`n&z=!&% zcN=34uD4&{&nr&ZYwzm>bfMs znXCSl6_@;5R0qE#|2XBpU-|lX>u36ZXH+L|_*+4(`7pI(t&=5OTD70NRUltG6!$a2 zol#lCBaVPpQ8wNCojc`~8t;Kvx_7!aDs^Apc@C@((!hoRdn4;9c!sQ2MbgvC*>}A= zJv4<;#6*gUjj1*Fe?}=IKYKB+Vyq@Tl(FbKM$Hv}n^G||1CRj6+##`oHZv~$5^SY` zkz&bWSsIUFLi1egRqQOVc6UyR31-Aj!Bg^?*{kM6Gu25_da*pknkuWBi(@B2D!+tA z?j||=*7q)&OB0>>%;H^_j|a0HwAA{Ho+n_jhxL8Q0`gc+bSp!j#Ufp~@9w99rQ>nW zPt()R!-GHm=I57H8$GbW+I)NCmEZXy&$qshsm|QmrMG=m3q2bFy^@acMiI;RTNg?W zp{ZQcavfjwBGx%q?gvYC904Jsl)oEd-rU8wtRBAhw9fDq;MeGRNQ=X>kfjVgn2~2J zL-q^O`njSz`GP^YtGh zYaM+3j)bNk|EJ3&vNWFUjcLsdnHY-xQy7CU|)x}P1Nz!Tfdv4v`c!uq2YVK4*ZFgz0U-Ofh_4n^EVmiAs z^X}Q)0sL%jxE^!;wSem}3_pNJwb|M9+!%1hHKbGiBLc1X4Q(Bwy^Z%MiN@|1VrKS3 zL=&9SR?srFsn`nJ*f(AVg07zcu;KVKIaD- ztrx|>fW5irPWB-9i8sqR1qRWK*U3w51p)6Xc)5t(r5*%-Y{g1Urq+vMYIM4&&y{QM z>sPqq(a(ytRUL5o5vA$?=ef+v7H+!1EaMlwg^$^war}F-8$@^Kz%s=QpSl_q5hH%$ zG>QWG*s+81_@0d#pBr=yeD%eb2N1gEQPN>-mXRzDyDh|b@O}X5p#MpFpe=pxXUsp4 zw#)CcG4$x-29tmBRX^JY1FyBZDOM#!8x~Oef)+Tpq220$SFKmYKz{5xv)14bb0}1U z@V>Qbf;z!nORVJ=K1M`pD_@MX=*qSK>hCcJv0B|xw0>n(4gB4X#P=Y-FXV2u!hio? zDTCtiixtOy1yaZ6J_FxpgPf{>_jp!njg@>UqbXqGU0fM9N?&v`Y9%2sS7x??SCfxy ziFA<(&iY0}QMTsTra)@g+;>5_#7SA5B_p+dI{tnM2-HitJ12n!`r)UBK}Wx1H+E0t z`O*eixqW2buRk@h6I9Q06?v^($+w*mZb$#^biP3Dbb8)~mxN_mYq{6AUY)Hxj~Nfe zUf}Z8huRT1N66;A@mhL&&2tUb1rhS@>7kBn+|)?B!!s|wCVKq2mVHhd{U_SFN0FD` z-;vxRNgt=@f39=p?5`fzkEGZ6FB#6Am>{XqT8u0hw>>u&ZE=3E zdZhcq9Y+YVrsR6<>FVOSm)J$_*Zmu^^mI<@leE5)fDX0}B*0)ZsSx|vQ|?@|2l40# z^~L7~@%N^FtG(9r`;I+5UHavhW63|d;T^GB__=YH?@C2nV^FY8PWvxT&qyx&Uj5?g zaw#>`0C8{MyKON2W7HWKJ7;k$D6vJ z4O2lpAb4Ky8Y(Znb$?;_oEhPt;WHq1OpxG7#p(k;$ASGMGy&KNU!#c`{S_HIq8MI#d?)3R?2r;9aAc#XwSBd3#DYez)Lz zYWW^du`i{*@_?qw@)J~>^7ENwcOUU-XuJw#zHyuvrmf&$es#l)2A{s#EU{Hm8iDWf zzWB9kAqoFDj|kIt=6q6Xv!tz(5+`GN)A>kr;$2B@OdurX1jH&1cGnKbXpm?6*0jXk zZe{i@iQQY77tsB90Q1voSANu8Nu19F{_vPggXqI=WwY^sZI;+7DVw0AP@LkftXUd_ ze_T3b8u)`irkPV?n;%X?c-GP_BiiKM(B>E^jR8A6(u z>xl{cVLzD$(Z#q#V2w`_0j`^}SVIUt!Aquz=o9Ui8Er@1$*5z8q&$+;YpoW%KgRw~iTM*_eloWoGm5`G z3Klou>%hM1lz%E(&6R>t4CHySI08etK@0 zV?hWURyV-(ua&p*sj=q!N(*cYp5T*Wo+=E{hMB5Jc&_3+4eA;5d0CRGDhR0f7z%H7 zG~9@v9z5T|=Qp6+XyMx+p&O;Xf2z+_W2nYxJhX@M6@^tN9ncCq)q%Sms5*7T5#2kKY@=iI$hqAwBPkuO zpb3gykOZY062%;y{XGdI>t9e3F0hB8yXlp3yC+QUiQG82hFFcwg?yc5nmyKSMC9h> zsmoj>G?m|IPu=ye2%$SdjP*APnJ3ZW{)XNJ$@qB=?vD|>{L#dr13FfY-Tu)LJeKhBqN z?9glZiwc_(IZ_U^`8rYO>s%Rb4AM_A@O1PBf>&@@$%9nLcx5q;jK9f~b>^BY{h^RQ z_@fMf3rP@5*c-4b)7?$E;UwW*DeY19I8ocFiXq1p==VI5$^p3vl23t zS-RZ=w)a&I^P39W5?NY~wF<_c0eMc)-cVLZ2PYsEq<;-l*?)u3I@dZZiE}j1{ZC;% zD%~eq38v?vrp&$*soXDYoN@!dstgnmPcRWpail2z-{1(ab%xK?d-QE}iF#O*x|W%f zzFB=NOJmAFVU3dJ4Q7Ln0z6wX1i&^dGsA0nxB!mmIIE#@TKV4Dt@r3mdA`n+-D-6q z_v^d^nP!Ac$PHJNA>^Kv^?9AYW;G`{%+EA>m+s=Z)bKYT0RICxwb<8vf4{Wf+aGQk zjd|Uhb#_zHO4qp+3hZcQi$&dVt>&M!> zuhe-j)I2LBx%awr#R^Hnaz&)A85w_y*pt2S{+bO!orAQd305Rj86#GN3Dg!=XTb5c z8y{p{!jib#(P8>j*TjFs@6|oSihiDhPwd>)X6~e#cP^5gbA&NlfeBJ8KnXc0ntYl~Ws$hvEfdr|Kp>>LDX4$`y{6 zz~N(agM8B)L4u@C@AZKh&BZEnLE4yLMMyHuMT2D(CkW2iWS!jW4au7Wax1Msn6ASM zfiQe*-mc70I1xmi6O_$|P@S}>h>SEM)j?;p;odce(Ww?x0J7p7-a=m(FoBtSB$r9h zK(iTuqBHzD>O35l#BE1Zq&q-?7?#AjFu=iQjBI#tvBHn(p3LiGGBYmHAVj^uQ;@`?k;S{l*jfIa`2h(b%oaq7 z1IwTjCAJtsZD{1#1VFgRVpBz zIYoHERdmmO9uHxMLOSZ_kS((lB?_Eq_VzH10Sjr6iE!rgpQj`VsdU-cYY-lfL7@#Y zBeF)yMV@0*VN5>2Uz&G!^?wg$vdlK4rToWWlnvj*Jp9CxNvjC0Hjd*IMk-qLgZ4{x|m`60(# zgH<iou>Y$ z2(>nda4U^kAAl*{wk27bkEE(}Sq)o*lt2|6noqLe=6z&7Ee1H5gj#k7EH6P~pxAv4 zodfm;7)p*!84-*UKADS7c5!nF3lj7K3VDiNkavD4|3Q50un`LifMF6J$ls?{-HojmXaVr#89jJPgjG z^I>%{{qSOEacx01F3u`0zX%CjgqmNJfe7hVuhVIohm|h1K!nLF&ard0S~_>G zBOTS_+?-AV0S<$!$H$h>vz7Wv5Kw|8zAKV_&_^$TwSDJlB#rytFU1rHFYtXI_TccB zdscqMmP-6f8yUZ}mA*&&2qWWI%chLL-sIv#!*v}MiI64;QBKMClsUyiA@7$>>Dpkb zACEZE+kav6-rCmIcrX~v#%Q}8aj=8O-1g3BETkssOoR$suCE$iT^~=s zrdd&8L&N3kTnNSYl<;>0UKR2j*^#7$Zp4;Zr{w=5zlh}L$jb+AnjM2})jG!tzobsp zoL;WTOjxY&!K_xpShjLlID49kTvZDFxR7tZG{KCs5ubk{g#7>KSZs9Z z`!XOOE+E?~V6kmek+m*Iib5KUQYzp>4xM+1eP0WHtAaCf09S}S`9@9%$GY}Qj!!^$ z%6A2VBs$lN1?=Xf3uj2qyvhe*4(c z=fi6OKNBDzO?x>f6aI`0da#^9Wn_(vxRC!#{yq6V^0iB&p46YJ+#SUaG@f;zb#FMr z-*$x~Ia{`t8Y6w^O=Yhv*ukO1wvU_y_t9Epd}@YiR=RnClvfmrIU$#FEpaZ5sUBH6 z-s~G}kPF&i8jyhH0mAiAT$s&{srywwD(73*i?lak7OosB^!Xen;)lxdhYnAKsl-^o33g<71ZEIXOR zLqY>!3&SHn*`&~~^)YqoTX$q&M$u`Xf}$}HX)r`7#1nE@l0eR485?6N3WLDrYnYY` z7+0ASw5p?xK_jY_^mT;ZT|D^A>tkg*5Gyi&uSa(lyHxn-9b4MnK!U4o9)^Zi<;F)O z43OmM*Q)Xr0bz~FD5_=c-$&ML%p()s8u2x~Xpq35eYjZz}?fDuU)4jOq zy%@o3*ZAA6o`_yI;WX`i^wc8{K9{e!_y~OOhCPsUZ$M^mAkA;w08RLGL!}&4KB?#9 zwIg37Y*S*ZJ1WHrH!X!oMVCNshXsHMUgI=}$;Ux~I=>(=OaQ@v3Dba8A1vvmo;h06 zOn`a?2f@AZNqv+{+NKwhz66`Jj%^>y>v^?9J7~yd!$_VZ;(AM@Vyq1}}9{X!^hjopPgLdV&zzps)WbX?5D|Z|^)|f4HsB1hy zCvRg%c2NzpTKKlznB>~%*FZ`&MOa9^A{Nb~k)~>`s#;c=)Hoc6g!%C#J_f7&BG0Ru z!6wr}`x-h58y|`bx)p31W#GJ33$v?nmT(t~rfxwi*7-fC1lvKm%j8BeoE));Ba<8?Z}ekI;Hj+gB(+et+!RBa|Yklt2O)0qyu= zwjTQg`itjF$vqe|I4}hae0$--)b)-2nE$(ywym8YsXEjZo_8^@H40~FK+;V=4$pdq zr!B~piQ>%i=S&7tXLHPgVJv!y2h+dzJcI9>ccb@Z{Q#wq`#e1D13h!IhM_So91_)J z14?rE9f(G$_)`1j`%isCq+N^CG`)8J&h{N|#l;Qy-X%LD>0W}&UP6~Hfe0P6+nnan zK|`z%vD}Uq2*r07xOM=bi(|n|yM9-V5C(U_Z6i8l3!GT`dzZHb`-A&}dxLv|2ZIMz z&;~8(6OEw(@&m(Sr;TnY16u%0jXyuhvhr-Np%q&58ilYdnYjkJA}nynvkGltrAST% zouC)A75Bge0m{P;+bdX=8opn<$>LkWcBPTbqaD9k-rO+J*qD|ns4KeQyv;DmZSEHc zj*m&4TGJGmp@m{i88+~|MBq}qZ!9T_CIka}|5%Qf#T8eUVP~h`IiB}@oVpsVx8Km> zsh-)>*E8ttNq9WoE+MDh>QDPOtjl%Aqpy?58?X>IT>D_3T^1d+vr499t?zQlk|VA2 zKTIOYtV@oHXv z_5bdGr^rI#7x}V%0|I|D1)KSm&3tGRA6Tolh&sb%cT3azhMVBpBQ%#zMHrm@8{qvy z{UfohNJo#~CAoPWBfwne9f`AF9)CXIv*~*hzM^j?tREBJH!<0rQ+{Y*Jeo~jZ*RGU zls}T5k!Nqjb>pvVAotzue*$Fxy%d?>O}@gqMCqKEX-A|-kV|eVFTLe7Z2Cd`Qt?QiYC^np^))HXFU9X7y%lj&$khX; z8-uAqtcCKbESS4l+El$I`SP3)(rNiM9MZ0h!pjZkxH5YF-JFoRGk|7{seVMg0Zk zth2ZN%=|p1X9k2qj4*=p0=+dx@Tw00R02ZL5CBD~2vef;E(S9+U@<59C<3m_2_jC6 zA)m|2`sUf^G3=u?N!JfL^&0NKbO`S(ua2?!4dlp;N)6B6S~4CCf}qA zApwx3l{9VXx7$KN3|44bDXB)Vq6JWl*tNcOYuu4Mv&v6iwLOPf?Dw#wVU-8}R;^M{ zB*}*-J&Zw&hWzyFyHJhcJIhF0@5K$354Xkfbwgl5|g zo$dF%**HPgIjx~kKuBz|k0; z><|2oXb-xWuAu5;+@NKc`6lpx9=<4~o`GWH>IBu$@_xypU!QE4$BZ(^f*;^6Lzz9} zC}DkFu6_q>8JqZoP_nYo2ES!vH8jU7M_v;CFhq;E17mb2Rx2AdRT!E=ksI9xt=b-j z%oh-ARkmR}ErgV^(0k>PeYI7~^#Ga&AXQTin6V$)$^wwcsRl}=T;TJO$B(nBL-nMC zrsYPN0^0N}pukiom?Fsa*N&oVH>2)BccYy5IfBwE(`9jnO~){eoJ)w0{o_i)DvGSX zq_8XY)(?p*>A&LtsDns*hp#g&AoBCB${m13mRjf3J0Qg%R82X6x`ynBukc!3gHVFT zMF`cMTA^1Gmlk3Noi^qRdEcY}$uL!lnx~7nrdATZg(fTLamyBRSGrE2hZjO-JT`$0 zRxr2=$6$9X*O8^BwMl`?Foug`zP<_%Ni=JduV{LL`$jZp0{o($FBdn`bdb@KB3ccuaE=Zf_bp;#Lq6O9HA> zb38f7WDF5O53}Q0~4L^mg-pU8U`gGnBP9=hxXQ`iq1%J6J#7 zz7Ao1N@QWM0;!Yzs{5(coMENI5V{a)7Kg)4VeB2;kXVNs^A`+Z?`d~KKCt_WG|fxT ztlpagZPb)#ZKT>g{Zkj9MyJ$&JfOZB(_|3Pr17aJ+ki_*y-Usn+gj5nTSjv`LKAOe zMq}`%MCF1tstVY<=yDENaSMW-{(es#spApt(`HxmnkMbn8;?Czc6hH$nEB(KJ1Soi zg#N}8_)e#=5)gC?j2x*<^L8p?TGN=2nOgh^VNtT$aO7=wWlR+KK&9FhOl4H6RqGHe zfnJ~PX*s;g zcQsp3S_|1*Q)7bZcxG_(5rsO+BsIY(r`s8)Vu?(pL8SVoab! zb+Tkj8auYr8{7L9wS6UDMvyZNNOKAyDvpVMlvVjDy1-4Ywt1h$Zrycvi4`+MXfcjX z!C0PBsW2gFX1-d+$nv;bb)pvr7Z)4!2XV3fAQ9NbyE$cx=T~Bp-)y=_42vnq4;@01XYmAs+zGT)0=)irKt% zp)UJ{(tK4K-5nh*IKJ(K4OVjf2)8&$YA}42KjUSpTV!)Gd=oTW8@0w#whItLnn-zm z7j47XHe7~wR`QZT{g)afi*X#9Kxe+Ak`;G-naLL$w5rM#hJecO7kr+nr&3MT4C7J8 zJyA*Jyj}sJYFo5Aqm9Wb_1%aTkM5>{6&M569+;P-jkiyc7&+YH4@jP1EH^hXV^Mj@ z19B@Juuv`Y4GPKCGhB|g7I|)1Xi3`3sNbXt0~qjWdgnAH28uGNpO1go{P40@kA$3A z+evJ_ahY0xrnW)^*bid;%Eik=)r<)+Ff5{!c5_{bHg z9KiSZ)O{GND^8OO2utoFAVAw{{W|xNlAqL@ZrQx`qU+3)yJSD%(C$vBKirM>n;9$Q z?)(p4r^z0+u2;8Qrp5E;++&A1S9l*mv&nxMFZX~98eq&+aOEPj8hoKgk*hX&ES44M zYmb!4Qh>cIo2LLq9Mi0*6)V#w*^M6HoHfzg1P7(l5Kf&_p{z#Ws{ zLp;Jc$SEC#a>y|UY_Euf=9=i9M~-Qh7drw2Cg$Z0uAF)c?@-L;SPS?4@Bd_4r^%;LO)vj6qSqy~kzv}1(fpSlFgI#@WsjGm5h0+3 zF=<<&&VAqcEJZHJH*o2C13qW(TaV|ZSKb$i^%9SI!vlJ~aNwy~Y&XO+A>*}s>Jm%h zI24<`11gtt4olpku|8hsF@$0+>GV9eh4X3LsuO-1B0FtVM!f7S3#wabb^3uT-Z_*9 z9zw0V_!lrC#VqYEqs;7O8F+)P7bT|tHIf3PVl3VGdhAs8m41%02Dr9907Fik?x&-` zQ?3Pk@SWgFBrsx=<|0}#BdE33q4(`(-2c5M=HtB2<n=F#uj7rk$b&6uVh6WUWEt((lgVYTz3e7qH+8wo37zG3gME>Y`)m1g(xnKG| zLg~I;+oF#UvdA_a(s4l>;2;YTqD>{M*f~M=DS^Y_3a1>zP=3k2OV})vQDkm`MNRi;ECpls@v!3d-leNQT^Lw}zlKsOT9L??7dm(XBG&(E} zP;~Ku4ZhgttKO*h%`(hl_nT!@#xdG_=eE49RvMDc8c|ELG>lBlxiOE{-n4(9Kjjb? zwjutY$9_1AVOqV$!9NcRP3mfo$1ok%hn}xtU2%=gzcrE16I2=|3Kvvv`SPAyw0in@ z=E-dUS$k8w!Yu$D1zpl>-J4bUwG@wuqq*q)@8sDM+PS$q@5z~S$aOiDo8oV~+@H8W zqPapRw(j3HR_O>od8@zJ3wTkUE$OmC@xNxFhvlWv&GN+}DX)2K7gEXpJ9*vrJ?|)A zD~}hxvf$|oj@Z7QtqPZ%8@yu9GYnr9_`eu>#9t2G=3goDc-~@yM94o{K4;IcyfHo> z4+LKjc#@Ha-pECp{6gan!*lo*qoeqP{IdO2->09mFxXCx?MB6gM{Cf*Y=b?n-&eP* z$2GKq*`o~@N(H6`s7ky8$cykV{=^S*vOBK6*8UqhV6l}C+4GukV#GrF3_W0&xN9UUw;EhRO zsC_2!5D|juVqr;cETgw0SuOE#0SGzvLK6L9QDo>)GN4VCpSCqfhDhD?ad2osGPq&m zZ)?3+Z&o^y!9fhhrFLNT{N&S+S&09azZ+%Am*JPNUAQ~(K3}AwY%epU2%$uwS&ENw!ibquc&jCcoBz^V4`U}jynJBht35B`3K z?_d3klJdSPFFnG8Z6V=0@-S8D?m~{ktGY0z3e_#o4N04aJa;L0-rz%NcM8YlNIcp& z*MO5GAfCL40G>d?{xCfaw@<$}r!6u`sq61T-YBEfD@wK^@&^m!R<5M35^~j9S*h+( zQ6ABTz}6d7xN6(u)Mx-c+Lya+Rbe`L^#Vens=H|l&c$W4A(;N9`y!=O3@*uwu9WU%Ftw;jk%@m0gMD?0a)Pz}bGvPstxL zlcu1>a|tcJE1cpe2yOi{v02{$epiP38kZoD2)6Ed!b_Uzv#R^EbJuof=mC2yU#adk zJUCP<*Y72`XRqCHF0gyKl45E33ky5Ms+cCetmdfJgN59kiAc~}*FXb{Bm+w|F8bhd zmZGD|k;C1O%_+dvd6fqkd+_Ocn+K^F4)SZ=*ob&&hLG*jgxG3@$R!rk{hhrm3oJ$F z&ao4BP$#E)e3-fWo_;x3wlvm3S}YB9jq^4+I)KqOMwqfE^&``Zl3$}+Jca2sNm`@* zCBCxj#e;i3&#~I`$KtNkBjQD!p?^)v(r#}X9%#Mv5bE-#6!tfa!2v=iEsuW+p-*kwPVfu2Qj;>jANS|KNLRVSn(9MC$XfeTKFlypZOcTVX9#~7q# z=t{;>>5T9}aEvF@)D4~sD43!!(?nIWJd+dU4t8{gB#xDev@bo#C4%TIfeqfp$T&Rb zxFrOv$9Zo>k_p9^V3cx_g>(j;u=flM2iLY=67RkLOr!W{ql|<1Cq&Ykb^^wDhj&iV zM#xTJ>q#uTDzSi^y%RW15v6SLLJ*fZgd>GDgfQD;3+n&mSv|1GHgIKU;&^wr^|^p11D__bQ-Rao+XAV#F||u%FGdzbk;Uj1abI|VE1D;oyMD{fJU00_ z4z3CH%NAmy%g}Bc*zL&;x-NTnSan?Wdg|z05RvE;WNGct&2cUaCnxZl9KTUbvEV!K z^(VRVUA=gOn%Qcjm+}2a_zuaBG?H)k;}`Dy_RR+_b)G)?^wDmX^*7(Q`EB1lu=SeV zjR#CHh9ff8IC%|>`+8r`5&`{s!jkB4)_JcHy;EsmJFtzkw=wWS^aCgPH|sm__?hj+ zN&Uj^WCE_ihFrT;FCT2Qm?{sJboFoWMUA2I1wHVJU&2-62>B8eB&sf|oK*Oi`es+B z*J5^nxoi2Ai1DiYwtx;`>!cpFpW>yCU~U0t9%n-mTa^_<-O)KtosTTLaWD?6{KLRn zKNH}WmDnQK+fTlHYHh;kR2N&_leTVdMA&pk>6&^15qUbDUN^pKat zf3*ET@(0o;#+5Qnr7nznXCAi^Fj(-*C?hMYx~dX4m%>A)da3jvt2d3h7D#AnO-SLG}5Ls#m>_TtXV z{6)ODcX!iGhg8!+$jrXM@haA~A%>f(`l)r_#gmUJBh= zZR)XFvcJ(sEjR3WnOao`VNvwz?lj?Os+^x~S|}({QJ-VOa)Lv*NYk4hXYr_mUki;ht+e57q})NFZqjU_zfgc<#oSIJ>Snm-82b|(Xw zA2b}|v1d_a;B8pMSGBI=dBw8vsol;Ye-nxT8;7ANR1r%Q(Ut@RODf7~%u_P)mHFAi zF+wT1#7$5E7EqiY^A88zuF z<=xS_FjMRiK^^mJ(Ii1BopL(N;;e{8b8Tc*t&OTx50m9w3xauE>f)qOEF%~H0`@?y zU!5V=1tueW36aMdD=34H8)qvp?)H-KfSOcYLv|~|U{qe0S6&Ip77%hEX^12?eRRE@ z$3GfR^7YBvpe4NiO82;Xb}w17wS{uXk-T+7H>?WWS;LjRl9%TAv0ntBQ^mgbmSer6 zfoWUHXC^gq4z{*eY%jrsfK#7r8ZWo31T&4Z{MxI%{}dV24d${0CE422vn*uf2CLyP z94-l*Q-UbJsP^HoLkvwO7YsR8Y`zx(QALF=L4$Y|;r)Fu+O#XB)<4in*1;C&1glB{ zc%nih(peT{++y^ghFhL7MaKvzJv7JpG|yuZ%UGG(7>OJO&JFD0(NJJ)muSSfz*w`y z5t#~0R1R>@=0-!I5P^UZ5`&JosMg?|)s-3HmKbEjBSNE~9Ac#fAl_Os2wH-?@CbFo zQIzXR`IH|2MpkH$cN_9j8tPRT1Zh0Wb+sgTV`-#(It))HXz{!#RGutwT`&%+2Q8M5 zT7pXM+N9krRd@nbmY~@2k-xApyiRe+7UVhVj&)9%gOL$wA=*^plv16>fb7FTAZ$Ht zDi*}4rCNs!QL{?tUw}B5Cu&WNCTo10T4+U@@Z%MP>Htktm#YgO(rV(bknC^*-<#N) zq&tDkPLSr435bopPU%TGfL;R>bcf z)Ja?(#sQBX`#h5Y()WLW6WCy^-U(JHcDMuI+p!%=8X$^Ur;PtG(K-qC3kzM z&7DHiLwX16A0bS%^dNlEZ#ysFauUZPwkx#8xgrSgZeOqzu#?J52syePS3e`{z zgW<}tWLT663;k+C>Kjhb-LI^jXI)R?L+S*Y1SK@t)aFy7aTX#7y2)xZ3UNoK!}D6w z{FEt0@6tp`Vu~21h*B>BJk*kFQ%M&J9NO%%LS3S<%h4UXq>N3+?EBc=zq_C6y80aI zxNuz8IUq#|c#R|x3&PDB-__RTRmw>Af02^1Rk0I_Ld7P2L=-j@Ba9Yc3D0PGr}&ha zV^;;Gd7WC-njb8Q zu*z8`xKb7UI-jr#KGho8v<+fQAvShIWv>&6ID&p8Elyv{&<{~5XEVQGn8tImhkDSC z^cg+~($L-3aR@fVFdM_YYVLBDixH!`lMrF_gN5N^L5oiOH)?_)>y|*4o1pB{}R#h7|^2 zu#~$Cm@4|*ctIEQG6YQzja4=#z3zARThz6=J{}LiTc(Ku(^yIGnvC+Fv6r%O>FNjO zIKU)(Qm-nrdFy4ibt7??r0UAfMs5-L$thFbvbK{)4c!K-WI&7(eO;ZcGgu>vxcC`2iMOLOl&MDfkdvQX7n01A&5D3J6tl&dp+h~bVJplb8 zoy3m=6>%Bc^=5mE&H;lbuv0GE7alAinmZTdm>tt$b`TmQ|cT;8tbZ(;u}J zcV$N|uo%~h9k>u)V!^I*7n@;S(sSL+l#_|g$c3Cxf;tbV(2h+3B(JA*ipp(RN1cZS z*@PBkY6VCWIA&mh3_V!{t^W-&g%_wC1q8$;cG#209bbM0)^FK(N0U82KIeDBwL)s%to}ONx%3 ze+t7_+#y=jYuu(ne1gM1)t3y$k_xj2R0hE#q+x1-^PzT|N-oBsi}EHxnUmdo7~s}2X7tPzsG;s{obK{MusNFzZ~#; zK#t&BtI0~NuWw{*uNI$Hi6J__Qo{s2bC>0otpK8HHsg;f;xGg(&&0ih_Z72I_u{;~ z-nDB9xmo4W+<8(zP7yDc@Z_UrN`_@M^T);6S4!X|`KKnLqfUO$<9PWmVjNG9gkcaU zM-X}3;Qhvi*FW*j?&Y3P&|cMD*hlKZMilCQ`+Jro3@ISB@a%Yk3+Lk1>Y;S z?VH<_pKsheKIE@#^IHDl_DgLkpb%aOXG;Q<7VdoxErArz%Uo3*I03i&00=DDHY@Fg z&1XvOb?UrKoz_31*BQ9 z56y}`MrmvP)t1v#{6UScIe5lhcbG#sE9sFv3&#rZ*%=}AQ{}&~O5U213aB{4@qnaA z-pm8U57$7(w;!*&IM!rnaW)^@5EA}dQt7thXY-3p-uwCTlO8_F9NkLqN@?EQON{sx zb*ymtl6!1b?MpBuIOIV`k~@kf&~UTz2IXZ`1%J|AC;?|ObFf-(=>fy4WJ=J4wd z97p^y1FArNm;lzA3Y0s(;pi6ad5Kp!=&(VY+RJx){JDNp1|q-QqiWO0Jk=!&j}GGR zC;WEW3CE%QNqYVvC{zw*fzn}M+A6OVNCcUUa9d`eCYb|&SvCT^ zHK-1ssYAX#?v6*_Mu&|0ko3lokI}B_xbGTcdKx&TeS4fkk>2d$5Vtp1Bu}8qM@-XML4zim0*Ufst)U14>t3XUUwgg|`N9_okx6NMl#MS}?xo?Jp3ITrQ6Bj^ zVyH-DU<=}$bafmtu5xSUzFVuXp489^DcXqeYG7-<3Xh6~kcj+?cs<~v>SL7-#}f=X zL7v-;MuniZ6}*63?!-I-G5q}_b6DdhkfYuUap-RA5+tb0Avu8iaAl1a76-J@^y&8j zu$Rz69n*ppDnTkt&s^wP^cjHsgaC)DX#S0@1+?*C)Wrf*j2v#z@bNtzfWRJnN>yE~4hjNfs>zc5bMbi>Y}kSQ zfYJ(~a|95IJmxUrv*bR4gNS}F{xKq_3BMTjU@(sQM@eRxD?^v(qoQ|!&I~O!`FnWV z5L6|+a%+O#1R)R(vMZ;Iq^DHQix7=8r8{F`u~$eG=0#bEBZg9-vxe#vbjx2YW0iZ= zle&`xD`>W2o8FOg$uy)PPY?_z*?>on)@k!0Y*ZsaY{1T4Uk^!x7a8!T+P0H9c|em} zei{pZh**rF@Liq3x-YlY0g2+fttpcgUO+9#$L3@=8*=F3qbFR}*bRB*bnp___lNn1 znU{4IYkbIGqT5XJpU#?@&lH9@uj||OKbcjM42SEQ?L0(44LI9Js5s`LCbx-f5+)7B zOjRfZ{MCDNy&N+Mh-@@8A0|T-M|?<@Ma37=#0tX*nM{YIjHK*`w(`k2z}$VS^X^>& zyvFab?G>Ka=>T2Ta5u@4pu1EJVB?@LxrU9v5nN2fKhY{<>Pt^4N|}rq0q0jnYO9Ui zg(yay%=8#Z#eRvN z)?8UfUUct^0YYiy*9&rz`%(rABy|*7&gg4|PCcTggNBs#YFer)RavesM{3Wj%xe6g z4kM2|#<;UaAMomsYkq+b%UQ$)qpI#K#lQSt~2 zmO9~jQ&Eg6WW0jekj60v91j*d@Lr+=YZ)>Ye1H7pfA1gxuzy=3NNt%j{u;uG5JsaD z;gow{kc>Le9QtsbAUs)mr!dLDce{S@96$Co;s0rb4Z*?4Xvjf-dwVqQzWN0?ArB*S zGum5dEjU~uM(tb8BN#P#m?`Ovt$L7;LF*49OHsEU=TPlr7Z5wBw{Mj9)=&J+9l(P( zZwv?Hoi6gr{!$e`2L~S_l!xV|6AJ7G{Ze5J$BynRnf#~q9&dK8aCt@S8NR``z)%)P z@ilDRZt%_8khj-vN5G&7+RCjT3iWHeW+>TtZII!k;hWIsPT)f$I2tL0V26-p82wPe zdPq0QhHk_)H8EoEVc%x zFA`JkVr`l{TKBTR?eM%49};*zg3LuN;T(^nJ+Sq^J~}8=#=HzBtn1;&kvR(4xD0Ad zA0=h?PIr^BpgQ3x{$wBi-Z1v?eTJy=#u?!yx(5&1HQ7R^f_ATmYeRb;4?_lzQPh>dO!Y@sNA zNSJkmt~fI2t$29K)?JT12sqIdUE7^s&Shs?$OLuie=NJ_rp<-jj}L4Tm_qo z*SZdIY>A>>dO|yx#casPAn%l-w@SNA8%LMtSgm`ZJ+b$hR^fP`?yPKOE3_9q6*w{A zF|I2a+zu{9ue;OC1Tr!4hI+z48|gmT%(YOmN*qe+hE;W*{-XlL)r$=n%+Tcpg%;zW z=lpirnJ%EdaE^7kV(c;yZ*-GxLtO?Ub-mmPx7NLzeCmA*kI~5g&f8h^&@$|5`B9j; z~^h zy`~P7TfCW1p$NK`nJB#l6nVvyVKp}sIP6e-p5b~H?5e*VXiRj#j}RJ(#^ekImvxV% zeL^{bS<$gf`%2e~-|CcSu6;{)=)yY9Cg_0k&~=bzMQ3we*r^8NhT#Bf0j+o|sg~I3 zeing36p9kPIH^QJDS<0MB@!SWg3KU@&8XCnaL!yDD{C~R_e9;rF?So65Kov%%mS6* zp)+q!tovt4KG)&>Y?!k=@^8|T5h77!>pYuSXwt5QW~Y-wMkypc9mdn4P5l@A4!+rY z<^$<`OC%j@^SM&zGoz2DC26WBNeDOhp@jXZ?R2!p4_t-9040jAsCUTlB<+l@>Okso zCy)7{=$827>1y2WDJcpbDdd_2mWH!TnNM`BFGWh{z|1062~{w2gvE$EXhJ7%JZBM< zI_~h^u^8t)h3Tj;1M}nXIM^K&D+YBR)`wk4x~ekUR`bE2Q`SyryoC846qRB(apam* zksDbIlnwH@-_^2KNOcprox85Kp7JL_W$|ldD3X*sB?=T6OIqQJ%LFS6^N^yalK!+~ z>dq=mVRSHBg8mTOYJR0T-47txnbAraEwDP+jADpeFl8GD0i$+^b+8ciZ`vb%3>ZUw z!b0x6JH=OCi(LkGYAk;(qgq+W(j(u)VV4wz^OfR2>o}INCu$bCB_#XtS~{(j3aS-8 z1;BM->&b$s;+XI)R9v2C)>a=P+sKh_*NIS?JEXx{IA-G|P8aAO(IL~&b|z$;fZ5{| zdp)Y4G@k-sX2|h0fG4y+s^4 z<{3j+yJk#R>+J32O0dbdhU=z(&^XGkDdWkiq@Ika7iZsP!%b}ySw3{U;-fX#lRLb9 zSKJYqOnS7_%gj@tBbf}eih`4r24V#qlBS6$gRu#uwGO`P)-gc6< zb4D9<6=qqa6%jzS6MRr71$pQteT#BmBLXhls5? z{z2vva*La`WXjTFpS03g9T(xg4E0hEVXxKf6BY++L1CS{-z+_9@=q-}mwW*;3@~W_`DIq$ z&BvtskAS}fBYah0F1v!a;2Oa2EeAX~`=|Jec4+x>ftzKg;EBCzu}v^e5~;`}^9;l^ z2YI8aZt%Oc#xZ?zvaqpz37yqNuMjVRGPmV9^x%SRX8cx6F`a|}FaB*QoVIBjlzc%> z$THBeWp8?L=LXjRH3Koh{0fkG$|u1agn;v4Sn95qcG3lyW)&*=hpREd=g))wxRHBc z)eOLf3V#i^+{;7Q@Wu2yY`Q~%a>zW`KTt$YL}s;=i}I|Eeca1fvHCi-fCw8njH1}` zv^0k{r+Az_ESl}jm2QxZT05$>RihQOj=~7PSYr8rQqz9UpnS>mtX=O!i)*k1bf^pn zY!2ID*qOp~D$mQvES%2kYd635XP@nl?VV zAUhRK1zH~^wpZ)h1)tb^R5Pv`_duh9Tq`24A|cTR+={KL0(FWH%+Va#`40n-py%eH z)Tpbo%@XtCBh6jbSSu(aWUkp?oB9+I-?l-*d2))op3`R>gsbO;%FI2Fm)vOXR_t84 zNOR785IHZFDANO7AgFm=RA&XMkx_AHo4bK66kEOZhCvS_wM15o?~6VEU0j4r?vuP~ zG`aw_E?o^V^ErocE*ciAGM}ZefQIVB$<%ep12WYT<xULzEeFanG$aPN3Eqe>jtMxl&;Y*m@xKc?qYl`G|i z)8J;#0al1#_F~z6q?48C!1l{v`hk5ya>1miP?k>>Bpnlx((xiQFM$Vs`T?5fvK8*{ zMyibAj;r%SA${-{Hj9sTFlG#K;!sAtGJC;NgBXONP0Db(Vaw?JAF*O%jMuHKIt_1m z)Y~VHTLP3>Oma3b%(NCJxv^?2T#XxNGztGs59I(E4ugFHCH)D8I6xr-39_-x=EIUz zA+pAr1%mAQAXa)eH;uraUxo1N{I@mjazq?QhH>ViNL>&E%SNG9EW*QTOBw@VMn?n@ zq=vD5vxS{=G1oFFXtHzlRL*w>Um@(EH&4}=?WG>Ac3`^`(Pu3d#I+k+huuf$umg#) zLuyUgL!|rdD0Dh+QHKPyCMk4uo{nj^!JwaLNzXW;3vwO0F0SdAHUrJRJ{;3#ph?H% zG%%+9!SR^)zF#T6`ekO_VeBOAhXh-c6Y0`o7stXlrcUC&MuKef5Z%k1YPF-C-70M4 z!?!QtNzxKbGB~XAM&AX*DWRZoOGJSNtFzl(paW!~l8@t28N$rC3c52VE0fXthELfx zmiw3I6dD>r!t3F0C)y1WaUn7+lttxRi~?k#T1rS>vaK}2KjnqVT*Fnbo8OMKYY=e; z8D=0ZcH;DE>bG5U*>YWrkr{JD$Oz-abx@6ulo9QWVrtgZ^^RBUk+p8^v$PbFu={{^ z6`G{@S|1N6FjcP83)gQ&wuv53!vk`5Fq_PZf>$%skF%2d18ZP0x&zz1N65Wc1}1@n z?8o|O$IHe;g0QIImy!lz?an9wBTz#(LYmbhcY8v_QW1OkoI5w`!fhNqSVB8M7G(4? z4AFv#5k$07OPG>7;Z9x2EJY4)LJWw;zlIXjciX|G$>yZtLOtu+vwg6J%t7-j1BuCy z;aL_Hb$6#LEcmv$(~otbHjO12DFgywidlI)*gMSpvAlOPY?OCreZm8`0v3WZ~0^f7~7@ zPB>ZM8Y}@Mty^V8aK^-%rtS-iNSq@e(J)6?pUG4ZQFV_BOg1VyrI&cZ9k3?Q~746y}bde;FV2akAj+P3y zNN2}3kKa-Ydapwt;7m1iA5@?tu7b|M-j6noNImd_bI#mnq;p z$qnjhLOtQ z`7^QhgU)V#!~Vmnr$OmY1(*g`zkWRYqR`@0p+g&9ZDUq-SwgLGg?EFgLTp%d^mca~&yO(N_6e-?Tec}K<4r{{L<1vjGnC+&N zWnurJG`BAfwGV1q0j(17=~`f_nEyvdC;^ zh(OABfp?9+_aOK*#=N_BI$Soy$UTH&Be?yfD!&Saww`m%T_SZLB=TL==fhlMOYS&l zyr*`n7>2W9mqoL4E_S7@P>A7>84TzGCpu-}N;qRwT71hkW3aju`!vc4Z{@5$L|2I| zK0*Ntj#B8xi3fZq7Ydb`@I& zd;+l7a@H;Is0BpHEAI8YvmPyr`?q7E0j0u(b=FZg$`u^ z*ra{NCuzKBWg_72sNqEM-bYocqIjX6Yr~Qb{e`}hm04wrChKIuFu)&L#Gd-|Yoi?n zRcDNIQ|1VYhonG+}v%x_J4QZYw3E4?uNT%5@k9=0Mmk9P#0@foP_Hg2^168&n zkB+w2%JnCPM9z;4aC&hft~~dI&6-Z~I+dMcDzUV#>oB6%-qQDD;g==t$+qN!WM(W^UCL0;qpiDj`0_wUIEZ1@ z;UP8iQ=ywy?Q`Xs^kXTvm_l!{u(*`mT;%8jgde_EM}Q3PvChq^<+agWK-Om;)*N80 zTThDTspB?V%Cs_`2y8Y_;SM{T;9V$ZNq~(Zz%8nx&Z2YTG1PjY$uMl=%ya1bb4zL8 ztu&1s`D=-O1>&{^vzB&Vo^;({Hv!O*H@gC^0$YUYN}?@^$PGExy~q@bI=1zRF@`Yv z-P&4hJnB7i?7^%(5{WEF7p=@4M-flwMziDZux-k2s2e zE1>pOxOx(O5pfI#IDCbn{ogf_8+fb54XkgEVXfoOvWGs$WR1XNX{iAO+AA(y-!XvPQ%&7m2#`I zwYA1Y!G({fJaebO?*PQFFE zhsSmc{?70+={~a4`VLBo^K3Xw?H(_j3+Pmqu!>b*{BW{R^CL$fT=9$lbCh{K>v%uD z#P;Kf54`5PBHXHVdv^t;%@2NEnPtTn`(8927Jkdk^)8o16*;p+9h-esa;KfQ3m2)9 zGS~|6FDRP>Sr3ylEdXiOVWf77B4zQe8C(t3HkihrUO z#5BwZk>Fp-TNCNI)?MpjS7gBzVzwluxw&C+Mjtg-+hp)=M_+zM`U~6QIcg4j^Phpo z&skR^dR`+mg4kaZFD&9S>4ZVm(a-uEdhfJw`_WYtl8?!%fS0C9zY}42^1>eeY@pFg z#oD%F;rWf;$Wi;xI#t+$7Xp){e+e=I7;KP_$g|hHaL^em&qw!oL3@&CyPr2m)`4@Y zsy;Y2%i;XJUmam3Gj5OOJ+2->S@+F3pQ(Fpji$XJs~cUlNK&#p-}}c=G1C|K zpj)`qY@?WTyFlEHOf^qwVs9llioFQrjprs~a!O9gX=ps}lQH}|i^Is-vzJm>8!zJAXBRTgJR&RdZG?-HeNwR->1*E}@S`93p*85B* zYPtZ9#^s1NJl)1|9e2wq;gcla-U=Es00F}8-8>~$o*S&_iGElS&v^=+* z%SpLnh_PB*V(zB2)T=0(=((9FRWC@7@-VblKZbG$xnxneOp0_n#TrsBmifZN31^=E z@}t&ve(fP*1X4^0m6?^niyxAQ=|VMZbs2RF3+aY6fMNn|X^Sb<`KQTzrJ)}PBskYA z7I{=1IiF#fbS)-qHoHX)S^fqRHOb%_{Hu_{6)8T&AwG-d{z$Ke#M+X`dTCc1G;gtx zXhA%lpo~;uJRlnzsuL5%Yr&Ibt0gDv34pOv2rvlup|87#CT?EZLKH=OFGGp%@7QR&S zA^IX(mfItkiz7_UB7Y$rChRqG8fm5>4DBmK07=9H=7ApfwshNux%o(AQ4t_Tc=dGG;&|Cr3#2Og|BBT+hNG9sA!xjX|N)_S9eKbKBr0;Ya%J;g~4Ft zI4w?SnKx`D3+UaA)f?@An;|-+urRcnjySPmBp2hbaTpfc+mkO&s2fyc#rYlCq7EVuK!`V&^qt6aK~??(q%1f*${po&dCAZsF@rk;UbSY@`vPH-9y4rFw>ldJOA z#2Ku>4zoozC*n=iHjw51*#Yf~xpTY0!0ssn`22Tz>uZ^ zvMsS>MJ!yM_0PwF!s@9|0_5ntw+EYIi(-VgZpd(JqB=rC`48Zm7kT1i* zKv+GSgPCGf>wr=eI3aI`a-^pWmYOqk?}3c4xY8xd&hp{1SG{Vu5^O`;1=6E086xx; zWAnY$V%oO3)b4$Su#MiFt0B8`qOEP%)n^@&k{+eny1MpM<-WjsZS@Ykj%Y}W{?wl< zXn(2ch17RExSD*#!wJU!K;U@~*Tvl9ErG-wR)^s5EC^F-ZO`83WMEU_N`wrLkU;S^ zyrxbNjRheOm^n}Q69Qp|R5jIYr4Ays@lR6N`4l7y@mO+sf-6~u!V@h8pLKUt3()G^ zBMU30kHB|tqz95XjWc}rBmE(0o@!`a+p|SNRTNcswA4mEw;)i|?SR{ChnilaZ2Iok zZlT4E05kkQG_8)0@IGxPlB2m}0xDuuv1o|N(&2VK#CnqS_eo@!o)DR~%P(U#?8M1Q zK#`NtY|3=}!L5#@(TR`*B9OnHyMj||<4q=XyV;}@4|N1$PKOVOxX`29=elZHtEN&f zr0V%Z9Ykv5Rbd->RLb-OCTSJwg54`G5;_?zkJZhTqN=7_wo-Kvsf|~K#U24Uxk)0G zUH+gT!bQ_g?Dk^rgk-tv>~okwkp(o8)jUeL`eueKD+;+k!m4=cDU ztOLg$2x8^yTyhKrQ^b%H)`Jm?HzRID_OjPALIcrKWGQL|vI0?|8AejI2w8+$g{(r7 zA_dHWJ`vDy$qPPUNi=@4J3y;6D00+irhFNAU|X+%MwD=YLn2%L895<}oOD}J7=m^* z^;*U<$Z>!>*fSv5OkezY@Sqxdykm%m;NJyuKs)Pru<~L!`Rq9tj z3+5oSsp!eZJ3NUt%Q?P|bw}3wE~Y>);=MOTF1C&@A4~X<88f7!ZMGfvIjRM)clQHL zQ_Fm`@ItR(#G&Rrx?dz#9`SKLvg?Dt%rk5`XfoAj-{A@=lpo4A1T*E)+61N><`}lrc&;@$TTr$*6`yCBEZ6C^fA;;^@gP6#7Xf(X72AYvwaH$B$&AbNWFN8|@C11`2%$0WAay1RVz8 zd)$0hx3JWB1HucX<=wJ0AL#w|)u%L&h9mYH8hjMft*g;@{qkNsj}QdAjpX{t;e$mW zhW1I&z^1-`gJ=NyzW3+OC2CfnM`)qI^z{fR0DUv#+k5b#zWuhqS609adMq<}S$p@U z#p4Vw=T!NCL4w_c?hIo3#D}{9*kT6By!r~kr^Tr3gDB;59YotC4HG$%w=2G8fitl8 zW0ziBgO6RI2uC>6r^qxqMyHsVuh^zGLh*bvzHe;lsKJo~0Ty8}(ra4lB)lKCvNM-w zd}0#ky?KLgm!VeOew*SeH}RC*D#k%Jjr6iVe#E!iCcFnZb~1-2_IfG$!BH_e*)n4M zX5k0d;3`+I8}9|uh^q}L<=>dz-%ujvE~?e#xM>)7z7gKH6ac6>^-dCcJ_V&6K7+Vv z$ZMVuI_H4;O^j5||5NW}^6`x_A`^&7_Pdy`>HV1#t@_7#%3Ws$S;xp^{yl?78MxWe z^E_0l_N2ycVn2U7B0bq$*BW87#&xnTM6~XBN_{&QnS35Y^Q8WuC-W~Gd@(Svz0{u? zxQFo<_XQ=`uLn!>-KKL_9>+H;S1z2jqWkG`AH3D05_d;*T+<}uq3ZY|Tp10YMuR`R zsHQg6|2`-w2Z>2*GM3=MeeC*OtoAmornB`N&9?Pl@rN&kQzx$2OY@$wIO4g$)_JAvP9qT*S?pp9q z;VTeFKXMDQnPl{hBVj3%wn4M%x}vVi>PR~OMeXr2U1)uHn$H*RcY+<`=MA{9#XP>= z5O95ero0 zYXqzTyuqrovg}0vbd7Pjqw#LE`%3;=!q2o1nR{}%LgAI;shB<9^BIhIvVg@IzqXs} z&j7!A|4l1sumQRBh%^#?o&`?sr~he$4%}VJymqyhlE05I#a;KZv-MOUoq&58P;~H| zz_kCx=G~p>cunzk11rVx>IXOA3EVvpSoI)2@VFtu+htgN^~s@mGt%2}WoV!nwmCd{ zm}ROv;<=idK?Svc=)*l;9v*x0o0EE=1i_G9h%U5*@XP4Wn8&N}EFBMD9Qklv{f zko(PZQb+M}(!Yxqb4Yf#`14MB7Dxx|R`DMrYR}oiT69^G#XCFR-JJ4`c+Mg`TBJgn zDgIvR@=nU?VbM1#nBm%=mYuiITg^5|L&#g?!8M=Wdn{THG#H`}bV7RVC$(jd_^A!l zjzgmG)2k~QfPB5hk|Z*hJR*VcaY85#RisOIMPyx<)3mrS-72=i6&F|GdwX_7(%pm1 z?xDRstG@>N*bIzLW(+ObZ42iLrMnFy4N{DI<=F4>+oj!;^?Rpm`S@GScL%Qok$^2gS-PtRdC;QpnFu9wFsMkySS@x21=-hOW z3L zZ$CbIXxQ-%F^ik7S z4qa#=no#3#Kna&D5Ae;Ntxecf#`Ha%8aGIVVZ4^Fn5^8tCrnIiP8le1 z5noyUJV&2Y=O&ZxI>NiVzSXtwJoAhQUYdu-O?anGkxOPABw-=1bzZ19+vY&?WFuVW zPPr>zQ0ThDU~B^cr!1M#YTpmy`)48(VeVu&RSrtAHD#%~WI6>(^;l+IR~BWz|9kSg z0x>^CAasW>W<=h%oEo|ns-Nr(Q}4*K`3tt5Ell+N7yw+ zg-b)}G18J1BWqoW<9~eTyRxc2t-tLbd44&<6?HT2L^4rGfrrv}>qpsPbTcBiS5Orr zckc4U6-e`1GWqfY zZ0>T$a%R_~SSi1vHCQI)=Ms@%hwQ| zYxUVvzj*K}t!q2IOQQseObxShZB5ywNPo$qk^4Uq$|Ke$$^<;aCDT!6Zn z6Ww12%+d7KAe|+onmLu{CsIw%aJn$KYj4-Fw3l|@H8Ys17lKZ!?K^XiCwTM?19>_1Q zR~Vw;r${b#g1X(S6kaQENJPYf&ViNgPFa0iy;}Tn??`SK_zmk_(g)=fvRtcEYNPaO zYE+e~ELWE!h%Mz`tJbXYi1krl7K)lM^n#vmHtZ&RTelc6GKC<_4R_{e>c|}`b`d|aj~MkTHj4AN7nVffrQy0R0x@Nj-FY< zJdu8w^QYj4XT#1YAI=EuRz?gWjvNy3LGpE z;>ogVAEZUS3Bm^lV7z4qY8NgIaUK|VMqt}MR`{+msV%fpKeg)qml2>U3)ycOkjetr zwhe-2FG5X|hy_U?S+}h|4j7ciKq2OhXjq`81f{ejH@aP6bvNTvbAZ6xoRhb=O|NhE zaX0EVt%NQ6;b;+*g4%38K5KMB#90kRz1hi6@fT-F2ROlRbh#8HI=D?`Zt|&1*pkHD zl(=2PkfBtWGLcaT6mi5fPr9nTku=uKE~TXZE?@Yn$?mL7GbD2z$31o2o2C_hJk7SAlKi;x3$nTWfWs8#Z)>>ME?Mnuh#(p`QXz6u!4>MzXsLgxhM@ zInBk^5)bTw0t8q4)lW;a+-JH+uAby%S$*) zw(L?=#LeE7g?v4eq@OnQ_4ZUfK$cxNSg{s6bk4K+{8E8Ajp*7Hy>P)(cjP%&1PPnyhe@!CselY?D?!%R4Q1@b#a4u6xi4;&;nei?9AiF;0tP&9UbO{Og9nI zMFCT~ql`p3w`x|ahn?d3VOYmuMy!@uv>q1*C0Q7q3qjzk6nFAgD=Tq44&uMIi>4;- zt`cyp#&<^9;ggUsW*Vq=8cOw#-v$P{Xinks-_Y zUU=*T<@$8IfF z0be2D@c=VtCQkz+1J1Pr=Um>m2&>hU@iM(c4fz)}-HmmxO=ejg6}RM~FUB-N)22dmQ+fAd zg+E`{(iac9z}@!*+-atLQn~#6#<_Fp=%eqL6=C1KZNJY<0#~~<-b&=)g)IcSPvlO- z3M(FSSx#M>IpWRT@UkoJH7r^1VB;N&oJ2d(n%OoCO=uVjg~m5f@z7qs1SoXD;wNJI^hvP!=C_V(WPss?u@l!#n(KTkSY& zYyEuZDFY_M7nflpN0b{n8S?Afp5?}i7Tpp)T~uO|e>%>N)O))Jsmk#ALUjBm2d4Qw zIT3ha@zTrnh)AvOP1~w*VvAVSiB`udF_fYV`#alLHi?D>ldri3HcRtjr>dkp7k#oI zBM6&$ync~iKSVs40x~k>a6|=5W7#z^Io0{2rX6ojqqm2_ABf~iVh$6Z-f9og{1%pG!CWj0I zzZl&q?J1vdHmbsD_D=%)fy@TLA~Opi@IOWOGfhd80uJYx_^5P(!PwLB^$D7&aWK%dF?$Y%L%|H6ls%f9Z%%w-0 zN8@#oIsEFTS-5qV+Rlq8qpR<^a#pZI*WvZ6glmGfojz1@*n7?e`agZy|A8MCdQ&xcFi-*bxv5uYv!$Qy zjWmOt)mp7iFj({kvACeIX=7V(px%PfDskt;rdeM%j2h)x0`fgjeX+xjT z4S?05tL2}=>uL?7!OvZ!<|7WmKE8(a@^ua;G5+W4G)mW~C=uOmlnU(%ztx1%oAjmd z-38uxNtP#vyji+B;_$@cl&2aepWT%o-3#yH^>_o#2Jq1w8^(F?A50>qzwyi?ZmU0& z;qzCYXa?k-0n=OG0{UZ^-+eVR-N29aEZ0h0&;6(W&ta6u&!5QR?gMDfck_r9SHR6JDMky}2z$aj|nzdN4YYtAd#} zHx!(dQrybVXPhT$6(g>!%W*FZ*mY}4B@?Gi`QU81$pVsm4Y?4-F zZ{F|jCp21iZ8HhKJGs$ove9Y&&;2W#`{u|Hicm-Ao6cQ_D{}Zt`|tLfnY^{ftE+hw zkz~ed;*FY>(ZKG?Pv?;$_{=E3EdqLC2jx1JMzOXFlkM_Qbz7q}rKB@1MmLu=K@PQ) zXfB=TL(Sk2JsO1tC4m8OYV+QcTPVWRFI~ebGfaxOC7~h8oL=6OB|9eyQyuR+bup0? z5R=DPHdrUv&DwIK)R5jBo3hU;hI`)AaCoCA(N{o)R4DNOv`*=v31D!a9Zg@X_ta2;CTpSUR8 zZy$DY{@MY5>VU#4(NTo6AKsyBqJe8mheP;DeJd>3MB%`-KiH!RB4M?CC`1g~V@2Q` zty-TuqGvPb)I3W>M~mXDdFgjO9L$!y9*N@g=NfaKQ`DZPWfaKk4Ik+17WqjfD6NX7R?%i=c3Z(6kL-@!%6Lx%w?s}Z#gU;E1WqCCXyLqjm8K>5 zLCPno`8xd^q+gSuf95J3`ed5^Z<3Q@xKFXAb?r&rf7a&k>>?# zeRgweYh3+{x=OB|H-L^hNF(S#&2%TIQoq5bm=Bi01^G-H)>fwa0dZz^QiiteZ*RJ0 z7=^F1)X#8qM}*zA9%`X|owYEa@U2~FVG7nlrtr^YMF%_gLaZI9K20MlNh&D8h3gk5JF_sPz6H)?{nQ9=|g5CcyRS6+q9MAE9h@eMqJ=1 z|0|GWdpovbcU{j5=XE$Lu$#GcL?tPT%*sGVs-b=z7l8+T@KBEBjBE)2PGfGo1{0OL zYNN|X^qxa;qKS(_6=m3ghA=y(UJL}Nauz1C$6V+uO3g}wJ&?@sDJ@=xk?bJFIz6c; znve_rDpqp@ze+C87=)ynE9n*?BuOcwCrj44%l^jd%&-O5d3C!c1l@+ULblD?~oSzAT#+jM=8% zlTm@lVLUoC6uE18R?Eb_Mwqz*8D18~VL8Zvo)Aro zSCNFhhmtQ@;k1CeVV~G;ZYulnlsNFRGRji&Lh8Y``I zF-gsG;(8V%*O9Sft1{e@9<1@%YcxtD%hEP`TU*`kfD`syU;_`hWWyW`w~dV`U?FDQsTvz-_3ufY^0RC}QX^35hX5Xtdw9kl z7eg>tnC4Z$x9@$cD4p3RIAxZKR}KyjIzm>mDEvkqouJA zwiBpaV~Wx`^dWf_>*MH`!WHe>9H^}pws1%FVe6{N3+Zp$40#9BT6=v1*9s}MWev5h7_AdqkU;^0aDq; zyC&BvDr|%piag|$ox{GBzxNFVO3E7^IU(;|c~KApD^($gaY?TV2LA#NAwd3Mv<7fX z?2d@BoGFUqO}JKJ)ScKAM<4Bw`8!F0%RV5k$a;SolN*=Y7AwOWJBH*^~J7yOz1vDnIb>Re{*tkfi zn48UbaZya%X;cZTmA4x*sg$loGA@jn;2z$LEYDh&WDOG~3Y3aRS&h39ZohhP;ma4UDxnamw)sCNleYj*3fasgm(4_N>F_%9{g=AB= zD(VWAc=4)ZQFR|PqX-v`*5D+W=15L1DPN#MPTLRMpFT=N{kB1Q_FVrV9nwv538|W{ z0d&ncaV^yiFQtZ3YUW7;jC5HGPoIiNOCV(D)u%GV>Sh>9LN^GB`3k^3JZlwz(}=)d zA-;TA*##3y8;Zu@>?avg$i0A7_C$;dT)8JngmSZND_Bq!8#M@*o=J-oCmKX8*~uz5 z-uKl!0~cy(rMA|o>RqF7g#dV{S^cvqqvdV^MS|<4Vztghh1VJ(pve& zHj&X6ebC|p8w!xd(w$X?Bxs!>x z*}ptoL7;kd0jIikTfk~*PuGOol+A<5da;>Q;cq#y<5xzuWQ>(uOtBLi7o#c~ zt-wBkNgY&5qk~cboolZjpivBwVHmS+ppsUdY-J;k5&j&zjfM>XFD!21S%+b%VWiqP zuF5CcvN5psWG8kku`&^iz!$4}T~srym}N;!f-*F6bAdE$*2>ms5_yGDiO?2z%PZ3l z|0aFEW~5wPYsI6HYK^^d?xW0ZITzNYU)_6aB3Tx=)cRbH@ODA1>^dkRwB1W>M%Q}4E5R`fzH7#N4-Z1FC9>Z`t58cvP@t( z>Yw1b1qV^Lt@XI)5gtO_NB5uvZ$g81xALU&H=~#y$NZ8S^y%hCoC`>6QRlH;^7X}N z=-x|QiG~t1?DPYNk2RsSm+d`x$Jc?*85fRUf43D*^%<$rKps_1?^bBcPS>WW%n1pE_Iz?pc3Z7@2kN`St zRNse2dvzbt(XSOrhXek;LN(*t+JZdqltO3!yEw=H#~hgO0u1(DT~ApyTghD*qOgu7w=c5KJ zwEV0i?sCk>dPi$z`mD0v9*A^@-hR8AU49<-^>*~=v;*Lv`6rW@^n>8kg_&~>UI010 z|8bgo=pr8Khq0+ydjP)H^rJ<5_TE`}lnS^Wemg@K?xO|`XoDeG466m)PfZ$YsWJ zo0$t~j(V)QJvl845)^(@d1Y-q#M${ebD6Em0W>+DB~@q)5V88}3Y1y^k~9xKBO+!7 zLe_*`cw`C?AarL(S5IH?GiQ5S+{w)gFk(w3WffZkYK_@R$+dtFd7l64B=5g1mG=Pw zkZZ}mY~He?+KVLa4y?)%Hag|!@58TV!B@fO4NLc->4q)e8B+ zjMh%^z=&}uT7qtOX$BOj%GF#?I_QuDl0XW`QHg3?Lkj31UeWHz>@oh{y-@r(m?tkr zw>`(eHOek-`B2+WvYVrE2Ga5^Q2?$#KKI&M@knLAR}@3PYqIkz+27+Sw&C_)WP{hY zZN9dXKlDb+mv3wooL9TN_aoWpWJc9^*Eh1^tGjB>9pntW(q4N*l6z78^uQf@Z@Qgh zwC@v{_VT`p6BikMou03}aFkg$PAagPyUD;1bgA22KD=`99eTe%0rdEG(h5()4{d5! z9=uF=;VRY09Z?o+v(`v48f=(Hus8E(KYpnV#6vXVQ`9T3-JWq_ z$|XTT8O9`q#(c5t+a#~oX#=;N9cKB7ToCj5C+#=tAZDU_skZJjiIz(CO?64X*M zTcWBmsj8H2Pj;p{CaQqaNZ-4!-a`ds6OPDRch)$KmlDV% z9iBID)f&xZAP)dhX-{2MRC@XQfMC?dQqhX~R zN~6L1^%IAw!ylG?C1GZJyG{-+9zH)%(JnYYvHvIVV|VI}>@7ISeFGz(YCkiRu|;YJ zcYH&GSbb@SID(*r9gRk*9s~yq!@A2!!~#f~zd!_DZziCb_JEjRk5d$W@vi6yf>kK9 zuBEnUj{i3r+mXgBwW6}J0vooWfzS-Ds>*Z#jmBg%z>VeW>82RzK?{UiK?z!VdITEJ z>}a-Wy$chxYn%e-wa}GNX^N|r(RwX*C05!d!H%)-_H)+>*2n9ECGv3ja`O}B-M; z2re)*7VUK+__mnf7owF@!^GaN4-9XCY9F|&g%?97De~-D;?E+y8k}BcCo58b<}OnZ!1T`wYEYH~-(z?V{b8rH%%2*GUqyHQB2y*y^J{ z;*Ub{!a8cK`407+yEu;H%|W!8r)vS1=OecjD{C(bZ~R5W4bmu+u3XKvmZ;dNfQ=_@ zykFYm^^y2~F^BDG!GxPc}A*ZR@!OaCj&=bApaI z6JKB}OT0itH2#5t*A2ZCnI*LQYw1S!u9YO<%Ensj`cnz0JMLUNuKJsOM0OfrAtL+o zwOwReH!k_QRoMYu z88xfMC23TeEukYTRwhE*?-0}I4yihEm?$Qw^RMSHNNi7V<9`z`e{O7jzd0*d+=|?3 zk=GnfI(!L0grxmJN9mT)4yr*lGBmE&HB86%WLwC>V^<;~B_Pm44T8Ry;UFtMSGwTfkOz;=+2+>SunbC@MdTUr6Ds`3HKEthPJsQa1AtkR@AzwR^-0q zqH8w4-pE-h2b~D4=;xEbApHYk0%E$n7XXKlCVpP6B#Z5s!8IW=%ZaT!1G2w>DU1?} z>f@rF$}3l~Wr4Ai460m*q}?^$B`T1{!MEcTV6nanvx`^GPg`XvFUS=Jj;3X`Rqee> z<%FE;=gVM4X12@|V6vFdtOm;RUJed{MqxYSGqJ5hRuQ6XAJM3`-vRg)vQQ*hm`Oue(MVIVT=x$dEQCtmJh1u-%}=0mAByqtNpN)g|e|__b*(N24}~ zz2qRsK2;Wh=MGFB&w*IBpU-SxH*vU+b>7FXSx~B2tA`wM&|1VEh>SWo?7$Ws@#4!YM0R-R@ypoXmlJWC|ywJcP4 zL}QBHNIONujG*)6vboVK=55eE-F|4-G-@vrzC;fb5yDRN^GaUw)HzSUbX?;cm3uZdgL!=z06yG8^GjH_Ac~{( z`jxTsE(Mf;l{YDt2+b654o^d5!F>cph2c%UH}W9-bI_Bw5gt}OtzHJ2WzXVU^x2{m z1L4_H+f0m)Aa7v^G56}}MhZW<`1^qQ{+)8LL(Y>U9O3K5RO`2$a6&)+Cu?Ddxt`q^EI80!GP$7Z^o?c{SU`xZWp z=H1a0-GOk_50@4J7B^Ct37$$pcqRnmn7p1RFEexxBY|Q&d%30q=8;uL*LdJoX6B1> zY8c*drIr4OQ-P~dv%Zw9Dm($qS#T6A?`0ftMbS6K8|L`Z{aKUTz=E-5aj{*?=n4dA zAOsYYbSAwFs#{09bBnWg+3d(QY;eT#Y=DELhJwY{ZLIHzXXNj|C`l77-1Fw>ee^lo zgPL%`?_SZh?~>S^g;X^H6(IWV=uc2cJcLpCX79_8|40`s$CqC{sNYDb;`i*-C?^@v z-vhPxkaL`$qXFk<5E$(IL4ic7*itSMiPEK(3exkimeZ_s1K zX&&6|ySd^j2O@CftW5r`?p7m5bB1_;LS*3nh?Gw4#yqjS^8MWSzsQl-sqj!=LJ2rKtWqq=xR0;R%H3f zhZf9ilL*=xz(PrJ1aU6|nX%QQeQ4Q!CQ>6S$U-ul;sfsJwP4da6J7POvV~)}CD~OJ z3ka>=&yf2=DurtRa7ZW4c7rjrbcYh;f`7`4vNtw{SCG`zwryvN%N+tQA-Tq7KY)KO zn2rI{KS3N1U(vYADh=)pAwr%GpKI(vnXo&>@U(FNWx@1Z(j)ccrMP*$IeOHc=Fl?ndqM+pK!-*g#R>Q1ohFLC|S0PEm8=edGo~%tY>@9((Q8Pp%;bH69huyr( zXi9Z{%+>t3X+xI8fL2!xJ9Ip$l2ho3NQng zL#gE#-FF?PF0_#54*A*_C@LxCl?e3lR2dmh!Ob^FdDJ3Y$PX#um4OHQn zH#^C--CUmw=elp_de$H7pw7+) z?=NAN*o=SXw7j+#XhVQ?Pj41*Odj+7S8oF{Nf!EXhe;@Dq)lw#T}`&#@S9xIj|%WB z0=1Il^N*WwS;!{wWpBnjlJTE0AI|f-R&`CO56VOS2Y&MR2Ft4&l<{&4q5li6!YlH+ z{2v7nWw|clx94R2dDb+my>&t$CbNRbW#)yvo>v4j>lC9&UaP5Vbgl*HFAI4B_A^xc zd}Izg1a_(sa*}A^mMZt{DyOKIW=PrLg zIL}^V^+;gsZC@HV%;+MxU!=S{u0QoGjwNBS?LEIKZbGzdxz4`ZiNYh@kRdfMbM18b@2p|&9{`yJ& zF7c5=mQuhadHTec^5OhLN_H?U8~3Dqw+%Y^p&+_?WQfVHxeMHN&J4)D+>j(mhRzS= zwh;A34@Cl}kPSEgPpxP-0$;zZ54*W+kJ>Kkf1(OkT9~zil;bUG8`t+0UNx_TaJI+e z{d7+<-gEOemzN3q{mJNtd46PdH0_D?w-ngbJM)tmzC)c7;wrnfV#(59D+CLh?5Z&_4{7roJgKfvW(+OmAyk zb<=;$Rr|QZ4T4%SC77K3R8R63nZMqH7g;5>zD{q$I?u_u4WXr-5%x?IJ@RO{` zBtJWNa3bASZu(Jg-6T&nFtNDlcl>LfbpJLs_1P&YvqkokiS}oFUZD&7 z6WTHi#~Pep;3fY?l;nmP*wXq)(aEo8gY76)Eaqjwg8C9}o@Hq-ZjW>^bj#dN3N6=v zD|1+m{IF^Z_OjOoRnisgGOM*I_$4S_*{?Nubhtnd)0pcCfkkJ?LLZuwOxWQ1ZB< z#lKm=B_^_e&VBQ#WpUvAvLa9Uy4SS>#C^vr{&gr)aa<}%EQb^!Qr}DSHR^f{aH>_tmY&K5 zsX~AI>eKoW)L^bS*V7WOV^#=>?I+8%k3K%44JCfq_|WkLV!n^L1xj@Q78VZ2%1FLb z7S0d3XO4c^Vb#9be&G1o7Ucd^L(aB#YTs^(MzVtR_3PxJ~QcZ^n1P9yyS6NYyxv%5C8~M@3^o;XFM%Y(!>wQB;l~jL5dS)=$r0d&?^K z5q(cY+!1o9eeL0tbLEcS2O#V#I&o{Ffpb}e%E5O?KLfySl?^#123TO28)l#VgWYP> zavP2EJ!GO{fWx|{mPMcp2b&>vl#&@3qeJoqSses)Kn(;l^3lz!hSho}ajJ*_+i zV3g(qbP-q??6fEbo5Lywqvh|Bi6-lMR!!OD0e@(6zFCieP2m8qz-M+IQ^m8R1v;#M zJO*TMTur*!F_#{oDacy0sUuZ~3H}2QFrKXD89WKTSX|p)VNs~3X`JFTCV5r?z3vtU zuY=!!fDF%r?`ob?-H6ih3%$Ya$sDgk&11s3()J~*>4lB1rL3NMOiQ^V542*Lp60a3 znEFVah4lf?7141aA|)8j;EeBio7msmT^g7(>2hnW5X=L5Z*x}^Y8NSQ48-LSw(BV~ z)MiUt=h}tUBC+(~O;2IVo%X-w{@QPVLx8UGE=LZzUmNw?fo+-$*{6guF#lNQD_|FQ zqk4o)K_Fh1QRjRXPT?C~jr8Q{gnhrBaHp-`T&`;p5@TozKGBect+l5aI^IE6n9)G` zA(LokmOj&hTf|!vWuiGQ)ixKByJNcf*o8zIxb8XB45NfXCN>HP`WcjP<2^7hy9~K= zk@cQ|tlZT!XGfAbD9P6YDK<6_QWeBK1l?&;-7$%clg3dnUo@9lV;suJubConXCK~Op zx3tQ1voc^Wh_jYA4pI#=sbdF85_+P`hqkK9pK`&>@30U2HFaQw1Ye7M1%&m^@3`AY&aqw z!wiuKI?Y<({}F&eY^XQ=cf&<68#BE(V&6$iArYp7?b#VlYl<=rp z#U62sX~Neu3JwyIR#!QZPV|riV=nNtHx{s!A#3R&+PcknrA#uFXUh%kV)VeExk$e! zsWOYV{4}{WHW*Mep6;9puf6F}9%{zw3FDX?8gpSEQc!2z%a$=V^e>GVCy4%sQL1c{ zxG|9AZ8-Yt{2HTn)80UwtOSNL=3$MzEVgvM6a|DgLJYJaiJ}tW&?4zkl018z?qo3F z$7tEj6>C=Vv2Sat&5W?QX_Af@><2s^0qZ*y-sIa19PQ_rB9j*&uzuSXt(s9Jo>>c7snN?fiO4N{N0Q78Q8Y&)GQ2ag zW5Z3e&Nzb$h-id-$a9wDW|~}6g!wNMMx3zA4V2jF--#j;cbFUpUMZ|0$DD-+yNPMisJA|(Zw6RX z3t@CY&me;^IInNl6?r0hV+%N-54YibEif^PmUinf*_OXr*%-(7pUg~5 z%LHo?R#|uW;C{I=VSd+V`@TNk1nRHdGovNZ&K(fP7)DiIiA~AS6Qsw(q;@7-H{kRc zFbdZMP9O7c-7fY_dO*_|zjHu5RT)IB2V6@Al`(3}iit$*64d$dMBx#Mj9UIbBd59z z-AR}~lZriSQ_z$HJ2Sq+LIEyrlxiQthRPCd*rjA90)leUAUqRs1Gdr`)KnEow#r(9 z3(=%83-z9f@>tv^LncemE7Dn99cvDI2tJu{s9F1{S{ zFF}%OR6?%f1Fy%*V^69{lyIj=W54^`id8z9Hj!UMH5pdvA9>}q%3RKc*5vZVGI8;p zFWQ;QAGi@)A!DXe*mu2EO+Ft)t|lFxXPhR>MW%7`A+l#zRLrGk{vMpehzMUZgQqDp3Wy4{g?Xe*KqLp~)-x?rc9 z9yhO*6lz`P@nn(NR7@50_xJ*L21FjY$L4YHDmI8eKq%G-X{_Nh?h^5E<_c7f-$~xs z4L7W21l!8ZF>w$qHR&;#DqAEKrW6LEB-@&}XZ@T;F(dNQ`?TDKsnV4dj7MWeVS+ix zQj#(+Lqes^nHZ;8wP>YcH4W^e!aRvnokhBB(P1t~mgeN?yNa=OP^G4bMV7=(;_o-) zDQmc^MM>)gG7x#Tze_+~9&@n=)Q+$RR-uKtCmUCDirA%wp~q{qHFrY~E3&JNndHx? z^~In~8{k?N|Bc8&57Ld0wpo15qowYUzYgLx=|3B&zZX)BVz0^VOml1eV-E->SIc@MVQ(Ec&Th#kPbNg8j4Q8-)Qb0k3hnwMUiHp+!neJMEbB;FadV z?D&G>WI3mm$P$%C1V1r~-A>TG3mWwH*SN&R;=G zV}M3XTj4q=sfDON8e{*G$CA zsXvf7?)y2qcJtT8ca6p_k)WQwk|%pS663r>gn-ry*T()+ZT9F!>tv#S?KdrIVn2(j zc%=&>8fxDszsHpaC(#x|9~e6a##)%-T&qT2>4L_z=q{0{lLe6pwI4lAElnl*R_r;7 zKSKt=T@qN_;M#Q>-=78ZT)U|18DxQ3;5)v@Nkbj&=@G1G7kwCaG*f}th_9ZWYcK-8 zElB-lAqH0?XBQ3TSTy%%7BRRwOYBwbI$R~lx{Ia)eAk&Rg|MTC>Z#r(yg{J-g4CZC z*9TT7&#s#WNf0XKMe}x!TTPyJ+!N9D^Wv#5=K8?uG}-mgBu%6EeD~Yeo>vO)0MeOcWGtyGq00g{f58LuxSak zL>Pv4SM4VVR+!Vs;%(OgiGAZS@xEXV!{A7GUfjxkhU+!;hkFWW#xr;kxZis|n101!tKUovqWR#DUY@x(y%hsp zsE~!JjkUk?hzD7j)LbZPM4oKdQLxb5vLm<7t4UK_ouN)1h`AK~Zfnh{uA3*n#&&|4sz?Q&sy^dx zvuHz!z6ZctC-DRywa?m|T=n0ZeDbKcey=9jo-t$onc4FB<882F@p(u zuq1=x2a=*eQ=>>5YUgr>`i(TONaEJmoXM`!rBYfo*=}&XfDHxQzBDjVLSTlzp1H3U z>+(M`5FJDps95bbOau{6VBFoP~53s&$=K&ai3)(1C6uUe`$Nxe|l; zeFAM*6F@;Ebs+U3e&3AtTHC7MR{XuK-0-$y{%u{Y+`LoM`9&lLJd)TyjvDBk;H7^} z{_QJ-!BgoX{aoLdwxhPCe}>T1O#aMV!lYSfG&f61#rVoENZALk{v`(S8XrEvm$Ag2 z?(qIiBGOol))}*Q`=vKq*J|kLH`+L5EWp{{7o3A*zBr2Ad!G5%>c++e2C&f!AJE3G z>jT-UwLEZ}zLJBmaqH7T+SGM8C^qy!gC^GObZ8)L^?0DnQVa*$)594UKQz4q>%~;l z=Y~F$DutN;_77P9rwd5rQ^O&_At2Q;16S8Bp^ZbE27}98cF@>e5W*Uj6 zQQI@(vay^@Q34BmIcv2RG9$8-sC$W2{!QHhLWVA*{EESk6xl?$tC0I%m4nwt&d{H0 z(%JA)`4UNjrcDp#@5PfKMw}GvnRpXEYU^+5+(@r`5uyUl&KPyIuRL7&PcM3ghFm6JmXS08L5x{Sv<>Gp0 zV{@u~08sV>7vLifzrW7QWn7L!ID~LW0gE|y$O3P7B`Q+FS{0I%;drm6TJ1jYgo>9% zib6%o^caY)xv!=wi&UghYo1HuL`zXXAPp5m#RbVEv>i&5yPuH{$X}PMTs|a+akndpVMyFM86lypVmL|m zNg5<)Bsw$CMOq2Tm0>QyC2-GzTrXK_!_bjn5_Rd~usmpWo~2}wULHgdL+@AUh%vFc zc(IX)mqRMzK}cM}-H13sv=fM_c7%-pGUD6tJ^45J@A1Fmry0(7ac3Cij_1-UG6xpO zh}6eBGw>X%#S9}J6p_t)#p8I3cHVj3O`hmKK(+xfvc&;mG7HFzV;&H|=`{QMho2b) zLx2M!z&&z1fckyb1<$e=LZKe0_M|C0!;{;ix1cZWHehD&hBRG#>|YwiRP}CMcAbR# zf=0Oqf__@PZD%$KrA_Z5vom+|m#_AS$SV@5a7QEa<$D$bc(=AT!}CeA1&7K}r+?LY zU20CNq+_hs)`c9k8RptJ&gzS1^-Qe?8_9Ik8+ef_8-RGiEf1G!rg|j+GGxhcCzk>M E0CfGIUjP6A diff --git a/themes/classic/assets/css/a77ade19de3d3762dfbf1fe553b293cc.eot b/themes/classic/assets/css/a77ade19de3d3762dfbf1fe553b293cc.eot deleted file mode 100644 index 8c3f10642497e1b49cf06a82b74a4f93d35d9106..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279454 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 z 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 diff --git a/themes/classic/assets/css/570eb83859dc23dd0eec423a49e147fe.woff2 b/themes/classic/assets/css/570eb83859dc23dd0eec423a49e147fe.woff2 deleted file mode 100644 index 9fa211252080046a23b2449dbdced6abc2b0bb34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44300 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 QW8}wPUeo^@jR61v08@RD2LJ#7 diff --git a/themes/classic/assets/css/5dc400bcedda37b13f35cb44623193cf.svg b/themes/classic/assets/css/5dc400bcedda37b13f35cb44623193cf.svg deleted file mode 100644 index a8552d88..00000000 --- a/themes/classic/assets/css/5dc400bcedda37b13f35cb44623193cf.svg +++ /dev/null @@ -1,27050 +0,0 @@ - - - - -Copyright 2012 Google Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/5ea9fdf2293930126fa9c544968009ae.svg b/themes/classic/assets/css/5ea9fdf2293930126fa9c544968009ae.svg deleted file mode 100644 index 2396312c..00000000 --- a/themes/classic/assets/css/5ea9fdf2293930126fa9c544968009ae.svg +++ /dev/null @@ -1,27184 +0,0 @@ - - - - -Copyright 2012 Google Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/7988be8b63edf9c4accebf94d5db7927.svg b/themes/classic/assets/css/7988be8b63edf9c4accebf94d5db7927.svg deleted file mode 100644 index e6bc45c5..00000000 --- a/themes/classic/assets/css/7988be8b63edf9c4accebf94d5db7927.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/7a3ebca0cba2e2c6090e84e1d77e0f94.woff2 b/themes/classic/assets/css/7a3ebca0cba2e2c6090e84e1d77e0f94.woff2 deleted file mode 100644 index 229d8699f41adc3e610e213b6ec3b1d529e8981f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121368 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 - - - - - - - - - - - - diff --git a/themes/classic/assets/css/80e74ff9406650e53bbec1e292c2c094.svg b/themes/classic/assets/css/80e74ff9406650e53bbec1e292c2c094.svg deleted file mode 100644 index 859d7dca..00000000 --- a/themes/classic/assets/css/80e74ff9406650e53bbec1e292c2c094.svg +++ /dev/null @@ -1,24745 +0,0 @@ - - - - -Copyright 2012 Google Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/themes/classic/assets/css/846c191efd3d0aacde5a916cf2ebf1a4.woff b/themes/classic/assets/css/846c191efd3d0aacde5a916cf2ebf1a4.woff deleted file mode 100644 index 07640c15933caf534786a3b499654ddb35bf40f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 221000 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

  • T+6^4PI`OyJup)?yEyX$a$^S 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 EdEF@6Frc)W5>GA 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 Array - ( - [0] => Array - ( - [id_custom_field] => 1 - [field_type] => boolean - [field_validation] => - [field_placement] => shipping - [position] => 0 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 0 - [dependant_field] => 0 - [dependant_value] => 0 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => Chcę otrzymać fakturę - [field_value] => Yes - ) - - [1] => Array - ( - [id_custom_field] => 2 - [field_type] => text - [field_validation] => - [field_placement] => shipping - [position] => 1 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 1 - [dependant_field] => 1 - [dependant_value] => 1 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => Firma - [field_value] => Project-Pro - ) - - [2] => Array - ( - [id_custom_field] => 3 - [field_type] => text - [field_validation] => - [field_placement] => shipping - [position] => 2 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 1 - [dependant_field] => 1 - [dependant_value] => 1 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => NIP - [field_value] => 5170167517 - ) - - [3] => Array - ( - [id_custom_field] => 4 - [field_type] => text - [field_validation] => - [field_placement] => shipping - [position] => 3 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 1 - [dependant_field] => 1 - [dependant_value] => 1 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => Adres - [field_value] => Okulickiego 18/1 - ) - - [4] => Array - ( - [id_custom_field] => 5 - [field_type] => text - [field_validation] => - [field_placement] => shipping - [position] => 4 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 1 - [dependant_field] => 1 - [dependant_value] => 1 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => Miasto - [field_value] => Rzeszów - ) - - [5] => Array - ( - [id_custom_field] => 6 - [field_type] => text - [field_validation] => - [field_placement] => shipping - [position] => 5 - [assoc_shops] => 1 - [value_required] => 0 - [editable] => 0 - [extensions] => jpg - [products] => - [attachment_size] => 2.00 - [show_customer] => 1 - [show_email] => 0 - [show_admin] => 1 - [active] => 1 - [dependant] => 1 - [dependant_field] => 1 - [dependant_value] => 1 - [id_heading] => 0 - [created_time] => 0000-00-00 00:00:00 - [update_time] => 0000-00-00 00:00:00 - [field_name] => Kod pocztowy - [field_value] => 35-222 - ) - - ) - -) diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index 054dcb0ca31269966da57d3cef34423d10b45f89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-or_5dIc1LbRZ?yvAMZgYDJz}1KCDo_DXB4sR;X_zDIXPuFPTGj}if5rtm z81zo7jpKMG+6;e@0e*KYsG*G}5@g5&_qBOZ z?FFKeF0U4?w)MzGi`YSo0Xnjh)VFu@ob_dUczS#N=wXuEk3Xx=^XKYbzHr?N4!A1L ziH9Z{=u#I6>KNjT_~}jcvp>FGBq!VF)oppCTzy+B+y77Ua`PH(^1Mup0b{@zm}Y?X zY?jihppC|WF<=Z#7~t - Order deny,allow - Deny from all - - -# Apache 2.4 - - Require all denied - diff --git a/src/Adapter/Addons/AddonsDataProvider.php b/src/Adapter/Addons/AddonsDataProvider.php deleted file mode 100644 index da6173df..00000000 --- a/src/Adapter/Addons/AddonsDataProvider.php +++ /dev/null @@ -1,229 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Addons; - -use Exception; -use PhpEncryption; -use PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager; -use PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface; -use PrestaShopBundle\Service\DataProvider\Marketplace\ApiClient; -use Symfony\Component\HttpFoundation\Request; - -/** - * Data provider for new Architecture, about Addons. - * - * This class will provide data from Addons API - */ -class AddonsDataProvider implements AddonsInterface -{ - /** - * @var bool - */ - protected static $is_addons_up = true; - - /** - * @var ApiClient - */ - private $marketplaceClient; - - /** - * @var ModuleZipManager - */ - private $zipManager; - - /** - * @var PhpEncryption - */ - private $encryption; - - /** - * @var string the cache directory location - */ - public $cacheDir; - - public function __construct(ApiClient $apiClient, ModuleZipManager $zipManager) - { - $this->marketplaceClient = $apiClient; - $this->zipManager = $zipManager; - $this->encryption = new PhpEncryption(_NEW_COOKIE_KEY_); - } - - /** - * @param $module_id - * - * @return bool - * - * @throws Exception - */ - public function downloadModule($module_id) - { - $params = [ - 'id_module' => $module_id, - 'format' => 'json', - ]; - - // Module downloading - try { - $module_data = $this->request('module_download', $params); - } catch (Exception $e) { - if (!$this->isAddonsAuthenticated()) { - throw new Exception('Error sent by Addons. You may need to be logged.', 0, $e); - } else { - throw new Exception('Error sent by Addons. You may be not allowed to download this module.', 0, $e); - } - } - - $temp_filename = tempnam($this->cacheDir, 'mod'); - if (file_put_contents($temp_filename, $module_data) !== false) { - $this->zipManager->storeInModulesFolder($temp_filename); - - return true; - } else { - throw new Exception('Cannot store module content in temporary folder !'); - } - } - - /** - * @return bool - * - * @todo Does this function should be in a User related class ? - */ - public function isAddonsAuthenticated() - { - $request = Request::createFromGlobals(); - - return $request->cookies->get('username_addons', false) - && $request->cookies->get('password_addons', false); - } - - /** - * {@inheritdoc} - */ - public function request($action, $params = []) - { - if (!$this->isAddonsUp()) { - throw new Exception('Previous call failed and disabled client.'); - } - - // We merge the addons credentials - if ($this->isAddonsAuthenticated()) { - $params = array_merge($this->getAddonsCredentials(), $params); - } - - $this->marketplaceClient->reset(); - - try { - switch ($action) { - case 'native': - return $this->marketplaceClient->getNativesModules(); - case 'service': - return $this->marketplaceClient->getServices(); - case 'native_all': - return $this->marketplaceClient->setIsoCode('all') - ->getNativesModules(); - case 'must-have': - return $this->marketplaceClient->getMustHaveModules(); - case 'customer': - return $this->marketplaceClient->getCustomerModules($params['username_addons'], $params['password_addons']); - case 'customer_themes': - return $this->marketplaceClient - ->setUserMail($params['username_addons']) - ->setPassword($params['password_addons']) - ->getCustomerThemes(); - case 'check_customer': - return $this->marketplaceClient - ->setUserMail($params['username_addons']) - ->setPassword($params['password_addons']) - ->getCheckCustomer(); - case 'check_module': - return $this->marketplaceClient - ->setUserMail($params['username_addons']) - ->setPassword($params['password_addons']) - ->setModuleName($params['module_name']) - ->setModuleKey($params['module_key']) - ->getCheckModule(); - case 'module_download': - if ($this->isAddonsAuthenticated()) { - return $this->marketplaceClient - ->setUserMail($params['username_addons']) - ->setPassword($params['password_addons']) - ->getModuleZip($params['id_module']); - } - - return $this->marketplaceClient->getModuleZip($params['id_module']); - case 'module': - return $this->marketplaceClient->getModule($params['id_module']); - case 'install-modules': - return $this->marketplaceClient->getPreInstalledModules(); - case 'categories': - return $this->marketplaceClient->getCategories(); - } - } catch (Exception $e) { - self::$is_addons_up = false; - - throw $e; - } - } - - /** - * @return array - * - * @throws Exception - */ - protected function getAddonsCredentials() - { - $request = Request::createFromGlobals(); - $username = $this->encryption->decrypt($request->cookies->get('username_addons')); - $password = $this->encryption->decrypt($request->cookies->get('password_addons')); - - return [ - 'username_addons' => $username, - 'password_addons' => $password, - ]; - } - - /** Does this function should be in a User related class ? **/ - public function getAddonsEmail() - { - $request = Request::createFromGlobals(); - $username = $this->encryption->decrypt($request->cookies->get('username_addons')); - - return [ - 'username_addons' => $username, - ]; - } - - /** - * Check if a request has already failed. - * - * @return bool - */ - public function isAddonsUp() - { - return self::$is_addons_up; - } -} diff --git a/src/Adapter/Address/AbstractAddressHandler.php b/src/Adapter/Address/AbstractAddressHandler.php deleted file mode 100644 index f1d4339c..00000000 --- a/src/Adapter/Address/AbstractAddressHandler.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address; - -use Address; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\InvalidAddressFieldException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShopException; - -/** - * Provides reusable methods for address command/query handlers - */ -abstract class AbstractAddressHandler -{ - /** - * @param AddressId $addressId - * - * @return Address - * - * @throws AddressException - * @throws AddressNotFoundException - */ - protected function getAddress(AddressId $addressId) - { - try { - $address = new Address($addressId->getValue()); - } catch (PrestaShopException $e) { - throw new AddressException('Failed to create new address', 0, $e); - } - - if ($address->id !== $addressId->getValue()) { - throw new AddressNotFoundException(sprintf('Address with id "%s" was not found.', $addressId->getValue())); - } - - return $address; - } - - /** - * Deletes legacy Address - * - * @param Address $address - * - * @return bool - * - * @throws AddressException - */ - protected function deleteAddress(Address $address): bool - { - try { - return $address->delete(); - } catch (PrestaShopException $e) { - throw new AddressException(sprintf('An error occurred when deleting Address object with id "%s".', $address->id)); - } - } - - /** - * @param Address $address - * - * @throws InvalidAddressFieldException - * @throws PrestaShopException - */ - protected function validateAddress(Address $address): void - { - if (true !== ($validateResult = $address->validateFields(false, true)) - || true !== ($validateResult = $address->validateFieldsLang(false, true))) { - throw new InvalidAddressFieldException(sprintf('Address fields contain invalid values: %s', $validateResult)); - } - } -} diff --git a/src/Adapter/Address/AbstractCustomerAddressHandler.php b/src/Adapter/Address/AbstractCustomerAddressHandler.php deleted file mode 100644 index b6ec69f5..00000000 --- a/src/Adapter/Address/AbstractCustomerAddressHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address; - -use CustomerAddress; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShopDatabaseException; - -abstract class AbstractCustomerAddressHandler extends AbstractAddressHandler -{ - /** - * @return string[] - * - * @throws AddressException - */ - protected function getRequiredFields(): array - { - try { - $requiredFields = (new CustomerAddress())->getFieldsRequiredDatabase(); - } catch (PrestaShopDatabaseException $e) { - throw new AddressException('Something went wrong while retrieving required fields for address', 0, $e); - } - - if (empty($requiredFields)) { - return []; - } - - $fields = []; - - foreach ($requiredFields as $field) { - $fields[] = $field['field_name']; - } - - return $fields; - } -} diff --git a/src/Adapter/Address/AbstractManufacturerAddressHandler.php b/src/Adapter/Address/AbstractManufacturerAddressHandler.php deleted file mode 100644 index 0f27c951..00000000 --- a/src/Adapter/Address/AbstractManufacturerAddressHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address; - -use Address; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Provides reusable methods for manufacturer address address command/query handlers - * - * @deprecated Since 1.7.7 Use AbstractAddressHandler instead - */ -abstract class AbstractManufacturerAddressHandler -{ - /** - * Gets legacy Address - * - * @param AddressId $addressId - * - * @return Address - * - * @throws AddressNotFoundException - */ - protected function getAddress(AddressId $addressId) - { - $address = new Address($addressId->getValue()); - - if ($address->id !== $addressId->getValue()) { - throw new AddressNotFoundException(sprintf('Address with id "%s" was not found.', $addressId->getValue())); - } - - return $address; - } -} diff --git a/src/Adapter/Address/CommandHandler/AddCustomerAddressHandler.php b/src/Adapter/Address/CommandHandler/AddCustomerAddressHandler.php deleted file mode 100644 index 348caafe..00000000 --- a/src/Adapter/Address/CommandHandler/AddCustomerAddressHandler.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Address; -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\AddCustomerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotAddAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShopException; - -final class AddCustomerAddressHandler extends AbstractAddressHandler implements AddCustomerAddressHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AddressException - * @throws AddressConstraintException - * @throws CannotAddAddressException - */ - public function handle(AddCustomerAddressCommand $command): AddressId - { - $address = $this->createAddressFromCommand($command); - - try { - $this->validateAddress($address); - - if (false === $address->add()) { - throw new CannotAddAddressException(sprintf('Failed to add new address "%s"', $command->getAddress())); - } - } catch (PrestaShopException $e) { - throw new AddressException(sprintf('An error occurred when adding new address "%s"', $command->getAddress())); - } - - return new AddressId((int) $address->id); - } - - /** - * @param AddCustomerAddressCommand $command - * - * @return Address - */ - private function createAddressFromCommand(AddCustomerAddressCommand $command): Address - { - $address = new Address(); - - $address->id_customer = $command->getCustomerId()->getValue(); - $address->lastname = $command->getLastName(); - $address->firstname = $command->getFirstName(); - $address->address1 = $command->getAddress(); - $address->id_country = $command->getCountryId()->getValue(); - $address->city = $command->getCity(); - $address->alias = $command->getAddressAlias(); - $address->postcode = $command->getPostCode(); - $address->address2 = $command->getAddress2(); - $address->dni = $command->getDni(); - $address->company = $command->getCompany(); - $address->vat_number = $command->getVatNumber(); - $address->id_state = $command->getStateId()->getValue(); - $address->phone = $command->getHomePhone(); - $address->phone_mobile = $command->getMobilePhone(); - $address->other = $command->getOther(); - - return $address; - } -} diff --git a/src/Adapter/Address/CommandHandler/AddManufacturerAddressHandler.php b/src/Adapter/Address/CommandHandler/AddManufacturerAddressHandler.php deleted file mode 100644 index 3c5337c5..00000000 --- a/src/Adapter/Address/CommandHandler/AddManufacturerAddressHandler.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Address; -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddManufacturerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\AddManufacturerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShopException; - -/** - * Adds manufacturer address using legacy object model - */ -final class AddManufacturerAddressHandler extends AbstractAddressHandler implements AddManufacturerAddressHandlerInterface -{ - /** - * @param AddManufacturerAddressCommand $command - * - * @return AddressId - * - * @throws AddressException - */ - public function handle(AddManufacturerAddressCommand $command) - { - $address = $this->createAddressFromCommand($command); - - try { - $this->validateAddress($address); - if (false === $address->add()) { - throw new AddressException(sprintf('Failed to add new address "%s"', $command->getAddress())); - } - } catch (PrestaShopException $e) { - throw new AddressException(sprintf('An error occurred when adding new address "%s"', $command->getAddress())); - } - - return new AddressId((int) $address->id); - } - - /** - * @param AddManufacturerAddressCommand $command - * - * @return Address - */ - private function createAddressFromCommand(AddManufacturerAddressCommand $command) - { - $address = new Address(); - $address->id_manufacturer = $command->getManufacturerId(); - $address->lastname = $command->getLastName(); - $address->firstname = $command->getFirstName(); - $address->address1 = $command->getAddress(); - $address->address2 = $command->getAddress2(); - $address->postcode = $command->getPostCode(); - $address->id_country = $command->getCountryId(); - $address->city = $command->getCity(); - $address->id_state = $command->getStateId(); - $address->phone = $command->getHomePhone(); - $address->phone_mobile = $command->getMobilePhone(); - $address->other = $command->getOther(); - $address->dni = $command->getDni(); - $address->alias = 'manufacturer'; - - return $address; - } -} diff --git a/src/Adapter/Address/CommandHandler/BulkDeleteAddressHandler.php b/src/Adapter/Address/CommandHandler/BulkDeleteAddressHandler.php deleted file mode 100644 index d8025f88..00000000 --- a/src/Adapter/Address/CommandHandler/BulkDeleteAddressHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\BulkDeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\BulkDeleteAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\BulkDeleteAddressException; - -/** - * Handles command which deletes addresses in bulk action - */ -final class BulkDeleteAddressHandler extends AbstractAddressHandler implements BulkDeleteAddressHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws BulkDeleteAddressException - */ - public function handle(BulkDeleteAddressCommand $command) - { - $errors = []; - - foreach ($command->getAdressIds() as $addressId) { - try { - $address = $this->getAddress($addressId); - - if (!$this->deleteAddress($address)) { - $errors[] = $address->id; - } - } catch (AddressException $e) { - $errors[] = $addressId->getValue(); - } - } - - if (!empty($errors)) { - throw new BulkDeleteAddressException($errors, 'Failed to delete all of selected addresses'); - } - } -} diff --git a/src/Adapter/Address/CommandHandler/DeleteAddressHandler.php b/src/Adapter/Address/CommandHandler/DeleteAddressHandler.php deleted file mode 100644 index 5c1f4432..00000000 --- a/src/Adapter/Address/CommandHandler/DeleteAddressHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\DeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\DeleteAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\DeleteAddressException; - -/** - * Handles command which deletes address - */ -final class DeleteAddressHandler extends AbstractAddressHandler implements DeleteAddressHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteAddressCommand $command) - { - $addressId = $command->getAddressId(); - $address = $this->getAddress($addressId); - - if (!$this->deleteAddress($address)) { - throw new DeleteAddressException(sprintf('Cannot delete Address object with id "%s".', $addressId->getValue()), DeleteAddressException::FAILED_DELETE); - } - } -} diff --git a/src/Adapter/Address/CommandHandler/EditCartAddressHandler.php b/src/Adapter/Address/CommandHandler/EditCartAddressHandler.php deleted file mode 100644 index 657952c3..00000000 --- a/src/Adapter/Address/CommandHandler/EditCartAddressHandler.php +++ /dev/null @@ -1,172 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Cart; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCartAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditCartAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditCustomerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotUpdateCartAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Cart\CartAddressType; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShopException; - -/** - * EditCartAddressHandler manages an address update, it then updates cart - * relation to the newly created address. - */ -class EditCartAddressHandler implements EditCartAddressHandlerInterface -{ - /** - * @var EditCustomerAddressHandlerInterface - */ - private $addressHandler; - - /** - * @param EditCustomerAddressHandlerInterface $addressHandler - */ - public function __construct(EditCustomerAddressHandlerInterface $addressHandler) - { - $this->addressHandler = $addressHandler; - } - - /** - * {@inheritdoc} - * - * @throws AddressConstraintException - * @throws CannotUpdateCartAddressException - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function handle(EditCartAddressCommand $command): AddressId - { - try { - $cart = new Cart($command->getCartId()->getValue()); - if (!Validate::isLoadedObject($cart) || $command->getCartId()->getValue() !== (int) $cart->id) { - throw new CartNotFoundException(sprintf('Cart with id "%d" was not found', $command->getCartId()->getValue())); - } - - $addressCommand = $this->createEditAddressCommand($command, $cart); - /** @var AddressId $addressId */ - $addressId = $this->addressHandler->handle($addressCommand); - - switch ($command->getAddressType()) { - case CartAddressType::DELIVERY_ADDRESS_TYPE: - $cart->id_address_delivery = $addressId->getValue(); - break; - case CartAddressType::INVOICE_ADDRESS_TYPE: - $cart->id_address_invoice = $addressId->getValue(); - break; - } - if (!$cart->update()) { - throw new CannotUpdateCartAddressException(sprintf('An error occurred when updating address for cart "%d"', $command->getCartId()->getValue())); - } - } catch (PrestaShopException $e) { - throw new CannotUpdateCartAddressException(sprintf('An error occurred when updating address for cart "%d"', $command->getCartId()->getValue())); - } - - return $addressId; - } - - /** - * @param EditCartAddressCommand $cartCommand - * - * @return EditCustomerAddressCommand - * - * @throws AddressConstraintException - * @throws CountryConstraintException - * @throws StateConstraintException - * @throws PrestaShopException - */ - private function createEditAddressCommand(EditCartAddressCommand $cartCommand, Cart $cart): EditCustomerAddressCommand - { - $addressId = null; - switch ($cartCommand->getAddressType()) { - case CartAddressType::DELIVERY_ADDRESS_TYPE: - $addressId = (int) $cart->id_address_delivery; - break; - case CartAddressType::INVOICE_ADDRESS_TYPE: - $addressId = (int) $cart->id_address_invoice; - break; - } - $addressCommand = new EditCustomerAddressCommand($addressId); - if (null !== $cartCommand->getAddressAlias()) { - $addressCommand->setAddressAlias($cartCommand->getAddressAlias()); - } - if (null !== $cartCommand->getFirstName()) { - $addressCommand->setFirstName($cartCommand->getFirstName()); - } - if (null !== $cartCommand->getLastName()) { - $addressCommand->setLastName($cartCommand->getLastName()); - } - if (null !== $cartCommand->getAddress()) { - $addressCommand->setAddress($cartCommand->getAddress()); - } - if (null !== $cartCommand->getCity()) { - $addressCommand->setCity($cartCommand->getCity()); - } - if (null !== $cartCommand->getPostCode()) { - $addressCommand->setPostCode($cartCommand->getPostCode()); - } - if (null !== $cartCommand->getCountryId()) { - $addressCommand->setCountryId($cartCommand->getCountryId()->getValue()); - } - if (null !== $cartCommand->getDni()) { - $addressCommand->setDni($cartCommand->getDni()); - } - if (null !== $cartCommand->getCompany()) { - $addressCommand->setCompany($cartCommand->getCompany()); - } - if (null !== $cartCommand->getVatNumber()) { - $addressCommand->setVatNumber($cartCommand->getVatNumber()); - } - if (null !== $cartCommand->getAddress2()) { - $addressCommand->setAddress2($cartCommand->getAddress2()); - } - if (null !== $cartCommand->getStateId()) { - $addressCommand->setStateId($cartCommand->getStateId()->getValue()); - } - if (null !== $cartCommand->getHomePhone()) { - $addressCommand->setHomePhone($cartCommand->getHomePhone()); - } - if (null !== $cartCommand->getMobilePhone()) { - $addressCommand->setMobilePhone($cartCommand->getMobilePhone()); - } - if (null !== $cartCommand->getOther()) { - $addressCommand->setOther($cartCommand->getOther()); - } - - return $addressCommand; - } -} diff --git a/src/Adapter/Address/CommandHandler/EditCustomerAddressHandler.php b/src/Adapter/Address/CommandHandler/EditCustomerAddressHandler.php deleted file mode 100644 index 52516de1..00000000 --- a/src/Adapter/Address/CommandHandler/EditCustomerAddressHandler.php +++ /dev/null @@ -1,169 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Address; -use Country; -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditCustomerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotAddAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotUpdateAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\DeleteAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShopException; - -/** - * Handles update of customer address - */ -final class EditCustomerAddressHandler extends AbstractAddressHandler implements EditCustomerAddressHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AddressException - * @throws AddressConstraintException - * @throws CannotUpdateAddressException - */ - public function handle(EditCustomerAddressCommand $command): AddressId - { - try { - $editedAddress = $this->getAddressFromCommand($command); - $this->validateAddress($editedAddress); - - // The address is used by an order so it is not edited directly, instead a copy is created and - if ($editedAddress->isUsed()) { - // Get a copy of current address - $copyAddress = new Address($editedAddress->id); - - // Reset ID to force recreating a new address - $editedAddress->id = $editedAddress->id_address = null; - - // We consider this address as necessarily NOT deleted, in case you were editing a deleted address - // from an order then the newly edited address should not be deleted, so that you can select it - $editedAddress->deleted = 0; - if (false === $editedAddress->save()) { - throw new CannotAddAddressException(sprintf('Failed to add new address "%s"', $command->getAddress())); - } - // Soft delete the former address - if (false === $copyAddress->delete()) { - throw new DeleteAddressException(sprintf('Cannot delete Address object with id "%s".', $copyAddress->id), DeleteAddressException::FAILED_DELETE); - } - } elseif (false === $editedAddress->update()) { - throw new CannotUpdateAddressException(sprintf('Failed to update address "%s"', $editedAddress->id)); - } - } catch (PrestaShopException $e) { - throw new AddressException(sprintf('An error occurred when updating address "%s"', $command->getAddressId()->getValue())); - } - - return new AddressId((int) $editedAddress->id); - } - - /** - * @param EditCustomerAddressCommand $command - * - * @return Address - * - * @throws AddressException - * @throws AddressNotFoundException - */ - private function getAddressFromCommand(EditCustomerAddressCommand $command): Address - { - $address = $this->getAddress($command->getAddressId()); - - if (null !== $command->getLastName()) { - $address->lastname = $command->getLastName(); - } - - if (null !== $command->getFirstName()) { - $address->firstname = $command->getFirstName(); - } - - if (null !== $command->getAddress()) { - $address->address1 = $command->getAddress(); - } - - if (null !== $command->getPostCode()) { - $address->postcode = $command->getPostCode(); - } - - if (null !== $command->getCountryId()) { - $address->id_country = $command->getCountryId()->getValue(); - } - - if (null !== $command->getStateId()) { - $address->id_state = $command->getStateId()->getValue(); - } elseif (null !== $command->getCountryId()) { - // If country was changed but not state we check if state value needs to be reset - $country = new Country($command->getCountryId()->getValue()); - if (!$country->contains_states) { - $address->id_state = 0; - } - } - - if (null !== $command->getCity()) { - $address->city = $command->getCity(); - } - - if (null !== $command->getAddressAlias()) { - $address->alias = $command->getAddressAlias(); - } - - if (null !== $command->getAddress2()) { - $address->address2 = $command->getAddress2(); - } - - if (null !== $command->getDni()) { - $address->dni = $command->getDni(); - } - - if (null !== $command->getCompany()) { - $address->company = $command->getCompany(); - } - - if (null !== $command->getVatNumber()) { - $address->vat_number = $command->getVatNumber(); - } - - if (null !== $command->getHomePhone()) { - $address->phone = $command->getHomePhone(); - } - - if (null !== $command->getMobilePhone()) { - $address->phone_mobile = $command->getMobilePhone(); - } - - if (null !== $command->getOther()) { - $address->other = $command->getOther(); - } - - return $address; - } -} diff --git a/src/Adapter/Address/CommandHandler/EditManufacturerAddressHandler.php b/src/Adapter/Address/CommandHandler/EditManufacturerAddressHandler.php deleted file mode 100644 index 919b553a..00000000 --- a/src/Adapter/Address/CommandHandler/EditManufacturerAddressHandler.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Address; -use Country; -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditManufacturerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditManufacturerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShopException; - -/** - * Handles command which edits manufacturer address - */ -final class EditManufacturerAddressHandler extends AbstractAddressHandler implements EditManufacturerAddressHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditManufacturerAddressCommand $command) - { - $addressId = $command->getAddressId(); - $address = $this->getAddress($addressId); - $this->populateAddressWithData($address, $command); - - try { - $this->validateAddress($address); - if (!$address->update()) { - throw new AddressException(sprintf('Cannot update address with id "%s"', $address->id)); - } - } catch (PrestaShopException $e) { - throw new AddressException(sprintf('Cannot update address with id "%s"', $address->id)); - } - } - - /** - * Populates Address object with given data - * - * @param $address - * @param EditManufacturerAddressCommand $command - */ - private function populateAddressWithData(Address $address, $command) - { - if (null !== $command->getManufacturerId()) { - $address->id_manufacturer = $command->getManufacturerId(); - } - if (null !== $command->getLastName()) { - $address->lastname = $command->getLastName(); - } - if (null !== $command->getFirstName()) { - $address->firstname = $command->getFirstName(); - } - if (null !== $command->getAddress()) { - $address->address1 = $command->getAddress(); - } - if (null !== $command->getAddress2()) { - $address->address2 = $command->getAddress2(); - } - if (null !== $command->getPostCode()) { - $address->postcode = $command->getPostCode(); - } - if (null !== $command->getCity()) { - $address->city = $command->getCity(); - } - if (null !== $command->getCountryId()) { - $address->id_country = $command->getCountryId(); - } - if (null !== $command->getStateId()) { - $address->id_state = $command->getStateId(); - } elseif (null !== $command->getCountryId()) { - // If country was changed but not state we check if state value needs to be reset - $country = new Country($command->getCountryId()); - if (!$country->contains_states) { - $address->id_state = 0; - } - } - if (null !== $command->getHomePhone()) { - $address->phone = $command->getHomePhone(); - } - if (null !== $command->getMobilePhone()) { - $address->phone_mobile = $command->getMobilePhone(); - } - if (null !== $command->getOther()) { - $address->other = $command->getOther(); - } - if (null !== $command->getDni()) { - $address->dni = $command->getDni(); - } - } -} diff --git a/src/Adapter/Address/CommandHandler/EditOrderAddressHandler.php b/src/Adapter/Address/CommandHandler/EditOrderAddressHandler.php deleted file mode 100644 index ad5e5248..00000000 --- a/src/Adapter/Address/CommandHandler/EditOrderAddressHandler.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use Order; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditOrderAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditCustomerAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\EditOrderAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotUpdateOrderAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderDeliveryAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderInvoiceAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ChangeOrderDeliveryAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ChangeOrderInvoiceAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderAddressType; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShopException; - -/** - * EditOrderAddressCommandHandler manages an address update, it then updates order and cart - * relation to the newly created address. - */ -class EditOrderAddressHandler implements EditOrderAddressHandlerInterface -{ - /** - * @var EditCustomerAddressHandlerInterface - */ - private $addressHandler; - - /** - * @var ChangeOrderDeliveryAddressHandlerInterface - */ - private $deliveryAddressHandler; - - /** - * @var ChangeOrderInvoiceAddressHandlerInterface - */ - private $invoiceAddressHandler; - - /** - * @param EditCustomerAddressHandlerInterface $addressHandler - * @param ChangeOrderDeliveryAddressHandlerInterface $deliveryAddressHandler - * @param ChangeOrderInvoiceAddressHandlerInterface $invoiceAddressHandler - */ - public function __construct( - EditCustomerAddressHandlerInterface $addressHandler, - ChangeOrderDeliveryAddressHandlerInterface $deliveryAddressHandler, - ChangeOrderInvoiceAddressHandlerInterface $invoiceAddressHandler - ) { - $this->addressHandler = $addressHandler; - $this->deliveryAddressHandler = $deliveryAddressHandler; - $this->invoiceAddressHandler = $invoiceAddressHandler; - } - - /** - * {@inheritdoc} - * - * @throws AddressConstraintException - * @throws CannotUpdateOrderAddressException - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function handle(EditOrderAddressCommand $command): AddressId - { - try { - $addressCommand = $this->createEditAddressCommand($command); - /** @var AddressId $addressId */ - $addressId = $this->addressHandler->handle($addressCommand); - - switch ($command->getAddressType()) { - case OrderAddressType::DELIVERY_ADDRESS_TYPE: - $this->deliveryAddressHandler->handle(new ChangeOrderDeliveryAddressCommand( - $command->getOrderId()->getValue(), $addressId->getValue() - )); - break; - case OrderAddressType::INVOICE_ADDRESS_TYPE: - $this->invoiceAddressHandler->handle(new ChangeOrderInvoiceAddressCommand( - $command->getOrderId()->getValue(), $addressId->getValue() - )); - break; - } - } catch (PrestaShopException $e) { - throw new CannotUpdateOrderAddressException(sprintf('An error occurred when updating address for order "%s"', $command->getOrderId()->getValue())); - } - - return $addressId; - } - - /** - * @param EditOrderAddressCommand $orderCommand - * - * @return EditCustomerAddressCommand - * - * @throws AddressConstraintException - * @throws CountryConstraintException - * @throws StateConstraintException - * @throws PrestaShopException - */ - private function createEditAddressCommand(EditOrderAddressCommand $orderCommand): EditCustomerAddressCommand - { - $order = new Order($orderCommand->getOrderId()->getValue()); - $addressId = null; - switch ($orderCommand->getAddressType()) { - case OrderAddressType::DELIVERY_ADDRESS_TYPE: - $addressId = (int) $order->id_address_delivery; - break; - case OrderAddressType::INVOICE_ADDRESS_TYPE: - $addressId = (int) $order->id_address_invoice; - break; - } - $addressCommand = new EditCustomerAddressCommand($addressId); - if (null !== $orderCommand->getAddressAlias()) { - $addressCommand->setAddressAlias($orderCommand->getAddressAlias()); - } - if (null !== $orderCommand->getFirstName()) { - $addressCommand->setFirstName($orderCommand->getFirstName()); - } - if (null !== $orderCommand->getLastName()) { - $addressCommand->setLastName($orderCommand->getLastName()); - } - if (null !== $orderCommand->getAddress()) { - $addressCommand->setAddress($orderCommand->getAddress()); - } - if (null !== $orderCommand->getCity()) { - $addressCommand->setCity($orderCommand->getCity()); - } - if (null !== $orderCommand->getPostCode()) { - $addressCommand->setPostCode($orderCommand->getPostCode()); - } - if (null !== $orderCommand->getCountryId()) { - $addressCommand->setCountryId($orderCommand->getCountryId()->getValue()); - } - if (null !== $orderCommand->getDni()) { - $addressCommand->setDni($orderCommand->getDni()); - } - if (null !== $orderCommand->getCompany()) { - $addressCommand->setCompany($orderCommand->getCompany()); - } - if (null !== $orderCommand->getVatNumber()) { - $addressCommand->setVatNumber($orderCommand->getVatNumber()); - } - if (null !== $orderCommand->getAddress2()) { - $addressCommand->setAddress2($orderCommand->getAddress2()); - } - if (null !== $orderCommand->getStateId()) { - $addressCommand->setStateId($orderCommand->getStateId()->getValue()); - } - if (null !== $orderCommand->getHomePhone()) { - $addressCommand->setHomePhone($orderCommand->getHomePhone()); - } - if (null !== $orderCommand->getMobilePhone()) { - $addressCommand->setMobilePhone($orderCommand->getMobilePhone()); - } - if (null !== $orderCommand->getOther()) { - $addressCommand->setOther($orderCommand->getOther()); - } - - return $addressCommand; - } -} diff --git a/src/Adapter/Address/CommandHandler/SetRequiredFieldsForAddressHandler.php b/src/Adapter/Address/CommandHandler/SetRequiredFieldsForAddressHandler.php deleted file mode 100644 index 5de8e368..00000000 --- a/src/Adapter/Address/CommandHandler/SetRequiredFieldsForAddressHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\CommandHandler; - -use CustomerAddress; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\SetRequiredFieldsForAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler\SetRequiredFieldsForAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotSetRequiredFieldsForAddressException; -use PrestaShopDatabaseException; - -/** - * Handles command which sets required fields for address. - * - * @internal - */ -final class SetRequiredFieldsForAddressHandler implements SetRequiredFieldsForAddressHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotSetRequiredFieldsForAddressException - */ - public function handle(SetRequiredFieldsForAddressCommand $command) - { - $address = new CustomerAddress(); - - try { - if ($address->addFieldsRequiredDatabase($command->getRequiredFields())) { - return; - } - } catch (PrestaShopDatabaseException $e) { - } - - throw new CannotSetRequiredFieldsForAddressException(sprintf('Cannot set "%s" required fields for customer', implode(',', $command->getRequiredFields()))); - } -} diff --git a/src/Adapter/Address/QueryHandler/GetCustomerAddressForEditingHandler.php b/src/Adapter/Address/QueryHandler/GetCustomerAddressForEditingHandler.php deleted file mode 100644 index 2d142118..00000000 --- a/src/Adapter/Address/QueryHandler/GetCustomerAddressForEditingHandler.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Adapter\Address\AbstractCustomerAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler\GetCustomerAddressForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableCustomerAddress; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShop\PrestaShop\Core\Domain\State\ValueObject\StateId; -use PrestaShopException; - -/** - * Handles query which gets customer address for editing - */ -final class GetCustomerAddressForEditingHandler extends AbstractCustomerAddressHandler implements GetCustomerAddressForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AddressException - * @throws AddressNotFoundException - * @throws CustomerException - * @throws CustomerNotFoundException - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function handle(GetCustomerAddressForEditing $query): EditableCustomerAddress - { - $addressId = $query->getAddressId(); - $address = $this->getAddress($addressId); - - try { - $customerId = new CustomerId((int) $address->id_customer); - $customer = new Customer($customerId->getValue()); - } catch (PrestaShopException $e) { - throw new CustomerException('Failed to get customer', 0, $e); - } - - if ($customer->id !== $customerId->getValue()) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found.', $customerId->getValue())); - } - - $editableCustomerAddress = new EditableCustomerAddress( - $addressId, - $customerId, - $customer->email, - $address->alias, - $address->firstname, - $address->lastname, - $address->address1, - $address->city, - new CountryId((int) $address->id_country), - $address->postcode, - $address->dni, - $address->company, - $address->vat_number, - $address->address2, - new StateId($address->id_state), - $address->phone, - $address->phone_mobile, - $address->other, - $this->getRequiredFields() - ); - - return $editableCustomerAddress; - } -} diff --git a/src/Adapter/Address/QueryHandler/GetManufacturerAddressForEditingHandler.php b/src/Adapter/Address/QueryHandler/GetManufacturerAddressForEditingHandler.php deleted file mode 100644 index c0747f8e..00000000 --- a/src/Adapter/Address/QueryHandler/GetManufacturerAddressForEditingHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Address\AbstractAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetManufacturerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler\GetManufacturerAddressForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableManufacturerAddress; - -/** - * Handles query which gets manufacturer address for editing - */ -final class GetManufacturerAddressForEditingHandler extends AbstractAddressHandler implements GetManufacturerAddressForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetManufacturerAddressForEditing $query) - { - $addressId = $query->getAddressId(); - - $address = $this->getAddress($addressId); - - return new EditableManufacturerAddress( - $addressId, - $address->lastname, - $address->firstname, - $address->address1, - $address->city, - (int) $address->id_manufacturer, - (int) $address->id_country, - $address->address2, - $address->postcode, - (int) $address->id_state, - $address->phone, - $address->phone_mobile, - $address->other, - $address->dni - ); - } -} diff --git a/src/Adapter/Address/QueryHandler/GetRequiredFieldsForAddressHandler.php b/src/Adapter/Address/QueryHandler/GetRequiredFieldsForAddressHandler.php deleted file mode 100644 index 4cdb5083..00000000 --- a/src/Adapter/Address/QueryHandler/GetRequiredFieldsForAddressHandler.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Address\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Address\AbstractCustomerAddressHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetRequiredFieldsForAddress; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler\GetRequiredFieldsForAddressHandlerInterface; - -/** - * Handles query which gets required fields for address - * - * @internal - */ -final class GetRequiredFieldsForAddressHandler extends AbstractCustomerAddressHandler implements GetRequiredFieldsForAddressHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AddressException - */ - public function handle(GetRequiredFieldsForAddress $query): array - { - return $this->getRequiredFields(); - } -} diff --git a/src/Adapter/AddressFactory.php b/src/Adapter/AddressFactory.php deleted file mode 100644 index 884d66cf..00000000 --- a/src/Adapter/AddressFactory.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Address; - -/** - * Class responsible of creation of Address ObjectModel. - */ -class AddressFactory -{ - /** - * Initialize an address corresponding to the specified id address or if empty to the - * default shop configuration. - * - * @param int|null $id_address - * @param bool $with_geoloc - * - * @return Address - */ - public function findOrCreate($id_address = null, $with_geoloc = false) - { - $func_args = func_get_args(); - - return call_user_func_array(['\\Address', 'initialize'], $func_args); - } - - /** - * Check if an address exists depending on given $id_address. - * - * @param $id_address - * - * @return bool - */ - public function addressExists($id_address) - { - return Address::addressExists($id_address); - } -} diff --git a/src/Adapter/Admin/AbstractAdminQueryBuilder.php b/src/Adapter/Admin/AbstractAdminQueryBuilder.php deleted file mode 100644 index 96127b13..00000000 --- a/src/Adapter/Admin/AbstractAdminQueryBuilder.php +++ /dev/null @@ -1,221 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Admin; - -use PrestaShop\PrestaShop\Adapter\Validate; -use Symfony\Component\Process\Exception\LogicException; - -/** - * Base class for data provider, to give common Adapter functions. - * - * Contains methods to compile SQL from parseable arrays of select, tables, joins, where, etc... - */ -abstract class AbstractAdminQueryBuilder -{ - const FILTERING_LIKE_BOTH = 'LIKE \'%%%s%%\''; - const FILTERING_LIKE_LEFT = 'LIKE \'%%%s\''; - const FILTERING_LIKE_RIGHT = 'LIKE \'%s%%\''; - const FILTERING_EQUAL_NUMERIC = '= %s'; - const FILTERING_EQUAL_STRING = '= \'%s\''; - - /** - * @var string|null - */ - private $lastCompiledSql = null; - - /** - * @param array $whereArray - * - * @return mixed|string - */ - private function compileSqlWhere(array $whereArray) - { - $operator = 'AND'; - $s = []; - while ($item = array_shift($whereArray)) { - if ($item == 'OR') { - $operator = 'OR'; - } elseif ($item == 'AND') { - $operator = 'AND'; - } else { - $s[] = (is_array($item) ? $this->compileSqlWhere($item) : $item); - } - } - if (count($s) == 1) { - return $s[0]; - } - - return '(' . implode(' ' . $operator . ' ', $s) . ')'; - } - - /** - * Compiles a SQL query (SELECT), from a group of associative arrays. - * - * @see \PrestaShop\PrestaShop\Adapter\Product\AdminProductDataProvider::getCatalogProductList() for an example. - * - * Format example for $table: - * $table = array( - * 'p' => 'product', // First table: a simple name - * 'pl' => array( // Next: arrays to set join properly - * 'table' => 'product_lang', - * 'join' => 'LEFT JOIN', - * 'on' => 'pl.`id_product` = p.`id_product` AND pl.`id_lang` = '.$idLang.' AND pl.`id_shop` = '.$idShop - * ), - * 'sav' => array( - * 'table' => 'stock_available', - * 'join' => 'LEFT JOIN', - * 'on' => 'sav.`id_product` = p.`id_product` AND sav.`id_product_attribute` = 0 AND sav.id_shop_group = 1 AND sav.id_shop = 0' - * ), - * ... - * ); - * - * Format example for $select: - * $select = array( - * 'id_product' => array('table' => 'p', 'field' => 'id_product', 'filtering' => self::FILTERING_EQUAL_NUMERIC), - * 'reference' => array('table' => 'p', 'field' => 'reference', 'filtering' => self::FILTERING_LIKE_BOTH), - * ... - * ); - * - * Format example for $where: - * $where = array( - * 'AND', // optional if AND, mandatory if OR. - * 1, // First condition: let 1 here if there is no condition, then "WHERE 1;" will work better than "WHERE ;" - * array('OR', '2', '3'), - * array( - * 'AND', - * array('OR', '4', '5'), - * array('6', '7') - * ) - * ); - * In the WHERE, it's up to you to build each condition string. You can use the 'filtering' data in the $select array to help you: - * $where[] = $select[$field]['table'].'.`'.$select[$field]['field'].'` '.sprintf($select[$field]['filtering'], $filterValue); - * - * Format example for $order: - * $order = array('name ASC', 'id_product DESC'); - * - * @param array[array[mixed]] $select - * @param array[mixed] $table - * @param array[mixed] $where - * @param array[string] $groupBy - * @param array[string] $order - * @param string $limit - * - * @throws LogicException if SQL elements cannot be joined - * - * @return string the SQL query ready to be executed - */ - protected function compileSqlQuery(array $select, array $table, array $where = [], array $groupBy = [], array $order = [], $limit = null) - { - $sql = []; - - // SELECT - $s = []; - foreach ($select as $alias => $field) { - $a = is_string($alias) ? ' AS `' . $alias . '`' : ''; - if (is_array($field)) { - if (isset($field['table'])) { - $s[] = ' ' . $field['table'] . '.`' . $field['field'] . '` ' . $a; - } elseif (isset($field['select'])) { - $s[] = ' ' . $field['select'] . $a; - } - } else { - $s[] = ' ' . $field . $a; - } - } - if (count($s) === 0) { - throw new LogicException('Compile SQL failed: No field to SELECT!'); - } - $sql[] = 'SELECT SQL_CALC_FOUND_ROWS' . implode(',' . PHP_EOL, $s); - - // FROM / JOIN - $s = []; - foreach ($table as $alias => $join) { - if (!is_array($join)) { - if (count($s) > 0) { - throw new LogicException('Compile SQL failed: cannot join the table ' . $join . ' into SQL query without JOIN sepcs.'); - } - $s[0] = ' `' . _DB_PREFIX_ . $join . '` ' . $alias; - } else { - if (count($s) === 0) { - throw new LogicException('Compile SQL failed: cannot join the table alias ' . $alias . ' into SQL query before to insert initial table.'); - } - $s[] = ' ' . $join['join'] . ' `' . _DB_PREFIX_ . $join['table'] . '` ' . $alias . ((isset($join['on'])) ? ' ON (' . $join['on'] . ')' : ''); - } - } - if (count($s) === 0) { - throw new LogicException('Compile SQL failed: No table to insert into FROM!'); - } - $sql[] = 'FROM ' . implode(' ' . PHP_EOL, $s); - - // WHERE (recursive call) - if (count($where)) { - $s = $this->compileSqlWhere($where); - if (strlen($s) > 0) { - $sql[] = 'WHERE ' . $s . PHP_EOL; - } - } - - // GROUP BY - if (!empty($groupBy)) { - $sql[] = 'GROUP BY ' . implode(', ', array_map('pSQL', $groupBy)) . PHP_EOL; - } - - // ORDER - if (count($order) > 0) { - $goodOrder = []; - foreach ($order as $o) { - $value = explode(' ', $o); - if (!empty($value) && 2 === count($value) && Validate::isOrderBy($value[0]) && Validate::isOrderWay($value[1])) { - $goodOrder[] = ' `' . bqSQL($value[0]) . '` ' . $value[1]; - } - } - - if (count($goodOrder) > 0) { - $sql[] = 'ORDER BY ' . implode(', ', $goodOrder) . PHP_EOL; - } - } - - // LIMIT - if ($limit) { - $sql[] = 'LIMIT ' . $limit . PHP_EOL; - } - - $this->lastCompiledSql = implode(' ' . PHP_EOL, $sql) . ';'; - - return $this->lastCompiledSql; - } - - /** - * Returns the last SQL query that was compiled on this Provider. - * - * @return string The last SQL query that was compiled with $this->compileSqlQuery() - */ - public function getLastCompiledSql() - { - return $this->lastCompiledSql; - } -} diff --git a/src/Adapter/Admin/LegacyBlockHelperSubscriber.php b/src/Adapter/Admin/LegacyBlockHelperSubscriber.php deleted file mode 100644 index 76ebbf55..00000000 --- a/src/Adapter/Admin/LegacyBlockHelperSubscriber.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Admin; - -use PrestaShopBundle\Service\Hook\RenderingHookEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * Adds listeners to renderhook Twig function, to let adding legacy helpers like Kpi, etc... - */ -class LegacyBlockHelperSubscriber implements EventSubscriberInterface -{ - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array The listeners array - */ - public static function getSubscribedEvents() - { - return [ - 'legacy_block_kpi' => ['renderKpi', 0], - ]; - } - - /** - * Renders a Kpi block for a given legacy controller name. - * - * @param RenderingHookEvent $event - * - * @throws \Exception - */ - public function renderKpi(RenderingHookEvent $event) - { - if (!array_key_exists('kpi_controller', $event->getHookParameters())) { - throw new \Exception('The legacy_kpi hook need a kpi_controller parameter (legacy controller full class name).'); - } - - $controller = $event->getHookParameters()['kpi_controller']; - $controller = new $controller('new-theme'); - $renderKpis = $controller->renderKpis() !== null ? $controller->renderKpis() : []; - - $event->setContent($renderKpis); - } -} diff --git a/src/Adapter/Admin/NotificationsConfiguration.php b/src/Adapter/Admin/NotificationsConfiguration.php deleted file mode 100644 index 5f741462..00000000 --- a/src/Adapter/Admin/NotificationsConfiguration.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Admin; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Manages the configuration data about notifications options. - */ -class NotificationsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'show_notifs_new_orders' => $this->configuration->getBoolean('PS_SHOW_NEW_ORDERS'), - 'show_notifs_new_customers' => $this->configuration->getBoolean('PS_SHOW_NEW_CUSTOMERS'), - 'show_notifs_new_messages' => $this->configuration->getBoolean('PS_SHOW_NEW_MESSAGES'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_SHOW_NEW_ORDERS', (bool) $configuration['show_notifs_new_orders']); - $this->configuration->set('PS_SHOW_NEW_CUSTOMERS', (bool) $configuration['show_notifs_new_customers']); - $this->configuration->set('PS_SHOW_NEW_MESSAGES', (bool) $configuration['show_notifs_new_messages']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['show_notifs_new_orders'], - $configuration['show_notifs_new_customers'], - $configuration['show_notifs_new_messages'] - ); - } -} diff --git a/src/Adapter/Admin/PagePreference.php b/src/Adapter/Admin/PagePreference.php deleted file mode 100644 index 6aa26801..00000000 --- a/src/Adapter/Admin/PagePreference.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Admin; - -use AppKernel; -use Db; -use PrestaShopBundle\Service\TransitionalBehavior\AdminPagePreferenceInterface; -use Symfony\Component\HttpFoundation\Session\SessionInterface; -use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage; - -/** - * Adapter to know which page's version to display. - * - * This implementation gives methods to use to take decision: - * - if we should display the new refactored page, or the old legacy one. - * - if we should display the switch on the admin layout to change this setting. - * - * Data is stored in the cookie, as legacy does. - */ -class PagePreference implements AdminPagePreferenceInterface -{ - /** - * @var SessionInterface - */ - private $session; - - public function __construct(SessionInterface $session) - { - if ($session->isStarted()) { - $this->session = $session; - } else { - $sessionClass = get_class($session); - $this->session = new $sessionClass(new PhpBridgeSessionStorage()); - } - } - - /** - * {@inheritdoc} - */ - public function getTemporaryShouldUseLegacyPage($page) - { - if (!$page) { - throw new \InvalidParameterException('$page parameter missing'); - } - - return $this->session->has('should_use_legacy_page_for_' . $page) && $this->session->get('should_use_legacy_page_for_' . $page, 0) == 1; - } - - /** - * {@inheritdoc} - */ - public function setTemporaryShouldUseLegacyPage($page, $useLegacy) - { - if (!$page) { - throw new \InvalidParameterException('$page parameter missing'); - } - - if ((bool) $useLegacy) { - $this->session->set('should_use_legacy_page_for_' . $page, 1); - } else { - $this->session->remove('should_use_legacy_page_for_' . $page); - } - } - - /** - * {@inheritdoc} - */ - public function getTemporaryShouldAllowUseLegacyPage($page = null) - { - // Dev mode: always shown - if (_PS_MODE_DEV_) { - return true; - } - - $version = Db::getInstance()->getValue('SELECT `value` FROM `' . _DB_PREFIX_ . 'configuration` WHERE `name` = "PS_INSTALL_VERSION"'); - if (!$version) { - return false; - } - $installVersion = explode('.', $version); - $currentVersion = explode('.', AppKernel::VERSION); - - // Prod mode, depends on the page - switch ($page) { - case 'product': - // never show it for Product page in production mode. - return false; - default: - // show only for 1.7.x - if ($currentVersion[0] != '1' || $currentVersion[1] != '7') { - return false; - } - // show only if upgrade from older version than current one - if ($installVersion[0] >= $currentVersion[0] || $installVersion[1] >= $currentVersion[1]) { - return false; - } - } - - return true; - } -} diff --git a/src/Adapter/Admin/UrlGenerator.php b/src/Adapter/Admin/UrlGenerator.php deleted file mode 100644 index f1808aae..00000000 --- a/src/Adapter/Admin/UrlGenerator.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Admin; - -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use ReflectionClass; -use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Routing\RequestContext; -use Symfony\Component\Routing\Router; - -/** - * This UrlGeneratorInterface implementation (in a Sf service) will provides Legacy URLs. - * - * To be used by Symfony controllers, to generate a link to a Legacy page. - * Call an instance of it through the Symfony container: - * $container->get('prestashop.core.admin.url_generator_legacy'); - * Or via the UrlGeneratorFactory (as Sf service): - * $container->get('prestashop.core.admin.url_generator_factory')->forLegacy(); - */ -class UrlGenerator implements UrlGeneratorInterface -{ - /** - * @var LegacyContext - */ - private $legacyContext; - - /** - * @var Router - */ - private $router; - - /** - * Constructor. - * - * @param LegacyContext $legacyContext - * @param Router - */ - public function __construct(LegacyContext $legacyContext, Router $router) - { - $this->legacyContext = $legacyContext; - $this->router = $router; - } - - /** - * {@inheritdoc} - */ - public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) - { - // By default, consider given parameters in legacy format (no mapping if route not found). - $legacyController = $name; - $legacyParameters = $parameters; - - // resolve route & legacy mapping - list($legacyController, $legacyParameters) = $this->getLegacyOptions($name, $parameters); - - return $this->legacyContext->getAdminLink($legacyController, true, $legacyParameters); - } - - /** - * Try to get controller & parameters with mapping options. - * - * If failed to find options, then return the input values. - * - * @param string $routeName - * @param string[] $parameters The route parameters to convert - * - * @return array[] An array with: the legacy controller name, then the parameters array - */ - final public function getLegacyOptions($routeName, $parameters = []) - { - $legacyController = $routeName; - $legacyParameters = $parameters; - - $route = $this->router->getRouteCollection()->get($routeName); - if ($route) { - if ($route->hasDefault('_legacy_controller')) { - $legacyController = $route->getDefault('_legacy_controller'); - if ($route->hasDefault('_legacy_param_mapper_class') && $route->hasDefault('_legacy_param_mapper_method')) { - $class = $route->getDefault('_legacy_param_mapper_class'); - $method = $route->getDefault('_legacy_param_mapper_method'); - $method = (new ReflectionClass('\\' . $class))->getMethod($method); - $legacyParameters = $method->invoke(($method->isStatic()) ? null : $method->getDeclaringClass()->newInstance(), $parameters); - } - } - } - - return [$legacyController, $legacyParameters]; - } - - /** - * {@inheritdoc} - */ - public function setContext(RequestContext $context) - { - throw new LogicException('Cannot use this UrlGeneratorInterface implementation with a Symfony context. Please call AdminUrlGeneratorFactory::forLegacy() to reach the right instance.'); - } - - /** - * {@inheritdoc} - */ - public function getContext() - { - throw new LogicException('Cannot use this UrlGeneratorInterface implementation with a Symfony context. Please call AdminUrlGeneratorFactory::forLegacy() to reach the right instance.'); - } -} diff --git a/src/Adapter/Assets/AssetUrlGeneratorTrait.php b/src/Adapter/Assets/AssetUrlGeneratorTrait.php deleted file mode 100644 index e74dbff7..00000000 --- a/src/Adapter/Assets/AssetUrlGeneratorTrait.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -namespace PrestaShop\PrestaShop\Adapter\Assets; - -use Tools as ToolsLegacy; - -trait AssetUrlGeneratorTrait -{ - /** - * @var string - */ - protected $fqdn; - - /** - * @param string $fullPath - * - * @return string - */ - protected function getUriFromPath($fullPath) - { - return str_replace($this->configuration->get('_PS_ROOT_DIR_'), rtrim($this->configuration->get('__PS_BASE_URI__'), '/'), $fullPath); - } - - /** - * @param string $fullUri - * - * @return string - */ - protected function getPathFromUri($fullUri) - { - if ('' !== ($trimmedUri = rtrim($this->configuration->get('__PS_BASE_URI__'), '/'))) { - return $this->configuration->get('_PS_ROOT_DIR_') . preg_replace('#\\' . $trimmedUri . '#', '', $fullUri, 1); - } - - return $this->configuration->get('_PS_ROOT_DIR_') . $fullUri; - } - - /** - * @return string - */ - protected function getFQDN() - { - if (null === $this->fqdn) { - if ($this->configuration->get('PS_SSL_ENABLED') && ToolsLegacy::usingSecureMode()) { - $this->fqdn = $this->configuration->get('_PS_BASE_URL_SSL_'); - } else { - $this->fqdn = $this->configuration->get('_PS_BASE_URL_'); - } - } - - return $this->fqdn; - } -} diff --git a/src/Adapter/Attachment/AbstractAttachmentHandler.php b/src/Adapter/Attachment/AbstractAttachmentHandler.php deleted file mode 100644 index 026432a7..00000000 --- a/src/Adapter/Attachment/AbstractAttachmentHandler.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment; - -use Attachment; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\DeleteAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Abstract attachment handler - */ -abstract class AbstractAttachmentHandler -{ - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @param ValidatorInterface $validator - */ - public function __construct(ValidatorInterface $validator) - { - $this->validator = $validator; - } - - /** - * @param array $localizedTexts - * - * @throws AttachmentConstraintException - */ - protected function assertHasDefaultLanguage(array $localizedTexts) - { - $errors = $this->validator->validate($localizedTexts, new DefaultLanguage()); - - if (0 !== count($errors)) { - throw new AttachmentConstraintException('Missing name in default language', AttachmentConstraintException::MISSING_NAME_IN_DEFAULT_LANGUAGE); - } - } - - /** - * @param array $localizedDescription - * - * @throws AttachmentConstraintException - */ - protected function assertDescriptionContainsCleanHtml(array $localizedDescription) - { - foreach ($localizedDescription as $description) { - $errors = $this->validator->validate($description, new CleanHtml()); - - if (0 !== count($errors)) { - throw new AttachmentConstraintException(sprintf('Given description "%s" contains javascript events or script tags', $description), AttachmentConstraintException::INVALID_DESCRIPTION); - } - } - } - - /** - * @return string - */ - protected function getUniqueFileName(): string - { - $uniqueFileName = sha1(uniqid()); - - return $uniqueFileName; - } - - /** - * @param Attachment $attachment - * - * @throws AttachmentConstraintException - * @throws PrestaShopException - */ - protected function assertValidFields(Attachment $attachment) - { - if (!$attachment->validateFields(false) && !$attachment->validateFieldsLang(false)) { - throw new AttachmentConstraintException('Attachment contains invalid field values', AttachmentConstraintException::INVALID_FIELDS); - } - } - - /** - * @param AttachmentId $attachmentId - * - * @return Attachment - * - * @throws AttachmentNotFoundException - */ - protected function getAttachment(AttachmentId $attachmentId): Attachment - { - $attachmentIdValue = $attachmentId->getValue(); - try { - $attachment = new Attachment($attachmentIdValue); - } catch (PrestaShopException $e) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentId->getValue())); - } - - if ($attachment->id !== $attachmentId->getValue()) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentId->getValue())); - } - - return $attachment; - } - - /** - * Deletes legacy Attachment - * - * @param Attachment $attachment - * - * @return bool - * - * @throws DeleteAttachmentException - */ - protected function deleteAttachment(Attachment $attachment): bool - { - try { - return $attachment->delete(); - } catch (PrestaShopException $e) { - throw new DeleteAttachmentException(sprintf('An error occurred when deleting Attachment object with id "%s".', $attachment->id)); - } - } -} diff --git a/src/Adapter/Attachment/CommandHandler/AddAttachmentHandler.php b/src/Adapter/Attachment/CommandHandler/AddAttachmentHandler.php deleted file mode 100644 index 7224549b..00000000 --- a/src/Adapter/Attachment/CommandHandler/AddAttachmentHandler.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler; - -use Attachment; -use PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler; -use PrestaShop\PrestaShop\Adapter\File\Uploader\AttachmentFileUploader; -use PrestaShop\PrestaShop\Core\Domain\Attachment\AttachmentFileUploaderInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\AddAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler\AddAttachmentHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotAddAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\EmptyFileException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Handles attachment creation and file uploading procedures - */ -final class AddAttachmentHandler extends AbstractAttachmentHandler implements AddAttachmentHandlerInterface -{ - /** - * @var AttachmentFileUploader - */ - protected $fileUploader; - - /** - * @param ValidatorInterface $validator - * @param AttachmentFileUploaderInterface $fileUploader - */ - public function __construct(ValidatorInterface $validator, AttachmentFileUploaderInterface $fileUploader) - { - parent::__construct($validator); - - $this->fileUploader = $fileUploader; - } - - /** - * {@inheritdoc} - * - * @throws AttachmentConstraintException - * @throws AttachmentException - * @throws AttachmentNotFoundException - */ - public function handle(AddAttachmentCommand $command): AttachmentId - { - try { - if ($command->getFilePathName() === null) { - throw new EmptyFileException('No file found to be uploaded'); - } - - $attachment = new Attachment(); - - $this->assertDescriptionContainsCleanHtml($command->getLocalizedDescriptions()); - $this->assertHasDefaultLanguage($command->getLocalizedNames()); - - $uniqueFileName = $this->getUniqueFileName(); - - $attachment->description = $command->getLocalizedDescriptions(); - $attachment->name = $command->getLocalizedNames(); - $attachment->file_name = $command->getOriginalName(); - $attachment->file = $uniqueFileName; - $attachment->mime = $command->getMimeType(); - - $this->assertValidFields($attachment); - - $this->fileUploader->upload($command->getFilePathName(), $uniqueFileName, $command->getFileSize()); - - if (false === $attachment->add()) { - throw new CannotAddAttachmentException('Failed to add attachment'); - } - } catch (PrestaShopException $e) { - throw new AttachmentException('An unexpected error occurred when adding attachment', 0, $e); - } - - return new AttachmentId($attachment->id); - } -} diff --git a/src/Adapter/Attachment/CommandHandler/BulkDeleteAttachmentsHandler.php b/src/Adapter/Attachment/CommandHandler/BulkDeleteAttachmentsHandler.php deleted file mode 100644 index e6388050..00000000 --- a/src/Adapter/Attachment/CommandHandler/BulkDeleteAttachmentsHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\BulkDeleteAttachmentsCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler\BulkDeleteAttachmentsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\BulkDeleteAttachmentsException; - -/** - * Bulk delete attachments handler - */ -final class BulkDeleteAttachmentsHandler extends AbstractAttachmentHandler implements BulkDeleteAttachmentsHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws BulkDeleteAttachmentsException - */ - public function handle(BulkDeleteAttachmentsCommand $command) - { - $errors = []; - - foreach ($command->getAttachmentIds() as $attachmentId) { - try { - $attachment = $this->getAttachment($attachmentId); - - if (!$this->deleteAttachment($attachment)) { - $errors[] = $attachment->id; - } - } catch (AttachmentException $e) { - $errors[] = $attachmentId->getValue(); - } - } - - if (!empty($errors)) { - throw new BulkDeleteAttachmentsException($errors, 'Failed to delete all of selected attachments'); - } - } -} diff --git a/src/Adapter/Attachment/CommandHandler/DeleteAttachmentHandler.php b/src/Adapter/Attachment/CommandHandler/DeleteAttachmentHandler.php deleted file mode 100644 index 09730822..00000000 --- a/src/Adapter/Attachment/CommandHandler/DeleteAttachmentHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\DeleteAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler\DeleteAttachmentHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\DeleteAttachmentException; - -/** - * Delete attachment handler - */ -final class DeleteAttachmentHandler extends AbstractAttachmentHandler implements DeleteAttachmentHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws DeleteAttachmentException - * @throws AttachmentNotFoundException - */ - public function handle(DeleteAttachmentCommand $command) - { - $attachment = $this->getAttachment($command->getAttachmentId()); - - if (!$this->deleteAttachment($attachment)) { - throw new DeleteAttachmentException(sprintf('Cannot delete Attachment object with id "%s".', $attachment->id)); - } - } -} diff --git a/src/Adapter/Attachment/CommandHandler/EditAttachmentHandler.php b/src/Adapter/Attachment/CommandHandler/EditAttachmentHandler.php deleted file mode 100644 index f24b0133..00000000 --- a/src/Adapter/Attachment/CommandHandler/EditAttachmentHandler.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler; - -use Attachment; -use PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler; -use PrestaShop\PrestaShop\Adapter\File\Uploader\AttachmentFileUploader; -use PrestaShop\PrestaShop\Core\Domain\Attachment\AttachmentFileUploaderInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\EditAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler\EditAttachmentHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotUpdateAttachmentException; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Handles editing of attachment and file uploading procedures - */ -final class EditAttachmentHandler extends AbstractAttachmentHandler implements EditAttachmentHandlerInterface -{ - /** - * @var AttachmentFileUploader - */ - protected $fileUploader; - - /** - * @param ValidatorInterface $validator - * @param AttachmentFileUploaderInterface $fileUploader - */ - public function __construct(ValidatorInterface $validator, AttachmentFileUploaderInterface $fileUploader) - { - parent::__construct($validator); - - $this->fileUploader = $fileUploader; - } - - /** - * {@inheritdoc} - * - * @throws AttachmentConstraintException - * @throws AttachmentException - * @throws AttachmentNotFoundException - * @throws CannotUpdateAttachmentException - */ - public function handle(EditAttachmentCommand $command) - { - $attachmentIdValue = $command->getAttachmentId()->getValue(); - - try { - $attachment = new Attachment($attachmentIdValue); - } catch (PrestaShopException $e) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentIdValue)); - } - - if ($attachment->id !== $attachmentIdValue) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentIdValue)); - } - - $this->updateAttachmentFromCommandData($attachment, $command); - } - - /** - * @param Attachment $attachment - * @param EditAttachmentCommand $command - * - * @throws AttachmentConstraintException - * @throws AttachmentException - * @throws AttachmentNotFoundException - * @throws CannotUpdateAttachmentException - */ - private function updateAttachmentFromCommandData(Attachment $attachment, EditAttachmentCommand $command) - { - try { - if (!$attachment->validateFields(false) && !$attachment->validateFieldsLang(false)) { - throw new AttachmentConstraintException('Attachment contains invalid field values', AttachmentConstraintException::INVALID_FIELDS); - } - - $this->assertDescriptionContainsCleanHtml($command->getLocalizedDescriptions()); - $this->assertHasDefaultLanguage($command->getLocalizedNames()); - - $attachment->description = $command->getLocalizedDescriptions(); - $attachment->name = $command->getLocalizedNames(); - - $this->assertValidFields($attachment); - - if (null !== $command->getPathName()) { - $uniqueFileName = $this->getUniqueFileName(); - - $attachment->file_name = $command->getOriginalFileName(); - $attachment->file = $uniqueFileName; - $attachment->mime = $command->getMimeType(); - - $this->assertValidFields($attachment); - - $this->fileUploader->upload( - $command->getPathName(), - $uniqueFileName, - $command->getFileSize(), - $command->getAttachmentId()->getValue() - ); - } - - if (false === $attachment->update()) { - throw new CannotUpdateAttachmentException('Failed to update attachment'); - } - } catch (PrestaShopException $e) { - throw new AttachmentException('An unexpected error occurred when updating attachment', 0, $e); - } - } -} diff --git a/src/Adapter/Attachment/QueryHandler/GetAttachmentForEditingHandler.php b/src/Adapter/Attachment/QueryHandler/GetAttachmentForEditingHandler.php deleted file mode 100644 index 00fc65b0..00000000 --- a/src/Adapter/Attachment/QueryHandler/GetAttachmentForEditingHandler.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\QueryHandler; - -use Attachment; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachmentForEditing; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryHandler\GetAttachmentForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\EditableAttachment; -use PrestaShopException; -use SplFileInfo; - -/** - * Handles command that gets attachment for editing - * - * @internal - */ -final class GetAttachmentForEditingHandler implements GetAttachmentForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AttachmentNotFoundException - */ - public function handle(GetAttachmentForEditing $query): EditableAttachment - { - $attachmentIdValue = $query->getAttachmentId()->getValue(); - - try { - $attachment = new Attachment($attachmentIdValue); - } catch (PrestaShopException $e) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentIdValue)); - } - - if ($attachment->id !== $attachmentIdValue) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentIdValue)); - } - - $filePath = _PS_DOWNLOAD_DIR_ . $attachment->file; - $file = file_exists($filePath) ? new SplFileInfo($filePath) : null; - - $editableAttachment = new EditableAttachment( - $attachment->file_name, - $attachment->name, - $attachment->description - ); - - if (null !== $file) { - $editableAttachment->setFile($file); - } - - return $editableAttachment; - } -} diff --git a/src/Adapter/Attachment/QueryHandler/GetAttachmentHandler.php b/src/Adapter/Attachment/QueryHandler/GetAttachmentHandler.php deleted file mode 100644 index 316fb8e2..00000000 --- a/src/Adapter/Attachment/QueryHandler/GetAttachmentHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attachment\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachment; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryHandler\GetAttachmentHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\Attachment; - -/** - * Provides path and original file name of attachment - */ -final class GetAttachmentHandler extends AbstractAttachmentHandler implements GetAttachmentHandlerInterface -{ - /** - * @var string - */ - private $downloadDirectory; - - /** - * @param string $downloadDirectory - */ - public function __construct(string $downloadDirectory) - { - $this->downloadDirectory = $downloadDirectory; - } - - /** - * {@inheritdoc} - * - * @throws AttachmentNotFoundException - */ - public function handle(GetAttachment $query): Attachment - { - $attachment = $this->getAttachment($query->getAttachmentId()); - $path = $this->downloadDirectory . $attachment->file; - - if (!file_exists($path)) { - throw new AttachmentNotFoundException(sprintf('Attachment file was not found at %s', $path)); - } - - return new Attachment( - $path, - $attachment->file_name - ); - } -} diff --git a/src/Adapter/Attribute/AbstractAttributeHandler.php b/src/Adapter/Attribute/AbstractAttributeHandler.php deleted file mode 100644 index b368b14d..00000000 --- a/src/Adapter/Attribute/AbstractAttributeHandler.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attribute; - -use Attribute; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\ValueObject\AttributeId; -use PrestaShopException; - -/** - * Provides common methods for attribute command/query handlers - */ -abstract class AbstractAttributeHandler -{ - /** - * @param AttributeId $attributeId - * - * @return Attribute - * - * @throws AttributeException - */ - protected function getAttributeById($attributeId) - { - $idValue = $attributeId->getValue(); - - try { - $attribute = new Attribute($idValue); - - if ($attribute->id !== $idValue) { - throw new AttributeNotFoundException(sprintf('Attribute with id "%s" was not found.', $idValue)); - } - } catch (PrestaShopException $e) { - throw new AttributeException(sprintf('An error occurred when trying to get attribute with id %s', $idValue)); - } - - return $attribute; - } - - /** - * @param Attribute $attribute - * - * @return bool - * - * @throws AttributeException - */ - protected function deleteAttribute(Attribute $attribute) - { - try { - return $attribute->delete(); - } catch (PrestaShopException $e) { - throw new AttributeException(sprintf('An error occurred when trying to delete attribute with id %s', $attribute->id)); - } - } -} diff --git a/src/Adapter/Attribute/AdminAttributeGeneratorControllerWrapper.php b/src/Adapter/Attribute/AdminAttributeGeneratorControllerWrapper.php deleted file mode 100644 index 67a1a4ad..00000000 --- a/src/Adapter/Attribute/AdminAttributeGeneratorControllerWrapper.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attribute; - -use AdminAttributeGeneratorController; -use Combination; -use Context; -use Product; -use SpecificPriceRule; -use Stock; -use StockAvailable; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * Admin controller wrapper for new Architecture, about Category admin controller. - */ -class AdminAttributeGeneratorControllerWrapper -{ - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct() - { - $context = Context::getContext(); - $this->translator = $context->getTranslator(); - } - - /** - * Generate product attributes. - * - * @param object $product The product - * @param array $options The array with all attributes combinations - */ - public function processGenerate($product, $options) - { - SpecificPriceRule::disableAnyApplication(); - - //add combination if not already exists - $combinations = array_values(AdminAttributeGeneratorController::createCombinations(array_values($options))); - $combinationsValues = array_values(array_map(function () use ($product) { - return [ - 'id_product' => $product->id, - ]; - }, $combinations)); - - $product->generateMultipleCombinations($combinationsValues, $combinations, false); - - Product::updateDefaultAttribute($product->id); - SpecificPriceRule::enableAnyApplication(); - SpecificPriceRule::applyAllRules([(int) $product->id]); - } - - /** - * Delete a product attribute. - * - * @param int $idAttribute The attribute ID - * @param int $idProduct The product ID - * - * @return array - */ - public function ajaxProcessDeleteProductAttribute($idAttribute, $idProduct) - { - if (!Combination::isFeatureActive()) { - return false; - } - - if ($idProduct && Validate::isUnsignedId($idProduct) && Validate::isLoadedObject($product = new Product($idProduct))) { - if (($depends_on_stock = StockAvailable::dependsOnStock($idProduct)) && StockAvailable::getQuantityAvailableByProduct($idProduct, $idAttribute)) { - return [ - 'status' => 'error', - 'message' => $this->translator->trans('It is not possible to delete a combination while it still has some quantities in the Advanced Stock Management. You must delete its stock first.', [], 'Admin.Catalog.Notification'), - ]; - } else { - $product->deleteAttributeCombination((int) $idAttribute); - $product->checkDefaultAttributes(); - Tools::clearColorListCache((int) $product->id); - if (!$product->hasAttributes()) { - $product->cache_default_attribute = 0; - $product->update(); - } else { - Product::updateDefaultAttribute($idProduct); - } - - if ($depends_on_stock && !Stock::deleteStockByIds($idProduct, $idAttribute)) { - return [ - 'status' => 'error', - 'message' => $this->translator->trans('Error while deleting the stock', [], 'Admin.Catalog.Notification'), - ]; - } else { - return [ - 'status' => 'ok', - 'message' => $this->translator->trans('Successful deletion', [], 'Admin.Catalog.Notification'), - ]; - } - } - } else { - return [ - 'status' => 'error', - 'message' => $this->translator->trans('You cannot delete this attribute.', [], 'Admin.Catalog.Notification'), - ]; - } - } -} diff --git a/src/Adapter/Attribute/AttributeDataProvider.php b/src/Adapter/Attribute/AttributeDataProvider.php deleted file mode 100644 index 1c498338..00000000 --- a/src/Adapter/Attribute/AttributeDataProvider.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attribute; - -use Attribute; -use Combination; -use Context; -use Db; -use Product; -use Shop; - -/** - * This class will provide data from DB / ORM about Attributes. - */ -class AttributeDataProvider -{ - /** - * Get all attributes for a given language. - * - * @param int $id_lang Language id - * @param bool $not_null Get only not null fields if true - * - * @return array Attributes - */ - public static function getAttributes($id_lang, $not_null = false) - { - return Attribute::getAttributes($id_lang, $not_null); - } - - /** - * Get all attributes ids for a given group. - * - * @param int $id_group Attribute group id - * @param bool $not_null Get only not null fields if true - * - * @return array Attributes - */ - public static function getAttributeIdsByGroup($id_group, $not_null = false) - { - if (!Combination::isFeatureActive()) { - return []; - } - - $result = Db::getInstance()->executeS(' - SELECT DISTINCT a.`id_attribute` - FROM `' . _DB_PREFIX_ . 'attribute_group` ag - LEFT JOIN `' . _DB_PREFIX_ . 'attribute` a - ON a.`id_attribute_group` = ag.`id_attribute_group` - ' . Shop::addSqlAssociation('attribute_group', 'ag') . ' - ' . Shop::addSqlAssociation('attribute', 'a') . ' - WHERE ag.`id_attribute_group` = ' . (int) $id_group . ' - ' . ($not_null ? 'AND a.`id_attribute` IS NOT NULL' : '') . ' - ORDER BY a.`position` ASC - '); - - return array_map(function ($a) { - return $a['id_attribute']; - }, $result); - } - - /** - * Get combination for a product. - * - * @param int $idProduct - * - * @return array Combinations - */ - public function getProductCombinations($idProduct) - { - $context = Context::getContext(); - - //get product - $product = new Product((int) $idProduct, false); - if (!is_object($product) || empty($product->id)) { - return false; - } - - $allCombinations = $product->getAttributeCombinations(1, false); - $allCombinationsIds = array_map(function ($o) { - return $o['id_product_attribute']; - }, $allCombinations); - - $combinations = []; - foreach ($allCombinationsIds as $combinationId) { - $combinations[] = $product->getAttributeCombinationsById($combinationId, $context->employee->id_lang)[0]; - } - - return $combinations; - } - - /** - * Get combination images ids. - * - * @param int $idAttribute - * - * @return array - */ - public function getImages($idAttribute) - { - return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT a.`id_image` as id - FROM `' . _DB_PREFIX_ . 'product_attribute_image` a - ' . Shop::addSqlAssociation('product_attribute', 'a') . ' - WHERE a.`id_product_attribute` = ' . (int) $idAttribute . ' - '); - } -} diff --git a/src/Adapter/Attribute/CommandHandler/BulkDeleteAttributeHandler.php b/src/Adapter/Attribute/CommandHandler/BulkDeleteAttributeHandler.php deleted file mode 100644 index f5972bc1..00000000 --- a/src/Adapter/Attribute/CommandHandler/BulkDeleteAttributeHandler.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attribute\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Attribute\AbstractAttributeHandler; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\BulkDeleteAttributeCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\CommandHandler\BulkDeleteAttributeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\DeleteAttributeException; - -/** - * Handles command which deletes attributes in bulk action using legacy object model - */ -final class BulkDeleteAttributeHandler extends AbstractAttributeHandler implements BulkDeleteAttributeHandlerInterface -{ - /** - * @param BulkDeleteAttributeCommand $command - * - * @throws AttributeException - */ - public function handle(BulkDeleteAttributeCommand $command) - { - foreach ($command->getAttributeIds() as $attributeId) { - $attribute = $this->getAttributeById($attributeId); - - if (false === $this->deleteAttribute($attribute)) { - throw new DeleteAttributeException(sprintf('Failed to delete attribute with id "%s"', $attribute->id), DeleteAttributeException::FAILED_BULK_DELETE); - } - } - } -} diff --git a/src/Adapter/Attribute/CommandHandler/DeleteAttributeHandler.php b/src/Adapter/Attribute/CommandHandler/DeleteAttributeHandler.php deleted file mode 100644 index 23efd12d..00000000 --- a/src/Adapter/Attribute/CommandHandler/DeleteAttributeHandler.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Attribute\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Attribute\AbstractAttributeHandler; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\DeleteAttributeCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\CommandHandler\DeleteAttributeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\DeleteAttributeException; - -/** - * Handles command which deletes the Attribute using legacy object model - */ -final class DeleteAttributeHandler extends AbstractAttributeHandler implements DeleteAttributeHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AttributeException - */ - public function handle(DeleteAttributeCommand $command) - { - $attribute = $this->getAttributeById($command->getAttributeId()); - - if (false === $this->deleteAttribute($attribute)) { - throw new DeleteAttributeException(sprintf('Failed to delete attribute with id "%s".', $attribute->id), DeleteAttributeException::FAILED_DELETE); - } - } -} diff --git a/src/Adapter/AttributeGroup/AbstractAttributeGroupHandler.php b/src/Adapter/AttributeGroup/AbstractAttributeGroupHandler.php deleted file mode 100644 index f55680a6..00000000 --- a/src/Adapter/AttributeGroup/AbstractAttributeGroupHandler.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\AttributeGroup; - -use AttributeGroup; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\ValueObject\AttributeGroupId; -use PrestaShopException; - -/** - * Provides reusable methods for attribute group handlers - */ -abstract class AbstractAttributeGroupHandler -{ - /** - * @param AttributeGroupId $attributeGroupId - * - * @return AttributeGroup - * - * @throws AttributeGroupException - */ - protected function getAttributeGroupById($attributeGroupId) - { - $idValue = $attributeGroupId->getValue(); - - try { - $attributeGroup = new AttributeGroup($idValue); - - if ($attributeGroup->id !== $idValue) { - throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $idValue)); - } - } catch (PrestaShopException $e) { - throw new AttributeGroupException(sprintf('An error occurred when trying to get attribute group with id %s', $idValue)); - } - - return $attributeGroup; - } - - /** - * @param AttributeGroup $attributeGroup - * - * @return bool - * - * @throws AttributeGroupException - */ - protected function deleteAttributeGroup(AttributeGroup $attributeGroup) - { - try { - return $attributeGroup->delete(); - } catch (PrestaShopException $e) { - throw new AttributeGroupException(sprintf('An error occurred when trying to delete attribute with id %s', $attributeGroup->id)); - } - } -} diff --git a/src/Adapter/AttributeGroup/AttributeGroupViewDataProvider.php b/src/Adapter/AttributeGroup/AttributeGroupViewDataProvider.php deleted file mode 100644 index ee25cd9c..00000000 --- a/src/Adapter/AttributeGroup/AttributeGroupViewDataProvider.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\AttributeGroup; - -use AttributeGroup; -use PrestaShop\PrestaShop\Core\AttributeGroup\AttributeGroupViewDataProviderInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupNotFoundException; -use PrestaShopException; - -/** - * Provides data required for attribute group view action using legacy object models - */ -final class AttributeGroupViewDataProvider implements AttributeGroupViewDataProviderInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param int $contextLangId - * @param ConfigurationInterface $configuration - */ - public function __construct($contextLangId, ConfigurationInterface $configuration) - { - $this->contextLangId = $contextLangId; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isColorGroup($attributeGroupId) - { - $attributeGroup = $this->getAttributeGroupById($attributeGroupId); - - return (bool) $attributeGroup->is_color_group; - } - - /** - * {@inheritdoc} - */ - public function getAttributeGroupNameById($attributeGroupId) - { - $attributeGroup = $this->getAttributeGroupById($attributeGroupId); - - if (!isset($attributeGroup->name[$this->contextLangId])) { - return $attributeGroup->name[$this->configuration->get('PS_LANG_DEFAULT')]; - } - - return $attributeGroup->name[$this->contextLangId]; - } - - /** - * Gets legacy AttributeGroup object by provided id - * - * @param int $attributeGroupId - * - * @return AttributeGroup - * - * @throws AttributeGroupException - * @throws AttributeGroupNotFoundException - */ - private function getAttributeGroupById($attributeGroupId) - { - try { - $attributeGroup = new AttributeGroup($attributeGroupId); - - if ($attributeGroup->id !== $attributeGroupId) { - throw new AttributeGroupNotFoundException(sprintf('Attribute group with id "%s" was not found.', $attributeGroupId)); - } - } catch (PrestaShopException $e) { - throw new AttributeGroupException(sprintf('An error occurred when trying to get attribute group with id %s', $attributeGroupId)); - } - - return $attributeGroup; - } -} diff --git a/src/Adapter/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandler.php b/src/Adapter/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandler.php deleted file mode 100644 index b3835af3..00000000 --- a/src/Adapter/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\AttributeGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\AttributeGroup\AbstractAttributeGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\BulkDeleteAttributeGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\CommandHandler\BulkDeleteAttributeGroupHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\DeleteAttributeGroupException; - -/** - * Handles command which deletes multiple attribute groups using legacy object model - */ -final class BulkDeleteAttributeGroupHandler extends AbstractAttributeGroupHandler implements BulkDeleteAttributeGroupHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteAttributeGroupCommand $command) - { - foreach ($command->getAttributeGroupIds() as $attributeGroupId) { - $attributeGroup = $this->getAttributeGroupById($attributeGroupId); - - if (false === $this->deleteAttributeGroup($attributeGroup)) { - throw new DeleteAttributeGroupException(sprintf('Failed to delete attribute group with id "%s"', $attributeGroupId->getValue()), DeleteAttributeGroupException::FAILED_BULK_DELETE); - } - } - } -} diff --git a/src/Adapter/AttributeGroup/CommandHandler/DeleteAttributeGroupHandler.php b/src/Adapter/AttributeGroup/CommandHandler/DeleteAttributeGroupHandler.php deleted file mode 100644 index b56679df..00000000 --- a/src/Adapter/AttributeGroup/CommandHandler/DeleteAttributeGroupHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\AttributeGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\AttributeGroup\AbstractAttributeGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\DeleteAttributeGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\CommandHandler\DeleteAttributeGroupHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\DeleteAttributeGroupException; - -/** - * Handles command which deletes attribute group using legacy object model - */ -final class DeleteAttributeGroupHandler extends AbstractAttributeGroupHandler implements DeleteAttributeGroupHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws AttributeGroupException - */ - public function handle(DeleteAttributeGroupCommand $command) - { - $attributeGroupId = $command->getAttributeGroupId(); - $attributeGroup = $this->getAttributeGroupById($attributeGroupId); - - if (false === $this->deleteAttributeGroup($attributeGroup)) { - throw new DeleteAttributeGroupException(sprintf('Failed deleting attribute group with id "%s"', $attributeGroupId->getValue()), DeleteAttributeGroupException::FAILED_DELETE); - } - } -} diff --git a/src/Adapter/Backup/Backup.php b/src/Adapter/Backup/Backup.php deleted file mode 100644 index bb6604c5..00000000 --- a/src/Adapter/Backup/Backup.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Backup; - -use DateTimeImmutable; -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopBackup; -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; - -/** - * Class Backup represents single database backup. - * - * @internal - */ -final class Backup implements BackupInterface -{ - /** - * @var PrestaShopBackup - */ - private $legacyBackup; - - /** - * @var string - */ - private $fileName; - - /** - * @param string $fileName Backup file name - */ - public function __construct($fileName) - { - $this->fileName = $fileName; - $this->legacyBackup = new PrestaShopBackup($fileName); - } - - /** - * {@inheritdoc} - */ - public function getFileName() - { - return $this->fileName; - } - - /** - * {@inheritdoc} - */ - public function getFilePath() - { - return $this->legacyBackup->getBackupPath() . $this->getFileName(); - } - - /** - * {@inheritdoc} - */ - public function getUrl() - { - return $this->legacyBackup->getBackupURL(); - } - - /** - * {@inheritdoc} - */ - public function getSize() - { - return filesize($this->legacyBackup->id); - } - - /** - * {@inheritdoc} - */ - public function getAge() - { - return time() - $this->getDate()->getTimestamp(); - } - - /** - * {@inheritdoc} - */ - public function getDate() - { - list($timestamp) = explode('-', $this->fileName); - - return new DateTimeImmutable('@' . $timestamp); - } -} diff --git a/src/Adapter/Backup/BackupRemover.php b/src/Adapter/Backup/BackupRemover.php deleted file mode 100644 index c10d0ef1..00000000 --- a/src/Adapter/Backup/BackupRemover.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Backup; - -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopBackup; -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; -use PrestaShop\PrestaShop\Core\Backup\Manager\BackupRemoverInterface; - -/** - * Class BackupRemover deletes given backup. - * - * @internal - */ -final class BackupRemover implements BackupRemoverInterface -{ - /** - * {@inheritdoc} - */ - public function remove(BackupInterface $backup) - { - $legacyBackup = new PrestaShopBackup($backup->getFileName()); - - return $legacyBackup->delete(); - } -} diff --git a/src/Adapter/Backup/BackupRepository.php b/src/Adapter/Backup/BackupRepository.php deleted file mode 100644 index c74c92e1..00000000 --- a/src/Adapter/Backup/BackupRepository.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Backup; - -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopBackup; -use PrestaShop\PrestaShop\Core\Backup\BackupCollection; -use PrestaShop\PrestaShop\Core\Backup\Repository\BackupRepositoryInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Class BackupRepository is responsible for providing available backups. - * - * @internal - */ -final class BackupRepository implements BackupRepositoryInterface -{ - /** - * {@inheritdoc} - */ - public function retrieveBackups() - { - $backupFinder = (new Finder()) - ->files() - ->in(PrestaShopBackup::getBackupPath()) - ->name('/^([_a-zA-Z0-9\-]*[\d]+-[a-z\d]+)\.sql(\.gz|\.bz2)?$/') - ->depth(0); - - $backups = new BackupCollection(); - - /** @var SplFileInfo $file */ - foreach ($backupFinder as $file) { - $backups->add(new Backup($file->getFilename())); - } - - return $backups; - } -} diff --git a/src/Adapter/Backup/DatabaseBackupCreator.php b/src/Adapter/Backup/DatabaseBackupCreator.php deleted file mode 100644 index 0dd133dd..00000000 --- a/src/Adapter/Backup/DatabaseBackupCreator.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Backup; - -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopBackup; -use PrestaShop\PrestaShop\Core\Backup\Exception\BackupException; -use PrestaShop\PrestaShop\Core\Backup\Exception\DirectoryIsNotWritableException; -use PrestaShop\PrestaShop\Core\Backup\Manager\BackupCreatorInterface; - -/** - * Class DatabaseBackupCreator is responsible for creating database backups. - * - * @internal - */ -final class DatabaseBackupCreator implements BackupCreatorInterface -{ - /** - * {@inheritdoc} - */ - public function createBackup() - { - ini_set('max_execution_time', 0); - - if (!is_writable(PrestaShopBackup::getBackupPath())) { - throw new DirectoryIsNotWritableException('To create backup, its directory must be writable'); - } - - $legacyBackup = new PrestaShopBackup(); - if (!$legacyBackup->add()) { - throw new BackupException('Failed to create backup'); - } - - $backupFilePathParts = explode(DIRECTORY_SEPARATOR, $legacyBackup->id); - - return new Backup(end($backupFilePathParts)); - } -} diff --git a/src/Adapter/BestSales/BestSalesProductSearchProvider.php b/src/Adapter/BestSales/BestSalesProductSearchProvider.php deleted file mode 100644 index 8a04889f..00000000 --- a/src/Adapter/BestSales/BestSalesProductSearchProvider.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\BestSales; - -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrder; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use ProductSale; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -class BestSalesProductSearchProvider implements ProductSearchProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var SortOrderFactory - */ - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * - * @return ProductSearchResult - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - $sortBySales = (new SortOrder('product', 'sales', 'desc'))->setLabel( - $this->translator->trans('Sales, highest to lowest', [], 'Shop.Theme.Catalog') - ); - - if (!Tools::getValue('order', 0)) { - $query->setSortOrder($sortBySales); - } - - if (!$products = ProductSale::getBestSales( - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay() - )) { - $products = []; - } - - $count = (int) ProductSale::getNbSales(); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - [ - $sortBySales, - (new SortOrder('product', 'name', 'asc'))->setLabel( - $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'desc'))->setLabel( - $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'asc'))->setLabel( - $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'desc'))->setLabel( - $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog') - ), - ] - ); - } - - return $result; - } -} diff --git a/src/Adapter/CMS/CMSDataProvider.php b/src/Adapter/CMS/CMSDataProvider.php deleted file mode 100644 index 6335f6f7..00000000 --- a/src/Adapter/CMS/CMSDataProvider.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS; - -use CMS; - -/** - * Class CMSDataProvider provides CMS data using legacy code. - */ -class CMSDataProvider -{ - /** - * Gets all CMS pages. - * - * @param int $languageId - * - * @return array - */ - public function getCMSPages($languageId = null) - { - return CMS::listCms($languageId); - } - - /** - * Gets one CMS object by ID. - * - * @param int $cmsId - * - * @return CMS - */ - public function getCMSById($cmsId) - { - return new CMS($cmsId); - } - - /** - * Gets CMS choices for choice type. - * - * @param int $languageId - * - * @return array - */ - public function getCMSChoices($languageId = null) - { - $choices = []; - - foreach ($this->getCMSPages($languageId) as $cms) { - $choices[$cms['meta_title']] = $cms['id_cms']; - } - - return $choices; - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/AbstractCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/AbstractCmsPageHandler.php deleted file mode 100644 index c76bd338..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/AbstractCmsPageHandler.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use CMS; -use CMSCategory; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Abstraction which holds all common functions required for cms page functionality. - * - * @internal - */ -abstract class AbstractCmsPageHandler extends AbstractObjectModelHandler -{ - /** - * Gets cms object if it exists. If it does not exist it throws exceptions. - * - * @param int $cmsId - * - * @return CMS - * - * @throws CmsPageException - */ - protected function getCmsPageIfExistsById($cmsId) - { - try { - $cms = new CMS($cmsId); - - if (0 >= $cms->id) { - throw new CmsPageNotFoundException(sprintf('Cms page with id "%s" not found', $cmsId)); - } - } catch (PrestaShopException $exception) { - throw new CmsPageException(sprintf('An error occurred when trying to get cms page with id %s', $cmsId)); - } - - return $cms; - } - - /** - * Checks whether cms page category exists by provided id. - * - * @param $cmsCategoryId - * - * @throws CmsPageCategoryException - */ - protected function assertCmsCategoryExists($cmsCategoryId) - { - try { - $cmsCategory = new CMSCategory($cmsCategoryId); - if (0 >= $cmsCategory->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms page category with id "%s" not found', $cmsCategoryId)); - } - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException(sprintf('An error occurred when trying to get cms page category with id %s', $cmsCategoryId)); - } - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/AddCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/AddCmsPageHandler.php deleted file mode 100644 index de47853c..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/AddCmsPageHandler.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use CMS; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\AddCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\AddCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotAddCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; -use PrestaShopException; - -/** - * Handles AddCmsPageCommand using legacy object model - */ -final class AddCmsPageHandler extends AbstractCmsPageHandler implements AddCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddCmsPageCommand $command) - { - $cms = $this->createCmsFromCommand($command); - - try { - if (false === $cms->validateFields(false) || false === $cms->validateFieldsLang(false)) { - throw new CmsPageException('Cms page contains invalid field values'); - } - - if (false === $cms->add()) { - throw new CannotAddCmsPageException('Failed to add cms page'); - } - $this->associateWithShops($cms, $command->getShopAssociation()); - } catch (PrestaShopException $e) { - throw new CmsPageException('An unexpected error occurred when adding cms page', 0, $e); - } - - return new CmsPageId((int) $cms->id); - } - - /** - * @param AddCmsPageCommand $command - * - * @return CMS - */ - protected function createCmsFromCommand(AddCmsPageCommand $command) - { - $cmsCategoryId = $command->getCmsPageCategory()->getValue(); - $this->assertCmsCategoryExists($cmsCategoryId); - - $cms = new CMS(); - $cms->id_cms_category = $cmsCategoryId; - $cms->meta_title = $command->getLocalizedTitle(); - $cms->head_seo_title = $command->getLocalizedMetaTitle(); - $cms->meta_description = $command->getLocalizedMetaDescription(); - $cms->meta_keywords = $command->getLocalizedMetaKeyword(); - $cms->link_rewrite = $command->getLocalizedFriendlyUrl(); - $cms->content = $command->getLocalizedContent(); - $cms->indexation = $command->isIndexedForSearch(); - $cms->active = $command->isDisplayed(); - - return $cms; - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/BulkDeleteCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/BulkDeleteCmsPageHandler.php deleted file mode 100644 index 40fa53a6..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/BulkDeleteCmsPageHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDeleteCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\BulkDeleteCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotDeleteCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShopException; - -/** - * Deletes multiple cms pages - */ -final class BulkDeleteCmsPageHandler extends AbstractCmsPageHandler implements BulkDeleteCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageException - */ - public function handle(BulkDeleteCmsPageCommand $command) - { - try { - foreach ($command->getCmsPages() as $cmsPageId) { - $cms = $this->getCmsPageIfExistsById($cmsPageId->getValue()); - - if (false === $cms->delete()) { - throw new CannotDeleteCmsPageException(sprintf('An error occurred when deleting cms page with id %s', $cmsPageId->getValue()), CannotDeleteCmsPageException::FAILED_BULK_DELETE); - } - } - } catch (PrestaShopException $exception) { - throw new CmsPageException('An unexpected error occurred when deleting cms page', 0, $exception); - } - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/BulkDisableCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/BulkDisableCmsPageHandler.php deleted file mode 100644 index c28b9f2e..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/BulkDisableCmsPageHandler.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDisableCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\BulkDisableCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotDisableCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShopException; - -/** - * Disables multiple cms pages. - */ -final class BulkDisableCmsPageHandler extends AbstractCmsPageHandler implements BulkDisableCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - * - * @param BulkDisableCmsPageCommand $command - * - * @throws CannotDisableCmsPageException - * @throws CmsPageException - * @throws CmsPageNotFoundException - */ - public function handle(BulkDisableCmsPageCommand $command) - { - try { - $this->disableCmsPages($command); - } catch (PrestaShopException $exception) { - throw new CmsPageException('An error occurred when bulk disabling the cms pages', 0, $exception); - } - } - - /** - * @param BulkDisableCmsPageCommand $command - * - * @throws CannotDisableCmsPageException - * @throws PrestaShopException - * @throws \PrestaShopDatabaseException - * @throws CmsPageException - * @throws CmsPageNotFoundException - */ - private function disableCmsPages(BulkDisableCmsPageCommand $command) - { - foreach ($command->getCmsPages() as $cmsPage) { - $cms = $this->getCmsPageIfExistsById($cmsPage->getValue()); - - $cms->active = false; - - if (false === $cms->update()) { - throw new CannotDisableCmsPageException(sprintf('Failed to disable cms page with id %s', $cmsPage->getValue())); - } - } - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/BulkEnableCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/BulkEnableCmsPageHandler.php deleted file mode 100644 index 6f2ce07c..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/BulkEnableCmsPageHandler.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkEnableCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\BulkEnableCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotEnableCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShopException; - -/** - * Enables multiple cms pages. - */ -final class BulkEnableCmsPageHandler extends AbstractCmsPageHandler implements BulkEnableCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageException - */ - public function handle(BulkEnableCmsPageCommand $command) - { - try { - $this->enableCmsPages($command); - } catch (PrestaShopException $exception) { - throw new CmsPageException('An error occurred when bulk enabling the cms pages', 0, $exception); - } - } - - /** - * @param BulkEnableCmsPageCommand $command - * - * @throws CannotEnableCmsPageException - * @throws CmsPageException - * @throws PrestaShopException - * @throws \PrestaShopDatabaseException - * @throws CmsPageNotFoundException - */ - private function enableCmsPages(BulkEnableCmsPageCommand $command) - { - foreach ($command->getCmsPages() as $cmsPage) { - $cms = $this->getCmsPageIfExistsById($cmsPage->getValue()); - - $cms->active = true; - - if (false === $cms->update()) { - throw new CannotEnableCmsPageException(sprintf('Failed to enable cms page with id %s', $cmsPage->getValue())); - } - } - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/DeleteCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/DeleteCmsPageHandler.php deleted file mode 100644 index 739575d3..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/DeleteCmsPageHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\DeleteCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\DeleteCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotDeleteCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShopException; - -/** - * Deletes given cms page. - */ -final class DeleteCmsPageHandler extends AbstractCmsPageHandler implements DeleteCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageException - */ - public function handle(DeleteCmsPageCommand $command) - { - $cms = $this->getCmsPageIfExistsById($command->getCmsPageId()->getValue()); - - try { - if (false === $cms->delete()) { - throw new CannotDeleteCmsPageException(sprintf('An error occurred when deleting cms page with id %s', $command->getCmsPageId()->getValue()), CannotDeleteCmsPageException::FAILED_DELETE); - } - } catch (PrestaShopException $e) { - throw new CmsPageException(sprintf('An unexpected error occurred when deleting cms page with id %s', $command->getCmsPageId()->getValue()), 0, $e); - } - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/EditCmsPageHandler.php b/src/Adapter/CMS/Page/CommandHandler/EditCmsPageHandler.php deleted file mode 100644 index 3c6e4a58..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/EditCmsPageHandler.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use CMS; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\EditCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\EditCmsPageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotEditCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShopException; - -/** - * Edits cms page - */ -final class EditCmsPageHandler extends AbstractCmsPageHandler implements EditCmsPageHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageException - * @throws CmsPageCategoryException - */ - public function handle(EditCmsPageCommand $command) - { - $cms = $this->createCmsFromCommand($command); - - try { - if (false === $cms->validateFields(false) || false === $cms->validateFieldsLang(false)) { - throw new CmsPageException('Cms page contains invalid field values'); - } - if (false === $cms->update()) { - throw new CannotEditCmsPageException(sprintf('Failed to update cms page with id %s', $command->getCmsPageId()->getValue())); - } - if (null !== $command->getShopAssociation()) { - $this->associateWithShops($cms, $command->getShopAssociation()); - } - } catch (PrestaShopException $e) { - throw new CmsPageException(sprintf('An unexpected error occurred when editing cms page with id %s', $command->getCmsPageId()->getValue()), 0, $e); - } - } - - /** - * @param EditCmsPageCommand $command - * - * @return CMS - * - * @throws CmsPageException - * @throws CmsPageNotFoundException - * @throws CmsPageCategoryException - */ - private function createCmsFromCommand(EditCmsPageCommand $command) - { - $cms = $this->getCmsPageIfExistsById($command->getCmsPageId()->getValue()); - - if (null !== $command->getCmsPageCategoryId()) { - $this->assertCmsCategoryExists($command->getCmsPageCategoryId()->getValue()); - - $cms->id_cms_category = $command->getCmsPageCategoryId()->getValue(); - } - - if (null !== $command->getLocalizedTitle()) { - $cms->meta_title = $command->getLocalizedTitle(); - } - - if (null !== $command->getLocalizedMetaTitle()) { - $cms->head_seo_title = $command->getLocalizedMetaTitle(); - } - - if (null !== $command->getLocalizedMetaDescription()) { - $cms->meta_description = $command->getLocalizedMetaDescription(); - } - - if (null !== $command->getLocalizedMetaKeyword()) { - $cms->meta_keywords = $command->getLocalizedMetaKeyword(); - } - - if (null !== $command->getLocalizedFriendlyUrl()) { - $cms->link_rewrite = $command->getLocalizedFriendlyUrl(); - } - - if (null !== $command->getLocalizedContent()) { - $cms->content = $command->getLocalizedContent(); - } - - if (null !== $command->isIndexedForSearch()) { - $cms->indexation = $command->isIndexedForSearch(); - } - - if (null !== $command->isDisplayed()) { - $cms->active = $command->isDisplayed(); - } - - return $cms; - } -} diff --git a/src/Adapter/CMS/Page/CommandHandler/ToggleCmsPageStatusHandler.php b/src/Adapter/CMS/Page/CommandHandler/ToggleCmsPageStatusHandler.php deleted file mode 100644 index b592caca..00000000 --- a/src/Adapter/CMS/Page/CommandHandler/ToggleCmsPageStatusHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\ToggleCmsPageStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler\ToggleCmsPageStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotToggleCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShopException; - -/** - * Changes the status of cms page. - */ -final class ToggleCmsPageStatusHandler extends AbstractCmsPageHandler implements ToggleCmsPageStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageException - */ - public function handle(ToggleCmsPageStatusCommand $command) - { - $cms = $this->getCmsPageIfExistsById($command->getCmsPageId()->getValue()); - - try { - if (false === $cms->toggleStatus()) { - throw new CannotToggleCmsPageException(sprintf('Failed to toggle cms page with id %s status', $command->getCmsPageId()->getValue())); - } - } catch (PrestaShopException $exception) { - throw new CmsPageException(sprintf('An unexpected error occurred when toggling cms page with id %s status', $command->getCmsPageId()->getValue())); - } - } -} diff --git a/src/Adapter/CMS/Page/QueryHandler/GetCmsCategoryIdForRedirectionHandler.php b/src/Adapter/CMS/Page/QueryHandler/GetCmsCategoryIdForRedirectionHandler.php deleted file mode 100644 index 491920da..00000000 --- a/src/Adapter/CMS/Page/QueryHandler/GetCmsCategoryIdForRedirectionHandler.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\AbstractCmsPageHandler; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryHandler\GetCmsCategoryIdHandlerForRedirectionInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * This class is used for getting the id which is used later on to redirect to the right page after certain controller - * actions. - */ -final class GetCmsCategoryIdForRedirectionHandler extends AbstractCmsPageHandler implements GetCmsCategoryIdHandlerForRedirectionInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetCmsCategoryIdForRedirection $query) - { - try { - $cms = $this->getCmsPageIfExistsById($query->getCmsPageId()->getValue()); - $categoryId = (int) $cms->id_cms_category; - } catch (CmsPageException $exception) { - $categoryId = CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID; - } - - return new CmsPageCategoryId($categoryId); - } -} diff --git a/src/Adapter/CMS/Page/QueryHandler/GetCmsPageForEditingHandler.php b/src/Adapter/CMS/Page/QueryHandler/GetCmsPageForEditingHandler.php deleted file mode 100644 index 9e99d8e3..00000000 --- a/src/Adapter/CMS/Page/QueryHandler/GetCmsPageForEditingHandler.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\Page\QueryHandler; - -use Link; -use PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\AbstractCmsPageHandler; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\getCmsPageForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryHandler\GetCmsPageForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryResult\EditableCmsPage; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShopException; - -/** - * Gets cms page for editing - */ -final class GetCmsPageForEditingHandler extends AbstractCmsPageHandler implements GetCmsPageForEditingHandlerInterface -{ - /** - * @var Link - */ - private $link; - - /** - * @var int - */ - private $langId; - - /** - * @param Link $link - * @param int $langId - */ - public function __construct(Link $link, $langId) - { - $this->link = $link; - $this->langId = $langId; - } - - /** - * @param GetCmsPageForEditing $query - * - * @return EditableCmsPage - * - * @throws CmsPageException - * @throws CmsPageCategoryException - * @throws CmsPageNotFoundException - */ - public function handle(getCmsPageForEditing $query) - { - $cmsPageId = $query->getCmsPageId()->getValue(); - $cms = $this->getCmsPageIfExistsById($cmsPageId); - - try { - return new EditableCmsPage( - (int) $cms->id, - (int) $cms->id_cms_category, - $cms->meta_title, - $cms->head_seo_title, - $cms->meta_description, - $cms->meta_keywords, - $cms->link_rewrite, - $cms->content, - $cms->indexation, - $cms->active, - $cms->getAssociatedShops(), - $this->link->getCMSLink($cms, null, null, $this->langId) - ); - } catch (PrestaShopException $e) { - throw new CmsPageException(sprintf('An error occurred when getting cms page for editing with id "%s"', $cmsPageId)); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CategoriesProvider.php b/src/Adapter/CMS/PageCategory/CategoriesProvider.php deleted file mode 100644 index 3deb9cd6..00000000 --- a/src/Adapter/CMS/PageCategory/CategoriesProvider.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory; - -use Db; -use DbQuery; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use PrestaShopDatabaseException; - -/** - * Class CategoriesProvider is responsible for providing cms page categories data. - */ -class CategoriesProvider -{ - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @param int $contextLanguageId - * @param array $contextShopIds - */ - public function __construct( - $contextLanguageId, - array $contextShopIds - ) { - $this->contextLanguageId = (int) $contextLanguageId; - $this->contextShopIds = array_map(function ($item) { return (int) $item; }, $contextShopIds); - } - - /** - * Gets all nested cms page categories. - * - * @return array - * - * @throws PrestaShopDatabaseException - */ - public function getAllNestedCategories() - { - return $this->collectNestedCategoriesIdsAndNames(CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID); - } - - /** - * Gets recursive category ids and names - * - * @param int $cmsPageCategoryId - * - * @return array - [ - * 'id_cms_category' => 1, - * 'name' => 'root category', - * 'children' => [...] - * ] - * - * @throws PrestaShopDatabaseException - */ - private function collectNestedCategoriesIdsAndNames($cmsPageCategoryId) - { - $mainCategoryQuery = new DbQuery(); - $mainCategoryQuery - ->select('c.`id_cms_category`, cl.`name`') - ->from('cms_category', 'c') - ->innerJoin( - 'cms_category_lang', - 'cl', - 'cl.`id_cms_category` = c.`id_cms_category`' - ) - ->where('c.`id_cms_category` = ' . (int) $cmsPageCategoryId) - ->where('cl.`id_lang` = ' . $this->contextLanguageId) - ->where('cl.`id_shop` IN (' . implode(',', $this->contextShopIds) . ')') - ->groupBy('c.`id_cms_category`') - ; - - $result = Db::getInstance()->getRow($mainCategoryQuery); - $categories = is_array($result) ? $result : []; - - $childrenQuery = new DbQuery(); - $childrenQuery - ->select('c.`id_cms_category`, cl.`name`') - ->from('cms_category', 'c') - ->innerJoin( - 'cms_category_lang', - 'cl', - 'cl.`id_cms_category` = c.`id_cms_category`' - ) - ->where('c.`id_parent` = ' . (int) $cmsPageCategoryId) - ->where('cl.`id_lang` = ' . $this->contextLanguageId) - ->where('cl.`id_shop` IN (' . implode(',', $this->contextShopIds) . ')') - ->groupBy('c.`id_cms_category`') - ; - - $childCategories = Db::getInstance()->executeS($childrenQuery); - $childCategories = is_array($childCategories) ? $childCategories : []; - - foreach ($childCategories as $childCategory) { - $categories['children'][] = $this->collectNestedCategoriesIdsAndNames($childCategory['id_cms_category']); - } - - return $categories; - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/AbstractCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/AbstractCmsPageCategoryHandler.php deleted file mode 100644 index 4f27fe0e..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/AbstractCmsPageCategoryHandler.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\IsUrlRewrite; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Holds the abstraction required for Adding or updating the cms page category. - */ -abstract class AbstractCmsPageCategoryHandler extends AbstractObjectModelHandler -{ - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @param ValidatorInterface $validator - */ - public function __construct(ValidatorInterface $validator) - { - $this->validator = $validator; - } - - /** - * @param array $localisedTexts - * - * @return bool - */ - protected function assertHasDefaultLanguage(array $localisedTexts) - { - $errors = $this->validator->validate($localisedTexts, new DefaultLanguage()); - - return 0 === count($errors); - } - - /** - * @param array $localisedUrls - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertIsValidLinkRewrite(array $localisedUrls) - { - foreach ($localisedUrls as $localisedUrl) { - $errors = $this->validator->validate($localisedUrl, new IsUrlRewrite()); - - if (0 !== count($errors)) { - throw new CmsPageCategoryConstraintException(sprintf('Given friendly url "%s" is not valid for link rewrite', $localisedUrl), CmsPageCategoryConstraintException::INVALID_LINK_REWRITE); - } - } - } - - /** - * @param array $localisedDescription - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertDescriptionContainsCleanHtml(array $localisedDescription) - { - foreach ($localisedDescription as $description) { - $errors = $this->validator->validate($description, new CleanHtml()); - - if (0 !== count($errors)) { - throw new CmsPageCategoryConstraintException(sprintf('Given description "%s" contains javascript events or script tags', $description), CmsPageCategoryConstraintException::INVALID_DESCRIPTION); - } - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/AddCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/AddCmsPageCategoryHandler.php deleted file mode 100644 index ea67b22c..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/AddCmsPageCategoryHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\AddCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\AddCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotAddCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use PrestaShopException; - -/** - * Adds cms page category - */ -final class AddCmsPageCategoryHandler extends AbstractCmsPageCategoryHandler implements AddCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(AddCmsPageCategoryCommand $command) - { - if (!$this->assertHasDefaultLanguage($command->getLocalisedName())) { - throw new CmsPageCategoryConstraintException('Missing name in default language', CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_NAME); - } - - if (!$this->assertHasDefaultLanguage($command->getLocalisedFriendlyUrl())) { - throw new CmsPageCategoryConstraintException('Missing friendly url in default language', CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_FRIENDLY_URL); - } - - $this->assertIsValidLinkRewrite($command->getLocalisedFriendlyUrl()); - $this->assertDescriptionContainsCleanHtml($command->getLocalisedDescription()); - - try { - $cmsPageCategory = new CMSCategory(); - $cmsPageCategory->name = $command->getLocalisedName(); - $cmsPageCategory->active = $command->isDisplayed(); - $cmsPageCategory->id_parent = $command->getParentId()->getValue(); - $cmsPageCategory->description = $command->getLocalisedDescription(); - $cmsPageCategory->meta_title = $command->getLocalisedMetaTitle(); - $cmsPageCategory->meta_description = $command->getLocalisedMetaDescription(); - $cmsPageCategory->meta_keywords = $command->getLocalisedMetaKeywords(); - - $cmsPageCategory->link_rewrite = $command->getLocalisedFriendlyUrl(); - - if (false === $cmsPageCategory->add()) { - throw new CannotAddCmsPageCategoryException('Failed to add cms page category'); - } - - $this->associateWithShops($cmsPageCategory, $command->getShopAssociation()); - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException('An unexpected error occurred when adding cms page category', 0, $exception); - } - - return new CmsPageCategoryId((int) $cmsPageCategory->id); - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandler.php deleted file mode 100644 index f9a9c6ae..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDeleteCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\BulkDeleteCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotDeleteCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Class BulkDeleteCmsPageCategoryHandler is responsible for deleting multiple cms page categories. - */ -final class BulkDeleteCmsPageCategoryHandler implements BulkDeleteCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(BulkDeleteCmsPageCategoryCommand $command) - { - try { - foreach ($command->getCmsPageCategoryIds() as $cmsPageCategoryId) { - $entity = new CMSCategory($cmsPageCategoryId->getValue()); - - if (0 >= $entity->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for deleting.', $cmsPageCategoryId->getValue())); - } - - if (false === $entity->delete()) { - throw new CannotDeleteCmsPageCategoryException(sprintf('Unable to delete cms category object with id "%s"', $cmsPageCategoryId->getValue()), CannotDeleteCmsPageCategoryException::FAILED_BULK_DELETE); - } - } - } catch (PrestaShopException $e) { - throw new CmsPageCategoryException('Unexpected error occurred when handling bulk delete cms category', 0, $e); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/BulkDisableCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/BulkDisableCmsPageCategoryHandler.php deleted file mode 100644 index d05ef260..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/BulkDisableCmsPageCategoryHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDisableCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\BulkDisableCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotDisableCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Class BulkDisableCmsPageCategoryHandler is responsible for deleting multiple cms page categories. - */ -final class BulkDisableCmsPageCategoryHandler implements BulkDisableCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(BulkDisableCmsPageCategoryCommand $command) - { - try { - foreach ($command->getCmsPageCategoryIds() as $cmsPageCategoryId) { - $entity = new CMSCategory($cmsPageCategoryId->getValue()); - - if (0 >= $entity->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for disabling status.', $cmsPageCategoryId->getValue())); - } - - $entity->active = false; - - if (false === $entity->update()) { - throw new CannotDisableCmsPageCategoryException(sprintf('Unable to disable cms category object with id "%s"', $cmsPageCategoryId->getValue())); - } - } - } catch (PrestaShopException $e) { - throw new CmsPageCategoryException('Unexpected error occurred when handling bulk disable cms category', 0, $e); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/BulkEnableCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/BulkEnableCmsPageCategoryHandler.php deleted file mode 100644 index 009dfb7a..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/BulkEnableCmsPageCategoryHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkEnableCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\BulkEnableCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotEnableCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Class BulkEnableCmsPageCategoryCommand is responsible for enabling cms category pages. - */ -final class BulkEnableCmsPageCategoryHandler implements BulkEnableCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(BulkEnableCmsPageCategoryCommand $command) - { - try { - foreach ($command->getCmsPageCategoryIds() as $cmsPageCategoryId) { - $entity = new CMSCategory($cmsPageCategoryId->getValue()); - - if (0 >= $entity->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for enabling status.', $cmsPageCategoryId->getValue())); - } - - $entity->active = true; - - if (false === $entity->update()) { - throw new CannotEnableCmsPageCategoryException(sprintf('Unable to enable cms category object with id "%s"', $cmsPageCategoryId->getValue())); - } - } - } catch (PrestaShopException $e) { - throw new CmsPageCategoryException('Unexpected error occurred when handling bulk enable cms category', 0, $e); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/DeleteCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/DeleteCmsPageCategoryHandler.php deleted file mode 100644 index 76ae1840..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/DeleteCmsPageCategoryHandler.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\DeleteCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\DeleteCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotDeleteCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Class DeleteCmsPageCategoryHandler is responsible for deleting cms page category. - */ -final class DeleteCmsPageCategoryHandler implements DeleteCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(DeleteCmsPageCategoryCommand $command) - { - try { - $entity = new CMSCategory($command->getCmsPageCategoryId()->getValue()); - - if (0 >= $entity->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for deletion.', $command->getCmsPageCategoryId()->getValue())); - } - - if (false === $entity->delete()) { - throw new CannotDeleteCmsPageCategoryException(sprintf('Unable to delete cms category object with id "%s"', $command->getCmsPageCategoryId()->getValue()), CannotDeleteCmsPageCategoryException::FAILED_DELETE); - } - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException(sprintf('An error occurred when deleting cms category object with id "%s"', $command->getCmsPageCategoryId()->getValue()), 0, $exception); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/EditCmsPageCategoryHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/EditCmsPageCategoryHandler.php deleted file mode 100644 index e954064e..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/EditCmsPageCategoryHandler.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\EditCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\EditCmsPageCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotUpdateCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Edits cms page category. - */ -final class EditCmsPageCategoryHandler extends AbstractCmsPageCategoryHandler implements EditCmsPageCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(EditCmsPageCategoryCommand $command) - { - try { - $cmsPageCategory = new CMSCategory($command->getCmsPageCategoryId()->getValue()); - - if (0 >= $cmsPageCategory->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Unable to find cms page category with id "%s"', $cmsPageCategory->id)); - } - - if (null !== $command->getLocalisedName()) { - if (!$this->assertHasDefaultLanguage($command->getLocalisedName())) { - throw new CmsPageCategoryConstraintException('Missing name in default language', CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_NAME); - } - $cmsPageCategory->name = $command->getLocalisedName(); - } - - if (null !== $command->isDisplayed()) { - $cmsPageCategory->active = $command->isDisplayed(); - } - - if (null !== $command->getParentId()) { - $this->assertCmsCategoryCanBeMovedToParent( - $command->getCmsPageCategoryId()->getValue(), - $command->getParentId()->getValue() - ); - $cmsPageCategory->id_parent = $command->getParentId()->getValue(); - } - - if (null !== $command->getLocalisedDescription()) { - $this->assertDescriptionContainsCleanHtml($command->getLocalisedDescription()); - $cmsPageCategory->description = $command->getLocalisedDescription(); - } - - if (null !== $command->getLocalisedMetaTitle()) { - $cmsPageCategory->meta_title = $command->getLocalisedMetaTitle(); - } - - if (null !== $command->getLocalisedMetaDescription()) { - $cmsPageCategory->meta_description = $command->getLocalisedMetaDescription(); - } - - if (null !== $command->getLocalisedMetaKeywords()) { - $cmsPageCategory->meta_keywords = $command->getLocalisedMetaKeywords(); - } - - if (null !== $command->getLocalisedFriendlyUrl()) { - if (!$this->assertHasDefaultLanguage($command->getLocalisedFriendlyUrl())) { - throw new CmsPageCategoryConstraintException('Missing friendly url in default language', CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_FRIENDLY_URL); - } - $this->assertIsValidLinkRewrite($command->getLocalisedFriendlyUrl()); - - $cmsPageCategory->link_rewrite = $command->getLocalisedFriendlyUrl(); - } - - if (false === $cmsPageCategory->update()) { - throw new CannotUpdateCmsPageCategoryException('Failed to update cms page category'); - } - - if (null !== $command->getShopAssociation()) { - $this->associateWithShops($cmsPageCategory, $command->getShopAssociation()); - } - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException('An unexpected error occurred when updating cms page category', 0, $exception); - } - } - - /** - * Adds if the current category is not being moved to the same category or its own child. - * - * @param int $cmsCategoryId - * @param int $cmsCategoryParentId - * - * @throws CmsPageCategoryConstraintException - */ - private function assertCmsCategoryCanBeMovedToParent($cmsCategoryId, $cmsCategoryParentId) - { - if (!CMSCategory::checkBeforeMove($cmsCategoryId, $cmsCategoryParentId)) { - throw new CmsPageCategoryConstraintException(sprintf('Unable to move cms category "%s" to parent category "%s"', $cmsCategoryId, $cmsCategoryParentId), CmsPageCategoryConstraintException::CANNOT_MOVE_CATEGORY_TO_PARENT); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandler.php b/src/Adapter/CMS/PageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandler.php deleted file mode 100644 index f48a04ce..00000000 --- a/src/Adapter/CMS/PageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandler.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\ToggleCmsPageCategoryStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler\ToggleCmsPageCategoryStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotToggleCmsPageCategoryStatusException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShopException; - -/** - * Class ToggleCmsPageCategoryStatusHandler is responsible for turning on and off cms page category status. - */ -final class ToggleCmsPageCategoryStatusHandler implements ToggleCmsPageCategoryStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(ToggleCmsPageCategoryStatusCommand $command) - { - try { - $entity = new CMSCategory($command->getCmsPageCategoryId()->getValue()); - - if (0 >= $entity->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for status changing.', $command->getCmsPageCategoryId()->getValue())); - } - - if (false === $entity->toggleStatus()) { - throw new CannotToggleCmsPageCategoryStatusException(sprintf('Unable to toggle cms category with id "%s"', $command->getCmsPageCategoryId()->getValue())); - } - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException(sprintf('An error occurred when toggling status for cms page object with id "%s"', $command->getCmsPageCategoryId()->getValue()), 0, $exception); - } - } -} diff --git a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandler.php b/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandler.php deleted file mode 100644 index f28a8db7..00000000 --- a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandler.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoriesForBreadcrumb; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler\GetCmsPageCategoriesForBreadcrumbHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\Breadcrumb; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\BreadcrumbItem; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use PrestaShopException; - -/** - * Class GetCmsPageCategoriesForBreadcrumbHandler is responsible for providing required data for displaying cms page category - * breadcrumbs. - */ -final class GetCmsPageCategoriesForBreadcrumbHandler implements GetCmsPageCategoriesForBreadcrumbHandlerInterface -{ - /** - * @var int - */ - private $contextLanguageId; - - /** - * @param int $contextLanguageId - */ - public function __construct($contextLanguageId) - { - $this->contextLanguageId = $contextLanguageId; - } - - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(GetCmsPageCategoriesForBreadcrumb $query) - { - try { - $currentCategory = new CMSCategory( - $query->getCurrentCategoryId()->getValue(), - $this->contextLanguageId - ); - - if (0 >= $currentCategory->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found for retrieving breadcrumbs', $query->getCurrentCategoryId()->getValue())); - } - - $rootCategory = new CMSCategory( - CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID, - $this->contextLanguageId - ); - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException(sprintf('An error occurred when finding cms category object with id "%s" or root category by id "%s"', $query->getCurrentCategoryId()->getValue(), CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID), 0, $exception); - } - - $rootCategoryData = [ - 'id_cms_category' => CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID, - 'name' => $rootCategory->name, - ]; - - if (CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID === $query->getCurrentCategoryId()->getValue()) { - return new Breadcrumb([ - new BreadcrumbItem( - (int) $rootCategoryData['id_cms_category'], - $rootCategoryData['name'] - ), - ]); - } - - $parentCategories = $currentCategory->getParentsCategories($this->contextLanguageId); - $parentCategories[] = $rootCategoryData; - $parentCategories = array_reverse($parentCategories); - - $categories = []; - foreach ($parentCategories as $category) { - $categories[] = new BreadcrumbItem( - (int) $category['id_cms_category'], - $category['name'] - ); - } - - return new Breadcrumb($categories); - } -} diff --git a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryForEditingHandler.php b/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryForEditingHandler.php deleted file mode 100644 index b654d32a..00000000 --- a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryForEditingHandler.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler\GetCmsPageCategoryForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\EditableCmsPageCategory; -use PrestaShopException; - -/** - * Class GetCmsPageCategoryForEditingHandler is responsible for retrieving cms page category form data. - * - * @internal - */ -final class GetCmsPageCategoryForEditingHandler implements GetCmsPageCategoryForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(GetCmsPageCategoryForEditing $query) - { - try { - $cmsPageCategory = new CMSCategory($query->getCmsPageCategoryId()->getValue()); - - if (0 >= $cmsPageCategory->id) { - throw new CmsPageCategoryNotFoundException(sprintf('Cms category object with id "%s" has not been found', $query->getCmsPageCategoryId()->getValue())); - } - - $shopIds = is_array($cmsPageCategory->getAssociatedShops()) ? $cmsPageCategory->getAssociatedShops() : []; - } catch (PrestaShopException $exception) { - throw new CmsPageCategoryException(sprintf('An error occurred when retrieving cms page category data with id %s', $query->getCmsPageCategoryId()->getValue()), 0, $exception); - } - - return new EditableCmsPageCategory( - is_array($cmsPageCategory->name) ? $cmsPageCategory->name : [], - $cmsPageCategory->active, - (int) $cmsPageCategory->id_parent, - is_array($cmsPageCategory->description) ? $cmsPageCategory->description : [], - is_array($cmsPageCategory->meta_description) ? $cmsPageCategory->meta_description : [], - is_array($cmsPageCategory->meta_keywords) ? $cmsPageCategory->meta_keywords : [], - is_array($cmsPageCategory->meta_title) ? $cmsPageCategory->meta_title : [], - is_array($cmsPageCategory->link_rewrite) ? $cmsPageCategory->link_rewrite : [], - $shopIds - ); - } -} diff --git a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandler.php b/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandler.php deleted file mode 100644 index d19cd31a..00000000 --- a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandler.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryNameForListing; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler\GetCmsPageCategoryNameForListingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Gets name by cms category which are used for display in cms listing. - */ -final class GetCmsPageCategoryNameForListingHandler implements GetCmsPageCategoryNameForListingHandlerInterface -{ - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @param int $contextLanguageId - * @param RequestStack $requestStack - */ - public function __construct( - $contextLanguageId, - RequestStack $requestStack - ) { - $this->contextLanguageId = $contextLanguageId; - $this->requestStack = $requestStack; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCmsPageCategoryNameForListing $query) - { - $cmsCategory = new CMSCategory($this->getCmsCategoryIdFromRequest()); - - return isset($cmsCategory->name[$this->contextLanguageId]) ? $cmsCategory->name[$this->contextLanguageId] : ''; - } - - /** - * Gets id from request or fall-backs to the default one if not found. - * - * @return int - */ - private function getCmsCategoryIdFromRequest() - { - $currentRequest = $this->requestStack->getCurrentRequest(); - $categoryIdFromRequest = null; - if (null !== $currentRequest) { - $categoryIdFromRequest = $currentRequest->query->getInt('id_cms_category'); - } - - return $categoryIdFromRequest ?: CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID; - } -} diff --git a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandler.php b/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandler.php deleted file mode 100644 index 3221262a..00000000 --- a/src/Adapter/CMS/PageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler; - -use CMSCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageParentCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler\GetCmsPageParentCategoryIdForRedirectionHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use PrestaShopException; - -/** - * Class GetCmsPageParentCategoryIdForRedirectionHandler is responsible for providing cms page categories parent id - * for redirecting to the right controller after create, edit, delete, toggle actions. - */ -final class GetCmsPageParentCategoryIdForRedirectionHandler implements GetCmsPageParentCategoryIdForRedirectionHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function handle(GetCmsPageParentCategoryIdForRedirection $query) - { - try { - $entity = new CMSCategory($query->getCmsPageCategoryId()->getValue()); - $parentId = (int) $entity->id_parent; - } catch (PrestaShopException $e) { - $parentId = CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID; - } - - return new CmsPageCategoryId($parentId); - } -} diff --git a/src/Adapter/Cache/CacheAdapter.php b/src/Adapter/Cache/CacheAdapter.php deleted file mode 100644 index c300d7bc..00000000 --- a/src/Adapter/Cache/CacheAdapter.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache; - -use Cache; - -/** - * Adapter for generic cache methods. - */ -class CacheAdapter -{ - /** - * @param string $key - * @param string $value - */ - public function store($key, $value) - { - return Cache::store($key, $value); - } - - /** - * @param string $key - * - * @return mixed - */ - public function retrieve($key) - { - return Cache::retrieve($key); - } - - /** - * @param string $key - * - * @return bool - */ - public function isStored($key) - { - return Cache::isStored($key); - } -} diff --git a/src/Adapter/Cache/CacheClearer.php b/src/Adapter/Cache/CacheClearer.php deleted file mode 100644 index b28e5c5f..00000000 --- a/src/Adapter/Cache/CacheClearer.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; - -/** - * Class able to clear application caches. - * - * @internal - */ -class CacheClearer -{ - /** - * @var CacheClearerInterface - */ - private $cacheClearerChain; - - /** - * @var CacheClearerInterface - */ - private $symfonyCacheClearer; - - /** - * @var CacheClearerInterface - */ - private $mediaCacheClearer; - - /** - * @var CacheClearerInterface - */ - private $smartyCacheClearer; - - /** - * @param CacheClearerInterface $cacheClearerChain - * @param CacheClearerInterface $symfonyCacheClearer - * @param CacheClearerInterface $mediaCacheClearer - * @param CacheClearerInterface $smartyCacheClearer - */ - public function __construct( - CacheClearerInterface $cacheClearerChain, - CacheClearerInterface $symfonyCacheClearer, - CacheClearerInterface $mediaCacheClearer, - CacheClearerInterface $smartyCacheClearer - ) { - $this->cacheClearerChain = $cacheClearerChain; - $this->symfonyCacheClearer = $symfonyCacheClearer; - $this->mediaCacheClearer = $mediaCacheClearer; - $this->smartyCacheClearer = $smartyCacheClearer; - } - - /** - * Clear all application caches. - * - * @deprecated since 1.7.6. Use CacheClearerChain instead. - */ - public function clearAllCaches() - { - @trigger_error( - 'Deprecated since 1.7.6, to be removed in 1.8. Use CacheClearerChain instead.', - E_USER_DEPRECATED - ); - - $this->cacheClearerChain->clear(); - } - - /** - * Clear Symfony cache. - * - * @deprecated since 1.7.6. Use SymfonyCacheClearer instead. - */ - public function clearSymfonyCache() - { - @trigger_error( - 'Deprecated since 1.7.6, to be removed in 1.8. Use SymfonyCacheClearer instead.', - E_USER_DEPRECATED - ); - - $this->symfonyCacheClearer->clear(); - } - - /** - * Clear media cache only. - * - * @deprecated since 1.7.6. Use MediaCacheClearer instead. - */ - public function clearMediaCache() - { - @trigger_error( - 'Deprecated since 1.7.6, to be removed in 1.8. Use MediaCacheClearer instead.', - E_USER_DEPRECATED - ); - - $this->mediaCacheClearer->clear(); - } - - /** - * Clear smarty cache only. - * - * @deprecated since 1.7.6. Use SmartyCacheClearer instead. - */ - public function clearSmartyCache() - { - @trigger_error( - 'Deprecated since 1.7.6, to be removed in 1.8. Use SmartyCacheClearer instead.', - E_USER_DEPRECATED - ); - - $this->smartyCacheClearer->clear(); - } -} diff --git a/src/Adapter/Cache/CachingConfiguration.php b/src/Adapter/Cache/CachingConfiguration.php deleted file mode 100644 index f4e8ba35..00000000 --- a/src/Adapter/Cache/CachingConfiguration.php +++ /dev/null @@ -1,157 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache; - -use PrestaShop\PrestaShop\Adapter\Configuration\PhpParameters; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class manages Caching configuration for a Shop. - */ -class CachingConfiguration implements DataConfigurationInterface -{ - /** - * @var MemcacheServerManager - */ - private $memcacheServerManager; - - /** - * @var PhpParameters - */ - private $phpParameters; - - /** - * @var CacheClearerInterface - */ - private $symfonyCacheClearer; - - /** - * @var bool check if the caching is enabled - */ - private $isCachingEnabled; - - /** - * @var string the selected Caching system: 'CacheApc' for instance - */ - private $cachingSystem; - - /** - * @param MemcacheServerManager $memcacheServerManager - * @param PhpParameters $phpParameters - * @param CacheClearerInterface $symfonyCacheClearer - * @param $isCachingEnabled - * @param $cachingSystem - */ - public function __construct( - MemcacheServerManager $memcacheServerManager, - PhpParameters $phpParameters, - CacheClearerInterface $symfonyCacheClearer, - $isCachingEnabled, - $cachingSystem - ) { - $this->memcacheServerManager = $memcacheServerManager; - $this->phpParameters = $phpParameters; - $this->symfonyCacheClearer = $symfonyCacheClearer; - $this->isCachingEnabled = $isCachingEnabled; - $this->cachingSystem = $cachingSystem; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'use_cache' => $this->isCachingEnabled, - 'caching_system' => $this->cachingSystem, - 'servers' => $this->memcacheServerManager->getServers(), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $errors = $this->updatePhpCacheConfiguration($configuration); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['use_cache'], - $configuration['caching_system'], - $configuration['servers'] - ); - } - - /** - * Update the Php configuration for Cache feature and system. - * - * @return array the errors list during the update operation - */ - private function updatePhpCacheConfiguration(array $configuration) - { - $errors = []; - - if ( - $configuration['use_cache'] !== $this->isCachingEnabled - && null !== $configuration['caching_system'] - ) { - $this->phpParameters->setProperty('parameters.ps_cache_enable', $configuration['use_cache']); - } - - if ( - null !== $configuration['caching_system'] - && $configuration['caching_system'] !== $this->cachingSystem - ) { - $this->phpParameters->setProperty('parameters.ps_caching', $configuration['caching_system']); - } - - if (false === $this->phpParameters->saveConfiguration()) { - $errors[] = [ - 'key' => 'The settings file cannot be overwritten.', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [], - ]; - } - - $this->symfonyCacheClearer->clear(); - - return $errors; - } -} diff --git a/src/Adapter/Cache/Clearer/ClassIndexCacheClearer.php b/src/Adapter/Cache/Clearer/ClassIndexCacheClearer.php deleted file mode 100644 index 47093203..00000000 --- a/src/Adapter/Cache/Clearer/ClassIndexCacheClearer.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache\Clearer; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShopAutoload; - -/** - * Class ClassIndexCacheClearer clears current class index and generates new one. - * - * @internal - */ -final class ClassIndexCacheClearer implements CacheClearerInterface -{ - /** - * {@inheritdoc} - */ - public function clear() - { - PrestaShopAutoload::getInstance()->generateIndex(); - } -} diff --git a/src/Adapter/Cache/Clearer/MediaCacheClearer.php b/src/Adapter/Cache/Clearer/MediaCacheClearer.php deleted file mode 100644 index f8b21bda..00000000 --- a/src/Adapter/Cache/Clearer/MediaCacheClearer.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache\Clearer; - -use Media; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; - -/** - * Class MediaCacheClearer clears Front Office theme's Javascript & CSS cache. - * - * @internal - */ -final class MediaCacheClearer implements CacheClearerInterface -{ - /** - * {@inheritdoc} - */ - public function clear() - { - Media::clearCache(); - } -} diff --git a/src/Adapter/Cache/Clearer/SmartyCacheClearer.php b/src/Adapter/Cache/Clearer/SmartyCacheClearer.php deleted file mode 100644 index 28893632..00000000 --- a/src/Adapter/Cache/Clearer/SmartyCacheClearer.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache\Clearer; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use Tools; - -/** - * Class SmartyCacheClearer clears Smarty cache. - * - * @internal - */ -final class SmartyCacheClearer implements CacheClearerInterface -{ - /** - * {@inheritdoc} - */ - public function clear() - { - Tools::clearSmartyCache(); - } -} diff --git a/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php b/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php deleted file mode 100644 index f34c14c8..00000000 --- a/src/Adapter/Cache/Clearer/SymfonyCacheClearer.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache\Clearer; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use Tools; - -/** - * Class SymfonyCacheClearer clears Symfony cache directly from filesystem. - * - * @internal - */ -final class SymfonyCacheClearer implements CacheClearerInterface -{ - /** - * {@inheritdoc} - */ - public function clear() - { - Tools::clearSf2Cache(); - } -} diff --git a/src/Adapter/Cache/Clearer/XmlCacheClearer.php b/src/Adapter/Cache/Clearer/XmlCacheClearer.php deleted file mode 100644 index c0220085..00000000 --- a/src/Adapter/Cache/Clearer/XmlCacheClearer.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache\Clearer; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use Tools; - -/** - * Class XmlCacheClearer clears cache under /config/xml/ directory. - * - * @internal - */ -final class XmlCacheClearer implements CacheClearerInterface -{ - /** - * {@inheritdoc} - */ - public function clear() - { - Tools::clearXMLCache(); - } -} diff --git a/src/Adapter/Cache/CombineCompressCacheConfiguration.php b/src/Adapter/Cache/CombineCompressCacheConfiguration.php deleted file mode 100644 index 38f29a6b..00000000 --- a/src/Adapter/Cache/CombineCompressCacheConfiguration.php +++ /dev/null @@ -1,225 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem as PsFileSystem; -use Symfony\Component\Filesystem\Exception\IOExceptionInterface; -use Symfony\Component\Filesystem\Filesystem; - -/** - * This class manages CCC features configuration for a Shop. - */ -class CombineCompressCacheConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var Tools - */ - private $tools; - - /** - * @var string Absolute path to the theme directory - */ - private $themePath; - - /** - * @var string Current active theme name - */ - private $themeName; - - public function __construct( - Configuration $configuration, - Filesystem $filesystem, - Tools $tools, - $themePath, - $themeName - ) { - $this->configuration = $configuration; - $this->filesystem = $filesystem; - $this->tools = $tools; - $this->themePath = $themePath; - $this->themeName = $themeName; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'smart_cache_css' => $this->configuration->getBoolean('PS_CSS_THEME_CACHE'), - 'smart_cache_js' => $this->configuration->getBoolean('PS_JS_THEME_CACHE'), - 'apache_optimization' => $this->configuration->getBoolean('PS_HTACCESS_CACHE_CONTROL'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $this->updateCachesVersionsIfNeeded($configuration); - if ($configuration['smart_cache_css'] || $configuration['smart_cache_js']) { - // Manage JS & CSS Smart cache - if (!$this->createThemeCacheFolder()) { - $errors[] = [ - 'key' => 'To use Smarty Cache, the directory %directorypath% must be writable.', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [ - '%directorypath%' => $this->getThemeCacheFolder(), - ], - ]; - } - } - - // Manage Apache optimization - $apacheError = $this->manageApacheOptimization((bool) $configuration['apache_optimization']); - - if (count($apacheError) > 0) { - $errors[] = $apacheError; - } - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['smart_cache_css'], - $configuration['smart_cache_js'], - $configuration['apache_optimization'] - ); - } - - /** - * @return string Absolute path the the current active theme - */ - private function getThemeCacheFolder() - { - return $this->themePath . '/' . $this->themeName . '/cache/'; - } - - /** - * Creates Cache folder for the active theme. - * - * @return bool - */ - private function createThemeCacheFolder() - { - try { - $folder = $this->getThemeCacheFolder(); - $this->filesystem->mkdir($folder, PsFileSystem::DEFAULT_MODE_FOLDER); - - return true; - } catch (IOExceptionInterface $e) { - return false; - } - } - - /** - * Update Cache version of assets if needed. - * - * @param array the configuration - */ - private function updateCachesVersionsIfNeeded(array $configuration) - { - $cacheCSS = $configuration['smart_cache_css']; - $currentCacheCSS = $this->configuration->get('PS_CSS_THEME_CACHE'); - - $cacheJS = $configuration['smart_cache_js']; - $currentCacheJS = $this->configuration->get('PS_JS_THEME_CACHE'); - - if ($cacheCSS !== $currentCacheCSS) { - $cssCacheVersion = $this->configuration->get('PS_CCCCSS_VERSION') + 1; - $this->configuration->set('PS_CCCCSS_VERSION', $cssCacheVersion); - $this->configuration->set('PS_CSS_THEME_CACHE', $cacheCSS); - } - - if ($cacheJS !== $currentCacheJS) { - $jsCacheVersion = $this->configuration->get('PS_CCCJS_VERSION') + 1; - $this->configuration->set('PS_CCCCSS_VERSION', $jsCacheVersion); - $this->configuration->set('PS_JS_THEME_CACHE', $cacheJS); - } - } - - /** - * Creates .htaccess if Apache optimization feature is enabled. - * - * @param bool $enabled - * - * @return array not empty in case of error - */ - private function manageApacheOptimization($enabled) - { - $errors = []; - $isCurrentlyEnabled = (bool) $this->configuration->get('PS_HTACCESS_CACHE_CONTROL'); - - // feature activation - if (false === $isCurrentlyEnabled && true === $enabled) { - $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', true); - if (!$this->tools->generateHtaccess()) { - $errors = [ - 'key' => 'Before being able to use this tool, you need to:[1][2]Create a blank .htaccess in your root directory.[/2][2]Give it write permissions (CHMOD 666 on Unix system).[/2][/1]', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [ - '[1]' => '

      ', - '[/1]' => '
    ', - '[2]' => '
  • ', - '[/2]' => '
  • ', - ], - ]; - $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', false); - } - } - - if (true === $isCurrentlyEnabled && false === $enabled) { - $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', false); - $this->tools->generateHtaccess(); - } - - return $errors; - } -} diff --git a/src/Adapter/Cache/MemcacheServerManager.php b/src/Adapter/Cache/MemcacheServerManager.php deleted file mode 100644 index 55ef6c54..00000000 --- a/src/Adapter/Cache/MemcacheServerManager.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cache; - -use Doctrine\DBAL\Connection; -use Memcache; -use Memcached; - -/** - * This class manages Memcache(d) servers in "Configure > Advanced Parameters > Performance" page. - */ -class MemcacheServerManager -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $tableName; - - public function __construct(Connection $connection, $dbPrefix) - { - $this->connection = $connection; - $this->tableName = $dbPrefix . 'memcached_servers'; - } - - /** - * Add a memcache server. - * - * @param string $serverIp - * @param int $serverPort - * @param int $serverWeight - */ - public function addServer($serverIp, $serverPort, $serverWeight) - { - $this->connection->executeUpdate('INSERT INTO ' . $this->tableName . ' (ip, port, weight) VALUES(:serverIp, :serverPort, :serverWeight)', [ - 'serverIp' => $serverIp, - 'serverPort' => (int) $serverPort, - 'serverWeight' => (int) $serverWeight, - ]); - - return [ - 'id' => $this->connection->lastInsertId(), - 'server_ip' => $serverIp, - 'server_port' => $serverPort, - 'server_weight' => $serverWeight, - ]; - } - - /** - * Test if a Memcache configuration is valid. - * - * @param string $serverIp - * @param string @serverPort - * - * @return bool - */ - public function testConfiguration($serverIp, $serverPort) - { - if (extension_loaded('memcached')) { - $memcached = new Memcached(); - $memcached->addServer($serverIp, $serverPort); - $version = $memcached->getVersion(); - - return is_array($version) && false === in_array('255.255.255', $version, true); - } - - return true === @memcache_connect($serverIp, $serverPort); - } - - /** - * Delete a memcache server (a deletion returns the number of rows deleted). - * - * @param int $serverId_server id (in database) - * - * @return bool - */ - public function deleteServer($serverId) - { - $deletionSuccess = $this->connection->delete($this->tableName, ['id_memcached_server' => $serverId]); - - return 1 === $deletionSuccess; - } - - /** - * Get list of memcached servers. - * - * @return array - */ - public function getServers() - { - return $this->connection->fetchAll('SELECT * FROM ' . $this->tableName, []); - } -} diff --git a/src/Adapter/CacheManager.php b/src/Adapter/CacheManager.php deleted file mode 100644 index 8672b8a0..00000000 --- a/src/Adapter/CacheManager.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Cache; - -/** - * Class CacheManager drives the cache behavior. - * - * Features to drive the legacy cache from new code architecture. - */ -class CacheManager -{ - /** - * Cleans the cache for specific cache key. - * - * @param $key - */ - public function clean($key) - { - Cache::clean($key); - } -} diff --git a/src/Adapter/Carrier/CarrierDataProvider.php b/src/Adapter/Carrier/CarrierDataProvider.php deleted file mode 100644 index f3baa446..00000000 --- a/src/Adapter/Carrier/CarrierDataProvider.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Carrier; - -use Carrier; -use PrestaShop\PrestaShop\Adapter\Configuration; - -/** - * This class will provide data from DB / ORM about Category. - */ -class CarrierDataProvider -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * Get all carriers in a given language. - * - * @param int $id_lang Language id - * @param bool $active Returns only active carriers when true - * @param bool $delete - * @param bool|int $id_zone - * @param string|null $ids_group - * @param $modules_filters , possible values: - * PS_CARRIERS_ONLY - * CARRIERS_MODULE - * CARRIERS_MODULE_NEED_RANGE - * PS_CARRIERS_AND_CARRIER_MODULES_NEED_RANGE - * ALL_CARRIERS - * - * @return array Carriers - */ - public function getCarriers($id_lang, $active = false, $delete = false, $id_zone = false, $ids_group = null, $modules_filters = Carrier::PS_CARRIERS_ONLY) - { - return Carrier::getCarriers($id_lang, $active, $delete, $id_zone, $ids_group, $modules_filters); - } - - /** - * Get all active carriers in given language, usable for choice form type. - * - * @param int|null $languageId if not provided - will use the default language - * - * @return array carrier choices - */ - public function getActiveCarriersChoices($languageId = null) - { - if (null === $languageId) { - $languageId = $this->configuration->getInt('PS_LANG_DEFAULT'); - } - - $carriers = $this->getCarriers($languageId, true, false, false, null, $this->getAllCarriersConstant()); - $carriersChoices = []; - - foreach ($carriers as $carrier) { - $carriersChoices[$carrier['name']] = $carrier['id_carrier']; - } - - return $carriersChoices; - } - - /** - * Get carriers order by choices. - * - * @return array order by choices - */ - public function getOrderByChoices() - { - return [ - 'Price' => Carrier::SORT_BY_PRICE, - 'Position' => Carrier::SORT_BY_POSITION, - ]; - } - - /** - * Get carriers order way choices. - * - * @return array order way choices - */ - public function getOrderWayChoices() - { - return [ - 'Ascending' => Carrier::SORT_BY_ASC, - 'Descending' => Carrier::SORT_BY_DESC, - ]; - } - - /** - * Get the CarrierCore class ALL_CARRIERS constant value. - * - * @return int - */ - public function getAllCarriersConstant() - { - return Carrier::ALL_CARRIERS; - } -} diff --git a/src/Adapter/Carrier/CarrierOptionsConfiguration.php b/src/Adapter/Carrier/CarrierOptionsConfiguration.php deleted file mode 100644 index 6b61a89e..00000000 --- a/src/Adapter/Carrier/CarrierOptionsConfiguration.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Carrier; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class CarrierOptionsConfiguration is responsible for saving and loading Carrier Options configuration. - */ -class CarrierOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * CarrierOptionsConfiguration constructor. - * - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'default_carrier' => $this->configuration->getInt('PS_CARRIER_DEFAULT'), - 'carrier_default_order_by' => $this->configuration->getInt('PS_CARRIER_DEFAULT_SORT'), - 'carrier_default_order_way' => $this->configuration->getInt('PS_CARRIER_DEFAULT_ORDER'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_CARRIER_DEFAULT', $configuration['default_carrier']); - $this->configuration->set('PS_CARRIER_DEFAULT_SORT', $configuration['carrier_default_order_by']); - $this->configuration->set('PS_CARRIER_DEFAULT_ORDER', $configuration['carrier_default_order_way']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['default_carrier'], - $configuration['carrier_default_order_by'], - $configuration['carrier_default_order_way'] - ); - } -} diff --git a/src/Adapter/Carrier/HandlingConfiguration.php b/src/Adapter/Carrier/HandlingConfiguration.php deleted file mode 100644 index 79a7dc10..00000000 --- a/src/Adapter/Carrier/HandlingConfiguration.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Carrier; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class HandlingConfiguration is responsible for saving and loading Handling options configuration. - */ -class HandlingConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * HandlingConfiguration constructor. - * - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'shipping_handling_charges' => $this->configuration->get('PS_SHIPPING_HANDLING'), - 'free_shipping_price' => $this->configuration->get('PS_SHIPPING_FREE_PRICE'), - 'free_shipping_weight' => $this->configuration->get('PS_SHIPPING_FREE_WEIGHT'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_SHIPPING_HANDLING', $configuration['shipping_handling_charges']); - $this->configuration->set('PS_SHIPPING_FREE_PRICE', $configuration['free_shipping_price']); - $this->configuration->set('PS_SHIPPING_FREE_WEIGHT', $configuration['free_shipping_weight']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['shipping_handling_charges'], - $configuration['free_shipping_price'], - $configuration['free_shipping_weight'] - ); - } -} diff --git a/src/Adapter/Cart/AbstractCartHandler.php b/src/Adapter/Cart/AbstractCartHandler.php deleted file mode 100644 index 681827c5..00000000 --- a/src/Adapter/Cart/AbstractCartHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart; - -use Cart; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShopException; - -/** - * Provides reusable methods for cart handlers - * - * @internal - */ -abstract class AbstractCartHandler -{ - /** - * @param CartId $cartId - * - * @return Cart - * - * @throws CartNotFoundException - */ - protected function getCart(CartId $cartId) - { - try { - $cart = new Cart($cartId->getValue()); - } catch (PrestaShopException $e) { - throw new CartException(sprintf('An error occurred when trying to load cart with id "%s', $cartId->getValue())); - } - - if (!Validate::isLoadedObject($cart) || $cartId->getValue() !== (int) $cart->id) { - throw new CartNotFoundException(sprintf('Cart with id "%s" was not found', $cartId->getValue())); - } - - return $cart; - } -} diff --git a/src/Adapter/Cart/CartPresenter.php b/src/Adapter/Cart/CartPresenter.php deleted file mode 100644 index 170b2cdc..00000000 --- a/src/Adapter/Cart/CartPresenter.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Cart\CartPresenter - */ -class CartPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Cart\CartPresenter -{ -} diff --git a/src/Adapter/Cart/CommandHandler/AddCartRuleToCartHandler.php b/src/Adapter/Cart/CommandHandler/AddCartRuleToCartHandler.php deleted file mode 100644 index fb3bcd2b..00000000 --- a/src/Adapter/Cart/CommandHandler/AddCartRuleToCartHandler.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Cache; -use Cart; -use CartRule; -use Context; -use Currency; -use Customer; -use Language; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCartRuleToCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\AddCartRuleToCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleValidityException; -use Shop; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * @internal - */ -final class AddCartRuleToCartHandler extends AbstractCartHandler implements AddCartRuleToCartHandlerInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param TranslatorInterface $translator - * @param ContextStateManager $contextStateManager - */ - public function __construct( - TranslatorInterface $translator, - ContextStateManager $contextStateManager - ) { - $this->translator = $translator; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(AddCartRuleToCartCommand $command) - { - $cart = $this->getCart($command->getCartId()); - $cartRule = new CartRule($command->getCartRuleId()->getValue()); - - $this->contextStateManager - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setLanguage(new Language($cart->id_lang)) - ->setCustomer(new Customer($cart->id_customer)) - ->setShop(new Shop($cart->id_shop)) - ; - - $errorMessage = $this->validateCartRule($cartRule, $cart); - - if ($errorMessage) { - $this->contextStateManager->restorePreviousContext(); - - throw new CartRuleValidityException($errorMessage); - } - - if (!$cart->addCartRule($cartRule->id)) { - $this->contextStateManager->restorePreviousContext(); - - throw new CartException('Failed to add cart rule to cart.'); - } - - $this->contextStateManager->restorePreviousContext(); - } - - /** - * Validates if the cart rule is applicable to cart - * - * Returns null if cart rule is valid. - * Returns translated error message if cart rule is not valid. - * - * @param CartRule $cartRule - * - * @return string|null - */ - private function validateCartRule(CartRule $cartRule, Cart $cart): ?string - { - Context::getContext()->cart = $cart; - $previousCartRules = $cart->getCartRules(); - $isValid = $cartRule->checkValidity(Context::getContext(), false, true); - - foreach ($previousCartRules as $previousCartRule) { - Cache::clean('getContextualValue_' . $previousCartRule['id_discount'] . '_*'); - } - - // if its valid, don't return any error message - if (true === $isValid) { - return null; - } - - // if its not valid, then this var contains translated error message - return $isValid; - } -} diff --git a/src/Adapter/Cart/CommandHandler/AddCustomizationHandler.php b/src/Adapter/Cart/CommandHandler/AddCustomizationHandler.php deleted file mode 100644 index 1b4c0971..00000000 --- a/src/Adapter/Cart/CommandHandler/AddCustomizationHandler.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Configuration; -use CustomizationField; -use ImageManager; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCustomizationCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\AddCustomizationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Exception\FileUploadException; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\CustomizationSettings; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\Exception\CustomizationConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\Exception\CustomizationException; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\ValueObject\CustomizationId; -use PrestaShopException; -use Product; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Handles @var AddCustomizationCommand using legacy object model. - */ -final class AddCustomizationHandler extends AbstractCartHandler implements AddCustomizationHandlerInterface -{ - /** - * If customization fields are not required and none of them are provided - * then no customizations are saved and null returned. - * Else, saved customizationId is returned or exception is thrown. - * - * @param AddCustomizationCommand $command - * - * @return int - * - * @throws CartNotFoundException - * @throws CustomizationConstraintException - * @throws CustomizationException - * @throws FileUploadException - */ - public function handle(AddCustomizationCommand $command): ?CustomizationId - { - $productId = $command->getProductId()->getValue(); - - $cart = $this->getCart($command->getCartId()); - $product = new Product($productId); - - $customizationFields = $product->getCustomizationFieldIds(); - $customizationValues = $command->getCustomizationValuesByFieldIds(); - - foreach ($customizationFields as $customizationField) { - $customizationFieldId = (int) $customizationField['id_customization_field']; - $isRequired = (bool) $customizationField['required']; - - if ($isRequired && empty($customizationValues[$customizationFieldId])) { - throw new CustomizationConstraintException(sprintf('Customization field #%s is required', $customizationFieldId), CustomizationConstraintException::FIELD_IS_REQUIRED); - } - - if (empty($customizationValues[$customizationFieldId])) { - continue; - } - - try { - if (Product::CUSTOMIZE_TEXTFIELD == $customizationField['type']) { - $this->assertCustomTextField($customizationFieldId, $customizationValues[$customizationFieldId]); - - $customizationId = $cart->addTextFieldToProduct( - $productId, - $customizationFieldId, - Product::CUSTOMIZE_TEXTFIELD, - $customizationValues[$customizationFieldId], - true - ); - } else { - $fileName = $this->uploadImage($customizationValues[$customizationFieldId]); - - $customizationId = $cart->addPictureToProduct( - $productId, - $customizationFieldId, - Product::CUSTOMIZE_FILE, - $fileName, - true - ); - } - - if (false === $customizationId) { - throw new CustomizationException(sprintf('Failed to add customized data for customization field with id "%s"', $customizationFieldId)); - } - } catch (PrestaShopException $e) { - throw new CustomizationException(sprintf('An error occurred while trying to add customized data for customization field with id "%s"', $customizationFieldId)); - } - } - - if (!isset($customizationId)) { - return null; - } - - return new CustomizationId($customizationId); - } - - /** - * Uploads image from customized field - * - * @param UploadedFile $file - * - * @return string - * - * @throws FileUploadException - */ - private function uploadImage(UploadedFile $file): string - { - $this->validateUpload($file); - - //@todo: check if copy is okay to use instead of move_uploaded_file(this fails creating new request from global later) - //@todo: implement UploadedFile::move() instead of copy(); - if (!($tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !copy($file->getPathname(), $tmpName)) { - throw new FileUploadException('An error occurred during the image upload process.'); - } - $fileName = md5(uniqid('', true)); - $resized = ImageManager::resize($tmpName, _PS_UPLOAD_DIR_ . $fileName) && - ImageManager::resize( - $tmpName, - _PS_UPLOAD_DIR_ . $fileName . '_small', - (int) Configuration::get('PS_PRODUCT_PICTURE_WIDTH'), - (int) Configuration::get('PS_PRODUCT_PICTURE_HEIGHT') - ); - - if (!$resized) { - throw new FileUploadException('An error occurred when resizing the uploaded image'); - } - - unlink($tmpName); - - return $fileName; - } - - /** - * Validates uploaded image - * - * @param UploadedFile $file - * - * @throws FileUploadException - */ - private function validateUpload(UploadedFile $file): void - { - $maxFileSize = (int) Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'); - - if ((int) $maxFileSize > 0 && $file->getSize() > (int) $maxFileSize) { - throw new FileUploadException(sprintf('Image is too large (%s kB). Maximum allowed: %s kB', $file->getSize() / 1024, $maxFileSize / 1024), UPLOAD_ERR_FORM_SIZE); - } - - if (!ImageManager::isRealImage($file->getPathname(), $file->getType()) || !ImageManager::isCorrectImageFileExt($file->getClientOriginalName(), null) || preg_match('/\%00/', $file->getClientOriginalName())) { - throw new FileUploadException('Image format not recognized, allowed formats are: .gif, .jpg, .png', UPLOAD_ERR_EXTENSION); - } - - if ($file->getError()) { - throw new FileUploadException('Error while uploading image', $file->getError()); - } - } - - /** - * @param int $customFieldId - * @param string $value - * - * @throws CustomizationConstraintException - */ - private function assertCustomTextField(int $customFieldId, string $value) - { - $customization = new CustomizationField($customFieldId); - - if ($customization->required && '' === $value) { - throw new CustomizationConstraintException(sprintf('Customization field #%s is required', $customFieldId), CustomizationConstraintException::FIELD_IS_REQUIRED); - } - - if (strlen($value) > CustomizationSettings::MAX_TEXT_LENGTH) { - throw new CustomizationConstraintException(sprintf('Customization field #%s value is too long', $customFieldId), CustomizationConstraintException::FIELD_IS_TOO_LONG); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/AddProductToCartHandler.php b/src/Adapter/Cart/CommandHandler/AddProductToCartHandler.php deleted file mode 100644 index 8a386173..00000000 --- a/src/Adapter/Cart/CommandHandler/AddProductToCartHandler.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCustomizationCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddProductToCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductQuantityInCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\AddCustomizationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\AddProductToCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateProductQuantityInCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; - -/** - * Handles add product to cart command - */ -final class AddProductToCartHandler extends AbstractCartHandler implements AddProductToCartHandlerInterface -{ - /** - * @var AddCustomizationHandlerInterface - */ - private $addCustomizationHandler; - - /** - * @var UpdateProductQuantityInCartHandlerInterface - */ - private $updateProductQuantityInCartHandler; - - /** - * @param AddCustomizationHandlerInterface $addCustomizationHandler - * @param UpdateProductQuantityInCartHandlerInterface $updateProductQuantityInCartHandler - */ - public function __construct( - AddCustomizationHandlerInterface $addCustomizationHandler, - UpdateProductQuantityInCartHandlerInterface $updateProductQuantityInCartHandler - ) { - $this->addCustomizationHandler = $addCustomizationHandler; - $this->updateProductQuantityInCartHandler = $updateProductQuantityInCartHandler; - } - - /** - * {@inheritdoc} - */ - public function handle(AddProductToCartCommand $command): void - { - $cartIdValue = $command->getCartId()->getValue(); - $productIdValue = $command->getProductId()->getValue(); - $combinationId = null !== $command->getCombinationId() ? $command->getCombinationId()->getValue() : null; - $customizationId = null; - - if (!empty($command->getCustomizationsByFieldIds())) { - $customizationIdVO = $this->addCustomizationHandler->handle(new AddCustomizationCommand( - $cartIdValue, - $command->getProductId()->getValue(), - $command->getCustomizationsByFieldIds() - )); - if (null !== $customizationIdVO) { - $customizationId = $customizationIdVO->getValue(); - } - } - - $cart = $this->getCart($command->getCartId()); - $product = $cart->getProductQuantity($productIdValue, $combinationId, $customizationId); - - $quantity = $command->getQuantity() + (int) $product['quantity']; - $this->assertQuantityIsPositiveInt($quantity); - - $this->updateProductQuantityInCartHandler->handle(new UpdateProductQuantityInCartCommand( - $cartIdValue, - $productIdValue, - $quantity, - $combinationId, - $customizationId - )); - } - - /** - * @param int $quantity - * - * @throws CartConstraintException - */ - private function assertQuantityIsPositiveInt(int $quantity): void - { - if (0 > $quantity) { - throw new CartConstraintException( - sprintf('Quantity must be positive integer, but %s given.', $quantity), - CartConstraintException::INVALID_QUANTITY - ); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/CreateEmptyCustomerCartHandler.php b/src/Adapter/Cart/CommandHandler/CreateEmptyCustomerCartHandler.php deleted file mode 100644 index f6a63afe..00000000 --- a/src/Adapter/Cart/CommandHandler/CreateEmptyCustomerCartHandler.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Cart; -use Configuration; -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\CreateEmptyCustomerCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\CreateEmptyCustomerCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShopException; - -/** - * @internal - */ -final class CreateEmptyCustomerCartHandler implements CreateEmptyCustomerCartHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(CreateEmptyCustomerCartCommand $command) - { - $customer = new Customer($command->getCustomerId()->getValue()); - - $lastEmptyCartId = $customer->getLastEmptyCart(false); - - if ($lastEmptyCartId) { - $cart = new Cart($lastEmptyCartId); - } else { - $cart = $this->createEmptyCustomerCart($customer); - } - - return new CartId((int) $cart->id); - } - - /** - * @param Customer $customer - * - * @return Cart - * - * @throws PrestaShopException - */ - private function createEmptyCustomerCart(Customer $customer): Cart - { - $cart = new Cart(); - - $cart->recyclable = 0; - $cart->gift = 0; - $cart->id_customer = $customer->id; - $cart->secure_key = $customer->secure_key; - - $cart->id_shop = $customer->id_shop; - $cart->id_lang = (int) Configuration::get('PS_LANG_DEFAULT'); - $cart->id_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT'); - - $addresses = $customer->getAddresses($cart->id_lang); - $addressId = !empty($addresses) ? (int) reset($addresses)['id_address'] : null; - $cart->id_address_delivery = $addressId; - $cart->id_address_invoice = $addressId; - - $cart->setNoMultishipping(); - $cart->save(); - - return $cart; - } -} diff --git a/src/Adapter/Cart/CommandHandler/RemoveCartRuleFromCartHandler.php b/src/Adapter/Cart/CommandHandler/RemoveCartRuleFromCartHandler.php deleted file mode 100644 index 03fe93a2..00000000 --- a/src/Adapter/Cart/CommandHandler/RemoveCartRuleFromCartHandler.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveCartRuleFromCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\RemoveCartRuleFromCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; - -/** - * @internal - */ -final class RemoveCartRuleFromCartHandler extends AbstractCartHandler implements RemoveCartRuleFromCartHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(RemoveCartRuleFromCartCommand $command) - { - $cart = $this->getCart($command->getCartId()); - - if (!$cart->removeCartRule($command->getCartRuleId()->getValue())) { - throw new CartException(sprintf('Failed to remove cart rule with id "%d" from cart', $command->getCartRuleId()->getValue())); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/RemoveProductFromCartHandler.php b/src/Adapter/Cart/CommandHandler/RemoveProductFromCartHandler.php deleted file mode 100644 index 356bf982..00000000 --- a/src/Adapter/Cart/CommandHandler/RemoveProductFromCartHandler.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Currency; -use Customer; -use Language; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveProductFromCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\RemoveProductFromCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use Shop; - -/** - * Handles removing product from context cart. - * - * @internal - */ -final class RemoveProductFromCartHandler extends AbstractCartHandler implements RemoveProductFromCartHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ContextStateManager $contextStateManager - */ - public function __construct( - ContextStateManager $contextStateManager - ) { - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(RemoveProductFromCartCommand $command) - { - $cart = $this->getCart($command->getCartId()); - - $this->contextStateManager - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setLanguage(new Language($cart->id_lang)) - ->setCustomer(new Customer($cart->id_customer)) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - $removed = $cart->deleteProduct( - $command->getProductId()->getValue(), - $command->getCombinationId() ?: 0, - $command->getCustomizationId() ?: 0 - ); - - if (!$removed) { - throw new CartException(sprintf('Failed to remove product with id "%d" from cart', $command->getProductId()->getValue())); - } - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/SendCartToCustomerHandler.php b/src/Adapter/Cart/CommandHandler/SendCartToCustomerHandler.php deleted file mode 100644 index f116ec9e..00000000 --- a/src/Adapter/Cart/CommandHandler/SendCartToCustomerHandler.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Cart; -use Context; -use Customer; -use Language; -use Mail; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\SendCartToCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\SendCartToCustomerHanlderInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use Validate; - -/** - * @internal - */ -final class SendCartToCustomerHandler implements SendCartToCustomerHanlderInterface -{ - /** - * {@inheritdoc} - */ - public function handle(SendCartToCustomerCommand $command) - { - $cart = $this->getCart($command->getCartId()); - $customer = $this->getCustomer($cart->id_customer); - - $mailVars = [ - '{order_link}' => $this->generateCheckoutUrl($cart), - '{firstname}' => $customer->firstname, - '{lastname}' => $customer->lastname, - ]; - - $cartLanguage = new Language((int) $cart->id_lang); - - $emailWasSent = Mail::send( - (int) $cart->id_lang, - 'backoffice_order', - Context::getContext()->getTranslator()->trans( - 'Process the payment of your order', - [], - 'Emails.Subject', - $cartLanguage->locale - ), - $mailVars, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - $cart->id_shop - ); - - if (!$emailWasSent) { - throw new CartException('Failed to send email to customer.'); - } - } - - /** - * @param CartId $cartId - * - * @return Cart - * - * @throws CartNotFoundException - */ - private function getCart(CartId $cartId) - { - $cart = new Cart($cartId->getValue()); - - if (!Validate::isLoadedObject($cart)) { - throw new CartNotFoundException(sprintf('Cart with id "%d" was not found', $cartId->getValue())); - } - - return $cart; - } - - /** - * @param int $customerId - * - * @return Customer - * - * @throws CartException - */ - private function getCustomer($customerId) - { - $customer = new Customer($customerId); - - if (!Validate::isLoadedObject($customer)) { - throw new CartException(sprintf('Customer with id "%d" was not found', $customerId)); - } - - return $customer; - } - - /** - * @param Cart $cart - * - * @return string - */ - private function generateCheckoutUrl(Cart $cart) - { - return Context::getContext()->link->getPageLink( - 'order', - false, - (int) $cart->id_lang, - [ - 'step' => 3, - 'recover_cart' => $cart->id, - 'token_cart' => md5(_COOKIE_KEY_ . 'recover_cart_' . (int) $cart->id), - ] - ); - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateCartAddressesHandler.php b/src/Adapter/Cart/CommandHandler/UpdateCartAddressesHandler.php deleted file mode 100644 index 683f0acd..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateCartAddressesHandler.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Cart; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartAddressesCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCarrierCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartAddressesHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartCarrierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; - -/** - * @internal - */ -final class UpdateCartAddressesHandler extends AbstractCartHandler implements UpdateCartAddressesHandlerInterface -{ - /** - * @var UpdateCartCarrierHandlerInterface - */ - private $updateCartCarrierHandler; - - /** - * @param UpdateCartCarrierHandlerInterface $updateCartCarrierHandler - */ - public function __construct(UpdateCartCarrierHandlerInterface $updateCartCarrierHandler) - { - $this->updateCartCarrierHandler = $updateCartCarrierHandler; - } - - /** - * @param UpdateCartAddressesCommand $command - */ - public function handle(UpdateCartAddressesCommand $command) - { - $cart = $this->getCart($command->getCartId()); - $this->fillCartWithCommandData($cart, $command); - - if (false === $cart->update()) { - throw new CartException(sprintf('Failed to update addresses for cart with id "%s"', $cart->id)); - } - - $this->updateCartCarrierHandler->handle(new UpdateCartCarrierCommand($cart->id, $cart->id_carrier)); - } - - /** - * Fetches updatable fields from command to cart - * - * @param Cart $cart - * @param UpdateCartAddressesCommand $command - */ - private function fillCartWithCommandData(Cart $cart, UpdateCartAddressesCommand $command): void - { - if ($command->getNewDeliveryAddressId()) { - // updateDeliveryAddressId() will actually allow the address change to be impacted on all - // other data linked to the cart delivery address (and it doesn't modify the invoice address) - $cart->updateDeliveryAddressId((int) $cart->id_address_delivery, $command->getNewDeliveryAddressId()->getValue()); - } - - if ($command->getNewInvoiceAddressId()) { - $cart->id_address_invoice = $command->getNewInvoiceAddressId()->getValue(); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateCartCarrierHandler.php b/src/Adapter/Cart/CommandHandler/UpdateCartCarrierHandler.php deleted file mode 100644 index 07458153..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateCartCarrierHandler.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Carrier; -use Currency; -use Customer; -use Language; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCarrierCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartCarrierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use Shop; -use Validate; - -/** - * @internal - */ -final class UpdateCartCarrierHandler extends AbstractCartHandler implements UpdateCartCarrierHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ContextStateManager $contextStateManager - */ - public function __construct(ContextStateManager $contextStateManager) - { - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateCartCarrierCommand $command) - { - $this->assertActiveCarrier($command->getNewCarrierId()); - - $cart = $this->getCart($command->getCartId()); - $this->contextStateManager - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setLanguage(new Language($cart->id_lang)) - ->setCustomer(new Customer($cart->id_customer)) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - $cart->setDeliveryOption([ - (int) $cart->id_address_delivery => $this->formatLegacyDeliveryOptionFromCarrierId($command->getNewCarrierId()), - ]); - - $cart->update(); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param int $carrierId - * - * @throws CartConstraintException - */ - private function assertActiveCarrier(int $carrierId): void - { - if (0 === $carrierId) { - return; - } - - $carrier = new Carrier($carrierId); - - if (!Validate::isLoadedObject($carrier) || (int) $carrier->id !== $carrierId) { - throw new CartConstraintException(sprintf('Carrier with id "%d" was not found', $carrierId), CartConstraintException::INVALID_CARRIER); - } - if (!$carrier->active) { - throw new CartConstraintException(sprintf('Carrier with id "%d" is not active', $carrierId), CartConstraintException::INVALID_CARRIER); - } - } - - /** - * Delivery option consists of deliveryAddress and carrierId. - * - * Legacy multishipping feature used comma separated carriers in delivery option (e.g. {'1':'6,7'} - * Now that multishipping is gone - delivery option should consist of one carrier and one address. - * - * However the structure of deliveryOptions is still used with comma in legacy, so - * this method provides assurance for deliveryOption structure until major refactoring - * - * @param int $carrierId - * - * @return string - */ - private function formatLegacyDeliveryOptionFromCarrierId(int $carrierId): string - { - return sprintf('%d,', $carrierId); - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateCartCurrencyHandler.php b/src/Adapter/Cart/CommandHandler/UpdateCartCurrencyHandler.php deleted file mode 100644 index 114d4f88..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateCartCurrencyHandler.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Currency; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShopException; - -/** - * @internal - */ -final class UpdateCartCurrencyHandler extends AbstractCartHandler implements UpdateCartCurrencyHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateCartCurrencyCommand $command): void - { - $currency = $this->getCurrencyObject($command->getNewCurrencyId()); - - $this->assertCurrencyIsNotDeleted($currency); - $this->assertCurrencyIsActive($currency); - - $cart = $this->getCart($command->getCartId()); - $cart->id_currency = (int) $currency->id; - - try { - if (false === $cart->update()) { - throw new CartException('Failed to update cart currency.'); - } - } catch (PrestaShopException $e) { - throw new CartException(sprintf('An error occurred while trying to update currency for cart with id "%s"', $cart->id)); - } - } - - /** - * @param CurrencyId $currencyId - * - * @return Currency - * - * @throws CurrencyNotFoundException - */ - private function getCurrencyObject(CurrencyId $currencyId): Currency - { - $currency = new Currency($currencyId->getValue()); - - if ($currencyId->getValue() !== $currency->id) { - throw new CurrencyNotFoundException(sprintf('Currency with id "%s" was not found', $currencyId->getValue())); - } - - return $currency; - } - - /** - * @param Currency $currency - * - * @throws CurrencyException - */ - private function assertCurrencyIsActive(Currency $currency): void - { - if (!$currency->active) { - throw new CurrencyException(sprintf('Currency "%s" cannot be used in cart because it is disabled', $currency->iso_code), CurrencyException::IS_DISABLED); - } - } - - /** - * @param Currency $currency - * - * @throws CurrencyException - */ - private function assertCurrencyIsNotDeleted(Currency $currency): void - { - if ($currency->deleted) { - throw new CurrencyException(sprintf('Currency "%s" cannot be used in cart because it is deleted', $currency->iso_code), CurrencyException::IS_DELETED); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php b/src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php deleted file mode 100644 index ad867186..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateCartDeliverySettingsHandler.php +++ /dev/null @@ -1,250 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Cart; -use CartRule; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartDeliverySettingsCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartDeliverySettingsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\InvalidGiftMessageException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CannotDeleteCartRuleException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleException; -use PrestaShopException; -use Symfony\Component\Translation\TranslatorInterface; -use Validate; - -/** - * @internal - */ -final class UpdateCartDeliverySettingsHandler extends AbstractCartHandler implements UpdateCartDeliverySettingsHandlerInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - */ - public function __construct(TranslatorInterface $translator, ConfigurationInterface $configuration) - { - $this->translator = $translator; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateCartDeliverySettingsCommand $command): void - { - $cart = $this->getCart($command->getCartId()); - - if (($command->getGiftMessage() !== null) && (!Validate::isMessage($command->getGiftMessage()))) { - throw new InvalidGiftMessageException(); - } - - $this->handleFreeShippingOption($cart, $command); - $shouldSaveCartAfterGiftOption = $this->handleGiftOption($cart, $command); - $shouldSaveCartAfterWrappingOption = $this->handleRecycledWrappingOption($cart, $command); - $shouldSaveCartAfterGiftMessageOption = $this->handleGiftMessageOption($cart, $command); - - $shouldSaveCart = ($shouldSaveCartAfterGiftOption - || $shouldSaveCartAfterWrappingOption - || $shouldSaveCartAfterGiftMessageOption); - - if ($shouldSaveCart) { - try { - if (false === $cart->update()) { - throw new CartException('Failed to update cart delivery settings'); - } - } catch (PrestaShopException $e) { - throw new CartException(sprintf('An error occurred while trying to update delivery settings for cart with id "%d"', $cart->id)); - } - } - } - - /** - * Sometimes, the cart rule to enable 'free shipping' exists - * but is not linked to the cart. We look for this cart rule - * to avoid creating duplicates. - * - * @param string $code - * - * @return CartRule|null - * - * @throws PrestaShopException - */ - private function getCartRuleForBackOfficeFreeShipping($code): ?CartRule - { - $cartRuleId = CartRule::getIdByCode($code); - - if (!$cartRuleId) { - return null; - } - - return new CartRule((int) $cartRuleId); - } - - /** - * @param Cart $cart - * @param string $backOfficeOrderCode - * - * @return CartRule - */ - private function createCartRule(Cart $cart, string $backOfficeOrderCode): CartRule - { - $freeShippingCartRule = new CartRule(); - $freeShippingCartRule->code = $backOfficeOrderCode; - $freeShippingCartRule->name = [ - $this->configuration->get('PS_LANG_DEFAULT') => $this->translator->trans( - 'Free Shipping', - [], - 'Admin.Orderscustomers.Feature' - ), - ]; - $freeShippingCartRule->id_customer = (int) $cart->id_customer; - $freeShippingCartRule->free_shipping = true; - $freeShippingCartRule->quantity = 1; - $freeShippingCartRule->quantity_per_user = 1; - $freeShippingCartRule->minimum_amount_currency = (int) $cart->id_currency; - $freeShippingCartRule->reduction_currency = (int) $cart->id_currency; - $freeShippingCartRule->date_from = date('Y-m-d H:i:s'); - $freeShippingCartRule->date_to = date('Y-m-d H:i:s', time() + 24 * 36000); - $freeShippingCartRule->active = 1; - $freeShippingCartRule->add(); - - return $freeShippingCartRule; - } - - /** - * This method works as follows: - * 1. if free shipping should be enabled, enable it - * 2. if free shipping should not be enabled and cart already does not have free shipping, do nothing - * 3.if free shipping should not be enabled and cart has free shipping, disable it - * - * @param Cart $cart - * @param UpdateCartDeliverySettingsCommand $command - * - * @throws CannotDeleteCartRuleException - */ - protected function handleFreeShippingOption(Cart $cart, UpdateCartDeliverySettingsCommand $command): void - { - $backOfficeOrderCode = sprintf('%s%s', CartRule::BO_ORDER_CODE_PREFIX, $cart->id); - - $freeShippingCartRule = $this->getCartRuleForBackOfficeFreeShipping($backOfficeOrderCode); - - $freeShippingShouldBeEnabled = $command->allowFreeShipping(); - - // Step 1 - if ($freeShippingShouldBeEnabled) { - if (null === $freeShippingCartRule) { - // there is not yet a 'free shipping' cart rule available in the system so we create it - $freeShippingCartRule = $this->createCartRule($cart, $backOfficeOrderCode); - } - $cart->addCartRule((int) $freeShippingCartRule->id); - - return; - } - - if (null === $freeShippingCartRule) { - return; - } - - $cart->removeCartRule((int) $freeShippingCartRule->id); - - try { - if (false === $freeShippingCartRule->delete()) { - throw new CannotDeleteCartRuleException(sprintf('Failed deleting cart rule #%s', $freeShippingCartRule->id)); - } - } catch (PrestaShopException $e) { - throw new CartRuleException(sprintf('An error occurred when trying to delete cart rule #%s', $freeShippingCartRule->id)); - } - } - - /** - * @param Cart $cart - * @param UpdateCartDeliverySettingsCommand $command - * - * @return bool should save the cart or not - * - * @throws CartException - * @throws PrestaShopException - */ - private function handleGiftOption(Cart $cart, UpdateCartDeliverySettingsCommand $command): bool - { - if ($command->isAGift() === null) { - return false; - } - - $cart->gift = $command->isAGift(); - - return true; - } - - /** - * @param Cart $cart - * @param UpdateCartDeliverySettingsCommand $command - * - * @return bool should save the cart or not - */ - private function handleRecycledWrappingOption(Cart $cart, UpdateCartDeliverySettingsCommand $command): bool - { - if ($command->useRecycledPackaging() === null) { - return false; - } - - $cart->recyclable = $command->useRecycledPackaging(); - - return true; - } - - /** - * @param Cart $cart - * @param UpdateCartDeliverySettingsCommand $command - * - * @return bool should save the cart or not - */ - private function handleGiftMessageOption(Cart $cart, UpdateCartDeliverySettingsCommand $command): bool - { - if ($command->getGiftMessage() === null) { - return false; - } - - $cart->gift_message = $command->getGiftMessage(); - - return true; - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateCartLanguageHandler.php b/src/Adapter/Cart/CommandHandler/UpdateCartLanguageHandler.php deleted file mode 100644 index 350ee1d6..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateCartLanguageHandler.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Language; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateCartLanguageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShopException; - -/** - * @internal - */ -final class UpdateCartLanguageHandler extends AbstractCartHandler implements UpdateCartLanguageHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateCartLanguageCommand $command): void - { - $language = $this->getLanguageObject($command->getNewLanguageId()); - - $this->assertLanguageIsActive($language); - - $cart = $this->getCart($command->getCartId()); - $cart->id_lang = (int) $language->id; - - try { - if (false === $cart->update()) { - throw new CartException('Failed to update cart language'); - } - } catch (PrestaShopException $e) { - throw new CartException(sprintf('An error occurred while trying to update language for cart with id "%s"', $cart->id)); - } - } - - /** - * @param LanguageId $languageId - * - * @return Language - * - * @throws LanguageException - * @throws LanguageNotFoundException - */ - private function getLanguageObject(LanguageId $languageId): Language - { - try { - $lang = new Language($languageId->getValue()); - } catch (PrestaShopException $e) { - throw new LanguageException($languageId, sprintf('An error occurred when fetching language object with id %s', $languageId->getValue())); - } - - if ($languageId->getValue() !== $lang->id) { - throw new LanguageNotFoundException($languageId, sprintf('Language with id "%s" was not found', $languageId->getValue())); - } - - return $lang; - } - - /** - * @param Language $lang - * - * @throws LanguageException - */ - private function assertLanguageIsActive(Language $lang): void - { - if (!$lang->active) { - throw new LanguageException(sprintf('Language with id "%s" is not active', $lang->id), LanguageException::NOT_ACTIVE); - } - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateProductPriceInCartHandler.php b/src/Adapter/Cart/CommandHandler/UpdateProductPriceInCartHandler.php deleted file mode 100644 index 29debc44..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateProductPriceInCartHandler.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductPriceInCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateProductPriceInCartHandlerInterface; -use SpecificPrice; - -/** - * Updates product price in cart using SpecificPrice. - * - * @internal - */ -final class UpdateProductPriceInCartHandler extends AbstractCartHandler implements UpdateProductPriceInCartHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateProductPriceInCartCommand $command) - { - $cart = $this->getCart($command->getCartId()); - - $this->deleteSpecificPriceIfExists($command); - - $specificPrice = new SpecificPrice(); - $specificPrice->id_cart = (int) $cart->id; - $specificPrice->id_shop = 0; - $specificPrice->id_shop_group = 0; - $specificPrice->id_currency = 0; - $specificPrice->id_country = 0; - $specificPrice->id_group = 0; - $specificPrice->id_customer = (int) $cart->id_customer; - $specificPrice->id_product = (int) $command->getProductId()->getValue(); - $specificPrice->id_product_attribute = (int) $command->getCombinationId(); - $specificPrice->price = $command->getPrice(); - $specificPrice->from_quantity = 1; - $specificPrice->reduction = 0; - $specificPrice->reduction_type = 'amount'; - $specificPrice->from = '0000-00-00 00:00:00'; - $specificPrice->to = '0000-00-00 00:00:00'; - - $specificPrice->add(); - } - - /** - * Deletes specific price for cart & product if it already exists. - * - * @param UpdateProductPriceInCartCommand $command - */ - private function deleteSpecificPriceIfExists(UpdateProductPriceInCartCommand $command) - { - SpecificPrice::deleteByIdCart( - $command->getCartId()->getValue(), - $command->getProductId()->getValue(), - $command->getCombinationId() - ); - } -} diff --git a/src/Adapter/Cart/CommandHandler/UpdateProductQuantityInCartHandler.php b/src/Adapter/Cart/CommandHandler/UpdateProductQuantityInCartHandler.php deleted file mode 100644 index 5ed46322..00000000 --- a/src/Adapter/Cart/CommandHandler/UpdateProductQuantityInCartHandler.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\CommandHandler; - -use Attribute; -use Cart; -use Context; -use Customer; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductQuantityInCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler\UpdateProductQuantityInCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\MinimalQuantityException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductCustomizationNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductOutOfStockException; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; -use Product; -use Shop; - -/** - * @internal - */ -final class UpdateProductQuantityInCartHandler extends AbstractCartHandler implements UpdateProductQuantityInCartHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ContextStateManager $contextStateManager - */ - public function __construct(ContextStateManager $contextStateManager) - { - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateProductQuantityInCartCommand $command) - { - $cart = $this->getCart($command->getCartId()); - $this->contextStateManager - ->setCart($cart) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - $this->updateProductQuantityInCart($cart, $command); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Cart $cart - * @param UpdateProductQuantityInCartCommand $command - * - * @throws CartConstraintException - * @throws CartException - * @throws ProductException - * @throws ProductNotFoundException - * @throws ProductOutOfStockException - */ - private function updateProductQuantityInCart(Cart $cart, UpdateProductQuantityInCartCommand $command): void - { - $previousQty = $this->findPreviousQuantityInCart($cart, $command); - $qtyDiff = abs($command->getNewQuantity() - $previousQty); - - if ($qtyDiff === 0) { - throw new CartConstraintException(sprintf('Cart quantity is already %d', $command->getNewQuantity()), CartConstraintException::UNCHANGED_QUANTITY); - } - - // $cart::updateQty needs customer context - $customer = new Customer($cart->id_customer); - Context::getContext()->customer = $customer; - - $this->assertOrderDoesNotExistForCart($cart); - - $product = $this->getProductObject($command->getProductId()); - $combinationIdValue = $command->getCombinationId() ? $command->getCombinationId()->getValue() : 0; - $customizationId = $command->getCustomizationId(); - - $this->assertProductIsInStock($product, $command); - $this->assertProductCustomization($product, $command); - - if ($previousQty < $command->getNewQuantity()) { - $action = 'up'; - } else { - $action = 'down'; - } - - $updateResult = $cart->updateQty( - $qtyDiff, - $command->getProductId()->getValue(), - $combinationIdValue, - $customizationId ? $customizationId->getValue() : false, - $action - ); - - if (!$updateResult) { - throw new CartException('Failed to update product quantity in cart'); - } - - // It seems that $updateResult can be -1, - // when adding product with less quantity than minimum required. - if ($updateResult < 0) { - $minQuantity = $combinationIdValue ? - Attribute::getAttributeMinimalQty($combinationIdValue) : - $product->minimal_quantity; - - throw new MinimalQuantityException('Minimum quantity of %d must be added to cart.', $minQuantity); - } - } - - /** - * @param Cart $cart - * - * @throws CartException - */ - private function assertOrderDoesNotExistForCart(Cart $cart) - { - if ($cart->orderExists()) { - throw new CartException(sprintf('Order for cart with id "%s" already exists.', $cart->id)); - } - } - - /** - * @param ProductId $productId - * - * @return Product - * - * @throws ProductNotFoundException - */ - private function getProductObject(ProductId $productId) - { - $product = new Product($productId->getValue(), true); - - if ($product->id !== $productId->getValue()) { - throw new ProductNotFoundException(sprintf('Product with id "%s" was not found', $productId->getValue())); - } - - return $product; - } - - /** - * @param Product $product - * @param UpdateProductQuantityInCartCommand $command - * - * @throws ProductOutOfStockException - */ - private function assertProductIsInStock(Product $product, UpdateProductQuantityInCartCommand $command) - { - if (null !== $command->getCombinationId()) { - $isAvailableWhenOutOfStock = Product::isAvailableWhenOutOfStock($product->out_of_stock); - $isEnoughQuantity = Attribute::checkAttributeQty( - $command->getCombinationId()->getValue(), - $command->getNewQuantity() - ); - - if (!$isAvailableWhenOutOfStock && !$isEnoughQuantity) { - throw new ProductOutOfStockException(sprintf('Product with id "%s" is out of stock, thus cannot be added to cart', $product->id)); - } - - return; - } - - if (!$product->checkQty($command->getNewQuantity())) { - throw new ProductOutOfStockException(sprintf('Product with id "%s" is out of stock, thus cannot be added to cart', $product->id)); - } - } - - /** - * If product is customizable and customization is not provided, - * then exception is thrown. - * - * @param Product $product - * @param UpdateProductQuantityInCartCommand $command - * - * @throws ProductCustomizationNotFoundException - */ - private function assertProductCustomization(Product $product, UpdateProductQuantityInCartCommand $command) - { - if (null === $command->getCustomizationId() && !$product->hasAllRequiredCustomizableFields()) { - throw new ProductCustomizationNotFoundException(sprintf( - 'Missing customization for product with id "%s"', - $product->id - )); - } - } - - /** - * @param Cart $cart - * @param UpdateProductQuantityInCartCommand $command - * - * @return int - */ - private function findPreviousQuantityInCart(Cart $cart, UpdateProductQuantityInCartCommand $command): int - { - $isCombination = ($command->getCombinationId() !== null); - $isCustomization = ($command->getCustomizationId() !== null); - - foreach ($cart->getProducts() as $cartProduct) { - $equalProductId = (int) $cartProduct['id_product'] === $command->getProductId()->getValue(); - if ($isCombination) { - if ($equalProductId && (int) $cartProduct['id_product_attribute'] === $command->getCombinationId()->getValue()) { - return (int) $cartProduct['quantity']; - } - } elseif ($isCustomization) { - if ($equalProductId && (int) $cartProduct['id_customization'] === $command->getCustomizationId()->getValue()) { - return (int) $cartProduct['quantity']; - } - } elseif ($equalProductId) { - return (int) $cartProduct['quantity']; - } - } - - return 0; - } -} diff --git a/src/Adapter/Cart/Comparator/CartProductUpdate.php b/src/Adapter/Cart/Comparator/CartProductUpdate.php deleted file mode 100644 index 27610060..00000000 --- a/src/Adapter/Cart/Comparator/CartProductUpdate.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Cart\Comparator; - -use PrestaShop\PrestaShop\Core\Domain\Product\Combination\ValueObject\CombinationId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -class CartProductUpdate -{ - /** - * @var ProductId - */ - private $productId; - - /** - * @var CombinationId|null - */ - private $combinationId; - - /** - * @var int - */ - private $deltaQuantity; - - /** - * @var bool - */ - private $created; - - /** - * @param int $productId - * @param int $combinationId - * @param int $deltaQuantity - * @param bool $created - */ - public function __construct(int $productId, int $combinationId, int $deltaQuantity, bool $created) - { - $this->productId = new ProductId($productId); - $this->combinationId = $combinationId > 0 ? new CombinationId($combinationId) : null; - $this->deltaQuantity = $deltaQuantity; - $this->created = $created; - } - - /** - * @param CartProductUpdate $cartProductUpdate - * - * @return bool - */ - public function productMatches(CartProductUpdate $cartProductUpdate): bool - { - if ($this->getProductId()->getValue() !== $cartProductUpdate->getProductId()->getValue()) { - return false; - } - $combinationIdValue = null !== $this->getCombinationId() ? $this->getCombinationId()->getValue() : 0; - $checkedIdValue = null !== $cartProductUpdate->getCombinationId() ? $cartProductUpdate->getCombinationId()->getValue() : 0; - - return $combinationIdValue === $checkedIdValue; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return CombinationId|null - */ - public function getCombinationId(): ?CombinationId - { - return $this->combinationId; - } - - /** - * @return int - */ - public function getDeltaQuantity(): int - { - return $this->deltaQuantity; - } - - /** - * @param int $deltaQuantity - * - * @return $this - */ - public function setDeltaQuantity(int $deltaQuantity): self - { - $this->deltaQuantity = $deltaQuantity; - - return $this; - } - - /** - * @return bool - */ - public function isCreated(): bool - { - return $this->created; - } - - /** - * @return array - */ - public function toArray(): array - { - return [ - 'id_product' => $this->productId->getValue(), - 'id_product_attribute' => null !== $this->combinationId ? $this->combinationId->getValue() : 0, - 'delta_quantity' => $this->deltaQuantity, - 'created' => $this->created, - ]; - } -} diff --git a/src/Adapter/Cart/Comparator/CartProductsComparator.php b/src/Adapter/Cart/Comparator/CartProductsComparator.php deleted file mode 100644 index ed0868e5..00000000 --- a/src/Adapter/Cart/Comparator/CartProductsComparator.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Cart\Comparator; - -use Cart; - -/** - * This class saves a cart's products when it's created, you can then ask for the difference - * that happened on this cart. - */ -class CartProductsComparator -{ - /** - * @var Cart - */ - private $cart; - - /** - * @var array - */ - private $savedProducts; - - /** - * @param Cart $cart - */ - public function __construct(Cart $cart) - { - $this->cart = $cart; - $this->savedProducts = $cart->getProducts(true); - } - - /** - * Returns a list of products that were strictly updated (not created) compared to the state of the cart - * when this object was created, it removes the already known modified products provided as argument. - * - * @param CartProductUpdate[] $knownUpdates - * - * @return CartProductUpdate[] - */ - public function getUpdatedProducts(array $knownUpdates = []): array - { - $newProducts = $this->cart->getProducts(true); - $allUpdateProducts = $this->getAllUpdatedProducts($newProducts); - - return $this->filterKnownUpdates($allUpdateProducts, $knownUpdates); - } - - /** - * Returns a list of products that were strictly created (not updated) compared to the state of the cart - * when this object was created, it removes the already known modified products provided as argument. - * - * @param CartProductUpdate[] $knownUpdates - * - * @return CartProductUpdate[] - */ - public function getAdditionalProducts(array $knownUpdates = []): array - { - $newProducts = $this->cart->getProducts(true); - $allAdditionalProducts = $this->getAllAdditionalProducts($newProducts); - - return $this->filterKnownUpdates($allAdditionalProducts, $knownUpdates); - } - - /** - * Returns a list of products that were modified (created and/or updated) compared to the state of the cart - * when this object was created, it removes the already known modified products provided as argument. - * - * @param CartProductUpdate[] $knownUpdates - * - * @return CartProductUpdate[] - */ - public function getModifiedProducts(array $knownUpdates = []): array - { - $newProducts = $this->cart->getProducts(true); - $modifiedProducts = array_merge($this->getAllUpdatedProducts($newProducts), $this->getAllAdditionalProducts($newProducts)); - - return $this->filterKnownUpdates($modifiedProducts, $knownUpdates); - } - - /** - * Returns the list of updates for products that were not in the cart previously - * - * @param array[] $newProducts - * - * @return array - */ - private function getAllAdditionalProducts(array $newProducts): array - { - $additionalProducts = []; - foreach ($newProducts as $newProduct) { - // Then try and find the product in new products - $oldProduct = $this->getMatchingProduct($this->savedProducts, $newProduct); - if (null === $oldProduct) { - $additionalProducts[] = new CartProductUpdate( - (int) $newProduct['id_product'], - (int) $newProduct['id_product_attribute'], - (int) $newProduct['cart_quantity'], - true - ); - } - } - - return $additionalProducts; - } - - /** - * Returns a list of all products that were updated compared to the creation of this object. - * - * @param array[] $newProducts - * - * @return CartProductUpdate[] - */ - private function getAllUpdatedProducts(array $newProducts): array - { - $updatedProducts = []; - foreach ($this->savedProducts as $oldProduct) { - // Then try and find the product in new products - $newProduct = $this->getMatchingProduct($newProducts, $oldProduct); - if (null === $newProduct) { - $deltaQuantity = -(int) $oldProduct['cart_quantity']; - } else { - $deltaQuantity = (int) $newProduct['cart_quantity'] - (int) $oldProduct['cart_quantity']; - } - - if ($deltaQuantity) { - $updatedProducts[] = new CartProductUpdate( - (int) $oldProduct['id_product'], - (int) $oldProduct['id_product_attribute'], - $deltaQuantity, - false - ); - } - } - - return $updatedProducts; - } - - /** - * @param CartProductUpdate[] $updates - * @param CartProductUpdate[] $knownUpdates - * - * @return CartProductUpdate[] - */ - private function filterKnownUpdates(array $updates, array $knownUpdates): array - { - $filteredUpdates = []; - foreach ($updates as $updateProduct) { - foreach ($knownUpdates as $knownUpdate) { - if ($knownUpdate->productMatches($updateProduct)) { - $updateProduct->setDeltaQuantity( - $updateProduct->getDeltaQuantity() - $knownUpdate->getDeltaQuantity() - ); - - break; - } - } - if (0 !== $updateProduct->getDeltaQuantity()) { - $filteredUpdates[] = $updateProduct; - } - } - - return $filteredUpdates; - } - - /** - * @param array $products - * @param array $searchedProduct - * - * @return array|null - */ - private function getMatchingProduct(array $products, array $searchedProduct): ?array - { - return array_reduce($products, function ($carry, $item) use ($searchedProduct) { - if (null !== $carry) { - return $carry; - } - - $productMatch = $item['id_product'] == $searchedProduct['id_product']; - $combinationMatch = $item['id_product_attribute'] == $searchedProduct['id_product_attribute']; - - return $productMatch && $combinationMatch ? $item : null; - }); - } -} diff --git a/src/Adapter/Cart/QueryHandler/GetCartForOrderCreationHandler.php b/src/Adapter/Cart/QueryHandler/GetCartForOrderCreationHandler.php deleted file mode 100644 index 85421c3e..00000000 --- a/src/Adapter/Cart/QueryHandler/GetCartForOrderCreationHandler.php +++ /dev/null @@ -1,559 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\QueryHandler; - -use Address; -use AddressFormat; -use Carrier; -use Cart; -use CartRule; -use Currency; -use Customer; -use Language; -use Link; -use Message; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\Cart\AbstractCartHandler; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForOrderCreation; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler\GetCartForOrderCreationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartAddress; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartDeliveryOption; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartProduct; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartShipping; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartSummary; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\Customization; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CustomizationFieldData; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; -use PrestaShopException; -use Product; -use Shop; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Handles GetCartForOrderCreation query using legacy object models - */ -final class GetCartForOrderCreationHandler extends AbstractCartHandler implements GetCartForOrderCreationHandlerInterface -{ - /** - * @var LocaleInterface - */ - private $locale; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var Link - */ - private $contextLink; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param LocaleInterface $locale - * @param int $contextLangId - * @param Link $contextLink - * @param ContextStateManager $contextStateManager - * @param TranslatorInterface $translator - */ - public function __construct( - LocaleInterface $locale, - int $contextLangId, - Link $contextLink, - ContextStateManager $contextStateManager, - TranslatorInterface $translator - ) { - $this->locale = $locale; - $this->contextLangId = $contextLangId; - $this->contextLink = $contextLink; - $this->contextStateManager = $contextStateManager; - $this->translator = $translator; - } - - /** - * @param GetCartForOrderCreation $query - * - * @return CartForOrderCreation - * - * @throws CartNotFoundException - * @throws LocalizationException - * @throws PrestaShopException - */ - public function handle(GetCartForOrderCreation $query): CartForOrderCreation - { - $cart = $this->getCart($query->getCartId()); - $currency = new Currency($cart->id_currency); - $language = new Language($cart->id_lang); - - $this->contextStateManager - ->setCart($cart) - ->setCurrency($currency) - ->setLanguage($language) - ->setCustomer(new Customer($cart->id_customer)) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - $addresses = $this->getAddresses($cart); - - if ($query->hideDiscounts()) { - $legacySummary = $cart->getSummaryDetails($cart->id_lang, true); - $products = $this->extractProductsWithGiftSplitFromLegacySummary($cart, $legacySummary, $currency); - } else { - $legacySummary = $cart->getRawSummaryDetails($cart->id_lang, true); - $products = $this->extractProductsFromLegacySummary($cart, $legacySummary, $currency); - } - - $result = new CartForOrderCreation( - $cart->id, - $products, - (int) $currency->id, - (int) $language->id, - $this->extractCartRulesFromLegacySummary($cart, $legacySummary, $currency, $query->hideDiscounts()), - $addresses, - $this->extractSummaryFromLegacySummary($legacySummary, $currency, $cart), - $addresses ? $this->extractShippingFromLegacySummary($cart, $legacySummary, $query->hideDiscounts()) : null - ); - - $this->contextStateManager->restorePreviousContext(); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - - return $result; - } - - /** - * @param Cart $cart - * - * @return CartAddress[] - */ - private function getAddresses(Cart $cart): array - { - $customer = new Customer($cart->id_customer); - $cartAddresses = []; - - foreach ($customer->getAddresses($cart->id_lang) as $data) { - $addressId = (int) $data['id_address']; - $cartAddresses[$addressId] = $this->buildCartAddress($addressId, $cart); - } - - // Add addresses already assigned to cart if absent (in case they are deleted) - if (0 !== (int) $cart->id_address_delivery && !isset($cartAddresses[$cart->id_address_delivery])) { - $cartAddresses[$cart->id_address_delivery] = $this->buildCartAddress( - $cart->id_address_delivery, - $cart - ); - } - if (0 !== (int) $cart->id_address_invoice && !isset($cartAddresses[$cart->id_address_invoice])) { - $cartAddresses[$cart->id_address_invoice] = $this->buildCartAddress( - $cart->id_address_invoice, - $cart - ); - } - - return array_values($cartAddresses); - } - - /** - * @param int $addressId - * @param Cart $cart - * - * @return CartAddress - */ - private function buildCartAddress(int $addressId, Cart $cart): CartAddress - { - $address = new Address($addressId); - - return new CartAddress( - $address->id, - $address->alias, - AddressFormat::generateAddress($address, [], '
    '), - (int) $cart->id_address_delivery === $address->id, - (int) $cart->id_address_invoice === $address->id - ); - } - - /** - * @param Cart $cart - * @param array $legacySummary - * @param Currency $currency - * @param bool $hideDiscounts - * - * @return CartForOrderCreation\CartRule[] - */ - private function extractCartRulesFromLegacySummary(Cart $cart, array $legacySummary, Currency $currency, bool $hideDiscounts = false): array - { - $cartRules = []; - - foreach ($legacySummary['discounts'] as $discount) { - $cartRuleId = (int) $discount['id_cart_rule']; - $cartRules[$cartRuleId] = new CartForOrderCreation\CartRule( - (int) $discount['id_cart_rule'], - $discount['name'], - $discount['description'], - (new Number((string) $discount['value_tax_exc']))->round($currency->precision) - ); - } - - if ($hideDiscounts) { - foreach ($cart->getCartRules(CartRule::FILTER_ACTION_GIFT) as $giftRule) { - $giftRuleId = (int) $giftRule['id_cart_rule']; - $finalValue = new Number((string) $giftRule['value_tax_exc']); - - if (isset($cartRules[$giftRuleId])) { - // it is possible that one cart rule can have a gift product, but also have other conditions, - //so we need to sum their reduction values - /** @var CartForOrderCreation\CartRule $cartRule */ - $cartRule = $cartRules[$giftRuleId]; - $finalValue = $finalValue->plus(new Number($cartRule->getValue())); - } - - $cartRules[$giftRuleId] = new CartForOrderCreation\CartRule( - (int) $giftRule['id_cart_rule'], - $giftRule['name'], - $giftRule['description'], - $finalValue->round($currency->precision) - ); - } - } - - return $cartRules; - } - - /** - * @param Cart $cart - * @param array $legacySummary - * @param Currency $currency - * - * @return CartProduct[] - */ - private function extractProductsWithGiftSplitFromLegacySummary(Cart $cart, array $legacySummary, Currency $currency): array - { - $products = []; - $mergedGifts = $this->mergeGiftProducts($legacySummary['gift_products']); - - foreach ($legacySummary['products'] as $product) { - $productKey = $this->generateUniqueProductKey($product); - - //decrease product quantity for each identical product which is marked as gift - if (isset($mergedGifts[$productKey])) { - $identicalGiftedProduct = $mergedGifts[$productKey]; - $product['quantity'] -= $identicalGiftedProduct['quantity']; - } - - $products[] = $this->buildCartProduct($cart, $currency, $product); - } - - foreach ($mergedGifts as $product) { - $products[] = $this->buildCartProduct($cart, $currency, $product); - } - - return $products; - } - - /** - * @param Cart $cart - * @param array $legacySummary - * @param Currency $currency - * - * @return CartProduct[] - */ - private function extractProductsFromLegacySummary(Cart $cart, array $legacySummary, Currency $currency): array - { - $products = []; - foreach ($legacySummary['products'] as $product) { - $products[] = $this->buildCartProduct($cart, $currency, $product); - } - - return $products; - } - - /** - * @param array $giftProducts - * - * @return array - */ - private function mergeGiftProducts(array $giftProducts): array - { - $mergedGifts = []; - - foreach ($giftProducts as $giftProduct) { - $productKey = $this->generateUniqueProductKey($giftProduct); - - if (!isset($mergedGifts[$productKey])) { - // set first gift and make sure its quantity is 1. - $mergedGifts[$productKey] = $giftProduct; - $mergedGifts[$productKey]['quantity'] = 1; - } else { - //increase existing gift quantity by 1 - ++$mergedGifts[$productKey]['quantity']; - } - } - - return $mergedGifts; - } - - /** - * Forms a unique product key using combination and customization ids. - * - * @param array $product - * - * @return string - */ - private function generateUniqueProductKey(array $product): string - { - return sprintf( - '%s_%s_%s', - (int) $product['id_product'], - (int) $product['id_product_attribute'], - (int) $product['id_customization'] - ); - } - - /** - * @param Cart $cart - * @param array $legacySummary - * @param bool $hideDiscounts - * - * @return CartShipping|null - */ - private function extractShippingFromLegacySummary(Cart $cart, array $legacySummary, bool $hideDiscounts = true): ?CartShipping - { - $deliveryOptionsByAddress = $cart->getDeliveryOptionList(); - $deliveryAddress = (int) $cart->id_address_delivery; - - //Check if there is any delivery options available for cart delivery address - if (!array_key_exists($deliveryAddress, $deliveryOptionsByAddress)) { - return null; - } - - /** @var Carrier $carrier */ - $carrier = $legacySummary['carrier']; - $isFreeShipping = !empty($cart->getCartRules(CartRule::FILTER_ACTION_SHIPPING)); - - return new CartShipping( - $isFreeShipping && $hideDiscounts ? '0' : (string) $legacySummary['total_shipping'], - $isFreeShipping, - $this->fetchCartDeliveryOptions($deliveryOptionsByAddress, $deliveryAddress), - (int) $carrier->id ?: null, - (bool) $cart->gift, - (bool) $cart->recyclable, - $cart->gift_message - ); - } - - /** - * Fetch CartDeliveryOption[] DTO's from legacy array - * - * @param array $deliveryOptionsByAddress - * @param int $deliveryAddressId - * - * @return array - */ - private function fetchCartDeliveryOptions(array $deliveryOptionsByAddress, int $deliveryAddressId) - { - $deliveryOptions = []; - // legacy multishipping feature allowed to split cart shipping to multiple addresses. - // now when the multishipping feature is removed - // the list of carriers should be shared across whole cart for single delivery address - foreach ($deliveryOptionsByAddress[$deliveryAddressId] as $deliveryOption) { - foreach ($deliveryOption['carrier_list'] as $carrier) { - $carrier = $carrier['instance']; - // make sure there is no duplicate carrier - $deliveryOptions[(int) $carrier->id] = new CartDeliveryOption( - (int) $carrier->id, - $carrier->name, - $carrier->delay[$this->contextLangId] - ); - } - } - - //make sure array is not associative - return array_values($deliveryOptions); - } - - /** - * @param array $legacySummary - * @param Currency $currency - * @param Cart $cart - * - * @return CartSummary - * - * @throws LocalizationException - */ - private function extractSummaryFromLegacySummary(array $legacySummary, Currency $currency, Cart $cart): CartSummary - { - $cartId = (int) $cart->id; - - $discount = $this->locale->formatPrice(-1 * $legacySummary['total_discounts_tax_exc'], $currency->iso_code); - - $orderMessage = ''; - if ($message = Message::getMessageByCartId($cartId)) { - $orderMessage = $message['message']; - } - - return new CartSummary( - $this->locale->formatPrice($legacySummary['total_products'], $currency->iso_code), - $discount, - $this->locale->formatPrice($legacySummary['total_shipping'], $currency->iso_code), - $this->locale->formatPrice($legacySummary['total_shipping_tax_exc'], $currency->iso_code), - $this->locale->formatPrice($legacySummary['total_tax'], $currency->iso_code), - $this->locale->formatPrice($legacySummary['total_price'], $currency->iso_code), - $this->locale->formatPrice($legacySummary['total_price_without_tax'], $currency->iso_code), - $orderMessage, - $this->contextLink->getPageLink( - 'order', - false, - (int) $cart->id_lang, - http_build_query([ - 'step' => 3, - 'recover_cart' => $cartId, - 'token_cart' => md5(_COOKIE_KEY_ . 'recover_cart_' . $cartId), - ]) - ) - ); - } - - /** - * Provides product customizations data - * - * @param Cart $cart - * @param array $product the product array from legacy summary - * - * @return Customization|null - */ - private function getProductCustomizedData(Cart $cart, array $product): ?Customization - { - $customizationId = (int) $product['id_customization']; - - if (!$customizationId) { - return null; - } - - $customizations = Product::getAllCustomizedDatas( - $cart->id, - $cart->id_lang, - true, - null, - $customizationId - ); - - if ($customizations) { - $productCustomizedFieldsData = $this->getProductCustomizedFieldsData($customizations, $product); - } - - if (empty($productCustomizedFieldsData)) { - return null; - } - - return new CartForOrderCreation\Customization($customizationId, $productCustomizedFieldsData); - } - - /** - * Provides customized fields data for product - * - * @param array $customizations - * @param array $product - * - * @return array - */ - private function getProductCustomizedFieldsData(array $customizations, array $product) - { - $customizationFieldsData = []; - - if (isset($customizations[$product['id_product']][$product['id_product_attribute']])) { - foreach ($customizations[$product['id_product']][$product['id_product_attribute']] as $customizationByAddress) { - foreach ($customizationByAddress as $customization) { - if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) { - foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) { - $customizationFieldsData[] = new CustomizationFieldData( - Product::CUSTOMIZE_TEXTFIELD, - $text['name'], - $text['value'] - ); - } - } - - if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) { - foreach ($customization['datas'][Product::CUSTOMIZE_FILE] as $file) { - $customizationFieldsData[] = new CustomizationFieldData( - Product::CUSTOMIZE_FILE, - $file['name'], - _THEME_PROD_PIC_DIR_ . $file['value'] . '_small' - ); - } - } - } - } - } - - return $customizationFieldsData; - } - - /** - * @param Cart $cart - * @param Currency $currency - * @param array $product - * @param bool $isGift - * - * @return CartProduct - */ - private function buildCartProduct( - Cart $cart, - Currency $currency, - array $product - ): CartProduct { - return new CartProduct( - (int) $product['id_product'], - isset($product['id_product_attribute']) ? (int) $product['id_product_attribute'] : 0, - $product['name'], - isset($product['attributes_small']) ? $product['attributes_small'] : '', - $product['reference'], - \Tools::ps_round($product['price'], $currency->precision), - $product['quantity'], - \Tools::ps_round($product['total'], $currency->precision), - $this->contextLink->getImageLink($product['link_rewrite'], $product['id_image'], 'small_default'), - $this->getProductCustomizedData($cart, $product), - !empty($product['is_gift']) - ); - } -} diff --git a/src/Adapter/Cart/QueryHandler/GetCartForViewingHandler.php b/src/Adapter/Cart/QueryHandler/GetCartForViewingHandler.php deleted file mode 100644 index 9212f216..00000000 --- a/src/Adapter/Cart/QueryHandler/GetCartForViewingHandler.php +++ /dev/null @@ -1,314 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\QueryHandler; - -use Cart; -use Context; -use Currency; -use Customer; -use DateTime; -use Gender; -use Group; -use Order; -use PrestaShop\PrestaShop\Adapter\ImageManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForViewing; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler\GetCartForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartView; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use Product; -use StockAvailable; -use Validate; - -/** - * @internal - */ -final class GetCartForViewingHandler implements GetCartForViewingHandlerInterface -{ - /** - * @var ImageManager - */ - private $imageManager; - - /** - * @var Locale - */ - private $locale; - - /** - * @param ImageManager $imageManager - * @param Locale $locale - */ - public function __construct(ImageManager $imageManager, Locale $locale) - { - $this->imageManager = $imageManager; - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCartForViewing $query) - { - $cartId = $query->getCartId()->getValue(); - $cart = new Cart($cartId); - - if ($cart->id !== $cartId) { - throw new CartNotFoundException(sprintf('Cart with id "%s" were not found', $cartId)); - } - - $customer = new Customer($cart->id_customer); - $currency = new Currency($cart->id_currency); - - $context = Context::getContext(); - $context->cart = $cart; - $context->currency = $currency; - $context->customer = $customer; - - $products = $cart->getProducts(); - $summary = $cart->getSummaryDetails(); - - $id_order = (int) Order::getIdByCartId($cart->id); - $order = new Order($id_order); - - if (Validate::isLoadedObject($order)) { - $tax_calculation_method = $order->getTaxCalculationMethod(); - $id_shop = (int) $order->id_shop; - } else { - $id_shop = (int) $cart->id_shop; - $tax_calculation_method = Group::getPriceDisplayMethod(Group::getCurrent()->id); - } - - if ($tax_calculation_method == PS_TAX_EXC) { - $total_products = $summary['total_products']; - $total_discounts = $summary['total_discounts_tax_exc']; - $total_wrapping = $summary['total_wrapping_tax_exc']; - $total_price = $summary['total_price_without_tax']; - $total_shipping = $summary['total_shipping_tax_exc']; - } else { - $total_products = $summary['total_products_wt']; - $total_discounts = $summary['total_discounts']; - $total_wrapping = $summary['total_wrapping']; - $total_price = $summary['total_price']; - $total_shipping = $summary['total_shipping']; - } - - foreach ($products as &$product) { - if ($tax_calculation_method == PS_TAX_EXC) { - $product['product_price'] = $product['price']; - $product['product_total'] = $product['total']; - } else { - $product['product_price'] = $product['price_wt']; - $product['product_total'] = $product['total_wt']; - } - - $product['qty_in_stock'] = StockAvailable::getQuantityAvailableByProduct( - $product['id_product'], - isset($product['id_product_attribute']) ? $product['id_product_attribute'] : null, - (int) $id_shop - ); - - $customized_datas = Product::getAllCustomizedDatas( - $context->cart->id, - null, - true, - null, - (int) $product['id_customization'] - ); - $context->cart->setProductCustomizedDatas($product, $customized_datas); - - if ($customized_datas) { - Product::addProductCustomizationPrice($product, $customized_datas); - } - } - - $customerStats = $customer->getStats(); - $gender = new Gender($customer->id_gender, $context->language->id); - - $products = $this->prepareProductForView($products, $currency, $context->language->id); - - $customerInformation = [ - 'id' => $customer->id, - 'first_name' => $customer->firstname, - 'last_name' => $customer->lastname, - 'gender' => $gender->name, - 'email' => $customer->email, - 'registration_date' => (new DateTime($customer->date_add))->format($context->language->date_format_lite), - 'valid_orders_count' => $customerStats['nb_orders'], - 'total_spent_since_registration' => $this->locale->formatPrice( - $customerStats['total_orders'] ?: 0, - $currency->iso_code - ), - ]; - - $orderInformation = [ - 'id' => $order->id, - 'placed_date' => (new DateTime($order->date_add))->format($context->language->date_format_lite), - ]; - - $cartSummary = [ - 'products' => $products, - 'cart_rules' => $this->getCartRulesForView($cart), - 'total_products' => $total_products, - 'total_products_formatted' => $this->locale->formatPrice($total_products, $currency->iso_code), - 'total_discounts' => $total_discounts, - 'total_discounts_formatted' => $this->locale->formatPrice($total_discounts, $currency->iso_code), - 'total_wrapping' => $total_wrapping, - 'total_wrapping_formatted' => $this->locale->formatPrice($total_wrapping, $currency->iso_code), - 'total_shipping' => $total_shipping, - 'total_shipping_formatted' => $this->locale->formatPrice($total_shipping, $currency->iso_code), - 'total' => $total_price, - 'total_formatted' => $this->locale->formatPrice($total_price, $currency->iso_code), - 'is_tax_included' => $tax_calculation_method == PS_TAX_INC, - ]; - - return new CartView($cart->id, $cart->id_currency, $customerInformation, $orderInformation, $cartSummary); - } - - /** - * @param array $products - * @param Currency $currency - * @param int $languageId - * - * @return array - */ - private function prepareProductForView(array $products, Currency $currency, int $languageId) - { - $formattedProducts = []; - - foreach ($products as $product) { - if ($product['id_product_attribute']) { - $image = Product::getCombinationImageById($product['id_product_attribute'], $languageId); - } else { - $image = Product::getCover($product['id_product']); - } - - $formattedProduct = [ - 'id' => $product['id_product'], - 'name' => $product['name'], - 'attributes' => isset($product['attributes']) ? $product['attributes'] : '', - 'reference' => $product['name'], - 'supplier_reference' => $product['supplier_reference'], - 'stock_quantity' => $product['qty_in_stock'], - 'customization_quantity' => $product['customizationQuantityTotal'], - 'cart_quantity' => $product['cart_quantity'], - 'total_price' => $product['product_total'], - 'unit_price' => $product['product_price'], - 'total_price_formatted' => $this->locale->formatPrice($product['product_total'], $currency->iso_code), - 'unit_price_formatted' => $this->locale->formatPrice($product['product_price'], $currency->iso_code), - 'image' => $this->imageManager->getThumbnailForListing($image['id_image']), - ]; - - if (isset($product['customizationQuantityTotal'])) { - $formattedProduct['cart_quantity'] = - $product['cart_quantity'] - $product['customizationQuantityTotal']; - } - - $productCustomization = []; - - if ($product['customizedDatas']) { - $formattedProduct['unit_price'] = $product['price_wt']; - $formattedProduct['unit_price_formatted'] = $this->locale->formatPrice($product['price_wt'], $currency->iso_code); - $formattedProduct['total_price'] = $product['total_customization_wt']; - $formattedProduct['total_price_formatted'] = $this->locale->formatPrice( - $product['total_customization_wt'], - $currency->iso_code - ); - $formattedProduct['quantity'] = $product['customizationQuantityTotal']; - - foreach ($product['customizedDatas'] as $customizationPerAddress) { - foreach ($customizationPerAddress as $customization) { - if (((int) $customization['id_customization'] !== (int) $product['id_customization']) && - count($customizationPerAddress) === 1 - ) { - continue; - } - - $productCustomization = [ - 'quantity' => $customization['quantity'], - 'fields' => [], - ]; - - foreach ($customization['datas'] as $type => $data) { - if (Product::CUSTOMIZE_FILE === $type) { - foreach ($data as $item) { - $productCustomization['fields'][] = [ - 'name' => $item['name'], - 'value' => $item['value'], - 'type' => 'customizable_file', - 'image' => _THEME_PROD_PIC_DIR_ . $item['value'] . '_small', - ]; - } - } elseif (Product::CUSTOMIZE_TEXTFIELD === $type) { - foreach ($data as $item) { - $productCustomization['fields'][] = [ - 'name' => $item['name'], - 'value' => $item['value'], - 'type' => 'customizable_text_field', - ]; - } - } - } - } - } - } - - $formattedProduct['customization'] = $productCustomization; - - $formattedProducts[] = $formattedProduct; - } - - return $formattedProducts; - } - - /** - * @param Cart $cart - * - * @return array - */ - private function getCartRulesForView(Cart $cart) - { - $cartRules = $cart->getCartRules(); - $cartRulesView = []; - - $cartCurrency = new Currency($cart->id_currency); - - foreach ($cartRules as $cartRule) { - $cartRulesView[] = [ - 'id' => $cartRule['id_cart_rule'], - 'name' => $cartRule['name'], - 'is_free_shipping' => !$cartRule['value_real'] && $cartRule['free_shipping'], - 'formatted_value' => $this->locale->formatPrice( - $cartRule['value_real'], - $cartCurrency->iso_code - ), - ]; - } - - return $cartRulesView; - } -} diff --git a/src/Adapter/Cart/QueryHandler/GetLastEmptyCustomerCartHandler.php b/src/Adapter/Cart/QueryHandler/GetLastEmptyCustomerCartHandler.php deleted file mode 100644 index 7dc18dbc..00000000 --- a/src/Adapter/Cart/QueryHandler/GetLastEmptyCustomerCartHandler.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Cart\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetLastEmptyCustomerCart; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler\GetLastEmptyCustomerCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShopException; - -/** - * Gets last empty cart for customer using legacy object model - */ -final class GetLastEmptyCustomerCartHandler implements GetLastEmptyCustomerCartHandlerInterface -{ - /** - * @param GetLastEmptyCustomerCart $query - * - * @return CartId - * - * @throws CartException - * @throws CartNotFoundException - * @throws CustomerNotFoundException - * @throws CartConstraintException - */ - public function handle(GetLastEmptyCustomerCart $query): CartId - { - $customerId = $query->getCustomerId()->getValue(); - - try { - $customer = new Customer($customerId); - - if ($customer->id !== $customerId) { - throw new CustomerNotFoundException($query->getCustomerId(), sprintf('Customer with id "%s" was not found.', $customerId)); - } - - $cartId = $customer->getLastEmptyCart(false); - - if (false === $cartId) { - throw new CartNotFoundException(sprintf('Empty cart not found for customer with id "%s"', $customerId)); - } - } catch (PrestaShopException $e) { - throw new CartException(sprintf('An error occurred while trying to find empty cart for customer with id "%s"', $customerId)); - } - - return new CartId($cartId); - } -} diff --git a/src/Adapter/CartRule/CommandHandler/AddCartRuleHandler.php b/src/Adapter/CartRule/CommandHandler/AddCartRuleHandler.php deleted file mode 100644 index b97711d4..00000000 --- a/src/Adapter/CartRule/CommandHandler/AddCartRuleHandler.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CartRule\CommandHandler; - -use CartRule; -use PrestaShop\PrestaShop\Adapter\CartRule\LegacyDiscountApplicationType; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Command\AddCartRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CartRule\CommandHandler\AddCartRuleHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction\CartRuleActionInterface; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleId; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\DiscountApplicationType; -use PrestaShopException; - -/** - * Handles adding new cart rule using legacy logic. - */ -final class AddCartRuleHandler implements AddCartRuleHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddCartRuleCommand $command): CartRuleId - { - try { - $cartRule = $this->buildCartRuleFromCommandData($command); - - if (false === $cartRule->validateFields(false) || false === $cartRule->validateFieldsLang(false)) { - throw new CartRuleConstraintException('Cart rule contains invalid field values'); - } - if (false === $cartRule->add()) { - throw new CartRuleException('Failed to add new cart rule'); - } - } catch (PrestaShopException $e) { - throw new CartRuleException('An error occurred when trying to add new cart rule'); - } - - return new CartRuleId((int) $cartRule->id); - } - - /** - * @param AddCartRuleCommand $command - * - * @return CartRule - * - * @throws PrestaShopException - */ - private function buildCartRuleFromCommandData(AddCartRuleCommand $command): CartRule - { - $cartRule = new CartRule(); - - $cartRule->name = $command->getLocalizedNames(); - $cartRule->description = $command->getDescription(); - $cartRule->code = $command->getCode(); - $cartRule->highlight = $command->isHighlightInCart(); - $cartRule->partial_use = $command->isAllowPartialUse(); - $cartRule->priority = $command->getPriority(); - $cartRule->active = $command->isActive(); - - $this->fillCartRuleConditionsFromCommandData($cartRule, $command); - $this->fillCartRuleActionsFromCommandData($cartRule, $command); - - return $cartRule; - } - - /** - * Fills cart rule with conditions data from command. - * - * @param CartRule $cartRule - * @param AddCartRuleCommand $command - */ - private function fillCartRuleConditionsFromCommandData(CartRule $cartRule, AddCartRuleCommand $command): void - { - $cartRule->id_customer = null !== $command->getCustomerId() ? $command->getCustomerId()->getValue() : null; - - $cartRule->date_from = $command->getValidFrom()->format('Y-m-d H:i:s'); - $cartRule->date_to = $command->getValidTo()->format('Y-m-d H:i:s'); - - $minimumAmount = $command->getMinimumAmountCondition(); - $cartRule->minimum_amount = (string) $minimumAmount->getMoneyAmount()->getAmount(); - $cartRule->minimum_amount_currency = $minimumAmount->getMoneyAmount()->getCurrencyId()->getValue(); - $cartRule->minimum_amount_shipping = !$minimumAmount->isShippingExcluded(); - $cartRule->minimum_amount_tax = !$minimumAmount->isTaxExcluded(); - - $cartRule->quantity = $command->getTotalQuantity(); - $cartRule->quantity_per_user = $command->getQuantityPerUser(); - - $cartRule->country_restriction = $command->hasCountryRestriction(); - $cartRule->carrier_restriction = $command->hasCarrierRestriction(); - $cartRule->group_restriction = $command->hasGroupRestriction(); - $cartRule->cart_rule_restriction = $command->hasCartRuleRestriction(); - $cartRule->product_restriction = $command->hasProductRestriction(); - $cartRule->shop_restriction = $command->hasShopRestriction(); - } - - /** - * Fills cart rule with actions data from command. - * - * @param CartRule $cartRule - * @param AddCartRuleCommand $command - */ - private function fillCartRuleActionsFromCommandData(CartRule $cartRule, AddCartRuleCommand $command): void - { - $cartRuleAction = $command->getCartRuleAction(); - $amountDiscount = $cartRuleAction->getAmountDiscount(); - $percentageDiscount = $cartRuleAction->getPercentageDiscount(); - $giftProduct = $cartRuleAction->getGiftProduct(); - $cartRule->free_shipping = $cartRuleAction->isFreeShipping(); - - $cartRule->gift_product = null !== $giftProduct ? $giftProduct->getProductId()->getValue() : null; - $cartRule->gift_product_attribute = null !== $giftProduct ? $giftProduct->getProductAttributeId() : null; - $cartRule->reduction_amount = null !== $amountDiscount ? - (string) $amountDiscount->getMoneyAmount()->getAmount() : - null; - $cartRule->reduction_currency = null !== $amountDiscount ? - $amountDiscount->getMoneyAmount()->getCurrencyId()->getValue() : - null; - - // Legacy reduction_tax property is true when it's tax included, false when tax excluded. - $cartRule->reduction_tax = null !== $amountDiscount ? !$amountDiscount->isTaxExcluded() : null; - - $cartRule->reduction_percent = null !== $percentageDiscount ? $percentageDiscount->getPercentage() : null; - $cartRule->reduction_exclude_special = null !== $percentageDiscount ? - !$percentageDiscount->appliesToDiscountedProducts() : - null; - - $discountApplicationType = $command->getDiscountApplicationType(); - - if (null !== $discountApplicationType) { - $this->fillDiscountApplicationType( - $cartRule, - $command, - $cartRuleAction, - $discountApplicationType - ); - } - } - - /** - * @param CartRule $cartRule - * @param AddCartRuleCommand $command - * @param CartRuleActionInterface $cartRuleAction - * @param DiscountApplicationType $discountApplicationType - * - * @throws CartRuleConstraintException - */ - private function fillDiscountApplicationType( - CartRule $cartRule, - AddCartRuleCommand $command, - CartRuleActionInterface $cartRuleAction, - DiscountApplicationType $discountApplicationType - ): void { - $hasAmountDiscount = null !== $cartRuleAction->getAmountDiscount(); - $hasPercentageDiscount = null !== $cartRuleAction->getPercentageDiscount(); - - switch ($discountApplicationType->getValue()) { - case DiscountApplicationType::SELECTED_PRODUCTS: - if (!$hasPercentageDiscount) { - throw new CartRuleConstraintException('Cart rule, which is applied to selected products, must have percent discount type.', CartRuleConstraintException::INCOMPATIBLE_CART_RULE_ACTIONS); - } - - $cartRule->reduction_product = LegacyDiscountApplicationType::SELECTED_PRODUCTS; - - break; - case DiscountApplicationType::CHEAPEST_PRODUCT: - if (!$hasPercentageDiscount) { - throw new CartRuleConstraintException('Cart rule, which is applied to cheapest product, must have percent discount type.', CartRuleConstraintException::INCOMPATIBLE_CART_RULE_ACTIONS); - } - - $cartRule->reduction_product = LegacyDiscountApplicationType::CHEAPEST_PRODUCT; - - break; - case DiscountApplicationType::SPECIFIC_PRODUCT: - if (!$hasPercentageDiscount && !$hasAmountDiscount) { - throw new CartRuleConstraintException('Cart rule, which is applied to a specific product, ' . 'must have percentage or amount application type.', CartRuleConstraintException::INCOMPATIBLE_CART_RULE_ACTIONS); - } - - if (null === $command->getDiscountProductId()) { - throw new CartRuleConstraintException('Cart rule, which is applied to a specific product, must have a product specified.', CartRuleConstraintException::MISSING_DISCOUNT_APPLICATION_PRODUCT); - } - - $cartRule->reduction_product = $command->getDiscountProductId()->getValue(); - - break; - case DiscountApplicationType::ORDER_WITHOUT_SHIPPING: - if (!$hasAmountDiscount && !$hasPercentageDiscount) { - throw new CartRuleConstraintException('Cart rule, which is applied to whole order without shipping, ' . 'must have percentage or amount application type.', CartRuleConstraintException::INCOMPATIBLE_CART_RULE_ACTIONS); - } - - $cartRule->reduction_product = LegacyDiscountApplicationType::ORDER_WITHOUT_SHIPPING; - - break; - } - } -} diff --git a/src/Adapter/CartRule/LegacyDiscountApplicationType.php b/src/Adapter/CartRule/LegacyDiscountApplicationType.php deleted file mode 100644 index 31fad0ea..00000000 --- a/src/Adapter/CartRule/LegacyDiscountApplicationType.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CartRule; - -/** - * Legacy discount application types, used in cart rules, are defined in this class. - */ -final class LegacyDiscountApplicationType -{ - /** - * Discount is applied for selected products - */ - public const SELECTED_PRODUCTS = -2; - - /** - * Discount is applied to cheapest product - */ - public const CHEAPEST_PRODUCT = -1; - - /** - * Discount is applied to order without shipping - */ - public const ORDER_WITHOUT_SHIPPING = 0; - - /** - * Class used only for constants. - */ - private function __construct() - { - } -} diff --git a/src/Adapter/CartRule/QueryHandler/SearchCartRulesHandler.php b/src/Adapter/CartRule/QueryHandler/SearchCartRulesHandler.php deleted file mode 100644 index ce05ddcf..00000000 --- a/src/Adapter/CartRule/QueryHandler/SearchCartRulesHandler.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CartRule\QueryHandler; - -use CartRule; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Query\SearchCartRules; -use PrestaShop\PrestaShop\Core\Domain\CartRule\QueryHandler\SearchCartRulesHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CartRule\QueryResult\FoundCartRule; - -/** - * Searches for cart rules by search phrase using legacy object model - */ -final class SearchCartRulesHandler implements SearchCartRulesHandlerInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @param int $contextLangId - */ - public function __construct(int $contextLangId) - { - $this->contextLangId = $contextLangId; - } - - /** - * @param SearchCartRules $query - * - * @return FoundCartRule[] - */ - public function handle(SearchCartRules $query): array - { - $searchPhrase = $query->getSearchPhrase(); - $foundCartRules = []; - $cartRules = CartRule::getCartsRuleByCode($searchPhrase, $this->contextLangId, true); - - foreach ($cartRules as $cartRule) { - $foundCartRules[] = new FoundCartRule( - (int) $cartRule['id_cart_rule'], - $cartRule['name'], - $cartRule['code'] - ); - } - - return $foundCartRules; - } -} diff --git a/src/Adapter/CatalogPriceRule/AbstractCatalogPriceRuleHandler.php b/src/Adapter/CatalogPriceRule/AbstractCatalogPriceRuleHandler.php deleted file mode 100644 index 00df9497..00000000 --- a/src/Adapter/CatalogPriceRule/AbstractCatalogPriceRuleHandler.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule; - -use DateTime; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; -use PrestaShopException; -use SpecificPriceRule; - -/** - * Provides reusable methods for CatalogPriceRule handlers - */ -abstract class AbstractCatalogPriceRuleHandler -{ - /** - * Gets legacy SpecificPriceRule - * - * @param CatalogPriceRuleId $catalogPriceRuleId - * - * @return SpecificPriceRule - */ - protected function getSpecificPriceRule(CatalogPriceRuleId $catalogPriceRuleId): SpecificPriceRule - { - try { - $specificPriceRule = new SpecificPriceRule($catalogPriceRuleId->getValue()); - } catch (PrestaShopException $e) { - throw new CatalogPriceRuleException('Failed to create new SpecificPriceRule object', 0, $e); - } - - if ($specificPriceRule->id !== $catalogPriceRuleId->getValue()) { - throw new CatalogPriceRuleNotFoundException(sprintf('SpecificPriceRule with id "%s" was not found.', $catalogPriceRuleId->getValue())); - } - - return $specificPriceRule; - } - - /** - * Deletes legacy SpecificPriceRule - * - * @param SpecificPriceRule $specificPriceRule - * - * @return bool - * - * @throws CatalogPriceRuleException - */ - protected function deleteSpecificPriceRule(SpecificPriceRule $specificPriceRule) - { - try { - return $specificPriceRule->delete(); - } catch (PrestaShopException $e) { - throw new CatalogPriceRuleException(sprintf('An error occurred when deleting SpecificPriceRule object with id "%s".', $specificPriceRule->id)); - } - } - - /** - * @param DateTime $from - * @param DateTime $to - * - * @throws CatalogPriceRuleConstraintException - */ - protected function assertDateRangeIsNotInverse(DateTime $from, DateTime $to) - { - if ($from->diff($to)->invert) { - throw new CatalogPriceRuleConstraintException('The date time for catalog price rule cannot be inverse', CatalogPriceRuleConstraintException::INVALID_DATE_RANGE); - } - } -} diff --git a/src/Adapter/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandler.php b/src/Adapter/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandler.php deleted file mode 100644 index b2ae3f4d..00000000 --- a/src/Adapter/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandler.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\CatalogPriceRule\AbstractCatalogPriceRuleHandler; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\AddCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler\AddCatalogPriceRuleHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; -use PrestaShopException; -use SpecificPriceRule; - -/** - * Handles adding new catalog price rule using legacy object model - */ -final class AddCatalogPriceRuleHandler extends AbstractCatalogPriceRuleHandler implements AddCatalogPriceRuleHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddCatalogPriceRuleCommand $command): CatalogPriceRuleId - { - try { - $specificPriceRule = $this->fetchSpecificPriceRuleFromCommand($command); - - if (false === $specificPriceRule->validateFields(false)) { - throw new CatalogPriceRuleException('Specific price rule contains invalid field values'); - } - - if (false === $specificPriceRule->add()) { - throw new CatalogPriceRuleException(sprintf('Failed to create specific price rule')); - } - $specificPriceRule->deleteConditions(); - $specificPriceRule->apply(); - } catch (PrestaShopException $e) { - throw new CatalogPriceRuleException('An unexpected error occurred while creating specific price rule', 0, $e); - } - - return new CatalogPriceRuleId((int) $specificPriceRule->id); - } - - /** - * @param AddCatalogPriceRuleCommand $command - * - * @return SpecificPriceRule - * - * @throws PrestaShopException - */ - private function fetchSpecificPriceRuleFromCommand(AddCatalogPriceRuleCommand $command): SpecificPriceRule - { - $specificPriceRule = new SpecificPriceRule(); - $specificPriceRule->name = $command->getName(); - $specificPriceRule->id_shop = $command->getShopId(); - $specificPriceRule->id_currency = $command->getCurrencyId(); - $specificPriceRule->id_country = $command->getCountryId(); - $specificPriceRule->id_group = $command->getGroupId(); - $specificPriceRule->from_quantity = $command->getFromQuantity(); - $specificPriceRule->price = $command->getPrice(); - $specificPriceRule->reduction_type = $command->getReduction()->getType(); - $specificPriceRule->reduction = (string) $command->getReduction()->getValue(); - $specificPriceRule->reduction_tax = $command->isTaxIncluded(); - - $from = $command->getDateTimeFrom(); - $to = $command->getDateTimeTo(); - - if ($from && $to) { - $this->assertDateRangeIsNotInverse($from, $to); - } - - if ($from) { - $specificPriceRule->from = $from->format('Y-m-d H:i:s'); - } - - if ($to) { - $specificPriceRule->to = $to->format('Y-m-d H:i:s'); - } - - return $specificPriceRule; - } -} diff --git a/src/Adapter/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandler.php b/src/Adapter/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandler.php deleted file mode 100644 index 7f5efe19..00000000 --- a/src/Adapter/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\CatalogPriceRule\AbstractCatalogPriceRuleHandler; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\BulkDeleteCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler\BulkDeleteCatalogPriceRuleHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CannotDeleteCatalogPriceRuleException; - -/** - * Deletes catalog prices rules in bulk action using legacy object model - */ -final class BulkDeleteCatalogPriceRuleHandler extends AbstractCatalogPriceRuleHandler implements BulkDeleteCatalogPriceRuleHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteCatalogPriceRuleCommand $command) - { - foreach ($catalogPriceRuleId = $command->getCatalogPriceRuleIds() as $catalogPriceRuleId) { - $specificPriceRule = $this->getSpecificPriceRule($catalogPriceRuleId); - - if (null === $this->deleteSpecificPriceRule($specificPriceRule)) { - throw new CannotDeleteCatalogPriceRuleException(sprintf('Cannot delete SpecificPriceRule object with id "%s".', $catalogPriceRuleId->getValue()), CannotDeleteCatalogPriceRuleException::FAILED_BULK_DELETE); - } - } - } -} diff --git a/src/Adapter/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandler.php b/src/Adapter/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandler.php deleted file mode 100644 index 4b606d2f..00000000 --- a/src/Adapter/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\CatalogPriceRule\AbstractCatalogPriceRuleHandler; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\DeleteCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler\DeleteCatalogPriceRuleHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CannotDeleteCatalogPriceRuleException; - -/** - * Handles deletion of catalog price rule using legacy object model - */ -final class DeleteCatalogPriceRuleHandler extends AbstractCatalogPriceRuleHandler implements DeleteCatalogPriceRuleHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteCatalogPriceRuleCommand $command) - { - $catalogPriceRuleId = $command->getCatalogPriceRuleId(); - $specificPriceRule = $this->getSpecificPriceRule($catalogPriceRuleId); - - if (null === $this->deleteSpecificPriceRule($specificPriceRule)) { - throw new CannotDeleteCatalogPriceRuleException(sprintf('Cannot delete SpecificPriceRule object with id "%s".', $catalogPriceRuleId->getValue()), CannotDeleteCatalogPriceRuleException::FAILED_DELETE); - } - } -} diff --git a/src/Adapter/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandler.php b/src/Adapter/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandler.php deleted file mode 100644 index 9ae44207..00000000 --- a/src/Adapter/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandler.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler; - -use DateTime; -use PrestaShop\PrestaShop\Adapter\CatalogPriceRule\AbstractCatalogPriceRuleHandler; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\EditCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler\EditCatalogPriceRuleHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CannotUpdateCatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Util\DateTime\DateTime as UtilsDateTime; -use PrestaShopException; -use SpecificPriceRule; - -/** - * Handles command which edits catalog price rule handler using legacy object model - */ -final class EditCatalogPriceRuleHandler extends AbstractCatalogPriceRuleHandler implements EditCatalogPriceRuleHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditCatalogPriceRuleCommand $command) - { - try { - $specificPriceRule = $this->fetchSpecificPriceRuleFromCommand($command); - - if (false === $specificPriceRule->validateFields(false)) { - throw new CatalogPriceRuleException('Specific price rule contains invalid field values'); - } - - if (false === $specificPriceRule->update()) { - throw new CannotUpdateCatalogPriceRuleException(sprintf('Failed to update specific price rule with id %s', $specificPriceRule->id)); - } - $specificPriceRule->deleteConditions(); - $specificPriceRule->apply(); - } catch (PrestaShopException $e) { - throw new CatalogPriceRuleException(sprintf('An unexpected error occurred when editing specific price rule with id %s', $command->getCatalogPriceRuleId()->getValue()), 0, $e); - } - } - - /** - * Creates SpecificPriceRule object from given command - * - * @param EditCatalogPriceRuleCommand $command - * - * @return SpecificPriceRule - * - * @throws PrestaShopException - */ - private function fetchSpecificPriceRuleFromCommand(EditCatalogPriceRuleCommand $command): SpecificPriceRule - { - $specificPriceRule = new SpecificPriceRule($command->getCatalogPriceRuleId()->getValue()); - $this->fetchDateRange($command, $specificPriceRule); - - if (null !== $command->getName()) { - $specificPriceRule->name = $command->getName(); - } - if (null !== $command->getShopId()) { - $specificPriceRule->id_shop = $command->getShopId(); - } - if (null !== $command->getCurrencyId()) { - $specificPriceRule->id_currency = $command->getCurrencyId(); - } - if (null !== $command->getCountryId()) { - $specificPriceRule->id_country = $command->getCountryId(); - } - if (null !== $command->getGroupId()) { - $specificPriceRule->id_group = $command->getGroupId(); - } - if (null !== $command->getFromQuantity()) { - $specificPriceRule->from_quantity = $command->getFromQuantity(); - } - if (null !== $command->getPrice()) { - $specificPriceRule->price = $command->getPrice(); - } - - if (null !== $command->isTaxIncluded()) { - $specificPriceRule->reduction_tax = $command->isTaxIncluded(); - } - if (null !== $command->getReduction()) { - $specificPriceRule->reduction_type = $command->getReduction()->getType(); - $specificPriceRule->reduction = $command->getReduction()->getValue(); - } - - return $specificPriceRule; - } - - /** - * Fetches date range from command to object model also asserting that the range is not inverse - * - * @param EditCatalogPriceRuleCommand $command - * @param SpecificPriceRule $specificPriceRule - * - * @throws CatalogPriceRuleConstraintException - */ - private function fetchDateRange(EditCatalogPriceRuleCommand $command, SpecificPriceRule $specificPriceRule) - { - $commandDateFrom = $command->getDateTimeFrom(); - $commandDateTo = $command->getDateTimeTo(); - - $modelDateFrom = $specificPriceRule->from; - $modelDateTo = $specificPriceRule->to; - - //if `date from` value is being updated - if (null !== $commandDateFrom) { - //and if `date to` is set in database - if (UtilsDateTime::NULL_VALUE !== $modelDateTo) { - //asserts that range between these values is not inverse - $this->assertDateRangeIsNotInverse($commandDateFrom, new DateTime($modelDateTo)); - } - - $specificPriceRule->from = $commandDateFrom->format('Y-m-d H:i:s'); - } - - //if `date to` value is being updated - if (null !== $commandDateTo) { - //and if `date from` is set in database - if (UtilsDateTime::NULL_VALUE !== $modelDateFrom) { - //asserts that range between these values is not inverse - $this->assertDateRangeIsNotInverse(new DateTime($modelDateFrom), $commandDateTo); - } - - $specificPriceRule->to = $commandDateTo->format('Y-m-d H:i:s'); - } - } -} diff --git a/src/Adapter/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandler.php b/src/Adapter/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandler.php deleted file mode 100644 index 5b00ca3c..00000000 --- a/src/Adapter/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CatalogPriceRule\QueryHandler; - -use DateTime; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\CatalogPriceRule\AbstractCatalogPriceRuleHandler; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query\GetCatalogPriceRuleForEditing; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryHandler\GetCatalogPriceRuleForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryResult\EditableCatalogPriceRule; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; -use PrestaShop\PrestaShop\Core\Util\DateTime\DateTime as DateTimeUtils; - -/** - * Handles command which gets catalog price rule for editing using legacy object model - */ -final class GetCatalogPriceRuleForEditingHandler extends AbstractCatalogPriceRuleHandler implements GetCatalogPriceRuleForEditingHandlerInterface -{ - /** - * @param GetCatalogPriceRuleForEditing $query - * - * @return EditableCatalogPriceRule - */ - public function handle(GetCatalogPriceRuleForEditing $query): EditableCatalogPriceRule - { - $catalogPriceRuleId = $query->getCatalogPriceRuleId(); - $specificPriceRule = $this->getSpecificPriceRule($catalogPriceRuleId); - - $from = $specificPriceRule->from; - $to = $specificPriceRule->to; - - return new EditableCatalogPriceRule( - new CatalogPriceRuleId((int) $specificPriceRule->id), - $specificPriceRule->name, - (int) $specificPriceRule->id_shop, - (int) $specificPriceRule->id_currency, - (int) $specificPriceRule->id_country, - (int) $specificPriceRule->id_group, - (int) $specificPriceRule->from_quantity, - new Number($specificPriceRule->price), - new Reduction($specificPriceRule->reduction_type, (float) $specificPriceRule->reduction), - (bool) $specificPriceRule->reduction_tax, - $from !== DateTimeUtils::NULL_VALUE ? new DateTime($from) : null, - $to !== DateTimeUtils::NULL_VALUE ? new DateTime($to) : null - ); - } -} diff --git a/src/Adapter/Category/AdminCategoryControllerWrapper.php b/src/Adapter/Category/AdminCategoryControllerWrapper.php deleted file mode 100644 index 1c1b4079..00000000 --- a/src/Adapter/Category/AdminCategoryControllerWrapper.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category; - -use AdminCategoriesController; - -/** - * Admin controller wrapper for new Architecture, about Category admin controller. - */ -class AdminCategoryControllerWrapper -{ - /** - * Get instance of legacy class AdminCategoriesController. - * - * @return AdminCategoriesController - */ - public function getInstance() - { - return new AdminCategoriesController(); - } -} diff --git a/src/Adapter/Category/CategoryDataProvider.php b/src/Adapter/Category/CategoryDataProvider.php deleted file mode 100644 index a0320c46..00000000 --- a/src/Adapter/Category/CategoryDataProvider.php +++ /dev/null @@ -1,271 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category; - -use Category; -use Context; -use ObjectModel; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Shop; - -/** - * This class will provide data from DB / ORM about Category. - */ -class CategoryDataProvider -{ - /** - * @var int - */ - private $languageId; - - /** @var array the list of existing active categories until root */ - private $categoryList; - - public function __construct(LegacyContext $context) - { - $this->languageId = $context->getLanguage()->id; - $categories = Category::getSimpleCategoriesWithParentInfos($this->languageId); - // index by categories and construct the categoryList - foreach ($categories as $category) { - $this->categoryList[$category['id_category']] = $category; - } - } - - /** - * Get a category. - * - * @param null $idCategory - * @param null $idLang - * @param null $idShop - * - * @throws \LogicException If the category id is not set - * - * @return Category - */ - public function getCategory($idCategory = null, $idLang = null, $idShop = null) - { - if (!$idCategory) { - throw new \LogicException('You need to provide a category id', 5002); - } - - $category = new Category($idCategory, $idLang, $idShop); - - if ($category) { - $category->image = Context::getContext()->link->getCatImageLink($category->name, $category->id); - } - - return $category; - } - - /** - * Get all nested categories. - * - * @param int|null $root_category - * @param bool|int $id_lang - * @param bool $active - * @param int|null $groups - * @param bool $use_shop_restriction - * @param string $sql_filter - * @param string $sql_sort - * @param string $sql_limit - * - * @return array categories - */ - public function getNestedCategories($root_category = null, $id_lang = false, $active = true, $groups = null, $use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '') - { - if (!$id_lang) { - $id_lang = $this->languageId; - } - - return Category::getNestedCategories($root_category, $id_lang, $active, $groups, $use_shop_restriction, $sql_filter, $sql_sort, $sql_limit); - } - - /** - * Return available categories Names - excluding Root category. - * - * @param int|null $root_category - * @param bool|int $id_lang - * @param bool $active return only active categories - * @param $groups - * @param bool $use_shop_restriction - * @param string $sql_filter - * @param string $sql_sort - * @param string $sql_limit - * - * @return array Categories - */ - public function getAllCategoriesName($root_category = null, $id_lang = false, $active = true, $groups = null, $use_shop_restriction = true, $sql_filter = '', $sql_sort = '', $sql_limit = '') - { - if (!$id_lang) { - $id_lang = $this->languageId; - } - - $categories = Category::getAllCategoriesName($root_category, $id_lang, $active, $groups, $use_shop_restriction, $sql_filter, $sql_sort, $sql_limit); - array_shift($categories); - - return $categories; - } - - /** - * Return a simple array id/name of categories for a specified product. - * - * @param \Product $product - * - * @return array Categories - */ - public function getCategoriesByProduct(ObjectModel $product) - { - $productCategories = $product->getCategories(); - - $results = []; - foreach ($productCategories as $productCategory) { - if (isset($this->categoryList[$productCategory])) { - $category = $this->categoryList[$productCategory]; - $results[] = [ - 'id' => $category['id_category'], - 'name' => $category['name'], - 'breadcrumb' => $this->getBreadCrumb($category['id_category']), - ]; - $productCategories[$category['name']] = $category['id_category']; - } - } - - return $results; - } - - /** - * Return a simple array id/name of categories. - * - * @return array Categories - */ - public function getCategoriesWithBreadCrumb() - { - $results = []; - foreach ($this->categoryList as $category) { - $results[] = [ - 'id' => $category['id_category'], - 'name' => $category['name'], - 'breadcrumb' => $this->getBreadCrumb($category['id_category']), - ]; - } - - return $results; - } - - /** - * Construct the breadcrumb using the already constructed list of all categories. - * - * @param int $categoryId - * @param string $delimiter - * - * @return string - */ - public function getBreadCrumb($categoryId, $delimiter = ' > ') - { - $categories = $this->getParentNamesFromList($categoryId); - $categories = array_reverse($categories, true); - - return implode($delimiter, $categories); - } - - /** - * @param int $categoryId - * - * @return array - */ - public function getParentNamesFromList($categoryId) - { - $categories = []; - - while (isset($this->categoryList[$categoryId])) { - $category = $this->categoryList[$categoryId]; - $categories[] = $category['name']; - $categoryId = $category['id_parent']; - } - - return $categories; - } - - /** - * Get Categories formatted like ajax_product_file.php using Category::getNestedCategories. - * - * @param $query - * @param $limit - * @param bool $nameAsBreadCrumb - * - * @return array - */ - public function getAjaxCategories($query, $limit, $nameAsBreadCrumb = false) - { - if (empty($query)) { - $query = ''; - } else { - $query = "AND cl.name LIKE '%" . pSQL($query) . "%'"; - } - - if (is_int($limit)) { - $limit = 'LIMIT ' . $limit; - } else { - $limit = ''; - } - - $searchCategories = Category::getAllCategoriesName( - null, - Context::getContext()->language->id, - true, - null, - true, - $query, - '', - $limit - ); - - $results = []; - foreach ($searchCategories as $category) { - $breadCrumb = $this->getBreadCrumb($category['id_category']); - $results[] = [ - 'id' => $category['id_category'], - 'name' => ($nameAsBreadCrumb ? $breadCrumb : $category['name']), - 'breadcrumb' => $breadCrumb, - 'image' => Context::getContext()->link->getCatImageLink($category['name'], $category['id_category']), - ]; - } - - return $results; - } - - /** - * @param int|null $idLang - * @param Shop|null $shop - * - * @return Category - */ - public function getRootCategory($idLang = null, Shop $shop = null) - { - return Category::getRootCategory($idLang, $shop); - } -} diff --git a/src/Adapter/Category/CategoryProductSearchProvider.php b/src/Adapter/Category/CategoryProductSearchProvider.php deleted file mode 100644 index 9530adf0..00000000 --- a/src/Adapter/Category/CategoryProductSearchProvider.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category; - -use Category; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Responsible of getting products for specific category. - */ -class CategoryProductSearchProvider implements ProductSearchProviderInterface -{ - private $translator; - private $category; - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator, - Category $category - ) { - $this->translator = $translator; - $this->category = $category; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * @param string $type - * - * @return array|false|int - * - * @throws \PrestaShopDatabaseException - */ - private function getProductsOrCount( - ProductSearchContext $context, - ProductSearchQuery $query, - $type = 'products' - ) { - if ($query->getSortOrder()->isRandom()) { - return $this->category->getProducts( - $context->getIdLang(), - 1, - $query->getResultsPerPage(), - null, - null, - $type !== 'products', - true, - true, - $query->getResultsPerPage() - ); - } else { - return $this->category->getProducts( - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay(), - $type !== 'products' - ); - } - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * - * @return ProductSearchResult - * - * @throws \PrestaShopDatabaseException - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - $products = $this->getProductsOrCount($context, $query, 'products'); - $count = $this->getProductsOrCount($context, $query, 'count'); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - $this->sortOrderFactory->getDefaultSortOrders() - ); - } - - return $result; - } -} diff --git a/src/Adapter/Category/CategoryViewDataProvider.php b/src/Adapter/Category/CategoryViewDataProvider.php deleted file mode 100644 index 858396c7..00000000 --- a/src/Adapter/Category/CategoryViewDataProvider.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category; - -use Category; -use PrestaShop\PrestaShop\Adapter\Shop\Context; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use Tools; - -/** - * Class CategoryViewDataProvider provides category view data for categories listing page. - * - * @internal - */ -class CategoryViewDataProvider -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var FeatureInterface - */ - private $multishopFeature; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var Context - */ - private $shopContext; - - /** - * @param ConfigurationInterface $configuration - * @param FeatureInterface $multishopFeature - * @param Context $shopContext - * @param int $contextLangId - */ - public function __construct( - ConfigurationInterface $configuration, - FeatureInterface $multishopFeature, - Context $shopContext, - $contextLangId - ) { - $this->configuration = $configuration; - $this->multishopFeature = $multishopFeature; - $this->contextLangId = $contextLangId; - $this->shopContext = $shopContext; - } - - /** - * Get category view data. - * - * @param int $categoryId - * - * @return array - */ - public function getViewData($categoryId) - { - $category = new Category($categoryId); - - $categoriesWithoutParentCount = count(Category::getCategoriesWithoutParent()); - $categoriesTree = $category->getParentsCategories(); - - if (empty($categoriesTree) - && ($category->id != (int) $this->configuration->get('PS_ROOT_CATEGORY') || Tools::isSubmit('id_category')) - && $this->shopContext->isShopContext() - && !$this->multishopFeature->isUsed() - && $categoriesWithoutParentCount > 1 - ) { - $categoriesTree = [['name' => $category->name[$this->contextLangId]]]; - } - - $categoriesTree = array_reverse($categoriesTree); - - return [ - 'breadcrumb_tree' => $categoriesTree, - 'id' => $category->id, - 'id_parent' => $category->id_parent, - 'is_home_category' => $this->configuration->get('PS_HOME_CATEGORY') == $category->id, - 'name' => $category->name[$this->contextLangId], - ]; - } -} diff --git a/src/Adapter/Category/CommandHandler/AbstractDeleteCategoryHandler.php b/src/Adapter/Category/CommandHandler/AbstractDeleteCategoryHandler.php deleted file mode 100644 index 90169ba1..00000000 --- a/src/Adapter/Category/CommandHandler/AbstractDeleteCategoryHandler.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryDeleteMode; -use Product; -use Shop; - -/** - * Class AbstractDeleteCategoryHandler. - */ -abstract class AbstractDeleteCategoryHandler -{ - /** - * Handle products category after its deletion. - * - * @param int $parentCategoryId - * @param CategoryDeleteMode $mode - */ - protected function handleProductsUpdate($parentCategoryId, CategoryDeleteMode $mode) - { - $productsWithoutCategory = \Db::getInstance()->executeS(' - SELECT p.`id_product` - FROM `' . _DB_PREFIX_ . 'product` p - ' . Shop::addSqlAssociation('product', 'p') . ' - WHERE NOT EXISTS ( - SELECT 1 FROM `' . _DB_PREFIX_ . 'category_product` cp WHERE cp.`id_product` = p.`id_product` - ) - '); - - foreach ($productsWithoutCategory as $productWithoutCategory) { - $product = new Product((int) $productWithoutCategory['id_product']); - - if ($product->id) { - if (0 === $parentCategoryId || $mode->shouldRemoveProducts()) { - $product->delete(); - - continue; - } - - if ($mode->shouldDisableProducts()) { - $product->active = 0; - } - - $product->id_category_default = $parentCategoryId; - $product->addToCategories($parentCategoryId); - $product->save(); - } - } - } -} diff --git a/src/Adapter/Category/CommandHandler/AddCategoryHandler.php b/src/Adapter/Category/CommandHandler/AddCategoryHandler.php deleted file mode 100644 index 6877ba59..00000000 --- a/src/Adapter/Category/CommandHandler/AddCategoryHandler.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\AddCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotAddCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Adds new category using legacy object model. - * - * @internal - */ -final class AddCategoryHandler extends AbstractObjectModelHandler implements AddCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @param AddCategoryCommand $command - * - * @return CategoryId - */ - public function handle(AddCategoryCommand $command) - { - $category = $this->createCategoryFromCommand($command); - - return new CategoryId((int) $category->id); - } - - /** - * @param AddCategoryCommand $command - * - * @return Category - * - * @throws CannotAddCategoryException - * @throws CategoryConstraintException - */ - private function createCategoryFromCommand(AddCategoryCommand $command) - { - $category = new Category(); - $category->id_parent = $command->getParentCategoryId(); - $category->active = $command->isActive(); - - if (null !== $command->getLocalizedNames()) { - $category->name = $command->getLocalizedNames(); - } - - if (null !== $command->getLocalizedLinkRewrites()) { - $category->link_rewrite = $command->getLocalizedLinkRewrites(); - } - - if (null !== $command->getLocalizedDescriptions()) { - $category->description = $command->getLocalizedDescriptions(); - } - - if (null !== $command->getLocalizedMetaTitles()) { - $category->meta_title = $command->getLocalizedMetaTitles(); - } - - if (null !== $command->getLocalizedMetaDescriptions()) { - $category->meta_description = $command->getLocalizedMetaDescriptions(); - } - - if (null !== $command->getLocalizedMetaKeywords()) { - $category->meta_keywords = $command->getLocalizedMetaKeywords(); - } - - if (null !== $command->getAssociatedGroupIds()) { - $category->groupBox = $command->getAssociatedGroupIds(); - } - - if (false === $category->validateFields(false)) { - throw new CannotAddCategoryException('Invalid category data'); - } - - if (false === $category->validateFieldsLang(false)) { - throw new CannotAddCategoryException('Invalid category data'); - } - - if (false === $category->add()) { - throw new CannotAddCategoryException('Failed to add new category.'); - } - - if ($command->getAssociatedShopIds()) { - $this->associateWithShops($category, $command->getAssociatedShopIds()); - } - - return $category; - } -} diff --git a/src/Adapter/Category/CommandHandler/AddRootCategoryHandler.php b/src/Adapter/Category/CommandHandler/AddRootCategoryHandler.php deleted file mode 100644 index 06faa4cb..00000000 --- a/src/Adapter/Category/CommandHandler/AddRootCategoryHandler.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddRootCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\AddRootCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotAddCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class AddRootCategoryHandler. - */ -final class AddRootCategoryHandler extends AbstractObjectModelHandler implements AddRootCategoryHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - * - * @throws CannotAddCategoryException - */ - public function handle(AddRootCategoryCommand $command) - { - $category = $this->createRootCategoryFromCommand($command); - - return new CategoryId((int) $category->id); - } - - /** - * Creates legacy root category - * - * @param AddRootCategoryCommand $command - * - * @return Category - */ - private function createRootCategoryFromCommand(AddRootCategoryCommand $command) - { - $category = new Category(); - $category->is_root_category = true; - $category->level_depth = 1; - $category->id_parent = $this->configuration->get('PS_ROOT_CATEGORY'); - $category->name = $command->getLocalizedNames(); - $category->link_rewrite = $command->getLocalizedLinkRewrites(); - $category->active = $command->isActive(); - - if (null !== $command->getLocalizedDescriptions()) { - $category->description = $command->getLocalizedDescriptions(); - } - - if (null !== $command->getLocalizedMetaTitles()) { - $category->meta_title = $command->getLocalizedMetaTitles(); - } - - if (null !== $command->getLocalizedMetaDescriptions()) { - $category->meta_description = $command->getLocalizedMetaDescriptions(); - } - - if (null !== $command->getLocalizedMetaKeywords()) { - $category->meta_keywords = $command->getLocalizedMetaKeywords(); - } - - if (null !== $command->getAssociatedGroupIds()) { - $category->groupBox = $command->getAssociatedGroupIds(); - } - - if (false === $category->validateFields(false)) { - throw new CategoryException('Invalid data for root category creation'); - } - - if (false === $category->validateFieldsLang(false)) { - throw new CategoryException('Invalid data for root category creation'); - } - - if (false === $category->save()) { - throw new CannotAddCategoryException('Failed to create root category'); - } - - if ($command->getAssociatedShopIds()) { - $this->associateWithShops($category, $command->getAssociatedShopIds()); - } - - return $category; - } -} diff --git a/src/Adapter/Category/CommandHandler/BulkDeleteCategoriesHandler.php b/src/Adapter/Category/CommandHandler/BulkDeleteCategoriesHandler.php deleted file mode 100644 index 6904a926..00000000 --- a/src/Adapter/Category/CommandHandler/BulkDeleteCategoriesHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDeleteCategoriesCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\BulkDeleteCategoriesHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteRootCategoryForShopException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\FailedToDeleteCategoryException; - -/** - * Class BulkDeleteCategoriesHandler. - */ -final class BulkDeleteCategoriesHandler extends AbstractDeleteCategoryHandler implements BulkDeleteCategoriesHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CategoryNotFoundException - * @throws CannotDeleteRootCategoryForShopException - * @throws FailedToDeleteCategoryException - */ - public function handle(BulkDeleteCategoriesCommand $command) - { - foreach ($command->getCategoryIds() as $categoryId) { - $category = new Category($categoryId->getValue()); - - if (!$category->id) { - throw new CategoryNotFoundException($categoryId, sprintf('Category with id %s cannot be found.', var_export($categoryId->getValue(), true))); - } - - if ($category->isRootCategoryForAShop()) { - throw new CannotDeleteRootCategoryForShopException(sprintf('Shop\'s root category with id %s cannot be deleted.', var_export($categoryId->getValue(), true))); - } - - if (!$category->delete()) { - throw new FailedToDeleteCategoryException(sprintf('Failed to delete category with id %s', var_export($categoryId->getValue(), true))); - } - - $this->handleProductsUpdate((int) $category->id_parent, $command->getDeleteMode()); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/BulkUpdateCategoriesStatusHandler.php b/src/Adapter/Category/CommandHandler/BulkUpdateCategoriesStatusHandler.php deleted file mode 100644 index cf6cf198..00000000 --- a/src/Adapter/Category/CommandHandler/BulkUpdateCategoriesStatusHandler.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkUpdateCategoriesStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\BulkUpdateCategoriesStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotUpdateCategoryStatusException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; - -/** - * Class ChangeCategoriesStatusHandler. - * - * @internal - */ -final class BulkUpdateCategoriesStatusHandler implements BulkUpdateCategoriesStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotUpdateCategoryStatusException - * @throws CategoryNotFoundException - */ - public function handle(BulkUpdateCategoriesStatusCommand $command) - { - foreach ($command->getCategoryIds() as $categoryId) { - $entity = new Category($categoryId->getValue()); - $entity->active = $command->getNewStatus(); - - if (!$entity->id) { - throw new CategoryNotFoundException($categoryId, sprintf('Category with id "%s" was not found', $categoryId->getValue())); - } - - if (!$entity->update()) { - throw new CannotUpdateCategoryStatusException(sprintf('Cannot update status for category with id "%s"', $categoryId->getValue())); - } - } - } -} diff --git a/src/Adapter/Category/CommandHandler/DeleteCategoryCoverImageHandler.php b/src/Adapter/Category/CommandHandler/DeleteCategoryCoverImageHandler.php deleted file mode 100644 index db043a13..00000000 --- a/src/Adapter/Category/CommandHandler/DeleteCategoryCoverImageHandler.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use ImageType; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCoverImageCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\DeleteCategoryCoverImageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteImageException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use Symfony\Component\Filesystem\Exception\IOException; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Handles category cover image deleting command. - * - * @internal - */ -final class DeleteCategoryCoverImageHandler implements DeleteCategoryCoverImageHandlerInterface -{ - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param Filesystem $filesystem - * @param ConfigurationInterface $configuration - */ - public function __construct( - Filesystem $filesystem, - ConfigurationInterface $configuration - ) { - $this->filesystem = $filesystem; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(DeleteCategoryCoverImageCommand $command) - { - $categoryId = $command->getCategoryId(); - $category = new Category($categoryId->getValue()); - - $this->assertCategoryExists($categoryId, $category); - - $this->deleteCoverImage($category); - $this->deleteThumbnailImage($category); - $this->deleteTemporaryThumbnailImage($category); - $this->deleteImagesForAllTypes($category); - } - - /** - * @param CategoryId $categoryId - * @param Category $category - * - * @throws CategoryNotFoundException - */ - private function assertCategoryExists(CategoryId $categoryId, Category $category) - { - if ($category->id !== $categoryId->getValue()) { - throw new CategoryNotFoundException($categoryId, sprintf('Category with id "%s" was not found.', $categoryId->getValue())); - } - } - - /** - * @param Category $category - * - * @throws CannotDeleteImageException - */ - private function deleteCoverImage(Category $category) - { - if (false === $category->deleteImage(true)) { - throw new CannotDeleteImageException(sprintf('Cannot delete cover image for category with id "%s"', $category->id), CannotDeleteImageException::COVER_IMAGE); - } - } - - /** - * @param Category $category - * - * @throws CannotDeleteImageException - */ - private function deleteThumbnailImage(Category $category) - { - $thumbnailPath = $this->configuration->get('_PS_CAT_IMG_DIR_') . $category->id . '_thumb.jpg'; - - try { - if ($this->filesystem->exists($thumbnailPath)) { - $this->filesystem->remove($thumbnailPath); - } - } catch (IOException $e) { - throw new CannotDeleteImageException(sprintf('Cannot delete thumbnail image for category with id "%s"', $category->id), CannotDeleteImageException::THUMBNAIL_IMAGE, $e); - } - } - - /** - * @param Category $category - * - * @throws CannotDeleteImageException - */ - private function deleteTemporaryThumbnailImage(Category $category) - { - $temporaryThumbnailPath = $this->configuration->get('_PS_TMP_IMG_DIR_') . 'category_' . $category->id . '-thumb.jpg'; - - try { - if ($this->filesystem->exists($temporaryThumbnailPath)) { - $this->filesystem->remove($temporaryThumbnailPath); - } - } catch (IOException $e) { - throw new CannotDeleteImageException(sprintf('Cannot delete thumbnail image for category with id "%s"', $category->id), CannotDeleteImageException::THUMBNAIL_IMAGE, $e); - } - } - - /** - * @param Category $category - * - * @throws CannotDeleteImageException - */ - private function deleteImagesForAllTypes(Category $category) - { - $imageTypes = ImageType::getImagesTypes('categories'); - $imageTypeFormattedName = ImageType::getFormattedName('small'); - $categoryImageDir = $this->configuration->get('_PS_CAT_IMG_DIR_'); - - try { - foreach ($imageTypes as $imageType) { - $imagePath = $categoryImageDir . $category->id . '-' . $imageType['name'] . '.jpg'; - - if ($imageTypeFormattedName === $imageType['name'] - && $this->filesystem->exists($imagePath) - ) { - $this->filesystem->remove($imagePath); - } - } - } catch (IOException $e) { - throw new CannotDeleteImageException(sprintf('Cannot delete image with type "%s" for category with id "%s"', $imageType['name'], $category->id), CannotDeleteImageException::COVER_IMAGE, $e); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/DeleteCategoryHandler.php b/src/Adapter/Category/CommandHandler/DeleteCategoryHandler.php deleted file mode 100644 index ab84e321..00000000 --- a/src/Adapter/Category/CommandHandler/DeleteCategoryHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\DeleteCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteRootCategoryForShopException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\FailedToDeleteCategoryException; - -/** - * Class DeleteCategoryHandler. - */ -final class DeleteCategoryHandler extends AbstractDeleteCategoryHandler implements DeleteCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CategoryNotFoundException - * @throws CannotDeleteRootCategoryForShopException - * @throws FailedToDeleteCategoryException - */ - public function handle(DeleteCategoryCommand $command) - { - $categoryIdValue = $command->getCategoryId()->getValue(); - $category = new Category($categoryIdValue); - - if (!$category->id) { - throw new CategoryNotFoundException($command->getCategoryId(), sprintf('Category with id %s cannot be found.', var_export($categoryIdValue, true))); - } - - if ($category->isRootCategoryForAShop()) { - throw new CannotDeleteRootCategoryForShopException(sprintf('Shop\'s root category with id %s cannot be deleted.', var_export($categoryIdValue, true))); - } - - if (!$category->delete()) { - throw new FailedToDeleteCategoryException(sprintf('Failed to delete category with id %s', var_export($categoryIdValue, true))); - } - - $this->handleProductsUpdate((int) $category->id_parent, $command->getDeleteMode()); - } -} diff --git a/src/Adapter/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandler.php b/src/Adapter/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandler.php deleted file mode 100644 index e941bccf..00000000 --- a/src/Adapter/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandler.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryMenuThumbnailImageCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\DeleteCategoryMenuThumbnailImageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteImageException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use Symfony\Component\Filesystem\Exception\IOException; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Handles command which deletes given category menu thumbnail. - * - * @internal - */ -final class DeleteCategoryMenuThumbnailImageHandler implements DeleteCategoryMenuThumbnailImageHandlerInterface -{ - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var CacheClearerInterface - */ - private $smartyCacheClearer; - - /** - * @param Filesystem $filesystem - * @param ConfigurationInterface $configuration - * @param CacheClearerInterface $smartyCacheClearer - */ - public function __construct( - Filesystem $filesystem, - ConfigurationInterface $configuration, - CacheClearerInterface $smartyCacheClearer - ) { - $this->filesystem = $filesystem; - $this->configuration = $configuration; - $this->smartyCacheClearer = $smartyCacheClearer; - } - - /** - * {@inheritdoc} - */ - public function handle(DeleteCategoryMenuThumbnailImageCommand $command) - { - $categoryId = $command->getCategoryId(); - $menuThumbnailId = $command->getMenuThumbnailId(); - - $category = new Category($categoryId->getValue()); - - if ($category->id !== $categoryId->getValue()) { - throw new CategoryNotFoundException($categoryId, sprintf('Category with id "%s" was not found', $categoryId)); - } - - $thumbnailPath = sprintf( - '%s%s-%s_thumb.jpg', - $this->configuration->get('_PS_CAT_IMG_DIR_'), - $category->id, - $menuThumbnailId->getValue() - ); - - try { - if ($this->filesystem->exists($thumbnailPath)) { - $this->filesystem->remove($thumbnailPath); - - $this->smartyCacheClearer->clear(); - } - } catch (IOException $e) { - throw new CannotDeleteImageException(sprintf('Cannot delete menu thumbnail with id "%s" for category with id "%s".', $menuThumbnailId->getValue(), $categoryId->getValue()), CannotDeleteImageException::MENU_THUMBNAIL_IMAGE, $e); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/EditCategoryHandler.php b/src/Adapter/Category/CommandHandler/EditCategoryHandler.php deleted file mode 100644 index 0147c837..00000000 --- a/src/Adapter/Category/CommandHandler/EditCategoryHandler.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\EditCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotEditCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; - -/** - * Class EditCategoryHandler. - * - * @internal - */ -final class EditCategoryHandler extends AbstractObjectModelHandler implements EditCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CategoryNotFoundException - */ - public function handle(EditCategoryCommand $command) - { - $category = new Category($command->getCategoryId()->getValue()); - - if (!$category->id) { - throw new CategoryNotFoundException($command->getCategoryId(), sprintf('Category with id "%s" cannot be found.', $command->getCategoryId()->getValue())); - } - - $this->updateCategoryFromCommandData($category, $command); - } - - /** - * Updates legacy object model with data from command - * - * @param Category $category - * @param EditCategoryCommand $command - * - * @throws CannotEditCategoryException - */ - private function updateCategoryFromCommandData(Category $category, EditCategoryCommand $command) - { - if (null !== $command->isActive()) { - $category->active = $command->isActive(); - } - - if (null !== $command->getParentCategoryId()) { - $category->id_parent = $command->getParentCategoryId(); - } - - if (null !== $command->getLocalizedNames()) { - $category->name = $command->getLocalizedNames(); - } - - if (null !== $command->getLocalizedLinkRewrites()) { - $category->link_rewrite = $command->getLocalizedLinkRewrites(); - } - - if (null !== $command->getLocalizedDescriptions()) { - $category->description = $command->getLocalizedDescriptions(); - } - - if (null !== $command->getLocalizedMetaTitles()) { - $category->meta_title = $command->getLocalizedMetaTitles(); - } - - if (null !== $command->getLocalizedMetaDescriptions()) { - $category->meta_description = $command->getLocalizedMetaDescriptions(); - } - - if (null !== $command->getLocalizedMetaKeywords()) { - $category->meta_keywords = $command->getLocalizedMetaKeywords(); - } - - if (null !== $command->getAssociatedGroupIds()) { - $category->groupBox = $command->getAssociatedGroupIds(); - } - - if (false === $category->validateFields(false)) { - throw new CannotEditCategoryException('Invalid data when updating category'); - } - - if (false === $category->validateFieldsLang(false)) { - throw new CannotEditCategoryException('Invalid data when updating category'); - } - - if (false === $category->update()) { - throw new CannotEditCategoryException(sprintf('Failed to edit Category with id "%s".', $category->id)); - } - - if ($command->getAssociatedShopIds()) { - $this->associateWithShops($category, $command->getAssociatedShopIds()); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/EditRootCategoryHandler.php b/src/Adapter/Category/CommandHandler/EditRootCategoryHandler.php deleted file mode 100644 index 619fe93a..00000000 --- a/src/Adapter/Category/CommandHandler/EditRootCategoryHandler.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditRootCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\EditRootCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotEditCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; - -/** - * Class EditRootCategoryHandler. - */ -final class EditRootCategoryHandler extends AbstractObjectModelHandler implements EditRootCategoryHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotEditCategoryException - * @throws CategoryNotFoundException - */ - public function handle(EditRootCategoryCommand $command) - { - $category = new Category($command->getCategoryId()->getValue()); - - if (!$category->id) { - throw new CategoryNotFoundException($command->getCategoryId(), sprintf('Category with id "%s" cannot be found.', $command->getCategoryId()->getValue())); - } - - $this->updateRootCategoryFromCommandData($category, $command); - } - - /** - * @param Category $category - * @param EditRootCategoryCommand $command - */ - private function updateRootCategoryFromCommandData(Category $category, EditRootCategoryCommand $command) - { - if (null !== $command->isActive()) { - $category->active = $command->isActive(); - } - - if (null !== $command->getLocalizedNames()) { - $category->name = $command->getLocalizedNames(); - } - - if (null !== $command->getLocalizedLinkRewrites()) { - $category->link_rewrite = $command->getLocalizedLinkRewrites(); - } - - if (null !== $command->getLocalizedDescriptions()) { - $category->description = $command->getLocalizedDescriptions(); - } - - if (null !== $command->getLocalizedMetaTitles()) { - $category->meta_title = $command->getLocalizedMetaTitles(); - } - - if (null !== $command->getLocalizedMetaDescriptions()) { - $category->meta_description = $command->getLocalizedMetaDescriptions(); - } - - if (null !== $command->getLocalizedMetaKeywords()) { - $category->meta_keywords = $command->getLocalizedMetaKeywords(); - } - - if (null !== $command->getAssociatedGroupIds()) { - $category->groupBox = $command->getAssociatedGroupIds(); - } - - if ($command->getAssociatedShopIds()) { - $this->associateWithShops($category, $command->getAssociatedShopIds()); - } - - if (false === $category->validateFields(false)) { - throw new CategoryException('Invalid data for updating category root'); - } - - if (false === $category->validateFieldsLang(false)) { - throw new CategoryException('Invalid data for updating category root'); - } - - if (false === $category->update()) { - throw new CannotEditCategoryException(sprintf('Failed to edit Category with id "%s".', $category->id)); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/SetCategoryIsEnabledHandler.php b/src/Adapter/Category/CommandHandler/SetCategoryIsEnabledHandler.php deleted file mode 100644 index 729ed04b..00000000 --- a/src/Adapter/Category/CommandHandler/SetCategoryIsEnabledHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\SetCategoryIsEnabledCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\SetCategoryIsEnabledHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotUpdateCategoryStatusException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; - -/** - * @internal - */ -final class SetCategoryIsEnabledHandler implements SetCategoryIsEnabledHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CategoryNotFoundException - * @throws CannotUpdateCategoryStatusException - */ - public function handle(SetCategoryIsEnabledCommand $command) - { - $categoryId = $command->getCategoryId()->getValue(); - $entity = new Category($categoryId); - - if (!$entity->id) { - throw new CategoryNotFoundException($command->getCategoryId(), sprintf('Category with id "%s" was not found', $categoryId)); - } - - if (!$entity->toggleStatus()) { - throw new CannotUpdateCategoryStatusException(sprintf('Cannot update status for category with id "%s"', $categoryId)); - } - } -} diff --git a/src/Adapter/Category/CommandHandler/UpdateCategoryPositionHandler.php b/src/Adapter/Category/CommandHandler/UpdateCategoryPositionHandler.php deleted file mode 100644 index b9088ce3..00000000 --- a/src/Adapter/Category/CommandHandler/UpdateCategoryPositionHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\CommandHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\UpdateCategoryPositionCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler\UpdateCategoryPositionHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; - -/** - * Updates category position using legacy object model - */ -final class UpdateCategoryPositionHandler implements UpdateCategoryPositionHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateCategoryPositionCommand $command) - { - $parentCategoryId = $command->getParentCategoryId()->getValue(); - $categoryId = $command->getCategoryId()->getValue(); - - $position = null; - - foreach ($command->getPositions() as $key => $value) { - list(, $positionParentCategoryId, $positionCategoryId) = explode('_', $value); - - if ((int) $positionParentCategoryId === $parentCategoryId && (int) $positionCategoryId === $categoryId) { - $position = $key; - - break; - } - } - - if (null === $position) { - throw new CategoryException('Category position cannot be updated'); - } - - $category = new Category($categoryId); - - if (!$category->id) { - throw new CategoryNotFoundException($command->getCategoryId(), sprintf('Category with id "%s" was not found', $categoryId)); - } - - if ($category->updatePosition($command->getWay(), $position)) { - /* Position '0' was not found in given positions so try to reorder parent category*/ - if (!$command->isFoundFirst()) { - Category::cleanPositions((int) $category->id_parent); - } - } - } -} diff --git a/src/Adapter/Category/QueryHandler/GetCategoryForEditingHandler.php b/src/Adapter/Category/QueryHandler/GetCategoryForEditingHandler.php deleted file mode 100644 index 4fe152b9..00000000 --- a/src/Adapter/Category/QueryHandler/GetCategoryForEditingHandler.php +++ /dev/null @@ -1,231 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\QueryHandler; - -use Category; -use Db; -use ImageManager; -use ImageType; -use PDO; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryHandler\GetCategoryForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryResult\EditableCategory; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\MenuThumbnailId; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; -use Shop; - -/** - * Class GetCategoryForEditingHandler. - */ -final class GetCategoryForEditingHandler implements GetCategoryForEditingHandlerInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @param ImageTagSourceParserInterface $imageTagSourceParser - */ - public function __construct(ImageTagSourceParserInterface $imageTagSourceParser) - { - $this->imageTagSourceParser = $imageTagSourceParser; - } - - /** - * {@inheritdoc} - * - * @throws CategoryNotFoundException - */ - public function handle(GetCategoryForEditing $query) - { - $category = new Category($query->getCategoryId()->getValue()); - - if (!$category->id || (!$category->isAssociatedToShop() && Shop::getContext() == Shop::CONTEXT_SHOP)) { - throw new CategoryNotFoundException($query->getCategoryId(), sprintf('Category with id "%s" was not found', $query->getCategoryId()->getValue())); - } - - /** - * Select recursivly the subcategories in one SQL request - */ - $subcategories = Db::getInstance()->query( - 'SELECT id_category ' . - 'FROM ( ' . - ' SELECT * FROM `' . _DB_PREFIX_ . 'category`' . - ' ORDER BY id_parent, id_category' . - ') category_sorted, ' . - '(SELECT @pv := ' . (int) $category->id . ') initialisation ' . - 'WHERE FIND_IN_SET(id_parent, @pv) ' . - 'AND LENGTH(@pv := CONCAT(@pv, \',\', id_category))' - ); - - $editableCategory = new EditableCategory( - $query->getCategoryId(), - $category->name, - (bool) $category->active, - $category->description, - (int) $category->id_parent, - $category->meta_title, - $category->meta_description, - $category->meta_keywords, - $category->link_rewrite, - $category->getGroups(), - $category->getAssociatedShops(), - (bool) $category->is_root_category, - $this->getCoverImage($query->getCategoryId()), - $this->getThumbnailImage($query->getCategoryId()), - $this->getMenuThumbnailImages($query->getCategoryId()), - $subcategories->fetchAll(PDO::FETCH_COLUMN) - ); - - return $editableCategory; - } - - /** - * @param CategoryId $categoryId - * - * @return array|null cover image data or null if category does not have cover - */ - private function getCoverImage(CategoryId $categoryId) - { - $imageType = 'jpg'; - $image = _PS_CAT_IMG_DIR_ . $categoryId->getValue() . '.' . $imageType; - - $imageTag = ImageManager::thumbnail( - $image, - 'category' . '_' . $categoryId->getValue() . '.' . $imageType, - 350, - $imageType, - true, - true - ); - - $imageSize = file_exists($image) ? filesize($image) / 1000 : ''; - - if (empty($imageTag) || empty($imageSize)) { - return null; - } - - return [ - 'size' => sprintf('%skB', $imageSize), - 'path' => $this->imageTagSourceParser->parse($imageTag), - ]; - } - - /** - * @param CategoryId $categoryId - * - * @return array - */ - private function getThumbnailImage(CategoryId $categoryId) - { - $image = _PS_CAT_IMG_DIR_ . $categoryId->getValue() . '.jpg'; - $imageTypes = ImageType::getImagesTypes('categories'); - - if (count($imageTypes) > 0) { - $thumb = ''; - $imageTag = ''; - $formattedSmall = ImageType::getFormattedName('small'); - $imageType = new ImageType(); - foreach ($imageTypes as $k => $imageType) { - if ($formattedSmall == $imageType['name']) { - $thumb = _PS_CAT_IMG_DIR_ . $categoryId->getValue() . '-' . $imageType['name'] . '.jpg'; - if (is_file($thumb)) { - $imageTag = ImageManager::thumbnail( - $thumb, - 'category_' . (int) $categoryId->getValue() . '-thumb.jpg', - (int) $imageType['width'], - 'jpg', - true, - true - ); - } - } - } - - if (!is_file($thumb)) { - $thumb = $image; - $imageName = 'category_' . $categoryId->getValue() . '-thumb.jpg'; - - $imageTag = ImageManager::thumbnail($image, $imageName, 125, 'jpg', true, true); - ImageManager::resize( - _PS_TMP_IMG_DIR_ . $imageName, - _PS_TMP_IMG_DIR_ . $imageName, - (int) $imageType['width'], - (int) $imageType['height'] - ); - } - - $thumbSize = file_exists($thumb) ? filesize($thumb) / 1000 : false; - - if (empty($imageTag) || false === $thumbSize) { - return null; - } - - return [ - 'size' => sprintf('%skB', $thumbSize), - 'path' => $this->imageTagSourceParser->parse($imageTag), - ]; - } - - return null; - } - - /** - * @param CategoryId $categoryId - * - * @return array - */ - private function getMenuThumbnailImages(CategoryId $categoryId) - { - $menuThumbnails = []; - - foreach (MenuThumbnailId::ALLOWED_ID_VALUES as $id) { - $thumbnailPath = _PS_CAT_IMG_DIR_ . $categoryId->getValue() . '-' . $id . '_thumb.jpg'; - - if (file_exists($thumbnailPath)) { - $imageTag = ImageManager::thumbnail( - $thumbnailPath, - 'category_' . $categoryId->getValue() . '-' . $id . '_thumb.jpg', - 100, - 'jpg', - true, - true - ); - - $menuThumbnails[$id] = [ - 'path' => $this->imageTagSourceParser->parse($imageTag), - 'id' => $id, - ]; - } - } - - return $menuThumbnails; - } -} diff --git a/src/Adapter/Category/QueryHandler/GetCategoryIsEnabledHandler.php b/src/Adapter/Category/QueryHandler/GetCategoryIsEnabledHandler.php deleted file mode 100644 index c6ae80f8..00000000 --- a/src/Adapter/Category/QueryHandler/GetCategoryIsEnabledHandler.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Category\QueryHandler; - -use Category; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryIsEnabled; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryHandler\GetCategoryIsEnabledHandlerInterface; - -/** - * @internal - */ -final class GetCategoryIsEnabledHandler implements GetCategoryIsEnabledHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetCategoryIsEnabled $query) - { - $categoryId = $query->getCategoryId()->getValue(); - $category = new Category($categoryId); - - if ($category->id !== $categoryId) { - throw new CategoryNotFoundException($query->getCategoryId(), sprintf('Category with id "%s" was not found.', $categoryId)); - } - - return (bool) $category->active; - } -} diff --git a/src/Adapter/ClassLang.php b/src/Adapter/ClassLang.php deleted file mode 100644 index 981551f6..00000000 --- a/src/Adapter/ClassLang.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -/** - * Not used in PrestaShop. - * - * @deprecated since 1.7.5, to be removed in 1.8 - */ -class ClassLang -{ - /** - * @var string - */ - private $locale; - - /** - * ClassLang constructor. - * - * @param $locale - */ - public function __construct($locale) - { - $this->locale = $locale; - } - - /** - * @param $className - * - * @return bool - */ - public function getClassLang($className) - { - if (!class_exists($className)) { - return false; - } - - return new $className($this->locale); - } -} diff --git a/src/Adapter/CombinationDataProvider.php b/src/Adapter/CombinationDataProvider.php deleted file mode 100644 index 8fd129f1..00000000 --- a/src/Adapter/CombinationDataProvider.php +++ /dev/null @@ -1,198 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Combination; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use Product; - -/** - * This class will provide data from DB / ORM about product combination. - */ -class CombinationDataProvider -{ - /** - * @var LegacyContext - */ - private $context; - - /** - * @var ProductDataProvider - */ - private $productAdapter; - - /** - * @var Locale - */ - private $locale; - - /** - * @param Locale $locale - */ - public function __construct(Locale $locale) - { - $this->context = new LegacyContext(); - $this->productAdapter = new ProductDataProvider(); - $this->locale = $locale; - } - - /** - * Get a combination values. - * - * @deprecated since 1.7.3.1 really slow, use getFormCombinations instead. - * - * @param int $combinationId The id_product_attribute - * - * @return array combinations - */ - public function getFormCombination($combinationId) - { - $product = new Product((new Combination($combinationId))->id_product); - - return $this->completeCombination( - $product->getAttributeCombinationsById( - $combinationId, - $this->context->getContext()->language->id - ), - $product - ); - } - - /** - * Retrieve combinations data for a specific language id. - * - * @param array $combinationIds - * @param int $languageId - * - * @return array a list of formatted combinations - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - public function getFormCombinations(array $combinationIds, $languageId) - { - $productId = (new Combination($combinationIds[0]))->id_product; - $product = new Product($productId); - $combinations = []; - - foreach ($combinationIds as $combinationId) { - $combinations[$combinationId] = $this->completeCombination( - $product->getAttributeCombinationsById( - $combinationId, - $languageId - ), - $product - ); - } - - return $combinations; - } - - /** - * @param array $attributesCombinations - * @param Product $product - * - * @return array - */ - public function completeCombination($attributesCombinations, $product) - { - $combination = $attributesCombinations[0]; - - $attribute_price_impact = 0; - if ($combination['price'] > 0) { - $attribute_price_impact = 1; - } elseif ($combination['price'] < 0) { - $attribute_price_impact = -1; - } - - $attribute_weight_impact = 0; - if ($combination['weight'] > 0) { - $attribute_weight_impact = 1; - } elseif ($combination['weight'] < 0) { - $attribute_weight_impact = -1; - } - - $attribute_unity_price_impact = 0; - if ($combination['unit_price_impact'] > 0) { - $attribute_unity_price_impact = 1; - } elseif ($combination['unit_price_impact'] < 0) { - $attribute_unity_price_impact = -1; - } - - $finalPrice = (new Number((string) $product->price)) - ->plus(new Number((string) $combination['price'])) - ->toPrecision(CommonAbstractType::PRESTASHOP_DECIMALS); - - return [ - 'id_product_attribute' => $combination['id_product_attribute'], - 'attribute_reference' => $combination['reference'], - 'attribute_ean13' => $combination['ean13'], - 'attribute_isbn' => $combination['isbn'], - 'attribute_upc' => $combination['upc'], - 'attribute_mpn' => $combination['mpn'], - 'attribute_wholesale_price' => $combination['wholesale_price'], - 'attribute_price_impact' => $attribute_price_impact, - 'attribute_price' => $combination['price'], - 'attribute_price_display' => $this->locale->formatPrice($combination['price'], $this->context->getContext()->currency->iso_code), - 'final_price' => (string) $finalPrice, - 'attribute_priceTI' => '', - 'attribute_ecotax' => $combination['ecotax'], - 'attribute_weight_impact' => $attribute_weight_impact, - 'attribute_weight' => $combination['weight'], - 'attribute_unit_impact' => $attribute_unity_price_impact, - 'attribute_unity' => $combination['unit_price_impact'], - 'attribute_minimal_quantity' => $combination['minimal_quantity'], - 'attribute_low_stock_threshold' => $combination['low_stock_threshold'], - 'attribute_low_stock_alert' => (bool) $combination['low_stock_alert'], - 'available_date_attribute' => $combination['available_date'], - 'attribute_default' => (bool) $combination['default_on'], - 'attribute_location' => $this->productAdapter->getLocation($product->id, $combination['id_product_attribute']), - 'attribute_quantity' => $this->productAdapter->getQuantity($product->id, $combination['id_product_attribute']), - 'name' => $this->getCombinationName($attributesCombinations), - 'id_product' => $product->id, - ]; - } - - /** - * @param array $attributesCombinations - * - * @return string - */ - private function getCombinationName($attributesCombinations) - { - $name = []; - - foreach ($attributesCombinations as $attribute) { - $name[] = $attribute['group_name'] . ' - ' . $attribute['attribute_name']; - } - - return implode(', ', $name); - } -} diff --git a/src/Adapter/Configuration.php b/src/Adapter/Configuration.php deleted file mode 100644 index 0cb51c5a..00000000 --- a/src/Adapter/Configuration.php +++ /dev/null @@ -1,341 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Combination; -use Configuration as ConfigurationLegacy; -use Feature; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Configuration\ShopConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint; -use PrestaShopBundle\Exception\NotImplementedException; -use Shop; -use Symfony\Component\HttpFoundation\ParameterBag; - -/** - * Adapter of Configuration ObjectModel. - */ -class Configuration extends ParameterBag implements ShopConfigurationInterface -{ - /** - * @var Shop - */ - private $shop; - - public function __construct(array $parameters = []) - { - // Do nothing - if (!empty($parameters)) { - throw new \LogicException('No parameter can be handled in constructor. Use method set() instead.'); - } - } - - /** - * @throws NotImplementedException - */ - public function all() - { - throw new NotImplementedException(); - } - - /** - * {@inheritdoc} - */ - public function keys() - { - return array_keys($this->all()); - } - - /** - * {@inheritdoc} - */ - public function replace(array $parameters = []) - { - $this->add($parameters); - } - - /** - * {@inheritdoc} - */ - public function add(array $parameters = []) - { - foreach ($parameters as $key => $value) { - $this->set($key, $value); - } - } - - /** - * Returns constant defined by given $key if exists or check directly into PrestaShop - * \Configuration. - * - * @param string $key - * @param mixed $default The default value if the parameter key does not exist - * @param ShopConstraint|null $shopConstraint - * - * @return mixed - */ - public function get($key, $default = null, ShopConstraint $shopConstraint = null) - { - if (defined($key)) { - return constant($key); - } - - $shopId = $this->getShopId($shopConstraint); - $shopGroupId = $this->getShopGroupId($shopConstraint); - $isStrict = $this->isStrict($shopConstraint); - - //If configuration has never been accessed it is still empty and hasKey/isLangKey will always return false - if (!ConfigurationLegacy::configurationIsLoaded()) { - ConfigurationLegacy::loadConfiguration(); - } - - // if the key is multi lang related, we return an array with the value per language. - if (ConfigurationLegacy::isLangKey($key)) { - return $this->getLocalized($key, $shopId, $shopGroupId); - } - - // Since hasKey doesn't check manage the fallback shop > shop group > global, we handle it manually - $hasKey = ConfigurationLegacy::hasKey($key, null, null, $shopId); - if ($hasKey || $isStrict) { - return $hasKey ? ConfigurationLegacy::get($key, null, null, $shopId) : null; - } - - $hasKey = ConfigurationLegacy::hasKey($key, null, $shopGroupId); - if ($hasKey || $isStrict) { - return $hasKey ? ConfigurationLegacy::get($key, null, $shopGroupId) : null; - } - - if ($hasKey = ConfigurationLegacy::hasKey($key) || $isStrict) { - return $hasKey ? ConfigurationLegacy::get($key) : null; - } - - return $default; - } - - /** - * Set configuration value. - * - * @param string $key - * @param mixed $value - * @param ShopConstraint|null $shopConstraint - * @param array $options Options @deprecated Will be removed in next major - * - * @return $this - * - * @throws \Exception - */ - public function set($key, $value, ShopConstraint $shopConstraint = null, array $options = []) - { - // By default, set a piece of configuration for all available shops and shop groups - $shopGroupId = null; - $shopId = null; - - if ($this->shop instanceof Shop && null === $shopConstraint) { - $shopGroupId = $this->shop->id_shop_group; - $shopId = $this->shop->id; - } else { - $shopId = $this->getShopId($shopConstraint); - $shopGroupId = $this->getShopGroupId($shopConstraint); - } - - $html = isset($options['html']) ? (bool) $options['html'] : false; - - $success = ConfigurationLegacy::updateValue( - $key, - $value, - $html, - $shopGroupId, - $shopId - ); - - if (!$success) { - throw new \Exception('Could not update configuration'); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function has($key, ShopConstraint $shopConstraint = null) - { - $shopId = $this->getShopId($shopConstraint); - $shopGroupId = $this->getShopGroupId($shopConstraint); - $isStrict = $this->isStrict($shopConstraint); - - $hasKey = ConfigurationLegacy::hasKey($key, null, null, $shopId); - if ($hasKey || $isStrict) { - return $hasKey; - } - - $hasKey = ConfigurationLegacy::hasKey($key, null, $shopGroupId); - if ($hasKey || $isStrict) { - return $hasKey; - } - - return ConfigurationLegacy::hasKey($key); - } - - /** - * Removes a configuration key. - * - * @param type $key - * - * @return type - */ - public function remove($key) - { - $success = \Configuration::deleteByName( - $key - ); - - if (!$success) { - throw new \Exception('Could not update configuration'); - } - - return $this; - } - - /** - * Unset configuration value. - * - * @param $key - * - * @return $this - * - * @throws \Exception - * - * @deprecated since version 1.7.4.0 - */ - public function delete($key) - { - $this->remove($key); - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - return new \ArrayIterator($this->all()); - } - - /** - * {@inheritdoc} - */ - public function count() - { - return count($this->all()); - } - - /** - * Return if Feature feature is active or not. - * - * @return bool - */ - public function featureIsActive() - { - return Feature::isFeatureActive(); - } - - /** - * Return if Combination feature is active or not. - * - * @return bool - */ - public function combinationIsActive() - { - return Combination::isFeatureActive(); - } - - /** - * Restrict updates of a piece of configuration to a single shop. - * - * @param Shop $shop - */ - public function restrictUpdatesTo(Shop $shop) - { - $this->shop = $shop; - } - - /** - * Get localized configuration in all languages - * - * @param string $key - * @param int|null $shopId - * @param int|null $shopGroupId - * - * @return array Array of langId => localizedConfiguration - */ - private function getLocalized($key, ?int $shopId = null, ?int $shopGroupId = null) - { - $configuration = []; - - foreach (Language::getIDs(false, $shopId ?: false) as $langId) { - $configuration[$langId] = ConfigurationLegacy::get($key, $langId, $shopGroupId, $shopId); - } - - return $configuration; - } - - /** - * @param ShopConstraint|null $shopConstraint - * - * @return int|null - */ - private function getShopId(?ShopConstraint $shopConstraint): ?int - { - return null !== $shopConstraint && null !== $shopConstraint->getShopId() - ? $shopConstraint->getShopId()->getValue() - : null - ; - } - - /** - * @param ShopConstraint|null $shopConstraint - * - * @return int|null - */ - private function getShopGroupId(?ShopConstraint $shopConstraint): ?int - { - return null !== $shopConstraint && null !== $shopConstraint->getShopGroupId() - ? $shopConstraint->getShopGroupId()->getValue() - : null - ; - } - - /** - * @param ShopConstraint|null $shopConstraint - * - * @return bool - */ - private function isStrict(?ShopConstraint $shopConstraint): bool - { - return null !== $shopConstraint ? $shopConstraint->isStrict() : false; - } -} diff --git a/src/Adapter/Configuration/CommandHandler/SwitchDebugModeHandler.php b/src/Adapter/Configuration/CommandHandler/SwitchDebugModeHandler.php deleted file mode 100644 index 283d4ba6..00000000 --- a/src/Adapter/Configuration/CommandHandler/SwitchDebugModeHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Configuration\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Debug\DebugMode; -use PrestaShop\PrestaShop\Core\Domain\Configuration\Command\SwitchDebugModeCommand; -use PrestaShop\PrestaShop\Core\Domain\Configuration\CommandHandler\SwitchDebugModeHandlerInterface; - -/** - * Handles command that switches debug mode - * - * @internal - */ -final class SwitchDebugModeHandler implements SwitchDebugModeHandlerInterface -{ - /** - * @var DebugMode - */ - private $debugMode; - - /** - * @param DebugMode $debugMode - */ - public function __construct(DebugMode $debugMode) - { - $this->debugMode = $debugMode; - } - - /** - * {@inheritdoc} - */ - public function handle(SwitchDebugModeCommand $command) - { - $isDebugModeEnabled = $this->debugMode->isDebugModeEnabled(); - - if (!$isDebugModeEnabled && $command->enableDebugMode()) { - $this->debugMode->enable(); - - return; - } - - if ($isDebugModeEnabled && !$command->enableDebugMode()) { - $this->debugMode->disable(); - } - } -} diff --git a/src/Adapter/Configuration/KpiConfiguration.php b/src/Adapter/Configuration/KpiConfiguration.php deleted file mode 100644 index aea49564..00000000 --- a/src/Adapter/Configuration/KpiConfiguration.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Configuration; - -use ConfigurationKPI; -use PrestaShop\PrestaShop\Adapter\Configuration; - -/** - * Class KpiConfiguration provides access to legacy ConfigurationKpi methods. - */ -class KpiConfiguration extends Configuration -{ - /** - * Changes configuration definition before calling it's methods. - * - * @param $name - * @param $arguments - * - * @return mixed - */ - public function __call($name, $arguments) - { - if (is_callable([$this, $name])) { - ConfigurationKPI::setKpiDefinition(); - $result = call_user_func([$this, $name], $arguments); - ConfigurationKPI::unsetKpiDefinition(); - - return $result; - } - } -} diff --git a/src/Adapter/Configuration/LogsConfiguration.php b/src/Adapter/Configuration/LogsConfiguration.php deleted file mode 100644 index 57fa6777..00000000 --- a/src/Adapter/Configuration/LogsConfiguration.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Configuration; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This class will manage Logs configuration for a Shop. - */ -class LogsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return ['logs_by_email' => $this->configuration->get('PS_LOGS_BY_EMAIL')]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_LOGS_BY_EMAIL', $configuration['logs_by_email']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $resolver = new OptionsResolver(); - $resolver - ->setRequired(['logs_by_email']) - ->resolve($configuration); - - return true; - } -} diff --git a/src/Adapter/Configuration/PhpParameters.php b/src/Adapter/Configuration/PhpParameters.php deleted file mode 100644 index 25787d56..00000000 --- a/src/Adapter/Configuration/PhpParameters.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Configuration; - -use InvalidArgumentException; -use Shudrum\Component\ArrayFinder\ArrayFinder; -use Symfony\Component\Filesystem\Exception\IOException; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Class able to manage configuration stored in Php files. - */ -class PhpParameters -{ - /** - * @var array the current configuration - */ - private $configuration = []; - - /** - * @var string the PHP filename - */ - private $filename; - - public function __construct($filename) - { - if (!is_readable($filename)) { - throw new InvalidArgumentException("File $filename is not readable for configuration"); - } - - $this->filename = $filename; - $phpArray = require $this->filename; - $this->configuration = new ArrayFinder($phpArray); - } - - /** - * @return array return the complete configuration - */ - public function getConfiguration() - { - return $this->configuration->get(); - } - - /** - * Insert a value into configuration at the specified path. - * - * @param $propertyPath - * @param $value - */ - public function setProperty($propertyPath, $value) - { - $this->configuration->set($propertyPath, $value); - } - - /** - * Persist the modifications done on the original configuration file. - * - * @return bool - */ - public function saveConfiguration() - { - try { - $filesystem = new Filesystem(); - $filesystem->dumpFile($this->filename, 'configuration->get(), true) . ';' . "\n"); - - if (function_exists('opcache_invalidate')) { - opcache_invalidate($this->filename); - } - } catch (IOException $e) { - return false; - } - - return true; - } -} diff --git a/src/Adapter/Contact/CommandHandler/AddContactHandler.php b/src/Adapter/Contact/CommandHandler/AddContactHandler.php deleted file mode 100644 index c6b807c5..00000000 --- a/src/Adapter/Contact/CommandHandler/AddContactHandler.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Contact\CommandHandler; - -use Contact; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\AddContactCommand; -use PrestaShop\PrestaShop\Core\Domain\Contact\CommandHandler\AddContactHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\CannotAddContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Class AddContactHandler is used for adding contact data. - * - * @internal - */ -final class AddContactHandler extends AbstractObjectModelHandler implements AddContactHandlerInterface -{ - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @param ValidatorInterface $validator - */ - public function __construct(ValidatorInterface $validator) - { - $this->validator = $validator; - } - - /** - * {@inheritdoc} - * - * @throws CannotAddContactException - * @throws ContactException - */ - public function handle(AddContactCommand $command) - { - $this->assertLocalisedTitleContainsDefaultLanguage($command->getLocalisedTitles()); - - try { - $entity = new Contact(); - $entity->name = $command->getLocalisedTitles(); - $entity->customer_service = $command->isMessageSavingEnabled(); - - if (null !== $command->getEmail()) { - $entity->email = $command->getEmail()->getValue(); - } - - if (null !== $command->getLocalisedDescription()) { - $this->assertDescriptionContainsCleanHtmlValues($command->getLocalisedDescription()); - $entity->description = $command->getLocalisedDescription(); - } - - if (false === $entity->add()) { - throw new CannotAddContactException('Unable to add contact'); - } - - if (null !== $command->getShopAssociation()) { - $this->associateWithShops($entity, $command->getShopAssociation()); - } - } catch (PrestaShopException $exception) { - throw new ContactException('An unexpected error occurred when adding contact', 0, $exception); - } - - return new ContactId((int) $entity->id); - } - - /** - * Checks if the localised titles array contains value for the default language. - * - * @param array $localisedTitle - * - * @throws ContactConstraintException - */ - private function assertLocalisedTitleContainsDefaultLanguage(array $localisedTitle) - { - $errors = $this->validator->validate($localisedTitle, new DefaultLanguage()); - - if (0 !== count($errors)) { - throw new ContactConstraintException('Title field is not found for default language', ContactConstraintException::MISSING_TITLE_FOR_DEFAULT_LANGUAGE); - } - } - - /** - * Assets that the value should not contain script tags or javascript events. - * - * @param array $localisedDescriptions - * - * @throws ContactConstraintException - */ - private function assertDescriptionContainsCleanHtmlValues(array $localisedDescriptions) - { - foreach ($localisedDescriptions as $description) { - $errors = $this->validator->validate($description, new CleanHtml()); - - if (0 !== count($errors)) { - throw new ContactConstraintException(sprintf('Given description "%s" contains javascript events or script tags', $description), ContactConstraintException::INVALID_DESCRIPTION); - } - } - } -} diff --git a/src/Adapter/Contact/CommandHandler/EditContactHandler.php b/src/Adapter/Contact/CommandHandler/EditContactHandler.php deleted file mode 100644 index 249fb903..00000000 --- a/src/Adapter/Contact/CommandHandler/EditContactHandler.php +++ /dev/null @@ -1,158 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Contact\CommandHandler; - -use Contact; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\EditContactCommand; -use PrestaShop\PrestaShop\Core\Domain\Contact\CommandHandler\EditContactHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\CannotUpdateContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactNotFoundException; -use PrestaShopDatabaseException; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Class EditContactHandler is responsible for editing contact data. - * - * @internal - */ -final class EditContactHandler extends AbstractObjectModelHandler implements EditContactHandlerInterface -{ - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @param ValidatorInterface $validator - */ - public function __construct(ValidatorInterface $validator) - { - $this->validator = $validator; - } - - /** - * {@inheritdoc} - * - * @throws ContactException - */ - public function handle(EditContactCommand $command) - { - try { - $entity = $this->getContactEntityIfFound($command->getContactId()->getValue()); - - if (null !== $command->getLocalisedTitles()) { - $this->assertLocalisedTitleContainsDefaultLanguage($command->getLocalisedTitles()); - $entity->name = $command->getLocalisedTitles(); - } - - if (null !== $command->getLocalisedDescription()) { - $this->assertDescriptionContainsCleanHtmlValues($command->getLocalisedDescription()); - $entity->description = $command->getLocalisedDescription(); - } - - if (null !== $command->getEmail()) { - $entity->email = $command->getEmail()->getValue(); - } - - if (null !== $command->isMessagesSavingEnabled()) { - $entity->customer_service = $command->isMessagesSavingEnabled(); - } - - if (false === $entity->update()) { - throw new CannotUpdateContactException(sprintf('Unable to update contact object with id %s', $command->getContactId()->getValue())); - } - - if (null !== $command->getShopAssociation()) { - $this->associateWithShops($entity, $command->getShopAssociation()); - } - } catch (PrestaShopException $e) { - throw new ContactException(sprintf('An unexpected error occurred when retrieving contact with id %s', var_export($command->getContactId()->getValue(), true)), 0, $e); - } - } - - /** - * Validates that values does not contain script tags or javascript events. - * - * @param array $localisedDescriptions - * - * @throws ContactConstraintException - */ - private function assertDescriptionContainsCleanHtmlValues(array $localisedDescriptions) - { - foreach ($localisedDescriptions as $description) { - $errors = $this->validator->validate($description, new CleanHtml()); - - if (0 !== count($errors)) { - throw new ContactConstraintException(sprintf('Given description "%s" contains javascript events or script tags', $description), ContactConstraintException::INVALID_DESCRIPTION); - } - } - } - - /** - * Checks if the localised titles array contains value for the default language. - * - * @param array $localisedTitle - * - * @throws ContactConstraintException - */ - private function assertLocalisedTitleContainsDefaultLanguage(array $localisedTitle) - { - $errors = $this->validator->validate($localisedTitle, new DefaultLanguage()); - - if (0 !== count($errors)) { - throw new ContactConstraintException('Title field is not found for default language', ContactConstraintException::MISSING_TITLE_FOR_DEFAULT_LANGUAGE); - } - } - - /** - * Gets contact entity. - * - * @param int $contactId - * - * @return Contact - * - * @throws ContactNotFoundException - * @throws PrestaShopException - * @throws PrestaShopDatabaseException - */ - private function getContactEntityIfFound($contactId) - { - $entity = new Contact($contactId); - - if (0 >= $entity->id) { - throw new ContactNotFoundException(sprintf('Contact object with id %s was not found', var_export($contactId, true))); - } - - return $entity; - } -} diff --git a/src/Adapter/Contact/QueryHandler/GetContactForEditingHandler.php b/src/Adapter/Contact/QueryHandler/GetContactForEditingHandler.php deleted file mode 100644 index a9085902..00000000 --- a/src/Adapter/Contact/QueryHandler/GetContactForEditingHandler.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Contact\QueryHandler; - -use Contact; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Query\GetContactForEditing; -use PrestaShop\PrestaShop\Core\Domain\Contact\QueryHandler\GetContactForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Contact\QueryResult\EditableContact; -use PrestaShopException; -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class GetContactForEditingHandler is responsible for getting the data for contact edit page. - * - * @internal - */ -final class GetContactForEditingHandler implements GetContactForEditingHandlerInterface -{ - /** - * @var DataTransformerInterface - */ - private $stringArrayToIntegerArrayDataTransformer; - - /** - * @param DataTransformerInterface $stringArrayToIntegerArrayDataTransformer - */ - public function __construct(DataTransformerInterface $stringArrayToIntegerArrayDataTransformer) - { - $this->stringArrayToIntegerArrayDataTransformer = $stringArrayToIntegerArrayDataTransformer; - } - - /** - * {@inheritdoc} - * - * @throws ContactException - */ - public function handle(GetContactForEditing $query) - { - try { - $contact = new Contact($query->getContactId()->getValue()); - - if (0 >= $contact->id) { - throw new ContactNotFoundException(sprintf('Contact object with id %s was not found', var_export($query->getContactId()->getValue(), true))); - } - $editableContact = new EditableContact( - $query->getContactId()->getValue(), - $contact->name, - $contact->email, - (bool) $contact->customer_service, - $contact->description, - $this->stringArrayToIntegerArrayDataTransformer->reverseTransform($contact->getAssociatedShops()) - ); - } catch (PrestaShopException $e) { - throw new ContactException(sprintf('An unexpected error occurred when retrieving contact with id %s', var_export($query->getContactId()->getValue(), true)), 0, $e); - } - - return $editableContact; - } -} diff --git a/src/Adapter/Container/ContainerBuilderExtensionInterface.php b/src/Adapter/Container/ContainerBuilderExtensionInterface.php deleted file mode 100644 index 1bc2504d..00000000 --- a/src/Adapter/Container/ContainerBuilderExtensionInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * Interface ContainerBuilderExtensionInterface is used to externalize some container - * building actions from the PrestaShop\PrestaShop\Adapter\ContainerBuilder (register - * an extension, init some parameters). - * - * This builder extension system needs to be used for actions that can't be performed in a - * CompilerPassInterface due to the compilation workflow (some actions MUST be done before - * the compilation stars, this is where this system comes in handy). - */ -interface ContainerBuilderExtensionInterface -{ - /** - * This method is called by the ContainerBuilder before compiling the container. This is where you - * can add extension, compiler pass, or parameters to the container. - * - * @param ContainerBuilder $container - */ - public function build(ContainerBuilder $container); -} diff --git a/src/Adapter/Container/ContainerParametersExtension.php b/src/Adapter/Container/ContainerParametersExtension.php deleted file mode 100644 index ceef4e87..00000000 --- a/src/Adapter/Container/ContainerParametersExtension.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use PrestaShop\PrestaShop\Core\EnvironmentInterface; -use PrestaShopBundle\Kernel\ModuleRepository; -use PrestaShopBundle\Kernel\ModuleRepositoryFactory; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * This container extension is in charge of initializing the container parameters. - * It uses the same type of init as the kernel container thanks to the set_parameters.php - * script which allows it to be as close as possible to the symfony kernel AND the script - * automatically manage env test switching. - * - * We also add a few default parameters which are expected by doctrine and some of our - * compiler pass which need the list of active modules. - * - * Note: this can't be done as a CompilerPassInterface because parameters need to be set before extensions - * are registered (especially Doctrine extension). - */ -class ContainerParametersExtension implements ContainerBuilderExtensionInterface -{ - /** - * @var EnvironmentInterface - */ - private $environment; - - /** - * @param EnvironmentInterface $environment - */ - public function __construct(EnvironmentInterface $environment) - { - $this->environment = $environment; - } - - /** - * {@inheritdoc} - */ - public function build(ContainerBuilder $container) - { - //This script is used in config.yml to init the container parameters - //It is also able to generate the parameters.php file if it does not exist - include _PS_ROOT_DIR_ . '/app/config/set_parameters.php'; - $container->addResource(new FileResource(_PS_ROOT_DIR_ . '/app/config/parameters.php')); - - //Most of these parameters are just necessary fro doctrine services definitions - $container->setParameter('kernel.bundles', []); - $container->setParameter('kernel.root_dir', _PS_ROOT_DIR_ . '/app'); - $container->setParameter('kernel.project_dir', _PS_ROOT_DIR_); - $container->setParameter('kernel.name', 'app'); - $container->setParameter('kernel.debug', $this->environment->isDebug()); - $container->setParameter('kernel.environment', $this->environment->getName()); - - //Note: this is not the same folder in test env because PS_CACHE_DIR only manages dev and prod env - //but it should! So for now let's do it the right way here and let's fix the rest later when EnvironmentInterface - //will be correctly/fully integrated. - $container->setParameter('kernel.cache_dir', $this->environment->getCacheDir()); - - //Init the active modules - $factory = new ModuleRepositoryFactory($container->getParameterBag()->all()); - /** @var ModuleRepository $moduleRepository */ - $moduleRepository = $factory->getRepository(); - $container->setParameter('kernel.active_modules', $moduleRepository->getActiveModules()); - } -} diff --git a/src/Adapter/Container/DoctrineBuilderExtension.php b/src/Adapter/Container/DoctrineBuilderExtension.php deleted file mode 100644 index 9efd20bf..00000000 --- a/src/Adapter/Container/DoctrineBuilderExtension.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension; -use PrestaShop\PrestaShop\Core\EnvironmentInterface; -use PrestaShopBundle\DependencyInjection\Compiler\ModulesDoctrineCompilerPass; -use PrestaShopBundle\DependencyInjection\Config\ConfigYamlLoader; -use Symfony\Component\Config\FileLocator; -use Symfony\Component\DependencyInjection\ContainerBuilder; - -/** - * Class DoctrineBuilderExtension is used to init the doctrine service in the ContainerBuilder. - * This is a manual initialisation of Doctrine because we are not in a symfony context, so we need - * add the extension manually (required parameters are managed by ContainerParametersExtension). - * - * Note: this can't be done as a CompilerPassInterface because extensions need to be registered before compilation. - */ -class DoctrineBuilderExtension implements ContainerBuilderExtensionInterface -{ - /** @var EnvironmentInterface */ - private $environment; - - /** - * @param EnvironmentInterface $environment - */ - public function __construct(EnvironmentInterface $environment) - { - $this->environment = $environment; - } - - /** - * {@inheritdoc} - */ - public function build(ContainerBuilder $container) - { - $configDirectories = [$container->getParameter('kernel.root_dir') . '/config']; - $fileLocator = new FileLocator($configDirectories); - - $configLoader = new ConfigYamlLoader($fileLocator); - $configPath = sprintf('config_legacy_%s.yml', $this->environment->getName()); - $configLoader->load($configPath); - $config = $configLoader->getConfig(); - - $container->registerExtension(new DoctrineExtension()); - $container->loadFromExtension('doctrine', $config['doctrine']); - $container->addCompilerPass(new ModulesDoctrineCompilerPass()); - } -} diff --git a/src/Adapter/Container/LegacyContainer.php b/src/Adapter/Container/LegacyContainer.php deleted file mode 100644 index 3077a58a..00000000 --- a/src/Adapter/Container/LegacyContainer.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use Symfony\Component\DependencyInjection\Container; - -/** - * This class is only used when we build containers for legacy environment. It - * is used as a base class when dumping the container in our ContainerBuilder. - * - * It implements LegacyContainerInterface which allows to detect if the container - * was built by Symfony or by PrestaShop. - */ -class LegacyContainer extends Container implements LegacyContainerInterface -{ -} diff --git a/src/Adapter/Container/LegacyContainerBuilder.php b/src/Adapter/Container/LegacyContainerBuilder.php deleted file mode 100644 index 7fa146ae..00000000 --- a/src/Adapter/Container/LegacyContainerBuilder.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use Symfony\Component\DependencyInjection\ContainerBuilder as SfContainerBuilder; - -/** - * This class is only used when we build containers for legacy environment. It - * is used as a base builder when we build the container in our ContainerBuilder. - * - * It is needed during the first generation of the container as it is used as a container - * during this process, next calls usually use the built container class that extends LegacyContainer. - * - * It implements LegacyContainerInterface which allows to detect if the container - * was built by Symfony or by PrestaShop. - */ -class LegacyContainerBuilder extends SfContainerBuilder implements LegacyContainerInterface -{ -} diff --git a/src/Adapter/Container/LegacyContainerInterface.php b/src/Adapter/Container/LegacyContainerInterface.php deleted file mode 100644 index 569089d2..00000000 --- a/src/Adapter/Container/LegacyContainerInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Container; - -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * This interface is only used when we build containers for legacy environment. It - * is common to LegacyContainer and LegacyContainerBuilder. - * - * It allows to easily (and without losing performance) detect if the container is a - * Symfony one (generated by kernel) or a legacy one (generated by PrestaShop core). - */ -interface LegacyContainerInterface extends ContainerInterface -{ -} diff --git a/src/Adapter/ContainerBuilder.php b/src/Adapter/ContainerBuilder.php deleted file mode 100644 index 228619ff..00000000 --- a/src/Adapter/ContainerBuilder.php +++ /dev/null @@ -1,244 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Doctrine\Common\Cache\ArrayCache; -use Doctrine\ORM\Tools\Setup; -use Exception; -use LegacyCompilerPass; -use PrestaShop\PrestaShop\Adapter\Container\ContainerBuilderExtensionInterface; -use PrestaShop\PrestaShop\Adapter\Container\ContainerParametersExtension; -use PrestaShop\PrestaShop\Adapter\Container\DoctrineBuilderExtension; -use PrestaShop\PrestaShop\Adapter\Container\LegacyContainer; -use PrestaShop\PrestaShop\Adapter\Container\LegacyContainerBuilder; -use PrestaShop\PrestaShop\Core\EnvironmentInterface; -use PrestaShopBundle\DependencyInjection\Compiler\LoadServicesFromModulesPass; -use Symfony\Component\Config\ConfigCache; -use Symfony\Component\Config\FileLocator; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\DependencyInjection\Compiler\PassConfig; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\DependencyInjection\Dumper\PhpDumper; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; - -/** - * Build the Container for PrestaShop Legacy. - */ -class ContainerBuilder -{ - /** - * @var ContainerInterface - */ - private static $containers; - - /** - * @var string - */ - private $environment; - - /** - * @var string - */ - private $containerName; - - /** - * @var string - */ - private $containerClassName; - - /** - * @var string - */ - private $dumpFile; - - /** - * @var ConfigCache - */ - private $containerConfigCache; - - /** - * @param string $containerName - * @param bool $isDebug - * - * @return LegacyContainerBuilder - * - * @throws Exception - */ - public static function getContainer($containerName, $isDebug) - { - if (!isset(self::$containers[$containerName])) { - $builder = new ContainerBuilder(new Environment($isDebug)); - self::$containers[$containerName] = $builder->buildContainer($containerName); - } - - return self::$containers[$containerName]; - } - - /** - * @param EnvironmentInterface $environment - */ - public function __construct(EnvironmentInterface $environment) - { - $this->environment = $environment; - } - - /** - * @param string $containerName - * - * @return ContainerInterface|LegacyContainerBuilder - * - * @throws Exception - */ - public function buildContainer($containerName) - { - $this->containerName = $containerName; - $this->containerClassName = ucfirst($this->containerName) . 'Container'; - $this->dumpFile = $this->environment->getCacheDir() . $this->containerClassName . '.php'; - $this->containerConfigCache = new ConfigCache($this->dumpFile, $this->environment->isDebug()); - - //These methods load required files like autoload or annotation metadata so we need to load - //them at each container creation, this can't be compiled. - $this->loadDoctrineAnnotationMetadata(); - - $container = $this->loadDumpedContainer(); - if (null === $container) { - $container = $this->compileContainer(); - } - $this->loadModulesAutoloader($container); - - return $container; - } - - /** - * @return ContainerInterface|null - */ - private function loadDumpedContainer() - { - $container = null; - if ($this->containerConfigCache->isFresh()) { - require_once $this->dumpFile; - $container = new $this->containerClassName(); - } - - return $container; - } - - /** - * @return LegacyContainerBuilder - * - * @throws Exception - */ - private function compileContainer() - { - $container = new LegacyContainerBuilder(); - //If the container builder is modified the container logically should be rebuilt - $container->addResource(new FileResource(__FILE__)); - - $container->addCompilerPass(new LoadServicesFromModulesPass($this->containerName), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1); - $container->addCompilerPass(new LegacyCompilerPass()); - - //Build extensions - $builderExtensions = [ - new ContainerParametersExtension($this->environment), - new DoctrineBuilderExtension($this->environment), - ]; - /** @var ContainerBuilderExtensionInterface $builderExtension */ - foreach ($builderExtensions as $builderExtension) { - $builderExtension->build($container); - } - - $this->loadServicesFromConfig($container); - $container->compile(); - - //Dump the container file - $dumper = new PhpDumper($container); - $this->containerConfigCache->write( - $dumper->dump([ - 'class' => $this->containerClassName, - 'base_class' => LegacyContainer::class, - ]), - $container->getResources() - ); - - return $container; - } - - /** - * In symfony context doctrine classes (like Table, Entity, ...) are available thanks to - * the autoloader. In this specific context we don't have the general autoloader, so we need - * to include these classes manually. This is performed in Doctrine\ORM\Configuration::newDefaultAnnotationDriver - * which is called in Setup::createAnnotationMetadataConfiguration. - */ - private function loadDoctrineAnnotationMetadata() - { - //IMPORTANT: we need to provide a cache because doctrine tries to init a connection on redis, memcached, ... on its own - Setup::createAnnotationMetadataConfiguration([], $this->environment->isDebug(), null, new ArrayCache()); - } - - /** - * @param LegacyContainerBuilder $container - * - * @throws Exception - */ - private function loadServicesFromConfig(LegacyContainerBuilder $container) - { - $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); - $servicesPath = sprintf( - '%sservices/%s/services_%s.yml', - _PS_CONFIG_DIR_, - $this->containerName, - $this->environment->getName() - ); - $loader->load($servicesPath); - } - - /** - * Loops through all active modules and automatically include their autoload (if present). - * Needs to be done as earlier as possible in application lifecycle. Unfortunately this can't - * be done in a compiler pass because they are only executed on compilation and this needs to - * be done at each container instanciation. - * - * @param ContainerInterface $container - * - * @throws Exception - */ - private function loadModulesAutoloader(ContainerInterface $container) - { - if (!$container->hasParameter('kernel.active_modules')) { - return; - } - - $activeModules = $container->getParameter('kernel.active_modules'); - foreach ($activeModules as $module) { - $autoloader = _PS_MODULE_DIR_ . $module . '/vendor/autoload.php'; - - if (file_exists($autoloader)) { - include_once $autoloader; - } - } - } -} diff --git a/src/Adapter/ContainerFinder.php b/src/Adapter/ContainerFinder.php deleted file mode 100644 index 9d80dcf0..00000000 --- a/src/Adapter/ContainerFinder.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Context; -use Controller; -use PrestaShop\PrestaShop\Core\Exception\ContainerNotFoundException; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Find the container - */ -class ContainerFinder -{ - /** - * @var Context - */ - protected $context; - - /** - * ContainerFinder constructor. - * - * @param Context $context - */ - public function __construct(Context $context) - { - $this->context = $context; - } - - /** - * @return ContainerBuilder|ContainerInterface - * - * @throws ContainerNotFoundException - */ - public function getContainer() - { - if (isset($this->context->container)) { - return $this->context->container; - } - if (isset($this->context->controller) - && $this->context->controller instanceof Controller - && ($container = $this->context->controller->getContainer()) - && null !== $container - ) { - return $container; - } - $container = SymfonyContainer::getInstance(); - if (null !== $container) { - return $container; - } - - throw new ContainerNotFoundException('Kernel Container is not available'); - } -} diff --git a/src/Adapter/ContextStateManager.php b/src/Adapter/ContextStateManager.php deleted file mode 100644 index e7e71e3b..00000000 --- a/src/Adapter/ContextStateManager.php +++ /dev/null @@ -1,285 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter; - -use Cart; -use Context; -use Country; -use Currency; -use Customer; -use Language; -use Shop; - -/** - * Allows manipulating context state. - * This was adapted for specific broken legacy use cases when the previous state of context must be restored after some actions. - * - * e.g. order creation from back office. - * Legacy requires Context properties (currency, country etc.) instead of using cart properties - * so some context props must be changed for a while and then restored to previous state. - */ -final class ContextStateManager -{ - private const MANAGED_FIELDS = [ - 'cart', - 'country', - 'currency', - 'language', - 'customer', - 'shop', - 'shopContext', - ]; - - /** - * @var Context - */ - private $context; - - /** - * @var array - */ - private $contextFieldsStack = [[]]; - - /** - * @param Context $context - */ - public function __construct(Context $context) - { - $this->context = $context; - } - - /** - * @return Context - */ - public function getContext(): Context - { - return $this->context; - } - - /** - * Sets context cart and saves previous value - * - * @param Cart|null $cart - * - * @return $this - */ - public function setCart(?Cart $cart): self - { - $this->saveContextField('cart'); - $this->context->cart = $cart; - - return $this; - } - - /** - * Sets context country and saves previous value - * - * @param Country|null $country - * - * @return $this - */ - public function setCountry(?Country $country): self - { - $this->saveContextField('country'); - $this->context->country = $country; - - return $this; - } - - /** - * Sets context currency and saves previous value - * - * @param Currency|null $currency - * - * @return $this - */ - public function setCurrency(?Currency $currency): self - { - $this->saveContextField('currency'); - $this->context->currency = $currency; - - return $this; - } - - /** - * Sets context language and saves previous value - * - * @param Language|null $language - * - * @return $this - */ - public function setLanguage(?Language $language): self - { - $this->saveContextField('language'); - $this->context->language = $language; - - return $this; - } - - /** - * Sets context customer and saves previous value - * - * @param Customer|null $customer - * - * @return $this - */ - public function setCustomer(?Customer $customer): self - { - $this->saveContextField('customer'); - $this->context->customer = $customer; - - return $this; - } - - /** - * Sets context shop and saves previous value - * - * @param Shop $shop - * - * @return $this - * - * @throws \PrestaShopException - */ - public function setShop(Shop $shop): self - { - $this->saveContextField('shop'); - $this->context->shop = $shop; - Shop::setContext(Shop::CONTEXT_SHOP, $shop->id); - - return $this; - } - - /** - * Restores context to a state before changes - * - * @return self - */ - public function restorePreviousContext(): self - { - $currentStashIndex = array_key_last($this->contextFieldsStack); - foreach (array_keys($this->contextFieldsStack[$currentStashIndex]) as $fieldName) { - $this->restoreContextField($fieldName); - } - $this->removeLastSavedContext(); - - return $this; - } - - /** - * Saves the current overridden fields in the context, allowing you to set new values to the - * current Context. Next time you call restorePreviousContext the context will be refilled with - * the values that were saved during this call. - * - * This is useful if several services use the ContextStateManager, this way if every service - * saved the context before modifying it there is no risk of removing previous modifications - * when you restore the context, because the different states have been stacked. - * - * @return $this - */ - public function saveCurrentContext(): self - { - // Saves all the fields that have not been overridden - foreach (self::MANAGED_FIELDS as $contextField) { - $this->saveContextField($contextField); - } - - // Add a new empty layer - $this->contextFieldsStack[] = []; - - return $this; - } - - /** - * Save context field into local array - * - * @param string $fieldName - */ - private function saveContextField(string $fieldName) - { - $currentStashIndex = array_key_last($this->contextFieldsStack); - // NOTE: array_key_exists important here, isset cannot be used because it would not detect if null is stored - if (!array_key_exists($fieldName, $this->contextFieldsStack[$currentStashIndex])) { - if ('shop' === $fieldName) { - $this->contextFieldsStack[$currentStashIndex]['shop'] = $this->context->$fieldName; - $this->contextFieldsStack[$currentStashIndex]['shopContext'] = Shop::getContext(); - } else { - $this->contextFieldsStack[$currentStashIndex][$fieldName] = $this->context->$fieldName; - } - } - } - - /** - * Restores context saved value, and remove save value from local array - * - * @param string $fieldName - */ - private function restoreContextField(string $fieldName): void - { - $currentStashIndex = array_key_last($this->contextFieldsStack); - // NOTE: array_key_exists important here, isset cannot be used because it would not detect if null is stored - if (array_key_exists($fieldName, $this->contextFieldsStack[$currentStashIndex])) { - if ('shop' === $fieldName) { - $this->restoreShopContext($currentStashIndex); - } - $this->context->$fieldName = $this->contextFieldsStack[$currentStashIndex][$fieldName]; - unset($this->contextFieldsStack[$currentStashIndex][$fieldName]); - } - } - - /** - * Restore the ShopContext, this is used when Shop has been overridden, we need to - * restore context->shop of course But also the static fields in Shop class - * - * @param int $currentStashIndex - */ - private function restoreShopContext(int $currentStashIndex): void - { - $shop = $this->contextFieldsStack[$currentStashIndex]['shop']; - $shopId = $shop instanceof Shop ? $shop->id : null; - $shopContext = $this->contextFieldsStack[$currentStashIndex]['shopContext']; - if (null !== $shopContext) { - Shop::setContext($shopContext, $shopId); - } - unset($this->contextFieldsStack[$currentStashIndex]['shopContext']); - } - - /** - * Removes the last saved stashed context, in case this method is called too many times - * we always keep one layer available - */ - private function removeLastSavedContext(): void - { - array_pop($this->contextFieldsStack); - - // Always keep at least one layer (in case we remove too many) - if (empty($this->contextFieldsStack)) { - $this->contextFieldsStack[] = []; - } - } -} diff --git a/src/Adapter/Converter/ExcelToCsvFileConverter.php b/src/Adapter/Converter/ExcelToCsvFileConverter.php deleted file mode 100644 index 96e83988..00000000 --- a/src/Adapter/Converter/ExcelToCsvFileConverter.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Converter; - -use PhpOffice\PhpSpreadsheet\IOFactory; -use PrestaShop\PrestaShop\Core\File\Converter\FileConverterInterface; -use SplFileInfo; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Class ExcelToCsvFileConverter converts excel files to CSV. - */ -final class ExcelToCsvFileConverter implements FileConverterInterface -{ - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var string - */ - private $csvDirectory; - - /** - * @var string - */ - private $excelDirectory; - - /** - * @param Filesystem $filesystem - * @param string $csvDirectory path to CSV files directory - * @param string $excelDirectory path to excel files directory - */ - public function __construct(Filesystem $filesystem, $csvDirectory, $excelDirectory) - { - $this->filesystem = $filesystem; - $this->csvDirectory = $csvDirectory; - $this->excelDirectory = $excelDirectory; - } - - /** - * {@inheritdoc} - */ - public function convert(SplFileInfo $sourceFile) - { - if (preg_match('#(.*?)\.(csv)#is', $sourceFile->getFilename())) { - // File is already in CSV - return $sourceFile; - } - - if (!$this->filesystem->exists($this->excelDirectory)) { - $this->filesystem->mkdir($this->excelDirectory); - } - - $destinationFilename = basename($sourceFile->getFilename(), $sourceFile->getExtension()) . '.csv'; - $destinationFilePath = $this->excelDirectory . $destinationFilename; - - if (!$this->filesystem->exists($destinationFilePath)) { - $excelReader = IOFactory::createReaderForFile($sourceFile->getFilename()); - $excelReader->setReadDataOnly(true); - $excelFile = $excelReader->load($sourceFile->getFilename() . $destinationFilename); - $csvWriter = IOFactory::createWriter($excelFile, 'Csv'); - $csvWriter->setSheetIndex(0); - $csvWriter->setDelimiter(';'); - $csvWriter->save($destinationFilePath); - } - - return new SplFileInfo($destinationFilePath); - } -} diff --git a/src/Adapter/CoreException.php b/src/Adapter/CoreException.php deleted file mode 100644 index f4f772c0..00000000 --- a/src/Adapter/CoreException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -/** - * @todo: find why this class have been created and used. - */ -class CoreException extends \Exception -{ -} diff --git a/src/Adapter/Country/CountryDataProvider.php b/src/Adapter/Country/CountryDataProvider.php deleted file mode 100644 index 8ac35d4b..00000000 --- a/src/Adapter/Country/CountryDataProvider.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Country; - -use Configuration; -use Country; -use Db; -use DbQuery; - -/** - * This class will provide data from DB / ORM about Country - */ -class CountryDataProvider -{ - /** - * Return available countries. - * - * @param int $id_lang Language ID - * @param bool $active return only active coutries - * @param bool $contain_states return only country with states - * @param bool $list_states Include the states list with the returned list - * - * @return array Countries and corresponding zones - */ - public function getCountries($id_lang, $active = false, $contain_states = false, $list_states = true) - { - return Country::getCountries($id_lang, $active, $contain_states, $list_states); - } - - /** - * Returns list of countries IDs which need DNI - * - * @return array - */ - public function getCountriesIdWhichNeedDni() - { - $query = new DbQuery(); - $query - ->select('c.`id_country`') - ->from('country', 'c') - ->where('c.`need_identification_number` = 1') - ; - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - - return array_map(function ($country) { return $country['id_country']; }, $result); - } - - /** - * Returns list of countries IDs which need Postcode - * - * @return array - * - * @throws \PrestaShopDatabaseException - */ - public function getCountriesIdWhichNeedPostcode() - { - $query = new DbQuery(); - $query - ->select('c.`id_country`') - ->from('country', 'c') - ->where('c.`need_zip_code` = 1') - ; - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - - return array_map(function ($country) { return $country['id_country']; }, $result); - } - - /** - * Returns list of countries IDS which need a state - * - * @return array - * - * @throws \PrestaShopDatabaseException - */ - public function getCountriesIdWhichNeedState() - { - $query = new DbQuery(); - $query - ->select('c.`id_country`') - ->from('country', 'c') - ->where('c.`contains_states` = 1') - ; - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - - return array_map(function ($country) { return $country['id_country']; }, $result); - } - - /** - * Get Country IsoCode by Id. - * - * @param int $id Country Id - * - * @return string the related iso code - */ - public function getIsoCodebyId($id = null) - { - $countryId = (null === $id) ? Configuration::get('PS_COUNTRY_DEFAULT') : $id; - - return Country::getIsoById($countryId); - } - - /** - * Get country Id by ISO code. - * - * @param string $isoCode Country ISO code - * - * @return int - */ - public function getIdByIsoCode($isoCode) - { - return Country::getByIso($isoCode); - } -} diff --git a/src/Adapter/Country/CountryRequiredFieldsProvider.php b/src/Adapter/Country/CountryRequiredFieldsProvider.php deleted file mode 100644 index dbad18ec..00000000 --- a/src/Adapter/Country/CountryRequiredFieldsProvider.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Country; - -use PrestaShop\PrestaShop\Core\Country\CountryRequiredFieldsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; - -class CountryRequiredFieldsProvider implements CountryRequiredFieldsProviderInterface -{ - /** - * @var CountryDataProvider - */ - private $countryDataProvider; - - public function __construct(CountryDataProvider $countryDataProvider) - { - $this->countryDataProvider = $countryDataProvider; - } - - /** - * {@inheritdoc} - * - * @throws CountryNotFoundException - */ - public function isStatesRequired(CountryId $countryId): bool - { - $countries = $this->countryDataProvider->getCountriesIdWhichNeedState(); - - return in_array($countryId->getValue(), $countries); - } - - /** - * {@inheritdoc} - * - * @throws CountryNotFoundException - */ - public function isDniRequired(CountryId $countryId): bool - { - $countries = $this->countryDataProvider->getCountriesIdWhichNeedDni(); - - return in_array($countryId->getValue(), $countries); - } -} diff --git a/src/Adapter/Country/CountryZipCodeRequirementsProvider.php b/src/Adapter/Country/CountryZipCodeRequirementsProvider.php deleted file mode 100644 index c32700aa..00000000 --- a/src/Adapter/Country/CountryZipCodeRequirementsProvider.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Country; - -use Country; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Country\CountryZipCodeRequirements; -use PrestaShop\PrestaShop\Core\Country\CountryZipCodeRequirementsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use PrestaShop\PrestaShop\Core\Domain\Country\ZipCodePatternResolver; -use PrestaShopException; - -final class CountryZipCodeRequirementsProvider implements CountryZipCodeRequirementsProviderInterface -{ - /** - * @var int - */ - private $langId; - - /** - * @var ZipCodePatternResolver - */ - private $patternResolver; - - /** - * @param LegacyContext $context - * @param ZipCodePatternResolver $patternResolver - */ - public function __construct(LegacyContext $context, ZipCodePatternResolver $patternResolver) - { - $this->langId = (int) $context->getLanguage()->id; - $this->patternResolver = $patternResolver; - } - - /** - * {@inheritdoc} - * - * @throws CountryNotFoundException - */ - public function getCountryZipCodeRequirements(CountryId $countryId): CountryZipCodeRequirements - { - $countryIdValue = $countryId->getValue(); - - try { - $country = new Country($countryIdValue); - } catch (PrestaShopException $e) { - throw new CountryNotFoundException(sprintf('Country with id "%s" was not found.', $countryIdValue)); - } - - if ($country->id !== $countryIdValue) { - throw new CountryNotFoundException(sprintf('Country with id "%s" was not found.', $countryIdValue)); - } - - $requirements = new CountryZipCodeRequirements($country->need_zip_code); - - if (isset($country->name[$this->langId])) { - $requirements->setCountryName($country->name[$this->langId]); - } - - if ($country->need_zip_code && !empty($country->zip_code_format)) { - $pattern = $this->patternResolver->getRegexPattern($country->zip_code_format, $country->iso_code); - $humanReadablePattern = $this->patternResolver->getHumanReadablePattern( - $country->zip_code_format, - $country->iso_code - ); - - $requirements->setPatterns($pattern, $humanReadablePattern); - } - - return $requirements; - } -} diff --git a/src/Adapter/Country/QueryHandler/GetCountryRequiredFieldsHandler.php b/src/Adapter/Country/QueryHandler/GetCountryRequiredFieldsHandler.php deleted file mode 100644 index 276d12cb..00000000 --- a/src/Adapter/Country/QueryHandler/GetCountryRequiredFieldsHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Country\QueryHandler; - -use PrestaShop\PrestaShop\Core\Country\CountryRequiredFieldsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\Query\GetCountryRequiredFields; -use PrestaShop\PrestaShop\Core\Domain\Country\QueryHandler\GetCountryRequiredFieldsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\QueryResult\CountryRequiredFields; - -/** - * Handles and provides country state requirements - */ -final class GetCountryRequiredFieldsHandler implements GetCountryRequiredFieldsHandlerInterface -{ - /** @var CountryRequiredFieldsProviderInterface */ - private $requiredFieldsProvider; - - /** - * @param CountryRequiredFieldsProviderInterface $requiredFieldsProvider - */ - public function __construct(CountryRequiredFieldsProviderInterface $requiredFieldsProvider) - { - $this->requiredFieldsProvider = $requiredFieldsProvider; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCountryRequiredFields $query): CountryRequiredFields - { - return new CountryRequiredFields( - $this->requiredFieldsProvider->isStatesRequired($query->getCountryId()), - $this->requiredFieldsProvider->isDniRequired($query->getCountryId()) - ); - } -} diff --git a/src/Adapter/CreditSlip/CreditSlipTemplateTypeProvider.php b/src/Adapter/CreditSlip/CreditSlipTemplateTypeProvider.php deleted file mode 100644 index 5e07f565..00000000 --- a/src/Adapter/CreditSlip/CreditSlipTemplateTypeProvider.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CreditSlip; - -use PDF; -use PrestaShop\PrestaShop\Core\PDF\PDFTemplateTypeProviderInterface; - -/** - * Provides credit slip PDF template type. - */ -final class CreditSlipTemplateTypeProvider implements PDFTemplateTypeProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getPDFTemplateType() - { - return PDF::TEMPLATE_ORDER_SLIP; - } -} diff --git a/src/Adapter/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandler.php b/src/Adapter/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandler.php deleted file mode 100644 index 6af8fd76..00000000 --- a/src/Adapter/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CreditSlip\QueryHandler; - -use OrderSlip; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception\CreditSlipException; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception\CreditSlipNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\Query\GetCreditSlipIdsByDateRange; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\QueryHandler\GetCreditSlipIdsByDateRangeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\ValueObject\CreditSlipId; -use PrestaShopException; - -/** - * Handles query which gets CreditSlipIds by provided date range - */ -final class GetCreditSlipIdsByDateRangeHandler implements GetCreditSlipIdsByDateRangeHandlerInterface -{ - /** - * Handles the query using legacy object model - * - * {@inheritdoc} - */ - public function handle(GetCreditSlipIdsByDateRange $query) - { - try { - $from = $query->getDateTimeFrom()->format('Y-m-d'); - $to = $query->getDateTimeTo()->format('Y-m-d'); - $ids = OrderSlip::getSlipsIdByDate($from, $to); - - if (empty($ids)) { - throw new CreditSlipNotFoundException(sprintf('No credit slips found for date range "%s - %s"', $from, $to), CreditSlipNotFoundException::BY_DATE_RANGE); - } - - $creditSlipIds = []; - foreach ($ids as $id) { - $creditSlipIds[] = new CreditSlipId($id); - } - } catch (PrestaShopException $e) { - throw new CreditSlipException('Something went wrong when trying to get OrderSlip ids by date range', 0, $e); - } - - return $creditSlipIds; - } -} diff --git a/src/Adapter/Currency/CommandHandler/AbstractCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/AbstractCurrencyHandler.php deleted file mode 100644 index 1c8581a6..00000000 --- a/src/Adapter/Currency/CommandHandler/AbstractCurrencyHandler.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Currency; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotCreateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotUpdateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Currency\PatternTransformer; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShopDatabaseException; -use PrestaShopException; - -/** - * Class AbstractCurrencyHandler is responsible for encapsulating common behavior for legacy currency object model. - * - * @internal - */ -abstract class AbstractCurrencyHandler extends AbstractObjectModelHandler -{ - /** - * @var LocaleRepository - */ - protected $localeRepoCLDR; - - /** - * @var LanguageInterface[] - */ - protected $languages; - - /** - * @var CurrencyCommandValidator - */ - protected $validator; - - /** - * @param LocaleRepository $localeRepoCLDR - * @param LanguageInterface[] $languages - * @param CurrencyCommandValidator $validator - */ - public function __construct( - LocaleRepository $localeRepoCLDR, - array $languages, - CurrencyCommandValidator $validator - ) { - $this->localeRepoCLDR = $localeRepoCLDR; - $this->languages = $languages; - $this->validator = $validator; - } - - /** - * Associations conversion rate to given shop ids. - * - * @param Currency $entity - * @param array $shopIds - */ - protected function associateConversionRateToShops(Currency $entity, array $shopIds) - { - $columnsToUpdate = []; - foreach ($shopIds as $shopId) { - $columnsToUpdate[$shopId] = [ - 'conversion_rate' => $entity->conversion_rate, - ]; - } - - $this->updateMultiStoreColumns($entity, $columnsToUpdate); - } - - /** - * @param Currency $entity - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - * @throws \PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException - */ - protected function refreshLocalizedData(Currency $entity) - { - $languagesData = []; - foreach ($this->languages as $language) { - $languagesData[] = [ - 'id_lang' => $language->getId(), - ]; - } - - //This method will insert the missing localized names/symbols and detect if the currency has been modified - $entity->refreshLocalizedCurrencyData($languagesData, $this->localeRepoCLDR); - } - - /** - * @param Currency $entity - * @param array $localizedTransformations - * - * @throws LanguageNotFoundException - */ - protected function applyPatternTransformations(Currency $entity, array $localizedTransformations) - { - $transformer = new PatternTransformer(); - $localizedPatterns = []; - foreach ($localizedTransformations as $langId => $transformationType) { - if (empty($transformationType)) { - continue; - } - - $languageCurrencyPattern = $this->getCurrencyPatternByLanguageId($langId); - $localizedPatterns[$langId] = $transformer->transform($languageCurrencyPattern, $transformationType); - } - $entity->setLocalizedPatterns($localizedPatterns); - } - - /** - * @param Currency $entity - * @param AddCurrencyCommand $command - * - * @throws CannotCreateCurrencyException - * @throws LanguageNotFoundException - * @throws LocalizationException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - protected function addEntity(Currency $entity, AddCurrencyCommand $command) - { - $entity->iso_code = $command->getIsoCode()->getValue(); - $entity->active = $command->isEnabled(); - $entity->deleted = false; - $entity->conversion_rate = $command->getExchangeRate()->getValue(); - - // When creating a currency we reset the fields even if empty (then they will be generated by refreshLocalizedData) - $entity->setLocalizedNames($command->getLocalizedNames()); - $entity->setLocalizedSymbols($command->getLocalizedSymbols()); - $this->applyPatternTransformations($entity, $command->getLocalizedTransformations()); - - $this->refreshLocalizedData($entity); - $this->validateCurrency($entity); - - //IMPORTANT: specify that we want to save null values - if (false === $entity->save(true, true)) { - throw new CannotCreateCurrencyException('Failed to create new currency'); - } - - $this->associateWithShops($entity, $command->getShopIds()); - $this->associateConversionRateToShops($entity, $command->getShopIds()); - } - - /** - * @param Currency $entity - * @param EditCurrencyCommand $command - * - * @throws CannotUpdateCurrencyException - * @throws LanguageNotFoundException - * @throws LocalizationException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - protected function updateEntity(Currency $entity, EditCurrencyCommand $command) - { - if (null !== $command->getExchangeRate()) { - $entity->conversion_rate = $command->getExchangeRate()->getValue(); - } - if (null !== $command->getPrecision()) { - $entity->precision = $command->getPrecision()->getValue(); - } - $entity->active = $command->isEnabled(); - - if (!empty($command->getLocalizedNames())) { - $entity->setLocalizedNames($command->getLocalizedNames()); - } - if (!empty($command->getLocalizedSymbols())) { - $entity->setLocalizedSymbols($command->getLocalizedSymbols()); - } - if (!empty($command->getLocalizedTransformations())) { - $this->applyPatternTransformations($entity, $command->getLocalizedTransformations()); - } - - $this->refreshLocalizedData($entity); - $this->validateCurrency($entity); - - //IMPORTANT: specify that we want to save null values - if (false === $entity->update(true)) { - throw new CannotUpdateCurrencyException( - sprintf( - 'An error occurred when updating currency object with id "%s"', - $command->getCurrencyId()->getValue() - ) - ); - } - - if (!empty($command->getShopIds())) { - $this->associateWithShops($entity, $command->getShopIds()); - $this->associateConversionRateToShops($entity, $command->getShopIds()); - } - } - - /** - * @param Currency $currency - * - * @throws CurrencyConstraintException - * @throws PrestaShopException - */ - private function validateCurrency(Currency $currency): void - { - $this->validateLocalizedField($currency, 'name', CurrencyConstraintException::INVALID_NAME); - $this->validateLocalizedField($currency, 'symbol', CurrencyConstraintException::INVALID_SYMBOL); - $this->validateLocalizedField($currency, 'pattern', CurrencyConstraintException::INVALID_SYMBOL); - } - - /** - * @param Currency $currency - * @param string $propertyName - * @param int $errorCode - * - * @throws CurrencyConstraintException - * @throws PrestaShopException - */ - private function validateLocalizedField(Currency $currency, string $propertyName, int $errorCode): void - { - $localizedValues = $currency->{$propertyName}; - - foreach ($localizedValues as $langId => $value) { - if (true !== $currency->validateField($propertyName, $value, $langId)) { - throw new CurrencyConstraintException( - sprintf( - 'Invalid Currency localized property "%s" for language with id "%d"', - $propertyName, - $langId - ), - $errorCode - ); - } - } - } - - /** - * @param int $langId - * - * @return string - * - * @throws LanguageNotFoundException - */ - private function getCurrencyPatternByLanguageId(int $langId) - { - /** @var LanguageInterface $language */ - foreach ($this->languages as $language) { - if ($langId === $language->getId()) { - return $this->localeRepoCLDR->getLocale($language->getLocale())->getCurrencyPattern(); - } - } - - throw new LanguageNotFoundException(new LanguageId($langId)); - } -} diff --git a/src/Adapter/Currency/CommandHandler/AddOfficialCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/AddOfficialCurrencyHandler.php deleted file mode 100644 index e2d3a5e0..00000000 --- a/src/Adapter/Currency/CommandHandler/AddOfficialCurrencyHandler.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\AddCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotCreateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\Locale; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShopException; - -/** - * Adds a new currency. - * - * @internal - */ -final class AddOfficialCurrencyHandler extends AbstractCurrencyHandler implements AddCurrencyHandlerInterface -{ - /** - * @var CurrencyDataProviderInterface - */ - private $currencyDataProvider; - - /** - * @param LocaleRepository $localeRepoCLDR - * @param LanguageInterface[] $languages - * @param CurrencyCommandValidator $validator - * @param CurrencyDataProviderInterface $currencyDataProvider - */ - public function __construct( - LocaleRepository $localeRepoCLDR, - array $languages, - CurrencyCommandValidator $validator, - CurrencyDataProviderInterface $currencyDataProvider - ) { - parent::__construct($localeRepoCLDR, $languages, $validator); - $this->currencyDataProvider = $currencyDataProvider; - } - - /** - * {@inheritdoc} - * - * @throws CannotCreateCurrencyException - * @throws CurrencyConstraintException - * @throws CurrencyException - * @throws CurrencyNotFoundException - * @throws LocalizationException - * @throws LanguageNotFoundException - */ - public function handle(AddCurrencyCommand $command) - { - $this->validator->assertCurrencyIsNotAvailableInDatabase($command->getIsoCode()->getValue()); - - try { - $entity = $this->currencyDataProvider->getCurrencyByIsoCodeOrCreate($command->getIsoCode()->getValue()); - - $entity->unofficial = false; - $entity->numeric_iso_code = $this->findNumericIsoCodeFromAlphaCode($command->getIsoCode()->getValue()); - $entity->precision = $this->getPrecision($command); - - $this->addEntity($entity, $command); - } catch (PrestaShopException $exception) { - throw new CurrencyException('Failed to create new currency', 0, $exception); - } - - return new CurrencyId((int) $entity->id); - } - - /** - * @param AddCurrencyCommand $command - * - * @return int - */ - private function getPrecision(AddCurrencyCommand $command): int - { - if (null !== $command->getPrecision()) { - return $command->getPrecision()->getValue(); - } - - // CLDR locale give us the CLDR reference specification - $cldrLocale = $this->getCLDRLocale(); - // CLDR currency gives data from CLDR reference, for the given language - $cldrCurrency = $cldrLocale->getCurrency($command->getIsoCode()->getValue()); - - return $cldrCurrency->getDecimalDigits(); - } - - /** - * @param string $isoCode - * - * @return string - * - * @throws CurrencyNotFoundException - */ - private function findNumericIsoCodeFromAlphaCode($isoCode): string - { - $cldrLocale = $this->getCLDRLocale(); - $allCurrencies = $cldrLocale->getAllCurrencies(); - - $matchingRealCurrency = null; - foreach ($allCurrencies as $currencyData) { - if ($currencyData->getIsoCode() === $isoCode) { - return $currencyData->getNumericIsoCode(); - } - } - - throw new CurrencyNotFoundException(sprintf('ISO code "%s" does not match any currency in CLDR database', $isoCode)); - } - - /** - * Returns a CLDR locale, since they all contain the same info about currencies - * it doesn't matter which one is used so we return the one matching the first - * provided language. - * - * @return Locale - */ - private function getCLDRLocale() - { - /** @var LanguageInterface $language */ - $language = $this->languages[0]; - - return $this->localeRepoCLDR->getLocale($language->getLocale()); - } -} diff --git a/src/Adapter/Currency/CommandHandler/AddUnofficialCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/AddUnofficialCurrencyHandler.php deleted file mode 100644 index f43e90d4..00000000 --- a/src/Adapter/Currency/CommandHandler/AddUnofficialCurrencyHandler.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddUnofficialCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\AddUnofficialCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotCreateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\InvalidUnofficialCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShopException; - -/** - * Adds a new unofficial currency. - * - * @internal - */ -final class AddUnofficialCurrencyHandler extends AbstractCurrencyHandler implements AddUnofficialCurrencyHandlerInterface -{ - /** - * @var CurrencyDataProviderInterface - */ - private $currencyDataProvider; - - /** - * @param LocaleRepository $localeRepoCLDR - * @param LanguageInterface[] $languages - * @param CurrencyCommandValidator $validator - * @param CurrencyDataProviderInterface $currencyDataProvider - */ - public function __construct( - LocaleRepository $localeRepoCLDR, - array $languages, - CurrencyCommandValidator $validator, - CurrencyDataProviderInterface $currencyDataProvider - ) { - parent::__construct($localeRepoCLDR, $languages, $validator); - $this->currencyDataProvider = $currencyDataProvider; - } - - /** - * {@inheritdoc} - * - * @throws CannotCreateCurrencyException - * @throws CurrencyException - * @throws CurrencyConstraintException - * @throws InvalidUnofficialCurrencyException - * @throws LanguageNotFoundException - * @throws LocalizationException - */ - public function handle(AddUnofficialCurrencyCommand $command) - { - $this->validator->assertCurrencyIsNotInReference($command->getIsoCode()->getValue()); - $this->validator->assertCurrencyIsNotAvailableInDatabase($command->getIsoCode()->getValue()); - - try { - $entity = $this->currencyDataProvider->getCurrencyByIsoCodeOrCreate($command->getIsoCode()->getValue()); - - $entity->unofficial = true; - $entity->numeric_iso_code = null; - if (null !== $command->getPrecision()) { - $entity->precision = $command->getPrecision()->getValue(); - } - - $this->addEntity($entity, $command); - } catch (PrestaShopException $exception) { - throw new CurrencyException('Failed to create new currency', 0, $exception); - } - - return new CurrencyId((int) $entity->id); - } -} diff --git a/src/Adapter/Currency/CommandHandler/CurrencyCommandValidator.php b/src/Adapter/Currency/CommandHandler/CurrencyCommandValidator.php deleted file mode 100644 index 93658b4f..00000000 --- a/src/Adapter/Currency/CommandHandler/CurrencyCommandValidator.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Configuration; -use Currency; -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDisableDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\InvalidUnofficialCurrencyException; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; -use Shop; - -/** - * Validates that modifications managed via currency commands are valid and respect this domain - * specific rules (avoid duplicate currencies, remove default currency, ...). - */ -final class CurrencyCommandValidator -{ - /** - * @var LocaleRepository - */ - private $localeRepoCLDR; - - /** - * @var CurrencyDataProviderInterface - */ - private $currencyDataProvider; - - /** - * @var int - */ - private $defaultCurrencyId; - - /** - * @param LocaleRepository $localeRepoCLDR - * @param CurrencyDataProviderInterface $currencyDataProvider - * @param int $defaultCurrencyId - */ - public function __construct( - LocaleRepository $localeRepoCLDR, - CurrencyDataProviderInterface $currencyDataProvider, - int $defaultCurrencyId - ) { - $this->localeRepoCLDR = $localeRepoCLDR; - $this->currencyDataProvider = $currencyDataProvider; - $this->defaultCurrencyId = $defaultCurrencyId; - } - - /** - * @param string $isoCode - * - * @throws InvalidUnofficialCurrencyException - */ - public function assertCurrencyIsNotInReference(string $isoCode) - { - /* - * Every locale has the same list of currencies (even those defined in only one language) so it - * doesn't matter which one is used to perform this check. - */ - $locale = $this->localeRepoCLDR->getLocale('en'); - $cldrCurrency = $locale->getCurrency($isoCode); - if (null !== $cldrCurrency) { - throw new InvalidUnofficialCurrencyException(sprintf('Unofficial currency with iso code "%s" is invalid because it matches a currency from CLDR database', $isoCode), $isoCode); - } - } - - /** - * Throws an error if currency is available in the database (soft deleted currencies don't count) - * - * @param string $isoCode - * - * @throws CurrencyConstraintException - */ - public function assertCurrencyIsNotAvailableInDatabase(string $isoCode) - { - $currency = $this->currencyDataProvider->getCurrencyByIsoCode($isoCode); - - if (null !== $currency && !$currency->deleted) { - throw new CurrencyConstraintException(sprintf('Currency with iso code "%s" already exists and cannot be created', $isoCode), CurrencyConstraintException::CURRENCY_ALREADY_EXISTS); - } - } - - /** - * Prevents from default currency being disabled. - * - * @param EditCurrencyCommand $command - * - * @throws CannotDisableDefaultCurrencyException - */ - public function assertDefaultCurrencyIsNotBeingDisabled(EditCurrencyCommand $command) - { - if (!$command->isEnabled() && $command->getCurrencyId()->getValue() === $this->defaultCurrencyId) { - throw new CannotDisableDefaultCurrencyException(sprintf('Currency with id "%s" is the default currency and cannot be disabled.', $command->getCurrencyId()->getValue())); - } - } - - /** - * On each shop there might be different default currency. This function prevents from removing shop association - * from each shop and checks that the shop is not being disabled as well. - * - * @param Currency $currency - * @param EditCurrencyCommand $command - * - * @throws DefaultCurrencyInMultiShopException - */ - public function assertDefaultCurrencyIsNotBeingRemovedOrDisabledFromShop(Currency $currency, EditCurrencyCommand $command) - { - if (empty($command->getShopIds())) { - return; - } - $shopIds = $command->getShopIds(); - $allShopIds = Shop::getShops(false, null, true); - - foreach ($allShopIds as $shopId) { - $shopDefaultCurrencyId = (int) Configuration::get( - 'PS_CURRENCY_DEFAULT', - null, - null, - $shopId - ); - - if ((int) $currency->id !== $shopDefaultCurrencyId) { - continue; - } - - if (!in_array($shopId, $shopIds)) { - $shop = new Shop($shopId); - throw new DefaultCurrencyInMultiShopException($currency->getName(), $shop->name, sprintf('Currency with id %s cannot be unassigned from shop with id %s because its the default currency.', $currency->id, $shopId), DefaultCurrencyInMultiShopException::CANNOT_REMOVE_CURRENCY); - } - - if (!$command->isEnabled()) { - $shop = new Shop($shopId); - throw new DefaultCurrencyInMultiShopException($currency->getName(), $shop->name, sprintf('Currency with id %s cannot be disabled from shop with id %s because its the default currency.', $currency->id, $shopId), DefaultCurrencyInMultiShopException::CANNOT_DISABLE_CURRENCY); - } - } - } -} diff --git a/src/Adapter/Currency/CommandHandler/DeleteCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/DeleteCurrencyHandler.php deleted file mode 100644 index ab406115..00000000 --- a/src/Adapter/Currency/CommandHandler/DeleteCurrencyHandler.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Configuration; -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\DeleteCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\DeleteCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDeleteCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDeleteDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShopException; -use Shop; - -/** - * Class DeleteCurrencyHandler is responsible for handling the deletion of currency logic. - * - * @internal - */ -final class DeleteCurrencyHandler implements DeleteCurrencyHandlerInterface -{ - /** - * @var int - */ - private $defaultCurrencyId; - - /** - * @param int $defaultCurrencyId - */ - public function __construct($defaultCurrencyId) - { - $this->defaultCurrencyId = (int) $defaultCurrencyId; - } - - /** - * {@inheritdoc} - * - * @throws CurrencyException - */ - public function handle(DeleteCurrencyCommand $command) - { - $entity = new Currency($command->getCurrencyId()->getValue()); - - if (0 >= $entity->id) { - throw new CurrencyNotFoundException(sprintf('Currency object with id "%s" has not been found for deletion.', $command->getCurrencyId()->getValue())); - } - - $this->assertDefaultCurrencyIsNotBeingRemoved($command->getCurrencyId()->getValue()); - $this->assertDefaultCurrencyIsNotBeingRemovedFromAnyShop($entity); - - try { - if (false === $entity->delete()) { - throw new CannotDeleteCurrencyException(sprintf('Unable to delete currency object with id "%s"', $command->getCurrencyId()->getValue())); - } - } catch (PrestaShopException $e) { - throw new CurrencyException(sprintf('An error occurred when deleting Currency object with id "%s"', $command->getCurrencyId()->getValue()), 0, $e); - } - } - - /** - * @param int $currencyId - * - * @throws CannotDeleteDefaultCurrencyException - */ - private function assertDefaultCurrencyIsNotBeingRemoved($currencyId) - { - if ($currencyId === $this->defaultCurrencyId) { - throw new CannotDeleteDefaultCurrencyException(sprintf('Currency with id "%s" is the default currency and cannot be deleted.', $currencyId)); - } - } - - /** - * Prevents from removing the currency from any shop context. - * - * @param Currency $currency - * - * @throws DefaultCurrencyInMultiShopException - */ - private function assertDefaultCurrencyIsNotBeingRemovedFromAnyShop(Currency $currency) - { - $allShopIds = Shop::getShops(false, null, true); - - foreach ($allShopIds as $shopId) { - $shopDefaultCurrencyId = (int) Configuration::get( - 'PS_CURRENCY_DEFAULT', - null, - null, - $shopId - ); - - if ((int) $currency->id !== $shopDefaultCurrencyId) { - continue; - } - - $shop = new Shop($shopId); - throw new DefaultCurrencyInMultiShopException($currency->name, $shop->name, sprintf('Currency with id %s cannot be removed from shop with id %s because its the default currency.', $currency->id, $shopId), DefaultCurrencyInMultiShopException::CANNOT_REMOVE_CURRENCY); - } - } -} diff --git a/src/Adapter/Currency/CommandHandler/EditOfficialCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/EditOfficialCurrencyHandler.php deleted file mode 100644 index ee33f9cd..00000000 --- a/src/Adapter/Currency/CommandHandler/EditOfficialCurrencyHandler.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\EditCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDisableDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotUpdateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShopException; - -/** - * Class EditOfficialCurrencyHandler is responsible for updating currencies. - * - * @internal - */ -final class EditOfficialCurrencyHandler extends AbstractCurrencyHandler implements EditCurrencyHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotDisableDefaultCurrencyException - * @throws CannotUpdateCurrencyException - * @throws CurrencyException - * @throws CurrencyNotFoundException - * @throws DefaultCurrencyInMultiShopException - * @throws LocalizationException - * @throws LanguageNotFoundException - */ - public function handle(EditCurrencyCommand $command) - { - try { - $entity = new Currency($command->getCurrencyId()->getValue()); - if (0 >= $entity->id) { - throw new CurrencyNotFoundException(sprintf('Currency object with id "%s" was not found for currency update', $command->getCurrencyId()->getValue())); - } - $this->verify($entity, $command); - $this->updateEntity($entity, $command); - } catch (PrestaShopException $exception) { - throw new CurrencyException(sprintf('An error occurred when updating currency object with id "%s"', $command->getCurrencyId()->getValue()), 0, $exception); - } - } - - /** - * @param Currency $entity - * @param EditCurrencyCommand $command - * - * @throws CannotDisableDefaultCurrencyException - * @throws DefaultCurrencyInMultiShopException - */ - private function verify(Currency $entity, EditCurrencyCommand $command) - { - $this->validator->assertDefaultCurrencyIsNotBeingDisabled($command); - $this->validator->assertDefaultCurrencyIsNotBeingRemovedOrDisabledFromShop($entity, $command); - } -} diff --git a/src/Adapter/Currency/CommandHandler/EditUnofficialCurrencyHandler.php b/src/Adapter/Currency/CommandHandler/EditUnofficialCurrencyHandler.php deleted file mode 100644 index 9205c282..00000000 --- a/src/Adapter/Currency/CommandHandler/EditUnofficialCurrencyHandler.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditUnofficialCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\EditUnofficialCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDisableDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotUpdateCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\InvalidUnofficialCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShopException; - -/** - * Class EditUnofficialCurrencyHandler is responsible for updating unofficial currencies. - * - * @internal - */ -final class EditUnofficialCurrencyHandler extends AbstractCurrencyHandler implements EditUnofficialCurrencyHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotDisableDefaultCurrencyException - * @throws CannotUpdateCurrencyException - * @throws CurrencyException - * @throws CurrencyNotFoundException - * @throws DefaultCurrencyInMultiShopException - * @throws LocalizationException - * @throws LanguageNotFoundException - */ - public function handle(EditUnofficialCurrencyCommand $command) - { - try { - $entity = new Currency($command->getCurrencyId()->getValue()); - if (0 >= $entity->id) { - throw new CurrencyNotFoundException(sprintf('Currency object with id "%s" was not found for currency update', $command->getCurrencyId()->getValue())); - } - $this->verify($entity, $command); - - if (null !== $command->getIsoCode()) { - $entity->iso_code = $command->getIsoCode()->getValue(); - } - $this->updateEntity($entity, $command); - } catch (PrestaShopException $exception) { - throw new CurrencyException(sprintf('An error occurred when updating currency object with id "%s"', $command->getCurrencyId()->getValue()), 0, $exception); - } - } - - /** - * @param Currency $entity - * @param EditUnofficialCurrencyCommand $command - * - * @throws CannotDisableDefaultCurrencyException - * @throws CurrencyConstraintException - * @throws DefaultCurrencyInMultiShopException - * @throws InvalidUnofficialCurrencyException - */ - private function verify(Currency $entity, EditUnofficialCurrencyCommand $command) - { - $this->validator->assertDefaultCurrencyIsNotBeingDisabled($command); - if (null !== $command->getIsoCode()) { - $this->validator->assertCurrencyIsNotInReference($command->getIsoCode()->getValue()); - if ($entity->iso_code !== $command->getIsoCode()->getValue()) { - $this->validator->assertCurrencyIsNotAvailableInDatabase($command->getIsoCode()->getValue()); - } - } - $this->validator->assertDefaultCurrencyIsNotBeingRemovedOrDisabledFromShop($entity, $command); - } -} diff --git a/src/Adapter/Currency/CommandHandler/RefreshExchangeRatesHandler.php b/src/Adapter/Currency/CommandHandler/RefreshExchangeRatesHandler.php deleted file mode 100644 index c2cad8b8..00000000 --- a/src/Adapter/Currency/CommandHandler/RefreshExchangeRatesHandler.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\RefreshExchangeRatesCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\RefreshExchangeRatesHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotRefreshExchangeRatesException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; - -/** - * Class RefreshExchangeRatesHandler is responsible for refreshing currency exchange rates. - * - * @internal - */ -final class RefreshExchangeRatesHandler implements RefreshExchangeRatesHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CurrencyException - */ - public function handle(RefreshExchangeRatesCommand $command) - { - $error = Currency::refreshCurrencies(); - - if ($error) { - throw new CannotRefreshExchangeRatesException($error); - } - } -} diff --git a/src/Adapter/Currency/CommandHandler/ToggleCurrencyStatusHandler.php b/src/Adapter/Currency/CommandHandler/ToggleCurrencyStatusHandler.php deleted file mode 100644 index 6b125ff2..00000000 --- a/src/Adapter/Currency/CommandHandler/ToggleCurrencyStatusHandler.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use Configuration; -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleCurrencyStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\ToggleCurrencyStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDisableDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotToggleCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShopException; -use Shop; - -/** - * Class ToggleCurrencyStatusHandler is responsible for toggling currency status. - * - * @internal - */ -final class ToggleCurrencyStatusHandler implements ToggleCurrencyStatusHandlerInterface -{ - /** - * @var int - */ - private $defaultCurrencyId; - - /** - * @param int $defaultCurrencyId - */ - public function __construct($defaultCurrencyId) - { - $this->defaultCurrencyId = (int) $defaultCurrencyId; - } - - /** - * {@inheritdoc} - * - * @throws CurrencyException - */ - public function handle(ToggleCurrencyStatusCommand $command) - { - $entity = new Currency($command->getCurrencyId()->getValue()); - - if (0 >= $entity->id) { - throw new CurrencyNotFoundException(sprintf('Currency object with id "%s" has not been found for toggling.', $command->getCurrencyId()->getValue())); - } - - if ($entity->active) { - $this->assertDefaultCurrencyIsNotBeingDisabled($entity); - $this->assertDefaultCurrencyIsNotBeingDisabledFromAnyShop($entity); - } - - try { - if (false === $entity->toggleStatus()) { - throw new CannotToggleCurrencyException(sprintf('Unable to toggle Currency with id "%s"', $command->getCurrencyId()->getValue())); - } - } catch (PrestaShopException $e) { - throw new CurrencyException(sprintf('An error occurred when toggling status for Currency object with id "%s"', $command->getCurrencyId()->getValue()), 0, $e); - } - } - - /** - * @param Currency $currency - * - * @throws CannotDisableDefaultCurrencyException - */ - private function assertDefaultCurrencyIsNotBeingDisabled(Currency $currency) - { - if ((int) $currency->id === $this->defaultCurrencyId) { - throw new CannotDisableDefaultCurrencyException(sprintf('Currency with id "%s" is the default currency and cannot be disabled.', $currency->id)); - } - } - - /** - * @param Currency $currency - * - * @throws DefaultCurrencyInMultiShopException - */ - private function assertDefaultCurrencyIsNotBeingDisabledFromAnyShop(Currency $currency) - { - $allShopIds = Shop::getShops(false, null, true); - - foreach ($allShopIds as $shopId) { - $shopDefaultCurrencyId = (int) Configuration::get( - 'PS_CURRENCY_DEFAULT', - null, - null, - $shopId - ); - - if ((int) $currency->id !== $shopDefaultCurrencyId) { - continue; - } - - $shop = new Shop($shopId); - throw new DefaultCurrencyInMultiShopException($currency->name, $shop->name, sprintf('Currency with id %s cannot be disabled from shop with id %s because its the default currency.', $currency->id, $shopId), DefaultCurrencyInMultiShopException::CANNOT_DISABLE_CURRENCY); - } - } -} diff --git a/src/Adapter/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandler.php b/src/Adapter/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandler.php deleted file mode 100644 index 90d457cd..00000000 --- a/src/Adapter/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandler.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\CommandHandler; - -use CronJobs; -use Db; -use Exception; -use Module; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Entity\DbQuery; -use PrestaShop\PrestaShop\Adapter\Shop\ShopUrlDataProvider; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleExchangeRateAutomatizationCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler\ToggleExchangeRateAutomatizationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\AutomateExchangeRatesUpdateException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShopException; -use Shop; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -/** - * Class ToggleExchangeRateAutomatizationHandler is responsible for turning on or off the setting - if its on then - * in CronJobs module it creates new record with url which points to the script which is being executed at certain time - * of period. If the setting is off then it removes that record. - * - * @todo: an issue with multi-store cron task scheduler. - * - * @internal - */ -final class ToggleExchangeRateAutomatizationHandler implements ToggleExchangeRateAutomatizationHandlerInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var Shop - */ - private $contextShop; - - /** - * @var bool - */ - private $isCronJobModuleInstalled; - - /** - * @var ShopUrlDataProvider - */ - private $shopUrlDataProvider; - - /** - * @var string - */ - private $adminBaseUrl; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param Configuration $configuration - * @param Shop $contextShop - * @param ShopUrlDataProvider $shopUrlDataProvider - * @param TranslatorInterface $translator - * @param bool $isCronJobModuleInstalled - * @param string $adminBaseUrl - * @param string $dbPrefix - */ - public function __construct( - Configuration $configuration, - Shop $contextShop, - ShopUrlDataProvider $shopUrlDataProvider, - TranslatorInterface $translator, - $isCronJobModuleInstalled, - $adminBaseUrl, - $dbPrefix - ) { - $this->configuration = $configuration; - $this->contextShop = $contextShop; - $this->isCronJobModuleInstalled = $isCronJobModuleInstalled; - $this->shopUrlDataProvider = $shopUrlDataProvider; - $this->adminBaseUrl = $adminBaseUrl; - $this->dbPrefix = $dbPrefix; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - * - * @throws CurrencyException - */ - public function handle(ToggleExchangeRateAutomatizationCommand $command) - { - if (!$this->isCronJobModuleInstalled) { - throw new AutomateExchangeRatesUpdateException('Live exchange rates feature cannot be modified because "cronjob" module is not installed', AutomateExchangeRatesUpdateException::CRON_TASK_MANAGER_MODULE_NOT_INSTALLED); - } - - $this->configuration->restrictUpdatesTo($this->contextShop); - - $cronId = (int) $this->configuration->get('PS_ACTIVE_CRONJOB_EXCHANGE_RATE'); - $thereIsOneCronRunning = ($cronId !== 0); - - try { - if ($thereIsOneCronRunning && $command->exchangeRateStatus()) { - $this->removeConfigurationIfNotFoundOrIsDeactivated($cronId); - - return; - } - - if (!$thereIsOneCronRunning && $command->exchangeRateStatus()) { - $this->enableExchangeRatesScheduler(); - - return; - } - - if ($thereIsOneCronRunning && !$command->exchangeRateStatus()) { - $this->disableExchangeRatesScheduler($cronId); - - return; - } - } catch (Exception $exception) { - throw new CurrencyException('An unexpected error occurred when trying to update live exchange rates', 0, $exception); - } - } - - /** - * @return string - * - * @throws PrestaShopException - */ - private function getCronUrl() - { - $protocol = Tools::getShopProtocol(); - $shopDomain = $this->shopUrlDataProvider->getMainShopUrl()->domain; - $cronFileLink = sprintf( - 'cron_currency_rates.php?secure_key=%s', - md5($this->configuration->get('_COOKIE_KEY_') . $this->configuration->get('PS_SHOP_NAME')) - ); - - return $protocol . $shopDomain . $this->adminBaseUrl . $cronFileLink; - } - - /** - * @param string $cronUrl - * - * @return bool - * - * @throws Exception - */ - private function createCronJob($cronUrl) - { - /** @var CronJobs $cronJobsModule */ - $cronJobsModule = Module::getInstanceByName('cronjobs'); - - $isCronAdded = $cronJobsModule->addOneShotTask( - $cronUrl, - $this->translator->trans( - 'Live exchange Rate for %shop_name%', - [ - '%shop_name%' => $this->configuration->get('PS_SHOP_NAME'), - ], - 'Admin.International.Feature' - ) - ); - - $this->configuration->set('PS_ACTIVE_CRONJOB_EXCHANGE_RATE', Db::getInstance()->Insert_ID()); - - return $isCronAdded; - } - - /** - * It checks if the given cronjob exists or is active. If it does not exist or it is not active when the configura - * tion value is being reset. - * - * @param int $cronId - * - * @throws Exception - */ - private function removeConfigurationIfNotFoundOrIsDeactivated($cronId) - { - $query = new DbQuery(); - $query - ->select('*') - ->from('cronjobs') - ->where('`id_cronjob`=' . (int) $cronId) - ; - - /** @var array $row */ - $row = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($query); - - if (!is_array($row) || empty($row['active'])) { - $this->configuration->set('PS_ACTIVE_CRONJOB_EXCHANGE_RATE', 0); - } - } - - /** - * Creates new cronjob for exchange rates auto update. - * - * @throws PrestaShopException - * @throws AutomateExchangeRatesUpdateException - * @throws Exception - */ - private function enableExchangeRatesScheduler() - { - $cronUrl = $this->getCronUrl(); - - if (false === $this->createCronJob($cronUrl)) { - throw new AutomateExchangeRatesUpdateException('Failed to create a cron task for live exchange rate update', AutomateExchangeRatesUpdateException::CRON_TASK_CREATION_FAILED); - } - } - - /** - * Removes given cronjob from configuration and also from cronjobs table. - * - * @param int $cronId - * - * @throws Exception - */ - private function disableExchangeRatesScheduler($cronId) - { - $this->configuration->set('PS_ACTIVE_CRONJOB_EXCHANGE_RATE', 0); - - Db::getInstance()->execute( - 'DELETE FROM ' . $this->dbPrefix . 'cronjobs WHERE `id_cronjob`=' . (int) $cronId - ); - } -} diff --git a/src/Adapter/Currency/CurrencyDataProvider.php b/src/Adapter/Currency/CurrencyDataProvider.php deleted file mode 100644 index 6e7282b0..00000000 --- a/src/Adapter/Currency/CurrencyDataProvider.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency; - -use Currency; -use Exception; -use Language; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; - -/** - * This class will provide data from DB / ORM about Currency. - */ -class CurrencyDataProvider implements CurrencyDataProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var int - */ - private $shopId; - - /** @var Currency */ - private $defaultCurrency; - - /** - * @param ConfigurationInterface $configuration - * @param int $shopId - */ - public function __construct(ConfigurationInterface $configuration, $shopId) - { - $this->configuration = $configuration; - $this->shopId = $shopId; - } - - /** - * {@inheritdoc} - */ - public function getCurrencies($object = false, $active = true, $group_by = false) - { - return Currency::getCurrencies($object = false, $active = true, $group_by = false); - } - - /** - * {@inheritdoc} - */ - public function findAll($currentShopOnly = true) - { - return Currency::findAll(true, false, $currentShopOnly); - } - - /** - * {@inheritdoc} - */ - public function findAllInstalled() - { - return Currency::findAllInstalled(); - } - - /** - * {@inheritdoc} - */ - public function getCurrencyByIsoCode($isoCode, $idLang = null) - { - $currencyId = Currency::getIdByIsoCode($isoCode, 0, false, true); - if (!$currencyId) { - return null; - } - - if (empty($idLang)) { - $idLang = $this->configuration->get('PS_LANG_DEFAULT'); - } - - return new Currency($currencyId, $idLang); - } - - /** - * @param string $isoCode - * @param string $locale - * - * @return Currency|null - */ - public function getCurrencyByIsoCodeAndLocale($isoCode, $locale) - { - $idLang = Language::getIdByLocale($locale, true); - - return $this->getCurrencyByIsoCode($isoCode, $idLang); - } - - /** - * {@inheritdoc} - */ - public function getCurrencyByIsoCodeOrCreate($isoCode, $idLang = null) - { - // Soft deleted currencies are not kept duplicated any more, so if one try to recreate it the one in database is reused - $currency = $this->getCurrencyByIsoCode($isoCode, $idLang); - if (null === $currency) { - if (null === $idLang) { - $idLang = $this->configuration->get('PS_LANG_DEFAULT'); - } - $currency = new Currency(null, $idLang); - } - - return $currency; - } - - /** - * {@inheritdoc} - */ - public function saveCurrency(Currency $currencyEntity) - { - if (false === $currencyEntity->save()) { - throw new Exception('Failed saving Currency entity'); - } - } - - /** - * {@inheritdoc} - */ - public function getCurrencyById($currencyId) - { - return new Currency($currencyId); - } - - /** - * {@inheritdoc} - */ - public function getDefaultCurrencyIsoCode() - { - return $this->getDefaultCurrency()->iso_code; - } - - /** - * Returns default Currency set in Configuration - * - * @return Currency - */ - public function getDefaultCurrency() - { - if (null === $this->defaultCurrency) { - $this->defaultCurrency = new Currency((int) $this->configuration->get('PS_CURRENCY_DEFAULT'), null, $this->shopId); - } - - return $this->defaultCurrency; - } -} diff --git a/src/Adapter/Currency/CurrencyManager.php b/src/Adapter/Currency/CurrencyManager.php deleted file mode 100644 index 25d6f7d8..00000000 --- a/src/Adapter/Currency/CurrencyManager.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency; - -use Currency; -use ObjectModel; -use Shop; - -/** - * Class CurrencyManager is responsible for dealing with currency data using legacy classes. - */ -class CurrencyManager -{ - /** - * Updates currency data after default currency has changed. - */ - public function updateDefaultCurrency() - { - /* Set conversion rate of default currency to 1 */ - ObjectModel::updateMultishopTable('Currency', ['conversion_rate' => 1], 'a.id_currency'); - - $tmpContext = Shop::getContext(); - if ($tmpContext == Shop::CONTEXT_GROUP) { - $tmpShop = Shop::getContextShopGroupID(); - } else { - $tmpShop = (int) Shop::getContextShopID(); - } - - foreach (Shop::getContextListShopID() as $shopId) { - Shop::setContext(Shop::CONTEXT_SHOP, (int) $shopId); - Currency::refreshCurrencies(); - } - - Shop::setContext($tmpContext, $tmpShop); - } -} diff --git a/src/Adapter/Currency/QueryHandler/GetCurrencyExchangeRateHandler.php b/src/Adapter/Currency/QueryHandler/GetCurrencyExchangeRateHandler.php deleted file mode 100644 index 0520b9af..00000000 --- a/src/Adapter/Currency/QueryHandler/GetCurrencyExchangeRateHandler.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\QueryHandler; - -use PrestaShop\PrestaShop\Core\Currency\Exception\CurrencyFeedException; -use PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\ExchangeRateNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler\GetCurrencyExchangeRateHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ExchangeRate; - -/** - * Class GetCurrencyExchangeRateHandler handles the GetCurrencyExchangeRate query - * and returns the exchange rate of a specified currency via a ExchangeRate value object. - */ -class GetCurrencyExchangeRateHandler implements GetCurrencyExchangeRateHandlerInterface -{ - /** @var ExchangeRateProvider */ - private $exchangeRateProvider; - - /** - * @param ExchangeRateProvider $exchangeRateProvider - */ - public function __construct(ExchangeRateProvider $exchangeRateProvider) - { - $this->exchangeRateProvider = $exchangeRateProvider; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCurrencyExchangeRate $query) - { - try { - $currencyExchangeRate = $this->exchangeRateProvider->getExchangeRate($query->getIsoCode()->getValue()); - } catch (CurrencyFeedException $e) { - throw new ExchangeRateNotFoundException(sprintf('Exchange rate for Currency with iso code %s was not found', $query->getIsoCode()->getValue()), 0, $e); - } - - return new ExchangeRate($currencyExchangeRate); - } -} diff --git a/src/Adapter/Currency/QueryHandler/GetCurrencyForEditingHandler.php b/src/Adapter/Currency/QueryHandler/GetCurrencyForEditingHandler.php deleted file mode 100644 index 95c2c2d7..00000000 --- a/src/Adapter/Currency/QueryHandler/GetCurrencyForEditingHandler.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\QueryHandler; - -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyForEditing; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler\GetCurrencyForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\EditableCurrency; -use PrestaShop\PrestaShop\Core\Localization\Currency\PatternTransformer; - -/** - * Class GetCurrencyForEditingHandler is responsible for retrieving required data used in currency form. - * - * @internal - */ -final class GetCurrencyForEditingHandler implements GetCurrencyForEditingHandlerInterface -{ - /** - * @var int - */ - private $contextShopId; - - /** - * @param int $contextShopId - */ - public function __construct($contextShopId) - { - $this->contextShopId = $contextShopId; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCurrencyForEditing $query) - { - $entity = new Currency( - $query->getCurrencyId()->getValue(), - null, - $this->contextShopId - ); - - if (0 >= $entity->id) { - throw new CurrencyNotFoundException(sprintf('Currency object with id "%s" was not found for editing', $query->getCurrencyId()->getValue())); - } - - $transformer = new PatternTransformer(); - $transformations = []; - foreach ($entity->getLocalizedPatterns() as $langId => $pattern) { - $transformations[$langId] = !empty($pattern) ? $transformer->getTransformationType($pattern) : ''; - } - - return new EditableCurrency( - $entity->id, - $entity->iso_code, - $entity->getLocalizedNames(), - $entity->getLocalizedSymbols(), - $transformations, - $entity->conversion_rate, - $entity->precision, - $entity->active, - $entity->unofficial, - $entity->getAssociatedShops() - ); - } -} diff --git a/src/Adapter/Currency/QueryHandler/GetReferenceCurrencyHandler.php b/src/Adapter/Currency/QueryHandler/GetReferenceCurrencyHandler.php deleted file mode 100644 index 6b301675..00000000 --- a/src/Adapter/Currency/QueryHandler/GetReferenceCurrencyHandler.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Currency\QueryHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetReferenceCurrency; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler\GetReferenceCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ReferenceCurrency; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\CurrencyInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; - -class GetReferenceCurrencyHandler implements GetReferenceCurrencyHandlerInterface -{ - /** - * @var LocaleRepository - */ - private $localeRepository; - - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var LanguageInterface[] - */ - private $languages; - - /** - * @param LocaleRepository $localeRepository - * @param CommandBusInterface $queryBus - * @param array $languages - */ - public function __construct( - LocaleRepository $localeRepository, - CommandBusInterface $queryBus, - array $languages - ) { - $this->localeRepository = $localeRepository; - $this->queryBus = $queryBus; - $this->languages = $languages; - } - - /** - * {@inheritdoc} - */ - public function handle(GetReferenceCurrency $query): ReferenceCurrency - { - $localizedNames = []; - $localizedSymbols = []; - $localizedPatterns = []; - $currency = null; - /** @var LanguageInterface $language */ - foreach ($this->languages as $language) { - $locale = $this->localeRepository->getLocale($language->getLocale()); - $localeCurrency = $locale->getCurrency($query->getIsoCode()->getValue()); - if (null !== $localeCurrency) { - $currency = $localeCurrency; - $localizedNames[$language->getId()] = $localeCurrency->getDisplayName(); - $localizedSymbols[$language->getId()] = $localeCurrency->getSymbol(CurrencyInterface::SYMBOL_TYPE_NARROW) ?: $localeCurrency->getIsoCode(); - } else { - $localizedNames[$language->getId()] = $query->getIsoCode()->getValue(); - $localizedSymbols[$language->getId()] = $query->getIsoCode()->getValue(); - } - $localizedPatterns[$language->getId()] = $locale->getCurrencyPattern(); - } - - if (null === $currency) { - throw new CurrencyNotFoundException(sprintf('Can not find reference currency with ISO code %s', $query->getIsoCode()->getValue())); - } - - return new ReferenceCurrency( - $currency->getIsoCode(), - $currency->getNumericIsoCode(), - $localizedNames, - $localizedSymbols, - $localizedPatterns, - $currency->getDecimalDigits() - ); - } -} diff --git a/src/Adapter/Customer/CommandHandler/AbstractCustomerHandler.php b/src/Adapter/Customer/CommandHandler/AbstractCustomerHandler.php deleted file mode 100644 index 5b34ea1d..00000000 --- a/src/Adapter/Customer/CommandHandler/AbstractCustomerHandler.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\MissingCustomerRequiredFieldsException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Provides reusable methods for customer command handlers. - * - * @internal - */ -abstract class AbstractCustomerHandler -{ - /** - * @param CustomerId $customerId - * @param Customer $customer - * - * @throws CustomerNotFoundException - */ - protected function assertCustomerWasFound(CustomerId $customerId, Customer $customer) - { - if ($customer->id !== $customerId->getValue()) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found.', $customerId->getValue())); - } - } - - /** - * @param Customer $customer - * - * @throws MissingCustomerRequiredFieldsException - */ - protected function assertRequiredFieldsAreNotMissing(Customer $customer) - { - $errors = $customer->validateFieldsRequiredDatabase(); - - if (!empty($errors)) { - $missingFields = array_keys($errors); - - throw new MissingCustomerRequiredFieldsException($missingFields, sprintf('One or more required fields for customer are missing. Missing fields are: %s', implode(',', $missingFields))); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/AddCustomerHandler.php b/src/Adapter/Customer/CommandHandler/AddCustomerHandler.php deleted file mode 100644 index 7572933e..00000000 --- a/src/Adapter/Customer/CommandHandler/AddCustomerHandler.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Crypto\Hashing; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\AddCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\AddCustomerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerDefaultGroupAccessException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\DuplicateCustomerEmailException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\RequiredField; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Handles command that adds new customer - * - * @internal - */ -final class AddCustomerHandler extends AbstractCustomerHandler implements AddCustomerHandlerInterface -{ - /** - * @var Hashing - */ - private $hashing; - - /** - * @var string Value of legacy _COOKIE_KEY_ - */ - private $legacyCookieKey; - - /** - * @param Hashing $hashing - * @param string $legacyCookieKey - */ - public function __construct(Hashing $hashing, $legacyCookieKey) - { - $this->hashing = $hashing; - $this->legacyCookieKey = $legacyCookieKey; - } - - /** - * {@inheritdoc} - */ - public function handle(AddCustomerCommand $command) - { - $customer = new Customer(); - - $this->fillCustomerWithCommandData($customer, $command); - - // validateFieldsRequiredDatabase() below is using $_POST - // to check if required fields are set - $_POST[RequiredField::PARTNER_OFFERS] = $command->isPartnerOffersSubscribed(); - - $this->assertRequiredFieldsAreNotMissing($customer); - - if (false === $customer->validateFields(false)) { - throw new CustomerException('Customer contains invalid field values'); - } - - $this->assertCustomerWithGivenEmailDoesNotExist($command->getEmail()); - $this->assertCustomerCanAccessDefaultGroup($command); - - $customer->add(); - - return new CustomerId((int) $customer->id); - } - - /** - * @param Email $email - */ - private function assertCustomerWithGivenEmailDoesNotExist(Email $email) - { - $customer = new Customer(); - $customer->getByEmail($email->getValue()); - - if ($customer->id) { - throw new DuplicateCustomerEmailException($email, sprintf('Customer with email "%s" already exists', $email->getValue())); - } - } - - /** - * @param Customer $customer - * @param AddCustomerCommand $command - */ - private function fillCustomerWithCommandData(Customer $customer, AddCustomerCommand $command) - { - $apeCode = null !== $command->getApeCode() ? - $command->getApeCode()->getValue() : - null; - - $hashedPassword = $this->hashing->hash( - $command->getPassword()->getValue(), - $this->legacyCookieKey - ); - - $customer->firstname = $command->getFirstName()->getValue(); - $customer->lastname = $command->getLastName()->getValue(); - $customer->email = $command->getEmail()->getValue(); - $customer->passwd = $hashedPassword; - $customer->id_default_group = $command->getDefaultGroupId(); - $customer->groupBox = $command->getGroupIds(); - $customer->id_gender = $command->getGenderId(); - $customer->active = $command->isEnabled(); - $customer->optin = $command->isPartnerOffersSubscribed(); - $customer->birthday = $command->getBirthday()->getValue(); - $customer->id_shop = $command->getShopId(); - - // fill b2b customer fields - $customer->company = $command->getCompanyName(); - $customer->siret = $command->getSiretCode(); - $customer->ape = $apeCode; - $customer->website = $command->getWebsite(); - $customer->outstanding_allow_amount = $command->getAllowedOutstandingAmount(); - $customer->max_payment_days = $command->getMaxPaymentDays(); - $customer->id_risk = $command->getRiskId(); - } - - /** - * @param AddCustomerCommand $command - */ - private function assertCustomerCanAccessDefaultGroup(AddCustomerCommand $command) - { - if (!in_array($command->getDefaultGroupId(), $command->getGroupIds())) { - throw new CustomerDefaultGroupAccessException(sprintf('Customer default group with id "%s" must be in access groups', $command->getDefaultGroupId())); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/BulkDeleteCustomerHandler.php b/src/Adapter/Customer/CommandHandler/BulkDeleteCustomerHandler.php deleted file mode 100644 index d4c92197..00000000 --- a/src/Adapter/Customer/CommandHandler/BulkDeleteCustomerHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDeleteCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\BulkDeleteCustomerHandlerInterface; - -/** - * Handles command that deletes customers in bulk action. - * - * @internal - */ -final class BulkDeleteCustomerHandler extends AbstractCustomerHandler implements BulkDeleteCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteCustomerCommand $command) - { - foreach ($command->getCustomerIds() as $customerId) { - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - if ($command->getDeleteMethod()->isAllowedToRegisterAfterDelete()) { - $customer->delete(); - - continue; - } - - $customer->deleted = 1; - $customer->update(); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/BulkDisableCustomerHandler.php b/src/Adapter/Customer/CommandHandler/BulkDisableCustomerHandler.php deleted file mode 100644 index d69e760a..00000000 --- a/src/Adapter/Customer/CommandHandler/BulkDisableCustomerHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDisableCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\BulkDisableCustomerHandlerInterface; - -/** - * Handles command that disables customers in bulk action. - * - * @internal - */ -final class BulkDisableCustomerHandler extends AbstractCustomerHandler implements BulkDisableCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDisableCustomerCommand $command) - { - foreach ($command->getCustomerIds() as $customerId) { - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - $customer->active = false; - $customer->update(); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/BulkEnableCustomerHandler.php b/src/Adapter/Customer/CommandHandler/BulkEnableCustomerHandler.php deleted file mode 100644 index 444db4f0..00000000 --- a/src/Adapter/Customer/CommandHandler/BulkEnableCustomerHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkEnableCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\BulkEnableCustomerHandlerInterface; - -/** - * Handles command which enables given customers. - * - * @internal - */ -final class BulkEnableCustomerHandler extends AbstractCustomerHandler implements BulkEnableCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkEnableCustomerCommand $command) - { - foreach ($command->getCustomerIds() as $customerId) { - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - $customer->active = true; - $customer->update(); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/DeleteCustomerHandler.php b/src/Adapter/Customer/CommandHandler/DeleteCustomerHandler.php deleted file mode 100644 index 8745beed..00000000 --- a/src/Adapter/Customer/CommandHandler/DeleteCustomerHandler.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\DeleteCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\DeleteCustomerHandlerInterface; - -/** - * Handles delete customer command. - * - * @internal - */ -final class DeleteCustomerHandler extends AbstractCustomerHandler implements DeleteCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteCustomerCommand $command) - { - $customerId = $command->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - if ($command->getDeleteMethod()->isAllowedToRegisterAfterDelete()) { - $customer->delete(); - - return; - } - - // soft delete customer - // in order to forbid signing in again - $customer->deleted = 1; - $customer->update(); - } -} diff --git a/src/Adapter/Customer/CommandHandler/EditCustomerHandler.php b/src/Adapter/Customer/CommandHandler/EditCustomerHandler.php deleted file mode 100644 index f67af963..00000000 --- a/src/Adapter/Customer/CommandHandler/EditCustomerHandler.php +++ /dev/null @@ -1,254 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Crypto\Hashing; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\EditCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\EditCustomerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerDefaultGroupAccessException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\DuplicateCustomerEmailException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\RequiredField; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Handles commands which edits given customer with provided data. - * - * @internal - */ -final class EditCustomerHandler extends AbstractCustomerHandler implements EditCustomerHandlerInterface -{ - /** - * @var Hashing - */ - private $hashing; - - /** - * @var string Value of legacy _COOKIE_KEY_ - */ - private $legacyCookieKey; - - /** - * @param Hashing $hashing - * @param string $legacyCookieKey - */ - public function __construct(Hashing $hashing, $legacyCookieKey) - { - $this->hashing = $hashing; - $this->legacyCookieKey = $legacyCookieKey; - } - - /** - * {@inheritdoc} - */ - public function handle(EditCustomerCommand $command) - { - $customerId = $command->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - $this->assertCustomerWithUpdatedEmailDoesNotExist($customer, $command); - $this->assertCustomerCanAccessDefaultGroup($customer, $command); - - $this->updateCustomerWithCommandData($customer, $command); - - // validateFieldsRequiredDatabase() below is using $_POST - // to check if required fields are set - if ($command->isPartnerOffersSubscribed() !== null) { - $_POST[RequiredField::PARTNER_OFFERS] = $command->isPartnerOffersSubscribed(); - } elseif ($command->isNewsletterSubscribed() !== null) { - $_POST[RequiredField::NEWSLETTER] = $command->isNewsletterSubscribed(); - } - - // before validation, we need to get the list of customer mandatory fields from the database - // and set their current values (only if it is not being modified: if it is not in $_POST) - $requiredFields = $customer->getFieldsRequiredDatabase(); - foreach ($requiredFields as $field) { - if (!array_key_exists($field['field_name'], $_POST)) { - $_POST[$field['field_name']] = $customer->{$field['field_name']}; - } - } - - $this->assertRequiredFieldsAreNotMissing($customer); - - if (false === $customer->validateFields(false)) { - throw new CustomerException('Customer contains invalid field values'); - } - - if (false === $customer->update()) { - throw new CustomerException('Failed to update customer'); - } - } - - /** - * @param Customer $customer - * @param EditCustomerCommand $command - */ - private function updateCustomerWithCommandData(Customer $customer, EditCustomerCommand $command) - { - if (null !== $command->getGenderId()) { - $customer->id_gender = $command->getGenderId(); - } - - if (null !== $command->getFirstName()) { - $customer->firstname = $command->getFirstName()->getValue(); - } - - if (null !== $command->getLastName()) { - $customer->lastname = $command->getLastName()->getValue(); - } - - if (null !== $command->getEmail()) { - $customer->email = $command->getEmail()->getValue(); - } - - if (null !== $command->getPassword()) { - $hashedPassword = $this->hashing->hash( - $command->getPassword()->getValue(), - $this->legacyCookieKey - ); - - $customer->passwd = $hashedPassword; - } - - if (null !== $command->getBirthday()) { - $customer->birthday = $command->getBirthday()->getValue(); - } - - if (null !== $command->isEnabled()) { - $customer->active = $command->isEnabled(); - } - - if (null !== $command->isPartnerOffersSubscribed()) { - $customer->optin = $command->isPartnerOffersSubscribed(); - } - - if (null !== $command->getGroupIds()) { - $customer->groupBox = $command->getGroupIds(); - } - - if (null !== $command->getDefaultGroupId()) { - $customer->id_default_group = $command->getDefaultGroupId(); - } - - if (null !== $command->isNewsletterSubscribed()) { - $customer->newsletter = $command->isNewsletterSubscribed(); - } - - $this->updateCustomerB2bData($customer, $command); - } - - /** - * @param Customer $customer - * @param EditCustomerCommand $command - */ - private function updateCustomerB2bData(Customer $customer, EditCustomerCommand $command) - { - if (null !== $command->getCompanyName()) { - $customer->company = $command->getCompanyName(); - } - - if (null !== $command->getSiretCode()) { - $customer->siret = $command->getSiretCode(); - } - - if (null !== $command->getApeCode()) { - $customer->ape = $command->getApeCode()->getValue(); - } - - if (null !== $command->getWebsite()) { - $customer->website = $command->getWebsite(); - } - - if (null !== $command->getAllowedOutstandingAmount()) { - $customer->outstanding_allow_amount = $command->getAllowedOutstandingAmount(); - } - - if (null !== $command->getMaxPaymentDays()) { - $customer->max_payment_days = $command->getMaxPaymentDays(); - } - - if (null !== $command->getRiskId()) { - $customer->id_risk = $command->getRiskId(); - } - } - - /** - * @param Customer $customer - * @param EditCustomerCommand $command - */ - private function assertCustomerWithUpdatedEmailDoesNotExist(Customer $customer, EditCustomerCommand $command) - { - // if email is not being updated - // then assertion is not needed - if (null === $command->getEmail()) { - return; - } - - if ($command->getEmail()->isEqualTo(new Email($customer->email))) { - return; - } - - $customerByEmail = new Customer(); - $customerByEmail->getByEmail($command->getEmail()->getValue()); - - if ($customerByEmail->id) { - throw new DuplicateCustomerEmailException($command->getEmail(), sprintf('Customer with email "%s" already exists', $command->getEmail()->getValue())); - } - } - - /** - * @param Customer $customer - * @param EditCustomerCommand $command - */ - private function assertCustomerCanAccessDefaultGroup(Customer $customer, EditCustomerCommand $command) - { - // if neither default group - // nor group ids are being edited - // then no need to assert - if (null === $command->getDefaultGroupId() - || null === $command->getGroupIds() - ) { - return; - } - - $defaultGroupId = null !== $command->getDefaultGroupId() ? - $command->getDefaultGroupId() : - $customer->id_default_group - ; - $groupIds = null !== $command->getGroupIds() ? - $command->getGroupIds() : - $customer->getGroups() - ; - - if (!in_array($defaultGroupId, $groupIds)) { - throw new CustomerDefaultGroupAccessException(sprintf('Customer default group with id "%s" must be in access groups', $command->getDefaultGroupId())); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandler.php b/src/Adapter/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandler.php deleted file mode 100644 index 5d9e01aa..00000000 --- a/src/Adapter/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandler.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetPrivateNoteAboutCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\SetPrivateNoteAboutCustomerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; - -/** - * Handles command that saves private note for customer - * - * @internal - */ -final class SetPrivateNoteAboutCustomerHandler implements SetPrivateNoteAboutCustomerHandlerInterface -{ - /** - * @param SetPrivateNoteAboutCustomerCommand $command - */ - public function handle(SetPrivateNoteAboutCustomerCommand $command) - { - $customerId = $command->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - if ($customer->id !== $customerId->getValue()) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found.', $customerId->getValue())); - } - - $customer->note = $command->getPrivateNote(); - $customer->update(); - } -} diff --git a/src/Adapter/Customer/CommandHandler/SetRequiredFieldsForCustomerHandler.php b/src/Adapter/Customer/CommandHandler/SetRequiredFieldsForCustomerHandler.php deleted file mode 100644 index 0080481f..00000000 --- a/src/Adapter/Customer/CommandHandler/SetRequiredFieldsForCustomerHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetRequiredFieldsForCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\SetRequiredFieldsForCustomerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CannotSetRequiredFieldsForCustomerException; - -/** - * Handles command which sets required fields for customer. - * - * @internal - */ -final class SetRequiredFieldsForCustomerHandler implements SetRequiredFieldsForCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(SetRequiredFieldsForCustomerCommand $command) - { - $customer = new Customer(); - - if (!$customer->addFieldsRequiredDatabase($command->getRequiredFields())) { - throw new CannotSetRequiredFieldsForCustomerException(sprintf('Cannot set "%s" required fields for customer', implode(',', $command->getRequiredFields()))); - } - } -} diff --git a/src/Adapter/Customer/CommandHandler/TransformGuestToCustomerHandler.php b/src/Adapter/Customer/CommandHandler/TransformGuestToCustomerHandler.php deleted file mode 100644 index d6c3e4f3..00000000 --- a/src/Adapter/Customer/CommandHandler/TransformGuestToCustomerHandler.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\CommandHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\TransformGuestToCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler\TransformGuestToCustomerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerTransformationException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Handles guest to customer transformation command - * - * @internal - */ -final class TransformGuestToCustomerHandler implements TransformGuestToCustomerHandlerInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @param int $contextLangId - */ - public function __construct($contextLangId) - { - $this->contextLangId = $contextLangId; - } - - /** - * @param TransformGuestToCustomerCommand $command - */ - public function handle(TransformGuestToCustomerCommand $command) - { - $customerId = $command->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerExists($customerId, $customer); - $this->assertCustomerIsGuest($customer); - - if (!$customer->transformToCustomer($this->contextLangId)) { - throw new CustomerTransformationException(sprintf('Failed to transform guest into customer'), CustomerTransformationException::TRANSFORMATION_FAILED); - } - } - - /** - * @param CustomerId $customerId - * @param Customer $customer - * - * @throws CustomerNotFoundException - */ - private function assertCustomerExists(CustomerId $customerId, Customer $customer) - { - if ($customer->id !== $customerId->getValue()) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found', $customerId->getValue())); - } - } - - /** - * @param Customer $customer - * - * @throws CustomerTransformationException - */ - private function assertCustomerIsGuest(Customer $customer) - { - if (Customer::customerExists($customer->email)) { - throw new CustomerTransformationException(sprintf('Customer with id "%s" already exists as non-guest', $customer->id), CustomerTransformationException::CUSTOMER_IS_NOT_GUEST); - } - } -} diff --git a/src/Adapter/Customer/CustomerConfiguration.php b/src/Adapter/Customer/CustomerConfiguration.php deleted file mode 100644 index cfc08d34..00000000 --- a/src/Adapter/Customer/CustomerConfiguration.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class CustomerConfiguration is responsible for saving & loading customer configuration. - */ -class CustomerConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'redisplay_cart_at_login' => $this->configuration->getBoolean('PS_CART_FOLLOWING'), - 'send_email_after_registration' => $this->configuration->getBoolean('PS_CUSTOMER_CREATION_EMAIL'), - 'password_reset_delay' => $this->configuration->getInt('PS_PASSWD_TIME_FRONT'), - 'enable_b2b_mode' => $this->configuration->getBoolean('PS_B2B_ENABLE'), - 'ask_for_birthday' => $this->configuration->getBoolean('PS_CUSTOMER_BIRTHDATE'), - 'enable_offers' => $this->configuration->getBoolean('PS_CUSTOMER_OPTIN'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_CART_FOLLOWING', (int) $config['redisplay_cart_at_login']); - $this->configuration->set('PS_CUSTOMER_CREATION_EMAIL', (int) $config['send_email_after_registration']); - $this->configuration->set('PS_PASSWD_TIME_FRONT', (int) $config['password_reset_delay']); - $this->configuration->set('PS_B2B_ENABLE', (int) $config['enable_b2b_mode']); - $this->configuration->set('PS_CUSTOMER_BIRTHDATE', (int) $config['ask_for_birthday']); - $this->configuration->set('PS_CUSTOMER_OPTIN', (int) $config['enable_offers']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['redisplay_cart_at_login'], - $config['send_email_after_registration'], - $config['password_reset_delay'], - $config['enable_b2b_mode'], - $config['ask_for_birthday'], - $config['enable_offers'] - ); - } -} diff --git a/src/Adapter/Customer/CustomerDataProvider.php b/src/Adapter/Customer/CustomerDataProvider.php deleted file mode 100644 index 736ea74e..00000000 --- a/src/Adapter/Customer/CustomerDataProvider.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer; - -use Customer; -use Db; -use Symfony\Component\Process\Exception\LogicException; - -/** - * This class will provide data from DB / ORM about Customer. - */ -class CustomerDataProvider -{ - /** - * @param int $id - * - * @throws LogicException If the customer id is not set - * - * @return object customer - */ - public function getCustomer($id) - { - if (!$id) { - throw new LogicException('You need to provide a customer id', null, 5002); - } - - $customer = new Customer($id); - - return $customer; - } - - public function getIdByEmail(string $email) - { - $id = null; - $customers = Customer::getCustomersByEmail($email); - if (!empty($customers)) { - $id = current($customers)['id_customer']; - } - - return $id; - } - - /** - * @param int $customerId - * @param int $langId - * - * @return array - */ - public function getCustomerAddresses($customerId, $langId) - { - $customer = $this->getCustomer($customerId); - - return $customer->getAddresses($langId); - } - - /** - * Get Default Customer Group ID. - * - * @param int $idCustomer Customer ID - * - * @return mixed|string|null - */ - public function getDefaultGroupId($idCustomer) - { - return Customer::getDefaultGroupId($idCustomer); - } - - /** - * Provides customer messages - * - * @param int $customerId - */ - public function getCustomerMessages(int $customerId, ?int $orderId = null, ?int $limit = null) - { - $mainSql = 'SELECT cm.*, c.`firstname` AS cfirstname, c.`lastname` AS clastname, - e.`firstname` AS efirstname, e.`lastname` AS elastname - FROM ' . _DB_PREFIX_ . 'customer_thread ct - LEFT JOIN ' . _DB_PREFIX_ . 'customer_message cm - ON ct.id_customer_thread = cm.id_customer_thread - LEFT JOIN `' . _DB_PREFIX_ . 'customer` c - ON ct.`id_customer` = c.`id_customer` - LEFT OUTER JOIN `' . _DB_PREFIX_ . 'employee` e - ON e.`id_employee` = cm.`id_employee` - WHERE ct.id_customer = ' . $customerId; - - if ($orderId) { - $mainSql .= ' AND ct.`id_order` = ' . $orderId; - } - - $mainSql .= ' GROUP BY cm.id_customer_message - ORDER BY cm.date_add DESC'; - - $count = Db::getInstance()->executeS("SELECT COUNT(*) AS total FROM ($mainSql) AS messages"); - - if ($limit) { - $mainSql .= " LIMIT $limit"; - } - - return [ - 'total' => empty($count) ? 0 : (int) $count[0]['total'], - 'messages' => Db::getInstance()->executeS($mainSql), - ]; - } -} diff --git a/src/Adapter/Customer/CustomerDataSource.php b/src/Adapter/Customer/CustomerDataSource.php deleted file mode 100644 index 26a59aee..00000000 --- a/src/Adapter/Customer/CustomerDataSource.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer; - -use Customer; -use PrestaShop\PrestaShop\Core\Customer\CustomerDataSourceInterface; - -final class CustomerDataSource implements CustomerDataSourceInterface -{ - /** - * {@inheritdoc} - */ - public function hasCustomerWithEmail(string $email): bool - { - return Customer::customerExists($email, false, false); - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetCustomerCartsHandler.php b/src/Adapter/Customer/QueryHandler/GetCustomerCartsHandler.php deleted file mode 100644 index 90be229f..00000000 --- a/src/Adapter/Customer/QueryHandler/GetCustomerCartsHandler.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Cart; -use Currency; -use Customer; -use PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\AbstractCustomerHandler; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerCarts; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerCartsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\CartSummary; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; - -/** - * Handles GetCustomerCartsQuery using legacy object models - */ -final class GetCustomerCartsHandler extends AbstractCustomerHandler implements GetCustomerCartsHandlerInterface -{ - /** - * @var LocaleInterface - */ - private $locale; - - /** - * @param LocaleInterface $locale - */ - public function __construct( - LocaleInterface $locale - ) { - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCustomerCarts $query): array - { - $customerId = $query->getCustomerId(); - $this->assertCustomerWasFound($customerId, new Customer($customerId->getValue())); - - return $this->getCarts($customerId->getValue()); - } - - /** - * @param int $customerId - * - * @return array - * - * @throws LocalizationException - */ - private function getCarts(int $customerId): array - { - $carts = Cart::getCustomerCarts($customerId, false); - $summarizedCarts = []; - - foreach ($carts as $key => $customerCart) { - $cartId = (int) $customerCart['id_cart']; - $currency = new Currency((int) $customerCart['id_currency']); - $cart = new Cart($cartId); - - $summarizedCarts[] = new CartSummary( - $cart->id, - $cart->date_add, - $this->locale->formatPrice($cart->getOrderTotal(), $currency->iso_code) - ); - } - - return $summarizedCarts; - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetCustomerForAddressCreationHandler.php b/src/Adapter/Customer/QueryHandler/GetCustomerForAddressCreationHandler.php deleted file mode 100644 index 4c0d7e7a..00000000 --- a/src/Adapter/Customer/QueryHandler/GetCustomerForAddressCreationHandler.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerByEmailNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForAddressCreation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerForAddressCreationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\AddressCreationCustomerInformation; -use PrestaShopDatabaseException; - -/** - * Handles finding customer by email - */ -final class GetCustomerForAddressCreationHandler implements GetCustomerForAddressCreationHandlerInterface -{ - /** - * {@inheritdoc} - * - * @return AddressCreationCustomerInformation - * - * @throws CustomerByEmailNotFoundException - * @throws CustomerException - */ - public function handle(GetCustomerForAddressCreation $query): AddressCreationCustomerInformation - { - $email = $query->getCustomerEmail(); - - try { - $result = Customer::searchByName($email); - } catch (PrestaShopDatabaseException $e) { - throw new CustomerException(sprintf('Failed to fetch results for customers with email %s', $email)); - } - - if (empty($result)) { - throw new CustomerByEmailNotFoundException(sprintf('Failed to find customer with email %s', $email)); - } - - $customer = reset($result); - - $customerInformation = new AddressCreationCustomerInformation( - (int) $customer['id_customer'], - $customer['firstname'], - $customer['lastname'] - ); - - if (null !== $customer['company']) { - $customerInformation->setCompany($customer['company']); - } - - return $customerInformation; - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetCustomerForEditingHandler.php b/src/Adapter/Customer/QueryHandler/GetCustomerForEditingHandler.php deleted file mode 100644 index 516de51d..00000000 --- a/src/Adapter/Customer/QueryHandler/GetCustomerForEditingHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\EditableCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Birthday; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Handles command that gets customer for editing - * - * @internal - */ -final class GetCustomerForEditingHandler implements GetCustomerForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetCustomerForEditing $query) - { - $customerId = $query->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - if ($customer->id !== $customerId->getValue()) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found', $customerId->getValue())); - } - - $birthday = null === $customer->birthday ? - Birthday::createEmpty() : - new Birthday($customer->birthday) - ; - - return new EditableCustomer( - $customerId, - (int) $customer->id_gender, - new FirstName($customer->firstname), - new LastName($customer->lastname), - new Email($customer->email), - $birthday, - (bool) $customer->active, - (bool) $customer->optin, - (bool) $customer->newsletter, - $customer->getGroups(), - (int) $customer->id_default_group, - (string) $customer->company, - (string) $customer->siret, - (string) $customer->ape, - (string) $customer->website, - (float) $customer->outstanding_allow_amount, - (int) $customer->max_payment_days, - (int) $customer->id_risk - ); - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php b/src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php deleted file mode 100644 index d3d8bba6..00000000 --- a/src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php +++ /dev/null @@ -1,601 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Carrier; -use Cart; -use CartRule; -use Category; -use Context; -use Currency; -use Customer; -use CustomerThread; -use Db; -use Gender; -use Group; -use Language; -use Link; -use Order; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\AddressInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\BoughtProductInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\CartInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\DiscountInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\GeneralInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\GroupInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\LastConnectionInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\MessageInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrderInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrdersInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\PersonalInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ProductsInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ReferrerInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\SentEmailInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\Subscriptions; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewableCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewedProductInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use Product; -use Referrer; -use Shop; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * Handles commands which gets customer for viewing in Back Office. - * - * @internal - */ -final class GetCustomerForViewingHandler implements GetCustomerForViewingHandlerInterface -{ - /** - * @var LegacyContext - */ - private $context; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var Link - */ - private $link; - - /** - * @var Locale - */ - private $locale; - - /** - * @param TranslatorInterface $translator - * @param int $contextLangId - * @param Link $link - * @param Locale $locale - */ - public function __construct( - TranslatorInterface $translator, - $contextLangId, - Link $link, - Locale $locale - ) { - $this->context = new LegacyContext(); - $this->contextLangId = $contextLangId; - $this->translator = $translator; - $this->link = $link; - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCustomerForViewing $query) - { - $customerId = $query->getCustomerId(); - $customer = new Customer($customerId->getValue()); - - $this->assertCustomerWasFound($customerId, $customer); - - Context::getContext()->customer = $customer; - - return new ViewableCustomer( - $customerId, - $this->getGeneralInformation($customer), - $this->getPersonalInformation($customer), - $this->getCustomerOrders($customer), - $this->getCustomerCarts($customer), - $this->getCustomerProducts($customer), - $this->getCustomerMessages($customer), - $this->getCustomerDiscounts($customer), - $this->getLastEmailsSentToCustomer($customer), - $this->getLastCustomerConnections($customer), - $this->getCustomerGroups($customer), - $this->getCustomerReferrers($customer), - $this->getCustomerAddresses($customer) - ); - } - - /** - * @param Customer $customer - * - * @return GeneralInformation - */ - private function getGeneralInformation(Customer $customer) - { - return new GeneralInformation( - $customer->note, - Customer::customerExists($customer->email) - ); - } - - /** - * @param Customer $customer - * - * @return PersonalInformation - */ - private function getPersonalInformation(Customer $customer) - { - $customerStats = $customer->getStats(); - - $gender = new Gender($customer->id_gender, $this->contextLangId); - $socialTitle = $gender->name ?: $this->translator->trans('Unknown', [], 'Admin.Orderscustomers.Feature'); - - if ($customer->birthday && '0000-00-00' !== $customer->birthday) { - $birthday = sprintf( - $this->translator->trans('%1$d years old (birth date: %2$s)', [], 'Admin.Orderscustomers.Feature'), - $customerStats['age'], - Tools::displayDate($customer->birthday) - ); - } else { - $birthday = $this->translator->trans('Unknown', [], 'Admin.Orderscustomers.Feature'); - } - - $registrationDate = Tools::displayDate($customer->date_add, null, true); - $lastUpdateDate = Tools::displayDate($customer->date_upd, null, true); - $lastVisitDate = $customerStats['last_visit'] ? - Tools::displayDate($customerStats['last_visit'], null, true) : - $this->translator->trans('Never', [], 'Admin.Global'); - - $customerShop = new Shop($customer->id_shop); - $customerLanguage = new Language($customer->id_lang); - - $customerSubscriptions = new Subscriptions( - (bool) $customer->newsletter, - (bool) $customer->optin - ); - - return new PersonalInformation( - $customer->firstname, - $customer->lastname, - $customer->email, - $customer->isGuest(), - $socialTitle, - $birthday, - $registrationDate, - $lastUpdateDate, - $lastVisitDate, - $this->getCustomerRankBySales($customer->id), - $customerShop->name, - $customerLanguage->name, - $customerSubscriptions, - (bool) $customer->active - ); - } - - /** - * @param int $customerId - * - * @return int|null customer rank or null if customer is not ranked - */ - private function getCustomerRankBySales($customerId) - { - $sql = 'SELECT SUM(total_paid_real) FROM ' . _DB_PREFIX_ . 'orders WHERE id_customer = ' . (int) $customerId . ' AND valid = 1'; - - if ($totalPaid = Db::getInstance()->getValue($sql)) { - $sql = ' - SELECT SQL_CALC_FOUND_ROWS COUNT(*) - FROM ' . _DB_PREFIX_ . 'orders - WHERE valid = 1 - AND id_customer != ' . (int) $customerId . ' - GROUP BY id_customer - HAVING SUM(total_paid_real) > ' . (int) $totalPaid; - - Db::getInstance()->getValue($sql); - - return (int) Db::getInstance()->getValue('SELECT FOUND_ROWS()') + 1; - } - - return null; - } - - /** - * @param Customer $customer - * - * @return OrdersInformation - */ - private function getCustomerOrders(Customer $customer) - { - $validOrders = []; - $invalidOrders = []; - - $orders = Order::getCustomerOrders($customer->id, true); - $totalSpent = 0; - - foreach ($orders as $order) { - $order['total_paid_real_not_formated'] = $order['total_paid_real']; - $order['total_paid_real'] = $this->locale->formatPrice( - $order['total_paid_real'], - Currency::getIsoCodeById((int) $order['id_currency']) - ); - - if (!isset($order['order_state'])) { - $order['order_state'] = $this->translator->trans( - 'There is no status defined for this order.', - [], - 'Admin.Orderscustomers.Notification' - ); - } - - $customerOrderInformation = new OrderInformation( - (int) $order['id_order'], - Tools::displayDate($order['date_add']), - $order['payment'], - $order['order_state'], - (int) $order['nb_products'], - $order['total_paid_real'] - ); - - if ($order['valid']) { - $validOrders[] = $customerOrderInformation; - $totalSpent += $order['total_paid_real_not_formated'] / $order['conversion_rate']; - } else { - $invalidOrders[] = $customerOrderInformation; - } - } - - return new OrdersInformation( - $this->locale->formatPrice($totalSpent, $this->context->getContext()->currency->iso_code), - $validOrders, - $invalidOrders - ); - } - - /** - * @param Customer $customer - * - * @return CartInformation[] - */ - private function getCustomerCarts(Customer $customer) - { - $carts = Cart::getCustomerCarts($customer->id); - $customerCarts = []; - - foreach ($carts as $cart) { - $cart = new Cart((int) $cart['id_cart']); - Context::getContext()->cart = $cart; - - $currency = new Currency($cart->id_currency); - Context::getContext()->currency = $currency; - - $carrier = new Carrier($cart->id_carrier); - $summary = $cart->getSummaryDetails(); - - $customerCarts[] = new CartInformation( - sprintf('%06d', $cart->id), - Tools::displayDate($cart->date_add, null, true), - $this->locale->formatPrice($summary['total_price'], $currency->iso_code), - $carrier->name - ); - } - - Context::getContext()->currency = Currency::getDefaultCurrency(); - - return $customerCarts; - } - - /** - * @param Customer $customer - * - * @return ProductsInformation - */ - private function getCustomerProducts(Customer $customer) - { - $boughtProducts = []; - $viewedProducts = []; - - $products = $customer->getBoughtProducts(); - foreach ($products as $product) { - $boughtProducts[] = new BoughtProductInformation( - (int) $product['id_order'], - Tools::displayDate($product['date_add'], null, false), - $product['product_name'], - $product['product_quantity'] - ); - } - - $sql = ' - SELECT DISTINCT cp.id_product, c.id_cart, c.id_shop, cp.id_shop AS cp_id_shop - FROM ' . _DB_PREFIX_ . 'cart_product cp - JOIN ' . _DB_PREFIX_ . 'cart c ON (c.id_cart = cp.id_cart) - JOIN ' . _DB_PREFIX_ . 'product p ON (cp.id_product = p.id_product) - WHERE c.id_customer = ' . (int) $customer->id . ' - AND NOT EXISTS ( - SELECT 1 - FROM ' . _DB_PREFIX_ . 'orders o - JOIN ' . _DB_PREFIX_ . 'order_detail od ON (o.id_order = od.id_order) - WHERE product_id = cp.id_product AND o.valid = 1 AND o.id_customer = ' . (int) $customer->id . ' - ) - '; - - $viewedProductsData = Db::getInstance()->executeS($sql); - foreach ($viewedProductsData as $productData) { - $product = new Product( - $productData['id_product'], - false, - $this->contextLangId, - $productData['id_shop'] - ); - - if (!Validate::isLoadedObject($product)) { - continue; - } - - $productUrl = $this->link->getProductLink( - $product->id, - $product->link_rewrite, - Category::getLinkRewrite($product->id_category_default, $this->contextLangId), - null, - null, - $productData['cp_id_shop'] - ); - - $viewedProducts[] = new ViewedProductInformation( - (int) $product->id, - $product->name, - $productUrl - ); - } - - return new ProductsInformation( - $boughtProducts, - $viewedProducts - ); - } - - /** - * @param Customer $customer - * - * @return MessageInformation[] - */ - private function getCustomerMessages(Customer $customer) - { - $customerMessages = []; - $messages = CustomerThread::getCustomerMessages((int) $customer->id); - - $messageStatuses = [ - 'open' => $this->translator->trans('Open', [], 'Admin.Orderscustomers.Feature'), - 'closed' => $this->translator->trans('Closed', [], 'Admin.Orderscustomers.Feature'), - 'pending1' => $this->translator->trans('Pending 1', [], 'Admin.Orderscustomers.Feature'), - 'pending2' => $this->translator->trans('Pending 2', [], 'Admin.Orderscustomers.Feature'), - ]; - - foreach ($messages as $message) { - $status = isset($messageStatuses[$message['status']]) ? - $messageStatuses[$message['status']] : - $message['status']; - - $customerMessages[] = new MessageInformation( - (int) $message['id_customer_thread'], - substr(strip_tags(html_entity_decode($message['message'], ENT_NOQUOTES, 'UTF-8')), 0, 75), - $status, - Tools::displayDate($message['date_add'], null, true) - ); - } - - return $customerMessages; - } - - /** - * @param Customer $customer - * - * @return DiscountInformation[] - */ - private function getCustomerDiscounts(Customer $customer) - { - $discounts = CartRule::getCustomerCartRules($this->contextLangId, $customer->id, false, false); - $customerDiscounts = []; - - foreach ($discounts as $discount) { - $availableQuantity = $discount['quantity'] > 0 ? (int) $discount['quantity_for_user'] : 0; - - $customerDiscounts[] = new DiscountInformation( - (int) $discount['id_cart_rule'], - $discount['code'], - $discount['name'], - (bool) $discount['active'], - $availableQuantity - ); - } - - return $customerDiscounts; - } - - /** - * @param Customer $customer - * - * @return SentEmailInformation[] - */ - private function getLastEmailsSentToCustomer(Customer $customer) - { - $emails = $customer->getLastEmails(); - $customerEmails = []; - - foreach ($emails as $email) { - $customerEmails[] = new SentEmailInformation( - Tools::displayDate($email['date_add'], null, true), - $email['language'], - $email['subject'], - $email['template'] - ); - } - - return $customerEmails; - } - - /** - * @param Customer $customer - * - * @return LastConnectionInformation[] - */ - private function getLastCustomerConnections(Customer $customer) - { - $connections = $customer->getLastConnections(); - $lastConnections = []; - - if (!is_array($connections)) { - $connections = []; - } - - foreach ($connections as $connection) { - $httpReferer = $connection['http_referer'] ? - preg_replace('/^www./', '', parse_url($connection['http_referer'], PHP_URL_HOST)) : - $this->translator->trans('Direct link', [], 'Admin.Orderscustomers.Notification'); - - $lastConnections[] = new LastConnectionInformation( - $connection['id_connections'], - Tools::displayDate($connection['date_add']), - $connection['pages'], - $connection['time'], - $httpReferer, - $connection['ipaddress'] - ); - } - - return $lastConnections; - } - - /** - * @param Customer $customer - * - * @return GroupInformation[] - */ - private function getCustomerGroups(Customer $customer) - { - $groups = $customer->getGroups(); - $customerGroups = []; - - foreach ($groups as $groupId) { - $group = new Group($groupId); - - $customerGroups[] = new GroupInformation( - (int) $group->id, - $group->name[$this->contextLangId] - ); - } - - return $customerGroups; - } - - /** - * @param Customer $customer - * - * @return ReferrerInformation[] - */ - private function getCustomerReferrers(Customer $customer) - { - $referrers = Referrer::getReferrers($customer->id); - $customerReferrers = []; - - foreach ($referrers as $referrer) { - $customerReferrers[] = new ReferrerInformation( - Tools::displayDate($referrer['date_add'], null, true), - $referrer['name'], - $referrer['shop_name'] - ); - } - - return $customerReferrers; - } - - /** - * @param Customer $customer - * - * @return AddressInformation[] - */ - private function getCustomerAddresses(Customer $customer) - { - $addresses = $customer->getAddresses($this->contextLangId); - $customerAddresses = []; - - foreach ($addresses as $address) { - $company = $address['company'] ?: '--'; - $fullAddress = sprintf( - '%s %s %s %s', - $address['address1'], - $address['address2'] ?: '', - $address['postcode'], - $address['city'] - ); - - $customerAddresses[] = new AddressInformation( - (int) $address['id_address'], - $company, - sprintf('%s %s', $address['firstname'], $address['lastname']), - $fullAddress, - $address['country'], - (string) $address['phone'], - (string) $address['phone_mobile'] - ); - } - - return $customerAddresses; - } - - /** - * @param CustomerId $customerId - * @param Customer $customer - * - * @throws CustomerNotFoundException - */ - private function assertCustomerWasFound(CustomerId $customerId, Customer $customer) - { - if (!$customer->id) { - throw new CustomerNotFoundException($customerId, sprintf('Customer with id "%s" was not found.', $customerId->getValue())); - } - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetCustomerOrdersHandler.php b/src/Adapter/Customer/QueryHandler/GetCustomerOrdersHandler.php deleted file mode 100644 index 0b4fe60c..00000000 --- a/src/Adapter/Customer/QueryHandler/GetCustomerOrdersHandler.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Currency; -use Customer; -use Order; -use PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\AbstractCustomerHandler; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerOrders; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetCustomerOrdersHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrderSummary; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; - -/** - * Handles GetCustomerOrders query using legacy object models - */ -final class GetCustomerOrdersHandler extends AbstractCustomerHandler implements GetCustomerOrdersHandlerInterface -{ - /** - * @var LocaleInterface - */ - private $locale; - - /** - * @param LocaleInterface $locale - */ - public function __construct( - LocaleInterface $locale - ) { - $this->locale = $locale; - } - - /** - * @param GetCustomerOrders $query - * - * @return OrderSummary[] - * - * @throws CustomerNotFoundException - */ - public function handle(GetCustomerOrders $query): array - { - $customerId = $query->getCustomerId(); - - $this->assertCustomerWasFound($customerId, new Customer($customerId->getValue())); - - return $this->getOrders($customerId->getValue()); - } - - /** - * @param int $customerId - * - * @throws LocalizationException - */ - private function getOrders(int $customerId) - { - $summarizedOrders = []; - - $customerOrders = Order::getCustomerOrders($customerId); - foreach ($customerOrders as $customerOrder) { - $currency = new Currency((int) $customerOrder['id_currency']); - - $summarizedOrders[] = new OrderSummary( - (int) $customerOrder['id_order'], - $customerOrder['date_add'], - $customerOrder['payment'], - $customerOrder['order_state'] ?: '', - (int) $customerOrder['nb_products'], - $this->locale->formatPrice( - $customerOrder['total_paid_real'], - $currency->iso_code - ) - ); - } - - return $summarizedOrders; - } -} diff --git a/src/Adapter/Customer/QueryHandler/GetRequiredFieldsForCustomerHandler.php b/src/Adapter/Customer/QueryHandler/GetRequiredFieldsForCustomerHandler.php deleted file mode 100644 index 580b64a4..00000000 --- a/src/Adapter/Customer/QueryHandler/GetRequiredFieldsForCustomerHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetRequiredFieldsForCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\GetRequiredFieldsForCustomerHandlerInterface; - -/** - * Handles query which gets required fields for customer sign up - * - * @internal - */ -final class GetRequiredFieldsForCustomerHandler implements GetRequiredFieldsForCustomerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetRequiredFieldsForCustomer $query) - { - $requiredFields = (new Customer())->getFieldsRequiredDatabase(); - - if (empty($requiredFields)) { - return []; - } - - $fields = []; - - foreach ($requiredFields as $field) { - $fields[] = $field['field_name']; - } - - return $fields; - } -} diff --git a/src/Adapter/Customer/QueryHandler/SearchCustomersHandler.php b/src/Adapter/Customer/QueryHandler/SearchCustomersHandler.php deleted file mode 100644 index dc36f2be..00000000 --- a/src/Adapter/Customer/QueryHandler/SearchCustomersHandler.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Customer\QueryHandler; - -use Customer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\SearchCustomers; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler\SearchCustomersHandlerInterface; - -/** - * Handles query that searches for customers by given phrases - * - * @internal - */ -final class SearchCustomersHandler implements SearchCustomersHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(SearchCustomers $query) - { - $limit = 50; - $phrases = array_unique($query->getPhrases()); - - $customers = []; - - foreach ($phrases as $searchPhrase) { - if (empty($searchPhrase)) { - continue; - } - - $customersResult = Customer::searchByName($searchPhrase, $limit); - if (!is_array($customersResult)) { - continue; - } - - foreach ($customersResult as $customerArray) { - if (!$customerArray['active']) { - continue; - } - - $customerArray['fullname_and_email'] = sprintf( - '%s %s - %s', - $customerArray['firstname'], - $customerArray['lastname'], - $customerArray['email'] - ); - - unset( - $customerArray['passwd'], - $customerArray['secure_key'], - $customerArray['last_passwd_gen'], - $customerArray['reset_password_token'], - $customerArray['reset_password_validity'] - ); - $customers[$customerArray['id_customer']] = $customerArray; - } - } - - return $customers; - } -} diff --git a/src/Adapter/CustomerService/CommandHandler/AddOrderCustomerMessageHandler.php b/src/Adapter/CustomerService/CommandHandler/AddOrderCustomerMessageHandler.php deleted file mode 100644 index 28acc869..00000000 --- a/src/Adapter/CustomerService/CommandHandler/AddOrderCustomerMessageHandler.php +++ /dev/null @@ -1,264 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler; - -use Configuration; -use Customer; -use CustomerMessage; -use CustomerThread; -use Language; -use Mail; -use Order; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Command\AddOrderCustomerMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\CommandHandler\AddOrderCustomerMessageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CannotSendEmailException; -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CustomerMessageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CustomerMessageException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; -use Tools; - -final class AddOrderCustomerMessageHandler implements AddOrderCustomerMessageHandlerInterface -{ - /** - * @var int - */ - private $contextShopId; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var int - */ - private $contextEmployeeId; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @param TranslatorInterface $translator - * @param ValidatorInterface $validator - * @param int $contextShopId - * @param int $contextLanguageId - * @param int $contextEmployeeId - */ - public function __construct( - TranslatorInterface $translator, - ValidatorInterface $validator, - int $contextShopId, - int $contextLanguageId, - int $contextEmployeeId - ) { - $this->contextShopId = $contextShopId; - $this->contextLanguageId = $contextLanguageId; - $this->contextEmployeeId = $contextEmployeeId; - $this->translator = $translator; - $this->validator = $validator; - } - - /** - * {@inheritdoc} - * - * @throws CustomerMessageException - * @throws OrderNotFoundException - */ - public function handle(AddOrderCustomerMessageCommand $command): void - { - $this->assertIsValidMessage($command->getMessage()); - - $order = new Order($command->getOrderId()->getValue()); - - if (0 >= $order->id) { - throw new OrderNotFoundException($command->getOrderId(), "Order with id {$command->getOrderId()->getValue()} was not found"); - } - - $customer = new Customer($order->id_customer); - - if (0 >= $customer->id) { - throw new CustomerMessageException("Associated order customer with id {$command->getOrderId()->getValue()} was not found", CustomerMessageException::ORDER_CUSTOMER_NOT_FOUND); - } - - $customerServiceThreadId = CustomerThread::getIdCustomerThreadByEmailAndIdOrder( - $customer->email, - $order->id - ); - - if (!$customerServiceThreadId) { - try { - $customerServiceThreadId = $this->createCustomerMessageThread($order); - } catch (\PrestaShopException $e) { - throw new CustomerMessageException('An unexpected error occurred when creating customer message thread', 0, $e); - } - } - - try { - $this->createMessage($customerServiceThreadId, $command); - } catch (\PrestaShopException $e) { - throw new CustomerMessageException('An unexpected error occurred when creating customer message', 0, $e); - } - - $failedMailSentMessage = 'An unexpected error occurred when sending the email'; - - try { - $isSent = $this->sendMail($customer, $order, $command); - - if (!$isSent) { - throw new CannotSendEmailException($failedMailSentMessage); - } - } catch (\PrestaShopException $e) { - throw new CannotSendEmailException($failedMailSentMessage, 0, $e); - } - } - - /** - * @param string $message - * - * @throws CustomerMessageConstraintException - */ - private function assertIsValidMessage(string $message): void - { - $errors = $this->validator->validate($message, new CleanHtml()); - - if (0 !== \count($errors)) { - throw new CustomerMessageConstraintException(sprintf('Given message "%s" contains javascript events or script tags', $message), CustomerMessageConstraintException::INVALID_MESSAGE); - } - } - - /** - * Creates customer message thread which groups customer message in an order group. - * - * @param Order $order - * - * @return int - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function createCustomerMessageThread(Order $order): int - { - $orderCustomer = new Customer($order->id_customer); - - $customerThread = new CustomerThread(); - $customerThread->id_contact = 0; - $customerThread->id_customer = (int) $order->id_customer; - $customerThread->id_shop = $this->contextShopId; - $customerThread->id_order = $order->id; - $customerThread->id_lang = $this->contextLanguageId; - $customerThread->email = $orderCustomer->email; - $customerThread->status = 'open'; - $customerThread->token = Tools::passwdGen(12); - $customerThread->add(); - - return $customerThread->id; - } - - /** - * Creates actual message. - * - * @param int $customerServiceThreadId - * @param AddOrderCustomerMessageCommand $command - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function createMessage(int $customerServiceThreadId, AddOrderCustomerMessageCommand $command): void - { - $customerMessage = new CustomerMessage(); - $customerMessage->id_customer_thread = $customerServiceThreadId; - $customerMessage->id_employee = $this->contextEmployeeId; - $customerMessage->message = $command->getMessage(); - $customerMessage->private = $command->isPrivate(); - $customerMessage->add(); - } - - /** - * Sends email to customer - * - * @param Customer $customer - * @param Order $order - * @param AddOrderCustomerMessageCommand $command - * - * @return bool - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function sendMail(Customer $customer, Order $order, AddOrderCustomerMessageCommand $command): bool - { - if ($command->isPrivate()) { - return true; - } - - $message = $command->getMessage(); - - if (Configuration::get('PS_MAIL_TYPE', null, null, $order->id_shop) != Mail::TYPE_TEXT) { - $message = Tools::nl2br(Tools::htmlentitiesUTF8($command->getMessage())); - } - - $orderLanguage = new Language((int) $order->id_lang); - $varsTpl = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => $order->id, - '{order_name}' => $order->getUniqReference(), - '{message}' => $message, - ]; - - return Mail::Send( - (int) $order->id_lang, - 'order_merchant_comment', - $this->translator->trans( - 'New message regarding your order', - [], - 'Emails.Subject', - $orderLanguage->locale - ), - $varsTpl, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - (int) $order->id_shop - ); - } -} diff --git a/src/Adapter/CustomerService/CommandHandler/ForwardCustomerThreadHandler.php b/src/Adapter/CustomerService/CommandHandler/ForwardCustomerThreadHandler.php deleted file mode 100644 index 151483c8..00000000 --- a/src/Adapter/CustomerService/CommandHandler/ForwardCustomerThreadHandler.php +++ /dev/null @@ -1,337 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler; - -use Contact; -use Context; -use CustomerMessage; -use Db; -use Employee; -use Mail; -use Order; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ForwardCustomerThreadCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler\ForwardCustomerThreadHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerServiceException; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * @internal - */ -final class ForwardCustomerThreadHandler implements ForwardCustomerThreadHandlerInterface -{ - /** - * @var Context - */ - private $context; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param Context $context - * @param ConfigurationInterface $configuration - */ - public function __construct(Context $context, ConfigurationInterface $configuration) - { - $this->context = $context; - $this->translator = $this->context->getTranslator(); - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(ForwardCustomerThreadCommand $command) - { - if ($command->forwardToEmployee()) { - $this->forwardToEmployee($command); - } else { - $this->forwardToSomeoneElse($command); - } - } - - /** - * Forward customer thread to another employee - * - * @param ForwardCustomerThreadCommand $command - */ - private function forwardToEmployee(ForwardCustomerThreadCommand $command) - { - $customerThreadMessage = $this->getCustomerThreadMessage($command->getCustomerThreadId()); - - $content = $this->renderMessage( - $customerThreadMessage, - $command->getEmployeeId()->getValue() - ); - - $customerMessage = $this->createCustomerMessage($command); - $employee = new Employee($command->getEmployeeId()->getValue()); - - $params = [ - '{messages}' => stripslashes($content), - '{employee}' => $this->context->employee->firstname . ' ' . $this->context->employee->lastname, - '{comment}' => stripslashes(Tools::nl2br($command->getComment())), - '{firstname}' => $employee->firstname, - '{lastname}' => $employee->lastname, - ]; - - $forwardEmailSent = Mail::Send( - $this->context->language->id, - 'forward_msg', - $this->context->getTranslator()->trans( - 'Fwd: Customer message', - [], - 'Emails.Subject', - $this->context->language->locale - ), - $params, - $employee->email, - $employee->firstname . ' ' . $employee->lastname, - $this->context->employee->email, - $this->context->employee->firstname . ' ' . $this->context->employee->lastname, - null, - null, - _PS_MAIL_DIR_, - true - ); - - if ($forwardEmailSent) { - $customerMessage->private = 1; - $customerMessage->message = sprintf( - '%s %s %s %s %s %s', - $this->translator->trans('Message forwarded to', [], 'Admin.Catalog.Feature'), - $employee->firstname, - $employee->lastname, - PHP_EOL, - $this->translator->trans('Comment:', [], 'Admin.Catalog.Feature'), - $command->getComment() - ); - - $customerMessage->add(); - } - } - - /** - * Forward customer thread to someone else - * - * @param ForwardCustomerThreadCommand $command - */ - private function forwardToSomeoneElse(ForwardCustomerThreadCommand $command) - { - $customerThreadMessage = $this->getCustomerThreadMessage($command->getCustomerThreadId()); - - $content = $this->renderMessage($customerThreadMessage); - - $params = [ - '{messages}' => Tools::nl2br(stripslashes($content)), - '{employee}' => $this->context->employee->firstname . ' ' . $this->context->employee->lastname, - '{comment}' => stripslashes($command->getComment()), - '{firstname}' => '', - '{lastname}' => '', - ]; - - $customerMessage = $this->createCustomerMessage($command); - - $forwardEmailSent = Mail::Send( - $this->context->language->id, - 'forward_msg', - $this->translator->trans( - 'Fwd: Customer message', - [], - 'Emails.Subject', - $this->context->language->locale - ), - $params, - $command->getEmail()->getValue(), - null, - $this->context->employee->email, - $this->context->employee->firstname . ' ' . $this->context->employee->lastname, - null, - null, - _PS_MAIL_DIR_, - true - ); - - if ($forwardEmailSent) { - $customerMessage->message = sprintf( - '%s %s %s %s %s', - $this->translator->trans('Message forwarded to', [], 'Admin.Catalog.Feature'), - $command->getEmail()->getValue(), - PHP_EOL, - $this->translator->trans('Comment:', [], 'Admin.Catalog.Feature'), - $command->getComment() - ); - - $customerMessage->add(); - } - } - - /** - * @param array $message - * @param int|null $id_employee - * - * @return string - */ - protected function renderMessage(array $message, $id_employee = null) - { - $tpl = $this->context->smarty->createTemplate( - 'controllers' . DIRECTORY_SEPARATOR . 'customer_threads/message.tpl', - $this->context->smarty - ); - - $contacts = Contact::getContacts($this->context->language->id); - $contact_array = []; - - foreach ($contacts as $contact) { - $contact_array[$contact['id_contact']] = [ - 'id_contact' => $contact['id_contact'], - 'name' => $contact['name'], - ]; - } - - $contacts = $contact_array; - - if (!empty($message['id_product']) - && empty($message['employee_name']) - ) { - $id_order_product = Order::getIdOrderProduct( - (int) $message['id_customer'], - (int) $message['id_product'] - ); - } - - $message['date_add'] = Tools::displayDate($message['date_add'], null, true); - $message['user_agent'] = strip_tags($message['user_agent']); - $message['message'] = $this->replaceUrlsWithTags($message['message']); - - $isValidOrderId = true; - $order = new Order((int) $message['id_order']); - - if (!Validate::isLoadedObject($order)) { - $isValidOrderId = false; - } - - $baseAdminLink = Tools::getAdminUrl(basename(_PS_ADMIN_DIR_)); - - $threadUrl = $baseAdminLink . '/' . $this->context->link->getAdminLink('AdminCustomerThreads', true, [], [ - 'id_customer_thread' => (int) $message['id_customer_thread'], - 'viewcustomer_thread' => 1, - ]); - - $tpl->assign([ - 'thread_url' => $threadUrl, - 'link' => $this->context->link, - 'token' => Tools::getAdminToken( - 'AdminCustomerThreads' . (int) $message['id_customer_thread'] . (int) $this->context->employee->id - ), - 'message' => $message, - 'id_order_product' => isset($id_order_product) ? $id_order_product : null, - 'email' => true, - 'id_employee' => $id_employee, - 'PS_SHOP_NAME' => $this->configuration->get('PS_SHOP_NAME'), - 'file_name' => file_exists(_PS_UPLOAD_DIR_ . $message['file_name']), - 'contacts' => $contacts, - 'is_valid_order_id' => $isValidOrderId, - ]); - - return $tpl->fetch(); - } - - /** - * @param CustomerThreadId $customerThreadId - * - * @return array - */ - private function getCustomerThreadMessage(CustomerThreadId $customerThreadId) - { - return Db::getInstance()->getRow(' - SELECT ct.*, cm.*, cl.name subject, CONCAT(e.firstname, \' \', e.lastname) employee_name, - CONCAT(c.firstname, \' \', c.lastname) customer_name, c.firstname - FROM ' . _DB_PREFIX_ . 'customer_thread ct - LEFT JOIN ' . _DB_PREFIX_ . 'customer_message cm - ON (ct.id_customer_thread = cm.id_customer_thread) - LEFT JOIN ' . _DB_PREFIX_ . 'contact_lang cl - ON (cl.id_contact = ct.id_contact AND cl.id_lang = ' . (int) $this->context->language->id . ') - LEFT OUTER JOIN ' . _DB_PREFIX_ . 'employee e - ON e.id_employee = cm.id_employee - LEFT OUTER JOIN ' . _DB_PREFIX_ . 'customer c - ON (c.email = ct.email) - WHERE ct.id_customer_thread = ' . (int) $customerThreadId->getValue() . ' - ORDER BY cm.date_add DESC - '); - } - - /** - * @param ForwardCustomerThreadCommand $command - * - * @return CustomerMessage - */ - private function createCustomerMessage(ForwardCustomerThreadCommand $command) - { - $customerMessage = new CustomerMessage(); - $customerMessage->id_employee = (int) $this->context->employee->id; - $customerMessage->id_customer_thread = (int) $command->getCustomerThreadId()->getValue(); - $customerMessage->ip_address = (int) ip2long(Tools::getRemoteAddr()); - - if (false === $customerMessage->validateField('message', $command->getComment())) { - throw new CustomerServiceException(sprintf('Comment "%s" is not valid.', $command->getComment())); - } - - return $customerMessage; - } - - /** - * Replaces URLs with
    tags in string. - * - * @param string $text - * - * @return string - */ - private function replaceUrlsWithTags($text) - { - return preg_replace( - '/(https?:\/\/[a-z0-9#%&_=\(\)\.\? \+\-@\/]{6,1000})([\s\n<])/Uui', - '\1\2', - html_entity_decode( - $text, - ENT_QUOTES, - 'UTF-8' - ) - ); - } -} diff --git a/src/Adapter/CustomerService/CommandHandler/ReplyToCustomerThreadHandler.php b/src/Adapter/CustomerService/CommandHandler/ReplyToCustomerThreadHandler.php deleted file mode 100644 index 22db6d23..00000000 --- a/src/Adapter/CustomerService/CommandHandler/ReplyToCustomerThreadHandler.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler; - -use Contact; -use Context; -use Customer; -use CustomerMessage; -use CustomerThread; -use Language; -use Mail; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ReplyToCustomerThreadCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler\ReplyToCustomerThreadHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerServiceException; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadStatus; -use ShopUrl; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * @internal - */ -final class ReplyToCustomerThreadHandler implements ReplyToCustomerThreadHandlerInterface -{ - /** - * @var Context - */ - private $context; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param Context $context - */ - public function __construct(Context $context) - { - $this->context = $context; - $this->translator = $context->getTranslator(); - } - - /** - * @param ReplyToCustomerThreadCommand $command - */ - public function handle(ReplyToCustomerThreadCommand $command) - { - $customerThread = new CustomerThread( - $command->getCustomerThreadId()->getValue() - ); - - ShopUrl::cacheMainDomainForShop((int) $customerThread->id_shop); - - $customerMessage = $this->createCustomerMessage( - $customerThread, - $command->getReplyMessage() - ); - - $replyWasSent = $this->sendReplyEmail($customerThread, $customerMessage); - - if ($replyWasSent) { - $customerThread->status = CustomerThreadStatus::CLOSED; - $customerThread->update(); - } - } - - /** - * @param CustomerThread $customerThread - * @param string $replyMessage - * - * @return CustomerMessage - */ - private function createCustomerMessage(CustomerThread $customerThread, $replyMessage) - { - $customerMessage = new CustomerMessage(); - $customerMessage->id_employee = (int) $this->context->employee->id; - $customerMessage->id_customer_thread = $customerThread->id; - $customerMessage->ip_address = (int) ip2long(Tools::getRemoteAddr()); - $customerMessage->message = $replyMessage; - - if (false === $customerMessage->validateField('message', $customerMessage->message)) { - throw new CustomerServiceException('Invalid reply message'); - } - - if (false === $customerMessage->add()) { - throw new CustomerServiceException('Failed to add customer message'); - } - - return $customerMessage; - } - - /** - * @param CustomerThread $customerThread - * @param CustomerMessage $customerMessage - * - * @return bool - */ - private function sendReplyEmail(CustomerThread $customerThread, CustomerMessage $customerMessage) - { - $customer = new Customer($customerThread->id_customer); - - $params = [ - '{reply}' => Tools::nl2br($customerMessage->message), - '{link}' => Tools::url( - $this->context->link->getPageLink('contact', true, null, null, false, $customerThread->id_shop), - 'id_customer_thread=' . (int) $customerThread->id . '&token=' . $customerThread->token - ), - '{firstname}' => $customer->firstname, - '{lastname}' => $customer->lastname, - ]; - - $contact = new Contact((int) $customerThread->id_contact, (int) $customerThread->id_lang); - - if (Validate::isLoadedObject($contact)) { - $fromName = $contact->name; - $fromEmail = $contact->email; - } else { - $fromName = null; - $fromEmail = null; - } - - $language = new Language((int) $customerThread->id_lang); - - return Mail::Send( - (int) $customerThread->id_lang, - 'reply_msg', - $this->translator->trans( - 'An answer to your message is available #ct%thread_id% #tc%thread_token%', - [ - '%thread_id%' => $customerThread->id, - '%thread_token%' => $customerThread->token, - ], - 'Emails.Subject', - $language->locale - ), - $params, - $customerThread->email, - null, - $fromEmail, - $fromName, - null, - null, - _PS_MAIL_DIR_, - true, - $customerThread->id_shop - ); - } -} diff --git a/src/Adapter/CustomerService/QueryHandler/GetCustomerThreadForViewingHandler.php b/src/Adapter/CustomerService/QueryHandler/GetCustomerThreadForViewingHandler.php deleted file mode 100644 index 0063303b..00000000 --- a/src/Adapter/CustomerService/QueryHandler/GetCustomerThreadForViewingHandler.php +++ /dev/null @@ -1,388 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\CustomerService\QueryHandler; - -use Contact; -use Context; -use Currency; -use Customer; -use CustomerThread; -use DateTime; -use Employee; -use Order; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerThreadNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerThreadForViewing; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryHandler\GetCustomerThreadForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerInformation; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadMessage; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadTimeline; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadTimelineItem; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadView; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadMessageType; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadStatus; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use Product; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * @internal - */ -final class GetCustomerThreadForViewingHandler implements GetCustomerThreadForViewingHandlerInterface -{ - /** - * @var Context - */ - private $context; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param Context $context - */ - public function __construct(Context $context) - { - $this->context = $context; - $this->translator = $context->getTranslator(); - } - - /** - * {@inheritdoc} - */ - public function handle(GetCustomerThreadForViewing $query) - { - $customerThread = $this->getCustomerThread($query->getCustomerThreadId()); - - $messages = CustomerThread::getMessageCustomerThreads($query->getCustomerThreadId()->getValue()); - - return new CustomerThreadView( - $query->getCustomerThreadId(), - new LanguageId((int) $customerThread->id_lang), - $this->getAvailableActions($customerThread), - $this->getCustomerInformation($customerThread), - $this->getContactName($customerThread), - $this->getCustomerThreadMessages($messages), - $this->getTimeline($messages, $customerThread) - ); - } - - /** - * @param array $messages - * - * @return CustomerThreadMessage[] - */ - private function getCustomerThreadMessages(array $messages) - { - $threadMessages = []; - - foreach ($messages as $key => $message) { - $employeeImage = null; - - if ($message['id_employee']) { - $employee = new Employee($message['id_employee']); - $employeeImage = $employee->getImage(); - } - - $attachmentFile = null; - - if (!empty($message['file_name']) - && file_exists(_PS_UPLOAD_DIR_ . $message['file_name']) - ) { - $attachmentFile = _THEME_PROD_PIC_DIR_ . $message['file_name']; - } - - $productId = null; - $productName = null; - - if ($message['id_product']) { - $product = new Product((int) $message['id_product'], false, $this->context->language->id); - - if (Validate::isLoadedObject($product)) { - $productId = (int) $product->id; - $productName = $product->name; - } - } - - $type = $message['id_employee'] ? - CustomerThreadMessageType::EMPLOYEE : - CustomerThreadMessageType::CUSTOMER; - - $threadMessages[] = new CustomerThreadMessage( - $type, - $message['message'], - $message['date_add'], - $employeeImage, - $message['employee_name'], - $message['customer_name'], - $attachmentFile, - $productId, - $productName - ); - } - - return $threadMessages; - } - - /** - * @param CustomerThreadId $customerThreadId - * - * @return CustomerThread - */ - private function getCustomerThread(CustomerThreadId $customerThreadId) - { - $customerThread = new CustomerThread($customerThreadId->getValue()); - - if ($customerThread->id !== $customerThreadId->getValue()) { - throw new CustomerThreadNotFoundException(sprintf('Customer thread with id "%s" was not found', $customerThreadId->getValue())); - } - - return $customerThread; - } - - /** - * Get customer thread messages in timeline - * - * @param array $messages - * @param CustomerThread $customerThread - * - * @return CustomerThreadTimeline - */ - private function getTimeline(array $messages, CustomerThread $customerThread) - { - $timeline = []; - - foreach ($messages as $message) { - $product = new Product((int) $message['id_product'], false, $this->context->language->id); - - $content = ''; - - if (!$message['private']) { - $content .= sprintf( - '%s %s
    ', - $this->translator->trans('Message to:', [], 'Admin.Catalog.Feature'), - !$message['id_employee'] ? $message['subject'] : $message['customer_name'] - ); - } - - if (Validate::isLoadedObject($product)) { - $content .= sprintf( - '
    %s%s

    ', - $this->translator->trans('Product:', [], 'Admin.Catalog.Feature'), - $product->name - ); - } - - $content .= Tools::safeOutput($message['message']); - - $timeline[$message['date_add']][] = [ - 'arrow' => 'left', - 'background_color' => '', - 'icon' => 'email', - 'content' => $content, - 'date' => $message['date_add'], - 'related_order_id' => null, - ]; - } - - $order = new Order((int) $customerThread->id_order); - - if (Validate::isLoadedObject($order)) { - $order_history = $order->getHistory($this->context->language->id); - foreach ($order_history as $history) { - $link_order = $this->context->link->getAdminLink('AdminOrders', true, [], [ - 'vieworder' => 1, - 'id_order' => (int) $order->id, - ]); - - $content = sprintf( - '%s #%d

    ', - Tools::safeOutput($link_order), - $this->translator->trans('Order', [], 'Admin.Global'), - $order->id - ); - - $content .= sprintf( - '%s %s', - $this->translator->trans('Status:', [], 'Admin.Catalog.Feature'), - $history['ostate_name'] - ); - - $timeline[$history['date_add']][] = [ - 'arrow' => 'right', - 'alt' => true, - 'background_color' => $history['color'], - 'icon' => 'credit_card', - 'content' => $content, - 'date' => $history['date_add'], - 'see_more_link' => $link_order, - 'related_order_id' => (int) $order->id, - ]; - } - } - - krsort($timeline); - - $timelineItems = []; - - foreach ($timeline as $items) { - foreach ($items as $item) { - $timelineItems[] = new CustomerThreadTimelineItem( - $item['content'], - $item['icon'], - $item['arrow'], - $item['date'], - isset($item['background_color']) ? $item['background_color'] : null, - $item['related_order_id'] - ); - } - } - - return new CustomerThreadTimeline($timelineItems); - } - - /** - * @param CustomerThread $thread - * - * @return array - */ - private function getAvailableActions(CustomerThread $thread) - { - $actions = []; - - if ($thread->status !== CustomerThreadStatus::CLOSED) { - $actions[CustomerThreadStatus::CLOSED] = [ - 'label' => $this->translator->trans('Mark as "handled"', [], 'Admin.Catalog.Feature'), - 'value' => CustomerThreadStatus::CLOSED, - ]; - } else { - $actions[CustomerThreadStatus::OPEN] = [ - 'label' => $this->translator->trans('Re-open', [], 'Admin.Catalog.Feature'), - 'value' => CustomerThreadStatus::OPEN, - ]; - } - - if ($thread->status !== CustomerThreadStatus::PENDING_1) { - $actions[CustomerThreadStatus::PENDING_1] = [ - 'label' => $this->translator->trans( - 'Mark as "pending 1" (will be answered later)', - [], - 'Admin.Catalog.Feature' - ), - 'value' => CustomerThreadStatus::PENDING_1, - ]; - } else { - $actions[CustomerThreadStatus::PENDING_1] = [ - 'label' => $this->translator->trans('Disable pending status', [], 'Admin.Catalog.Feature'), - 'value' => CustomerThreadStatus::OPEN, - ]; - } - - if ($thread->status !== CustomerThreadStatus::PENDING_2) { - $actions[CustomerThreadStatus::PENDING_2] = [ - 'label' => $this->translator->trans( - 'Mark as "pending 2" (will be answered later)', - [], - 'Admin.Catalog.Feature' - ), - 'value' => CustomerThreadStatus::PENDING_2, - ]; - } else { - $actions[CustomerThreadStatus::PENDING_2] = [ - 'label' => $this->translator->trans('Disable pending status', [], 'Admin.Catalog.Feature'), - 'value' => CustomerThreadStatus::OPEN, - ]; - } - - return $actions; - } - - /** - * @param CustomerThread $thread - * - * @return CustomerInformation - */ - private function getCustomerInformation(CustomerThread $thread) - { - if (!$thread->id_customer) { - return CustomerInformation::withEmailOnly($thread->email); - } - - $customer = new Customer($thread->id_customer); - $orders = Order::getCustomerOrders($customer->id); - - $totalOk = 0; - $ordersOk = []; - - if ($orders && count($orders)) { - foreach ($orders as $key => $order) { - if ($order['valid']) { - $ordersOk[] = $order; - $totalOk += $order['total_paid_real'] / $order['conversion_rate']; - } - - $orders[$key]['date_add'] = Tools::displayDate($order['date_add']); - $orders[$key]['total_paid_real'] = Tools::displayPrice( - $order['total_paid_real'], - new Currency((int) $order['id_currency']) - ); - } - } - - return new CustomerInformation( - $customer->id, - $customer->firstname, - $customer->lastname, - $thread->email, - count($ordersOk), - $totalOk ? Tools::displayPrice($totalOk, $this->context->currency) : $totalOk, - (new DateTime($customer->date_add))->format($this->context->language->date_format_lite) - ); - } - - /** - * @param CustomerThread $thread - * - * @return string|null - */ - private function getContactName(CustomerThread $thread) - { - $contacts = Contact::getContacts($this->context->language->id); - - foreach ($contacts as $contact) { - if ((int) $contact['id_contact'] === (int) $thread->id_contact) { - return $contact['name']; - } - } - - return null; - } -} diff --git a/src/Adapter/Database.php b/src/Adapter/Database.php deleted file mode 100644 index ecbabac1..00000000 --- a/src/Adapter/Database.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Db; -use DbQuery; - -/** - * Adapter for Db legacy class. - */ -class Database implements \PrestaShop\PrestaShop\Core\Foundation\Database\DatabaseInterface -{ - /** - * Perform a SELECT sql statement. - * - * @param string $sqlString - * - * @return array|false - * - * @throws \PrestaShopDatabaseException - */ - public function select($sqlString) - { - return Db::getInstance()->executeS($sqlString); - } - - /** - * Escape $unsafe to be used into a SQL statement. - * - * @param string $unsafeData - * - * @return string - */ - public function escape($unsafeData) - { - return Db::getInstance()->escape($unsafeData, true, true); - } - - /** - * Returns a value from the first row, first column of a SELECT query. - * - * @param string|DbQuery $sql - * @param bool $useMaster - * @param bool $useCache - * - * @return string|false|null - */ - public function getValue($sql, $useMaster = true, $useCache = true) - { - return Db::getInstance($useMaster)->getValue($sql, $useCache); - } - - /** - * Returns the text of the error message from previous database operation. - * - * @return string - */ - public function getErrorMessage() - { - return Db::getInstance()->getMsgError(); - } - - /** - * Enable the cache. - */ - public function enableCache() - { - Db::getInstance()->enableCache(); - } - - /** - * Disable the cache. - */ - public function disableCache() - { - Db::getInstance()->disableCache(); - } -} diff --git a/src/Adapter/Debug/DebugMode.php b/src/Adapter/Debug/DebugMode.php deleted file mode 100644 index 09249ad3..00000000 --- a/src/Adapter/Debug/DebugMode.php +++ /dev/null @@ -1,185 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Debug; - -use Tools; - -/** - * Utilitary class to manages the Debug mode legacy application. - */ -class DebugMode -{ - const DEBUG_MODE_SUCCEEDED = 0; - const DEBUG_MODE_ERROR_NO_READ_ACCESS = 1; - const DEBUG_MODE_ERROR_NO_READ_ACCESS_CUSTOM = 2; - const DEBUG_MODE_ERROR_NO_WRITE_ACCESS = 3; - const DEBUG_MODE_ERROR_NO_WRITE_ACCESS_CUSTOM = 4; - const DEBUG_MODE_ERROR_NO_DEFINITION_FOUND = 5; - - /** - * Is Debug Mode enabled? Checks on custom defines file first. - * - * @return bool Whether debug mode is enabled - */ - public function isDebugModeEnabled() - { - $definesClean = ''; - $customDefinesPath = _PS_ROOT_DIR_ . '/config/defines_custom.inc.php'; - $definesPath = _PS_ROOT_DIR_ . '/config/defines.inc.php'; - - if (is_readable($customDefinesPath)) { - $definesClean = php_strip_whitespace($customDefinesPath); - } - - if (!preg_match('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', $definesClean, $debugModeValue)) { - $definesClean = php_strip_whitespace($definesPath); - if (!preg_match('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', $definesClean, $debugModeValue)) { - return false; - } - } - - return 'true' === Tools::strtolower($debugModeValue[1]); - } - - /** - * Enable Debug mode. - * - * @return int Whether changing debug mode succeeded or error code - */ - public function enable() - { - return $this->changePsModeDevValue('true'); - } - - /** - * Disable debug mode. - * - * @return int Whether changing debug mode succeeded or error code - */ - public function disable() - { - return $this->changePsModeDevValue('false'); - } - - /** - * Check read permission on custom defines.inc.php. - * - * @return bool Whether the file can be read - */ - private function isCustomDefinesReadable() - { - return is_readable(_PS_ROOT_DIR_ . '/config/defines_custom.inc.php'); - } - - /** - * Check read permission on main defines.inc.php. - * - * @return bool Whether the file can be read - */ - private function isMainDefinesReadable() - { - return is_readable(_PS_ROOT_DIR_ . '/config/defines.inc.php'); - } - - /** - * Update Debug Mode value in main defines file. - * - * @param string $value should be "true" or "false" - * - * @return int the debug mode - */ - private function updateDebugModeValueInMainFile($value) - { - $filename = _PS_ROOT_DIR_ . '/config/defines.inc.php'; - $cleanedFileContent = php_strip_whitespace($filename); - $fileContent = Tools::file_get_contents($filename); - - if (!preg_match('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', $cleanedFileContent)) { - return self::DEBUG_MODE_ERROR_NO_DEFINITION_FOUND; - } - - $fileContent = preg_replace('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', 'define(\'_PS_MODE_DEV_\', ' . $value . ');', $fileContent); - if (!@file_put_contents($filename, $fileContent)) { - return self::DEBUG_MODE_ERROR_NO_WRITE_ACCESS; - } - - if (function_exists('opcache_invalidate')) { - opcache_invalidate($filename); - } - - return self::DEBUG_MODE_SUCCEEDED; - } - - /** - * Update Debug Mode value in custom defines file. - * - * @param string $value should be "true" or "false" - * - * @return int the debug mode - */ - private function updateDebugModeValueInCustomFile($value) - { - $customFileName = _PS_ROOT_DIR_ . '/config/defines_custom.inc.php'; - $cleanedFileContent = php_strip_whitespace($customFileName); - $fileContent = Tools::file_get_contents($customFileName); - - if (!empty($cleanedFileContent) && preg_match('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', $cleanedFileContent)) { - $fileContent = preg_replace('/define\(\'_PS_MODE_DEV_\', ([a-zA-Z]+)\);/Ui', 'define(\'_PS_MODE_DEV_\', ' . $value . ');', $fileContent); - - if (!@file_put_contents($customFileName, $fileContent)) { - return self::DEBUG_MODE_ERROR_NO_WRITE_ACCESS_CUSTOM; - } - - if (function_exists('opcache_invalidate')) { - opcache_invalidate($customFileName); - } - - return self::DEBUG_MODE_SUCCEEDED; - } - } - - /** - * Change value of _PS_MODE_DEV_ constant. - * - * @param string $value should be "true" or "false" - * - * @return int the debug mode - */ - private function changePsModeDevValue($value) - { - // Check custom defines file first - if ($this->isCustomDefinesReadable()) { - return $this->updateDebugModeValueInCustomFile($value); - } - - if ($this->isMainDefinesReadable()) { - return $this->updateDebugModeValueInMainFile($value); - } else { - return self::DEBUG_MODE_ERROR_NO_READ_ACCESS; - } - } -} diff --git a/src/Adapter/Debug/DebugModeConfiguration.php b/src/Adapter/Debug/DebugModeConfiguration.php deleted file mode 100644 index f53931d5..00000000 --- a/src/Adapter/Debug/DebugModeConfiguration.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Debug; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class manages Debug mode configuration for a Shop. - */ -class DebugModeConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var DebugMode Debug mode manager - */ - private $debugMode; - - /** - * @var string Path to the application defines path - */ - private $configDefinesPath; - - public function __construct(DebugMode $debugMode, Configuration $configuration, $configDefinesPath) - { - $this->debugMode = $debugMode; - $this->configuration = $configuration; - $this->configDefinesPath = $configDefinesPath; - } - - /** - * Returns configuration used to manage Debug mode in back office. - * - * @return array - */ - public function getConfiguration() - { - return [ - 'disable_non_native_modules' => $this->configuration->getBoolean('PS_DISABLE_NON_NATIVE_MODULE'), - 'disable_overrides' => $this->configuration->getBoolean('PS_DISABLE_OVERRIDES'), - 'debug_mode' => $this->debugMode->isDebugModeEnabled(), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_DISABLE_NON_NATIVE_MODULE', $configuration['disable_non_native_modules']); - $this->configuration->set('PS_DISABLE_OVERRIDES', $configuration['disable_overrides']); - - $status = $this->updateDebugMode((bool) $configuration['debug_mode']); - - switch ($status) { - case DebugMode::DEBUG_MODE_SUCCEEDED: - break; - case DebugMode::DEBUG_MODE_ERROR_NO_WRITE_ACCESS: - $errors[] = [ - 'key' => 'Error: Could not write to file. Make sure that the correct permissions are set on the file %s', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [$this->configDefinesPath], - ]; - - break; - case DebugMode::DEBUG_MODE_ERROR_NO_DEFINITION_FOUND: - $errors[] = [ - 'key' => 'Error: Could not find whether debug mode is enabled. Make sure that the correct permissions are set on the file %s', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [$this->configDefinesPath], - ]; - - break; - case DebugMode::DEBUG_MODE_ERROR_NO_WRITE_ACCESS_CUSTOM: - $errors[] = [ - 'key' => 'Error: Could not write to file. Make sure that the correct permissions are set on the file %s', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [$this->configDefinesPath], - ]; - - break; - case DebugMode::DEBUG_MODE_ERROR_NO_READ_ACCESS: - $errors[] = [ - 'key' => 'Error: Could not write to file. Make sure that the correct permissions are set on the file %s', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [$this->configDefinesPath], - ]; - - break; - default: - break; - } - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['disable_non_native_modules'], - $configuration['disable_overrides'], - $configuration['debug_mode'] - ); - } - - /** - * Change Debug mode value if needed. - * - * @param $enableStatus - * - * @return int the status of update - */ - private function updateDebugMode($enableStatus) - { - $currentDebugMode = $this->debugMode->isDebugModeEnabled(); - - if ($enableStatus !== $currentDebugMode) { - return (true === $enableStatus) ? $this->debugMode->enable() : $this->debugMode->disable(); - } - } -} diff --git a/src/Adapter/Domain/AbstractObjectModelHandler.php b/src/Adapter/Domain/AbstractObjectModelHandler.php deleted file mode 100644 index 51fd4f0c..00000000 --- a/src/Adapter/Domain/AbstractObjectModelHandler.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Domain; - -use Context; -use Db; -use ImageManager; -use ObjectModel; -use PrestaShopDatabaseException; -use Shop; - -/** - * Class AbstractObjectModelHandler is responsible for executing legacy code which is common for legacy ObjectModel. - * - * @internal - */ -abstract class AbstractObjectModelHandler -{ - /** - * This function assigns stores ids to the given object. It removes previously set shop ids and adds new ids instead. - * - * @param ObjectModel $objectModel - * @param array $shopAssociation - * - * @throws PrestaShopDatabaseException - */ - protected function associateWithShops(ObjectModel $objectModel, array $shopAssociation) - { - if (empty($shopAssociation) || !Shop::isFeatureActive()) { - return; - } - - $tableName = (string) $objectModel::$definition['table']; - $primaryKeyName = (string) $objectModel::$definition['primary']; - $primaryKeyValue = (int) $objectModel->id; - - if (!Shop::isTableAssociated($tableName)) { - return; - } - - // Get list of shop id we want to exclude from asso deletion - $excludeIds = $shopAssociation; - foreach (Db::getInstance()->executeS('SELECT id_shop FROM ' . _DB_PREFIX_ . 'shop') as $row) { - if (!Context::getContext()->employee->hasAuthOnShop($row['id_shop'])) { - $excludeIds[] = $row['id_shop']; - } - } - - $excludeShopsCondtion = $excludeIds ? - ' AND id_shop NOT IN (' . implode(', ', array_map('intval', $excludeIds)) . ')' : - '' - ; - - Db::getInstance()->delete( - $tableName . '_shop', - '`' . $primaryKeyName . '` = ' . $primaryKeyValue . $excludeShopsCondtion - ); - - $insert = []; - foreach ($shopAssociation as $shopId) { - // Check if context employee has access to the shop before inserting shop association. - if (Context::getContext()->employee->hasAuthOnShop($shopId)) { - $insert[] = [ - $primaryKeyName => $primaryKeyValue, - 'id_shop' => (int) $shopId, - ]; - } - } - - Db::getInstance()->insert( - $tableName . '_shop', - $insert, - false, - true, - Db::INSERT_IGNORE - ); - } - - /** - * @param ObjectModel $objectModel - * @param array $multiStoreColumnAssociation - an array key contains shop id while values contains the mapping of - * column and its value - */ - protected function updateMultiStoreColumns(ObjectModel $objectModel, array $multiStoreColumnAssociation) - { - $tableName = (string) $objectModel::$definition['table']; - $primaryKey = (string) $objectModel::$definition['primary']; - $primaryKeyValue = (int) $objectModel->id; - - foreach ($multiStoreColumnAssociation as $shopId => $items) { - $shop = new Shop($shopId); - - if (0 >= $shop->id || !is_array($items)) { - continue; - } - - $update = []; - foreach ($items as $columnName => $columnValue) { - $update[$columnName] = pSQL($columnValue); - } - - Db::getInstance()->update( - $tableName . '_shop', - $update, - $primaryKey . '=' . $primaryKeyValue - ); - } - } - - /** - * @param string $imagePath the original image path - * @param int $imageId - * @param string $belongsTo object name to which image belongs (e.g. 'supplier', 'manufacturer') - * - * @return string - */ - protected function getTmpImageTag($imagePath, $imageId, $belongsTo) - { - return ImageManager::thumbnail( - $imagePath, - $belongsTo . '_' . $imageId . '.jpg', - 350, - 'jpg', - true, - true - ); - } - - /** - * Calculates and returns image size in kb for provided image path. Returns null if image doesn't exist - * - * @param string $imagePath - * - * @return float|null - */ - protected function getImageSize($imagePath) - { - return file_exists($imagePath) ? filesize($imagePath) / 1000 : null; - } -} diff --git a/src/Adapter/Email/EmailConfigurationTester.php b/src/Adapter/Email/EmailConfigurationTester.php deleted file mode 100644 index c42f2e70..00000000 --- a/src/Adapter/Email/EmailConfigurationTester.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Email; - -use PrestaShop\PrestaShop\Adapter\Entity\Mail; -use PrestaShop\PrestaShop\Adapter\Entity\Tools; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Email\EmailConfigurationTesterInterface; -use PrestaShop\PrestaShop\Core\Email\MailOption; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class EmailConfigurationTester is responsible for sending test email. - * - * @internal - */ -final class EmailConfigurationTester implements EmailConfigurationTesterInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param ConfigurationInterface $configuration - * @param TranslatorInterface $translator - */ - public function __construct( - ConfigurationInterface $configuration, - TranslatorInterface $translator - ) { - $this->configuration = $configuration; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function testConfiguration(array $config) - { - $content = $this->translator->trans( - 'This is a test message. Your server is now configured to send email.', - [], - 'Admin.Advparameters.Feature' - ); - $subject = $this->translator->trans('Test message -- Prestashop', [], 'Admin.Advparameters.Feature'); - - $smtpChecked = MailOption::METHOD_SMTP === (int) $config['mail_method']; - - $password = !empty($config['smtp_password']) ? - urldecode($config['smtp_password']) : - $this->configuration->get('PS_MAIL_PASSWD'); - $password = str_replace( - ['<', '>', '"', '&'], - ['<', '>', '"', '&'], - Tools::htmlentitiesUTF8($password) - ); - - $result = Mail::sendMailTest( - Tools::htmlentitiesUTF8($smtpChecked), - Tools::htmlentitiesUTF8($config['smtp_server']), - Tools::htmlentitiesUTF8($content), - Tools::htmlentitiesUTF8($subject), - Tools::htmlentitiesUTF8('text/html'), - Tools::htmlentitiesUTF8($config['send_email_to']), - Tools::htmlentitiesUTF8($this->configuration->get('PS_SHOP_EMAIL')), - Tools::htmlentitiesUTF8($config['smtp_username']), - $password, - Tools::htmlentitiesUTF8($config['smtp_port']), - Tools::htmlentitiesUTF8($config['smtp_encryption']) - ); - - $errors = []; - - if (false === $result || is_string($result)) { - $errors[] = - $this->translator->trans('Error: Please check your configuration', [], 'Admin.Advparameters.Feature'); - } - - if (is_string($result)) { - $errors[] = $result; - } - - return $errors; - } -} diff --git a/src/Adapter/Email/EmailLogEraser.php b/src/Adapter/Email/EmailLogEraser.php deleted file mode 100644 index 792dcf62..00000000 --- a/src/Adapter/Email/EmailLogEraser.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Email; - -use PrestaShop\PrestaShop\Adapter\Entity\Mail; -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopCollection; -use PrestaShop\PrestaShop\Core\Email\EmailLogEraserInterface; - -/** - * Class EmailLogEraser provides API for erasing email logs. - * - * @internal - */ -final class EmailLogEraser implements EmailLogEraserInterface -{ - /** - * {@inheritdoc} - */ - public function erase(array $mailLogIds) - { - $errors = []; - - if (empty($mailLogIds)) { - $errors[] = [ - 'key' => 'You must select at least one element to delete.', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - - return $errors; - } - - $emailLogs = new PrestaShopCollection('Mail'); - $emailLogs->where('id_mail', 'in', $mailLogIds); - - /** @var Mail $emailLog */ - foreach ($emailLogs->getResults() as $emailLog) { - if (!$emailLog->delete()) { - $errors[] = [ - 'key' => 'Can\'t delete #%id%', - 'parameters' => [ - '%id%' => $emailLog->id, - ], - 'domain' => 'Admin.Notifications.Error', - ]; - - continue; - } - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function eraseAll() - { - return Mail::eraseAllLogs(); - } -} diff --git a/src/Adapter/Employee/AvatarProvider.php b/src/Adapter/Employee/AvatarProvider.php deleted file mode 100644 index 0eeea31b..00000000 --- a/src/Adapter/Employee/AvatarProvider.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\Employee\AvatarProviderInterface; - -/** - * Class AvatarProvider provides employee avatar data. - */ -final class AvatarProvider implements AvatarProviderInterface -{ - /** - * @var Tools - */ - private $tools; - - /** - * @param Tools $tools - */ - public function __construct(Tools $tools) - { - $this->tools = $tools; - } - - /** - * {@inheritdoc} - */ - public function getDefaultAvatarUrl() - { - return $this->tools->getAdminImageUrl('prestashop-avatar.png'); - } -} diff --git a/src/Adapter/Employee/ContextEmployeeProvider.php b/src/Adapter/Employee/ContextEmployeeProvider.php deleted file mode 100644 index 4ed253ba..00000000 --- a/src/Adapter/Employee/ContextEmployeeProvider.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use Employee; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; - -/** - * Class ContextEmployeeProvider provides context employee data. - */ -final class ContextEmployeeProvider implements ContextEmployeeProviderInterface -{ - /** - * @var Employee - */ - private $contextEmployee; - - /** - * @param Employee $contextEmployee - */ - public function __construct(Employee $contextEmployee) - { - $this->contextEmployee = $contextEmployee; - } - - /** - * {@inheritdoc} - */ - public function isSuperAdmin() - { - return $this->contextEmployee->isSuperAdmin(); - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return (int) $this->contextEmployee->id; - } - - /** - * {@inheritdoc} - */ - public function getLanguageId() - { - return (int) $this->contextEmployee->id_lang; - } - - /** - * {@inheritdoc} - */ - public function getProfileId() - { - return (int) $this->contextEmployee->id_profile; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return [ - 'id' => (int) $this->contextEmployee->id, - 'profileId' => (int) $this->contextEmployee->id_profile, - 'languageId' => (int) $this->contextEmployee->id_lang, - 'firstname' => $this->contextEmployee->firstname, - 'lastname' => $this->contextEmployee->lastname, - 'email' => $this->contextEmployee->email, - ]; - } -} diff --git a/src/Adapter/Employee/EmployeeDataProvider.php b/src/Adapter/Employee/EmployeeDataProvider.php deleted file mode 100644 index 4bf33632..00000000 --- a/src/Adapter/Employee/EmployeeDataProvider.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use Employee; -use PrestaShop\PrestaShop\Core\Employee\EmployeeDataProviderInterface; - -/** - * Class EmployeeDataProvider provides employee data using legacy logic. - */ -final class EmployeeDataProvider implements EmployeeDataProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getEmployeeHashedPassword($employeeId) - { - $employee = new Employee($employeeId); - - return (string) $employee->passwd; - } - - /** - * {@inheritdoc} - */ - public function isSuperAdmin($employeeId) - { - $employee = new Employee($employeeId); - - return $employee->isSuperAdmin(); - } -} diff --git a/src/Adapter/Employee/EmployeeFormAccessChecker.php b/src/Adapter/Employee/EmployeeFormAccessChecker.php deleted file mode 100644 index d5342095..00000000 --- a/src/Adapter/Employee/EmployeeFormAccessChecker.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use PrestaShop\PrestaShop\Core\Employee\Access\EmployeeFormAccessCheckerInterface; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShop\PrestaShop\Core\Employee\EmployeeDataProviderInterface; -use PrestaShopBundle\Entity\Repository\TabRepository; -use Tab; - -/** - * Class EmployeeFormAccessChecker checks employee's access to the employee form. - */ -final class EmployeeFormAccessChecker implements EmployeeFormAccessCheckerInterface -{ - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @var TabRepository - */ - private $tabRepository; - - /** - * @var EmployeeDataProviderInterface - */ - private $employeeDataProvider; - - /** - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - * @param EmployeeDataProviderInterface $employeeDataProvider - * @param TabRepository $tabRepository - */ - public function __construct( - ContextEmployeeProviderInterface $contextEmployeeProvider, - EmployeeDataProviderInterface $employeeDataProvider, - TabRepository $tabRepository - ) { - $this->contextEmployeeProvider = $contextEmployeeProvider; - $this->employeeDataProvider = $employeeDataProvider; - $this->tabRepository = $tabRepository; - } - - /** - * {@inheritdoc} - */ - public function isRestrictedAccess($employeeId) - { - if (!is_int($employeeId)) { - throw new \InvalidArgumentException(sprintf('Employee ID must be an integer, %s given', gettype($employeeId))); - } - - return $employeeId === $this->contextEmployeeProvider->getId(); - } - - /** - * {@inheritdoc} - */ - public function canAccessEditFormFor($employeeId) - { - // To access super admin edit form you must be a super admin. - if ($this->employeeDataProvider->isSuperAdmin($employeeId)) { - return $this->contextEmployeeProvider->isSuperAdmin(); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function canAccessAddonsConnect() - { - return Tab::checkTabRights( - $this->tabRepository->findOneIdByClassName('AdminModulesController') - ); - } -} diff --git a/src/Adapter/Employee/FormLanguageChanger.php b/src/Adapter/Employee/FormLanguageChanger.php deleted file mode 100644 index 11bf4c32..00000000 --- a/src/Adapter/Employee/FormLanguageChanger.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use Language; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Employee\FormLanguageChangerInterface; - -/** - * Class FormLanguageChanger is responsible for changing the language, - * which is used in forms by the employee. - * It is not the language in which form texts are translated, but rather - * the language, which is selected by default in the translatable fields. - */ -final class FormLanguageChanger implements FormLanguageChangerInterface -{ - /** - * @var LegacyContext - */ - private $legacyContext; - - /** - * @param LegacyContext $legacyContext - */ - public function __construct(LegacyContext $legacyContext) - { - $this->legacyContext = $legacyContext; - } - - /** - * {@inheritdoc} - */ - public function changeLanguageInCookies($languageIsoCode) - { - $this->legacyContext->getContext()->cookie->employee_form_lang = (int) Language::getIdByIso($languageIsoCode); - $this->legacyContext->getContext()->cookie->write(); - } -} diff --git a/src/Adapter/Employee/NavigationMenuToggler.php b/src/Adapter/Employee/NavigationMenuToggler.php deleted file mode 100644 index e39f2722..00000000 --- a/src/Adapter/Employee/NavigationMenuToggler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Employee; - -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Employee\NavigationMenuTogglerInterface; - -/** - * Class NavigationMenuToggler handles collapsing/expanding the navigation for context employee. - */ -final class NavigationMenuToggler implements NavigationMenuTogglerInterface -{ - /** - * @var LegacyContext - */ - private $legacyContext; - - /** - * @param LegacyContext $legacyContext - */ - public function __construct(LegacyContext $legacyContext) - { - $this->legacyContext = $legacyContext; - } - - /** - * {@inheritdoc} - */ - public function toggleNavigationMenuInCookies($shouldCollapse) - { - $this->legacyContext->getContext()->cookie->collapse_menu = (int) $shouldCollapse; - $this->legacyContext->getContext()->cookie->write(); - } -} diff --git a/src/Adapter/EntityMapper.php b/src/Adapter/EntityMapper.php deleted file mode 100644 index 36b69cb8..00000000 --- a/src/Adapter/EntityMapper.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Cache; -use Db; -use DbQuery; -use Shop; - -/** - * Not used in PrestaShop core, only in tests. - * - * @deprecated since 1.7.5, to be removed in 1.8 - */ -class EntityMapper -{ - /** - * Load ObjectModel. - * - * @param $id - * @param $id_lang - * @param $entity \ObjectModel - * @param $entity_defs - * @param $id_shop - * @param $should_cache_objects - * - * @throws \PrestaShopDatabaseException - */ - public function load($id, $id_lang, $entity, $entity_defs, $id_shop, $should_cache_objects) - { - // Load object from database if object id is present - $cache_id = 'objectmodel_' . $entity_defs['classname'] . '_' . (int) $id . '_' . (int) $id_shop . '_' . (int) $id_lang; - if (!$should_cache_objects || !\Cache::isStored($cache_id)) { - $sql = new DbQuery(); - $sql->from($entity_defs['table'], 'a'); - $sql->where('a.`' . bqSQL($entity_defs['primary']) . '` = ' . (int) $id); - - // Get lang informations - if ($id_lang && isset($entity_defs['multilang']) && $entity_defs['multilang']) { - $sql->leftJoin($entity_defs['table'] . '_lang', 'b', 'a.`' . bqSQL($entity_defs['primary']) . '` = b.`' . bqSQL($entity_defs['primary']) . '` AND b.`id_lang` = ' . (int) $id_lang); - if ($id_shop && !empty($entity_defs['multilang_shop'])) { - $sql->where('b.`id_shop` = ' . (int) $id_shop); - } - } - - // Get shop informations - if (Shop::isTableAssociated($entity_defs['table'])) { - $sql->leftJoin($entity_defs['table'] . '_shop', 'c', 'a.`' . bqSQL($entity_defs['primary']) . '` = c.`' . bqSQL($entity_defs['primary']) . '` AND c.`id_shop` = ' . (int) $id_shop); - } - - if ($object_datas = Db::getInstance()->getRow($sql)) { - if (!$id_lang && isset($entity_defs['multilang']) && $entity_defs['multilang']) { - $sql = 'SELECT * - FROM `' . bqSQL(_DB_PREFIX_ . $entity_defs['table']) . '_lang` - WHERE `' . bqSQL($entity_defs['primary']) . '` = ' . (int) $id - . (($id_shop && $entity->isLangMultishop()) ? ' AND `id_shop` = ' . (int) $id_shop : ''); - - if ($object_datas_lang = Db::getInstance()->executeS($sql)) { - foreach ($object_datas_lang as $row) { - foreach ($row as $key => $value) { - if ($key != $entity_defs['primary'] && array_key_exists($key, $entity)) { - if (!isset($object_datas[$key]) || !is_array($object_datas[$key])) { - $object_datas[$key] = []; - } - - $object_datas[$key][$row['id_lang']] = $value; - } - } - } - } - } - $entity->id = (int) $id; - foreach ($object_datas as $key => $value) { - if (array_key_exists($key, $entity_defs['fields']) - || array_key_exists($key, $entity)) { - $entity->{$key} = $value; - } else { - unset($object_datas[$key]); - } - } - if ($should_cache_objects) { - Cache::store($cache_id, $object_datas); - } - } - } else { - $object_datas = Cache::retrieve($cache_id); - if ($object_datas) { - $entity->id = (int) $id; - foreach ($object_datas as $key => $value) { - $entity->{$key} = $value; - } - } - } - } -} diff --git a/src/Adapter/EntityMetaDataRetriever.php b/src/Adapter/EntityMetaDataRetriever.php deleted file mode 100644 index b85ea9d9..00000000 --- a/src/Adapter/EntityMetaDataRetriever.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\PrestaShop\Core\Foundation\Database\EntityMetaData; - -/** - * Retrieve all meta data of an ObjectModel. - */ -class EntityMetaDataRetriever -{ - /** - * @param string $className - * - * @return EntityMetaData - * - * @throws \PrestaShop\PrestaShop\Adapter\CoreException - */ - public function getEntityMetaData($className) - { - $metaData = new EntityMetaData(); - - $metaData->setEntityClassName($className); - - if (property_exists($className, 'definition')) { - // Legacy entity - $classVars = get_class_vars($className); - $metaData->setTableName($classVars['definition']['table']); - $metaData->setPrimaryKeyFieldNames([$classVars['definition']['primary']]); - } else { - throw new CoreException(sprintf('Cannot get metadata for entity `%s`.', $className)); - } - - return $metaData; - } -} diff --git a/src/Adapter/Environment.php b/src/Adapter/Environment.php deleted file mode 100644 index 80fa4ce9..00000000 --- a/src/Adapter/Environment.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\PrestaShop\Core\EnvironmentInterface; - -/** - * Class Environment is used to store/access environment information like the current - * environment name or to know if debug mode is enabled. It can be built via - * dependency injection but it also manages default fallback based on legacy PrestaShop - * const. - */ -class Environment implements EnvironmentInterface -{ - /** - * @var bool - */ - private $isDebug; - - /** - * @var string - */ - private $name; - - /** - * @param bool|null $isDebug - * @param string|null $name - */ - public function __construct($isDebug = null, $name = null) - { - if (null === $isDebug) { - $this->isDebug = defined(_PS_MODE_DEV_) ? _PS_MODE_DEV_ : true; - } else { - $this->isDebug = $isDebug; - } - - if (null !== $name) { - $this->name = $name; - } else { - if (defined(_PS_ENV_)) { - $this->name = _PS_ENV_; - } else { - $this->name = $this->isDebug ? 'dev' : 'prod'; - } - } - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function isDebug() - { - return $this->isDebug; - } - - /** - * {@inheritdoc} - */ - public function getCacheDir() - { - if (defined('_PS_CACHE_DIR_')) { - return _PS_CACHE_DIR_; - } - - return _PS_ROOT_DIR_ . '/var/cache/' . $this->getName() . '/'; - } -} diff --git a/src/Adapter/Feature/CombinationFeature.php b/src/Adapter/Feature/CombinationFeature.php deleted file mode 100644 index 58ca6a00..00000000 --- a/src/Adapter/Feature/CombinationFeature.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature; - -use Combination; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; - -/** - * This class manages Combination feature. - */ -class CombinationFeature implements FeatureInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isUsed() - { - return Combination::isCurrentlyUsed(); - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return Combination::isFeatureActive(); - } - - /** - * {@inheritdoc} - */ - public function enable() - { - $this->configuration->set('PS_COMBINATION_FEATURE_ACTIVE', true); - } - - /** - * {@inheritdoc} - */ - public function disable() - { - $this->configuration->set('PS_COMBINATION_FEATURE_ACTIVE', false); - } - - /** - * {@inheritdoc} - */ - public function update($status) - { - true === $status ? $this->enable() : $this->disable(); - } -} diff --git a/src/Adapter/Feature/CommandHandler/AddFeatureHandler.php b/src/Adapter/Feature/CommandHandler/AddFeatureHandler.php deleted file mode 100644 index c62172a9..00000000 --- a/src/Adapter/Feature/CommandHandler/AddFeatureHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature\CommandHandler; - -use Feature; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\AddFeatureCommand; -use PrestaShop\PrestaShop\Core\Domain\Feature\CommandHandler\AddFeatureHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\CannotAddFeatureException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Handles adding of features using legacy logic. - */ -final class AddFeatureHandler extends AbstractObjectModelHandler implements AddFeatureHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddFeatureCommand $command) - { - $feature = new Feature(); - - $feature->name = $command->getLocalizedNames(); - - if (false === $feature->validateFields(false)) { - throw new FeatureConstraintException('Invalid feature data'); - } - - if (false === $feature->validateFieldsLang(false)) { - throw new FeatureConstraintException('Invalid feature data', FeatureConstraintException::INVALID_NAME); - } - - if (false === $feature->add()) { - throw new CannotAddFeatureException('Unable to create new feature'); - } - - $this->associateWithShops($feature, $command->getShopAssociation()); - - return new FeatureId($feature->id); - } -} diff --git a/src/Adapter/Feature/CommandHandler/EditFeatureHandler.php b/src/Adapter/Feature/CommandHandler/EditFeatureHandler.php deleted file mode 100644 index ce8df8c1..00000000 --- a/src/Adapter/Feature/CommandHandler/EditFeatureHandler.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature\CommandHandler; - -use Feature; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\EditFeatureCommand; -use PrestaShop\PrestaShop\Core\Domain\Feature\CommandHandler\EditFeatureHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\CannotEditFeatureException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureNotFoundException; - -/** - * Handles feature editing. - */ -final class EditFeatureHandler extends AbstractObjectModelHandler implements EditFeatureHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditFeatureCommand $command) - { - $feature = new Feature($command->getFeatureId()->getValue()); - - if (empty($feature->id)) { - throw new FeatureNotFoundException('Feature could not be found.'); - } - - if (null !== $command->getLocalizedNames()) { - $feature->name = $command->getLocalizedNames(); - } - - if (null !== $command->getAssociatedShopIds()) { - $this->associateWithShops($feature, $command->getAssociatedShopIds()); - } - - if (false === $feature->validateFields(false)) { - throw new FeatureConstraintException('Invalid data when updating feature'); - } - - if (false === $feature->validateFieldsLang(false)) { - throw new FeatureConstraintException('Invalid data when updating feature', FeatureConstraintException::INVALID_NAME); - } - - if (false === $feature->update()) { - throw new CannotEditFeatureException(sprintf('Failed to edit Feature with id "%s".', $feature->id)); - } - } -} diff --git a/src/Adapter/Feature/FeatureDataProvider.php b/src/Adapter/Feature/FeatureDataProvider.php deleted file mode 100644 index 5023a3fd..00000000 --- a/src/Adapter/Feature/FeatureDataProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature; - -use Feature; -use FeatureValue; - -/** - * This class will provide data from DB / ORM about Feature. - */ -class FeatureDataProvider -{ - /** - * Get all features for a given language. - * - * @param int $id_lang Language id - * @param bool $with_shop - * - * @return array Multiple arrays with feature's data - */ - public static function getFeatures($id_lang, $with_shop = true) - { - return Feature::getFeatures($id_lang, $with_shop); - } - - /** - * Get all values for a given feature and language. - * - * @param int $id_lang Language id - * @param int $id_feature Feature id - * @param bool $custom - * - * @return array Array with feature's values - */ - public static function getFeatureValuesWithLang($id_lang, $id_feature, $custom = false) - { - return FeatureValue::getFeatureValuesWithLang($id_lang, $id_feature, $custom); - } - - /** - * Get all language for a given value. - * - * @param bool $id_feature_value Feature value id - * - * @return array Array with value's languages - */ - public static function getFeatureValueLang($id_feature_value) - { - return FeatureValue::getFeatureValueLang($id_feature_value); - } -} diff --git a/src/Adapter/Feature/FeatureFeature.php b/src/Adapter/Feature/FeatureFeature.php deleted file mode 100644 index 3b0e3d5c..00000000 --- a/src/Adapter/Feature/FeatureFeature.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature; - -use Feature; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; - -/** - * This class manages Feature feature. - */ -class FeatureFeature implements FeatureInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isUsed() - { - return Feature::isCurrentlyUsed(); - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return Feature::isFeatureActive(); - } - - /** - * {@inheritdoc} - */ - public function enable() - { - $this->configuration->set('PS_FEATURE_FEATURE_ACTIVE', true); - } - - /** - * {@inheritdoc} - */ - public function disable() - { - $this->configuration->set('PS_FEATURE_FEATURE_ACTIVE', false); - } - - /** - * {@inheritdoc} - */ - public function update($status) - { - true === $status ? $this->enable() : $this->disable(); - } -} diff --git a/src/Adapter/Feature/GroupFeature.php b/src/Adapter/Feature/GroupFeature.php deleted file mode 100644 index 186bcaae..00000000 --- a/src/Adapter/Feature/GroupFeature.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature; - -use Group; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; - -/** - * This class manages Group feature. - */ -class GroupFeature implements FeatureInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isUsed() - { - return Group::isCurrentlyUsed(); - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return Group::isFeatureActive(); - } - - /** - * {@inheritdoc} - */ - public function enable() - { - $this->configuration->set('PS_GROUP_FEATURE_ACTIVE', true); - } - - /** - * {@inheritdoc} - */ - public function disable() - { - $this->configuration->set('PS_GROUP_FEATURE_ACTIVE', false); - } - - /** - * {@inheritdoc} - */ - public function update($status) - { - true === $status ? $this->enable() : $this->disable(); - } -} diff --git a/src/Adapter/Feature/MultistoreFeature.php b/src/Adapter/Feature/MultistoreFeature.php deleted file mode 100644 index 42c37232..00000000 --- a/src/Adapter/Feature/MultistoreFeature.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature; - -use PrestaShop\PrestaShop\Adapter\Entity\Shop; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreConfig; - -/** - * Class MultistoreFeature provides data about multishop feature usage. - * - * @internal - */ -final class MultistoreFeature implements FeatureInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isUsed() - { - // internally it checks if feature is active - // and at least 2 shops exist - return Shop::isFeatureActive(); - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return (bool) $this->configuration->get(MultistoreConfig::FEATURE_STATUS); - } - - /** - * {@inheritdoc} - */ - public function enable() - { - $this->configuration->set(MultistoreConfig::FEATURE_STATUS, 1); - } - - /** - * {@inheritdoc} - */ - public function disable() - { - $this->configuration->set(MultistoreConfig::FEATURE_STATUS, 0); - } - - /** - * {@inheritdoc} - */ - public function update($status) - { - $status ? $this->enable() : $this->disable(); - } -} diff --git a/src/Adapter/Feature/QueryHandler/GetFeatureForEditingHandler.php b/src/Adapter/Feature/QueryHandler/GetFeatureForEditingHandler.php deleted file mode 100644 index da6ad252..00000000 --- a/src/Adapter/Feature/QueryHandler/GetFeatureForEditingHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Feature\QueryHandler; - -use Feature; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Query\GetFeatureForEditing; -use PrestaShop\PrestaShop\Core\Domain\Feature\QueryHandler\GetFeatureForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Feature\QueryResult\EditableFeature; - -/** - * Handles get feature for editing query. - */ -final class GetFeatureForEditingHandler implements GetFeatureForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetFeatureForEditing $query) - { - $feature = new Feature($query->getFeatureId()->getValue()); - - if (empty($feature->id)) { - throw new FeatureNotFoundException('Feature could not be found.'); - } - - return new EditableFeature( - $query->getFeatureId(), - $feature->name, - $feature->getAssociatedShops() - ); - } -} diff --git a/src/Adapter/File/HtaccessFileGenerator.php b/src/Adapter/File/HtaccessFileGenerator.php deleted file mode 100644 index e84480f5..00000000 --- a/src/Adapter/File/HtaccessFileGenerator.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\File; - -use PrestaShop\PrestaShop\Adapter\Cache\CacheClearer; -use PrestaShop\PrestaShop\Adapter\Tools; - -/** - * Class HtaccessFileGenerator is responsible for generating htaccess file with its default content. - */ -class HtaccessFileGenerator -{ - /** - * @var CacheClearer - */ - private $cacheClearer; - - /** - * @var Tools - */ - private $tools; - - /** - * @var bool - */ - private $multipleViewsConfiguration; - - /** - * HtaccessFileGenerator constructor. - * - * @param CacheClearer $cacheClearer - * @param Tools $tools - * @param bool $multipleViewsConfiguration - */ - public function __construct(CacheClearer $cacheClearer, Tools $tools, $multipleViewsConfiguration) - { - $this->cacheClearer = $cacheClearer; - $this->tools = $tools; - $this->multipleViewsConfiguration = $multipleViewsConfiguration; - } - - /** - * Generates htaccess file and its content. - * - * @param bool|null $disableMultiView if null, rely on the Shop configuration - * - * @return bool - */ - public function generateFile($disableMultiView = null) - { - if (null === $disableMultiView) { - $disableMultiView = $this->multipleViewsConfiguration; - } - - $isGenerated = $disableMultiView ? $this->tools->generateHtaccessWithMultiViews() : $this->tools->generateHtaccessWithoutMultiViews(); - - if ($isGenerated) { - $this->cacheClearer->clearAllCaches(); - } - - return $isGenerated; - } -} diff --git a/src/Adapter/File/RobotsTextFileGenerator.php b/src/Adapter/File/RobotsTextFileGenerator.php deleted file mode 100644 index c5c79e69..00000000 --- a/src/Adapter/File/RobotsTextFileGenerator.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\File; - -use Tools; - -/** - * Class RobotsTextFileGenerator is responsible for generating robots txt file. - */ -class RobotsTextFileGenerator -{ - /** - * Generates the robots.txt file. - * - * @return bool - */ - public function generateFile() - { - return Tools::generateRobotsFile(true); - } -} diff --git a/src/Adapter/File/Uploader/AttachmentFileUploader.php b/src/Adapter/File/Uploader/AttachmentFileUploader.php deleted file mode 100644 index 54cff044..00000000 --- a/src/Adapter/File/Uploader/AttachmentFileUploader.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\File\Uploader; - -use Attachment; -use ErrorException; -use PrestaShop\PrestaShop\Core\Configuration\UploadSizeConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\AttachmentFileUploaderInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentUploadFailedException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotUnlinkAttachmentException; -use PrestaShopException; -use Symfony\Component\HttpFoundation\File\Exception\FileException; - -/** - * Uploads attachment file and if needed deletes old attachment file - * - * @internal - */ -final class AttachmentFileUploader implements AttachmentFileUploaderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var UploadSizeConfigurationInterface - */ - private $uploadSizeConfiguration; - - public function __construct( - ConfigurationInterface $configuration, - UploadSizeConfigurationInterface $uploadSizeConfiguration - ) { - $this->configuration = $configuration; - $this->uploadSizeConfiguration = $uploadSizeConfiguration; - } - - /** - * {@inheritdoc} - * - * @throws AttachmentConstraintException - * @throws AttachmentNotFoundException - * @throws AttachmentUploadFailedException - */ - public function upload( - string $filePath, - string $uniqueFileName, - int $fileSize, - int $id = null, - $throwExceptionOnFailure = true - ): void { - $this->checkFileAllowedForUpload($fileSize); - $this->uploadFile($filePath, $uniqueFileName, $fileSize); - if ($id !== null) { - $this->deleteOldFile($id, $throwExceptionOnFailure); - } - } - - /** - * @param bool $throwExceptionOnFailure - * - * @throws AttachmentNotFoundException - * @throws CannotUnlinkAttachmentException - */ - private function deleteOldFile(int $attachmentId, $throwExceptionOnFailure): void - { - try { - $attachment = new Attachment($attachmentId); - $fileLink = _PS_DOWNLOAD_DIR_ . $attachment->file; - - try { - unlink($fileLink); - } catch (ErrorException $e) { - if ($throwExceptionOnFailure) { - throw new CannotUnlinkAttachmentException($e->getMessage(), 0, null, $fileLink); - } - } - } catch (PrestaShopException $e) { - throw new AttachmentNotFoundException(sprintf('Attachment with id "%s" was not found.', $attachmentId)); - } - } - - /** - * @throws AttachmentConstraintException - * @throws AttachmentUploadFailedException - */ - private function uploadFile(string $filePath, string $uniqid, int $fileSize): void - { - if ($fileSize > ($this->configuration->get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024 * 1024)) { - throw new AttachmentConstraintException( - sprintf( - 'Max file size allowed is "%s" bytes. Uploaded file size is "%s".', - (string) ($this->configuration->get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024), - number_format(($fileSize / 1024), 2, '.', '') - ), - AttachmentConstraintException::INVALID_FILE_SIZE - ); - } - - try { - move_uploaded_file($filePath, _PS_DOWNLOAD_DIR_ . $uniqid); - } catch (FileException $e) { - throw new AttachmentUploadFailedException(sprintf('Failed to copy the file %s.', $filePath)); - } - } - - /** - * @throws AttachmentConstraintException - */ - private function checkFileAllowedForUpload(int $fileSize): void - { - $maxFileSize = $this->uploadSizeConfiguration->getMaxUploadSizeInBytes(); - - if ($maxFileSize > 0 && $fileSize > $maxFileSize) { - throw new AttachmentConstraintException( - sprintf('Max file size allowed is "%s" bytes. Uploaded file size is "%s".', $maxFileSize, $fileSize), - AttachmentConstraintException::INVALID_FILE_SIZE - ); - } - } -} diff --git a/src/Adapter/Form/ChoiceProvider/CarrierForOrderChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/CarrierForOrderChoiceProvider.php deleted file mode 100644 index 997aa0e9..00000000 --- a/src/Adapter/Form/ChoiceProvider/CarrierForOrderChoiceProvider.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Address; -use Carrier; -use Cart; -use Customer; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * @internal - */ -final class CarrierForOrderChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices(array $options): array - { - $options = $this->resolveOptions($options); - - $cart = Cart::getCartByOrderId($options['order_id']); - $groups = Customer::getGroupsStatic((int) $cart->id_customer); - $address = new Address((int) $cart->id_address_delivery); - - $carriers = Carrier::getCarriersForOrder(Address::getZoneById((int) $address->id), $groups, $cart); - $choices = []; - - foreach ($carriers as $carrier) { - $delay = $carrier['delay'] ? sprintf(' (%s)', $carrier['delay']) : ''; - - $choices[$carrier['name'] . $delay] = (int) $carrier['id_carrier']; - } - - return $choices; - } - - /** - * @param array $options - * - * @return array - */ - private function resolveOptions(array $options): array - { - $resolver = new OptionsResolver(); - $resolver->setRequired([ - 'order_id', - ]); - $resolver->setAllowedTypes('order_id', 'int'); - - return $resolver->resolve($options); - } -} diff --git a/src/Adapter/Form/ChoiceProvider/CategoryTreeChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/CategoryTreeChoiceProvider.php deleted file mode 100644 index 1c8285af..00000000 --- a/src/Adapter/Form/ChoiceProvider/CategoryTreeChoiceProvider.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Category\CategoryDataProvider; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class CategoryTreeChoiceProvider provides categories as tree choices. - */ -final class CategoryTreeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var CategoryDataProvider - */ - private $categoryDataProvider; - - /** - * @var int - */ - private $contextShopRootCategoryId; - - /** - * @var bool - */ - private $enabledCategoriesOnly; - - /** - * @param CategoryDataProvider $categoryDataProvider - * @param int $contextShopRootCategoryId - * @param bool $enabledCategoriesOnly - */ - public function __construct(CategoryDataProvider $categoryDataProvider, $contextShopRootCategoryId, $enabledCategoriesOnly = false) - { - $this->categoryDataProvider = $categoryDataProvider; - $this->contextShopRootCategoryId = $contextShopRootCategoryId; - $this->enabledCategoriesOnly = $enabledCategoriesOnly; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $categories = $this->categoryDataProvider->getNestedCategories($this->contextShopRootCategoryId, false, $this->enabledCategoriesOnly); - $choices = []; - - foreach ($categories as $category) { - $choices[] = $this->buildChoiceTree($category); - } - - return $choices; - } - - /** - * @param array $category - * - * @return array - */ - private function buildChoiceTree(array $category) - { - $tree = [ - 'id_category' => $category['id_category'], - 'name' => $category['name'], - ]; - - if (isset($category['children'])) { - foreach ($category['children'] as $childCategory) { - $tree['children'][] = $this->buildChoiceTree($childCategory); - } - } - - return $tree; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/CountryStateByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/CountryStateByIdChoiceProvider.php deleted file mode 100644 index cae03303..00000000 --- a/src/Adapter/Form/ChoiceProvider/CountryStateByIdChoiceProvider.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Country; -use PrestaShop\PrestaShop\Core\Exception\CoreException; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopException; -use State; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Provides choices of country states with state name as key and id as value - */ -final class CountryStateByIdChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices(array $options) - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - $resolvedOptions = $resolver->resolve($options); - $choices = []; - - try { - $countryId = $resolvedOptions['id_country']; - $countryHasStates = (new Country($countryId))->contains_states; - - if (!$countryHasStates) { - return []; - } - - $states = State::getStatesByIdCountry($countryId, $resolvedOptions['only_active']); - - foreach ($states as $state) { - $choices[$state['name']] = $state['id_state']; - } - } catch (PrestaShopException $e) { - throw new CoreException(sprintf('An error occurred when getting states for country id "%s"', $countryId)); - } - - return $choices; - } - - /** - * Configures array parameters and default values - * - * @param OptionsResolver $resolver - */ - private function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults(['only_active' => false]); - $resolver->setRequired('id_country'); - $resolver->setAllowedTypes('id_country', 'int'); - $resolver->setAllowedTypes('only_active', 'bool'); - $this->allowIdCountryGreaterThanZero($resolver); - } - - /** - * @param OptionsResolver $resolver - */ - private function allowIdCountryGreaterThanZero(OptionsResolver $resolver) - { - $resolver->setAllowedValues('id_country', function ($value) { - return 0 < $value; - }); - } -} diff --git a/src/Adapter/Form/ChoiceProvider/CurrencySymbolByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/CurrencySymbolByIdChoiceProvider.php deleted file mode 100644 index c7efe859..00000000 --- a/src/Adapter/Form/ChoiceProvider/CurrencySymbolByIdChoiceProvider.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Currency; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; - -/** - * Provides currency choices where currency is represented by symbol (e.g. € for euro) and value is currency id. - */ -final class CurrencySymbolByIdChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices(array $options): array - { - $currencies = Currency::getCurrenciesByIdShop($options['id_shop']); - $choices = []; - - foreach ($currencies as $currency) { - $choices[$currency['symbol']] = (int) $currency['id_currency']; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/EmployeeNameByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/EmployeeNameByIdChoiceProvider.php deleted file mode 100644 index e348d7b6..00000000 --- a/src/Adapter/Form/ChoiceProvider/EmployeeNameByIdChoiceProvider.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Employee; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * @internal - */ -final class EmployeeNameByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $employees = Employee::getEmployees(); - - $choices = []; - - foreach ($employees as $employee) { - $name = sprintf('%s. %s', substr($employee['firstname'], 0, 1), $employee['lastname']); - - $choices[$name] = (int) $employee['id_employee']; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/GenderByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/GenderByIdChoiceProvider.php deleted file mode 100644 index 4309429f..00000000 --- a/src/Adapter/Form/ChoiceProvider/GenderByIdChoiceProvider.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Gender; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class GenderByIdChoiceProvider provides gender choices with label as title and value as gender id. - */ -final class GenderByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $genders = Gender::getGenders(); - $choices = []; - - /** @var Gender $gender */ - foreach ($genders as $gender) { - $choices[$gender->name] = $gender->id; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/GroupByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/GroupByIdChoiceProvider.php deleted file mode 100644 index 624fb5d3..00000000 --- a/src/Adapter/Form/ChoiceProvider/GroupByIdChoiceProvider.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Group; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Provides choices for customer groups - */ -final class GroupByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var int - */ - private $contextLangId; - - /** - * @param ConfigurationInterface $configuration - * @param int $contextLangId - */ - public function __construct(ConfigurationInterface $configuration, $contextLangId) - { - $this->configuration = $configuration; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - $groups = Group::getGroups($this->contextLangId, true); - - $groupsToSkip = [ - (int) $this->configuration->get('PS_UNIDENTIFIED_GROUP'), - (int) $this->configuration->get('PS_GUEST_GROUP'), - ]; - - foreach ($groups as $group) { - $groupId = $group['id_group']; - - if (in_array($groups, $groupsToSkip)) { - continue; - } - - $choices[$group['name']] = (int) $groupId; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/InstalledPaymentModulesChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/InstalledPaymentModulesChoiceProvider.php deleted file mode 100644 index da0a982b..00000000 --- a/src/Adapter/Form/ChoiceProvider/InstalledPaymentModulesChoiceProvider.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Module; -use PaymentModule; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Validate; - -final class InstalledPaymentModulesChoiceProvider implements FormChoiceProviderInterface -{ - private static $paymentModules; - - /** - * {@inheritdoc} - */ - public function getChoices(): array - { - if (!self::$paymentModules) { - self::$paymentModules = []; - - foreach (PaymentModule::getInstalledPaymentModules() as $payment) { - $module = Module::getInstanceByName($payment['name']); - if (Validate::isLoadedObject($module) && $module->active) { - self::$paymentModules[$module->name] = $module->displayName; - } - } - } - - return self::$paymentModules; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/ManufacturerNameByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/ManufacturerNameByIdChoiceProvider.php deleted file mode 100644 index 0c463538..00000000 --- a/src/Adapter/Form/ChoiceProvider/ManufacturerNameByIdChoiceProvider.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Provides choices of manufacturers with manufacturer name as key and id as value - */ -final class ManufacturerNameByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $manufacturers; - - public function __construct(array $manufacturers) - { - $this->manufacturers = $manufacturers; - } - - /** - * Get choices. - * - * @return array - */ - public function getChoices() - { - $choices = []; - - foreach ($this->manufacturers as $manufacturer) { - $choices[$manufacturer['name']] = (int) $manufacturer['id_manufacturer']; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/OrderCountriesChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/OrderCountriesChoiceProvider.php deleted file mode 100644 index 567b2822..00000000 --- a/src/Adapter/Form/ChoiceProvider/OrderCountriesChoiceProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Context; -use Country; -use Db; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Shop; - -/** - * Choices for countries in which at least one order has been placed - */ -final class OrderCountriesChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - if (!Country::isCurrentlyUsed('country', true)) { - return []; - } - - $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT DISTINCT c.id_country, cl.`name` - FROM `' . _DB_PREFIX_ . 'orders` o - ' . Shop::addSqlAssociation('orders', 'o') . ' - INNER JOIN `' . _DB_PREFIX_ . 'address` a - ON a.id_address = o.id_address_delivery - INNER JOIN `' . _DB_PREFIX_ . 'country` c - ON a.id_country = c.id_country - INNER JOIN `' . _DB_PREFIX_ . 'country_lang` cl - ON (c.`id_country` = cl.`id_country` - AND cl.`id_lang` = ' . (int) Context::getContext()->language->id . ') - ORDER BY cl.name ASC' - ); - - $choices = []; - - foreach ($result as $row) { - $choices[$row['name']] = $row['id_country']; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/OrderInvoiceByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/OrderInvoiceByIdChoiceProvider.php deleted file mode 100644 index a92bcd52..00000000 --- a/src/Adapter/Form/ChoiceProvider/OrderInvoiceByIdChoiceProvider.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use Currency; -use Order; -use OrderInvoice; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; - -final class OrderInvoiceByIdChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * @var LocaleInterface - */ - private $locale; - - /** - * @param LocaleInterface $locale - */ - public function __construct(LocaleInterface $locale) - { - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function getChoices(array $options): array - { - $order = new Order($options['id_order']); - $invoices = $order->getInvoicesCollection(); - $labelFormat = isset($options['display_total']) && false !== $options['display_total'] ? '%s - %s' : '%s'; - - $choices = []; - - /** @var OrderInvoice $invoice */ - foreach ($invoices as $invoice) { - $invoiceLabel = sprintf( - $labelFormat, - $invoice->getInvoiceNumberFormatted($options['id_lang'], $order->id_shop), - $this->locale->formatPrice($invoice->total_paid_tax_incl, Currency::getIsoCodeById($invoice->getOrder()->id_currency)) - ); - $choices[$invoiceLabel] = $invoice->id; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/ProfileByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/ProfileByIdChoiceProvider.php deleted file mode 100644 index cf120c39..00000000 --- a/src/Adapter/Form/ChoiceProvider/ProfileByIdChoiceProvider.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Profile; - -/** - * Class ProfileByIdChoiceProvider provides employee profile choices with name as label and profile id as value. - */ -final class ProfileByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @param int $contextLangId - */ - public function __construct($contextLangId) - { - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $profiles = Profile::getProfiles($this->contextLangId); - $choices = []; - - foreach ($profiles as $profile) { - $choices[$profile['name']] = $profile['id_profile']; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/ResourcesChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/ResourcesChoiceProvider.php deleted file mode 100644 index 3841fd73..00000000 --- a/src/Adapter/Form/ChoiceProvider/ResourcesChoiceProvider.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use WebserviceRequest; - -/** - * Provides resources that can be accessed by webservice request - * - * @internal - */ -final class ResourcesChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $legacyResources = WebserviceRequest::getResources(); - $choices = []; - - foreach (array_keys($legacyResources) as $resource) { - $choices[$resource] = $resource; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/RiskByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/RiskByIdChoiceProvider.php deleted file mode 100644 index 077b57e8..00000000 --- a/src/Adapter/Form/ChoiceProvider/RiskByIdChoiceProvider.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Risk; - -/** - * Class RiskByIdChoiceProvider - * - * @internal - */ -final class RiskByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $risks = Risk::getRisks(); - $choices = []; - - /** @var Risk $risk */ - foreach ($risks as $risk) { - $choices[$risk->name] = (int) $risk->id; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/ShopNameByIdChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/ShopNameByIdChoiceProvider.php deleted file mode 100644 index 0c9ec8ef..00000000 --- a/src/Adapter/Form/ChoiceProvider/ShopNameByIdChoiceProvider.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Shop; - -/** - * Provides shop names by name => id value pairs - */ -final class ShopNameByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $shopsById = []; - - foreach (Shop::getShops() as $shop) { - $shopsById[$shop['name']] = $shop['id_shop']; - } - - return $shopsById; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/ShopTreeChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/ShopTreeChoiceProvider.php deleted file mode 100644 index dc524b2d..00000000 --- a/src/Adapter/Form/ChoiceProvider/ShopTreeChoiceProvider.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Shop; -use ShopGroup; - -/** - * Class ShopTreeChoiceProvider provides shop choices for choice tree. - * - * @internal - */ -final class ShopTreeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $shopGroups = ShopGroup::getShopGroups(); - $choices = []; - - /** @var ShopGroup $shopGroup */ - foreach ($shopGroups as $shopGroup) { - $shopGroupChoices = [ - 'name' => $shopGroup->name, - 'id_shop' => null, - 'children' => [], - ]; - - $shops = ShopGroup::getShopsFromGroup($shopGroup->id); - - foreach ($shops as $shopId) { - $shop = Shop::getShop($shopId['id_shop']); - - // If context employee doesn't have access to a shop, $shop will be false - if (false === $shop) { - continue; - } - - $shopGroupChoices['children'][] = [ - 'name' => $shop['name'], - 'id_shop' => $shop['id_shop'], - ]; - } - - $choices[] = $shopGroupChoices; - } - - return $choices; - } -} diff --git a/src/Adapter/Form/ChoiceProvider/TaxRuleGroupChoiceProvider.php b/src/Adapter/Form/ChoiceProvider/TaxRuleGroupChoiceProvider.php deleted file mode 100644 index c3bec81d..00000000 --- a/src/Adapter/Form/ChoiceProvider/TaxRuleGroupChoiceProvider.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use TaxRulesGroup; - -/** - * Provides tax rule group choices with tax rule name as key and id as value - */ -final class TaxRuleGroupChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - $rules = TaxRulesGroup::getTaxRulesGroupsForOptions(); - - $choices = []; - foreach ($rules as $rule) { - $choices[$rule['name']] = $rule['id_tax_rules_group']; - } - - return $choices; - } -} diff --git a/src/Adapter/GeneralConfiguration.php b/src/Adapter/GeneralConfiguration.php deleted file mode 100644 index ff544282..00000000 --- a/src/Adapter/GeneralConfiguration.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Manages the configuration data about general options. - */ -class GeneralConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'check_modules_update' => $this->configuration->getBoolean('PRESTASTORE_LIVE'), - 'check_ip_address' => $this->configuration->getBoolean('PS_COOKIE_CHECKIP'), - 'front_cookie_lifetime' => $this->configuration->get('PS_COOKIE_LIFETIME_FO'), - 'back_cookie_lifetime' => $this->configuration->get('PS_COOKIE_LIFETIME_BO'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PRESTASTORE_LIVE', (bool) $configuration['check_modules_update']); - $this->configuration->set('PS_COOKIE_CHECKIP', (bool) $configuration['check_ip_address']); - $this->configuration->set('PS_COOKIE_LIFETIME_FO', (int) $configuration['front_cookie_lifetime']); - $this->configuration->set('PS_COOKIE_LIFETIME_BO', (int) $configuration['back_cookie_lifetime']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['check_modules_update'], - $configuration['check_ip_address'], - $configuration['front_cookie_lifetime'], - $configuration['back_cookie_lifetime'] - ); - } -} diff --git a/src/Adapter/Geolocation/GeolocationByIpAddressConfiguration.php b/src/Adapter/Geolocation/GeolocationByIpAddressConfiguration.php deleted file mode 100644 index d68289db..00000000 --- a/src/Adapter/Geolocation/GeolocationByIpAddressConfiguration.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Geolocation; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class GeolocationByIpAddressConfiguration is responsible for configuring geolocation configuration. - */ -final class GeolocationByIpAddressConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct( - Configuration $configuration - ) { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'geolocation_enabled' => $this->configuration->getBoolean('PS_GEOLOCATION_ENABLED'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_GEOLOCATION_ENABLED', $config['geolocation_enabled']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset($config['geolocation_enabled']); - } -} diff --git a/src/Adapter/Geolocation/GeolocationIpAddressWhitelistConfiguration.php b/src/Adapter/Geolocation/GeolocationIpAddressWhitelistConfiguration.php deleted file mode 100644 index 8b52b376..00000000 --- a/src/Adapter/Geolocation/GeolocationIpAddressWhitelistConfiguration.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Geolocation; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class GeolocationIpAddressWhitelistConfiguration is responsible for configuring geolocation IP address whitelist data. - */ -final class GeolocationIpAddressWhitelistConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'geolocation_whitelist' => $this->configuration->get('PS_GEOLOCATION_WHITELIST'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_GEOLOCATION_WHITELIST', $config['geolocation_whitelist']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['geolocation_whitelist'] - ); - } -} diff --git a/src/Adapter/Geolocation/GeolocationOptionsConfiguration.php b/src/Adapter/Geolocation/GeolocationOptionsConfiguration.php deleted file mode 100644 index 6b18610e..00000000 --- a/src/Adapter/Geolocation/GeolocationOptionsConfiguration.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Geolocation; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class GeolocationOptionsConfiguration is responsible for configuring geolocation options data. - */ -final class GeolocationOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'geolocation_behaviour' => $this->configuration->get('PS_GEOLOCATION_BEHAVIOR'), - 'geolocation_na_behaviour' => $this->configuration->getInt('PS_GEOLOCATION_NA_BEHAVIOR'), - 'geolocation_countries' => $this->configuration->get('PS_ALLOWED_COUNTRIES'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_GEOLOCATION_BEHAVIOR', $config['geolocation_behaviour']); - $this->configuration->set('PS_GEOLOCATION_NA_BEHAVIOR', $config['geolocation_na_behaviour']); - $this->configuration->set('PS_ALLOWED_COUNTRIES', $config['geolocation_countries']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['geolocation_behaviour'], - $config['geolocation_na_behaviour'] - ); - } -} diff --git a/src/Adapter/Grid/Action/Row/AccessibilityChecker/CategoryForViewAccessibilityChecker.php b/src/Adapter/Grid/Action/Row/AccessibilityChecker/CategoryForViewAccessibilityChecker.php deleted file mode 100644 index 27d00f93..00000000 --- a/src/Adapter/Grid/Action/Row/AccessibilityChecker/CategoryForViewAccessibilityChecker.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Grid\Action\Row\AccessibilityChecker; - -use Category; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; - -/** - * Class CategoryForViewAccessibilityChecker. - * - * @internal - */ -final class CategoryForViewAccessibilityChecker implements AccessibilityCheckerInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @param int $contextLangId - */ - public function __construct($contextLangId) - { - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function isGranted(array $category) - { - return Category::hasChildren($category['id_category'], $this->contextLangId, false); - } -} diff --git a/src/Adapter/Grid/Search/Factory/SearchCriteriaWithCategoryParentIdFilterFactory.php b/src/Adapter/Grid/Search/Factory/SearchCriteriaWithCategoryParentIdFilterFactory.php deleted file mode 100644 index 53d94965..00000000 --- a/src/Adapter/Grid/Search/Factory/SearchCriteriaWithCategoryParentIdFilterFactory.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Grid\Search\Factory; - -use Category; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Shop\Context; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\Factory\DecoratedSearchCriteriaFactory; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteria; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Class SearchCriteriaWithCategoryParentIdFilterFactory. - * - * @internal - */ -final class SearchCriteriaWithCategoryParentIdFilterFactory implements DecoratedSearchCriteriaFactory -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var Context - */ - private $shopContext; - - /** - * @var FeatureInterface - */ - private $multistoreFeature; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var int - */ - private $contextShopCategoryId; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @param Configuration $configuration - * @param Context $shopContext - * @param FeatureInterface $multistoreFeature - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param int $contextShopCategoryId - * @param RequestStack $requestStack - */ - public function __construct( - Configuration $configuration, - Context $shopContext, - FeatureInterface $multistoreFeature, - MultistoreContextCheckerInterface $multistoreContextChecker, - $contextShopCategoryId, - RequestStack $requestStack - ) { - $this->configuration = $configuration; - $this->shopContext = $shopContext; - $this->multistoreFeature = $multistoreFeature; - $this->multistoreContextChecker = $multistoreContextChecker; - $this->contextShopCategoryId = $contextShopCategoryId; - $this->requestStack = $requestStack; - } - - /** - * {@inheritdoc} - */ - public function createFrom(SearchCriteriaInterface $searchCriteria) - { - $categoryParentId = $this->resolveCategoryParentId(); - - $filters = array_merge( - $searchCriteria->getFilters(), - ['id_category_parent' => $categoryParentId] - ); - - return new SearchCriteria( - $filters, - $searchCriteria->getOrderBy(), - $searchCriteria->getOrderWay(), - $searchCriteria->getOffset(), - $searchCriteria->getLimit() - ); - } - - /** - * @return int Category parent id - */ - private function resolveCategoryParentId() - { - /** @var Request $request */ - $request = $this->requestStack->getCurrentRequest(); - if (!empty($request->attributes->get('categoryId'))) { - return (int) $request->attributes->get('categoryId'); - } - - $categoriesCountWithoutParent = count(Category::getCategoriesWithoutParent()); - $isMultistoreFeatureUsed = $this->multistoreFeature->isUsed(); - - if (!$isMultistoreFeatureUsed && $categoriesCountWithoutParent > 1) { - return $this->configuration->getInt('PS_ROOT_CATEGORY'); - } - - if ($isMultistoreFeatureUsed && 1 === $categoriesCountWithoutParent) { - return $this->configuration->getInt('PS_HOME_CATEGORY'); - } - - if ($isMultistoreFeatureUsed - && $categoriesCountWithoutParent > 1 - && !$this->multistoreContextChecker->isSingleShopContext() - ) { - if ($this->multistoreFeature->isActive() - && count($this->shopContext->getShops(true, true)) === 1 - ) { - return $this->contextShopCategoryId; - } - - return $this->configuration->getInt('PS_ROOT_CATEGORY'); - } - - return $this->contextShopCategoryId; - } -} diff --git a/src/Adapter/Group/GroupDataProvider.php b/src/Adapter/Group/GroupDataProvider.php deleted file mode 100644 index aa8bed04..00000000 --- a/src/Adapter/Group/GroupDataProvider.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Group; - -use Group; - -/** - * This class will provide data from DB / ORM about Group. - */ -class GroupDataProvider -{ - /** - * Return available groups. - * - * @param int $id_lang - * @param bool $id_shop - * - * @return array Groups - */ - public function getGroups($id_lang, $id_shop = false) - { - return Group::getGroups($id_lang, $id_shop); - } - - /** - * Return current group object - * Use context. - * - * @return Group Group object - */ - public static function getCurrent() - { - return Group::getCurrent(); - } -} diff --git a/src/Adapter/Group/Provider/DefaultGroupsProvider.php b/src/Adapter/Group/Provider/DefaultGroupsProvider.php deleted file mode 100644 index a01254c1..00000000 --- a/src/Adapter/Group/Provider/DefaultGroupsProvider.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Group\Provider; - -use Group; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Group\Provider\DefaultGroup; -use PrestaShop\PrestaShop\Core\Group\Provider\DefaultGroups; -use PrestaShop\PrestaShop\Core\Group\Provider\DefaultGroupsProviderInterface; - -/** - * Provides default customer groups - * - * @internal - */ -final class DefaultGroupsProvider implements DefaultGroupsProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var int - */ - private $contextLangId; - - /** - * @param ConfigurationInterface $configuration - * @param int $contextLangId - */ - public function __construct(ConfigurationInterface $configuration, $contextLangId) - { - $this->configuration = $configuration; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function getGroups() - { - $visitorsGroup = new Group($this->configuration->get('PS_UNIDENTIFIED_GROUP')); - $guestsGroup = new Group($this->configuration->get('PS_GUEST_GROUP')); - $customersGroup = new Group($this->configuration->get('PS_CUSTOMER_GROUP')); - - $visitorName = isset($visitorsGroup->name[$this->contextLangId]) ? - $visitorsGroup->name[$this->contextLangId] : - reset($visitorsGroup->name) - ; - $visitorsGroupDto = new DefaultGroup((int) $visitorsGroup->id, $visitorName); - - $groupsName = isset($guestsGroup->name[$this->contextLangId]) ? - $guestsGroup->name[$this->contextLangId] : - $guestsGroup->name - ; - $guestsGroupDto = new DefaultGroup((int) $guestsGroup->id, $groupsName); - - $customersName = isset($customersGroup->name[$this->contextLangId]) ? - $customersGroup->name[$this->contextLangId] : - reset($customersGroup->name) - ; - $customersGroupDto = new DefaultGroup((int) $customersGroup->id, $customersName); - - return new DefaultGroups( - $visitorsGroupDto, - $guestsGroupDto, - $customersGroupDto - ); - } -} diff --git a/src/Adapter/Hook/HookDispatcher.php b/src/Adapter/Hook/HookDispatcher.php deleted file mode 100644 index 341c06c2..00000000 --- a/src/Adapter/Hook/HookDispatcher.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Hook; - -use PrestaShop\PrestaShop\Core\Hook\Hook; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Hook\HookInterface; -use PrestaShop\PrestaShop\Core\Hook\RenderedHook; -use PrestaShopBundle\Service\Hook\HookEvent; -use PrestaShopBundle\Service\Hook\RenderingHookEvent; -use Symfony\Component\EventDispatcher\Event; -use Symfony\Component\EventDispatcher\EventDispatcher; - -/** - * This dispatcher is used to trigger hook listeners. - * - * The dispatch process cannot be stopped like a common EventDispatcher. - * - * If the event is a RenderingHookEvent, then the final result is - * an array of contents accessed from $event->getContent(). - */ -class HookDispatcher extends EventDispatcher implements HookDispatcherInterface -{ - /** - * @var array - */ - private $renderingContent = []; - - /** - * @var bool - */ - private $propagationStoppedCalledBy = false; - - /** - * {@inheritdoc} - * This override will check if $event is an instance of HookEvent. - * - * @throws \Exception if the Event is not HookEvent or a subclass - */ - public function dispatch($eventName, Event $event = null) - { - if ($event === null) { - $event = new HookEvent(); - } - - if (!$event instanceof HookEvent) { - throw new \Exception('HookDispatcher must dispatch a HookEvent subclass only. ' . get_class($event) . ' given.'); - } - - if ($listeners = $this->getListeners(strtolower($eventName))) { - $this->doDispatch($listeners, $eventName, $event); - } - - return $event; - } - - /** - * {@inheritdoc} - */ - public function dispatchHook(HookInterface $hook) - { - return $this->dispatchForParameters( - $hook->getName(), - $hook->getParameters() - ); - } - - /** - * Calls multiple hooks with the same parameter set. - * - * Each event is independent for each hook call. Parameter set is duplicated. - * - * @param array $eventNames the hooks to dispatch to - * @param array $eventParameters the parameters set to insert in each HookEvent instance - * - * @throws \Exception if the Event is not HookEvent or a subclass - */ - public function dispatchMultiple(array $eventNames, array $eventParameters) - { - foreach ($eventNames as $name) { - $this->dispatch($name, (new HookEvent())->setHookParameters($eventParameters)); - } - } - - /** - * {@inheritdoc} - * This override will avoid PropagationStopped to break the dispatching process. - * After dispatch, in case of RenderingHookEvent, the final content array will be set in event. - */ - protected function doDispatch($listeners, $eventName, Event $event) - { - $this->propagationStoppedCalledBy = false; - foreach ($listeners as $listener) { - // removes $this to parameters. Hooks should not have access to dispatcher - ob_start(); - $listener($event, $eventName, null); - $obContent = ob_get_clean(); - - if ($event instanceof RenderingHookEvent) { - $listenerName = $event->popListener() ?: $listener[1]; - - $eventContent = $event->popContent(); - $this->renderingContent[$listenerName] = (!is_string($eventContent) || strlen($eventContent) > strlen($obContent)) - ? $eventContent - : $obContent; - } - if ($event->isPropagationStopped()) { - $this->propagationStoppedCalledBy = $listener; - } - } - if ($event instanceof RenderingHookEvent) { - $event->setContent($this->renderingContent); - $this->renderingContent = []; - } - } - - /** - * Creates a HookEvent, sets its parameters, and dispatches it. - * - * @param $eventName string The hook name - * @param array $parameters Hook parameters - * - * @return Event the event that has been passed to each listener - * - * @throws \Exception - */ - public function dispatchForParameters($eventName, array $parameters = []) - { - $event = new HookEvent(); - $event->setHookParameters($parameters); - - return $this->dispatch($eventName, $event); - } - - /** - * Creates a RenderingHookEvent, sets its parameters, and dispatches it. Returns the event with the response(s). - * - * @param string $eventName the hook name - * @param array $parameters Hook parameters - * - * @return Event The event that has been passed to each listener. Contains the responses. - * - * @throws \Exception - */ - public function renderForParameters($eventName, array $parameters = []) - { - $event = new RenderingHookEvent(); - $event->setHookParameters($parameters); - - return $this->dispatch($eventName, $event); - } - - /** - * {@inheritdoc} - */ - public function dispatchWithParameters($hookName, array $hookParameters = []) - { - $this->dispatch(new Hook($hookName, $hookParameters)); - } - - /** - * {@inheritdoc} - */ - public function dispatchRendering(HookInterface $hook) - { - $event = $this->renderForParameters( - $hook->getName(), - $hook->getParameters() - ); - - return new RenderedHook($hook, $event->getContent()); - } - - /** - * {@inheritdoc} - */ - public function dispatchRenderingWithParameters($hookName, array $hookParameters = []) - { - return $this->dispatchRendering(new Hook($hookName, $hookParameters)); - } -} diff --git a/src/Adapter/Hook/HookInformationProvider.php b/src/Adapter/Hook/HookInformationProvider.php deleted file mode 100644 index e53d47d1..00000000 --- a/src/Adapter/Hook/HookInformationProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Hook; - -use Hook; - -/** - * Give information about the hooks. - */ -class HookInformationProvider -{ - /** - * @param string $hookName - * - * @return bool - */ - public function isDisplayHookName($hookName) - { - return Hook::isDisplayHookName($hookName); - } - - /** - * Return Hooks List. - * - * @param bool $position Where position is active - * @param bool $onlyDisplayHooks Only hook with display hook name - * - * @return array Hooks List - */ - public function getHooks($position = false, $onlyDisplayHooks = false) - { - return Hook::getHooks($position, $onlyDisplayHooks); - } - - /** - * Return Hooks list. - * - * @param int $hookId Hook id - * @param int $moduleId Module id - * - * @return array Modules list - */ - public function getModulesFromHook($hookId, $moduleId = null) - { - return Hook::getModulesFromHook($hookId, $moduleId); - } -} diff --git a/src/Adapter/HookManager.php b/src/Adapter/HookManager.php deleted file mode 100644 index 0db8a816..00000000 --- a/src/Adapter/HookManager.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Hook; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Bridge to execute hooks in modern pages. - */ -class HookManager -{ - /** - * Execute modules for specified hook. - * - * @param string $hook_name Hook Name - * @param array $hook_args Parameters for the functions - * @param int $id_module Execute hook for this module only - * @param bool $array_return If specified, module output will be set by name in an array - * @param bool $check_exceptions Check permission exceptions - * @param bool $use_push Force change to be refreshed on Dashboard widgets - * @param int $id_shop If specified, hook will be execute the shop with this ID - * - * @throws \PrestaShopException - * - * @return string/array modules output - */ - public function exec( - $hook_name, - $hook_args = [], - $id_module = null, - $array_return = false, - $check_exceptions = true, - $use_push = false, - $id_shop = null - ) { - $sfContainer = SymfonyContainer::getInstance(); - $request = null; - - if ($sfContainer instanceof ContainerInterface) { - $request = $sfContainer->get('request_stack')->getCurrentRequest(); - } - - if (null !== $request) { - $hook_args = array_merge(['request' => $request], $hook_args); - - // If Symfony application is booted, we use it to dispatch Hooks - $hookDispatcher = $sfContainer->get('prestashop.core.hook.dispatcher'); - - return $hookDispatcher - ->dispatchRenderingWithParameters($hook_name, $hook_args) - ->getContent(); - } else { - try { - return Hook::exec($hook_name, $hook_args, $id_module, $array_return, $check_exceptions, $use_push, $id_shop); - } catch (\Exception $e) { - $logger = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\LegacyLogger'); - $logger->error(sprintf('Exception on hook %s for module %s. %s', $hook_name, $id_module, $e->getMessage())); - } - } - } -} diff --git a/src/Adapter/Hosting/HostingInformation.php b/src/Adapter/Hosting/HostingInformation.php deleted file mode 100644 index 24fc4830..00000000 --- a/src/Adapter/Hosting/HostingInformation.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Hosting; - -use Db; -use Tools; - -/** - * Provides hosting system information. - */ -class HostingInformation -{ - /** - * @return array - */ - public function getDatabaseInformation() - { - return [ - 'version' => Db::getInstance()->getVersion(), - 'server' => _DB_SERVER_, - 'name' => _DB_NAME_, - 'user' => _DB_USER_, - 'prefix' => _DB_PREFIX_, - 'engine' => _MYSQL_ENGINE_, - 'driver' => Db::getClass(), - ]; - } - - /** - * @return array - */ - public function getServerInformation() - { - return [ - 'version' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'n/a', - 'php' => $this->getPhpInformation(), - ]; - } - - /** - * @return array - */ - private function getPhpInformation() - { - return [ - 'version' => PHP_VERSION, - 'memoryLimit' => ini_get('memory_limit'), - 'maxExecutionTime' => ini_get('max_execution_time'), - 'maxFileSizeUpload' => ini_get('upload_max_filesize'), - ]; - } - - /** - * @return string - */ - public function getUname() - { - return function_exists('php_uname') ? php_uname('s') . ' ' . php_uname('v') . ' ' . php_uname('m') : ''; - } - - /** - * @return bool - */ - public function isApacheInstawebModule() - { - return Tools::apacheModExists('mod_instaweb'); - } - - /** - * Check if the shop is hosted on PrestaCloud. - * - * @return bool - */ - public function isHostMode() - { - return defined('_PS_HOST_MODE_'); - } -} diff --git a/src/Adapter/Image/ImageRetriever.php b/src/Adapter/Image/ImageRetriever.php deleted file mode 100644 index 088a32f0..00000000 --- a/src/Adapter/Image/ImageRetriever.php +++ /dev/null @@ -1,297 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image; - -use Image; -use ImageManager; -use ImageType; -use Language; -use Link; -use Product; - -/** - * This class is mainly responsible of Product images. - */ -class ImageRetriever -{ - /** - * @var Link - */ - private $link; - - public function __construct(Link $link) - { - $this->link = $link; - } - - /** - * @param array $product - * @param Language $language - * - * @return array - */ - public function getAllProductImages(array $product, Language $language) - { - $productInstance = new Product( - $product['id_product'], - false, - $language->id - ); - - $images = $productInstance->getImages($language->id); - - if (empty($images)) { - return []; - } - - $combinationImages = $productInstance->getCombinationImages($language->id); - if (!$combinationImages) { - $combinationImages = []; - } - $imageToCombinations = []; - - foreach ($combinationImages as $imgs) { - foreach ($imgs as $img) { - $imageToCombinations[$img['id_image']][] = $img['id_product_attribute']; - } - } - - $images = array_map(function (array $image) use ( - $productInstance, - $imageToCombinations - ) { - $image = array_merge($this->getImage( - $productInstance, - $image['id_image'] - ), $image); - - if (isset($imageToCombinations[$image['id_image']])) { - $image['associatedVariants'] = $imageToCombinations[$image['id_image']]; - } else { - $image['associatedVariants'] = []; - } - - return $image; - }, $images); - - return $images; - } - - /** - * @param array $product - * @param Language $language - * - * @return array - */ - public function getProductImages(array $product, Language $language) - { - $images = $this->getAllProductImages($product, $language); - - $productAttributeId = $product['id_product_attribute']; - $filteredImages = []; - - foreach ($images as $image) { - if (in_array($productAttributeId, $image['associatedVariants'])) { - $filteredImages[] = $image; - } - } - - return (0 === count($filteredImages)) ? $images : $filteredImages; - } - - /** - * @param $object - * @param int $id_image - * - * @return array|null - * - * @throws \PrestaShopDatabaseException - */ - public function getImage($object, $id_image) - { - if (!$id_image) { - return null; - } - - if (get_class($object) === 'Product') { - $type = 'products'; - $getImageURL = 'getImageLink'; - $root = _PS_PROD_IMG_DIR_; - $imageFolderPath = implode(DIRECTORY_SEPARATOR, [ - rtrim($root, DIRECTORY_SEPARATOR), - rtrim(Image::getImgFolderStatic($id_image), DIRECTORY_SEPARATOR), - ]); - } elseif (get_class($object) === 'Store') { - $type = 'stores'; - $getImageURL = 'getStoreImageLink'; - $root = _PS_STORE_IMG_DIR_; - $imageFolderPath = rtrim($root, DIRECTORY_SEPARATOR); - } else { - $type = 'categories'; - $getImageURL = 'getCatImageLink'; - $root = _PS_CAT_IMG_DIR_; - $imageFolderPath = rtrim($root, DIRECTORY_SEPARATOR); - } - - $urls = []; - $image_types = ImageType::getImagesTypes($type, true); - - $extPath = $imageFolderPath . DIRECTORY_SEPARATOR . 'fileType'; - $ext = @file_get_contents($extPath) ?: 'jpg'; - - $mainImagePath = implode(DIRECTORY_SEPARATOR, [ - $imageFolderPath, - $id_image . '.' . $ext, - ]); - - foreach ($image_types as $image_type) { - $resizedImagePath = implode(DIRECTORY_SEPARATOR, [ - $imageFolderPath, - $id_image . '-' . $image_type['name'] . '.' . $ext, - ]); - - if (!file_exists($resizedImagePath)) { - ImageManager::resize( - $mainImagePath, - $resizedImagePath, - (int) $image_type['width'], - (int) $image_type['height'] - ); - } - - $url = $this->link->$getImageURL( - isset($object->link_rewrite) ? $object->link_rewrite : $object->name, - $id_image, - $image_type['name'] - ); - - $urls[$image_type['name']] = [ - 'url' => $url, - 'width' => (int) $image_type['width'], - 'height' => (int) $image_type['height'], - ]; - } - - uasort($urls, function (array $a, array $b) { - return $a['width'] * $a['height'] > $b['width'] * $b['height'] ? 1 : -1; - }); - - $keys = array_keys($urls); - - $small = $urls[$keys[0]]; - $large = end($urls); - $medium = $urls[$keys[ceil((count($keys) - 1) / 2)]]; - - return [ - 'bySize' => $urls, - 'small' => $small, - 'medium' => $medium, - 'large' => $large, - 'legend' => isset($object->meta_title) ? $object->meta_title : $object->name, - 'id_image' => $id_image, - ]; - } - - /** - * @param string $imageHash - * - * @return array - */ - public function getCustomizationImage($imageHash) - { - $large_image_url = rtrim($this->link->getBaseLink(), '/') . '/upload/' . $imageHash; - $small_image_url = $large_image_url . '_small'; - - $small = [ - 'url' => $small_image_url, - ]; - - $large = [ - 'url' => $large_image_url, - ]; - - $medium = $large; - - return [ - 'bySize' => [ - 'small' => $small, - 'medium' => $medium, - 'large' => $large, - ], - 'small' => $small, - 'medium' => $medium, - 'large' => $large, - 'legend' => '', - ]; - } - - /** - * @param Language $language - * - * @return array - * - * @throws \PrestaShopDatabaseException - */ - public function getNoPictureImage(Language $language) - { - $urls = []; - $type = 'products'; - $image_types = ImageType::getImagesTypes($type, true); - - foreach ($image_types as $image_type) { - $url = $this->link->getImageLink( - '', - $language->iso_code . '-default', - $image_type['name'] - ); - - $urls[$image_type['name']] = [ - 'url' => $url, - 'width' => (int) $image_type['width'], - 'height' => (int) $image_type['height'], - ]; - } - - uasort($urls, function (array $a, array $b) { - return $a['width'] * $a['height'] > $b['width'] * $b['height'] ? 1 : -1; - }); - - $keys = array_keys($urls); - - $small = $urls[$keys[0]]; - $large = end($urls); - $medium = $urls[$keys[ceil((count($keys) - 1) / 2)]]; - - return [ - 'bySize' => $urls, - 'small' => $small, - 'medium' => $medium, - 'large' => $large, - 'legend' => '', - ]; - } -} diff --git a/src/Adapter/Image/Uploader/AbstractImageUploader.php b/src/Adapter/Image/Uploader/AbstractImageUploader.php deleted file mode 100644 index ef055ac7..00000000 --- a/src/Adapter/Image/Uploader/AbstractImageUploader.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use Configuration; -use ImageManager; -use ImageType; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use PrestaShopException; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Tools; - -/** - * Class AbstractImageUploader encapsulates reusable legacy methods used for image uploading. - * - * @internal - */ -abstract class AbstractImageUploader implements ImageUploaderInterface -{ - /** - * Check if image is allowed to be uploaded. - * - * @param UploadedFile $image - * - * @throws UploadedImageConstraintException - */ - protected function checkImageIsAllowedForUpload(UploadedFile $image) - { - $maxFileSize = Tools::getMaxUploadSize(); - - if ($maxFileSize > 0 && $image->getSize() > $maxFileSize) { - throw new UploadedImageConstraintException(sprintf('Max file size allowed is "%s" bytes. Uploaded image size is "%s".', $maxFileSize, $image->getSize()), UploadedImageConstraintException::EXCEEDED_SIZE); - } - - if (!ImageManager::isRealImage($image->getPathname(), $image->getClientMimeType()) - || !ImageManager::isCorrectImageFileExt($image->getClientOriginalName()) - || preg_match('/\%00/', $image->getClientOriginalName()) // prevent null byte injection - ) { - throw new UploadedImageConstraintException(sprintf('Image format "%s", not recognized, allowed formats are: .gif, .jpg, .png', $image->getClientOriginalExtension()), UploadedImageConstraintException::UNRECOGNIZED_FORMAT); - } - } - - /** - * Creates temporary image from uploaded file - * - * @param UploadedFile $image - * - * @throws ImageUploadException - * - * @return string - */ - protected function createTemporaryImage(UploadedFile $image) - { - $temporaryImageName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - - if (!$temporaryImageName || !move_uploaded_file($image->getPathname(), $temporaryImageName)) { - throw new ImageUploadException('Failed to create temporary image file'); - } - - return $temporaryImageName; - } - - /** - * Uploads resized image from temporary folder to image destination - * - * @param $temporaryImageName - * @param $destination - * - * @throws ImageOptimizationException - * @throws MemoryLimitException - */ - protected function uploadFromTemp($temporaryImageName, $destination) - { - if (!ImageManager::checkImageMemoryLimit($temporaryImageName)) { - throw new MemoryLimitException('Cannot upload image due to memory restrictions'); - } - - if (!ImageManager::resize($temporaryImageName, $destination)) { - throw new ImageOptimizationException('An error occurred while uploading the image. Check your directory permissions.'); - } - - unlink($temporaryImageName); - } - - /** - * Generates different size images - * - * @param int $id - * @param string $imageDir - * @param string $belongsTo to whom the image belongs (for example 'suppliers' or 'categories') - * - * @return bool - * - * @throws ImageOptimizationException - */ - protected function generateDifferentSize($id, $imageDir, $belongsTo) - { - $resized = true; - - try { - $imageTypes = ImageType::getImagesTypes($belongsTo); - - foreach ($imageTypes as $imageType) { - $resized &= $this->resize($id, $imageDir, $imageType); - } - } catch (PrestaShopException $e) { - throw new ImageOptimizationException('Unable to resize one or more of your pictures.'); - } - - if (!$resized) { - throw new ImageOptimizationException('Unable to resize one or more of your pictures.'); - } - - return $resized; - } - - /** - * Resizes the image depending from its type - * - * @param int $id - * @param string $imageDir - * @param array $imageType - * - * @return bool - */ - private function resize($id, $imageDir, array $imageType) - { - $ext = '.jpg'; - $width = $imageType['width']; - $height = $imageType['height']; - - if (Configuration::get('PS_HIGHT_DPI')) { - $ext = '2x.jpg'; - $width *= 2; - $height *= 2; - } - - return ImageManager::resize( - $imageDir . $id . '.jpg', - $imageDir . $id . '-' . stripslashes($imageType['name']) . $ext, - (int) $width, - (int) $height - ); - } -} diff --git a/src/Adapter/Image/Uploader/CategoryCoverImageUploader.php b/src/Adapter/Image/Uploader/CategoryCoverImageUploader.php deleted file mode 100644 index 3d2902b7..00000000 --- a/src/Adapter/Image/Uploader/CategoryCoverImageUploader.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use Category; -use ImageManager; -use ImageType; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class CategoryCoverImageUploader. - * - * @internal - */ -final class CategoryCoverImageUploader extends AbstractImageUploader -{ - /** - * {@inheritdoc} - * - * @throws MemoryLimitException - * @throws ImageOptimizationException - * @throws ImageUploadException - * @throws UploadedImageConstraintException - */ - public function upload($id, UploadedFile $uploadedImage) - { - $this->checkImageIsAllowedForUpload($uploadedImage); - $this->deleteOldImage($id); - $this->uploadImage($id, $uploadedImage); - $this->generateDifferentTypes($id); - } - - /** - * Delete old category image. - * - * @param int $id - */ - private function deleteOldImage($id) - { - $category = new Category($id); - $category->deleteImage(); - } - - /** - * @param int $id - * @param UploadedFile $image - * - * @throws ImageOptimizationException - * @throws ImageUploadException - * @throws MemoryLimitException - */ - private function uploadImage($id, UploadedFile $image) - { - $temporaryImageName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - - if (!$temporaryImageName) { - throw new ImageUploadException('Failed to create temporary image file'); - } - - if (!move_uploaded_file($image->getPathname(), $temporaryImageName)) { - throw new ImageUploadException('Failed to upload image'); - } - - if (!ImageManager::checkImageMemoryLimit($temporaryImageName)) { - throw new MemoryLimitException('Cannot upload image due to memory restrictions'); - } - - $optimizationSucceeded = ImageManager::resize( - $temporaryImageName, - _PS_IMG_DIR_ . 'c' . DIRECTORY_SEPARATOR . $id . '.jpg', - null, - null, - 'jpg' - ); - - if (!$optimizationSucceeded) { - throw new ImageOptimizationException('Failed to optimize image after uploading'); - } - - unlink($temporaryImageName); - } - - /** - * @param int $id - * - * @throws ImageUploadException - */ - private function generateDifferentTypes($id) - { - if (!file_exists(_PS_CAT_IMG_DIR_ . $id . '.jpg')) { - return; - } - - $imagesTypes = ImageType::getImagesTypes('categories'); - foreach ($imagesTypes as $k => $imageType) { - $generated = ImageManager::resize( - _PS_CAT_IMG_DIR_ . $id . '.jpg', - _PS_CAT_IMG_DIR_ . $id . '-' . stripslashes($imageType['name']) . '.jpg', - (int) $imageType['width'], - (int) $imageType['height'] - ); - - if (!$generated) { - throw new ImageUploadException('Error occurred when uploading image'); - } - } - } -} diff --git a/src/Adapter/Image/Uploader/CategoryMenuThumbnailUploader.php b/src/Adapter/Image/Uploader/CategoryMenuThumbnailUploader.php deleted file mode 100644 index cad4ebbc..00000000 --- a/src/Adapter/Image/Uploader/CategoryMenuThumbnailUploader.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use HelperImageUploader; -use ImageManager; -use PrestaShop\PrestaShop\Adapter\Cache\CacheClearer; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\MenuThumbnailsLimitException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\MenuThumbnailId; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class CategoryMenuThumbnailUploader. - */ -final class CategoryMenuThumbnailUploader implements ImageUploaderInterface -{ - /** - * @var CacheClearer - */ - private $cacheClearer; - - /** - * @param CacheClearer $cacheClearer - */ - public function __construct(CacheClearer $cacheClearer) - { - $this->cacheClearer = $cacheClearer; - } - - /** - * {@inheritdoc} - * - * @throws ImageUploadException - */ - public function upload($categoryId, UploadedFile $uploadedImage) - { - //Get total of image already present in directory - $files = scandir(_PS_CAT_IMG_DIR_, SCANDIR_SORT_NONE); - $usedKeys = []; - - foreach ($files as $file) { - $matches = []; - - if (preg_match('/^' . $categoryId . '-([0-9])?_thumb.jpg/i', $file, $matches) === 1) { - $usedKeys[] = (int) $matches[1]; - } - } - - $availableKeys = array_diff(MenuThumbnailId::ALLOWED_ID_VALUES, $usedKeys); - - // HelperImageUploader::process() expects - // uploaded file to be available in $_FILES - $_FILES['thumbnail'] = [ - 'error' => [$uploadedImage->getError()], - 'name' => [$uploadedImage->getClientOriginalName()], - 'size' => [$uploadedImage->getSize()], - 'tmp_name' => [$uploadedImage->getPathname()], - 'type' => [$uploadedImage->getMimeType()], - ]; - - $helper = new HelperImageUploader('thumbnail'); - $uploadedFiles = $helper->process(); - - if (count($availableKeys) < count($uploadedFiles)) { - throw new MenuThumbnailsLimitException(sprintf('Maximum number of menu thumbnails was reached for category "%s"', $categoryId)); - } - - foreach ($uploadedFiles as &$uploadedFile) { - $key = array_shift($availableKeys); - - // Evaluate the memory required to resize the image: if it's too much, you can't resize it. - if (isset($uploadedFile['save_path']) && !ImageManager::checkImageMemoryLimit($uploadedFile['save_path'])) { - throw new MemoryLimitException(sprintf('Cannot resize menu thumbnail for category with id "%s" due to reached memory limit.', $categoryId)); - } - - // Copy new image - if (!isset($uploadedFile['save_path']) - || !ImageManager::resize($uploadedFile['save_path'], _PS_CAT_IMG_DIR_ . $categoryId . '-' . $key . '_thumb.jpg') - ) { - throw new ImageUploadException('An error occurred while uploading the image.'); - } - - if (isset($uploadedFile['save_path']) && is_file($uploadedFile['save_path'])) { - unlink($uploadedFile['save_path']); - } - - // Necessary to prevent hacking - if (isset($uploadedFile['save_path'])) { - unset($uploadedFile['save_path']); - } - - if (isset($uploadedFile['tmp_name'])) { - unset($uploadedFile['tmp_name']); - } - } - - $this->cacheClearer->clearSmartyCache(); - } -} diff --git a/src/Adapter/Image/Uploader/CategoryThumbnailImageUploader.php b/src/Adapter/Image/Uploader/CategoryThumbnailImageUploader.php deleted file mode 100644 index 01b99ca5..00000000 --- a/src/Adapter/Image/Uploader/CategoryThumbnailImageUploader.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use ImageManager; -use ImageType; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class CategoryThumbnailImageUploader. - */ -final class CategoryThumbnailImageUploader extends AbstractImageUploader -{ - /** - * {@inheritdoc} - * - * @throws UploadedImageConstraintException - * @throws ImageUploadException - * @throws ImageOptimizationException - */ - public function upload($id, UploadedFile $uploadedImage) - { - $imagesTypes = ImageType::getImagesTypes('categories'); - $formattedName = ImageType::getFormattedName('small'); - - foreach ($imagesTypes as $k => $imagesType) { - if ($formattedName !== $imagesType['name']) { - continue; - } - - $this->checkImageIsAllowedForUpload($uploadedImage); - - $tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - if (!$tmpName) { - throw new ImageUploadException('Failed to create temporary category thumbnail image file'); - } - - if (!move_uploaded_file($uploadedImage->getPathname(), $tmpName)) { - throw new ImageUploadException('Failed to upload category thumbnail image'); - } - - if (!ImageManager::resize( - $tmpName, - _PS_CAT_IMG_DIR_ . $id . '-' . stripslashes($imagesType['name']) . '.jpg', - (int) $imagesType['width'], - (int) $imagesType['height'] - )) { - throw new ImageOptimizationException('Failed to optimize category thumbnail image after uploading'); - } - - if (($imageSize = getimagesize($tmpName)) && is_array($imageSize)) { - ImageManager::resize( - $tmpName, - _PS_CAT_IMG_DIR_ . $id . '_thumb.jpg', - (int) $imageSize[0], - (int) $imageSize[1] - ); - } - - unlink($tmpName); - } - } -} diff --git a/src/Adapter/Image/Uploader/ManufacturerImageUploader.php b/src/Adapter/Image/Uploader/ManufacturerImageUploader.php deleted file mode 100644 index 72e65378..00000000 --- a/src/Adapter/Image/Uploader/ManufacturerImageUploader.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use Configuration; -use ImageManager; -use ImageType; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShopException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Uploads manufacturer logo image - */ -final class ManufacturerImageUploader extends AbstractImageUploader -{ - /** - * {@inheritdoc} - */ - public function upload($manufacturerId, UploadedFile $image) - { - $this->checkImageIsAllowedForUpload($image); - $temporaryImageName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - - if (!$temporaryImageName) { - throw new ImageUploadException('An error occurred while uploading the image. Check your directory permissions.'); - } - - if (!move_uploaded_file($image->getPathname(), $temporaryImageName)) { - throw new ImageUploadException('An error occurred while uploading the image. Check your directory permissions.'); - } - - // Evaluate the memory required to resize the image: if it's too much, you can't resize it. - if (!ImageManager::checkImageMemoryLimit($temporaryImageName)) { - throw new MemoryLimitException('Due to memory limit restrictions, this image cannot be loaded. Increase your memory_limit value.'); - } - // Copy new image - if (!ImageManager::resize($temporaryImageName, _PS_MANU_IMG_DIR_ . $manufacturerId . '.jpg')) { - throw new ImageOptimizationException('An error occurred while uploading the image. Check your directory permissions.'); - } - - $this->generateDifferentSizeImages($manufacturerId); - } - - /** - * @param int $manufacturerId - * - * @return bool - */ - private function generateDifferentSizeImages($manufacturerId) - { - $resized = true; - $generateHighDpiImages = (bool) Configuration::get('PS_HIGHT_DPI'); - - try { - /* Generate images with different size */ - if (isset($_FILES) && - count($_FILES) && - file_exists(_PS_MANU_IMG_DIR_ . $manufacturerId . '.jpg') - ) { - $imageTypes = ImageType::getImagesTypes('manufacturers'); - - foreach ($imageTypes as $imageType) { - $resized &= ImageManager::resize( - _PS_MANU_IMG_DIR_ . $manufacturerId . '.jpg', - _PS_MANU_IMG_DIR_ . $manufacturerId . '-' . stripslashes($imageType['name']) . '.jpg', - (int) $imageType['width'], - (int) $imageType['height'] - ); - - if ($generateHighDpiImages) { - $resized &= ImageManager::resize( - _PS_MANU_IMG_DIR_ . $manufacturerId . '.jpg', - _PS_MANU_IMG_DIR_ . $manufacturerId . '-' . stripslashes($imageType['name']) . '2x.jpg', - (int) $imageType['width'] * 2, - (int) $imageType['height'] * 2 - ); - } - } - - $currentLogo = _PS_TMP_IMG_DIR_ . 'manufacturer_mini_' . $manufacturerId . '.jpg'; - - if ($resized && file_exists($currentLogo)) { - unlink($currentLogo); - } - } - } catch (PrestaShopException $e) { - throw new ImageOptimizationException('Unable to resize one or more of your pictures.'); - } - - if (!$resized) { - throw new ImageOptimizationException('Unable to resize one or more of your pictures.'); - } - - return $resized; - } -} diff --git a/src/Adapter/Image/Uploader/SupplierImageUploader.php b/src/Adapter/Image/Uploader/SupplierImageUploader.php deleted file mode 100644 index a52f9229..00000000 --- a/src/Adapter/Image/Uploader/SupplierImageUploader.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Image\Uploader; - -use Supplier; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Uploads supplier logo image - */ -final class SupplierImageUploader extends AbstractImageUploader -{ - /** - * {@inheritdoc} - */ - public function upload($supplierId, UploadedFile $image) - { - $this->checkImageIsAllowedForUpload($image); - $tempImageName = $this->createTemporaryImage($image); - $this->deleteOldImage($supplierId); - - $destination = _PS_SUPP_IMG_DIR_ . $supplierId . '.jpg'; - $this->uploadFromTemp($tempImageName, $destination); - - if (file_exists($destination)) { - $this->generateDifferentSize($supplierId, _PS_SUPP_IMG_DIR_, 'suppliers'); - } - } - - /** - * Deletes old image - * - * @param $id - */ - private function deleteOldImage($id) - { - $supplier = new Supplier($id); - $supplier->deleteImage(); - - $currentLogo = _PS_TMP_IMG_DIR_ . 'supplier_mini_' . $id . '.jpg'; - - if (file_exists($currentLogo)) { - unlink($currentLogo); - } - } -} diff --git a/src/Adapter/ImageManager.php b/src/Adapter/ImageManager.php deleted file mode 100644 index 1b724b5a..00000000 --- a/src/Adapter/ImageManager.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Image; -use ImageManager as LegacyImageManager; - -/** - * Class responsible of finding images and creating thumbnails. - */ -class ImageManager -{ - /** - * @var LegacyContext - */ - private $legacyContext; - - /** - * @param LegacyContext $legacyContext - */ - public function __construct(LegacyContext $legacyContext) - { - $this->legacyContext = $legacyContext; - } - - /** - * Old legacy way to generate a thumbnail. - * - * Use it upon a new Image management system is available. - * - * @param $imageId - * @param string $imageType - * @param string $tableName - * @param string $imageDir - * - * @return string The HTML < img > tag - */ - public function getThumbnailForListing($imageId, $imageType = 'jpg', $tableName = 'product', $imageDir = _PS_PROD_IMG_DIR_) - { - $thumbPath = $this->getThumbnailTag($imageId, $imageType, $tableName, $imageDir); - - // because legacy uses relative path to reach a directory under root directory... - $replacement = 'src="' . $this->legacyContext->getRootUrl(); - $thumbPath = preg_replace('/src="(\\.\\.\\/)+/', $replacement, $thumbPath); - - return $thumbPath; - } - - public function getThumbnailPath($imageId) - { - $imageType = 'jpg'; - $tableName = 'product'; - $imageDir = _PS_PROD_IMG_DIR_; - - $imagePath = $this->getImagePath($imageId, $imageType, $tableName, $imageDir); - $thumbnailCachedImageName = $this->makeCachedImageName($imageId, $imageType, $tableName); - LegacyImageManager::thumbnail( - $imagePath, - $thumbnailCachedImageName, - 45, - $imageType - ); - - return LegacyImageManager::getThumbnailPath($thumbnailCachedImageName, false); - } - - /** - * @param $imageId - * @param string $imageType - * @param string $tableName - * @param string $imageDir - * - * @return string - */ - private function getThumbnailTag($imageId, $imageType, $tableName, $imageDir) - { - $imagePath = $this->getImagePath($imageId, $imageType, $tableName, $imageDir); - - return LegacyImageManager::thumbnail( - $imagePath, - $this->makeCachedImageName($imageId, $imageType, $tableName), - 45, - $imageType - ); - } - - /** - * @param $imageId - * @param $imageType - * @param $tableName - * @param $imageDir - * - * @return string - */ - private function getImagePath($imageId, $imageType, $tableName, $imageDir) - { - if ($tableName == 'product') { - $image = new Image($imageId); - - return $imageDir . $image->getExistingImgPath() . '.' . $imageType; - } - - return $imageDir . $imageId . '.' . $imageType; - } - - /** - * @param $imageId - * @param $imageType - * @param $tableName - * - * @return string - */ - private function makeCachedImageName($imageId, $imageType, $tableName) - { - return $tableName . '_mini_' . $imageId . '.' . $imageType; - } -} diff --git a/src/Adapter/Import/CsvFileOpener.php b/src/Adapter/Import/CsvFileOpener.php deleted file mode 100644 index 4ee25804..00000000 --- a/src/Adapter/Import/CsvFileOpener.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import; - -use PrestaShop\PrestaShop\Core\File\Converter\FileConverterInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\UnreadableFileException; -use PrestaShop\PrestaShop\Core\Import\File\FileOpenerInterface; -use PrestaShop\PrestaShop\Core\Import\ImportDirectory; -use SplFileInfo; - -/** - * Class CsvFileOpener is responsible for opening the CSV import file. - */ -final class CsvFileOpener implements FileOpenerInterface -{ - /** - * @var FileConverterInterface - */ - private $excelToCsvConverter; - - /** - * @var ImportDirectory - */ - private $importDirectory; - - /** - * @param FileConverterInterface $excelToCsvConverter - * @param ImportDirectory $importDirectory - */ - public function __construct( - FileConverterInterface $excelToCsvConverter, - ImportDirectory $importDirectory - ) { - $this->excelToCsvConverter = $excelToCsvConverter; - $this->importDirectory = $importDirectory; - } - - /** - * {@inheritdoc} - */ - public function open(SplFileInfo $file) - { - $importFile = $this->excelToCsvConverter->convert($file); - $filePath = $importFile->getPathname(); - $isReadableFile = is_file($filePath) && is_readable($filePath); - - if (!$isReadableFile || !($handle = fopen($filePath, 'r'))) { - throw new UnreadableFileException(); - } - - $this->rewindBomAware($handle); - - return $handle; - } - - /** - * Rewind the file handle, skipping BOM signature. - * - * @param resource $handle - */ - private function rewindBomAware($handle) - { - if (!is_resource($handle)) { - return; - } - - rewind($handle); - - if (($bom = fread($handle, 3)) != "\xEF\xBB\xBF") { - rewind($handle); - } - } -} diff --git a/src/Adapter/Import/DataMatchSaver.php b/src/Adapter/Import/DataMatchSaver.php deleted file mode 100644 index 96abf4b6..00000000 --- a/src/Adapter/Import/DataMatchSaver.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import; - -use Doctrine\DBAL\Connection; - -/** - * Class DataMatchSaver saves data configuration match. - * This class will be removed with CQRS introduction. - */ -final class DataMatchSaver -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @param Connection $connection - * @param string $dbPrefix - */ - public function __construct(Connection $connection, $dbPrefix) - { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - } - - /** - * Save data match. - * - * @param string $name name of the match - * @param array $value value of the match - * @param int $skipRows number of rows to skip from the import file - * - * @return bool - */ - public function save($name, array $value, $skipRows) - { - return (bool) $this->connection->insert( - $this->dbPrefix . 'import_match', - [ - '`name`' => pSQL($name), - '`match`' => pSQL(implode('|', $value)), - '`skip`' => (int) $skipRows, - ] - ); - } -} diff --git a/src/Adapter/Import/Handler/AbstractImportHandler.php b/src/Adapter/Import/Handler/AbstractImportHandler.php deleted file mode 100644 index 86bb1dfa..00000000 --- a/src/Adapter/Import/Handler/AbstractImportHandler.php +++ /dev/null @@ -1,507 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import\Handler; - -use Language; -use ObjectModel; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Database; -use PrestaShop\PrestaShop\Adapter\Import\ImportDataFormatter; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\EmptyDataRowException; -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowInterface; -use PrestaShop\PrestaShop\Core\Import\Handler\ImportHandlerInterface; -use Psr\Log\LoggerInterface; -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessor; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class AbstractImportHandler is an abstract handler for import. - */ -abstract class AbstractImportHandler implements ImportHandlerInterface -{ - /** - * @var ImportDataFormatter - */ - protected $dataFormatter; - - /** - * @var array - */ - protected $contextShopIds; - - /** - * @var bool whether the multistore feature is enabled - */ - protected $isMultistoreEnabled; - - /** - * @var int - */ - protected $currentContextShopId; - - /** - * @var TranslatorInterface - */ - protected $translator; - - /** - * @var array all shops ids - */ - protected $allShopIds; - - /** - * @var string import type label - */ - protected $importTypeLabel; - - /** - * @var Database - */ - protected $legacyDatabase; - - /** - * @var int - */ - protected $languageId; - - /** - * @var Configuration - */ - protected $configuration; - - /** - * @var Validate - */ - protected $validate; - - /** - * @var PropertyAccessor - */ - protected $propertyAccessor; - - /** - * @var int - */ - protected $defaultLanguageId; - - /** - * @var array entity default values - */ - protected $defaultValues = []; - - /** - * Callback methods with field names as keys. - * Callback methods are executed on fields during import process. - * - * @var array - */ - private $callbacks = []; - - /** - * Multilingual entity fields. - * - * @var array - */ - private $languageFields = [ - 'name', - 'description', - 'description_short', - 'meta_title', - 'meta_keywords', - 'meta_description', - 'link_rewrite', - 'available_now', - 'available_later', - 'delivery_in_stock', - 'delivery_out_stock', - ]; - - /** - * @var array - */ - private $warnings = []; - - /** - * @var array - */ - private $errors = []; - - /** - * @var array - */ - private $notices = []; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var int employee ID, used for logs - */ - private $employeeId; - - /** - * @var CacheClearerInterface - */ - private $cacheClearer; - - /** - * @param ImportDataFormatter $dataFormatter - * @param array $allShopIds - * @param array $contextShopIds - * @param int $currentContextShopId - * @param bool $isMultistoreEnabled - * @param int $contextLanguageId - * @param TranslatorInterface $translator - * @param LoggerInterface $logger - * @param int $employeeId - * @param Database $legacyDatabase - * @param CacheClearerInterface $cacheClearer - * @param Configuration $configuration - * @param Validate $validate - */ - public function __construct( - ImportDataFormatter $dataFormatter, - array $allShopIds, - array $contextShopIds, - $currentContextShopId, - $isMultistoreEnabled, - $contextLanguageId, - TranslatorInterface $translator, - LoggerInterface $logger, - $employeeId, - Database $legacyDatabase, - CacheClearerInterface $cacheClearer, - Configuration $configuration, - Validate $validate - ) { - $this->dataFormatter = $dataFormatter; - $this->contextShopIds = $contextShopIds; - $this->currentContextShopId = $currentContextShopId; - $this->isMultistoreEnabled = $isMultistoreEnabled; - $this->translator = $translator; - $this->allShopIds = $allShopIds; - $this->contextLanguageId = $contextLanguageId; - $this->logger = $logger; - $this->employeeId = $employeeId; - $this->legacyDatabase = $legacyDatabase; - $this->cacheClearer = $cacheClearer; - $this->configuration = $configuration; - $this->validate = $validate; - $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); - $this->defaultLanguageId = $this->configuration->getInt('PS_LANG_DEFAULT'); - } - - /** - * {@inheritdoc} - */ - public function setUp(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - $languageIso = trim($importConfig->getLanguageIso()); - $locale = strtolower($languageIso) . '_' . strtoupper($languageIso) . '.UTF-8'; - setlocale(LC_COLLATE, $locale); - setlocale(LC_CTYPE, $locale); - - $dataFormatter = $this->dataFormatter; - $multipleValueSeparator = $importConfig->getMultipleValueSeparator(); - - $getBoolean = function ($value) use ($dataFormatter) { - return $dataFormatter->getBoolean($value); - }; - $getPrice = function ($value) use ($dataFormatter) { - return $dataFormatter->getPrice($value); - }; - $createMultilangField = function ($value) use ($dataFormatter) { - return $dataFormatter->createMultiLangField($value); - }; - $split = function ($value) use ($dataFormatter, $multipleValueSeparator) { - return $dataFormatter->split($value, $multipleValueSeparator); - }; - $this->callbacks = [ - 'active' => $getBoolean, - 'tax_rate' => $getPrice, - 'price_tex' => $getPrice, - 'price_tin' => $getPrice, - 'reduction_price' => $getPrice, - 'reduction_percent' => $getPrice, - 'wholesale_price' => $getPrice, - 'ecotax' => $getPrice, - 'name' => $createMultilangField, - 'description' => $createMultilangField, - 'description_short' => $createMultilangField, - 'meta_title' => $createMultilangField, - 'meta_keywords' => $createMultilangField, - 'meta_description' => $createMultilangField, - 'link_rewrite' => $createMultilangField, - 'available_now' => $createMultilangField, - 'available_later' => $createMultilangField, - 'category' => $split, - 'online_only' => $getBoolean, - 'accessories' => $split, - 'image_alt' => $split, - 'delivery_in_stock' => $createMultilangField, - 'delivery_out_stock' => $createMultilangField, - ]; - - $this->legacyDatabase->disableCache(); - } - - /** - * {@inheritdoc} - */ - public function importRow( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - DataRowInterface $dataRow - ) { - if ($dataRow->isEmpty()) { - $this->warning( - $this->translator->trans( - 'There is an empty row in the file that won\'t be imported.', - [], - 'Admin.Advparameters.Notification' - ) - ); - throw new EmptyDataRowException(); - } - - if (!$this->languageId) { - $this->languageId = Language::getIdByIso($importConfig->getLanguageIso()); - - if (!$this->validate->isUnsignedInt($this->languageId)) { - $this->languageId = $this->configuration->getInt('PS_LANG_DEFAULT'); - } - } - } - - /** - * {@inheritdoc} - */ - public function tearDown(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - if (!$runtimeConfig->shouldValidateData()) { - $offset = $runtimeConfig->getOffset(); - - $logMessage = sprintf( - $this->translator->trans('%s import', [], 'Admin.Advparameters.Notification'), - $this->importTypeLabel - ); - $logMessage .= ' '; - $logMessage .= sprintf( - $this->translator->trans('(from %s to %s)', [], 'Admin.Advparameters.Notification'), - $offset, - $runtimeConfig->getNumberOfProcessedRows() + $offset - ); - if ($importConfig->truncate()) { - $logMessage .= ' '; - $logMessage .= $this->translator->trans('with truncate', [], 'Admin.Advparameters.Notification'); - } - $this->logger->notice( - $logMessage, - [ - 'allow_duplicate' => true, - 'object_type' => $this->importTypeLabel, - ] - ); - - if ($runtimeConfig->isFinished()) { - $this->cacheClearer->clear(); - } - } - - $this->legacyDatabase->enableCache(); - } - - /** - * {@inheritdoc} - */ - public function getWarnings() - { - return $this->warnings; - } - - /** - * Add a warning message. - * - * @param string $message - */ - public function warning($message) - { - $this->warnings[] = $message; - } - - /** - * {@inheritdoc} - */ - public function getErrors() - { - return $this->errors; - } - - /** - * Add an error message. - * - * @param string $message - */ - public function error($message) - { - $this->errors[] = $message; - } - - /** - * {@inheritdoc} - */ - public function getNotices() - { - return $this->notices; - } - - /** - * Add a notice message. - * - * @param string $message - */ - public function notice($message) - { - $this->notices[] = $message; - } - - /** - * Fetch a data value by given entity field name out of data row. - * - * @param DataRowInterface $dataRow - * @param array $entityFields required to find the data cell index in data row - * @param string $entityFieldName - * - * @return string data value - */ - protected function fetchDataValueByKey(DataRowInterface $dataRow, array $entityFields, $entityFieldName) - { - $cellIndex = array_search($entityFieldName, $entityFields); - - if (false !== $cellIndex && $dataRow->offsetExists($cellIndex)) { - $dataCell = $dataRow->offsetGet($cellIndex); - - return trim($dataCell->getValue()); - } - - return ''; - } - - /** - * Set default values for entity. - * - * @param ObjectModel $entity - */ - protected function setDefaultValues(ObjectModel $entity) - { - $members = get_object_vars($entity); - - foreach ($this->defaultValues as $field => $defaultValue) { - $fieldExists = array_key_exists($field, $members); - if (!$fieldExists || $entity->$field === null) { - $entity->$field = $defaultValue; - } - } - } - - /** - * Fill entity data out of data row. - * - * @param ObjectModel $entity - * @param array $entityFields - * @param DataRowInterface $dataRow - * @param int $languageId - */ - protected function fillEntityData( - ObjectModel $entity, - array $entityFields, - DataRowInterface $dataRow, - $languageId - ) { - foreach ($entityFields as $field) { - $value = $this->fetchDataValueByKey($dataRow, $entityFields, $field); - - if (isset($this->callbacks[$field])) { - $value = $this->callbacks[$field]($value); - } - - $canBeTranslated = in_array($field, $this->languageFields) && $languageId; - - if ($canBeTranslated) { - foreach ($value as $langId => $formattedValue) { - if (empty($entity->{$field}[$languageId]) || $langId == $languageId) { - $entity->{$field}[$langId] = $formattedValue; - } - } - } elseif (!empty($value) || $value == '0') { - $entity->{$field} = $value; - } - } - } - - /** - * Add a warning message with additional entity data. - * - * @param string $message - * @param string $entityName - * @param int|null $entityId - */ - protected function addEntityWarning($message, $entityName, $entityId = null) - { - $this->warning(sprintf( - '%s (ID %s) %s', - (string) $entityName, - null !== $entityId ? (int) $entityId : '', - $message - )); - } - - /** - * Checks if entity exists in the database. - * - * @param ObjectModel $entity - * @param string $table database table without prefix, e.g. "product". - * - * @return bool - */ - protected function entityExists(ObjectModel $entity, $table) - { - return $entity->id && ObjectModel::existsInDatabase($entity->id, $table); - } -} diff --git a/src/Adapter/Import/Handler/CategoryImportHandler.php b/src/Adapter/Import/Handler/CategoryImportHandler.php deleted file mode 100644 index 3aae58d6..00000000 --- a/src/Adapter/Import/Handler/CategoryImportHandler.php +++ /dev/null @@ -1,553 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import\Handler; - -use Category; -use Doctrine\DBAL\Connection; -use ObjectModel; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Database; -use PrestaShop\PrestaShop\Adapter\Import\ImageCopier; -use PrestaShop\PrestaShop\Adapter\Import\ImportDataFormatter; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Entity; -use PrestaShop\PrestaShop\Core\Import\Exception\InvalidDataRowException; -use PrestaShop\PrestaShop\Core\Import\Exception\SkippedIterationException; -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowInterface; -use Psr\Log\LoggerInterface; -use Shop; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CategoryImportHandler holds legacy logic of category import. - */ -final class CategoryImportHandler extends AbstractImportHandler -{ - /** - * @var array core categories IDs, such as Root and Home - */ - private $coreCategories; - - /** - * @var ImageCopier - */ - private $imageCopier; - - /** - * @var Tools - */ - private $tools; - - /** - * @var Connection - */ - private $connection; - - /** - * @var string database prefix - */ - private $dbPrefix; - - /** - * @param ImportDataFormatter $dataFormatter - * @param array $allShopIds - * @param array $contextShopIds - * @param int $currentContextShopId - * @param bool $isMultistoreEnabled - * @param int $contextLanguageId - * @param TranslatorInterface $translator - * @param LoggerInterface $logger - * @param int $employeeId - * @param Database $legacyDatabase - * @param CacheClearerInterface $cacheClearer - * @param Configuration $configuration - * @param Validate $validate - * @param ImageCopier $imageCopier - * @param Tools $tools - * @param Connection $connection - * @param string $dbPrefix - */ - public function __construct( - ImportDataFormatter $dataFormatter, - array $allShopIds, - array $contextShopIds, - $currentContextShopId, - $isMultistoreEnabled, - $contextLanguageId, - TranslatorInterface $translator, - LoggerInterface $logger, - $employeeId, - Database $legacyDatabase, - CacheClearerInterface $cacheClearer, - Configuration $configuration, - Validate $validate, - ImageCopier $imageCopier, - Tools $tools, - Connection $connection, - $dbPrefix - ) { - parent::__construct( - $dataFormatter, - $allShopIds, - $contextShopIds, - $currentContextShopId, - $isMultistoreEnabled, - $contextLanguageId, - $translator, - $logger, - $employeeId, - $legacyDatabase, - $cacheClearer, - $configuration, - $validate - ); - $this->imageCopier = $imageCopier; - $this->tools = $tools; - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - $this->importTypeLabel = $this->translator->trans('Categories', [], 'Admin.Global'); - $this->defaultValues = [ - 'active' => '1', - 'parent' => $this->configuration->getInt('PS_HOME_CATEGORY'), - 'link_rewrite' => '', - ]; - } - - /** - * {@inheritdoc} - */ - public function setUp(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - parent::setUp($importConfig, $runtimeConfig); - - $this->coreCategories = [ - $this->configuration->getInt('PS_ROOT_CATEGORY'), - $this->configuration->getInt('PS_HOME_CATEGORY'), - ]; - } - - /** - * {@inheritdoc} - */ - public function importRow( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - DataRowInterface $dataRow - ) { - parent::importRow($importConfig, $runtimeConfig, $dataRow); - - $entityFields = $runtimeConfig->getEntityFields(); - $categoryId = $this->fetchDataValueByKey($dataRow, $entityFields, 'id'); - - $this->checkCategoryId($categoryId); - - if ($categoryId && ($importConfig->forceIds() || ObjectModel::existsInDatabase($categoryId, 'category'))) { - $category = new Category((int) $categoryId); - } else { - $category = new Category(); - } - - $category->id_shop_default = $this->currentContextShopId; - - $this->setDefaultValues($category); - $this->fillEntityData($category, $entityFields, $dataRow, $this->languageId); - $this->findParentCategory($category, $runtimeConfig, $categoryId); - $this->fillLinkRewrite($category, $categoryId); - $this->createCategory( - $category, - $importConfig, - $runtimeConfig, - $categoryId, - $this->fetchDataValueByKey($dataRow, $entityFields, 'name'), - $this->fetchDataValueByKey($dataRow, $entityFields, 'shop') - ); - - return $category; - } - - /** - * {@inheritdoc} - */ - public function tearDown(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - if (!$runtimeConfig->shouldValidateData() && $runtimeConfig->isFinished()) { - /* Import has finished, we can regenerate the categories nested tree */ - Category::regenerateEntireNtree(); - } - - parent::tearDown($importConfig, $runtimeConfig); - } - - /** - * Checks if given category ID is allowed in the import. - * - * @param int $categoryId - */ - private function checkCategoryId($categoryId) - { - if (in_array($categoryId, $this->coreCategories)) { - $this->error( - $this->translator->trans( - 'The category ID must be unique. It can\'t be the same as the one for Root or Home category.', - [], - 'Admin.Advparameters.Notification' - ) - ); - throw new InvalidDataRowException(); - } - } - - /** - * Find the parent category for category that's being imported. - * - * @param Category $category - * @param ImportRuntimeConfigInterface $runtimeConfig - * @param int $categoryId - */ - private function findParentCategory( - Category $category, - ImportRuntimeConfigInterface $runtimeConfig, - $categoryId - ) { - if (!isset($category->parent)) { - return; - } - - $isValidation = $runtimeConfig->shouldValidateData(); - - // Parent category - if (is_numeric($category->parent)) { - // Validation for parenting itself - if ($isValidation && $category->parent == $category->id) { - $this->error($this->translator->trans( - 'The category ID must be unique. It can\'t be the same as the one for the parent category (ID: %1$s).', - $categoryId ?: null, - 'Admin.Advparameters.Notification' - )); - - throw new InvalidDataRowException(); - } - - $sharedData = $runtimeConfig->getSharedData(); - $movedCategories = isset($sharedData['cat_moved']) ? $sharedData['cat_moved'] : []; - - if (isset($movedCategories[$category->parent])) { - $category->parent = $movedCategories[$category->parent]; - } - $category->id_parent = $category->parent; - } elseif (is_string($category->parent)) { - // Validation for parenting itself - if ($isValidation && isset($category->name) && ($category->parent == $category->name)) { - $this->error( - $this->translator->trans( - 'A category can\'t be its own parent. You should rename it (current name: %1$s).', - [$category->parent], - 'Admin.Advparameters.Notification' - ) - ); - - throw new InvalidDataRowException(); - } - $categoryParent = Category::searchByName($this->languageId, $category->parent, true); - if ($categoryParent['id_category']) { - $category->id_parent = (int) $categoryParent['id_category']; - $category->level_depth = (int) $categoryParent['level_depth'] + 1; - } else { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $categoryToCreate = new Category(); - $categoryToCreate->name = $this->dataFormatter->createMultiLangField($category->parent); - $categoryToCreate->active = 1; - $linkRewrite = $this->dataFormatter->createFriendlyUrl( - $categoryToCreate->name[$this->languageId] - ); - $categoryToCreate->link_rewrite = $this->dataFormatter->createMultiLangField($linkRewrite); - // Default parent is home for unknown category to create - $categoryToCreate->id_parent = $this->configuration->getInt('PS_HOME_CATEGORY'); - - $fieldsError = $category->validateFields($unfriendlyError, true); - $langFieldsError = $category->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if ($isValid && !$isValidation && $categoryToCreate->add()) { - $category->id_parent = $categoryToCreate->id; - } else { - if (!$isValidation) { - $this->error( - $this->translator->trans( - '%category_name% (ID: %id%) cannot be saved', - [ - '%category_name%' => $categoryToCreate->name[$this->languageId], - '%id%' => !empty($categoryToCreate->id) ? $categoryToCreate->id : 'null', - ], - 'Admin.Advparameters.Notification' - ) - ); - } - - if (!$isValid) { - $error = true !== $fieldsError ? $fieldsError : ''; - $error .= true !== $langFieldsError ? $langFieldsError : ''; - - $this->error($error . $this->legacyDatabase->getErrorMessage()); - } - } - } - } - } - - /** - * Fill link rewrite value for category. - * - * @param Category $category - * @param int $categoryId - */ - private function fillLinkRewrite(Category $category, $categoryId) - { - if (isset($category->link_rewrite) && !empty($category->link_rewrite[$this->defaultLanguageId])) { - $validLinkRewrite = $this->validate->isLinkRewrite($category->link_rewrite[$this->defaultLanguageId]); - $linkRewrite = $category->link_rewrite[$this->defaultLanguageId]; - } else { - $validLinkRewrite = false; - $linkRewrite = $category->link_rewrite; - } - - if (empty($linkRewrite) || !$validLinkRewrite) { - $category->link_rewrite = $this->dataFormatter->createFriendlyUrl( - $category->name[$this->defaultLanguageId] - ); - if ($category->link_rewrite == '') { - $category->link_rewrite = 'friendly-url-autogeneration-failed'; - $this->warning( - $this->translator->trans( - 'URL rewriting failed to auto-generate a friendly URL for: %category_name%', - [ - '%category_name%' => $category->name[$this->defaultLanguageId], - ], - 'Admin.Advparameters.Notification' - ) - ); - } - $category->link_rewrite = $this->dataFormatter->createMultiLangField($category->link_rewrite); - } - - if (!$validLinkRewrite) { - $this->notice( - $this->translator->trans( - 'Rewrite link for %1$s (ID %2$s): re-written as %3$s.', - [ - '%1$s' => $linkRewrite, - '%2$s' => !empty($categoryId) ? $categoryId : 'null', - '%3$s' => $category->link_rewrite[$this->defaultLanguageId], - ], - 'Admin.Advparameters.Notification' - ) - ); - } - } - - /** - * Create the category. - * - * @param Category $category - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - * @param int $categoryId - * @param string $categoryName - * @param string $shopData - */ - private function createCategory( - Category $category, - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - $categoryId, - $categoryName, - $shopData - ) { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $movedCategories = []; - $result = false; - - $fieldsError = $category->validateFields($unfriendlyError, true); - $langFieldsError = $category->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if ($isValid && empty($this->getErrors())) { - $categoryAlreadyCreated = Category::searchByNameAndParentCategoryId( - $this->languageId, - $category->name[$this->languageId], - $category->id_parent - ); - - // If category already in base, get id category back - if ($categoryAlreadyCreated['id_category']) { - $movedCategories[$category->id] = (int) $categoryAlreadyCreated['id_category']; - $category->id = (int) $categoryAlreadyCreated['id_category']; - if (Validate::isDate($categoryAlreadyCreated['date_add'])) { - $category->date_add = $categoryAlreadyCreated['date_add']; - } - } - - if ($category->id && $category->id == $category->id_parent) { - $this->error( - sprintf( - $this->translator->trans( - 'A category cannot be its own parent. The parent category ID is either missing or unknown (ID: %1$s).', - [], - 'Admin.Advparameters.Notification' - ), - !empty($categoryId) ? $categoryId : 'null' - ) - ); - - throw new InvalidDataRowException(); - } - - /* No automatic nTree regeneration for import */ - $category->doNotRegenerateNTree = true; - - // If id category AND id category already in base, trying to update - if ($category->id && - $category->categoryExists($category->id) && - !in_array($category->id, $this->coreCategories) && - !$runtimeConfig->shouldValidateData() - ) { - $result = $category->update(); - } - if ($category->id == $this->configuration->getInt('PS_ROOT_CATEGORY')) { - $this->error( - $this->translator->trans( - 'The root category cannot be modified.', - [], - 'Admin.Advparameters.Notification' - ) - ); - } - // If no id_category or update failed - $category->force_id = (bool) $importConfig->forceIds(); - if (!$result && !$runtimeConfig->shouldValidateData()) { - $result = $category->add(); - if ($categoryId && $category->id != $categoryId) { - $movedCategories[$categoryId] = $category->id; - } - } - } - - if ($movedCategories) { - $sharedData = $runtimeConfig->getSharedData(); - - if ($this->propertyAccessor->isWritable($sharedData, '[cat_moved]')) { - $sharedItem = $this->propertyAccessor->getValue($sharedData, '[cat_moved]'); - $sharedItem = is_array($sharedItem) ? $sharedItem + $movedCategories : $movedCategories; - $runtimeConfig->addSharedDataItem('cat_moved', $sharedItem); - } - } - - if ($runtimeConfig->shouldValidateData()) { - throw new SkippedIterationException(); - } - - //copying images of categories - if (!empty($category->image)) { - $copyResult = $this->imageCopier->copyImg( - $category->id, - null, - $category->image, - 'categories', - !$importConfig->skipThumbnailRegeneration() - ); - - if (!$copyResult) { - $this->warning( - $category->image . - ' ' . - $this->translator->trans('cannot be copied.', [], 'Admin.Advparameters.Notification') - ); - } - } - - // If both failed, mysql error - if (!$result) { - $this->error( - $this->translator->trans( - '%1$s (ID: %2$s) cannot be %3$s', - [ - !empty($categoryName) ? $this->tools->sanitize($categoryName) : 'No Name', - !empty($categoryId) ? $this->tools->sanitize($categoryId) : 'No ID', - $runtimeConfig->shouldValidateData() ? 'validated' : 'saved', - ], - 'Admin.Advparameters.Notification' - ) - ); - $error = $fieldsError !== true ? $fieldsError : ''; - $error .= $langFieldsError !== true ? $langFieldsError : ''; - $error .= $this->legacyDatabase->getErrorMessage(); - - if ($error) { - $this->error($error); - } - } else { - // Associate category to shop - if ($this->isMultistoreEnabled) { - $this->connection->delete( - $this->dbPrefix . 'category_shop', - [ - 'id_category' => (int) $category->id, - ] - ); - - if (empty($shopData)) { - $shopData = implode($importConfig->getMultipleValueSeparator(), $this->contextShopIds); - } - - // Get shops for each attributes - $shopData = explode($importConfig->getMultipleValueSeparator(), $shopData); - - foreach ($shopData as $shop) { - if (!empty($shop)) { - if (!is_numeric($shop)) { - $category->addShop(Shop::getIdByName($shop)); - } else { - $category->addShop($shop); - } - } - } - } - } - } - - /** - * {@inheritdoc} - */ - public function supports($importEntityType) - { - return $importEntityType === Entity::TYPE_CATEGORIES; - } -} diff --git a/src/Adapter/Import/Handler/ImportHandlerFinder.php b/src/Adapter/Import/Handler/ImportHandlerFinder.php deleted file mode 100644 index ae6fbc58..00000000 --- a/src/Adapter/Import/Handler/ImportHandlerFinder.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import\Handler; - -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportTypeException; -use PrestaShop\PrestaShop\Core\Import\Handler\ImportHandlerFinderInterface; -use PrestaShop\PrestaShop\Core\Import\Handler\ImportHandlerInterface; - -/** - * Class ImportHandlerFinder is responsible for finding a proper import handler. - */ -final class ImportHandlerFinder implements ImportHandlerFinderInterface -{ - /** - * @var ImportHandlerInterface[] - */ - private $importHandlers; - - /** - * @param ImportHandlerInterface[] $importHandlers - */ - public function __construct(ImportHandlerInterface ...$importHandlers) - { - $this->importHandlers = $importHandlers; - } - - /** - * {@inheritdoc} - */ - public function find($importEntityType) - { - foreach ($this->importHandlers as $importHandler) { - if ($importHandler->supports($importEntityType)) { - return $importHandler; - } - } - - throw new NotSupportedImportTypeException(); - } -} diff --git a/src/Adapter/Import/Handler/ProductImportHandler.php b/src/Adapter/Import/Handler/ProductImportHandler.php deleted file mode 100644 index 3801c434..00000000 --- a/src/Adapter/Import/Handler/ProductImportHandler.php +++ /dev/null @@ -1,1420 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import\Handler; - -use Address; -use Category; -use Doctrine\DBAL\Connection; -use Feature; -use FeatureValue; -use Image; -use Manufacturer; -use Module; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Database; -use PrestaShop\PrestaShop\Adapter\Import\ImageCopier; -use PrestaShop\PrestaShop\Adapter\Import\ImportDataFormatter; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Entity; -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowInterface; -use Product; -use ProductDownload; -use ProductSupplier; -use Psr\Log\LoggerInterface; -use Shop; -use SpecificPrice; -use StockAvailable; -use StockManagerFactory; -use Supplier; -use Symfony\Component\Translation\TranslatorInterface; -use Tag; -use TaxManagerFactory; -use TaxRulesGroup; -use Warehouse; -use WarehouseProductLocation; - -/** - * Class ProductImportHandler is responsible for product import. - */ -final class ProductImportHandler extends AbstractImportHandler -{ - /** - * @var Connection database connection - */ - private $connection; - - /** - * @var string product database table name - */ - private $productTable; - - /** - * @var string accessory database table name - */ - private $accessoryTable; - - /** - * @var Address - */ - private $shopAddress; - - /** - * @var Tools - */ - private $tools; - - /** - * @var ImageCopier - */ - private $imageCopier; - - /** - * @param ImportDataFormatter $dataFormatter - * @param array $allShopIds - * @param array $contextShopIds - * @param int $currentContextShopId - * @param bool $isMultistoreEnabled - * @param int $contextLanguageId - * @param TranslatorInterface $translator - * @param LoggerInterface $logger - * @param int $employeeId - * @param Database $legacyDatabase - * @param CacheClearerInterface $cacheClearer - * @param Connection $connection - * @param string $dbPrefix - * @param Configuration $configuration - * @param Address $shopAddress - * @param Validate $validate - * @param Tools $tools - * @param ImageCopier $imageCopier - */ - public function __construct( - ImportDataFormatter $dataFormatter, - array $allShopIds, - array $contextShopIds, - $currentContextShopId, - $isMultistoreEnabled, - $contextLanguageId, - TranslatorInterface $translator, - LoggerInterface $logger, - $employeeId, - Database $legacyDatabase, - CacheClearerInterface $cacheClearer, - Connection $connection, - $dbPrefix, - Configuration $configuration, - Address $shopAddress, - Validate $validate, - Tools $tools, - ImageCopier $imageCopier - ) { - parent::__construct( - $dataFormatter, - $allShopIds, - $contextShopIds, - $currentContextShopId, - $isMultistoreEnabled, - $contextLanguageId, - $translator, - $logger, - $employeeId, - $legacyDatabase, - $cacheClearer, - $configuration, - $validate - ); - - $this->connection = $connection; - $this->productTable = $dbPrefix . 'product'; - $this->accessoryTable = $dbPrefix . 'accessory'; - $this->defaultValues = [ - 'id_category' => [$this->configuration->getInt('PS_HOME_CATEGORY')], - 'id_category_default' => null, - 'active' => '1', - 'width' => 0.000000, - 'height' => 0.000000, - 'depth' => 0.000000, - 'weight' => 0.000000, - 'visibility' => 'both', - 'additional_shipping_cost' => 0.00, - 'unit_price' => 0, - 'quantity' => 0, - 'minimal_quantity' => 1, - 'low_stock_threshold' => null, - 'low_stock_alert' => false, - 'price' => 0, - 'id_tax_rules_group' => 0, - 'description_short' => [$this->defaultLanguageId => ''], - 'link_rewrite' => [$this->defaultLanguageId => ''], - 'online_only' => 0, - 'condition' => 'new', - 'available_date' => date('Y-m-d'), - 'date_add' => date('Y-m-d H:i:s'), - 'date_upd' => date('Y-m-d H:i:s'), - 'customizable' => 0, - 'uploadable_files' => 0, - 'text_fields' => 0, - 'advanced_stock_management' => 0, - 'depends_on_stock' => 0, - 'is_virtual' => 0, - ]; - $this->shopAddress = $shopAddress; - $this->tools = $tools; - $this->imageCopier = $imageCopier; - $this->importTypeLabel = $this->translator->trans('Products', [], 'Admin.Global'); - } - - /** - * {@inheritdoc} - */ - public function setUp(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - parent::setUp($importConfig, $runtimeConfig); - - if (!defined('PS_MASS_PRODUCT_CREATION')) { - define('PS_MASS_PRODUCT_CREATION', true); - } - - if (!$runtimeConfig->shouldValidateData()) { - Module::setBatchMode(true); - } - } - - /** - * {@inheritdoc} - */ - public function importRow( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - DataRowInterface $dataRow - ) { - parent::importRow($importConfig, $runtimeConfig, $dataRow); - - $entityFields = $runtimeConfig->getEntityFields(); - $productId = $this->fetchProductId( - $dataRow, - $runtimeConfig->getEntityFields(), - $importConfig->matchReferences() - ); - $productName = $this->fetchDataValueByKey($dataRow, $entityFields, 'name'); - $product = new Product($productId); - - $this->loadStock($product); - $this->setDefaultValues($product); - $this->fillEntityData($product, $entityFields, $dataRow, $this->languageId); - $this->loadShops($product, $importConfig, $productName); - $this->loadTaxes($product); - $this->loadManufacturer($product, false); - $this->loadSupplier($product, false); - $this->loadPrice($product); - $this->loadCategory($product, false); - $this->loadMetaData($product, $importConfig); - $this->fixFloatValues($product); - - $productExistsById = $this->entityExists($product, 'product'); - $productExistsByReference = $importConfig->matchReferences() && - $product->reference && - $product->existsRefInDatabase($product->reference) - ; - - if ($productExistsByReference || $productExistsById) { - $product->date_upd = date('Y-m-d H:i:s'); - } - - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $fieldsError = $product->validateFields($unfriendlyError, true); - $langFieldsError = $product->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if ($isValid) { - $productSaved = $this->loadProductData( - $product, - $importConfig, - $productExistsById, - $productExistsByReference, - $runtimeConfig->shouldValidateData(), - $dataRow, - $entityFields - ); - - if (!$productSaved) { - $productId = $this->fetchDataValueByKey($dataRow, $entityFields, 'id'); - - $this->error(sprintf( - $this->translator->trans('%1$s (ID: %2$s) cannot be saved', [], 'Admin.Advparameters.Notification'), - !empty($productName) ? $this->tools->sanitize($productName) : 'No Name', - !empty($productId) ? $this->tools->sanitize($productId) : 'No ID' - )); - - $this->error($fieldsError . $langFieldsError . $this->legacyDatabase->getErrorMessage()); - } else { - if (!$runtimeConfig->shouldValidateData()) { - $this->saveProductSupplier($product); - $this->saveProductTags($product, $importConfig, $productName); - $this->saveProductImages($product, $importConfig); - $this->saveFeatures($product, $importConfig); - } - - $this->saveSpecificPrice( - $product, - $this->fetchDataValueByKey($dataRow, $entityFields, 'reduction_price'), - $this->fetchDataValueByKey($dataRow, $entityFields, 'reduction_percent'), - $this->fetchDataValueByKey($dataRow, $entityFields, 'reduction_from'), - $this->fetchDataValueByKey($dataRow, $entityFields, 'reduction_to'), - $runtimeConfig->shouldValidateData(), - $productName - ); - $this->updateAdditionalData($product, $runtimeConfig->shouldValidateData()); - $this->saveStock( - $product, - $runtimeConfig->shouldValidateData(), - $productExistsById || $productExistsByReference - ); - - $this->linkAccessories($product, $runtimeConfig); - } - } - } - - /** - * {@inheritdoc} - */ - public function tearDown(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig) - { - parent::tearDown($importConfig, $runtimeConfig); - - if ($runtimeConfig->isFinished() && !$runtimeConfig->shouldValidateData()) { - $this->importAccessories($runtimeConfig); - } - - if (!$runtimeConfig->shouldValidateData()) { - Module::processDeferedFuncCall(); - Module::processDeferedClearCache(); - Tag::updateTagCount(); - } - } - - /** - * Legacy logic to create category. - * This method is internally called by legacy Category::searchByPath(), so it has to be public. - * - * @param int $defaultLanguageId - * @param string $categoryName - * @param int|null $parentCategoryId - */ - public function createCategory($defaultLanguageId, $categoryName, $parentCategoryId = null) - { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $homeCategoryId = $this->configuration->getInt('PS_HOME_CATEGORY'); - $category = new Category(); - - $category->id_shop_default = $this->isMultistoreEnabled ? (int) $this->currentContextShopId : 1; - $category->name = $this->dataFormatter->createMultiLangField(trim($categoryName)); - $category->active = 1; - $category->id_parent = (int) ($parentCategoryId ? $parentCategoryId : $homeCategoryId); - $category->link_rewrite = $this->dataFormatter->createMultiLangField( - $this->dataFormatter->createFriendlyUrl($category->name[$defaultLanguageId]) - ); - - $fieldsError = $category->validateFields($unfriendlyError, true); - $langFieldsError = $category->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if (!$isValid || !$category->add()) { - $this->error(sprintf( - $this->translator->trans( - '%1$s (ID: %2$s) cannot be saved', - [], - 'Admin.Advparameters.Notification' - ), - $category->name[$defaultLanguageId], - !empty($category->id) ? $category->id : 'null' - )); - - if (!$isValid) { - $error = true !== $fieldsError ? $fieldsError : ''; - $error .= true !== $langFieldsError ? $langFieldsError : ''; - - $this->error($error . $this->legacyDatabase->getErrorMessage()); - } - } - } - - /** - * Fetch the product ID. - * - * @param DataRowInterface $dataRow - * @param array $entityFields - * @param bool $fetchByReference if true, will fallback to finding the product ID by reference - * - * @return int|null - */ - private function fetchProductId( - DataRowInterface $dataRow, - array $entityFields, - $fetchByReference - ) { - $productId = $this->fetchDataValueByKey($dataRow, $entityFields, 'id'); - - if (!empty($productId)) { - return (int) $productId; - } - - if ($fetchByReference) { - $productReference = $this->fetchDataValueByKey($dataRow, $entityFields, 'reference'); - - if ($productReference) { - $statement = $this->connection->query( - 'SELECT p.`id_product` - FROM `' . $this->productTable . '` p - ' . Shop::addSqlAssociation('product', 'p') . ' - WHERE p.`reference` = "' . pSQL($productReference) . '"' - ); - $row = $statement->fetch(); - - return isset($row['id_product']) ? $row['id_product'] : null; - } - } - - return null; - } - - /** - * Load stock data for the product. - * - * @param Product $product - */ - private function loadStock(Product $product) - { - if (!Validate::isLoadedObject($product)) { - return; - } - - $product->loadStockData(); - $category_data = Product::getProductCategories((int) $product->id); - - if (is_array($category_data)) { - foreach ($category_data as $tmp) { - if (!isset($product->category) || !$product->category || is_array($product->category)) { - $product->category[] = $tmp; - } - } - } - } - - /** - * Load shops data into the product object. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - * @param string $productName used for error messages - */ - private function loadShops(Product $product, ImportConfigInterface $importConfig, $productName) - { - $defaultShopId = $this->configuration->getInt('PS_SHOP_DEFAULT'); - - if (!$this->isMultistoreEnabled) { - $product->shop = $defaultShopId; - $product->id_shop_default = $defaultShopId; - } elseif (!isset($product->shop) || empty($product->shop)) { - $product->shop = implode($importConfig->getMultipleValueSeparator(), $this->contextShopIds); - $product->id_shop_default = $this->currentContextShopId; - } - - // link product to shops - $product->id_shop_list = []; - $productShops = explode($importConfig->getMultipleValueSeparator(), $product->shop); - - if (is_array($productShops)) { - foreach ($productShops as $shop) { - if (!empty($shop)) { - $shop = is_numeric($shop) ? $shop : Shop::getIdByName($shop); - - if (!in_array($shop, $this->allShopIds)) { - $this->addEntityWarning( - $this->translator->trans('Shop is not valid', [], 'Admin.Advparameters.Notification'), - $productName, - $product->id - ); - } else { - $product->id_shop_list[] = $shop; - } - } - } - } - } - - /** - * Load taxes data into the product object. - * - * @param Product $product - */ - private function loadTaxes(Product $product) - { - if ($product->id_tax_rules_group) { - if (Validate::isLoadedObject(new TaxRulesGroup($product->id_tax_rules_group))) { - $taxManager = TaxManagerFactory::getManager($this->shopAddress, $product->id_tax_rules_group); - $taxCalculator = $taxManager->getTaxCalculator(); - $product->tax_rate = $taxCalculator->getTotalRate(); - } else { - $this->addEntityWarning( - $this->translator->trans( - 'Unknown tax rule group ID. You need to create a group with this ID first.', - [], - 'Admin.Advparameters.Notification' - ), - 'id_tax_rules_group', - $product->id_tax_rules_group - ); - } - } - - if (!$this->configuration->getBoolean('PS_USE_ECOTAX')) { - $product->ecotax = 0; - } - } - - /** - * Load manufacturer data into the product object. - * - * @param Product $product - * @param bool $validateOnly if true, will not create new manufacturer if not exists - */ - private function loadManufacturer(Product $product, $validateOnly) - { - if (!isset($product->manufacturer)) { - return; - } - - if (is_numeric($product->manufacturer) && Manufacturer::manufacturerExists($product->manufacturer)) { - $product->id_manufacturer = (int) $product->manufacturer; - } elseif (is_string($product->manufacturer) && !empty($product->manufacturer)) { - if ($manufacturer = Manufacturer::getIdByName($product->manufacturer)) { - $product->id_manufacturer = (int) $manufacturer; - } else { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - - $manufacturer = new Manufacturer(); - $manufacturer->name = $product->manufacturer; - $manufacturer->active = true; - - $fieldsError = $manufacturer->validateFields($unfriendlyError, true); - $langFieldsError = $manufacturer->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - // Creating the manufacturer if it's not validation step - if ($isValid && !$validateOnly && $manufacturer->add()) { - $product->id_manufacturer = (int) $manufacturer->id; - $manufacturer->associateTo($product->id_shop_list); - } else { - if (!$validateOnly) { - $this->error(sprintf( - $this->translator->trans( - '%1$s (ID: %2$s) cannot be saved', - [], - 'Admin.Advparameters.Notification' - ), - $manufacturer->name, - !empty($manufacturer->id) ? $manufacturer->id : 'null' - )); - } - - if (!$isValid) { - $error = true !== $fieldsError ? $fieldsError : ''; - $error .= true !== $langFieldsError ? $langFieldsError : ''; - - $this->error($error . $this->legacyDatabase->getErrorMessage()); - } - } - } - } - } - - /** - * Load supplier data into the product object. - * - * @param Product $product - * @param bool $validateOnly if true, will not create new supplier if not exists - */ - private function loadSupplier(Product $product, $validateOnly) - { - if (!isset($product->supplier)) { - return; - } - - if (is_numeric($product->supplier) && Supplier::supplierExists($product->supplier)) { - $product->id_supplier = (int) $product->supplier; - } elseif (is_string($product->supplier) && !empty($product->supplier)) { - if ($supplier = Supplier::getIdByName($product->supplier)) { - $product->id_supplier = (int) $supplier; - } else { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - - $supplier = new Supplier(); - $supplier->name = $product->supplier; - $supplier->active = true; - - $fieldsError = $supplier->validateFields($unfriendlyError, true); - $langFieldsError = $supplier->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - // Creating the supplier if it's not validation step - if ($isValid && !$validateOnly && $supplier->add()) { - $product->id_supplier = (int) $supplier->id; - $supplier->associateTo($product->id_shop_list); - } else { - if (!$validateOnly) { - $this->error(sprintf( - $this->translator->trans( - '%1$s (ID: %2$s) cannot be saved', - [], - 'Admin.Advparameters.Notification' - ), - $supplier->name, - !empty($supplier->id) ? $supplier->id : 'null' - )); - } - - if (!$isValid) { - $error = true !== $fieldsError ? $fieldsError : ''; - $error .= true !== $langFieldsError ? $langFieldsError : ''; - - $this->error($error . $this->legacyDatabase->getErrorMessage()); - } - } - } - } - } - - /** - * Load prices into product object. - * - * @param Product $product - */ - private function loadPrice(Product $product) - { - if (isset($product->price_tex) && !isset($product->price_tin)) { - $product->price = $product->price_tex; - } elseif (isset($product->price_tin) && !isset($product->price_tex)) { - $product->price = $product->price_tin; - // If a tax is already included in price, withdraw it from price - if ($product->tax_rate) { - $product->price = (float) number_format($product->price / (1 + $product->tax_rate / 100), 6, '.', ''); - } - } elseif (isset($product->price_tin, $product->price_tex)) { - $product->price = $product->price_tex; - } - } - - /** - * Load category data into product object. - * - * @param Product $product - * @param $validateOnly - */ - private function loadCategory(Product $product, $validateOnly) - { - if (isset($product->category) && is_array($product->category) && count($product->category)) { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $defaultLanguageId = $this->configuration->getInt('PS_LANG_DEFAULT'); - $homeCategoryId = $this->configuration->getInt('PS_HOME_CATEGORY'); - $product->id_category = []; // Reset default values array - - foreach ($product->category as $value) { - if (is_numeric($value)) { - if (Category::categoryExists($value)) { - $product->id_category[] = (int) $value; - } else { - $category = new Category(); - $category->id = (int) $value; - $category->name = $this->dataFormatter->createMultiLangField($value); - $category->active = 1; - $category->id_parent = $homeCategoryId; - $category->link_rewrite = $this->dataFormatter->createMultiLangField( - $this->dataFormatter->createFriendlyUrl($category->name[$defaultLanguageId]) - ); - - $fieldsError = $category->validateFields($unfriendlyError, true); - $langFieldsError = $category->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if ($isValid && !$validateOnly && $category->add()) { - $product->id_category[] = (int) $category->id; - } else { - if (!$validateOnly) { - $this->error(sprintf( - $this->translator->trans( - '%1$s (ID: %2$s) cannot be saved', - [], - 'Admin.Advparameters.Notification' - ), - $category->name[$defaultLanguageId], - !empty($category->id) ? $category->id : 'null' - )); - } - - if (!$isValid) { - $error = true !== $fieldsError ? $fieldsError : ''; - $error .= true !== $langFieldsError ? $langFieldsError : ''; - - $this->error($error . $this->legacyDatabase->getErrorMessage()); - } - } - } - } elseif (!$validateOnly && is_string($value) && !empty($value)) { - $category = Category::searchByPath( - $defaultLanguageId, - trim($value), - $this, - 'createCategory' - ); - if ($category['id_category']) { - $product->id_category[] = (int) $category['id_category']; - } else { - $this->error( - $this->translator->trans( - '%data% cannot be saved', - [ - '%data%' => trim($value), - ], - 'Admin.Advparameters.Notification' - ) - ); - } - } - } - - $product->id_category = array_values(array_unique($product->id_category)); - } - - // Category default now takes the value of the first new category during import - if (isset($product->id_category[0])) { - $product->id_category_default = (int) $product->id_category[0]; - } elseif (!empty($product->id_category_default)) { - $defaultProductShop = new Shop($product->id_shop_default); - $product->id_category_default = Category::getRootCategory( - null, - Validate::isLoadedObject($defaultProductShop) ? $defaultProductShop : null - )->id; - } - } - - /** - * Load meta data into the product object. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - */ - private function loadMetaData(Product $product, ImportConfigInterface $importConfig) - { - $linkRewrite = ''; - - $linkRewriteExists = is_array($product->link_rewrite) && isset($product->link_rewrite[$this->languageId]); - - if ($linkRewriteExists) { - $linkRewrite = trim($product->link_rewrite[$this->languageId]); - } - - $validLink = $this->validate->isLinkRewrite($linkRewrite); - - if (($linkRewriteExists && empty($product->link_rewrite[$this->languageId])) || !$validLink) { - $linkRewrite = $this->dataFormatter->createFriendlyUrl($product->name[$this->languageId]); - - if ($linkRewrite == '') { - $linkRewrite = 'friendly-url-autogeneration-failed'; - } - } - - if (!$validLink) { - $this->notice($this->translator->trans( - 'Rewrite link for %1$s (ID %2$s): re-written as %3$s.', - [ - '%1$s' => $product->name[$this->languageId], - '%2$s' => !empty($info['id']) ? $info['id'] : 'null', - '%3$s' => $linkRewrite, - ], - 'Admin.Advparameters.Notification' - )); - } - - if (!$validLink || !(is_array($product->link_rewrite) && count($product->link_rewrite))) { - $product->link_rewrite = $this->dataFormatter->createMultiLangField($linkRewrite); - } else { - $product->link_rewrite[(int) $this->languageId] = $linkRewrite; - } - - $multipleValueSeparator = $importConfig->getMultipleValueSeparator(); - - // replace the value of separator by coma - if ($multipleValueSeparator != ',') { - if (is_array($product->meta_keywords)) { - foreach ($product->meta_keywords as &$metaKeyword) { - if (!empty($metaKeyword)) { - $metaKeyword = str_replace($multipleValueSeparator, ',', $metaKeyword); - } - } - } - } - } - - /** - * Fix float values. - * - * @param Product $product - */ - private function fixFloatValues(Product $product) - { - // Convert comma into dot for all floating values - foreach (Product::$definition['fields'] as $key => $array) { - if ($array['type'] == Product::TYPE_FLOAT) { - $product->{$key} = str_replace(',', '.', $product->{$key}); - } - } - } - - /** - * Load other product data. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - * @param bool $productExistsById - * @param bool $productExistsByReference - * @param bool $validateOnly - * @param DataRowInterface $dataRow - * @param array $entityFields - * - * @return bool - */ - private function loadProductData( - Product $product, - ImportConfigInterface $importConfig, - $productExistsById, - $productExistsByReference, - $validateOnly, - DataRowInterface $dataRow, - array $entityFields - ) { - if (!$product->quantity) { - $product->quantity = 0; - } - - $product->force_id = (bool) $importConfig->forceIds(); - $result = true; - - if ($productExistsById || $productExistsByReference) { - $sqlPart = 'SELECT product_shop.`date_add`, p.`id_product` - FROM `' . _DB_PREFIX_ . 'product` p - ' . Shop::addSqlAssociation('product', 'p') . ' - WHERE '; - - if ($productExistsByReference) { - $sqlPart .= 'p.`reference` = "' . pSQL($product->reference) . '"'; - } elseif ($productExistsById) { - $sqlPart .= 'p.`id_product` = ' . (int) $product->id; - } - - $statement = $this->connection->query($sqlPart); - $row = $statement->fetch(); - - if ($productExistsByReference) { - $product->id = (int) $row['id_product']; - } - - $product->date_add = $row['date_add']; - - if (!$validateOnly) { - $result = $product->update(); - } - } else { - $result = $product->add($product->date_add == ''); - } - - if (!$validateOnly) { - if ($product->getType() == Product::PTYPE_VIRTUAL) { - StockAvailable::setProductOutOfStock((int) $product->id, 1); - } else { - StockAvailable::setProductOutOfStock((int) $product->id, (int) $product->out_of_stock); - } - - if ($productDownload_id = ProductDownload::getIdFromIdProduct((int) $product->id)) { - $productDownload = new ProductDownload($productDownload_id); - $productDownload->delete(true); - } - - if ($product->getType() == Product::PTYPE_VIRTUAL) { - $downloadDir = $this->configuration->get('_PS_DOWNLOAD_DIR_'); - - $productDownload = new ProductDownload(); - $productDownload->filename = ProductDownload::getNewFilename(); - $virtualProductFileUrl = $this->fetchDataValueByKey( - $dataRow, - $entityFields, - 'file_url' - ); - $this->tools->copy($virtualProductFileUrl, $downloadDir . $productDownload->filename); - $productDownload->id_product = (int) $product->id; - $productDownload->nb_downloadable = (int) $this->fetchDataValueByKey( - $dataRow, - $entityFields, - 'nb_downloadable' - ); - $productDownload->date_expiration = $this->fetchDataValueByKey( - $dataRow, - $entityFields, - 'date_expiration' - ); - $productDownload->nb_days_accessible = (int) $this->fetchDataValueByKey( - $dataRow, - $entityFields, - 'nb_days_accessible' - ); - $productDownload->display_filename = basename($virtualProductFileUrl); - $productDownload->add(); - } - } - - return $result; - } - - /** - * Save product supplier data. - * - * @param Product $product - */ - private function saveProductSupplier(Product $product) - { - if ($product->id && isset($product->id_supplier) && property_exists($product, 'supplier_reference')) { - $productSupplierId = (int) ProductSupplier::getIdByProductAndSupplier( - (int) $product->id, - 0, - (int) $product->id_supplier - ); - - $productSupplier = new ProductSupplier($productSupplierId); - $productSupplier->id_product = (int) $product->id; - $productSupplier->id_product_attribute = 0; - $productSupplier->id_supplier = (int) $product->id_supplier; - $productSupplier->product_supplier_price_te = $product->wholesale_price; - $productSupplier->product_supplier_reference = $product->supplier_reference; - $productSupplier->save(); - } - } - - /** - * Save specific price for a product. - * - * @param Product $product - * @param $reductionPrice - * @param $reductionPercent - * @param $reductionFrom - * @param $reductionTo - * @param $validateOnly - * @param $productName - */ - private function saveSpecificPrice( - Product $product, - $reductionPrice, - $reductionPercent, - $reductionFrom, - $reductionTo, - $validateOnly, - $productName - ) { - $reductionPercent = (float) $reductionPercent; - $reductionPrice = (float) $reductionPrice; - - if (!$reductionPrice <= 0 && $reductionPercent <= 0) { - return; - } - - foreach ($product->id_shop_list as $shopId) { - $specificPrice = SpecificPrice::getSpecificPrice($product->id, $shopId, 0, 0, 0, 1, 0, 0, 0, 0); - - if (is_array($specificPrice) && isset($specificPrice['id_specific_price'])) { - $specificPrice = new SpecificPrice((int) $specificPrice['id_specific_price']); - } else { - $specificPrice = new SpecificPrice(); - } - $specificPrice->id_product = (int) $product->id; - $specificPrice->id_specific_price_rule = 0; - $specificPrice->id_shop = $shopId; - $specificPrice->id_currency = 0; - $specificPrice->id_country = 0; - $specificPrice->id_group = 0; - $specificPrice->price = -1; - $specificPrice->id_customer = 0; - $specificPrice->from_quantity = 1; - $specificPrice->reduction = $reductionPrice ? $reductionPrice : $reductionPercent / 100; - $specificPrice->reduction_type = $reductionPrice ? 'amount' : 'percentage'; - $specificPrice->from = Validate::isDate($reductionFrom) ? $reductionFrom : '0000-00-00 00:00:00'; - $specificPrice->to = Validate::isDate($reductionTo) ? $reductionTo : '0000-00-00 00:00:00'; - - if (!$validateOnly && !$specificPrice->save()) { - $this->addEntityWarning( - $this->translator->trans('Discount is invalid', [], 'Admin.Advparameters.Notification'), - $this->tools->sanitize($productName), - $product->id - ); - } - } - } - - /** - * Save product tags data. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - * @param string $productName product name, used for error messages - */ - private function saveProductTags(Product $product, ImportConfigInterface $importConfig, $productName) - { - if (empty($product->tags)) { - return; - } - - $multipleValueSeparator = $importConfig->getMultipleValueSeparator(); - - if (isset($product->id) && $product->id) { - $tags = Tag::getProductTags($product->id); - if (is_array($tags) && count($tags)) { - if (!empty($product->tags)) { - $product->tags = explode($multipleValueSeparator, $product->tags); - } - if (is_array($product->tags) && count($product->tags)) { - foreach ($product->tags as $key => $tag) { - if (!empty($tag)) { - $product->tags[$key] = trim($tag); - } - } - $tags[$this->languageId] = $product->tags; - $product->tags = $tags; - } - } - } - // Delete tags for this id product, for no duplicating error - Tag::deleteTagsForProduct($product->id); - - if (!is_array($product->tags) && !empty($product->tags)) { - $product->tags = $this->dataFormatter->createMultiLangField($product->tags); - foreach ($product->tags as $key => $tags) { - $isTagAdded = Tag::addTags($key, $product->id, $tags, $multipleValueSeparator); - if (!$isTagAdded) { - $this->addEntityWarning( - $this->tools->sanitize($productName), - $product->id, - $this->translator->trans('Tags list is invalid', [], 'Admin.Advparameters.Notification') - ); - break; - } - } - } else { - foreach ($product->tags as $key => $tags) { - $str = ''; - - foreach ($tags as $one_tag) { - $str .= $one_tag . $multipleValueSeparator; - } - - $str = rtrim($str, $multipleValueSeparator); - $isTagAdded = Tag::addTags($key, $product->id, $str, $multipleValueSeparator); - - if (!$isTagAdded) { - $this->addEntityWarning( - $this->tools->sanitize($productName), - (int) $product->id, - $this->translator->trans( - 'Invalid tag(s) (%s)', - [ - $str, - ], - 'Admin.Notifications.Error' - ) - ); - break; - } - } - } - } - - /** - * Save product images. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - */ - private function saveProductImages(Product $product, ImportConfigInterface $importConfig) - { - //delete existing images if "delete_existing_images" is set to 1 - if (isset($product->delete_existing_images)) { - if ((bool) $product->delete_existing_images) { - $product->deleteImages(); - } - } - - if (isset($product->image) && is_array($product->image) && count($product->image)) { - $unfriendlyError = $this->configuration->getBoolean('UNFRIENDLY_ERROR'); - $product_has_images = (bool) Image::getImages($this->languageId, (int) $product->id); - - foreach ($product->image as $key => $url) { - $url = trim($url); - $error = false; - if (!empty($url)) { - $url = str_replace(' ', '%20', $url); - - $image = new Image(); - $image->id_product = (int) $product->id; - $image->position = Image::getHighestPosition($product->id) + 1; - $image->cover = (!$key && !$product_has_images) ? true : false; - $alt = $product->image_alt[$key]; - if (strlen($alt) > 0) { - $image->legend = $this->dataFormatter->createMultiLangField($alt); - } - - $fieldsError = $image->validateFields($unfriendlyError, true); - $langFieldsError = $image->validateFieldsLang($unfriendlyError, true); - $isValid = true === $fieldsError && true === $langFieldsError; - - if ($isValid && $image->add()) { - // associate image to selected shops - $image->associateTo($product->id_shop_list); - $copySucceeded = $this->imageCopier->copyImg( - $product->id, - $image->id, - $url, - 'products', - !$importConfig->skipThumbnailRegeneration() - ); - - if (!$copySucceeded) { - $image->delete(); - $this->warning( - $this->translator->trans( - 'Error copying image: %url%', - [ - '%url%' => $url, - ], - 'Admin.Advparameters.Notification' - ) - ); - } - } else { - $error = true; - } - } else { - $error = true; - } - - if ($error) { - $this->warning( - $this->translator->trans( - 'Product #%id%: the picture (%url%) cannot be saved.', - [ - '%id%' => $image->id_product, - '%url%' => $url, - ], - 'Admin.Advparameters.Notification' - ) - ); - } - } - } - } - - /** - * Update additional product data. - * - * @param Product $product - * @param bool $validateOnly - */ - private function updateAdditionalData(Product $product, $validateOnly) - { - if (!$validateOnly && isset($product->id_category) && is_array($product->id_category)) { - $product->updateCategories(array_map('intval', $product->id_category)); - } - - $product->checkDefaultAttributes(); - if (!$validateOnly && !$product->cache_default_attribute) { - Product::updateDefaultAttribute($product->id); - } - } - - /** - * Save product features. - * - * @param Product $product - * @param ImportConfigInterface $importConfig - */ - private function saveFeatures(Product $product, ImportConfigInterface $importConfig) - { - // Features import - $features = get_object_vars($product); - $multipleValueSeparator = $importConfig->getMultipleValueSeparator(); - - if (empty($features['features'])) { - return; - } - - foreach (explode($multipleValueSeparator, $features['features']) as $singleFeature) { - if (empty($singleFeature)) { - continue; - } - $feature = explode(':', $singleFeature); - $featureName = isset($feature[0]) ? trim($feature[0]) : ''; - $featureValue = isset($feature[1]) ? trim($feature[1]) : ''; - $position = isset($feature[2]) ? (int) $feature[2] - 1 : false; - $custom = isset($feature[3]) ? (int) $feature[3] : false; - - if (!empty($featureName) && !empty($featureValue)) { - $featureId = (int) Feature::addFeatureImport($featureName, $position); - $productId = null; - if ($importConfig->forceIds() || $importConfig->matchReferences()) { - $productId = (int) $product->id; - } - $featureValueId = (int) FeatureValue::addFeatureValueImport( - $featureId, - $featureValue, - $productId, - $this->languageId, - $custom - ); - Product::addFeatureProductImport($product->id, $featureId, $featureValueId); - } - } - - // clean feature positions to avoid conflict - Feature::cleanPositions(); - } - - /** - * Save stock data for the product. - * - * @param Product $product - * @param bool $validateOnly - * @param bool $productExists - */ - private function saveStock(Product $product, $validateOnly, $productExists) - { - $asmEnabled = $this->configuration->getBoolean('PS_ADVANCED_STOCK_MANAGEMENT'); - - // set advanced stock managment - if (!$validateOnly && isset($product->advanced_stock_management)) { - if ($product->advanced_stock_management != 1 && $product->advanced_stock_management != 0) { - $this->warning( - $this->translator->trans( - 'Advanced stock management has incorrect value. Not set for product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } elseif (!$asmEnabled && $product->advanced_stock_management == 1) { - $this->warning( - $this->translator->trans( - 'Advanced stock management is not enabled, cannot enable on product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } elseif ($productExists) { - $product->setAdvancedStockManagement($product->advanced_stock_management); - } - // automaticly disable depends on stock, if a_s_m set to disabled - if (StockAvailable::dependsOnStock($product->id) == 1 && $product->advanced_stock_management == 0) { - StockAvailable::setProductDependsOnStock($product->id, 0); - } - } - - // Check if warehouse exists - if (isset($product->warehouse) && $product->warehouse) { - if (!$asmEnabled) { - $this->warning( - $this->translator->trans( - 'Advanced stock management is not enabled, warehouse not set on product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } elseif (!$validateOnly) { - if (Warehouse::exists($product->warehouse)) { - // Get already associated warehouses - $associatedWarehousesCollection = WarehouseProductLocation::getCollection($product->id); - // Delete any entry in warehouse for this product - foreach ($associatedWarehousesCollection as $awc) { - $awc->delete(); - } - $warehouseLocationEntity = new WarehouseProductLocation(); - $warehouseLocationEntity->id_product = $product->id; - $warehouseLocationEntity->id_product_attribute = 0; - $warehouseLocationEntity->id_warehouse = $product->warehouse; - $warehouseLocationEntity->save(); - StockAvailable::synchronize($product->id); - } else { - $this->warning( - $this->translator->trans( - 'Warehouse did not exist, cannot set on product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } - } - } - - if ($this->isMultistoreEnabled) { - $shopIds = $product->id_shop_list; - } else { - $shopIds = [ - $this->currentContextShopId, - ]; - } - - // stock available - if (isset($product->depends_on_stock)) { - if ($product->depends_on_stock != 0 && $product->depends_on_stock != 1) { - $this->warning( - $this->translator->trans( - 'Incorrect value for "Depends on stock" for product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } elseif ((!$product->advanced_stock_management || $product->advanced_stock_management == 0) && $product->depends_on_stock == 1) { - $this->warning( - $this->translator->trans( - 'Advanced stock management is not enabled, cannot set "Depends on stock" for product %name%', - ['%name%' => $product->name[$this->languageId]], - 'Admin.Advparameters.Notification' - ) - ); - } elseif (!$validateOnly) { - StockAvailable::setProductDependsOnStock($product->id, $product->depends_on_stock); - } - - // This code allows us to set qty and disable depends on stock - if (!$validateOnly && isset($product->quantity)) { - // if depends on stock and quantity, add quantity to stock - if ($product->depends_on_stock == 1) { - $stockManager = StockManagerFactory::getManager(); - $price = str_replace(',', '.', $product->wholesale_price); - if ($price == 0) { - $price = 0.000001; - } - $price = round(floatval($price), 6); - $warehouse = new Warehouse($product->warehouse); - $productAdded = $stockManager->addProduct( - (int) $product->id, - 0, - $warehouse, - (int) $product->quantity, - 1, - $price, - true - ); - - if ($productAdded) { - StockAvailable::synchronize((int) $product->id); - } - } else { - foreach ($shopIds as $shop) { - StockAvailable::setQuantity((int) $product->id, 0, (int) $product->quantity, (int) $shop); - } - } - } - } elseif (!$validateOnly) { - // if not depends_on_stock set, use normal qty - foreach ($shopIds as $shop) { - StockAvailable::setQuantity((int) $product->id, 0, (int) $product->quantity, (int) $shop); - } - } - } - - /** - * Link product accessories. - * - * @param Product $product - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - private function linkAccessories(Product $product, ImportRuntimeConfigInterface $runtimeConfig) - { - // Accessories linkage - if ($runtimeConfig->shouldValidateData()) { - return; - } - - $hasAccessories = - isset($product->accessories) && - is_array($product->accessories) && - count($product->accessories) - ; - - if ($hasAccessories) { - $sharedData = $runtimeConfig->getSharedData(); - $accessories = isset($sharedData['accessories']) ? $sharedData['accessories'] : []; - $accessories[$product->id] = $product->accessories; - $runtimeConfig->addSharedDataItem('accessories', $accessories); - } - } - - /** - * Import accessories. - * - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - private function importAccessories(ImportRuntimeConfigInterface $runtimeConfig) - { - $sharedData = $runtimeConfig->getSharedData(); - - if (!isset($sharedData['accessories'])) { - return; - } - - foreach ($sharedData['accessories'] as $productId => $links) { - if (count($links) > 0) { // We delete and relink only if there is accessories to link... - // Bulk jobs: for performances, we need to do a minimum amount of SQL queries. No product inflation. - $uniqueIds = Product::getExistingIdsFromIdsOrRefs($links); - $this->connection->delete( - $this->accessoryTable, - [ - 'id_product_1' => (int) $productId, - ] - ); - Product::changeAccessoriesForProduct($uniqueIds, $productId); - } - } - } - - /** - * {@inheritdoc} - */ - public function supports($importEntityType) - { - return $importEntityType === Entity::TYPE_PRODUCTS; - } -} diff --git a/src/Adapter/Import/ImageCopier.php b/src/Adapter/Import/ImageCopier.php deleted file mode 100644 index c0c0c719..00000000 --- a/src/Adapter/Import/ImageCopier.php +++ /dev/null @@ -1,250 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import; - -use Image; -use ImageManager; -use ImageType; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; - -/** - * Class ImageCopier copies images during import process. - */ -final class ImageCopier -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var Tools - */ - private $tools; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @param ConfigurationInterface $configuration - * @param Tools $tools - * @param int $contextShopId - * @param HookDispatcherInterface $hookDispatcher - */ - public function __construct( - ConfigurationInterface $configuration, - Tools $tools, - $contextShopId, - HookDispatcherInterface $hookDispatcher - ) { - $this->configuration = $configuration; - $this->tools = $tools; - $this->contextShopId = $contextShopId; - $this->hookDispatcher = $hookDispatcher; - } - - /** - * Copy an image located in $url and save it in a path. - * - * @param int $entityId id of product or category (set in entity) - * @param int $imageId id of the image if watermark enabled - * @param string $url path or url to use - * @param string $entity 'products' or 'categories' - * @param bool $regenerate - * - * @return bool - */ - public function copyImg($entityId, $imageId = null, $url = '', $entity = 'products', $regenerate = true) - { - $tmpDir = $this->configuration->get('_PS_TMP_IMG_DIR_'); - $tmpFile = tempnam($tmpDir, 'ps_import'); - $watermarkTypes = explode(',', $this->configuration->get('WATERMARK_TYPES')); - - switch ($entity) { - default: - case 'products': - $image_obj = new Image($imageId); - $path = $image_obj->getPathForCreation(); - break; - case 'categories': - $path = $this->configuration->get('_PS_CAT_IMG_DIR_') . (int) $entityId; - break; - case 'manufacturers': - $path = $this->configuration->get('_PS_MANU_IMG_DIR_') . (int) $entityId; - break; - case 'suppliers': - $path = $this->configuration->get('_PS_SUPP_IMG_DIR_') . (int) $entityId; - break; - case 'stores': - $path = $this->configuration->get('_PS_STORE_IMG_DIR_') . (int) $entityId; - break; - } - - $url = urldecode(trim($url)); - $parsedUrl = parse_url($url); - - if (isset($parsedUrl['path'])) { - $uri = ltrim($parsedUrl['path'], '/'); - $parts = explode('/', $uri); - foreach ($parts as &$part) { - $part = rawurlencode($part); - } - unset($part); - $parsedUrl['path'] = '/' . implode('/', $parts); - } - - if (isset($parsedUrl['query'])) { - $query_parts = []; - parse_str($parsedUrl['query'], $query_parts); - $parsedUrl['query'] = http_build_query($query_parts); - } - - if (!function_exists('http_build_url')) { - require_once $this->configuration->get('_PS_TOOL_DIR_') . 'http_build_url/http_build_url.php'; - } - - $url = http_build_url('', $parsedUrl); - - $origTmpfile = $tmpFile; - - if ($this->tools->copy($url, $tmpFile)) { - // Evaluate the memory required to resize the image: if it's too much, you can't resize it. - if (!ImageManager::checkImageMemoryLimit($tmpFile)) { - @unlink($tmpFile); - - return false; - } - - $targetWidth = $targetHeight = 0; - $sourceWidth = $sourceHeight = 0; - $error = 0; - ImageManager::resize( - $tmpFile, - $path . '.jpg', - null, - null, - 'jpg', - false, - $error, - $targetWidth, - $targetHeight, - 5, - $sourceWidth, - $sourceHeight - ); - $imagesTypes = ImageType::getImagesTypes($entity, true); - - if ($regenerate) { - $previous_path = null; - $pathInfos = []; - $pathInfos[] = [$targetWidth, $targetHeight, $path . '.jpg']; - foreach ($imagesTypes as $imageType) { - $tmpFile = $this->getBestPath($imageType['width'], $imageType['height'], $pathInfos); - - if (ImageManager::resize( - $tmpFile, - $path . '-' . stripslashes($imageType['name']) . '.jpg', - $imageType['width'], - $imageType['height'], - 'jpg', - false, - $error, - $targetWidth, - $targetHeight, - 5, - $sourceWidth, - $sourceHeight - )) { - // the last image should not be added in the candidate list if it's bigger than the original image - if ($targetWidth <= $sourceWidth && $targetHeight <= $sourceHeight) { - $pathInfos[] = [$targetWidth, $targetHeight, $path . '-' . stripslashes($imageType['name']) . '.jpg']; - } - if ($entity == 'products') { - $file = $tmpDir . 'product_mini_' . (int) $entityId . '.jpg'; - if (is_file($file)) { - unlink($file); - } - - $file = $tmpDir . 'product_mini_' . (int) $entityId . '_' . (int) $this->contextShopId . '.jpg'; - if (is_file($file)) { - unlink($file); - } - } - } - if (in_array($imageType['id_image_type'], $watermarkTypes)) { - $this->hookDispatcher->dispatchWithParameters( - 'actionWatermark', - [ - 'id_image' => $imageId, - 'id_product' => $entityId, - ] - ); - } - } - } - } else { - @unlink($origTmpfile); - - return false; - } - unlink($origTmpfile); - - return true; - } - - /** - * Find the best path, compared to given dimensions. - * - * @param int $targetWidth - * @param int $targetHeight - * @param array $pathInfos - * - * @return string - */ - private function getBestPath($targetWidth, $targetHeight, $pathInfos) - { - $pathInfos = array_reverse($pathInfos); - $path = ''; - foreach ($pathInfos as $pathInfo) { - list($width, $height, $path) = $pathInfo; - if ($width >= $targetWidth && $height >= $targetHeight) { - return $path; - } - } - - return $path; - } -} diff --git a/src/Adapter/Import/ImportDataFormatter.php b/src/Adapter/Import/ImportDataFormatter.php deleted file mode 100644 index 7c608323..00000000 --- a/src/Adapter/Import/ImportDataFormatter.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import; - -use Language; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class ImportDataFormatter is an adapter with data formatting methods for import. - */ -final class ImportDataFormatter -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var Tools - */ - private $tools; - - public function __construct( - ConfigurationInterface $configuration, - Tools $tools - ) { - $this->configuration = $configuration; - $this->tools = $tools; - } - - /** - * @param $value - * - * @return bool - */ - public function getBoolean($value) - { - return (bool) $value; - } - - /** - * @param string $field - * - * @return float - */ - public function getPrice($field) - { - $field = (float) str_replace(',', '.', $field); - $field = (float) str_replace('%', '', $field); - - return $field; - } - - /** - * Create a multilang field. - * - * @param string $field - * - * @return array - */ - public function createMultiLangField($field) - { - $result = []; - - foreach (Language::getIDs(false) as $languageId) { - $result[$languageId] = $field; - } - - return $result; - } - - /** - * Split the field by separator. - * - * @param string $field - * @param string $separator - * - * @return array - */ - public function split($field, $separator) - { - if (empty($field)) { - return []; - } - - if (is_null($separator) || trim($separator) == '') { - $separator = ','; - } - - $uniqidPath = false; - - // try data:// protocol. If failed, old school file on filesystem. - if (false === ($fd = @fopen('data://text/plain;base64,' . base64_encode($field), 'rb'))) { - do { - $uniqidPath = $this->configuration->get('_PS_UPLOAD_DIR_') . uniqid(); - } while (file_exists($uniqidPath)); - file_put_contents($uniqidPath, $field); - $fd = fopen($uniqidPath, 'r'); - } - - if ($fd === false) { - return []; - } - - $content = fgetcsv($fd, 0, $separator); - fclose($fd); - - if ($uniqidPath !== false && file_exists($uniqidPath)) { - @unlink($uniqidPath); - } - - if (empty($content) || !is_array($content)) { - return []; - } - - return $content; - } - - /** - * Transform given value into a friendly url string. - * - * @param string $value - * - * @return string - */ - public function createFriendlyUrl($value) - { - return $this->tools->linkRewrite($value); - } -} diff --git a/src/Adapter/Import/ImportEntityDeleter.php b/src/Adapter/Import/ImportEntityDeleter.php deleted file mode 100644 index 7456806b..00000000 --- a/src/Adapter/Import/ImportEntityDeleter.php +++ /dev/null @@ -1,311 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Import; - -use Doctrine\DBAL\Connection; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Image\Deleter\ImageFileDeleterInterface; -use PrestaShop\PrestaShop\Core\Import\Entity; -use PrestaShop\PrestaShop\Core\Import\Entity\ImportEntityDeleterInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportEntityException; - -/** - * Class ImportEntityDeleter is responsible for deleting import entities. - */ -final class ImportEntityDeleter implements ImportEntityDeleterInterface -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string database prefix - */ - private $dbPrefix; - - /** - * @var Configuration - */ - private $configuration; - - /** - * @var ImageFileDeleterInterface - */ - private $imageFileDeleter; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param Configuration $configuration - * @param ImageFileDeleterInterface $imageFileDeleter - */ - public function __construct( - Connection $connection, - $dbPrefix, - Configuration $configuration, - ImageFileDeleterInterface $imageFileDeleter - ) { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - $this->configuration = $configuration; - $this->imageFileDeleter = $imageFileDeleter; - } - - /** - * {@inheritdoc} - */ - public function deleteAll($importEntity) - { - switch ($importEntity) { - case Entity::TYPE_CATEGORIES: - $this->deleteCategories(); - - break; - - case Entity::TYPE_PRODUCTS: - $this->deleteProducts(); - - break; - - case Entity::TYPE_COMBINATIONS: - $this->deleteCombinations(); - - break; - - case Entity::TYPE_CUSTOMERS: - $this->truncateTables([ - 'customer', - ]); - - break; - - case Entity::TYPE_ADDRESSES: - $this->truncateTables([ - 'address', - ]); - - break; - - case Entity::TYPE_MANUFACTURERS: - $this->deleteManufacturers(); - - break; - - case Entity::TYPE_SUPPLIERS: - $this->deleteSuppliers(); - - break; - - case Entity::TYPE_ALIAS: - $this->truncateTables([ - 'alias', - ]); - - break; - - default: - throw new NotSupportedImportEntityException("Import entity \"{$importEntity}\" is not supported"); - } - - $this->imageFileDeleter->deleteAllImages($this->configuration->get('_PS_TMP_IMG_DIR_')); - } - - /** - * Delete all suppliers data and images. - */ - private function deleteSuppliers() - { - $this->truncateTables([ - 'supplier', - 'supplier_lang', - 'supplier_shop', - ]); - - $this->imageFileDeleter->deleteFromPath($this->configuration->get('_PS_SUPP_IMG_DIR_')); - } - - /** - * Delete all manufacturers images and data. - */ - private function deleteManufacturers() - { - $this->truncateTables([ - 'manufacturer', - 'manufacturer_lang', - 'manufacturer_shop', - ]); - - $this->imageFileDeleter->deleteFromPath($this->configuration->get('_PS_MANU_IMG_DIR_')); - } - - /** - * Delete all categories images and data, except Root and Home. - */ - private function deleteCategories() - { - $protectedCategoriesIds = [ - $this->configuration->getInt('PS_HOME_CATEGORY'), - $this->configuration->getInt('PS_ROOT_CATEGORY'), - ]; - - $this->connection->executeQuery( - "DELETE FROM {$this->dbPrefix}category WHERE id_category NOT IN (?)", - [$protectedCategoriesIds], - [Connection::PARAM_INT_ARRAY] - ); - - $this->connection->executeQuery( - "DELETE FROM {$this->dbPrefix}category_lang WHERE id_category NOT IN (?)", - [$protectedCategoriesIds], - [Connection::PARAM_INT_ARRAY] - ); - - $this->connection->executeQuery( - "DELETE FROM {$this->dbPrefix}category_shop WHERE id_category NOT IN (?)", - [$protectedCategoriesIds], - [Connection::PARAM_INT_ARRAY] - ); - - $this->connection->executeQuery("ALTER TABLE {$this->dbPrefix}category AUTO_INCREMENT = 3"); - - $this->imageFileDeleter->deleteFromPath($this->configuration->get('_PS_CAT_IMG_DIR_')); - } - - /** - * Delete all products images and data. - */ - private function deleteProducts() - { - $truncateTables = [ - 'product', - 'product_shop', - 'feature_product', - 'product_lang', - 'category_product', - 'product_tag', - 'image', - 'image_lang', - 'image_shop', - 'specific_price', - 'specific_price_priority', - 'product_carrier', - 'cart_product', - 'product_attachment', - 'product_country_tax', - 'product_download', - 'product_group_reduction_cache', - 'product_sale', - 'product_supplier', - 'warehouse_product_location', - 'stock', - 'stock_available', - 'stock_mvt', - 'customization', - 'customization_field', - 'supply_order_detail', - 'attribute_impact', - 'product_attribute', - 'product_attribute_shop', - 'product_attribute_combination', - 'product_attribute_image', - 'pack', - ]; - - $this->truncateTables($truncateTables); - - $truncateIfExists = [ - 'favorite_product', - ]; - - $this->truncateTablesIfExist($truncateIfExists); - - $imgDir = $this->configuration->get('_PS_PROD_IMG_DIR_'); - $this->imageFileDeleter->deleteFromPath($imgDir, true, true); - } - - /** - * Delete all combinations data. - */ - private function deleteCombinations() - { - $truncateTables = [ - 'attribute', - 'attribute_impact', - 'attribute_lang', - 'attribute_group', - 'attribute_group_lang', - 'attribute_group_shop', - 'attribute_shop', - 'product_attribute', - 'product_attribute_shop', - 'product_attribute_combination', - 'product_attribute_image', - ]; - - $this->truncateTables($truncateTables); - $this->connection->executeQuery( - "DELETE FROM `{$this->dbPrefix}stock_available` WHERE id_product_attribute != 0" - ); - } - - /** - * Truncate multiple tables. - * - * @param array $tables - * - * @throws \Doctrine\DBAL\DBALException - */ - private function truncateTables(array $tables) - { - foreach ($tables as $table) { - $this->connection->executeQuery("TRUNCATE TABLE `{$this->dbPrefix}{$table}`"); - } - } - - /** - * Truncate tables if they exist. Truncates them one by one. - * - * @param array $tables - * - * @throws \Doctrine\DBAL\DBALException - */ - private function truncateTablesIfExist(array $tables) - { - foreach ($tables as $table) { - $tableExists = $this->connection->getSchemaManager()->tablesExist( - [ - "{$this->dbPrefix}{$table}", - ] - ); - - if ($tableExists) { - $this->connection->executeQuery("TRUNCATE TABLE `{$this->dbPrefix}{$table}`"); - } - } - } -} diff --git a/src/Adapter/Invoice/InvoiceOptionsConfiguration.php b/src/Adapter/Invoice/InvoiceOptionsConfiguration.php deleted file mode 100644 index b398553f..00000000 --- a/src/Adapter/Invoice/InvoiceOptionsConfiguration.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Invoice; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class InvoiceOptionsConfiguration is responsible for saving & loading invoice configuration. - */ -final class InvoiceOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_invoices' => $this->configuration->getBoolean('PS_INVOICE'), - 'enable_tax_breakdown' => $this->configuration->getBoolean('PS_INVOICE_TAXES_BREAKDOWN'), - 'enable_product_images' => $this->configuration->getBoolean('PS_PDF_IMG_INVOICE'), - 'invoice_prefix' => $this->configuration->get('PS_INVOICE_PREFIX'), - 'add_current_year' => $this->configuration->getBoolean('PS_INVOICE_USE_YEAR'), - 'reset_number_annually' => $this->configuration->getBoolean('PS_INVOICE_RESET'), - 'year_position' => $this->configuration->getInt('PS_INVOICE_YEAR_POS'), - 'invoice_number' => $this->configuration->getInt('PS_INVOICE_START_NUMBER'), - 'legal_free_text' => $this->configuration->get('PS_INVOICE_LEGAL_FREE_TEXT'), - 'footer_text' => $this->configuration->get('PS_INVOICE_FREE_TEXT'), - 'invoice_model' => $this->configuration->get('PS_INVOICE_MODEL'), - 'use_disk_cache' => $this->configuration->getBoolean('PS_PDF_USE_CACHE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_INVOICE', $configuration['enable_invoices']); - $this->configuration->set('PS_INVOICE_TAXES_BREAKDOWN', $configuration['enable_tax_breakdown']); - $this->configuration->set('PS_PDF_IMG_INVOICE', $configuration['enable_product_images']); - $this->configuration->set('PS_INVOICE_PREFIX', $configuration['invoice_prefix']); - $this->configuration->set('PS_INVOICE_USE_YEAR', $configuration['add_current_year']); - $this->configuration->set('PS_INVOICE_RESET', $configuration['reset_number_annually']); - $this->configuration->set('PS_INVOICE_YEAR_POS', $configuration['year_position']); - $this->configuration->set('PS_INVOICE_START_NUMBER', $configuration['invoice_number']); - $this->configuration->set('PS_INVOICE_LEGAL_FREE_TEXT', $configuration['legal_free_text']); - $this->configuration->set('PS_INVOICE_FREE_TEXT', $configuration['footer_text']); - $this->configuration->set('PS_INVOICE_MODEL', $configuration['invoice_model']); - $this->configuration->set('PS_PDF_USE_CACHE', $configuration['use_disk_cache']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_invoices'], - $configuration['enable_tax_breakdown'], - $configuration['enable_product_images'], - $configuration['invoice_prefix'], - $configuration['add_current_year'], - $configuration['reset_number_annually'], - $configuration['year_position'], - $configuration['invoice_number'], - $configuration['legal_free_text'], - $configuration['footer_text'], - $configuration['invoice_model'], - $configuration['use_disk_cache'] - ); - } -} diff --git a/src/Adapter/Invoice/InvoiceTemplateTypeProvider.php b/src/Adapter/Invoice/InvoiceTemplateTypeProvider.php deleted file mode 100644 index f1ae13ed..00000000 --- a/src/Adapter/Invoice/InvoiceTemplateTypeProvider.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Invoice; - -use PrestaShop\PrestaShop\Adapter\Entity\PDF; -use PrestaShop\PrestaShop\Core\PDF\PDFTemplateTypeProviderInterface; - -/** - * Class InvoiceTemplateTypeProvider provides invoice PDF template type. - */ -final class InvoiceTemplateTypeProvider implements PDFTemplateTypeProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getPDFTemplateType() - { - return PDF::TEMPLATE_INVOICE; - } -} diff --git a/src/Adapter/Invoice/OrderInvoiceDataProvider.php b/src/Adapter/Invoice/OrderInvoiceDataProvider.php deleted file mode 100644 index 5083ec5c..00000000 --- a/src/Adapter/Invoice/OrderInvoiceDataProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Invoice; - -use DateTimeInterface; -use PrestaShop\PrestaShop\Adapter\Entity\Order; -use PrestaShop\PrestaShop\Adapter\Entity\OrderInvoice; -use PrestaShop\PrestaShop\Core\Order\OrderInvoiceDataProviderInterface; - -/** - * Class OrderInvoiceDataProvider provides OrderInvoice data using legacy code. - */ -final class OrderInvoiceDataProvider implements OrderInvoiceDataProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getByDateInterval(DateTimeInterface $dateFrom, DateTimeInterface $dateTo) - { - return OrderInvoice::getByDateInterval( - $dateFrom->format('Y-m-d'), - $dateTo->format('Y-m-d') - ); - } - - /** - * {@inheritdoc} - */ - public function getByStatus($orderStateId) - { - return OrderInvoice::getByStatus($orderStateId); - } - - /** - * {@inheritdoc} - */ - public function getNextInvoiceNumber() - { - return Order::getLastInvoiceNumber() + 1; - } -} diff --git a/src/Adapter/Kpi/AbandonedCartKpi.php b/src/Adapter/Kpi/AbandonedCartKpi.php deleted file mode 100644 index a7c66001..00000000 --- a/src/Adapter/Kpi/AbandonedCartKpi.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use ConfigurationKPI; -use Context; -use HelperKpi; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * @internal - */ -final class AbandonedCartKpi implements KpiInterface -{ - /** - * {@inheritdoc} - */ - public function render() - { - $translator = Context::getContext()->getTranslator(); - - $helper = new HelperKpi(); - $helper->id = 'box-carts'; - $helper->icon = 'remove_shopping_cart'; - $helper->color = 'color1'; - $helper->title = $translator->trans('Abandoned Carts', [], 'Admin.Global'); - $helper->subtitle = $translator->trans('Today', [], 'Admin.Global'); - $helper->href = Context::getContext()->link->getAdminLink('AdminCarts') . '&action=filterOnlyAbandonedCarts'; - - if (ConfigurationKPI::get('ABANDONED_CARTS') !== false) { - $helper->value = ConfigurationKPI::get('ABANDONED_CARTS'); - } - - $helper->source = Context::getContext()->link->getAdminLink('AdminStats') - . '&ajax=1&action=getKpi&kpi=abandoned_cart'; - $helper->refresh = (bool) (ConfigurationKPI::get('ABANDONED_CARTS_EXPIRE') < time()); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/AverageCustomerAgeKpi.php b/src/Adapter/Kpi/AverageCustomerAgeKpi.php deleted file mode 100644 index 70e6941c..00000000 --- a/src/Adapter/Kpi/AverageCustomerAgeKpi.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Renders average age of all customers. - */ -final class AverageCustomerAgeKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-age'; - $helper->icon = 'calendar_today'; - $helper->color = 'color2'; - - $helper->title = $this->translator->trans('Average Age', [], 'Admin.Orderscustomers.Feature'); - $helper->subtitle = $this->translator->trans('All Time', [], 'Admin.Global'); - - if (false !== $this->kpiConfiguration->get('AVG_CUSTOMER_AGE')) { - $helper->value = $this->kpiConfiguration->get('AVG_CUSTOMER_AGE'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('AVG_CUSTOMER_AGE_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/AverageOrderValueKpi.php b/src/Adapter/Kpi/AverageOrderValueKpi.php deleted file mode 100644 index 30b244e5..00000000 --- a/src/Adapter/Kpi/AverageOrderValueKpi.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use ConfigurationKPI; -use Context; -use HelperKpi; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * @internal - */ -final class AverageOrderValueKpi implements KpiInterface -{ - /** - * {@inheritdoc} - */ - public function render() - { - $translator = Context::getContext()->getTranslator(); - - $helper = new HelperKpi(); - $helper->id = 'box-average-order'; - $helper->icon = 'account_balance_wallet'; - $helper->color = 'color1'; - $helper->title = $translator->trans('Average Order Value', [], 'Admin.Global'); - $helper->subtitle = $translator->trans('30 days', [], 'Admin.Global'); - - if (ConfigurationKPI::get('AVG_ORDER_VALUE') !== false) { - $helper->value = $translator->trans( - '%amount% tax excl.', - ['%amount%' => ConfigurationKPI::get('AVG_ORDER_VALUE')], - 'Admin.Orderscustomers.Feature' - ); - } - - $helper->source = Context::getContext()->link->getAdminLink('AdminStats') - . '&ajax=1&action=getKpi&kpi=average_order_value'; - $helper->refresh = (bool) (ConfigurationKPI::get('AVG_ORDER_VALUE_EXPIRE') < time()); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/AverageProductsInCategoryKpi.php b/src/Adapter/Kpi/AverageProductsInCategoryKpi.php deleted file mode 100644 index ea21310d..00000000 --- a/src/Adapter/Kpi/AverageProductsInCategoryKpi.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class AverageProductsInCategoryKpi. - * - * @internal - */ -final class AverageProductsInCategoryKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $kpiConfiguration - * @param string $sourceUrl - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-products-per-category'; - $helper->icon = 'search'; - $helper->color = 'color4'; - $helper->title = - $this->translator->trans('Average number of products per category', [], 'Admin.Catalog.Feature'); - - if (false !== $this->kpiConfiguration->get('PRODUCTS_PER_CATEGORY')) { - $helper->value = $this->kpiConfiguration->get('PRODUCTS_PER_CATEGORY'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('PRODUCTS_PER_CATEGORY_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/ConversionRateKpi.php b/src/Adapter/Kpi/ConversionRateKpi.php deleted file mode 100644 index 0ae68eaa..00000000 --- a/src/Adapter/Kpi/ConversionRateKpi.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use ConfigurationKPI; -use Context; -use HelperKpi; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * @internal - */ -final class ConversionRateKpi implements KpiInterface -{ - /** - * {@inheritdoc} - */ - public function render() - { - $translator = Context::getContext()->getTranslator(); - - $helper = new HelperKpi(); - $helper->id = 'box-conversion-rate'; - $helper->icon = 'assessment'; - $helper->color = 'color1'; - $helper->title = $translator->trans('Conversion Rate', [], 'Admin.Global'); - $helper->subtitle = $translator->trans('30 days', [], 'Admin.Global'); - - if (ConfigurationKPI::get('CONVERSION_RATE') !== false) { - $helper->value = ConfigurationKPI::get('CONVERSION_RATE'); - } - - if (ConfigurationKPI::get('CONVERSION_RATE_CHART') !== false) { - $helper->data = ConfigurationKPI::get('CONVERSION_RATE_CHART'); - } - - $helper->source = Context::getContext()->link->getAdminLink('AdminStats') - . '&ajax=1&action=getKpi&kpi=conversion_rate'; - $helper->refresh = (bool) (ConfigurationKPI::get('CONVERSION_RATE_EXPIRE') < time()); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/DisabledCategoriesKpi.php b/src/Adapter/Kpi/DisabledCategoriesKpi.php deleted file mode 100644 index 14a672f5..00000000 --- a/src/Adapter/Kpi/DisabledCategoriesKpi.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class DisabledCategoriesKpi. - * - * @internal - */ -final class DisabledCategoriesKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $kpiConfiguration - * @param string $sourceUrl - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-disabled-categories'; - $helper->icon = 'toggle_off'; - $helper->color = 'color1'; - $helper->title = $this->translator->trans('Disabled Categories', [], 'Admin.Catalog.Feature'); - - if (false !== $this->kpiConfiguration->get('DISABLED_CATEGORIES')) { - $helper->value = $this->kpiConfiguration->get('DISABLED_CATEGORIES'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('DISABLED_CATEGORIES_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/EmptyCategoriesKpi.php b/src/Adapter/Kpi/EmptyCategoriesKpi.php deleted file mode 100644 index a491253c..00000000 --- a/src/Adapter/Kpi/EmptyCategoriesKpi.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class EmptyCategoriesKpi. - * - * @internal - */ -final class EmptyCategoriesKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @var string - */ - private $hrefUrl; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - * @param string $sourceUrl - * @param string $hrefUrl - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $configuration, - $sourceUrl, - $hrefUrl - ) { - $this->translator = $translator; - $this->configuration = $configuration; - $this->sourceUrl = $sourceUrl; - $this->hrefUrl = $hrefUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-empty-categories'; - $helper->icon = 'bookmark'; - $helper->color = 'color2'; - $helper->href = $this->hrefUrl; - $helper->title = $this->translator->trans('Empty Categories', [], 'Admin.Catalog.Feature'); - - if (false !== $this->configuration->get('EMPTY_CATEGORIES')) { - $helper->value = $this->configuration->get('EMPTY_CATEGORIES'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->configuration->get('EMPTY_CATEGORIES_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/EnabledLanguagesKpi.php b/src/Adapter/Kpi/EnabledLanguagesKpi.php deleted file mode 100644 index 9f128c85..00000000 --- a/src/Adapter/Kpi/EnabledLanguagesKpi.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class EnabledLanguagesKpi is an implementation for enabled languages KPI. - */ -final class EnabledLanguagesKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var string - */ - private $clickLink; - - /** - * @var string - */ - private $sourceLink; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - * @param string $clickLink a link for clicking on the KPI - * @param string $sourceLink a link to refresh KPI - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $configuration, - $clickLink, - $sourceLink - ) { - $this->translator = $translator; - $this->configuration = $configuration; - $this->clickLink = $clickLink; - $this->sourceLink = $sourceLink; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $enabledLanguages = $this->configuration->get('ENABLED_LANGUAGES'); - - $kpi = new HelperKpi(); - $kpi->context->smarty->setTemplateDir(_PS_BO_ALL_THEMES_DIR_ . 'new-theme/template/'); - $kpi->id = 'box-languages'; - $kpi->icon = 'mic'; - $kpi->color = 'color1'; - $kpi->href = $this->clickLink; - $kpi->title = $this->translator->trans('Enabled Languages', [], 'Admin.International.Feature'); - - if (false !== $enabledLanguages) { - $kpi->value = $enabledLanguages; - } - - $kpi->source = $this->sourceLink; - $kpi->refresh = $this->configuration->get('ENABLED_LANGUAGES_EXPIRE') < time(); - - return $kpi->generate(); - } -} diff --git a/src/Adapter/Kpi/MainCountryKpi.php b/src/Adapter/Kpi/MainCountryKpi.php deleted file mode 100644 index 603b0503..00000000 --- a/src/Adapter/Kpi/MainCountryKpi.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class MainCountryKpi is an implementation for main countries KPI. - */ -final class MainCountryKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var string - */ - private $sourceLink; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - * @param string $sourceLink a link to refresh KPI - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $configuration, - $sourceLink - ) { - $this->translator = $translator; - $this->configuration = $configuration; - $this->sourceLink = $sourceLink; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $mainCountry = $this->configuration->get('MAIN_COUNTRY'); - - $kpi = new HelperKpi(); - $kpi->context->smarty->setTemplateDir(_PS_BO_ALL_THEMES_DIR_ . 'new-theme/template/'); - $kpi->id = 'box-country'; - $kpi->icon = 'home'; - $kpi->color = 'color2'; - $kpi->title = $this->translator->trans('Main Country', [], 'Admin.International.Feature'); - $kpi->subtitle = $this->translator->trans('30 Days', [], 'Admin.Global'); - - if (false !== $mainCountry) { - $kpi->value = $mainCountry; - } - - $kpi->source = $this->sourceLink; - $kpi->refresh = $this->configuration->get('MAIN_COUNTRY_EXPIRE') < time(); - - return $kpi->generate(); - } -} diff --git a/src/Adapter/Kpi/MostCommonCustomersGenderKpi.php b/src/Adapter/Kpi/MostCommonCustomersGenderKpi.php deleted file mode 100644 index de6e95b5..00000000 --- a/src/Adapter/Kpi/MostCommonCustomersGenderKpi.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Renders percent of most common customers gender. - */ -final class MostCommonCustomersGenderKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $kpiConfiguration - * @param string $sourceUrl - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-gender'; - $helper->icon = 'person'; - $helper->color = 'color1'; - $helper->title = $this->translator->trans('Customers', [], 'Admin.Global'); - $helper->subtitle = $this->translator->trans('All Time', [], 'Admin.Global'); - - if (false !== $this->kpiConfiguration->get('CUSTOMER_MAIN_GENDER')) { - $helper->value = $this->kpiConfiguration->get('CUSTOMER_MAIN_GENDER'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('CUSTOMER_MAIN_GENDER_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/NetProfitPerVisitKpi.php b/src/Adapter/Kpi/NetProfitPerVisitKpi.php deleted file mode 100644 index 301eef75..00000000 --- a/src/Adapter/Kpi/NetProfitPerVisitKpi.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use ConfigurationKPI; -use Context; -use HelperKpi; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * @internal - */ -final class NetProfitPerVisitKpi implements KpiInterface -{ - /** - * {@inheritdoc} - */ - public function render() - { - $translator = Context::getContext()->getTranslator(); - - $helper = new HelperKpi(); - $helper->id = 'box-net-profit-visit'; - $helper->icon = 'account_box'; - $helper->color = 'color1'; - $helper->title = $translator->trans('Net Profit per Visit', [], 'Admin.Orderscustomers.Feature'); - $helper->subtitle = $translator->trans('30 days', [], 'Admin.Orderscustomers.Feature'); - - if (ConfigurationKPI::get('NETPROFIT_VISIT') !== false) { - $helper->value = ConfigurationKPI::get('NETPROFIT_VISIT'); - } - - $helper->source = Context::getContext()->link->getAdminLink('AdminStats') - . '&ajax=1&action=getKpi&kpi=netprofit_visit'; - $helper->refresh = (bool) (ConfigurationKPI::get('NETPROFIT_VISIT_EXPIRE') < time()); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/NewsletterRegistrationsKpi.php b/src/Adapter/Kpi/NewsletterRegistrationsKpi.php deleted file mode 100644 index 576bf8eb..00000000 --- a/src/Adapter/Kpi/NewsletterRegistrationsKpi.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Renders number of how many customers have registered for newsletter. - */ -final class NewsletterRegistrationsKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $kpiConfiguration - * @param string $sourceUrl - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-newsletter'; - $helper->icon = 'mail_outline'; - $helper->color = 'color3'; - - $helper->title = $this->translator->trans('Newsletter Registrations', [], 'Admin.Orderscustomers.Feature'); - $helper->subtitle = $this->translator->trans('All Time', [], 'Admin.Global'); - - if (false !== $this->kpiConfiguration->get('NEWSLETTER_REGISTRATIONS')) { - $helper->value = $this->kpiConfiguration->get('NEWSLETTER_REGISTRATIONS'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('NEWSLETTER_REGISTRATIONS_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/OrdersPerCustomerKpi.php b/src/Adapter/Kpi/OrdersPerCustomerKpi.php deleted file mode 100644 index 78abd99c..00000000 --- a/src/Adapter/Kpi/OrdersPerCustomerKpi.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Renders amount of orders per customer. - */ -final class OrdersPerCustomerKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-orders'; - $helper->icon = 'shopping_basket'; - $helper->color = 'color4'; - - $helper->title = $this->translator->trans('Orders per Customer', [], 'Admin.Orderscustomers.Feature'); - $helper->subtitle = $this->translator->trans('All Time', [], 'Admin.Global'); - - if (false !== $this->kpiConfiguration->get('ORDERS_PER_CUSTOMER')) { - $helper->value = $this->kpiConfiguration->get('ORDERS_PER_CUSTOMER'); - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $this->kpiConfiguration->get('ORDERS_PER_CUSTOMER_EXPIRE') < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/ShoppingCartTotalKpi.php b/src/Adapter/Kpi/ShoppingCartTotalKpi.php deleted file mode 100644 index 82ca1d60..00000000 --- a/src/Adapter/Kpi/ShoppingCartTotalKpi.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use Cart; -use Context; -use Currency; -use Group; -use HelperKpi; -use Order; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use Validate; - -/** - * {@inheritdoc} - */ -final class ShoppingCartTotalKpi implements KpiInterface -{ - /** - * @var Locale - */ - private $locale; - - /** - * @var array - */ - private $options; - - /** - * @param Locale $locale - */ - public function __construct(Locale $locale) - { - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $translator = Context::getContext()->getTranslator(); - $cart = new Cart($this->options['cart_id']); - - $helper = new HelperKpi(); - $helper->id = 'box-kpi-cart'; - $helper->icon = 'shopping_cart'; - $helper->color = 'color1'; - $helper->title = $translator->trans('Total Cart', [], 'Admin.Orderscustomers.Feature'); - $helper->subtitle = $translator->trans('Cart #%ID%', ['%ID%' => $cart->id], 'Admin.Orderscustomers.Feature'); - $helper->value = $this->locale->formatPrice( - $this->getCartTotalPrice($cart), - Currency::getIsoCodeById((int) $cart->id_currency) - ); - - return $helper->generate(); - } - - /** - * Sets options for Kpi - * - * @param array $options - */ - public function setOptions(array $options) - { - $this->options = $options; - } - - /** - * @param Cart $cart - * - * @return float - */ - private function getCartTotalPrice(Cart $cart) - { - $summary = $cart->getSummaryDetails(); - - $id_order = (int) Order::getIdByCartId($cart->id); - $order = new Order($id_order); - - if (Validate::isLoadedObject($order)) { - $taxCalculationMethod = $order->getTaxCalculationMethod(); - } else { - $taxCalculationMethod = Group::getPriceDisplayMethod(Group::getCurrent()->id); - } - - $totalPrice = $taxCalculationMethod == PS_TAX_EXC ? - $summary['total_price_without_tax'] : - $summary['total_price']; - - return $totalPrice; - } -} diff --git a/src/Adapter/Kpi/TopCategoryKpi.php b/src/Adapter/Kpi/TopCategoryKpi.php deleted file mode 100644 index 6218b460..00000000 --- a/src/Adapter/Kpi/TopCategoryKpi.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class TopCategoryKpi. - * - * @internal - */ -final class TopCategoryKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $kpiConfiguration; - - /** - * @var string - */ - private $sourceUrl; - - /** - * @var int - */ - private $employeeIdLang; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $kpiConfiguration - * @param string $sourceUrl - * @param int $employeeIdLang - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $kpiConfiguration, - $sourceUrl, - $employeeIdLang - ) { - $this->translator = $translator; - $this->kpiConfiguration = $kpiConfiguration; - $this->sourceUrl = $sourceUrl; - $this->employeeIdLang = $employeeIdLang; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $helper = new HelperKpi(); - $helper->id = 'box-top-category'; - $helper->icon = 'money'; - $helper->color = 'color3'; - $helper->title = $this->translator->trans('Top Category', [], 'Admin.Catalog.Feature'); - $helper->subtitle = $this->translator->trans('30 days', [], 'Admin.Global'); - - $topCategory = $this->kpiConfiguration->get('TOP_CATEGORY'); - - if (isset($topCategory[$this->employeeIdLang])) { - $helper->value = $topCategory[$this->employeeIdLang]; - } - - $topCategoryExpire = $this->kpiConfiguration->get('TOP_CATEGORY_EXPIRE'); - if (isset($topCategoryExpire[$this->employeeIdLang])) { - $topCategoryExpire = $topCategoryExpire[$this->employeeIdLang]; - } else { - $topCategoryExpire = false; - } - - $helper->source = $this->sourceUrl; - $helper->refresh = $topCategoryExpire < time(); - - return $helper->generate(); - } -} diff --git a/src/Adapter/Kpi/TranslationsKpi.php b/src/Adapter/Kpi/TranslationsKpi.php deleted file mode 100644 index 8eb63bb1..00000000 --- a/src/Adapter/Kpi/TranslationsKpi.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Kpi; - -use HelperKpi; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class TranslationsKpi is an implementation for translations KPI. - */ -final class TranslationsKpi implements KpiInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var string - */ - private $sourceLink; - - /** - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - * @param string $sourceLink a link to refresh KPI - */ - public function __construct( - TranslatorInterface $translator, - ConfigurationInterface $configuration, - $sourceLink - ) { - $this->translator = $translator; - $this->configuration = $configuration; - $this->sourceLink = $sourceLink; - } - - /** - * {@inheritdoc} - */ - public function render() - { - $frontOfficeTranslations = $this->configuration->get('FRONTOFFICE_TRANSLATIONS'); - - $kpi = new HelperKpi(); - $kpi->context->smarty->setTemplateDir(_PS_BO_ALL_THEMES_DIR_ . 'new-theme/template/'); - $kpi->id = 'box-translations'; - $kpi->icon = 'list'; - $kpi->color = 'color3'; - $kpi->title = $this->translator->trans('Front office Translations', [], 'Admin.International.Feature'); - - if (false !== $frontOfficeTranslations) { - $kpi->value = $frontOfficeTranslations; - } - - $kpi->source = $this->sourceLink; - $kpi->refresh = $this->configuration->get('FRONTOFFICE_TRANSLATIONS_EXPIRE') < time(); - - return $kpi->generate(); - } -} diff --git a/src/Adapter/Language/CommandHandler/AbstractLanguageHandler.php b/src/Adapter/Language/CommandHandler/AbstractLanguageHandler.php deleted file mode 100644 index b5c8b7bb..00000000 --- a/src/Adapter/Language/CommandHandler/AbstractLanguageHandler.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Context; -use ImageManager; -use ImageType; -use Language; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\CopyingNoPictureException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageImageUploadingException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Encapsulates common legacy behavior for adding/editing language - */ -abstract class AbstractLanguageHandler extends AbstractObjectModelHandler -{ - /** - * Copies "No picture" image for specific language - * - * @param IsoCode $isoCode - * @param string $noPictureImagePath - */ - protected function copyNoPictureImage(IsoCode $isoCode, $noPictureImagePath) - { - if (!($temporaryImage = tempnam(_PS_TMP_IMG_DIR_, 'PS')) - || !move_uploaded_file($noPictureImagePath, $temporaryImage) - ) { - return; - } - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'p/' . $isoCode->getValue() . '.jpg')) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to product directory'), CopyingNoPictureException::PRODUCT_IMAGE_COPY_ERROR); - } - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'c/' . $isoCode->getValue() . '.jpg')) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to category directory'), CopyingNoPictureException::CATEGORY_IMAGE_COPY_ERROR); - } - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'm/' . $isoCode->getValue() . '.jpg')) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to brand directory'), CopyingNoPictureException::BRAND_IMAGE_COPY_ERROR); - } - - $imagesTypes = ImageType::getImagesTypes('products'); - - foreach ($imagesTypes as $imagesType) { - $imageName = $isoCode->getValue() . '-default-' . stripslashes($imagesType['name']) . '.jpg'; - $imageWidth = $imagesType['width']; - $imageHeight = $imagesType['height']; - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'p/' . $imageName, $imageWidth, $imageHeight)) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to product directory'), CopyingNoPictureException::PRODUCT_IMAGE_COPY_ERROR); - } - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'c/' . $imageName, $imageWidth, $imageHeight)) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to category directory'), CopyingNoPictureException::CATEGORY_IMAGE_COPY_ERROR); - } - - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . 'm/' . $imageName, $imageWidth, $imageHeight)) { - throw new CopyingNoPictureException(sprintf('An error occurred while copying "No Picture" image to brand directory'), CopyingNoPictureException::BRAND_IMAGE_COPY_ERROR); - } - } - - unlink($temporaryImage); - } - - /** - * @param int $languageId - * @param string $newImagePath - * @param string $imageDir - */ - protected function uploadImage($languageId, $newImagePath, $imageDir) - { - $temporaryImage = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - if (!$temporaryImage) { - return; - } - - if (!move_uploaded_file($newImagePath, $temporaryImage)) { - return; - } - - // Evaluate the memory required to resize the image: if it's too much, you can't resize it. - if (!ImageManager::checkImageMemoryLimit($temporaryImage)) { - throw new LanguageImageUploadingException('Due to memory limit restrictions, this image cannot be loaded. Increase your memory_limit value.', LanguageImageUploadingException::MEMORY_LIMIT_RESTRICTION); - } - - // Copy new image - if (!ImageManager::resize($temporaryImage, _PS_IMG_DIR_ . $imageDir . $languageId . '.jpg')) { - throw new LanguageImageUploadingException('An error occurred while uploading the image. Check your directory permissions.', LanguageImageUploadingException::UNEXPECTED_ERROR); - } - - if (file_exists(_PS_LANG_IMG_DIR_ . $languageId . '.jpg')) { - $shopId = Context::getContext()->shop->id; - $currentFile = _PS_TMP_IMG_DIR_ . 'lang_mini_' . $languageId . '_' . $shopId . '.jpg'; - - if (file_exists($currentFile)) { - unlink($currentFile); - } - } - - unlink($temporaryImage); - } - - /** - * @param LanguageId $languageId - * - * @return Language - */ - protected function getLegacyLanguageObject(LanguageId $languageId) - { - $language = new Language($languageId->getValue()); - - if ($languageId->getValue() !== $language->id) { - throw new LanguageNotFoundException($languageId, sprintf('Language with id "%s" was not found', $languageId->getValue())); - } - - return $language; - } -} diff --git a/src/Adapter/Language/CommandHandler/AddLanguageHandler.php b/src/Adapter/Language/CommandHandler/AddLanguageHandler.php deleted file mode 100644 index c31febdb..00000000 --- a/src/Adapter/Language/CommandHandler/AddLanguageHandler.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\AddLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\AddLanguageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Handles command which adds new language using legacy object model - * - * @internal - */ -final class AddLanguageHandler extends AbstractLanguageHandler implements AddLanguageHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddLanguageCommand $command) - { - $this->assertLanguageWithIsoCodeDoesNotExist($command->getIsoCode()); - - $this->copyNoPictureImage( - $command->getIsoCode(), - $command->getNoPictureImagePath() - ); - - $language = $this->createLegacyLanguageObjectFromCommand($command); - - $this->uploadFlagImage($language, $command); - $this->addShopAssociation($language, $command); - - return new LanguageId((int) $language->id); - } - - /** - * @param IsoCode $isoCode - * - * @throws LanguageConstraintException - */ - private function assertLanguageWithIsoCodeDoesNotExist(IsoCode $isoCode) - { - if (Language::getIdByIso($isoCode->getValue())) { - throw new LanguageConstraintException(sprintf('Language with ISO code "%s" already exists', $isoCode->getValue()), LanguageConstraintException::DUPLICATE_ISO_CODE); - } - } - - /** - * Add language and shop association - * - * @param Language $language - * @param AddLanguageCommand $command - */ - private function addShopAssociation(Language $language, AddLanguageCommand $command) - { - $this->associateWithShops( - $language, - $command->getShopAssociation() - ); - } - - /** - * @param AddLanguageCommand $command - * - * @return Language - */ - private function createLegacyLanguageObjectFromCommand(AddLanguageCommand $command) - { - $language = new Language(); - $language->name = $command->getName(); - $language->iso_code = $command->getIsoCode()->getValue(); - if (false !== ($languageDetails = Language::getLangDetails($command->getIsoCode()->getValue()))) { - $language->locale = $languageDetails['locale']; - } - $language->language_code = $command->getTagIETF()->getValue(); - $language->date_format_lite = $command->getShortDateFormat(); - $language->date_format_full = $command->getFullDateFormat(); - $language->is_rtl = $command->isRtl(); - $language->active = $command->isActive(); - - if (false === $language->validateFields(false)) { - throw new LanguageException('Cannot add language with invalid data'); - } - - if (false === $language->add()) { - throw new LanguageException(sprintf('Failed to add new language "%s"', $command->getName())); - } - - return $language; - } - - /** - * @param Language $language - * @param AddLanguageCommand $command - */ - private function uploadFlagImage(Language $language, AddLanguageCommand $command) - { - $this->uploadImage( - $language->id, - $command->getFlagImagePath(), - 'l' . DIRECTORY_SEPARATOR - ); - } -} diff --git a/src/Adapter/Language/CommandHandler/BulkDeleteLanguagesHandler.php b/src/Adapter/Language/CommandHandler/BulkDeleteLanguagesHandler.php deleted file mode 100644 index 61db163e..00000000 --- a/src/Adapter/Language/CommandHandler/BulkDeleteLanguagesHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Configuration; -use Context; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkDeleteLanguagesCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\BulkDeleteLanguagesHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use Shop; - -/** - * Deletes languages using legacy Language object model - * - * @internal - */ -final class BulkDeleteLanguagesHandler extends AbstractLanguageHandler implements BulkDeleteLanguagesHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteLanguagesCommand $command) - { - // language can only be modified in "ALL SHOPS" context - Shop::setContext(Shop::CONTEXT_ALL); - - foreach ($command->getLanguageIds() as $languageId) { - $language = $this->getLegacyLanguageObject($languageId); - - $this->assertLanguageIsNotDefault($language); - $this->assertLanguageIsNotInUse($language); - - if (false === $language->delete()) { - throw new LanguageException(sprintf('Failed to delele language "%s"', $language->iso_code)); - } - } - } - - /** - * @param Language $language - */ - private function assertLanguageIsNotDefault(Language $language) - { - if ($language->id === (int) Configuration::get('PS_LANG_DEFAULT')) { - throw new DefaultLanguageException(sprintf('Default language "%s" cannot be deleted', $language->iso_code), DefaultLanguageException::CANNOT_DELETE_ERROR); - } - } - - /** - * @param Language $language - */ - private function assertLanguageIsNotInUse(Language $language) - { - if ($language->id === (int) Context::getContext()->language->id) { - throw new DefaultLanguageException(sprintf('Used language "%s" cannot be deleted', $language->iso_code), DefaultLanguageException::CANNOT_DELETE_IN_USE_ERROR); - } - } -} diff --git a/src/Adapter/Language/CommandHandler/BulkToggleLanguagesStatusHandler.php b/src/Adapter/Language/CommandHandler/BulkToggleLanguagesStatusHandler.php deleted file mode 100644 index 5bd86efe..00000000 --- a/src/Adapter/Language/CommandHandler/BulkToggleLanguagesStatusHandler.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Configuration; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkToggleLanguagesStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\BulkToggleLanguagesStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; - -/** - * Toggles multiple languages status using legacy Language object model - * - * @internal - */ -final class BulkToggleLanguagesStatusHandler extends AbstractLanguageHandler implements BulkToggleLanguagesStatusHandlerInterface -{ - /** - * @param BulkToggleLanguagesStatusCommand $command - */ - public function handle(BulkToggleLanguagesStatusCommand $command) - { - foreach ($command->getLanguageIds() as $languageId) { - $language = $this->getLegacyLanguageObject($languageId); - - $this->assertLanguageIsNotDefault($language, $command); - - $language->active = $command->getStatus(); - - if (false === $language->update()) { - throw new LanguageException(sprintf('Failed to toggle language "%s" to status %s', $language->id, var_export($command->getStatus(), true))); - } - } - } - - /** - * @param Language $language - * @param BulkToggleLanguagesStatusCommand $command - */ - private function assertLanguageIsNotDefault(Language $language, BulkToggleLanguagesStatusCommand $command) - { - if (true === $command->getStatus()) { - return; - } - - if ($language->id === (int) Configuration::get('PS_LANG_DEFAULT')) { - throw new DefaultLanguageException(sprintf('Default language "%s" cannot be disabled', $language->iso_code), DefaultLanguageException::CANNOT_DISABLE_ERROR); - } - } -} diff --git a/src/Adapter/Language/CommandHandler/DeleteLanguageHandler.php b/src/Adapter/Language/CommandHandler/DeleteLanguageHandler.php deleted file mode 100644 index d66f6336..00000000 --- a/src/Adapter/Language/CommandHandler/DeleteLanguageHandler.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Configuration; -use Context; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\DeleteLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\DeleteLanguageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use Shop; - -/** - * Deletes language using legacy object model - * - * @internal - */ -final class DeleteLanguageHandler extends AbstractLanguageHandler implements DeleteLanguageHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteLanguageCommand $command) - { - $language = $this->getLegacyLanguageObject($command->getLanguageId()); - - $this->assertLanguageIsNotDefault($language); - $this->assertLanguageIsNotInUse($language); - - // language must be deleted in "ALL SHOPS" context - Shop::setContext(Shop::CONTEXT_ALL); - - if (false === $language->delete()) { - throw new LanguageException(sprintf('Failed to delele language "%s"', $language->iso_code)); - } - } - - /** - * @param Language $language - */ - private function assertLanguageIsNotDefault(Language $language) - { - if ($language->id === (int) Configuration::get('PS_LANG_DEFAULT')) { - throw new DefaultLanguageException(sprintf('Default language "%s" cannot be deleted', $language->iso_code), DefaultLanguageException::CANNOT_DELETE_ERROR); - } - } - - /** - * @param Language $language - */ - private function assertLanguageIsNotInUse(Language $language) - { - if ($language->id === (int) Context::getContext()->language->id) { - throw new DefaultLanguageException(sprintf('Used language "%s" cannot be deleted', $language->iso_code), DefaultLanguageException::CANNOT_DELETE_IN_USE_ERROR); - } - } -} diff --git a/src/Adapter/Language/CommandHandler/EditLanguageHandler.php b/src/Adapter/Language/CommandHandler/EditLanguageHandler.php deleted file mode 100644 index 22dd5946..00000000 --- a/src/Adapter/Language/CommandHandler/EditLanguageHandler.php +++ /dev/null @@ -1,239 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Configuration; -use Db; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\EditLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\EditLanguageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\CannotDisableDefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; - -/** - * Handles command which edits language using legacy object model - * - * @internal - */ -final class EditLanguageHandler extends AbstractLanguageHandler implements EditLanguageHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditLanguageCommand $command) - { - $language = $this->getLegacyLanguageObject($command->getLanguageId()); - - $this->assertLanguageWithIsoCodeDoesNotExist($language, $command); - $this->assertDefaultLanguageIsNotDisabled($command); - - $this->copyNoPictureIfChanged($language, $command); - $this->updateEmployeeLanguage($command); - $this->moveTranslationsIfIsoChanged($language, $command); - - $this->updateLanguageWithCommandData($language, $command); - $this->updateShopAssociationIfChanged($language, $command); - $this->uploadFlagImageIfChanged($language, $command); - } - - /** - * Update legacy language only with data that is set - * - * @param Language $language - * @param EditLanguageCommand $command - */ - private function updateLanguageWithCommandData(Language $language, EditLanguageCommand $command) - { - if (null !== $command->getName()) { - $language->name = $command->getName(); - } - - if (null !== $command->getIsoCode()) { - $language->iso_code = $command->getIsoCode()->getValue(); - if (false !== ($languageDetails = Language::getLangDetails($command->getIsoCode()->getValue()))) { - $language->locale = $languageDetails['locale']; - } - } - - if (null !== $command->getTagIETF()) { - $language->language_code = $command->getTagIETF()->getValue(); - } - - if (null !== $command->getShortDateFormat()) { - $language->date_format_lite = $command->getShortDateFormat(); - } - - if (null !== $command->getFullDateFormat()) { - $language->date_format_full = $command->getFullDateFormat(); - } - - if (null !== $command->isRtl()) { - $language->is_rtl = $command->isRtl(); - } - - if (null !== $command->isActive()) { - $language->active = $command->isActive(); - } - - if (false === $language->validateFields(false)) { - throw new LanguageException('Cannot add language with invalid data'); - } - - if (false === $language->update()) { - throw new LanguageException(sprintf('Cannot update language with id "%s"', $language->id)); - } - } - - /** - * Only copy new "No picture" if it's being updated - * - * @param Language $language - * @param EditLanguageCommand $command - */ - private function copyNoPictureIfChanged(Language $language, EditLanguageCommand $command) - { - if (null === $command->getNoPictureImagePath()) { - return; - } - - $isoCode = $command->getIsoCode(); - - if (!$isoCode instanceof IsoCode) { - $isoCode = new IsoCode($language->iso_code); - } - - $this->copyNoPictureImage( - $isoCode, - $command->getNoPictureImagePath() - ); - } - - /** - * Default language cannot be disabled - * - * @param EditLanguageCommand $command - */ - private function assertDefaultLanguageIsNotDisabled(EditLanguageCommand $command) - { - if (false === $command->isActive() - && $command->getLanguageId()->getValue() === (int) Configuration::get('PS_LANG_DEFAULT') - ) { - throw new CannotDisableDefaultLanguageException(sprintf('Language with id "%s" is default language and thus it cannot be disabled', $command->getLanguageId()->getValue())); - } - } - - /** - * If language that is being updated is disabled - * and there are employees that use this language - * then their language has to be updated to default - * - * @param EditLanguageCommand $command - */ - private function updateEmployeeLanguage(EditLanguageCommand $command) - { - if (false === $command->isActive()) { - Db::getInstance()->execute( - 'UPDATE `' . _DB_PREFIX_ . 'employee` - SET `id_lang`=' . (int) Configuration::get('PS_LANG_DEFAULT') . ' - WHERE `id_lang`=' . (int) $command->getLanguageId()->getValue() - ); - } - } - - /** - * Move translation files if language's ISO code has changed - * - * @param Language $language - * @param EditLanguageCommand $command - */ - private function moveTranslationsIfIsoChanged(Language $language, EditLanguageCommand $command) - { - if (null !== $command->getIsoCode() - && $language->iso_code !== $command->getIsoCode()->getValue() - ) { - $language->moveToIso($command->getLanguageId()->getValue()); - } - } - - /** - * @param Language $language - * @param EditLanguageCommand $command - */ - private function updateShopAssociationIfChanged(Language $language, EditLanguageCommand $command) - { - if (null === $command->getShopAssociation()) { - return; - } - - $this->associateWithShops( - $language, - $command->getShopAssociation() - ); - } - - /** - * Update language's flag image if it has changed - * - * @param Language $language - * @param EditLanguageCommand $command - */ - private function uploadFlagImageIfChanged(Language $language, EditLanguageCommand $command) - { - if (null === $command->getFlagImagePath()) { - return; - } - - $language->deleteImage(); - - $this->uploadImage( - $command->getLanguageId()->getValue(), - $command->getFlagImagePath(), - 'l' . DIRECTORY_SEPARATOR - ); - } - - /** - * Assert that language with updated ISO code does not exist - * - * @param Language $language - * @param EditLanguageCommand $command - */ - private function assertLanguageWithIsoCodeDoesNotExist(Language $language, EditLanguageCommand $command) - { - if (null !== $command->getIsoCode()) { - return; - } - - if ($language->iso_code === $command->getIsoCode()->getValue() - && Language::getIdByIso($command->getIsoCode()->getValue()) - ) { - throw new LanguageConstraintException(sprintf('Language with ISO code "%s" already exists', $command->getIsoCode()->getValue()), LanguageConstraintException::INVALID_ISO_CODE); - } - } -} diff --git a/src/Adapter/Language/CommandHandler/ToggleLanguageStatusHandler.php b/src/Adapter/Language/CommandHandler/ToggleLanguageStatusHandler.php deleted file mode 100644 index 0aaa4252..00000000 --- a/src/Adapter/Language/CommandHandler/ToggleLanguageStatusHandler.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\CommandHandler; - -use Configuration; -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\ToggleLanguageStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler\ToggleLanguageStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; - -/** - * Enables/disables language using legacy Language object model - * - * @internal - */ -final class ToggleLanguageStatusHandler extends AbstractLanguageHandler implements ToggleLanguageStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(ToggleLanguageStatusCommand $command) - { - $language = $this->getLegacyLanguageObject($command->getLanguageId()); - - $this->assertLanguageIsNotDefault($language, $command); - - $language->active = $command->getStatus(); - - if (false === $language->update()) { - throw new LanguageException(sprintf('Failed to toggle language "%s" to status %s', $language->id, var_export($command->getStatus(), true))); - } - } - - /** - * @param Language $language - * @param ToggleLanguageStatusCommand $command - */ - private function assertLanguageIsNotDefault(Language $language, ToggleLanguageStatusCommand $command) - { - if (true === $command->getStatus()) { - return; - } - - if ($language->id === (int) Configuration::get('PS_LANG_DEFAULT')) { - throw new DefaultLanguageException(sprintf('Default language "%s" cannot be disabled', $language->iso_code), DefaultLanguageException::CANNOT_DISABLE_ERROR); - } - } -} diff --git a/src/Adapter/Language/LanguageActivator.php b/src/Adapter/Language/LanguageActivator.php deleted file mode 100644 index 0947318d..00000000 --- a/src/Adapter/Language/LanguageActivator.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use Language; -use PrestaShop\PrestaShop\Core\Language\LanguageActivatorInterface; - -/** - * Class LanguageActivator is responsible for activating/deactivating language. - */ -final class LanguageActivator implements LanguageActivatorInterface -{ - /** - * {@inheritdoc} - */ - public function enable($langId) - { - $this->setActive($langId, true); - } - - /** - * {@inheritdoc} - */ - public function disable($langId) - { - $this->setActive($langId, false); - } - - /** - * Enable/disable language. - * - * @param int $langId - * @param bool $status - */ - private function setActive($langId, $status) - { - $lang = new Language((int) $langId); - - if ((int) $lang->active !== (int) $status) { - $lang->active = (int) $status; - $lang->save(); - } - } -} diff --git a/src/Adapter/Language/LanguageCopier.php b/src/Adapter/Language/LanguageCopier.php deleted file mode 100644 index a86af838..00000000 --- a/src/Adapter/Language/LanguageCopier.php +++ /dev/null @@ -1,265 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeCollection; -use PrestaShop\PrestaShop\Core\Language\Copier\LanguageCopierConfigInterface; -use PrestaShop\PrestaShop\Core\Language\Copier\LanguageCopierInterface; -use Symfony\Component\Filesystem\Exception\IOExceptionInterface; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class LanguageCopier responsible for copying a language into another language. - */ -final class LanguageCopier implements LanguageCopierInterface -{ - /** - * @var LanguageDataProvider - */ - private $languageDataProvider; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var ThemeCollection - */ - private $themeCollection; - - /** - * @param LanguageDataProvider $languageDataProvider - * @param TranslatorInterface $translator - * @param Filesystem $filesystem - * @param ThemeCollection $themeCollection - */ - public function __construct( - LanguageDataProvider $languageDataProvider, - TranslatorInterface $translator, - Filesystem $filesystem, - ThemeCollection $themeCollection - ) { - $this->languageDataProvider = $languageDataProvider; - $this->translator = $translator; - $this->filesystem = $filesystem; - $this->themeCollection = $themeCollection; - } - - /** - * {@inheritdoc} - */ - public function copy(LanguageCopierConfigInterface $config) - { - $errors = $this->validateConfig($config); - - if (!empty($errors)) { - return $errors; - } - - $languageFiles = $this->languageDataProvider->getFilesList( - $config->getLanguageFrom(), - $config->getThemeFrom(), - $config->getLanguageTo(), - $config->getThemeTo() - ); - - foreach ($languageFiles as $source => $destination) { - try { - $this->filesystem->mkdir(dirname($destination)); - } catch (IOExceptionInterface $exception) { - $errors[] = [ - 'key' => 'Cannot create the folder "%folder%". Please check your directory writing permissions.', - 'domain' => 'Admin.International.Notification', - 'parameters' => [ - '%folder%' => $destination, - ], - ]; - - continue; - } - - try { - $this->filesystem->copy($source, $destination); - } catch (IOExceptionInterface $exception) { - $errors[] = [ - 'key' => 'Impossible to copy "%source%" to "%dest%".', - 'domain' => 'Admin.International.Notification', - 'parameters' => [ - '%source%' => $source, - '%dest%' => $destination, - ], - ]; - - continue; - } - - if ($this->isModuleContext($source, $destination, $config->getLanguageFrom())) { - $changedModuleTranslationKeys = $this->changeModulesTranslationKeys( - $destination, - $config->getThemeFrom(), - $config->getThemeTo() - ); - - if (!$changedModuleTranslationKeys) { - $errors[] = [ - 'key' => 'Impossible to translate "%dest%".', - 'domain' => 'Admin.International.Notification', - 'parameters' => [ - '%dest%' => $destination, - ], - ]; - } - } - } - - if (!empty($errors)) { - $errors[] = [ - 'key' => 'A part of the data has been copied but some of the language files could not be found.', - 'domain' => 'Admin.International.Notification', - 'parameters' => [], - ]; - } - - return $errors; - } - - /** - * Validates given configuration. - * - * @param LanguageCopierConfigInterface $config - * - * @return array of errors - */ - private function validateConfig(LanguageCopierConfigInterface $config) - { - $errors = []; - - $languageFrom = $config->getLanguageFrom(); - $languageTo = $config->getLanguageTo(); - $themeFrom = $config->getThemeFrom(); - $themeTo = $config->getThemeTo(); - - if (empty($languageFrom) || empty($languageTo)) { - $errors[] = [ - 'key' => 'You must select two languages in order to copy data from one to another.', - 'domain' => 'Admin.International.Notification', - 'parameters' => [], - ]; - } elseif (empty($themeFrom) || empty($themeTo)) { - $errors[] = [ - 'key' => 'You must select two themes in order to copy data from one to another.', - 'domain' => 'Admin.International.Notification', - 'parameters' => [], - ]; - } elseif ( - $themeFrom === $themeTo && - $languageFrom === $languageTo - ) { - $errors[] = [ - 'key' => 'There is nothing to copy (same language and theme).', - 'domain' => 'Admin.International.Notification', - 'parameters' => [], - ]; - } else { - $fromThemeFound = false; - $toThemeFound = false; - - /** @var Theme $theme */ - foreach ($this->themeCollection as $theme) { - // Checking if "From" theme exists by name - if ($theme->getName() === $themeFrom) { - $fromThemeFound = true; - } - - // Checking if "To" theme exists by name - if ($theme->getName() === $themeTo) { - $toThemeFound = true; - } - } - - if (!$fromThemeFound || !$toThemeFound) { - $errors[] = [ - 'key' => 'Theme(s) not found', - 'domain' => 'Admin.International.Notification', - 'parameters' => [], - ]; - } - } - - return $errors; - } - - /** - * Checks if the source and destination paths are related to modules. - * - * @param string $source - * @param string $destination - * @param string $language - * - * @return bool - */ - private function isModuleContext($source, $destination, $language) - { - // Legacy condition - return false !== strpos($destination, 'modules') && basename($source) === $language . '.php'; - } - - /** - * A legacy method to change modules translation keys. - * - * @param string $path - * @param string $themeFrom - * @param string $themeTo - * - * @return bool result - */ - private function changeModulesTranslationKeys($path, $themeFrom, $themeTo) - { - $content = file_get_contents($path); - $arrayReplace = []; - $result = true; - - if (preg_match_all('#\$_MODULE\[\'([^\']+)\'\]#Ui', $content, $matches)) { - foreach ($matches[1] as $value) { - $arrayReplace[$value] = str_replace($themeFrom, $themeTo, $value); - } - - $content = str_replace(array_keys($arrayReplace), array_values($arrayReplace), $content); - $result = file_put_contents($path, $content) === false ? false : true; - } - - return $result; - } -} diff --git a/src/Adapter/Language/LanguageDataProvider.php b/src/Adapter/Language/LanguageDataProvider.php deleted file mode 100644 index e5a866a5..00000000 --- a/src/Adapter/Language/LanguageDataProvider.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use Exception; -use Language; - -/** - * Class LanguageDataProvider is responsible for providing language data from legacy part. - */ -class LanguageDataProvider -{ - /** - * Returns languages data. - * - * @param bool $active - * @param bool $shopId - * @param bool $onlyIds - * - * @return array - */ - public function getLanguages($active = true, $shopId = false, $onlyIds = false) - { - return Language::getLanguages($active, $shopId, $onlyIds); - } - - /** - * Returns language code by iso code. - * - * @param string $isoCode - ISO 3166-2 alpha-2 format code - * - * @return false|string|null - */ - public function getLanguageCodeByIso($isoCode) - { - return Language::getLanguageCodeByIso($isoCode); - } - - /** - * Gets language details from json file. - * - * @param string $locale - * - * @return array - * - * @throws Exception - */ - public function getLanguageDetails($locale) - { - $result = Language::getJsonLanguageDetails($locale); - - if (false === $result) { - return []; - } - - return $result; - } - - /** - * Gets the files list for given language, including files from modules. - * - * @param string $isoFrom - * @param string $themeFrom - * @param string $isoTo - * @param string $themeTo - * - * @return array - */ - public function getFilesList( - $isoFrom, - $themeFrom, - $isoTo, - $themeTo - ) { - return Language::getFilesList($isoFrom, $themeFrom, $isoTo, $themeTo, false, false, true); - } -} diff --git a/src/Adapter/Language/LanguageFlagThumbnailProvider.php b/src/Adapter/Language/LanguageFlagThumbnailProvider.php deleted file mode 100644 index 07730584..00000000 --- a/src/Adapter/Language/LanguageFlagThumbnailProvider.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use HelperList; -use ImageManager; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; - -/** - * Class LanguageThumbnailProvider provides path to language's flag thumbnail. - */ -final class LanguageFlagThumbnailProvider implements ImageProviderInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @var int - */ - private $contextShopId; - - /** - * @param ImageTagSourceParserInterface $imageTagSourceParser - * @param $contextShopId - */ - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser, - $contextShopId - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - $this->contextShopId = $contextShopId; - } - - /** - * {@inheritdoc} - */ - public function getPath($languageId) - { - $pathToImage = _PS_IMG_DIR_ . 'l' . DIRECTORY_SEPARATOR . $languageId . '.jpg'; - - $imageTag = ImageManager::thumbnail( - $pathToImage, - 'lang_mini_' . $languageId . '_' . $this->contextShopId . '.jpg', - HelperList::LIST_THUMBNAIL_SIZE, - 'jpg' - ); - - return $this->imageTagSourceParser->parse($imageTag); - } -} diff --git a/src/Adapter/Language/LanguageImageManager.php b/src/Adapter/Language/LanguageImageManager.php deleted file mode 100644 index a8cfb696..00000000 --- a/src/Adapter/Language/LanguageImageManager.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use ImageType; - -/** - * Handles language images (flag, "no image" placeholders) - */ -class LanguageImageManager -{ - /** - * Path where images are saved to - */ - const IMG_PATH = _PS_IMG_DIR_ . '/l/'; - - /** - * Path where flags are stored - */ - const FLAGS_SOURCE = _PS_IMG_DIR_ . 'flags/%s.jpg'; - - /** - * Path where flags are copied to - */ - const FLAGS_DESTINATION = self::IMG_PATH . '%d.jpg'; - - /** - * Default flag - */ - const FALLBACK_FLAG_SOURCE = self::IMG_PATH . 'none.jpg'; - - const IMAGE_DIRECTORIES = [ - _PS_CAT_IMG_DIR_, - _PS_MANU_IMG_DIR_, - _PS_PROD_IMG_DIR_, - _PS_SUPP_IMG_DIR_, - ]; - - const PLACEHOLDER_IMAGE_NAME_PATTERNS = [ - '%s.jpg', - '%s-default-%s.jpg', - ]; - - const DEFAULT_LANGUAGE_CODE = 'en'; - - /** - * Sets up the language flag image for the given language - * - * @param string $localeCode IETF language tag - * @param int $langId Language id - * @param string|null $flagCode If provided, use this flag code. By default, auto-detect using locale code. - */ - public function setupLanguageFlag(string $localeCode, int $langId, ?string $flagCode = null): void - { - $flagCode = $flagCode ?? $this->getFlagCountryCodeFromLocale($localeCode); - - $flagPath = $this->getFlagPath($flagCode); - - if (!file_exists($flagPath)) { - $flagPath = static::FALLBACK_FLAG_SOURCE; - } - - $destinationPath = $this->getFlagDestination($langId); - - $this->unlinkIfExists($destinationPath); - - copy($flagPath, $destinationPath); - } - - /** - * Creates default copies for the "no image" image - * - * @param string $isoCode 2-letter ISO code - */ - public function setupDefaultImagePlaceholder(string $isoCode): void - { - $filesToCopy = [ - $this->getPlaceholderImageFilename(static::DEFAULT_LANGUAGE_CODE) => $this->getPlaceholderImageFilename($isoCode), - ]; - - $imageTypes = ImageType::getAll(); - if (!empty($imageTypes)) { - foreach (array_keys($imageTypes) as $alias) { - $formattedImageType = ImageType::getFormattedName($alias); - $from = $this->getPlaceholderImageFilename(static::DEFAULT_LANGUAGE_CODE, $formattedImageType); - $to = $this->getPlaceholderImageFilename($isoCode, $formattedImageType); - $filesToCopy[$from] = $to; - } - } - - foreach (static::IMAGE_DIRECTORIES as $destinationDir) { - foreach ($filesToCopy as $sourceFile => $newFile) { - @copy(static::IMG_PATH . $sourceFile, $destinationDir . $newFile); - } - } - } - - /** - * Deletes images associated with the language - * - * @param int $langId - * @param string $isoCode 2-letter ISO code - */ - public function deleteImages(int $langId, string $isoCode): void - { - $images = [ - $this->getPlaceholderImageFilename($isoCode), - $this->getPlaceholderImageFilename($isoCode, ImageType::getFormattedName('thickbox')), - $this->getPlaceholderImageFilename($isoCode, ImageType::getFormattedName('home')), - $this->getPlaceholderImageFilename($isoCode, ImageType::getFormattedName('large')), - $this->getPlaceholderImageFilename($isoCode, ImageType::getFormattedName('medium')), - $this->getPlaceholderImageFilename($isoCode, ImageType::getFormattedName('small')), - ]; - foreach (static::IMAGE_DIRECTORIES as $directory) { - foreach ($images as $image) { - $this->unlinkIfExists($directory . $image); - $this->unlinkIfExists(static::IMG_PATH . $langId . '.jpg'); - } - } - } - - /** - * @param string $locale IETF language tag - * - * @return string - */ - private function getFlagCountryCodeFromLocale(string $locale): string - { - return strtolower(explode('-', $locale)[1]); - } - - /** - * @param string $countryCode - * - * @return string - */ - private function getFlagPath(string $countryCode): string - { - return sprintf(static::FLAGS_SOURCE, $countryCode); - } - - /** - * @param int $langId - * - * @return string - */ - private function getFlagDestination(int $langId): string - { - return sprintf(static::FLAGS_DESTINATION, $langId); - } - - /** - * Removes a file if it exists - * - * @param string $file - */ - private function unlinkIfExists(string $file): void - { - if (file_exists($file)) { - unlink($file); - } - } - - /** - * @param string $isoCode - * @param string|null $imageTypeName - * - * @return string - */ - private function getPlaceholderImageFilename(string $isoCode, string $imageTypeName = null): string - { - if (null !== $imageTypeName) { - return sprintf(static::PLACEHOLDER_IMAGE_NAME_PATTERNS[1], $isoCode, $imageTypeName); - } - - return sprintf(static::PLACEHOLDER_IMAGE_NAME_PATTERNS[0], $isoCode); - } -} diff --git a/src/Adapter/Language/LanguagePackInstaller.php b/src/Adapter/Language/LanguagePackInstaller.php deleted file mode 100644 index 16d65f76..00000000 --- a/src/Adapter/Language/LanguagePackInstaller.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use Language; -use PrestaShop\PrestaShop\Core\Foundation\Version; -use PrestaShop\PrestaShop\Core\Language\Pack\LanguagePackInstallerInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class LanguagePack is responsible for the language pack actions regarding installation. - */ -final class LanguagePackInstaller implements LanguagePackInstallerInterface -{ - /** - * @var Version - */ - private $version; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * LanguagePackInstaller constructor. - * - * @param TranslatorInterface $translator - * @param Version $version - */ - public function __construct(TranslatorInterface $translator, Version $version) - { - $this->version = $version; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function downloadAndInstallLanguagePack($iso) - { - $freshInstall = empty(Language::getIdByIso($iso)); - $result = Language::downloadAndInstallLanguagePack($iso, $this->version->getVersion(), null, $freshInstall); - - if (false === $result) { - return [ - $this->translator->trans( - 'Fatal error: ISO code is not correct', - [], - 'Admin.International.Notification' - ), - ]; - } - - if (is_array($result) && !empty($result)) { - return $result; - } - - return []; - } -} diff --git a/src/Adapter/Language/LanguageValidator.php b/src/Adapter/Language/LanguageValidator.php deleted file mode 100644 index e038404d..00000000 --- a/src/Adapter/Language/LanguageValidator.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language; - -use Language; -use PrestaShop\PrestaShop\Core\Language\LanguageValidatorInterface; - -/** - * Class LanguageValidator is responsible for supporting validations from legacy Language class part. - */ -final class LanguageValidator implements LanguageValidatorInterface -{ - /** - * {@inheritdoc} - */ - public function isInstalledByLocale($locale) - { - return Language::isInstalledByLocale($locale); - } -} diff --git a/src/Adapter/Language/Pack/LanguagePackImporter.php b/src/Adapter/Language/Pack/LanguagePackImporter.php deleted file mode 100644 index dcac8387..00000000 --- a/src/Adapter/Language/Pack/LanguagePackImporter.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\Pack; - -use PrestaShop\PrestaShop\Adapter\Language\LanguageDataProvider; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Language\Pack\Import\LanguagePackImporterInterface; -use PrestaShop\PrestaShop\Core\Language\Pack\LanguagePackInstallerInterface; - -/** - * Class LanguagePackImporter is responsible for importing language pack. - */ -final class LanguagePackImporter implements LanguagePackImporterInterface -{ - /** - * @var LanguagePackInstallerInterface - */ - private $languagePack; - - /** - * @var LanguageDataProvider - */ - private $languageProvider; - - /** - * @var CacheClearerInterface - */ - private $entireCacheClearer; - - /** - * @var string - */ - private $translationsDir; - - /** - * @param LanguagePackInstallerInterface $languagePack - * @param LanguageDataProvider $languageProvider - * @param CacheClearerInterface $entireCacheClearer - * @param string $translationsDir - */ - public function __construct( - LanguagePackInstallerInterface $languagePack, - LanguageDataProvider $languageProvider, - CacheClearerInterface $entireCacheClearer, - $translationsDir - ) { - $this->languagePack = $languagePack; - $this->languageProvider = $languageProvider; - $this->entireCacheClearer = $entireCacheClearer; - $this->translationsDir = $translationsDir; - } - - /** - * {@inheritdoc} - */ - public function import($isoCode) - { - $result = $this->languagePack->downloadAndInstallLanguagePack($isoCode); - - if (!empty($result)) { - return $result; - } - - $this->entireCacheClearer->clear(); - - return []; - } - - /** - * Gets language code in format of ISO 639-1. - * - * @param string $languageCode - language code to format - * - * @return string - */ - private function getFormattedLanguageCode($languageCode) - { - $explodedLangCode = explode('-', $languageCode); - - return sprintf( - '%s-%s', - isset($explodedLangCode[0]) ? $explodedLangCode[0] : '', - isset($explodedLangCode[1]) ? strtoupper($explodedLangCode[1]) : '' - ); - } -} diff --git a/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php b/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php deleted file mode 100644 index 4ced0853..00000000 --- a/src/Adapter/Language/QueryHandler/GetLanguageForEditingHandler.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\QueryHandler; - -use Language; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; -use PrestaShop\PrestaShop\Core\Domain\Language\QueryHandler\GetLanguageForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; - -/** - * Gets language for editing - * - * @internal - */ -final class GetLanguageForEditingHandler implements GetLanguageForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetLanguageForEditing $query) - { - $language = $this->getLegacyLanguageObject($query->getLanguageId()); - - return new EditableLanguage( - $query->getLanguageId(), - $language->name, - new IsoCode($language->iso_code), - new TagIETF($language->language_code), - $language->date_format_lite, - $language->date_format_full, - (bool) $language->is_rtl, - (bool) $language->active, - array_map(function ($shopId) { return (int) $shopId; }, $language->getAssociatedShops()) - ); - } - - /** - * @param LanguageId $languageId - * - * @return Language - */ - private function getLegacyLanguageObject(LanguageId $languageId) - { - $language = new Language($languageId->getValue()); - - if ($languageId->getValue() !== (int) $language->id) { - throw new LanguageNotFoundException($languageId, sprintf('Language with id "%s" was not found', $languageId->getValue())); - } - - return $language; - } -} diff --git a/src/Adapter/Language/RTL/InstalledLanguageChecker.php b/src/Adapter/Language/RTL/InstalledLanguageChecker.php deleted file mode 100644 index 64b166e2..00000000 --- a/src/Adapter/Language/RTL/InstalledLanguageChecker.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Language\RTL; - -use PrestaShop\PrestaShop\Adapter\Language\LanguageDataProvider; -use PrestaShop\PrestaShop\Core\Language\RTL\InstalledLanguageCheckerInterface; - -/** - * Class InstalledLanguageChecker - */ -final class InstalledLanguageChecker implements InstalledLanguageCheckerInterface -{ - /** - * @var LanguageDataProvider - */ - private $languageDataProvider; - - /** - * @param LanguageDataProvider $languageDataProvider - */ - public function __construct(LanguageDataProvider $languageDataProvider) - { - $this->languageDataProvider = $languageDataProvider; - } - - /** - * {@inheritdoc} - */ - public function isInstalledRtlLanguage() - { - $languages = $this->languageDataProvider->getLanguages(false); - - return in_array('1', array_column($languages, 'is_rtl')); - } -} diff --git a/src/Adapter/LegacyContext.php b/src/Adapter/LegacyContext.php deleted file mode 100644 index 82179dc5..00000000 --- a/src/Adapter/LegacyContext.php +++ /dev/null @@ -1,346 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use AdminController; -use AdminLegacyLayoutControllerCore; -use Context; -use Currency; -use Employee; -use Language; -use RuntimeException; -use Smarty; -use Symfony\Component\Process\Exception\LogicException; -use Tab; - -/** - * This adapter will complete the new architecture Context with legacy values. - * A merge is done, but the legacy values will be transferred to the new Context - * during legacy refactoring. - */ -class LegacyContext -{ - /** @var Currency */ - private $employeeCurrency; - - /** @var string Contains the base uri for mail themes (by default https://domain.com/mails/themes/). Used for mails assets. */ - private $mailThemesUri; - - /** @var Tools */ - private $tools; - - /** - * @param string|null $mailThemesUri - * @param Tools|null $tools - */ - public function __construct( - $mailThemesUri = null, - Tools $tools = null - ) { - $this->mailThemesUri = $mailThemesUri; - $this->tools = null !== $tools ? $tools : new Tools(); - } - - /** - * To be used only in Adapters. Should not been called by Core classes. Prefer to use Core\context class, - * that will contains all you need in the Core architecture. - * - * @throws LogicException If legacy context is not set properly - * - * @return Context the Legacy context, for Adapter use only - */ - public function getContext() - { - static $legacyContext = null; - - if (null === $legacyContext) { - $legacyContext = Context::getContext(); - - if ($legacyContext && !empty($legacyContext->shop) && !isset($legacyContext->controller) && isset($legacyContext->employee)) { - //init real legacy shop context - $adminController = new AdminController(); - $adminController->initShopContext(); - } - } - - return $legacyContext; - } - - /** - * Get smarty instance from legacy context. - * - * @return Smarty - */ - public function getSmarty() - { - return $this->getContext()->smarty; - } - - /** - * Gets the Admin base url (actually random directory name). - * - * @return string - */ - public function getAdminBaseUrl() - { - return __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) . '/'; - } - - /** - * Adapter to get Admin HTTP link. - * - * @param string $controller the controller name - * @param bool $withToken - * @param array[string] $extraParams - * - * @return string - */ - public function getAdminLink($controller, $withToken = true, $extraParams = []) - { - return $this->getContext()->link->getAdminLink($controller, $withToken, $extraParams, $extraParams); - } - - /** - * Returns the controller link in its legacy form, without trying to convert it in symfony url. - * - * @param string $controller - * @param bool $withToken - * @param array $extraParams - * - * @return string - */ - public function getLegacyAdminLink($controller, $withToken = true, $extraParams = []) - { - return $this->getContext()->link->getLegacyAdminLink($controller, $withToken, $extraParams); - } - - /** - * Adapter to get Front controller HTTP link. - * - * @param string $controller the controller name - * - * @return string - */ - public function getFrontUrl($controller) - { - $legacyContext = $this->getContext(); - - return $legacyContext->link->getPageLink($controller); - } - - /** - * Adapter to get Root Url. - * - * @return string The lagacy root URL - */ - public function getRootUrl() - { - return __PS_BASE_URI__; - } - - /** - * Adapter to get upload directory - * - * @return string - */ - public function getUploadDirectory() - { - return _PS_UPLOAD_DIR_; - } - - /** - * Url to the mail themes folder - * - * @return string - */ - public function getMailThemesUrl() - { - return $this->tools->getShopDomainSsl(true) . __PS_BASE_URI__ . $this->mailThemesUri; - } - - /** - * This fix is used to have a ready translation in the smarty 'l' function. - * Called by AutoResponseFormatTrait in beforeActionSuggestResponseFormat(). - * So if you do not use this Trait, you must call this method by yourself in the action. - * - * @param string $legacyController - */ - public function setupLegacyTranslationContext($legacyController = 'AdminTab') - { - Context::getContext()->override_controller_name_for_translations = $legacyController; - } - - /** - * Adapter to get admin legacy layout into legacy controller context. - * - * @param string $controllerName The legacy controller name - * @param string $title The page title to override default one - * @param array $headerToolbarBtn The header toolbar to override - * @param string $displayType The legacy display type variable - * @param bool $showContentHeader can force header toolbar (buttons and title) to be hidden with false value - * @param string $headerTabContent - * @param bool $enableSidebar Allow to use right sidebar to display docs for instance - * @param string $helpLink If specified, will be used instead of legacy one - * @param string[] $jsRouterMetadata array to provide base_url and security token for JS Router - * @param string $metaTitle - * @param bool $useRegularH1Structure allows complex

    structure if set to false - * - * @return string The html layout - */ - public function getLegacyLayout( - $controllerName, - $title, - $headerToolbarBtn, - $displayType, - $showContentHeader, - $headerTabContent, - $enableSidebar, - $helpLink = '', - $jsRouterMetadata = [], - $metaTitle = '', - $useRegularH1Structure = true - ) { - $originCtrl = new AdminLegacyLayoutControllerCore( - $controllerName, - $title, - $headerToolbarBtn, - $displayType, - $showContentHeader, - $headerTabContent, - $enableSidebar, - $helpLink, - $jsRouterMetadata, - $metaTitle, - $useRegularH1Structure - ); - $originCtrl->run(); - - return $originCtrl->outPutHtml; - } - - /** - * Returns available languages. The first one is the employee default one. - * - * @param bool $active Select only active languages - * @param int|bool $id_shop Shop ID - * @param bool $ids_only If true, returns an array of language IDs - * - * @return array Languages - */ - public function getLanguages($active = true, $id_shop = false, $ids_only = false) - { - $languages = Language::getLanguages($active, $id_shop, $ids_only); - $defaultLanguageFirst = $this->getLanguage(); - usort($languages, function ($a, $b) use ($defaultLanguageFirst) { - if ($a['id_lang'] == $defaultLanguageFirst->id) { - return -1; // $a is the default one. - } - if ($b['id_lang'] == $defaultLanguageFirst->id) { - return 1; // $b is the default one. - } - - return 0; - }); - - return $languages; - } - - /** - * Returns language ISO code set for the current employee. - * - * @return string Languages - */ - public function getEmployeeLanguageIso() - { - return Language::getIsoById($this->getContext()->employee->id_lang); - } - - /** - * Returns Currency set for the current employee. - * - * @return Currency - */ - public function getEmployeeCurrency() - { - if (null === $this->employeeCurrency && $this->getContext()->currency) { - $this->employeeCurrency = $this->getContext()->currency->sign; - } - - return $this->employeeCurrency; - } - - /** - * @return Language - */ - public function getLanguage() - { - $context = $this->getContext(); - - if ($context->language instanceof Language) { - return $context->language; - } - - return new Language(); - } - - /** - * Get employee's default tab name. - * - * @return string Default tab name for employee - * - * @throws RuntimeException Throws exception if employee does not exist in context - */ - public function getDefaultEmployeeTab() - { - $employee = $this->getContext()->employee; - - if (!$employee instanceof Employee) { - throw new RuntimeException('Cannot retrieve default employee tab. Employee does not exist in context!'); - } - - $idTab = $employee->default_tab; - $tab = new Tab($idTab); - - return $tab->class_name; - } - - /** - * @return string - */ - public function getMailThemesUri() - { - return $this->mailThemesUri; - } - - /** - * @return array Returns both enabled and disabled languages - */ - public function getAvailableLanguages() - { - return $this->getLanguages(false); - } -} diff --git a/src/Adapter/LegacyHookSubscriber.php b/src/Adapter/LegacyHookSubscriber.php deleted file mode 100644 index 38502eb5..00000000 --- a/src/Adapter/LegacyHookSubscriber.php +++ /dev/null @@ -1,302 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Context; -use Hook; -use PrestaShopBundle\Service\Hook\HookEvent; -use PrestaShopBundle\Service\Hook\RenderingHookEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * The subscriber for HookDispatcher that triggers legacy Hooks. - * - * This subscriber is registered into the HookDispatcher service via services.yml. - * The legacy hooks are registered one by one in the dispatcher, but each corresponding - * function is a magic method catched by __call(). - * This ensure the listeners' count is real. - * - * - *

    COVERED HOOKS FROM PrestaShop v1.7

    - * - *
    - *

    ProductController

    - *
      - *
    • actionProductAdd
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter from legacy code: not modified
      • - *
      • Parameters: - *
          - *
        1. product: [object] Product (unchanged)
        2. - *
        3. cookie: [object] Cookie (unchanged)
        4. - *
        5. cart: [object] Cart (unchanged)
        6. - *
        7. altern: ???
        8. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • actionProductDelete
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter from legacy code: not modified
      • - *
      • Parameters: - *
          - *
        1. id_product: [int] Product ID to be deleted (unchanged)
        2. - *
        3. product: [object] Product (unchanged)
        4. - *
        5. cookie: [object] Cookie (unchanged)
        6. - *
        7. cart: [object] Cart (unchanged)
        8. - *
        9. altern: ???
        10. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • actionProductUpdate
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter from legacy code or directly from an adapter: duplicated behavior.
      • - *
      • Parameters: - *
          - *
        1. id_product: [int] Product ID to be deleted (unchanged)
        2. - *
        3. product: [object] Product (unchanged)
        4. - *
        5. cookie: [object] Cookie (unchanged)
        6. - *
        7. cart: [object] Cart (unchanged)
        8. - *
        9. altern: ???
        10. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • actionAdminProductsListingFieldsModifier
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter with a DIFFERENT BEHAVIOR.
      • - *
      • Parameters for the new 1.7 behavior (if _ps_version present and >=1.7.0): - *
          - *
        1. _ps_version: [int] value of _PS_VERSION_ is present only if triggered on new Product catalog page (>=1.7)
        2. - *
        3. sql_select: [&array] SELECT fields (to modify directly if needed)
        4. - *
        5. sql_table: [&array] TABLES to join (to modify directly if needed)
        6. - *
        7. sql_where: [&array] WHERE clauses (to modify directly if needed)
        8. - *
        9. sql_order: [&array] ORDER BY clauses (to modify directly if needed)
        10. - *
        11. sql_limit: [&string] LIMIT clause (to modify directly if needed)
        12. - *
        13. cookie: [object] Cookie (unchanged)
        14. - *
        15. cart: [object] Cart (unchanged)
        16. - *
        17. altern: ???
        18. - *
        - *
      • - *
      • {@see AbstractAdminQueryBuilder::compileSqlQuery()} for more details about how to build these arrays.
      • - *
      • {@see AdminProductDataProvider::getCatalogProductList()} for an example.
      • - *
      • Returns: void (but you can modify input parameters passed by reference)
      • - *
      - *
    • - *
    • actionAdminProductsListingResultsModifier
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter with a DIFFERENT BEHAVIOR.
      • - *
      • Parameters for the new 1.7 behavior (if _ps_version present and >=1.7.0): - *
          - *
        1. _ps_version: [int] value of _PS_VERSION_ is present only if triggered on new Product catalog page (>=1.7)
        2. - *
        3. products: [&array] List of the products on the requested page, after sql query (modified by actionAdminProductsListingFieldsModifier hook)
        4. - *
        5. total: [integer] total count of products (without pagination) that matches with the requested filters
        6. - *
        7. cookie: [object] Cookie (unchanged)
        8. - *
        9. cart: [object] Cart (unchanged)
        10. - *
        11. altern: ???
        12. - *
        - *
      • - *
      • {@see AdminProductDataProvider::getCatalogProductList()} for an example.
      • - *
      • Returns: void (but you can modify input parameters passed by reference)
      • - *
      - *
    • - *
    • displayAdminProductsExtra
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by the new architecture in Twig template.
      • - *
      • Parameters for the new 1.7 behavior (if _ps_version present and >=1.7.0): - *
          - *
        1. _ps_version: [int] value of _PS_VERSION_ is present only if triggered on new Product details page (>=1.7)
        2. - *
        3. id_product: [int] Product ID to be detailed in the form
        4. - *
        5. cookie: [object] Cookie (unchanged)
        6. - *
        7. cart: [object] Cart (unchanged)
        8. - *
        9. altern: ???
        10. - *
        - *
      • - *
      • Returns: HTML code, all embedded. While the page has been refactored, JS and legacy HTML/CSS classes are all changed.
      • - *
      - *
    • - *
    • actionUpdateQuantity
      - *
        - *
      • Legacy code (for legacy Admin controller, Product pages) is not modified
      • - *
      • Since 1.7 (refactored Admin Product pages), triggered by an adapter from legacy code or directly from an adapter: duplicated behavior.
      • - *
      • Parameters: - *
          - *
        1. id_product: [int] Product ID to be updated (unchanged)
        2. - *
        3. id_product_attribute: [int] Product attribute ID to be updated (unchanged, 0 if the product has no attribute)
        4. - *
        5. quantity: [int] Quantity to set (unchanged)
        6. - *
        7. cookie: [object] Cookie (unchanged)
        8. - *
        9. cart: [object] Cart (unchanged)
        10. - *
        11. altern: ???
        12. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • action{Admin|AdminProductsController}{Duplicate|Delete|Sort|Activate|Deactivate}{Before|After}
      - *
        - *
      • Since 1.7, triggered from the Controller
      • - *
      • Parameter, one of these: - *
          - *
        1. product_list_id: [array] A list of product IDs concerning the action
        2. - *
        3. product_id: [int] The product ID concerning the action
        4. - *
        5. product_list_position: [array] The positions of products in the product_list_id parameter, to sort
        6. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • shouldUseLegacyPage
      - *
        - *
      • Since 1.7, triggered from the Controller. This is a transitional behavior and can be removed in the future.
      • - *
      • Parameters: - *
          - *
        1. page: [string] The page name concerning the parameter change ('product', etc...)
        2. - *
        3. use_legacy: [boolean] True if the user ask to use legacy page instead of the new one.
        4. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    • actionProductActivation
      - *
        - *
      • Since 1.7, triggered from the AdminProductDataUpdater via sf ProductController.
      • - *
      • Parameters: - *
          - *
        1. id_product: [int] Product ID to be updated
        2. - *
        3. product: [object] Product
        4. - *
        5. activated: [boolean] True if activation, False if deactivation.
        6. - *
        - *
      • - *
      • Returns: void
      • - *
      - *
    • - *
    - *
    - *
    - */ -class LegacyHookSubscriber implements EventSubscriberInterface -{ - /** - * Returns an array of event names this subscriber wants to listen to. - * - * The array keys are event names and the value are a function name - * that will be solved by magic __call(). The function contains data to extract: hookId, moduleId - * - * TODO: add cache layer on $listeners - * - * @return array The listeners array - */ - public static function getSubscribedEvents() - { - $listeners = []; - - //Hack SF2 cache clear : if context not mounted, bypass legacy call - $legacyContext = Context::getContext(); - if (!$legacyContext || empty($legacyContext->shop) || empty($legacyContext->employee)) { - return $listeners; - } - - $hooks = Hook::getHooks(); - - if (is_array($hooks)) { - foreach ($hooks as $hook) { - $name = strtolower($hook['name']); - $id = $hook['id_hook']; - - $moduleListeners = []; - $modules = []; - //SF2 cache clear bug fix : call bqSQL alias function - if (function_exists('bqSQL')) { - $modules = Hook::getHookModuleExecList($name); - } - - if (is_array($modules)) { - foreach ($modules as $order => $module) { - $moduleId = $module['id_module']; - $functionName = 'call_' . $id . '_' . $moduleId; - $moduleListeners[] = [$functionName, 2000 - $order]; - } - } else { - $moduleListeners[] = ['call_' . $id . '_0', 2000]; - } - - $listeners[$name] = $moduleListeners; - } - } - - return $listeners; - } - - /** - * This will handle magic methods registered as listeners. - * - * These methods are built with the following syntax: - * "call__(HookEvent $event, $hookName)" - * - * @param string $name The method called - * @param array $args The HookEvent, and then the hook name (eventName) - * - * @throws \BadMethodCallException - */ - public function __call($name, $args) - { - if (strpos($name, 'call_') !== 0) { - throw new \BadMethodCallException('The call to \'' . $name . '\' is not recognized.'); - } - - $ids = explode('_', $name); - array_shift($ids); // remove 'call' - - if (count($ids) !== 2) { - throw new \BadMethodCallException('The call to \'' . $name . '\' is not recognized.'); - } - - $moduleId = (int) $ids[1]; - list($event, $hookName) = $args; - - /** @var $event HookEvent */ - $content = Hook::exec($hookName, $event->getHookParameters(), $moduleId, ($event instanceof RenderingHookEvent)); - - if ( - $event instanceof RenderingHookEvent - && 0 !== $moduleId - && !empty($content) - ) { - $event->setContent([array_values($content)[0]], array_keys($content)[0]); - } - } -} diff --git a/src/Adapter/LegacyLogger.php b/src/Adapter/LegacyLogger.php deleted file mode 100644 index dfc8a1f1..00000000 --- a/src/Adapter/LegacyLogger.php +++ /dev/null @@ -1,170 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Monolog\Logger; -use PrestaShopLogger; -use Psr\Log\LoggerInterface; - -/** - * Class that bridge the legacy implementation of Logger with Psr Logger interface. - */ -class LegacyLogger implements LoggerInterface -{ - public function emergency($message, array $context = []) - { - $this->log(Logger::EMERGENCY, $message, $context); - } - - /** - * Action must be taken immediately. - * - * Example: Entire website down, database unavailable, etc. This should - * trigger the SMS alerts and wake you up. - * - * @param string $message - * @param array $context - */ - public function alert($message, array $context = []) - { - $this->log(Logger::ALERT, $message, $context); - } - - /** - * Critical conditions. - * - * Example: Application component unavailable, unexpected exception. - * - * @param string $message - * @param array $context - */ - public function critical($message, array $context = []) - { - $this->log(Logger::CRITICAL, $message, $context); - } - - /** - * Runtime errors that do not require immediate action but should typically - * be logged and monitored. - * - * @param string $message - * @param array $context - */ - public function error($message, array $context = []) - { - $this->log(Logger::ERROR, $message, $context); - } - - /** - * Exceptional occurrences that are not errors. - * - * Example: Use of deprecated APIs, poor use of an API, undesirable things - * that are not necessarily wrong. - * - * @param string $message - * @param array $context - */ - public function warning($message, array $context = []) - { - $this->log(Logger::WARNING, $message, $context); - } - - /** - * Normal but significant events. - * - * @param string $message - * @param array $context - */ - public function notice($message, array $context = []) - { - $this->log(Logger::NOTICE, $message, $context); - } - - /** - * Interesting events. - * - * Example: User logs in, SQL logs. - * - * @param string $message - * @param array $context - */ - public function info($message, array $context = []) - { - $this->log(Logger::INFO, $message, $context); - } - - /** - * Detailed debug information. - * - * @param string $message - * @param array $context - */ - public function debug($message, array $context = []) - { - $this->log(Logger::DEBUG, $message, $context); - } - - /** - * Logs with an arbitrary level. - * - * @param mixed $level - * @param string $message - * @param array $context - */ - public function log($level, $message, array $context = []) - { - switch ($level) { - case Logger::EMERGENCY: - case Logger::ALERT: - case Logger::CRITICAL: - $pslevel = 4; - - break; - case Logger::ERROR: - $pslevel = 3; - - break; - case Logger::WARNING: - $pslevel = 2; - - break; - case Logger::NOTICE: - case Logger::INFO: - case Logger::DEBUG: - $pslevel = 1; - - break; - } - - $error_code = !empty($context['error_code']) ? $context['error_code'] : null; - $object_type = !empty($context['object_type']) ? $context['object_type'] : null; - $object_id = !empty($context['object_id']) ? $context['object_id'] : null; - $allow_duplicate = !empty($context['allow_duplicate']) ? $context['allow_duplicate'] : null; - - PrestaShopLogger::addLog($message, $pslevel, $error_code, $object_type, $object_id, $allow_duplicate); - } -} diff --git a/src/Adapter/Localization/AdvancedConfiguration.php b/src/Adapter/Localization/AdvancedConfiguration.php deleted file mode 100644 index 304933b3..00000000 --- a/src/Adapter/Localization/AdvancedConfiguration.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Localization; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class AdvancedConfiguration is responsible for 'Improve > International > Localization' page - * 'Advanced' form data. - */ -class AdvancedConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'language_identifier' => $this->configuration->get('PS_LOCALE_LANGUAGE'), - 'country_identifier' => $this->configuration->get('PS_LOCALE_COUNTRY'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_LOCALE_LANGUAGE', $config['language_identifier']); - $this->configuration->set('PS_LOCALE_COUNTRY', $config['country_identifier']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['language_identifier'], - $config['country_identifier'] - ); - } -} diff --git a/src/Adapter/Localization/LegacyTranslator.php b/src/Adapter/Localization/LegacyTranslator.php deleted file mode 100644 index a2ac79ca..00000000 --- a/src/Adapter/Localization/LegacyTranslator.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Localization; - -use Translate; - -/** - * Wraps the Legacy translation system - * - * @deprecated The legacy translation system will be removed in the next major version - */ -class LegacyTranslator -{ - /** - * @param string $moduleName Module name - * @param string $originalString String to translate - * @param string|false $source - * @param null $sprintf - * @param bool $js - * @param string|null $locale - * @param bool $fallback [default=true] If true, this method falls back to the new translation system if no translation is found - * - * @return mixed|string - * - * @throws \Exception - */ - public function translate( - $moduleName, - $originalString, - $source, - $sprintf = null, - $js = false, - $locale = null, - $fallback = true, - $escape = true - ) { - return Translate::getModuleTranslation( - $moduleName, - $originalString, - $source, - $sprintf, - $js, - $locale, - $fallback, - $escape - ); - } -} diff --git a/src/Adapter/Localization/LocalUnitsConfiguration.php b/src/Adapter/Localization/LocalUnitsConfiguration.php deleted file mode 100644 index a41a001c..00000000 --- a/src/Adapter/Localization/LocalUnitsConfiguration.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Localization; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Class LocalUnitsConfiguration is responsible for 'Improve > International > Localization' page - * 'Local units' form data. - */ -class LocalUnitsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'weight_unit' => $this->configuration->get('PS_WEIGHT_UNIT'), - 'distance_unit' => $this->configuration->get('PS_DISTANCE_UNIT'), - 'volume_unit' => $this->configuration->get('PS_VOLUME_UNIT'), - 'dimension_unit' => $this->configuration->get('PS_DIMENSION_UNIT'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_WEIGHT_UNIT', $config['weight_unit']); - $this->configuration->set('PS_DISTANCE_UNIT', $config['distance_unit']); - $this->configuration->set('PS_VOLUME_UNIT', $config['volume_unit']); - $this->configuration->set('PS_DIMENSION_UNIT', $config['dimension_unit']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['weight_unit'], - $config['distance_unit'], - $config['volume_unit'], - $config['dimension_unit'] - ); - } -} diff --git a/src/Adapter/Localization/LocalizationConfiguration.php b/src/Adapter/Localization/LocalizationConfiguration.php deleted file mode 100644 index 5708ca70..00000000 --- a/src/Adapter/Localization/LocalizationConfiguration.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Localization; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Currency\CurrencyManager; -use PrestaShop\PrestaShop\Adapter\Language\LanguageActivator; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageActivatorInterface; - -/** - * Class LocalizationConfiguration is responsible for 'Improve > International > Localization' page - * 'Configuration' form data. - */ -class LocalizationConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var LanguageActivator - */ - private $languageActivator; - - /** - * @var CurrencyManager - */ - private $currencyManager; - - /** - * @var AdminModuleDataProvider - */ - private $adminModuleDataProvider; - - /** - * @param Configuration $configuration - * @param LanguageActivatorInterface $languageActivator - * @param CurrencyManager $currencyManager - * @param AdminModuleDataProvider $adminModuleDataProvider - */ - public function __construct( - Configuration $configuration, - LanguageActivatorInterface $languageActivator, - CurrencyManager $currencyManager, - AdminModuleDataProvider $adminModuleDataProvider - ) { - $this->configuration = $configuration; - $this->languageActivator = $languageActivator; - $this->currencyManager = $currencyManager; - $this->adminModuleDataProvider = $adminModuleDataProvider; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'default_language' => $this->configuration->getInt('PS_LANG_DEFAULT'), - 'detect_language_from_browser' => $this->configuration->getBoolean('PS_DETECT_LANG'), - 'default_country' => $this->configuration->getInt('PS_COUNTRY_DEFAULT'), - 'detect_country_from_browser' => $this->configuration->getBoolean('PS_DETECT_COUNTRY'), - 'default_currency' => $this->configuration->getInt('PS_CURRENCY_DEFAULT'), - 'timezone' => $this->configuration->get('PS_TIMEZONE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->languageActivator->enable((int) $config['default_language']); - - // only update currency related data if it has changed - $currentConfig = $this->getConfiguration(); - if ($currentConfig['default_currency'] != $config['default_currency']) { - $this->configuration->set('PS_CURRENCY_DEFAULT', (int) $config['default_currency']); - $this->currencyManager->updateDefaultCurrency(); - } - - // remove module list cache if the default country changed - if ($currentConfig['default_country'] != $config['default_country']) { - $this->adminModuleDataProvider->clearModuleListCache(); - } - - $this->configuration->set('PS_LANG_DEFAULT', (int) $config['default_language']); - $this->configuration->set('PS_DETECT_LANG', (int) $config['detect_language_from_browser']); - $this->configuration->set('PS_COUNTRY_DEFAULT', (int) $config['default_country']); - $this->configuration->set('PS_DETECT_COUNTRY', (int) $config['detect_country_from_browser']); - $this->configuration->set('PS_TIMEZONE', $config['timezone']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['default_language'], - $config['detect_language_from_browser'], - $config['default_country'], - $config['detect_country_from_browser'], - $config['default_currency'], - $config['timezone'] - ); - } -} diff --git a/src/Adapter/Mail/MailingInformation.php b/src/Adapter/Mail/MailingInformation.php deleted file mode 100644 index a4532927..00000000 --- a/src/Adapter/Mail/MailingInformation.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Mail; - -use Configuration; - -/** - * Retrieve mailing information. - */ -class MailingInformation -{ - /** - * @return bool - */ - public function isNativeMailUsed() - { - return Configuration::get('PS_MAIL_METHOD') == 1; - } - - /** - * @return array - */ - public function getSmtpInformation() - { - return [ - 'server' => Configuration::get('PS_MAIL_SERVER'), - 'user' => Configuration::get('PS_MAIL_USER'), - 'password' => Configuration::get('PS_MAIL_PASSWD'), - 'encryption' => Configuration::get('PS_MAIL_SMTP_ENCRYPTION'), - 'port' => Configuration::get('PS_MAIL_SMTP_PORT'), - ]; - } -} diff --git a/src/Adapter/MailTemplate/MailPartialTemplateRenderer.php b/src/Adapter/MailTemplate/MailPartialTemplateRenderer.php deleted file mode 100644 index af155196..00000000 --- a/src/Adapter/MailTemplate/MailPartialTemplateRenderer.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\MailTemplate; - -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use Smarty; -use Tools; - -/** - * Class MailPartialTemplateRenderer renders partial mail templates (especially for order). This - * feature was moved in this service so that it can be shared between PaymentModule and MailPreviewVariablesBuilder. - */ -class MailPartialTemplateRenderer -{ - /** @var Smarty */ - private $smarty; - - /** - * @param Smarty $smarty - */ - public function __construct(Smarty $smarty) - { - $this->smarty = $smarty; - } - - /** - * Fetch the content of $partialTemplateName inside the folder - * current_theme/mails/current_iso_lang/ if found, otherwise in - * mails/current_iso_lang. - * - * @param string $partialTemplateName template name with extension - * @param LanguageInterface $language - * @param array $variables sent to smarty as 'list' - * @param bool $cleanComments - * - * @return string - */ - public function render($partialTemplateName, LanguageInterface $language, array $variables = [], $cleanComments = false) - { - $potentialPaths = [ - _PS_THEME_DIR_ . 'mails' . DIRECTORY_SEPARATOR . $language->getIsoCode() . DIRECTORY_SEPARATOR . $partialTemplateName, - _PS_MAIL_DIR_ . $language->getIsoCode() . DIRECTORY_SEPARATOR . $partialTemplateName, - _PS_THEME_DIR_ . 'mails' . DIRECTORY_SEPARATOR . 'en' . DIRECTORY_SEPARATOR . $partialTemplateName, - _PS_MAIL_DIR_ . 'en' . DIRECTORY_SEPARATOR . $partialTemplateName, - _PS_MAIL_DIR_ . '_partials' . DIRECTORY_SEPARATOR . $partialTemplateName, - ]; - - foreach ($potentialPaths as $path) { - if (Tools::file_exists_cache($path)) { - $this->smarty->assign('list', $variables); - $content = $this->smarty->fetch($path); - if ($cleanComments) { - $content = preg_replace('/\s?\s?/s', '', $content); - } - - return $content; - } - } - - return ''; - } -} diff --git a/src/Adapter/MailTemplate/MailPreviewVariablesBuilder.php b/src/Adapter/MailTemplate/MailPreviewVariablesBuilder.php deleted file mode 100644 index a4d176ba..00000000 --- a/src/Adapter/MailTemplate/MailPreviewVariablesBuilder.php +++ /dev/null @@ -1,440 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\MailTemplate; - -use Address; -use AddressFormat; -use Carrier; -use Cart; -use Context; -use Order; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -use Product; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -/** - * Class MailPreviewVariablesBuilder is used to build fake (but realistic) template variables to preview email templates. - */ -final class MailPreviewVariablesBuilder -{ - const ORDER_CONFIRMATION = 'order_conf'; - - const DOWNLOAD_PRODUCT = 'download_product'; - - const EMAIL_ALERTS_MODULE = 'ps_emailalerts'; - const NEW_ORDER = 'new_order'; - const RETURN_SLIP = 'return_slip'; - - /** @var ConfigurationInterface */ - private $configuration; - - /** @var LegacyContext */ - private $legacyContext; - - /** - * @var Locale - */ - private $locale; - - /** @var ContextEmployeeProviderInterface */ - private $employeeProvider; - - /** @var Context */ - private $context; - - /** @var MailPartialTemplateRenderer */ - private $mailPartialTemplateRenderer; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * MailPreviewVariablesBuilder constructor. - * - * @param ConfigurationInterface $configuration - * @param LegacyContext $legacyContext - * @param ContextEmployeeProviderInterface $employeeProvider - * @param MailPartialTemplateRenderer $mailPartialTemplateRenderer - * @param Locale $locale - * @param TranslatorInterface $translatorComponent - */ - public function __construct( - ConfigurationInterface $configuration, - LegacyContext $legacyContext, - ContextEmployeeProviderInterface $employeeProvider, - MailPartialTemplateRenderer $mailPartialTemplateRenderer, - Locale $locale, - TranslatorInterface $translatorComponent - ) { - $this->configuration = $configuration; - $this->legacyContext = $legacyContext; - $this->context = $this->legacyContext->getContext(); - $this->employeeProvider = $employeeProvider; - $this->mailPartialTemplateRenderer = $mailPartialTemplateRenderer; - $this->locale = $locale; - $this->translator = $translatorComponent; - } - - /** - * @param LayoutInterface $mailLayout - * - * @return array - * - * @throws \SmartyException - */ - public function buildTemplateVariables(LayoutInterface $mailLayout) - { - $imageDir = $this->configuration->get('_PS_IMG_DIR_'); - $baseUrl = $this->context->link->getBaseLink(); - - //Logo url - $logoMail = $this->configuration->get('PS_LOGO_MAIL'); - $logo = $this->configuration->get('PS_LOGO'); - if (!empty($logoMail) && file_exists($imageDir . $logoMail)) { - $templateVars['{shop_logo}'] = $baseUrl . 'img/' . $logoMail; - } else { - if (!empty($logo) && file_exists($imageDir . $logo)) { - $templateVars['{shop_logo}'] = $baseUrl . 'img/' . $logo; - } else { - $templateVars['{shop_logo}'] = ''; - } - } - - $employeeData = $this->employeeProvider->getData(); - - $templateVars['{firstname}'] = $employeeData['firstname']; - $templateVars['{lastname}'] = $employeeData['lastname']; - $templateVars['{email}'] = $employeeData['email']; - $templateVars['{shop_name}'] = $this->context->shop->name; - $templateVars['{shop_url}'] = $this->context->link->getPageLink('index', true); - $templateVars['{my_account_url}'] = $this->context->link->getPageLink('my-account', true); - $templateVars['{guest_tracking_url}'] = $this->context->link->getPageLink('guest-tracking', true); - $templateVars['{history_url}'] = $this->context->link->getPageLink('history', true); - $templateVars['{color}'] = $this->configuration->get('PS_MAIL_COLOR'); - $templateVars = array_merge($templateVars, $this->buildOrderVariables($mailLayout)); - - return $templateVars; - } - - /** - * @param $id - * @param array $parameters - * @param null $domain - * @param null $local - * - * @return string - */ - protected function trans($id, $parameters = [], $domain = null, $local = null) - { - return $this->translator->trans($id, $parameters, $domain, $local); - } - - /** - * @return array - * - * @throws \PrestaShopException - * @throws \PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException - * @throws \SmartyException - */ - private function buildOrderVariables(LayoutInterface $mailLayout) - { - $orders = Order::getOrdersWithInformations(1); - $order = new Order($orders[0]['id_order']); - - if (self::ORDER_CONFIRMATION == $mailLayout->getName()) { - $productTemplateList = $this->getProductList($order); - $productListTxt = $this->mailPartialTemplateRenderer->render('order_conf_product_list.txt', $this->context->language, $productTemplateList); - $productListHtml = $this->mailPartialTemplateRenderer->render('order_conf_product_list.tpl', $this->context->language, $productTemplateList); - - $cartRulesList[] = [ - 'voucher_name' => 'Promo code', - 'voucher_reduction' => '-' . $this->locale->formatPrice(5, $this->context->currency->iso_code), - ]; - $cartRulesListTxt = $this->mailPartialTemplateRenderer->render('order_conf_cart_rules.txt', $this->context->language, $cartRulesList); - $cartRulesListHtml = $this->mailPartialTemplateRenderer->render('order_conf_cart_rules.tpl', $this->context->language, $cartRulesList); - - $productVariables = [ - '{products}' => $productListHtml, - '{products_txt}' => $productListTxt, - '{discounts}' => $cartRulesListHtml, - '{discounts_txt}' => $cartRulesListTxt, - ]; - } elseif (self::DOWNLOAD_PRODUCT == $mailLayout->getName()) { - $virtualProductTemplateList = $this->getFakeVirtualProductList(); - $virtualProductListTxt = $this->mailPartialTemplateRenderer->render('download_product_virtual_products.txt', $this->context->language, $virtualProductTemplateList); - $virtualProductListHtml = $this->mailPartialTemplateRenderer->render('download_product_virtual_products.tpl', $this->context->language, $virtualProductTemplateList); - $productVariables = [ - '{nbProducts}' => count($virtualProductTemplateList), - '{virtualProducts}' => $virtualProductListHtml, - '{virtualProductsTxt}' => $virtualProductListTxt, - ]; - } elseif (self::EMAIL_ALERTS_MODULE == $mailLayout->getModuleName() && self::NEW_ORDER == $mailLayout->getName()) { - $productVariables = [ - '{items}' => $this->getNewOrderItems($order), - ]; - } elseif (self::EMAIL_ALERTS_MODULE == $mailLayout->getModuleName() && self::RETURN_SLIP == $mailLayout->getName()) { - $productVariables = [ - '{items}' => $this->getReturnSlipItems($order), - ]; - } else { - return []; - } - - $carrier = new Carrier($order->id_carrier); - $delivery = new Address($order->id_address_delivery); - $invoice = new Address($order->id_address_invoice); - - return array_merge($productVariables, [ - '{carrier}' => $carrier->name, - '{delivery_block_txt}' => $this->getFormatedAddress($delivery, "\n"), - '{invoice_block_txt}' => $this->getFormatedAddress($invoice, "\n"), - '{delivery_block_html}' => $this->getFormatedAddress($delivery, '
    ', [ - 'firstname' => '%s', - 'lastname' => '%s', - ]), - '{invoice_block_html}' => $this->getFormatedAddress($invoice, '
    ', [ - 'firstname' => '%s', - 'lastname' => '%s', - ]), - '{date}' => Tools::displayDate($order->date_add, null, 1), - '{order_name}' => $order->getUniqReference(), - '{id_order}' => $order->id, - '{payment}' => Tools::substr($order->payment, 0, 255), - '{total_products}' => count($order->getProducts()), - '{total_discounts}' => $this->locale->formatPrice($order->total_discounts, $this->context->currency->iso_code), - '{total_wrapping}' => $this->locale->formatPrice($order->total_wrapping, $this->context->currency->iso_code), - '{total_shipping}' => $this->locale->formatPrice($order->total_shipping, $this->context->currency->iso_code), - '{total_shipping_tax_excl}' => $this->locale->formatPrice($order->total_shipping_tax_excl, $this->context->currency->iso_code), - '{total_shipping_tax_incl}' => $this->locale->formatPrice($order->total_shipping_tax_incl, $this->context->currency->iso_code), - '{total_tax_paid}' => $this->locale->formatPrice(($order->total_products_wt - $order->total_products) + ($order->total_shipping_tax_incl - $order->total_shipping_tax_excl), $this->context->currency->iso_code), - '{total_paid}' => $this->locale->formatPrice($order->total_paid, $this->context->currency->iso_code), - ]); - } - - /** - * @param Order $order - * - * @return string - * - * @throws \PrestaShopException - * @throws \PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException - */ - private function getNewOrderItems(Order $order) - { - $itemsTable = ''; - - $products = $order->getProducts(); - $customizedDatas = Product::getAllCustomizedDatas($order->id_cart); - Product::addCustomizationPrice($products, $customizedDatas); - foreach ($products as $key => $product) { - $unitPrice = $product['product_price_wt']; - - $customizationText = ''; - if (isset($customizedDatas[$product['product_id']][$product['product_attribute_id']])) { - foreach ($customizedDatas[$product['product_id']][$product['product_attribute_id']][$order->id_address_delivery] as $customization) { - if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) { - foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) { - $customizationText .= $text['name'] . ': ' . $text['value'] . '
    '; - } - } - - if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) { - $customizationText .= count($customization['datas'][Product::CUSTOMIZE_FILE]) . ' ' . $this->trans('image(s)', [], 'Modules.Mailalerts.Admin') . '
    '; - } - - $customizationText .= '---
    '; - } - if (method_exists('Tools', 'rtrimString')) { - $customizationText = Tools::rtrimString($customizationText, '---
    '); - } else { - $customizationText = preg_replace('/---
    $/', '', $customizationText); - } - } - - $url = $this->context->link->getProductLink($product['product_id']); - $itemsTable .= - ' - ' . $product['product_reference'] . ' - - ' . $product['product_name'] . '' - . (isset($product['attributes_small']) ? ' ' . $product['attributes_small'] : '') - . (!empty($customizationText) ? '
    ' . $customizationText : '') - . '
    - - ' . $this->locale->formatPrice($unitPrice, $this->context->currency->iso_code) . ' - ' . (int) $product['product_quantity'] . ' - ' - . $this->locale->formatPrice(($unitPrice * $product['product_quantity']), $this->context->currency->iso_code) - . ' - '; - } - foreach ($order->getCartRules() as $discount) { - $itemsTable .= - ' - ' . $this->trans('Voucher code:', [], 'Modules.Mailalerts.Admin') . ' ' . $discount['name'] . ' - -' . $this->locale->formatPrice($discount['value'], $this->context->currency->iso_code) . ' - '; - } - - return $itemsTable; - } - - /** - * @param Order $order - * - * @return string - * - * @throws \PrestaShopException - */ - private function getReturnSlipItems(Order $order) - { - $itemsTable = ''; - foreach ($order->getCartProducts() as $key => $product) { - $url = $this->context->link->getProductLink($product['product_id']); - $itemsTable .= - ' - ' . $product['product_reference'] . ' - - ' . $product['product_name'] . ' - - - ' . (int) $product['product_quantity'] . ' - '; - } - - return $itemsTable; - } - - /** - * @param Order $order - * - * @return array - * - * @throws \PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException - */ - private function getProductList(Order $order) - { - $cart = new Cart($order->id_cart); - $packageList = $cart->getPackageList(); - $package = current(current($packageList)); - $productList = $package['product_list']; - - $productTemplateList = []; - foreach ($productList as $product) { - $price = Product::getPriceStatic((int) $product['id_product'], false, ($product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null), 6, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{$this->configuration->get('PS_TAX_ADDRESS_TYPE')}, $specific_price, true, true, null, true, $product['id_customization']); - $priceWithTax = Product::getPriceStatic((int) $product['id_product'], true, ($product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null), 2, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{$this->configuration->get('PS_TAX_ADDRESS_TYPE')}, $specific_price, true, true, null, true, $product['id_customization']); - - $productPrice = Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $priceWithTax; - - $productTemplate = [ - 'id_product' => $product['id_product'], - 'reference' => $product['reference'], - 'name' => $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : ''), - 'price' => $this->locale->formatPrice($productPrice * $product['quantity'], $this->context->currency->iso_code), - 'quantity' => $product['quantity'], - 'customization' => [], - ]; - - if (isset($product['price']) && $product['price']) { - $productTemplate['unit_price'] = $this->locale->formatPrice($productPrice, $this->context->currency->iso_code); - $productTemplate['unit_price_full'] = $this->locale->formatPrice($productPrice, $this->context->currency->iso_code) - . ' ' . $product['unity']; - } else { - $productTemplate['unit_price'] = $productTemplate['unit_price_full'] = ''; - } - - $customizedDatas = Product::getAllCustomizedDatas((int) $order->id_cart, null, true, null, (int) $product['id_customization']); - if (isset($customizedDatas[$product['id_product']][$product['id_product_attribute']])) { - $productTemplate['customization'] = []; - foreach ($customizedDatas[$product['id_product']][$product['id_product_attribute']][$order->id_address_delivery] as $customization) { - $customizationText = ''; - if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) { - foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) { - $customizationText .= '' . $text['name'] . ': ' . $text['value'] . '
    '; - } - } - - if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) { - $customizationText .= $this->trans('%d image(s)', [count($customization['datas'][Product::CUSTOMIZE_FILE])], 'Admin.Payment.Notification') . '
    '; - } - - $customizationQuantity = (int) $customization['quantity']; - - $productTemplate['customization'][] = [ - 'customization_text' => $customizationText, - 'customization_quantity' => $customizationQuantity, - 'quantity' => $this->locale->formatPrice($customizationQuantity * $productPrice, $this->context->currency->iso_code), - ]; - } - } - $productTemplateList[] = $productTemplate; - } - - return $productTemplateList; - } - - /** - * @return array - */ - private function getFakeVirtualProductList() - { - $products = Product::getProducts($this->context->language->getId(), 0, 2, 'id_product', 'ASC'); - $results = []; - - foreach ($products as $productData) { - $product = new Product($productData['id_product']); - $results[] = [ - 'text' => Product::getProductName($productData['id_product']), - 'url' => $product->getLink(), - 'complementary_text' => '', - ]; - } - $results[1]['complementary_text'] = ' ' . $this->trans('expires on %s.', [date('Y-m-d')], 'Admin.Orderscustomers.Notification'); - $results[1]['complementary_text'] .= ' ' . $this->trans('downloadable %d time(s)', [10], 'Admin.Orderscustomers.Notification'); - - return $results; - } - - /** - * @param Address $address Address $the_address that needs to be txt formated - * @param string $lineSeparator Line separator - * @param array $fieldsStyle Associative array to replace styled fields - * - * @return string - */ - private function getFormatedAddress(Address $address, $lineSeparator, $fieldsStyle = []) - { - return AddressFormat::generateAddress($address, ['avoid' => []], $lineSeparator, ' ', $fieldsStyle); - } -} diff --git a/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php b/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php deleted file mode 100644 index 28a4c8b4..00000000 --- a/src/Adapter/MailTemplate/MailTemplateTwigRenderer.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\MailTemplate; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\TypeException; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutVariablesBuilderInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateRendererInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Transformation\TransformationCollection; -use PrestaShop\PrestaShop\Core\MailTemplate\Transformation\TransformationInterface; -use Symfony\Component\Templating\EngineInterface; - -/** - * MailTemplateTwigRenderer is a basic implementation of MailTemplateRendererInterface - * using the twig engine. - */ -class MailTemplateTwigRenderer implements MailTemplateRendererInterface -{ - /** @var EngineInterface */ - private $engine; - - /** @var LayoutVariablesBuilderInterface */ - private $variablesBuilder; - - /** @var HookDispatcherInterface */ - private $hookDispatcher; - - /** @var TransformationInterface[] */ - private $transformations; - - /** - * @param EngineInterface $engine - * @param LayoutVariablesBuilderInterface $variablesBuilder - * @param HookDispatcherInterface $hookDispatcher - * - * @throws TypeException - */ - public function __construct( - EngineInterface $engine, - LayoutVariablesBuilderInterface $variablesBuilder, - HookDispatcherInterface $hookDispatcher - ) { - $this->engine = $engine; - $this->variablesBuilder = $variablesBuilder; - $this->hookDispatcher = $hookDispatcher; - $this->transformations = new TransformationCollection(); - } - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * - * @throws TypeException - * - * @return string - * - * @throws FileNotFoundException - * @throws TypeException - */ - public function renderHtml(LayoutInterface $layout, LanguageInterface $language) - { - return $this->render($layout, $language, MailTemplateInterface::HTML_TYPE); - } - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * - * @throws FileNotFoundException - * @throws TypeException - * - * @return string - */ - public function renderTxt(LayoutInterface $layout, LanguageInterface $language) - { - return $this->render($layout, $language, MailTemplateInterface::TXT_TYPE); - } - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * @param string $templateType - * - * @return string - * - * @throws FileNotFoundException - * @throws TypeException - */ - private function render( - LayoutInterface $layout, - LanguageInterface $language, - $templateType - ) { - $layoutVariables = $this->variablesBuilder->buildVariables($layout, $language); - $layoutVariables['templateType'] = $templateType; - if (MailTemplateInterface::HTML_TYPE === $templateType) { - $layoutPath = !empty($layout->getHtmlPath()) ? $layout->getHtmlPath() : $layout->getTxtPath(); - } else { - $layoutPath = !empty($layout->getTxtPath()) ? $layout->getTxtPath() : $layout->getHtmlPath(); - } - if (!file_exists($layoutPath)) { - throw new FileNotFoundException(sprintf('Could not find layout file: %s', $layoutPath)); - } - - $renderedTemplate = $this->engine->render($layoutPath, $layoutVariables); - $templateTransformations = $this->getMailLayoutTransformations($layout, $templateType); - /** @var TransformationInterface $transformation */ - foreach ($templateTransformations as $transformation) { - $renderedTemplate = $transformation - ->setLanguage($language) - ->apply($renderedTemplate, $layoutVariables) - ; - } - - return $renderedTemplate; - } - - /** - * @param LayoutInterface $mailLayout - * @param string $templateType - * - * @return TransformationCollection - * - * @throws TypeException - */ - private function getMailLayoutTransformations(LayoutInterface $mailLayout, $templateType) - { - $templateTransformations = new TransformationCollection(); - /** @var TransformationInterface $transformation */ - foreach ($this->transformations as $transformation) { - if ($templateType !== $transformation->getType()) { - continue; - } - - $templateTransformations->add($transformation); - } - - //This hook allows to add/remove transformations during a layout rendering - $this->hookDispatcher->dispatchWithParameters( - MailTemplateRendererInterface::GET_MAIL_LAYOUT_TRANSFORMATIONS, - [ - 'mailLayout' => $mailLayout, - 'templateType' => $templateType, - 'layoutTransformations' => $templateTransformations, - ] - ); - - return $templateTransformations; - } - - /** - * {@inheritdoc} - */ - public function addTransformation(TransformationInterface $transformation) - { - $this->transformations[] = $transformation; - - return $this; - } -} diff --git a/src/Adapter/Manufacturer/AbstractManufacturerHandler.php b/src/Adapter/Manufacturer/AbstractManufacturerHandler.php deleted file mode 100644 index 3ef2f93a..00000000 --- a/src/Adapter/Manufacturer/AbstractManufacturerHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer; - -use Manufacturer; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; -use PrestaShopException; - -/** - * Provides reusable methods for manufacturer command/query handlers - */ -abstract class AbstractManufacturerHandler extends AbstractObjectModelHandler -{ - /** - * Gets legacy Manufacturer - * - * @param ManufacturerId $manufacturerId - * - * @return Manufacturer - * - * @throws ManufacturerException - */ - protected function getManufacturer(ManufacturerId $manufacturerId) - { - try { - $manufacturer = new Manufacturer($manufacturerId->getValue()); - } catch (PrestaShopException $e) { - throw new ManufacturerException('Failed to create new manufacturer', 0, $e); - } - - if ($manufacturer->id !== $manufacturerId->getValue()) { - throw new ManufacturerNotFoundException(sprintf('Manufacturer with id "%s" was not found.', $manufacturerId->getValue())); - } - - return $manufacturer; - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/AbstractManufacturerCommandHandler.php b/src/Adapter/Manufacturer/CommandHandler/AbstractManufacturerCommandHandler.php deleted file mode 100644 index ff68a6bb..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/AbstractManufacturerCommandHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use Manufacturer; -use PrestaShop\PrestaShop\Adapter\Manufacturer\AbstractManufacturerHandler; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerException; -use PrestaShopException; - -/** - * Provides reusable methods for manufacturer command handlers - */ -abstract class AbstractManufacturerCommandHandler extends AbstractManufacturerHandler -{ - /** - * Deletes legacy Manufacturer - * - * @param Manufacturer $manufacturer - * - * @return bool - * - * @throws ManufacturerException - */ - protected function deleteManufacturer(Manufacturer $manufacturer) - { - try { - return $manufacturer->delete(); - } catch (PrestaShopException $e) { - throw new ManufacturerException(sprintf('An error occurred when deleting Manufacturer object with id "%s".', $manufacturer->id)); - } - } - - /** - * Toggles legacy manufacturer status - * - * @param Manufacturer $manufacturer - * @param bool $newStatus - * - * @return bool - * - * @throws ManufacturerException - */ - protected function toggleManufacturerStatus(Manufacturer $manufacturer, $newStatus) - { - $manufacturer->active = $newStatus; - - try { - return $manufacturer->save(); - } catch (PrestaShopException $e) { - throw new ManufacturerException(sprintf('An error occurred when updating manufacturer status with id "%s"', $manufacturer->id)); - } - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/AddManufacturerHandler.php b/src/Adapter/Manufacturer/CommandHandler/AddManufacturerHandler.php deleted file mode 100644 index f247cc0d..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/AddManufacturerHandler.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use Manufacturer; -use PrestaShop\PrestaShop\Adapter\Manufacturer\AbstractManufacturerHandler; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\AddManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\AddManufacturerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Handles command which adds new manufacturer using legacy object model - */ -final class AddManufacturerHandler extends AbstractManufacturerHandler implements AddManufacturerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddManufacturerCommand $command) - { - $manufacturer = new Manufacturer(); - $this->fillLegacyManufacturerWithData($manufacturer, $command); - - try { - if (false === $manufacturer->validateFields(false)) { - throw new ManufacturerException('Manufacturer contains invalid field values'); - } - - if (!$manufacturer->add()) { - throw new ManufacturerException(sprintf('Failed to add new manufacturer "%s"', $command->getName())); - } - $this->addShopAssociation($manufacturer, $command); - } catch (\PrestaShopException $e) { - throw new ManufacturerException(sprintf('Failed to add new manufacturer "%s"', $command->getName())); - } - - return new ManufacturerId((int) $manufacturer->id); - } - - /** - * Add manufacturer and shop association - * - * @param Manufacturer $manufacturer - * @param AddManufacturerCommand $command - * - * @throws \PrestaShopDatabaseException - */ - private function addShopAssociation(Manufacturer $manufacturer, AddManufacturerCommand $command) - { - $this->associateWithShops( - $manufacturer, - $command->getShopAssociation() - ); - } - - /** - * @param Manufacturer $manufacturer - * @param AddManufacturerCommand $command - */ - private function fillLegacyManufacturerWithData(Manufacturer $manufacturer, AddManufacturerCommand $command) - { - $manufacturer->name = $command->getName(); - $manufacturer->short_description = $command->getLocalizedShortDescriptions(); - $manufacturer->description = $command->getLocalizedDescriptions(); - $manufacturer->meta_title = $command->getLocalizedMetaTitles(); - $manufacturer->meta_description = $command->getLocalizedMetaDescriptions(); - $manufacturer->meta_keywords = $command->getLocalizedMetaKeywords(); - $manufacturer->active = $command->isEnabled(); - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/BulkDeleteManufacturerHandler.php b/src/Adapter/Manufacturer/CommandHandler/BulkDeleteManufacturerHandler.php deleted file mode 100644 index 561d7c10..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/BulkDeleteManufacturerHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkDeleteManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\BulkDeleteManufacturerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\DeleteManufacturerException; - -/** - * Handles command which deletes manufacturers in bulk action - */ -final class BulkDeleteManufacturerHandler extends AbstractManufacturerCommandHandler implements BulkDeleteManufacturerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteManufacturerCommand $command) - { - foreach ($command->getManufacturerIds() as $manufacturerId) { - $manufacturer = $this->getManufacturer($manufacturerId); - - if (!$this->deleteManufacturer($manufacturer)) { - throw new DeleteManufacturerException(sprintf('Cannot delete Manufacturer object with id "%s".', $manufacturer->id), DeleteManufacturerException::FAILED_BULK_DELETE); - } - } - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandler.php b/src/Adapter/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandler.php deleted file mode 100644 index 59b510fc..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandler.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkToggleManufacturerStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\BulkToggleManufacturerStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\UpdateManufacturerException; - -/** - * Handles command which toggles manufacturer status in bulk action - */ -final class BulkToggleManufacturerStatusHandler extends AbstractManufacturerCommandHandler implements BulkToggleManufacturerStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkToggleManufacturerStatusCommand $command) - { - foreach ($command->getManufacturerIds() as $manufacturerId) { - $manufacturer = $this->getManufacturer($manufacturerId); - - if (!$this->toggleManufacturerStatus($manufacturer, $command->getExpectedStatus())) { - throw new UpdateManufacturerException(sprintf('Unable to toggle manufacturer status with id "%s"', $manufacturer->id), UpdateManufacturerException::FAILED_BULK_UPDATE_STATUS); - } - } - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/DeleteManufacturerHandler.php b/src/Adapter/Manufacturer/CommandHandler/DeleteManufacturerHandler.php deleted file mode 100644 index 45d621b7..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/DeleteManufacturerHandler.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\DeleteManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\DeleteManufacturerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\DeleteManufacturerException; - -/** - * Handles command which deletes manufacturer using legacy object model - */ -final class DeleteManufacturerHandler extends AbstractManufacturerCommandHandler implements DeleteManufacturerHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteManufacturerCommand $command) - { - $manufacturer = $this->getManufacturer($command->getManufacturerId()); - - if (!$this->deleteManufacturer($manufacturer)) { - throw new DeleteManufacturerException(sprintf('Cannot delete Manufacturer object with id "%s".', $manufacturer->id), DeleteManufacturerException::FAILED_DELETE); - } - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/EditManufacturerHandler.php b/src/Adapter/Manufacturer/CommandHandler/EditManufacturerHandler.php deleted file mode 100644 index a44ca3d1..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/EditManufacturerHandler.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use Manufacturer; -use PrestaShop\PrestaShop\Adapter\Manufacturer\AbstractManufacturerHandler; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\EditManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\EditManufacturerHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerException; -use PrestaShopException; - -/** - * Handles command which edits manufacturer using legacy object model - */ -final class EditManufacturerHandler extends AbstractManufacturerHandler implements EditManufacturerHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws ManufacturerException - */ - public function handle(EditManufacturerCommand $command) - { - $manufacturerId = $command->getManufacturerId(); - $manufacturer = $this->getManufacturer($manufacturerId); - $this->populateManufacturerWithData($manufacturer, $command); - - try { - if (false === $manufacturer->validateFields(false)) { - throw new ManufacturerException('Manufacturer contains invalid field values'); - } - - if (!$manufacturer->update()) { - throw new ManufacturerException(sprintf('Cannot update manufacturer with id "%s"', $manufacturer->id)); - } - - if (null !== $command->getAssociatedShops()) { - $this->associateWithShops($manufacturer, $command->getAssociatedShops()); - } - } catch (PrestaShopException $e) { - throw new ManufacturerException(sprintf('Cannot update manufacturer with id "%s"', $manufacturer->id)); - } - } - - /** - * Populates Manufacturer object with given data - * - * @param Manufacturer $manufacturer - * @param EditManufacturerCommand $command - */ - private function populateManufacturerWithData(Manufacturer $manufacturer, EditManufacturerCommand $command) - { - if (null !== $command->getName()) { - $manufacturer->name = $command->getName(); - } - if (null !== $command->getLocalizedShortDescriptions()) { - $manufacturer->short_description = $command->getLocalizedShortDescriptions(); - } - if (null !== $command->getLocalizedDescriptions()) { - $manufacturer->description = $command->getLocalizedDescriptions(); - } - if (null !== $command->getLocalizedMetaDescriptions()) { - $manufacturer->meta_description = $command->getLocalizedMetaDescriptions(); - } - if (null !== $command->getLocalizedMetaKeywords()) { - $manufacturer->meta_keywords = $command->getLocalizedMetaKeywords(); - } - if (null !== $command->getLocalizedMetaTitles()) { - $manufacturer->meta_title = $command->getLocalizedMetaTitles(); - } - if (null !== $command->isEnabled()) { - $manufacturer->active = $command->isEnabled(); - } - } -} diff --git a/src/Adapter/Manufacturer/CommandHandler/ToggleManufacturerStatusHandler.php b/src/Adapter/Manufacturer/CommandHandler/ToggleManufacturerStatusHandler.php deleted file mode 100644 index d8f19099..00000000 --- a/src/Adapter/Manufacturer/CommandHandler/ToggleManufacturerStatusHandler.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\ToggleManufacturerStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler\ToggleManufacturerStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\UpdateManufacturerException; - -/** - * Handles command which toggles manufacturer status - */ -final class ToggleManufacturerStatusHandler extends AbstractManufacturerCommandHandler implements ToggleManufacturerStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(ToggleManufacturerStatusCommand $command) - { - $manufacturer = $this->getManufacturer($command->getManufacturerId()); - - if (!$this->toggleManufacturerStatus($manufacturer, $command->getExpectedStatus())) { - throw new UpdateManufacturerException(sprintf('Unable to toggle manufacturer status with id "%s"', $manufacturer->id), UpdateManufacturerException::FAILED_UPDATE_STATUS); - } - } -} diff --git a/src/Adapter/Manufacturer/ManufacturerDataProvider.php b/src/Adapter/Manufacturer/ManufacturerDataProvider.php deleted file mode 100644 index a48c8dbf..00000000 --- a/src/Adapter/Manufacturer/ManufacturerDataProvider.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer; - -use Manufacturer; - -/** - * This class will provide data from DB / ORM about Manufacturer. - */ -class ManufacturerDataProvider -{ - /** - * Get all Manufacturer. - * - * @param bool $get_nb_products - * @param int $id_lang - * @param bool $active - * @param bool $p - * @param bool $n - * @param bool $all_group - * @param bool $group_by - * - * @return array Manufacturer - */ - public function getManufacturers($get_nb_products = false, $id_lang = 0, $active = true, $p = false, $n = false, $all_group = false, $group_by = false) - { - return Manufacturer::getManufacturers($get_nb_products, $id_lang, $active, $p, $n, $all_group, $group_by); - } -} diff --git a/src/Adapter/Manufacturer/ManufacturerLogoThumbnailProvider.php b/src/Adapter/Manufacturer/ManufacturerLogoThumbnailProvider.php deleted file mode 100644 index a02b4a94..00000000 --- a/src/Adapter/Manufacturer/ManufacturerLogoThumbnailProvider.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer; - -use HelperList; -use ImageManager; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; - -/** - * Provides path for manufacturer logo thumbnail - */ -final class ManufacturerLogoThumbnailProvider implements ImageProviderInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @param ImageTagSourceParserInterface $imageTagSourceParser - */ - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - } - - /** - * {@inheritdoc} - */ - public function getPath($manufacturerId) - { - $pathToImage = _PS_MANU_IMG_DIR_ . $manufacturerId . '.jpg'; - - $imageTag = ImageManager::thumbnail( - $pathToImage, - 'manufacturer_mini_' . $manufacturerId . '.jpg', - HelperList::LIST_THUMBNAIL_SIZE - ); - - return $this->imageTagSourceParser->parse($imageTag); - } -} diff --git a/src/Adapter/Manufacturer/ManufacturerProductSearchProvider.php b/src/Adapter/Manufacturer/ManufacturerProductSearchProvider.php deleted file mode 100644 index 1a2ff749..00000000 --- a/src/Adapter/Manufacturer/ManufacturerProductSearchProvider.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer; - -use Manufacturer; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Symfony\Component\Translation\TranslatorInterface; - -class ManufacturerProductSearchProvider implements ProductSearchProviderInterface -{ - private $translator; - private $manufacturer; - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator, - Manufacturer $manufacturer - ) { - $this->translator = $translator; - $this->manufacturer = $manufacturer; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * @param string $type - * - * @return array|bool - */ - private function getProductsOrCount( - ProductSearchContext $context, - ProductSearchQuery $query, - $type = 'products' - ) { - return $this->manufacturer->getProducts( - $this->manufacturer->id, - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay(), - $type !== 'products' - ); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * - * @return ProductSearchResult - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - $products = $this->getProductsOrCount($context, $query, 'products'); - $count = $this->getProductsOrCount($context, $query, 'count'); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - $this->sortOrderFactory->getDefaultSortOrders() - ); - } - - return $result; - } -} diff --git a/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForEditingHandler.php b/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForEditingHandler.php deleted file mode 100644 index 1adb4725..00000000 --- a/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForEditingHandler.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\QueryHandler; - -use ImageManager; -use PrestaShop\PrestaShop\Adapter\Manufacturer\AbstractManufacturerHandler; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryHandler\GetManufacturerForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\EditableManufacturer; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; - -/** - * Handles query which gets manufacturer for editing - */ -final class GetManufacturerForEditingHandler extends AbstractManufacturerHandler implements GetManufacturerForEditingHandlerInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - } - - /** - * {@inheritdoc} - */ - public function handle(GetManufacturerForEditing $query) - { - $manufacturerId = $query->getManufacturerId(); - $manufacturer = $this->getManufacturer($manufacturerId); - - return new EditableManufacturer( - $manufacturerId, - $manufacturer->name, - (bool) $manufacturer->active, - $manufacturer->short_description, - $manufacturer->description, - $manufacturer->meta_title, - $manufacturer->meta_description, - $manufacturer->meta_keywords, - $this->getLogoImage($manufacturerId), - $manufacturer->getAssociatedShops() - ); - } - - /** - * @param ManufacturerId $manufacturerId - * - * @return array|null - */ - private function getLogoImage(ManufacturerId $manufacturerId) - { - $pathToImage = _PS_MANU_IMG_DIR_ . $manufacturerId->getValue() . '.jpg'; - $imageTag = ImageManager::thumbnail( - $pathToImage, - 'manufacturer_' . $manufacturerId->getValue() . '.jpg', - 350, - 'jpg', - true, - true - ); - - $imageSize = file_exists($pathToImage) ? filesize($pathToImage) / 1000 : ''; - - if (empty($imageTag) || empty($imageSize)) { - return null; - } - - return [ - 'size' => sprintf('%skB', $imageSize), - 'path' => $this->imageTagSourceParser->parse($imageTag), - ]; - } -} diff --git a/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForViewingHandler.php b/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForViewingHandler.php deleted file mode 100644 index 9d36539c..00000000 --- a/src/Adapter/Manufacturer/QueryHandler/GetManufacturerForViewingHandler.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Manufacturer\QueryHandler; - -use Manufacturer; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryHandler\GetManufacturerForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\ViewableManufacturer; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; -use Product; - -/** - * Handles getting manufacturer for viewing query using legacy object model - */ -final class GetManufacturerForViewingHandler implements GetManufacturerForViewingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetManufacturerForViewing $query) - { - $manufacturer = $this->getManufacturer($query->getManufacturerId()); - - return new ViewableManufacturer( - $manufacturer->name, - $this->getManufacturerAddresses($manufacturer, $query->getLanguageId()), - $this->getManufacturerProducts($manufacturer, $query->getLanguageId()) - ); - } - - /** - * @param ManufacturerId $manufacturerId - * - * @return Manufacturer - */ - private function getManufacturer(ManufacturerId $manufacturerId) - { - $manufacturer = new Manufacturer($manufacturerId->getValue()); - - if ($manufacturer->id !== $manufacturerId->getValue()) { - throw new ManufacturerNotFoundException(sprintf('Manufacturer with id "%s" was not found.', $manufacturerId->getValue())); - } - - return $manufacturer; - } - - /** - * @param Manufacturer $manufacturer - * @param LanguageId $languageId - * - * @return array - */ - private function getManufacturerProducts(Manufacturer $manufacturer, LanguageId $languageId) - { - $products = []; - $manufacturerProducts = $manufacturer->getProductsLite($languageId->getValue()); - - foreach ($manufacturerProducts as $productData) { - $product = new Product($productData['id_product'], false, $languageId->getValue()); - $product->loadStockData(); - - $productCombinations = $product->getAttributeCombinations($languageId->getValue()); - $combinations = []; - - foreach ($productCombinations as $combination) { - $attributeId = $combination['id_product_attribute']; - - if (!isset($combinations[$attributeId])) { - $combinations[$attributeId] = [ - 'reference' => $combination['reference'], - 'ean13' => $combination['ean13'], - 'upc' => $combination['upc'], - 'mpn' => $combination['mpn'], - 'quantity' => $combination['quantity'], - 'attributes' => '', - ]; - } - - $attribute = sprintf( - '%s - %s', - $combination['group_name'], - $combination['attribute_name'] - ); - - if (!empty($combinations[$attributeId]['attributes'])) { - $attribute = sprintf(', %s', $attribute); - } - - $combinations[$attributeId]['attributes'] .= $attribute; - } - - $products[] = [ - 'id' => $product->id, - 'name' => $product->name, - 'reference' => $product->reference, - 'ean13' => $product->ean13, - 'upc' => $product->upc, - 'mpn' => $product->mpn, - 'quantity' => $product->quantity, - 'combinations' => $combinations, - ]; - } - - return $products; - } - - /** - * @param Manufacturer $manufacturer - * @param LanguageId $languageId - * - * @return array - */ - private function getManufacturerAddresses(Manufacturer $manufacturer, LanguageId $languageId) - { - $addresses = []; - $manufacturerAddresses = $manufacturer->getAddresses($languageId->getValue()); - - foreach ($manufacturerAddresses as $address) { - $addresses[] = [ - 'id' => $address['id_address'], - 'first_name' => $address['firstname'], - 'last_name' => $address['lastname'], - 'address1' => $address['address1'], - 'address2' => $address['address2'], - 'postcode' => $address['postcode'], - 'city' => $address['city'], - 'state' => $address['state'], - 'country' => $address['country'], - 'phone' => $address['phone'], - 'phone_mobile' => $address['phone_mobile'], - 'other' => $address['other'], - ]; - } - - return $addresses; - } -} diff --git a/src/Adapter/Media/MediaServerConfiguration.php b/src/Adapter/Media/MediaServerConfiguration.php deleted file mode 100644 index 87e187c3..00000000 --- a/src/Adapter/Media/MediaServerConfiguration.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Media; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class will provide Media servers configuration for a Shop. - */ -class MediaServerConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'media_server_one' => $this->configuration->get('PS_MEDIA_SERVER_1'), - 'media_server_two' => $this->configuration->get('PS_MEDIA_SERVER_2'), - 'media_server_three' => $this->configuration->get('PS_MEDIA_SERVER_3'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - $isValid = $this->validateConfiguration($configuration); - if (true === $isValid) { - $serverOne = $configuration['media_server_one']; - $serverTwo = $configuration['media_server_two']; - $serverThree = $configuration['media_server_three']; - - $this->configuration->set('PS_MEDIA_SERVER_1', $serverOne); - $this->configuration->set('PS_MEDIA_SERVER_2', $serverTwo); - $this->configuration->set('PS_MEDIA_SERVER_3', $serverThree); - - if (!empty($serverOne) || !empty($serverTwo) || !empty($serverThree)) { - $this->configuration->set('PS_MEDIA_SERVERS', 1); - } else { - $this->configuration->set('PS_MEDIA_SERVERS', 0); - } - } else { - $errors = $isValid; - } - - return $errors; - } - - /** - * {@inheritdoc} - * - * @todo: when PHP minimum version will be 7.1, use "FILTER_VALIDATE_DOMAIN" constraint. - */ - public function validateConfiguration(array $configuration) - { - $errors = []; - $serverOne = $configuration['media_server_one']; - $serverTwo = $configuration['media_server_two']; - $serverThree = $configuration['media_server_three']; - - if (!empty($serverOne) && !$this->isValidDomain($serverOne)) { - $errors[] = [ - 'key' => 'Media server #1 is invalid', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [], - ]; - } - - if (!empty($serverTwo) && !$this->isValidDomain($serverTwo)) { - $errors[] = [ - 'key' => 'Media server #2 is invalid', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [], - ]; - } - - if (!empty($serverThree) && !$this->isValidDomain($serverThree)) { - $errors[] = [ - 'key' => 'Media server #3 is invalid', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [], - ]; - } - - if (count($errors) > 0) { - return $errors; - } - - return true; - } - - /** - * To be removed once the minimum version is PHP 7.1. - * - * @param $domainName - * - * @return bool - */ - private function isValidDomain($domainName) - { - $ip = gethostbyname($domainName); - - return false !== filter_var($ip, FILTER_VALIDATE_IP); - } -} diff --git a/src/Adapter/Meta/CommandHandler/AddMetaHandler.php b/src/Adapter/Meta/CommandHandler/AddMetaHandler.php deleted file mode 100644 index 7cf16394..00000000 --- a/src/Adapter/Meta/CommandHandler/AddMetaHandler.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta\CommandHandler; - -use Meta; -use PrestaShop\PrestaShop\Adapter\Meta\MetaDataProvider; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\IsUrlRewrite; -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\AddMetaCommand; -use PrestaShop\PrestaShop\Core\Domain\Meta\CommandHandler\AddMetaHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\CannotAddMetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Class SaveMetaHandler is responsible for saving meta data. - * - * @internal - */ -final class AddMetaHandler implements AddMetaHandlerInterface -{ - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var int - */ - private $defaultLanguageId; - - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @var MetaDataProvider - */ - private $metaDataProvider; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param ValidatorInterface $validator - * @param int $defaultLanguageId - * @param MetaDataProvider $metaDataProvider - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - ValidatorInterface $validator, - $defaultLanguageId, - MetaDataProvider $metaDataProvider - ) { - $this->hookDispatcher = $hookDispatcher; - $this->defaultLanguageId = $defaultLanguageId; - $this->validator = $validator; - $this->metaDataProvider = $metaDataProvider; - } - - /** - * {@inheritdoc} - * - * @throws CannotAddMetaException - * @throws MetaException - */ - public function handle(AddMetaCommand $command) - { - $this->assertUrlRewriteHasDefaultLanguage($command); - $this->assertIsUrlRewriteValid($command); - $this->assertIsValidPageName($command); - - try { - $entity = new Meta(); - $entity->page = $command->getPageName()->getValue(); - $entity->title = $command->getLocalisedPageTitles(); - $entity->description = $command->getLocalisedMetaDescription(); - $entity->keywords = $command->getLocalisedMetaKeywords(); - - $rewriteUrls = $command->getLocalisedRewriteUrls(); - foreach ($rewriteUrls as $idLang => $rewriteUrl) { - if (!$rewriteUrl) { - $rewriteUrls[$idLang] = $rewriteUrls[$this->defaultLanguageId]; - } - } - - $entity->url_rewrite = $rewriteUrls; - $entity->add(); - - if (0 >= $entity->id) { - throw new CannotAddMetaException(sprintf('Invalid entity id after creation: %s', $entity->id)); - } - } catch (PrestaShopException $exception) { - throw new MetaException('Failed to create meta entity', 0, $exception); - } - - $this->hookDispatcher->dispatchWithParameters('actionAdminMetaSave'); - - return new MetaId((int) $entity->id); - } - - /** - * @param AddMetaCommand $command - * - * @throws MetaConstraintException - */ - private function assertUrlRewriteHasDefaultLanguage(AddMetaCommand $command) - { - $urlRewriteErrors = $this->validator->validate( - $command->getLocalisedRewriteUrls(), - new DefaultLanguage() - ); - - if (0 !== count($urlRewriteErrors) && 'index' !== $command->getPageName()->getValue()) { - throw new MetaConstraintException('The url rewrite is missing for the default language when creating new meta record', MetaConstraintException::INVALID_URL_REWRITE); - } - } - - /** - * @param AddMetaCommand $command - * - * @throws MetaConstraintException - */ - private function assertIsUrlRewriteValid(AddMetaCommand $command) - { - foreach ($command->getLocalisedRewriteUrls() as $idLang => $rewriteUrl) { - $errors = $this->validator->validate($rewriteUrl, new IsUrlRewrite()); - - if (0 !== count($errors)) { - throw new MetaConstraintException(sprintf('Url rewrite %s for language with id %s is not valid', $rewriteUrl, $idLang), MetaConstraintException::INVALID_URL_REWRITE); - } - } - } - - /** - * @param AddMetaCommand $command - * - * @throws MetaConstraintException - */ - private function assertIsValidPageName(AddMetaCommand $command) - { - $availablePages = $this->metaDataProvider->getAvailablePages(); - if (!in_array($command->getPageName()->getValue(), $availablePages, true)) { - throw new MetaConstraintException(sprintf('Given page name %s is not available. Available values are %s', $command->getPageName()->getValue(), var_export($availablePages, true)), MetaConstraintException::INVALID_PAGE_NAME); - } - } -} diff --git a/src/Adapter/Meta/CommandHandler/EditMetaHandler.php b/src/Adapter/Meta/CommandHandler/EditMetaHandler.php deleted file mode 100644 index 8fb5c9d7..00000000 --- a/src/Adapter/Meta/CommandHandler/EditMetaHandler.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta\CommandHandler; - -use Meta; -use PrestaShop\PrestaShop\Adapter\Meta\MetaDataProvider; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\IsUrlRewrite; -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\EditMetaCommand; -use PrestaShop\PrestaShop\Core\Domain\Meta\CommandHandler\EditMetaHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\CannotEditMetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaNotFoundException; -use PrestaShopException; -use Symfony\Component\Validator\Validator\ValidatorInterface; - -/** - * Class EditMetaHandler is responsible for editing meta data. - * - * @internal - */ -final class EditMetaHandler implements EditMetaHandlerInterface -{ - /** - * @var ValidatorInterface - */ - private $validator; - - /** - * @var MetaDataProvider - */ - private $metaDataProvider; - - /** - * @param ValidatorInterface $validator - * @param MetaDataProvider $metaDataProvider - */ - public function __construct( - ValidatorInterface $validator, - MetaDataProvider $metaDataProvider - ) { - $this->validator = $validator; - $this->metaDataProvider = $metaDataProvider; - } - - /** - * {@inheritdoc} - * - * @throws MetaException - */ - public function handle(EditMetaCommand $command) - { - try { - $entity = new Meta($command->getMetaId()->getValue()); - - if (0 >= $entity->id) { - throw new MetaNotFoundException(sprintf('Meta with id "%s" was not found for edit', $command->getMetaId()->getValue())); - } - - if (null !== $command->getPageName()) { - $this->assertIsValidPageName($entity->page, $command); - $entity->page = $command->getPageName()->getValue(); - } - - if (null !== $command->getLocalisedRewriteUrls()) { - $entity->url_rewrite = $command->getLocalisedRewriteUrls(); - } - - if (null !== $command->getLocalisedPageTitles()) { - $entity->title = $command->getLocalisedPageTitles(); - } - - if (null !== $command->getLocalisedMetaDescriptions()) { - $entity->description = $command->getLocalisedMetaDescriptions(); - } - - if (null !== $command->getLocalisedMetaKeywords()) { - $entity->keywords = $command->getLocalisedMetaKeywords(); - } - - $this->assertUrlRewriteHasDefaultLanguage($entity); - $this->assertIsUrlRewriteValid($entity); - - if (false === $entity->update()) { - throw new CannotEditMetaException(sprintf('Error occurred when updating Meta with id "%s"', $command->getMetaId()->getValue())); - } - } catch (PrestaShopException $exception) { - throw new CannotEditMetaException(sprintf('Error occurred when updating Meta with id "%s"', $command->getMetaId()->getValue()), 0, $exception); - } - } - - /** - * @param Meta $entity - * - * @throws MetaConstraintException - */ - private function assertUrlRewriteHasDefaultLanguage(Meta $entity) - { - $urlRewriteErrors = $this->validator->validate( - $entity->url_rewrite, - new DefaultLanguage() - ); - - if ('index' !== $entity->page && 0 !== count($urlRewriteErrors)) { - throw new MetaConstraintException('The url rewrite is missing for the default language when editing meta record', MetaConstraintException::INVALID_URL_REWRITE); - } - } - - /** - * @param Meta $entity - * - * @throws MetaConstraintException - */ - private function assertIsUrlRewriteValid(Meta $entity) - { - foreach ($entity->url_rewrite as $idLang => $rewriteUrl) { - $errors = $this->validator->validate($rewriteUrl, new IsUrlRewrite()); - - if (0 !== count($errors)) { - throw new MetaConstraintException(sprintf('Url rewrite %s for language with id %s is not valid', $rewriteUrl, $idLang), MetaConstraintException::INVALID_URL_REWRITE); - } - } - } - - /** - * @param $alreadyExistingPage - * @param EditMetaCommand $command - * - * @throws MetaConstraintException - */ - private function assertIsValidPageName($alreadyExistingPage, EditMetaCommand $command) - { - if ($command->getPageName()->getValue() === $alreadyExistingPage) { - return; - } - - $availablePages = $this->metaDataProvider->getAvailablePages(); - - if (!in_array($command->getPageName()->getValue(), $availablePages, true)) { - throw new MetaConstraintException(sprintf('Given page name %s is not available. Available values are %s', $command->getPageName()->getValue(), var_export($availablePages, true)), MetaConstraintException::INVALID_PAGE_NAME); - } - } -} diff --git a/src/Adapter/Meta/MetaDataProvider.php b/src/Adapter/Meta/MetaDataProvider.php deleted file mode 100644 index 8cf2d562..00000000 --- a/src/Adapter/Meta/MetaDataProvider.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use Db; -use DbQuery; -use Meta; -use PrestaShop\PrestaShop\Core\Meta\MetaDataProviderInterface; - -/** - * Class MetaDataProvider is responsible for providing data related with meta entity. - */ -class MetaDataProvider implements MetaDataProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getIdByPage($pageName) - { - $query = new DbQuery(); - $query->select('`id_meta`'); - $query->from('meta'); - $query->where('`page`= "' . pSQL($pageName) . '"'); - - $idMeta = 0; - $result = Db::getInstance()->getValue($query); - - if ($result) { - $idMeta = $result; - } - - return $idMeta; - } - - /** - * @return array - */ - public function getAvailablePages() - { - return Meta::getPages(true); - } - - /** - * {@inheritdoc} - */ - public function getDefaultMetaPageNameById($metaId) - { - $query = new DbQuery(); - $query->select('`page`'); - $query->from('meta'); - $query->where('`id_meta`=' . (int) $metaId); - $query->where('`page` NOT LIKE "module-%"'); - $result = Db::getInstance()->getValue($query); - - return is_string($result) ? $result : null; - } - - /** - * {@inheritdoc} - */ - public function getModuleMetaPageNameById($metaId) - { - $query = new DbQuery(); - $query->select('`page`'); - $query->from('meta'); - $query->where('`id_meta`=' . (int) $metaId); - $query->where('`page` LIKE "module-%"'); - - $result = Db::getInstance()->getValue($query); - - return is_string($result) ? $result : null; - } - - /** - * {@inheritdoc} - */ - public function getDefaultMetaPageNamesExcludingFilled() - { - $pages = Meta::getPages(true); - - $result = []; - foreach ($pages as $pageName => $fileName) { - if (!$this->isModuleFile($fileName)) { - $result[$pageName] = $fileName; - } - } - - return $result; - } - - /** - * {@inheritdoc} - */ - public function getNotConfiguredModuleMetaPageNames() - { - $pages = Meta::getPages(true); - - $result = []; - foreach ($pages as $pageName => $fileName) { - if ($this->isModuleFile($fileName)) { - $result[$pageName] = $fileName; - } - } - - return $result; - } - - /** - * Checks whenever the file contains module file pattern. - * - * @param string $fileName - * - * @return bool - */ - private function isModuleFile($fileName) - { - return 0 === strncmp($fileName, 'module-', 7); - } -} diff --git a/src/Adapter/Meta/MetaEraser.php b/src/Adapter/Meta/MetaEraser.php deleted file mode 100644 index b3e27e16..00000000 --- a/src/Adapter/Meta/MetaEraser.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use Meta; -use PrestaShopCollection; -use PrestaShopException; - -/** - * Class MetaEraser is responsible for removing data from meta entity. - */ -final class MetaEraser -{ - /** - * Erases data from meta entity. - * - * @param array $metaIds - * - * @return array - * - * @throws PrestaShopException - */ - public function erase(array $metaIds) - { - $errors = []; - - if (empty($metaIds)) { - $errors[] = [ - 'key' => 'You must select at least one element to delete.', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - - return $errors; - } - - $metaData = new PrestaShopCollection(Meta::class); - $metaData->where('id_meta', 'in', $metaIds); - - /** @var Meta $item */ - foreach ($metaData->getResults() as $item) { - if (!$item->delete()) { - $errors[] = [ - 'key' => 'Can\'t delete #%id%', - 'parameters' => [ - '%id%' => $item->id, - ], - 'domain' => 'Admin.Notifications.Error', - ]; - - continue; - } - } - - return $errors; - } -} diff --git a/src/Adapter/Meta/QueryHandler/GetMetaForEditingHandler.php b/src/Adapter/Meta/QueryHandler/GetMetaForEditingHandler.php deleted file mode 100644 index 6d47a77d..00000000 --- a/src/Adapter/Meta/QueryHandler/GetMetaForEditingHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta\QueryHandler; - -use Meta; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetMetaForEditing; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryHandler\GetMetaForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult\EditableMeta; - -/** - * Class GetMetaForEditingHandler is responsible for retrieving meta data. - * - * @internal - */ -final class GetMetaForEditingHandler implements GetMetaForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws MetaNotFoundException - */ - public function handle(GetMetaForEditing $query) - { - $metaId = $query->getMetaId(); - - $entity = new Meta($metaId->getValue()); - - if (0 >= $entity->id) { - throw new MetaNotFoundException(sprintf('Meta with id "%s" cannot be found', $metaId->getValue())); - } - - if ((int) $entity->id !== $metaId->getValue()) { - throw new MetaNotFoundException(sprintf('The retrieved id "%s" does not match requested Meta id "%s"', $entity->id, $metaId->getValue())); - } - - return new EditableMeta( - $metaId->getValue(), - $entity->page, - $entity->title, - $entity->description, - $entity->keywords, - $entity->url_rewrite - ); - } -} diff --git a/src/Adapter/Meta/QueryHandler/GetPagesForLayoutCustomizationHandler.php b/src/Adapter/Meta/QueryHandler/GetPagesForLayoutCustomizationHandler.php deleted file mode 100644 index 78cd3adb..00000000 --- a/src/Adapter/Meta/QueryHandler/GetPagesForLayoutCustomizationHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta\QueryHandler; - -use Meta; -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetPagesForLayoutCustomization; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryHandler\GetPagesForLayoutCustomizationHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult\LayoutCustomizationPage; - -/** - * Class GetMetaPagesListHandler. - */ -final class GetPagesForLayoutCustomizationHandler implements GetPagesForLayoutCustomizationHandlerInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @param int $contextLangId - */ - public function __construct($contextLangId) - { - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function handle(GetPagesForLayoutCustomization $query) - { - $metas = Meta::getAllMeta($this->contextLangId); - $pages = []; - - foreach ($metas as $meta) { - $pages[] = new LayoutCustomizationPage( - $meta['page'], - $meta['title'], - $meta['description'] - ); - } - - return $pages; - } -} diff --git a/src/Adapter/Meta/SEOOptionsDataConfiguration.php b/src/Adapter/Meta/SEOOptionsDataConfiguration.php deleted file mode 100644 index 395e8448..00000000 --- a/src/Adapter/Meta/SEOOptionsDataConfiguration.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class SEOOptionsDataConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'product_attributes_in_title' => $this->configuration->get('PS_PRODUCT_ATTRIBUTES_IN_TITLE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - try { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_PRODUCT_ATTRIBUTES_IN_TITLE', $configuration['product_attributes_in_title']); - } - } catch (CoreException $exception) { - $errors[] = $exception->getMessage(); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['product_attributes_in_title'] - ); - } -} diff --git a/src/Adapter/Meta/SetUpUrlsDataConfiguration.php b/src/Adapter/Meta/SetUpUrlsDataConfiguration.php deleted file mode 100644 index 44f9750e..00000000 --- a/src/Adapter/Meta/SetUpUrlsDataConfiguration.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\File\HtaccessFileGenerator; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class SetUpUrlsDataConfiguration is responsible for saving, validating and getting configurations related with urls - * configuration located in Shop parameters -> Traffic & Seo -> Seo & Urls. - */ -final class SetUpUrlsDataConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var HtaccessFileGenerator - */ - private $htaccessFileGenerator; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * SetUpUrlsDataConfiguration constructor. - * - * @param Configuration $configuration - * @param HtaccessFileGenerator $htaccessFileGenerator - * @param TranslatorInterface $translator - */ - public function __construct( - Configuration $configuration, - HtaccessFileGenerator $htaccessFileGenerator, - TranslatorInterface $translator - ) { - $this->configuration = $configuration; - $this->htaccessFileGenerator = $htaccessFileGenerator; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'friendly_url' => $this->configuration->getBoolean('PS_REWRITING_SETTINGS'), - 'accented_url' => $this->configuration->getBoolean('PS_ALLOW_ACCENTED_CHARS_URL'), - 'canonical_url_redirection' => $this->configuration->get('PS_CANONICAL_REDIRECT'), - 'disable_apache_multiview' => $this->configuration->getBoolean('PS_HTACCESS_DISABLE_MULTIVIEWS'), - 'disable_apache_mod_security' => $this->configuration->getBoolean('PS_HTACCESS_DISABLE_MODSEC'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_REWRITING_SETTINGS', $configuration['friendly_url']); - $this->configuration->set('PS_ALLOW_ACCENTED_CHARS_URL', $configuration['accented_url']); - $this->configuration->set('PS_CANONICAL_REDIRECT', $configuration['canonical_url_redirection']); - $this->configuration->set('PS_HTACCESS_DISABLE_MULTIVIEWS', $configuration['disable_apache_multiview']); - $this->configuration->set('PS_HTACCESS_DISABLE_MODSEC', $configuration['disable_apache_mod_security']); - - if (!$this->htaccessFileGenerator->generateFile($configuration['disable_apache_multiview'])) { - $this->configuration->set('PS_REWRITING_SETTINGS', 0); - - $errorMessage = $this->translator - ->trans( - 'Before being able to use this tool, you need to:', - [], - 'Admin.Shopparameters.Notification' - ); - - $errorMessage .= ' '; - $errorMessage .= $this->translator - ->trans( - 'Create a blank .htaccess in your root directory.', - [], - 'Admin.Shopparameters.Notification' - ); - - $errorMessage .= ' '; - $errorMessage .= $this->translator - ->trans( - 'Give it write permissions (CHMOD 666 on Unix system).', - [], - 'Admin.Shopparameters.Notification' - ); - - $errors[] = $errorMessage; - } - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['friendly_url'], - $configuration['accented_url'], - $configuration['canonical_url_redirection'], - $configuration['disable_apache_multiview'], - $configuration['disable_apache_mod_security'] - ); - } -} diff --git a/src/Adapter/Meta/ShopUrlDataConfiguration.php b/src/Adapter/Meta/ShopUrlDataConfiguration.php deleted file mode 100644 index 64c9d0d3..00000000 --- a/src/Adapter/Meta/ShopUrlDataConfiguration.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use PrestaShop\PrestaShop\Adapter\File\HtaccessFileGenerator; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShopException; -use ShopUrl; - -/** - * Class ShopUrlDataConfiguration is responsible for updating and getting data from shop_url table. - */ -final class ShopUrlDataConfiguration implements DataConfigurationInterface -{ - /** - * @var ShopUrl - */ - private $mainShopUrl; - - /** - * @var HtaccessFileGenerator - */ - private $htaccessFileGenerator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * ShopUrlDataConfiguration constructor. - * - * @param ShopUrl $mainShopUrl - * @param ConfigurationInterface $configuration - */ - public function __construct( - ShopUrl $mainShopUrl, - ConfigurationInterface $configuration, - HtaccessFileGenerator $htaccessFileGenerator - ) { - $this->mainShopUrl = $mainShopUrl; - $this->configuration = $configuration; - $this->htaccessFileGenerator = $htaccessFileGenerator; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'domain' => $this->mainShopUrl->domain, - 'domain_ssl' => $this->mainShopUrl->domain_ssl, - 'physical_uri' => $this->mainShopUrl->physical_uri, - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - try { - if ($this->validateConfiguration($configuration)) { - $this->mainShopUrl->domain = $configuration['domain']; - $this->mainShopUrl->domain_ssl = $configuration['domain_ssl']; - - if (is_string($configuration['physical_uri'])) { - $this->mainShopUrl->physical_uri = $configuration['physical_uri']; - } - - $this->mainShopUrl->update(); - - $this->configuration->set('PS_SHOP_DOMAIN', $configuration['domain']); - $this->configuration->set('PS_SHOP_DOMAIN_SSL', $configuration['domain_ssl']); - $this->htaccessFileGenerator->generateFile(); - } - } catch (PrestaShopException $exception) { - $errors[] = $exception->getMessage(); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['domain'], - $configuration['domain_ssl'] - ) && $this->isValidUri($configuration['physical_uri']); - } - - /** - * Check if it's a valid URI. - * - * @param string $uri - * - * @return bool - */ - private function isValidUri($uri) - { - return preg_match('#^(?:[~\-_\/&\.]|\w|%\d+|\s)+$#', $uri); - } -} diff --git a/src/Adapter/Meta/UrlSchemaDataConfiguration.php b/src/Adapter/Meta/UrlSchemaDataConfiguration.php deleted file mode 100644 index 78722fb2..00000000 --- a/src/Adapter/Meta/UrlSchemaDataConfiguration.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Meta; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class UrlSchemaDataConfiguration is responsible for validating, updating and retrieving data used in - * Shop parameters -> Traffix & Seo -> Seo & Urls -> Set Shop URL form field. - */ -final class UrlSchemaDataConfiguration implements DataConfigurationInterface -{ - /** - * @var array - */ - private $rules; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * UrlSchemaDataConfiguration constructor. - * - * @param ConfigurationInterface $configuration - * @param array $rules - */ - public function __construct(ConfigurationInterface $configuration, array $rules) - { - $this->rules = $rules; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - $configResult = []; - foreach ($this->rules as $routeId => $defaultRule) { - $result = $this->getConfigurationValue($routeId) ?: $defaultRule; - $configResult[$routeId] = $result; - } - - return $configResult; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - foreach ($configuration as $routeId => $value) { - $this->updateConfigurationValue($routeId, $value); - } - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $configurationExists = true; - foreach (array_keys($configuration) as $routeId) { - $configurationExists &= isset($this->rules[$routeId]); - } - - return $configurationExists; - } - - /** - * Gets configuration from configuration table. - * - * @param string $routeId - * - * @return string - */ - private function getConfigurationValue($routeId) - { - return $this->configuration->get($this->getConfigurationKey($routeId)); - } - - /** - * Updates configuration data. - * - * @param string $routeId - * @param string $rule - * - * @return mixed - */ - private function updateConfigurationValue($routeId, $rule) - { - return $this->configuration->set($this->getConfigurationKey($routeId), $rule); - } - - /** - * Gets key which is used to retrieve data from configuration table. - * - * @param string $routeId - * - * @return string - */ - private function getConfigurationKey($routeId) - { - return sprintf('PS_ROUTE_%s', $routeId); - } -} diff --git a/src/Adapter/Module/AdminModuleDataProvider.php b/src/Adapter/Module/AdminModuleDataProvider.php deleted file mode 100644 index 58053b93..00000000 --- a/src/Adapter/Module/AdminModuleDataProvider.php +++ /dev/null @@ -1,520 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use Context; -use Doctrine\Common\Cache\CacheProvider; -use Employee; -use Module as LegacyModule; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterOrigin; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface; -use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider; -use PrestaShopBundle\Service\DataProvider\Admin\ModuleInterface; -use Psr\Log\LoggerInterface; -use Symfony\Component\Routing\Router; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -/** - * Data provider for new Architecture, about Module object model. - * - * This class will provide data from DB / ORM about Modules for the Admin interface. - * This is an Adapter that works with the Legacy code and persistence behaviors. - */ -class AdminModuleDataProvider implements ModuleInterface -{ - const _CACHEKEY_MODULES_ = '_addons_modules'; - - const _DAY_IN_SECONDS_ = 86400; /* Cache for One Day */ - - /** - * @const array giving a translation domain key for each module action - */ - const _ACTIONS_TRANSLATION_DOMAINS_ = [ - 'install' => 'Admin.Actions', - 'uninstall' => 'Admin.Actions', - 'enable' => 'Admin.Actions', - 'disable' => 'Admin.Actions', - 'enable_mobile' => 'Admin.Modules.Feature', - 'disable_mobile' => 'Admin.Modules.Feature', - 'reset' => 'Admin.Actions', - 'upgrade' => 'Admin.Actions', - 'configure' => 'Admin.Actions', - ]; - - /** - * @var array of defined and callable module actions - */ - protected $moduleActions = ['install', 'uninstall', 'enable', 'disable', 'enable_mobile', 'disable_mobile', 'reset', 'upgrade']; - - /** - * @var int - */ - private $languageISO; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var Router|null - */ - private $router = null; - - /** - * @var AddonsInterface - */ - private $addonsDataProvider; - - /** - * @var CategoriesProvider - */ - private $categoriesProvider; - - /** - * @var ModuleDataProvider - */ - private $moduleProvider; - - /** - * @var CacheProvider - */ - private $cacheProvider; - - /** - * @var Employee - */ - private $employee; - - /** - * @var array - */ - protected $catalog_modules = []; - - /** - * @var array - */ - protected $catalog_modules_names; - - /** - * @var bool - */ - public $failed = false; - - public function __construct( - TranslatorInterface $translator, - LoggerInterface $logger, - AddonsInterface $addonsDataProvider, - CategoriesProvider $categoriesProvider, - ModuleDataProvider $modulesProvider, - CacheProvider $cacheProvider = null, - Employee $employee = null - ) { - list($this->languageISO) = explode('-', $translator->getLocale()); - - $this->logger = $logger; - $this->addonsDataProvider = $addonsDataProvider; - $this->categoriesProvider = $categoriesProvider; - $this->moduleProvider = $modulesProvider; - $this->cacheProvider = $cacheProvider; - $this->employee = $employee; - } - - /** - * @param Router $router - */ - public function setRouter(Router $router) - { - $this->router = $router; - } - - /** - * Clear the modules information from Addons cache. - */ - public function clearCatalogCache() - { - if ($this->cacheProvider) { - $this->cacheProvider->delete($this->languageISO . self::_CACHEKEY_MODULES_); - } - $this->catalog_modules = []; - } - - /** - * Clears module list cache. - */ - public function clearModuleListCache() - { - if (file_exists(LegacyModule::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST)) { - @unlink(LegacyModule::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST); - } - } - - /** - * @deprecated since version 1.7.3.0 - * - * @return array - */ - public function getAllModules() - { - return LegacyModule::getModulesOnDisk( - true, - $this->addonsDataProvider->isAddonsAuthenticated(), - (int) Context::getContext()->employee->id - ); - } - - /** - * @param array $filters - * - * @return array - */ - public function getCatalogModules(array $filters = []) - { - if (count($this->catalog_modules) === 0 && !$this->failed) { - $this->loadCatalogData(); - } - - return $this->applyModuleFilters( - $this->catalog_modules, - $filters - ); - } - - /** - * @param array $filter - * - * @return array - */ - public function getCatalogModulesNames(array $filter = []) - { - return array_keys($this->getCatalogModules($filter)); - } - - /** - * Check the permissions of the current context (CLI or employee) for a module. - * - * @param array $actions Actions to check - * @param string $name The module name - * - * @return array of allowed actions - */ - protected function filterAllowedActions(array $actions, $name = '') - { - $allowedActions = []; - foreach (array_keys($actions) as $actionName) { - if ($this->isAllowedAccess($actionName, $name)) { - $allowedActions[$actionName] = $actions[$actionName]; - } - } - - return $allowedActions; - } - - /** - * Check the permissions of the current context (CLI or employee) for a specified action. - * - * @param string $action The action called in the module - * @param string $name (Optionnal for 'install') The module name to check - * - * @return bool - */ - public function isAllowedAccess($action, $name = '') - { - if (Tools::isPHPCLI()) { - return true; - } - - if (in_array($action, ['install', 'upgrade'])) { - return $this->employee->can('add', 'AdminModulessf'); - } - - if ('uninstall' === $action) { - return $this->employee->can('delete', 'AdminModulessf') && $this->moduleProvider->can('uninstall', $name); - } - - return $this->employee->can('edit', 'AdminModulessf') && $this->moduleProvider->can('configure', $name); - } - - /** - * @param AddonsCollection $addons - * @param string|null $specific_action - * - * @return AddonsCollection - */ - public function generateAddonsUrls(AddonsCollection $addons, $specific_action = null) - { - foreach ($addons as $addon) { - $urls = []; - foreach ($this->moduleActions as $action) { - $urls[$action] = $this->router->generate('admin_module_manage_action', [ - 'action' => $action, - 'module_name' => $addon->attributes->get('name'), - ]); - } - $urls['configure'] = $this->router->generate('admin_module_configure_action', [ - 'module_name' => $addon->attributes->get('name'), - ]); - - if ($addon->database->has('installed') && $addon->database->getBoolean('installed')) { - if (!$addon->database->getBoolean('active')) { - $url_active = 'enable'; - unset( - $urls['install'], - $urls['disable'] - ); - } elseif ($addon->attributes->getBoolean('is_configurable')) { - $url_active = 'configure'; - unset( - $urls['enable'], - $urls['install'] - ); - } else { - $url_active = 'disable'; - unset( - $urls['install'], - $urls['enable'], - $urls['configure'] - ); - } - - if (!$addon->attributes->getBoolean('is_configurable')) { - unset($urls['configure']); - } - - if ($addon->canBeUpgraded()) { - $url_active = 'upgrade'; - } else { - unset( - $urls['upgrade'] - ); - } - if (!$addon->database->getBoolean('active_on_mobile')) { - unset($urls['disable_mobile']); - } else { - unset($urls['enable_mobile']); - } - if (!$addon->canBeUpgraded()) { - unset( - $urls['upgrade'] - ); - } - } elseif ( - !$addon->attributes->has('origin') || - $addon->disk->getBoolean('is_present') || - in_array($addon->attributes->get('origin'), ['native', 'native_all', 'partner', 'customer'], true) - ) { - $url_active = 'install'; - unset( - $urls['uninstall'], - $urls['enable'], - $urls['disable'], - $urls['enable_mobile'], - $urls['disable_mobile'], - $urls['reset'], - $urls['upgrade'], - $urls['configure'] - ); - } else { - $url_active = 'buy'; - } - - $urls = $this->filterAllowedActions($urls, $addon->attributes->get('name')); - $addon->attributes->set('urls', $urls); - $addon->attributes->set('actionTranslationDomains', self::_ACTIONS_TRANSLATION_DOMAINS_); - if ($specific_action && array_key_exists($specific_action, $urls)) { - $addon->attributes->set('url_active', $specific_action); - } elseif ($url_active === 'buy' || array_key_exists($url_active, $urls)) { - $addon->attributes->set('url_active', $url_active); - } else { - $addon->attributes->set('url_active', key($urls)); - } - - $categoryParent = $this->categoriesProvider->getParentCategory($addon->attributes->get('categoryName')); - $addon->attributes->set('categoryParent', $categoryParent); - } - - return $addons; - } - - /** - * @param $moduleId - * - * @return array - */ - public function getModuleAttributesById($moduleId) - { - return (array) $this->addonsDataProvider->request('module', ['id_module' => $moduleId]); - } - - /** - * @param array $modules - * @param array $filters - * - * @return array - */ - protected function applyModuleFilters(array $modules, array $filters) - { - if (!count($filters)) { - return $modules; - } - - // We get our module IDs to keep - foreach ($filters as $filter_name => $value) { - $search_result = []; - - switch ($filter_name) { - case 'search': - // We build our results array. - // We could remove directly the non-matching modules, but we will give that for the final loop of this function - - foreach (explode(' ', $value) as $keyword) { - if (empty($keyword)) { - continue; - } - - // Instead of looping on the whole module list, we use $module_ids which can already be reduced - // thanks to the previous array_intersect(...) - foreach ($modules as $key => $module) { - if (strpos($module->displayName, $keyword) !== false - || strpos($module->name, $keyword) !== false - || strpos($module->description, $keyword) !== false) { - $search_result[] = $key; - } - } - } - - break; - case 'name': - // exact given name (should return 0 or 1 result) - $search_result[] = $value; - - break; - default: - // "the switch statement is considered a looping structure for the purposes of continue." - continue 2; - } - - $modules = array_intersect_key($modules, array_flip($search_result)); - } - - return $modules; - } - - /** - * Load module catalogue. If not in cache, query Addons API. - */ - protected function loadCatalogData() - { - if ($this->cacheProvider && $this->cacheProvider->contains($this->languageISO . self::_CACHEKEY_MODULES_)) { - $this->catalog_modules = $this->cacheProvider->fetch($this->languageISO . self::_CACHEKEY_MODULES_); - } - - if (!$this->catalog_modules) { - $params = ['format' => 'json']; - $requests = [ - AddonListFilterOrigin::ADDONS_MUST_HAVE => 'must-have', - AddonListFilterOrigin::ADDONS_SERVICE => 'service', - AddonListFilterOrigin::ADDONS_NATIVE => 'native', - AddonListFilterOrigin::ADDONS_NATIVE_ALL => 'native_all', - ]; - if ($this->addonsDataProvider->isAddonsAuthenticated()) { - $requests[AddonListFilterOrigin::ADDONS_CUSTOMER] = 'customer'; - } - - try { - $listAddons = []; - // We execute each addons request - foreach ($requests as $action_filter_value => $action) { - if (!$this->addonsDataProvider->isAddonsUp()) { - continue; - } - // We add the request name in each product returned by Addons, - // so we know whether is bought - - $addons = $this->addonsDataProvider->request($action, $params); - foreach ($addons as $addonsType => $addon) { - if (empty($addon->name)) { - $this->logger->error(sprintf('The addon with id %s does not have name.', $addon->id)); - - continue; - } - - $addon->origin = $action; - $addon->origin_filter_value = $action_filter_value; - $addon->categoryParent = $this->categoriesProvider - ->getParentCategory($addon->categoryName); - if (isset($addon->version)) { - $addon->version_available = $addon->version; - } - if (!isset($addon->product_type)) { - $addon->productType = isset($addonsType) ? rtrim($addonsType, 's') : 'module'; - } else { - $addon->productType = $addon->product_type; - } - $listAddons[$addon->name] = $addon; - } - } - - if (!empty($listAddons)) { - $this->catalog_modules = $listAddons; - if ($this->cacheProvider) { - $this->cacheProvider->save($this->languageISO . self::_CACHEKEY_MODULES_, $this->catalog_modules, self::_DAY_IN_SECONDS_); - } - } else { - $this->fallbackOnCatalogCache(); - } - } catch (\Exception $e) { - if (!$this->fallbackOnCatalogCache()) { - $this->logger->error('Data from PrestaShop Addons is invalid, and cannot fallback on cache. ', ['exception' => $e->getMessage()]); - } - } - } - } - - /** - * If cache exists, get the Catalogue from the cache. - * - * @return array Module loaded from the cache - */ - protected function fallbackOnCatalogCache() - { - // Fallback on data from cache if exists - if ($this->cacheProvider) { - $this->catalog_modules = $this->cacheProvider->fetch($this->languageISO . self::_CACHEKEY_MODULES_); - } - - if (!$this->catalog_modules) { - $this->catalog_modules = []; - } - - $this->failed = true; - - return $this->catalog_modules; - } -} diff --git a/src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php b/src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php deleted file mode 100644 index 3c779ef5..00000000 --- a/src/Adapter/Module/Configuration/ModuleComplexConfigurationInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Configuration; - -use PrestaShop\PrestaShop\Adapter\Module\Module; - -/** - * @todo: document what is the contract of this interface. - */ -interface ModuleComplexConfigurationInterface -{ - /** - * @param Module $module - * @param array $params - * - * @return mixed - */ - public function run(Module $module, array $params); -} diff --git a/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php b/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php deleted file mode 100644 index e3097799..00000000 --- a/src/Adapter/Module/Configuration/ModuleSelfConfigurator.php +++ /dev/null @@ -1,506 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Configuration; - -use Doctrine\DBAL\Connection; -use Exception; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Process\Exception\InvalidArgumentException; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Yaml; - -/** - * This class allow system users and developers to configure their module - * with a single config file. - * - * Use validate() to check everything is ready to run. - * Use configure() to run the configuration with the provided parameters. - */ -class ModuleSelfConfigurator -{ - /** - * @var string|null the module name - */ - protected $module; - - /** - * @var string|null - */ - protected $configFile; - - /** - * @var array - */ - protected $configs = []; - - /** - * @var string - */ - protected $defaultConfigFile = 'self_config.yml'; - - /** - * @var ModuleRepository - */ - protected $moduleRepository; - - /** - * @var Configuration - */ - protected $configuration; - - /** - * @var Connection - */ - protected $connection; - - /** - * @var Filesystem - */ - protected $filesystem; - - public function __construct( - ModuleRepository $moduleRepository, - Configuration $configuration, - Connection $connection, - Filesystem $filesystem - ) { - $this->module = null; - $this->configFile = null; - - $this->moduleRepository = $moduleRepository; - $this->configuration = $configuration; - $this->connection = $connection; - $this->filesystem = $filesystem; - } - - /** - * Alias for $module setter. - * - * @param string $name - * - * @return $this - */ - public function module($name) - { - return $this->setModule($name); - } - - /** - * Set the module to be updated with its name. - * - * @param string $name - * - * @return $this - * - * @throws UnexpectedTypeException - */ - public function setModule($name) - { - if (!is_string($name)) { - throw new UnexpectedTypeException($name, 'string'); - } - $this->module = $name; - - return $this; - } - - /** - * If defined, get the config file path or if possible, guess it. - * - * @return string|null - * - * @throws InvalidArgumentException - */ - public function getFile() - { - // If set, return it - if ($this->configFile) { - return $this->configFile; - } - - // If we do not know in which module to search, we cannot go further - if (!$this->module) { - return null; - } - - // Find and store the first config file we find - $files = Finder::create() - ->files() - ->in(_PS_MODULE_DIR_ . $this->module) - ->name($this->defaultConfigFile, null, true); - - foreach ($files as $file) { - $this->configFile = $file->getRealPath(); - - return $this->configFile; - } - - return null; - } - - /** - * Alias for config file setter. - * - * @param string $filepath - * - * @return $this - */ - public function file($filepath) - { - return $this->setFile($filepath); - } - - /** - * Set the config file to parse. - * - * @param string $filepath - * - * @return $this - * - * @throws UnexpectedTypeException - */ - public function setFile($filepath) - { - if (!is_string($filepath)) { - throw new UnexpectedTypeException($filepath, 'string'); - } - - $this->configFile = $filepath; - - return $this; - } - - /** - * In order to prevent some failure, we can check all pre-requesites are respected. - * Any error will be reported in the array. - * - * @return array - */ - public function validate() - { - $errors = []; - if ($this->module === null) { - $errors[] = 'Module name not specified'; - } - - try { - $file = $this->getFile(); - } catch (InvalidArgumentException $e) { - $errors[] = $e->getMessage(); - $file = null; - } - - if ($file === null) { - $errors[] = 'No config file to apply'; - } elseif (!file_exists($file)) { - $errors[] = 'Specified config file is not found'; - } else { - try { - $config = $this->loadYmlFile($file); - } catch (ParseException $e) { - $errors[] = $e->getMessage(); - } - - if (empty($config)) { - $errors[] = 'Parsed config file is empty'; - } - } - - if (!$this->module || !$this->moduleRepository->getModule($this->module)->hasValidInstance()) { - $errors[] = 'The module specified is invalid'; - } - - return $errors; - } - - /** - * Launch the self configuration with all the context previously set! - * - * @return bool - */ - public function configure() - { - if (count($this->validate())) { - return false; - } - $config = $this->loadYmlFile($this->getFile()); - - $this->runConfigurationStep($config); - $this->runFilesStep($config); - $this->runSqlStep($config); - $this->runPhpStep($config); - - return true; - } - - // PROTECTED ZONE - - /** - * Helper function which adds the relative path from the YML config file. - * Do not alter URLs. - * - * @param string $file - * - * @return string - */ - protected function convertRelativeToAbsolutePaths($file) - { - // If we do not deal with any kind of URL, add the path to the YML config file - if (!filter_var($file, FILTER_VALIDATE_URL)) { - $file = dirname($this->getFile()) . '/' . $file; - } - - return $file; - } - - /** - * Finds and returns filepath from a config key in the YML config file. - * Can be a string of a value of "file" key. - * - * @param array $data - * - * @return string - * - * @throws Exception if file data not provided - */ - protected function extractFilePath($data) - { - if (is_scalar($data)) { - $file = $data; - } elseif (is_array($data) && !empty($data['file'])) { - $file = $data['file']; - } else { - throw new Exception('Missing file path'); - } - - return $this->convertRelativeToAbsolutePaths($file); - } - - /** - * Require a PHP file and instanciate the class of the same name in it. - * - * @param string $file - * - * @return stdClass - */ - protected function loadPhpFile($file) - { - // Load file - require_once $file; - - // Load class of same name as the file - $className = pathinfo($file, PATHINFO_FILENAME); - - return new $className(); - } - - /** - * Parse and return the YML content. - * - * @param string $file - * - * @return array - */ - protected function loadYmlFile($file) - { - if (array_key_exists($file, $this->configs)) { - return $this->configs[$file]; - } - $this->configs[$file] = Yaml::parse(file_get_contents($file)); - - return $this->configs[$file]; - } - - /** - * Run configuration for "configuration" step. - * - * @param array $config - */ - protected function runConfigurationStep($config) - { - if (empty($config['configuration'])) { - return; - } - - if (array_key_exists('update', $config['configuration'])) { - $this->runConfigurationUpdate($config['configuration']['update']); - } - - if (array_key_exists('delete', $config['configuration'])) { - $this->runConfigurationDelete($config['configuration']['delete']); - } - } - - /** - * Run configuration for "file" step. - * - * @param array $config - */ - protected function runFilesStep($config) - { - if (empty($config['files'])) { - return; - } - - foreach ($config['files'] as $copy) { - if (empty($copy['source'])) { - throw new Exception('Missing source file'); - } - if (empty($copy['dest'])) { - throw new Exception('Missing destination file'); - } - - // If we get a relative path from the yml, add the original path - foreach (['source', 'dest'] as $prop) { - $copy[$prop] = $this->convertRelativeToAbsolutePaths($copy[$prop]); - } - - $this->filesystem->copy( - $copy['source'], - $copy['dest'] - ); - } - } - - /** - * Run configuration for "php" step. - * - * @param array $config - */ - protected function runPhpStep($config) - { - if (empty($config['php'])) { - return; - } - - foreach ($config['php'] as $data) { - $file = $this->extractFilePath($data); - - $module = $this->moduleRepository->getModule($this->module); - $params = !empty($data['params']) ? $data['params'] : []; - - $this->loadPhpFile($file)->run($module, $params); - } - } - - /** - * Run configuration for "sql" step. - * - * @param array $config - */ - protected function runSqlStep($config) - { - if (empty($config['sql'])) { - return; - } - - // Avoid unconsistant state with transactions - $this->connection->beginTransaction(); - - try { - foreach ($config['sql'] as $data) { - $this->runSqlFile($data); - } - $this->connection->commit(); - } catch (Exception $e) { - $this->connection->rollBack(); - - throw $e; - } - } - - /** - * Subtask of Sql step. Get and prepare all SQL requests from a file. - * - * @param array $data - */ - protected function runSqlFile($data) - { - $content = file_get_contents($this->extractFilePath($data)); - - foreach (explode(';', $content) as $sql) { - $sql = trim($sql); - if (empty($sql)) { - continue; - } - - // Set _DB_PREFIX_ - $sql = str_replace( - [ - 'PREFIX_', - 'DB_NAME', - ], - [ - $this->configuration->get('_DB_PREFIX_'), - $this->configuration->get('_DB_NAME_'), - ], - $sql - ); - - $stmt = $this->connection->prepare($sql); - $stmt->execute(); - } - } - - /** - * Subtask of configuration step, for all configuration key to update. - * - * @param array $config - * - * @throws Exception - */ - protected function runConfigurationUpdate($config) - { - foreach ($config as $key => $data) { - if (is_array($data) && isset($data['value'])) { - $value = $data['value']; - } elseif (is_scalar($data)) { - // string / integer / decimal / bool - $value = $data; - } else { - throw new Exception(sprintf('No value given for key %s', $key)); - } - $this->configuration->set($key, $value); - } - } - - /** - * Subtask of configuration step, for all configuration keys to delete. - * - * @param array $config - */ - protected function runConfigurationDelete($config) - { - foreach ($config as $key) { - $this->configuration->delete($key); - } - } -} diff --git a/src/Adapter/Module/Module.php b/src/Adapter/Module/Module.php deleted file mode 100644 index 54ecd62f..00000000 --- a/src/Adapter/Module/Module.php +++ /dev/null @@ -1,483 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use Module as LegacyModule; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterOrigin; -use PrestaShop\PrestaShop\Core\Addon\Module\AddonListFilterDeviceStatus; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleInterface; -use Symfony\Component\HttpFoundation\ParameterBag; - -/** - * This class is the interface to the legacy Module class. - * - * It will allow current modules to work even with the new ModuleManager - */ -class Module implements ModuleInterface -{ - const ACTION_INSTALL = 'install'; - const ACTION_UNINSTALL = 'uninstall'; - const ACTION_ENABLE = 'enable'; - const ACTION_DISABLE = 'disable'; - const ACTION_ENABLE_MOBILE = 'enable_mobile'; - const ACTION_DISABLE_MOBILE = 'disable_mobile'; - const ACTION_RESET = 'reset'; - const ACTION_UPGRADE = 'upgrade'; - - /** @var LegacyModule Module The instance of the legacy module */ - public $instance = null; - - /** - * Module attributes (name, displayName etc.). - * - * @var \Symfony\Component\HttpFoundation\ParameterBag - */ - public $attributes; - - /** - * Module attributes from disk. - * - * @var \Symfony\Component\HttpFoundation\ParameterBag - */ - public $disk; - - /** - * Module attributes from database. - * - * @var \Symfony\Component\HttpFoundation\ParameterBag - */ - public $database; - - /** - * Default values for ParameterBag attributes. - * - * @var array - */ - private $attributes_default = [ - 'id' => 0, - 'name' => '', - 'categoryName' => '', - 'displayName' => '', - 'version' => null, - 'description' => '', - 'author' => '', - 'author_uri' => false, - 'tab' => 'others', - 'is_configurable' => 0, - 'need_instance' => 0, - 'limited_countries' => [], - 'parent_class' => 'Module', - 'is_paymentModule' => false, - 'productType' => 'module', - 'warning' => '', - 'img' => '', - 'badges' => [], - 'cover' => [], - 'screenshotsUrls' => [], - 'videoUrl' => null, - 'refs' => ['unknown'], - 'price' => [ - 'EUR' => 0, - 'USD' => 0, - 'GBP' => 0, - ], - 'type' => '', - // From the marketplace - 'url' => null, - 'avgRate' => 0, - 'nbRates' => 0, - 'fullDescription' => '', - 'confirmUninstall' => '', - ]; - - /** - * Default values for ParameterBag disk. - * - * @var array - */ - private $disk_default = [ - 'filemtype' => 0, - 'is_present' => 0, - 'is_valid' => 0, - 'version' => null, - 'path' => '', - ]; - - /** - * Default values for ParameterBag database. - * - * @var array - */ - private $database_default = [ - 'installed' => 0, - 'active' => 0, - 'active_on_mobile' => true, - 'version' => null, - 'last_access_date' => '0000-00-00 00:00:00', - 'date_add' => null, - 'date_upd' => null, - ]; - - /** - * @param array $attributes - * @param array $disk - * @param array $database - */ - public function __construct(array $attributes = [], array $disk = [], array $database = []) - { - $this->attributes = new ParameterBag($this->attributes_default); - $this->disk = new ParameterBag($this->disk_default); - $this->database = new ParameterBag($this->database_default); - // Set all attributes - $this->attributes->add($attributes); - $this->disk->add($disk); - $this->database->add($database); - - if ($this->database->get('installed')) { - $version = $this->database->get('version'); - } elseif (null === $this->attributes->get('version') && $this->disk->get('is_valid')) { - $version = $this->disk->get('version'); - } else { - $version = $this->attributes->get('version'); - } - - if (!$this->attributes->has('version_available')) { - $this->attributes->set('version_available', $this->disk->get('version')); - } - - $this->fillLogo(); - - $this->attributes->set('version', $version); - $this->attributes->set('type', $this->convertType($this->get('origin_filter_value'))); - - // Unfortunately, we can sometime have an array, and sometimes an object. - // This is the first place where this value *always* exists - $this->attributes->set('price', (array) $this->attributes->get('price')); - } - - /** - * @return legacyInstance|void - * - * @throws \Exception - */ - public function getInstance() - { - if (!$this->hasValidInstance()) { - return; - } - - return $this->instance; - } - - /** - * @return bool True if valid Module instance - */ - public function hasValidInstance() - { - if (($this->disk->has('is_present') && $this->disk->getBoolean('is_present') === false) - || ($this->disk->has('is_valid') && $this->disk->getBoolean('is_valid') === false) - ) { - return false; - } - - if ($this->instance === null) { - // We try to instantiate the legacy class if not done yet - try { - $this->instanciateLegacyModule($this->attributes->get('name')); - } catch (\Exception $e) { - $this->disk->set('is_valid', false); - - return false; - } - } - - $this->disk->set('is_valid', $this->instance instanceof LegacyModule); - - return $this->disk->get('is_valid'); - } - - /** - * @return bool - */ - public function isActive() - { - return (bool) $this->database->get('active'); - } - - /** - * {@inheritdoc} - */ - public function onInstall() - { - if (!$this->hasValidInstance()) { - return false; - } - - // If not modified, code used in installer is executed: - // "Notice: Use of undefined constant _PS_INSTALL_LANGS_PATH_ - assumed '_PS_INSTALL_LANGS_PATH_'" - LegacyModule::updateTranslationsAfterInstall(false); - - // Casted to Boolean, because some modules returns 1 instead true and 0 instead false. - // Other value types are not expected. See also: https://github.com/PrestaShop/PrestaShop/pull/11442#issuecomment-440485268 - // The best way is to check for non Boolean type and `throw \UnexpectedValueException`, - // but it's need much refactoring and testing. - // TODO: refactoring. - $result = (bool) $this->instance->install(); - - $this->database->set('installed', $result); - $this->database->set('active', $result); - $this->database->set('version', $this->attributes->get('version')); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onUninstall() - { - if (!$this->hasValidInstance()) { - return false; - } - - $result = $this->instance->uninstall(); - $this->database->set('installed', !$result); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onUpgrade($version) - { - $this->database->set('version', $this->attributes->get('version_available')); - - return true; - } - - /** - * {@inheritdoc} - */ - public function onEnable() - { - if (!$this->hasValidInstance()) { - return false; - } - - $result = $this->instance->enable(); - $this->database->set('active', $result); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onDisable() - { - if (!$this->hasValidInstance()) { - return false; - } - - $result = $this->instance->disable(); - $this->database->set('active', !$result); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onMobileEnable() - { - if (!$this->hasValidInstance()) { - return false; - } - - $result = $this->instance->enableDevice(AddonListFilterDeviceStatus::DEVICE_MOBILE); - $this->database->set('active_on_mobile', $result); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onMobileDisable() - { - if (!$this->hasValidInstance()) { - return false; - } - - $result = $this->instance->disableDevice(AddonListFilterDeviceStatus::DEVICE_MOBILE); - $this->database->set('active_on_mobile', !$result); - - return $result; - } - - /** - * {@inheritdoc} - */ - public function onReset() - { - if (!$this->hasValidInstance()) { - return false; - } - - return $this->instance->reset(); - } - - /** - * Retrieve an instance of Legacy Module Object model from data. - */ - protected function instanciateLegacyModule() - { - /** - * @TODO Temporary: This test prevents an error when switching branches with the cache. - * Can be removed at the next release (when we will be sure that it is defined) - */ - $path = $this->disk->get('path', ''); // Variable needed for empty() test - if (empty($path)) { - $this->disk->set('path', _PS_MODULE_DIR_ . DIRECTORY_SEPARATOR . $this->attributes->get('name')); - } - // End of temporary content - require_once $this->disk->get('path') . DIRECTORY_SEPARATOR . $this->attributes->get('name') . '.php'; - $this->instance = LegacyModule::getInstanceByName($this->attributes->get('name')); - } - - /** - * @param $attribute - * - * @return mixed - */ - public function get($attribute) - { - return $this->attributes->get($attribute, null); - } - - /** - * @param $attribute - * @param $value - */ - public function set($attribute, $value) - { - $this->attributes->set($attribute, $value); - } - - /** - * @param $value - * - * @return mixed|string - */ - private function convertType($value) - { - $conversionTable = [ - AddonListFilterOrigin::ADDONS_CUSTOMER => 'addonsBought', - AddonListFilterOrigin::ADDONS_MUST_HAVE => 'addonsMustHave', - ]; - - return isset($conversionTable[$value]) ? $conversionTable[$value] : ''; - } - - /** - * Set the module logo. - */ - public function fillLogo() - { - $img = $this->attributes->get('img'); - if (empty($img)) { - $this->attributes->set('img', __PS_BASE_URI__ . 'img/questionmark.png'); - } - $this->attributes->set('logo', __PS_BASE_URI__ . 'img/questionmark.png'); - - foreach (['logo.png', 'logo.gif'] as $logo) { - $logo_path = _PS_MODULE_DIR_ . $this->get('name') . DIRECTORY_SEPARATOR . $logo; - if (file_exists($logo_path)) { - $this->attributes->set('img', __PS_BASE_URI__ . basename(_PS_MODULE_DIR_) . '/' . $this->get('name') . '/' . $logo); - $this->attributes->set('logo', $logo); - - break; - } - } - } - - /** - * Inform the merchant an upgrade is wating to be applied from the disk or the marketplace. - * - * @return bool - */ - public function canBeUpgraded() - { - if ($this->database->get('installed') == 0) { - return false; - } - - // Potential update from API - if ($this->canBeUpgradedFromAddons()) { - return true; - } - - // Potential update from disk - return version_compare($this->database->get('version'), $this->disk->get('version'), '<'); - } - - /** - * Only check if an upgrade is available on the marketplace. - * - * @return bool - */ - public function canBeUpgradedFromAddons() - { - return $this->attributes->get('version_available') !== 0 - && version_compare($this->database->get('version'), $this->attributes->get('version_available'), '<'); - } - - /** - * Return installed modules. - * - * @param int $position Take only positionnables modules - * - * @return array Modules - */ - public function getModulesInstalled($position = 0) - { - return LegacyModule::getModulesInstalled((int) $position); - } - - /** - * Return an instance of the specified module. - * - * @param int $moduleId Module id - * - * @return Module instance - */ - public function getInstanceById($moduleId) - { - return LegacyModule::getInstanceById((int) $moduleId); - } -} diff --git a/src/Adapter/Module/ModuleDataProvider.php b/src/Adapter/Module/ModuleDataProvider.php deleted file mode 100644 index 97ac2179..00000000 --- a/src/Adapter/Module/ModuleDataProvider.php +++ /dev/null @@ -1,306 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use Db; -use Doctrine\ORM\EntityManager; -use Module as LegacyModule; -use PhpParser; -use PrestaShop\PrestaShop\Adapter\Shop\Context; -use PrestaShop\PrestaShop\Core\Addon\Module\AddonListFilterDeviceStatus; -use Psr\Log\LoggerInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * This class will provide data from DB / ORM about Module. - */ -class ModuleDataProvider -{ - /** - * Logger. - * - * @var LoggerInterface - */ - private $logger; - - /** - * Translator. - * - * @var \Symfony\Component\Translation\TranslatorInterface - */ - private $translator; - - /** - * EntityManager for module history. - * - * @var EntityManager - */ - private $entityManager; - - /** - * @var int - */ - private $employeeID; - - public function __construct(LoggerInterface $logger, TranslatorInterface $translator, EntityManager $entityManager = null) - { - $this->logger = $logger; - $this->translator = $translator; - $this->entityManager = $entityManager; - $this->employeeID = 0; - } - - /** - * @param $employeeID - */ - public function setEmployeeId($employeeID) - { - $this->employeeID = (int) $employeeID; - } - - /** - * Return all module information from database. - * - * @param string $name The technical module name to search - * - * @return array - */ - public function findByName($name) - { - $result = Db::getInstance()->getRow('SELECT `id_module` as `id`, `active`, `version` FROM `' . _DB_PREFIX_ . 'module` WHERE `name` = "' . pSQL($name) . '"'); - if ($result) { - $result['installed'] = 1; - $result['active'] = $this->isEnabled($name); - $result['active_on_mobile'] = (bool) ($this->getDeviceStatus($name) & AddonListFilterDeviceStatus::DEVICE_MOBILE); - $lastAccessDate = '0000-00-00 00:00:00'; - - if (!Tools::isPHPCLI() && null !== $this->entityManager && $this->employeeID) { - $moduleID = (int) $result['id']; - - $qb = $this->entityManager->createQueryBuilder(); - $qb->select('mh') - ->from('PrestaShopBundle:ModuleHistory', 'mh', 'mh.idModule') - ->where('mh.idEmployee = ?1') - ->setParameter(1, $this->employeeID); - $query = $qb->getQuery(); - $query->useResultCache(true); - $modulesHistory = $query->getResult(); - - if (array_key_exists($moduleID, $modulesHistory)) { - $lastAccessDate = $modulesHistory[$moduleID]->getDateUpd()->format('Y-m-d H:i:s'); - } - } - $result['last_access_date'] = $lastAccessDate; - - return $result; - } - - return ['installed' => 0]; - } - - /** - * Return translated module *Display Name*. - * - * @param string $module The technical module name - * - * @return string The translated Module displayName - */ - public function getModuleName($module) - { - return LegacyModule::getModuleName($module); - } - - /** - * Check current employee permission on a given module. - * - * @param string $action - * @param string $name - * - * @return bool True if allowed - */ - public function can($action, $name) - { - $module_id = LegacyModule::getModuleIdByName($name); - - if (empty($module_id)) { - return false; - } - - return LegacyModule::getPermissionStatic($module_id, $action); - } - - /** - * Check if a module is enabled in the current shop context. - * - * @param bool $name The technical module name - * - * @return bool True if enable - */ - public function isEnabled($name) - { - $id_shops = (new Context())->getContextListShopID(); - // ToDo: Load list of all installed modules ? - - $result = Db::getInstance()->getRow('SELECT m.`id_module` as `active`, ms.`id_module` as `shop_active` - FROM `' . _DB_PREFIX_ . 'module` m - LEFT JOIN `' . _DB_PREFIX_ . 'module_shop` ms ON m.`id_module` = ms.`id_module` - WHERE `name` = "' . pSQL($name) . '" - AND ms.`id_shop` IN (' . implode(',', array_map('intval', $id_shops)) . ')'); - if ($result) { - return (bool) ($result['active'] && $result['shop_active']); - } else { - return false; - } - } - - public function isInstalled($name) - { - // ToDo: Load list of all installed modules ? - return (bool) $this->getModuleIdByName($name); - } - - /** - * Returns the Module Id - * - * @param string $name The technical module name - * - * @return int the Module Id, or 0 if not found - */ - public function getModuleIdByName($name) - { - return (int) Db::getInstance()->getValue( - 'SELECT `id_module` FROM `' . _DB_PREFIX_ . 'module` WHERE `name` = "' . pSQL($name) . '"' - ); - } - - /** - * We won't load an invalid class. This function will check any potential parse error. - * - * @param string $name The technical module name to check - * - * @return bool true if valid - */ - public function isModuleMainClassValid($name) - { - if (!Validate::isModuleName($name)) { - return false; - } - - $file_path = _PS_MODULE_DIR_ . $name . '/' . $name . '.php'; - // Check if file exists (slightly faster than file_exists) - if (!(int) @filemtime($file_path)) { - return false; - } - - $parser = (new PhpParser\ParserFactory())->create(PhpParser\ParserFactory::PREFER_PHP7); - - try { - $parser->parse(file_get_contents($file_path)); - } catch (PhpParser\Error $exception) { - $this->logger->critical( - $this->translator->trans( - 'Parse error detected in main class of module %module%: %parse_error%', - [ - '%module%' => $name, - '%parse_error%' => $exception->getMessage(), - ], - 'Admin.Modules.Notification' - ) - ); - - return false; - } - - $logger = $this->logger; - // -> Even if we do not detect any parse error in the file, we may have issues - // when trying to load the file. (i.e with additional require_once). - // -> We use an anonymous function here because if a test is made twice - // on the same module, the test on require_once would immediately return true - // (as the file would have already been evaluated). - $require_correct = function ($name) use ($file_path, $logger) { - try { - require_once $file_path; - } catch (\Exception $e) { - $logger->error( - $this->translator->trans( - 'Error while loading file of module %module%. %error_message%', - [ - '%module%' => $name, - '%error_message%' => $e->getMessage(), ], - 'Admin.Modules.Notification' - ) - ); - - return false; - } - - return true; - }; - - return $require_correct($name); - } - - /** - * Check if the module is in the modules folder, with a valid class. - * - * @param string $name The technical module name to find - * - * @return bool True if found - */ - public function isOnDisk($name) - { - $path = _PS_MODULE_DIR_ . $name . '/' . $name . '.php'; - - return file_exists($path); - } - - /** - * Check if the module has been enabled on mobile. - * - * @param string $name The technical module name to check - * - * @return int The devices enabled for this module - */ - private function getDeviceStatus($name) - { - $id_shops = (new Context())->getContextListShopID(); - // ToDo: Load list of all installed modules ? - - $result = Db::getInstance()->getRow('SELECT m.`id_module` as `active`, ms.`id_module` as `shop_active`, ms.`enable_device` as `enable_device` - FROM `' . _DB_PREFIX_ . 'module` m - LEFT JOIN `' . _DB_PREFIX_ . 'module_shop` ms ON m.`id_module` = ms.`id_module` - WHERE `name` = "' . pSQL($name) . '" - AND ms.`id_shop` IN (' . implode(',', array_map('intval', $id_shops)) . ')'); - if ($result) { - return (int) $result['enable_device']; - } - - return false; - } -} diff --git a/src/Adapter/Module/ModuleDataUpdater.php b/src/Adapter/Module/ModuleDataUpdater.php deleted file mode 100644 index 5b4e0dbe..00000000 --- a/src/Adapter/Module/ModuleDataUpdater.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use Module as LegacyModule; -use PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface; -use Symfony\Component\Filesystem\Exception\IOException; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Responsible of managing updates of modules. - */ -class ModuleDataUpdater -{ - /** - * @var AddonsInterface - */ - private $addonsDataProvider; - - /** - * @var AdminModuleDataProvider - */ - private $adminModuleDataProvider; - - public function __construct(AddonsInterface $addonsDataProvider, AdminModuleDataProvider $adminModuleDataProvider) - { - $this->addonsDataProvider = $addonsDataProvider; - $this->adminModuleDataProvider = $adminModuleDataProvider; - } - - /** - * @param $name - * - * @return bool - */ - public function setModuleOnDiskFromAddons($name) - { - // Note : Data caching should be handled by the addons data provider - // Check if the module can be downloaded from addons - foreach ($this->adminModuleDataProvider->getCatalogModules(['name' => $name]) as $catalog_module) { - if ($catalog_module->name == $name && in_array($catalog_module->origin, ['native', 'native_all', 'must-have', 'customer'])) { - return $this->addonsDataProvider->downloadModule($catalog_module->id); - } - } - - return false; - } - - /** - * @param $name - * - * @return bool - */ - public function removeModuleFromDisk($name) - { - $fs = new FileSystem(); - - try { - $fs->remove(_PS_MODULE_DIR_ . '/' . $name); - - return true; - } catch (IOException $e) { - return false; - } - } - - /** - * @param $name - * - * @return bool - */ - public function upgrade($name) - { - // Calling this function will init legacy module data - $module_list = LegacyModule::getModulesOnDisk(); - - foreach ($module_list as $module) { - if ($module->name != $name) { - continue; - } - - if (LegacyModule::initUpgradeModule($module)) { - $legacy_instance = LegacyModule::getInstanceByName($name); - $legacy_instance->runUpgradeModule(); - - LegacyModule::upgradeModuleVersion($name, $module->version); - - return !count($legacy_instance->getErrors()); - } elseif (LegacyModule::getUpgradeStatus($name)) { - return true; - } - - return true; - } - - return false; - } -} diff --git a/src/Adapter/Module/ModulePresenter.php b/src/Adapter/Module/ModulePresenter.php deleted file mode 100644 index 3bd872b3..00000000 --- a/src/Adapter/Module/ModulePresenter.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Module\ModulePresenter - */ -class ModulePresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Module\ModulePresenter -{ -} diff --git a/src/Adapter/Module/ModuleZip.php b/src/Adapter/Module/ModuleZip.php deleted file mode 100644 index 2b7b8851..00000000 --- a/src/Adapter/Module/ModuleZip.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -/** - * Value object used to represent a partial Module object during unzipping - * of a module archive. - */ -class ModuleZip -{ - /** - * @var string Module technical name, guessed from the path [module name]/[module name].php - */ - private $name; - - /** - * @var string Temporary path to extract the module files before going into the modules folder - */ - private $sandboxPath; - - /** - * @var string Complete path to the source file (Zip) - */ - private $source; - - public function __construct($source) - { - $this->name = null; - $this->sandboxPath = null; - $this->source = $source; - } - - /** - * @return string|null - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getSource() - { - return $this->source; - } - - /** - * @return string|null - */ - public function getSandboxPath() - { - return $this->sandboxPath; - } - - /** - * @param $name - * - * @return $this - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * @param $sandboxPath - * - * @return $this - */ - public function setSandboxPath($sandboxPath) - { - $this->sandboxPath = $sandboxPath; - - return $this; - } -} diff --git a/src/Adapter/Module/ModuleZipManager.php b/src/Adapter/Module/ModuleZipManager.php deleted file mode 100644 index 97dc698b..00000000 --- a/src/Adapter/Module/ModuleZipManager.php +++ /dev/null @@ -1,221 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use Exception; -use PrestaShopBundle\Event\ModuleZipManagementEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use ZipArchive; - -/** - * Responsible of unzipping of Module Zip archives. - */ -class ModuleZipManager -{ - /* - * Data - */ - private static $sources = []; - - /* - * Services - */ - /** - * @var \Symfony\Component\Filesystem\Filesystem - */ - private $filesystem; - - /** - * Translator. - * - * @var TranslatorInterface - */ - private $translator; - - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; - - public function __construct( - Filesystem $filesystem, - TranslatorInterface $translator, - EventDispatcherInterface $eventDispatcher - ) { - $this->filesystem = $filesystem; - $this->translator = $translator; - $this->eventDispatcher = $eventDispatcher; - } - - /** - * Detect module name from zipball. - * - * @param string $source - * - * @return string - * - * @throws Exception If unable to find the module name - */ - public function getName($source) - { - $this->initSource($source); - - if ($this->getSource($source)->getName($source) !== null) { - return $this->getSource($source)->getName($source); - } - - if (!file_exists($source)) { - throw new Exception($this->translator->trans('Unable to find uploaded module at the following path: %file%', ['%file%' => $source], 'Admin.Modules.Notification')); - } - - $sandboxPath = $this->getSandboxPath($source); - $zip = new ZipArchive(); - if ($zip->open($source) === false || !$zip->extractTo($sandboxPath) || !$zip->close()) { - throw new Exception($this->translator->trans('Cannot extract module in %path% to get its name. %error%', ['%path%' => $sandboxPath, '%error%' => $zip->getStatusString()], 'Admin.Modules.Notification')); - } - - // Check the structure and get the module name - $directories = Finder::create() - ->directories() - ->in($sandboxPath) - ->depth('== 0') - ->exclude(['__MACOSX']) - ->ignoreVCS(true); - - $validModuleStructure = false; - // We must have only one folder in the zip, which contains the module files - if (iterator_count($directories->directories()) == 1) { - $directories = iterator_to_array($directories); - $moduleName = basename(current($directories)->getFileName()); - - // Inside of this folder, we MUST have a file called .php - $moduleFolder = Finder::create() - ->files() - ->in($sandboxPath . $moduleName) - ->depth('== 0') - ->exclude(['__MACOSX']) - ->ignoreVCS(true); - foreach (iterator_to_array($moduleFolder) as $file) { - if ($file->getFileName() === $moduleName . '.php') { - $validModuleStructure = true; - - break; - } - } - } - - if (!$validModuleStructure) { - $this->filesystem->remove($sandboxPath); - - throw new Exception($this->translator->trans('This file does not seem to be a valid module zip', [], 'Admin.Modules.Notification')); - } - - $this->getSource($source)->setName($moduleName); - - return $moduleName; - } - - /** - * When ready, send the module Zip in the modules folder. - * - * @param string $source - */ - public function storeInModulesFolder($source) - { - $name = $this->getName($source); - $sandboxPath = $this->getSandboxPath($source); - // Now we are sure to have a valid module, we copy it to the modules folder - $modulePath = _PS_MODULE_DIR_ . $name; - $this->filesystem->mkdir($modulePath); - $this->filesystem->mirror( - $sandboxPath . $name, - $modulePath, - null, - ['override' => true] - ); - $this->eventDispatcher - ->dispatch( - ModuleZipManagementEvent::DOWNLOAD, - new ModuleZipManagementEvent($this->getSource($source)) - ); - - $this->filesystem->remove($sandboxPath); - } - - /** - * @param $source - * - * @return string|null - */ - private function getSandboxPath($source) - { - $sandboxPath = $this->getSource($source)->getSandboxPath(); - if ($sandboxPath === null) { - $sandboxPath = _PS_CACHE_DIR_ . 'sandbox/' . uniqid() . '/'; - $this->filesystem->mkdir($sandboxPath); - $this->getSource($source)->setSandboxPath($sandboxPath); - } - - return $sandboxPath; - } - - /** - * Get a ModuleZip instance from a given source (= zip filepath). - * - * @param string $source - * - * @return ModuleZip|null - */ - private function getSource($source) - { - if (!array_key_exists($source, self::$sources)) { - return null; - } - - return self::$sources[$source]; - } - - /** - * Init all data regarding a source before proceeding it. - * - * @param string $source - */ - private function initSource($source) - { - if ((filter_var($source, FILTER_VALIDATE_URL))) { - $source = Tools::createFileFromUrl($source); - } - - if ($this->getSource($source) === null) { - self::$sources[$source] = new ModuleZip($source); - } - } -} diff --git a/src/Adapter/Module/PaymentModuleListProvider.php b/src/Adapter/Module/PaymentModuleListProvider.php deleted file mode 100644 index 7f74fb57..00000000 --- a/src/Adapter/Module/PaymentModuleListProvider.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; -use PrestaShop\PrestaShop\Core\Addon\AddonRepositoryInterface; -use PrestaShop\PrestaShop\Core\Module\DataProvider\PaymentModuleListProviderInterface; -use PrestaShopBundle\Entity\Repository\ModuleRepository; - -/** - * Class PaymentModuleListProvider is responsible for providing payment module list. - */ -final class PaymentModuleListProvider implements PaymentModuleListProviderInterface -{ - /** - * @var AddonRepositoryInterface - */ - private $addonRepository; - - /** - * @var ModuleRepository - */ - private $moduleRepository; - - /** - * @var int - */ - private $shopId; - - /** - * @param AddonRepositoryInterface $addonRepository - * @param ModuleRepository $moduleRepository - * @param int $shopId - */ - public function __construct( - AddonRepositoryInterface $addonRepository, - ModuleRepository $moduleRepository, - $shopId - ) { - $this->addonRepository = $addonRepository; - $this->moduleRepository = $moduleRepository; - $this->shopId = $shopId; - } - - /** - * {@inheritdoc} - */ - public function getPaymentModuleList() - { - $filters = (new AddonListFilter()) - ->setType(AddonListFilterType::MODULE) - ->setStatus(AddonListFilterStatus::INSTALLED); - - $modules = $this->addonRepository->getFilteredList($filters); - $paymentModules = []; - - /** @var Module $module */ - foreach ($modules as $module) { - if ($module->attributes->get('is_paymentModule')) { - $restrictedCountries = $this->moduleRepository->findRestrictedCountryIds( - $module->database->get('id'), - $this->shopId - ); - $restrictedCurrencies = $this->moduleRepository->findRestrictedCurrencyIds( - $module->database->get('id'), - $this->shopId - ); - $restrictedGroups = $this->moduleRepository->findRestrictedGroupIds( - $module->database->get('id'), - $this->shopId - ); - $restrictedCarriers = $this->moduleRepository->findRestrictedCarrierReferenceIds( - $module->database->get('id'), - $this->shopId - ); - - $module->attributes->set('countries', $restrictedCountries); - $module->attributes->set('currencies', $restrictedCurrencies); - $module->attributes->set('groups', $restrictedGroups); - $module->attributes->set('carriers', $restrictedCarriers); - - $paymentModules[$module->attributes->get('name')] = $module; - } - } - - return $paymentModules; - } -} diff --git a/src/Adapter/Module/Presenter/PaymentModulesPresenter.php b/src/Adapter/Module/Presenter/PaymentModulesPresenter.php deleted file mode 100644 index c2059c05..00000000 --- a/src/Adapter/Module/Presenter/PaymentModulesPresenter.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Presenter; - -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository; -use PrestaShop\PrestaShop\Core\Module\DataProvider\TabModuleListProviderInterface; - -/** - * Class PaymentModulesPresenter is responsible for presenting payment modules. - */ -class PaymentModulesPresenter -{ - /** - * @var string It will use legacy controller name to get payment modules for controller - */ - const PAYMENT_METHODS_CONTROLLER = 'AdminPayment'; - - /** - * @var TabModuleListProviderInterface - */ - private $tabModuleListProvider; - - /** - * @var ModuleDataProvider - */ - private $moduleDataProvider; - - /** - * @var PresenterInterface - */ - private $modulePresenter; - - /** - * @var ModuleRepository - */ - private $moduleRepository; - - /** - * @param TabModuleListProviderInterface $tabModuleListProvider - * @param ModuleDataProvider $moduleDataProvider - * @param PresenterInterface $modulePresenter - * @param ModuleRepository $moduleRepository - */ - public function __construct( - TabModuleListProviderInterface $tabModuleListProvider, - ModuleDataProvider $moduleDataProvider, - PresenterInterface $modulePresenter, - ModuleRepository $moduleRepository - ) { - $this->tabModuleListProvider = $tabModuleListProvider; - $this->moduleDataProvider = $moduleDataProvider; - $this->modulePresenter = $modulePresenter; - $this->moduleRepository = $moduleRepository; - } - - /** - * Get presented payment modules. - * - * @return array - */ - public function present() - { - $tabModuleNames = $this->tabModuleListProvider->getTabModules(self::PAYMENT_METHODS_CONTROLLER); - - $installedModules = $this->moduleRepository->getInstalledModules(); - $installedModuleNames = array_keys($installedModules); - - $paymentModulesToDisplay = []; - foreach ($tabModuleNames as $moduleName) { - if (!in_array($moduleName, $installedModuleNames) || - !$this->moduleDataProvider->can('configure', $moduleName) - ) { - continue; - } - - $installedModule = $installedModules[$moduleName]; - if ($installedModule->database->get('active')) { - $paymentModulesToDisplay[] = $this->modulePresenter->present($installedModule); - } - } - - return $paymentModulesToDisplay; - } -} diff --git a/src/Adapter/Module/PrestaTrust/ModuleEventSubscriber.php b/src/Adapter/Module/PrestaTrust/ModuleEventSubscriber.php deleted file mode 100644 index 99bd1be7..00000000 --- a/src/Adapter/Module/PrestaTrust/ModuleEventSubscriber.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\PrestaTrust; - -use PrestaShopBundle\Event\ModuleZipManagementEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * This class subscribes to the events module installation / uninstallation - * in order to install or remove its tabs as well. - */ -class ModuleEventSubscriber implements EventSubscriberInterface -{ - /** - * @var PrestaTrustChecker - */ - private $checker; - - /** - * These events can be enabled/disabled via the config file. - * - * @var bool - */ - private $enabled; - - public function __construct(PrestaTrustChecker $checker) - { - $this->checker = $checker; - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return [ - ModuleZipManagementEvent::DOWNLOAD => 'onNewModule', - ]; - } - - /** - * Event executed on module download (coming from the marketplace or the employee disk) - * If the feature is enabled in the project configuration, we will trigger our class PrestaTrustChecker to verify - * if the module is compliant. - * - * @param ModuleZipManagementEvent $event - */ - public function onNewModule(ModuleZipManagementEvent $event) - { - if (!$this->enabled) { - return; - } - - $this->checker->checkModuleZip($event->getModuleZip()); - } - - /** - * Check if the feature is enabled. - * - * @return bool - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * Enable / disable the PrestaTrust feature. - * - * @param bool $enabled - * - * @return $this - */ - public function setEnabled($enabled) - { - $this->enabled = (bool) $enabled; - - return $this; - } -} diff --git a/src/Adapter/Module/PrestaTrust/PrestaTrustChecker.php b/src/Adapter/Module/PrestaTrust/PrestaTrustChecker.php deleted file mode 100644 index 238f715e..00000000 --- a/src/Adapter/Module/PrestaTrust/PrestaTrustChecker.php +++ /dev/null @@ -1,273 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\PrestaTrust; - -use Doctrine\Common\Cache\Cache; -use Exception; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Adapter\Module\ModuleZip; -use PrestaShopBundle\Service\DataProvider\Marketplace\ApiClient; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\TranslatorInterface; -use ZipArchive; - -/** - * Responsible of Module verification by PrestaTrust system. - */ -class PrestaTrustChecker -{ - /** - * @var array - */ - protected $checked_extensions = ['php', 'js', 'css', 'tpl']; - - const SMART_CONTRACT_PATTERN = 'prestatrust-license-verification: '; - const CHECKS_ALL_OK = 'Module is authenticated.'; - const CHECKS_INTEGRITY_NOK = 'Warning, the module has been modified since its purchase from the Addons Marketplace.'; - const CHECKS_PROPERTY_NOK = 'Warning, the purchase proof is invalid. This license has already been used on another shop.'; - const CHECKS_ALL_NOK = 'Warning, the module has been modified and its purchase proof is invalid.'; - - /** - * @var Cache - */ - protected $cache; - - /** - * Addons marketplace API client. - * - * @var ApiClient - */ - protected $apiClient; - - /** - * @var TranslatorInterface - */ - protected $translator; - - /** - * @param Cache $cache Cache provider to keep data between two requests - * @param ApiClient $apiClient Addons Marketplace API client (Guzzle) - * @param TranslatorInterface $translator Translator for explanation messages - */ - public function __construct(Cache $cache, ApiClient $apiClient, TranslatorInterface $translator) - { - $this->cache = $cache; - $this->apiClient = $apiClient; - $this->translator = $translator; - } - - /** - * If the module is compliant, this class generates and adds all PrestaTrust related details. - * If not, the module remains untouched. We do not execute checks to avoid slow performances. - * - * @param Module $module - */ - public function loadDetailsIntoModule(Module $module) - { - if (!$this->isCompliant($module)) { - return; - } - - if (!$this->cache->contains($module->get('name'))) { - return; - } - - // Merge 2 existing sources of data - $details = (object) array_merge((array) $module->get('prestatrust', new \stdClass()), (array) $this->cache->fetch($module->get('name'))); - - $details->check_list = $this->requestCheck($details->hash, $this->findSmartContrat($module->disk->get('path'))); - $details->status = array_sum($details->check_list) == count($details->check_list); // True if all content is True - $details->message = $this->translator->trans($this->getMessage($details->check_list), [], 'Admin.Modules.Notification'); - - $module->set('prestatrust', $details); - } - - /** - * This function, called by the "module download" event, will look at the uploaded zip before its deletion. - * Looking at the original content (before unzipping) allows us to make sure we do not have altered content - * or remaining one from another zip. - * Any module copy pasted in the module folder won't go through this function. - * - * @param string $name Module technical name - * @param string $zipFile Module Zip location - */ - public function checkModuleZip(ModuleZip $zipFile) - { - // Do we need to check something in order to validate only PrestaTrust related modules? - - $details = new \stdClass(); - $details->hash = $this->calculateHash($zipFile->getSource()); - - $this->cache->save($zipFile->getName(), $details); - } - - /** - * Find all files with defined extensions, and calculate md5 from their content. - * - * @param string $zipFile Path to the module Zip file - * - * @return string Hash of the module - */ - protected function calculateHash($zipFile) - { - $preparehash = ''; - $zip = new ZipArchive(); - if (true !== $zip->open($zipFile)) { - return $preparehash; - } - - for ($i = 0; $i < $zip->numFiles; ++$i) { - $stat = $zip->statIndex($i); - $file_info = pathinfo($stat['name']); - - if (empty($file_info['filename']) || empty($file_info['extension'])) { - continue; - } - - if (in_array(trim($file_info['extension']), $this->checked_extensions)) { - $preparehash .= $zip->getFromName($file_info['dirname'] . '/' . $file_info['basename']); - } - } - $zip->close(); - - return hash('sha256', $preparehash); - } - - /** - * Find and return the smart contract address to be checked with the API. - * To find the address, we must find a file which matches the pattern "'prestatrust-license-verification:". - * The address will be found right after it, and must also match the file name. - * - * @param string $path Module root path - * - * @return string|null smart contract address, if found - */ - public function findSmartContrat($path) - { - $finder = Finder::create(); - $finder->files()->contains(self::SMART_CONTRACT_PATTERN)->in($path); - - // Get the first file in the results - foreach ($finder as $file) { - $sc = trim(str_replace(self::SMART_CONTRACT_PATTERN, '', $file->getContents())); - if ($sc === $file->getFilename()) { - return $sc; - } - } - - return null; - } - - /** - * Get message to display at the employee. It is used to explain briefly what is PrestaTrust and what - * went right (or wrong). - * - * @param array $check_list - * - * @return string Message displayed for confirmation - */ - protected function getMessage(array $check_list) - { - if ($check_list['integrity'] && $check_list['property']) { - return self::CHECKS_ALL_OK; - } - if (!$check_list['integrity'] && $check_list['property']) { - return self::CHECKS_INTEGRITY_NOK; - } - if ($check_list['integrity'] && !$check_list['property']) { - return self::CHECKS_PROPERTY_NOK; - } - - return self::CHECKS_ALL_NOK; - } - - /** - * Check if a module can be checked with PrestaTrust. To make it compliant, an attribute "author_address" - * must exist, start with "0x" and be 42 characters long. - * - * @param Module $module - * - * @return bool Module compliancy - */ - protected function isCompliant(Module $module) - { - if (!$module->attributes->has('author_address')) { - return false; - } - - $address = $module->attributes->get('author_address'); - - // Always ensure 0x prefix. - // Address should be 20bytes=40 HEX-chars + prefix. - if (!self::hasHexPrefix($address) || strlen($address) !== 42) { - return false; - } - - if (!function_exists('ctype_xdigit') || !ctype_xdigit(substr($address, strlen('0x')))) { - return false; - } - - return true; - } - - /** - * Check that the string starts with '0x'. - * - * @param string $str Author address - * - * @return bool True if starts with '0x' - */ - protected function hasHexPrefix($str) - { - $prefix = '0x'; - - return substr($str, 0, strlen($prefix)) === $prefix; - } - - /** - * Send to the Marketplace API our details about the module, and get results - * about its integrity and property. - * - * @param string $hash Calculted hash from the modules files - * @param string $contract Smart contract address from module - * - * @return array of check list results - */ - protected function requestCheck($hash, $contract) - { - try { - $result = $this->apiClient->getPrestaTrustCheck($hash, $contract); - - return [ - 'integrity' => (bool) ($result->hash_trusted), - 'property' => (bool) ($result->property_trusted), - ]; - } catch (Exception $e) { - return ['integrity' => false, 'property' => false]; - } - } -} diff --git a/src/Adapter/Module/Tab/ModuleTabManagementSubscriber.php b/src/Adapter/Module/Tab/ModuleTabManagementSubscriber.php deleted file mode 100644 index c0e8e4eb..00000000 --- a/src/Adapter/Module/Tab/ModuleTabManagementSubscriber.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Tab; - -use PrestaShopBundle\Event\ModuleManagementEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * This class subscribes to the events module installation / uninstallation - * in order to install or remove its tabs as well. - */ -class ModuleTabManagementSubscriber implements EventSubscriberInterface -{ - /** - * @var ModuleTabRegister - */ - private $moduleTabRegister; - /** - * @var ModuleTabUnregister - */ - private $moduleTabUnregister; - - public function __construct(ModuleTabRegister $moduleTabRegister, ModuleTabUnregister $moduleTabUnregister) - { - $this->moduleTabRegister = $moduleTabRegister; - $this->moduleTabUnregister = $moduleTabUnregister; - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() - { - return [ - ModuleManagementEvent::INSTALL => 'onModuleInstall', - ModuleManagementEvent::UNINSTALL => 'onModuleUninstall', - ModuleManagementEvent::ENABLE => 'onModuleEnable', - ModuleManagementEvent::DISABLE => 'onModuleDisable', - ]; - } - - /** - * @param ModuleManagementEvent $event - */ - public function onModuleInstall(ModuleManagementEvent $event) - { - $this->moduleTabRegister->registerTabs($event->getModule()); - } - - /** - * @param ModuleManagementEvent $event - */ - public function onModuleUninstall(ModuleManagementEvent $event) - { - $this->moduleTabUnregister->unregisterTabs($event->getModule()); - } - - /** - * @param ModuleManagementEvent $event - */ - public function onModuleEnable(ModuleManagementEvent $event) - { - $this->moduleTabRegister->enableTabs($event->getModule()); - } - - /** - * @param ModuleManagementEvent $event - */ - public function onModuleDisable(ModuleManagementEvent $event) - { - $this->moduleTabUnregister->disableTabs($event->getModule()); - } -} diff --git a/src/Adapter/Module/Tab/ModuleTabRegister.php b/src/Adapter/Module/Tab/ModuleTabRegister.php deleted file mode 100644 index e90b4f06..00000000 --- a/src/Adapter/Module/Tab/ModuleTabRegister.php +++ /dev/null @@ -1,434 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Tab; - -use Exception; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShopBundle\Entity\Repository\LangRepository; -use PrestaShopBundle\Entity\Repository\TabRepository; -use Psr\Log\LoggerInterface; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; -use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\Translation\TranslatorInterface; -use TabCore as Tab; - -/** - * Class responsible of register new tab in Back Office's menu. - */ -class ModuleTabRegister -{ - const SUFFIX = '_MTR'; - - /** - * @var string - */ - private $defaultParent = 'DEFAULT'; - - /** - * @var LangRepository - */ - protected $langRepository; - - /** - * @var TabRepository - */ - protected $tabRepository; - - /** - * @var \Psr\Log\LoggerInterface - */ - private $logger; - - /** - * @var \Symfony\Component\Translation\TranslatorInterface - */ - private $translator; - - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var array List all active languages on the shop - */ - private $languages; - - /** - * @var LoaderInterface - */ - private $routingConfigLoader; - - /** - * @param TabRepository $tabRepository - * @param LangRepository $langRepository - * @param LoggerInterface $logger - * @param TranslatorInterface $translator - * @param Filesystem $filesystem - * @param array $languages - * @param LoaderInterface $routingConfigLoader - */ - public function __construct( - TabRepository $tabRepository, - LangRepository $langRepository, - LoggerInterface $logger, - TranslatorInterface $translator, - Filesystem $filesystem, - array $languages, - LoaderInterface $routingConfigLoader - ) { - $this->langRepository = $langRepository; - $this->tabRepository = $tabRepository; - $this->logger = $logger; - $this->translator = $translator; - $this->filesystem = $filesystem; - $this->languages = $languages; - $this->routingConfigLoader = $routingConfigLoader; - } - - /** - * Fetch module-defined tabs and find undeclared ModuleAdminControllers. - * - * This is done automatically as part of the module installation. - * - * @param Module $module - */ - public function registerTabs(Module $module) - { - if (!$module->getInstance()) { - return; - } - - $tabs = $this->addUndeclaredTabs($module->get('name'), $module->getInstance()->getTabs()); - foreach ($tabs as $tab) { - try { - $this->registerTab($module, new ParameterBag($tab)); - } catch (Exception $e) { - $this->logger->error($e->getMessage()); - } - } - } - - /** - * @param Module $module - */ - public function enableTabs(Module $module) - { - $this->tabRepository->changeEnabledByModuleName($module->get('name'), true); - } - - /** - * Looks for ModuleAdminControllers not declared as Tab and - * add them to the list to register. - * - * @param string $moduleName - * @param array $tabs - * - * @return array - */ - protected function addUndeclaredTabs($moduleName, array $tabs) - { - // Function to get only class name from tabs already declared - $tabsNames = array_map(function ($tab) { - if (array_key_exists('class_name', $tab)) { - return $tab['class_name']; - } - }, $tabs); - - $detectedControllers = $this->getDetectedModuleControllers($moduleName); - foreach ($detectedControllers as $adminControllerName) { - if (in_array($adminControllerName, $tabsNames)) { - continue; - } - - if ($this->tabRepository->findOneIdByClassName($adminControllerName)) { - continue; - } - - $tabs[] = [ - 'class_name' => $adminControllerName, - 'visible' => false, - ]; - } - - return $tabs; - } - - /** - * Returns a list of all detected controllers, either from admin/controllers folder - * or from the routing file. - * - * @param string $moduleName - * - * @return array - * - * @throws Exception - */ - protected function getDetectedModuleControllers(string $moduleName): array - { - $legacyControllersFilenames = $this->getModuleAdminControllersFilename($moduleName); - $legacyControllers = array_map(function ($legacyControllersFilename) { - return str_replace('Controller.php', '', $legacyControllersFilename); - }, $legacyControllersFilenames); - $legacyControllers = $legacyControllers ?? []; - - $routingControllers = $this->getModuleControllersFromRouting($moduleName); - $routingControllers = $routingControllers ?? []; - - return array_merge($legacyControllers, $routingControllers); - } - - /** - * Check mandatory data for tab registration, such as class name and class exists. - * - * @param string $moduleName - * @param ParameterBag $data - * - * @return bool (= true) when no issue detected - * - * @throws Exception in case of invalid data - */ - protected function checkIsValid($moduleName, ParameterBag $data) - { - $className = $data->get('class_name', null); - if (null === $className) { - throw new Exception('Missing class name of tab'); - } - - // Check controller exists - $detectedControllers = $this->getDetectedModuleControllers($moduleName); - if (empty($data->get('route_name')) && !in_array($className, $detectedControllers)) { - throw new Exception(sprintf('Class "%sController" not found in controllers/admin nor routing file', $className)); - } - - // Deprecation check - if ($data->has('ParentClassName') && !$data->has('parent_class_name')) { - $this->logger->warning('Tab attribute "ParentClassName" is deprecated. You must use "parent_class_name" instead.'); - } - //Check if the tab was already added manually - if (!empty($this->tabRepository->findOneIdByClassName($className))) { - throw new Exception(sprintf('Cannot register tab "%s" because it already exists', $className)); - } - - return true; - } - - /** - * Find all ModuleAdminController classes from module. - * This allow to check a class exists for a registered tab and to register automatically all the classes - * not explicitely declared by the module developer. - * - * @param string $moduleName - * - * @return array of Symfony\Component\Finder\SplFileInfo, listing all the ModuleAdminControllers found - */ - protected function getModuleAdminControllers($moduleName) - { - $modulePath = _PS_ROOT_DIR_ . '/' . basename(_PS_MODULE_DIR_) . - '/' . $moduleName . '/controllers/admin/'; - - if (!$this->filesystem->exists($modulePath)) { - return []; - } - - $moduleFolder = Finder::create()->files() - ->in($modulePath) - ->depth('== 0') - ->name('*Controller.php') - ->exclude(['index.php']) - ->contains('/Controller\s+extends\s+/i'); - - return iterator_to_array($moduleFolder); - } - - /** - * Parses the routes file from the module and return the list of associated controller - * via the _legacy_controller routing option. - * - * @param string $moduleName - * - * @return string[] - * - * @throws Exception - */ - protected function getModuleControllersFromRouting(string $moduleName): array - { - $routingFile = _PS_ROOT_DIR_ . '/' . basename(_PS_MODULE_DIR_) . - '/' . $moduleName . '/config/routes.yml'; - - if (!$this->filesystem->exists($routingFile)) { - return []; - } - - $routingControllers = []; - $moduleRoutes = $this->routingConfigLoader->import($routingFile, 'yaml'); - foreach ($moduleRoutes->getIterator() as $route) { - $legacyController = $route->getDefault('_legacy_controller'); - if (!empty($legacyController)) { - $routingControllers[] = $legacyController; - } - } - - return $routingControllers; - } - - /** - * Convert SPLFileInfo array to file names. Better & easier to check if a class to register exists. - * - * @param string $moduleName - * - * @return array of strings - */ - protected function getModuleAdminControllersFilename($moduleName) - { - return array_map(function (SplFileInfo $file) { - return $file->getFilename(); - }, $this->getModuleAdminControllers($moduleName)); - } - - /** - * From the name given by the module maintainer, associate a value per language - * installed on the shop. - * - * @param mixed $names - * - * @return array Name to use for each installed language - */ - protected function getTabNames($names) - { - $translatedNames = []; - - foreach ($this->languages as $lang) { - // In case we just receive a string, we apply it to all languages - if (!is_array($names)) { - $translatedNames[$lang['id_lang']] = $names; - } elseif (array_key_exists($lang['locale'], $names)) { - $translatedNames[$lang['id_lang']] = $names[$lang['locale']]; - } elseif (array_key_exists($lang['language_code'], $names)) { - $translatedNames[$lang['id_lang']] = $names[$lang['language_code']]; - } elseif (array_key_exists($lang['iso_code'], $names)) { - $translatedNames[$lang['id_lang']] = $names[$lang['iso_code']]; - } else { - $translatedNames[$lang['id_lang']] = reset($names); // Get the first name available in the array - } - } - - return $translatedNames; - } - - /** - * Install a tab according to its defined structure. - * - * @param Module $module - * @param ParameterBag $tabDetails the structure of the tab - * - * @throws Exception in case of error from validation or save - */ - protected function registerTab(Module $module, ParameterBag $tabDetails) - { - $this->checkIsValid($module->get('name'), $tabDetails); - - /** - * Legacy Tab, to be replaced with Doctrine entity when right management - * won't be directly linked to the tab creation - * - * @ToDo - */ - $tab = new Tab(); - $tab->active = $tabDetails->getBoolean('visible', true); - $tab->enabled = true; - $tab->class_name = $tabDetails->get('class_name'); - $tab->route_name = $tabDetails->get('route_name'); - $tab->module = $module->get('name'); - $tab->name = $this->getTabNames($tabDetails->get('name', $tab->class_name)); - $tab->icon = $tabDetails->get('icon'); - $tab->id_parent = $this->findParentId($tabDetails); - - if (!$tab->save()) { - throw new Exception($this->translator->trans('Failed to install admin tab "%name%".', ['%name%' => $tab->name], 'Admin.Modules.Notification')); - } - } - - /** - * Find the parent ID from the given tab context. - * - * @param ParameterBag $tabDetails the structure of the tab - * - * @return int ID of the parent, 0 if none - */ - protected function findParentId(ParameterBag $tabDetails) - { - $idParent = 0; - $parentClassName = $tabDetails->get('parent_class_name', $tabDetails->get('ParentClassName')); - if (!empty($parentClassName)) { - // Could be a previously duplicated tab - $idParent = $this->tabRepository->findOneIdByClassName($parentClassName . self::SUFFIX); - if (!$idParent) { - $idParent = $this->tabRepository->findOneIdByClassName($parentClassName); - } - } elseif (true === $tabDetails->getBoolean('visible', true)) { - $idParent = $this->tabRepository->findOneIdByClassName($this->defaultParent); - } - - return $this->duplicateParentIfAlone((int) $idParent); - } - - /** - * When the tab you add is the first child of a parent tab, we must duplicate it in the children - * or its link will be overriden. - * - * @param int $idParent - * - * @return int new parent ID - */ - protected function duplicateParentIfAlone($idParent) - { - // If the given parent has already children, don't touch anything - if ($idParent === 0 || count($this->tabRepository->findByParentId($idParent))) { - return $idParent; - } - - $currentTab = new Tab($idParent); - $newTab = clone $currentTab; - $newTab->id = 0; - $newTab->id_parent = $currentTab->id_parent; - $newTab->class_name = $currentTab->class_name . self::SUFFIX; - $newTab->save(); - - // Second save in order to get the proper position (add() resets it) - $newTab->position = $currentTab->position; - $newTab->save(); - - $currentTab->id_parent = $newTab->id; - $currentTab->save(); - - return $newTab->id; - } -} diff --git a/src/Adapter/Module/Tab/ModuleTabUnregister.php b/src/Adapter/Module/Tab/ModuleTabUnregister.php deleted file mode 100644 index bc07c573..00000000 --- a/src/Adapter/Module/Tab/ModuleTabUnregister.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module\Tab; - -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShopBundle\Entity\Repository\LangRepository; -use PrestaShopBundle\Entity\Repository\TabRepository; -use PrestaShopBundle\Entity\Tab; -use Psr\Log\LoggerInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Tab as TabClass; - -/** - * Class responsible of unregister existing tabs of Back Office's menu. - */ -class ModuleTabUnregister -{ - /** - * @var LangRepository - */ - protected $langRepository; - - /** - * @var TabRepository - */ - protected $tabRepository; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct(TabRepository $tabRepository, LangRepository $langRepository, LoggerInterface $logger, TranslatorInterface $translator) - { - $this->langRepository = $langRepository; - $this->tabRepository = $tabRepository; - $this->logger = $logger; - $this->translator = $translator; - } - - /** - * Uninstall all module-defined tabs. - * - * This is done automatically as part of the module uninstallation. - * - * @return bool returns true if the module tabs were successfully uninstalled, false if any of them failed to do so - */ - public function unregisterTabs(Module $module) - { - // We use the Tab repository to have only - // installed tabs related to the module - $tabs = $this->tabRepository->findByModule($module->get('name')); - - foreach ($tabs as $tab) { - $this->unregisterTab($tab); - $this->removeDuplicatedParent($tab); - } - } - - /** - * @param Module $module - */ - public function disableTabs(Module $module) - { - $this->tabRepository->changeEnabledByModuleName($module->get('name'), false); - } - - /** - * Uninstalls a tab given its defined structure. - * - * @param Tab $tab the instance of entity tab - */ - private function unregisterTab(Tab $tab) - { - // We need to use the legacy class because of the right management - $tab_legacy = new TabClass($tab->getId()); - - if (!$tab_legacy->delete()) { - $this->logger->warning( - $this->translator->trans( - 'Failed to uninstall admin tab "%name%".', - [ - '%name%' => $tab->getClassName(), - ], - 'Admin.Modules.Notification' - ) - ); - } - } - - /** - * When we add a level of children in the menu tabs, we created a dummy parent. - * We must delete it when it has no more children than the original tab. - * - * @param Tab $tab - */ - private function removeDuplicatedParent(Tab $tab) - { - $remainingChildren = $this->tabRepository->findByParentId($tab->getIdParent()); - // Or more than one children, the parent tab is still used. - // If there is no children, the deletion is likely to be done manually by the module. - if (count($remainingChildren) !== 1) { - return; - } - - $parent = $this->tabRepository->find($tab->getIdParent()); - $child = end($remainingChildren); - - // We know we have a tab to delete if the parent name is the remaining child name+_MTR - if ($parent->getClassName() === $child->getClassName() . ModuleTabRegister::SUFFIX) { - $legacyTabParent = new TabClass($parent->getId()); - // Setting a wrong id_parent will prevent the children to move - $legacyTabParent->id_parent = -1; - $legacyTabParent->delete(); - - $legacyTab = new TabClass($child->getId()); - $legacyTab->id_parent = $parent->getIdParent(); - $legacyTab->save(); - // Updating the id_parent will override the position, that's why we save 2 times - $legacyTab->position = $parent->getPosition(); - $legacyTab->save(); - } - } -} diff --git a/src/Adapter/Module/TabModuleListProvider.php b/src/Adapter/Module/TabModuleListProvider.php deleted file mode 100644 index 4f81748c..00000000 --- a/src/Adapter/Module/TabModuleListProvider.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Module; - -use PrestaShop\PrestaShop\Adapter\Entity\Tab; -use PrestaShop\PrestaShop\Core\Module\DataProvider\TabModuleListProviderInterface; - -/** - * Class TabModuleListProvider is responsible for providing tab modules. - */ -final class TabModuleListProvider implements TabModuleListProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getTabModules($tabClassName) - { - $tabId = Tab::getIdFromClassName($tabClassName); - $modules = Tab::getTabModulesList($tabId); - - return $modules['default_list']; - } -} diff --git a/src/Adapter/NewProducts/NewProductsProductSearchProvider.php b/src/Adapter/NewProducts/NewProductsProductSearchProvider.php deleted file mode 100644 index d1d2caf2..00000000 --- a/src/Adapter/NewProducts/NewProductsProductSearchProvider.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\NewProducts; - -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrder; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Product; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Used to query the latest products, see NewProductsController in Front Office. - */ -class NewProductsProductSearchProvider implements ProductSearchProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var SortOrderFactory - */ - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * @param string $type - * - * @return array - */ - private function getProductsOrCount( - ProductSearchContext $context, - ProductSearchQuery $query, - $type = 'products' - ) { - return Product::getNewProducts( - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $type !== 'products', - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay() - ); - } - - /** - * {@inheritdoc} - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - if (!$products = $this->getProductsOrCount($context, $query, 'products')) { - $products = []; - } - $count = $this->getProductsOrCount($context, $query, 'count'); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - [ - (new SortOrder('product', 'date_add', 'desc'))->setLabel( - $this->translator->trans('Date added, newest to oldest', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'date_add', 'asc'))->setLabel( - $this->translator->trans('Date added, oldest to newest', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'asc'))->setLabel( - $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'desc'))->setLabel( - $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'asc'))->setLabel( - $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'desc'))->setLabel( - $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog') - ), - ] - ); - } - - return $result; - } -} diff --git a/src/Adapter/News/NewsDataProvider.php b/src/Adapter/News/NewsDataProvider.php deleted file mode 100644 index 89670123..00000000 --- a/src/Adapter/News/NewsDataProvider.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\News; - -use Context; -use PrestaShop\CircuitBreaker\Contract\CircuitBreakerInterface; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Country\CountryDataProvider; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Adapter\Validate; - -/** - * Provide the news from https://www.prestashop.com/blog/ - */ -class NewsDataProvider -{ - const NUM_ARTICLES = 2; - - const CLOSED_ALLOWED_FAILURES = 3; - const CLOSED_TIMEOUT_SECONDS = 3; - - const OPEN_ALLOWED_FAILURES = 3; - const OPEN_TIMEOUT_SECONDS = 3; - const OPEN_THRESHOLD_SECONDS = 86400; // 24 hours - - /** - * @var CircuitBreakerInterface - */ - private $circuitBreaker; - - /** - * @var Configuration - */ - private $configuration; - - /** - * @var int - */ - private $contextMode; - - /** - * @var CountryDataProvider - */ - private $countryDataProvider; - - /** - * @var Tools - */ - private $tools; - - /** - * @var Validate - */ - private $validate; - - /** - * NewsDataProvider constructor. - * - * @param CircuitBreakerInterface $circuitBreaker - * @param CountryDataProvider $countryDataProvider - * @param Tools $tools - * @param Configuration $configuration - * @param Validate $validate - * @param int $contextMode - */ - public function __construct( - CircuitBreakerInterface $circuitBreaker, - CountryDataProvider $countryDataProvider, - Tools $tools, - Configuration $configuration, - Validate $validate, - $contextMode - ) { - $this->circuitBreaker = $circuitBreaker; - $this->configuration = $configuration; - $this->contextMode = $contextMode; - $this->countryDataProvider = $countryDataProvider; - $this->tools = $tools; - $this->validate = $validate; - } - - /** - * @param string $isoCode - * - * @return array - * - * @throws \PrestaShopException - */ - public function getData($isoCode) - { - $data = ['has_errors' => true, 'rss' => []]; - $apiUrl = $this->configuration->get('_PS_API_URL_'); - - $blogXMLResponse = $this->circuitBreaker->call($apiUrl . '/rss/blog/blog-' . $isoCode . '.xml'); - - if (empty($blogXMLResponse)) { - $data['has_errors'] = false; - - return $data; - } - - $rss = @simplexml_load_string($blogXMLResponse); - if (!$rss) { - return $data; - } - - $articles_limit = self::NUM_ARTICLES; - - $shop_default_country_id = (int) $this->configuration->get('PS_COUNTRY_DEFAULT'); - $shop_default_iso_country = mb_strtoupper($this->countryDataProvider->getIsoCodebyId($shop_default_country_id), 'utf-8'); - $analytics_params = [ - 'utm_source' => 'back-office', - 'utm_medium' => 'rss', - 'utm_campaign' => 'back-office-' . $shop_default_iso_country, - ]; - - foreach ($rss->channel->item as $item) { - if ($articles_limit == 0) { - break; - } - if (!$this->validate->isCleanHtml((string) $item->title) - || !$this->validate->isCleanHtml((string) $item->description) - || empty($item->link) - || empty($item->title)) { - continue; - } - $analytics_params['utm_content'] = 'download'; - if (in_array($this->contextMode, [Context::MODE_HOST, Context::MODE_HOST_CONTRIB])) { - $analytics_params['utm_content'] = 'cloud'; - } - - $url_query = parse_url($item->link, PHP_URL_QUERY); - parse_str($url_query, $link_query_params); - $full_url_params = array_merge($link_query_params, $analytics_params); - $base_url = explode('?', (string) $item->link); - $base_url = (string) $base_url[0]; - $article_link = $base_url . '?' . http_build_query($full_url_params); - $date = strtotime($item->pubDate); - $data['rss'][] = [ - 'date' => $this->tools->displayDate(date('Y-m-d H:i:s', $date), null, false), - 'title' => htmlentities($item->title, ENT_QUOTES, 'utf-8'), - 'short_desc' => $this->tools->truncateString(strip_tags((string) $item->description), 150), - 'link' => (string) $article_link, - ]; - --$articles_limit; - } - $data['has_errors'] = false; - - return $data; - } -} diff --git a/src/Adapter/Notification/CommandHandler/UpdateEmployeeNotificationLastElementHandler.php b/src/Adapter/Notification/CommandHandler/UpdateEmployeeNotificationLastElementHandler.php deleted file mode 100644 index 9f554cb7..00000000 --- a/src/Adapter/Notification/CommandHandler/UpdateEmployeeNotificationLastElementHandler.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Notification\CommandHandler; - -use Notification; -use PrestaShop\PrestaShop\Core\Domain\Notification\Command\UpdateEmployeeNotificationLastElementCommand; -use PrestaShop\PrestaShop\Core\Domain\Notification\CommandHandler\UpdateEmployeeNotificationLastElementCommandHandlerInterface; - -/** - * Handle update employee's last notification element of a given type - * - * @internal - */ -final class UpdateEmployeeNotificationLastElementHandler implements UpdateEmployeeNotificationLastElementCommandHandlerInterface -{ - /** - * @param UpdateEmployeeNotificationLastElementCommand $command - */ - public function handle(UpdateEmployeeNotificationLastElementCommand $command) - { - (new Notification())->updateEmployeeLastElement($command->getType()->getValue()); - } -} diff --git a/src/Adapter/Notification/QueryHandler/GetNotificationLastElementsHandler.php b/src/Adapter/Notification/QueryHandler/GetNotificationLastElementsHandler.php deleted file mode 100644 index 4220d074..00000000 --- a/src/Adapter/Notification/QueryHandler/GetNotificationLastElementsHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Notification\QueryHandler; - -use Notification; -use PrestaShop\PrestaShop\Core\Domain\Notification\Query\GetNotificationLastElements; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryHandler\GetNotificationLastElementsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationResult; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationsResult; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationsResults; - -/** - * Get employee last notification elements - * - * @internal - */ -final class GetNotificationLastElementsHandler implements GetNotificationLastElementsHandlerInterface -{ - /** - * @param GetNotificationLastElements $query - * - * @return NotificationsResults - * - * {@inheritdoc} - */ - public function handle(GetNotificationLastElements $query): NotificationsResults - { - $elements = (new Notification())->getLastElements(); - $results = []; - foreach ($elements as $type => $notifications) { - $notificationsResult = []; - foreach ($notifications['results'] as $notification) { - $notificationsResult[] = new NotificationResult( - $notification['id_order'], - $notification['id_customer'], - $notification['customer_name'], - $notification['id_customer_message'], - $notification['id_customer_thread'], - $notification['customer_view_url'], - $notification['total_paid'], - $notification['carrier'], - $notification['iso_code'], - $notification['company'], - $notification['status'], - $notification['date_add'] - ); - } - $results[] = new NotificationsResult($type, $notifications['total'], $notificationsResult); - } - - return new NotificationsResults($results); - } -} diff --git a/src/Adapter/Number/RoundModeConverter.php b/src/Adapter/Number/RoundModeConverter.php deleted file mode 100644 index 8f0469e1..00000000 --- a/src/Adapter/Number/RoundModeConverter.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Number; - -use PrestaShop\Decimal\Operation\Rounding; -use PrestaShop\PrestaShop\Adapter\CoreException; - -class RoundModeConverter -{ - const MODE_MAP = [ - PS_ROUND_UP => Rounding::ROUND_CEIL, - PS_ROUND_DOWN => Rounding::ROUND_FLOOR, - PS_ROUND_HALF_UP => Rounding::ROUND_HALF_UP, - PS_ROUND_HALF_DOWN => Rounding::ROUND_HALF_DOWN, - PS_ROUND_HALF_EVEN => Rounding::ROUND_HALF_EVEN, - ]; - - /** - * @param int $legacyRoundMode - * - * @return string - * - * @throws CoreException - */ - public static function getNumberRoundMode(int $legacyRoundMode): string - { - if (!isset(static::MODE_MAP[$legacyRoundMode])) { - throw new CoreException(sprintf('Cannot map round mode %d', $legacyRoundMode)); - } - - return static::MODE_MAP[$legacyRoundMode]; - } -} diff --git a/src/Adapter/ObjectPresenter.php b/src/Adapter/ObjectPresenter.php deleted file mode 100644 index e1bd8c61..00000000 --- a/src/Adapter/ObjectPresenter.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Object\ObjectPresenter - */ -class ObjectPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Object\ObjectPresenter -{ -} diff --git a/src/Adapter/OptionalFeatures/OptionalFeaturesConfiguration.php b/src/Adapter/OptionalFeatures/OptionalFeaturesConfiguration.php deleted file mode 100644 index db432699..00000000 --- a/src/Adapter/OptionalFeatures/OptionalFeaturesConfiguration.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OptionalFeatures; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Feature\CombinationFeature; -use PrestaShop\PrestaShop\Adapter\Feature\FeatureFeature; -use PrestaShop\PrestaShop\Adapter\Feature\GroupFeature; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class will provide Optional features configuration for a Shop. - */ -class OptionalFeaturesConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @var CombinationFeature - */ - private $combinationFeature; - - /** - * @var FeatureFeature - */ - private $featureFeature; - - /** - * @var GroupFeature - */ - private $groupFeature; - - public function __construct( - Configuration $configuration, - CombinationFeature $combinationFeature, - FeatureFeature $featureFeature, - GroupFeature $groupFeature - ) { - $this->configuration = $configuration; - $this->combinationFeature = $combinationFeature; - $this->featureFeature = $featureFeature; - $this->groupFeature = $groupFeature; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'combinations' => $this->combinationFeature->isActive(), - 'features' => $this->featureFeature->isActive(), - 'customer_groups' => $this->groupFeature->isActive(), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->combinationFeature->update((bool) $configuration['combinations']); - $this->featureFeature->update((bool) $configuration['features']); - $this->groupFeature->update((bool) $configuration['customer_groups']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['combinations'], - $configuration['features'], - $configuration['customer_groups'] - ); - } -} diff --git a/src/Adapter/Order/AbstractOrderHandler.php b/src/Adapter/Order/AbstractOrderHandler.php deleted file mode 100644 index 71f99073..00000000 --- a/src/Adapter/Order/AbstractOrderHandler.php +++ /dev/null @@ -1,176 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use Address; -use Cart; -use Combination; -use Configuration; -use Currency; -use Customer; -use Group; -use Order; -use PrestaShop\PrestaShop\Adapter\Number\RoundModeConverter; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShopException; -use Product; -use Validate; - -/** - * Reusable methods for Order subdomain command/query handlers. - */ -abstract class AbstractOrderHandler -{ - /** - * @param OrderId $orderId - * - * @return Order - */ - protected function getOrder(OrderId $orderId) - { - try { - $order = new Order($orderId->getValue()); - } catch (PrestaShopException $e) { - throw new OrderException( - sprintf( - 'Error occured when trying to get order object #%s', - $orderId->getValue() - ), - 0, - $e - ); - } - - if ($order->id !== $orderId->getValue()) { - throw new OrderNotFoundException($orderId, sprintf('Order with id "%d" was not found.', $orderId->getValue())); - } - - return $order; - } - - /** - * @param Order $order - * - * @return bool - */ - protected function isTaxIncludedInOrder(Order $order): bool - { - return $this->getOrderTaxCalculationMethod($order) === PS_TAX_INC; - } - - /** - * @param Order $order - * - * @return int - */ - protected function getOrderTaxCalculationMethod(Order $order): int - { - $customer = new Customer($order->id_customer); - - return Group::getPriceDisplayMethod((int) $customer->id_default_group); - } - - /** - * @param Cart $cart - * - * @return int - */ - protected function getPrecisionFromCart(Cart $cart): int - { - $computingPrecision = new ComputingPrecision(); - $currency = new Currency((int) $cart->id_currency); - - return $computingPrecision->getPrecision($currency->precision); - } - - /** - * @param int $combinationId - * - * @return Combination|null - */ - protected function getCombination(int $combinationId) - { - $combination = null; - - if (0 !== $combinationId) { - $combination = new Combination($combinationId); - - if (!Validate::isLoadedObject($combination)) { - throw new OrderException('Product combination not found.'); - } - } - - return $combination; - } - - /** - * @param ProductId $productId - * @param int $langId - * - * @return Product - */ - protected function getProduct(ProductId $productId, $langId) - { - $product = new Product($productId->getValue(), false, $langId); - - if ($product->id !== $productId->getValue()) { - throw new OrderException(sprintf('Product with id "%d" is invalid.', $productId->getValue())); - } - - return $product; - } - - /** - * @return string - */ - protected function getNumberRoundMode(): string - { - return RoundModeConverter::getNumberRoundMode((int) Configuration::get('PS_PRICE_ROUND_MODE')); - } - - /** - * Delivery option consists of deliveryAddress and carrierId. - * - * Legacy multishipping feature used comma separated carriers in delivery option (e.g. {'1':'6,7'} - * Now that multishipping is gone - delivery option should consist of one carrier and one address. - * - * However the structure of deliveryOptions is still used with comma in legacy, so - * this method provides assurance for deliveryOption structure until major refactoring - * - * @param int $carrierId - * - * @return string - */ - protected function formatLegacyDeliveryOptionFromCarrierId(int $carrierId): string - { - return sprintf('%d,', $carrierId); - } -} diff --git a/src/Adapter/Order/CommandHandler/AbstractOrderCommandHandler.php b/src/Adapter/Order/CommandHandler/AbstractOrderCommandHandler.php deleted file mode 100644 index fe53852f..00000000 --- a/src/Adapter/Order/CommandHandler/AbstractOrderCommandHandler.php +++ /dev/null @@ -1,224 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Address; -use Cart; -use Configuration; -use Context; -use Country; -use Currency; -use Customer; -use Language; -use Order; -use OrderDetail; -use Pack; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\StockManager; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use Product; -use Shop; -use StockAvailable; -use StockManagerFactory; -use StockMvt; -use Warehouse; - -/** - * Abstracts reusable functionality for Order subdomain handlers. - * - * @internal - */ -abstract class AbstractOrderCommandHandler extends AbstractOrderHandler -{ - /** - * @param OrderDetail $orderDetail - * @param int $productQuantity - * @param bool $delete - */ - protected function reinjectQuantity(OrderDetail $orderDetail, $productQuantity, $delete = false) - { - // Reinject product - $reinjectableQuantity = (int) $orderDetail->product_quantity - (int) $orderDetail->product_quantity_reinjected; - $quantityToReinject = $productQuantity > $reinjectableQuantity ? $reinjectableQuantity : $productQuantity; - - $product = new Product( - $orderDetail->product_id, - false, - (int) Context::getContext()->language->id, - (int) $orderDetail->id_shop - ); - - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') - && $product->advanced_stock_management - && $orderDetail->id_warehouse != 0 - ) { - $manager = StockManagerFactory::getManager(); - $movements = StockMvt::getNegativeStockMvts( - $orderDetail->id_order, - $orderDetail->product_id, - $orderDetail->product_attribute_id, - $quantityToReinject - ); - - foreach ($movements as $movement) { - if ($quantityToReinject > $movement['physical_quantity']) { - $quantityToReinject = $movement['physical_quantity']; - } - - if (Pack::isPack((int) $product->id)) { - // Gets items - if ($product->pack_stock_type == Pack::STOCK_TYPE_PRODUCTS_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ($product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && Configuration::get('PS_PACK_STOCK_TYPE') > 0) - ) { - $products_pack = Pack::getItems((int) $product->id, (int) Configuration::get('PS_LANG_DEFAULT')); - // Foreach item - foreach ($products_pack as $product_pack) { - if ($product_pack->advanced_stock_management == 1) { - $manager->addProduct( - $product_pack->id, - $product_pack->id_pack_product_attribute, - new Warehouse($movement['id_warehouse']), - $product_pack->pack_quantity * $quantityToReinject, - null, - $movement['price_te'] - ); - } - } - } - - if ($product->pack_stock_type == Pack::STOCK_TYPE_PACK_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ( - $product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && (Configuration::get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_ONLY - || Configuration::get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_BOTH) - ) - ) { - $manager->addProduct( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - new Warehouse($movement['id_warehouse']), - $quantityToReinject, - null, - $movement['price_te'] - ); - } - } else { - $manager->addProduct( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - new Warehouse($movement['id_warehouse']), - $quantityToReinject, - null, - $movement['price_te'] - ); - } - } - - $productId = $orderDetail->product_id; - - if ($delete) { - $orderDetail->delete(); - } - - StockAvailable::synchronize($productId); - } elseif ($orderDetail->id_warehouse == 0) { - StockAvailable::updateQuantity( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - $quantityToReinject, - $orderDetail->id_shop, - true, - [ - 'id_order' => $orderDetail->id_order, - 'id_stock_mvt_reason' => Configuration::get('PS_STOCK_CUSTOMER_RETURN_REASON'), - ] - ); - - // sync all stock - (new StockManager())->updatePhysicalProductQuantity( - (int) $orderDetail->id_shop, - (int) Configuration::get('PS_OS_ERROR'), - (int) Configuration::get('PS_OS_CANCELED'), - null, - (int) $orderDetail->id_order - ); - - if ($delete) { - $orderDetail->delete(); - } - } else { - throw new OrderException('This product cannot be re-stocked.'); - } - } - - /** - * @param ContextStateManager $contextStateManager - * @param Cart $cart - */ - protected function setCartContext(ContextStateManager $contextStateManager, Cart $cart): void - { - $contextStateManager - ->setCart($cart) - ->setCustomer(new Customer($cart->id_customer)) - ->setCurrency(new Currency($cart->id_currency)) - ->setLanguage(new Language($cart->id_lang)) - ->setCountry($this->getCartTaxCountry($cart)) - ->setShop(new Shop($cart->id_shop)) - ; - } - - /** - * @param ContextStateManager $contextStateManager - * @param Order $order - */ - protected function setOrderContext(ContextStateManager $contextStateManager, Order $order): void - { - $cart = new Cart($order->id_cart); - $this->setCartContext($contextStateManager, $cart); - } - - /** - * @param Cart $cart - * - * @return Country - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - protected function getCartTaxCountry(Cart $cart): Country - { - $taxAddressType = Configuration::get('PS_TAX_ADDRESS_TYPE'); - $taxAddressId = property_exists($cart, $taxAddressType) ? $cart->{$taxAddressType} : $cart->id_address_delivery; - $taxAddress = new Address($taxAddressId); - - return new Country($taxAddress->id_country); - } -} diff --git a/src/Adapter/Order/CommandHandler/AddCartRuleToOrderHandler.php b/src/Adapter/Order/CommandHandler/AddCartRuleToOrderHandler.php deleted file mode 100644 index 2521a647..00000000 --- a/src/Adapter/Order/CommandHandler/AddCartRuleToOrderHandler.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use CartRule; -use Configuration; -use Currency; -use Customer; -use Order; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\InvalidCartRuleDiscountValueException; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\AddCartRuleToOrderCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\AddCartRuleToOrderHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderDiscountType; -use PrestaShopException; -use Shop; -use Validate; - -/** - * @internal - */ -final class AddCartRuleToOrderHandler extends AbstractOrderHandler implements AddCartRuleToOrderHandlerInterface -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param OrderAmountUpdater $orderAmountUpdater - * @param ContextStateManager $contextStateManager - */ - public function __construct(OrderAmountUpdater $orderAmountUpdater, ContextStateManager $contextStateManager) - { - $this->orderAmountUpdater = $orderAmountUpdater; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(AddCartRuleToOrderCommand $command): void - { - $this->assertPercentCartRule($command); - $order = $this->getOrder($command->getOrderId()); - - $this->contextStateManager - ->setCurrency(new Currency($order->id_currency)) - ->setCustomer(new Customer($order->id_customer)) - ->setShop(new Shop($order->id_shop)) - ; - - try { - $this->addCartRuleAndUpdateOrder($command, $order); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param AddCartRuleToOrderCommand $command - * @param Order $order - * - * @return void - * - * @throws InvalidCartRuleDiscountValueException - * @throws OrderException - * @throws PrestaShopException - * @throws \PrestaShopDatabaseException - */ - private function addCartRuleAndUpdateOrder(AddCartRuleToOrderCommand $command, Order $order): void - { - // If the discount is for only one invoice - $orderInvoice = null; - if ($order->hasInvoice() && null !== $command->getOrderInvoiceId()) { - $orderInvoice = new OrderInvoice($command->getOrderInvoiceId()->getValue()); - if (!Validate::isLoadedObject($orderInvoice)) { - throw new OrderException('Can\'t load Order Invoice object'); - } - } - $this->assertAmountCartRule($command, $order, $orderInvoice); - $this->assertFreeShippingCartRule($command, $order, $orderInvoice); - - $cart = Cart::getCartByOrderId($order->id); - $cartRuleObj = new CartRule(); - $cartRuleObj->date_from = date('Y-m-d H:i:s', strtotime('-1 hour', strtotime($order->date_add))); - $cartRuleObj->date_to = date('Y-m-d H:i:s', strtotime('+1 hour')); - $cartRuleObj->name[Configuration::get('PS_LANG_DEFAULT')] = $command->getCartRuleName(); - // This a one time cart rule, for a specific user that can only be used once - $cartRuleObj->id_customer = $cart->id_customer; - $cartRuleObj->quantity = 1; - $cartRuleObj->quantity_per_user = 1; - $cartRuleObj->active = 0; - $cartRuleObj->highlight = 0; - $cartRuleObj->reduction_currency = (int) $order->id_currency; - - if ($command->getCartRuleType() === OrderDiscountType::DISCOUNT_PERCENT) { - $cartRuleObj->reduction_percent = (float) (string) $command->getDiscountValue(); - } elseif ($command->getCartRuleType() === OrderDiscountType::DISCOUNT_AMOUNT) { - $discountValueTaxIncluded = (float) (string) $command->getDiscountValue(); - $cartRuleObj->reduction_amount = $discountValueTaxIncluded; - $cartRuleObj->reduction_tax = 1; - } elseif ($command->getCartRuleType() === OrderDiscountType::FREE_SHIPPING) { - $cartRuleObj->free_shipping = 1; - } - - try { - if (!$cartRuleObj->add()) { - throw new OrderException('An error occurred during the CartRule creation'); - } - } catch (PrestaShopException $e) { - throw new OrderException('An error occurred during the CartRule creation', 0, $e); - } - - try { - // It's important to add the cart rule to the cart Or it will be ignored when cart performs AutoRemove AddAdd - if (!$cart->addCartRule($cartRuleObj->id)) { - throw new OrderException('An error occurred while adding CartRule to cart'); - } - } catch (PrestaShopException $e) { - throw new OrderException('An error occurred while adding CartRule to cart', 0, $e); - } - - $this->orderAmountUpdater->update($order, $cart, null !== $orderInvoice ? (int) $orderInvoice->id : null); - } - - /** - * @param AddCartRuleToOrderCommand $command - * - * @throws InvalidCartRuleDiscountValueException - */ - private function assertPercentCartRule(AddCartRuleToOrderCommand $command): void - { - if (OrderDiscountType::DISCOUNT_PERCENT !== $command->getCartRuleType()) { - return; - } - - $discountValue = (float) (string) $command->getDiscountValue(); - if ($discountValue <= 0) { - throw new InvalidCartRuleDiscountValueException( - 'Percent value must be greater than 0', - InvalidCartRuleDiscountValueException::INVALID_MIN_PERCENT - ); - } elseif ($discountValue > 100) { - throw new InvalidCartRuleDiscountValueException( - 'Percent value must be less than 100', - InvalidCartRuleDiscountValueException::INVALID_MAX_PERCENT - ); - } - } - - /** - * @param AddCartRuleToOrderCommand $command - * @param Order $order - * @param OrderInvoice|null $orderInvoice - * - * @throws InvalidCartRuleDiscountValueException - */ - private function assertAmountCartRule(AddCartRuleToOrderCommand $command, Order $order, ?OrderInvoice $orderInvoice): void - { - if (OrderDiscountType::DISCOUNT_AMOUNT !== $command->getCartRuleType()) { - return; - } - - if (null === $command->getDiscountValue() || $command->getDiscountValue()->isLowerOrEqualThanZero()) { - throw new InvalidCartRuleDiscountValueException( - 'Discount amount specified is not positive', - InvalidCartRuleDiscountValueException::INVALID_MIN_AMOUNT - ); - } - - $discountValue = (float) (string) $command->getDiscountValue(); - if (null !== $orderInvoice) { - $orderInvoices = [$orderInvoice]; - } elseif ($order->hasInvoice()) { - $orderInvoices = $order->getInvoicesCollection()->getResults(); - } - if (!empty($orderInvoices)) { - foreach ($orderInvoices as $invoice) { - if ($discountValue > $invoice->total_paid_tax_incl) { - throw new InvalidCartRuleDiscountValueException( - 'Discount amount specified is too high', - InvalidCartRuleDiscountValueException::INVALID_MAX_AMOUNT - ); - } - } - } else { - if ($discountValue > $order->total_paid_tax_incl) { - throw new InvalidCartRuleDiscountValueException( - 'Discount amount specified is too high', - InvalidCartRuleDiscountValueException::INVALID_MAX_AMOUNT - ); - } - } - } - - /** - * @param AddCartRuleToOrderCommand $command - * @param Order $order - * @param OrderInvoice|null $orderInvoice - * - * @throws InvalidCartRuleDiscountValueException - */ - private function assertFreeShippingCartRule(AddCartRuleToOrderCommand $command, Order $order, ?OrderInvoice $orderInvoice): void - { - if (OrderDiscountType::FREE_SHIPPING !== $command->getCartRuleType()) { - return; - } - - if (null !== $orderInvoice) { - $orderInvoices = [$orderInvoice]; - } elseif ($order->hasInvoice()) { - $orderInvoices = $order->getInvoicesCollection()->getResults(); - } - if (!empty($orderInvoices)) { - foreach ($orderInvoices as $invoice) { - if ($invoice->total_paid_tax_incl <= $invoice->total_shipping_tax_incl) { - throw new InvalidCartRuleDiscountValueException( - 'Discount amount specified is too high', - InvalidCartRuleDiscountValueException::INVALID_FREE_SHIPPING - ); - } - } - } else { - if ($order->total_paid_tax_incl <= $order->total_shipping_tax_incl) { - throw new InvalidCartRuleDiscountValueException( - 'Discount amount specified is too high', - InvalidCartRuleDiscountValueException::INVALID_FREE_SHIPPING - ); - } - } - } -} diff --git a/src/Adapter/Order/CommandHandler/AddOrderFromBackOfficeHandler.php b/src/Adapter/Order/CommandHandler/AddOrderFromBackOfficeHandler.php deleted file mode 100644 index 72e4066c..00000000 --- a/src/Adapter/Order/CommandHandler/AddOrderFromBackOfficeHandler.php +++ /dev/null @@ -1,195 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Address; -use BoOrderCore; -use Cart; -use Configuration; -use Context; -use Country; -use Currency; -use Customer; -use Employee; -use Exception; -use Language; -use Message; -use Module; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\AddOrderFromBackOfficeCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\AddOrderFromBackOfficeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use Shop; -use Validate; - -/** - * @internal - */ -final class AddOrderFromBackOfficeHandler implements AddOrderFromBackOfficeHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ContextStateManager $contextStateManager - */ - public function __construct(ContextStateManager $contextStateManager) - { - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(AddOrderFromBackOfficeCommand $command) - { - $paymentModule = !Configuration::get('PS_CATALOG_MODE') ? - Module::getInstanceByName($command->getPaymentModuleName()) : - new BoOrderCore(); - - if (false === $paymentModule) { - throw new OrderException(sprintf('Payment method "%s" does not exist.', $paymentModule)); - } - - $cart = new Cart($command->getCartId()->getValue()); - - $this->assertAddressesAreNotDisabled($cart); - - //Context country, language and currency is used in PaymentModule::validateOrder (it should rely on cart address country instead) - $this->contextStateManager - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setCustomer(new Customer($cart->id_customer)) - ->setLanguage(new Language($cart->id_lang)) - ->setCountry($this->getTaxCountry($cart)) - ->setShop(new Shop($cart->id_shop)) - ; - - $translator = Context::getContext()->getTranslator(); - $employee = new Employee($command->getEmployeeId()->getValue()); - $message = sprintf( - '%s %s. %s', - $translator->trans('Manual order -- Employee:', [], 'Admin.Orderscustomers.Feature'), - $employee->firstname[0], - $employee->lastname - ); - - try { - $orderMessage = $command->getOrderMessage(); - if (!empty($orderMessage)) { - $this->addOrderMessage($cart, $orderMessage); - } - - $paymentModule->validateOrder( - (int) $cart->id, - $command->getOrderStateId(), - $cart->getOrderTotal(), - $paymentModule->displayName, - $message, - [], - null, - false, - $cart->secure_key - ); - } catch (Exception $e) { - throw new OrderException('Failed to add order. ' . $e->getMessage(), 0, $e); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - - if (!$paymentModule->currentOrder) { - throw new OrderException('Failed to add order.'); - } - - return new OrderId((int) $paymentModule->currentOrder); - } - - /** - * Saves customer message and link it to the cart. - * - * @param Cart $cart - * @param string $orderMessage - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - * @throws OrderConstraintException - */ - private function addOrderMessage(Cart $cart, string $orderMessage): void - { - if (!Validate::isMessage($orderMessage)) { - throw new OrderConstraintException('The order message is invalid', OrderConstraintException::INVALID_CUSTOMER_MESSAGE); - } - - $messageId = null; - if ($oldMessage = Message::getMessageByCartId((int) $cart->id)) { - $messageId = $oldMessage['id_message']; - } - $message = new Message((int) $messageId); - $message->message = $orderMessage; - $message->id_cart = (int) $cart->id; - $message->id_customer = (int) $cart->id_customer; - $message->save(); - } - - /** - * @param Cart $cart - */ - private function assertAddressesAreNotDisabled(Cart $cart) - { - $isDeliveryCountryDisabled = !Address::isCountryActiveById((int) $cart->id_address_delivery); - $isInvoiceCountryDisabled = !Address::isCountryActiveById((int) $cart->id_address_invoice); - - if ($isDeliveryCountryDisabled) { - throw new OrderException(sprintf('Delivery country for cart with id "%d" is disabled.', $cart->id)); - } - - if ($isInvoiceCountryDisabled) { - throw new OrderException(sprintf('Invoice country for cart with id "%d" is disabled.', $cart->id)); - } - } - - /** - * @param Cart $cart - * - * @return Country - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function getTaxCountry(Cart $cart) - { - $taxAddressType = Configuration::get('PS_TAX_ADDRESS_TYPE'); - $taxAddressId = property_exists($cart, $taxAddressType) ? $cart->{$taxAddressType} : $cart->id_address_delivery; - $taxAddress = new Address($taxAddressId); - - return new Country($taxAddress->id_country); - } -} diff --git a/src/Adapter/Order/CommandHandler/AddPaymentHandler.php b/src/Adapter/Order/CommandHandler/AddPaymentHandler.php deleted file mode 100644 index 11583ed2..00000000 --- a/src/Adapter/Order/CommandHandler/AddPaymentHandler.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Currency; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Payment\Command\AddPaymentCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Payment\CommandHandler\AddPaymentHandlerInterface; -use Validate; - -/** - * @internal - */ -final class AddPaymentHandler extends AbstractOrderHandler implements AddPaymentHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddPaymentCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - - $currency = new Currency($command->getPaymentCurrencyId()->getValue()); - $orderHasInvoice = $order->hasInvoice(); - - if ($orderHasInvoice) { - $orderInvoice = new OrderInvoice($command->getOrderInvoiceId()); - } else { - $orderInvoice = null; - } - - if (!Validate::isLoadedObject($currency)) { - throw new OrderException('The selected currency is invalid.'); - } - - if ($orderHasInvoice && !Validate::isLoadedObject($orderInvoice)) { - throw new OrderException('The invoice is invalid.'); - } - - $paymentAdded = $order->addOrderPayment( - (string) $command->getPaymentAmount(), - $command->getPaymentMethod(), - $command->getPaymentTransactionId(), - $currency, - $command->getPaymentDate()->format('Y-m-d H:i:s'), - $orderInvoice - ); - - if (!$paymentAdded) { - throw new OrderException('An error occurred during payment.'); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/AddProductToOrderHandler.php b/src/Adapter/Order/CommandHandler/AddProductToOrderHandler.php deleted file mode 100644 index 8a2b5e2b..00000000 --- a/src/Adapter/Order/CommandHandler/AddProductToOrderHandler.php +++ /dev/null @@ -1,608 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Address; -use Attribute; -use Carrier; -use Cart; -use CartRule; -use Combination; -use Configuration; -use Context; -use Currency; -use Customer; -use Hook; -use Order; -use OrderCarrier; -use OrderDetail; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductsComparator; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductUpdate; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderDetailUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateProductInOrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateProductInOrderInvoiceException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\AddProductToOrderCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler\AddProductToOrderHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductOutOfStockException; -use Product; -use Shop; -use StockAvailable; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -/** - * Handles adding product to an existing order using legacy object model classes. - * - * @internal - */ -final class AddProductToOrderHandler extends AbstractOrderHandler implements AddProductToOrderHandlerInterface -{ - /** - * @var Context - */ - private $context; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var int - */ - private $computingPrecision; - - /** - * @var OrderProductQuantityUpdater - */ - private $orderProductQuantityUpdater; - - /** - * @var OrderDetailUpdater - */ - private $orderDetailUpdater; - - /** - * @param TranslatorInterface $translator - * @param ContextStateManager $contextStateManager - * @param OrderAmountUpdater $orderAmountUpdater - * @param OrderProductQuantityUpdater $orderProductQuantityUpdater - * @param OrderDetailUpdater $orderDetailUpdater - */ - public function __construct( - TranslatorInterface $translator, - ContextStateManager $contextStateManager, - OrderAmountUpdater $orderAmountUpdater, - OrderProductQuantityUpdater $orderProductQuantityUpdater, - OrderDetailUpdater $orderDetailUpdater - ) { - $this->context = Context::getContext(); - $this->translator = $translator; - $this->contextStateManager = $contextStateManager; - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderProductQuantityUpdater = $orderProductQuantityUpdater; - $this->orderDetailUpdater = $orderDetailUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(AddProductToOrderCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - - $this->assertOrderWasNotShipped($order); - $this->assertProductNotDuplicate($order, $command); - - $cart = Cart::getCartByOrderId($order->id); - if (!($cart instanceof Cart)) { - throw new OrderException('Cart linked to the order cannot be found.'); - } - - $product = $this->getProduct($command->getProductId(), (int) $order->id_lang); - $combination = null !== $command->getCombinationId() ? $this->getCombination($command->getCombinationId()->getValue()) : null; - $combinationId = null !== $combination ? (int) $combination->id : 0; - - $this->checkProductInStock($product, $command); - - $this->contextStateManager - ->setCurrency(new Currency($order->id_currency)) - ->setCustomer(new Customer($order->id_customer)) - ->setCart($cart) - ->setShop(new Shop($order->id_shop)) - ; - - $this->computingPrecision = $this->getPrecisionFromCart($cart); - try { - $cartComparator = new CartProductsComparator($cart); - $this->addProductToCart($cart, $product, $combination, $command->getProductQuantity()); - $updatedCartProducts = $cart->getProducts(true); - - // We get all the modification (creation AND updates) and then filter them - $productModifications = $cartComparator->getModifiedProducts(); - $creationModifications = []; - $updateModifications = []; - foreach ($productModifications as $cartProductUpdate) { - // Real creation is naturally a creation update - if ($cartProductUpdate->isCreated()) { - $creationModifications[] = $cartProductUpdate; - continue; - } - - // Now we check if the update is about the currently added product This is important for multi invoice orders, in case - // the added product was already in previous invoices - $cartCombinationId = null !== $cartProductUpdate->getCombinationId() ? $cartProductUpdate->getCombinationId()->getValue() : 0; - if ($cartProductUpdate->getProductId()->getValue() === (int) $product->id && $cartCombinationId === $combinationId) { - $creationModifications[] = $cartProductUpdate; - } else { - $updateModifications[] = $cartProductUpdate; - } - } - - $createdProducts = $this->getCreatedCartProducts( - $creationModifications, - $updatedCartProducts - ); - - $invoice = $this->createNewOrEditExistingInvoice( - $command, - $order, - $cart, - $createdProducts - ); - - // Create Order detail information - $this->createOrderDetails( - $order, - $invoice, - $cart, - $createdProducts - ); - - // Once OrderDetail has been created we update it (and identical ones) with the correct price - $this->orderDetailUpdater->updateOrderDetailsForProduct( - $order, - $command->getProductId()->getValue(), - null !== $command->getCombinationId() ? $command->getCombinationId()->getValue() : 0, - $command->getProductPriceTaxExcluded(), - $command->getProductPriceTaxIncluded() - ); - StockAvailable::synchronize($product->id); - - $this->updateAffectedOrderDetails( - $order, - $updateModifications - ); - - // Update totals amount of order - $this->orderAmountUpdater->update($order, $cart, null !== $invoice ? (int) $invoice->id : null); - Hook::exec('actionOrderEdited', ['order' => $order]); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - * - * @throws OrderException - */ - private function assertOrderWasNotShipped(Order $order) - { - if ($order->hasBeenShipped()) { - throw new OrderException('Cannot add product to shipped order.'); - } - } - - /** - * @param Order $order - * @param OrderInvoice|null $invoice - * @param Cart $cart - * @param array $cartProducts - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function createOrderDetails(Order $order, ?OrderInvoice $invoice, Cart $cart, array $cartProducts): void - { - $orderDetail = new OrderDetail(); - $orderDetail->createList( - $order, - $cart, - $order->getCurrentOrderState(), - $cartProducts, - !empty($invoice->id) ? $invoice->id : 0 - ); - } - - /** - * When a product is added some other products may be affected (because of CartRule that would - * add some gift for example) So we update products which have been modified in the cart and - * update the related OrderDetail - * - * @param Order $order - * @param CartProductUpdate[] $updatedProducts - * - * @throws OrderException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function updateAffectedOrderDetails( - Order $order, - array $updatedProducts - ): void { - $orderDetails = $order->getOrderDetailList(); - foreach ($updatedProducts as $updatedProduct) { - $updatedCombinationId = null !== $updatedProduct->getCombinationId() ? $updatedProduct->getCombinationId()->getValue() : 0; - $affectedOrderDetail = null; - foreach ($orderDetails as $orderDetailData) { - if ((int) $orderDetailData['product_id'] === $updatedProduct->getProductId()->getValue() - && (int) $orderDetailData['product_attribute_id'] === $updatedCombinationId) { - $affectedOrderDetail = new OrderDetail($orderDetailData['id_order_detail']); - break; - } - } - - $newUpdatedQuantity = (int) $affectedOrderDetail->product_quantity + $updatedProduct->getDeltaQuantity(); - $orderInvoice = (int) $affectedOrderDetail->id_order_invoice !== 0 ? new OrderInvoice($affectedOrderDetail->id_order_invoice) : null; - $this->orderProductQuantityUpdater->update( - $order, - $affectedOrderDetail, - $newUpdatedQuantity, - $orderInvoice, - false - ); - } - } - - /** - * @param CartProductUpdate[] $creationUpdates - * @param CartProductUpdate[] $cartProducts - * - * @return array - */ - private function getCreatedCartProducts( - array $creationUpdates, - array $cartProducts - ): array { - $additionalProducts = []; - foreach ($creationUpdates as $additionalUpdate) { - $updateProductId = $additionalUpdate->getProductId()->getValue(); - $updateCombinationId = null !== $additionalUpdate->getCombinationId() ? $additionalUpdate->getCombinationId()->getValue() : 0; - $cartProduct = $this->getMatchingProduct($cartProducts, [ - 'id_product' => $updateProductId, - 'id_product_attribute' => $updateCombinationId, - ]); - $cartProduct['cart_quantity'] = $additionalUpdate->getDeltaQuantity(); - $additionalProducts[] = $cartProduct; - } - - return $additionalProducts; - } - - /** - * Find a specific product among the product array - * - * @param array $productList - * @param array $searchedProduct - * - * @return array|null - */ - private function getMatchingProduct(array $productList, array $searchedProduct): ?array - { - return array_reduce($productList, function ($carry, $item) use ($searchedProduct) { - if (null !== $carry) { - return $carry; - } - - $productMatch = $item['id_product'] == $searchedProduct['id_product']; - $combinationMatch = $item['id_product_attribute'] == $searchedProduct['id_product_attribute']; - - return $productMatch && $combinationMatch ? $item : null; - }); - } - - /** - * @param Cart $cart - * @param Product $product - * @param Combination|null $combination - * @param int $quantity - */ - private function addProductToCart(Cart $cart, Product $product, $combination, $quantity): void - { - /** - * Here we update product and customization in the cart. - * - * The last argument "skip quantity check" is set to true because - * 1) the quantity has already been checked, - * 2) (main reason) when the cart checks the availability ; it substracts - * its own quantity from available stock. - * - * This is because a product in a cart is not really out of the stock, because it is not checked out yet. - * - * Here we are editing an order, not a cart, so what has been ordered - * has already been substracted from the stock. - */ - $result = $cart->updateQty( - $quantity, - $product->id, - $combination ? $combination->id : null, - false, - 'up', - 0, - new Shop($cart->id_shop), - true, - true - ); - - if ($result < 0) { - // If product has attribute, minimal quantity is set with minimal quantity of attribute - $minimalQuantity = $combination - ? Attribute::getAttributeMinimalQty($combination->id) : - $product->minimal_quantity - ; - - throw new OrderException(sprintf('Minimum quantity of "%d" must be added', $minimalQuantity)); - } - - if (!$result) { - throw new OrderException(sprintf('Product with id "%s" is out of stock.', $product->id)); - } - } - - /** - * @param AddProductToOrderCommand $command - * @param Order $order - * @param Cart $cart - * @param array $products - * - * @return OrderInvoice|null - */ - private function createNewOrEditExistingInvoice( - AddProductToOrderCommand $command, - Order $order, - Cart $cart, - array $products - ) { - if ($order->hasInvoice()) { - return $command->getOrderInvoiceId() ? - $this->updateExistingInvoice($command->getOrderInvoiceId(), $cart, $products) : - $this->createNewInvoice($order, $cart, $command->hasFreeShipping(), $products); - } - - return null; - } - - /** - * @todo: Most of this method can be simplified, since OrderAmountUpdater computes everything - * the invoice computation here should be removable, as well as $order->addCartRule - * - * @param Order $order - * @param Cart $cart - * @param bool $isFreeShipping - * @param array $newProducts - */ - private function createNewInvoice(Order $order, Cart $cart, $isFreeShipping, array $newProducts) - { - $invoice = new OrderInvoice(); - - // If we create a new invoice, we calculate shipping cost - $totalMethod = Cart::BOTH; - - // Create Cart rule in order to make free shipping - if ($isFreeShipping) { - // @todo: use private method to create cart rule - $freeShippingCartRule = new CartRule(); - $freeShippingCartRule->id_customer = $order->id_customer; - $freeShippingCartRule->name = [ - Configuration::get('PS_LANG_DEFAULT') => $this->translator->trans( - '[Generated] CartRule for Free Shipping', - [], - 'Admin.Orderscustomers.Notification' - ), - ]; - $freeShippingCartRule->date_from = date('Y-m-d H:i:s'); - $freeShippingCartRule->date_to = date('Y-m-d H:i:s', time() + 24 * 3600); - $freeShippingCartRule->quantity = 1; - $freeShippingCartRule->quantity_per_user = 1; - $freeShippingCartRule->minimum_amount_currency = $order->id_currency; - $freeShippingCartRule->reduction_currency = $order->id_currency; - $freeShippingCartRule->free_shipping = true; - $freeShippingCartRule->active = 1; - $freeShippingCartRule->add(); - - // Add cart rule to cart and in order - $cart->addCartRule($freeShippingCartRule->id); - $values = [ - 'tax_incl' => $freeShippingCartRule->getContextualValue(true), - 'tax_excl' => $freeShippingCartRule->getContextualValue(false), - ]; - - $order->addCartRule( - $freeShippingCartRule->id, - $freeShippingCartRule->name[Configuration::get('PS_LANG_DEFAULT')], - $values - ); - } - - $invoice->id_order = $order->id; - if ($invoice->number) { - Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $order->id_shop); - } else { - $invoice->number = Order::getLastInvoiceNumber() + 1; - } - - $invoice_address = new Address( - (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)} - ); - $carrier = new Carrier((int) $order->id_carrier); - $taxCalculator = $carrier->getTaxCalculator($invoice_address); - - $invoice->total_paid_tax_excl = Tools::ps_round( - (float) $cart->getOrderTotal(false, $totalMethod, $newProducts), - $this->computingPrecision - ); - $invoice->total_paid_tax_incl = Tools::ps_round( - (float) $cart->getOrderTotal(true, $totalMethod, $newProducts), - $this->computingPrecision - ); - $invoice->total_products = (float) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $newProducts); - $invoice->total_products_wt = (float) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $newProducts); - $invoice->total_shipping_tax_excl = (float) $cart->getTotalShippingCost(null, false); - $invoice->total_shipping_tax_incl = (float) $cart->getTotalShippingCost(); - - $invoice->total_wrapping_tax_excl = abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $newProducts)); - $invoice->total_wrapping_tax_incl = abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $newProducts)); - $invoice->shipping_tax_computation_method = (int) $taxCalculator->computation_method; - $invoice->add(); - - $invoice->saveCarrierTaxCalculator($taxCalculator->getTaxesAmount($invoice->total_shipping_tax_excl)); - - $orderCarrier = new OrderCarrier(); - $orderCarrier->id_order = (int) $order->id; - $orderCarrier->id_carrier = (int) $order->id_carrier; - $orderCarrier->id_order_invoice = (int) $invoice->id; - $orderCarrier->weight = (float) $cart->getTotalWeight(); - $orderCarrier->shipping_cost_tax_excl = (float) $invoice->total_shipping_tax_excl; - $orderCarrier->shipping_cost_tax_incl = (float) $invoice->total_shipping_tax_incl; - $orderCarrier->add(); - - return $invoice; - } - - /** - * @todo: this whole method should be removable as well since ALL invoices are updated by OrderAmountUpdater - * - * @param int $orderInvoiceId - * @param Cart $cart - * @param array $newProducts - * - * @return OrderInvoice - */ - private function updateExistingInvoice($orderInvoiceId, Cart $cart, array $newProducts) - { - $invoice = new OrderInvoice($orderInvoiceId); - - $invoice->total_paid_tax_excl += Tools::ps_round( - (float) $cart->getOrderTotal(false, Cart::BOTH_WITHOUT_SHIPPING, $newProducts), - $this->computingPrecision - ); - $invoice->total_paid_tax_incl += Tools::ps_round( - (float) $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING, $newProducts), - $this->computingPrecision - ); - $invoice->total_products += (float) $cart->getOrderTotal( - false, - Cart::ONLY_PRODUCTS, - $newProducts - ); - $invoice->total_products_wt += (float) $cart->getOrderTotal( - true, - Cart::ONLY_PRODUCTS, - $newProducts - ); - - $invoice->update(); - - return $invoice; - } - - /** - * @param Product $product - * @param AddProductToOrderCommand $command - * - * @throws ProductOutOfStockException - */ - private function checkProductInStock(Product $product, AddProductToOrderCommand $command): void - { - //check if product is available in stock - if (!Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($command->getProductId()->getValue()))) { - $combinationId = null !== $command->getCombinationId() ? $command->getCombinationId()->getValue() : 0; - $availableQuantity = StockAvailable::getQuantityAvailableByProduct($command->getProductId()->getValue(), $combinationId); - - if ($availableQuantity < $command->getProductQuantity()) { - throw new ProductOutOfStockException(sprintf('Product with id "%s" is out of stock, thus cannot be added to cart', $product->id)); - } - } - } - - /** - * @param Order $order - * @param AddProductToOrderCommand $command - * - * @throws DuplicateProductInOrderException - * @throws DuplicateProductInOrderInvoiceException - */ - private function assertProductNotDuplicate(Order $order, AddProductToOrderCommand $command): void - { - $invoicesContainingProduct = []; - foreach ($order->getOrderDetailList() as $orderDetail) { - if ($command->getProductId()->getValue() !== (int) $orderDetail['product_id']) { - continue; - } - if (!empty($command->getCombinationId()) && $command->getCombinationId()->getValue() !== (int) $orderDetail['product_attribute_id']) { - continue; - } - $invoicesContainingProduct[] = (int) $orderDetail['id_order_invoice']; - } - - if (empty($invoicesContainingProduct)) { - return; - } - - // If it's a new invoice (or no invoice), the ID is null, so we check if the Order has invoice (in which case - // a new one is going to be created) If it doesn't have invoices we don't allow adding duplicate OrderDetail - if (empty($command->getOrderInvoiceId()) && !$order->hasInvoice()) { - throw new DuplicateProductInOrderException('You cannot add this product in the order as it is already present'); - } - - // If we are targeting a specific invoice check that the ID has not been found in the OrderDetail list - if (!empty($command->getOrderInvoiceId()) && in_array((int) $command->getOrderInvoiceId(), $invoicesContainingProduct)) { - $orderInvoice = new OrderInvoice($command->getOrderInvoiceId()); - $invoiceNumber = $orderInvoice->getInvoiceNumberFormatted((int) Configuration::get('PS_LANG_DEFAULT'), $order->id_shop); - throw new DuplicateProductInOrderInvoiceException($invoiceNumber, 'You cannot add this product in this invoice as it is already present'); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/BulkChangeOrderStatusHandler.php b/src/Adapter/Order/CommandHandler/BulkChangeOrderStatusHandler.php deleted file mode 100644 index f320ff06..00000000 --- a/src/Adapter/Order/CommandHandler/BulkChangeOrderStatusHandler.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Carrier; -use Configuration; -use Context; -use Order; -use OrderHistory; -use OrderState; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\BulkChangeOrderStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\BulkChangeOrderStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\ChangeOrderStatusException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use StockAvailable; - -/** - * @internal - */ -final class BulkChangeOrderStatusHandler implements BulkChangeOrderStatusHandlerInterface -{ - /** - * @param BulkChangeOrderStatusCommand $command - */ - public function handle(BulkChangeOrderStatusCommand $command) - { - $orderState = new OrderState($command->getNewOrderStatusId()); - - if ($orderState->id !== $command->getNewOrderStatusId()) { - throw new OrderException(sprintf('Order state with ID "%s" was not found.', $command->getNewOrderStatusId())); - } - - $ordersWithFailedToUpdateStatus = []; - $ordersWithFailedToSendEmail = []; - $ordersWithAssignedStatus = []; - - foreach ($command->getOrderIds() as $orderId) { - $order = $this->getOrderObject($orderId); - $currentOrderState = $order->getCurrentOrderState(); - - if ($currentOrderState->id === $orderState->id) { - $ordersWithAssignedStatus[] = $orderId; - - continue; - } - - $history = new OrderHistory(); - $history->id_order = $order->id; - $history->id_employee = (int) Context::getContext()->employee->id; - - $useExistingPayment = !$order->hasInvoice(); - $history->changeIdOrderState((int) $orderState->id, $order, $useExistingPayment); - - $carrier = new Carrier($order->id_carrier, $order->id_lang); - $templateVars = []; - - if ($history->id_order_state == Configuration::get('PS_OS_SHIPPING') && $order->shipping_number) { - $templateVars['{followup}'] = str_replace('@', $order->shipping_number, $carrier->url); - } - - if (!$history->add()) { - $ordersWithFailedToUpdateStatus[] = $orderId; - - continue; - } - - if (!$history->sendEmail($order, $templateVars)) { - $ordersWithFailedToSendEmail[] = $orderId; - - continue; - } - - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - foreach ($order->getProducts() as $product) { - if (StockAvailable::dependsOnStock($product['product_id'])) { - StockAvailable::synchronize($product['product_id'], (int) $product['id_shop']); - } - } - } - } - - if (!empty($ordersWithFailedToUpdateStatus) - || !empty($ordersWithFailedToSendEmail) - || !empty($ordersWithAssignedStatus) - ) { - throw new ChangeOrderStatusException($ordersWithFailedToUpdateStatus, $ordersWithFailedToSendEmail, $ordersWithAssignedStatus, 'Failed to update status or sent email when changing order status.'); - } - } - - /** - * @param OrderId $orderId - * - * @return Order - */ - private function getOrderObject(OrderId $orderId) - { - $order = new Order($orderId->getValue()); - - if ($order->id !== $orderId->getValue()) { - throw new OrderNotFoundException($orderId); - } - - return $order; - } -} diff --git a/src/Adapter/Order/CommandHandler/CancelOrderProductHandler.php b/src/Adapter/Order/CommandHandler/CancelOrderProductHandler.php deleted file mode 100644 index 3d68c265..00000000 --- a/src/Adapter/Order/CommandHandler/CancelOrderProductHandler.php +++ /dev/null @@ -1,248 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use Configuration; -use Customization; -use Hook; -use Order; -use OrderDetail; -use OrderHistory; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\CancellationActionType; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\CancelOrderProductCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\CancelOrderProductHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use Psr\Log\LoggerInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * @internal - */ -final class CancelOrderProductHandler extends AbstractOrderCommandHandler implements CancelOrderProductHandlerInterface -{ - /** - * @var OrderProductQuantityUpdater - */ - private $orderProductQuantityUpdater; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * CancelOrderProductHandler constructor. - * - * @param OrderProductQuantityUpdater $orderProductQuantityUpdater - * @param LoggerInterface $logger - * @param TranslatorInterface $translator - */ - public function __construct( - OrderProductQuantityUpdater $orderProductQuantityUpdater, - LoggerInterface $logger, - TranslatorInterface $translator - ) { - $this->orderProductQuantityUpdater = $orderProductQuantityUpdater; - $this->logger = $logger; - $this->translator = $translator; - } - - /** - * Legacy code for product cancellation handling in order page - */ - public function handle(CancelOrderProductCommand $command) - { - $order = new Order($command->getOrderId()->getValue()); - $this->checkInput($command); - $this->checkOrderState($order); - - $cartId = Cart::getCartIdByOrderId($command->getOrderId()->getValue()); - $customizationQuantities = Customization::countQuantityByCart($cartId); - $orderDetails = $this->getOrderDetails($command); - - $this->assertCancelableProductQuantities($orderDetails, $customizationQuantities); - - $this->cancelProducts($order, $orderDetails); - - if (empty($order->getOrderDetailList())) { - $this->cancelOrder($order); - } - } - - private function getOrderDetails(CancelOrderProductCommand $command) - { - $productList = []; - $customizedCancelQuantity = []; - $productCancelQuantity = []; - - foreach ($command->getCancelledProducts() as $orderDetailId => $cancelQuantity) { - $orderDetail = new OrderDetail($orderDetailId); - $productList[] = $orderDetail; - if ((int) $orderDetail->id_customization > 0) { - $customizedCancelQuantity[$orderDetail->id_customization] = $cancelQuantity; - } else { - $productCancelQuantity[$orderDetail->id_order_detail] = $cancelQuantity; - } - } - - return [ - 'productsOrderDetails' => $productList, - 'productCancelQuantity' => $productCancelQuantity, - 'customizedCancelQuantity' => $customizedCancelQuantity, - ]; - } - - private function checkInput(CancelOrderProductCommand $command) - { - if (empty($command->getCancelledProducts())) { - throw new InvalidCancelProductException(InvalidCancelProductException::NO_REFUNDS); - } - - foreach ($command->getCancelledProducts() as $orderDetailId => $quantity) { - if ((int) $quantity <= 0) { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_QUANTITY); - } - } - } - - /** - * @param Order $order* - */ - private function checkOrderState(Order $order) - { - if ($order->hasBeenPaid() || $order->hasPayments()) { - throw new InvalidOrderStateException( - InvalidOrderStateException::ALREADY_PAID, - 'Can not cancel product on an order which is already paid' - ); - } - } - - /** - * @param Order $order - */ - private function cancelOrder(Order $order) - { - $history = new OrderHistory(); - $history->id_order = (int) $order->id; - $history->changeIdOrderState(Configuration::get('PS_OS_CANCELED'), $order); - if (!$history->addWithemail()) { - // email failure must not block order update process - $this->logger->warning( - $this->translator->trans( - 'Order history email could not be sent, test your email configuration in the Advanced Parameters > E-mail section of your back office.', - [], - 'Admin.Orderscustomers.Notification' - ) - ); - } - } - - /** - * @param array $orderDetails - * - * @throws InvalidCancelProductException - */ - private function assertCancelableProductQuantities(array $orderDetails, array $customizationQuantities) - { - if (empty($orderDetails['productsOrderDetails'])) { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_QUANTITY, 0); - } - $customizationList = []; - foreach ($orderDetails['productsOrderDetails'] as $orderDetail) { - // check non customized product quantities - if ((int) $orderDetail->id_customization <= 0) { - $customizationQuantity = 0; - $cancelQuantity = $orderDetails['productCancelQuantity'][$orderDetail->id_order_detail]; - if (array_key_exists($orderDetail->product_id, $customizationQuantities) && array_key_exists($orderDetail->product_attribute_id, $customizationQuantities[$orderDetail->product_id])) { - $customizationQuantity = (int) $customizationQuantities[$orderDetail->product_id][$orderDetail->product_attribute_id]; - } - $cancellableQuantity = $orderDetail->product_quantity - $customizationQuantity - $orderDetail->product_quantity_refunded - $orderDetail->product_quantity_return; - if ($cancellableQuantity < $cancelQuantity) { - throw new InvalidCancelProductException(InvalidCancelProductException::QUANTITY_TOO_HIGH, $cancellableQuantity); - } - continue; - } - // get list of customizations - $customizationList[$orderDetail->id_customization] = $orderDetail->id_order_detail; - } - - if (empty($customizationList)) { - return; - } - - $customization_quantities = Customization::retrieveQuantitiesFromIds(array_keys($customizationList)); - - // check customized products quantities - foreach ($customizationList as $id_customization => $id_order_detail) { - $qtyCancelProduct = abs($orderDetails['customizedCancelQuantity'][$id_customization]); - $customization_quantity = $customization_quantities[$id_customization]; - if (!$qtyCancelProduct) { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_QUANTITY); - } - $cancellableQuantity = $customization_quantity['quantity'] - ($customization_quantity['quantity_refunded'] + $customization_quantity['quantity_returned']); - - if ($qtyCancelProduct > $cancellableQuantity) { - throw new InvalidCancelProductException(InvalidCancelProductException::QUANTITY_TOO_HIGH, $cancellableQuantity); - } - } - } - - /** - * @param Order $order - * @param array $orderDetails - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - * @throws \PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException - */ - private function cancelProducts(Order $order, array $orderDetails) - { - if (!empty($orderDetails['productsOrderDetails'])) { - foreach ($orderDetails['productsOrderDetails'] as $orderDetail) { - if ((int) $orderDetail->id_customization > 0) { - $qty_cancel_product = abs($orderDetails['customizedCancelQuantity'][$orderDetail->id_customization]); - } else { - $qty_cancel_product = $orderDetails['productCancelQuantity'][$orderDetail->id_order_detail]; - } - $newQuantity = max((int) $orderDetail->product_quantity - (int) $qty_cancel_product, 0); - $orderInvoice = $orderDetail->id_order_invoice != 0 ? new OrderInvoice($orderDetail->id_order_invoice) : null; - $this->orderProductQuantityUpdater->update($order, $orderDetail, $newQuantity, $orderInvoice); - Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetail->id_order_detail, 'action' => CancellationActionType::CANCEL_PRODUCT], null, false, true, false, $order->id_shop); - } - } - } -} diff --git a/src/Adapter/Order/CommandHandler/ChangeOrderCurrencyHandler.php b/src/Adapter/Order/CommandHandler/ChangeOrderCurrencyHandler.php deleted file mode 100644 index d3caae4c..00000000 --- a/src/Adapter/Order/CommandHandler/ChangeOrderCurrencyHandler.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use Currency; -use ObjectModel; -use Order; -use OrderCarrier; -use OrderDetail; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ChangeOrderCurrencyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShopCollection; -use PrestaShopException; -use Tools; -use Validate; - -/** - * @internal - */ -final class ChangeOrderCurrencyHandler extends AbstractOrderHandler implements ChangeOrderCurrencyHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(ChangeOrderCurrencyCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - - if ($command->getNewCurrencyId()->getValue() === (int) $order->id_currency || $order->valid) { - throw new OrderException('You cannot change the currency.'); - } - - try { - $oldCurrency = new Currency($order->id_currency); - $newCurrency = new Currency($command->getNewCurrencyId()->getValue()); - - if (!Validate::isLoadedObject($oldCurrency) || !Validate::isLoadedObject($newCurrency)) { - throw new OrderException('Can\'t load Currency object'); - } - - $this->updateOrderDetail($order, $oldCurrency, $newCurrency); - $this->updateOrderCarrier((int) $order->getIdOrderCarrier(), $oldCurrency, $newCurrency); - $this->updateInvoices($order->getInvoicesCollection(), $oldCurrency, $newCurrency); - $this->updateCart($order->id_cart, $newCurrency); - $this->updateOrder($order, $oldCurrency, $newCurrency); - } catch (PrestaShopException $e) { - throw new OrderException( - sprintf( - 'Error occurred when trying to change currency for order #%s', - $order->id - ), - 0, - $e - ); - } - } - - /** - * @param int $orderCarrierId - * @param Currency $oldCurrency - * @param Currency $newCurrency - */ - private function updateOrderCarrier(int $orderCarrierId, Currency $oldCurrency, Currency $newCurrency): void - { - if (!$orderCarrierId) { - return; - } - - $order_carrier = new OrderCarrier($orderCarrierId); - $order_carrier->shipping_cost_tax_excl = (float) Tools::convertPriceFull( - $order_carrier->shipping_cost_tax_excl, - $oldCurrency, - $newCurrency - ); - $order_carrier->shipping_cost_tax_incl = (float) Tools::convertPriceFull( - $order_carrier->shipping_cost_tax_incl, - $oldCurrency, - $newCurrency - ); - $order_carrier->update(); - } - - /** - * @param Order $order - * @param Currency $oldCurrency - * @param Currency $newCurrency - */ - private function updateOrderDetail(Order $order, Currency $oldCurrency, Currency $newCurrency): void - { - foreach ($order->getOrderDetailList() as $orderDetailItem) { - $orderDetail = new OrderDetail($orderDetailItem['id_order_detail']); - $fields = [ - 'ecotax', - 'product_price', - 'reduction_amount', - 'total_shipping_price_tax_excl', - 'total_shipping_price_tax_incl', - 'total_price_tax_incl', - 'total_price_tax_excl', - 'product_quantity_discount', - 'purchase_supplier_price', - 'reduction_amount', - 'reduction_amount_tax_incl', - 'reduction_amount_tax_excl', - 'unit_price_tax_incl', - 'unit_price_tax_excl', - 'original_product_price', - ]; - - $this->convertPriceFields($orderDetail, $fields, $oldCurrency, $newCurrency); - - $orderDetail->update(); - $orderDetail->updateTaxAmount($order); - } - } - - /** - * @param PrestaShopCollection $invoices - * @param Currency $oldCurrency - * @param Currency $newCurrency - */ - private function updateInvoices(PrestaShopCollection $invoices, Currency $oldCurrency, Currency $newCurrency): void - { - if (!$invoices->count()) { - return; - } - - foreach ($invoices as $invoice) { - $this->convertPriceFields($invoice, $this->getSharedAmountFields(), $oldCurrency, $newCurrency); - $invoice->save(); - } - } - - /** - * @param Order $order - * @param Currency $oldCurrency - * @param Currency $newCurrency - */ - private function updateOrder(Order $order, Currency $oldCurrency, Currency $newCurrency): void - { - $this->convertPriceFields($order, $this->getSharedAmountFields(), $oldCurrency, $newCurrency); - - $order->id_currency = $newCurrency->id; - $order->conversion_rate = (float) $newCurrency->conversion_rate; - $order->update(); - } - - /** - * @param int $cartId - * @param Currency $newCurrency - */ - private function updateCart(int $cartId, Currency $newCurrency): void - { - $cart = new Cart($cartId); - - $cart->id_currency = $newCurrency->id; - $cart->update(); - } - - /** - * Provides fields for Order and OrderInvoice amounts update - * - * @return array - */ - private function getSharedAmountFields(): array - { - return [ - 'total_discounts', - 'total_discounts_tax_incl', - 'total_discounts_tax_excl', - 'total_discount_tax_excl', - 'total_discount_tax_incl', - 'total_paid', - 'total_paid_tax_incl', - 'total_paid_tax_excl', - 'total_paid_real', - 'total_products', - 'total_products_wt', - 'total_shipping', - 'total_shipping_tax_incl', - 'total_shipping_tax_excl', - 'total_wrapping', - 'total_wrapping_tax_incl', - 'total_wrapping_tax_excl', - ]; - } - - /** - * @param Order|OrderDetail|OrderInvoice $object - * @param array $fields - * @param Currency $oldCurrency - * @param Currency $newCurrency - */ - private function convertPriceFields( - ObjectModel $object, - array $fields, - Currency $oldCurrency, - Currency $newCurrency - ) { - foreach ($fields as $field) { - if (isset($object->$field)) { - $object->{$field} = Tools::convertPriceFull($object->{$field}, $oldCurrency, $newCurrency); - } - } - } -} diff --git a/src/Adapter/Order/CommandHandler/ChangeOrderDeliveryAddressHandler.php b/src/Adapter/Order/CommandHandler/ChangeOrderDeliveryAddressHandler.php deleted file mode 100644 index e0e55549..00000000 --- a/src/Adapter/Order/CommandHandler/ChangeOrderDeliveryAddressHandler.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Address; -use Cart; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderDetailUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderDeliveryAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ChangeOrderDeliveryAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use Validate; - -/** - * @internal - */ -final class ChangeOrderDeliveryAddressHandler extends AbstractOrderHandler implements ChangeOrderDeliveryAddressHandlerInterface -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @var OrderDetailUpdater - */ - private $orderDetailTaxUpdater; - - /** - * @param OrderAmountUpdater $orderAmountUpdater - * @param OrderDetailUpdater $orderDetailTaxUpdater - */ - public function __construct( - OrderAmountUpdater $orderAmountUpdater, - OrderDetailUpdater $orderDetailTaxUpdater - ) { - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderDetailTaxUpdater = $orderDetailTaxUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(ChangeOrderDeliveryAddressCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - $address = new Address($command->getNewDeliveryAddressId()->getValue()); - - $cart = Cart::getCartByOrderId($order->id); - - if (!Validate::isLoadedObject($address)) { - throw new OrderException('New delivery address is not valid'); - } - - $cart->updateDeliveryAddressId((int) $cart->id_address_delivery, (int) $address->id); - $cart->setDeliveryOption([ - (int) $cart->id_address_delivery => $this->formatLegacyDeliveryOptionFromCarrierId($order->id_carrier), - ]); - $cart->update(); - - $order->id_address_delivery = $address->id; - $this->orderDetailTaxUpdater->updateOrderDetailsTaxes($order); - $this->orderAmountUpdater->update($order, $cart); - } -} diff --git a/src/Adapter/Order/CommandHandler/ChangeOrderInvoiceAddressHandler.php b/src/Adapter/Order/CommandHandler/ChangeOrderInvoiceAddressHandler.php deleted file mode 100644 index f916fdb4..00000000 --- a/src/Adapter/Order/CommandHandler/ChangeOrderInvoiceAddressHandler.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Address; -use Cart; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderDetailUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderInvoiceAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ChangeOrderInvoiceAddressHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use Validate; - -/** - * @internal - */ -final class ChangeOrderInvoiceAddressHandler extends AbstractOrderHandler implements ChangeOrderInvoiceAddressHandlerInterface -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @var OrderDetailUpdater - */ - private $orderDetailTaxUpdater; - - /** - * @param OrderAmountUpdater $orderAmountUpdater - * @param OrderDetailUpdater $orderDetailTaxUpdater - */ - public function __construct( - OrderAmountUpdater $orderAmountUpdater, - OrderDetailUpdater $orderDetailTaxUpdater - ) { - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderDetailTaxUpdater = $orderDetailTaxUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(ChangeOrderInvoiceAddressCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - $address = new Address($command->getNewInvoiceAddressId()->getValue()); - - $cart = Cart::getCartByOrderId($order->id); - - if (!Validate::isLoadedObject($address)) { - throw new OrderException('New invoice address is not valid'); - } - - $cart->id_address_invoice = $address->id; - $cart->update(); - - $order->id_address_invoice = $address->id; - $this->orderDetailTaxUpdater->updateOrderDetailsTaxes($order); - $this->orderAmountUpdater->update($order, $cart); - } -} diff --git a/src/Adapter/Order/CommandHandler/DeleteCartRuleFromOrderHandler.php b/src/Adapter/Order/CommandHandler/DeleteCartRuleFromOrderHandler.php deleted file mode 100644 index 6174bed8..00000000 --- a/src/Adapter/Order/CommandHandler/DeleteCartRuleFromOrderHandler.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use CartRule; -use Currency; -use Customer; -use Order; -use OrderCartRule; -use OrderDetail; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\DeleteCartRuleFromOrderCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\DeleteCartRuleFromOrderHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use Shop; -use Validate; - -/** - * @internal - */ -final class DeleteCartRuleFromOrderHandler extends AbstractOrderHandler implements DeleteCartRuleFromOrderHandlerInterface -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var OrderProductQuantityUpdater - */ - private $orderProductQuantityUpdater; - - /** - * @param OrderAmountUpdater $orderAmountUpdater - * @param ContextStateManager $contextStateManager - * @param OrderProductQuantityUpdater $orderProductQuantityUpdater - */ - public function __construct( - OrderAmountUpdater $orderAmountUpdater, - OrderProductQuantityUpdater $orderProductQuantityUpdater, - ContextStateManager $contextStateManager - ) { - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderProductQuantityUpdater = $orderProductQuantityUpdater; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(DeleteCartRuleFromOrderCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - $orderCartRule = new OrderCartRule($command->getOrderCartRuleId()); - if (!Validate::isLoadedObject($orderCartRule) || $orderCartRule->id_order != $order->id) { - throw new OrderException('Invalid order cart rule provided.'); - } - - $cart = Cart::getCartByOrderId($order->id); - if (!Validate::isLoadedObject($cart) || $order->id_cart != $cart->id) { - throw new OrderException('Invalid cart provided.'); - } - - $this->contextStateManager - ->setCurrency(new Currency($order->id_currency)) - ->setCustomer(new Customer($order->id_customer)) - ->setShop(new Shop($order->id_shop)) - ; - - try { - // Delete Order Cart Rule and update Order - $cartRule = new CartRule($orderCartRule->id_cart_rule); - $orderCartRule->softDelete(); - $cart->removeCartRule($orderCartRule->id_cart_rule); - - // If cart rule was a gift product we must update an OrderDetail manually - $giftOrderDetail = $this->getGiftOrderDetail($order, $cartRule); - if ($giftOrderDetail instanceof OrderDetail) { - $newQuantity = ((int) $giftOrderDetail->product_quantity) - 1; - - /* - * Note: we are lucky the stock updates happens smoothly, it was not re-injected by removing the CartRule - * because Cart doesn't update the stock but it will while we update the OrderDetail Lucky - * for us it's the same difference of 1 so it's all accurate in the end - */ - // This calls the OrderAmountUpdater internally so no need to perform both calls - $this->orderProductQuantityUpdater->update( - $order, - $giftOrderDetail, - $newQuantity, - (int) $giftOrderDetail->id_order_invoice !== 0 ? new OrderInvoice((int) $giftOrderDetail->id_order_invoice) : null, - false - ); - } else { - $this->orderAmountUpdater->update($order, $cart, $orderCartRule->id_order_invoice); - } - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - * @param CartRule $cartRule - * - * @return OrderDetail|null - */ - private function getGiftOrderDetail(Order $order, CartRule $cartRule): ?OrderDetail - { - $productId = (int) $cartRule->gift_product; - $productAttributeId = (int) $cartRule->gift_product_attribute; - - $fallbackOrderDetailId = null; - $giftOrderDetailId = null; - foreach ($order->getOrderDetailList() as $orderDetail) { - if ((int) $orderDetail['product_id'] !== $productId || (int) $orderDetail['product_attribute_id'] !== $productAttributeId) { - continue; - } - - // We try to find a row with at least 2 items - if ($orderDetail['product_quantity'] > 1) { - $giftOrderDetailId = $orderDetail['id_order_detail']; - - return new OrderDetail($giftOrderDetailId); - } - // keep the first one for fallback - $fallbackOrderDetailId = $fallbackOrderDetailId ?? $orderDetail['id_order_detail']; - } - - return (null === $fallbackOrderDetailId) ? null : new OrderDetail($fallbackOrderDetailId); - } -} diff --git a/src/Adapter/Order/CommandHandler/DeleteProductFromOrderHandler.php b/src/Adapter/Order/CommandHandler/DeleteProductFromOrderHandler.php deleted file mode 100644 index 665e061a..00000000 --- a/src/Adapter/Order/CommandHandler/DeleteProductFromOrderHandler.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use Currency; -use Customer; -use Hook; -use Order; -use OrderDetail; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\DeleteProductFromOrderCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler\DeleteProductFromOrderHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use Shop; -use Validate; - -/** - * @internal - */ -final class DeleteProductFromOrderHandler extends AbstractOrderCommandHandler implements DeleteProductFromOrderHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - /** - * @var OrderProductQuantityUpdater - */ - private $orderProductQuantityUpdater; - - /** - * @param ContextStateManager $contextStateManager - * @param OrderAmountUpdater $orderAmountUpdater - * @param OrderProductQuantityUpdater $orderProductQuantityUpdater - */ - public function __construct( - ContextStateManager $contextStateManager, - OrderAmountUpdater $orderAmountUpdater, - OrderProductQuantityUpdater $orderProductQuantityUpdater - ) { - $this->contextStateManager = $contextStateManager; - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderProductQuantityUpdater = $orderProductQuantityUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(DeleteProductFromOrderCommand $command) - { - $orderDetail = new OrderDetail($command->getOrderDetailId()); - $order = new Order($command->getOrderId()->getValue()); - - $this->assertProductCanBeDeleted($order, $orderDetail); - - $cart = new Cart($order->id_cart); - - $this->contextStateManager - ->setCart($cart) - ->setCurrency(new Currency($order->id_currency)) - ->setCustomer(new Customer($order->id_customer)) - ->setShop(new Shop($order->id_shop)) - ; - - try { - $order = $this->orderProductQuantityUpdater->update( - $order, - $orderDetail, - 0, - $orderDetail->id_order_invoice != 0 ? new OrderInvoice($orderDetail->id_order_invoice) : null - ); - - Hook::exec('actionOrderEdited', ['order' => $order]); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - */ - private function assertProductCanBeDeleted(Order $order, OrderDetail $orderDetail) - { - if (!Validate::isLoadedObject($orderDetail)) { - throw new OrderException('Order detail could not be found.'); - } - - if (!Validate::isLoadedObject($order)) { - throw new OrderNotFoundException(new OrderId((int) $order->id), 'Order could not be found.'); - } - - if ($orderDetail->id_order != $order->id) { - throw new OrderException('Order detail does not belong to order.'); - } - - // We can't edit a delivered order - if ($order->hasBeenDelivered()) { - throw new OrderException('Delivered order cannot be modified.'); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/DuplicateOrderCartHandler.php b/src/Adapter/Order/CommandHandler/DuplicateOrderCartHandler.php deleted file mode 100644 index ac48f996..00000000 --- a/src/Adapter/Order/CommandHandler/DuplicateOrderCartHandler.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use Currency; -use Customer; -use Language; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\DuplicateOrderCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\DuplicateOrderCartHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateOrderCartException; -use Shop; - -/** - * @internal - */ -final class DuplicateOrderCartHandler implements DuplicateOrderCartHandlerInterface -{ - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ContextStateManager $contextStateManager - */ - public function __construct(ContextStateManager $contextStateManager) - { - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(DuplicateOrderCartCommand $command) - { - // IMPORTANT: context customer must be set in order to correctly fill the address - $cart = Cart::getCartByOrderId($command->getOrderId()->getValue()); - $this->contextStateManager - ->setCart($cart) - ->setCustomer(new Customer($cart->id_customer)) - ->setCurrency(new Currency($cart->id_currency)) - ->setLanguage(new Language($cart->id_lang)) - ->setShop(new Shop($cart->id_shop)) - ; - $result = $cart->duplicate(); - - if (false === $result || !isset($result['cart'])) { - $this->contextStateManager->restorePreviousContext(); - throw new DuplicateOrderCartException(sprintf('Cannot duplicate cart from order "%s"', $command->getOrderId()->getValue())); - } - - $this->contextStateManager->restorePreviousContext(); - - return new CartId((int) $result['cart']->id); - } -} diff --git a/src/Adapter/Order/CommandHandler/GenerateInvoiceHandler.php b/src/Adapter/Order/CommandHandler/GenerateInvoiceHandler.php deleted file mode 100644 index b230a051..00000000 --- a/src/Adapter/Order/CommandHandler/GenerateInvoiceHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Configuration; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\GenerateInvoiceCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\CommandHandler\GenerateOrderInvoiceHandlerInterface; - -/** - * @internal - */ -final class GenerateInvoiceHandler extends AbstractOrderHandler implements GenerateOrderInvoiceHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GenerateInvoiceCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - - if (!Configuration::get('PS_INVOICE', null, null, $order->id_shop)) { - throw new OrderException('Invoice management has been disabled.'); - } - - if ($order->hasInvoice()) { - throw new OrderException('This order already has an invoice.'); - } - - $order->setInvoice(true); - } -} diff --git a/src/Adapter/Order/CommandHandler/IssuePartialRefundHandler.php b/src/Adapter/Order/CommandHandler/IssuePartialRefundHandler.php deleted file mode 100644 index 2f0a2a3f..00000000 --- a/src/Adapter/Order/CommandHandler/IssuePartialRefundHandler.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Context; -use Hook; -use Order; -use OrderCarrier; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundCalculator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundUpdater; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderSlipCreator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\VoucherGenerator; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\CancellationActionType; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssuePartialRefundCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\IssuePartialRefundHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use Validate; - -/** - * @internal - */ -final class IssuePartialRefundHandler extends AbstractOrderCommandHandler implements IssuePartialRefundHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var OrderRefundCalculator - */ - private $orderRefundCalculator; - - /** - * @var OrderSlipCreator - */ - private $orderSlipCreator; - - /** - * @var VoucherGenerator - */ - private $voucherGenerator; - - /** - * @var OrderRefundUpdater - */ - private $refundUpdater; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ConfigurationInterface $configuration - * @param OrderRefundCalculator $orderRefundCalculator - * @param OrderSlipCreator $orderSlipCreator - * @param VoucherGenerator $voucherGenerator - * @param OrderRefundUpdater $refundUpdater - * @param ContextStateManager $contextStateManager - */ - public function __construct( - ConfigurationInterface $configuration, - OrderRefundCalculator $orderRefundCalculator, - OrderSlipCreator $orderSlipCreator, - VoucherGenerator $voucherGenerator, - OrderRefundUpdater $refundUpdater, - ContextStateManager $contextStateManager - ) { - $this->configuration = $configuration; - $this->orderRefundCalculator = $orderRefundCalculator; - $this->orderSlipCreator = $orderSlipCreator; - $this->voucherGenerator = $voucherGenerator; - $this->refundUpdater = $refundUpdater; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(IssuePartialRefundCommand $command): void - { - /** @var Order $order */ - $order = $this->getOrder($command->getOrderId()); - if (!$order->hasBeenPaid() && !$order->hasPayments()) { - throw new InvalidOrderStateException( - InvalidOrderStateException::NOT_PAID, - 'Can not perform partial refund on an order which is not paid' - ); - } - - $this->setOrderContext($this->contextStateManager, $order); - - try { - $this->issuePartialRefund($command, $order); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param IssuePartialRefundCommand $command - * @param Order $order - */ - private function issuePartialRefund(IssuePartialRefundCommand $command, Order $order): void - { - $orderRefundSummary = $this->orderRefundCalculator->computeOrderRefund( - $order, - $command->getOrderDetailRefunds(), - $command->getShippingCostRefundAmount(), - $command->getVoucherRefundType(), - $command->getVoucherRefundAmount() - ); - - // @todo This part should probably be in a share abstract class as it will probably be common with other handlers - // Update order details and reinject quantities - $shouldReinjectProducts = !$order->hasBeenDelivered() || $command->restockRefundedProducts(); - foreach ($orderRefundSummary->getProductRefunds() as $orderDetailId => $productRefund) { - $orderDetail = $orderRefundSummary->getOrderDetailById($orderDetailId); - if ($shouldReinjectProducts) { - $this->reinjectQuantity($orderDetail, $productRefund['quantity']); - } - Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'action' => CancellationActionType::PARTIAL_REFUND], null, false, true, false, $order->id_shop); - } - - // Update order carrier weight - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - if (Validate::isLoadedObject($orderCarrier)) { - $orderCarrier->weight = (float) $order->getTotalWeight(); - if ($orderCarrier->update()) { - $order->weight = sprintf('%.3f %s', $orderCarrier->weight, $this->configuration->get('PS_WEIGHT_UNIT')); - } - } - - // Create order slip - if ($command->generateCreditSlip()) { - $this->orderSlipCreator->create($order, $orderRefundSummary); - } - - // Update refund details - $productsReturned = (int) $this->configuration->get('PS_ORDER_RETURN') === 1 && $order->hasBeenDelivered(); - $this->refundUpdater->updateRefundData( - $orderRefundSummary, - $productsReturned, - $shouldReinjectProducts - ); - - // Generate voucher if needed - if ($command->generateVoucher() && $orderRefundSummary->getRefundedAmount() > 0) { - $this->voucherGenerator->generateVoucher( - $order, - $orderRefundSummary->getRefundedAmount(), - Context::getContext()->currency->iso_code, - $orderRefundSummary->isTaxIncluded() - ); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/IssueReturnProductHandler.php b/src/Adapter/Order/CommandHandler/IssueReturnProductHandler.php deleted file mode 100644 index b4ee9845..00000000 --- a/src/Adapter/Order/CommandHandler/IssueReturnProductHandler.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Context; -use Hook; -use Order; -use OrderCarrier; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundCalculator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundSummary; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundUpdater; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderSlipCreator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\VoucherGenerator; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\CancellationActionType; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueReturnProductCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\IssueReturnProductHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\ReturnProductDisabledException; -use Validate; - -/** - * @internal - */ -class IssueReturnProductHandler extends AbstractOrderCommandHandler implements IssueReturnProductHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var OrderRefundCalculator - */ - private $orderRefundCalculator; - - /** - * @var OrderSlipCreator - */ - private $orderSlipCreator; - - /** - * @var VoucherGenerator - */ - private $voucherGenerator; - - /** - * @var OrderRefundUpdater - */ - private $refundUpdater; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ConfigurationInterface $configuration - * @param OrderRefundCalculator $orderRefundCalculator - * @param OrderSlipCreator $orderSlipCreator - * @param VoucherGenerator $voucherGenerator - * @param OrderRefundUpdater $refundUpdater - * @param ContextStateManager $contextStateManager - */ - public function __construct( - ConfigurationInterface $configuration, - OrderRefundCalculator $orderRefundCalculator, - OrderSlipCreator $orderSlipCreator, - VoucherGenerator $voucherGenerator, - OrderRefundUpdater $refundUpdater, - ContextStateManager $contextStateManager - ) { - $this->configuration = $configuration; - $this->orderRefundCalculator = $orderRefundCalculator; - $this->orderSlipCreator = $orderSlipCreator; - $this->voucherGenerator = $voucherGenerator; - $this->refundUpdater = $refundUpdater; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(IssueReturnProductCommand $command): void - { - if ((int) $this->configuration->get('PS_ORDER_RETURN') <= 0) { - throw new ReturnProductDisabledException(); - } - - $order = $this->getOrder($command->getOrderId()); - if (!$order->hasBeenDelivered()) { - throw new InvalidOrderStateException( - InvalidOrderStateException::DELIVERY_NOT_FOUND, - 'Can not perform return product on order with not delivered yet' - ); - } - $this->setOrderContext($this->contextStateManager, $order); - - try { - $this->issueReturn($command, $order); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - private function issueReturn(IssueReturnProductCommand $command, Order $order): void - { - $shippingRefundAmount = new Number((string) ($command->refundShippingCost() ? $order->total_shipping_tax_incl : 0)); - /** @var OrderRefundSummary $orderRefundSummary */ - $orderRefundSummary = $this->orderRefundCalculator->computeOrderRefund( - $order, - $command->getOrderDetailRefunds(), - $shippingRefundAmount, - $command->getVoucherRefundType(), - $command->getVoucherRefundAmount() - ); - - // Update order details and reinject quantities - foreach ($orderRefundSummary->getProductRefunds() as $orderDetailId => $productRefund) { - $orderDetail = $orderRefundSummary->getOrderDetailById($orderDetailId); - if ($command->restockRefundedProducts()) { - $this->reinjectQuantity($orderDetail, $productRefund['quantity']); - } - Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'action' => CancellationActionType::RETURN_PRODUCT], null, false, true, false, $order->id_shop); - } - - // Update order carrier weight - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - if (Validate::isLoadedObject($orderCarrier)) { - $orderCarrier->weight = (float) $order->getTotalWeight(); - if ($orderCarrier->update()) { - $order->weight = sprintf('%.3f %s', $orderCarrier->weight, $this->configuration->get('PS_WEIGHT_UNIT')); - } - } - - // Create order slip - if ($command->generateCreditSlip()) { - $this->orderSlipCreator->create($order, $orderRefundSummary); - } - - // Update refund details (by definition it returns products) - $this->refundUpdater->updateRefundData( - $orderRefundSummary, - true, - $command->restockRefundedProducts() - ); - - // Generate voucher if needed - if ($command->generateVoucher() && $orderRefundSummary->getRefundedAmount() > 0) { - $this->voucherGenerator->generateVoucher( - $order, - $orderRefundSummary->getRefundedAmount(), - Context::getContext()->currency->iso_code, - $orderRefundSummary->isTaxIncluded() - ); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php b/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php deleted file mode 100644 index 703d5e91..00000000 --- a/src/Adapter/Order/CommandHandler/IssueStandardRefundHandler.php +++ /dev/null @@ -1,193 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Context; -use Hook; -use Order; -use OrderCarrier; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundCalculator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundUpdater; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderSlipCreator; -use PrestaShop\PrestaShop\Adapter\Order\Refund\VoucherGenerator; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\CancellationActionType; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueStandardRefundCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\IssueStandardRefundHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\ReturnProductDisabledException; -use Validate; - -/** - * @internal - */ -class IssueStandardRefundHandler extends AbstractOrderCommandHandler implements IssueStandardRefundHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var OrderRefundCalculator - */ - private $orderRefundCalculator; - - /** - * @var OrderSlipCreator - */ - private $orderSlipCreator; - - /** - * @var VoucherGenerator - */ - private $voucherGenerator; - - /** - * @var OrderRefundUpdater - */ - private $refundUpdater; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @param ConfigurationInterface $configuration - * @param OrderRefundCalculator $orderRefundCalculator - * @param OrderSlipCreator $orderSlipCreator - * @param VoucherGenerator $voucherGenerator - * @param OrderRefundUpdater $refundUpdater - * @param ContextStateManager $contextStateManager - */ - public function __construct( - ConfigurationInterface $configuration, - OrderRefundCalculator $orderRefundCalculator, - OrderSlipCreator $orderSlipCreator, - VoucherGenerator $voucherGenerator, - OrderRefundUpdater $refundUpdater, - ContextStateManager $contextStateManager - ) { - $this->configuration = $configuration; - $this->orderRefundCalculator = $orderRefundCalculator; - $this->orderSlipCreator = $orderSlipCreator; - $this->voucherGenerator = $voucherGenerator; - $this->refundUpdater = $refundUpdater; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - */ - public function handle(IssueStandardRefundCommand $command): void - { - if ((int) $this->configuration->get('PS_ORDER_RETURN') <= 0) { - throw new ReturnProductDisabledException(); - } - - /** @var Order $order */ - $order = $this->getOrder($command->getOrderId()); - if (!$order->hasBeenPaid() && !$order->hasPayments()) { - throw new InvalidOrderStateException( - InvalidOrderStateException::NOT_PAID, - 'Can not perform standard refund on an order which is not paid' - ); - } - if ($order->hasBeenDelivered()) { - throw new InvalidOrderStateException( - InvalidOrderStateException::UNEXPECTED_DELIVERY, - 'Can not perform standard refund on order already delivered' - ); - } - - $this->setOrderContext($this->contextStateManager, $order); - - try { - $this->issueStandardRefund($command, $order); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param IssueStandardRefundCommand $command - * @param Order $order - */ - private function issueStandardRefund(IssueStandardRefundCommand $command, Order $order): void - { - $shippingRefundAmount = new Number((string) ($command->refundShippingCost() ? $order->total_shipping_tax_incl : 0)); - $orderRefundSummary = $this->orderRefundCalculator->computeOrderRefund( - $order, - $command->getOrderDetailRefunds(), - $shippingRefundAmount, - $command->getVoucherRefundType(), - $command->getVoucherRefundAmount() - ); - - // Update order details and reinject quantities - foreach ($orderRefundSummary->getProductRefunds() as $orderDetailId => $productRefund) { - $orderDetail = $orderRefundSummary->getOrderDetailById($orderDetailId); - // For standard refund the order is necessarily NOT delivered yet, so reinjection is automatic - $this->reinjectQuantity($orderDetail, $productRefund['quantity']); - Hook::exec('actionProductCancel', ['order' => $order, 'id_order_detail' => (int) $orderDetailId, 'action' => CancellationActionType::STANDARD_REFUND], null, false, true, false, $order->id_shop); - } - - // Update order carrier weight - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - if (Validate::isLoadedObject($orderCarrier)) { - $orderCarrier->weight = (float) $order->getTotalWeight(); - if ($orderCarrier->update()) { - $order->weight = sprintf('%.3f %s', $orderCarrier->weight, $this->configuration->get('PS_WEIGHT_UNIT')); - } - } - - // Create order slip - if ($command->generateCreditSlip()) { - $this->orderSlipCreator->create($order, $orderRefundSummary); - } - - // Update refund details (standard refund only happen for an order not delivered, so it can't return products) - $this->refundUpdater->updateRefundData( - $orderRefundSummary, - false, - true - ); - - // Generate voucher if needed - if ($command->generateVoucher() && $orderRefundSummary->getRefundedAmount() > 0) { - $this->voucherGenerator->generateVoucher( - $order, - $orderRefundSummary->getRefundedAmount(), - Context::getContext()->currency->iso_code, - $orderRefundSummary->isTaxIncluded() - ); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/ResendOrderEmailHandler.php b/src/Adapter/Order/CommandHandler/ResendOrderEmailHandler.php deleted file mode 100644 index 675684db..00000000 --- a/src/Adapter/Order/CommandHandler/ResendOrderEmailHandler.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Carrier; -use Configuration; -use OrderHistory; -use OrderState; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ResendOrderEmailCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\ResendOrderEmailHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderEmailSendException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use Validate; - -/** - * @internal - */ -final class ResendOrderEmailHandler extends AbstractOrderCommandHandler implements ResendOrderEmailHandlerInterface -{ - /** - * @param ResendOrderEmailCommand $command - */ - public function handle(ResendOrderEmailCommand $command): void - { - $order = $this->getOrder($command->getOrderId()); - $orderState = new OrderState($command->getOrderStatusId()); - - if (!Validate::isLoadedObject($orderState)) { - throw new OrderException(sprintf('An error occurred while loading order status. Order status with "%s" was not found.', $command->getOrderId()->getValue())); - } - - $history = new OrderHistory($command->getOrderHistoryId()); - - $carrier = new Carrier($order->id_carrier, $order->id_lang); - $templateVars = []; - - if ($orderState->id == Configuration::get('PS_OS_SHIPPING') && $order->shipping_number) { - $templateVars = ['{followup}' => str_replace('@', $order->shipping_number, $carrier->url)]; - } - - if (!$history->sendEmail($order, $templateVars)) { - throw new OrderEmailSendException('Failed to resend order email.', OrderEmailSendException::FAILED_RESEND); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/SendProcessOrderEmailHandler.php b/src/Adapter/Order/CommandHandler/SendProcessOrderEmailHandler.php deleted file mode 100644 index 74721f56..00000000 --- a/src/Adapter/Order/CommandHandler/SendProcessOrderEmailHandler.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Cart; -use Customer; -use Language; -use Link; -use Mail; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\SendProcessOrderEmailCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\SendProcessOrderEmailHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderEmailSendException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShopException; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Handles SendProcessOrderEmail command using legacy object model - */ -class SendProcessOrderEmailHandler implements SendProcessOrderEmailHandlerInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var Link - */ - private $contextLink; - - public function __construct( - TranslatorInterface $translator, - Link $contextLink - ) { - $this->translator = $translator; - $this->contextLink = $contextLink; - } - - /** - * {@inheritdoc} - */ - public function handle(SendProcessOrderEmailCommand $command): void - { - $cartId = $command->getCartId(); - - try { - $cart = $this->getCart($cartId); - $customer = $this->getCustomer(new CustomerId((int) $cart->id_customer)); - $langId = (int) $cart->id_lang; - $cartLanguage = new Language($langId); - - if (!Mail::send( - $langId, - 'backoffice_order', - $this->getSubject($cartLanguage), - $this->getEmailTemplateVars($cartId->getValue(), $cartLanguage, $customer), - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - $cart->id_shop - )) { - throw new OrderEmailSendException('Failed to send order process email to customer', OrderEmailSendException::FAILED_SEND_PROCESS_ORDER); - } - } catch (PrestaShopException $e) { - throw new OrderException('An error occurred when trying to get info for order processing'); - } - } - - /** - * Provides legacy cart object - * - * @param CartId $cartId - * - * @return Cart - * - * @throws CartNotFoundException - */ - private function getCart(CartId $cartId) - { - $cartIdValue = $cartId->getValue(); - $cart = new Cart($cartIdValue); - - if ($cart->id !== $cartIdValue) { - throw new CartNotFoundException(sprintf('Cart #%s not found', $cartIdValue)); - } - - return $cart; - } - - /** - * Provides legacy customer object - * - * @param CustomerId $customerId - * - * @return Customer - * - * @throws CustomerNotFoundException - */ - private function getCustomer(CustomerId $customerId) - { - $customerIdValue = $customerId->getValue(); - $customer = new Customer($customerIdValue); - - if ($customer->id !== $customerIdValue) { - throw new CustomerNotFoundException(new CustomerId($customerIdValue), sprintf('Customer #%s not found', $customerIdValue)); - } - - return $customer; - } - - /** - * Provides translated subject for email - * - * @param Language $cartLanguage - * - * @return string - */ - private function getSubject(Language $cartLanguage): string - { - return $this->translator->trans( - 'Process the payment of your order', - [], - 'Emails.Subject', - $cartLanguage->locale - ); - } - - /** - * Provides email template variables - * - * @param int $cartId - * @param Language $cartLanguage - * @param Customer $customer - * - * @return array - */ - private function getEmailTemplateVars(int $cartId, Language $cartLanguage, Customer $customer): array - { - $orderLink = $this->contextLink->getPageLink( - 'order', - false, - $cartLanguage->id, - http_build_query([ - 'step' => 3, - 'recover_cart' => $cartId, - 'token_cart' => md5(_COOKIE_KEY_ . 'recover_cart_' . $cartId), - ]) - ); - - return [ - '{order_link}' => $orderLink, - '{firstname}' => $customer->firstname, - '{lastname}' => $customer->lastname, - ]; - } -} diff --git a/src/Adapter/Order/CommandHandler/UpdateInvoiceNoteHandler.php b/src/Adapter/Order/CommandHandler/UpdateInvoiceNoteHandler.php deleted file mode 100644 index bfb2d682..00000000 --- a/src/Adapter/Order/CommandHandler/UpdateInvoiceNoteHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use OrderInvoice; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\UpdateInvoiceNoteCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\CommandHandler\UpdateInvoiceNoteHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Exception\InvoiceException; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Exception\InvoiceNotFoundException; -use Validate; - -/** - * @internal - */ -final class UpdateInvoiceNoteHandler implements UpdateInvoiceNoteHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateInvoiceNoteCommand $command): void - { - $note = $command->getNote(); - $orderInvoice = new OrderInvoice($command->getOrderInvoiceId()->getValue()); - - if (!Validate::isLoadedObject($orderInvoice) && Validate::isCleanHtml($note)) { - throw new InvoiceNotFoundException(sprintf('Order invoice with id "%d" was not found', $command->getOrderInvoiceId()->getValue())); - } - - $orderInvoice->note = $note; - - if (!$orderInvoice->save()) { - throw new InvoiceException('The invoice note was not saved.'); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php b/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php deleted file mode 100644 index 06d58f86..00000000 --- a/src/Adapter/Order/CommandHandler/UpdateOrderShippingDetailsHandler.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Carrier; -use Cart; -use Customer; -use Hook; -use OrderCarrier; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderShippingDetailsCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\UpdateOrderShippingDetailsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\TransistEmailSendingException; -use Validate; - -/** - * @internal - */ -final class UpdateOrderShippingDetailsHandler extends AbstractOrderHandler implements UpdateOrderShippingDetailsHandlerInterface -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @param OrderAmountUpdater $orderAmountUpdater - */ - public function __construct(OrderAmountUpdater $orderAmountUpdater) - { - $this->orderAmountUpdater = $orderAmountUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateOrderShippingDetailsCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - - $trackingNumber = $command->getShippingTrackingNumber(); - $carrierId = $command->getNewCarrierId(); - $oldTrackingNumber = $order->shipping_number; - - $orderCarrier = new OrderCarrier($command->getCurrentOrderCarrierId()); - if (!Validate::isLoadedObject($orderCarrier)) { - throw new OrderException('The order carrier ID is invalid.'); - } - - if (!empty($trackingNumber) && !Validate::isTrackingNumber($trackingNumber)) { - throw new OrderException('The tracking number is incorrect.'); - } - - //update carrier - ONLY if changed - then refresh shipping cost - $oldCarrierId = (int) $orderCarrier->id_carrier; - if ($oldCarrierId !== $carrierId) { - $cart = Cart::getCartByOrderId($order->id); - $cart->setDeliveryOption([ - (int) $cart->id_address_delivery => $this->formatLegacyDeliveryOptionFromCarrierId($carrierId), - ]); - $cart->save(); - - $orderCarrier->id_carrier = $carrierId; - $orderCarrier->update(); - - $order->id_carrier = $carrierId; - $this->orderAmountUpdater->update($order, $cart); - } - - //load fresh order carrier because updated just before - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - - // update shipping number - // Keep these two following lines for backward compatibility, remove on 1.6 version - $order->shipping_number = $trackingNumber; - $order->update(); - - // Update order_carrier - $orderCarrier->tracking_number = pSQL($trackingNumber); - if (!$orderCarrier->update()) { - throw new OrderException('The order carrier cannot be updated.'); - } - - //send mail only if tracking number is different AND not empty - if (!empty($trackingNumber) && $oldTrackingNumber != $trackingNumber) { - if (!$orderCarrier->sendInTransitEmail($order)) { - throw new TransistEmailSendingException('An error occurred while sending an email to the customer.'); - } - - $customer = new Customer((int) $order->id_customer); - $carrier = new Carrier((int) $order->id_carrier, $order->id_lang); - - Hook::exec('actionAdminOrdersTrackingNumberUpdate', [ - 'order' => $order, - 'customer' => $customer, - 'carrier' => $carrier, - ], null, false, true, false, $order->id_shop); - } - } -} diff --git a/src/Adapter/Order/CommandHandler/UpdateOrderStatusHandler.php b/src/Adapter/Order/CommandHandler/UpdateOrderStatusHandler.php deleted file mode 100644 index 5b3f669e..00000000 --- a/src/Adapter/Order/CommandHandler/UpdateOrderStatusHandler.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Carrier; -use Configuration; -use Context; -use OrderHistory; -use OrderState; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler\UpdateOrderStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\ChangeOrderStatusException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use StockAvailable; - -/** - * @internal - */ -final class UpdateOrderStatusHandler extends AbstractOrderHandler implements UpdateOrderStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(UpdateOrderStatusCommand $command) - { - $order = $this->getOrder($command->getOrderId()); - $orderState = $this->getOrderStateObject($command->getNewOrderStatusId()); - - $currentOrderState = $order->getCurrentOrderState(); - - if ($currentOrderState->id == $orderState->id) { - throw new OrderException('The order has already been assigned this status.'); - } - - // Create new OrderHistory - $history = new OrderHistory(); - $history->id_order = $order->id; - $history->id_employee = (int) Context::getContext()->employee->id; - - $useExistingPayments = false; - if (!$order->hasInvoice()) { - $useExistingPayments = true; - } - - $history->changeIdOrderState((int) $orderState->id, $order, $useExistingPayments); - - $carrier = new Carrier($order->id_carrier, $order->id_lang); - $templateVars = []; - - if ($history->id_order_state == Configuration::get('PS_OS_SHIPPING') && $order->shipping_number) { - $templateVars = [ - '{followup}' => str_replace('@', $order->shipping_number, $carrier->url), - ]; - } - - // Save all changes - $historyAdded = $history->addWithemail(true, $templateVars); - - if ($historyAdded) { - // synchronizes quantities if needed.. - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) { - foreach ($order->getProducts() as $product) { - if (StockAvailable::dependsOnStock($product['product_id'])) { - StockAvailable::synchronize($product['product_id'], (int) $product['id_shop']); - } - } - } - - return; - } - - throw new ChangeOrderStatusException([], [$command->getOrderId()], [], 'Failed to update status or sent email when changing order status.'); - } - - /** - * @param int $orderStatusId - * - * @return OrderState - */ - private function getOrderStateObject($orderStatusId) - { - $orderState = new OrderState($orderStatusId); - - if ($orderState->id !== $orderStatusId) { - throw new OrderException(sprintf('Order status with id "%s" was not found.', $orderStatusId)); - } - - return $orderState; - } -} diff --git a/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php b/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php deleted file mode 100644 index 627197bd..00000000 --- a/src/Adapter/Order/CommandHandler/UpdateProductInOrderHandler.php +++ /dev/null @@ -1,232 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order\CommandHandler; - -use Configuration; -use Exception; -use Hook; -use Order; -use OrderDetail; -use OrderInvoice; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Order\OrderDetailUpdater; -use PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\CannotEditDeliveredOrderProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\CannotFindProductInOrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DuplicateProductInOrderInvoiceException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\UpdateProductInOrderCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler\UpdateProductInOrderHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductOutOfStockException; -use Product; -use StockAvailable; -use Validate; - -/** - * @internal - */ -final class UpdateProductInOrderHandler extends AbstractOrderHandler implements UpdateProductInOrderHandlerInterface -{ - /** - * @var OrderProductQuantityUpdater - */ - private $orderProductQuantityUpdater; - - /** - * @var OrderDetailUpdater - */ - private $orderDetailUpdater; - - /** - * UpdateProductInOrderHandler constructor. - * - * @param OrderProductQuantityUpdater $orderProductQuantityUpdater - * @param OrderDetailUpdater $orderDetailUpdater - */ - public function __construct( - OrderProductQuantityUpdater $orderProductQuantityUpdater, - OrderDetailUpdater $orderDetailUpdater - ) { - $this->orderProductQuantityUpdater = $orderProductQuantityUpdater; - $this->orderDetailUpdater = $orderDetailUpdater; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateProductInOrderCommand $command) - { - try { - $order = $this->getOrder($command->getOrderId()); - - $orderDetail = new OrderDetail($command->getOrderDetailId()); - $orderInvoice = null; - if (!empty($command->getOrderInvoiceId())) { - $orderInvoice = new OrderInvoice($command->getOrderInvoiceId()); - } - - // Check fields validity - $this->assertProductCanBeUpdated($command, $orderDetail, $order, $orderInvoice); - $this->assertProductNotDuplicate($order, $orderDetail, $orderInvoice); - - // Update current OrderDetail with new price (the object will be updated by reference) - $this->orderDetailUpdater->updateOrderDetail( - $orderDetail, - $order, - $command->getPriceTaxExcluded(), - $command->getPriceTaxIncluded() - ); - - // We also need to update all identical OrderDetails to be sure that Cart will get the correct price - $this->orderDetailUpdater->updateOrderDetailsForProduct( - $order, - (int) $orderDetail->product_id, - (int) $orderDetail->product_attribute_id, - $command->getPriceTaxExcluded(), - $command->getPriceTaxIncluded() - ); - - // Update invoice, quantity and amounts - $order = $this->orderProductQuantityUpdater->update($order, $orderDetail, $command->getQuantity(), $orderInvoice); - - Hook::exec('actionOrderEdited', ['order' => $order]); - } catch (Exception $e) { - throw $e; - } - } - - /** - * @param UpdateProductInOrderCommand $command - * @param OrderDetail $orderDetail - * @param Order $order - * @param OrderInvoice|null $orderInvoice - * - * @throws OrderException - */ - private function assertProductCanBeUpdated( - UpdateProductInOrderCommand $command, - OrderDetail $orderDetail, - Order $order, - OrderInvoice $orderInvoice = null - ) { - // assert product exists - $product = new Product($orderDetail->product_id); - if ($product->id !== (int) $orderDetail->product_id) { - throw new CannotFindProductInOrderException('You cannot edit the price of a product that no longer exists in your catalog.'); - } - - if (!Validate::isLoadedObject($orderDetail)) { - throw new OrderException('The Order Detail object could not be loaded.'); - } - - if (null !== $orderInvoice && !Validate::isLoadedObject($orderInvoice)) { - throw new OrderException('The invoice object cannot be loaded.'); - } - - if (!Validate::isLoadedObject($order)) { - throw new OrderException('The order object cannot be loaded.'); - } - - if ($orderDetail->id_order != $order->id) { - throw new OrderException('You cannot edit the order detail for this order.'); - } - - // We can't edit a delivered order - if ($order->hasBeenDelivered()) { - throw new CannotEditDeliveredOrderProductException('You cannot edit a delivered order.'); - } - - if (null !== $orderInvoice && $orderInvoice->id_order != $order->id) { - throw new OrderException('You cannot use this invoice for the order'); - } - - if ($command->getPriceTaxIncluded()->isNegative() || $command->getPriceTaxExcluded()->isNegative()) { - throw new OrderException('Invalid price'); - } - - if (!Validate::isUnsignedInt($command->getQuantity())) { - throw new OrderException('Invalid quantity'); - } - - //check if product is available in stock - if (!Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($orderDetail->product_id))) { - $availableQuantity = StockAvailable::getQuantityAvailableByProduct($orderDetail->product_id, $orderDetail->product_attribute_id); - $quantityDiff = $command->getQuantity() - (int) $orderDetail->product_quantity; - - if ($quantityDiff > $availableQuantity) { - throw new ProductOutOfStockException('Not enough products in stock'); - } - } - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param OrderInvoice|null $orderInvoice - * - * @throws DuplicateProductInOrderInvoiceException - */ - private function assertProductNotDuplicate(Order $order, OrderDetail $orderDetail, ?OrderInvoice $orderInvoice = null): void - { - // If the OrderDetail's invoice is not changed no reason to check - if (null === $orderInvoice || (int) $orderInvoice->id === (int) $orderDetail->id_order_invoice) { - return; - } - - // If no multi invoice possible no reason to check - if (!$order->hasInvoice()) { - return; - } - - $invoicesContainingProduct = []; - foreach ($order->getOrderDetailList() as $orderDetailData) { - if ((int) $orderDetail->id === (int) $orderDetailData['id_order_detail']) { - continue; - } - if ((int) $orderDetail->product_id !== (int) $orderDetailData['product_id']) { - continue; - } - if ((int) $orderDetail->product_attribute_id !== (int) $orderDetailData['product_attribute_id']) { - continue; - } - $invoicesContainingProduct[] = (int) $orderDetailData['id_order_invoice']; - } - - // No invoices contain the product it's fine - if (empty($invoicesContainingProduct)) { - return; - } - - // The newly assigned invoice already contains this product, this it not possible - if (in_array((int) $orderInvoice->id, $invoicesContainingProduct)) { - $invoiceNumber = $orderInvoice->getInvoiceNumberFormatted((int) Configuration::get('PS_LANG_DEFAULT'), $order->id_shop); - throw new DuplicateProductInOrderInvoiceException($invoiceNumber, 'You cannot add this product in this invoice as it is already present'); - } - } -} diff --git a/src/Adapter/Order/Delivery/SlipOptionsConfiguration.php b/src/Adapter/Order/Delivery/SlipOptionsConfiguration.php deleted file mode 100644 index 30160d3b..00000000 --- a/src/Adapter/Order/Delivery/SlipOptionsConfiguration.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Delivery; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class manages Order delivery slip options configuration. - */ -final class SlipOptionsConfiguration implements DataConfigurationInterface -{ - const PREFIX = 'PS_DELIVERY_PREFIX'; - const NUMBER = 'PS_DELIVERY_NUMBER'; - const ENABLE_PRODUCT_IMAGE = 'PS_PDF_IMG_DELIVERY'; - - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * Returns configuration used to manage slip options in back office. - * - * @return array - */ - public function getConfiguration() - { - return [ - 'prefix' => $this->configuration->get(self::PREFIX), - 'number' => $this->configuration->getInt(self::NUMBER), - 'enable_product_image' => $this->configuration->getBoolean(self::ENABLE_PRODUCT_IMAGE), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set(self::PREFIX, $configuration['prefix']); - $this->configuration->set(self::NUMBER, $configuration['number']); - $this->configuration->set(self::ENABLE_PRODUCT_IMAGE, $configuration['enable_product_image']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['prefix'], - $configuration['number'], - $configuration['enable_product_image'] - ); - } -} diff --git a/src/Adapter/Order/Delivery/SlipPdfConfiguration.php b/src/Adapter/Order/Delivery/SlipPdfConfiguration.php deleted file mode 100644 index 1428fdff..00000000 --- a/src/Adapter/Order/Delivery/SlipPdfConfiguration.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Delivery; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Order\Invoice; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class manages Order delivery slip pdf configuration. - */ -final class SlipPdfConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * Returns configuration used to manage Slip pdf in back office. - * - * @return array - */ - public function getConfiguration() - { - return []; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - if (!Validate::isDate($configuration['date_to'])) { - $errors[] = [ - 'key' => "Invalid 'to' date", - 'domain' => 'Admin.Catalog.Notification', - 'parameters' => [], - ]; - } - - if (!Validate::isDate($configuration['date_from'])) { - $errors[] = [ - 'key' => "Invalid 'from' date", - 'domain' => 'Admin.Catalog.Notification', - 'parameters' => [], - ]; - } - - if (empty(Invoice::getByDeliveryDateInterval($configuration['date_from'], $configuration['date_to']))) { - $errors[] = [ - 'key' => 'No delivery slip was found for this period.', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - } - - return !empty($errors) ? $errors : []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['date_from'], - $configuration['date_to'] - ); - } -} diff --git a/src/Adapter/Order/GeneralConfiguration.php b/src/Adapter/Order/GeneralConfiguration.php deleted file mode 100644 index 3a9bb21d..00000000 --- a/src/Adapter/Order/GeneralConfiguration.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * General Settings configuration available in ShopParameters > Order Preferences. - */ -class GeneralConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_final_summary' => $this->configuration->getBoolean('PS_FINAL_SUMMARY_ENABLED'), - 'enable_guest_checkout' => $this->configuration->getBoolean('PS_GUEST_CHECKOUT_ENABLED'), - 'disable_reordering_option' => $this->configuration->getBoolean('PS_DISALLOW_HISTORY_REORDERING'), - 'purchase_minimum_value' => $this->configuration->get('PS_PURCHASE_MINIMUM'), - 'recalculate_shipping_cost' => $this->configuration->getBoolean('PS_ORDER_RECALCULATE_SHIPPING'), - 'allow_multishipping' => $this->configuration->getBoolean('PS_ALLOW_MULTISHIPPING'), - 'allow_delayed_shipping' => $this->configuration->getBoolean('PS_SHIP_WHEN_AVAILABLE'), - 'enable_tos' => $this->configuration->getBoolean('PS_CONDITIONS'), - 'tos_cms_id' => $this->configuration->get('PS_CONDITIONS_CMS_ID'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_FINAL_SUMMARY_ENABLED', $configuration['enable_final_summary']); - $this->configuration->set('PS_GUEST_CHECKOUT_ENABLED', $configuration['enable_guest_checkout']); - $this->configuration->set('PS_DISALLOW_HISTORY_REORDERING', $configuration['disable_reordering_option']); - $this->configuration->set('PS_PURCHASE_MINIMUM', $configuration['purchase_minimum_value']); - $this->configuration->set('PS_ORDER_RECALCULATE_SHIPPING', $configuration['recalculate_shipping_cost']); - $this->configuration->set('PS_ALLOW_MULTISHIPPING', $configuration['allow_multishipping']); - $this->configuration->set('PS_SHIP_WHEN_AVAILABLE', $configuration['allow_delayed_shipping']); - $this->configuration->set('PS_CONDITIONS', $configuration['enable_tos']); - $this->configuration->set('PS_CONDITIONS_CMS_ID', $configuration['tos_cms_id']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_final_summary'], - $configuration['enable_guest_checkout'], - $configuration['disable_reordering_option'], - $configuration['purchase_minimum_value'], - $configuration['recalculate_shipping_cost'], - $configuration['allow_multishipping'], - $configuration['allow_delayed_shipping'], - $configuration['enable_tos'], - $configuration['tos_cms_id'] - ); - } -} diff --git a/src/Adapter/Order/GiftOptionsConfiguration.php b/src/Adapter/Order/GiftOptionsConfiguration.php deleted file mode 100644 index 50a2311a..00000000 --- a/src/Adapter/Order/GiftOptionsConfiguration.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Gift Settings configuration available in ShopParameters > Order Preferences. - */ -class GiftOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_gift_wrapping' => $this->configuration->getBoolean('PS_GIFT_WRAPPING'), - 'gift_wrapping_price' => $this->configuration->get('PS_GIFT_WRAPPING_PRICE'), - 'gift_wrapping_tax_rules_group' => $this->configuration->get('PS_GIFT_WRAPPING_TAX_RULES_GROUP'), - 'offer_recyclable_pack' => $this->configuration->getBoolean('PS_RECYCLABLE_PACK'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_GIFT_WRAPPING', $configuration['enable_gift_wrapping']); - $this->configuration->set('PS_GIFT_WRAPPING_PRICE', $configuration['gift_wrapping_price']); - $this->configuration->set('PS_GIFT_WRAPPING_TAX_RULES_GROUP', $configuration['gift_wrapping_tax_rules_group']); - $this->configuration->set('PS_RECYCLABLE_PACK', $configuration['offer_recyclable_pack']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_gift_wrapping'], - $configuration['gift_wrapping_price'], - $configuration['gift_wrapping_tax_rules_group'], - $configuration['offer_recyclable_pack'] - ); - } -} diff --git a/src/Adapter/Order/Invoice.php b/src/Adapter/Order/Invoice.php deleted file mode 100644 index 19852862..00000000 --- a/src/Adapter/Order/Invoice.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use OrderInvoice as InvoiceLegacy; -use PrestaShop\PrestaShop\Core\Order\InvoiceInterface; - -/** - * Invoice Helper. - */ -final class Invoice implements InvoiceInterface -{ - /** - * {@inheritdoc} - */ - public static function getByDeliveryDateInterval($dateFrom, $dateTo) - { - return InvoiceLegacy::getByDeliveryDateInterval($dateFrom, $dateTo); - } -} diff --git a/src/Adapter/Order/OrderAmountUpdater.php b/src/Adapter/Order/OrderAmountUpdater.php deleted file mode 100644 index 2744e68d..00000000 --- a/src/Adapter/Order/OrderAmountUpdater.php +++ /dev/null @@ -1,512 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use Address; -use Cache; -use Carrier; -use Cart; -use CartRule; -use Currency; -use Customer; -use Language; -use Order; -use OrderCarrier; -use OrderCartRule; -use OrderDetail; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Cart\CartRuleData; -use PrestaShop\PrestaShop\Core\Domain\Configuration\ShopConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShopDatabaseException; -use PrestaShopException; -use Product; -use Shop; -use Tools; -use Validate; - -class OrderAmountUpdater -{ - /** - * @var ShopConfigurationInterface - */ - private $shopConfiguration; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var OrderDetailUpdater - */ - private $orderDetailUpdater; - - /** - * @var array - */ - private $orderConstraints = []; - - /** - * @var bool - */ - private $keepOrderPrices = true; - - /** - * @param ShopConfigurationInterface $shopConfiguration - * @param ContextStateManager $contextStateManager - * @param OrderDetailUpdater $orderDetailUpdater - */ - public function __construct( - ShopConfigurationInterface $shopConfiguration, - ContextStateManager $contextStateManager, - OrderDetailUpdater $orderDetailUpdater - ) { - $this->shopConfiguration = $shopConfiguration; - $this->contextStateManager = $contextStateManager; - $this->orderDetailUpdater = $orderDetailUpdater; - } - - /** - * @param Order $order - * @param Cart $cart - * @param int|null $orderInvoiceId - * - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - public function update( - Order $order, - Cart $cart, - ?int $orderInvoiceId = null - ): void { - $this->cleanCaches(); - - $this->contextStateManager - ->saveCurrentContext() - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setCustomer(new Customer($cart->id_customer)) - ->setLanguage(new Language($cart->id_lang)) - ->setCountry($cart->getTaxCountry()) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - // @todo: use https://github.com/PrestaShop/decimal for price computations - $computingPrecision = $this->getPrecisionFromCart($cart); - - // Update order details (if quantity or product price have been modified) - $this->updateOrderDetails($order, $cart); - - // Recalculate cart rules and Fix differences between cart's cartRules and order's cartRules - $this->updateOrderCartRules($order, $cart, $computingPrecision, $orderInvoiceId); - - // Update order totals - $this->updateOrderTotals($order, $cart, $computingPrecision); - - // Update carrier weight for shipping cost - $this->updateOrderCarrier($order, $cart); - - // Order::update is called after previous functions so that we only call it once - if (!$order->update()) { - throw new OrderException('Could not update order invoice in database.'); - } - - $this->updateOrderInvoices($order, $cart, $computingPrecision); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * There are many caches among legacy classes that can store previous prices - * we need to clean them to make sure the price is completely up to date - */ - private function cleanCaches(): void - { - // For many intermediate computations - Cart::resetStaticCache(); - - // For discount computation - CartRule::resetStaticCache(); - Cache::clean('getContextualValue_*'); - - // For shipping costs - Carrier::resetStaticCache(); - Cache::clean('getPackageShippingCost_*'); - } - - /** - * @param Order $order - * @param Cart $cart - * @param int $computingPrecision - */ - private function updateOrderTotals(Order $order, Cart $cart, int $computingPrecision): void - { - $orderProducts = $order->getCartProducts(); - - $carrierId = $order->id_carrier; - $order->total_discounts = (float) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - $order->total_discounts_tax_excl = (float) abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - $order->total_discounts_tax_incl = (float) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - - // We should always use Cart::BOTH for the order total since it contains all products, shipping fees and cart rules - $order->total_paid = Tools::ps_round( - (float) $cart->getOrderTotal(true, Cart::BOTH, $orderProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - $order->total_paid_tax_excl = Tools::ps_round( - (float) $cart->getOrderTotal(false, Cart::BOTH, $orderProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - $order->total_paid_tax_incl = Tools::ps_round( - (float) $cart->getOrderTotal(true, Cart::BOTH, $orderProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - - $order->total_products = (float) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $orderProducts, $carrierId, false, $this->keepOrderPrices); - $order->total_products_wt = (float) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $orderProducts, $carrierId, false, $this->keepOrderPrices); - - $order->total_wrapping = abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - $order->total_wrapping_tax_excl = abs($cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - $order->total_wrapping_tax_incl = abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices)); - - $totalShippingTaxIncluded = $order->total_shipping_tax_incl; - $totalShippingTaxExcluded = $order->total_shipping_tax_excl; - - $order->total_shipping = $cart->getOrderTotal(true, Cart::ONLY_SHIPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices); - $order->total_shipping_tax_excl = $cart->getOrderTotal(false, Cart::ONLY_SHIPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices); - $order->total_shipping_tax_incl = $cart->getOrderTotal(true, Cart::ONLY_SHIPPING, $orderProducts, $carrierId, false, $this->keepOrderPrices); - - if (!$this->getOrderConfiguration('PS_ORDER_RECALCULATE_SHIPPING', $order)) { - $shippingDiffTaxIncluded = $order->total_shipping_tax_incl - $totalShippingTaxIncluded; - $shippingDiffTaxExcluded = $order->total_shipping_tax_excl - $totalShippingTaxExcluded; - - $order->total_shipping = $totalShippingTaxIncluded; - $order->total_shipping_tax_incl = $totalShippingTaxIncluded; - $order->total_shipping_tax_excl = $totalShippingTaxExcluded; - - $order->total_paid -= $shippingDiffTaxIncluded; - $order->total_paid_tax_incl -= $shippingDiffTaxIncluded; - $order->total_paid_tax_excl -= $shippingDiffTaxExcluded; - } - } - - /** - * @param Order $order - * @param Cart $cart - * - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function updateOrderCarrier(Order $order, Cart $cart): void - { - $orderCarrier = new OrderCarrier((int) $order->getIdOrderCarrier()); - - if (Validate::isLoadedObject($orderCarrier)) { - $orderCarrier->weight = (float) $order->getTotalWeight(); - $orderCarrier->shipping_cost_tax_incl = (float) $order->total_shipping_tax_incl; - $orderCarrier->shipping_cost_tax_excl = (float) $order->total_shipping_tax_excl; - - if ($orderCarrier->update()) { - $order->weight = sprintf('%.3f ' . $this->getOrderConfiguration('PS_WEIGHT_UNIT', $order), $orderCarrier->weight); - } - } - - if (!$cart->isVirtualCart() && isset($order->id_carrier)) { - $carrier = new Carrier((int) $order->id_carrier, (int) $cart->id_lang); - if (null !== $carrier && Validate::isLoadedObject($carrier)) { - $taxAddressId = (int) $order->{$this->getOrderConfiguration('PS_TAX_ADDRESS_TYPE', $order)}; - $order->carrier_tax_rate = $carrier->getTaxesRate(new Address($taxAddressId)); - } - } - } - - /** - * @param Order $order - * @param Cart $cart - * - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function updateOrderDetails(Order $order, Cart $cart): void - { - // Get cart products with prices kept from order - $cartProducts = $cart->getProducts(true, false, null, true, $this->keepOrderPrices); - foreach ($order->getCartProducts() as $orderProduct) { - $orderDetail = new OrderDetail($orderProduct['id_order_detail'], null, $this->contextStateManager->getContext()); - $cartProduct = $this->getProductFromCart($cartProducts, (int) $orderDetail->product_id, (int) $orderDetail->product_attribute_id); - - $this->orderDetailUpdater->updateOrderDetail( - $orderDetail, - $order, - new Number((string) $cartProduct['price_with_reduction_without_tax']), - new Number((string) $cartProduct['price_with_reduction']) - ); - } - } - - /** - * @param array $cartProducts - * @param int $productId - * @param int $productAttributeId - * - * @return array - */ - private function getProductFromCart(array $cartProducts, int $productId, int $productAttributeId): array - { - $cartProduct = array_reduce($cartProducts, function ($carry, $item) use ($productId, $productAttributeId) { - if (null !== $carry) { - return $carry; - } - - $productMatch = $item['id_product'] == $productId; - $combinationMatch = $item['id_product_attribute'] == $productAttributeId; - - return $productMatch && $combinationMatch ? $item : null; - }); - - // This shouldn't happen, if it does something was not done before updating the Order (removing an OrderDetail maybe) - if (null === $cartProduct) { - throw new OrderException('Could not find the product in cart, meaning Order and Cart are out of sync'); - } - - return $cartProduct; - } - - /** - * Update cart rules to be synced with current cart: - * - cart rules attached to new product may be added/removed - * - global shop cart rules may be added/removed - * - cart rules amount may vary because other cart rules have been added/removed - * - * @param Order $order - * @param Cart $cart - * @param int $computingPrecision - * @param int|null $orderInvoiceId - * - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function updateOrderCartRules( - Order $order, - Cart $cart, - int $computingPrecision, - ?int $orderInvoiceId - ): void { - CartRule::autoAddToCart(); - CartRule::autoRemoveFromCart(); - $carrierId = $order->id_carrier; - - $newCartRules = $cart->getCartRules(); - // We need the calculator to compute the discount on the whole products because they can interact with each - // other so they can't be computed independently, it needs to keep order prices - $calculator = $cart->newCalculator($order->getCartProducts(), $newCartRules, $carrierId, $computingPrecision, $this->keepOrderPrices); - $calculator->processCalculation(); - - foreach ($order->getCartRules() as $orderCartRuleData) { - /** @var CartRuleData $cartRuleData */ - foreach ($calculator->getCartRulesData() as $cartRuleData) { - $cartRule = $cartRuleData->getCartRule(); - if ($cartRule->id == $orderCartRuleData['id_cart_rule']) { - // Cart rule is still in the cart no need to remove it, but we update it as the amount may have changed - $orderCartRule = new OrderCartRule($orderCartRuleData['id_order_cart_rule']); - $orderCartRule->id_order = $order->id; - $orderCartRule->name = $cartRule->name; - $orderCartRule->free_shipping = $cartRule->free_shipping; - $orderCartRule->value = Tools::ps_round($cartRuleData->getDiscountApplied()->getTaxIncluded(), $computingPrecision); - $orderCartRule->value_tax_excl = Tools::ps_round($cartRuleData->getDiscountApplied()->getTaxExcluded(), $computingPrecision); - $orderCartRule->save(); - continue 2; - } - } - - // This one is no longer in the new cart rules so we delete it - $orderCartRule = new OrderCartRule($orderCartRuleData['id_order_cart_rule']); - // This one really needs to be deleted because it doesn't match the applied cart rules any more - // we don't use soft deleted here (unlike in the handler) but hard delete - if (!$orderCartRule->delete()) { - throw new OrderException('Could not delete order cart rule from database.'); - } - } - - // Finally add the new cart rules that are not in the Order - foreach ($calculator->getCartRulesData() as $cartRuleData) { - $cartRule = $cartRuleData->getCartRule(); - foreach ($order->getCartRules() as $orderCartRuleData) { - if ($cartRule->id == $orderCartRuleData['id_cart_rule']) { - // This cart rule is already present no need to add it - continue 2; - } - } - - // Add missing order cart rule - $orderCartRule = new OrderCartRule(); - $orderCartRule->id_order = $order->id; - $orderCartRule->id_cart_rule = $cartRule->id; - $orderCartRule->id_order_invoice = $orderInvoiceId ?? 0; - $orderCartRule->name = $cartRule->name; - $orderCartRule->free_shipping = $cartRule->free_shipping; - $orderCartRule->value = Tools::ps_round($cartRuleData->getDiscountApplied()->getTaxIncluded(), $computingPrecision); - $orderCartRule->value_tax_excl = Tools::ps_round($cartRuleData->getDiscountApplied()->getTaxExcluded(), $computingPrecision); - $orderCartRule->save(); - } - } - - /** - * @param Order $order - * @param Cart $cart - * @param int $computingPrecision - * - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function updateOrderInvoices(Order $order, Cart $cart, int $computingPrecision): void - { - $invoiceProducts = []; - foreach ($order->getCartProducts() as $orderProduct) { - if (!empty($orderProduct['id_order_invoice'])) { - $invoiceProducts[$orderProduct['id_order_invoice']][] = $orderProduct; - } - } - - $invoiceCollection = $order->getInvoicesCollection(); - $firstInvoice = $invoiceCollection->getFirst(); - - foreach ($invoiceCollection as $invoice) { - // If all the invoice's products have been removed the offset won't exist - $currentInvoiceProducts = isset($invoiceProducts[$invoice->id]) ? $invoiceProducts[$invoice->id] : []; - - // Shipping are computed on first invoice only - $carrierId = $order->id_carrier; - $totalMethod = ($firstInvoice === null || $firstInvoice->id == $invoice->id) ? Cart::BOTH : Cart::BOTH_WITHOUT_SHIPPING; - $invoice->total_paid_tax_excl = Tools::ps_round( - (float) $cart->getOrderTotal(false, $totalMethod, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - $invoice->total_paid_tax_incl = Tools::ps_round( - (float) $cart->getOrderTotal(true, $totalMethod, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - - $invoice->total_products = Tools::ps_round( - (float) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - $invoice->total_products_wt = Tools::ps_round( - (float) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - - $invoice->total_discount_tax_excl = Tools::ps_round( - (float) $cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - - $invoice->total_discount_tax_incl = Tools::ps_round( - (float) $cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices), - $computingPrecision - ); - - $totalShippingTaxIncluded = $invoice->total_shipping_tax_incl; - $totalShippingTaxExcluded = $invoice->total_shipping_tax_excl; - - $invoice->total_shipping = $cart->getOrderTotal(true, Cart::ONLY_SHIPPING, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices); - $invoice->total_shipping_tax_excl = $cart->getOrderTotal(false, Cart::ONLY_SHIPPING, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices); - $invoice->total_shipping_tax_incl = $cart->getOrderTotal(true, Cart::ONLY_SHIPPING, $currentInvoiceProducts, $carrierId, false, $this->keepOrderPrices); - - if (!$this->getOrderConfiguration('PS_ORDER_RECALCULATE_SHIPPING', $order)) { - $shippingDiffTaxIncluded = $invoice->total_shipping_tax_incl - $totalShippingTaxIncluded; - $shippingDiffTaxExcluded = $invoice->total_shipping_tax_excl - $totalShippingTaxExcluded; - - $invoice->total_shipping = $totalShippingTaxIncluded; - $invoice->total_shipping_tax_incl = $totalShippingTaxIncluded; - $invoice->total_shipping_tax_excl = $totalShippingTaxExcluded; - - $invoice->total_paid -= $shippingDiffTaxIncluded; - $invoice->total_paid_tax_incl -= $shippingDiffTaxIncluded; - $invoice->total_paid_tax_excl -= $shippingDiffTaxExcluded; - } - - if (!$invoice->update()) { - throw new OrderException('Could not update order invoice in database.'); - } - } - } - - /** - * @param Cart $cart - * - * @return int - */ - private function getPrecisionFromCart(Cart $cart): int - { - $computingPrecision = new ComputingPrecision(); - $currency = new Currency((int) $cart->id_currency); - - return $computingPrecision->getPrecision((int) $currency->precision); - } - - /** - * @param string $key - * @param Order $order - * - * @return mixed - */ - private function getOrderConfiguration(string $key, Order $order) - { - return $this->shopConfiguration->get($key, null, $this->getOrderShopConstraint($order)); - } - - /** - * @param Order $order - * - * @return ShopConstraint - */ - private function getOrderShopConstraint(Order $order): ShopConstraint - { - $constraintKey = $order->id_shop . '-' . $order->id_shop_group; - if (!isset($this->orderConstraints[$constraintKey])) { - $this->orderConstraints[$constraintKey] = new ShopConstraint( - (int) $order->id_shop, - (int) $order->id_shop_group - ); - } - - return $this->orderConstraints[$constraintKey]; - } -} diff --git a/src/Adapter/Order/OrderDetailUpdater.php b/src/Adapter/Order/OrderDetailUpdater.php deleted file mode 100644 index a6ef317e..00000000 --- a/src/Adapter/Order/OrderDetailUpdater.php +++ /dev/null @@ -1,471 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use Address; -use Cart; -use Country; -use Currency; -use Customer; -use Db; -use Language; -use Order; -use OrderDetail; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Core\Domain\Configuration\ShopConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use Product; -use Shop; -use TaxCalculator; -use TaxManagerFactory; -use Tools; - -class OrderDetailUpdater -{ - private const COMPARISON_PRECISION = 6; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var ShopConfigurationInterface - */ - private $shopConfiguration; - - /** - * @param ContextStateManager $contextStateManager - * @param ShopConfigurationInterface $shopConfiguration - */ - public function __construct( - ContextStateManager $contextStateManager, - ShopConfigurationInterface $shopConfiguration - ) { - $this->contextStateManager = $contextStateManager; - $this->shopConfiguration = $shopConfiguration; - } - - /** - * @param OrderDetail $orderDetail - * @param Order $order - * @param Number $priceTaxExcluded - * @param Number $priceTaxIncluded - * - * @throws OrderException - */ - public function updateOrderDetail( - OrderDetail $orderDetail, - Order $order, - Number $priceTaxExcluded, - Number $priceTaxIncluded - ): void { - list($roundType, $computingPrecision, $taxAddress) = $this->prepareOrderContext($order); - - try { - $precisePriceTaxExcluded = $this->getPrecisePriceTaxExcluded($priceTaxIncluded, $priceTaxExcluded, $order, $orderDetail, $taxAddress); - $precisePriceTaxIncluded = $this->getPrecisePriceTaxIncluded($priceTaxIncluded, $priceTaxExcluded, $order, $orderDetail, $taxAddress); - - $this->applyOrderDetailPriceUpdate( - $orderDetail, - $precisePriceTaxExcluded, - $precisePriceTaxIncluded, - $roundType, - $computingPrecision - ); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - * @param int $productId - * @param int $combinationId - * @param Number $priceTaxExcluded - * @param Number $priceTaxIncluded - * - * @throws OrderException - */ - public function updateOrderDetailsForProduct( - Order $order, - int $productId, - int $combinationId, - Number $priceTaxExcluded, - Number $priceTaxIncluded - ): void { - list($roundType, $computingPrecision, $taxAddress) = $this->prepareOrderContext($order); - - try { - $this->applyUpdatesForProduct( - $order, - $productId, - $combinationId, - $priceTaxExcluded, - $priceTaxIncluded, - $roundType, - $computingPrecision, - $taxAddress - ); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - */ - public function updateOrderDetailsTaxes(Order $order): void - { - list($roundType, $computingPrecision, $taxAddress) = $this->prepareOrderContext($order); - - try { - $orderDetailsData = $order->getProducts(); - foreach ($orderDetailsData as $orderDetailData) { - $orderDetail = new OrderDetail($orderDetailData['id_order_detail']); - - // Clean existing order_detail_tax - Db::getInstance()->delete('order_detail_tax', 'id_order_detail = ' . (int) $orderDetail->id); - - $taxCalculator = $this->getTaxCalculatorByAddress($taxAddress, $orderDetail); - $taxesAmount = $taxCalculator->getTaxesAmount($orderDetail->unit_price_tax_excl); - $unitAmount = $totalAmount = 0; - if (!empty($taxesAmount)) { - $orderDetailTaxes = []; - foreach ($taxesAmount as $taxId => $amount) { - switch ($roundType) { - case Order::ROUND_ITEM: - $unitAmount = (float) Tools::ps_round($amount, $computingPrecision); - $totalAmount = $unitAmount * $orderDetail->product_quantity; - - break; - case Order::ROUND_LINE: - $unitAmount = $amount; - $totalAmount = Tools::ps_round($unitAmount * $orderDetail->product_quantity, $computingPrecision); - - break; - case Order::ROUND_TOTAL: - $unitAmount = $amount; - $totalAmount = $unitAmount * $orderDetail->product_quantity; - - break; - } - $orderDetailTaxes[] = [ - 'id_order_detail' => $orderDetail->id, - 'id_tax' => $taxId, - 'unit_amount' => (float) $unitAmount, - 'total_amount' => (float) $totalAmount, - ]; - $orderDetail->unit_price_tax_incl = (float) $orderDetail->unit_price_tax_excl + $unitAmount; - $orderDetail->total_price_tax_incl = (float) $orderDetail->total_price_tax_incl + $totalAmount; - } - - Db::getInstance()->insert('order_detail_tax', $orderDetailTaxes, false); - } - - // Update OrderDetail values - $orderDetail->unit_price_tax_incl = (float) $orderDetail->unit_price_tax_excl + $unitAmount; - $orderDetail->total_price_tax_incl = (float) $orderDetail->total_price_tax_incl + $totalAmount; - if (!$orderDetail->update()) { - throw new OrderException('An error occurred while editing the product line.'); - } - } - } finally { - $this->contextStateManager->restorePreviousContext(); - } - } - - /** - * @param Order $order - * - * @return array - */ - private function prepareOrderContext(Order $order): array - { - $shopConstraint = new ShopConstraint( - (int) $order->id_shop, - (int) $order->id_shop_group - ); - $roundType = (int) $this->shopConfiguration->get('PS_ROUND_TYPE', null, $shopConstraint); - $taxAddressType = $this->shopConfiguration->get('PS_TAX_ADDRESS_TYPE', null, $shopConstraint); - $taxAddress = new Address($order->{$taxAddressType}); - $country = new Country($taxAddress->id_country); - $currency = new Currency($order->id_currency); - $shop = new Shop($order->id_shop); - $computingPrecision = (new ComputingPrecision())->getPrecision((int) $currency->precision); - - $this->contextStateManager - ->saveCurrentContext() - ->setCart(new Cart($order->id_cart)) - ->setCustomer(new Customer($order->id_customer)) - ->setLanguage(new Language($order->id_lang)) - ->setCurrency($currency) - ->setCountry($country) - ->setShop($shop) - ; - - return [$roundType, $computingPrecision, $taxAddress]; - } - - /** - * @param OrderDetail $orderDetail - * @param Number $priceTaxExcluded - * @param Number $priceTaxIncluded - * @param int $roundType - * @param int $computingPrecision - * - * @throws OrderException - */ - private function applyOrderDetailPriceUpdate( - OrderDetail $orderDetail, - Number $priceTaxExcluded, - Number $priceTaxIncluded, - int $roundType, - int $computingPrecision - ): void { - $floatPriceTaxExcluded = (float) (string) $priceTaxExcluded; - $floatPriceTaxIncluded = (float) (string) $priceTaxIncluded; - - $orderDetail->product_price = $orderDetail->unit_price_tax_excl = $floatPriceTaxExcluded; - $orderDetail->unit_price_tax_incl = $floatPriceTaxIncluded; - switch ($roundType) { - case Order::ROUND_TOTAL: - $orderDetail->total_price_tax_excl = $floatPriceTaxExcluded * $orderDetail->product_quantity; - $orderDetail->total_price_tax_incl = $floatPriceTaxIncluded * $orderDetail->product_quantity; - - break; - case Order::ROUND_LINE: - $orderDetail->total_price_tax_excl = Tools::ps_round($floatPriceTaxExcluded * $orderDetail->product_quantity, $computingPrecision); - $orderDetail->total_price_tax_incl = Tools::ps_round($floatPriceTaxIncluded * $orderDetail->product_quantity, $computingPrecision); - - break; - - case Order::ROUND_ITEM: - default: - $orderDetail->product_price = $orderDetail->unit_price_tax_excl = Tools::ps_round($floatPriceTaxExcluded, $computingPrecision); - $orderDetail->unit_price_tax_incl = Tools::ps_round($floatPriceTaxIncluded, $computingPrecision); - $orderDetail->total_price_tax_excl = $orderDetail->unit_price_tax_excl * $orderDetail->product_quantity; - $orderDetail->total_price_tax_incl = $orderDetail->unit_price_tax_incl * $orderDetail->product_quantity; - - break; - } - - if (!$orderDetail->update()) { - throw new OrderException('An error occurred while editing the product line.'); - } - } - - /** - * @param Order $order - * @param int $productId - * @param int $combinationId - * @param Number $priceTaxExcluded - * @param Number $priceTaxIncluded - * @param int $roundType - * @param int $computingPrecision - * @param Address $taxAddress - * - * @throws OrderException - */ - private function applyUpdatesForProduct( - Order $order, - int $productId, - int $combinationId, - Number $priceTaxExcluded, - Number $priceTaxIncluded, - int $roundType, - int $computingPrecision, - Address $taxAddress - ): void { - $identicalOrderDetails = $this->getOrderDetailsForProduct($order, $productId, $combinationId); - if (empty($identicalOrderDetails)) { - return; - } - - // Get precise prices thanks to first OrderDetail (they all have the same price anyway) - $orderDetail = $identicalOrderDetails[0]; - $precisePriceTaxExcluded = $this->getPrecisePriceTaxExcluded($priceTaxIncluded, $priceTaxExcluded, $order, $orderDetail, $taxAddress); - $precisePriceTaxIncluded = $this->getPrecisePriceTaxIncluded($priceTaxIncluded, $priceTaxExcluded, $order, $orderDetail, $taxAddress); - - foreach ($identicalOrderDetails as $identicalOrderDetail) { - $this->applyOrderDetailPriceUpdate( - $identicalOrderDetail, - $precisePriceTaxExcluded, - $precisePriceTaxIncluded, - $roundType, - $computingPrecision - ); - } - } - - /** - * @param Order $order - * @param int $productId - * @param int $combinationId - * - * @return array - */ - private function getOrderDetailsForProduct( - Order $order, - int $productId, - int $combinationId - ): array { - $identicalOrderDetails = []; - $orderDetails = $order->getOrderDetailList(); - foreach ($orderDetails as $orderDetail) { - if ((int) $orderDetail['product_id'] === $productId - && (int) $orderDetail['product_attribute_id'] === $combinationId) { - $identicalOrderDetails[] = new OrderDetail($orderDetail['id_order_detail']); - } - } - - return $identicalOrderDetails; - } - - /** - * Since prices in input are sometimes rounded they don't precisely match, so in this case - * if the price is different from catalog we use price included as a base and recompute the - * price tax excluded with additional precision. - * - * @param Number $priceTaxIncluded - * @param Number $priceTaxExcluded - * @param Order $order - * @param OrderDetail $orderDetail - * @param Address $taxAddress - * - * @return Number - */ - private function getPrecisePriceTaxExcluded( - Number $priceTaxIncluded, - Number $priceTaxExcluded, - Order $order, - OrderDetail $orderDetail, - Address $taxAddress - ): Number { - $productOriginalPrice = $this->getProductRegularPrice($order, $orderDetail, $taxAddress); - - // If provided price is equal to catalog price no need to recompute - if ($productOriginalPrice->equals($priceTaxExcluded)) { - return $priceTaxExcluded; - } - - $productTaxCalculator = $this->getTaxCalculatorByAddress($taxAddress, $orderDetail); - $taxFactor = new Number((string) (1 + ($productTaxCalculator->getTotalRate() / 100))); - - $computedPriceTaxIncluded = $priceTaxExcluded->times($taxFactor); - if ($computedPriceTaxIncluded->equals($priceTaxIncluded)) { - return $priceTaxExcluded; - } - - // When price tax included is computed based on price tax excluded there is a difference - // so we recompute the price tax excluded based on the tax rate to have more precision - return $priceTaxIncluded->dividedBy($taxFactor); - } - - /** - * Since prices in input are sometimes rounded they don't precisely match, so in this case - * if the price is the same as the catalog we use price excluded as a base and recompute the - * price tax included with additional precision. - * - * @param Number $priceTaxIncluded - * @param Number $priceTaxExcluded - * @param Order $order - * @param OrderDetail $orderDetail - * @param Address $taxAddress - * - * @return Number - */ - private function getPrecisePriceTaxIncluded( - Number $priceTaxIncluded, - Number $priceTaxExcluded, - Order $order, - OrderDetail $orderDetail, - Address $taxAddress - ): Number { - $productOriginalPrice = $this->getProductRegularPrice($order, $orderDetail, $taxAddress); - - // If provided price is different from the catalog price we use the input price tax included as a base - if (!$productOriginalPrice->equals($priceTaxExcluded)) { - return $priceTaxIncluded; - } - - $productTaxCalculator = $this->getTaxCalculatorByAddress($taxAddress, $orderDetail); - $taxFactor = new Number((string) (1 + ($productTaxCalculator->getTotalRate() / 100))); - - return $priceTaxExcluded->times($taxFactor); - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param Address $taxAddress - * - * @return Number - */ - private function getProductRegularPrice( - Order $order, - OrderDetail $orderDetail, - Address $taxAddress - ): Number { - // Get price via getPriceStatic so that the catalog price rules are applied - - return new Number((string) Product::getPriceStatic( - (int) $orderDetail->product_id, - false, - (int) $orderDetail->product_attribute_id, - self::COMPARISON_PRECISION, - null, - false, - true, - 1, - false, - $order->id_customer, // We still use the customer ID in case this customer has some special prices - null, // But we keep the cart null as we don't want this order overridden price - $taxAddress->id - )); - } - - /** - * Get a TaxCalculator adapted for the OrderDetail's product and the specified address - * - * @param Address $address - * @param OrderDetail $orderDetail - * - * @return TaxCalculator - */ - private function getTaxCalculatorByAddress(Address $address, OrderDetail $orderDetail): TaxCalculator - { - $tax_manager = TaxManagerFactory::getManager($address, $orderDetail->getTaxRulesGroupId()); - - return $tax_manager->getTaxCalculator(); - } -} diff --git a/src/Adapter/Order/OrderPresenter.php b/src/Adapter/Order/OrderPresenter.php deleted file mode 100644 index fa555c42..00000000 --- a/src/Adapter/Order/OrderPresenter.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderPresenter - */ -class OrderPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderPresenter -{ -} diff --git a/src/Adapter/Order/OrderProductQuantityUpdater.php b/src/Adapter/Order/OrderProductQuantityUpdater.php deleted file mode 100644 index 674d8c91..00000000 --- a/src/Adapter/Order/OrderProductQuantityUpdater.php +++ /dev/null @@ -1,507 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use Cart; -use Configuration; -use Context; -use Currency; -use Customer; -use Customization; -use Db; -use Language; -use Order; -use OrderDetail; -use OrderInvoice; -use Pack; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductsComparator; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductUpdate; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Order\Refund\OrderProductRemover; -use PrestaShop\PrestaShop\Adapter\StockManager; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductOutOfStockException; -use Product; -use Shop; -use StockAvailable; -use StockManagerFactory; -use StockMvt; -use Warehouse; - -/** - * Increase or decrease quantity of an order's product. - * Recalculate cart rules, order's prices and shipping infos. - */ -class OrderProductQuantityUpdater -{ - /** - * @var OrderAmountUpdater - */ - private $orderAmountUpdater; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var OrderProductRemover - */ - private $orderProductRemover; - - public function __construct( - OrderAmountUpdater $orderAmountUpdater, - OrderProductRemover $orderProductRemover, - ContextStateManager $contextStateManager - ) { - $this->orderAmountUpdater = $orderAmountUpdater; - $this->orderProductRemover = $orderProductRemover; - $this->contextStateManager = $contextStateManager; - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param int $newQuantity - * @param OrderInvoice|null $orderInvoice - * @param bool $updateCart Used when you don't want to update the cart (CartRule removal for example) - * - * @return Order - * - * @throws OrderException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - public function update( - Order $order, - OrderDetail $orderDetail, - int $newQuantity, - ?OrderInvoice $orderInvoice, - bool $updateCart = true - ): Order { - $cart = new Cart($order->id_cart); - - $this->contextStateManager - ->saveCurrentContext() - ->setCart($cart) - ->setCurrency(new Currency($cart->id_currency)) - ->setCustomer(new Customer($cart->id_customer)) - ->setLanguage(new Language($cart->id_lang)) - ->setCountry($cart->getTaxCountry()) - ->setShop(new Shop($cart->id_shop)) - ; - - try { - $this->updateOrderDetail($order, $cart, $orderDetail, $newQuantity, $orderInvoice, $updateCart); - - // Update prices on the order after cart rules are recomputed - $this->orderAmountUpdater->update($order, $cart, null !== $orderInvoice ? (int) $orderInvoice->id : null); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - - return $order; - } - - /** - * @param Order $order - * @param Cart $cart - * @param OrderDetail $orderDetail - * @param int $newQuantity - * @param OrderInvoice|null $orderInvoice - * @param bool $updateCart - * - * @throws OrderException - * @throws ProductOutOfStockException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function updateOrderDetail( - Order $order, - Cart $cart, - OrderDetail $orderDetail, - int $newQuantity, - ?OrderInvoice $orderInvoice, - bool $updateCart - ): void { - $oldQuantity = (int) $orderDetail->product_quantity; - - // Perform deletion first, we don't want the OrderDetail to be saved with a quantity 0, this could lead to bugs - if (0 === $newQuantity) { - // Product deletion - $updatedProducts = $this->orderProductRemover->deleteProductFromOrder($order, $orderDetail, $updateCart); - $this->updateCustomizationOnProductDelete($order, $orderDetail, $oldQuantity); - $this->applyOtherProductUpdates($order, $cart, $orderInvoice, $updatedProducts); - } else { - $this->assertValidProductQuantity($orderDetail, $newQuantity); - // It's important to override the invoice, this is what allows to switch an OrderDetail from an invoice to another - if (null !== $orderInvoice) { - $orderDetail->id_order_invoice = $orderInvoice->id; - } - - $orderDetail->product_quantity = $newQuantity; - $orderDetail->reduction_percent = 0; - $orderDetail->update(); - - if ($orderDetail->id_customization > 0) { - $customization = new Customization($orderDetail->id_customization); - $customization->quantity = $newQuantity; - $customization->save(); - } - - // Update quantity on the cart and stock - if ($updateCart) { - $updatedProducts = $this->updateProductQuantity($cart, $orderDetail, $oldQuantity, $newQuantity); - $this->applyOtherProductUpdates($order, $cart, $orderInvoice, $updatedProducts); - } - } - - // Update product stocks - $this->updateStocks($cart, $orderDetail, $oldQuantity, $newQuantity); - } - - /** - * @param Order $order - * @param Cart $cart - * @param OrderInvoice|null $orderInvoice - * @param CartProductUpdate[] $updatedProducts - */ - private function applyOtherProductUpdates( - Order $order, - Cart $cart, - ?OrderInvoice $orderInvoice, - array $updatedProducts - ) { - // Some products have been affected by the removal of the initial product (probably related to a CartRule) - // So we detect the changes that happened in the cart and apply them on the OrderDetail - $orderDetails = $order->getOrderDetailList(); - foreach ($updatedProducts as $updatedProduct) { - $updatedCombinationId = $updatedProduct->getCombinationId() !== null ? $updatedProduct->getCombinationId()->getValue() : 0; - $updatedOrderDetail = null; - foreach ($orderDetails as $orderDetailData) { - if ((int) $orderDetailData['product_id'] === $updatedProduct->getProductId()->getValue() - && (int) $orderDetailData['product_attribute_id'] === $updatedCombinationId) { - $updatedOrderDetail = new OrderDetail($orderDetailData['id_order_detail']); - break; - } - } - - if (null !== $updatedOrderDetail) { - $newUpdatedQuantity = (int) $updatedOrderDetail->product_quantity + $updatedProduct->getDeltaQuantity(); - // Important: we update the OrderDetail but not the cart (it is already updated) to avoid infinite loop - $this->updateOrderDetail( - $order, - $cart, - $updatedOrderDetail, - $newUpdatedQuantity, - $orderInvoice, - false - ); - } - } - } - - /** - * @param Cart $cart - * @param OrderDetail $orderDetail - * @param int $oldQuantity - * @param int $newQuantity - * - * @return array - */ - private function updateProductQuantity( - Cart $cart, - OrderDetail $orderDetail, - int $oldQuantity, - int $newQuantity - ): array { - $deltaQuantity = $newQuantity - $oldQuantity; - - if (0 === $deltaQuantity) { - return []; - } - - $cartComparator = new CartProductsComparator($cart); - $knownUpdates = [ - new CartProductUpdate( - (int) $orderDetail->product_id, - (int) $orderDetail->product_attribute_id, - $deltaQuantity, - false - ), - ]; - - /** - * Here we update product and customization in the cart. - * - * The last argument "skip quantity check" is set to true because - * 1) the quantity has already been checked, - * 2) (main reason) when the cart checks the availability ; it substracts - * its own quantity from available stock. - * - * This is because a product in a cart is not really out of the stock, because it is not checked out yet. - * - * Here we are editing an order, not a cart, so what has been ordered - * has already been substracted from the stock. - */ - $updateQuantityResult = $cart->updateQty( - abs($deltaQuantity), - $orderDetail->product_id, - $orderDetail->product_attribute_id, - false, - $deltaQuantity < 0 ? 'down' : 'up', - 0, - new Shop($cart->id_shop), - true, - true - ); - - if (-1 === $updateQuantityResult) { - throw new \LogicException('Minimum quantity is not respected'); - } elseif (true !== $updateQuantityResult) { - throw new \LogicException('Something went wrong'); - } - - return $cartComparator->getUpdatedProducts($knownUpdates); - } - - /** - * @param Cart $cart - * @param OrderDetail $orderDetail - * @param int $oldQuantity - * @param int $newQuantity - * - * @throws OrderException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function updateStocks(Cart $cart, OrderDetail $orderDetail, int $oldQuantity, int $newQuantity): void - { - $deltaQuantity = $oldQuantity - $newQuantity; - - if (0 === $deltaQuantity) { - return; - } - - if (0 === $newQuantity) { - // Product deletion. Reinject quantity in stock - $this->reinjectQuantity($orderDetail, $oldQuantity, $newQuantity, true); - } elseif ($deltaQuantity > 0) { - // Increase product quantity - StockAvailable::updateQuantity( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - $deltaQuantity, - $cart->id_shop, - true, - [ - 'id_order' => $orderDetail->id_order, - 'id_stock_mvt_reason' => Configuration::get('PS_STOCK_CUSTOMER_RETURN_REASON'), - ] - ); - } else { - // Decrease product quantity. Reinject quantity in stock - $this->reinjectQuantity($orderDetail, $oldQuantity, $newQuantity, false); - } - } - - /** - * @param OrderDetail $orderDetail - * @param int $oldQuantity - * @param int $newQuantity - * @param bool $delete - * - * @throws OrderException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - protected function reinjectQuantity( - OrderDetail $orderDetail, - int $oldQuantity, - int $newQuantity, - $delete = false - ) { - // Reinject product - $reinjectableQuantity = $oldQuantity - $newQuantity; - $quantityToReinject = $oldQuantity > $reinjectableQuantity ? $reinjectableQuantity : $oldQuantity; - - $product = new Product( - $orderDetail->product_id, - false, - (int) Context::getContext()->language->id, - (int) $orderDetail->id_shop - ); - - if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') - && $product->advanced_stock_management - && $orderDetail->id_warehouse != 0 - ) { - $manager = StockManagerFactory::getManager(); - $movements = StockMvt::getNegativeStockMvts( - $orderDetail->id_order, - $orderDetail->product_id, - $orderDetail->product_attribute_id, - $quantityToReinject - ); - - foreach ($movements as $movement) { - if ($quantityToReinject > $movement['physical_quantity']) { - $quantityToReinject = $movement['physical_quantity']; - } - - if (Pack::isPack((int) $product->id)) { - // Gets items - if ($product->pack_stock_type == Pack::STOCK_TYPE_PRODUCTS_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ($product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && Configuration::get('PS_PACK_STOCK_TYPE') > 0) - ) { - $products_pack = Pack::getItems((int) $product->id, (int) Configuration::get('PS_LANG_DEFAULT')); - // Foreach item - foreach ($products_pack as $product_pack) { - if ($product_pack->advanced_stock_management == 1) { - $manager->addProduct( - $product_pack->id, - $product_pack->id_pack_product_attribute, - new Warehouse($movement['id_warehouse']), - $product_pack->pack_quantity * $quantityToReinject, - null, - $movement['price_te'] - ); - } - } - } - - if ($product->pack_stock_type == Pack::STOCK_TYPE_PACK_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ( - $product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && (Configuration::get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_ONLY - || Configuration::get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_BOTH) - ) - ) { - $manager->addProduct( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - new Warehouse($movement['id_warehouse']), - $quantityToReinject, - null, - $movement['price_te'] - ); - } - } else { - $manager->addProduct( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - new Warehouse($movement['id_warehouse']), - $quantityToReinject, - null, - $movement['price_te'] - ); - } - } - - $productId = $orderDetail->product_id; - - if ($delete) { - $orderDetail->delete(); - } - - StockAvailable::synchronize($productId); - } elseif ($orderDetail->id_warehouse == 0) { - StockAvailable::updateQuantity( - $orderDetail->product_id, - $orderDetail->product_attribute_id, - $quantityToReinject, - $orderDetail->id_shop, - true, - [ - 'id_order' => $orderDetail->id_order, - 'id_stock_mvt_reason' => Configuration::get('PS_STOCK_CUSTOMER_RETURN_REASON'), - ] - ); - - // sync all stock - (new StockManager())->updatePhysicalProductQuantity( - (int) $orderDetail->id_shop, - (int) Configuration::get('PS_OS_ERROR'), - (int) Configuration::get('PS_OS_CANCELED'), - null, - (int) $orderDetail->id_order - ); - - if ($delete) { - $orderDetail->delete(); - } - } else { - throw new OrderException('This product cannot be re-stocked.'); - } - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param int $oldQuantity - * - * @throws OrderException - */ - private function updateCustomizationOnProductDelete(Order $order, OrderDetail $orderDetail, int $oldQuantity): void - { - if (!(int) $order->getCurrentState()) { - throw new OrderException('Could not get a valid Order state before deletion'); - } - - if ($order->hasBeenPaid()) { - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'customization` SET `quantity_refunded` = `quantity_refunded` + ' . (int) $oldQuantity . ' WHERE `id_customization` = ' . (int) $orderDetail->id_customization . ' AND `id_cart` = ' . (int) $order->id_cart . ' AND `id_product` = ' . (int) $orderDetail->product_id); - } - - if (!Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization` WHERE `quantity` = 0')) { - throw new OrderException('Could not delete customization from database.'); - } - } - - /** - * @param OrderDetail $orderDetail - * @param int $newQuantity - * - * @throws ProductOutOfStockException - */ - private function assertValidProductQuantity(OrderDetail $orderDetail, int $newQuantity) - { - //check if product is available in stock - if (!Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($orderDetail->product_id))) { - $availableQuantity = StockAvailable::getQuantityAvailableByProduct($orderDetail->product_id, $orderDetail->product_attribute_id); - $quantityDiff = $newQuantity - (int) $orderDetail->product_quantity; - - if ($quantityDiff > $availableQuantity) { - throw new ProductOutOfStockException('Not enough products in stock'); - } - } - } -} diff --git a/src/Adapter/Order/OrderReturnPresenter.php b/src/Adapter/Order/OrderReturnPresenter.php deleted file mode 100644 index 46dacd75..00000000 --- a/src/Adapter/Order/OrderReturnPresenter.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderReturnPresenter - */ -class OrderReturnPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderReturnPresenter -{ -} diff --git a/src/Adapter/Order/OrderSiblingProvider.php b/src/Adapter/Order/OrderSiblingProvider.php deleted file mode 100644 index 7f95fbdc..00000000 --- a/src/Adapter/Order/OrderSiblingProvider.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order; - -use Order; -use PrestaShop\PrestaShop\Core\Order\OrderSiblingProviderInterface; - -class OrderSiblingProvider implements OrderSiblingProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getNextOrderId(int $orderId): int - { - $order = new Order($orderId); - - return (int) $order->getNextOrderId(); - } - - /** - * {@inheritdoc} - */ - public function getPreviousOrderId(int $orderId): int - { - $order = new Order($orderId); - - return (int) $order->getPreviousOrderId(); - } -} diff --git a/src/Adapter/Order/QueryHandler/GetOrderForViewingHandler.php b/src/Adapter/Order/QueryHandler/GetOrderForViewingHandler.php deleted file mode 100644 index f35b2b14..00000000 --- a/src/Adapter/Order/QueryHandler/GetOrderForViewingHandler.php +++ /dev/null @@ -1,808 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\QueryHandler; - -use Address; -use Carrier; -use Configuration; -use ConnectionsSource; -use Context; -use Country; -use Currency; -use Customer; -use DateTimeImmutable; -use Gender; -use Module; -use Order; -use OrderInvoice; -use OrderPayment; -use OrderSlip; -use OrderState; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Exception\InvalidSortingException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderDocumentType; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderProductsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler\GetOrderForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler\GetOrderProductsForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\LinkedOrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\LinkedOrdersForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderCarrierForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderCustomerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderDiscountForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderDiscountsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderDocumentForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderDocumentsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderHistoryForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderInvoiceAddressForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderMessageDateForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderMessageForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderMessagesForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPaymentForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPaymentsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPricesForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderReturnForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderReturnsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderShippingAddressForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderShippingForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderSourceForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderSourcesForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderStatusForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use State; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * Handle getting order for viewing - * - * @internal - */ -final class GetOrderForViewingHandler extends AbstractOrderHandler implements GetOrderForViewingHandlerInterface -{ - /** - * @var Locale - */ - private $locale; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var CustomerDataProvider - */ - private $customerDataProvider; - - /** - * @var Context - */ - private $context; - - /** - * @var GetOrderProductsForViewingHandlerInterface - */ - private $getOrderProductsForViewingHandler; - - /** - * @param ImageTagSourceParserInterface $imageTagSourceParser - * @param TranslatorInterface $translator - * @param int $contextLanguageId - * @param Locale $locale - * @param Context $context - * @param CustomerDataProvider $customerDataProvider - * @param GetOrderProductsForViewingHandlerInterface $getOrderProductsForViewingHandler - */ - public function __construct( - TranslatorInterface $translator, - int $contextLanguageId, - Locale $locale, - Context $context, - CustomerDataProvider $customerDataProvider, - GetOrderProductsForViewingHandlerInterface $getOrderProductsForViewingHandler - ) { - $this->translator = $translator; - $this->contextLanguageId = $contextLanguageId; - $this->locale = $locale; - $this->translator = $translator; - $this->context = $context; - $this->customerDataProvider = $customerDataProvider; - $this->getOrderProductsForViewingHandler = $getOrderProductsForViewingHandler; - } - - /** - * {@inheritdoc} - */ - public function handle(GetOrderForViewing $query): OrderForViewing - { - $order = $this->getOrder($query->getOrderId()); - $orderCarrier = new Carrier($order->id_carrier); - $taxCalculationMethod = $this->getOrderTaxCalculationMethod($order); - - $isTaxIncluded = ($taxCalculationMethod == PS_TAX_INC); - - $taxMethod = $isTaxIncluded ? - $this->translator->trans('Tax included', [], 'Admin.Global') : - $this->translator->trans('Tax excluded', [], 'Admin.Global'); - - $invoiceManagementIsEnabled = (bool) Configuration::get('PS_INVOICE', null, null, $order->id_shop); - - return new OrderForViewing( - (int) $order->id, - (int) $order->id_currency, - (int) $order->id_carrier, - (string) $orderCarrier->name, - (int) $order->id_shop, - $order->reference, - (bool) $order->isVirtual(), - $taxMethod, - $isTaxIncluded, - (bool) $order->valid, - $order->hasBeenPaid(), - $order->hasInvoice(), - $order->hasBeenDelivered(), - $order->hasBeenShipped(), - $invoiceManagementIsEnabled, - new DateTimeImmutable($order->date_add), - $this->getOrderCustomer($order), - $this->getOrderShippingAddress($order), - $this->getOrderInvoiceAddress($order), - $this->getOrderProducts($query->getOrderId(), $query->getProductsSorting()->getValue()), - $this->getOrderHistory($order), - $this->getOrderDocuments($order), - $this->getOrderShipping($order), - $this->getOrderReturns($order), - $this->getOrderPayments($order), - $this->getOrderMessages($order), - $this->getOrderPrices($order), - $this->getOrderDiscounts($order), - $this->getOrderSources($order), - $this->getLinkedOrders($order) - ); - } - - /** - * @param Order $order - * - * @return OrderCustomerForViewing|null - */ - private function getOrderCustomer(Order $order): ?OrderCustomerForViewing - { - $currency = new Currency($order->id_currency); - $customer = new Customer($order->id_customer); - - if (!Validate::isLoadedObject($customer)) { - return null; - } - - $gender = new Gender($customer->id_gender); - $genderName = ''; - - if (Validate::isLoadedObject($gender)) { - $genderName = $gender->name[$order->id_lang]; - } - - $customerStats = $customer->getStats(); - $totalSpentSinceRegistration = Tools::convertPrice($customerStats['total_orders'], $order->id_currency); - - return new OrderCustomerForViewing( - $customer->id, - $customer->firstname, - $customer->lastname, - $genderName, - $customer->email, - new DateTimeImmutable($customer->date_add), - $totalSpentSinceRegistration !== null ? $this->locale->formatPrice($totalSpentSinceRegistration, $currency->iso_code) : '', - $customerStats['nb_orders'], - $customer->note, - (bool) $customer->is_guest - ); - } - - /** - * @param Order $order - * - * @return OrderShippingAddressForViewing - */ - public function getOrderShippingAddress(Order $order): OrderShippingAddressForViewing - { - $address = new Address($order->id_address_delivery); - $country = new Country($address->id_country); - $stateName = ''; - - if ($address->id_state) { - $state = new State($address->id_state); - - $stateName = $state->name; - } - - return new OrderShippingAddressForViewing( - $address->id, - $address->firstname, - $address->lastname, - $address->company, - $address->address1, - $address->address2, - $stateName, - $address->city, - $country->name[$order->id_lang], - $address->postcode, - $address->phone, - $address->phone_mobile - ); - } - - /** - * @param Order $order - * - * @return OrderInvoiceAddressForViewing - */ - private function getOrderInvoiceAddress(Order $order): OrderInvoiceAddressForViewing - { - $address = new Address($order->id_address_invoice); - $country = new Country($address->id_country); - $stateName = ''; - - if ($address->id_state) { - $state = new State($address->id_state); - - $stateName = $state->name; - } - - return new OrderInvoiceAddressForViewing( - $address->id, - $address->firstname, - $address->lastname, - $address->company, - $address->address1, - $address->address2, - $stateName, - $address->city, - $country->name[$order->id_lang], - $address->postcode, - $address->phone, - $address->phone_mobile - ); - } - - /** - * @param Order $order - * - * @return OrderHistoryForViewing - */ - private function getOrderHistory(Order $order): OrderHistoryForViewing - { - $history = $order->getHistory($this->contextLanguageId); - - $statuses = []; - - foreach ($history as $item) { - $statuses[] = new OrderStatusForViewing( - (int) $item['id_order_history'], - (int) $item['id_order_state'], - $item['ostate_name'], - $item['color'], - new DateTimeImmutable($item['date_add']), - (bool) $item['send_email'], - $item['employee_firstname'], - $item['employee_lastname'] - ); - } - - return new OrderHistoryForViewing( - $order->current_state, - $statuses - ); - } - - /** - * @param Order $order - * - * @return OrderDocumentsForViewing - * - * @throws LocalizationException - */ - private function getOrderDocuments(Order $order): OrderDocumentsForViewing - { - $currency = new Currency($order->id_currency); - $documents = $order->getDocuments(); - - $documentsForViewing = []; - - /** @var OrderInvoice|OrderSlip $document */ - foreach ($documents as $document) { - $type = null; - $number = null; - $amount = null; - $numericAmount = null; - $amountMismatch = null; - $availableAction = null; - $isAddPaymentAllowed = false; - - if ($document instanceof OrderInvoice) { - $type = isset($document->is_delivery) ? OrderDocumentType::DELIVERY_SLIP : OrderDocumentType::INVOICE; - } elseif ($document instanceof OrderSlip) { - $type = OrderDocumentType::CREDIT_SLIP; - } - - if (OrderDocumentType::INVOICE === $type) { - $number = $document->getInvoiceNumberFormatted( - $this->contextLanguageId, - $order->id_shop - ); - - if ($document->getRestPaid()) { - $isAddPaymentAllowed = true; - } - $amount = $this->locale->formatPrice($document->total_paid_tax_incl, $currency->iso_code); - $numericAmount = $document->total_paid_tax_incl; - - if ($document->getTotalPaid()) { - if ($document->getRestPaid() > 0) { - $amountMismatch = sprintf( - '%s %s', - $this->locale->formatPrice($document->getRestPaid(), $currency->iso_code), - $this->translator->trans('not paid', [], 'Admin.Orderscustomers.Feature') - ); - } elseif ($document->getRestPaid() < 0) { - $amountMismatch = sprintf( - '%s %s', - $this->locale->formatPrice($document->getRestPaid(), $currency->iso_code), - $this->translator->trans('overpaid', [], 'Admin.Orderscustomers.Feature') - ); - } - } - } elseif (OrderDocumentType::DELIVERY_SLIP === $type) { - $number = sprintf( - '%s%06d', - Configuration::get('PS_DELIVERY_PREFIX', $this->contextLanguageId, null, $order->id_shop), - $document->delivery_number - ); - $amount = $this->locale->formatPrice( - $document->total_shipping_tax_incl, - $currency->iso_code - ); - $numericAmount = $document->total_shipping_tax_incl; - } elseif (OrderDocumentType::CREDIT_SLIP) { - $number = sprintf( - '%s%06d', - Configuration::get('PS_CREDIT_SLIP_PREFIX', $this->contextLanguageId), - $document->id - ); - $amount = $this->locale->formatPrice( - $document->total_products_tax_incl + $document->total_shipping_tax_incl, - $currency->iso_code - ); - $numericAmount = $document->total_products_tax_incl + $document->total_shipping_tax_incl; - } - - $documentsForViewing[] = new OrderDocumentForViewing( - $document->id, - $type, - new DateTimeImmutable($document->date_add), - $number, - $numericAmount, - $amount, - $amountMismatch, - $document instanceof OrderInvoice ? $document->note : null, - $isAddPaymentAllowed - ); - } - - $canGenerateInvoice = Configuration::get('PS_INVOICE') && - count($order->getInvoicesCollection()) && - $order->invoice_number; - - $canGenerateDeliverySlip = (bool) $order->delivery_number; - - return new OrderDocumentsForViewing( - $canGenerateInvoice, - $canGenerateDeliverySlip, - $documentsForViewing - ); - } - - /** - * @param Order $order - * - * @return OrderShippingForViewing - * - * @throws LocalizationException - */ - private function getOrderShipping(Order $order): OrderShippingForViewing - { - $taxCalculationMethod = $this->getOrderTaxCalculationMethod($order); - - $shipping = $order->getShipping(); - $carriers = []; - $carrierModuleInfo = null; - - $currency = new Currency($order->id_currency); - $carrier = new Carrier($order->id_carrier); - $carrierModuleInfo = null; - - if ($carrier->is_module) { - $module = Module::getInstanceByName($carrier->external_module_name); - if (method_exists($module, 'displayInfoByCart')) { - $carrierModuleInfo = $module->displayInfoByCart($order->id_cart); - } - } - - if (!$order->isVirtual()) { - foreach ($shipping as $item) { - if ($taxCalculationMethod == PS_TAX_INC) { - $price = Tools::displayPrice($item['shipping_cost_tax_incl'], $currency); - } else { - $price = Tools::displayPrice($item['shipping_cost_tax_excl'], $currency); - } - - $trackingUrl = null; - $trackingNumber = $item['tracking_number']; - - if ($item['url'] && $item['tracking_number']) { - $trackingUrl = str_replace('@', $item['tracking_number'], $item['url']); - } - - $weight = sprintf('%.3f %s', $item['weight'], Configuration::get('PS_WEIGHT_UNIT')); - - $carriers[] = new OrderCarrierForViewing( - (int) $item['id_order_carrier'], - new DateTimeImmutable($item['date_add']), - $item['carrier_name'], - $weight, - (int) $item['id_carrier'], - $price, - $trackingUrl, - $trackingNumber, - $item['can_edit'] - ); - } - } - - return new OrderShippingForViewing( - $carriers, - (bool) $order->recyclable, - (bool) $order->gift, - $order->gift_message, - $carrierModuleInfo - ); - } - - /** - * @param Order $order - * - * @return OrderReturnsForViewing - */ - private function getOrderReturns(Order $order): OrderReturnsForViewing - { - $returns = $order->getReturn(); - - if ($order->isVirtual()) { - return new OrderReturnsForViewing(); - } - - $orderReturns = []; - - foreach ($returns as $orderReturn) { - $trackingUrl = null; - $trackingNumber = null; - - if (isset($orderReturn['url'], $orderReturn['tracking_number'])) { - $trackingUrl = $orderReturn['url']; - $trackingNumber = $orderReturn['tracking_number']; - } elseif (isset($orderReturn['tracking_number'])) { - $trackingNumber = $orderReturn['tracking_number']; - } - - $orderReturns[] = new OrderReturnForViewing( - (int) $orderReturn['id_order_return'], - isset($orderReturn['id_order_invoice']) ? (int) $orderReturn['id_order_invoice'] : 0, - isset($orderReturn['id_carrier']) ? (int) $orderReturn['id_carrier'] : 0, - new DateTimeImmutable($orderReturn['date_add']), - $orderReturn['type'], - $orderReturn['state_name'], - $trackingUrl, - $trackingNumber - ); - } - - return new OrderReturnsForViewing($orderReturns); - } - - /** - * @param Order $order - * - * @return OrderPaymentsForViewing - * - * @throws LocalizationException - */ - private function getOrderPayments(Order $order): OrderPaymentsForViewing - { - $currency = new Currency($order->id_currency); - $payments = $order->getOrderPayments(); - - $currentState = $order->getCurrentOrderState(); - - $orderAmountToPay = null; - $orderAmountPaid = null; - $paymentMismatchOrders = []; - - if (count($payments) > 0) { - $noPaymentMismatch = round($order->getOrdersTotalPaid(), 2) == round($order->getTotalPaid(), 2) - || ($currentState && $currentState->id == 6); - - if (!$noPaymentMismatch) { - $orderAmountToPay = $this->locale->formatPrice($order->getOrdersTotalPaid(), $currency->iso_code); - $orderAmountPaid = $this->locale->formatPrice($order->getTotalPaid(), $currency->iso_code); - - foreach ($order->getBrother() as $relatedOrder) { - $paymentMismatchOrders[] = $relatedOrder->id; - } - } - } - - $orderPayments = []; - - /** @var OrderPayment $payment */ - foreach ($order->getOrderPaymentCollection() as $payment) { - $currency = new Currency($payment->id_currency); - $invoice = $payment->getOrderInvoice($order->id); - $invoiceNumber = $invoice ? - $invoice->getInvoiceNumberFormatted($this->contextLanguageId, $order->id_shop) : - null; - - $orderPayments[] = new OrderPaymentForViewing( - $payment->id, - new DateTimeImmutable($payment->date_add), - $payment->payment_method, - $payment->transaction_id, - $this->locale->formatPrice($payment->amount, $currency->iso_code), - $invoiceNumber, - $payment->card_number, - $payment->card_brand, - $payment->card_expiration, - $payment->card_holder - ); - } - - return new OrderPaymentsForViewing( - $orderPayments, - $orderAmountToPay, - $orderAmountPaid, - $paymentMismatchOrders - ); - } - - /** - * @param Order $order - * - * @return OrderMessagesForViewing - */ - private function getOrderMessages(Order $order): OrderMessagesForViewing - { - $orderMessagesForOrderPage = $this->customerDataProvider->getCustomerMessages( - (int) $order->id_customer, - (int) $order->id - ); - - $messages = []; - - foreach ($orderMessagesForOrderPage['messages'] as $orderMessage) { - $messageEmployeeId = (int) $orderMessage['id_employee']; - $isCurrentEmployeesMessage = (int) $this->context->employee->id === $messageEmployeeId; - - $messages[] = new OrderMessageForViewing( - (int) $orderMessage['id_customer_message'], - $orderMessage['message'], - new OrderMessageDateForViewing( - new DateTimeImmutable($orderMessage['date_add']), - $this->context->language->date_format_full - ), - $messageEmployeeId, - $isCurrentEmployeesMessage, - $orderMessage['efirstname'], - $orderMessage['elastname'], - $orderMessage['cfirstname'], - $orderMessage['clastname'], - (bool) $orderMessage['private'] - ); - } - - return new OrderMessagesForViewing($messages, $orderMessagesForOrderPage['total']); - } - - /** - * @param Order $order - * - * @return OrderPricesForViewing - * - * @throws LocalizationException - */ - private function getOrderPrices(Order $order): OrderPricesForViewing - { - $currency = new Currency($order->id_currency); - $customer = $order->getCustomer(); - - $isTaxExcluded = !$this->isTaxIncludedInOrder($order); - - $shipping_refundable_tax_excl = $order->total_shipping_tax_excl; - $shipping_refundable_tax_incl = $order->total_shipping_tax_incl; - - $slips = OrderSlip::getOrdersSlip($customer->id, $order->id); - foreach ($slips as $slip) { - $shipping_refundable_tax_excl -= $slip['total_shipping_tax_excl']; - $shipping_refundable_tax_incl -= $slip['total_shipping_tax_incl']; - } - - if ($isTaxExcluded) { - $productsPrice = (float) $order->total_products; - $discountsAmount = (float) $order->total_discounts_tax_excl; - $wrappingPrice = (float) $order->total_wrapping_tax_excl; - $shippingPrice = (float) $order->total_shipping_tax_excl; - $shippingRefundable = max(0, $shipping_refundable_tax_excl); - $totalAmount = (float) $order->total_paid_tax_excl; - } else { - $productsPrice = (float) $order->total_products_wt; - $discountsAmount = (float) $order->total_discounts_tax_incl; - $wrappingPrice = (float) $order->total_wrapping_tax_incl; - $shippingPrice = (float) $order->total_shipping_tax_incl; - $shippingRefundable = max(0, $shipping_refundable_tax_incl); - $totalAmount = (float) $order->total_paid_tax_incl; - } - - $taxesAmount = $order->total_paid_tax_incl - $order->total_paid_tax_excl; - - return new OrderPricesForViewing( - new Number((string) $productsPrice), - new Number((string) $discountsAmount), - new Number((string) $wrappingPrice), - new Number((string) $shippingPrice), - new Number((string) $shippingRefundable), - new Number((string) $taxesAmount), - new Number((string) $totalAmount), - Tools::displayPrice($productsPrice, $currency), - Tools::displayPrice($discountsAmount, $currency), - Tools::displayPrice($wrappingPrice, $currency), - Tools::displayPrice($shippingPrice, $currency), - Tools::displayPrice($shippingRefundable, $currency), - Tools::displayPrice($taxesAmount, $currency), - Tools::displayPrice($totalAmount, $currency) - ); - } - - /** - * @param Order $order - * - * @return OrderDiscountsForViewing - * - * @throws LocalizationException - */ - private function getOrderDiscounts(Order $order): OrderDiscountsForViewing - { - $isTaxIncluded = $this->isTaxIncludedInOrder($order); - $currency = new Currency($order->id_currency); - $discounts = $order->getCartRules(); - $discountsForViewing = []; - - foreach ($discounts as $discount) { - $discountAmount = $isTaxIncluded ? $discount['value'] : $discount['value_tax_excl']; - $discountsForViewing[] = new OrderDiscountForViewing( - (int) $discount['id_order_cart_rule'], - $discount['name'], - new Number((string) $discountAmount), - Tools::displayPrice($discountAmount, $currency) - ); - } - - return new OrderDiscountsForViewing($discountsForViewing); - } - - /** - * @param Order $order - * - * @return OrderSourcesForViewing - */ - private function getOrderSources(Order $order): OrderSourcesForViewing - { - $sourcesData = ConnectionsSource::getOrderSources($order->id); - $sources = []; - - if ( $sourcesData ) - foreach ($sourcesData as $sourceItem) { - $sources[] = new OrderSourceForViewing( - $sourceItem['http_referer'], - $sourceItem['request_uri'], - new DateTimeImmutable($sourceItem['date_add']), - $sourceItem['keywords'] - ); - } - - return new OrderSourcesForViewing($sources); - } - - /** - * @return LinkedOrdersForViewing - */ - private function getLinkedOrders(Order $order): LinkedOrdersForViewing - { - $brothersData = $order->getBrother(); - $brothers = []; - /** @var Order $brotherItem */ - foreach ($brothersData as $brotherItem) { - $isTaxExcluded = !$this->isTaxIncludedInOrder($brotherItem); - - $currency = new Currency($brotherItem->id_currency); - - if ($isTaxExcluded) { - $totalAmount = $this->locale->formatPrice($brotherItem->total_paid_tax_excl, $currency->iso_code); - } else { - $totalAmount = $this->locale->formatPrice($brotherItem->total_paid_tax_incl, $currency->iso_code); - } - - $orderState = new OrderState($brotherItem->current_state); - - $brothers[] = new LinkedOrderForViewing( - $brotherItem->id, - $orderState->name[$this->context->language->getId()], - $totalAmount - ); - } - - return new LinkedOrdersForViewing($brothers); - } - - /** - * @param OrderId $orderId - * @param string $productsOrder - * - * @return OrderProductsForViewing - * - * @throws OrderException - * @throws InvalidSortingException - */ - private function getOrderProducts(OrderId $orderId, string $productsOrder): OrderProductsForViewing - { - return $this->getOrderProductsForViewingHandler->handle( - GetOrderProductsForViewing::all($orderId->getValue(), $productsOrder) - ); - } -} diff --git a/src/Adapter/Order/QueryHandler/GetOrderPreviewHandler.php b/src/Adapter/Order/QueryHandler/GetOrderPreviewHandler.php deleted file mode 100644 index 5569e3bb..00000000 --- a/src/Adapter/Order/QueryHandler/GetOrderPreviewHandler.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\QueryHandler; - -use Carrier; -use Country; -use Currency; -use Customer; -use Group; -use Order; -use OrderCarrier; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\Entity\Address; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderPreview; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler\GetOrderPreviewHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPreview; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPreviewInvoiceDetails; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPreviewProductDetail; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPreviewShippingDetails; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Localization\Locale\Repository as LocaleRepository; -use State; -use StockAvailable; -use Validate; - -/** - * Handles GetOrderPreview query using legacy object model - */ -final class GetOrderPreviewHandler implements GetOrderPreviewHandlerInterface -{ - /** - * @var LocaleRepository - */ - private $localeRepository; - - /** - * @var string - */ - private $locale; - - /** - * @param LocaleRepository $localeRepository - * @param string $locale - */ - public function __construct( - LocaleRepository $localeRepository, - string $locale - ) { - $this->localeRepository = $localeRepository; - $this->locale = $locale; - } - - /** - * {@inheritdoc} - */ - public function handle(GetOrderPreview $query): OrderPreview - { - $order = $this->getOrder($query->getOrderId()); - $priceDisplayMethod = $this->getOrderTaxCalculationMethod($order); - - return new OrderPreview( - $this->getInvoiceDetails($order), - $this->getShippingDetails($order), - $this->getProductDetails($order), - $order->isVirtual(), - $priceDisplayMethod == PS_TAX_INC - ); - } - - /** - * @param OrderId $orderId - * - * @return Order - * - * @throws OrderNotFoundException - */ - private function getOrder(OrderId $orderId): Order - { - $order = new Order($orderId->getValue()); - if ($order->id !== $orderId->getValue()) { - throw new OrderNotFoundException($orderId, sprintf('Order with id "%s" was not found.', $orderId->getValue())); - } - - return $order; - } - - /** - * @param Order $order - * - * @return OrderPreviewInvoiceDetails - */ - private function getInvoiceDetails(Order $order): OrderPreviewInvoiceDetails - { - $customer = new Customer($order->id_customer); - $address = new Address($order->id_address_invoice); - $country = new Country($address->id_country); - $state = new State($address->id_state); - $stateName = Validate::isLoadedObject($state) ? $state->name : null; - - return new OrderPreviewInvoiceDetails( - $address->firstname, - $address->lastname, - $address->company, - $address->vat_number, - $address->address1, - $address->address2, - $address->city, - $address->postcode, - $stateName, - $country->name[$order->id_lang], - $customer ? $customer->email : null, - $address->phone - ); - } - - /** - * {@inheritdoc} - */ - private function getShippingDetails(Order $order): OrderPreviewShippingDetails - { - $address = new Address($order->id_address_delivery); - $country = new Country($address->id_country); - $carrier = new Carrier($order->id_carrier); - $state = new State($address->id_state); - - $carrierName = null; - $stateName = Validate::isLoadedObject($state) ? $state->name : null; - - if (Validate::isLoadedObject($carrier)) { - $carrierName = $carrier->name; - } - - $orderCarrierId = $order->getIdOrderCarrier(); - $orderCarrier = new OrderCarrier($orderCarrierId); - - return new OrderPreviewShippingDetails( - $address->firstname, - $address->lastname, - $address->company, - $address->vat_number, - $address->address1, - $address->address2, - $address->city, - $address->postcode, - $stateName, - $country->name[$order->id_lang], - $address->phone, - $carrierName, - $orderCarrier->tracking_number ?: null - ); - } - - /** - * @param Order $order - * - * @return OrderPreviewProductDetail[] - */ - private function getProductDetails(Order $order): array - { - $productDetails = []; - $currency = new Currency($order->id_currency); - $locale = $this->localeRepository->getLocale($this->locale); - - $taxCalculationMethod = $this->getOrderTaxCalculationMethod($order); - - foreach ($order->getProductsDetail() as $detail) { - $unitPrice = $detail['unit_price_tax_excl']; - $totalPrice = $detail['total_price_tax_excl']; - - $totalPriceTaxIncl = new Number($detail['total_price_tax_incl']); - $totalPriceTaxExcl = new Number($detail['total_price_tax_excl']); - - $totalTaxAmount = $totalPriceTaxIncl->minus($totalPriceTaxExcl); - - if (PS_TAX_INC === $taxCalculationMethod) { - $unitPrice = $detail['unit_price_tax_incl']; - $totalPrice = $detail['total_price_tax_incl']; - } - - $productDetails[] = new OrderPreviewProductDetail( - $detail['product_name'], - $detail['product_reference'], - StockAvailable::getLocation( - $detail['product_id'], - $detail['product_attribute_id'], - $detail['id_shop'] - ), - (int) $detail['product_quantity'], - $locale->formatPrice($unitPrice, $currency->iso_code), - $locale->formatPrice($totalPrice, $currency->iso_code), - $locale->formatPrice((string) $totalTaxAmount, $currency->iso_code) - ); - } - - return $productDetails; - } - - /** - * @param Order $order - * - * @return int - */ - private function getOrderTaxCalculationMethod(Order $order): int - { - $customer = new Customer($order->id_customer); - - return Group::getPriceDisplayMethod((int) $customer->id_default_group); - } -} diff --git a/src/Adapter/Order/QueryHandler/GetOrderProductsForViewingHandler.php b/src/Adapter/Order/QueryHandler/GetOrderProductsForViewingHandler.php deleted file mode 100644 index 1a7d4a1c..00000000 --- a/src/Adapter/Order/QueryHandler/GetOrderProductsForViewingHandler.php +++ /dev/null @@ -1,317 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\QueryHandler; - -use Currency; -use Db; -use Image; -use ImageManager; -use Order; -use OrderInvoice; -use OrderReturn; -use OrderSlip; -use Pack; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderProductsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler\GetOrderProductsForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductCustomizationForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductCustomizationsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductsForViewing; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\QuerySorting; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use Product; -use Shop; -use StockAvailable; -use Warehouse; -use WarehouseProductLocation; - -/** - * Handles GetOrderProductsForViewing query using legacy object models - */ -final class GetOrderProductsForViewingHandler extends AbstractOrderHandler implements GetOrderProductsForViewingHandlerInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var Locale - */ - private $locale; - - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser, - int $contextLanguageId, - Locale $locale - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - $this->contextLanguageId = $contextLanguageId; - $this->locale = $locale; - } - - public function handle(GetOrderProductsForViewing $query): OrderProductsForViewing - { - $order = $this->getOrder($query->getOrderId()); - $taxCalculationMethod = $this->getOrderTaxCalculationMethod($order); - - $products = $order->getProducts(); - $currency = new Currency((int) $order->id_currency); - $computingPrecision = new ComputingPrecision(); - $precision = $computingPrecision->getPrecision($currency->precision); - - foreach ($products as &$product) { - if ($product['image'] instanceof Image) { - $name = 'product_mini_' . (int) $product['product_id'] . (isset($product['product_attribute_id']) ? '_' . (int) $product['product_attribute_id'] : '') . '.jpg'; - // generate image cache, only for back office - $product['image_tag'] = ImageManager::thumbnail(_PS_IMG_DIR_ . 'p/' . $product['image']->getExistingImgPath() . '.jpg', $name, 45, 'jpg'); - if (file_exists(_PS_TMP_IMG_DIR_ . $name)) { - $product['image_size'] = getimagesize(_PS_TMP_IMG_DIR_ . $name); - } else { - $product['image_size'] = false; - } - } - - // Get total customized quantity for current product - $customized_product_quantity = 0; - - $customizations = []; - if (is_array($product['customizedDatas'])) { - foreach ($product['customizedDatas'] as $customizationPerAddress) { - foreach ($customizationPerAddress as $customizationId => $customization) { - $customized_product_quantity += (int) $customization['quantity']; - foreach ($customization['datas'] as $datas) { - foreach ($datas as $data) { - $customizations[] = new OrderProductCustomizationForViewing((int) $data['type'], $data['name'], $data['value']); - } - } - } - } - } - - $product['customizations'] = !empty($customizations) ? new OrderProductCustomizationsForViewing($customizations) : null; - $product['customized_product_quantity'] = $customized_product_quantity; - $product['current_stock'] = StockAvailable::getQuantityAvailableByProduct($product['product_id'], $product['product_attribute_id'], $product['id_shop']); - $product['quantity_refundable'] = $product['product_quantity'] - $product['product_quantity_return'] - $product['product_quantity_refunded']; - $product['amount_refundable'] = $product['total_price_tax_excl'] - $product['total_refunded_tax_excl']; - $product['amount_refundable_tax_incl'] = $product['total_price_tax_incl'] - $product['total_refunded_tax_incl']; - $product['displayed_max_refundable'] = $taxCalculationMethod === PS_TAX_EXC ? $product['amount_refundable'] : $product['amount_refundable_tax_incl']; - $resumeAmountKey = $taxCalculationMethod === PS_TAX_EXC ? 'total_refunded_tax_excl' : 'total_refunded_tax_incl'; - $product['amount_refunded'] = $product[$resumeAmountKey] ?? 0; - $product['refund_history'] = OrderSlip::getProductSlipDetail($product['id_order_detail']); - $product['return_history'] = OrderReturn::getProductReturnDetail($product['id_order_detail']); - - if ($product['id_warehouse'] != 0) { - $warehouse = new Warehouse((int) $product['id_warehouse']); - $product['warehouse_name'] = $warehouse->name; - $warehouse_location = WarehouseProductLocation::getProductLocation($product['product_id'], $product['product_attribute_id'], $product['id_warehouse']); - if (!empty($warehouse_location)) { - $product['warehouse_location'] = $warehouse_location; - } else { - $product['warehouse_location'] = false; - } - } else { - $product['warehouse_name'] = '--'; - $product['warehouse_location'] = false; - } - - $pack_items = $product['cache_is_pack'] ? Pack::getItemTable($product['id_product'], $this->contextLanguageId, true) : []; - foreach ($pack_items as &$pack_item) { - $pack_item['current_stock'] = StockAvailable::getQuantityAvailableByProduct($pack_item['id_product'], $pack_item['id_product_attribute'], $pack_item['id_shop']); - $this->setProductImageInformation($pack_item); - if ($pack_item['image'] instanceof Image) { - $name = 'product_mini_' . (int) $pack_item['id_product'] . (isset($pack_item['id_product_attribute']) ? '_' . (int) $pack_item['id_product_attribute'] : '') . '.jpg'; - // generate image cache, only for back office - $pack_item['image_tag'] = ImageManager::thumbnail(_PS_IMG_DIR_ . 'p/' . $pack_item['image']->getExistingImgPath() . '.jpg', $name, 45, 'jpg'); - if (file_exists(_PS_TMP_IMG_DIR_ . $name)) { - $pack_item['image_size'] = getimagesize(_PS_TMP_IMG_DIR_ . $name); - } else { - $pack_item['image_size'] = false; - } - } - } - - unset($pack_item); - - $product['pack_items'] = $pack_items; - } - - unset($product); - - if (QuerySorting::DESC === $query->getProductsSorting()->getValue()) { - // reorder products by order_detail_id DESC - krsort($products); - } else { - // reorder products by order_detail_id ASC - ksort($products); - } - - $productsForViewing = []; - - $isOrderTaxExcluded = ($taxCalculationMethod == PS_TAX_EXC); - foreach ($products as $product) { - $unitPrice = $isOrderTaxExcluded ? - $product['unit_price_tax_excl'] : - $product['unit_price_tax_incl'] - ; - - // if rounding type is set to "per item" we must round the unit price now, otherwise values won't match - // the totals in the order summary - if ((int) $order->round_type === Order::ROUND_ITEM) { - $unitPrice = (new Number((string) $unitPrice))->round($precision, $this->getNumberRoundMode()); - } - - $totalPrice = $unitPrice * - (!empty($product['customizedDatas']) ? $product['customizationQuantityTotal'] : $product['product_quantity']); - - $unitPriceFormatted = $this->locale->formatPrice($unitPrice, $currency->iso_code); - $totalPriceFormatted = $this->locale->formatPrice($totalPrice, $currency->iso_code); - - $imagePath = isset($product['image_tag']) ? - $this->imageTagSourceParser->parse($product['image_tag']) : - null; - $product['product_quantity_refunded'] = $product['product_quantity_refunded'] ?: false; - - $productType = !empty($product['pack_items']) ? OrderProductForViewing::TYPE_PACK : - OrderProductForViewing::TYPE_PRODUCT_WITHOUT_COMBINATIONS; - - $orderInvoice = new OrderInvoice($product['id_order_invoice']); - - $packItems = []; - foreach ($product['pack_items'] as $pack_item) { - $packItemType = !empty($pack_item['pack_items']) ? OrderProductForViewing::TYPE_PACK : - OrderProductForViewing::TYPE_PRODUCT_WITHOUT_COMBINATIONS; - $packItemImagePath = isset($pack_item['image_tag']) ? - $this->imageTagSourceParser->parse($pack_item['image_tag']) : - null; - $packItems[] = new OrderProductForViewing( - null, - $pack_item['id_product'], - 0, - $pack_item['name'], - $pack_item['reference'], - $pack_item['supplier_reference'], - $pack_item['pack_quantity'], - 0, - 0, - $pack_item['current_stock'], - $packItemImagePath, - '0', - '0', - '0', - $this->locale->formatPrice(0, $currency->iso_code), - 0, - $this->locale->formatPrice(0, $currency->iso_code), - '0', - $pack_item['location'], - null, - '', - $packItemType, - (bool) Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($pack_item['id_product'])) - ); - } - - $productsForViewing[] = new OrderProductForViewing( - $product['id_order_detail'], - $product['product_id'], - $product['product_attribute_id'], - $product['product_name'], - $product['product_reference'], - $product['product_supplier_reference'], - $product['product_quantity'], - $unitPriceFormatted, - $totalPriceFormatted, - $product['current_stock'], - $imagePath, - (new Number((string) $product['unit_price_tax_excl']))->round($precision, $this->getNumberRoundMode()), - (new Number((string) $product['unit_price_tax_incl']))->round($precision, $this->getNumberRoundMode()), - (string) $product['tax_rate'], - $this->locale->formatPrice($product['amount_refunded'], $currency->iso_code), - $product['product_quantity_refunded'] + $product['product_quantity_return'], - $this->locale->formatPrice($product['displayed_max_refundable'], $currency->iso_code), - (string) $product['displayed_max_refundable'], - $product['location'], - !empty($product['id_order_invoice']) ? $product['id_order_invoice'] : null, - !empty($product['id_order_invoice']) ? $orderInvoice->getInvoiceNumberFormatted($order->id_lang) : '', - $productType, - (bool) Product::isAvailableWhenOutOfStock(StockAvailable::outOfStock($product['product_id'])), - $packItems, - $product['customizations'] - ); - } - - $offset = $query->getOffset(); - $limit = $query->getLimit(); - - //@todo: its not really paginated, as all products are retrieved from legacy Order::getProducts(). But could be improved in future. - if (null !== $offset && $limit) { - $productsForViewing = array_slice($products, (int) $offset, (int) $limit); - } - - return new OrderProductsForViewing($productsForViewing); - } - - /** - * @param $pack_item - */ - private function setProductImageInformation(&$pack_item): void - { - if (isset($pack_item['id_product_attribute']) && $pack_item['id_product_attribute']) { - $id_image = Db::getInstance()->getValue(' - SELECT `image_shop`.id_image - FROM `' . _DB_PREFIX_ . 'product_attribute_image` pai' . - Shop::addSqlAssociation('image', 'pai', true) . ' - WHERE id_product_attribute = ' . (int) $pack_item['id_product_attribute']); - } - - if (!isset($id_image) || !$id_image) { - $id_image = Db::getInstance()->getValue( - ' - SELECT `image_shop`.id_image - FROM `' . _DB_PREFIX_ . 'image` i' . - Shop::addSqlAssociation('image', 'i', true, 'image_shop.cover=1') . ' - WHERE i.id_product = ' . (int) $pack_item['id_product'] - ); - } - - $pack_item['image'] = null; - $pack_item['image_size'] = null; - - if ($id_image) { - $pack_item['image'] = new Image($id_image); - } - } -} diff --git a/src/Adapter/Order/Refund/OrderProductRemover.php b/src/Adapter/Order/Refund/OrderProductRemover.php deleted file mode 100644 index 25d7f218..00000000 --- a/src/Adapter/Order/Refund/OrderProductRemover.php +++ /dev/null @@ -1,243 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use Cart; -use CartRule; -use Db; -use Order; -use OrderCartRule; -use OrderDetail; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductsComparator; -use PrestaShop\PrestaShop\Adapter\Cart\Comparator\CartProductUpdate; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DeleteCustomizedProductFromOrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\DeleteProductFromOrderException; -use Psr\Log\LoggerInterface; -use SpecificPrice; -use Symfony\Component\Translation\TranslatorInterface; - -class OrderProductRemover -{ - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * OrderProductRemover constructor. - * - * @param LoggerInterface $logger - */ - public function __construct(LoggerInterface $logger, TranslatorInterface $translator) - { - $this->logger = $logger; - $this->translator = $translator; - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param bool $updateCart Used when you don't want to update the cart (CartRule removal for example) - * - * @return array - */ - public function deleteProductFromOrder(Order $order, OrderDetail $orderDetail, bool $updateCart = true): array - { - $cart = new Cart($order->id_cart); - - // Important to remove order cart rule before the product is removed, so that cart rule can detect if it's applied on it - $this->deleteOrderCartRule($order, $orderDetail, $cart); - - if ((int) $orderDetail->id_customization > 0) { - $this->deleteCustomization($order, $orderDetail); - } - - $updatedProducts = []; - if ($updateCart) { - $updatedProducts = $this->updateCart($cart, $orderDetail); - } - - $this->deleteSpecificPrice($order, $orderDetail, $cart); - - $this->deleteOrderDetail( - $order, - $orderDetail - ); - - return $updatedProducts; - } - - /** - * @param Cart $cart - * @param OrderDetail $orderDetail - * - * @return CartProductUpdate[] - */ - private function updateCart(Cart $cart, OrderDetail $orderDetail): array - { - $cartComparator = new CartProductsComparator($cart); - $knownUpdates = [ - new CartProductUpdate( - (int) $orderDetail->product_id, - (int) $orderDetail->product_attribute_id, - -$orderDetail->product_quantity, - false - ), - ]; - - $cart->updateQty( - $orderDetail->product_quantity, - $orderDetail->product_id, - $orderDetail->product_attribute_id, - false, - 'down', - 0, - null, - true, - false, - false // Do not preserve gift removal - ); - - return $cartComparator->getUpdatedProducts($knownUpdates); - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * - * @throws DeleteProductFromOrderException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function deleteOrderDetail( - Order $order, - OrderDetail $orderDetail - ) { - if (!$orderDetail->delete()) { - throw new DeleteProductFromOrderException('Could not delete order detail'); - } - - $order->update(); - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - */ - private function deleteCustomization(Order $order, OrderDetail $orderDetail) - { - if (!(int) $order->getCurrentState()) { - throw new DeleteCustomizedProductFromOrderException('Could not get a valid Order state before deletion'); - } - if (!Db::getInstance()->execute('DELETE FROM `' . _DB_PREFIX_ . 'customization` WHERE `id_customization` = ' . (int) $orderDetail->id_customization . ' AND `id_cart` = ' . (int) $order->id_cart . ' AND `id_product` = ' . (int) $orderDetail->product_id)) { - throw new DeleteCustomizedProductFromOrderException('Could not delete customization from database.'); - } - } - - /** - * The deleted OrderCartRule are ignored by CartRule:autoAdd and CartRule:autoRemove so it is not able to clean - * them when the product is removed, hence the discount could never be re applied. So we manually check and remove - * them. - * - * @param Order $order - * @param OrderDetail $orderDetail - * @param Cart $cart - */ - private function deleteOrderCartRule( - Order $order, - OrderDetail $orderDetail, - Cart $cart - ): void { - $orderCartRules = $order->getDeletedCartRules(); - if (empty($orderCartRules)) { - return; - } - - $removedOrderCartRules = []; - foreach ($orderCartRules as $orderCartRule) { - $cartRule = new CartRule($orderCartRule['id_cart_rule']); - $discountedProducts = $cartRule->checkProductRestrictionsFromCart($cart, true, true, true); - foreach ($discountedProducts as $discountedProduct) { - // The return value is the concatenation of productId and attributeId, but the attributeId is always replaced by 0 - if ($discountedProduct === $orderDetail->product_id . '-0') { - if (!in_array($orderCartRule['id_order_cart_rule'], $removedOrderCartRules)) { - $removedOrderCartRules[] = $orderCartRule['id_order_cart_rule']; - } - } - } - } - - foreach ($removedOrderCartRules as $removedOrderCartRuleId) { - $orderCartRule = new OrderCartRule($removedOrderCartRuleId); - $orderCartRule->delete(); - } - } - - /** - * @param Order $order - * @param OrderDetail $orderDetail - * @param Cart $cart - */ - private function deleteSpecificPrice( - Order $order, - OrderDetail $orderDetail, - Cart $cart - ): void { - $productQuantity = $cart->getProductQuantity($orderDetail->product_id, $orderDetail->product_attribute_id); - if (!isset($productQuantity['quantity']) || (int) $productQuantity['quantity'] > 0) { - return; - } - - // WARNING: DO NOT use SpecificPrice::getSpecificPrice as it filters out fields that are not in database - // hence it ignores the customer or cart restriction and results are biased - $existingSpecificPriceId = SpecificPrice::exists( - (int) $orderDetail->product_id, - (int) $orderDetail->product_attribute_id, - 0, - 0, - 0, - $order->id_currency, - $order->id_customer, - SpecificPrice::ORDER_DEFAULT_FROM_QUANTITY, - SpecificPrice::ORDER_DEFAULT_DATE, - SpecificPrice::ORDER_DEFAULT_DATE, - false, - $order->id_cart - ); - if (!empty($existingSpecificPriceId)) { - $specificPrice = new SpecificPrice($existingSpecificPriceId); - $specificPrice->delete(); - } - } -} diff --git a/src/Adapter/Order/Refund/OrderRefundCalculator.php b/src/Adapter/Order/Refund/OrderRefundCalculator.php deleted file mode 100644 index cd518e5b..00000000 --- a/src/Adapter/Order/Refund/OrderRefundCalculator.php +++ /dev/null @@ -1,277 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use Address; -use Carrier; -use Currency; -use Customer; -use Customization; -use Group; -use Order; -use OrderDetail; -use OrderSlip; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderDetailRefund; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShopDatabaseException; -use PrestaShopException; -use TaxCalculator; -use Tools; - -/** - * Performs all computation for a refund on an Order, returns a OrderRefundDetail - * object which contains all the refund detail. - */ -class OrderRefundCalculator -{ - /** - * @param Order $order - * @param array $orderDetailRefunds - * @param Number $shippingRefund - * @param int $voucherRefundType - * @param Number|null $chosenVoucherAmount - * - * @return OrderRefundSummary - * - * @throws InvalidCancelProductException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - public function computeOrderRefund( - Order $order, - array $orderDetailRefunds, - Number $shippingRefund, - int $voucherRefundType, - ?Number $chosenVoucherAmount - ): OrderRefundSummary { - $isTaxIncluded = $this->isTaxIncludedInOrder($order); - $precision = $this->getPrecision($order); - - $orderDetailList = $this->getOrderDetailList($orderDetailRefunds); - $productRefunds = $this->flattenCheckedProductRefunds( - $orderDetailRefunds, - $isTaxIncluded, - $orderDetailList, - $precision - ); - - $numberZero = new Number('0'); - - $refundedAmount = $numberZero; - foreach ($productRefunds as $orderDetailId => $productRefund) { - $refundedAmount = $refundedAmount->plus(new Number((string) $productRefund['amount'])); - } - - $voucherChosen = false; - $voucherAmount = $numberZero; - if ($voucherRefundType === VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND) { - $voucherAmount = new Number((string) $order->total_discounts); - $refundedAmount = $refundedAmount->minus($voucherAmount); - } elseif ($voucherRefundType === VoucherRefundType::SPECIFIC_AMOUNT_REFUND) { - $voucherChosen = true; - $refundedAmount = $voucherAmount = $chosenVoucherAmount; - } - - $shippingCostAmount = $shippingRefund ?? $numberZero; - if ($shippingCostAmount->isPositive()) { - $shippingMaxRefund = new Number( - $isTaxIncluded ? - (string) $order->total_shipping_tax_incl : - (string) $order->total_shipping_tax_excl - ); - - $shippingSlipResume = OrderSlip::getShippingSlipResume($order->id); - $shippingSlipTotalTaxIncl = new Number((string) ($shippingSlipResume['total_shipping_tax_incl'] ?? 0)); - $shippingMaxRefund = $shippingMaxRefund->minus($shippingSlipTotalTaxIncl); - - if ($shippingCostAmount->isGreaterThan($shippingMaxRefund)) { - $shippingCostAmount = $shippingMaxRefund; - } - // Previously taxes were computed but then some values are mixed with and without taxes - // They all should be in the same state since OrderRefundSummary contains $isTaxIncluded - $refundedAmount = $refundedAmount->plus($shippingCostAmount); - } - - // Something has to be refunded (check refunds count instead of the sum in case a voucher is implied) - if (count($productRefunds) <= 0 && $refundedAmount->isLowerOrEqualThanZero()) { - throw new InvalidCancelProductException(InvalidCancelProductException::NO_REFUNDS); - } - - return new OrderRefundSummary( - $orderDetailList, - $productRefunds, - (float) (string) $refundedAmount, - (float) (string) $shippingCostAmount, - (float) (string) $voucherAmount, - $voucherChosen, - $isTaxIncluded, - $precision - ); - } - - /** - * @param array $orderDetailRefunds - * - * @return OrderDetail[] - * - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function getOrderDetailList(array $orderDetailRefunds) - { - $orderDetailList = []; - /** @var OrderDetailRefund $orderDetailRefund */ - foreach ($orderDetailRefunds as $orderDetailRefund) { - $orderDetailList[$orderDetailRefund->getOrderDetailId()] = new OrderDetail($orderDetailRefund->getOrderDetailId()); - } - - return $orderDetailList; - } - - /** - * @param array $orderDetailRefunds - * @param bool $isTaxIncluded - * @param array $orderDetails - * @param TaxCalculator $taxCalculator - * @param int $precision - * - * @return array - * - * @throws InvalidCancelProductException - */ - private function flattenCheckedProductRefunds( - array $orderDetailRefunds, - bool $isTaxIncluded, - array $orderDetails, - int $precision - ) { - $productRefunds = []; - /** @var OrderDetailRefund $orderDetailRefund */ - foreach ($orderDetailRefunds as $orderDetailRefund) { - $orderDetailId = $orderDetailRefund->getOrderDetailId(); - /** @var OrderDetail $orderDetail */ - $orderDetail = $orderDetails[$orderDetailId]; - $quantity = $orderDetailRefund->getProductQuantity(); - if ($orderDetail->id_customization) { - $customization = new Customization($orderDetail->id_customization); - $quantityLeft = (int) $customization->quantity - (int) $customization->quantity_refunded - $customization->quantity_returned; - } else { - $quantityLeft = (int) $orderDetail->product_quantity - (int) $orderDetail->product_quantity_refunded - (int) $orderDetail->product_quantity_return; - } - if ($quantity > $quantityLeft) { - throw new InvalidCancelProductException(InvalidCancelProductException::QUANTITY_TOO_HIGH, $quantityLeft); - } - - $productRefunds[$orderDetailId] = [ - 'quantity' => $quantity, - 'id_order_detail' => $orderDetailId, - ]; - - // Compute max refund by product (based on quantity left and already refunded amount) - $productUnitPrice = $isTaxIncluded ? (float) $orderDetail->unit_price_tax_incl : (float) $orderDetail->unit_price_tax_excl; - $productMaxRefund = (int) $quantity * $productUnitPrice; - - // If refunded amount is null it means the whole product is refunded (used for standard refund, and return product) - if (null === $orderDetailRefund->getRefundedAmount()) { - $productRefundAmount = (float) (string) $productMaxRefund; - } else { - $productRefundAmount = (float) (string) $orderDetailRefund->getRefundedAmount() <= $productMaxRefund ? - (float) (string) $orderDetailRefund->getRefundedAmount() : $productMaxRefund; - } - - $productRefunds[$orderDetailId]['amount'] = $productRefundAmount; - $productRefunds[$orderDetailId]['unit_price'] = - $productRefunds[$orderDetailId]['amount'] / $productRefunds[$orderDetailId]['quantity']; - - // We get the tax calculator from the OrderDetail which will make it use the tax rate at the moment the order was placed - $taxCalculator = $orderDetail->getTaxCalculator(); - - // Add data for OrderDetail updates, it's important to round because too many decimals will fail in Validate::isPrice - if ($isTaxIncluded) { - $productRefunds[$orderDetailId]['total_refunded_tax_incl'] = Tools::ps_round($productRefundAmount, $precision); - $productRefunds[$orderDetailId]['total_refunded_tax_excl'] = Tools::ps_round($taxCalculator->removeTaxes($productRefundAmount), $precision); - } else { - $productRefunds[$orderDetailId]['total_refunded_tax_excl'] = Tools::ps_round($productRefundAmount, $precision); - $productRefunds[$orderDetailId]['total_refunded_tax_incl'] = Tools::ps_round($taxCalculator->addTaxes($productRefundAmount), $precision); - } - - // Add missing fields - $productRefunds[$orderDetailId]['unit_price_tax_excl'] = (float) $orderDetail->unit_price_tax_excl; - $productRefunds[$orderDetailId]['unit_price_tax_incl'] = (float) $orderDetail->unit_price_tax_incl; - $productRefunds[$orderDetailId]['total_price_tax_excl'] = (float) $orderDetail->unit_price_tax_excl * $productRefunds[$orderDetailId]['quantity']; - $productRefunds[$orderDetailId]['total_price_tax_incl'] = (float) $orderDetail->unit_price_tax_incl * $productRefunds[$orderDetailId]['quantity']; - } - - return $productRefunds; - } - - /** - * @param Order $order - * - * @return bool - */ - private function isTaxIncludedInOrder(Order $order): bool - { - $customer = new Customer($order->id_customer); - - $taxCalculationMethod = Group::getPriceDisplayMethod((int) $customer->id_default_group); - - return $taxCalculationMethod === PS_TAX_INC; - } - - /** - * @param Order $order - * - * @return TaxCalculator - * - * @throws PrestaShopException - */ - private function getCarrierTaxCalculatorFromOrder(Order $order): TaxCalculator - { - $carrier = new Carrier((int) $order->id_carrier); - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_delivery, false); - - return $carrier->getTaxCalculator($address); - } - - /** - * @param Order $order - * - * @return int - */ - private function getPrecision(Order $order): int - { - $currency = new Currency($order->id_currency); - $computingPrecision = new ComputingPrecision(); - - return $computingPrecision->getPrecision($currency->precision); - } -} diff --git a/src/Adapter/Order/Refund/OrderRefundSummary.php b/src/Adapter/Order/Refund/OrderRefundSummary.php deleted file mode 100644 index 688731e4..00000000 --- a/src/Adapter/Order/Refund/OrderRefundSummary.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use OrderDetail; - -/** - * Container of all the necessary information for an order refund - */ -class OrderRefundSummary -{ - /** - * @var OrderDetail[] - */ - private $orderDetails; - - /** - * @var array - */ - private $productRefunds; - - /** - * @var float - */ - private $refundedAmount; - - /** - * @var float - */ - private $refundedShipping; - - /** - * @var float - */ - private $voucherAmount; - - /** - * @var bool - */ - private $voucherChosen; - - /** - * @var bool - */ - private $isTaxIncluded; - - /** - * @var int - */ - private $precision; - - /** - * @param array $orderDetails - * @param array $productRefunds - * @param float $refundedAmount - * @param float $refundedShipping - * @param float $voucherAmount - * @param bool $voucherChosen - * @param bool $isTaxIncluded - * @param int $precision - */ - public function __construct( - array $orderDetails, - array $productRefunds, - float $refundedAmount, - float $refundedShipping, - float $voucherAmount, - bool $voucherChosen, - bool $isTaxIncluded, - int $precision - ) { - $this->orderDetails = $orderDetails; - $this->productRefunds = $productRefunds; - $this->refundedAmount = $refundedAmount; - $this->refundedShipping = $refundedShipping; - $this->voucherAmount = $voucherAmount; - $this->voucherChosen = $voucherChosen; - $this->isTaxIncluded = $isTaxIncluded; - $this->precision = $precision; - } - - /** - * @return OrderDetail[] - */ - public function getOrderDetails(): array - { - return $this->orderDetails; - } - - /** - * @return array - */ - public function getProductRefunds(): array - { - return $this->productRefunds; - } - - /** - * @return float - */ - public function getRefundedAmount(): float - { - return $this->refundedAmount; - } - - /** - * @return float - */ - public function getRefundedShipping(): float - { - return $this->refundedShipping; - } - - /** - * @return float - */ - public function getVoucherAmount(): float - { - return $this->voucherAmount; - } - - /** - * @return bool - */ - public function isVoucherChosen(): bool - { - return $this->voucherChosen; - } - - /** - * @return bool - */ - public function isTaxIncluded(): bool - { - return $this->isTaxIncluded; - } - - /** - * @return int - */ - public function getPrecision(): int - { - return $this->precision; - } - - /** - * @param int $orderDetailId - * - * @return OrderDetail|null - */ - public function getOrderDetailById(int $orderDetailId): ?OrderDetail - { - return isset($this->orderDetails[$orderDetailId]) ? $this->orderDetails[$orderDetailId] : null; - } -} diff --git a/src/Adapter/Order/Refund/OrderRefundUpdater.php b/src/Adapter/Order/Refund/OrderRefundUpdater.php deleted file mode 100644 index 376a5749..00000000 --- a/src/Adapter/Order/Refund/OrderRefundUpdater.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use Customization; -use Order; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\CancelProductFromOrderException; -use PrestaShopDatabaseException; -use PrestaShopException; - -class OrderRefundUpdater -{ - /** - * @param OrderRefundSummary $orderRefundSummary - * @param bool $returnedProducts - * @param bool $restock - * - * @throws CancelProductFromOrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - public function updateRefundData( - OrderRefundSummary $orderRefundSummary, - bool $returnedProducts, - bool $restock - ) { - // Update order details (after credit slip to avoid updating refunded quantities while the credit slip fails) - foreach ($orderRefundSummary->getProductRefunds() as $orderDetailId => $productRefund) { - $orderDetail = $orderRefundSummary->getOrderDetailById($orderDetailId); - // There is a distinction between a product returned and refunded (depending if the order was delivered or not) - if ($returnedProducts) { - $orderDetail->product_quantity_return += $productRefund['quantity']; - } else { - $orderDetail->product_quantity_refunded += $productRefund['quantity']; - } - - // This was previously done in OrderSlip::create, but it was not consistent and too complicated - // Besides this now allows to track refunded products even when credit slip is not generated - $orderDetail->total_refunded_tax_excl += $productRefund['total_refunded_tax_excl']; - $orderDetail->total_refunded_tax_incl += $productRefund['total_refunded_tax_incl']; - - if ($restock) { - $reinjectableQuantity = (int) $orderDetail->product_quantity - (int) $orderDetail->product_quantity_reinjected; - $quantityToReinject = $productRefund['quantity'] > $reinjectableQuantity ? $reinjectableQuantity : $productRefund['quantity']; - $orderDetail->product_quantity_reinjected += $quantityToReinject; - } - - if (!$orderDetail->update()) { - throw new CancelProductFromOrderException('Cannot update order detail'); - } - - // Update customization - if ($orderDetail->id_customization) { - $customization = new Customization($orderDetail->id_customization); - if ($returnedProducts) { - $customization->quantity_returned += $productRefund['quantity']; - } else { - $customization->quantity_refunded += $productRefund['quantity']; - } - - if (!$customization->update()) { - throw new CancelProductFromOrderException('Cannot update customization'); - } - } - } - } -} diff --git a/src/Adapter/Order/Refund/OrderSlipCreator.php b/src/Adapter/Order/Refund/OrderSlipCreator.php deleted file mode 100644 index 1dbf27fb..00000000 --- a/src/Adapter/Order/Refund/OrderSlipCreator.php +++ /dev/null @@ -1,337 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use Address; -use Carrier; -use Currency; -use Customer; -use Db; -use Hook; -use Language; -use Mail; -use Order; -use OrderDetail; -use OrderSlip; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; -use PrestaShopDatabaseException; -use PrestaShopException; -use StockAvailable; -use Symfony\Component\Translation\TranslatorInterface; -use TaxCalculator; -use TaxManagerFactory; -use Tools; - -/** - * Class OrderSlipCreator is responsible of creating an OrderSlip for a refund - */ -class OrderSlipCreator -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param ConfigurationInterface $configuration - * @param TranslatorInterface $translator - */ - public function __construct( - ConfigurationInterface $configuration, - TranslatorInterface $translator - ) { - $this->configuration = $configuration; - $this->translator = $translator; - } - - /** - * @param Order $order - * @param OrderRefundSummary $orderRefundSummary - * - * @throws InvalidCancelProductException - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - public function create( - Order $order, - OrderRefundSummary $orderRefundSummary - ) { - if ($orderRefundSummary->getRefundedAmount() > 0) { - $orderSlipCreated = $this->createOrderSlip( - $order, - $orderRefundSummary->getProductRefunds(), - $orderRefundSummary->getRefundedShipping(), - $orderRefundSummary->getVoucherAmount(), - $orderRefundSummary->isVoucherChosen(), - !$orderRefundSummary->isTaxIncluded(), - $orderRefundSummary->getPrecision() - ); - - if (!$orderSlipCreated) { - throw new OrderException('You cannot generate a partial credit slip.'); - } - - $fullQuantityList = array_map(function ($orderDetail) { return $orderDetail['quantity']; }, $orderRefundSummary->getProductRefunds()); - Hook::exec('actionOrderSlipAdd', [ - 'order' => $order, - 'productList' => $orderRefundSummary->getProductRefunds(), - 'qtyList' => $fullQuantityList, - ], null, false, true, false, $order->id_shop); - - $customer = new Customer((int) $order->id_customer); - - // @todo: use private method to send mail - $params = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => $order->id, - '{order_name}' => $order->getUniqReference(), - ]; - - $orderLanguage = new Language((int) $order->id_lang); - - // @todo: use a dedicated Mail class (see #13945) - // @todo: remove this @and have a proper error handling - @Mail::Send( - (int) $order->id_lang, - 'credit_slip', - $this->translator->trans( - 'New credit slip regarding your order', - [], - 'Emails.Subject', - $orderLanguage->locale - ), - $params, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - (int) $order->id_shop - ); - - /** @var OrderDetail $orderDetail */ - foreach ($orderRefundSummary->getOrderDetails() as $orderDetail) { - if ($this->configuration->get('PS_ADVANCED_STOCK_MANAGEMENT')) { - StockAvailable::synchronize($orderDetail->product_id); - } - } - } else { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); - } - } - - /** - * This is a copy of OrderSlip::create except the OrderDetail modification has been removed - * since it's now managed in the handler, this allows to update order details even without - * generating a credit slip - * - * @todo this copy uses array data but could probably be refactored to use OrderDetailRefund objects - * - * @param Order $order - * @param array $product_list - * @param float $shipping_cost - * @param float $amount - * @param bool $amount_choosen - * @param bool $add_tax - * @param int $precision - * - * @return bool - * - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - */ - private function createOrderSlip( - Order $order, - array $product_list, - float $shipping_cost = 0, - float $amount = 0, - bool $amount_choosen = false, - bool $add_tax = true, - int $precision = 6 - ) { - $currency = new Currency((int) $order->id_currency); - $orderSlip = new OrderSlip(); - $orderSlip->id_customer = (int) $order->id_customer; - $orderSlip->id_order = (int) $order->id; - $orderSlip->conversion_rate = $currency->conversion_rate; - - if ($add_tax) { - $add_or_remove = 'add'; - $inc_or_ex_1 = 'excl'; - $inc_or_ex_2 = 'incl'; - } else { - $add_or_remove = 'remove'; - $inc_or_ex_1 = 'incl'; - $inc_or_ex_2 = 'excl'; - } - - $orderSlip->total_shipping_tax_excl = 0; - $orderSlip->total_shipping_tax_incl = 0; - $orderSlip->partial = 0; - - if ($shipping_cost > 0) { - $orderSlip->shipping_cost = true; - $carrier = new Carrier((int) $order->id_carrier); - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_delivery, false); - $tax_calculator = $carrier->getTaxCalculator($address); - $orderSlip->{'total_shipping_tax_' . $inc_or_ex_1} = $shipping_cost; - - if ($tax_calculator instanceof TaxCalculator) { - $orderSlip->{'total_shipping_tax_' . $inc_or_ex_2} = Tools::ps_round($tax_calculator->{$add_or_remove . 'Taxes'}($orderSlip->{'total_shipping_tax_' . $inc_or_ex_1}), $precision); - } else { - $orderSlip->{'total_shipping_tax_' . $inc_or_ex_2} = $orderSlip->{'total_shipping_tax_' . $inc_or_ex_1}; - } - } else { - $orderSlip->shipping_cost = false; - } - - $orderSlip->amount = 0; - $orderSlip->total_products_tax_excl = 0; - $orderSlip->total_products_tax_incl = 0; - $total_products = []; - foreach ($product_list as &$product) { - $order_detail = new OrderDetail((int) $product['id_order_detail']); - $price = (float) $product['unit_price']; - $quantity = (int) $product['quantity']; - - // @todo: define if we use invoice or delivery address, or we use configuration PS_TAX_ADDRESS_TYPE - $address = Address::initialize($order->id_address_invoice, false); - $id_address = (int) $address->id; - $id_tax_rules_group = (int) $order_detail->id_tax_rules_group; - $tax_calculator = $order_detail->getTaxCalculator(); - - $orderSlip->{'total_products_tax_' . $inc_or_ex_1} += $price * $quantity; - - if (in_array($this->configuration->get('PS_ROUND_TYPE'), [Order::ROUND_ITEM, Order::ROUND_LINE])) { - if (!isset($total_products[$id_tax_rules_group])) { - $total_products[$id_tax_rules_group] = 0; - } - } else { - if (!isset($total_products[$id_tax_rules_group . '_' . $id_address])) { - $total_products[$id_tax_rules_group . '_' . $id_address] = 0; - } - } - - $product_tax_incl_line = Tools::ps_round($tax_calculator->{$add_or_remove . 'Taxes'}($price) * $quantity, $precision); - - switch ($this->configuration->get('PS_ROUND_TYPE')) { - case Order::ROUND_ITEM: - $product_tax_incl = Tools::ps_round($tax_calculator->{$add_or_remove . 'Taxes'}($price), $precision) * $quantity; - $total_products[$id_tax_rules_group] += $product_tax_incl; - - break; - case Order::ROUND_LINE: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group] += $product_tax_incl; - - break; - case Order::ROUND_TOTAL: - $product_tax_incl = $product_tax_incl_line; - $total_products[$id_tax_rules_group . '_' . $id_address] += $price * $quantity; - - break; - } - - $product['unit_price_tax_' . $inc_or_ex_1] = $price; - $product['unit_price_tax_' . $inc_or_ex_2] = Tools::ps_round($tax_calculator->{$add_or_remove . 'Taxes'}($price), $precision); - $product['total_price_tax_' . $inc_or_ex_1] = Tools::ps_round($price * $quantity, $precision); - $product['total_price_tax_' . $inc_or_ex_2] = Tools::ps_round($product_tax_incl, $precision); - } - - unset($product); - - foreach ($total_products as $key => $price) { - if ($this->configuration->get('PS_ROUND_TYPE') == Order::ROUND_TOTAL) { - $tmp = explode('_', $key); - $address = Address::initialize((int) $tmp[1], true); - $tax_calculator = TaxManagerFactory::getManager($address, $tmp[0])->getTaxCalculator(); - $orderSlip->{'total_products_tax_' . $inc_or_ex_2} += Tools::ps_round($tax_calculator->{$add_or_remove . 'Taxes'}($price), $precision); - } else { - $orderSlip->{'total_products_tax_' . $inc_or_ex_2} += $price; - } - } - - $orderSlip->{'total_products_tax_' . $inc_or_ex_2} -= $amount && !$amount_choosen ? $amount : 0; - $orderSlip->amount = $amount_choosen ? $amount : $orderSlip->{'total_products_tax_' . $inc_or_ex_1}; - $orderSlip->shipping_cost_amount = $orderSlip->total_shipping_tax_incl; - - if ((float) $amount && !$amount_choosen) { - $orderSlip->order_slip_type = VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND; - } - if (((float) $amount && $amount_choosen) || $orderSlip->shipping_cost_amount > 0) { - $orderSlip->order_slip_type = VoucherRefundType::SPECIFIC_AMOUNT_REFUND; - } - - if (!$orderSlip->add()) { - return false; - } - - $res = true; - - foreach ($product_list as $product) { - $res &= $this->addProductOrderSlip((int) $orderSlip->id, $product); - } - - return (bool) $res; - } - - /** - * @param array $product - * - * @return bool - * - * @throws PrestaShopDatabaseException - */ - private function addProductOrderSlip(int $orderSlipId, array $product): bool - { - return (bool) Db::getInstance()->insert('order_slip_detail', [ - 'id_order_slip' => $orderSlipId, - 'id_order_detail' => (int) $product['id_order_detail'], - 'product_quantity' => $product['quantity'], - 'unit_price_tax_excl' => $product['unit_price_tax_excl'], - 'unit_price_tax_incl' => $product['unit_price_tax_incl'], - 'total_price_tax_excl' => $product['total_price_tax_excl'], - 'total_price_tax_incl' => $product['total_price_tax_incl'], - 'amount_tax_excl' => $product['total_price_tax_excl'], - 'amount_tax_incl' => $product['total_price_tax_incl'], - ]); - } -} diff --git a/src/Adapter/Order/Refund/VoucherGenerator.php b/src/Adapter/Order/Refund/VoucherGenerator.php deleted file mode 100644 index 6c5a99fe..00000000 --- a/src/Adapter/Order/Refund/VoucherGenerator.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Order\Refund; - -use CartRule; -use Customer; -use Language; -use Mail; -use Order; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShopDatabaseException; -use PrestaShopException; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class VoucherGenerator is responsible of generating a voucher for a customer - * for an order refund. - */ -class VoucherGenerator -{ - /** - * @var Locale - */ - private $locale; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param Locale $locale - * @param TranslatorInterface $translator - */ - public function __construct( - Locale $locale, - TranslatorInterface $translator - ) { - $this->locale = $locale; - $this->translator = $translator; - } - - /** - * @param Order $order - * @param float $voucherAmount - * @param string $currencyIsoCode - * @param bool $isTaxIncluded - * - * @throws OrderException - * @throws PrestaShopDatabaseException - * @throws PrestaShopException - * @throws LocalizationException - */ - public function generateVoucher( - Order $order, - float $voucherAmount, - string $currencyIsoCode, - bool $isTaxIncluded - ) { - $cartRule = new CartRule(); - $cartRule->description = $this->translator->trans( - 'Credit slip for order #%d', - ['#%d' => $order->id], - 'Admin.Orderscustomers.Feature' - ); - - $langIds = Language::getIDs(false); - foreach ($langIds as $langId) { - // Define a temporary name - $cartRule->name[$langId] = sprintf('V0C%1$dO%2$d', $order->id_customer, $order->id); - } - - // Define a temporary code - $cartRule->code = sprintf('V0C%1$dO%2$d', $order->id_customer, $order->id); - $cartRule->quantity = 1; - $cartRule->quantity_per_user = 1; - - // Specific to the customer - $cartRule->id_customer = $order->id_customer; - $now = time(); - $cartRule->date_from = date('Y-m-d H:i:s', $now); - $cartRule->date_to = date('Y-m-d H:i:s', strtotime('+1 year')); - $cartRule->partial_use = 1; - $cartRule->active = 1; - - $cartRule->reduction_amount = $voucherAmount; - $cartRule->reduction_tax = $isTaxIncluded; - $cartRule->minimum_amount_currency = $order->id_currency; - $cartRule->reduction_currency = $order->id_currency; - - if (!$cartRule->add()) { - throw new OrderException('You cannot generate a voucher.'); - } - - // Update the voucher code and name - foreach ($langIds as $langId) { - $cartRule->name[$langId] = sprintf('V%1$dC%2$dO%3$d', $cartRule->id, $order->id_customer, $order->id); - } - - $cartRule->code = sprintf('V%1$dC%2$dO%3$d', $cartRule->id, $order->id_customer, $order->id); - - if (!$cartRule->update()) { - throw new OrderException('You cannot generate a voucher.'); - } - - $customer = new Customer((int) ($order->id_customer)); - - $params = [ - '{lastname}' => $customer->lastname, - '{firstname}' => $customer->firstname, - '{id_order}' => $order->id, - '{order_name}' => $order->getUniqReference(), - '{voucher_amount}' => $this->locale->formatPrice($cartRule->reduction_amount, $currencyIsoCode), - '{voucher_num}' => $cartRule->code, - ]; - - // @todo: use private method to send mail and later a decoupled mail sender - $orderLanguage = new Language((int) $order->id_lang); - - @Mail::Send( - (int) $order->id_lang, - 'voucher', - $this->translator->trans( - 'New voucher for your order #%s', - [$order->reference], - 'Emails.Subject', - $orderLanguage->locale - ), - $params, - $customer->email, - $customer->firstname . ' ' . $customer->lastname, - null, - null, - null, - null, - _PS_MAIL_DIR_, - true, - (int) $order->id_shop - ); - } -} diff --git a/src/Adapter/OrderMessage/AbstractOrderMessageHandler.php b/src/Adapter/OrderMessage/AbstractOrderMessageHandler.php deleted file mode 100644 index 2699f039..00000000 --- a/src/Adapter/OrderMessage/AbstractOrderMessageHandler.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage; - -use OrderMessage; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Provides common methods for OrderMessage command/query handlers that uses object model - * - * @internal - */ -abstract class AbstractOrderMessageHandler -{ - /** - * @param OrderMessageId $orderMessageId - * - * @return OrderMessage - */ - protected function getOrderMessage(OrderMessageId $orderMessageId): OrderMessage - { - $orderMessage = new OrderMessage($orderMessageId->getValue()); - - if ($orderMessage->id !== $orderMessageId->getValue()) { - throw new OrderMessageNotFoundException($orderMessageId, sprintf('Order message with id "%s" was not found', $orderMessageId->getValue())); - } - - return $orderMessage; - } -} diff --git a/src/Adapter/OrderMessage/CommandHandler/AddOrderMessageHandler.php b/src/Adapter/OrderMessage/CommandHandler/AddOrderMessageHandler.php deleted file mode 100644 index 9ca28504..00000000 --- a/src/Adapter/OrderMessage/CommandHandler/AddOrderMessageHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler; - -use OrderMessage; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\AddOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler\AddOrderMessageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageException; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; -use PrestaShopException; - -/** - * Handles adding new order message using legacy object model - * - * @internal - */ -final class AddOrderMessageHandler implements AddOrderMessageHandlerInterface -{ - /** - * @param AddOrderMessageCommand $command - * - * @return OrderMessageId - */ - public function handle(AddOrderMessageCommand $command): OrderMessageId - { - $orderMessage = new OrderMessage(); - - $orderMessage->name = $command->getLocalizedName(); - $orderMessage->message = $command->getLocalizedMessage(); - - try { - $orderMessage->validateFields(); - $orderMessage->validateFieldsLang(); - } catch (PrestaShopException $e) { - throw new OrderMessageException('Order message contains invalid fields', 0, $e); - } - - try { - if (false === $orderMessage->add()) { - throw new OrderMessageException('Failed to add order message'); - } - } catch (PrestaShopException $e) { - throw new OrderMessageException('Failed to add order message', 0, $e); - } - - return new OrderMessageId((int) $orderMessage->id); - } -} diff --git a/src/Adapter/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandler.php b/src/Adapter/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandler.php deleted file mode 100644 index cd9b22a6..00000000 --- a/src/Adapter/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\OrderMessage\AbstractOrderMessageHandler; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\BulkDeleteOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler\BulkDeleteOrderMessageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageException; -use PrestaShopException; - -/** - * Deletes Order messages in bulk action using object model - * - * @internal - */ -final class BulkDeleteOrderMessageHandler extends AbstractOrderMessageHandler implements BulkDeleteOrderMessageHandlerInterface -{ - /** - * @param BulkDeleteOrderMessageCommand $command - */ - public function handle(BulkDeleteOrderMessageCommand $command): void - { - foreach ($command->getOrderMessageIds() as $orderMessageId) { - $orderMessage = $this->getOrderMessage($orderMessageId); - - try { - if (false === $orderMessage->delete()) { - throw new OrderMessageException(sprintf('Failed to delete Order message with id "%d" during bulk delete', $orderMessage->id), OrderMessageException::FAILED_BULK_DELETE); - } - } catch (PrestaShopException $e) { - throw new OrderMessageException(sprintf('Failed to delete Order message with id "%s"', $orderMessage->id)); - } - } - } -} diff --git a/src/Adapter/OrderMessage/CommandHandler/DeleteOrderMessageHandler.php b/src/Adapter/OrderMessage/CommandHandler/DeleteOrderMessageHandler.php deleted file mode 100644 index 2ed4e538..00000000 --- a/src/Adapter/OrderMessage/CommandHandler/DeleteOrderMessageHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\OrderMessage\AbstractOrderMessageHandler; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\DeleteOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler\DeleteOrderMessageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageException; -use PrestaShopException; - -/** - * Handles deleting order message using object model - * - * @internal - */ -final class DeleteOrderMessageHandler extends AbstractOrderMessageHandler implements DeleteOrderMessageHandlerInterface -{ - /** - * @param DeleteOrderMessageCommand $command - */ - public function handle(DeleteOrderMessageCommand $command): void - { - $orderMessage = $this->getOrderMessage($command->getOrderMessageId()); - - try { - if (false === $orderMessage->delete()) { - throw new OrderMessageException(sprintf('Failed to delete Order message with id "%d"', $orderMessage->id), OrderMessageException::FAILED_DELETE); - } - } catch (PrestaShopException $e) { - throw new OrderMessageException(sprintf('Failed to delete Order message with id "%s"', $orderMessage->id)); - } - } -} diff --git a/src/Adapter/OrderMessage/CommandHandler/EditOrderMessageHandler.php b/src/Adapter/OrderMessage/CommandHandler/EditOrderMessageHandler.php deleted file mode 100644 index 88080e02..00000000 --- a/src/Adapter/OrderMessage/CommandHandler/EditOrderMessageHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\OrderMessage\AbstractOrderMessageHandler; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\EditOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler\EditOrderMessageHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageException; -use PrestaShopException; - -/** - * Handles editing order message using legacy object model - * - * @internal - */ -final class EditOrderMessageHandler extends AbstractOrderMessageHandler implements EditOrderMessageHandlerInterface -{ - /** - * @param EditOrderMessageCommand $command - */ - public function handle(EditOrderMessageCommand $command): void - { - $orderMessage = $this->getOrderMessage($command->getOrderMessageId()); - - if (null !== $command->getLocalizedName()) { - $orderMessage->name = $command->getLocalizedName(); - } - - if (null !== $command->getLocalizedMessage()) { - $orderMessage->message = $command->getLocalizedMessage(); - } - - try { - $orderMessage->validateFields(); - $orderMessage->validateFieldsLang(); - } catch (PrestaShopException $e) { - throw new OrderMessageException('Order message contains invalid fields', 0, $e); - } - - try { - if (false === $orderMessage->update()) { - throw new OrderMessageException(sprintf('Failed to update order message with id "%s"', $command->getOrderMessageId()->getValue())); - } - } catch (PrestaShopException $e) { - throw new OrderMessageException(sprintf('Failed to update order message with id "%s"', $command->getOrderMessageId()->getValue()), 0, $e); - } - } -} diff --git a/src/Adapter/OrderMessage/OrderMessageProvider.php b/src/Adapter/OrderMessage/OrderMessageProvider.php deleted file mode 100644 index 99619d54..00000000 --- a/src/Adapter/OrderMessage/OrderMessageProvider.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage; - -use OrderMessage; - -/** - * Gets order messages. - */ -class OrderMessageProvider -{ - /** - * @var int - */ - private $contextLanguageId; - - /** - * @param int $contextLanguageId - */ - public function __construct(int $contextLanguageId) - { - $this->contextLanguageId = $contextLanguageId; - } - - public function getMessages(): array - { - $result = OrderMessage::getOrderMessages($this->contextLanguageId); - - return \is_array($result) ? $result : []; - } -} diff --git a/src/Adapter/OrderMessage/QueryHandler/GetOrderMessageForEditingHandler.php b/src/Adapter/OrderMessage/QueryHandler/GetOrderMessageForEditingHandler.php deleted file mode 100644 index 99936fff..00000000 --- a/src/Adapter/OrderMessage/QueryHandler/GetOrderMessageForEditingHandler.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderMessage\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\OrderMessage\AbstractOrderMessageHandler; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query\GetOrderMessageForEditing; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryHandler\GetOrderMessageForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryResult\EditableOrderMessage; - -/** - * Get order message for editing using object model - * - * @internal - */ -final class GetOrderMessageForEditingHandler extends AbstractOrderMessageHandler implements GetOrderMessageForEditingHandlerInterface -{ - /** - * @param GetOrderMessageForEditing $query - * - * @return EditableOrderMessage - */ - public function handle(GetOrderMessageForEditing $query): EditableOrderMessage - { - $orderMessage = $this->getOrderMessage($query->getOrderMessageId()); - - return new EditableOrderMessage( - $query->getOrderMessageId(), - $orderMessage->name, - $orderMessage->message - ); - } -} diff --git a/src/Adapter/OrderState/OrderStateDataProvider.php b/src/Adapter/OrderState/OrderStateDataProvider.php deleted file mode 100644 index ee2f5674..00000000 --- a/src/Adapter/OrderState/OrderStateDataProvider.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\OrderState; - -use OrderState; -use PrestaShop\PrestaShop\Core\Order\OrderStateDataProviderInterface; - -/** - * Class OrderStateDataProvider provides OrderState data using legacy code. - */ -final class OrderStateDataProvider implements OrderStateDataProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getOrderStates($languageId) - { - return OrderState::getOrderStates($languageId, false); - } -} diff --git a/src/Adapter/PDF/CreditSlipPdfGenerator.php b/src/Adapter/PDF/CreditSlipPdfGenerator.php deleted file mode 100644 index 47d3d724..00000000 --- a/src/Adapter/PDF/CreditSlipPdfGenerator.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\PDF; - -use Context; -use Doctrine\DBAL\Connection; -use ObjectModel; -use OrderSlip; -use PDF; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\ValueObject\CreditSlipId; -use PrestaShop\PrestaShop\Core\PDF\Exception\MissingDataException; -use PrestaShop\PrestaShop\Core\PDF\Exception\PdfException; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use PrestaShopException; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Responsible for generating CreditSlip PDF - */ -final class CreditSlipPdfGenerator implements PDFGeneratorInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @var Connection - */ - private $connection; - - /** - * @param TranslatorInterface $translator - * @param string $dbPrefix - * @param Connection $connection - */ - public function __construct( - TranslatorInterface $translator, - $dbPrefix, - Connection $connection - ) { - $this->translator = $translator; - $this->dbPrefix = $dbPrefix; - $this->connection = $connection; - } - - /** - * Generates PDF from given data using legacy object models - * - * @param CreditSlipId[] $creditSlipIds - * - * @throws PdfException - */ - public function generatePDF(array $creditSlipIds) - { - $ids = []; - foreach ($creditSlipIds as $creditSlipId) { - $ids[] = $creditSlipId->getValue(); - } - - try { - $slipsList = $this->getCreditSlipsList($ids); - $slipsCollection = ObjectModel::hydrateCollection('OrderSlip', $slipsList); - - $pdf = new PDF($slipsCollection, PDF::TEMPLATE_ORDER_SLIP, Context::getContext()->smarty); - $pdf->render(); - } catch (PrestaShopException $e) { - throw new PdfException('Something went wrong when trying to generate pdf', 0, $e); - } - } - - /** - * Gets credit slips array from sql - * - * @param int[] $creditSlipIds - * - * @return OrderSlip[] - * - * @throws MissingDataException - */ - private function getCreditSlipsList($creditSlipIds) - { - if (!empty($creditSlipIds)) { - $qb = $this->connection->createQueryBuilder() - ->select('*') - ->from($this->dbPrefix . 'order_slip', 'os') - ->where('id_order_slip IN (:creditSlipIds)') - ->setParameter('creditSlipIds', $creditSlipIds, Connection::PARAM_INT_ARRAY) - ; - - $slipsList = $qb->execute()->fetchAll(); - } - - if (!empty($slipsList)) { - return $slipsList; - } - - throw new MissingDataException('Missing data required to generate PDF'); - } -} diff --git a/src/Adapter/PDF/DeliverySlipPdfGenerator.php b/src/Adapter/PDF/DeliverySlipPdfGenerator.php deleted file mode 100644 index dc0e97f2..00000000 --- a/src/Adapter/PDF/DeliverySlipPdfGenerator.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\PDF; - -use Context; -use Order; -use PDF; -use PrestaShop\PrestaShop\Core\Exception\CoreException; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use RuntimeException; -use Symfony\Component\Translation\TranslatorInterface; -use Validate; - -/** - * Generates delivery slip for given order - * - * @internal - */ -final class DeliverySlipPdfGenerator implements PDFGeneratorInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function generatePDF(array $orderId) - { - if (count($orderId) !== 1) { - throw new CoreException(sprintf('"%s" supports generating delivery slip for single order only.', get_class($this))); - } - - $orderId = reset($orderId); - $order = new Order((int) $orderId); - - if (!Validate::isLoadedObject($order)) { - throw new RuntimeException($this->translator->trans('The order cannot be found within your database.', [], 'Admin.Orderscustomers.Notification')); - } - - $order_invoice_collection = $order->getInvoicesCollection(); - - $pdf = new PDF($order_invoice_collection, PDF::TEMPLATE_DELIVERY_SLIP, Context::getContext()->smarty); - $pdf->render(); - } -} diff --git a/src/Adapter/PDF/OrderInvoicePdfGenerator.php b/src/Adapter/PDF/OrderInvoicePdfGenerator.php deleted file mode 100644 index a036e9ac..00000000 --- a/src/Adapter/PDF/OrderInvoicePdfGenerator.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\PDF; - -use Context; -use Hook; -use Order; -use PDF; -use PrestaShop\PrestaShop\Core\Exception\CoreException; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use RuntimeException; -use Symfony\Component\Translation\TranslatorInterface; -use Validate; - -/** - * Generates invoice for given order. - */ -final class OrderInvoicePdfGenerator implements PDFGeneratorInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function generatePDF(array $orderId) - { - if (count($orderId) !== 1) { - throw new CoreException(sprintf('"%s" supports generating invoice for single order only.', get_class($this))); - } - - $orderId = reset($orderId); - $order = new Order((int) $orderId); - if (!Validate::isLoadedObject($order)) { - throw new RuntimeException($this->translator->trans('The order cannot be found within your database.', [], 'Admin.Orderscustomers.Notification')); - } - - $order_invoice_list = $order->getInvoicesCollection(); - - Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]); - - $pdf = new PDF($order_invoice_list, PDF::TEMPLATE_INVOICE, Context::getContext()->smarty); - $pdf->render(); - } -} diff --git a/src/Adapter/PDF/PDFGenerator.php b/src/Adapter/PDF/PDFGenerator.php deleted file mode 100644 index 4874ed7a..00000000 --- a/src/Adapter/PDF/PDFGenerator.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\PDF; - -use PrestaShop\PrestaShop\Adapter\Entity\PDF; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use PrestaShop\PrestaShop\Core\PDF\PDFTemplateTypeProviderInterface; -use Smarty; - -/** - * Class PDFManager responsible for PDF generation using legacy code. - */ -final class PDFGenerator implements PDFGeneratorInterface -{ - /** - * @var Smarty - */ - private $smarty; - - /** - * @var PDFTemplateTypeProviderInterface - */ - private $templateTypeProvider; - - /** - * @param Smarty $smarty - * @param PDFTemplateTypeProviderInterface $templateTypeProvider - */ - public function __construct( - Smarty $smarty, - PDFTemplateTypeProviderInterface $templateTypeProvider - ) { - $this->smarty = $smarty; - $this->templateTypeProvider = $templateTypeProvider; - } - - /** - * {@inheritdoc} - */ - public function generatePDF(array $objectCollection) - { - $pdf = new PDF($objectCollection, $this->templateTypeProvider->getPDFTemplateType(), $this->smarty); - $pdf->render(); - } -} diff --git a/src/Adapter/Pack/PackDataProvider.php b/src/Adapter/Pack/PackDataProvider.php deleted file mode 100644 index 9a79ef2a..00000000 --- a/src/Adapter/Pack/PackDataProvider.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Pack; - -use Context; -use Pack; -use Product; - -/** - * This class will provide data from DB / ORM about product pack. - */ -class PackDataProvider -{ - /** - * Get product pack items. - * - * @param int $id_product - * @param int $id_lang - */ - public function getItems($id_product, $id_lang) - { - $packItems = Pack::getItems($id_product, $id_lang); - - foreach ($packItems as $packItem) { - $cover = $packItem->id_pack_product_attribute ? Product::getCombinationImageById($packItem->id_pack_product_attribute, $id_lang) : Product::getCover($packItem->id); - $packItem->image = Context::getContext()->link->getImageLink($packItem->link_rewrite, $cover ? $cover['id_image'] : '', 'home_default'); - } - - return $packItems; - } -} diff --git a/src/Adapter/Preferences/PreferencesConfiguration.php b/src/Adapter/Preferences/PreferencesConfiguration.php deleted file mode 100644 index 0e63094c..00000000 --- a/src/Adapter/Preferences/PreferencesConfiguration.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Preferences; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class will provide Shop Preferences configuration. - */ -class PreferencesConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_ssl' => $this->configuration->getBoolean('PS_SSL_ENABLED'), - 'enable_ssl_everywhere' => $this->configuration->getBoolean('PS_SSL_ENABLED_EVERYWHERE'), - 'enable_token' => $this->configuration->getBoolean('PS_TOKEN_ENABLE'), - 'allow_html_iframes' => $this->configuration->getBoolean('PS_ALLOW_HTML_IFRAME'), - 'use_htmlpurifier' => $this->configuration->getBoolean('PS_USE_HTMLPURIFIER'), - 'price_round_mode' => $this->configuration->get('PS_PRICE_ROUND_MODE'), - 'price_round_type' => $this->configuration->get('PS_ROUND_TYPE'), - 'display_suppliers' => $this->configuration->getBoolean('PS_DISPLAY_SUPPLIERS'), - 'display_manufacturers' => $this->configuration->getBoolean('PS_DISPLAY_MANUFACTURERS'), - 'display_best_sellers' => $this->configuration->getBoolean('PS_DISPLAY_BEST_SELLERS'), - 'multishop_feature_active' => $this->configuration->getBoolean('PS_MULTISHOP_FEATURE_ACTIVE'), - 'shop_activity' => $this->configuration->get('PS_SHOP_ACTIVITY'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_SSL_ENABLED', $configuration['enable_ssl']); - $this->configuration->set('PS_SSL_ENABLED_EVERYWHERE', $configuration['enable_ssl_everywhere']); - $this->configuration->set('PS_TOKEN_ENABLE', $configuration['enable_token']); - $this->configuration->set('PS_ALLOW_HTML_IFRAME', $configuration['allow_html_iframes']); - $this->configuration->set('PS_USE_HTMLPURIFIER', $configuration['use_htmlpurifier']); - $this->configuration->set('PS_PRICE_ROUND_MODE', $configuration['price_round_mode']); - $this->configuration->set('PS_ROUND_TYPE', $configuration['price_round_type']); - $this->configuration->set('PS_DISPLAY_SUPPLIERS', $configuration['display_suppliers']); - $this->configuration->set('PS_DISPLAY_MANUFACTURERS', $configuration['display_manufacturers']); - $this->configuration->set('PS_DISPLAY_BEST_SELLERS', $configuration['display_best_sellers']); - $this->configuration->set('PS_MULTISHOP_FEATURE_ACTIVE', $configuration['multishop_feature_active']); - $this->configuration->set('PS_SHOP_ACTIVITY', $configuration['shop_activity']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_ssl'], - $configuration['enable_ssl_everywhere'], - $configuration['enable_token'], - $configuration['allow_html_iframes'], - $configuration['use_htmlpurifier'], - $configuration['price_round_mode'], - $configuration['price_round_type'], - $configuration['display_suppliers'], - $configuration['display_manufacturers'], - $configuration['display_best_sellers'], - $configuration['multishop_feature_active'] - ); - } -} diff --git a/src/Adapter/Presenter/AbstractLazyArray.php b/src/Adapter/Presenter/AbstractLazyArray.php deleted file mode 100644 index e92a569d..00000000 --- a/src/Adapter/Presenter/AbstractLazyArray.php +++ /dev/null @@ -1,392 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter; - -use ArrayAccess; -use ArrayIterator; -use ArrayObject; -use Countable; -use Doctrine\Common\Util\Inflector; -use Iterator; -use JsonSerializable; -use ReflectionClass; -use ReflectionException; -use ReflectionMethod; -use RuntimeException; - -/** - * This class is useful to provide the same behaviour than an array, but which load the result of each key on demand - * (LazyLoading). - * - * Example: - * - * If your want to define the ['addresses'] array access in your lazyArray object, just define the public method - * getAddresses() and add the annotation arrayAccess to it. e.g: - * - * @arrayAccess - * - * @return array - * - * public function getAddresses() - * - * The method name should always be the index name converted to camelCase and prefixed with get. e.g: - * - * ['add_to_cart'] => getAddToCart() - * - * You can also add an array with already defined key to the lazyArray be calling the appendArray function. - * e.g.: you have a $product array containing $product['id'] = 10; $product['url'] = 'foo'; - * If you call ->appendArray($product) on the lazyArray, it will define the key ['id'] and ['url'] as well - * for the lazyArray. - * Note if the key already exists as a method, it will be skip. In our example, if getUrl() is defined with the - * annotation @arrayAccess, the $product['url'] = 'foo'; will be ignored - */ -abstract class AbstractLazyArray implements Iterator, ArrayAccess, Countable, JsonSerializable -{ - /** - * @var ArrayObject - */ - private $arrayAccessList; - - /** - * @var ArrayIterator - */ - private $arrayAccessIterator; - - /** - * @var array - */ - private $methodCacheResults = []; - - /** - * AbstractLazyArray constructor. - * - * @throws ReflectionException - */ - public function __construct() - { - $this->arrayAccessList = new ArrayObject(); - $reflectionClass = new ReflectionClass(get_class($this)); - $methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC); - foreach ($methods as $method) { - $methodDoc = $method->getDocComment(); - if (strpos($methodDoc, '@arrayAccess') !== false) { - $this->arrayAccessList[$this->convertMethodNameToIndex($method->getName())] = - [ - 'type' => 'method', - 'value' => $method->getName(), - ]; - } - } - $this->arrayAccessIterator = $this->arrayAccessList->getIterator(); - } - - /** - * Make the lazyArray serializable like an array. - * - * @return array - * - * @throws RuntimeException - */ - public function jsonSerialize() - { - $arrayResult = []; - foreach ($this->arrayAccessList as $key => $value) { - $arrayResult[$key] = $this->offsetGet($key); - } - - return $arrayResult; - } - - /** - * Set array key and values from $array into the LazyArray. - * - * @param array $array - */ - public function appendArray($array) - { - foreach ($array as $key => $value) { - // do not override any existing method - if (!$this->arrayAccessList->offsetExists($key)) { - $this->arrayAccessList->offsetSet( - $key, - [ - 'type' => 'variable', - 'value' => $value, - ] - ); - } - } - } - - /** - * The number of keys defined into the lazyArray. - * - * @return int - */ - public function count() - { - return $this->arrayAccessList->count(); - } - - /** - * The properties are provided as an array. But callers checking the type of this class (is_object === true) - * think they must use the object syntax. - * - * Check if the index exists inside the lazyArray. - * - * @param string $index - * - * @return bool - */ - public function __isset($index) - { - return $this->offsetExists($index); - } - - /** - * The properties are provided as an array. But callers checking the type of this class (is_object === true) - * think they must use the object syntax. - * - * Get the value associated with the $index from the lazyArray. - * - * @param mixed $index - * - * @return mixed - * - * @throws RuntimeException - */ - public function __get($index) - { - return $this->offsetGet($index); - } - - /** - * The properties are provided as an array. But callers checking the type of this class (is_object === true) - * think they must use the object syntax. - * - * @param mixed $offset - * @param mixed $value - * @param bool $force if set, allow override of an existing method - * - * @throws RuntimeException - */ - public function __set($name, $value) - { - $this->offsetSet($name, $value); - } - - /** - * The properties are provided as an array. But callers checking the type of this class (is_object === true) - * think they must use the object syntax. - * - * @param mixed $offset - * @param bool $force if set, allow unset of an existing method - * - * @throws RuntimeException - */ - public function __unset($name) - { - $this->offsetUnset($name); - } - - /** - * Needed to ensure that any changes to this object won't bleed to other instances - */ - public function __clone() - { - $this->arrayAccessList = clone $this->arrayAccessList; - $this->arrayAccessIterator = clone $this->arrayAccessIterator; - } - - /** - * Get the value associated with the $index from the lazyArray. - * - * @param mixed $index - * - * @return mixed - * - * @throws RuntimeException - */ - public function offsetGet($index) - { - if (isset($this->arrayAccessList[$index])) { - // if the index is associated with a method, execute the method an cache the result - if ($this->arrayAccessList[$index]['type'] === 'method') { - if (!isset($this->methodCacheResults[$index])) { - $methodName = $this->arrayAccessList[$index]['value']; - $this->methodCacheResults[$index] = $this->{$methodName}(); - } - $result = $this->methodCacheResults[$index]; - } else { // if the index is associated with a value, just return the value - $result = $this->arrayAccessList[$index]['value']; - } - - return $result; - } - - return []; - } - - /** - * Check if the index exists inside the lazyArray. - * - * @param mixed $index - * - * @return bool - */ - public function offsetExists($index) - { - return isset($this->arrayAccessList[$index]); - } - - /** - * Copy the lazyArray. - * - * @return AbstractLazyArray - */ - public function getArrayCopy() - { - return clone $this; - } - - /** - * Get the result associated with the current index. - * - * @return mixed - * - * @throws RuntimeException - */ - public function current() - { - $key = $this->arrayAccessIterator->key(); - - return $this->offsetGet($key); - } - - /** - * Go to the next result inside the lazyArray. - */ - public function next() - { - $this->arrayAccessIterator->next(); - } - - /** - * Get the key associated with the current index. - * - * @return mixed|string - */ - public function key() - { - return $this->arrayAccessIterator->key(); - } - - /** - * Check if we are at the end of the lazyArray. - * - * @return bool - */ - public function valid() - { - return $this->arrayAccessIterator->valid(); - } - - /** - * Go back to the first element of the lazyArray. - */ - public function rewind() - { - $this->arrayAccessIterator->rewind(); - } - - /** - * Set the keys not present in the given $array to null. - * - * @param array $array - * - * @throws RuntimeException - */ - public function intersectKey($array) - { - $arrayCopy = $this->arrayAccessList->getArrayCopy(); - foreach ($arrayCopy as $key => $value) { - if (!array_key_exists($key, $array)) { - $this->offsetUnset($key, true); - } - } - } - - /** - * @param mixed $offset - * @param mixed $value - * @param bool $force if set, allow override of an existing method - * - * @throws RuntimeException - */ - public function offsetSet($offset, $value, $force = false) - { - if (!$force && $this->arrayAccessList->offsetExists($offset)) { - $result = $this->arrayAccessList->offsetGet($offset); - if ($result['type'] !== 'variable') { - throw new RuntimeException('Trying to set the index ' . print_r($offset, true) . ' of the LazyArray ' . get_class($this) . ' already defined by a method is not allowed'); - } - } - $this->arrayAccessList->offsetSet($offset, [ - 'type' => 'variable', - 'value' => $value, - ]); - } - - /** - * @param mixed $offset - * @param bool $force if set, allow unset of an existing method - * - * @throws RuntimeException - */ - public function offsetUnset($offset, $force = false) - { - $result = $this->arrayAccessList->offsetGet($offset); - if ($force || $result['type'] === 'variable') { - $this->arrayAccessList->offsetUnset($offset); - } else { - throw new RuntimeException('Trying to unset the index ' . print_r($offset, true) . ' of the LazyArray ' . get_class($this) . ' already defined by a method is not allowed'); - } - } - - /** - * @param string $methodName - * - * @return string - */ - private function convertMethodNameToIndex($methodName) - { - // remove "get" prefix from the function name - $strippedMethodName = substr($methodName, 3); - - return Inflector::tableize($strippedMethodName); - } -} diff --git a/src/Adapter/Presenter/Cart/CartPresenter.php b/src/Adapter/Presenter/Cart/CartPresenter.php deleted file mode 100644 index 44a7abe3..00000000 --- a/src/Adapter/Presenter/Cart/CartPresenter.php +++ /dev/null @@ -1,669 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Cart; - -use Cart; -use CartRule; -use Configuration; -use Context; -use Country; -use Hook; -use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; -use PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingPresenter; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever; -use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings; -use Product; -use Symfony\Component\Translation\TranslatorInterface; -use TaxConfiguration; -use Tools; - -class CartPresenter implements PresenterInterface -{ - /** - * @var PriceFormatter - */ - private $priceFormatter; - - /** - * @var \Link - */ - private $link; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ImageRetriever - */ - private $imageRetriever; - - /** - * @var TaxConfiguration - */ - private $taxConfiguration; - - public function __construct() - { - $context = Context::getContext(); - $this->priceFormatter = new PriceFormatter(); - $this->link = $context->link; - $this->translator = $context->getTranslator(); - $this->imageRetriever = new ImageRetriever($this->link); - $this->taxConfiguration = new TaxConfiguration(); - } - - /** - * @return bool - */ - private function includeTaxes() - { - return $this->taxConfiguration->includeTaxes(); - } - - /** - * @param array $rawProduct - * - * @return \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductLazyArray|\PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingLazyArray - */ - private function presentProduct(array $rawProduct) - { - $settings = new ProductPresentationSettings(); - - $settings->catalog_mode = Configuration::isCatalogMode(); - $settings->catalog_mode_with_prices = (int) Configuration::get('PS_CATALOG_MODE_WITH_PRICES'); - $settings->include_taxes = $this->includeTaxes(); - $settings->allow_add_variant_to_cart_from_listing = (int) Configuration::get('PS_ATTRIBUTE_CATEGORY_DISPLAY'); - $settings->stock_management_enabled = Configuration::get('PS_STOCK_MANAGEMENT'); - $settings->showPrices = Configuration::showPrices(); - - if (isset($rawProduct['attributes']) && is_string($rawProduct['attributes'])) { - $rawProduct['attributes'] = $this->getAttributesArrayFromString($rawProduct['attributes']); - } - $rawProduct['remove_from_cart_url'] = $this->link->getRemoveFromCartURL( - $rawProduct['id_product'], - $rawProduct['id_product_attribute'] - ); - - $rawProduct['up_quantity_url'] = $this->link->getUpQuantityCartURL( - $rawProduct['id_product'], - $rawProduct['id_product_attribute'] - ); - - $rawProduct['down_quantity_url'] = $this->link->getDownQuantityCartURL( - $rawProduct['id_product'], - $rawProduct['id_product_attribute'] - ); - - $rawProduct['update_quantity_url'] = $this->link->getUpdateQuantityCartURL( - $rawProduct['id_product'], - $rawProduct['id_product_attribute'] - ); - - $resetFields = [ - 'ecotax_rate', - 'specific_prices', - 'customizable', - 'online_only', - 'reduction', - 'reduction_without_tax', - 'new', - 'condition', - 'pack', - ]; - foreach ($resetFields as $field) { - if (!array_key_exists($field, $rawProduct)) { - $rawProduct[$field] = ''; - } - } - - if ($this->includeTaxes()) { - $rawProduct['price_amount'] = $rawProduct['price_wt']; - $rawProduct['price'] = $this->priceFormatter->format($rawProduct['price_wt']); - } else { - $rawProduct['price_amount'] = $rawProduct['price']; - $rawProduct['price'] = $rawProduct['price_tax_exc'] = $this->priceFormatter->format($rawProduct['price']); - } - - if ($rawProduct['price_amount'] && $rawProduct['unit_price_ratio'] > 0) { - $rawProduct['unit_price'] = $rawProduct['price_amount'] / $rawProduct['unit_price_ratio']; - } - - $rawProduct['total'] = $this->priceFormatter->format( - $this->includeTaxes() ? - $rawProduct['total_wt'] : - $rawProduct['total'] - ); - - $rawProduct['quantity_wanted'] = $rawProduct['cart_quantity']; - - $presenter = new ProductListingPresenter( - $this->imageRetriever, - $this->link, - $this->priceFormatter, - new ProductColorsRetriever(), - $this->translator - ); - - return $presenter->present( - $settings, - $rawProduct, - Context::getContext()->language - ); - } - - /** - * @param array $products - * @param Cart $cart - * - * @return array - */ - public function addCustomizedData(array $products, Cart $cart) - { - return array_map(function ($product) use ($cart) { - $customizations = []; - - $data = Product::getAllCustomizedDatas($cart->id, null, true, null, (int) $product['id_customization']); - - if (!$data) { - $data = []; - } - $id_product = (int) $product['id_product']; - $id_product_attribute = (int) $product['id_product_attribute']; - if (array_key_exists($id_product, $data)) { - if (array_key_exists($id_product_attribute, $data[$id_product])) { - foreach ($data[$id_product] as $byAddress) { - foreach ($byAddress as $byAddressCustomizations) { - foreach ($byAddressCustomizations as $customization) { - $presentedCustomization = [ - 'quantity' => $customization['quantity'], - 'fields' => [], - 'id_customization' => null, - ]; - - foreach ($customization['datas'] as $byType) { - foreach ($byType as $data) { - $field = []; - switch ($data['type']) { - case Product::CUSTOMIZE_FILE: - $field['type'] = 'image'; - $field['image'] = $this->imageRetriever->getCustomizationImage( - $data['value'] - ); - - break; - case Product::CUSTOMIZE_TEXTFIELD: - $field['type'] = 'text'; - $field['text'] = $data['value']; - - break; - default: - $field['type'] = null; - } - $field['label'] = $data['name']; - $field['id_module'] = $data['id_module']; - $presentedCustomization['id_customization'] = $data['id_customization']; - $presentedCustomization['fields'][] = $field; - } - } - - $product['up_quantity_url'] = $this->link->getUpQuantityCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - $product['down_quantity_url'] = $this->link->getDownQuantityCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - $product['remove_from_cart_url'] = $this->link->getRemoveFromCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - $product['update_quantity_url'] = $this->link->getUpdateQuantityCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - - $presentedCustomization['up_quantity_url'] = $this->link->getUpQuantityCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - - $presentedCustomization['down_quantity_url'] = $this->link->getDownQuantityCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - - $presentedCustomization['remove_from_cart_url'] = $this->link->getRemoveFromCartURL( - $product['id_product'], - $product['id_product_attribute'], - $presentedCustomization['id_customization'] - ); - - $presentedCustomization['update_quantity_url'] = $product['update_quantity_url']; - - $customizations[] = $presentedCustomization; - } - } - } - } - } - - usort($customizations, function (array $a, array $b) { - if ( - $a['quantity'] > $b['quantity'] - || count($a['fields']) > count($b['fields']) - || $a['id_customization'] > $b['id_customization'] - ) { - return -1; - } else { - return 1; - } - }); - - $product['customizations'] = $customizations; - - return $product; - }, $products); - } - - /** - * @param Cart $cart - * @param bool $shouldSeparateGifts - * - * @return array - * - * @throws \Exception - */ - public function present($cart, $shouldSeparateGifts = false) - { - if (!is_a($cart, 'Cart')) { - throw new \Exception('CartPresenter can only present instance of Cart'); - } - - if ($shouldSeparateGifts) { - $rawProducts = $cart->getProductsWithSeparatedGifts(); - } else { - $rawProducts = $cart->getProducts(true); - } - - $products = array_map([$this, 'presentProduct'], $rawProducts); - $products = $this->addCustomizedData($products, $cart); - $subtotals = []; - - $productsTotalExcludingTax = $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS); - $total_excluding_tax = $cart->getOrderTotal(false); - $total_including_tax = $cart->getOrderTotal(true); - $total_discount = $cart->getDiscountSubtotalWithoutGifts($this->includeTaxes()); - $totalCartAmount = $cart->getOrderTotal($this->includeTaxes(), Cart::ONLY_PRODUCTS); - - $subtotals['products'] = [ - 'type' => 'products', - 'label' => $this->translator->trans('Subtotal', [], 'Shop.Theme.Checkout'), - 'amount' => $totalCartAmount, - 'value' => $this->priceFormatter->format($totalCartAmount), - ]; - - if ($total_discount) { - $subtotals['discounts'] = [ - 'type' => 'discount', - 'label' => $this->translator->trans('Discount(s)', [], 'Shop.Theme.Checkout'), - 'amount' => $total_discount, - 'value' => $this->priceFormatter->format($total_discount), - ]; - } else { - $subtotals['discounts'] = null; - } - - if ($cart->gift) { - $giftWrappingPrice = ($cart->getGiftWrappingPrice($this->includeTaxes()) != 0) - ? $cart->getGiftWrappingPrice($this->includeTaxes()) - : 0; - - $subtotals['gift_wrapping'] = [ - 'type' => 'gift_wrapping', - 'label' => $this->translator->trans('Gift wrapping', [], 'Shop.Theme.Checkout'), - 'amount' => $giftWrappingPrice, - 'value' => ($giftWrappingPrice > 0) - ? $this->priceFormatter->convertAndFormat($giftWrappingPrice) - : $this->translator->trans('Free', [], 'Shop.Theme.Checkout'), - ]; - } - - if (!$cart->isVirtualCart()) { - $shippingCost = $cart->getTotalShippingCost(null, $this->includeTaxes()); - } else { - $shippingCost = 0; - } - $subtotals['shipping'] = [ - 'type' => 'shipping', - 'label' => $this->translator->trans('Shipping', [], 'Shop.Theme.Checkout'), - 'amount' => $shippingCost, - 'value' => $this->getShippingDisplayValue($cart, $shippingCost), - ]; - - $subtotals['tax'] = null; - if (Configuration::get('PS_TAX_DISPLAY')) { - $taxAmount = $total_including_tax - $total_excluding_tax; - $subtotals['tax'] = [ - 'type' => 'tax', - 'label' => ($this->includeTaxes()) - ? $this->translator->trans('Included taxes', [], 'Shop.Theme.Checkout') - : $this->translator->trans('Taxes', [], 'Shop.Theme.Checkout'), - 'amount' => $taxAmount, - 'value' => $this->priceFormatter->format($taxAmount), - ]; - } - - $totals = [ - 'total' => [ - 'type' => 'total', - 'label' => $this->translator->trans('Total', [], 'Shop.Theme.Checkout'), - 'amount' => $this->includeTaxes() ? $total_including_tax : $total_excluding_tax, - 'value' => $this->priceFormatter->format( - $this->includeTaxes() ? $total_including_tax : $total_excluding_tax - ), - ], - 'total_including_tax' => [ - 'type' => 'total', - 'label' => $this->translator->trans('Total (tax incl.)', [], 'Shop.Theme.Checkout'), - 'amount' => $total_including_tax, - 'value' => $this->priceFormatter->format($total_including_tax), - ], - 'total_excluding_tax' => [ - 'type' => 'total', - 'label' => $this->translator->trans('Total (tax excl.)', [], 'Shop.Theme.Checkout'), - 'amount' => $total_excluding_tax, - 'value' => $this->priceFormatter->format($total_excluding_tax), - ], - ]; - - $products_count = array_reduce($products, function ($count, $product) { - return $count + $product['quantity']; - }, 0); - - $summary_string = $products_count === 1 ? - $this->translator->trans('1 item', [], 'Shop.Theme.Checkout') : - $this->translator->trans('%count% items', ['%count%' => $products_count], 'Shop.Theme.Checkout'); - - $minimalPurchase = $this->priceFormatter->convertAmount((float) Configuration::get('PS_PURCHASE_MINIMUM')); - - Hook::exec('overrideMinimalPurchasePrice', [ - 'minimalPurchase' => &$minimalPurchase, - ]); - - // TODO: move it to a common parent, since it's copied in OrderPresenter and ProductPresenter - $labels = [ - 'tax_short' => ($this->includeTaxes()) - ? $this->translator->trans('(tax incl.)', [], 'Shop.Theme.Global') - : $this->translator->trans('(tax excl.)', [], 'Shop.Theme.Global'), - 'tax_long' => ($this->includeTaxes()) - ? $this->translator->trans('(tax included)', [], 'Shop.Theme.Global') - : $this->translator->trans('(tax excluded)', [], 'Shop.Theme.Global'), - ]; - - $discounts = $cart->getDiscounts(); - $vouchers = $this->getTemplateVarVouchers($cart); - - $cartRulesIds = array_flip(array_map( - function ($voucher) { - return $voucher['id_cart_rule']; - }, - $vouchers['added'] - )); - - $discounts = array_filter($discounts, function ($discount) use ($cartRulesIds, $cart) { - $voucherCustomerId = (int) $discount['id_customer']; - $voucherIsRestrictedToASingleCustomer = ($voucherCustomerId !== 0); - $voucherIsEmptyCode = empty($discount['code']); - if ($voucherIsRestrictedToASingleCustomer && $cart->id_customer !== $voucherCustomerId && $voucherIsEmptyCode) { - return false; - } - - return !array_key_exists($discount['id_cart_rule'], $cartRulesIds); - }); - - return [ - 'products' => $products, - 'totals' => $totals, - 'subtotals' => $subtotals, - 'products_count' => $products_count, - 'summary_string' => $summary_string, - 'labels' => $labels, - 'id_address_delivery' => $cart->id_address_delivery, - 'id_address_invoice' => $cart->id_address_invoice, - 'is_virtual' => $cart->isVirtualCart(), - 'vouchers' => $vouchers, - 'discounts' => $discounts, - 'minimalPurchase' => $minimalPurchase, - 'minimalPurchaseRequired' => ($productsTotalExcludingTax < $minimalPurchase) ? - $this->translator->trans( - 'A minimum shopping cart total of %amount% (tax excl.) is required to validate your order. Current cart total is %total% (tax excl.).', - [ - '%amount%' => $this->priceFormatter->format($minimalPurchase), - '%total%' => $this->priceFormatter->format($productsTotalExcludingTax), - ], - 'Shop.Theme.Checkout' - ) : - '', - ]; - } - - /** - * Accepts a cart object with the shipping cost amount and formats the shipping cost display value accordingly. - * If the shipping cost is 0, then we must check if this is because of a free carrier and thus display 'Free' or - * simply because the system was unable to determine shipping cost at this point and thus send an empty string to hide the shipping line. - * - * @param Cart $cart - * @param float $shippingCost - * - * @return string - */ - private function getShippingDisplayValue($cart, $shippingCost) - { - $shippingDisplayValue = ''; - - // if one of the applied cart rules have free shipping, then the shipping display value is 'Free' - foreach ($cart->getCartRules() as $rule) { - if ($rule['free_shipping'] && !$rule['carrier_restriction']) { - return $this->translator->trans('Free', [], 'Shop.Theme.Checkout'); - } - } - - if ($shippingCost != 0) { - $shippingDisplayValue = $this->priceFormatter->format($shippingCost); - } else { - $defaultCountry = null; - - if (isset(Context::getContext()->cookie->id_country)) { - $defaultCountry = new Country(Context::getContext()->cookie->id_country); - } - - $deliveryOptionList = $cart->getDeliveryOptionList($defaultCountry); - - if (isset($deliveryOptionList) && count($deliveryOptionList) > 0) { - foreach ($deliveryOptionList as $option) { - foreach ($option as $currentCarrier) { - if (isset($currentCarrier['is_free']) && $currentCarrier['is_free'] > 0) { - $shippingDisplayValue = $this->translator->trans('Free', [], 'Shop.Theme.Checkout'); - break 2; - } - } - } - } - } - - return $shippingDisplayValue; - } - - private function getTemplateVarVouchers(Cart $cart) - { - $cartVouchers = $cart->getCartRules(); - $vouchers = []; - - $cartHasTax = null === $cart->id ? false : $cart::getTaxesAverageUsed($cart); - $freeShippingAlreadySet = false; - foreach ($cartVouchers as $cartVoucher) { - $vouchers[$cartVoucher['id_cart_rule']]['id_cart_rule'] = $cartVoucher['id_cart_rule']; - $vouchers[$cartVoucher['id_cart_rule']]['name'] = $cartVoucher['name']; - $vouchers[$cartVoucher['id_cart_rule']]['code'] = $cartVoucher['code']; - $vouchers[$cartVoucher['id_cart_rule']]['reduction_percent'] = $cartVoucher['reduction_percent']; - $vouchers[$cartVoucher['id_cart_rule']]['reduction_currency'] = $cartVoucher['reduction_currency']; - - // Voucher reduction depending of the cart tax rule - // if $cartHasTax & voucher is tax excluded, set amount voucher to tax included - if ($cartHasTax && $cartVoucher['reduction_tax'] == '0') { - $cartVoucher['reduction_amount'] = $cartVoucher['reduction_amount'] * (1 + $cartHasTax / 100); - } - - $vouchers[$cartVoucher['id_cart_rule']]['reduction_amount'] = $cartVoucher['reduction_amount']; - - if ($this->cartVoucherHasGiftProductReduction($cartVoucher)) { - $cartVoucher['reduction_amount'] = $cartVoucher['value_real']; - } - - $totalCartVoucherReduction = 0; - - if (!$this->cartVoucherHasPercentReduction($cartVoucher) - && !$this->cartVoucherHasAmountReduction($cartVoucher) - && !$this->cartVoucherHasGiftProductReduction($cartVoucher)) { - $freeShippingOnly = true; - if ($freeShippingAlreadySet) { - unset($vouchers[$cartVoucher['id_cart_rule']]); - continue; - } else { - $freeShippingAlreadySet = true; - } - } else { - $freeShippingOnly = false; - $totalCartVoucherReduction = $this->includeTaxes() ? $cartVoucher['value_real'] : $cartVoucher['value_tax_exc']; - } - - // when a voucher has only a shipping reduction, the value displayed must be "Free Shipping" - if ($freeShippingOnly) { - $cartVoucher['reduction_formatted'] = $this->translator->trans( - 'Free shipping', - [], - 'Admin.Shipping.Feature' - ); - } else { - $cartVoucher['reduction_formatted'] = '-' . $this->priceFormatter->format($totalCartVoucherReduction); - } - $vouchers[$cartVoucher['id_cart_rule']]['reduction_formatted'] = $cartVoucher['reduction_formatted']; - $vouchers[$cartVoucher['id_cart_rule']]['delete_url'] = $this->link->getPageLink( - 'cart', - true, - null, - [ - 'deleteDiscount' => $cartVoucher['id_cart_rule'], - 'token' => Tools::getToken(false), - ] - ); - } - - return [ - 'allowed' => (int) CartRule::isFeatureActive(), - 'added' => $vouchers, - ]; - } - - /** - * @param array $cartVoucher - * - * @return bool - */ - private function cartVoucherHasFreeShipping($cartVoucher) - { - return !empty($cartVoucher['free_shipping']); - } - - /** - * @param array $cartVoucher - * - * @return bool - */ - private function cartVoucherHasPercentReduction($cartVoucher) - { - return isset($cartVoucher['reduction_percent']) - && $cartVoucher['reduction_percent'] > 0 - && $cartVoucher['reduction_amount'] == '0.00'; - } - - /** - * @param array $cartVoucher - * - * @return bool - */ - private function cartVoucherHasAmountReduction($cartVoucher) - { - return isset($cartVoucher['reduction_amount']) && $cartVoucher['reduction_amount'] > 0; - } - - /** - * @param array $cartVoucher - * - * @return bool - */ - private function cartVoucherHasGiftProductReduction($cartVoucher) - { - return !empty($cartVoucher['gift_product']); - } - - /** - * Receives a string containing a list of attributes affected to the product and returns them as an array. - * - * @param string $attributes - * - * @return array Converted attributes in an array - */ - protected function getAttributesArrayFromString($attributes) - { - $separator = Configuration::get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'); - $pattern = '/(?>(?P[^:]+:[^:]+)' . $separator . '+(?!' . $separator . '([^:' . $separator . '])+:))/'; - $attributesArray = []; - $matches = []; - if (!preg_match_all($pattern, $attributes . $separator, $matches)) { - return $attributesArray; - } - - foreach ($matches['attribute'] as $attribute) { - list($key, $value) = explode(':', $attribute); - $attributesArray[trim($key)] = ltrim($value); - } - - return $attributesArray; - } -} diff --git a/src/Adapter/Presenter/Module/ModulePresenter.php b/src/Adapter/Presenter/Module/ModulePresenter.php deleted file mode 100644 index f59ac848..00000000 --- a/src/Adapter/Presenter/Module/ModulePresenter.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Module; - -use Currency; -use Exception; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; - -class ModulePresenter implements PresenterInterface -{ - /** - * @var Currency - */ - private $currency; - - /** @var PriceFormatter */ - private $priceFormatter; - - public function __construct(Currency $currency, PriceFormatter $priceFormatter) - { - $this->currency = $currency; - $this->priceFormatter = $priceFormatter; - } - - /** - * @param Module $module - * - * @return array - */ - public function present($module) - { - if (!($module instanceof Module)) { - throw new Exception('ModulePresenter can only present instance of Module'); - } - - $attributes = $module->attributes->all(); - $attributes['picos'] = $this->addPicos($attributes); - $attributes['price'] = $this->getModulePrice($attributes['price']); - $attributes['starsRate'] = str_replace('.', '', round($attributes['avgRate'] * 2) / 2); // Round to the nearest 0.5 - - return [ - 'attributes' => $attributes, - 'disk' => $module->disk->all(), - 'database' => $module->database->all(), - ]; - } - - private function getModulePrice($prices) - { - $iso_code = $this->currency->iso_code; - if (array_key_exists($iso_code, $prices)) { - $prices['displayPrice'] = $this->priceFormatter->convertAndFormat($prices[$iso_code]); - $prices['raw'] = $prices[$iso_code]; - } else { - $prices['displayPrice'] = '$' . $prices['USD']; - $prices['raw'] = $prices['USD']; - } - - return $prices; - } - - /** - * Transform a collection of addons as a simple array of data. - * - * @param AddonsCollection|array $modules - * - * @return array - */ - public function presentCollection($modules) - { - $presentedProducts = []; - foreach ($modules as $name => $product) { - $presentedProducts[$name] = $this->present($product); - } - - return $presentedProducts; - } - - /** - * Generate the list of small icons to be displayed near the module name. - * - * @param array $attributes Attributes of presented module - * - * @return array - */ - private function addPicos(array $attributes) - { - $picos = []; - - // PrestaTrust display - if (!empty($attributes['prestatrust']) && !empty($attributes['prestatrust']->pico)) { - $text = ''; - $class = ''; - if (isset($attributes['prestatrust']->status)) { - $text = $attributes['prestatrust']->status ? 'OK' : 'KO'; - $class = $attributes['prestatrust']->status ? 'text-success' : 'text-warning'; - } - $picos['prestatrust'] = [ - 'img' => $attributes['prestatrust']->pico, - 'label' => 'prestatrust', - 'text' => $text, - 'class' => $class, - ]; - } - - return $picos; - } -} diff --git a/src/Adapter/Presenter/Object/ObjectPresenter.php b/src/Adapter/Presenter/Object/ObjectPresenter.php deleted file mode 100644 index ccbf27c3..00000000 --- a/src/Adapter/Presenter/Object/ObjectPresenter.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Object; - -use Exception; -use Hook; -use ObjectModel; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; - -class ObjectPresenter implements PresenterInterface -{ - /** - * @param ObjectModel $object - * - * @return array - * - * @throws Exception - */ - public function present($object) - { - if (!($object instanceof ObjectModel)) { - throw new Exception('ObjectPresenter can only present ObjectModel classes'); - } - - $presentedObject = []; - - $fields = $object::$definition['fields']; - foreach ($fields as $fieldName => $null) { - $presentedObject[$fieldName] = $object->{$fieldName}; - } - $presentedObject['id'] = $object->id; - - $mustRemove = ['deleted', 'active']; - foreach ($mustRemove as $fieldName) { - if (isset($presentedObject[$fieldName])) { - unset($presentedObject[$fieldName]); - } - } - - $this->filterHtmlContent($object::$definition['table'], $presentedObject, $object->getHtmlFields()); - - return $presentedObject; - } - - /** - * Execute filterHtml hook for html Content for objectPresenter. - * - * @param $type - * @param $presentedObject - * @param $htmlFields - */ - private function filterHtmlContent($type, &$presentedObject, $htmlFields) - { - if (!empty($htmlFields) && is_array($htmlFields)) { - $filteredHtml = Hook::exec( - 'filterHtmlContent', - [ - 'type' => $type, - 'htmlFields' => $htmlFields, - 'object' => $presentedObject, - ], - null, - false, - true, - false, - null, - true - ); - - if (!empty($filteredHtml['object'])) { - $presentedObject = $filteredHtml['object']; - } - } - } -} diff --git a/src/Adapter/Presenter/Order/OrderDetailLazyArray.php b/src/Adapter/Presenter/Order/OrderDetailLazyArray.php deleted file mode 100644 index 04704be1..00000000 --- a/src/Adapter/Presenter/Order/OrderDetailLazyArray.php +++ /dev/null @@ -1,257 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Cart; -use Configuration; -use Context; -use Currency; -use HistoryController; -use Order; -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShopBundle\Translation\TranslatorComponent; -use PrestaShopException; -use Tools; - -class OrderDetailLazyArray extends AbstractLazyArray -{ - /** - * @var Locale - */ - private $locale; - - /** - * @var Order - */ - private $order; - - /** - * @var Context - */ - private $context; - - /** - * @var TranslatorComponent - */ - private $translator; - - /** - * OrderDetailLazyArray constructor. - * - * @param Order $order - */ - public function __construct(Order $order) - { - $this->order = $order; - $this->context = Context::getContext(); - $this->translator = Context::getContext()->getTranslator(); - $this->locale = $this->context->getCurrentLocale(); - parent::__construct(); - } - - /** - * @arrayAccess - * - * @return int - */ - public function getId() - { - return $this->order->id; - } - - /** - * @arrayAccess - * - * @return string - */ - public function getReference() - { - return $this->order->reference; - } - - /** - * @arrayAccess - * - * @return string - * - * @throws PrestaShopException - */ - public function getOrderDate() - { - return Tools::displayDate($this->order->date_add, null, false); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getDetailsUrl() - { - return $this->context->link->getPageLink('order-detail', true, null, 'id_order=' . $this->order->id); - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getReorderUrl() - { - return HistoryController::getUrlToReorder((int) $this->order->id, $this->context); - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getInvoiceUrl() - { - return HistoryController::getUrlToInvoice($this->order, $this->context); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getGiftMessage() - { - return nl2br($this->order->gift_message); - } - - /** - * @arrayAccess - * - * @return int - */ - public function getIsReturnable() - { - return (int) $this->order->isReturnable(); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getPayment() - { - return $this->order->payment; - } - - /** - * @arrayAccess - * - * @return string - */ - public function getModule() - { - return $this->order->module; - } - - /** - * @arrayAccess - * - * @return bool - */ - public function getRecyclable() - { - return (bool) $this->order->recyclable; - } - - /** - * @arrayAccess - * - * @return bool - */ - public function getIsValid() - { - return $this->order->valid; - } - - /** - * @arrayAccess - * - * @return bool - */ - public function getIsVirtual() - { - $cart = new Cart($this->order->id_cart); - - return $cart->isVirtualCart(); - } - - /** - * @arrayAccess - * - * @return array - */ - public function getShipping() - { - $order = $this->order; - - $shippingList = $order->getShipping(); - $orderShipping = []; - - foreach ($shippingList as $shippingId => $shipping) { - if (isset($shipping['carrier_name']) && $shipping['carrier_name']) { - $orderShipping[$shippingId] = $shipping; - $orderShipping[$shippingId]['shipping_date'] = - Tools::displayDate($shipping['date_add'], null, false); - $orderShipping[$shippingId]['shipping_weight'] = - ($shipping['weight'] > 0) ? sprintf('%.3f', $shipping['weight']) . ' ' . - Configuration::get('PS_WEIGHT_UNIT') : '-'; - $shippingCost = - (!$order->getTaxCalculationMethod()) ? $shipping['shipping_cost_tax_excl'] - : $shipping['shipping_cost_tax_incl']; - $orderShipping[$shippingId]['shipping_cost'] = - ($shippingCost > 0) ? $this->locale->formatPrice($shippingCost, (Currency::getIsoCodeById((int) $order->id_currency))) - : $this->translator->trans('Free', [], 'Shop.Theme.Checkout'); - - $tracking_line = '-'; - if ($shipping['tracking_number']) { - if ($shipping['url'] && $shipping['tracking_number']) { - $tracking_line = '' . $shipping['tracking_number'] . ''; - } else { - $tracking_line = $shipping['tracking_number']; - } - } - - $orderShipping[$shippingId]['tracking'] = $tracking_line; - } - } - - return $orderShipping; - } -} diff --git a/src/Adapter/Presenter/Order/OrderLazyArray.php b/src/Adapter/Presenter/Order/OrderLazyArray.php deleted file mode 100644 index 85c54e19..00000000 --- a/src/Adapter/Presenter/Order/OrderLazyArray.php +++ /dev/null @@ -1,463 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Address; -use AddressFormat; -use Carrier; -use Cart; -use Configuration; -use Context; -use Currency; -use CustomerMessage; -use Doctrine\Common\Annotations\AnnotationException; -use Order; -use OrderReturn; -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; -use PrestaShop\PrestaShop\Adapter\Presenter\Cart\CartPresenter; -use PrestaShop\PrestaShop\Adapter\Presenter\Object\ObjectPresenter; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShopBundle\Translation\TranslatorComponent; -use PrestaShopException; -use ProductDownload; -use ReflectionException; -use TaxConfiguration; -use Tools; - -class OrderLazyArray extends AbstractLazyArray -{ - /** @var CartPresenter */ - private $cartPresenter; - - /** @var ObjectPresenter */ - private $objectPresenter; - - /** @var PriceFormatter */ - private $priceFormatter; - - /** @var TranslatorComponent */ - private $translator; - - /** @var TaxConfiguration */ - private $taxConfiguration; - - /** @var Order */ - private $order; - - /** @var OrderSubtotalLazyArray */ - private $subTotals; - - /** - * OrderArray constructor. - * - * @throws AnnotationException - * @throws ReflectionException - */ - public function __construct(Order $order) - { - $this->order = $order; - $this->cartPresenter = new CartPresenter(); - $this->objectPresenter = new ObjectPresenter(); - $this->priceFormatter = new PriceFormatter(); - $this->translator = Context::getContext()->getTranslator(); - $this->taxConfiguration = new TaxConfiguration(); - $this->subTotals = new OrderSubtotalLazyArray($this->order); - parent::__construct(); - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getTotals() - { - $amounts = $this->getAmounts(); - - return $amounts['totals']; - } - - /** - * @arrayAccess - * - * @return int - */ - public function getIdAddressInvoice() - { - return $this->order->id_address_invoice; - } - - /** - * @arrayAccess - * - * @return int - */ - public function getIdAddressDelivery() - { - return $this->order->id_address_delivery; - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getSubtotals() - { - return $this->subTotals; - } - - /** - * @arrayAccess - * - * @return int - */ - public function getProductsCount() - { - return count($this->getProducts()); - } - - /** - * @arrayAccess - * - * @return mixed - * - * @throws PrestaShopException - */ - public function getShipping() - { - $details = $this->getDetails(); - - return $details['shipping']; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getProducts() - { - $order = $this->order; - $cart = new Cart($order->id_cart); - - $orderProducts = $order->getProducts(); - $cartProducts = $this->cartPresenter->present($cart); - $orderPaid = $order->getCurrentOrderState() && $order->getCurrentOrderState()->paid; - - $includeTaxes = $this->includeTaxes(); - foreach ($orderProducts as &$orderProduct) { - // Use data from OrderDetail in case that the Product has been deleted - $orderProduct['name'] = $orderProduct['product_name']; - $orderProduct['quantity'] = $orderProduct['product_quantity']; - $orderProduct['id_product'] = $orderProduct['product_id']; - $orderProduct['id_product_attribute'] = $orderProduct['product_attribute_id']; - - $productPrice = $includeTaxes ? 'product_price_wt' : 'product_price'; - $totalPrice = $includeTaxes ? 'total_wt' : 'total_price'; - - $orderProduct['price'] = $this->priceFormatter->format( - $orderProduct[$productPrice], - Currency::getCurrencyInstance((int) $order->id_currency) - ); - $orderProduct['total'] = $this->priceFormatter->format( - $orderProduct[$totalPrice], - Currency::getCurrencyInstance((int) $order->id_currency) - ); - - if ($orderPaid && $orderProduct['is_virtual']) { - $id_product_download = ProductDownload::getIdFromIdProduct($orderProduct['product_id']); - $product_download = new ProductDownload($id_product_download); - if ($product_download->display_filename != '') { - $orderProduct['download_link'] = - $product_download->getTextLink(false, $orderProduct['download_hash']) - . '&id_order=' . (int) $order->id - . '&secure_key=' . $order->secure_key; - } - } - - foreach ($cartProducts['products'] as $cartProduct) { - if (($cartProduct['id_product'] === $orderProduct['id_product']) - && ($cartProduct['id_product_attribute'] === $orderProduct['id_product_attribute'])) { - if (isset($cartProduct['attributes'])) { - $orderProduct['attributes'] = $cartProduct['attributes']; - } else { - $orderProduct['attributes'] = []; - } - $orderProduct['cover'] = $cartProduct['cover']; - $orderProduct['unit_price_full'] = $cartProduct['unit_price_full']; - } - } - - OrderReturn::addReturnedQuantity($orderProducts, $order->id); - } - - $orderProducts = $this->cartPresenter->addCustomizedData($orderProducts, $cart); - - return $orderProducts; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getAmounts() - { - $order = $this->order; - - $amounts['subtotals'] = $this->subTotals; - - $amounts['totals'] = []; - $amount = $this->includeTaxes() ? $order->total_paid : $order->total_paid_tax_excl; - $amounts['totals']['total'] = [ - 'type' => 'total', - 'label' => $this->translator->trans('Total', [], 'Shop.Theme.Checkout'), - 'amount' => $amount, - 'value' => $this->priceFormatter->format($amount, Currency::getCurrencyInstance((int) $order->id_currency)), - ]; - - $amounts['totals']['total_paid'] = [ - 'type' => 'total_paid', - 'label' => $this->translator->trans('Total paid', [], 'Shop.Theme.Checkout'), - 'amount' => $order->total_paid_real, - 'value' => $this->priceFormatter->format( - $order->total_paid_real, - Currency::getCurrencyInstance((int) $order->id_currency) - ), - ]; - - $amounts['totals']['total_including_tax'] = [ - 'type' => 'total_including_tax', - 'label' => $this->translator->trans('Total (tax incl.)', [], 'Shop.Theme.Checkout'), - 'amount' => $order->total_paid_tax_incl, - 'value' => $this->priceFormatter->format( - $order->total_paid_tax_incl, - Currency::getCurrencyInstance((int) $order->id_currency) - ), - ]; - - $amounts['totals']['total_excluding_tax'] = [ - 'type' => 'total_excluding_tax', - 'label' => $this->translator->trans('Total (tax excl.)', [], 'Shop.Theme.Checkout'), - 'amount' => $order->total_paid_tax_excl, - 'value' => $this->priceFormatter->format( - $order->total_paid_tax_excl, - Currency::getCurrencyInstance((int) $order->id_currency) - ), - ]; - - return $amounts; - } - - /** - * @arrayAccess - * - * @return OrderDetailLazyArray - */ - public function getDetails() - { - return new OrderDetailLazyArray($this->order); - } - - /** - * @arrayAccess - * - * @return array - */ - public function getHistory() - { - $order = $this->order; - - $orderHistory = []; - $context = Context::getContext(); - $historyList = $order->getHistory($context->language->id, false, true); - - foreach ($historyList as $historyId => $history) { - if ($history['id_order_state'] == $order->current_state) { - $historyId = 'current'; - } - $orderHistory[$historyId] = $history; - $orderHistory[$historyId]['history_date'] = Tools::displayDate($history['date_add'], null, false); - $orderHistory[$historyId]['contrast'] = (Tools::getBrightness($history['color']) > 128) ? 'dark' : 'bright'; - } - - if (!isset($orderHistory['current'])) { - $orderHistory['current'] = $this->getDefaultHistory(); - } - - return $orderHistory; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getMessages() - { - $order = $this->order; - - $messages = []; - $customerMessages = CustomerMessage::getMessagesByOrderId((int) $order->id, false); - - foreach ($customerMessages as $cmId => $customerMessage) { - $messages[$cmId] = $customerMessage; - $messages[$cmId]['message'] = nl2br($customerMessage['message']); - $messages[$cmId]['message_date'] = Tools::displayDate($customerMessage['date_add'], null, true); - if (isset($customerMessage['elastname']) && $customerMessage['elastname']) { - $messages[$cmId]['name'] = $customerMessage['efirstname'] . ' ' . $customerMessage['elastname']; - } elseif ($customerMessage['clastname']) { - $messages[$cmId]['name'] = $customerMessage['cfirstname'] . ' ' . $customerMessage['clastname']; - } else { - $messages[$cmId]['name'] = Configuration::get('PS_SHOP_NAME'); - } - } - - return $messages; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getCarrier() - { - $order = $this->order; - - $carrier = new Carrier((int) $order->id_carrier, (int) $order->id_lang); - $orderCarrier = $this->objectPresenter->present($carrier); - $orderCarrier['name'] = ($carrier->name == '0') ? Configuration::get('PS_SHOP_NAME') : $carrier->name; - $orderCarrier['delay'] = $carrier->delay; - - return $orderCarrier; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getAddresses() - { - $order = $this->order; - - $orderAddresses = [ - 'delivery' => [], - 'invoice' => [], - ]; - - $addressDelivery = new Address((int) $order->id_address_delivery); - $addressInvoice = new Address((int) $order->id_address_invoice); - - if (!$order->isVirtual()) { - $orderAddresses['delivery'] = $this->objectPresenter->present($addressDelivery); - $orderAddresses['delivery']['formatted'] = - AddressFormat::generateAddress($addressDelivery, [], '
    '); - } - - $orderAddresses['invoice'] = $this->objectPresenter->present($addressInvoice); - $orderAddresses['invoice']['formatted'] = AddressFormat::generateAddress($addressInvoice, [], '
    '); - - return $orderAddresses; - } - - /** - * @arrayAccess - * - * @return string - */ - public function getFollowUp() - { - $order = $this->order; - - $carrier = $this->getCarrier(); - if (!empty($carrier['url']) && !empty($order->shipping_number)) { - return str_replace('@', $order->shipping_number, $carrier['url']); - } - - return ''; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getLabels() - { - return [ - 'tax_short' => ($this->includeTaxes()) - ? $this->translator->trans('(tax incl.)', [], 'Shop.Theme.Global') - : $this->translator->trans('(tax excl.)', [], 'Shop.Theme.Global'), - 'tax_long' => ($this->includeTaxes()) - ? $this->translator->trans('(tax included)', [], 'Shop.Theme.Global') - : $this->translator->trans('(tax excluded)', [], 'Shop.Theme.Global'), - ]; - } - - /** - * @return bool|mixed - */ - private function includeTaxes() - { - return $this->taxConfiguration->includeTaxes(); - } - - /** - * @return array - */ - private function getDefaultHistory() - { - return [ - 'id_order_state' => '', - 'invoice' => '', - 'send_email' => '', - 'module_name' => '', - 'color' => '', - 'unremovable' => '', - 'hidden' => '', - 'logable' => '', - 'delivery' => '', - 'shipped' => '', - 'paid' => '', - 'pdf_invoice' => '', - 'pdf_delivery' => '', - 'deleted' => '', - 'id_order_history' => '', - 'id_employee' => '', - 'id_order' => '', - 'date_add' => '', - 'employee_firstname' => '', - 'employee_lastname' => '', - 'ostate_name' => '', - 'history_date' => '', - 'contrast' => '', - ]; - } -} diff --git a/src/Adapter/Presenter/Order/OrderPresenter.php b/src/Adapter/Presenter/Order/OrderPresenter.php deleted file mode 100644 index 1c2c49bd..00000000 --- a/src/Adapter/Presenter/Order/OrderPresenter.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Exception; -use Order; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; - -class OrderPresenter implements PresenterInterface -{ - /** - * @param Order $order - * - * @return OrderLazyArray - * - * @throws Exception - */ - public function present($order) - { - if (!($order instanceof Order)) { - throw new Exception('OrderPresenter can only present instance of Order'); - } - - return new OrderLazyArray($order); - } -} diff --git a/src/Adapter/Presenter/Order/OrderReturnLazyArray.php b/src/Adapter/Presenter/Order/OrderReturnLazyArray.php deleted file mode 100644 index e92d966f..00000000 --- a/src/Adapter/Presenter/Order/OrderReturnLazyArray.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Link; -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; -use PrestaShopException; -use Tools; - -class OrderReturnLazyArray extends AbstractLazyArray -{ - /** - * @var string - */ - private $prefix; - - /** - * @var Link - */ - private $link; - - /** @var array */ - private $orderReturn; - - /** - * OrderReturnLazyArray constructor. - * - * @param string $prefix - * @param Link $link - * @param array $orderReturn - * - * @throws \ReflectionException - */ - public function __construct($prefix, Link $link, array $orderReturn) - { - $this->prefix = $prefix; - $this->link = $link; - $this->orderReturn = $orderReturn; - parent::__construct(); - $this->appendArray($orderReturn); - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getId() - { - return $this->orderReturn['id_order_return']; - } - - /** - * @arrayAccess - * - * @return string - */ - public function getDetailsUrl() - { - return $this->link->getPageLink( - 'order-detail', - true, - null, - 'id_order=' . (int) $this->orderReturn['id_order'] - ); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getReturnUrl() - { - return $this->link->getPageLink( - 'order-return', - true, - null, - 'id_order_return=' . (int) $this->orderReturn['id_order_return'] - ); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getReturnNumber() - { - return $this->prefix . sprintf('%06d', $this->orderReturn['id_order_return']); - } - - /** - * @arrayAccess - * - * @return string - * - * @throws PrestaShopException - */ - public function getReturnDate() - { - return Tools::displayDate($this->orderReturn['date_add'], null, false); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getPrintUrl() - { - return ($this->orderReturn['state'] == 2) - ? $this->link->getPageLink( - 'pdf-order-return', - true, - null, - 'id_order_return=' . (int) $this->orderReturn['id_order_return'] - ) - : ''; - } -} diff --git a/src/Adapter/Presenter/Order/OrderReturnPresenter.php b/src/Adapter/Presenter/Order/OrderReturnPresenter.php deleted file mode 100644 index f036f886..00000000 --- a/src/Adapter/Presenter/Order/OrderReturnPresenter.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Exception; -use Link; -use PrestaShop\PrestaShop\Adapter\Presenter\PresenterInterface; - -class OrderReturnPresenter implements PresenterInterface -{ - /** - * @var string - */ - private $prefix; - - /** - * @var Link - */ - private $link; - - /** - * OrderReturnPresenter constructor. - * - * @param $prefix - * @param Link $link - */ - public function __construct($prefix, Link $link) - { - $this->prefix = $prefix; - $this->link = $link; - } - - /** - * @param $orderReturn - * - * @return OrderReturnLazyArray - * - * @throws \ReflectionException - */ - public function present($orderReturn) - { - if (!is_array($orderReturn)) { - throw new Exception('orderReturnPresenter can only present order_return passed as array'); - } - - return new OrderReturnLazyArray($this->prefix, $this->link, $orderReturn); - } -} diff --git a/src/Adapter/Presenter/Order/OrderSubtotalLazyArray.php b/src/Adapter/Presenter/Order/OrderSubtotalLazyArray.php deleted file mode 100644 index 4e033b4e..00000000 --- a/src/Adapter/Presenter/Order/OrderSubtotalLazyArray.php +++ /dev/null @@ -1,224 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Order; - -use Cart; -use Configuration; -use Context; -use Currency; -use Order; -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShopBundle\Translation\TranslatorComponent; -use TaxConfiguration; - -class OrderSubtotalLazyArray extends AbstractLazyArray -{ - /** @var Order */ - private $order; - - /** @var Context */ - private $context; - - /** @var TaxConfiguration */ - private $taxConfiguration; - - /** @var PriceFormatter */ - private $priceFormatter; - - /** @var bool */ - private $includeTaxes; - - /** @var TranslatorComponent */ - private $translator; - - /** - * OrderSubtotalLazyArray constructor. - * - * @param Order $order - */ - public function __construct(Order $order) - { - $this->context = Context::getContext(); - $this->taxConfiguration = new TaxConfiguration(); - $this->includeTaxes = $this->includeTaxes(); - $this->priceFormatter = new PriceFormatter(); - $this->translator = Context::getContext()->getTranslator(); - $this->order = $order; - parent::__construct(); - } - - /** - * @arrayAccess - * - * @return array - */ - public function getProducts() - { - $totalProducts = ($this->includeTaxes) ? $this->order->total_products_wt : $this->order->total_products; - - return [ - 'type' => 'products', - 'label' => $this->translator->trans('Subtotal', [], 'Shop.Theme.Checkout'), - 'amount' => $totalProducts, - 'value' => $this->priceFormatter->format( - $totalProducts, - Currency::getCurrencyInstance((int) $this->order->id_currency) - ), - ]; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getDiscounts() - { - $discountAmount = ($this->includeTaxes) - ? $this->order->total_discounts_tax_incl - : $this->order->total_discounts_tax_excl; - if ((float) $discountAmount) { - return [ - 'type' => 'discount', - 'label' => $this->translator->trans('Discount', [], 'Shop.Theme.Checkout'), - 'amount' => $discountAmount, - 'value' => $this->priceFormatter->format( - $discountAmount, - Currency::getCurrencyInstance((int) $this->order->id_currency) - ), - ]; - } - - return [ - 'type' => 'discount', - 'label' => null, - 'amount' => null, - 'value' => '', - ]; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getShipping() - { - $cart = new Cart($this->order->id_cart); - if (!$cart->isVirtualCart()) { - $shippingCost = ($this->includeTaxes) - ? $this->order->total_shipping_tax_incl : $this->order->total_shipping_tax_excl; - - return [ - 'type' => 'shipping', - 'label' => $this->translator->trans('Shipping and handling', [], 'Shop.Theme.Checkout'), - 'amount' => $shippingCost, - 'value' => $shippingCost != 0 ? $this->priceFormatter->format( - $shippingCost, - Currency::getCurrencyInstance((int) $this->order->id_currency) - ) - : $this->translator->trans('Free', [], 'Shop.Theme.Checkout'), - ]; - } - - return [ - 'type' => 'shipping', - 'label' => null, - 'amount' => null, - 'value' => '', - ]; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getTax() - { - if (!Configuration::get('PS_TAX_DISPLAY')) { - return [ - 'type' => 'tax', - 'label' => null, - 'amount' => null, - 'value' => '', - ]; - } - - $tax = $this->order->total_paid_tax_incl - $this->order->total_paid_tax_excl; - - return [ - 'type' => 'tax', - 'label' => $this->translator->trans('Tax', [], 'Shop.Theme.Checkout'), - 'amount' => $tax, - 'value' => $this->priceFormatter->format( - $tax, - Currency::getCurrencyInstance((int) $this->order->id_currency) - ), - ]; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getGiftWrapping() - { - if ($this->order->gift) { - $giftWrapping = ($this->includeTaxes) - ? $this->order->total_wrapping_tax_incl - : $this->order->total_wrapping_tax_excl; - - return [ - 'type' => 'gift_wrapping', - 'label' => $this->translator->trans('Gift wrapping', [], 'Shop.Theme.Checkout'), - 'amount' => $giftWrapping, - 'value' => $this->priceFormatter->format( - $giftWrapping, - Currency::getCurrencyInstance((int) $this->order->id_currency) - ), - ]; - } - - return [ - 'type' => 'gift_wrapping', - 'label' => null, - 'amount' => null, - 'value' => '', - ]; - } - - /** - * @return bool - */ - private function includeTaxes() - { - return $this->taxConfiguration->includeTaxes(); - } -} diff --git a/src/Adapter/Presenter/PresenterInterface.php b/src/Adapter/Presenter/PresenterInterface.php deleted file mode 100644 index db13d403..00000000 --- a/src/Adapter/Presenter/PresenterInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter; - -interface PresenterInterface -{ - /** - * @param mixed $object - * - * @return array|AbstractLazyArray - */ - public function present($object); -} diff --git a/src/Adapter/Presenter/Product/ProductLazyArray.php b/src/Adapter/Presenter/Product/ProductLazyArray.php deleted file mode 100644 index 3038bd16..00000000 --- a/src/Adapter/Presenter/Product/ProductLazyArray.php +++ /dev/null @@ -1,1050 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Product; - -use Configuration; -use Hook; -use Language; -use Link; -use PrestaShop\Decimal\Number; -use PrestaShop\Decimal\Operation\Rounding; -use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever; -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever; -use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings; -use Product; -use Symfony\Component\Translation\Exception\InvalidArgumentException; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -class ProductLazyArray extends AbstractLazyArray -{ - /** - * @var ImageRetriever - */ - private $imageRetriever; - - /** - * @var Link - */ - private $link; - - /** - * @var PriceFormatter - */ - private $priceFormatter; - - /** - * @var ProductColorsRetriever - */ - private $productColorsRetriever; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ProductPresentationSettings - */ - protected $settings; - - /** - * @var array - */ - protected $product; - - /** - * @var Language - */ - private $language; - - public function __construct( - ProductPresentationSettings $settings, - array $product, - Language $language, - ImageRetriever $imageRetriever, - Link $link, - PriceFormatter $priceFormatter, - ProductColorsRetriever $productColorsRetriever, - TranslatorInterface $translator - ) { - $this->settings = $settings; - $this->product = $product; - $this->language = $language; - $this->imageRetriever = $imageRetriever; - $this->link = $link; - $this->priceFormatter = $priceFormatter; - $this->productColorsRetriever = $productColorsRetriever; - $this->translator = $translator; - - $this->fillImages( - $settings, - $product, - $language - ); - - $this->addPriceInformation( - $settings, - $product, - $language - ); - - $this->addQuantityInformation( - $settings, - $product, - $language - ); - - parent::__construct(); - $this->appendArray($this->product); - } - - /** - * @arrayAccess - * - * @return mixed - */ - public function getId() - { - return $this->product['id_product']; - } - - /** - * @arrayAccess - * - * @return array|mixed - */ - public function getAttributes() - { - if (isset($this->product['attributes'])) { - return $this->product['attributes']; - } - - return []; - } - - /** - * @arrayAccess - * - * @return bool - */ - public function getShowPrice() - { - return $this->shouldShowPrice($this->settings, $this->product); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getWeightUnit() - { - return Configuration::get('PS_WEIGHT_UNIT'); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getUrl() - { - return $this->getProductURL($this->product, $this->language); - } - - /** - * @arrayAccess - * - * @return string - */ - public function getCanonicalUrl() - { - return $this->getProductURL($this->product, $this->language, true); - } - - /** - * @arrayAccess - * - * @return string|null - */ - public function getAddToCartUrl() - { - if ($this->shouldEnableAddToCartButton($this->product, $this->settings)) { - return $this->link->getAddToCartURL( - $this->product['id_product'], - $this->product['id_product_attribute'] - ); - } - - return null; - } - - /** - * @arrayAccess - * - * @return array|bool - * - * @throws InvalidArgumentException - */ - public function getCondition() - { - if (empty($this->product['show_condition'])) { - return false; - } - - switch ($this->product['condition']) { - case 'new': - return [ - 'type' => 'new', - 'label' => $this->translator->trans('New product', [], 'Shop.Theme.Catalog'), - 'schema_url' => 'https://schema.org/NewCondition', - ]; - case 'used': - return [ - 'type' => 'used', - 'label' => $this->translator->trans('Used', [], 'Shop.Theme.Catalog'), - 'schema_url' => 'https://schema.org/UsedCondition', - ]; - - break; - case 'refurbished': - return [ - 'type' => 'refurbished', - 'label' => $this->translator->trans('Refurbished', [], 'Shop.Theme.Catalog'), - 'schema_url' => 'https://schema.org/RefurbishedCondition', - ]; - - break; - default: - return false; - } - } - - /** - * @arrayAccess - * - * @return string|null - */ - public function getDeliveryInformation() - { - if ($this->product['quantity'] > 0) { - return Configuration::get('PS_LABEL_DELIVERY_TIME_AVAILABLE', $this->language->id); - } elseif ($this->product['allow_oosp']) { - return Configuration::get('PS_LABEL_DELIVERY_TIME_OOSBOA', $this->language->id); - } - - return null; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getEmbeddedAttributes() - { - $whitelist = $this->getProductAttributeWhitelist(); - $embeddedProductAttributes = []; - foreach ($this->product as $attribute => $value) { - if (in_array($attribute, $whitelist)) { - $embeddedProductAttributes[$attribute] = $value; - } - } - - return $embeddedProductAttributes; - } - - /** - * @arrayAccess - * - * @return string|null - */ - public function getFileSizeFormatted() - { - if (!isset($this->product['attachments'])) { - return null; - } - foreach ($this->product['attachments'] as &$attachment) { - return Tools::formatBytes($attachment['file_size'], 2); - } - - return null; - } - - /** - * @arrayAccess - * - * @return array - * - * @throws \ReflectionException - */ - public function getAttachments() - { - foreach ($this->product['attachments'] as &$attachment) { - if (!isset($attachment['file_size_formatted'])) { - $attachment['file_size_formatted'] = Tools::formatBytes($attachment['file_size'], 2); - } - } - - return $this->product['attachments']; - } - - /** - * @arrayAccess - * - * @return array|mixed - */ - public function getQuantityDiscounts() - { - return (isset($this->product['quantity_discounts'])) ? $this->product['quantity_discounts'] : []; - } - - /** - * @arrayAccess - * - * @return mixed|null - */ - public function getReferenceToDisplay() - { - if (isset($this->product['attributes'])) { - foreach ($this->product['attributes'] as $attribute) { - if (isset($attribute['reference']) && $attribute['reference'] != null) { - return $attribute['reference']; - } - } - } - - if ('' !== $this->product['reference']) { - return $this->product['reference']; - } - - return null; - } - - /** - * @arrayAccess - * - * @return array|null - */ - public function getGroupedFeatures() - { - if ($this->product['features']) { - return $this->buildGroupedFeatures($this->product['features']); - } - - return null; - } - - /** - * @arrayAccess - * - * @return string - */ - public function getSeoAvailability() - { - $seoAvailability = 'https://schema.org/'; - if ($this->product['quantity'] > 0) { - $seoAvailability .= 'InStock'; - } elseif ($this->product['quantity'] <= 0 && $this->product['allow_oosp']) { - $seoAvailability .= 'PreOrder'; - } else { - $seoAvailability .= 'OutOfStock'; - } - - return $seoAvailability; - } - - /** - * @arrayAccess - * - * @return array - * - * @throws InvalidArgumentException - */ - public function getLabels() - { - return [ - 'tax_short' => ($this->settings->include_taxes) - ? $this->translator->trans('(tax incl.)', [], 'Shop.Theme.Global') - : $this->translator->trans('(tax excl.)', [], 'Shop.Theme.Global'), - 'tax_long' => ($this->settings->include_taxes) - ? $this->translator->trans('Tax included', [], 'Shop.Theme.Global') - : $this->translator->trans('Tax excluded', [], 'Shop.Theme.Global'), - ]; - } - - /** - * @arrayAccess - * - * @return array|null - */ - public function getEcotax() - { - if (isset($this->product['ecotax'])) { - return [ - 'value' => $this->priceFormatter->format($this->product['ecotax']), - 'amount' => $this->product['ecotax'], - 'rate' => $this->product['ecotax_rate'], - ]; - } - - return null; - } - - /** - * @arrayAccess - * - * @return array - * - * @throws InvalidArgumentException - */ - public function getFlags() - { - $flags = []; - - $show_price = $this->shouldShowPrice($this->settings, $this->product); - - if ($show_price && $this->product['online_only']) { - $flags['online-only'] = [ - 'type' => 'online-only', - 'label' => $this->translator->trans('Online only', [], 'Shop.Theme.Catalog'), - ]; - } - - if ($show_price && $this->product['on_sale'] && !$this->settings->catalog_mode) { - $flags['on-sale'] = [ - 'type' => 'on-sale', - 'label' => $this->translator->trans('On sale!', [], 'Shop.Theme.Catalog'), - ]; - } - - if ($show_price && $this->product['reduction']) { - if ($this->product['discount_type'] === 'percentage') { - $flags['discount'] = [ - 'type' => 'discount', - 'label' => $this->product['discount_percentage'], - ]; - } elseif ($this->product['discount_type'] === 'amount') { - $flags['discount'] = [ - 'type' => 'discount', - 'label' => $this->product['discount_amount_to_display'], - ]; - } else { - $flags['discount'] = [ - 'type' => 'discount', - 'label' => $this->translator->trans('Reduced price', [], 'Shop.Theme.Catalog'), - ]; - } - } - - if ($this->product['new']) { - $flags['new'] = [ - 'type' => 'new', - 'label' => $this->translator->trans('New', [], 'Shop.Theme.Catalog'), - ]; - } - - if ($this->product['pack']) { - $flags['pack'] = [ - 'type' => 'pack', - 'label' => $this->translator->trans('Pack', [], 'Shop.Theme.Catalog'), - ]; - } - - Hook::exec('actionProductFlagsModifier', [ - 'flags' => &$flags, - 'product' => $this->product, - ]); - - return $flags; - } - - /** - * @arrayAccess - * - * @return array - */ - public function getMainVariants() - { - $colors = $this->productColorsRetriever->getColoredVariants($this->product['id_product']); - - if (!is_array($colors)) { - return []; - } - - return array_map(function (array $color) { - $color['add_to_cart_url'] = $this->link->getAddToCartURL( - $color['id_product'], - $color['id_product_attribute'] - ); - $color['url'] = $this->getProductURL($color, $this->language); - $color['type'] = 'color'; - $color['html_color_code'] = $color['color']; - unset($color['color']); - - return $color; - }, $colors); - } - - /** - * @arrayAccess - * - * @return 0|null - */ - public function getSpecificReferences() - { - if (isset($this->product['attributes']) && !isset($this->product['cart_quantity'])) { - $specificReferences = array_slice($this->product['attributes'], 0)[0]; - //this attributes should not be displayed in FO - unset( - $specificReferences['id_attribute'], - $specificReferences['id_attribute_group'], - $specificReferences['name'], - $specificReferences['group'], - $specificReferences['reference'] - ); - - //if the attribute's references doesn't exist then get the product's references or unset it - foreach ($specificReferences as $key => $value) { - if (empty($value)) { - $translatedKey = $this->getTranslatedKey($key); - unset($specificReferences[$key]); - if (!empty($this->product[$key])) { - $specificReferences[$translatedKey] = $this->product[$key]; - } - } - } - - if (empty($specificReferences)) { - $specificReferences = null; - } - - return $specificReferences; - } - - return null; - } - - /** - * Prices should be shown for products with active "Show price" option - * and customer groups with active "Show price" option. - * - * @param ProductPresentationSettings $settings - * @param array $product - * - * @return bool - */ - private function shouldShowPrice( - ProductPresentationSettings $settings, - array $product - ) { - return $settings->shouldShowPrice() && (bool) $product['show_price']; - } - - /** - * The "Add to cart" button should be shown for products available for order. - * - * @param $product - * - * @return mixed - */ - private function shouldShowAddToCartButton($product) - { - return (bool) $product['available_for_order']; - } - - private function fillImages( - ProductPresentationSettings $settings, - array $product, - Language $language - ) { - // Get all product images, including potential cover - $productImages = $this->imageRetriever->getAllProductImages( - $product, - $language - ); - - // Get filtered product images matching the specified id_product_attribute - $this->product['images'] = $this->filterImagesForCombination($productImages, $product['id_product_attribute']); - - // Get default image for selected combination (used for product page, cart details, ...) - $this->product['default_image'] = reset($this->product['images']); - foreach ($this->product['images'] as $image) { - // If one of the image is a cover it is used as such - if (isset($image['cover']) && null !== $image['cover']) { - $this->product['default_image'] = $image; - - break; - } - } - - // Get generic product image, used for product listing - if (isset($product['cover_image_id'])) { - // First try to find cover in product images - foreach ($productImages as $productImage) { - if ($productImage['id_image'] == $product['cover_image_id']) { - $this->product['cover'] = $productImage; - break; - } - } - - // If the cover is not associated to the product images it is fetched manually - if (!isset($this->product['cover'])) { - $coverImage = $this->imageRetriever->getImage(new Product($product['id_product'], false, $language->getId()), $product['cover_image_id']); - $this->product['cover'] = array_merge($coverImage, [ - 'legend' => $coverImage['legend'], - ]); - } - } - - // If no cover fallback on default image - if (!isset($this->product['cover'])) { - $this->product['cover'] = $this->product['default_image']; - } - } - - /** - * @param array $images - * @param int $productAttributeId - * - * @return array - */ - private function filterImagesForCombination(array $images, int $productAttributeId) - { - $filteredImages = []; - - foreach ($images as $image) { - if (in_array($productAttributeId, $image['associatedVariants'])) { - $filteredImages[] = $image; - } - } - - return (0 === count($filteredImages)) ? $images : $filteredImages; - } - - private function addPriceInformation( - ProductPresentationSettings $settings, - array $product, - Language $language - ) { - $this->product['has_discount'] = false; - $this->product['discount_type'] = null; - $this->product['discount_percentage'] = null; - $this->product['discount_percentage_absolute'] = null; - $this->product['discount_amount'] = null; - $this->product['discount_amount_to_display'] = null; - - if ($settings->include_taxes) { - $price = $regular_price = $product['price']; - } else { - $price = $regular_price = $product['price_tax_exc']; - } - - if ($product['specific_prices']) { - $this->product['has_discount'] = (0 != $product['reduction']); - $this->product['discount_type'] = $product['specific_prices']['reduction_type']; - - $absoluteReduction = new Number($product['specific_prices']['reduction']); - $absoluteReduction = $absoluteReduction->times(new Number('100')); - $negativeReduction = $absoluteReduction->toNegative(); - $presAbsoluteReduction = $absoluteReduction->round(2, Rounding::ROUND_HALF_UP); - $presNegativeReduction = $negativeReduction->round(2, Rounding::ROUND_HALF_UP); - - // TODO: add percent sign according to locale preferences - $this->product['discount_percentage'] = Tools::displayNumber($presNegativeReduction) . '%'; - $this->product['discount_percentage_absolute'] = Tools::displayNumber($presAbsoluteReduction) . '%'; - if ($settings->include_taxes) { - $regular_price = $product['price_without_reduction']; - $this->product['discount_amount'] = $this->priceFormatter->format( - $product['reduction'] - ); - } else { - $regular_price = $product['price_without_reduction_without_tax']; - $this->product['discount_amount'] = $this->priceFormatter->format( - $product['reduction_without_tax'] - ); - } - $this->product['discount_amount_to_display'] = '-' . $this->product['discount_amount']; - } - - $this->product['price_amount'] = $price; - $this->product['price'] = $this->priceFormatter->format($price); - $this->product['regular_price_amount'] = $regular_price; - $this->product['regular_price'] = $this->priceFormatter->format($regular_price); - - if ($product['reduction'] < $product['price_without_reduction']) { - $this->product['discount_to_display'] = $this->product['discount_amount']; - } else { - $this->product['discount_to_display'] = $this->product['regular_price']; - } - - if (isset($product['unit_price']) && $product['unit_price']) { - $this->product['unit_price'] = $this->priceFormatter->format($product['unit_price']); - $this->product['unit_price_full'] = $this->priceFormatter->format($product['unit_price']) - . ' ' . $product['unity']; - } else { - $this->product['unit_price'] = $this->product['unit_price_full'] = ''; - } - } - - /** - * @param array $product - * @param ProductPresentationSettings $settings - * - * @return bool - */ - protected function shouldEnableAddToCartButton(array $product, ProductPresentationSettings $settings) - { - if (($product['customizable'] == 2 || !empty($product['customization_required']))) { - $shouldEnable = false; - - if (isset($product['customizations'])) { - $shouldEnable = true; - foreach ($product['customizations']['fields'] as $field) { - if ($field['required'] && !$field['is_customized']) { - $shouldEnable = false; - } - } - } - } else { - $shouldEnable = true; - } - - $shouldEnable = $shouldEnable && $this->shouldShowAddToCartButton($product); - - if ($settings->stock_management_enabled - && !$product['allow_oosp'] - && ($product['quantity'] <= 0 - || $product['quantity'] - $this->getQuantityWanted() < 0 - || $product['quantity'] - $this->getMinimalQuantity() < 0) - ) { - $shouldEnable = false; - } - - return $shouldEnable; - } - - /** - * @return int Quantity of product requested by the customer - */ - private function getQuantityWanted() - { - return (int) Tools::getValue('quantity_wanted', 1); - } - - /** - * @return int Minimal quantity of product requested by the customer - */ - private function getMinimalQuantity() - { - return (int) $this->product['minimal_quantity']; - } - - /** - * {@inheritdoc} - * - * @param array $product - * @param Language $language - * @param bool $canonical - * - * @return string - */ - private function getProductURL( - array $product, - Language $language, - $canonical = false - ) { - $linkRewrite = isset($product['link_rewrite']) ? $product['link_rewrite'] : null; - $category = isset($product['category']) ? $product['category'] : null; - $ean13 = isset($product['ean13']) ? $product['ean13'] : null; - - return $this->link->getProductLink( - $product['id_product'], - $linkRewrite, - $category, - $ean13, - $language->id, - null, - !$canonical && $product['id_product_attribute'] > 0 ? $product['id_product_attribute'] : null, - false, - false, - true - ); - } - - /** - * @param ProductPresentationSettings $settings - * @param array $product - * @param Language $language - */ - public function addQuantityInformation( - ProductPresentationSettings $settings, - array $product, - Language $language - ) { - $show_price = $this->shouldShowPrice($settings, $product); - $show_availability = $show_price && $settings->stock_management_enabled; - $this->product['show_availability'] = $show_availability; - $product['quantity_wanted'] = $this->getQuantityWanted(); - - if (isset($product['available_date']) && '0000-00-00' == $product['available_date']) { - $product['available_date'] = null; - } - - if ($show_availability) { - if ($product['quantity'] - $product['quantity_wanted'] >= 0) { - $this->product['availability_date'] = $product['available_date']; - - if ($product['quantity'] < $settings->lastRemainingItems) { - $this->applyLastItemsInStockDisplayRule(); - } else { - $this->product['availability_message'] = $product['available_now'] ? $product['available_now'] - : Configuration::get('PS_LABEL_IN_STOCK_PRODUCTS', $language->id); - $this->product['availability'] = 'available'; - } - } elseif ($product['allow_oosp']) { - $this->product['availability_message'] = $product['available_later'] ? $product['available_later'] - : Configuration::get('PS_LABEL_OOS_PRODUCTS_BOA', $language->id); - $this->product['availability_date'] = $product['available_date']; - $this->product['availability'] = 'available'; - } elseif ($product['quantity_wanted'] > 0 && $product['quantity'] > 0) { - $this->product['availability_message'] = $this->translator->trans( - 'There are not enough products in stock', - [], - 'Shop.Notifications.Error' - ); - $this->product['availability'] = 'unavailable'; - $this->product['availability_date'] = null; - } elseif (!empty($product['quantity_all_versions']) && $product['quantity_all_versions'] > 0) { - $this->product['availability_message'] = $this->translator->trans( - 'Product available with different options', - [], - 'Shop.Theme.Catalog' - ); - $this->product['availability_date'] = $product['available_date']; - $this->product['availability'] = 'unavailable'; - } else { - $this->product['availability_message'] = - Configuration::get('PS_LABEL_OOS_PRODUCTS_BOD', $language->id); - $this->product['availability_date'] = $product['available_date']; - $this->product['availability'] = 'unavailable'; - } - } else { - $this->product['availability_message'] = null; - $this->product['availability_date'] = null; - $this->product['availability'] = null; - } - } - - /** - * Override availability message. - */ - protected function applyLastItemsInStockDisplayRule() - { - $this->product['availability_message'] = $this->translator->trans( - 'Last items in stock', - [], - 'Shop.Theme.Catalog' - ); - $this->product['availability'] = 'last_remaining_items'; - } - - /** - * @param string $key - * - * @return string - */ - private function getTranslatedKey($key) - { - switch ($key) { - case 'ean13': - return $this->translator->trans('ean13', [], 'Shop.Theme.Catalog'); - case 'isbn': - return $this->translator->trans('isbn', [], 'Shop.Theme.Catalog'); - case 'upc': - return $this->translator->trans('upc', [], 'Shop.Theme.Catalog'); - case 'mpn': - return $this->translator->trans('MPN', [], 'Shop.Theme.Catalog'); - } - - return $key; - } - - /** - * @return array - */ - protected function getProductAttributeWhitelist() - { - return [ - 'add_to_cart_url', - 'additional_shipping_cost', - 'advanced_stock_management', - 'allow_oosp', - 'attachments', - 'attribute_price', - 'attributes', - 'availability', - 'availability_date', - 'availability_message', - 'available_date', - 'available_for_order', - 'available_later', - 'available_now', - 'cache_default_attribute', - 'canonical_url', - 'category', - 'category_name', - 'condition', - 'cover', - 'customer_group_discount', - 'customizable', - 'customization_required', - 'customizations', - 'date_add', - 'date_upd', - 'delivery_in_stock', - 'delivery_out_stock', - 'description', - 'description_short', - 'discount_amount', - 'discount_amount_to_display', - 'discount_percentage', - 'discount_percentage_absolute', - 'discount_type', - 'ecotax', - 'ecotax_rate', - 'extraContent', - 'features', - 'flags', - 'has_discount', - 'id', - 'id_category_default', - 'id_customization', - 'id_image', - 'id_manufacturer', - 'id_product', - 'id_product_attribute', - 'id_shop_default', - 'id_supplier', - 'id_type_redirected', - 'images', - 'indexed', - 'is_customizable', - 'is_virtual', - 'labels', - 'link', - 'link_rewrite', - 'low_stock_alert', - 'low_stock_threshold', - 'main_variants', - 'meta_description', - 'meta_keywords', - 'meta_title', - 'minimal_quantity', - 'name', - 'new', - 'nopackprice', - 'on_sale', - 'online_only', - 'out_of_stock', - 'pack', - 'pack_stock_type', - 'packItems', - 'price', - 'price_amount', - 'price_tax_exc', - 'price_without_reduction', - 'quantity', - 'quantity_all_versions', - 'quantity_discounts', - 'quantity_label', - 'quantity_wanted', - 'rate', - 'redirect_type', - 'reduction', - 'reference', - 'reference_to_display', - 'show_availability', - 'show_condition', - 'show_price', - 'show_quantities', - 'specific_prices', - 'tax_name', - 'text_fields', - 'unit_price', - 'unit_price_full', - 'unit_price_ratio', - 'unity', - 'uploadable_files', - 'url', - 'virtual', - 'visibility', - 'weight_unit', - ]; - } - - /** - * Assemble the same features in one array. - * - * @param array $productFeatures - * - * @return array - */ - protected function buildGroupedFeatures(array $productFeatures) - { - $valuesByFeatureName = []; - $groupedFeatures = []; - - // features can either be "raw" (id_feature, id_product_id_feature_value) - // or "full" (id_feature, name, value) - // grouping can only be performed if they are "full" - if (empty($productFeatures) || !array_key_exists('name', reset($productFeatures))) { - return []; - } - - foreach ($productFeatures as $feature) { - $featureName = $feature['name']; - // build an array of unique features - $groupedFeatures[$featureName] = $feature; - // aggregate feature values separately - $valuesByFeatureName[$featureName][] = $feature['value']; - } - - // replace value from features that have multiple values with the ones we aggregated earlier - foreach ($valuesByFeatureName as $featureName => $values) { - if (count($values) > 1) { - sort($values, SORT_NATURAL); - $groupedFeatures[$featureName]['value'] = implode("\n", $values); - } - } - - return $groupedFeatures; - } -} diff --git a/src/Adapter/Presenter/Product/ProductListingLazyArray.php b/src/Adapter/Presenter/Product/ProductListingLazyArray.php deleted file mode 100644 index f9bcd5fc..00000000 --- a/src/Adapter/Presenter/Product/ProductListingLazyArray.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Product; - -use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings; - -class ProductListingLazyArray extends ProductLazyArray -{ - /** - * @arrayAccess - * - * @return string|null - */ - public function getAddToCartUrl() - { - if ($this->product['id_product_attribute'] != 0 && !$this->settings->allow_add_variant_to_cart_from_listing) { - return null; - } - - if ($this->product['customizable'] == 2 || !empty($this->product['customization_required'])) { - return null; - } - - return parent::getAddToCartUrl(); - } - - /** - * @param array $product - * @param ProductPresentationSettings $settings - * - * @return bool - */ - protected function shouldEnableAddToCartButton(array $product, ProductPresentationSettings $settings) - { - if (isset($product['attributes']) - && count($product['attributes']) > 0 - && !$settings->allow_add_variant_to_cart_from_listing) { - return false; - } - - return parent::shouldEnableAddToCartButton($product, $settings); - } -} diff --git a/src/Adapter/Presenter/Product/ProductListingPresenter.php b/src/Adapter/Presenter/Product/ProductListingPresenter.php deleted file mode 100644 index dfaa7516..00000000 --- a/src/Adapter/Presenter/Product/ProductListingPresenter.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Product; - -use Language; -use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings; - -class ProductListingPresenter extends ProductPresenter -{ - /** - * @param ProductPresentationSettings $settings - * @param array $product - * @param Language $language - * - * @return ProductLazyArray|ProductListingLazyArray - * - * @throws \ReflectionException - */ - public function present( - ProductPresentationSettings $settings, - array $product, - Language $language - ) { - return new ProductListingLazyArray( - $settings, - $product, - $language, - $this->imageRetriever, - $this->link, - $this->priceFormatter, - $this->productColorsRetriever, - $this->translator - ); - } -} diff --git a/src/Adapter/Presenter/Product/ProductPresenter.php b/src/Adapter/Presenter/Product/ProductPresenter.php deleted file mode 100644 index 866152d9..00000000 --- a/src/Adapter/Presenter/Product/ProductPresenter.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Presenter\Product; - -use Language; -use Link; -use PrestaShop\PrestaShop\Adapter\Image\ImageRetriever; -use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter; -use PrestaShop\PrestaShop\Adapter\Product\ProductColorsRetriever; -use PrestaShop\PrestaShop\Core\Product\ProductPresentationSettings; -use Symfony\Component\Translation\TranslatorInterface; - -class ProductPresenter -{ - /** - * @var ImageRetriever - */ - protected $imageRetriever; - - /** - * @var Link - */ - protected $link; - - /** - * @var PriceFormatter - */ - protected $priceFormatter; - - /** - * @var ProductColorsRetriever - */ - protected $productColorsRetriever; - - /** - * @var TranslatorInterface - */ - protected $translator; - - public function __construct( - ImageRetriever $imageRetriever, - Link $link, - PriceFormatter $priceFormatter, - ProductColorsRetriever $productColorsRetriever, - TranslatorInterface $translator - ) { - $this->imageRetriever = $imageRetriever; - $this->link = $link; - $this->priceFormatter = $priceFormatter; - $this->productColorsRetriever = $productColorsRetriever; - $this->translator = $translator; - } - - public function present( - ProductPresentationSettings $settings, - array $product, - Language $language - ) { - return new ProductLazyArray( - $settings, - $product, - $language, - $this->imageRetriever, - $this->link, - $this->priceFormatter, - $this->productColorsRetriever, - $this->translator - ); - } -} diff --git a/src/Adapter/PricesDrop/PricesDropProductSearchProvider.php b/src/Adapter/PricesDrop/PricesDropProductSearchProvider.php deleted file mode 100644 index 1b99fda0..00000000 --- a/src/Adapter/PricesDrop/PricesDropProductSearchProvider.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\PricesDrop; - -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrder; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Product; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Used to query the Prices Drop, see PricesDropController in Front Office. - */ -class PricesDropProductSearchProvider implements ProductSearchProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var SortOrderFactory - */ - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * @param string $type - * - * @return array - */ - private function getProductsOrCount( - ProductSearchContext $context, - ProductSearchQuery $query, - $type = 'products' - ) { - return Product::getPricesDrop( - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $type !== 'products', - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay() - ); - } - - /** - * {@inheritdoc} - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - if (!$products = $this->getProductsOrCount($context, $query, 'products')) { - $products = []; - } - $count = $this->getProductsOrCount($context, $query, 'count'); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - [ - (new SortOrder('product', 'name', 'asc'))->setLabel( - $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'desc'))->setLabel( - $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'asc'))->setLabel( - $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'desc'))->setLabel( - $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog') - ), - ] - ); - } - - return $result; - } -} diff --git a/src/Adapter/Product/AdminProductDataProvider.php b/src/Adapter/Product/AdminProductDataProvider.php deleted file mode 100644 index de200287..00000000 --- a/src/Adapter/Product/AdminProductDataProvider.php +++ /dev/null @@ -1,472 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use AppKernel; -use Configuration; -use Context; -use Currency; -use Db; -use DbQuery; -use Doctrine\ORM\EntityManager; -use Hook; -use PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder; -use PrestaShop\PrestaShop\Adapter\ImageManager; -use PrestaShop\PrestaShop\Adapter\Validate; -use PrestaShopBundle\Entity\AdminFilter; -use PrestaShopBundle\Service\DataProvider\Admin\ProductInterface; -use Product; -use Psr\Cache\CacheItemPoolInterface; -use StockAvailable; -use Tools; - -/** - * Data provider for new Architecture, about Product object model. - * - * This class will provide data from DB / ORM about Products for the Admin interface. - * This is an Adapter that works with the Legacy code and persistence behaviors. - */ -class AdminProductDataProvider extends AbstractAdminQueryBuilder implements ProductInterface -{ - /** - * @var EntityManager - */ - private $entityManager; - - /** - * @var ImageManager - */ - private $imageManager; - - /** - * @var CacheItemPoolInterface - */ - private $cache; - - public function __construct( - EntityManager $entityManager, - ImageManager $imageManager, - CacheItemPoolInterface $cache - ) { - $this->entityManager = $entityManager; - $this->imageManager = $imageManager; - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function getPersistedFilterParameters() - { - $employee = Context::getContext()->employee; - $employeeId = $employee->id ?: 0; - - $cachedFilters = $this->cache->getItem("app.product_filters_${employeeId}"); - - if (!$cachedFilters->isHit()) { - $shop = Context::getContext()->shop; - $filter = $this->entityManager->getRepository('PrestaShopBundle:AdminFilter')->findOneBy([ - 'employee' => $employeeId, - 'shop' => $shop->id ?: 0, - 'controller' => 'ProductController', - 'action' => 'catalogAction', - ]); - - /** @var $filter AdminFilter */ - if (null === $filter) { - $filters = AdminFilter::getProductCatalogEmptyFilter(); - } else { - $filters = $filter->getProductCatalogFilter(); - } - - $cachedFilters->set($filters); - $this->cache->save($cachedFilters); - } - - return $cachedFilters->get(); - } - - /** - * {@inheritdoc} - */ - public function isCategoryFiltered() - { - $filters = $this->getPersistedFilterParameters(); - - return !empty($filters['filter_category']) && $filters['filter_category'] > 0; - } - - /** - * {@inheritdoc} - */ - public function isColumnFiltered() - { - $filters = $this->getPersistedFilterParameters(); - foreach ($filters as $filterKey => $filterValue) { - if (strpos($filterKey, 'filter_column_') === 0 && $filterValue !== '') { - return true; // break at first column filter found - } - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function persistFilterParameters(array $parameters) - { - $employee = Context::getContext()->employee; - $shop = Context::getContext()->shop; - $filter = $this->entityManager->getRepository('PrestaShopBundle:AdminFilter')->findOneBy([ - 'employee' => $employee->id ?: 0, - 'shop' => $shop->id ?: 0, - 'controller' => 'ProductController', - 'action' => 'catalogAction', - ]); - - if (!$filter) { - $filter = new AdminFilter(); - $filter->setEmployee($employee->id ?: 0)->setShop($shop->id ?: 0)->setController('ProductController')->setAction('catalogAction'); - } - - $filter->setProductCatalogFilter($parameters); - $this->entityManager->persist($filter); - - // if each filter is == '', then remove item from DB :) - if (count(array_diff($filter->getProductCatalogFilter(), [''])) == 0) { - $this->entityManager->remove($filter); - } - - $this->entityManager->flush(); - - //Flush cache - $employee = Context::getContext()->employee; - $employeeId = $employee->id ?: 0; - - $this->cache->deleteItem("app.product_filters_${employeeId}"); - } - - /** - * {@inheritdoc} - */ - public function combinePersistentCatalogProductFilter($paramsIn = [], $avoidPersistence = false) - { - // retrieve persisted filter parameters - $persistedParams = $this->getPersistedFilterParameters(); - // merge with new values - $paramsOut = array_merge($persistedParams, (array) $paramsIn); - // persist new values - if (!$avoidPersistence) { - $this->persistFilterParameters($paramsOut); - } - - // return new values - return $paramsOut; - } - - /** - * {@inheritdoc} - */ - public function getCatalogProductList( - $offset, - $limit, - $orderBy, - $sortOrder, - $post = [], - $avoidPersistence = false, - $formatCldr = true - ) { - $offset = (int) $offset; - $limit = (int) $limit; - $orderBy = Validate::isOrderBy($orderBy) ? $orderBy : 'id_product'; - $sortOrder = Validate::isOrderWay($sortOrder) ? $sortOrder : 'desc'; - - $filterParams = $this->combinePersistentCatalogProductFilter(array_merge( - $post, - ['last_offset' => $offset, 'last_limit' => $limit, 'last_orderBy' => $orderBy, 'last_sortOrder' => $sortOrder] - ), $avoidPersistence); - $filterParams = AdminFilter::sanitizeFilterParameters($filterParams); - - $showPositionColumn = $this->isCategoryFiltered(); - if ($orderBy == 'position_ordering' && $showPositionColumn) { - foreach ($filterParams as $key => $param) { - if (strpos($key, 'filter_column_') === 0) { - $filterParams[$key] = ''; - } - } - } - if ($orderBy == 'position_ordering') { - $orderBy = 'position'; - } - - $idShop = Context::getContext()->shop->id; - $idLang = Context::getContext()->language->id; - - $sqlSelect = [ - 'id_product' => ['table' => 'p', 'field' => 'id_product', 'filtering' => ' %s '], - 'reference' => ['table' => 'p', 'field' => 'reference', 'filtering' => self::FILTERING_LIKE_BOTH], - 'price' => ['table' => 'sa', 'field' => 'price', 'filtering' => ' %s '], - 'id_shop_default' => ['table' => 'p', 'field' => 'id_shop_default'], - 'is_virtual' => ['table' => 'p', 'field' => 'is_virtual'], - 'name' => ['table' => 'pl', 'field' => 'name', 'filtering' => self::FILTERING_LIKE_BOTH], - 'link_rewrite' => ['table' => 'pl', 'field' => 'link_rewrite', 'filtering' => self::FILTERING_LIKE_BOTH], - 'active' => ['table' => 'sa', 'field' => 'active', 'filtering' => self::FILTERING_EQUAL_NUMERIC], - 'shopname' => ['table' => 'shop', 'field' => 'name'], - 'id_image' => ['table' => 'image_shop', 'field' => 'id_image'], - 'name_category' => ['table' => 'cl', 'field' => 'name', 'filtering' => self::FILTERING_LIKE_BOTH], - 'price_final' => '0', - 'nb_downloadable' => ['table' => 'pd', 'field' => 'nb_downloadable'], - 'sav_quantity' => ['table' => 'sav', 'field' => 'quantity', 'filtering' => ' %s '], - 'badge_danger' => ['select' => 'IF(sav.`quantity`<=0, 1, 0)', 'filtering' => 'IF(sav.`quantity`<=0, 1, 0) = %s'], - ]; - $sqlTable = [ - 'p' => 'product', - 'pl' => [ - 'table' => 'product_lang', - 'join' => 'LEFT JOIN', - 'on' => 'pl.`id_product` = p.`id_product` AND pl.`id_lang` = ' . $idLang . ' AND pl.`id_shop` = ' . $idShop, - ], - 'sav' => [ - 'table' => 'stock_available', - 'join' => 'LEFT JOIN', - 'on' => 'sav.`id_product` = p.`id_product` AND sav.`id_product_attribute` = 0' . - StockAvailable::addSqlShopRestriction(null, $idShop, 'sav'), - ], - 'sa' => [ - 'table' => 'product_shop', - 'join' => 'JOIN', - 'on' => 'p.`id_product` = sa.`id_product` AND sa.id_shop = ' . $idShop, - ], - 'cl' => [ - 'table' => 'category_lang', - 'join' => 'LEFT JOIN', - 'on' => 'sa.`id_category_default` = cl.`id_category` AND cl.`id_lang` = ' . $idLang . ' AND cl.id_shop = ' . $idShop, - ], - 'c' => [ - 'table' => 'category', - 'join' => 'LEFT JOIN', - 'on' => 'c.`id_category` = cl.`id_category`', - ], - 'shop' => [ - 'table' => 'shop', - 'join' => 'LEFT JOIN', - 'on' => 'shop.id_shop = ' . $idShop, - ], - 'image_shop' => [ - 'table' => 'image_shop', - 'join' => 'LEFT JOIN', - 'on' => 'image_shop.`id_product` = p.`id_product` AND image_shop.`cover` = 1 AND image_shop.id_shop = ' . $idShop, - ], - 'i' => [ - 'table' => 'image', - 'join' => 'LEFT JOIN', - 'on' => 'i.`id_image` = image_shop.`id_image`', - ], - 'pd' => [ - 'table' => 'product_download', - 'join' => 'LEFT JOIN', - 'on' => 'pd.`id_product` = p.`id_product`', - ], - ]; - $sqlWhere = ['AND', 1]; - $sqlOrder = [$orderBy . ' ' . $sortOrder]; - if ($orderBy != 'id_product') { - $sqlOrder[] = 'id_product asc'; // secondary order by (useful when ordering by active, quantity, price, etc...) - } - $sqlLimit = $offset . ', ' . $limit; - - // Column 'position' added if filtering by category - if ($showPositionColumn) { - $filteredCategoryId = (int) $filterParams['filter_category']; - $sqlSelect['position'] = ['table' => 'cp', 'field' => 'position']; - $sqlTable['cp'] = [ - 'table' => 'category_product', - 'join' => 'INNER JOIN', - 'on' => 'cp.`id_product` = p.`id_product` AND cp.`id_category` = ' . $filteredCategoryId, - ]; - } elseif ($orderBy == 'position') { - // We do not show position column, so we do not join the table, so we do not order by position! - $sqlOrder = ['id_product ASC']; - } - - $sqlGroupBy = []; - - // exec legacy hook but with different parameters (retro-compat < 1.7 is broken here) - Hook::exec('actionAdminProductsListingFieldsModifier', [ - '_ps_version' => AppKernel::VERSION, - 'sql_select' => &$sqlSelect, - 'sql_table' => &$sqlTable, - 'sql_where' => &$sqlWhere, - 'sql_group_by' => &$sqlGroupBy, - 'sql_order' => &$sqlOrder, - 'sql_limit' => &$sqlLimit, - ]); - foreach ($filterParams as $filterParam => $filterValue) { - if (!$filterValue && $filterValue !== '0') { - continue; - } - if (strpos($filterParam, 'filter_column_') === 0) { - $filterValue = Db::getInstance()->escape($filterValue, in_array($filterParam, [ - 'filter_column_id_product', - 'filter_column_sav_quantity', - 'filter_column_price', - ]), true); - $field = substr($filterParam, 14); // 'filter_column_' takes 14 chars - if (isset($sqlSelect[$field]['table'])) { - $sqlWhere[] = $sqlSelect[$field]['table'] . '.`' . $sqlSelect[$field]['field'] . '` ' . sprintf($sqlSelect[$field]['filtering'], $filterValue); - } else { - $sqlWhere[] = '(' . sprintf($sqlSelect[$field]['filtering'], $filterValue) . ')'; - } - } - // for 'filter_category', see next if($showPositionColumn) block. - } - $sqlWhere[] = 'state = ' . Product::STATE_SAVED; - - // exec legacy hook but with different parameters (retro-compat < 1.7 is broken here) - Hook::exec('actionAdminProductsListingFieldsModifier', [ - '_ps_version' => AppKernel::VERSION, - 'sql_select' => &$sqlSelect, - 'sql_table' => &$sqlTable, - 'sql_where' => &$sqlWhere, - 'sql_group_by' => &$sqlGroupBy, - 'sql_order' => &$sqlOrder, - 'sql_limit' => &$sqlLimit, - ]); - - $sql = $this->compileSqlQuery($sqlSelect, $sqlTable, $sqlWhere, $sqlGroupBy, $sqlOrder, $sqlLimit); - $products = Db::getInstance()->executeS($sql, true, false); - $total = Db::getInstance()->executeS('SELECT FOUND_ROWS();', true, false); - $total = $total[0]['FOUND_ROWS()']; - - // post treatment - $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); - $localeCldr = Tools::getContextLocale(Context::getContext()); - - foreach ($products as &$product) { - $product['total'] = $total; // total product count (filtered) - $product['price_final'] = Product::getPriceStatic( - $product['id_product'], - true, - null, - Context::getContext()->getComputingPrecision(), - null, - false, - false, - 1, - true, - null, - null, - null, - $nothing, - true, - true - ); - - if ($formatCldr) { - $product['price'] = $localeCldr->formatPrice($product['price'], $currency->iso_code); - $product['price_final'] = $localeCldr->formatPrice($product['price_final'], $currency->iso_code); - } - $product['image'] = $this->imageManager->getThumbnailForListing($product['id_image']); - $product['image_link'] = Context::getContext()->link->getImageLink($product['link_rewrite'], $product['id_image']); - } - - // post treatment by hooks - // exec legacy hook but with different parameters (retro-compat < 1.7 is broken here) - Hook::exec('actionAdminProductsListingResultsModifier', [ - '_ps_version' => AppKernel::VERSION, - 'products' => &$products, - 'total' => $total, - ]); - - return $products; - } - - /** - * {@inheritdoc} - */ - public function countAllProducts() - { - $idShop = Context::getContext()->shop->id; - - $query = new DbQuery(); - $query->select('COUNT(ps.id_product)'); - $query->from('product_shop', 'ps'); - $query->where('ps.id_shop = ' . (int) $idShop); - - $total = Db::getInstance()->getValue($query); - - return (int) $total; - } - - /** - * Translates new Core route parameters into their Legacy equivalent. - * - * @param string[] $coreParameters The new Core route parameters - * - * @return string[] The URL parameters for Legacy URL (GETs) - */ - public function mapLegacyParametersProductForm($coreParameters = []) - { - $params = []; - if ($coreParameters['id'] == '0') { - $params['addproduct'] = 1; - } else { - $params['updateproduct'] = 1; - $params['id_product'] = $coreParameters['id']; - } - - return $params; - } - - /** - * {@inheritdoc} - */ - public function getPaginationLimitChoices() - { - $paginationLimitChoices = [20, 50, 100]; - - $memory = Tools::getMemoryLimit(); - - if ($memory >= 512 * 1024 * 1024) { - $paginationLimitChoices[] = 300; - } - if ($memory >= 1536 * 1024 * 1024) { - $paginationLimitChoices[] = 1000; - } - - return $paginationLimitChoices; - } - - /** - * {@inheritdoc} - */ - public function isNewProductDefaultActivated() - { - return (bool) Configuration::get('PS_PRODUCT_ACTIVATION_DEFAULT'); - } -} diff --git a/src/Adapter/Product/AdminProductDataUpdater.php b/src/Adapter/Product/AdminProductDataUpdater.php deleted file mode 100644 index 39599511..00000000 --- a/src/Adapter/Product/AdminProductDataUpdater.php +++ /dev/null @@ -1,299 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Category; -use Configuration; -use Db; -use GroupReduction; -use Image; -use Pack; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Exception\UpdateProductException; -use PrestaShopBundle\Service\DataUpdater\Admin\ProductInterface; -use Product; -use Search; -use Shop; -use ShopGroup; -use Validate; - -/** - * This class will update/insert/delete data from DB / ORM about Product, for both Front and Admin interfaces. - */ -class AdminProductDataUpdater implements ProductInterface -{ - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * Constructor. HookDispatcher is injected by Sf container. - * - * @param HookDispatcher $hookDispatcher - */ - public function __construct(HookDispatcherInterface $hookDispatcher) - { - $this->hookDispatcher = $hookDispatcher; - } - - /** - * {@inheritdoc} - */ - public function activateProductIdList(array $productListId, $activate = true) - { - if (count($productListId) < 1) { - throw new \Exception('AdminProductDataUpdater->activateProductIdList() should always receive at least one ID. Zero given.', 5003); - } - - $failedIdList = []; - foreach ($productListId as $productId) { - $product = new Product($productId); - if (!Validate::isLoadedObject($product) - || $product->validateFields(false, true) !== true - || $product->validateFieldsLang(false, true) !== true) { - $failedIdList[] = $productId; - - continue; - } - $product->active = ($activate ? 1 : 0); - $product->update(); - if (in_array($product->visibility, ['both', 'search']) && Configuration::get('PS_SEARCH_INDEXATION')) { - Search::indexation(false, $product->id); - } - $this->hookDispatcher->dispatchWithParameters('actionProductActivation', ['id_product' => (int) $product->id, 'product' => $product, 'activated' => $activate]); - } - - if (count($failedIdList) > 0) { - throw new UpdateProductException('Cannot change activation state on many requested products', 5004); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function deleteProductIdList(array $productIdList) - { - if (count($productIdList) < 1) { - throw new \Exception('AdminProductDataUpdater->deleteProductIdList() should always receive at least one ID. Zero given.', 5005); - } - - $failedIdList = $productIdList; // Since we have just one call to delete all, cannot have distinctive fails. - // Hooks: will trigger actionProductDelete multiple times - $result = (new Product())->deleteSelection($productIdList); - - if ($result === 0) { - throw new UpdateProductException('Cannot delete many requested products.', 5006); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function duplicateProductIdList(array $productIdList) - { - if (count($productIdList) < 1) { - throw new \Exception('AdminProductDataUpdater->duplicateProductIdList() should always receive at least one ID. Zero given.', 5005); - } - - $failedIdList = []; - foreach ($productIdList as $productId) { - try { - $this->duplicateProduct($productId); - } catch (\Exception $e) { - $failedIdList[] = $productId; - - continue; - } - } - - if (count($failedIdList) > 0) { - throw new UpdateProductException('Cannot duplicate many requested products', 5004); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function deleteProduct($productId) - { - $product = new Product($productId); - if (!Validate::isLoadedObject($product)) { - throw new \Exception('AdminProductDataUpdater->deleteProduct() received an unknown ID.', 5005); - } - - // dumb? no: delete() makes a lot of things, and can reject deletion in specific cases. - // Hooks: will trigger actionProductDelete - $result = $product->delete(); - - if ($result === 0) { - throw new UpdateProductException('Cannot delete the requested product.', 5007); - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function duplicateProduct($productId, $namePattern = 'copy of %s') - { - //TODO : use the $namePattern var to input translated version of 'copy of %s', if translation requested. - $product = new Product($productId); - if (!Validate::isLoadedObject($product)) { - throw new \Exception('AdminProductDataUpdater->duplicateProduct() received an unknown ID.', 5005); - } - - if (($error = $product->validateFields(false, true)) !== true - || ($error = $product->validateFieldsLang(false, true)) !== true) { - throw new UpdateProductException(sprintf('Cannot duplicate this product: %s', $error)); - } - - $id_product_old = $product->id; - if (empty($product->price) && Shop::getContext() == Shop::CONTEXT_GROUP) { - $shops = ShopGroup::getShopsFromGroup(Shop::getContextShopGroupID()); - foreach ($shops as $shop) { - if ($product->isAssociatedToShop($shop['id_shop'])) { - $product_price = new Product($id_product_old, false, null, $shop['id_shop']); - $product->price = $product_price->price; - } - } - } - - unset( - $product->id, - $product->id_product - ); - - $product->indexed = 0; - $product->active = 0; - - // change product name to prefix it - foreach ($product->name as $langKey => $oldName) { - if (!preg_match('/^' . str_replace('%s', '.*', preg_quote($namePattern, '/') . '$/'), $oldName)) { - $newName = sprintf($namePattern, $oldName); - if (mb_strlen($newName, 'UTF-8') <= 127) { - $product->name[$langKey] = $newName; - } - } - } - - if ($product->add() - && Category::duplicateProductCategories($id_product_old, $product->id) - && Product::duplicateSuppliers($id_product_old, $product->id) - && ($combination_images = Product::duplicateAttributes($id_product_old, $product->id)) !== false - && GroupReduction::duplicateReduction($id_product_old, $product->id) - && Product::duplicateAccessories($id_product_old, $product->id) - && Product::duplicateFeatures($id_product_old, $product->id) - && Product::duplicateSpecificPrices($id_product_old, $product->id) - && Pack::duplicate($id_product_old, $product->id) - && Product::duplicateCustomizationFields($id_product_old, $product->id) - && Product::duplicatePrices($id_product_old, $product->id) - && Product::duplicateTags($id_product_old, $product->id) - && Product::duplicateTaxes($id_product_old, $product->id) - && Product::duplicateDownload($id_product_old, $product->id)) { - if ($product->hasAttributes()) { - Product::updateDefaultAttribute($product->id); - } - - if (!Image::duplicateProductImages($id_product_old, $product->id, $combination_images)) { - throw new UpdateProductException('An error occurred while copying images.', 5008); - } else { - $this->hookDispatcher->dispatchWithParameters('actionProductAdd', ['id_product_old' => $id_product_old, 'id_product' => (int) $product->id, 'product' => $product]); - if (in_array($product->visibility, ['both', 'search']) && Configuration::get('PS_SEARCH_INDEXATION')) { - Search::indexation(false, $product->id); - } - - return $product->id; - } - } else { - if ($product->id !== null) { - $product->delete(); - } - throw new \Exception('An error occurred while creating an object.', 5009); - } - } - - /** - * {@inheritdoc} - */ - public function sortProductIdList(array $productList, $filterParams) - { - if (count($productList) < 2) { - return false; - } - - if (!isset($filterParams['filter_category'])) { - throw new \Exception('Cannot sort when filterParams does not contains \'filter_category\'.', 5010); - } - - foreach ($filterParams as $k => $v) { - if ($v == '' || strpos($k, 'filter_') !== 0) { - continue; - } - if ($k == 'filter_category') { - continue; - } - - throw new \Exception('Cannot sort when filterParams contains other filter than \'filter_category\'.', 5010); - } - - $categoryId = $filterParams['filter_category']; - $minPosition = min(array_values($productList)); - $productsIds = implode(',', array_map('intval', array_keys($productList))); - - /* - * First request to update position on category_product - */ - Db::getInstance()->query('SET @i := ' . (((int) $minPosition) - 1)); - $updatePositions = 'UPDATE `' . _DB_PREFIX_ . 'category_product` cp ' . - 'SET cp.`position` = (SELECT @i := @i + 1) ' . - 'WHERE cp.`id_category` = ' . (int) $categoryId . ' AND cp.`id_product` IN (' . $productsIds . ') ' . - 'ORDER BY FIELD(cp.`id_product`, ' . $productsIds . ')'; - Db::getInstance()->query($updatePositions); - - /** - * Second request to update date_upd because - * ORDER BY is not working on multi-tables update - */ - $updateProducts = 'UPDATE `' . _DB_PREFIX_ . 'product` p ' . - '' . Shop::addSqlAssociation('product', 'p') . ' ' . - 'SET ' . - ' p.`date_upd` = "' . date('Y-m-d H:i:s') . '", ' . - ' product_shop.`date_upd` = "' . date('Y-m-d H:i:s') . '" ' . - 'WHERE p.`id_product` IN (' . $productsIds . ') '; - Db::getInstance()->query($updateProducts); - - return true; - } -} diff --git a/src/Adapter/Product/AdminProductWrapper.php b/src/Adapter/Product/AdminProductWrapper.php deleted file mode 100644 index 3f748700..00000000 --- a/src/Adapter/Product/AdminProductWrapper.php +++ /dev/null @@ -1,951 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use AdminProductsController; -use Attachment; -use Category; -use Combination; -use Configuration; -use Context; -use Customer; -use Db; -use Hook; -use Image; -use Language; -use ObjectModel; -use PrestaShop\PrestaShop\Adapter\Entity\Customization; -use PrestaShop\PrestaShop\Core\Foundation\Database\EntityNotFoundException; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShopBundle\Utils\FloatParser; -use Product; -use ProductDownload; -use Shop; -use ShopUrl; -use SpecificPrice; -use SpecificPriceRule; -use StockAvailable; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; -use Validate; - -/** - * Admin controller wrapper for new Architecture, about Product admin controller. - */ -class AdminProductWrapper -{ - /** - * @var array - */ - private $errors = []; - - /** - * @var Locale - */ - private $locale; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var array - */ - private $employeeAssociatedShops; - - /** - * @var FloatParser - */ - private $floatParser; - - /** - * Constructor : Inject Symfony\Component\Translation Translator. - * - * @param object $translator - * @param array $employeeAssociatedShops - * @param Locale $locale - * @param FloatParser|null $floatParser - */ - public function __construct($translator, array $employeeAssociatedShops, Locale $locale, FloatParser $floatParser = null) - { - $this->translator = $translator; - $this->employeeAssociatedShops = $employeeAssociatedShops; - $this->locale = $locale; - $this->floatParser = $floatParser ?? new FloatParser(); - } - - /** - * getInstance - * Get the legacy AdminProductsControllerCore instance. - * - * @return AdminProductsController instance - */ - public function getInstance() - { - return new AdminProductsController(); - } - - /** - * processProductAttribute - * Update a combination. - * - * @param object $product - * @param array $combinationValues the posted values - * - * @return AdminProductsController instance - */ - public function processProductAttribute($product, $combinationValues) - { - $id_product_attribute = (int) $combinationValues['id_product_attribute']; - $images = []; - - if (!Combination::isFeatureActive() || $id_product_attribute == 0) { - return; - } - - if (!isset($combinationValues['attribute_wholesale_price'])) { - $combinationValues['attribute_wholesale_price'] = 0; - } - if (!isset($combinationValues['attribute_price_impact'])) { - $combinationValues['attribute_price_impact'] = 0; - } - if (!isset($combinationValues['attribute_weight_impact'])) { - $combinationValues['attribute_weight_impact'] = 0; - } - if (!isset($combinationValues['attribute_ecotax'])) { - $combinationValues['attribute_ecotax'] = 0; - } - if ((isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1)) { - $product->deleteDefaultAttributes(); - } - if (!empty($combinationValues['id_image_attr'])) { - $images = $combinationValues['id_image_attr']; - } else { - $combination = new Combination($id_product_attribute); - $combination->setImages([]); - } - if (!isset($combinationValues['attribute_low_stock_threshold'])) { - $combinationValues['attribute_low_stock_threshold'] = null; - } - if (!isset($combinationValues['attribute_low_stock_alert'])) { - $combinationValues['attribute_low_stock_alert'] = false; - } - - $product->updateAttribute( - $id_product_attribute, - $combinationValues['attribute_wholesale_price'], - $combinationValues['attribute_price'] * $combinationValues['attribute_price_impact'], - $combinationValues['attribute_weight'] * $combinationValues['attribute_weight_impact'], - $combinationValues['attribute_unity'] * $combinationValues['attribute_unit_impact'], - $combinationValues['attribute_ecotax'], - $images, - $combinationValues['attribute_reference'], - $combinationValues['attribute_ean13'], - (isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1), - isset($combinationValues['attribute_location']) ? $combinationValues['attribute_location'] : null, - $combinationValues['attribute_upc'], - $combinationValues['attribute_minimal_quantity'], - $combinationValues['available_date_attribute'], - false, - [], - $combinationValues['attribute_isbn'], - $combinationValues['attribute_low_stock_threshold'], - $combinationValues['attribute_low_stock_alert'], - $combinationValues['attribute_mpn'] - ); - - StockAvailable::setProductDependsOnStock((int) $product->id, $product->depends_on_stock, null, $id_product_attribute); - StockAvailable::setProductOutOfStock((int) $product->id, $product->out_of_stock, null, $id_product_attribute); - StockAvailable::setLocation((int) $product->id, $combinationValues['attribute_location'], null, $id_product_attribute); - - $product->checkDefaultAttributes(); - - if ((isset($combinationValues['attribute_default']) && $combinationValues['attribute_default'] == 1)) { - Product::updateDefaultAttribute((int) $product->id); - if (isset($id_product_attribute)) { - $product->cache_default_attribute = (int) $id_product_attribute; - } - - // We need to reload the product because some other calls have modified the database - // It's done just for the setAvailableDate to avoid side effects - Product::disableCache(); - $consistentProduct = new Product($product->id); - if ($available_date = $combinationValues['available_date_attribute']) { - $consistentProduct->setAvailableDate($available_date); - } else { - $consistentProduct->setAvailableDate(); - } - Product::enableCache(); - } - - if (isset($combinationValues['attribute_quantity'])) { - $this->processQuantityUpdate($product, $combinationValues['attribute_quantity'], $id_product_attribute); - } - } - - /** - * Update a quantity for a product or a combination. - * - * Does not work in Advanced stock management. - * - * @param Product $product - * @param int $quantity - * @param int $forAttributeId - */ - public function processQuantityUpdate(Product $product, $quantity, $forAttributeId = 0) - { - // Hook triggered by legacy code below: actionUpdateQuantity('id_product', 'id_product_attribute', 'quantity') - StockAvailable::setQuantity((int) $product->id, $forAttributeId, $quantity); - Hook::exec('actionProductUpdate', ['id_product' => (int) $product->id, 'product' => $product]); - } - - /** - * Update the out of stock strategy. - * - * @param Product $product - * @param int $out_of_stock - */ - public function processProductOutOfStock(Product $product, $out_of_stock) - { - StockAvailable::setProductOutOfStock((int) $product->id, (int) $out_of_stock); - } - - /** - * @param Product $product - * @param string $location - */ - public function processLocation(Product $product, $location) - { - StockAvailable::setLocation($product->id, $location); - } - - /** - * Set if a product depends on stock (ASM). For a product or a combination. - * - * Does work only in Advanced stock management. - * - * @param Product $product - * @param bool $dependsOnStock - * @param int $forAttributeId - */ - public function processDependsOnStock(Product $product, $dependsOnStock, $forAttributeId = 0) - { - StockAvailable::setProductDependsOnStock((int) $product->id, $dependsOnStock, null, $forAttributeId); - } - - /** - * Add/Update a SpecificPrice object. - * - * @param int $id_product - * @param array $specificPriceValues the posted values - * @param int (optional) $id_specific_price if this is an update of an existing specific price, null else - * - * @return AdminProductsController instance - */ - public function processProductSpecificPrice($id_product, $specificPriceValues, $idSpecificPrice = null) - { - // ---- data formatting ---- - $id_product_attribute = $specificPriceValues['sp_id_product_attribute']; - $id_shop = $specificPriceValues['sp_id_shop'] ? $specificPriceValues['sp_id_shop'] : 0; - $id_currency = $specificPriceValues['sp_id_currency'] ? $specificPriceValues['sp_id_currency'] : 0; - $id_country = $specificPriceValues['sp_id_country'] ? $specificPriceValues['sp_id_country'] : 0; - $id_group = $specificPriceValues['sp_id_group'] ? $specificPriceValues['sp_id_group'] : 0; - $id_customer = !empty($specificPriceValues['sp_id_customer']['data']) ? $specificPriceValues['sp_id_customer']['data'][0] : 0; - $price = isset($specificPriceValues['leave_bprice']) ? '-1' : $this->floatParser->fromString($specificPriceValues['sp_price']); - $from_quantity = $specificPriceValues['sp_from_quantity']; - $reduction = $this->floatParser->fromString($specificPriceValues['sp_reduction']); - $reduction_tax = $specificPriceValues['sp_reduction_tax']; - $reduction_type = !$reduction ? 'amount' : $specificPriceValues['sp_reduction_type']; - $reduction_type = $reduction_type == '-' ? 'amount' : $reduction_type; - $from = $specificPriceValues['sp_from']; - if (!$from) { - $from = '0000-00-00 00:00:00'; - } - $to = $specificPriceValues['sp_to']; - if (!$to) { - $to = '0000-00-00 00:00:00'; - } - $isThisAnUpdate = (null !== $idSpecificPrice); - - // ---- validation ---- - if (($price == '-1') && ((float) $reduction == '0')) { - $this->errors[] = $this->translator->trans('No reduction value has been submitted', [], 'Admin.Catalog.Notification'); - } elseif ($to != '0000-00-00 00:00:00' && strtotime($to) < strtotime($from)) { - $this->errors[] = $this->translator->trans('Invalid date range', [], 'Admin.Catalog.Notification'); - } elseif ($reduction_type == 'percentage' && ((float) $reduction <= 0 || (float) $reduction > 100)) { - $this->errors[] = $this->translator->trans('Submitted reduction value (0-100) is out-of-range', [], 'Admin.Catalog.Notification'); - } - $validationResult = $this->validateSpecificPrice( - $id_product, - $id_shop, - $id_currency, - $id_country, - $id_group, - $id_customer, - $price, - $from_quantity, - $reduction, - $reduction_type, - $from, - $to, - $id_product_attribute, - $isThisAnUpdate - ); - - if (false === $validationResult || count($this->errors)) { - return $this->errors; - } - - // ---- data modification ---- - if ($isThisAnUpdate) { - $specificPrice = new SpecificPrice($idSpecificPrice); - } else { - $specificPrice = new SpecificPrice(); - } - - $specificPrice->id_product = (int) $id_product; - $specificPrice->id_product_attribute = (int) $id_product_attribute; - $specificPrice->id_shop = (int) $id_shop; - $specificPrice->id_currency = (int) ($id_currency); - $specificPrice->id_country = (int) ($id_country); - $specificPrice->id_group = (int) ($id_group); - $specificPrice->id_customer = (int) $id_customer; - $specificPrice->price = (float) ($price); - $specificPrice->from_quantity = (int) ($from_quantity); - $specificPrice->reduction = (float) ($reduction_type == 'percentage' ? $reduction / 100 : $reduction); - $specificPrice->reduction_tax = $reduction_tax; - $specificPrice->reduction_type = $reduction_type; - $specificPrice->from = $from; - $specificPrice->to = $to; - - if ($isThisAnUpdate) { - $dataSavingResult = $specificPrice->save(); - } else { - $dataSavingResult = $specificPrice->add(); - } - - if (false === $dataSavingResult) { - $this->errors[] = $this->translator->trans('An error occurred while updating the specific price.', [], 'Admin.Catalog.Notification'); - } - - return $this->errors; - } - - /** - * Validate a specific price. - */ - private function validateSpecificPrice( - $id_product, - $id_shop, - $id_currency, - $id_country, - $id_group, - $id_customer, - $price, - $from_quantity, - $reduction, - $reduction_type, - $from, - $to, - $id_combination = 0, - $isThisAnUpdate = false - ) { - if (!Validate::isUnsignedId($id_shop) || !Validate::isUnsignedId($id_currency) || !Validate::isUnsignedId($id_country) || !Validate::isUnsignedId($id_group) || !Validate::isUnsignedId($id_customer)) { - $this->errors[] = 'Wrong IDs'; - } elseif ((!isset($price) && !isset($reduction)) || (isset($price) && !Validate::isNegativePrice($price)) || (isset($reduction) && !Validate::isPrice($reduction))) { - $this->errors[] = 'Invalid price/discount amount'; - } elseif (!Validate::isUnsignedInt($from_quantity)) { - $this->errors[] = 'Invalid quantity'; - } elseif ($reduction && !Validate::isReductionType($reduction_type)) { - $this->errors[] = 'Please select a discount type (amount or percentage).'; - } elseif ($from && $to && (!Validate::isDateFormat($from) || !Validate::isDateFormat($to))) { - $this->errors[] = 'The from/to date is invalid.'; - } elseif (!$isThisAnUpdate && SpecificPrice::exists((int) $id_product, $id_combination, $id_shop, $id_group, $id_country, $id_currency, $id_customer, $from_quantity, $from, $to, false)) { - $this->errors[] = 'A specific price already exists for these parameters.'; - } else { - return true; - } - - return false; - } - - /** - * Get specific prices list for a product. - * - * @param object $product - * @param object $defaultCurrency - * @param array $shops Available shops - * @param array $currencies Available currencies - * @param array $countries Available countries - * @param array $groups Available users groups - * - * @return array - */ - public function getSpecificPricesList($product, $defaultCurrency, $shops, $currencies, $countries, $groups) - { - $content = []; - $specific_prices = SpecificPrice::getByProductId((int) $product->id); - - $tmp = []; - foreach ($shops as $shop) { - $tmp[$shop['id_shop']] = $shop; - } - $shops = $tmp; - $tmp = []; - foreach ($currencies as $currency) { - $tmp[$currency['id_currency']] = $currency; - } - $currencies = $tmp; - - $tmp = []; - foreach ($countries as $country) { - $tmp[$country['id_country']] = $country; - } - $countries = $tmp; - - $tmp = []; - foreach ($groups as $group) { - $tmp[$group['id_group']] = $group; - } - $groups = $tmp; - - if (is_array($specific_prices) && count($specific_prices)) { - foreach ($specific_prices as $specific_price) { - $id_currency = $specific_price['id_currency'] ? $specific_price['id_currency'] : $defaultCurrency->id; - if (!isset($currencies[$id_currency])) { - continue; - } - - $current_specific_currency = $currencies[$id_currency]; - if ($specific_price['reduction_type'] == 'percentage') { - $impact = '- ' . ($specific_price['reduction'] * 100) . ' %'; - } elseif ($specific_price['reduction'] > 0) { - $impact = '- ' . $this->locale->formatPrice($specific_price['reduction'], $current_specific_currency['iso_code']) . ' '; - if ($specific_price['reduction_tax']) { - $impact .= '(' . $this->translator->trans('Tax incl.', [], 'Admin.Global') . ')'; - } else { - $impact .= '(' . $this->translator->trans('Tax excl.', [], 'Admin.Global') . ')'; - } - } else { - $impact = '--'; - } - - if ($specific_price['from'] == '0000-00-00 00:00:00' && $specific_price['to'] == '0000-00-00 00:00:00') { - $period = $this->translator->trans('Unlimited', [], 'Admin.Global'); - } else { - $period = $this->translator->trans('From', [], 'Admin.Global') . ' ' . ($specific_price['from'] != '0000-00-00 00:00:00' ? $specific_price['from'] : '0000-00-00 00:00:00') . '
    ' . $this->translator->trans('to', [], 'Admin.Global') . ' ' . ($specific_price['to'] != '0000-00-00 00:00:00' ? $specific_price['to'] : '0000-00-00 00:00:00'); - } - if ($specific_price['id_product_attribute']) { - $combination = new Combination((int) $specific_price['id_product_attribute']); - $attributes = $combination->getAttributesName(1); - $attributes_name = ''; - foreach ($attributes as $attribute) { - $attributes_name .= $attribute['name'] . ' - '; - } - $attributes_name = rtrim($attributes_name, ' - '); - } else { - $attributes_name = $this->translator->trans('All combinations', [], 'Admin.Catalog.Feature'); - } - - $rule = new SpecificPriceRule((int) $specific_price['id_specific_price_rule']); - $rule_name = ($rule->id ? $rule->name : '--'); - - if ($specific_price['id_customer']) { - $customer = new Customer((int) $specific_price['id_customer']); - if (Validate::isLoadedObject($customer)) { - $customer_full_name = $customer->firstname . ' ' . $customer->lastname; - } - unset($customer); - } - - if (!$specific_price['id_shop'] || in_array($specific_price['id_shop'], Shop::getContextListShopID())) { - $can_delete_specific_prices = true; - if (Shop::isFeatureActive()) { - $can_delete_specific_prices = (count($this->employeeAssociatedShops) > 1 && !$specific_price['id_shop']) || $specific_price['id_shop']; - } - - $price = Tools::ps_round($specific_price['price'], 2); - $fixed_price = (($price == Tools::ps_round($product->price, 2) && $current_specific_currency['id_currency'] == $defaultCurrency->id) || $specific_price['price'] == -1) ? '--' : $this->locale->formatPrice($price, $current_specific_currency['iso_code']); - - $content[] = [ - 'id_specific_price' => $specific_price['id_specific_price'], - 'id_product' => $product->id, - 'rule_name' => $rule_name, - 'attributes_name' => $attributes_name, - 'shop' => ($specific_price['id_shop'] ? $shops[$specific_price['id_shop']]['name'] : $this->translator->trans('All shops', [], 'Admin.Global')), - 'currency' => ($specific_price['id_currency'] ? $currencies[$specific_price['id_currency']]['name'] : $this->translator->trans('All currencies', [], 'Admin.Global')), - 'country' => ($specific_price['id_country'] ? $countries[$specific_price['id_country']]['name'] : $this->translator->trans('All countries', [], 'Admin.Global')), - 'group' => ($specific_price['id_group'] ? $groups[$specific_price['id_group']]['name'] : $this->translator->trans('All groups', [], 'Admin.Global')), - 'customer' => (isset($customer_full_name) ? $customer_full_name : $this->translator->trans('All customers', [], 'Admin.Global')), - 'fixed_price' => $fixed_price, - 'impact' => $impact, - 'period' => $period, - 'from_quantity' => $specific_price['from_quantity'], - 'can_delete' => (!$rule->id && $can_delete_specific_prices) ? true : false, - 'can_edit' => (!$rule->id && $can_delete_specific_prices) ? true : false, - ]; - - unset($customer_full_name); - } - } - } - - return $content; - } - - /** - * @param int $id - * - * @return SpecificPrice - * - * @throws PrestaShopObjectNotFoundException - */ - public function getSpecificPriceDataById($id) - { - $price = new SpecificPrice($id); - if (null === $price->id) { - throw new EntityNotFoundException(sprintf('Cannot find specific price with id %d', $id)); - } - - return $price; - } - - /** - * Delete a specific price. - * - * @param int $id_specific_price - * - * @return array error & status - */ - public function deleteSpecificPrice($id_specific_price) - { - if (!$id_specific_price || !Validate::isUnsignedId($id_specific_price)) { - $error = $this->translator->trans('The specific price ID is invalid.', [], 'Admin.Catalog.Notification'); - } else { - $specificPrice = new SpecificPrice((int) $id_specific_price); - if (!$specificPrice->delete()) { - $error = $this->translator->trans('An error occurred while attempting to delete the specific price.', [], 'Admin.Catalog.Notification'); - } - } - - if (isset($error)) { - return [ - 'status' => 'error', - 'message' => $error, - ]; - } - - return [ - 'status' => 'ok', - 'message' => $this->translator->trans('Successful deletion', [], 'Admin.Notifications.Success'), - ]; - } - - /** - * Get price priority. - * - * @param int|null $idProduct - * - * @return array - */ - public function getPricePriority($idProduct = null) - { - if (!$idProduct) { - return [ - 0 => 'id_shop', - 1 => 'id_currency', - 2 => 'id_country', - 3 => 'id_group', - ]; - } - - $specific_price_priorities = SpecificPrice::getPriority((int) $idProduct); - - // Not use id_customer - if ($specific_price_priorities[0] == 'id_customer') { - unset($specific_price_priorities[0]); - } - - return array_values($specific_price_priorities); - } - - /** - * Process customization collection. - * - * @param object $product - * @param array $data - * - * @return bool - */ - public function processProductCustomization($product, $data) - { - $customization_ids = []; - if ($data) { - foreach ($data as $customization) { - $customization_ids[] = (int) $customization['id_customization_field']; - } - } - - $shopList = Shop::getContextListShopID(); - - /* Update the customization fields to be deleted in the next step if not used */ - $product->softDeleteCustomizationFields($customization_ids); - - $usedCustomizationIds = $product->getUsedCustomizationFieldsIds(); - $usedCustomizationIds = array_column($usedCustomizationIds, 'index'); - $usedCustomizationIds = array_map('intval', $usedCustomizationIds); - $usedCustomizationIds = array_unique(array_merge($usedCustomizationIds, $customization_ids), SORT_REGULAR); - - //remove customization field langs for current context shops - $productCustomization = $product->getCustomizationFieldIds(); - $toDeleteCustomizationIds = []; - foreach ($productCustomization as $customizationFiled) { - if (!in_array((int) $customizationFiled['id_customization_field'], $usedCustomizationIds)) { - $toDeleteCustomizationIds[] = (int) $customizationFiled['id_customization_field']; - } - //if the customization_field is still in use, only delete the current context shops langs, - if (in_array((int) $customizationFiled['id_customization_field'], $customization_ids)) { - Customization::deleteCustomizationFieldLangByShop($customizationFiled['id_customization_field'], $shopList); - } - } - - //remove unused customization for the product - $product->deleteUnusedCustomizationFields($toDeleteCustomizationIds); - - //create new customizations - $countFieldText = 0; - $countFieldFile = 0; - $productCustomizableValue = 0; - $hasRequiredField = false; - - $new_customization_fields_ids = []; - - if ($data) { - foreach ($data as $key => $customization) { - if ($customization['require']) { - $hasRequiredField = true; - } - - //create label - if (isset($customization['id_customization_field'])) { - $id_customization_field = (int) $customization['id_customization_field']; - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'customization_field` - SET `required` = ' . ($customization['require'] ? 1 : 0) . ', `type` = ' . (int) $customization['type'] . ' - WHERE `id_customization_field` = ' . $id_customization_field); - } else { - Db::getInstance()->execute( - 'INSERT INTO `' . _DB_PREFIX_ . 'customization_field` (`id_product`, `type`, `required`) - VALUES (' - . (int) $product->id . ', ' - . (int) $customization['type'] . ', ' - . ($customization['require'] ? 1 : 0) - . ')' - ); - $id_customization_field = (int) Db::getInstance()->Insert_ID(); - } - - $new_customization_fields_ids[$key] = $id_customization_field; - - // Create multilingual label name - $langValues = ''; - foreach (Language::getLanguages() as $language) { - $name = $customization['label'][$language['id_lang']]; - foreach ($shopList as $id_shop) { - $langValues .= '(' - . (int) $id_customization_field . ', ' - . (int) $language['id_lang'] . ', ' - . (int) $id_shop . ',\'' - . pSQL($name) - . '\'), '; - } - } - Db::getInstance()->execute( - 'INSERT INTO `' . _DB_PREFIX_ . 'customization_field_lang` (`id_customization_field`, `id_lang`, `id_shop`, `name`) VALUES ' - . rtrim( - $langValues, - ', ' - ) - ); - - if ($customization['type'] == Product::CUSTOMIZE_FILE) { - ++$countFieldFile; - } else { - ++$countFieldText; - } - } - - $productCustomizableValue = $hasRequiredField ? 2 : 1; - } - - //update product count fields labels - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product` SET `customizable` = ' . $productCustomizableValue . ', `uploadable_files` = ' . (int) $countFieldFile . ', `text_fields` = ' . (int) $countFieldText . ' WHERE `id_product` = ' . (int) $product->id); - - //update product_shop count fields labels - ObjectModel::updateMultishopTable('product', [ - 'customizable' => $productCustomizableValue, - 'uploadable_files' => (int) $countFieldFile, - 'text_fields' => (int) $countFieldText, - ], 'a.id_product = ' . (int) $product->id); - - Configuration::updateGlobalValue('PS_CUSTOMIZATION_FEATURE_ACTIVE', '1'); - - return $new_customization_fields_ids; - } - - /** - * Update product download. - * - * @param object $product - * @param array $data - * - * @return bool - */ - public function updateDownloadProduct($product, $data) - { - $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); - $download = new ProductDownload($id_product_download ? $id_product_download : null); - - if ((int) $data['is_virtual_file'] == 1) { - $fileName = null; - $file = $data['file']; - - if (!empty($file)) { - $fileName = ProductDownload::getNewFilename(); - $file->move(_PS_DOWNLOAD_DIR_, $fileName); - } - - $product->setDefaultAttribute(0); //reset cache_default_attribute - - $download->id_product = (int) $product->id; - $download->display_filename = $data['name']; - $download->filename = $fileName ? $fileName : $download->filename; - $download->date_add = date('Y-m-d H:i:s'); - $download->date_expiration = $data['expiration_date'] ? $data['expiration_date'] . ' 23:59:59' : ''; - $download->nb_days_accessible = (int) $data['nb_days']; - $download->nb_downloadable = (int) $data['nb_downloadable']; - $download->active = 1; - $download->is_shareable = 0; - - if (!$id_product_download) { - $download->save(); - } else { - $download->update(); - } - } else { - if (!empty($id_product_download)) { - $download->date_expiration = date('Y-m-d H:i:s', time() - 1); - $download->active = 0; - $download->update(); - } - } - - return $download; - } - - /** - * Delete file from a virtual product. - * - * @param object $product - */ - public function processDeleteVirtualProductFile($product) - { - $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); - $download = new ProductDownload($id_product_download ? $id_product_download : null); - - if ($download && !empty($download->filename)) { - unlink(_PS_DOWNLOAD_DIR_ . $download->filename); - Db::getInstance()->execute('UPDATE `' . _DB_PREFIX_ . 'product_download` SET filename = "" WHERE `id_product_download` = ' . (int) $download->id); - } - } - - /** - * Delete a virtual product. - * - * @param object $product - */ - public function processDeleteVirtualProduct($product) - { - $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); - $download = new ProductDownload($id_product_download ? $id_product_download : null); - - if ($download) { - $download->delete(true); - } - } - - /** - * Add attachement file. - * - * @param object $product - * @param array $data - * @param array $locales - * - * @return object|null Attachement - */ - public function processAddAttachment($product, $data, $locales) - { - $attachment = null; - $file = $data['file']; - if (!empty($file)) { - $fileName = sha1(microtime()); - $attachment = new Attachment(); - - foreach ($locales as $locale) { - $attachment->name[(int) $locale['id_lang']] = $data['name']; - $attachment->description[(int) $locale['id_lang']] = $data['description']; - } - - $attachment->file = $fileName; - $attachment->mime = $file->getMimeType(); - $attachment->file_name = $file->getClientOriginalName(); - - $file->move(_PS_DOWNLOAD_DIR_, $fileName); - - if ($attachment->add()) { - $attachment->attachProduct($product->id); - } - } - - return $attachment; - } - - /** - * Process product attachments. - * - * @param object $product - * @param array $data - */ - public function processAttachments($product, $data) - { - Attachment::attachToProduct($product->id, $data); - } - - /** - * Update images positions. - * - * @param array $data Indexed array with id product/position - */ - public function ajaxProcessUpdateImagePosition($data) - { - foreach ($data as $id => $position) { - $img = new Image((int) $id); - $img->position = (int) $position; - $img->update(); - } - } - - /** - * Update image legend and cover. - * - * @param int $idImage - * @param array $data - * - * @return object image - */ - public function ajaxProcessUpdateImage($idImage, $data) - { - $img = new Image((int) $idImage); - if ($data['cover']) { - Image::deleteCover((int) $img->id_product); - $img->cover = 1; - } - $img->legend = $data['legend']; - $img->update(); - - return $img; - } - - /** - * Generate preview URL. - * - * @param object $product - * @param bool $preview - * - * @return string preview url - */ - public function getPreviewUrl($product, $preview = true) - { - $context = Context::getContext(); - $id_lang = Configuration::get('PS_LANG_DEFAULT', null, null, $context->shop->id); - - if (!ShopUrl::getMainShopDomain()) { - return false; - } - - $is_rewrite_active = (bool) Configuration::get('PS_REWRITING_SETTINGS'); - $preview_url = $context->link->getProductLink( - $product, - $product->link_rewrite[$context->language->id], - Category::getLinkRewrite($product->id_category_default, $context->language->id), - null, - $id_lang, - (int) $context->shop->id, - 0, - $is_rewrite_active - ); - - if (!$product->active && $preview) { - $preview_url = $this->getPreviewUrlDeactivate($preview_url); - } - - return $preview_url; - } - - /** - * Generate preview URL deactivate. - * - * @param string $preview_url - * - * @return string preview url deactivate - */ - public function getPreviewUrlDeactivate($preview_url) - { - $context = Context::getContext(); - $token = Tools::getAdminTokenLite('AdminProducts'); - - $admin_dir = dirname($_SERVER['PHP_SELF']); - $admin_dir = substr($admin_dir, strrpos($admin_dir, '/') + 1); - $preview_url_deactivate = $preview_url . ((strpos($preview_url, '?') === false) ? '?' : '&') . 'adtoken=' . $token . '&ad=' . $admin_dir . '&id_employee=' . (int) $context->employee->id . '&preview=1'; - - return $preview_url_deactivate; - } - - /** - * Generate preview URL. - * - * @param int $productId - * - * @return string preview url - */ - public function getPreviewUrlFromId($productId) - { - $product = new Product($productId, false); - - return $this->getPreviewUrl($product); - } -} diff --git a/src/Adapter/Product/AttachmentDataProvider.php b/src/Adapter/Product/AttachmentDataProvider.php deleted file mode 100644 index 1df06665..00000000 --- a/src/Adapter/Product/AttachmentDataProvider.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Db; - -/** - * This class will provide data from DB / ORM about attachment. - */ -class AttachmentDataProvider -{ - /** - * Get all attachments. - * - * @param int $id_lang - * - * @return array Attachment - */ - public function getAllAttachments($id_lang) - { - return Db::getInstance()->executeS(' - SELECT * - FROM ' . _DB_PREFIX_ . 'attachment a - LEFT JOIN ' . _DB_PREFIX_ . 'attachment_lang al - ON (a.id_attachment = al.id_attachment AND al.id_lang = ' . (int) $id_lang . ') - '); - } -} diff --git a/src/Adapter/Product/CommandHandler/AssignProductToCategoryHandler.php b/src/Adapter/Product/CommandHandler/AssignProductToCategoryHandler.php deleted file mode 100644 index 27d84b7d..00000000 --- a/src/Adapter/Product/CommandHandler/AssignProductToCategoryHandler.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider; -use PrestaShop\PrestaShop\Core\Domain\Product\Command\AssignProductToCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\CommandHandler\AssignProductToCategoryHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\CannotAssignProductToCategoryException; - -/** - * Adds a category to a product - * - * @internal - */ -final class AssignProductToCategoryHandler extends AbstractObjectModelHandler implements AssignProductToCategoryHandlerInterface -{ - /** - * @param AssignProductToCategoryCommand $command - */ - public function handle(AssignProductToCategoryCommand $command) - { - $this->assignProductToCategory($command); - } - - /** - * @param AssignProductToCategoryCommand $command - * - * @throws CannotAssignProductToCategoryException - */ - private function assignProductToCategory(AssignProductToCategoryCommand $command) - { - $productDataProvider = new ProductDataProvider(); - $product = $productDataProvider->getProductInstance($command->getProductId()->getValue()); - $product->addToCategories($command->getCategoryId()->getValue()); - if (false === $product->save()) { - throw new CannotAssignProductToCategoryException(sprintf('Failed to add category to product %d', $command->getProductId()->getValue())); - } - } -} diff --git a/src/Adapter/Product/CommandHandler/UpdateProductStatusCommandHandler.php b/src/Adapter/Product/CommandHandler/UpdateProductStatusCommandHandler.php deleted file mode 100644 index 1db83e6a..00000000 --- a/src/Adapter/Product/CommandHandler/UpdateProductStatusCommandHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Entity\Product; -use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\CommandHandler\UpdateProductStatusCommandHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\CannotUpdateProductException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductNotFoundException; - -/** - * @internal - */ -class UpdateProductStatusCommandHandler implements UpdateProductStatusCommandHandlerInterface -{ - /** - * @param UpdateProductStatusCommand $command - */ - public function handle(UpdateProductStatusCommand $command) - { - $productId = $command->getProductId()->getValue(); - $product = new Product($productId); - - if ($product->id !== $productId) { - throw new ProductNotFoundException(sprintf('Product with id "%s" was not found', $productId)); - } - if ($product->active != $command->getEnable()) { - if (!$product->toggleStatus()) { - throw new CannotUpdateProductException(sprintf('Cannot update status for product with id "%s"', $productId)); - } - } - } -} diff --git a/src/Adapter/Product/FilterCategoriesRequestPurifier.php b/src/Adapter/Product/FilterCategoriesRequestPurifier.php deleted file mode 100644 index bba3183d..00000000 --- a/src/Adapter/Product/FilterCategoriesRequestPurifier.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Symfony\Component\HttpFoundation\Request; - -/** - * Extracted from Product Controller, used to cleanup the request. - * For internal use only. - */ -final class FilterCategoriesRequestPurifier -{ - const CATEGORY = 'filter_category'; - - /** - * Changes the filter category values in case it is not numeric or signed. - * - * @param Request $request - * - * @return Request - */ - public function purify(Request $request) - { - if ($request->isMethod('POST')) { - $value = $request->request->get(self::CATEGORY); - if (null !== $value && (!is_numeric($value) || $value < 0)) { - $request->request->set(self::CATEGORY, ''); - } - } - - return $request; - } -} diff --git a/src/Adapter/Product/GeneralConfiguration.php b/src/Adapter/Product/GeneralConfiguration.php deleted file mode 100644 index 90897e4c..00000000 --- a/src/Adapter/Product/GeneralConfiguration.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This class loads and saves general configuration for product. - */ -class GeneralConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'catalog_mode' => $this->configuration->getBoolean('PS_CATALOG_MODE'), - 'catalog_mode_with_prices' => $this->configuration->getBoolean('PS_CATALOG_MODE_WITH_PRICES'), - 'new_days_number' => $this->configuration->get('PS_NB_DAYS_NEW_PRODUCT'), - 'short_description_limit' => $this->configuration->get('PS_PRODUCT_SHORT_DESC_LIMIT'), - 'quantity_discount' => $this->configuration->get('PS_QTY_DISCOUNT_ON_COMBINATION'), - 'force_friendly_url' => $this->configuration->getBoolean('PS_FORCE_FRIENDLY_PRODUCT'), - 'default_status' => $this->configuration->getBoolean('PS_PRODUCT_ACTIVATION_DEFAULT'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $catalogMode = (int) $config['catalog_mode']; - $this->configuration->set('PS_CATALOG_MODE', $catalogMode); - $this->configuration->set('PS_CATALOG_MODE_WITH_PRICES', $catalogMode ? (int) $config['catalog_mode_with_prices'] : 0); - $this->configuration->set('PS_NB_DAYS_NEW_PRODUCT', (int) $config['new_days_number']); - $this->configuration->set('PS_PRODUCT_SHORT_DESC_LIMIT', (int) $config['short_description_limit']); - $this->configuration->set('PS_QTY_DISCOUNT_ON_COMBINATION', (int) $config['quantity_discount']); - $this->configuration->set('PS_FORCE_FRIENDLY_PRODUCT', (int) $config['force_friendly_url']); - $this->configuration->set('PS_PRODUCT_ACTIVATION_DEFAULT', (int) $config['default_status']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $resolver = new OptionsResolver(); - $resolver->setRequired([ - 'catalog_mode', - 'catalog_mode_with_prices', - 'new_days_number', - 'short_description_limit', - 'quantity_discount', - 'force_friendly_url', - 'default_status', - ]); - - $resolver->resolve($configuration); - - return true; - } -} diff --git a/src/Adapter/Product/ListParametersUpdater.php b/src/Adapter/Product/ListParametersUpdater.php deleted file mode 100644 index e1aca8d8..00000000 --- a/src/Adapter/Product/ListParametersUpdater.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use PrestaShop\PrestaShop\Core\Exception\ProductException; - -/** - * Can manage filter parameters from request in Product Catalogue Page. - * For internal use only. - */ -final class ListParametersUpdater -{ - /** - * In case of position ordering all the filters should be reset. - * - * @param array $filterParameters - * @param string $orderBy - * @param bool $hasCategoryFilter - * - * @return array $filterParameters - */ - public function cleanFiltersForPositionOrdering($filterParameters, $orderBy, $hasCategoryFilter) - { - if ($orderBy == 'position_ordering' && $hasCategoryFilter) { - foreach (array_keys($filterParameters) as $key) { - if (strpos($key, 'filter_column_') === 0) { - $filterParameters[$key] = ''; - } - } - } - - return $filterParameters; - } - - /** - * @param array $queryFilterParameters - * @param array $persistedFilterParameters - * @param array $defaultFilterParameters - * - * @return array - * - * @throws ProductException - */ - public function buildListParameters( - array $queryFilterParameters, - array $persistedFilterParameters, - array $defaultFilterParameters - ) { - $filters = [ - 'offset' => (int) $this->getParameter( - 'offset', - $queryFilterParameters, - $persistedFilterParameters, - $defaultFilterParameters - ), - 'limit' => (int) $this->getParameter( - 'limit', - $queryFilterParameters, - $persistedFilterParameters, - $defaultFilterParameters - ), - 'orderBy' => (string) $this->getParameter( - 'orderBy', - $queryFilterParameters, - $persistedFilterParameters, - $defaultFilterParameters - ), - 'sortOrder' => (string) $this->getParameter( - 'sortOrder', - $queryFilterParameters, - $persistedFilterParameters, - $defaultFilterParameters - ), - ]; - - /* - * We need to force the sort order when the order by - * is set to position_ordering - */ - if ('position_ordering' === $filters['orderBy']) { - $filters['sortOrder'] = 'asc'; - } - - return $filters; - } - - /** - * @param string $parameterName - * @param array $queryFilterParameters - * @param array $persistedFilterParameters - * @param array $defaultFilterParameters - * - * @return string|int - * - * @throws ProductException - */ - private function getParameter( - $parameterName, - array $queryFilterParameters, - array $persistedFilterParameters, - array $defaultFilterParameters - ) { - if (isset($queryFilterParameters[$parameterName])) { - $value = $queryFilterParameters[$parameterName]; - } elseif (isset($persistedFilterParameters[$parameterName])) { - $value = $persistedFilterParameters[$parameterName]; - } elseif (isset($defaultFilterParameters[$parameterName])) { - $value = $defaultFilterParameters[$parameterName]; - } else { - throw new ProductException('Could not find the parameter %s', 'Admin.Notifications.Error', [$parameterName]); - } - - if ($value === 'last' && isset($persistedFilterParameters['last_' . $parameterName])) { - $value = $persistedFilterParameters['last_' . $parameterName]; - } - - return $value; - } -} diff --git a/src/Adapter/Product/PackItemsManager.php b/src/Adapter/Product/PackItemsManager.php deleted file mode 100644 index 19ace581..00000000 --- a/src/Adapter/Product/PackItemsManager.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Pack; -use PrestaShop\PrestaShop\Adapter\ServiceLocator; -use Product; - -/** - * Class responsible of getting information about Pack Items. - */ -class PackItemsManager -{ - /** - * Get the Products contained in the given Pack. - * - * @param \Pack $pack - * @param int $id_lang Optional - * - * @return array(Product) The products contained in this Pack, with special dynamic attributes [pack_quantity, id_pack_product_attribute] - */ - public function getPackItems($pack, $id_lang = false) - { - if ($id_lang === false) { - $configuration = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\ConfigurationInterface'); - $id_lang = (int) $configuration->get('PS_LANG_DEFAULT'); - } - - return Pack::getItems($pack->id, $id_lang); - } - - /** - * Get all Packs that contains the given item in the corresponding declination. - * - * @param Product $item - * @param int $item_attribute_id - * @param bool|int $id_lang Optional - * - * @return array(Pack) The packs that contains the given item, with special dynamic attribute [pack_item_quantity] - */ - public function getPacksContainingItem($item, $item_attribute_id, $id_lang = false) - { - if ($id_lang === false) { - $configuration = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\ConfigurationInterface'); - $id_lang = (int) $configuration->get('PS_LANG_DEFAULT'); - } - - return Pack::getPacksContainingItem($item->id, $item_attribute_id, $id_lang); - } - - /** - * Is this product a pack? - * - * @param Product $product - * - * @return bool - */ - public function isPack($product) - { - return Pack::isPack($product->id); - } - - /** - * Is this product in a pack? - * If $id_product_attribute specified, then will restrict search on the given combination, - * else this method will match a product if at least one of all its combination is in a pack. - * - * @param Product $product - * @param int $id_product_attribute Optional combination of the product - * - * @return bool - */ - public function isPacked($product, $id_product_attribute = false) - { - return Pack::isPacked($product->id, $id_product_attribute); - } -} diff --git a/src/Adapter/Product/PageConfiguration.php b/src/Adapter/Product/PageConfiguration.php deleted file mode 100644 index 0781a9c3..00000000 --- a/src/Adapter/Product/PageConfiguration.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class PageConfiguration is responsible for saving & loading product page configuration. - */ -class PageConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'display_quantities' => $this->configuration->getBoolean('PS_DISPLAY_QTIES'), - 'display_last_quantities' => $this->configuration->get('PS_LAST_QTIES'), - 'display_unavailable_attributes' => $this->configuration->getBoolean('PS_DISP_UNAVAILABLE_ATTR'), - 'allow_add_variant_to_cart_from_listing' => $this->configuration->getBoolean('PS_ATTRIBUTE_CATEGORY_DISPLAY'), - 'attribute_anchor_separator' => $this->configuration->get('PS_ATTRIBUTE_ANCHOR_SEPARATOR'), - 'display_discount_price' => $this->configuration->getBoolean('PS_DISPLAY_DISCOUNT_PRICE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_DISPLAY_QTIES', (int) $config['display_quantities']); - $this->configuration->set('PS_LAST_QTIES', (int) $config['display_last_quantities']); - $this->configuration->set('PS_DISP_UNAVAILABLE_ATTR', (int) $config['display_unavailable_attributes']); - $this->configuration->set('PS_ATTRIBUTE_CATEGORY_DISPLAY', (int) $config['allow_add_variant_to_cart_from_listing']); - $this->configuration->set('PS_ATTRIBUTE_ANCHOR_SEPARATOR', $config['attribute_anchor_separator']); - $this->configuration->set('PS_DISPLAY_DISCOUNT_PRICE', (int) $config['display_discount_price']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - $resolver = new OptionsResolver(); - $resolver->setRequired([ - 'display_quantities', - 'display_last_quantities', - 'display_unavailable_attributes', - 'allow_add_variant_to_cart_from_listing', - 'attribute_anchor_separator', - 'display_discount_price', - ]); - - $resolver->resolve($config); - - return true; - } -} diff --git a/src/Adapter/Product/PaginationConfiguration.php b/src/Adapter/Product/PaginationConfiguration.php deleted file mode 100644 index 75df1752..00000000 --- a/src/Adapter/Product/PaginationConfiguration.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class PaginationConfiguration is responsible for saving & loading pagination configuration for products. - */ -class PaginationConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'products_per_page' => $this->configuration->get('PS_PRODUCTS_PER_PAGE'), - 'default_order_by' => $this->configuration->get('PS_PRODUCTS_ORDER_BY'), - 'default_order_way' => $this->configuration->get('PS_PRODUCTS_ORDER_WAY'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_PRODUCTS_PER_PAGE', (int) $config['products_per_page']); - $this->configuration->set('PS_PRODUCTS_ORDER_BY', (int) $config['default_order_by']); - $this->configuration->set('PS_PRODUCTS_ORDER_WAY', (int) $config['default_order_way']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $resolver = new OptionsResolver(); - $resolver->setRequired([ - 'products_per_page', - 'default_order_by', - 'default_order_way', - ]); - - $resolver->resolve($configuration); - - return true; - } -} diff --git a/src/Adapter/Product/PriceCalculator.php b/src/Adapter/Product/PriceCalculator.php deleted file mode 100644 index b05e4f0b..00000000 --- a/src/Adapter/Product/PriceCalculator.php +++ /dev/null @@ -1,212 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Context; -use Product; - -/** - * Access Product price depending on taxes, eco tax, reductions. - */ -class PriceCalculator -{ - /** - * @param int $idProduct Product id - * @param bool $useTax With taxes or not (optional) - * @param int|null $idProductAttribute product attribute id (optional). - * If set to false, do not apply the combination price impact. - * NULL does apply the default combination price impact - * @param int $decimals Number of decimals (optional) - * @param int|null $divisor Useful when paying many time without fees (optional) - * @param bool $onlyReduc Returns only the reduction amount - * @param bool $useReduc Set if the returned amount will include reduction - * @param int $quantity Required for quantity discount application (default value: 1) - * @param bool $forceAssociatedTax DEPRECATED - NOT USED Force to apply the associated tax. - * Only works when the parameter $usetax is true - * @param int|null $idCustomer Customer ID (for customer group reduction) - * @param int|null $idCart Cart ID. Required when the cookie is not accessible - * (e.g., inside a payment module, a cron task...) - * @param int|null $idAddress Customer address ID. Required for price (tax included) - * calculation regarding the guest localization - * @param null $specificPriceOutput If a specific price applies regarding the previous parameters, - * this variable is filled with the corresponding SpecificPrice object - * @param bool $withEcotax insert ecotax in price output - * @param bool $useGroupReduction - * @param Context|null $context - * @param bool $useCustomerPrice - * @param int|null $idCustomization - * - * @return float Product price - */ - public function getProductPrice( - $idProduct, - $useTax = true, - $idProductAttribute = null, - $decimals = 6, - $divisor = null, - $onlyReduc = false, - $useReduc = true, - $quantity = 1, - $forceAssociatedTax = false, - $idCustomer = null, - $idCart = null, - $idAddress = null, - &$specificPriceOutput = null, - $withEcotax = true, - $useGroupReduction = true, - Context $context = null, - $useCustomerPrice = true, - $idCustomization = null - ) { - return Product::getPriceStatic( - $idProduct, - $useTax, - $idProductAttribute, - $decimals, - $divisor, - $onlyReduc, - $useReduc, - $quantity, - $forceAssociatedTax, - $idCustomer, - $idCart, - $idAddress, - $specificPriceOutput, - $withEcotax, - $useGroupReduction, - $context, - $useCustomerPrice, - $idCustomization - ); - } - - /** - * Price calculation / Get product price. - * - * @param int $idShop Shop id - * @param int $idProduct Product id - * @param int $idProductAttribute Product attribute id - * @param int $idCountry Country id - * @param int $idState State id - * @param string $zipCode - * @param int $idCurrency Currency id - * @param int $idGroup Group id - * @param int $quantity Quantity Required for Specific prices : quantity discount application - * @param bool $useTax with (1) or without (0) tax - * @param int $decimals Number of decimals returned - * @param bool $onlyReduc Returns only the reduction amount - * @param bool $useReduc Set if the returned amount will include reduction - * @param bool $withEcotax insert ecotax in price output - * @param null $specificPrice If a specific price applies regarding the previous parameters, - * this variable is filled with the corresponding SpecificPrice object - * @param bool $useGroupReduction - * @param int $idCustomer - * @param bool $useCustomerPrice - * @param int $idCart - * @param int $realQuantity - * @param int $idCustomization - * - * @return float Product price - **/ - public function priceCalculation( - $idShop, - $idProduct, - $idProductAttribute, - $idCountry, - $idState, - $zipCode, - $idCurrency, - $idGroup, - $quantity, - $useTax, - $decimals, - $onlyReduc, - $useReduc, - $withEcotax, - &$specificPrice, - $useGroupReduction, - $idCustomer = 0, - $useCustomerPrice = true, - $idCart = 0, - $realQuantity = 0, - $idCustomization = 0 - ) { - return Product::priceCalculation( - $idShop, - $idProduct, - $idProductAttribute, - $idCountry, - $idState, - $zipCode, - $idCurrency, - $idGroup, - $quantity, - $useTax, - $decimals, - $onlyReduc, - $useReduc, - $withEcotax, - $specificPrice, - $useGroupReduction, - $idCustomer, - $useCustomerPrice, - $idCart, - $realQuantity, - $idCustomization - ); - } - - /** - * @param int $orderId Order id - * @param int $productId Product id - * @param int $combinationId Combination (Product attribute) id - * @param bool $withTaxes With or without taxes - * @param bool $useReduction With or without reduction - * @param bool $withEcoTax With or without ecto tax - * - * @return float|null - * - * @throws \PrestaShopDatabaseException - */ - public function getOrderPrice( - int $orderId, - int $productId, - int $combinationId, - bool $withTaxes, - bool $useReduction, - bool $withEcoTax - ): ?float { - return Product::getPriceFromOrder( - $orderId, - $productId, - $combinationId, - $withTaxes, - $useReduction, - $withEcoTax - ); - } -} diff --git a/src/Adapter/Product/PriceFormatter.php b/src/Adapter/Product/PriceFormatter.php deleted file mode 100644 index b0aeae7d..00000000 --- a/src/Adapter/Product/PriceFormatter.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Tools; - -/** - * Format a price depending on locale and currency. - */ -class PriceFormatter -{ - /** - * @param float $price - * @param string|null $currency - * - * @return float - */ - public function convertAmount($price, $currency = null) - { - return (float) Tools::convertPrice($price, $currency); - } - - /** - * @param float $price - * @param string|null $currency - * - * @return string - */ - public function format($price, $currency = null) - { - return Tools::displayPrice($price, $currency); - } - - /** - * @param float $price - * - * @return string - */ - public function convertAndFormat($price) - { - return $this->format($this->convertAmount($price)); - } -} diff --git a/src/Adapter/Product/ProductColorsRetriever.php b/src/Adapter/Product/ProductColorsRetriever.php deleted file mode 100644 index 8f8ea2ca..00000000 --- a/src/Adapter/Product/ProductColorsRetriever.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Product; - -/** - * Retrieve colors of a Product, if any. - */ -class ProductColorsRetriever -{ - /** - * @param int $id_product - * - * @return mixed|null - */ - public function getColoredVariants($id_product) - { - $attributesColorList = Product::getAttributesColorList([$id_product]); - - return (is_array($attributesColorList)) ? current($attributesColorList) : null; - } -} diff --git a/src/Adapter/Product/ProductDataProvider.php b/src/Adapter/Product/ProductDataProvider.php deleted file mode 100644 index 59783c1e..00000000 --- a/src/Adapter/Product/ProductDataProvider.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use Context; -use Image; -use Product; -use StockAvailable; - -/** - * This class will provide data from DB / ORM about Product, for both Front and Admin interfaces. - */ -class ProductDataProvider -{ - /** - * Get a new ProductCore instance. - * - * @param null $idProduct - * - * @return Product - */ - public function getProductInstance($idProduct = null) - { - if ($idProduct) { - return new Product($idProduct); - } - - return new Product(); - } - - /** - * Get a product. - * - * @param int $id_product - * @param bool $full - * @param int|null $id_lang - * @param int|null $id_shop - * @param object|null $context - * - * @throws \LogicException If the product id is not set - * - * @return Product $product - */ - public function getProduct($id_product, $full = false, $id_lang = null, $id_shop = null, $context = null) - { - if (!$id_product) { - throw new \LogicException('You need to provide a product id', 5002); - } - - $product = new Product($id_product, $full, $id_lang, $id_shop, $context); - if ($product) { - if (!is_array($product->link_rewrite)) { - $linkRewrite = $product->link_rewrite; - } else { - $linkRewrite = $product->link_rewrite[$id_lang ? $id_lang : key($product->link_rewrite)]; - } - - $cover = Product::getCover($product->id); - $product->image = Context::getContext()->link->getImageLink($linkRewrite, $cover ? $cover['id_image'] : '', 'home_default'); - } - - return $product; - } - - /** - * Get default taxe rate product. - * - * @return int id tax rule group - */ - public function getIdTaxRulesGroup() - { - $product = new Product(); - - return $product->getIdTaxRulesGroup(); - } - - /** - * Get product quantity. - * - * @param int $id_product - * @param int|null $id_product_attribute - * @param bool|null $cache_is_pack - * - * @return int stock - */ - public function getQuantity($id_product, $id_product_attribute = null, $cache_is_pack = null) - { - return Product::getQuantity($id_product, $id_product_attribute, $cache_is_pack); - } - - /** - * @param int $id_product - * @param int $id_product_attribute Optional - * - * @return string - */ - public function getLocation($id_product, $id_product_attribute = 0) - { - return StockAvailable::getLocation($id_product, $id_product_attribute); - } - - /** - * Get associated images to product. - * - * @param int $id_product - * @param int $id_lang - * - * @return array - */ - public function getImages($id_product, $id_lang) - { - $id_shop = (int) Context::getContext()->shop->id; - $data = []; - foreach (Image::getImages($id_lang, $id_product, null, $id_shop) as $image) { - $data[] = $this->getImage($image['id_image']); - } - - return $data; - } - - /** - * Get an image. - * - * @param int $id_image - * - * @return array() - */ - public function getImage($id_image) - { - $imageData = new Image((int) $id_image); - - return [ - 'id' => $imageData->id, - 'id_product' => $imageData->id_product, - 'position' => $imageData->position, - 'cover' => $imageData->cover ? true : false, - 'legend' => $imageData->legend, - 'format' => $imageData->image_format, - 'base_image_url' => _THEME_PROD_DIR_ . $imageData->getImgPath(), - ]; - } -} diff --git a/src/Adapter/Product/QueryHandler/GetProductIsEnabledHandler.php b/src/Adapter/Product/QueryHandler/GetProductIsEnabledHandler.php deleted file mode 100644 index daf477e3..00000000 --- a/src/Adapter/Product/QueryHandler/GetProductIsEnabledHandler.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Entity\Product; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductIsEnabled; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryHandler\GetProductIsEnabledHandlerInterface; - -/** - * @internal - */ -final class GetProductIsEnabledHandler implements GetProductIsEnabledHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetProductIsEnabled $query) - { - $productId = $query->getProductId()->getValue(); - $product = new Product($productId); - - if ($product->id !== $productId) { - throw new ProductNotFoundException(sprintf('Product with id "%s" was not found.', $productId)); - } - - return (bool) $product->active; - } -} diff --git a/src/Adapter/Product/QueryHandler/SearchProductsHandler.php b/src/Adapter/Product/QueryHandler/SearchProductsHandler.php deleted file mode 100644 index 58b34773..00000000 --- a/src/Adapter/Product/QueryHandler/SearchProductsHandler.php +++ /dev/null @@ -1,318 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Product\QueryHandler; - -use Address; -use Configuration; -use Currency; -use Order; -use PrestaShop\PrestaShop\Adapter\ContextStateManager; -use PrestaShop\PrestaShop\Adapter\Currency\CurrencyDataProvider; -use PrestaShop\PrestaShop\Adapter\Order\AbstractOrderHandler; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\Domain\Product\Query\SearchProducts; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryHandler\SearchProductsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\FoundProduct; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\ProductCombination; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\ProductCustomizationField; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; -use Product; -use Shop; - -/** - * Handles products search using legacy object model - */ -final class SearchProductsHandler extends AbstractOrderHandler implements SearchProductsHandlerInterface -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var LocaleInterface - */ - private $contextLocale; - - /** - * @var ContextStateManager - */ - private $contextStateManager; - - /** - * @var CurrencyDataProvider - */ - private $currencyDataProvider; - - /** - * @var Tools - */ - private $tools; - - /** - * @param int $contextLangId - * @param LocaleInterface $contextLocale - * @param Tools $tools - * @param CurrencyDataProvider $currencyDataProvider - * @param ContextStateManager $contextStateManager - */ - public function __construct( - int $contextLangId, - LocaleInterface $contextLocale, - Tools $tools, - CurrencyDataProvider $currencyDataProvider, - ContextStateManager $contextStateManager - ) { - $this->contextLangId = $contextLangId; - $this->contextLocale = $contextLocale; - $this->currencyDataProvider = $currencyDataProvider; - $this->tools = $tools; - $this->contextStateManager = $contextStateManager; - } - - /** - * {@inheritdoc} - * - * @param SearchProducts $query - * - * @return array - */ - public function handle(SearchProducts $query): array - { - $currency = $this->currencyDataProvider->getCurrencyByIsoCode($query->getAlphaIsoCode()->getValue()); - $this->contextStateManager - ->setCurrency($currency) - ; - if (null !== $query->getOrderId()) { - $order = $this->getOrder($query->getOrderId()); - $this->contextStateManager - ->setShop(new Shop($order->id_shop)) - ; - } - - try { - $foundProducts = $this->searchProducts($query, $currency); - } finally { - $this->contextStateManager->restorePreviousContext(); - } - - return $foundProducts; - } - - /** - * @param SearchProducts $query - * @param Currency $currency - * - * @return array - */ - private function searchProducts(SearchProducts $query, Currency $currency): array - { - $computingPrecision = new ComputingPrecision(); - $currencyPrecision = $computingPrecision->getPrecision((int) $currency->precision); - - $order = $address = null; - if (null !== $query->getOrderId()) { - $order = $this->getOrder($query->getOrderId()); - $orderAddressId = $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)}; - $address = new Address($orderAddressId); - } - - $products = Product::searchByName( - $this->contextLangId, - $query->getPhrase(), - null, - $query->getResultsLimit() - ); - - $foundProducts = []; - if ($products) { - foreach ($products as $product) { - $foundProduct = $this->createFoundProductFromLegacy( - new Product($product['id_product']), - $query->getAlphaIsoCode()->getValue(), - $currencyPrecision, - $order, - $address - ); - $foundProducts[] = $foundProduct; - } - } - - return $foundProducts; - } - - /** - * @param Product $product - * @param string $isoCodeCurrency - * @param int $computingPrecision - * @param Order|null $order - * @param Address|null $address - * - * @return FoundProduct - */ - private function createFoundProductFromLegacy( - Product $product, - string $isoCodeCurrency, - int $computingPrecision, - ?Order $order = null, - ?Address $address = null - ): FoundProduct { - // It's important to use null (not 0) as attribute ID so that Product::priceCalculation can fallback to default combination - $priceTaxExcluded = $this->getProductPriceForOrder((int) $product->id, null, false, $computingPrecision, $order); - $priceTaxIncluded = $this->getProductPriceForOrder((int) $product->id, null, true, $computingPrecision, $order); - $product->loadStockData(); - - return new FoundProduct( - $product->id, - $product->name[$this->contextLangId], - $this->contextLocale->formatPrice($priceTaxExcluded, $isoCodeCurrency), - $this->tools->round($priceTaxIncluded, $computingPrecision), - $this->tools->round($priceTaxExcluded, $computingPrecision), - $product->getTaxesRate($address), - Product::getQuantity($product->id), - $product->location, - (bool) Product::isAvailableWhenOutOfStock($product->out_of_stock), - $this->getProductCombinations($product, $isoCodeCurrency, $computingPrecision, $order), - $this->getProductCustomizationFields($product) - ); - } - - /** - * @param Product $product - * - * @return ProductCustomizationField[] - */ - private function getProductCustomizationFields(Product $product): array - { - $fields = $product->getCustomizationFields(); - $customizationFields = []; - - if (false !== $fields) { - foreach ($fields as $typeId => $typeFields) { - foreach ($typeFields as $field) { - $customizationField = new ProductCustomizationField( - (int) $field[$this->contextLangId]['id_customization_field'], - (int) $typeId, - $field[$this->contextLangId]['name'], - (bool) $field[$this->contextLangId]['required'] - ); - - $customizationFields[$customizationField->getCustomizationFieldId()] = $customizationField; - } - } - } - - return $customizationFields; - } - - /** - * @param Product $product - * @param string $currencyIsoCode - * @param int $computingPrecision - * @param Order|null $order - * - * @return array - */ - private function getProductCombinations( - Product $product, - string $currencyIsoCode, - int $computingPrecision, - ?Order $order = null - ): array { - $productCombinations = []; - $combinations = $product->getAttributeCombinations(); - - if (false !== $combinations) { - foreach ($combinations as $combination) { - $productAttributeId = (int) $combination['id_product_attribute']; - $attribute = $combination['attribute_name']; - - if (isset($productCombinations[$productAttributeId])) { - $existingAttribute = $productCombinations[$productAttributeId]->getAttribute(); - $attribute = $existingAttribute . ' - ' . $attribute; - } - - $priceTaxExcluded = $this->getProductPriceForOrder((int) $product->id, $productAttributeId, false, $computingPrecision, $order); - $priceTaxIncluded = $this->getProductPriceForOrder((int) $product->id, $productAttributeId, true, $computingPrecision, $order); - - $productCombination = new ProductCombination( - $productAttributeId, - $attribute, - $combination['quantity'], - $this->contextLocale->formatPrice($priceTaxExcluded, $currencyIsoCode), - $priceTaxExcluded, - $priceTaxIncluded, - $combination['location'], - $combination['reference'] - ); - - $productCombinations[$productCombination->getAttributeCombinationId()] = $productCombination; - } - } - - return $productCombinations; - } - - /** - * @param int $productId - * @param int|null $productAttributeId - * @param bool $withTaxes - * @param int $computingPrecision - * @param Order|null $order - * - * @return float - */ - private function getProductPriceForOrder( - int $productId, - ?int $productAttributeId, - bool $withTaxes, - int $computingPrecision, - ?Order $order) - { - if (null === $order) { - return Product::getPriceStatic($productId, $withTaxes, $productAttributeId, $computingPrecision); - } - - return Product::getPriceStatic( - $productId, - $withTaxes, - $productAttributeId, - $computingPrecision, - null, - false, - true, - 1, - false, - $order->id_customer, - $order->id_cart, - $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)} - ); - } -} diff --git a/src/Adapter/Product/StockConfiguration.php b/src/Adapter/Product/StockConfiguration.php deleted file mode 100644 index aa362c74..00000000 --- a/src/Adapter/Product/StockConfiguration.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Product; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class StockConfiguration is responsible for saving & loading products stock configuration. - */ -class StockConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'allow_ordering_oos' => $this->configuration->getBoolean('PS_ORDER_OUT_OF_STOCK'), - 'stock_management' => $this->configuration->getBoolean('PS_STOCK_MANAGEMENT'), - 'in_stock_label' => $this->configuration->get('PS_LABEL_IN_STOCK_PRODUCTS'), - 'oos_allowed_backorders' => $this->configuration->get('PS_LABEL_OOS_PRODUCTS_BOA'), - 'oos_denied_backorders' => $this->configuration->get('PS_LABEL_OOS_PRODUCTS_BOD'), - 'delivery_time' => (array) $this->configuration->get('PS_LABEL_DELIVERY_TIME_AVAILABLE'), - 'oos_delivery_time' => (array) $this->configuration->get('PS_LABEL_DELIVERY_TIME_OOSBOA'), - 'pack_stock_management' => $this->configuration->get('PS_PACK_STOCK_TYPE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_ORDER_OUT_OF_STOCK', (int) $config['allow_ordering_oos']); - $this->configuration->set('PS_STOCK_MANAGEMENT', (int) $config['stock_management']); - $this->configuration->set('PS_LABEL_IN_STOCK_PRODUCTS', $config['in_stock_label']); - $this->configuration->set('PS_LABEL_OOS_PRODUCTS_BOA', $config['oos_allowed_backorders']); - $this->configuration->set('PS_LABEL_OOS_PRODUCTS_BOD', $config['oos_denied_backorders']); - $this->configuration->set('PS_LABEL_DELIVERY_TIME_AVAILABLE', $config['delivery_time']); - $this->configuration->set('PS_LABEL_DELIVERY_TIME_OOSBOA', $config['oos_delivery_time']); - $this->configuration->set('PS_PACK_STOCK_TYPE', $config['pack_stock_management']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $resolver = new OptionsResolver(); - $resolver->setRequired([ - 'allow_ordering_oos', - 'stock_management', - 'in_stock_label', - 'delivery_time', - 'oos_allowed_backorders', - 'oos_delivery_time', - 'oos_denied_backorders', - 'pack_stock_management', - ]); - - $resolver->resolve($configuration); - - return true; - } -} diff --git a/src/Adapter/Profile/CommandHandler/AbstractProfileHandler.php b/src/Adapter/Profile/CommandHandler/AbstractProfileHandler.php deleted file mode 100644 index f6d4922d..00000000 --- a/src/Adapter/Profile/CommandHandler/AbstractProfileHandler.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\FailedToDeleteProfileException; -use Profile; - -/** - * @internal - */ -abstract class AbstractProfileHandler -{ - /** - * Checks if given profile is not assigned to any employee. - * - * @param Profile $profile - * - * @throws FailedToDeleteProfileException - */ - protected function assertProfileIsNotAssignedToEmployee(Profile $profile) - { - $profileEmployees = Employee::getEmployeesByProfile($profile->id); - - if (!empty($profileEmployees)) { - throw new FailedToDeleteProfileException(sprintf('Failed to delete profile with id "%d", because it is assigned to employee.', $profile->id), FailedToDeleteProfileException::PROFILE_IS_ASSIGNED_TO_EMPLOYEE); - } - } -} diff --git a/src/Adapter/Profile/CommandHandler/AddProfileHandler.php b/src/Adapter/Profile/CommandHandler/AddProfileHandler.php deleted file mode 100644 index f0bd4d88..00000000 --- a/src/Adapter/Profile/CommandHandler/AddProfileHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\AddProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler\AddProfileHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; -use Profile; - -/** - * Adds new employee profile using legacy object model - */ -final class AddProfileHandler implements AddProfileHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddProfileCommand $command) - { - $profile = new Profile(); - $profile->name = $command->getLocalizedNames(); - - if (false === $profile->validateFieldsLang(false)) { - throw new ProfileException('Cannot create Profile because it contains invalid data'); - } - - if (false === $profile->add()) { - throw new ProfileException('Failed to create Profile'); - } - - return new ProfileId((int) $profile->id); - } -} diff --git a/src/Adapter/Profile/CommandHandler/BulkDeleteProfileHandler.php b/src/Adapter/Profile/CommandHandler/BulkDeleteProfileHandler.php deleted file mode 100644 index 7d569204..00000000 --- a/src/Adapter/Profile/CommandHandler/BulkDeleteProfileHandler.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\BulkDeleteProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler\BulkDeleteProfileHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\CannotDeleteSuperAdminProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\FailedToDeleteProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileNotFoundException; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShopException; -use Profile; - -/** - * Class BulkDeleteProfileHandler - * - * @internal - */ -final class BulkDeleteProfileHandler extends AbstractProfileHandler implements BulkDeleteProfileHandlerInterface -{ - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @param int $superAdminProfileId - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - */ - public function __construct($superAdminProfileId, ContextEmployeeProviderInterface $contextEmployeeProvider) - { - $this->superAdminProfileId = $superAdminProfileId; - $this->contextEmployeeProvider = $contextEmployeeProvider; - } - - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteProfileCommand $command) - { - $entityIds = $command->getProfileIds(); - - foreach ($entityIds as $entityId) { - $entityIdValue = $entityId->getValue(); - - try { - $entity = new Profile($entityIdValue); - - if ($entity->id != $entityIdValue) { - throw new ProfileNotFoundException(sprintf('Profile with id %s cannot be found.', var_export($entityIdValue, true))); - } - - if ($this->contextEmployeeProvider->getProfileId() === $entity->id) { - throw new FailedToDeleteProfileException(sprintf('Failed to delete Profile with id %s', var_export($entityIdValue, true)), FailedToDeleteProfileException::PROFILE_IS_ASSIGNED_TO_CONTEXT_EMPLOYEE); - } - - if ($entity->id == $this->superAdminProfileId) { - throw new CannotDeleteSuperAdminProfileException(sprintf('Cannot delete Profile with id %s', var_export($entityIdValue, true))); - } - - $this->assertProfileIsNotAssignedToEmployee($entity); - - if (false === $entity->delete()) { - throw new FailedToDeleteProfileException(sprintf('Failed to delete Profile with id %s', var_export($entityIdValue, true)), FailedToDeleteProfileException::UNEXPECTED_ERROR); - } - } catch (PrestaShopException $e) { - throw new ProfileException(sprintf('Unexpected error occurred when deleting Profile with id %s', var_export($entityIdValue, true)), 0, $e); - } - } - } -} diff --git a/src/Adapter/Profile/CommandHandler/DeleteProfileHandler.php b/src/Adapter/Profile/CommandHandler/DeleteProfileHandler.php deleted file mode 100644 index e2e87a2e..00000000 --- a/src/Adapter/Profile/CommandHandler/DeleteProfileHandler.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\DeleteProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler\DeleteProfileHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\CannotDeleteSuperAdminProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\FailedToDeleteProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileNotFoundException; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShopException; -use Profile; - -/** - * Class DeleteProfileHandler - * - * @internal - */ -final class DeleteProfileHandler extends AbstractProfileHandler implements DeleteProfileHandlerInterface -{ - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @param int $superAdminProfileId - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - */ - public function __construct($superAdminProfileId, ContextEmployeeProviderInterface $contextEmployeeProvider) - { - $this->superAdminProfileId = $superAdminProfileId; - $this->contextEmployeeProvider = $contextEmployeeProvider; - } - - /** - * {@inheritdoc} - */ - public function handle(DeleteProfileCommand $command) - { - $entityId = $command->getProfileId()->getValue(); - - try { - $entity = new Profile($entityId); - - if ($entity->id != $entityId) { - throw new ProfileNotFoundException(sprintf('Profile with id %s cannot be found.', var_export($entityId, true))); - } - - if ($this->contextEmployeeProvider->getProfileId() === $entity->id) { - throw new FailedToDeleteProfileException(sprintf('Failed to delete Profile with id %s', var_export($entityId, true)), FailedToDeleteProfileException::PROFILE_IS_ASSIGNED_TO_CONTEXT_EMPLOYEE); - } - - $this->assertProfileIsNotAssignedToEmployee($entity); - - if ($entity->id == $this->superAdminProfileId) { - throw new CannotDeleteSuperAdminProfileException(sprintf('Cannot delete Profile with id %s', var_export($entityId, true))); - } - - if (false === $entity->delete()) { - throw new FailedToDeleteProfileException(sprintf('Failed to delete Profile with id %s', var_export($entityId, true))); - } - } catch (PrestaShopException $e) { - throw new ProfileException(sprintf('Unexpected error occurred when deleting Profile with id %s', var_export($entityId, true)), 0, $e); - } - } -} diff --git a/src/Adapter/Profile/CommandHandler/EditProfileHandler.php b/src/Adapter/Profile/CommandHandler/EditProfileHandler.php deleted file mode 100644 index 9d147e2f..00000000 --- a/src/Adapter/Profile/CommandHandler/EditProfileHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\EditProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler\EditProfileHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; -use Profile; - -/** - * Edits Profile using legacy object model - */ -final class EditProfileHandler implements EditProfileHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditProfileCommand $command) - { - $profile = $this->getProfile($command->getProfileId()); - $profile->name = $command->getLocalizedNames(); - - if (false === $profile->validateFieldsLang(false)) { - throw new ProfileException('Cannot edit Profile because it contains invalid data'); - } - - if (false === $profile->update()) { - throw new ProfileException('Failed to edit Profile'); - } - } - - /** - * @param ProfileId $profileId - * - * @return Profile - * - * @throws ProfileNotFoundException - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - private function getProfile(ProfileId $profileId) - { - $profile = new Profile($profileId->getValue()); - - if ($profile->id !== $profileId->getValue()) { - throw new ProfileNotFoundException(sprintf('Profile with id "%s" was not found', $profileId->getValue())); - } - - return $profile; - } -} diff --git a/src/Adapter/Profile/Employee/AbstractEmployeeHandler.php b/src/Adapter/Profile/Employee/AbstractEmployeeHandler.php deleted file mode 100644 index cb03b9bc..00000000 --- a/src/Adapter/Profile/Employee/AbstractEmployeeHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -abstract class AbstractEmployeeHandler -{ - /** - * @param EmployeeId $employeeId - * - * @return Employee - * - * @throws EmployeeNotFoundException - */ - protected function getEmployee(EmployeeId $employeeId): Employee - { - $employee = new Employee($employeeId->getValue()); - - if ($employee->id !== $employeeId->getValue()) { - throw new EmployeeNotFoundException($employeeId, sprintf('Employee with id "%s" was not found', $employeeId->getValue())); - } - - return $employee; - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/AbstractEmployeeHandler.php b/src/Adapter/Profile/Employee/CommandHandler/AbstractEmployeeHandler.php deleted file mode 100644 index b5130ca1..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/AbstractEmployeeHandler.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Context; -use Employee; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\AdminEmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\CannotDeleteWarehouseManagerException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeCannotChangeItselfException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use Warehouse; - -/** - * Class AbstractEmployeeStatusHandler. - */ -abstract class AbstractEmployeeHandler extends AbstractObjectModelHandler -{ - /** - * @param EmployeeId $employeeId - * @param Employee $employee - * - * @throws EmployeeNotFoundException - */ - protected function assertEmployeeWasFoundById(EmployeeId $employeeId, Employee $employee) - { - if (!$employee->id) { - throw new EmployeeNotFoundException($employeeId, sprintf('Employee with id "%s" cannot be found.', $employeeId->getValue())); - } - } - - /** - * If employee is admin and no other admins exists, then terminate command execution. - * - * @param Employee $employee - */ - protected function assertEmployeeIsNotTheOnlyAdminInShop(Employee $employee) - { - if ($employee->isLastAdmin()) { - throw new AdminEmployeeException(sprintf('Employee with id %s is the only admin in shop and status cannot be changed.', $employee->id), AdminEmployeeException::CANNOT_CHANGE_LAST_ADMIN); - } - } - - /** - * If logged in employee is trying to toggle itself, then terminate execution. - * - * @param Employee $employee - */ - protected function assertLoggedInEmployeeIsNotTheSameAsBeingUpdatedEmployee(Employee $employee) - { - if (Context::getContext()->employee->id === $employee->id) { - throw new EmployeeCannotChangeItselfException('Employee cannot change status of itself.', EmployeeCannotChangeItselfException::CANNOT_CHANGE_STATUS); - } - } - - /** - * Make sure that given employee does not manage any warehouse. - * - * Even though Warehouse feature was removed in 1.7 - * but the code related to it still exists - * thus assertion is kept for BC i guess. - * - * @param Employee $employee - */ - protected function assertEmployeeDoesNotManageWarehouse(Employee $employee) - { - $warehouses = Warehouse::getWarehousesByEmployee($employee->id); - - if (count($warehouses) > 0) { - throw new CannotDeleteWarehouseManagerException(sprintf('Employee with id %s is warehouse manager and cannot be deleted.', $employee->id)); - } - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/AddEmployeeHandler.php b/src/Adapter/Profile/Employee/CommandHandler/AddEmployeeHandler.php deleted file mode 100644 index 7efec336..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/AddEmployeeHandler.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Crypto\Hashing; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\AddEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\AddEmployeeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmailAlreadyUsedException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidProfileException; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Employee\Access\ProfileAccessCheckerInterface; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; - -/** - * Handles command which adds new employee using legacy object model - * - * @internal - */ -final class AddEmployeeHandler extends AbstractEmployeeHandler implements AddEmployeeHandlerInterface -{ - /** - * @var Hashing - */ - private $hashing; - - /** - * @var ProfileAccessCheckerInterface - */ - private $profileAccessChecker; - - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @param Hashing $hashing - * @param ProfileAccessCheckerInterface $profileAccessChecker - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - */ - public function __construct( - Hashing $hashing, - ProfileAccessCheckerInterface $profileAccessChecker, - ContextEmployeeProviderInterface $contextEmployeeProvider - ) { - $this->hashing = $hashing; - $this->profileAccessChecker = $profileAccessChecker; - $this->contextEmployeeProvider = $contextEmployeeProvider; - } - - /** - * {@inheritdoc} - */ - public function handle(AddEmployeeCommand $command) - { - $canAccessProfile = $this->profileAccessChecker->canEmployeeAccessProfile( - $this->contextEmployeeProvider->getId(), - (int) $command->getProfileId() - ); - - if (!$canAccessProfile) { - throw new InvalidProfileException('You cannot access the provided profile.'); - } - - $this->assertEmailIsNotAlreadyUsed($command->getEmail()->getValue()); - - $employee = $this->createLegacyEmployeeObjectFromCommand($command); - - $this->associateWithShops($employee, $command->getShopAssociation()); - - return new EmployeeId((int) $employee->id); - } - - /** - * Create legacy employee object. - * - * @param AddEmployeeCommand $command - * - * @return Employee - */ - private function createLegacyEmployeeObjectFromCommand(AddEmployeeCommand $command) - { - $employee = new Employee(); - $employee->firstname = $command->getFirstName()->getValue(); - $employee->lastname = $command->getLastName()->getValue(); - $employee->email = $command->getEmail()->getValue(); - $employee->id_lang = $command->getLanguageId(); - $employee->id_profile = $command->getProfileId(); - $employee->default_tab = $command->getDefaultPageId(); - $employee->active = $command->isActive(); - $employee->passwd = $this->hashing->hash($command->getPlainPassword()->getValue()); - $employee->id_last_order = $employee->getLastElementsForNotify('order'); - $employee->id_last_customer_message = $employee->getLastElementsForNotify('customer_message'); - $employee->id_last_customer = $employee->getLastElementsForNotify('customer'); - - if (false === $employee->add()) { - throw new EmployeeException(sprintf('Failed to add new employee with email "%s"', $command->getEmail()->getValue())); - } - - return $employee; - } - - /** - * @param string $email - * - * @throws EmailAlreadyUsedException - */ - private function assertEmailIsNotAlreadyUsed($email) - { - if (Employee::employeeExists($email)) { - throw new EmailAlreadyUsedException($email, 'An account already exists for this email address'); - } - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/BulkDeleteEmployeeHandler.php b/src/Adapter/Profile/Employee/CommandHandler/BulkDeleteEmployeeHandler.php deleted file mode 100644 index 0374ebed..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/BulkDeleteEmployeeHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkDeleteEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\BulkDeleteEmployeeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\CannotDeleteEmployeeException; - -/** - * Class BulkDeleteEmployeeHandler. - */ -final class BulkDeleteEmployeeHandler extends AbstractEmployeeHandler implements BulkDeleteEmployeeHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteEmployeeCommand $command) - { - foreach ($command->getEmployeeIds() as $employeeId) { - $employee = new Employee($employeeId->getValue()); - - $this->assertEmployeeWasFoundById($employeeId, $employee); - $this->assertLoggedInEmployeeIsNotTheSameAsBeingUpdatedEmployee($employee); - $this->assertEmployeeIsNotTheOnlyAdminInShop($employee); - $this->assertEmployeeDoesNotManageWarehouse($employee); - - if (!$employee->delete()) { - throw new CannotDeleteEmployeeException($employeeId, sprintf('Cannot delete employee with id "%s".', $employeeId->getValue())); - } - } - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/BulkUpdateEmployeeStatusHandler.php b/src/Adapter/Profile/Employee/CommandHandler/BulkUpdateEmployeeStatusHandler.php deleted file mode 100644 index ed3cbcd9..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/BulkUpdateEmployeeStatusHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkUpdateEmployeeStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\BulkUpdateEmployeeStatusHandlerInterface; - -/** - * Class BulkUpdateEmployeeStatusHandler. - */ -final class BulkUpdateEmployeeStatusHandler extends AbstractEmployeeHandler implements BulkUpdateEmployeeStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkUpdateEmployeeStatusCommand $command) - { - foreach ($command->getEmployeeIds() as $employeeId) { - $employee = new Employee($employeeId->getValue()); - - $this->assertEmployeeWasFoundById($employeeId, $employee); - $this->assertLoggedInEmployeeIsNotTheSameAsBeingUpdatedEmployee($employee); - $this->assertEmployeeIsNotTheOnlyAdminInShop($employee); - - $employee->active = $command->getStatus(); - $employee->save(); - } - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/DeleteEmployeeHandler.php b/src/Adapter/Profile/Employee/CommandHandler/DeleteEmployeeHandler.php deleted file mode 100644 index d26cd017..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/DeleteEmployeeHandler.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\DeleteEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\DeleteEmployeeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\CannotDeleteEmployeeException; - -/** - * Class DeleteEmployeeHandler. - */ -final class DeleteEmployeeHandler extends AbstractEmployeeHandler implements DeleteEmployeeHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteEmployeeCommand $command) - { - $employeeId = $command->getEmployeeId(); - $employee = new Employee($employeeId->getValue()); - - $this->assertEmployeeWasFoundById($employeeId, $employee); - $this->assertLoggedInEmployeeIsNotTheSameAsBeingUpdatedEmployee($employee); - $this->assertEmployeeIsNotTheOnlyAdminInShop($employee); - $this->assertEmployeeDoesNotManageWarehouse($employee); - - if (!$employee->delete()) { - throw new CannotDeleteEmployeeException($employeeId, sprintf('Cannot delete employee with id "%s".', $employeeId->getValue())); - } - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/EditEmployeeHandler.php b/src/Adapter/Profile/Employee/CommandHandler/EditEmployeeHandler.php deleted file mode 100644 index dbd7f35a..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/EditEmployeeHandler.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Crypto\Hashing; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\EditEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\EditEmployeeHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmailAlreadyUsedException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidProfileException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\MissingShopAssociationException; -use PrestaShop\PrestaShop\Core\Employee\Access\ProfileAccessCheckerInterface; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use Shop; - -/** - * Handles command which edits employee using legacy object model - * - * @internal - */ -final class EditEmployeeHandler extends AbstractEmployeeHandler implements EditEmployeeHandlerInterface -{ - /** - * @var Hashing - */ - private $hashing; - - /** - * @var ProfileAccessCheckerInterface - */ - private $profileAccessChecker; - - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @var LegacyContext - */ - private $legacyContext; - - /** - * @param Hashing $hashing - * @param ProfileAccessCheckerInterface $profileAccessChecker - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - * @param LegacyContext $legacyContext - */ - public function __construct( - Hashing $hashing, - ProfileAccessCheckerInterface $profileAccessChecker, - ContextEmployeeProviderInterface $contextEmployeeProvider, - LegacyContext $legacyContext - ) { - $this->hashing = $hashing; - $this->profileAccessChecker = $profileAccessChecker; - $this->contextEmployeeProvider = $contextEmployeeProvider; - $this->legacyContext = $legacyContext; - } - - /** - * {@inheritdoc} - */ - public function handle(EditEmployeeCommand $command) - { - $canAccessProfile = $this->profileAccessChecker->canEmployeeAccessProfile( - $this->contextEmployeeProvider->getId(), - (int) $command->getProfileId() - ); - - if (!$canAccessProfile) { - throw new InvalidProfileException('You cannot access the provided profile.'); - } - - $employee = new Employee($command->getEmployeeId()->getValue()); - - $this->assertEmailIsNotAlreadyUsed($employee, $command->getEmail()->getValue()); - - $this->updateEmployeeWithCommandData($employee, $command); - - if (null !== $command->getPlainPassword() && $employee->id == $this->contextEmployeeProvider->getId()) { - $this->updatePasswordInCookie($employee); - } - } - - /** - * Update employee object model with data from employee edit command. - * - * @param Employee $employee - * @param EditEmployeeCommand $command - * - * @throws EmployeeException - */ - private function updateEmployeeWithCommandData(Employee $employee, EditEmployeeCommand $command) - { - $employee->firstname = $command->getFirstName()->getValue(); - $employee->lastname = $command->getLastName()->getValue(); - $employee->email = $command->getEmail()->getValue(); - $employee->default_tab = $command->getDefaultPageId(); - $employee->id_lang = $command->getLanguageId(); - $employee->id_last_order = $employee->getLastElementsForNotify('order'); - $employee->id_last_customer_message = $employee->getLastElementsForNotify('customer_message'); - $employee->id_last_customer = $employee->getLastElementsForNotify('customer'); - - // Allow changing profile and active status only when editing not own account. - if ($employee->id != $this->contextEmployeeProvider->getId()) { - $employee->id_profile = $command->getProfileId(); - $employee->active = $command->isActive(); - } - - $shopAssociation = $command->getShopAssociation(); - - if (!$employee->isSuperAdmin() && empty($shopAssociation)) { - throw new MissingShopAssociationException('Employee must be associated to at least one shop.'); - } - - if (null !== $command->getPlainPassword()) { - $employee->passwd = $this->hashing->hash($command->getPlainPassword()->getValue()); - } - - if (false === $employee->update()) { - throw new EmployeeException(sprintf('Cannot update employee with id "%s"', $employee->id)); - } - - if ($employee->isSuperAdmin()) { - $shopAssociation = array_values(Shop::getShops(false, null, true)); - } - - // Allow changing shop association only when editing not own account. - if (null !== $shopAssociation && $employee->id != $this->contextEmployeeProvider->getId()) { - $this->associateWithShops($employee, $shopAssociation); - } - } - - /** - * @param Employee $employee - * @param string $email - * - * @throws EmailAlreadyUsedException - */ - private function assertEmailIsNotAlreadyUsed(Employee $employee, $email) - { - // Don't count own email as usage. - if ($employee->email === $email) { - return; - } - - if (Employee::employeeExists($email)) { - throw new EmailAlreadyUsedException($email, 'An account already exists for this email address'); - } - } - - /** - * Update employee password in cookie. - * - * @param Employee $employee - */ - private function updatePasswordInCookie(Employee $employee) - { - $this->legacyContext->getContext()->cookie->passwd = $employee->passwd; - $this->legacyContext->getContext()->employee->passwd = $employee->passwd; - $this->legacyContext->getContext()->cookie->write(); - } -} diff --git a/src/Adapter/Profile/Employee/CommandHandler/ToggleEmployeeStatusHandler.php b/src/Adapter/Profile/Employee/CommandHandler/ToggleEmployeeStatusHandler.php deleted file mode 100644 index 90307344..00000000 --- a/src/Adapter/Profile/Employee/CommandHandler/ToggleEmployeeStatusHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\ToggleEmployeeStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler\ToggleEmployeeStatusHandlerInterface; - -/** - * Class ToggleEmployeeStatusHandler encapsulates Employee status toggling using legacy Employee object model. - */ -final class ToggleEmployeeStatusHandler extends AbstractEmployeeHandler implements ToggleEmployeeStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(ToggleEmployeeStatusCommand $command) - { - $employeeId = $command->getEmployeeId(); - $employee = new Employee($employeeId->getValue()); - - $this->assertEmployeeWasFoundById($employeeId, $employee); - $this->assertLoggedInEmployeeIsNotTheSameAsBeingUpdatedEmployee($employee); - $this->assertEmployeeIsNotTheOnlyAdminInShop($employee); - - $employee->toggleStatus(); - } -} diff --git a/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeEmailByIdHandler.php b/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeEmailByIdHandler.php deleted file mode 100644 index 3ab59077..00000000 --- a/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeEmailByIdHandler.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Profile\Employee\AbstractEmployeeHandler; -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeEmailById; -use PrestaShop\PrestaShop\Core\Domain\Employee\QueryHandler\GetEmployeeEmailByIdHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -final class GetEmployeeEmailByIdHandler extends AbstractEmployeeHandler implements GetEmployeeEmailByIdHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetEmployeeEmailById $query): Email - { - $employee = $this->getEmployee($query->getEmployeeId()); - - return new Email($employee->email); - } -} diff --git a/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeForEditingHandler.php b/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeForEditingHandler.php deleted file mode 100644 index d394962c..00000000 --- a/src/Adapter/Profile/Employee/QueryHandler/GetEmployeeForEditingHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\Employee\QueryHandler; - -use Employee; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeForEditing; -use PrestaShop\PrestaShop\Core\Domain\Employee\QueryHandler\GetEmployeeForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\QueryResult\EditableEmployee; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Handles command that gets employee for editing. - */ -final class GetEmployeeForEditingHandler implements GetEmployeeForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetEmployeeForEditing $query) - { - $employeeId = $query->getEmployeeId(); - $employee = new Employee($employeeId->getValue()); - - if ($employee->id !== $employeeId->getValue()) { - throw new EmployeeNotFoundException($employeeId, sprintf('Employee with id "%s" was not found', $employeeId->getValue())); - } - - return new EditableEmployee( - $employeeId, - new FirstName($employee->firstname), - new LastName($employee->lastname), - new Email($employee->email), - $employee->getImage(), - (int) $employee->default_tab, - (int) $employee->id_lang, - (bool) $employee->active, - (int) $employee->id_profile, - $employee->getAssociatedShops() - ); - } -} diff --git a/src/Adapter/Profile/ProfileDataProvider.php b/src/Adapter/Profile/ProfileDataProvider.php deleted file mode 100644 index 0f2f3e39..00000000 --- a/src/Adapter/Profile/ProfileDataProvider.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile; - -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use Profile; - -/** - * Class ProfileDataProvider provides employee profile data using legacy logic. - */ -class ProfileDataProvider -{ - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - * @param int $superAdminProfileId - */ - public function __construct( - ContextEmployeeProviderInterface $contextEmployeeProvider, - $superAdminProfileId - ) { - $this->contextEmployeeProvider = $contextEmployeeProvider; - $this->superAdminProfileId = $superAdminProfileId; - } - - /** - * Get employee profiles. - * - * @param int $languageId - * - * @return array - */ - public function getProfiles($languageId) - { - $profiles = Profile::getProfiles($languageId); - - if ($profiles && !$this->contextEmployeeProvider->isSuperAdmin()) { - foreach ($profiles as $key => $profile) { - if ($profile['id_profile'] == $this->superAdminProfileId) { - unset($profiles[$key]); - break; - } - } - } - - return $profiles ?: []; - } -} diff --git a/src/Adapter/Profile/QueryHandler/GetProfileForEditingHandler.php b/src/Adapter/Profile/QueryHandler/GetProfileForEditingHandler.php deleted file mode 100644 index b8dfc975..00000000 --- a/src/Adapter/Profile/QueryHandler/GetProfileForEditingHandler.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Profile\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Query\GetProfileForEditing; -use PrestaShop\PrestaShop\Core\Domain\Profile\QueryHandler\GetProfileForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\QueryResult\EditableProfile; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; -use Profile; - -/** - * Gets Profile for editing using legacy object model - */ -final class GetProfileForEditingHandler implements GetProfileForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetProfileForEditing $query) - { - $profile = $this->getProfile($query->getProfileId()); - - return new EditableProfile( - $query->getProfileId(), - $profile->name - ); - } - - /** - * @param ProfileId $profileId - * - * @return Profile - * - * @throws ProfileNotFoundException - */ - private function getProfile(ProfileId $profileId) - { - $profile = new Profile($profileId->getValue()); - - if ($profile->id !== $profileId->getValue()) { - throw new ProfileNotFoundException(sprintf('Profile with id "%s" was not found', $profileId->getValue())); - } - - return $profile; - } -} diff --git a/src/Adapter/Requirement/CheckMissingOrUpdatedFiles.php b/src/Adapter/Requirement/CheckMissingOrUpdatedFiles.php deleted file mode 100644 index 60b62079..00000000 --- a/src/Adapter/Requirement/CheckMissingOrUpdatedFiles.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Requirement; - -use AppKernel; - -/** - * Part of requirements for a PrestaShop website - * Check if all required files exists. - */ -class CheckMissingOrUpdatedFiles -{ - /** - * @param string|null $dir - * @param string $path - * - * @return array - */ - public function getListOfUpdatedFiles($dir = null, $path = '') - { - $fileList = [ - 'missing' => [], - 'updated' => [], - ]; - - if (null === $dir) { - $xml = @simplexml_load_file(_PS_API_URL_ . '/xml/md5-' . AppKernel::MAJOR_VERSION . '/' . AppKernel::VERSION . '.xml'); - if (!$xml) { - return $fileList; - } - - $dir = $xml->ps_root_dir[0]; - } - - $excludeRegexp = '(install(-dev|-new)?|themes|tools|cache|docs|download|img|localization|log|mails|translations|upload|modules|override/(:?.*)index.php$)'; - $adminDir = basename(_PS_ADMIN_DIR_); - - foreach ($dir->md5file as $file) { - $filename = preg_replace('#^admin/#', $adminDir . '/', $path . $file['name']); - if (preg_match('#^' . $excludeRegexp . '#', $filename)) { - continue; - } - - if (!file_exists(_PS_ROOT_DIR_ . '/' . $filename)) { - $fileList['missing'][] = $filename; - } elseif (md5_file(_PS_ROOT_DIR_ . '/' . $filename) !== (string) $file) { - $fileList['updated'][] = $filename; - } - } - - foreach ($dir->dir as $subdir) { - $fileList = array_merge_recursive($fileList, $this->getListOfUpdatedFiles($subdir, $path . $subdir['name'] . '/')); - } - - return $fileList; - } -} diff --git a/src/Adapter/Requirement/CheckRequirements.php b/src/Adapter/Requirement/CheckRequirements.php deleted file mode 100644 index e6005e07..00000000 --- a/src/Adapter/Requirement/CheckRequirements.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Requirement; - -use ConfigurationTest; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Check system requirements of a PrestaShop website. - */ -class CheckRequirements -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * Returns a summary of all system requirements. - * - * @return array - */ - public function getSummary() - { - $paramsRequiredResults = ConfigurationTest::check(ConfigurationTest::getDefaultTests()); - - $isHostMode = defined('_PS_HOST_MODE_'); - - if (!$isHostMode) { - $paramsOptionalResults = ConfigurationTest::check(ConfigurationTest::getDefaultTestsOp()); - } - - $failRequired = in_array('fail', $paramsRequiredResults); - - $testsErrors = $this->getErrorMessages(); - - if ($failRequired && 'ok' !== $paramsRequiredResults['files']) { - $tmp = ConfigurationTest::test_files(true); - if (is_array($tmp) && count($tmp)) { - $testsErrors['files'] = $testsErrors['files'] . '
    (' . implode(', ', $tmp) . ')'; - } - } - - $testsErrors = $this->fillMissingDescriptions($testsErrors, $paramsRequiredResults); - - $results = [ - 'failRequired' => $failRequired, - 'testsErrors' => $testsErrors, - 'testsRequired' => $paramsRequiredResults, - ]; - - if (!$isHostMode) { - $results = array_merge($results, [ - 'testsErrors' => $this->fillMissingDescriptions($testsErrors, $paramsOptionalResults), - 'failOptional' => in_array('fail', $paramsOptionalResults), - 'testsOptional' => $paramsOptionalResults, - ]); - } - - return $results; - } - - /** - * @return array - */ - private function getErrorMessages() - { - return [ - 'phpversion' => $this->translator->trans('Update your PHP version.', [], 'Admin.Advparameters.Notification'), - 'upload' => $this->translator->trans('Configure your server to allow file uploads.', [], 'Admin.Advparameters.Notification'), - 'system' => $this->translator->trans('Configure your server to allow the creation of directories and files with write permissions.', [], 'Admin.Advparameters.Notification'), - 'curl' => $this->translator->trans('Enable the CURL extension on your server.', [], 'Admin.Advparameters.Notification'), - 'dom' => $this->translator->trans('Enable the DOM extension on your server.', [], 'Admin.Advparameters.Notification'), - 'fileinfo' => $this->translator->trans('Enable the Fileinfo extension on your server.', [], 'Admin.Advparameters.Notification'), - 'gd' => $this->translator->trans('Enable the GD library on your server.', [], 'Admin.Advparameters.Notification'), - 'json' => $this->translator->trans('Enable the JSON extension on your server.', [], 'Admin.Advparameters.Notification'), - 'mbstring' => $this->translator->trans('Enable the Mbstring extension on your server.', [], 'Admin.Advparameters.Notification'), - 'openssl' => $this->translator->trans('Enable the OpenSSL extension on your server.', [], 'Admin.Advparameters.Notification'), - 'pdo_mysql' => $this->translator->trans('Enable the PDO Mysql extension on your server.', [], 'Admin.Advparameters.Notification'), - 'simplexml' => $this->translator->trans('Enable the XML extension on your server.', [], 'Admin.Advparameters.Notification'), - 'zip' => $this->translator->trans('Enable the ZIP extension on your server.', [], 'Admin.Advparameters.Notification'), - 'mysql_support' => $this->translator->trans('Enable the MySQL support on your server.', [], 'Admin.Advparameters.Notification'), - 'config_dir' => $this->translator->trans('Set write permissions for the "config" folder.', [], 'Admin.Advparameters.Notification'), - 'cache_dir' => $this->translator->trans('Set write permissions for the "cache" folder.', [], 'Admin.Advparameters.Notification'), - 'sitemap' => $this->translator->trans('Set write permissions for the "sitemap.xml" file.', [], 'Admin.Advparameters.Notification'), - 'img_dir' => $this->translator->trans('Set write permissions for the "img" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'log_dir' => $this->translator->trans('Set write permissions for the "log" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'mails_dir' => $this->translator->trans('Set write permissions for the "mails" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'module_dir' => $this->translator->trans('Set write permissions for the "modules" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'theme_cache_dir' => $this->translator->trans('Set write permissions for the "themes/%s/cache/" folder and subfolders, recursively.', ['%s' => _THEME_NAME_], 'Admin.Advparameters.Notification'), - 'theme_lang_dir' => $this->translator->trans('Set write permissions for the "themes/%s/lang/" folder and subfolders, recursively.', ['%s' => _THEME_NAME_], 'Admin.Advparameters.Notification'), - 'theme_pdf_lang_dir' => $this->translator->trans('Set write permissions for the "themes/%s/pdf/lang/" folder and subfolders, recursively.', ['%s' => _THEME_NAME_], 'Admin.Advparameters.Notification'), - 'config_sf2_dir' => $this->translator->trans('Set write permissions for the "app/config/" folder and subfolders, recursively.', [], 'Admin.Advparameters.Notification'), - 'translations_sf2' => $this->translator->trans('Set write permissions for the "app/Resources/translations/" folder and subfolders, recursively.', [], 'Admin.Advparameters.Notification'), - 'translations_dir' => $this->translator->trans('Set write permissions for the "translations" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'customizable_products_dir' => $this->translator->trans('Set write permissions for the "upload" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'virtual_products_dir' => $this->translator->trans('Set write permissions for the "download" folder and subfolders.', [], 'Admin.Advparameters.Notification'), - 'fopen' => $this->translator->trans('Allow the PHP fopen() function on your server.', [], 'Admin.Advparameters.Notification'), - 'gz' => $this->translator->trans('Enable GZIP compression on your server.', [], 'Admin.Advparameters.Notification'), - 'files' => $this->translator->trans('Some PrestaShop files are missing from your server.', [], 'Admin.Advparameters.Notification'), - 'new_phpversion' => $this->translator->trans('You are using PHP %s version. Soon, the latest PHP version supported by PrestaShop will be PHP 5.6. To make sure you’re ready for the future, we recommend you to upgrade to PHP 5.6 now!', ['%s' => PHP_VERSION], 'Admin.Advparameters.Notification'), - 'apache_mod_rewrite' => $this->translator->trans('Enable the Apache mod_rewrite module', [], 'Admin.Advparameters.Notification'), - ]; - } - - /** - * Add default message on missing check descriptions. - * - * @param array $errorMessages - * @param array $checks - * - * @return array Error messages with fallback for missing entries - */ - private function fillMissingDescriptions($errorMessages, $checks) - { - foreach (array_keys(array_diff_key($checks, $errorMessages)) as $key) { - $errorMessages[$key] = $this->translator->trans('%key% (missing description)', ['%key%' => $key], 'Admin.Advparameters.Feature'); - } - - return $errorMessages; - } -} diff --git a/src/Adapter/RoundingMapper.php b/src/Adapter/RoundingMapper.php deleted file mode 100644 index 9e1f6c76..00000000 --- a/src/Adapter/RoundingMapper.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\Decimal\Operation\Rounding; - -/** - * Maps rounding modes from legacy rounding modes values to the new PrestaShop/Decimal's Rounding constant values. - */ -final class RoundingMapper -{ - /** - * Maps rounding modes from legacy rounding modes values to the new PrestaShop/Decimal's Rounding constant values. - * eg. : asking mapping for PS_ROUND_UP (value : 0) would return Rounding::ROUND_CEIL (value : 'ceil'). - * - * @param int $legacyRoundingMode - * The legacy rounding mode value - * - * @return string - * The corresponding Rounding class' constant value - */ - public static function mapRounding($legacyRoundingMode) - { - $roundModes = [ - PS_ROUND_UP => Rounding::ROUND_CEIL, - PS_ROUND_DOWN => Rounding::ROUND_FLOOR, - PS_ROUND_HALF_UP => Rounding::ROUND_HALF_UP, - PS_ROUND_HALF_DOWN => Rounding::ROUND_HALF_DOWN, - PS_ROUND_HALF_EVEN => Rounding::ROUND_HALF_EVEN, - PS_ROUND_HALF_ODD => Rounding::ROUND_HALF_EVEN, // Rounding::ROUND_HALF_ODD does not exist (never used) - ]; - if (!array_key_exists((int) $legacyRoundingMode, $roundModes)) { - throw new \InvalidArgumentException('Unknown legacy rounding mode : ' . (int) $legacyRoundingMode); - } - - return $roundModes[$legacyRoundingMode]; - } -} diff --git a/src/Adapter/Routes/DefaultRouteProvider.php b/src/Adapter/Routes/DefaultRouteProvider.php deleted file mode 100644 index cdf9bbcd..00000000 --- a/src/Adapter/Routes/DefaultRouteProvider.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Routes; - -use Dispatcher; -use PrestaShopException; - -/** - * Class DefaultRouteProvider is responsible for retrieving data from dispatcher entity. - */ -class DefaultRouteProvider -{ - /** - * Gets keywords used in generating different routes. - * - * @return array - the key is the route id - product_rule, category_rule etc... and the values are keyword array - * used to generate the route. If param field exists in keywords array then it is mandatory field to use. - * - * @throws PrestaShopException - */ - public function getKeywords() - { - $routes = $this->getDefaultRoutes(); - - $result = []; - foreach ($routes as $routeId => $value) { - $result[$routeId] = $value['keywords']; - } - - return $result; - } - - /** - * Gets rules which are used for routes generation. - * - * @return array - he key is the route id - product_rule, category_rule etc... and the value is rule itself. - * - * @throws PrestaShopException - */ - public function getRules() - { - $routes = $this->getDefaultRoutes(); - - $result = []; - foreach ($routes as $routeId => $value) { - $result[$routeId] = $value['rule']; - } - - return $result; - } - - /** - * Gets default routes which contains data such as keywords, rule etc. - * - * @return array - * - * @throws PrestaShopException - */ - private function getDefaultRoutes() - { - return Dispatcher::getInstance()->default_routes; - } -} diff --git a/src/Adapter/Routes/RouteValidator.php b/src/Adapter/Routes/RouteValidator.php deleted file mode 100644 index 8d178d02..00000000 --- a/src/Adapter/Routes/RouteValidator.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Routes; - -use Dispatcher; -use PrestaShopException; -use Validate; - -/** - * Class RouteValidator is responsible for validating routes. - */ -class RouteValidator -{ - /** - * Check for a route pattern validity. - * - * @param string $pattern to validate - * - * @return bool Validity is ok or not - */ - public function isRoutePattern($pattern) - { - return Validate::isRoutePattern($pattern); - } - - /** - * Check if a route rule contain all required keywords of default route definition. - * - * @param string $routeId - * @param string $rule Rule to verify - * - * @return array - returns list of missing keywords - * - * @throws PrestaShopException - */ - public function doesRouteContainsRequiredKeywords($routeId, $rule) - { - $missingKeywords = []; - $validationResult = Dispatcher::getInstance()->validateRoute($routeId, $rule, $missingKeywords); - - return $validationResult ? [] : $missingKeywords; - } -} diff --git a/src/Adapter/Routing/AdminLinkBuilder.php b/src/Adapter/Routing/AdminLinkBuilder.php deleted file mode 100644 index 0fd2f44c..00000000 --- a/src/Adapter/Routing/AdminLinkBuilder.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Routing; - -use Link; -use PrestaShop\PrestaShop\Core\Routing\EntityLinkBuilderInterface; - -/** - * Class AdminLinkBuilder is able to build entity links based on the Link::getAdminLink - * method (which indirectly allows it to build symfony url as well). - */ -class AdminLinkBuilder implements EntityLinkBuilderInterface -{ - /** @var Link */ - private $link; - - /** @var array */ - private $entityControllers; - - /** - * This class can manage entities based on the $entityControllers parameter, - * you need to specify an array map with then entity/table short name and its - * associated legacy controller: - * e.g. $entityControllers = [ - * 'product' => 'AdminProducts', - * 'customer' => 'AdminCustomers', - * ]; - * - * @param Link $link Link class that generates links - * @param array $entityControllers List of entities with appropriate controller - */ - public function __construct(Link $link, array $entityControllers) - { - $this->link = $link; - $this->entityControllers = $entityControllers; - } - - /** - * {@inheritdoc} - */ - public function getViewLink($entity, array $parameters) - { - $controller = $this->entityControllers[$entity]; - $parameters = $this->buildActionParameters('view', $entity, $parameters); - - return $this->link->getAdminLink($controller, true, $parameters); - } - - /** - * {@inheritdoc} - */ - public function getEditLink($entity, array $parameters) - { - $controller = $this->entityControllers[$entity]; - $parameters = $this->buildActionParameters('update', $entity, $parameters); - - return $this->link->getAdminLink($controller, true, $parameters); - } - - /** - * @param string $action - * @param string $entity - * @param array $parameters - * - * @return array - */ - private function buildActionParameters($action, $entity, array $parameters) - { - unset($parameters['current_index']); - unset($parameters['token']); - $editAction = $action . $entity; - - return array_merge( - $parameters, - [$editAction => 1] - ); - } - - /** - * {@inheritdoc} - */ - public function canBuild($entity) - { - return !empty($this->entityControllers[$entity]); - } -} diff --git a/src/Adapter/Routing/LegacyHelperLinkBuilder.php b/src/Adapter/Routing/LegacyHelperLinkBuilder.php deleted file mode 100644 index 4ad09b11..00000000 --- a/src/Adapter/Routing/LegacyHelperLinkBuilder.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Routing; - -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Routing\EntityLinkBuilderInterface; - -/** - * Class LegacyHelperLinkBuilder is able to build entity links "manually" by concatenating - * the parameters to the current index. This way of building links is deprecated and should - * be replaced with Symfony router or Link::getAdminLink - */ -class LegacyHelperLinkBuilder implements EntityLinkBuilderInterface -{ - /** - * @param string $entity - * @param array $parameters - * - * @return string - * - * @throws InvalidArgumentException - */ - public function getViewLink($entity, array $parameters) - { - if (!isset($parameters['current_index'])) { - throw new InvalidArgumentException('Missing parameter current_index to build legacy link'); - } - - $currentIndex = $parameters['current_index']; - $parameters = $this->buildActionParameters('view', $entity, $parameters); - - return $currentIndex . '&' . http_build_query($parameters); - } - - /** - * @param string $entity - * @param array $parameters - * - * @return string - * - * @throws InvalidArgumentException - */ - public function getEditLink($entity, array $parameters) - { - if (!isset($parameters['current_index'])) { - throw new InvalidArgumentException('Missing parameter current_index to build legacy link'); - } - - $currentIndex = $parameters['current_index']; - $parameters = $this->buildActionParameters('update', $entity, $parameters); - - return $currentIndex . '&' . http_build_query($parameters); - } - - /** - * @param string $action - * @param string $entity - * @param array $parameters - * - * @return array - */ - private function buildActionParameters($action, $entity, array $parameters) - { - unset($parameters['current_index']); - $actionParameter = $action . $entity; - - /** - * Legacy actions are displayed with empty value (e.g ?controller=ProductAdminController&updateproduct&id_product=1) - * Some modules don't just check that the parameter is set but also that it is empty... - * The closest thing we have with http_build_query is controller=ProductAdminController&updateproduct=&id_product=1 - */ - $parameters = array_merge( - [$actionParameter => ''], - $parameters - ); - - return $parameters; - } - - /** - * {@inheritdoc} - */ - public function canBuild($entity) - { - return true; - } -} diff --git a/src/Adapter/Search/SearchProductSearchProvider.php b/src/Adapter/Search/SearchProductSearchProvider.php deleted file mode 100644 index 920f658f..00000000 --- a/src/Adapter/Search/SearchProductSearchProvider.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Search; - -use Hook; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Search; -use Symfony\Component\Translation\TranslatorInterface; -use Tools; - -/** - * Class responsible of retrieving products in Search page of Front Office. - * - * @see SearchController - */ -class SearchProductSearchProvider implements ProductSearchProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var SortOrderFactory - */ - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator - ) { - $this->translator = $translator; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * {@inheritdoc} - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - $products = []; - $count = 0; - - if (($string = $query->getSearchString())) { - $queryString = Tools::replaceAccentedChars(urldecode($string)); - - $result = Search::find( - $context->getIdLang(), - $queryString, - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay(), - false, // ajax, what's the link? - false, // $use_cookie, ignored anyway - null - ); - $products = $result['result']; - $count = $result['total']; - - Hook::exec('actionSearch', [ - 'searched_query' => $queryString, - 'total' => $count, - - // deprecated since 1.7.x - 'expr' => $queryString, - ]); - } elseif (($tag = $query->getSearchTag())) { - $queryString = urldecode($tag); - - $products = Search::searchTag( - $context->getIdLang(), - $queryString, - false, - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(true), - $query->getSortOrder()->toLegacyOrderWay(), - false, - null - ); - - $count = Search::searchTag( - $context->getIdLang(), - $queryString, - true, - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(true), - $query->getSortOrder()->toLegacyOrderWay(), - false, - null - ); - - Hook::exec('actionSearch', [ - 'searched_query' => $queryString, - 'total' => $count, - - // deprecated since 1.7.x - 'expr' => $queryString, - ]); - } - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - $this->sortOrderFactory->getDefaultSortOrders() - ); - } - - return $result; - } -} diff --git a/src/Adapter/Security/Admin.php b/src/Adapter/Security/Admin.php deleted file mode 100644 index dfcada1c..00000000 --- a/src/Adapter/Security/Admin.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Security; - -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; -use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -/** - * Admin Middleware security. - */ -class Admin -{ - /** - * @var LegacyContext - */ - private $context; - - /** - * @var \Context - */ - private $legacyContext; - - /** - * @var TokenStorage - */ - private $securityTokenStorage; - - /** - * @var UserProviderInterface - */ - private $userProvider; - - public function __construct(LegacyContext $context, TokenStorage $securityTokenStorage, UserProviderInterface $userProvider) - { - $this->context = $context; - $this->legacyContext = $context->getContext(); - $this->securityTokenStorage = $securityTokenStorage; - $this->userProvider = $userProvider; - } - - /** - * Check if employee is logged in - * If not logged in, redirect to admin home page. - * - * @param GetResponseEvent $event - * - * @return bool or redirect - */ - public function onKernelRequest(GetResponseEvent $event) - { - //if employee loggdin in legacy context, authenticate him into sf2 security context - if (isset($this->legacyContext->employee) && $this->legacyContext->employee->isLoggedBack()) { - $user = $this->userProvider->loadUserByUsername($this->legacyContext->employee->email); - $token = new UsernamePasswordToken($user, null, 'admin', $user->getRoles()); - $this->securityTokenStorage->setToken($token); - - return true; - } - - // in case of exception handler sub request, avoid infinite redirection - if ($event->getRequestType() === HttpKernelInterface::SUB_REQUEST - && $event->getRequest()->attributes->has('exception') - ) { - return true; - } - - //employee not logged in - $event->stopPropagation(); - - //if http request - add 403 error - $request = Request::createFromGlobals(); - if ($request->isXmlHttpRequest()) { - header('HTTP/1.1 403 Forbidden'); - exit(); - } - - //redirect to admin home page - header('Location: ' . $this->context->getAdminLink('', false)); - exit(); - } -} diff --git a/src/Adapter/Security/SslMiddleware.php b/src/Adapter/Security/SslMiddleware.php deleted file mode 100644 index b561281b..00000000 --- a/src/Adapter/Security/SslMiddleware.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Security; - -use Configuration; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Tools; - -/** - * Middleware that is triggered during kernel.request event on Symfony routing process, to redirect to HTTPS in some cases. - * - * If PS_SSL_ENABLED & (PS_SSL_ENABLED_EVERYWHERE | REFERER is HTTPS) - * Then redirect to the equivalent URL to HTTPS. - * Warning : will lost post data, - */ -class SslMiddleware -{ - /** - * Registered as kernel.request event listener. - * - * If the condition needs a redirection to HTTPS, then the current process is interrupted, the headers are sent directly. - * - * @param GetResponseEvent $event - */ - public function onKernelRequest(GetResponseEvent $event) - { - // already SSL, do nothing more - if (Tools::usingSecureMode()) { - return; - } - - $enabled = (1 == Configuration::get('PS_SSL_ENABLED')); - $forced = (1 == Configuration::get('PS_SSL_ENABLED_EVERYWHERE')); - $serverParams = $event->getRequest()->server; - $refererSsl = ($serverParams->has('HTTP_REFERER') && strpos($serverParams->get('HTTP_REFERER'), 'https') === 0); - - if ($enabled && ($forced || $refererSsl)) { - $this->redirectToSsl($event); - } - } - - private function redirectToSsl(GetResponseEvent $event) - { - $event->stopPropagation(); - $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - header('HTTP/1.1 302 Found'); - header("Location: $redirect"); - exit(); - } -} diff --git a/src/Adapter/ServiceLocator.php b/src/Adapter/ServiceLocator.php deleted file mode 100644 index 7100e5f0..00000000 --- a/src/Adapter/ServiceLocator.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\PrestaShop\Core\Foundation\IoC\Container; - -/** - * @internal - * - * To be removed in 1.7.1. - */ -class ServiceLocator -{ - /** - * Set a service container Instance. - * - * @var Container - */ - private static $service_container; - - public static function setServiceContainerInstance(Container $container) - { - self::$service_container = $container; - } - - /** - * Get a service depending on its given $serviceName. - * - * @param $serviceName - * - * @return mixed|object - * - * @throws CoreException - */ - public static function get($serviceName) - { - if (empty(self::$service_container) || null === self::$service_container) { - throw new CoreException('Service container is not set.'); - } - - return self::$service_container->make($serviceName); - } -} diff --git a/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php b/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php deleted file mode 100644 index 0e23e392..00000000 --- a/src/Adapter/Shop/CommandHandler/UploadLogosHandler.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop\CommandHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Exception\FileUploadException; -use PrestaShop\PrestaShop\Core\Domain\Shop\Command\UploadLogosCommand; -use PrestaShop\PrestaShop\Core\Domain\Shop\CommandHandler\UploadLogosHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Shop\DTO\ShopLogoSettings; -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopException; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Shop\LogoUploader; -use PrestaShopException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class UploadLogosHandler - */ -final class UploadLogosHandler implements UploadLogosHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var LogoUploader - */ - private $logoUploader; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @param ConfigurationInterface $configuration - * @param LogoUploader $logoUploader - * @param HookDispatcherInterface $hookDispatcher - */ - public function __construct( - ConfigurationInterface $configuration, - LogoUploader $logoUploader, - HookDispatcherInterface $hookDispatcher - ) { - $this->configuration = $configuration; - $this->logoUploader = $logoUploader; - $this->hookDispatcher = $hookDispatcher; - } - - /** - * {@inheritdoc} - * - * @throws ShopException - * @throws FileUploadException - */ - public function handle(UploadLogosCommand $command) - { - $this->configuration->set('PS_IMG_UPDATE_TIME', time()); - - try { - if (null !== $command->getUploadedHeaderLogo()) { - $this->uploadHeaderLogo($command->getUploadedHeaderLogo()); - } - - if (null !== $command->getUploadedMailLogo()) { - $this->uploadMailLogo($command->getUploadedMailLogo()); - } - - if (null !== $command->getUploadedInvoiceLogo()) { - $this->uploadInvoiceLogo($command->getUploadedInvoiceLogo()); - } - - if (null !== $command->getUploadedFavicon()) { - $this->uploadFavicon($command->getUploadedFavicon()); - } - } catch (PrestaShopException $exception) { - throw new ShopException('An unexpected error occurred when uploading image', 0, $exception); - } - - $this->hookDispatcher->dispatchWithParameters('actionAdminThemesControllerUpdate_optionsAfter'); - } - - /** - * @param UploadedFile $uploadedFile - */ - private function uploadHeaderLogo(UploadedFile $uploadedFile) - { - $this->setUploadedFileToBeCompatibleWithLegacyUploader(ShopLogoSettings::HEADER_LOGO_FILE_NAME, $uploadedFile); - - $this->logoUploader->updateHeader(); - } - - /** - * @param UploadedFile $uploadedFile - */ - private function uploadMailLogo(UploadedFile $uploadedFile) - { - $this->setUploadedFileToBeCompatibleWithLegacyUploader(ShopLogoSettings::MAIL_LOGO_FILE_NAME, $uploadedFile); - - $this->logoUploader->updateMail(); - } - - /** - * @param UploadedFile $uploadedHeaderLogo - */ - private function uploadInvoiceLogo(UploadedFile $uploadedHeaderLogo) - { - $this->setUploadedFileToBeCompatibleWithLegacyUploader(ShopLogoSettings::INVOICE_LOGO_FILE_NAME, $uploadedHeaderLogo); - - $this->logoUploader->updateInvoice(); - } - - /** - * @param UploadedFile $uploadedHeaderLogo - */ - private function uploadFavicon(UploadedFile $uploadedHeaderLogo) - { - $this->setUploadedFileToBeCompatibleWithLegacyUploader(ShopLogoSettings::FAVICON_FILE_NAME, $uploadedHeaderLogo); - - $this->logoUploader->updateFavicon(); - } - - /** - * @param string $legacyFileName - * @param UploadedFile $uploadedFile - * - * @return array - */ - private function setUploadedFileToBeCompatibleWithLegacyUploader($legacyFileName, UploadedFile $uploadedFile) - { - $_FILES[$legacyFileName] = [ - 'name' => $uploadedFile->getClientOriginalName(), - 'type' => $uploadedFile->getMimeType(), - 'tmp_name' => $uploadedFile->getPathname(), - 'error' => $uploadedFile->getError(), - 'size' => $uploadedFile->getSize(), - ]; - - return $_FILES; - } -} diff --git a/src/Adapter/Shop/Context.php b/src/Adapter/Shop/Context.php deleted file mode 100644 index a53fb813..00000000 --- a/src/Adapter/Shop/Context.php +++ /dev/null @@ -1,231 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop; - -use Context as LegacyContext; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; -use PrestaShop\PrestaShop\Core\Shop\ShopContextInterface; -use Shop; -use ShopGroup; - -/** - * This class will provide legacy shop context. - */ -class Context implements MultistoreContextCheckerInterface, ShopContextInterface -{ - /** - * Get shops list. - * - * @param bool $active - * @param bool $get_as_list_id - * - * @return array - */ - public function getShops($active = true, $get_as_list_id = false) - { - return Shop::getShops($active, Shop::getContextShopGroupID(), $get_as_list_id); - } - - /** - * Get current ID of shop if context is CONTEXT_SHOP. - * - * @return int - */ - public function getContextShopID($null_value_without_multishop = false) - { - return Shop::getContextShopID($null_value_without_multishop); - } - - /** - * Get a list of ID concerned by the shop context (E.g. if context is shop group, get list of children shop ID). - * - * @param bool|string $share If false, dont check share datas from group. Else can take a Shop::SHARE_* constant value - * - * @return array - */ - public function getContextListShopID($share = false) - { - return Shop::getContextListShopID($share); - } - - /** - * Return the result of getContextListShopID() for customers usecase - * This handles the "multishop sharing customer" feature setting - * - * @return array - */ - public function getContextListShopIDUsingCustomerSharingSettings() - { - $groupSettings = Shop::getGroupFromShop(Shop::getContextShopID(), false); - - if ($groupSettings['share_customer']) { - return Shop::getContextListShopID(Shop::SHARE_CUSTOMER); - } else { - return Shop::getContextListShopID(); - } - } - - /** - * Get if it's a GroupShop context. - * - * @return bool - * - * @deprecated since 1.7.6.0, to be removed in 1.8. Use $this->isGroupShopContext() instead. - */ - public function isShopGroupContext() - { - return $this->isGroupShopContext(); - } - - /** - * Get if it's a Shop context. - * - * @return bool - */ - public function isShopContext() - { - return Shop::getContext() === Shop::CONTEXT_SHOP; - } - - /** - * Get if it's a All context. - * - * @return bool - * - * @deprecated since 1.7.6.0, to be removed in 1.8. Use $this->isAllShopContext() instead. - */ - public function isAllContext() - { - return $this->isAllShopContext(); - } - - /** - * Check if shop context is Shop. - * - * @return bool - */ - public function isSingleShopContext() - { - if (!Shop::isFeatureActive()) { - return true; - } - - return $this->isShopContext(); - } - - /** - * Update Multishop context for only one shop. - * - * @param int $id Shop id to set in the current context - */ - public function setShopContext($id) - { - Shop::setContext(Shop::CONTEXT_SHOP, $id); - } - - /** - * Update Multishop context for only one shop group. - * - * @param int $id Shop id to set in the current context - */ - public function setShopGroupContext($id) - { - Shop::setContext(Shop::CONTEXT_GROUP, $id); - } - - /** - * Update Multishop context for only one shop group. - * - * @param int $id Shop id to set in the current context - */ - public function setAllContext($id) - { - Shop::setContext(Shop::CONTEXT_ALL, $id); - } - - public function getContextShopGroup() - { - return Shop::getContextShopGroup(); - } - - /** - * Retrieve group ID of a shop. - * - * @param $shopId - * @param bool $asId - * - * @return int - */ - public function getGroupFromShop($shopId, $asId = true) - { - return Shop::getGroupFromShop($shopId, $asId); - } - - /** - * @param $shopGroupId - * - * @return ShopGroup - */ - public function ShopGroup($shopGroupId) - { - return new ShopGroup($shopGroupId); - } - - /** - * {@inheritdoc} - */ - public function isAllShopContext() - { - return Shop::getContext() === Shop::CONTEXT_ALL; - } - - /** - * {@inheritdoc} - */ - public function isGroupShopContext() - { - return Shop::getContext() === Shop::CONTEXT_GROUP; - } - - /** - * Get list of all shop IDs. - * - * @return array - */ - public function getAllShopIds() - { - return Shop::getCompleteListOfShopsID(); - } - - /** - * {@inheritdoc} - */ - public function getShopName() - { - return LegacyContext::getContext()->shop->name; - } -} diff --git a/src/Adapter/Shop/MaintenanceConfiguration.php b/src/Adapter/Shop/MaintenanceConfiguration.php deleted file mode 100644 index d7d904b5..00000000 --- a/src/Adapter/Shop/MaintenanceConfiguration.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class loads and saves data configuration for the Maintenance page. - */ -class MaintenanceConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_shop' => $this->configuration->getBoolean('PS_SHOP_ENABLE'), - 'maintenance_ip' => $this->configuration->get('PS_MAINTENANCE_IP'), - 'maintenance_text' => $this->configuration->get('PS_MAINTENANCE_TEXT'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_SHOP_ENABLE', $configuration['enable_shop']); - $this->configuration->set('PS_MAINTENANCE_IP', $configuration['maintenance_ip']); - $this->configuration->set('PS_MAINTENANCE_TEXT', $configuration['maintenance_text'], null, ['html' => true]); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_shop'], - $configuration['maintenance_ip'], - $configuration['maintenance_text'] - ); - } -} diff --git a/src/Adapter/Shop/QueryHandler/GetLogosPathsHandler.php b/src/Adapter/Shop/QueryHandler/GetLogosPathsHandler.php deleted file mode 100644 index 95d79639..00000000 --- a/src/Adapter/Shop/QueryHandler/GetLogosPathsHandler.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop\QueryHandler; - -use Configuration; -use PrestaShop\PrestaShop\Core\Domain\Shop\Query\GetLogosPaths; -use PrestaShop\PrestaShop\Core\Domain\Shop\QueryHandler\GetLogosPathsHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Shop\QueryResult\LogosPaths; - -/** - * Responsible for providing header, email, invoice and favicon logo paths for specific shop context. - */ -final class GetLogosPathsHandler implements GetLogosPathsHandlerInterface -{ - /** - * @var string - */ - private $imageBaseUrl; - - /** - * @var string - */ - private $imageDirectory; - - /** - * @param string $imageBaseUrl - * @param string $imageDirectory - */ - public function __construct($imageBaseUrl, $imageDirectory) - { - $this->imageBaseUrl = $imageBaseUrl; - $this->imageDirectory = $imageDirectory; - } - - /** - * {@inheritdoc} - */ - public function handle(GetLogosPaths $query) - { - return new LogosPaths( - $this->getHeaderLogoPath(), - $this->getMailLogoPath(), - $this->getInvoiceLogoPath(), - $this->getFaviconPath() - ); - } - - /** - * Get path to context's shop logo. - * - * @return string - */ - private function getHeaderLogoPath() - { - return $this->imageBaseUrl . Configuration::get('PS_LOGO'); - } - - /** - * Get path to context's shop mail logo. - * - * @return string - */ - private function getMailLogoPath() - { - if (!$mailLogo = Configuration::get('PS_LOGO_MAIL')) { - return $this->getHeaderLogoPath(); - } - - $mailLogoPath = $this->imageDirectory . $mailLogo; - - if (!file_exists($mailLogoPath)) { - return $this->getHeaderLogoPath(); - } - - return $this->imageBaseUrl . $mailLogo; - } - - /** - * Get path to context's shop invoice logo. - * - * @return string - */ - private function getInvoiceLogoPath() - { - if (!$invoiceLogo = Configuration::get('PS_LOGO_INVOICE')) { - return $this->getHeaderLogoPath(); - } - - $invoiceLogoPath = $this->imageDirectory . $invoiceLogo; - - if (!file_exists($invoiceLogoPath)) { - return $this->getHeaderLogoPath(); - } - - return $this->imageBaseUrl . $invoiceLogo; - } - - /** - * Get path to context's shop favicon. - * - * @return string - */ - private function getFaviconPath() - { - return $this->imageBaseUrl . Configuration::get('PS_FAVICON'); - } -} diff --git a/src/Adapter/Shop/ShopInformation.php b/src/Adapter/Shop/ShopInformation.php deleted file mode 100644 index 57960ba5..00000000 --- a/src/Adapter/Shop/ShopInformation.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop; - -use AppKernel; -use PrestaShop\PrestaShop\Adapter\LegacyContext; - -/** - * Retrieve common information from a the actual Shop. - * - * Depends on Context, avoid re-use of this class - */ -class ShopInformation -{ - /** - * @var \Context - */ - private $context; - - /** - * @param LegacyContext $legacyContext - */ - public function __construct(LegacyContext $legacyContext) - { - $this->context = $legacyContext->getContext(); - } - - /** - * @return array - */ - public function getShopInformation() - { - return [ - 'version' => AppKernel::VERSION, - 'url' => $this->context->shop->getBaseURL(), - 'path' => _PS_ROOT_DIR_, - 'theme' => $this->context->shop->theme->getName(), - ]; - } -} diff --git a/src/Adapter/Shop/ShopUrlDataProvider.php b/src/Adapter/Shop/ShopUrlDataProvider.php deleted file mode 100644 index 09c970cf..00000000 --- a/src/Adapter/Shop/ShopUrlDataProvider.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop; - -use PrestaShopException; -use ShopUrl; -use Validate; - -/** - * Class ShopUrlDataProvider is responsible for providing data from shop_url table. - */ -class ShopUrlDataProvider -{ - /** - * @var int - */ - private $contextShopId; - - /** - * ShopUrlDataProvider constructor. - * - * @param int $contextShopId - */ - public function __construct($contextShopId) - { - $this->contextShopId = $contextShopId; - } - - /** - * Gets main shop url data. - * - * @return ShopUrl - * - * @throws PrestaShopException - */ - public function getMainShopUrl() - { - /** @var ShopUrl $result */ - $result = ShopUrl::getShopUrls($this->contextShopId)->where('main', '=', 1)->getFirst(); - - if (!Validate::isLoadedObject($result)) { - return new ShopUrl(); - } - - return $result; - } - - /** - * Checks whenever the main shop url exists for current shop context. - * - * @return bool - * - * @throws PrestaShopException - */ - public function doesMainShopUrlExist() - { - $shopUrl = ShopUrl::getShopUrls($this->contextShopId)->where('main', '=', 1)->getFirst(); - - return Validate::isLoadedObject($shopUrl); - } -} diff --git a/src/Adapter/Shop/Url/BaseUrlProvider.php b/src/Adapter/Shop/Url/BaseUrlProvider.php deleted file mode 100644 index b58d558f..00000000 --- a/src/Adapter/Shop/Url/BaseUrlProvider.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop\Url; - -use Link; -use PrestaShop\PrestaShop\Core\Shop\Url\UrlProviderInterface; - -/** - * Class BaseUrlProvider provides base Front Office URL for context shop. - */ -final class BaseUrlProvider implements UrlProviderInterface -{ - /** - * @var Link - */ - private $link; - - /** - * @param Link $link - */ - public function __construct(Link $link) - { - $this->link = $link; - } - - /** - * {@inheritdoc} - */ - public function getUrl() - { - return $this->link->getBaseLink(); - } -} diff --git a/src/Adapter/Shop/Url/CategoryProvider.php b/src/Adapter/Shop/Url/CategoryProvider.php deleted file mode 100644 index 75d52ca1..00000000 --- a/src/Adapter/Shop/Url/CategoryProvider.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop\Url; - -use Link; -use PrestaShop\PrestaShop\Core\Shop\Url\UrlProviderInterface; - -/** - * Class CategoryProvider provides base Front Office URL for context shop. - */ -final class CategoryProvider implements UrlProviderInterface -{ - /** - * @var Link - */ - private $link; - - /** - * @param Link $link - */ - public function __construct(Link $link) - { - $this->link = $link; - } - - /** - * Create a link to a category. - * - * @param int $categoryId - * @param string $rewrite - * - * @return string - */ - public function getUrl($categoryId = null, $rewrite = null) - { - return $this->link->getCategoryLink((int) $categoryId, $rewrite); - } -} diff --git a/src/Adapter/Shop/Url/CmsProvider.php b/src/Adapter/Shop/Url/CmsProvider.php deleted file mode 100644 index b39f0008..00000000 --- a/src/Adapter/Shop/Url/CmsProvider.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Shop\Url; - -use Link; -use PrestaShop\PrestaShop\Core\Shop\Url\UrlProviderInterface; - -/** - * Class CmsProvider provides base Front Office URL for context shop. - */ -final class CmsProvider implements UrlProviderInterface -{ - /** - * @var Link - */ - private $link; - - /** - * @param Link $link - */ - public function __construct(Link $link) - { - $this->link = $link; - } - - /** - * Create a link to a cms. - * - * @param int $cmsId - * @param string $rewrite - * - * @return string - */ - public function getUrl($cmsId = null, $rewrite = null) - { - return $this->link->getCmsLink((int) $cmsId, $rewrite); - } -} diff --git a/src/Adapter/Smarty/SmartyCacheConfiguration.php b/src/Adapter/Smarty/SmartyCacheConfiguration.php deleted file mode 100644 index d8e00a62..00000000 --- a/src/Adapter/Smarty/SmartyCacheConfiguration.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Smarty; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * This class will manage Smarty configuration for a Shop. - */ -class SmartyCacheConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'template_compilation' => $this->configuration->get('PS_SMARTY_FORCE_COMPILE'), - 'cache' => $this->configuration->getBoolean('PS_SMARTY_CACHE'), - 'multi_front_optimization' => $this->configuration->getBoolean('PS_SMARTY_LOCAL'), - 'caching_type' => $this->configuration->get('PS_SMARTY_CACHING_TYPE'), - 'clear_cache' => $this->configuration->get('PS_SMARTY_CLEAR_CACHE'), - 'smarty_console' => $this->configuration->get('PS_SMARTY_CONSOLE'), - 'smarty_console_key' => $this->configuration->get('PS_SMARTY_CONSOLE_KEY'), - ]; - } - - /** - * {@inheritdoc} - * - * Note: 'smarty_console' and 'smarty_console_key' keys are not allowed for update. - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_SMARTY_FORCE_COMPILE', $configuration['template_compilation']); - $this->configuration->set('PS_SMARTY_CACHE', $configuration['cache']); - $this->configuration->set('PS_SMARTY_LOCAL', $configuration['multi_front_optimization']); - $this->configuration->set('PS_SMARTY_CACHING_TYPE', $configuration['caching_type']); - $this->configuration->set('PS_SMARTY_CLEAR_CACHE', $configuration['clear_cache']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['template_compilation'], - $configuration['cache'], - $configuration['multi_front_optimization'], - $configuration['caching_type'], - $configuration['clear_cache'], - $configuration['smarty_console'], - $configuration['smarty_console_key'] - ); - } -} diff --git a/src/Adapter/SpecificPrice/AbstractSpecificPriceHandler.php b/src/Adapter/SpecificPrice/AbstractSpecificPriceHandler.php deleted file mode 100644 index 794875bb..00000000 --- a/src/Adapter/SpecificPrice/AbstractSpecificPriceHandler.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SpecificPrice; - -use DateTime; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceException; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\ValueObject\SpecificPriceId; -use PrestaShopException; -use SpecificPrice; - -/** - * Provides reusable methods for specific price handlers - */ -abstract class AbstractSpecificPriceHandler -{ - /** - * Gets legacy SpecificPrice object - * - * @param SpecificPriceId $specificPriceId - * - * @return SpecificPrice - * - * @throws SpecificPriceException - * @throws SpecificPriceNotFoundException - */ - protected function getSpecificPrice(SpecificPriceId $specificPriceId): SpecificPrice - { - $specificPriceIdValue = $specificPriceId->getValue(); - - try { - $specificPrice = new SpecificPrice($specificPriceIdValue); - } catch (PrestaShopException $e) { - throw new SpecificPriceException('Failed to fetch new specific price', 0, $e); - } - - if ($specificPrice->id !== $specificPriceIdValue) { - throw new SpecificPriceNotFoundException(sprintf('Specific price with id "%s" was not found.', $specificPriceIdValue)); - } - - return $specificPrice; - } - - /** - * Checks if date range values are not inverse. (range from not bigger than range to) - * - * @param DateTime $from - * @param DateTime $to - * - * @throws SpecificPriceConstraintException - */ - protected function assertDateRangeIsNotInverse(DateTime $from, DateTime $to) - { - if ($from->diff($to)->invert) { - throw new SpecificPriceConstraintException('The date time for specific price cannot be inverse', SpecificPriceConstraintException::INVALID_DATE_RANGE); - } - } -} diff --git a/src/Adapter/SpecificPrice/CommandHandler/AddSpecificPriceHandler.php b/src/Adapter/SpecificPrice/CommandHandler/AddSpecificPriceHandler.php deleted file mode 100644 index 96c9398a..00000000 --- a/src/Adapter/SpecificPrice/CommandHandler/AddSpecificPriceHandler.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SpecificPrice\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\SpecificPrice\AbstractSpecificPriceHandler; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\AddSpecificPriceCommand; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\CommandHandler\AddSpecificPriceHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceException; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\ValueObject\SpecificPriceId; -use PrestaShop\PrestaShop\Core\Util\DateTime\DateTime; -use PrestaShopException; -use SpecificPrice; - -/** - * Handles AddSpecificPriceCommand using legacy object model - */ -final class AddSpecificPriceHandler extends AbstractSpecificPriceHandler implements AddSpecificPriceHandlerInterface -{ - /** - * @param AddSpecificPriceCommand $command - * - * @return SpecificPriceId - * - * @throws SpecificPriceConstraintException - * @throws SpecificPriceException - */ - public function handle(AddSpecificPriceCommand $command): SpecificPriceId - { - try { - $specificPrice = $this->createSpecificPriceFromCommand($command); - - if (false === $specificPrice->validateFields(false)) { - throw new SpecificPriceConstraintException('Specific price contains invalid field values'); - } - - if (!$specificPrice->add()) { - throw new SpecificPriceException('Failed to add new specific price'); - } - } catch (PrestaShopException $e) { - throw new SpecificPriceException('An error occurred when trying to add new specific price'); - } - - return new SpecificPriceId($specificPrice->id); - } - - /** - * Creates legacy SpecificPrice object from command - * - * @param AddSpecificPriceCommand $command - * - * @return SpecificPrice - * - * @throws PrestaShopException - * @throws SpecificPriceConstraintException - */ - private function createSpecificPriceFromCommand(AddSpecificPriceCommand $command): SpecificPrice - { - $specificPrice = new SpecificPrice(); - - $specificPrice->id_product = $command->getProductId()->getValue(); - $specificPrice->reduction_type = $command->getReduction()->getType(); - $specificPrice->reduction = $command->getReduction()->getValue(); - $specificPrice->reduction_tax = $command->isIncludeTax(); - $specificPrice->price = $command->getPrice(); - $specificPrice->from_quantity = $command->getFromQuantity(); - $specificPrice->id_shop_group = $command->getShopGroupId() ?? 0; - $specificPrice->id_shop = $command->getShopId() ?? 0; - $specificPrice->id_cart = $command->getCartId() ?? 0; - $specificPrice->id_product_attribute = $command->getProductAttributeId() ?? 0; - $specificPrice->id_currency = $command->getCurrencyId() ?? 0; - $specificPrice->id_specific_price_rule = $command->getCartRuleId() ?? 0; - $specificPrice->id_country = $command->getCountryId() ?? 0; - $specificPrice->id_group = $command->getGroupId() ?? 0; - $specificPrice->id_customer = $command->getCustomerId() ?? 0; - $specificPrice->from = DateTime::NULL_VALUE; - $specificPrice->to = DateTime::NULL_VALUE; - - $from = $command->getDateTimeFrom(); - $to = $command->getDateTimeTo(); - - if ($from && $to) { - $this->assertDateRangeIsNotInverse($from, $to); - } - - if ($from) { - $specificPrice->from = $from->format('Y-m-d H:i:s'); - } - - if ($to) { - $specificPrice->to = $to->format('Y-m-d H:i:s'); - } - - return $specificPrice; - } -} diff --git a/src/Adapter/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandler.php b/src/Adapter/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandler.php deleted file mode 100644 index a52d4a79..00000000 --- a/src/Adapter/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SpecificPrice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\DeleteSpecificPriceByCartProductCommand; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\CommandHandler\DeleteSpecificPriceByCartProductHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceException; -use PrestaShopException; -use SpecificPrice; - -/** - * Handles DeleteSpecificPriceByCartProduct command using legacy object model - */ -final class DeleteSpecificPriceByCartProductHandler implements DeleteSpecificPriceByCartProductHandlerInterface -{ - /** - * @param DeleteSpecificPriceByCartProductCommand $command - * - * @throws SpecificPriceException - */ - public function handle(DeleteSpecificPriceByCartProductCommand $command): void - { - $productAttributeId = $command->getProductAttributeId() ?? false; - $cartIdValue = $command->getCartId()->getValue(); - $productIdValue = $command->getProductId()->getValue(); - - try { - if (false === SpecificPrice::deleteByIdCart($cartIdValue, $productIdValue, $productAttributeId)) { - throw new SpecificPriceException(sprintf('Failed to delete specific price for cart #%s product #%s', $cartIdValue, $productIdValue)); - } - } catch (PrestaShopException $e) { - throw new SpecificPriceException(sprintf('An error occurred when trying to delete specific price for cart #%s product #%s', $cartIdValue, $productIdValue)); - } - } -} diff --git a/src/Adapter/SqlManager/CommandHandler/AddSqlRequestHandler.php b/src/Adapter/SqlManager/CommandHandler/AddSqlRequestHandler.php deleted file mode 100644 index bccd7ad3..00000000 --- a/src/Adapter/SqlManager/CommandHandler/AddSqlRequestHandler.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\AddSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler\AddSqlRequestHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\CannotAddSqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; -use PrestaShopException; -use RequestSql; - -/** - * Class AddSqlRequestHandler handles SqlRequest creation command. - * - * @internal - */ -final class AddSqlRequestHandler implements AddSqlRequestHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotAddSqlRequestException - * @throws SqlRequestException - */ - public function handle(AddSqlRequestCommand $command) - { - try { - $entity = new RequestSql(); - $entity->name = $command->getName(); - $entity->sql = $command->getSql(); - - $entity->add(); - - if (0 >= $entity->id) { - throw new CannotAddSqlRequestException(sprintf('Invalid entity id after creation: %s', $entity->id)); - } - - return new SqlRequestId($entity->id); - } catch (PrestaShopException $e) { - throw new SqlRequestException('Failed to create SqlRequest', 0, $e); - } - } -} diff --git a/src/Adapter/SqlManager/CommandHandler/BulkDeleteSqlRequestHandler.php b/src/Adapter/SqlManager/CommandHandler/BulkDeleteSqlRequestHandler.php deleted file mode 100644 index 5b2a0415..00000000 --- a/src/Adapter/SqlManager/CommandHandler/BulkDeleteSqlRequestHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\BulkDeleteSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler\BulkDeleteSqlRequestHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\CannotDeleteSqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShopException; -use RequestSql; - -/** - * Class BulkDeleteSqlRequestHandler handles bulk delete of SqlRequest command. - */ -final class BulkDeleteSqlRequestHandler implements BulkDeleteSqlRequestHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SqlRequestException - */ - public function handle(BulkDeleteSqlRequestCommand $command) - { - try { - foreach ($command->getSqlRequestIds() as $sqlRequestId) { - $entity = new RequestSql($sqlRequestId->getValue()); - - if (false === $entity->delete()) { - throw new CannotDeleteSqlRequestException(sprintf('Failed to delete SqlRequest with id %s', $sqlRequestId), CannotDeleteSqlRequestException::CANNOT_BULK_DELETE); - } - } - } catch (PrestaShopException $e) { - throw new SqlRequestException('Unexpected error occurred when handling bulk delete SqlRequest', 0, $e); - } - } -} diff --git a/src/Adapter/SqlManager/CommandHandler/DeleteSqlRequestHandler.php b/src/Adapter/SqlManager/CommandHandler/DeleteSqlRequestHandler.php deleted file mode 100644 index ccc5d4ea..00000000 --- a/src/Adapter/SqlManager/CommandHandler/DeleteSqlRequestHandler.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\DeleteSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler\DeleteSqlRequestHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\CannotDeleteSqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestNotFoundException; -use PrestaShopException; -use RequestSql; - -/** - * Class DeleteSqlRequestHandler. - * - * @internal - */ -final class DeleteSqlRequestHandler implements DeleteSqlRequestHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotDeleteSqlRequestException - * @throws SqlRequestNotFoundException - * @throws SqlRequestException - */ - public function handle(DeleteSqlRequestCommand $command) - { - $entityId = $command->getSqlRequestId()->getValue(); - - try { - $entity = new RequestSql($entityId); - - if (0 >= $entity->id) { - throw new SqlRequestNotFoundException(sprintf('SqlRequest with id "%s" was not found for edit', var_export($entityId, true))); - } - - if (false === $entity->delete()) { - throw new CannotDeleteSqlRequestException(sprintf('Could not delete SqlRequest with id %s', var_export($entityId)), CannotDeleteSqlRequestException::CANNOT_SINGLE_DELETE); - } - } catch (PrestaShopException $e) { - throw new SqlRequestException(sprintf('Unexpected error occurred when deleting SqlRequest with id %s', var_export($entityId, true)), 0, $e); - } - } -} diff --git a/src/Adapter/SqlManager/CommandHandler/EditSqlRequestHandler.php b/src/Adapter/SqlManager/CommandHandler/EditSqlRequestHandler.php deleted file mode 100644 index edbdc9a1..00000000 --- a/src/Adapter/SqlManager/CommandHandler/EditSqlRequestHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\EditSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler\EditSqlRequestHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\CannotEditSqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestNotFoundException; -use PrestaShopException; -use RequestSql; - -/** - * Class EditSqlRequestHandler is responsible for updating SqlRequest. - * - * @internal - */ -final class EditSqlRequestHandler implements EditSqlRequestHandlerInterface -{ - /** - * {@inheritdoc} - * - * @param EditSqlRequestCommand $command - * - * @throws CannotEditSqlRequestException - * @throws SqlRequestException - * @throws SqlRequestNotFoundException - */ - public function handle(EditSqlRequestCommand $command) - { - try { - $entity = new RequestSql($command->getSqlRequestId()->getValue()); - - if (0 >= $entity->id) { - throw new SqlRequestNotFoundException(sprintf('SqlRequest with id "%s" was not found for edit', $command->getSqlRequestId()->getValue())); - } - - if (null !== $command->getName()) { - $entity->name = $command->getName(); - } - - if (null !== $command->getSql()) { - $entity->sql = $command->getSql(); - } - - if (false === $entity->update()) { - throw new CannotEditSqlRequestException(sprintf('Error occurred when updating SqlRequest with id "%s"', $command->getSqlRequestId()->getValue())); - } - } catch (PrestaShopException $e) { - throw new SqlRequestException(sprintf('Error occurred when updating SqlRequest with id "%s"', $command->getSqlRequestId()->getValue())); - } - } -} diff --git a/src/Adapter/SqlManager/QueryHandler/GetDatabaseTableFieldsListHandler.php b/src/Adapter/SqlManager/QueryHandler/GetDatabaseTableFieldsListHandler.php deleted file mode 100644 index f1cdb1f3..00000000 --- a/src/Adapter/SqlManager/QueryHandler/GetDatabaseTableFieldsListHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTableFields; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTableFieldsList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler\GetDatabaseTableFieldsListHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\DatabaseTableField; -use RequestSql; - -/** - * Class GetDatabaseTableFieldsListHandler. - * - * @internal - */ -final class GetDatabaseTableFieldsListHandler implements GetDatabaseTableFieldsListHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetDatabaseTableFieldsList $query) - { - $attributes = (new RequestSql())->getAttributesByTable($query->getTableName()); - $fields = []; - - foreach ($attributes as $attribute) { - $fields[] = new DatabaseTableField( - $attribute['Field'], - $attribute['Type'] - ); - } - - return new DatabaseTableFields($fields); - } -} diff --git a/src/Adapter/SqlManager/QueryHandler/GetDatabaseTablesListHandler.php b/src/Adapter/SqlManager/QueryHandler/GetDatabaseTablesListHandler.php deleted file mode 100644 index 5653832f..00000000 --- a/src/Adapter/SqlManager/QueryHandler/GetDatabaseTablesListHandler.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTablesList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTablesList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler\GetDatabaseTablesListHandlerInterface; -use RequestSql; - -/** - * Class GetDatabaseTablesListHandler. - * - * @internal - */ -final class GetDatabaseTablesListHandler implements GetDatabaseTablesListHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetDatabaseTablesList $query) - { - $dbTables = (new RequestSql())->getTables(); - - return new DatabaseTablesList($dbTables); - } -} diff --git a/src/Adapter/SqlManager/QueryHandler/GetSqlRequestExecutionResultHandler.php b/src/Adapter/SqlManager/QueryHandler/GetSqlRequestExecutionResultHandler.php deleted file mode 100644 index 780cc641..00000000 --- a/src/Adapter/SqlManager/QueryHandler/GetSqlRequestExecutionResultHandler.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler; - -use Db; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler\GetSqlRequestExecutionResultHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestExecutionResult; -use PrestaShopException; -use RequestSql; - -/** - * Class GetSqlRequestExecutionResultHandler. - * - * @internal - */ -final class GetSqlRequestExecutionResultHandler implements GetSqlRequestExecutionResultHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SqlRequestNotFoundException - * @throws SqlRequestException - */ - public function handle(GetSqlRequestExecutionResult $query) - { - try { - $id = $query->getSqlRequestId()->getValue(); - $entity = new RequestSql($id); - - if (0 >= $entity->id) { - throw new SqlRequestNotFoundException(sprintf('SqlRequest with id %s was not found', $id)); - } - - $rows = Db::getInstance()->executeS($entity->sql); - - if (empty($rows)) { - return new SqlRequestExecutionResult([], []); - } - - $columns = array_keys(reset($rows)); - $rows = $this->hideSensitiveData($rows); - - return new SqlRequestExecutionResult( - $columns, - $rows - ); - } catch (PrestaShopException $e) { - throw new SqlRequestException('Unexpected error occurred', 0, $e); - } - } - - /** - * Replaces sensitive data with placeholder values. - * - * @param array $records - * - * @return array Records with hidden sensitive data - * - * @throws PrestaShopException - */ - private function hideSensitiveData(array $records) - { - foreach ($records as $key => $record) { - foreach ((new RequestSql())->attributes as $sensitiveAttribute => $placeholder) { - if (isset($record[$sensitiveAttribute])) { - $records[$key][$sensitiveAttribute] = $placeholder; - } - } - } - - return $records; - } -} diff --git a/src/Adapter/SqlManager/QueryHandler/GetSqlRequestForEditingHandler.php b/src/Adapter/SqlManager/QueryHandler/GetSqlRequestForEditingHandler.php deleted file mode 100644 index 10a65ae9..00000000 --- a/src/Adapter/SqlManager/QueryHandler/GetSqlRequestForEditingHandler.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\EditableSqlRequest; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestForEditing; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler\GetSqlRequestForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; -use RequestSql; - -/** - * Class GetSqlRequestForEditingHandler. - * - * @internal - */ -final class GetSqlRequestForEditingHandler implements GetSqlRequestForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SqlRequestException - * @throws SqlRequestNotFoundException - */ - public function handle(GetSqlRequestForEditing $query) - { - $entity = $this->loadById($query->getRequestSqlId()); - - return $this->buildEditableSqlRequest($entity); - } - - /** - * @param SqlRequestId $requestSqlId - * - * @return RequestSql - * - * @throws SqlRequestNotFoundException - */ - private function loadById(SqlRequestId $requestSqlId) - { - $entity = new RequestSql($requestSqlId->getValue()); - - if (0 >= $entity->id) { - throw new SqlRequestNotFoundException(sprintf('SqlRequest with id "%s" cannot be found', $requestSqlId->getValue())); - } - - if ((int) $entity->id !== $requestSqlId->getValue()) { - throw new SqlRequestNotFoundException(sprintf('The retrieved id "%s" does not match requested SqlRequest id "%s"', $entity->id, $requestSqlId->getValue())); - } - - return $entity; - } - - /** - * @param RequestSql $entity - * - * @return EditableSqlRequest - * - * @throws SqlRequestException - */ - private function buildEditableSqlRequest(RequestSql $entity) - { - return new EditableSqlRequest( - new SqlRequestId($entity->id), - $entity->name, - $entity->sql - ); - } -} diff --git a/src/Adapter/SqlManager/SqlQueryValidator.php b/src/Adapter/SqlManager/SqlQueryValidator.php deleted file mode 100644 index 0d990648..00000000 --- a/src/Adapter/SqlManager/SqlQueryValidator.php +++ /dev/null @@ -1,415 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager; - -use ErrorException; -use PrestaShop\PrestaShop\Adapter\Entity\RequestSql; -use PrestaShopDatabaseException; - -/** - * Class SqlQueryValidator is responsible for validating Request SQL model data. - */ -class SqlQueryValidator -{ - /** - * Check if SQL is valid for Reqest SQL model. - * Only "Select" sqls should be valid. - * - * @param string $sql - * - * @return array Array of errors if any - */ - public function validate($sql) - { - $errors = []; - - try { - $requestSql = new RequestSql(); - $parser = $requestSql->parsingSql($sql); - $validate = $requestSql->validateParser($parser, false, $sql); - - if (!$validate || count($requestSql->error_sql)) { - $errors = $this->getErrors($requestSql->error_sql); - } - } catch (ErrorException $e) { - $errors[] = [ - 'key' => 'Bad SQL query', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - } catch (PrestaShopDatabaseException $e) { - $errors[] = [ - 'key' => 'Bad SQL query', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - } - - return $errors; - } - - /** - * Get request sql errors. - * - * @param array $sqlErrors - * - * @return array - */ - private function getErrors(array $sqlErrors) - { - $errors = []; - - foreach ($sqlErrors as $key => $sqlError) { - if (false === is_array($sqlError)) { - $sqlError = []; - } - - if ('checkedFrom' === $key) { - $errors[] = $this->getFromKeywordError($sqlError); - } elseif ('checkedSelect' === $key) { - $errors[] = $this->getSelectKeywordError($sqlError); - } elseif ('checkedWhere' === $key) { - $errors[] = $this->getWhereKeywordError($sqlError); - } elseif ('checkedHaving' === $key) { - $errors[] = $this->getHavingKeywordError($sqlError); - } elseif ('checkedOrder' === $key) { - $errors[] = $this->getOrderKeywordError($sqlError); - } elseif ('checkedGroupBy' === $key) { - $errors[] = $this->getGroupKeywordError($sqlError); - } elseif ('checkedLimit' === $key) { - $errors[] = $this->getLimitKeywordError(); - } elseif ('returnNameTable' === $key) { - $errors[] = $this->getReferenceError($sqlError); - } elseif ('testedRequired' === $key) { - $errors[] = $this->getRequiredKeyError($sqlError); - } elseif ('testedUnauthorized' === $key) { - $errors[] = $this->getUnauthorizedKeyError($sqlError); - } - } - - return $errors; - } - - /** - * Get SQL error for "FROM" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getFromKeywordError(array $legacyError) - { - if (isset($legacyError['table'])) { - return [ - 'key' => 'The "%tablename%" table does not exist.', - 'parameters' => [ - '%tablename%' => $legacyError['table'], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedForm', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "SELECT" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getSelectKeywordError(array $legacyError) - { - if (isset($legacyError['table'])) { - return [ - 'key' => 'The "%tablename%" table does not exist.', - 'parameters' => [ - '%tablename%' => $legacyError['table'], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - if (isset($legacyError['*'])) { - return [ - 'key' => 'The "*" operator cannot be used in a nested query.', - 'parameters' => [], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedSelect', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "WHERE" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getWhereKeywordError(array $legacyError) - { - if (isset($legacyError['operator'])) { - return [ - 'key' => 'The operator "%s" is incorrect.', - 'parameters' => [ - '%operator%' => $legacyError['operator'], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedWhere', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "HAVING" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getHavingKeywordError(array $legacyError) - { - if (isset($legacyError['operator'])) { - return [ - 'key' => 'The "%operator%" operator is incorrect.', - 'parameters' => [ - '%operator%' => $legacyError['operator'], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedHaving', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "ORDER" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getOrderKeywordError(array $legacyError) - { - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedOrder', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "GROUP" keyword validation. - * - * @param array $legacyError - * - * @return array - */ - private function getGroupKeywordError(array $legacyError) - { - if (isset($legacyError['attribut'])) { - return [ - 'key' => 'The "%attribute%" attribute does not exist in the "%table%" table.', - 'parameters' => [ - '%attribute%' => $legacyError['attribut'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'Undefined "%s" error', - 'parameters' => [ - 'checkedGroupBy', - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get SQL error for "LIMIT" keyword validation. - * - * @return array - */ - private function getLimitKeywordError() - { - return [ - 'key' => 'The LIMIT clause must contain numeric arguments.', - 'parameters' => [], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get reference related SQL error. - * - * @param array $legacyError - * - * @return array - */ - private function getReferenceError(array $legacyError) - { - if (isset($legacyError['reference'])) { - return [ - 'key' => 'The "%reference%" reference does not exist in the "%table%" table.', - 'parameters' => [ - '%reference%' => $legacyError['reference'][0], - '%table%' => $legacyError['attribut'][1], - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - return [ - 'key' => 'When multiple tables are used, each attribute must refer back to a table.', - 'parameters' => [], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } - - /** - * Get required key error. - * - * @param string $legacyError - * - * @return array - */ - private function getRequiredKeyError($legacyError) - { - return [ - 'key' => '"%key%" does not exist.', - 'parameters' => [ - '%key%' => $legacyError, - ], - 'domain' => 'Admin.Notifications.Error', - ]; - } - - /** - * Get unauthorized key error. - * - * @param string $legacyError - * - * @return array - */ - private function getUnauthorizedKeyError($legacyError) - { - return [ - 'key' => '"%key%" is an unauthorized keyword.', - 'parameters' => [ - '%key%' => $legacyError, - ], - 'domain' => 'Admin.Advparameters.Notification', - ]; - } -} diff --git a/src/Adapter/SqlManager/SqlRequestFormDataValidator.php b/src/Adapter/SqlManager/SqlRequestFormDataValidator.php deleted file mode 100644 index 817d9c00..00000000 --- a/src/Adapter/SqlManager/SqlRequestFormDataValidator.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\SqlManager; - -use RequestSql; - -/** - * Class SqlRequestFormDataValidator validates SqlRequest data that is submitted via from. - * - * @internal - */ -class SqlRequestFormDataValidator -{ - /** - * @var SqlQueryValidator - */ - private $sqlQueryValidator; - - /** - * @param SqlQueryValidator $sqlQueryValidator - */ - public function __construct(SqlQueryValidator $sqlQueryValidator) - { - $this->sqlQueryValidator = $sqlQueryValidator; - } - - /** - * Validate SqlRequest form data. - * - * @param array $data - * - * @return array Errors if any - */ - public function validate(array $data) - { - if ($errors = $this->sqlQueryValidator->validate($data['sql'])) { - return $errors; - } - - $requestSql = new RequestSql(); - $requestSql->name = $data['name']; - $requestSql->sql = $data['sql']; - - if (true !== $error = $requestSql->validateFields(false, true)) { - return [$error]; - } - - return []; - } -} diff --git a/src/Adapter/StockManager.php b/src/Adapter/StockManager.php deleted file mode 100644 index 2249a6ee..00000000 --- a/src/Adapter/StockManager.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Db; -use PrestaShop\PrestaShop\Adapter\Configuration as ConfigurationAdapter; -use PrestaShop\PrestaShop\Adapter\Shop\Context as ShopAdapter; -use PrestaShopBundle\Service\DataProvider\StockInterface; -use StockAvailable; - -/** - * Data provider for new Architecture, about Product stocks. - * - * This class will provide data from DB / ORM about Product stocks. - */ -class StockManager implements StockInterface -{ - /** - * Gets available stock for a given product / combination / shop. - * - * @param object $product - * @param null $id_product_attribute - * @param null $id_shop - * - * @return StockAvailable - */ - public function getStockAvailableByProduct($product, $id_product_attribute = null, $id_shop = null) - { - $stockAvailable = $this->newStockAvailable($this->getStockAvailableIdByProductId($product->id, $id_product_attribute, $id_shop)); - - if (!$stockAvailable->id) { - $shopAdapter = new ShopAdapter(); - $stockAvailable->id_product = (int) $product->id; - $stockAvailable->id_product_attribute = (int) $id_product_attribute; - - $outOfStock = $this->outOfStock((int) $product->id, $id_shop); - $stockAvailable->out_of_stock = (int) $outOfStock; - - if ($id_shop === null) { - $shop_group = $shopAdapter->getContextShopGroup(); - } else { - $shop_group = $shopAdapter->ShopGroup((int) $shopAdapter->getGroupFromShop((int) $id_shop)); - } - - // if quantities are shared between shops of the group - if ($shop_group->share_stock) { - $stockAvailable->id_shop = 0; - $stockAvailable->id_shop_group = (int) $shop_group->id; - } else { - $stockAvailable->id_shop = (int) $id_shop; - $stockAvailable->id_shop_group = 0; - } - $stockAvailable->add(); - } - - return $stockAvailable; - } - - /** - * Returns True if Stocks are managed by a module (or by legacy ASM). - * - * @return bool True if Stocks are managed by a module (or by legacy ASM) - */ - public function isAsmGloballyActivated() - { - return (bool) (new ConfigurationAdapter())->get('PS_ADVANCED_STOCK_MANAGEMENT'); - } - - /** - * @param $shopId - * @param $errorState - * @param $cancellationState - * @param int|null $idProduct - * @param int|null $idOrder - * - * @return bool - */ - public function updatePhysicalProductQuantity($shopId, $errorState, $cancellationState, $idProduct = null, $idOrder = null) - { - $this->updateReservedProductQuantity($shopId, $errorState, $cancellationState, $idProduct, $idOrder); - - $updatePhysicalQuantityQuery = ' - UPDATE {table_prefix}stock_available sa - SET sa.physical_quantity = sa.quantity + sa.reserved_quantity - WHERE sa.id_shop = ' . (int) $shopId . ' - '; - - if ($idProduct) { - $updatePhysicalQuantityQuery .= ' AND sa.id_product = ' . (int) $idProduct; - } - - if ($idOrder) { - $updatePhysicalQuantityQuery .= ' AND sa.id_product IN (SELECT product_id FROM {table_prefix}order_detail WHERE id_order = ' . (int) $idOrder . ')'; - } - - $updatePhysicalQuantityQuery = str_replace('{table_prefix}', _DB_PREFIX_, $updatePhysicalQuantityQuery); - - return Db::getInstance()->execute($updatePhysicalQuantityQuery); - } - - /** - * @param $shopId - * @param $errorState - * @param $cancellationState - * @param int|null $idProduct - * @param int|null $idOrder - * - * @return bool - */ - private function updateReservedProductQuantity($shopId, $errorState, $cancellationState, $idProduct = null, $idOrder = null) - { - $updateReservedQuantityQuery = ' - UPDATE {table_prefix}stock_available sa - SET sa.reserved_quantity = ( - SELECT SUM(od.product_quantity - od.product_quantity_refunded) - FROM {table_prefix}orders o - INNER JOIN {table_prefix}order_detail od ON od.id_order = o.id_order - INNER JOIN {table_prefix}order_state os ON os.id_order_state = o.current_state - WHERE o.id_shop = :shop_id AND - os.shipped != 1 AND ( - o.valid = 1 OR ( - os.id_order_state != :error_state AND - os.id_order_state != :cancellation_state - ) - ) AND sa.id_product = od.product_id AND - sa.id_product_attribute = od.product_attribute_id - GROUP BY od.product_id, od.product_attribute_id - ) - WHERE sa.id_shop = :shop_id - '; - - $strParams = [ - '{table_prefix}' => _DB_PREFIX_, - ':shop_id' => (int) $shopId, - ':error_state' => (int) $errorState, - ':cancellation_state' => (int) $cancellationState, - ]; - - if ($idProduct) { - $updateReservedQuantityQuery .= ' AND sa.id_product = :product_id'; - $strParams[':product_id'] = (int) $idProduct; - } - - if ($idOrder) { - $updateReservedQuantityQuery .= ' AND sa.id_product IN (SELECT product_id FROM {table_prefix}order_detail WHERE id_order = :order_id)'; - $strParams[':order_id'] = (int) $idOrder; - } - - $updateReservedQuantityQuery = strtr($updateReservedQuantityQuery, $strParams); - - return Db::getInstance()->execute($updateReservedQuantityQuery); - } - - /** - * Instance a new StockAvailable. - * - * @param null $stockAvailableId - * - * @return StockAvailable - */ - public function newStockAvailable($stockAvailableId = null) - { - if (is_int($stockAvailableId)) { - return new StockAvailable($stockAvailableId); - } - - return new StockAvailable(); - } - - /** - * Use legacy getStockAvailableIdByProductId. - * - * @param $productId - * @param null $productAttributeId - * @param null $shopId - * - * @return bool|int - */ - public function getStockAvailableIdByProductId($productId, $productAttributeId = null, $shopId = null) - { - return StockAvailable::getStockAvailableIdByProductId($productId, $productAttributeId, $shopId); - } - - /** - * For a given product, get its "out of stock" flag. - * - * @param int $productId - * @param int $shopId Optional : gets context if null @see Context::getContext() - * - * @return bool : depends on stock @see $depends_on_stock - */ - public function outOfStock($productId, $shopId = null) - { - return StockAvailable::outOfStock($productId, $shopId); - } -} diff --git a/src/Adapter/Supplier/AbstractSupplierHandler.php b/src/Adapter/Supplier/AbstractSupplierHandler.php deleted file mode 100644 index d4f13ba8..00000000 --- a/src/Adapter/Supplier/AbstractSupplierHandler.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use Address; -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; -use PrestaShopException; -use Supplier; - -/** - * Provides reusable methods for supplier command/query handlers - */ -abstract class AbstractSupplierHandler extends AbstractObjectModelHandler -{ - /** - * Gets legacy Supplier - * - * @param SupplierId $supplierId - * - * @return Supplier - * - * @throws SupplierException - */ - protected function getSupplier(SupplierId $supplierId) - { - try { - $supplier = new Supplier($supplierId->getValue()); - } catch (PrestaShopException $e) { - throw new SupplierException('Failed to create new supplier', 0, $e); - } - - if ($supplier->id !== $supplierId->getValue()) { - throw new SupplierNotFoundException(sprintf('Supplier with id "%s" was not found.', $supplierId->getValue())); - } - - return $supplier; - } - - /** - * @param SupplierId $supplierId - * - * @return Address - * - * @throws SupplierException - */ - protected function getSupplierAddress(SupplierId $supplierId) - { - $supplierIdValue = $supplierId->getValue(); - try { - $addressId = Address::getAddressIdBySupplierId($supplierIdValue); - - $address = new Address($addressId); - - if (null === $address->id_supplier) { - throw new AddressNotFoundException(sprintf('Address for supplier with id "%s" was not found', $supplierIdValue)); - } - } catch (PrestaShopException $e) { - throw new SupplierException('Failed to get supplier address', 0, $e); - } - - return $address; - } - - protected function removeSupplier(SupplierId $supplierId) - { - $supplier = $this->getSupplier($supplierId); - - try { - return $supplier->delete(); - } catch (PrestaShopException $e) { - throw new SupplierException(sprintf('An error occurred when deleting Supplier object with id "%s".', $supplier->id)); - } - } - - /** - * @param Supplier $supplier - * @param Address $address - * - * @throws PrestaShopException - * @throws SupplierException - */ - protected function validateFields(Supplier $supplier, Address $address) - { - if (false === $supplier->validateFields(false) || false === $supplier->validateFieldsLang(false)) { - throw new SupplierException('Supplier contains invalid field values'); - } - - if (false === $address->validateFields(false) || false === $address->validateFieldsLang(false)) { - throw new SupplierException('Supplier address contains invalid field values'); - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/AbstractDeleteSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/AbstractDeleteSupplierHandler.php deleted file mode 100644 index d73c9c42..00000000 --- a/src/Adapter/Supplier/CommandHandler/AbstractDeleteSupplierHandler.php +++ /dev/null @@ -1,162 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use Address; -use Db; -use PrestaShop\PrestaShop\Adapter\Supplier\SupplierAddressProvider; -use PrestaShop\PrestaShop\Adapter\Supplier\SupplierOrderValidator; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierAddressException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierProductRelationException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; -use PrestaShopException; -use Supplier; - -/** - * Class AbstractDeleteSupplierHandler defines common actions required for - * both BulkDeleteSupplierHandler and DeleteSupplierHandler. - */ -abstract class AbstractDeleteSupplierHandler -{ - /** - * @var SupplierOrderValidator - */ - private $supplierOrderValidator; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @var SupplierAddressProvider - */ - private $supplierAddressProvider; - - /** - * @param SupplierOrderValidator $supplierOrderValidator - * @param SupplierAddressProvider $supplierAddressProvider - * @param string $dbPrefix - */ - public function __construct( - SupplierOrderValidator $supplierOrderValidator, - SupplierAddressProvider $supplierAddressProvider, - $dbPrefix - ) { - $this->supplierOrderValidator = $supplierOrderValidator; - $this->dbPrefix = $dbPrefix; - $this->supplierAddressProvider = $supplierAddressProvider; - } - - /** - * Removes supplier and all related content with it such as image, supplier and product relation - * and supplier address. - * - * @param SupplierId $supplierId - * - * @throws SupplierException - */ - protected function removeSupplier(SupplierId $supplierId) - { - try { - $entity = new Supplier($supplierId->getValue()); - - if (0 >= $entity->id) { - throw new SupplierNotFoundException(sprintf('Supplier object with id "%s" was not found for deletion.', $supplierId->getValue())); - } - - if ($this->hasPendingOrders($supplierId)) { - throw new CannotDeleteSupplierException($supplierId->getValue(), sprintf('Supplier with id %s cannot be deleted due to it has pending orders', $supplierId->getValue()), CannotDeleteSupplierException::HAS_PENDING_ORDERS); - } - - if (false === $this->deleteProductSupplierRelation($supplierId)) { - throw new CannotDeleteSupplierProductRelationException(sprintf('Unable to delete suppliers with id "%s" product relation from product_supplier table', $supplierId->getValue())); - } - - if (1 >= count($entity->getAssociatedShops()) && false === $this->deleteSupplierAddress($supplierId)) { - throw new CannotDeleteSupplierAddressException(sprintf('Unable to set deleted flag for supplier with id "%s" address', $supplierId->getValue())); - } - - if (false === $entity->delete()) { - throw new SupplierException(sprintf('Unable to delete supplier object with id "%s"', $supplierId->getValue())); - } - } catch (PrestaShopException $exception) { - throw new SupplierException(sprintf('An error occurred when deleting the supplier object with id "%s"', $supplierId->getValue()), 0, $exception); - } - } - - /** - * Deletes product supplier relation. - * - * @param SupplierId $supplierId - * - * @return bool - */ - private function deleteProductSupplierRelation(SupplierId $supplierId) - { - $sql = 'DELETE FROM `' . $this->dbPrefix . 'product_supplier` WHERE `id_supplier`=' . $supplierId->getValue(); - - return Db::getInstance()->execute($sql); - } - - /** - * Deletes supplier address. - * - * @param SupplierId $supplierId - * - * @return bool - */ - private function deleteSupplierAddress(SupplierId $supplierId) - { - $supplierAddressId = $this->supplierAddressProvider->getIdBySupplier($supplierId->getValue()); - - $address = new Address($supplierAddressId); - - if ($address->id) { - $address->deleted = true; - - return $address->update(); - } - - return true; - } - - /** - * Checks if the given supplier has pending orders. - * - * @param SupplierId $supplierId - * - * @return bool - */ - private function hasPendingOrders(SupplierId $supplierId) - { - return $this->supplierOrderValidator->hasPendingOrders($supplierId->getValue()); - } -} diff --git a/src/Adapter/Supplier/CommandHandler/AddSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/AddSupplierHandler.php deleted file mode 100644 index 9976b04d..00000000 --- a/src/Adapter/Supplier/CommandHandler/AddSupplierHandler.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use Address; -use PrestaShop\PrestaShop\Adapter\Supplier\AbstractSupplierHandler; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\AddSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\AddSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; -use PrestaShopDatabaseException; -use PrestaShopException; -use Supplier; - -/** - * Handles command which adds new supplier using legacy object model - */ -final class AddSupplierHandler extends AbstractSupplierHandler implements AddSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(AddSupplierCommand $command) - { - $supplier = new Supplier(); - $this->fillSupplierWithData($supplier, $command); - $address = $this->fetchSupplierAddressFromCommand($command); - - try { - $this->validateFields($supplier, $address); - - if (!$address->add()) { - throw new SupplierException(sprintf('Failed to add new supplier address "%s"', $address->address1)); - } - - if (!$supplier->add()) { - throw new SupplierException(sprintf('Failed to add new supplier "%s"', $command->getName())); - } - - $this->addShopAssociation($supplier, $command); - $address->id_supplier = $supplier->id; - $address->update(); - } catch (PrestaShopException $e) { - throw new SupplierException(sprintf('Failed to add new supplier "%s"', $command->getName())); - } - - return new SupplierId((int) $supplier->id); - } - - /** - * Add supplier and shop association - * - * @param Supplier $supplier - * @param AddSupplierCommand $command - * - * @throws PrestaShopDatabaseException - */ - private function addShopAssociation(Supplier $supplier, AddSupplierCommand $command) - { - $this->associateWithShops( - $supplier, - $command->getShopAssociation() - ); - } - - /** - * @param Supplier $supplier - * @param AddSupplierCommand $command - */ - private function fillSupplierWithData(Supplier $supplier, AddSupplierCommand $command) - { - $currentDateTime = date('Y-m-d H:i:s'); - - $supplier->name = $command->getName(); - $supplier->description = $command->getLocalizedDescriptions(); - $supplier->meta_description = $command->getLocalizedMetaDescriptions(); - $supplier->meta_title = $command->getLocalizedMetaTitles(); - $supplier->meta_keywords = $command->getLocalizedMetaKeywords(); - $supplier->date_add = $currentDateTime; - $supplier->date_upd = $currentDateTime; - $supplier->active = $command->isEnabled(); - } - - /** - * Creates legacy address from given command data - * - * @param AddSupplierCommand $command - * - * @return Address - */ - private function fetchSupplierAddressFromCommand(AddSupplierCommand $command) - { - $address = new Address(); - $address->alias = 'supplier'; - $address->firstname = 'supplier'; - $address->lastname = 'supplier'; - $address->address1 = $command->getAddress(); - $address->address2 = $command->getAddress2(); - $address->id_country = $command->getCountryId(); - $address->city = $command->getCity(); - $address->id_state = $command->getStateId(); - $address->phone = $command->getPhone(); - $address->phone_mobile = $command->getMobilePhone(); - $address->postcode = $command->getPostCode(); - $address->dni = $command->getDni(); - - return $address; - } -} diff --git a/src/Adapter/Supplier/CommandHandler/BulkDeleteSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/BulkDeleteSupplierHandler.php deleted file mode 100644 index ff665f9d..00000000 --- a/src/Adapter/Supplier/CommandHandler/BulkDeleteSupplierHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDeleteSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\BulkDeleteSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; - -/** - * Class BulkDeleteSupplierHandler is responsible for deleting multiple suppliers. - */ -final class BulkDeleteSupplierHandler extends AbstractDeleteSupplierHandler implements BulkDeleteSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(BulkDeleteSupplierCommand $command) - { - foreach ($command->getSupplierIds() as $supplierId) { - try { - $this->removeSupplier($supplierId); - } catch (SupplierException $e) { - if (SupplierException::class === get_class($e)) { - throw new CannotDeleteSupplierException(sprintf('Cannot delete Supplier object with id "%s".', $supplierId->getValue()), CannotDeleteSupplierException::FAILED_BULK_DELETE); - } - - throw $e; - } - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/BulkDisableSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/BulkDisableSupplierHandler.php deleted file mode 100644 index 0cbc86f5..00000000 --- a/src/Adapter/Supplier/CommandHandler/BulkDisableSupplierHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDisableSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\BulkDisableSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotUpdateSupplierStatusException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShopException; -use Supplier; - -/** - * Class BulkDisableSupplierHandler is responsible for disabling multiple suppliers. - */ -final class BulkDisableSupplierHandler implements BulkDisableSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(BulkDisableSupplierCommand $command) - { - try { - foreach ($command->getSupplierIds() as $supplierId) { - $entity = new Supplier($supplierId->getValue()); - - if (0 >= $entity->id) { - throw new SupplierNotFoundException(sprintf('Supplier object with id "%s" has not been found for disabling status.', $supplierId->getValue())); - } - - $entity->active = false; - - if (false === $entity->update()) { - throw new CannotUpdateSupplierStatusException(sprintf('Unable to disable supplier object with id "%s"', $supplierId->getValue())); - } - } - } catch (PrestaShopException $e) { - throw new SupplierException('Unexpected error occurred when handling bulk disable supplier', 0, $e); - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/BulkEnableSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/BulkEnableSupplierHandler.php deleted file mode 100644 index 47524f48..00000000 --- a/src/Adapter/Supplier/CommandHandler/BulkEnableSupplierHandler.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkEnableSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\BulkEnableSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotUpdateSupplierStatusException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShopException; -use Supplier; - -/** - * Class BulkEnableSupplierHandler is responsible for enabling multiple suppliers. - */ -final class BulkEnableSupplierHandler implements BulkEnableSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(BulkEnableSupplierCommand $command) - { - try { - foreach ($command->getSupplierIds() as $supplierId) { - $entity = new Supplier($supplierId->getValue()); - - if (0 >= $entity->id) { - throw new SupplierNotFoundException(sprintf('Supplier object with id "%s" has not been found for enabling status.', $supplierId->getValue())); - } - - $entity->active = true; - - if (false === $entity->update()) { - throw new CannotUpdateSupplierStatusException(sprintf('Unable to enable supplier object with id "%s"', $supplierId->getValue())); - } - } - } catch (PrestaShopException $e) { - throw new SupplierException('Unexpected error occurred when handling bulk enable supplier', 0, $e); - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/DeleteSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/DeleteSupplierHandler.php deleted file mode 100644 index 91f7d9f5..00000000 --- a/src/Adapter/Supplier/CommandHandler/DeleteSupplierHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\DeleteSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\DeleteSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; - -/** - * Class DeleteSupplierHandler is responsible for deleting the supplier. - */ -final class DeleteSupplierHandler extends AbstractDeleteSupplierHandler implements DeleteSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(DeleteSupplierCommand $command) - { - $supplierId = $command->getSupplierId(); - try { - $this->removeSupplier($supplierId); - } catch (SupplierException $e) { - if (SupplierException::class === get_class($e)) { - throw new CannotDeleteSupplierException(sprintf('Cannot delete Supplier object with id "%s".', $supplierId->getValue()), CannotDeleteSupplierException::FAILED_DELETE); - } - - throw $e; - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/EditSupplierHandler.php b/src/Adapter/Supplier/CommandHandler/EditSupplierHandler.php deleted file mode 100644 index 93c051d3..00000000 --- a/src/Adapter/Supplier/CommandHandler/EditSupplierHandler.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use Address; -use PrestaShop\PrestaShop\Adapter\Supplier\AbstractSupplierHandler; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\EditSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\EditSupplierHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShopException; -use Supplier; - -/** - * Handles command which edits supplier using legacy object model - */ -final class EditSupplierHandler extends AbstractSupplierHandler implements EditSupplierHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(EditSupplierCommand $command) - { - $supplierId = $command->getSupplierId(); - $supplier = $this->getSupplier($supplierId); - $address = $this->getSupplierAddress($supplierId); - - $this->populateSupplierWithData($supplier, $command); - $this->populateAddressWithData($address, $command); - - try { - $this->validateFields($supplier, $address); - - if (false === $supplier->update()) { - throw new SupplierException(sprintf('Cannot update supplier with id "%s"', $supplier->id)); - } - if (false === $address->update()) { - throw new SupplierException(sprintf('Cannot update supplier address with id "%s"', $address->id)); - } - if (null !== $command->getAssociatedShops()) { - $this->associateWithShops($supplier, $command->getAssociatedShops()); - } - } catch (PrestaShopException $e) { - throw new SupplierException(sprintf('Cannot update supplier with id "%s"', $supplier->id)); - } - } - - /** - * Populates Supplier object with given data - * - * @param Supplier $supplier - * @param EditSupplierCommand $command - */ - private function populateSupplierWithData(Supplier $supplier, EditSupplierCommand $command) - { - if (null !== $command->getName()) { - $supplier->name = $command->getName(); - } - if (null !== $command->getLocalizedDescriptions()) { - $supplier->description = $command->getLocalizedDescriptions(); - } - if (null !== $command->getLocalizedMetaDescriptions()) { - $supplier->meta_description = $command->getLocalizedMetaDescriptions(); - } - if (null !== $command->getLocalizedMetaKeywords()) { - $supplier->meta_keywords = $command->getLocalizedMetaKeywords(); - } - if (null !== $command->getLocalizedMetaTitles()) { - $supplier->meta_title = $command->getLocalizedMetaTitles(); - } - if (null !== $command->isEnabled()) { - $supplier->active = $command->isEnabled(); - } - $supplier->date_upd = date('Y-m-d H:i:s'); - } - - /** - * Populates Supplier address with given data - * - * @param Address $address - * @param EditSupplierCommand $command - */ - private function populateAddressWithData(Address $address, EditSupplierCommand $command) - { - if (null !== $command->getAddress()) { - $address->address1 = $command->getAddress(); - } - if (null !== $command->getAddress2()) { - $address->address2 = $command->getAddress2(); - } - if (null !== $command->getPostCode()) { - $address->postcode = $command->getPostCode(); - } - if (null !== $command->getPhone()) { - $address->phone = $command->getPhone(); - } - if (null !== $command->getMobilePhone()) { - $address->phone_mobile = $command->getMobilePhone(); - } - if (null !== $command->getCity()) { - $address->city = $command->getCity(); - } - if (null !== $command->getCountryId()) { - $address->id_country = $command->getCountryId(); - } - if (null !== $command->getStateId()) { - $address->id_state = $command->getStateId(); - } - if (null !== $command->getDni()) { - $address->dni = $command->getDni(); - } - } -} diff --git a/src/Adapter/Supplier/CommandHandler/ToggleSupplierStatusHandler.php b/src/Adapter/Supplier/CommandHandler/ToggleSupplierStatusHandler.php deleted file mode 100644 index fc6de9d7..00000000 --- a/src/Adapter/Supplier/CommandHandler/ToggleSupplierStatusHandler.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\ToggleSupplierStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler\ToggleSupplierStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotToggleSupplierStatusException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShopException; -use Supplier; - -/** - * Class ToggleSupplierStatusHandler is responsible for toggling supplier status. - */ -final class ToggleSupplierStatusHandler implements ToggleSupplierStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function handle(ToggleSupplierStatusCommand $command) - { - try { - $entity = new Supplier($command->getSupplierId()->getValue()); - - if (0 >= $entity->id) { - throw new SupplierNotFoundException(sprintf('Supplier object with id "%s" has not been found for status changing.', $command->getSupplierId()->getValue())); - } - - if (false === $entity->toggleStatus()) { - throw new CannotToggleSupplierStatusException(sprintf('Unable to toggle supplier with id "%s"', $command->getSupplierId()->getValue())); - } - } catch (PrestaShopException $exception) { - throw new SupplierException(sprintf('An error occurred when toggling status for supplier object with id "%s"', $command->getSupplierId()->getValue()), 0, $exception); - } - } -} diff --git a/src/Adapter/Supplier/QueryHandler/GetSupplierForEditingHandler.php b/src/Adapter/Supplier/QueryHandler/GetSupplierForEditingHandler.php deleted file mode 100644 index 887dbe46..00000000 --- a/src/Adapter/Supplier/QueryHandler/GetSupplierForEditingHandler.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Supplier\AbstractSupplierHandler; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForEditing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryHandler\GetSupplierForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\EditableSupplier; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; - -/** - * Handles query which gets supplier for editing - */ -final class GetSupplierForEditingHandler extends AbstractSupplierHandler implements GetSupplierForEditingHandlerInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @var int - */ - private $contextShopId; - - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser, - $contextShopId - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - $this->contextShopId = $contextShopId; - } - - /** - * {@inheritdoc} - */ - public function handle(GetSupplierForEditing $query) - { - $supplierId = $query->getSupplierId(); - $supplier = $this->getSupplier($supplierId); - $address = $this->getSupplierAddress($supplierId); - - return new EditableSupplier( - $supplierId, - $supplier->name, - $supplier->description, - $address->address1, - $address->city, - $address->address2, - (int) $address->id_country, - $address->postcode, - (int) $address->id_state, - $address->phone, - $address->phone_mobile, - $supplier->meta_title, - $supplier->meta_description, - $supplier->meta_keywords, - (bool) $supplier->active, - $supplier->getAssociatedShops(), - $address->dni, - $this->getLogoImage($supplierId->getValue()) - ); - } - - /** - * @param int $imageId - * - * @return array|null - */ - private function getLogoImage(int $imageId): ?array - { - $imagePath = _PS_SUPP_IMG_DIR_ . $imageId . '.jpg'; - $imageTag = $this->getTmpImageTag($imagePath, $imageId, 'supplier'); - $imageSize = $this->getImageSize($imagePath); - - if (empty($imageTag) || null === $imageSize) { - return null; - } - - return [ - 'size' => sprintf('%skB', $imageSize), - 'path' => $this->imageTagSourceParser->parse($imageTag), - ]; - } -} diff --git a/src/Adapter/Supplier/QueryHandler/GetSupplierForViewingHandler.php b/src/Adapter/Supplier/QueryHandler/GetSupplierForViewingHandler.php deleted file mode 100644 index f5190d13..00000000 --- a/src/Adapter/Supplier/QueryHandler/GetSupplierForViewingHandler.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier\QueryHandler; - -use Currency; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForViewing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryHandler\GetSupplierForViewingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\ViewableSupplier; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShopException; -use Product; -use Supplier; - -/** - * Handles query which gets supplier for viewing - */ -final class GetSupplierForViewingHandler implements GetSupplierForViewingHandlerInterface -{ - /** - * @var Locale - */ - private $locale; - - /** - * @param Locale $locale - */ - public function __construct( - Locale $locale - ) { - $this->locale = $locale; - } - - /** - * {@inheritdoc} - * - * @throws SupplierException - * @throws LocalizationException - */ - public function handle(GetSupplierForViewing $query) - { - $supplier = $this->getSupplier($query->getSupplierId()); - - return new ViewableSupplier( - $supplier->name, - $this->getSupplierProducts($supplier, $query->getLanguageId()) - ); - } - - /** - * @param SupplierId $supplierId - * - * @return Supplier - * - * @throws SupplierNotFoundException - */ - private function getSupplier(SupplierId $supplierId) - { - $supplier = new Supplier($supplierId->getValue()); - - if ($supplier->id !== $supplierId->getValue()) { - throw new SupplierNotFoundException(sprintf('Supplier with id "%s" was not found.', $supplierId->getValue())); - } - - return $supplier; - } - - /** - * @param Supplier $supplier - * @param LanguageId $languageId - * - * @return array - * - * @throws LocalizationException - * @throws SupplierException - */ - private function getSupplierProducts(Supplier $supplier, LanguageId $languageId) - { - $products = []; - $supplierProducts = $supplier->getProductsLite($languageId->getValue()); - - try { - foreach ($supplierProducts as $productData) { - $product = new Product($productData['id_product'], false, $languageId->getValue()); - $product->loadStockData(); - - $productCombinations = $product->getAttributeCombinations($languageId->getValue()); - $combinations = []; - - foreach ($productCombinations as $combination) { - $attributeId = $combination['id_product_attribute']; - if (!isset($combinations[$attributeId])) { - $productInfo = Supplier::getProductInformationsBySupplier( - $supplier->id, - $product->id, - $combination['id_product_attribute'] - ); - $combinations[$attributeId] = [ - 'reference' => $combination['reference'], - 'supplier_reference' => $combination['supplier_reference'], - 'wholesale_price' => $this->locale->formatPrice( - $productInfo['product_supplier_price_te'], - Currency::getIsoCodeById((int) $productInfo['id_currency']) - ), - 'ean13' => $combination['ean13'], - 'upc' => $combination['upc'], - 'quantity' => $combination['quantity'], - 'attributes' => '', - ]; - } - $attribute = sprintf( - '%s - %s', - $combination['group_name'], - $combination['attribute_name'] - ); - - if (!empty($combinations[$attributeId]['attributes'])) { - $attribute = sprintf(', %s', $attribute); - } - - $combinations[$attributeId]['attributes'] = $attribute; - } - - $productInfo = Supplier::getProductInformationsBySupplier( - $supplier->id, - $product->id, - 0 - ); - $product->wholesale_price = $productInfo['product_supplier_price_te']; - $product->supplier_reference = $productInfo['product_supplier_reference']; - $products[] = [ - 'id' => $product->id, - 'name' => $product->name, - 'reference' => $product->reference, - 'supplier_reference' => $product->supplier_reference, - 'wholesale_price' => $this->locale->formatPrice($product->wholesale_price, Currency::getIsoCodeById((int) $productInfo['id_currency'])), - 'ean13' => $product->ean13, - 'upc' => $product->upc, - 'quantity' => $product->quantity, - 'combinations' => $combinations, - ]; - } - } catch (PrestaShopException $e) { - throw new SupplierException(sprintf('Failed to get products for supplier with id "%s".', $supplier->id)); - } - - return $products; - } -} diff --git a/src/Adapter/Supplier/SupplierAddressProvider.php b/src/Adapter/Supplier/SupplierAddressProvider.php deleted file mode 100644 index e1b1eeaa..00000000 --- a/src/Adapter/Supplier/SupplierAddressProvider.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use Address; - -/** - * Class SupplierAddressProvider is responsible for supplier address data retrieval. - */ -class SupplierAddressProvider -{ - /** - * Gets address id by supplier - * - * @param int $supplierId - * - * @return int - */ - public function getIdBySupplier($supplierId) - { - return Address::getAddressIdBySupplierId($supplierId); - } -} diff --git a/src/Adapter/Supplier/SupplierDataProvider.php b/src/Adapter/Supplier/SupplierDataProvider.php deleted file mode 100644 index 84ed87fc..00000000 --- a/src/Adapter/Supplier/SupplierDataProvider.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use ProductSupplier; -use Supplier; - -/** - * This class will provide data from DB / ORM about Supplier. - */ -class SupplierDataProvider -{ - /** - * Get all suppliers. - * - * @param bool $get_nb_products - * @param int $id_lang - * @param bool $active - * @param bool $p - * @param bool $n - * @param bool $all_groups - * - * @return array Suppliers - */ - public function getSuppliers($get_nb_products = false, $id_lang = 0, $active = true, $p = false, $n = false, $all_groups = false) - { - return Supplier::getSuppliers($get_nb_products, $id_lang, $active, $p, $n, $all_groups); - } - - /** - * Get product suppliers. - * - * @param int $id_product - * @param bool $group_by_supplier - * - * @return array Suppliers - */ - public function getProductSuppliers($id_product, $group_by_supplier = true) - { - $suppliersCollection = ProductSupplier::getSupplierCollection($id_product, $group_by_supplier); - - return $suppliersCollection->getResults(); - } - - /** - * For a given product and supplier, gets the product supplier data. - * - * @param int $id_product - * @param int $id_product_attribute - * @param int $id_supplier - * - * @return array - */ - public function getProductSupplierData($id_product, $id_product_attribute, $id_supplier) - { - return ProductSupplier::getProductSupplierData($id_product, $id_product_attribute, $id_supplier); - } - - /** - * Get supplier name by id. - * - * @param int $id_supplier - * - * @return string - */ - public function getNameById($id_supplier) - { - return Supplier::getNameById($id_supplier); - } -} diff --git a/src/Adapter/Supplier/SupplierLogoThumbnailProvider.php b/src/Adapter/Supplier/SupplierLogoThumbnailProvider.php deleted file mode 100644 index dec20078..00000000 --- a/src/Adapter/Supplier/SupplierLogoThumbnailProvider.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use PrestaShop\PrestaShop\Adapter\ImageManager; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; -use PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParserInterface; - -/** - * Class SupplierLogoThumbnailProvider is responsible for providing thumbnail path for supplier logo image. - */ -final class SupplierLogoThumbnailProvider implements ImageProviderInterface -{ - /** - * @var ImageTagSourceParserInterface - */ - private $imageTagSourceParser; - - /** - * @var ImageManager - */ - private $imageManager; - - /** - * @param ImageTagSourceParserInterface $imageTagSourceParser - * @param ImageManager $imageManager - */ - public function __construct( - ImageTagSourceParserInterface $imageTagSourceParser, - ImageManager $imageManager - ) { - $this->imageTagSourceParser = $imageTagSourceParser; - $this->imageManager = $imageManager; - } - - /** - * {@inheritdoc} - */ - public function getPath($supplierId) - { - $imageTag = $this->imageManager->getThumbnailForListing( - $supplierId, - 'jpg', - 'supplier', - _PS_SUPP_IMG_DIR_ - ); - - return $this->imageTagSourceParser->parse($imageTag); - } -} diff --git a/src/Adapter/Supplier/SupplierOrderValidator.php b/src/Adapter/Supplier/SupplierOrderValidator.php deleted file mode 100644 index 2bc4198d..00000000 --- a/src/Adapter/Supplier/SupplierOrderValidator.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use SupplyOrder; - -/** - * Class SupplierOrderValidator is responsible for handling supplier and its corresponding order validity. - */ -class SupplierOrderValidator -{ - /** - * Checks if the given supplier has pending orders. - * - * @param int $supplierId - * - * @return bool - */ - public function hasPendingOrders($supplierId) - { - return SupplyOrder::supplierHasPendingOrders($supplierId); - } -} diff --git a/src/Adapter/Supplier/SupplierProductSearchProvider.php b/src/Adapter/Supplier/SupplierProductSearchProvider.php deleted file mode 100644 index 09ca6e50..00000000 --- a/src/Adapter/Supplier/SupplierProductSearchProvider.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Supplier; - -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery; -use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult; -use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory; -use Supplier; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class responsible of retrieving products in Suppliers page of Front Office. - * - * @see SupplierController - */ -class SupplierProductSearchProvider implements ProductSearchProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var Supplier - */ - private $supplier; - - /** - * @var SortOrderFactory - */ - private $sortOrderFactory; - - public function __construct( - TranslatorInterface $translator, - Supplier $supplier - ) { - $this->translator = $translator; - $this->supplier = $supplier; - $this->sortOrderFactory = new SortOrderFactory($this->translator); - } - - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * @param string $type - * - * @return array|bool - */ - private function getProductsOrCount( - ProductSearchContext $context, - ProductSearchQuery $query, - $type = 'products' - ) { - return $this->supplier->getProducts( - $this->supplier->id, - $context->getIdLang(), - $query->getPage(), - $query->getResultsPerPage(), - $query->getSortOrder()->toLegacyOrderBy(), - $query->getSortOrder()->toLegacyOrderWay(), - $type !== 'products' - ); - } - - /** - * {@inheritdoc} - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ) { - $products = $this->getProductsOrCount($context, $query, 'products'); - $count = $this->getProductsOrCount($context, $query, 'count'); - - $result = new ProductSearchResult(); - - if (!empty($products)) { - $result - ->setProducts($products) - ->setTotalProductsCount($count); - - $result->setAvailableSortOrders( - $this->sortOrderFactory->getDefaultSortOrders() - ); - } - - return $result; - } -} diff --git a/src/Adapter/Support/ContactDeleter.php b/src/Adapter/Support/ContactDeleter.php deleted file mode 100644 index 88637da0..00000000 --- a/src/Adapter/Support/ContactDeleter.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Support; - -use Contact; -use PrestaShopCollection; - -/** - * Class ContactDeleter deletes contact records, using legacy code. - */ -final class ContactDeleter -{ - /** - * Delete contacts by given IDs. - * - * @param array $contactIds - * - * @return array of errors - */ - public function delete(array $contactIds) - { - $errors = []; - - if (empty($contactIds)) { - $errors[] = [ - 'key' => 'You must select at least one element to delete.', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - - return $errors; - } - - $contactCollection = new PrestaShopCollection(Contact::class); - $contactCollection->where('id_contact', 'in', $contactIds); - - foreach ($contactCollection as $contact) { - if (!$contact->delete()) { - $errors[] = [ - 'key' => 'Can\'t delete #%id%', - 'parameters' => [ - '%id%' => $contact->id, - ], - 'domain' => 'Admin.Notifications.Error', - ]; - - continue; - } - } - - return $errors; - } -} diff --git a/src/Adapter/Support/ContactRepository.php b/src/Adapter/Support/ContactRepository.php deleted file mode 100644 index 6204e347..00000000 --- a/src/Adapter/Support/ContactRepository.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Support; - -use PrestaShop\PrestaShop\Adapter\Entity\Contact; -use PrestaShop\PrestaShop\Core\Support\ContactRepositoryInterface; - -/** - * Class ContactRepository is responsible for retrieving contact data from database. - * - * @internal - */ -final class ContactRepository implements ContactRepositoryInterface -{ - /** - * {@inheritdoc} - */ - public function findAllByLangId($langId) - { - return Contact::getContacts($langId); - } -} diff --git a/src/Adapter/SymfonyContainer.php b/src/Adapter/SymfonyContainer.php deleted file mode 100644 index d816be1e..00000000 --- a/src/Adapter/SymfonyContainer.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Symfony\Component\HttpKernel\KernelInterface; - -/** - * Class SymfonyContainer. - * - * This is a TEMPORARY class for quick access to the Symfony Container - */ -final class SymfonyContainer -{ - /** @var self */ - private static $instance = null; - - /** - * Get a singleton instance of SymfonyContainer. - * - * @return \Symfony\Component\DependencyInjection\ContainerInterface; - */ - public static function getInstance() - { - if (!isset(self::$instance)) { - global $kernel; - - if (null !== $kernel && $kernel instanceof KernelInterface) { - self::$instance = $kernel->getContainer(); - } - } - - return self::$instance; - } - - public static function resetStaticCache() - { - self::$instance = null; - } -} diff --git a/src/Adapter/System/SystemInformation.php b/src/Adapter/System/SystemInformation.php deleted file mode 100644 index a287a5de..00000000 --- a/src/Adapter/System/SystemInformation.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\System; - -use PrestaShop\PrestaShop\Adapter\Hosting\HostingInformation; -use PrestaShop\PrestaShop\Adapter\Mail\MailingInformation; -use PrestaShop\PrestaShop\Adapter\Shop\ShopInformation; - -/** - * Provides a summary of system information. - */ -class SystemInformation -{ - /** - * @var HostingInformation - */ - private $hostingInformation; - - /** - * @var MailingInformation - */ - private $mailingInformation; - - /** - * @var ShopInformation - */ - private $shopInformation; - - public function __construct( - HostingInformation $hostingInformation, - MailingInformation $mailingInformation, - ShopInformation $shopInformation - ) { - $this->hostingInformation = $hostingInformation; - $this->mailingInformation = $mailingInformation; - $this->shopInformation = $shopInformation; - } - - /** - * @return array - */ - public function getSummary() - { - return [ - 'notHostMode' => !$this->hostingInformation->isHostMode(), - 'server' => $this->hostingInformation->getServerInformation(), - 'instaWebInstalled' => $this->hostingInformation->isApacheInstawebModule(), - 'uname' => $this->hostingInformation->getUname(), - 'database' => $this->hostingInformation->getDatabaseInformation(), - 'shop' => $this->shopInformation->getShopInformation(), - 'isNativePHPmail' => $this->mailingInformation->isNativeMailUsed(), - 'smtp' => $this->mailingInformation->getSmtpInformation(), - ]; - } -} diff --git a/src/Adapter/Tab/TabDataProvider.php b/src/Adapter/Tab/TabDataProvider.php deleted file mode 100644 index bf312982..00000000 --- a/src/Adapter/Tab/TabDataProvider.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tab; - -use Profile; -use Tab; - -/** - * Class TabDataProvider provides Tabs data using legacy logic. - */ -class TabDataProvider -{ - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @var int - */ - private $contextEmployeeProfileId; - - /** - * @param int $contextEmployeeProfileId - * @param int $superAdminProfileId - */ - public function __construct($contextEmployeeProfileId, $superAdminProfileId) - { - $this->superAdminProfileId = $superAdminProfileId; - $this->contextEmployeeProfileId = $contextEmployeeProfileId; - } - - /** - * Gets viewable tabs for current context employee. - * - * @param int $languageId - * - * @return array - */ - public function getViewableTabsForContextEmployee($languageId) - { - return $this->getViewableTabs($this->contextEmployeeProfileId, $languageId); - } - - /** - * Gets tabs that given employee profile can view. - * - * @param int $profileId - * @param int $languageId - * - * @return array - */ - public function getViewableTabs($profileId, $languageId) - { - $viewableTabs = []; - - foreach (Tab::getTabs($languageId, 0) as $tab) { - if ($this->canAccessTab($profileId, $tab['id_tab'])) { - $viewableTabs[$tab['id_tab']] = [ - 'id_tab' => $tab['id_tab'], - 'name' => $tab['name'], - 'children' => [], - ]; - - foreach (Tab::getTabs($languageId, $tab['id_tab']) as $children) { - if ($this->canAccessTab($profileId, $children['id_tab'])) { - foreach (Tab::getTabs($languageId, $children['id_tab']) as $subchild) { - if ($this->canAccessTab($profileId, $subchild['id_tab'])) { - $viewableTabs[$tab['id_tab']]['children'][] = [ - 'id_tab' => $subchild['id_tab'], - 'name' => $subchild['name'], - ]; - } - } - } - } - } - } - - return $viewableTabs; - } - - /** - * Check if given profile can access a tab. - * - * @param int $profileId - * @param int $tabId - * @param string $accessLevel view, add, edit or delete - * - * @return bool - */ - private function canAccessTab($profileId, $tabId, $accessLevel = 'view') - { - if (!in_array($accessLevel, ['view', 'add', 'edit', 'delete'])) { - return false; - } - - if ($profileId == $this->superAdminProfileId) { - return true; - } - - $tabAccess = Profile::getProfileAccesses($profileId); - - if (isset($tabAccess[$tabId][$accessLevel])) { - return $tabAccess[$tabId][$accessLevel] === '1'; - } - - return false; - } -} diff --git a/src/Adapter/Tax/AbstractTaxHandler.php b/src/Adapter/Tax/AbstractTaxHandler.php deleted file mode 100644 index db4c17e4..00000000 --- a/src/Adapter/Tax/AbstractTaxHandler.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; -use PrestaShopException; -use Tax; - -/** - * Provides reusable methods for tax command/query handlers. - */ -abstract class AbstractTaxHandler -{ - /** - * Gets legacy Tax - * - * @param TaxId $taxId - * - * @return Tax - */ - protected function getTax(TaxId $taxId) - { - try { - $tax = new Tax($taxId->getValue()); - } catch (PrestaShopException $e) { - throw new TaxException('Failed to create new tax', 0, $e); - } - - if ($tax->id !== $taxId->getValue()) { - throw new TaxNotFoundException(sprintf('Tax with id "%s" was not found.', $taxId->getValue())); - } - - return $tax; - } -} diff --git a/src/Adapter/Tax/CommandHandler/AddTaxHandler.php b/src/Adapter/Tax/CommandHandler/AddTaxHandler.php deleted file mode 100644 index 45177706..00000000 --- a/src/Adapter/Tax/CommandHandler/AddTaxHandler.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\AddTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\AddTaxHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; -use PrestaShopException; -use Tax; - -/** - * Handles command which is responsible for tax editing - */ -final class AddTaxHandler extends AbstractTaxHandler implements AddTaxHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws TaxException - */ - public function handle(AddTaxCommand $command) - { - $tax = new Tax(); - - $tax->name = $command->getLocalizedNames(); - $tax->rate = $command->getRate(); - $tax->active = $command->isEnabled(); - - try { - if (false === $tax->validateFields(false) || false === $tax->validateFieldsLang(false)) { - throw new TaxException('Tax contains invalid field values'); - } - - if (!$tax->save()) { - throw new TaxException(sprintf('Cannot create tax with id "%s"', $tax->id)); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('Cannot create tax with id "%s"', $tax->id)); - } - - return new TaxId((int) $tax->id); - } -} diff --git a/src/Adapter/Tax/CommandHandler/BulkDeleteTaxHandler.php b/src/Adapter/Tax/CommandHandler/BulkDeleteTaxHandler.php deleted file mode 100644 index d41f4679..00000000 --- a/src/Adapter/Tax/CommandHandler/BulkDeleteTaxHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkDeleteTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\BulkDeleteTaxHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\DeleteTaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShopException; - -/** - * Handles command which deletes Taxes on bulk action using legacy object model - */ -final class BulkDeleteTaxHandler extends AbstractTaxHandler implements BulkDeleteTaxHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkDeleteTaxCommand $command) - { - foreach ($command->getTaxIds() as $taxId) { - $taxIdValue = $taxId->getValue(); - $tax = $this->getTax($taxId); - - try { - if (!$tax->delete()) { - throw new DeleteTaxException(sprintf('Cannot delete Tax object with id "%s"', $taxIdValue), DeleteTaxException::FAILED_BULK_DELETE); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('An error occurred when deleting Tax object with id "%s"', $taxIdValue)); - } - } - } -} diff --git a/src/Adapter/Tax/CommandHandler/BulkToggleTaxStatusHandler.php b/src/Adapter/Tax/CommandHandler/BulkToggleTaxStatusHandler.php deleted file mode 100644 index c4ece470..00000000 --- a/src/Adapter/Tax/CommandHandler/BulkToggleTaxStatusHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkToggleTaxStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\BulkToggleTaxStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\UpdateTaxException; -use PrestaShopException; - -/** - * Handles command which toggles taxes status on bulk action using legacy object model - */ -final class BulkToggleTaxStatusHandler extends AbstractTaxHandler implements BulkToggleTaxStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(BulkToggleTaxStatusCommand $command) - { - foreach ($command->getTaxIds() as $taxId) { - $tax = $this->getTax($taxId); - $tax->active = $command->getExpectedStatus(); - - try { - if (!$tax->save()) { - throw new UpdateTaxException(sprintf('Unable to toggle Tax with id "%s"', $taxId->getValue()), UpdateTaxException::FAILED_BULK_UPDATE_STATUS); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('An error occurred when updating Tax status with id "%s"', $taxId->getValue())); - } - } - } -} diff --git a/src/Adapter/Tax/CommandHandler/DeleteTaxHandler.php b/src/Adapter/Tax/CommandHandler/DeleteTaxHandler.php deleted file mode 100644 index e67e358a..00000000 --- a/src/Adapter/Tax/CommandHandler/DeleteTaxHandler.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\DeleteTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\DeleteTaxHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\DeleteTaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShopException; - -/** - * Handles command which deletes Tax using legacy object model - */ -final class DeleteTaxHandler extends AbstractTaxHandler implements DeleteTaxHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(DeleteTaxCommand $command) - { - $tax = $this->getTax($command->getTaxId()); - $taxIdValue = $command->getTaxId()->getValue(); - - try { - if (!$tax->delete()) { - throw new DeleteTaxException(sprintf('Cannot delete Tax object with id "%s"', $taxIdValue), DeleteTaxException::FAILED_DELETE); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('An error occurred when deleting Tax object with id "%s"', $taxIdValue)); - } - } -} diff --git a/src/Adapter/Tax/CommandHandler/EditTaxHandler.php b/src/Adapter/Tax/CommandHandler/EditTaxHandler.php deleted file mode 100644 index a55f3dba..00000000 --- a/src/Adapter/Tax/CommandHandler/EditTaxHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\EditTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\EditTaxHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShopException; -use Tax; - -/** - * Handles command which is responsible for tax editing - */ -final class EditTaxHandler extends AbstractTaxHandler implements EditTaxHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws TaxException - */ - public function handle(EditTaxCommand $command) - { - $tax = $this->getTax($command->getTaxId()); - - if (null !== $command->getLocalizedNames()) { - $tax->name = $command->getLocalizedNames(); - } - if (null !== $command->getRate()) { - $tax->rate = $command->getRate(); - } - if (null !== $command->isEnabled()) { - $tax->active = $command->isEnabled(); - } - - try { - if (false === $tax->validateFields(false) || false === $tax->validateFieldsLang(false)) { - throw new TaxException('Tax contains invalid field values'); - } - - if (!$tax->update()) { - throw new TaxException(sprintf('Cannot update tax with id "%s"', $tax->id)); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('Cannot update tax with id "%s"', $tax->id)); - } - } -} diff --git a/src/Adapter/Tax/CommandHandler/ToggleTaxStatusHandler.php b/src/Adapter/Tax/CommandHandler/ToggleTaxStatusHandler.php deleted file mode 100644 index 22f94124..00000000 --- a/src/Adapter/Tax/CommandHandler/ToggleTaxStatusHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\ToggleTaxStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler\ToggleTaxStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\UpdateTaxException; -use PrestaShopException; - -/** - * Handles command which toggles Tax status using legacy object model - */ -final class ToggleTaxStatusHandler extends AbstractTaxHandler implements ToggleTaxStatusHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(ToggleTaxStatusCommand $command) - { - $tax = $this->getTax($command->getTaxId()); - $taxIdValue = $command->getTaxId()->getValue(); - $tax->active = $command->getExpectedStatus(); - - try { - if (!$tax->save()) { - throw new UpdateTaxException(sprintf('Unable to toggle Tax with id "%s"', $taxIdValue), UpdateTaxException::FAILED_UPDATE_STATUS); - } - } catch (PrestaShopException $e) { - throw new TaxException(sprintf('An error occurred when enabling ETax with id "%s"', $taxIdValue)); - } - } -} diff --git a/src/Adapter/Tax/Ecotax/ProductEcotaxResetter.php b/src/Adapter/Tax/Ecotax/ProductEcotaxResetter.php deleted file mode 100644 index 2a2e8526..00000000 --- a/src/Adapter/Tax/Ecotax/ProductEcotaxResetter.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\Ecotax; - -use PrestaShop\PrestaShop\Core\Tax\Ecotax\ProductEcotaxResetterInterface; -use Product; - -/** - * Resets ecotax for products using legacy object model - */ -final class ProductEcotaxResetter implements ProductEcotaxResetterInterface -{ - /** - * {@inheritdoc} - */ - public function reset() - { - Product::resetEcoTax(); - } -} diff --git a/src/Adapter/Tax/QueryHandler/GetTaxForEditingHandler.php b/src/Adapter/Tax/QueryHandler/GetTaxForEditingHandler.php deleted file mode 100644 index 0e19942f..00000000 --- a/src/Adapter/Tax/QueryHandler/GetTaxForEditingHandler.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\Tax\AbstractTaxHandler; -use PrestaShop\PrestaShop\Core\Domain\Tax\Query\GetTaxForEditing; -use PrestaShop\PrestaShop\Core\Domain\Tax\QueryHandler\GetTaxForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\QueryResult\EditableTax; - -/** - * Handles query which gets tax for editing - */ -final class GetTaxForEditingHandler extends AbstractTaxHandler implements GetTaxForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetTaxForEditing $query) - { - $tax = $this->getTax($query->getTaxId()); - - return new EditableTax( - $query->getTaxId(), - $tax->name, - (float) $tax->rate, - (bool) $tax->active - ); - } -} diff --git a/src/Adapter/Tax/TaxRuleDataProvider.php b/src/Adapter/Tax/TaxRuleDataProvider.php deleted file mode 100644 index df9d5959..00000000 --- a/src/Adapter/Tax/TaxRuleDataProvider.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Tax; - -use Address; -use Context; -use Product; -use Tax; -use TaxManagerFactory; -use TaxRulesGroup; - -/** - * This class will provide data from DB / ORM about tax rules. - */ -class TaxRuleDataProvider -{ - /** - * Get all Tax Rules Groups. - * - * @param bool $only_active - * - * @return array TaxRulesGroup - */ - public function getTaxRulesGroups($only_active = true) - { - return TaxRulesGroup::getTaxRulesGroups($only_active); - } - - /** - * Get most used Tax. - * - * @return int - */ - public function getIdTaxRulesGroupMostUsed() - { - return Product::getIdTaxRulesGroupMostUsed(); - } - - /** - * Get all Tax Rules Groups with rates. - * - * @return array TaxRulesGroup - */ - public function getTaxRulesGroupWithRates() - { - $address = new Address(); - $address->id_country = (int) Context::getContext()->country->id; - $tax_rules_groups = $this->getTaxRulesGroups(); - $tax_rates = [ - 0 => [ - 'id_tax_rules_group' => 0, - 'rates' => [0], - 'computation_method' => 0, - ], - ]; - - foreach ($tax_rules_groups as $tax_rules_group) { - $id_tax_rules_group = (int) $tax_rules_group['id_tax_rules_group']; - $tax_calculator = TaxManagerFactory::getManager($address, $id_tax_rules_group)->getTaxCalculator(); - $tax_rates[$id_tax_rules_group] = [ - 'id_tax_rules_group' => $id_tax_rules_group, - 'rates' => [], - 'computation_method' => (int) $tax_calculator->computation_method, - ]; - - if (isset($tax_calculator->taxes) && count($tax_calculator->taxes)) { - foreach ($tax_calculator->taxes as $tax) { - $tax_rates[$id_tax_rules_group]['rates'][] = (float) $tax->rate; - } - } else { - $tax_rates[$id_tax_rules_group]['rates'][] = 0; - } - } - - return $tax_rates; - } - - /** - * Get product eco taxe rate. - * - * @return float tax - */ - public function getProductEcotaxRate() - { - return Tax::getProductEcotaxRate(); - } - - /** - * Gets a list of tax rules groups for choice type. - * - * @param bool $onlyActive if true, returns only active tax rules groups - * - * @return array - */ - public function getTaxRulesGroupChoices($onlyActive = true) - { - $taxRulesGroups = $this->getTaxRulesGroups($onlyActive); - $choices = []; - - foreach ($taxRulesGroups as $taxRulesGroup) { - $choices[$taxRulesGroup['name']] = $taxRulesGroup['id_tax_rules_group']; - } - - return $choices; - } -} diff --git a/src/Adapter/TaxRulesGroup/AbstractTaxRulesGroupHandler.php b/src/Adapter/TaxRulesGroup/AbstractTaxRulesGroupHandler.php deleted file mode 100644 index 0c39d236..00000000 --- a/src/Adapter/TaxRulesGroup/AbstractTaxRulesGroupHandler.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotDeleteTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; -use PrestaShopException; -use TaxRulesGroup; - -/** - * Provides common methods for tax rules group handlers - */ -abstract class AbstractTaxRulesGroupHandler -{ - /** - * Gets legacy TaxRuleGroup object - * - * @param TaxRulesGroupId $taxRulesGroupId - * - * @return TaxRulesGroup - * - * @throws TaxRulesGroupNotFoundException - */ - protected function getTaxRulesGroup(TaxRulesGroupId $taxRulesGroupId): TaxRulesGroup - { - $taxRulesGroupIdValue = $taxRulesGroupId->getValue(); - - try { - $taxRulesGroup = new TaxRulesGroup($taxRulesGroupIdValue); - } catch (PrestaShopException $e) { - throw new TaxRulesGroupNotFoundException(sprintf('Tax rules group with id "%s" was not found.', $taxRulesGroupIdValue)); - } - - if ($taxRulesGroup->id !== $taxRulesGroupIdValue) { - throw new TaxRulesGroupNotFoundException(sprintf('Tax rules group with id "%s" was not found.', $taxRulesGroupIdValue)); - } - - return $taxRulesGroup; - } - - /** - * Deletes legacy TaxRulesGroup - * - * @param TaxRulesGroup $taxRulesGroup - * - * @return bool - * - * @throws CannotDeleteTaxRulesGroupException - */ - protected function deleteTaxRulesGroup(TaxRulesGroup $taxRulesGroup): bool - { - try { - return $taxRulesGroup->delete(); - } catch (PrestaShopException $e) { - throw new CannotDeleteTaxRulesGroupException(sprintf('An error occurred when deleting tax rules group object with id "%s".', $taxRulesGroup->id)); - } - } - - /** - * Set legacy tax rules group status - * - * @param TaxRulesGroup $taxRulesGroup - * @param bool $newStatus - * - * @return bool - * - * @throws TaxRulesGroupException - */ - protected function setTaxRulesGroupStatus(TaxRulesGroup $taxRulesGroup, bool $newStatus) - { - $taxRulesGroup->active = $newStatus; - - try { - return $taxRulesGroup->save(); - } catch (PrestaShopException $e) { - throw new TaxRulesGroupException(sprintf('An error occurred when updating tax rules group status with id "%s"', $taxRulesGroup->id)); - } - } -} diff --git a/src/Adapter/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandler.php b/src/Adapter/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandler.php deleted file mode 100644 index 3a13d923..00000000 --- a/src/Adapter/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\TaxRulesGroup\AbstractTaxRulesGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkDeleteTaxRulesGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler\BulkDeleteTaxRulesGroupHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotBulkDeleteTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupException; - -/** - * Handles multiple tax rules group deletion - */ -final class BulkDeleteTaxRulesGroupHandler extends AbstractTaxRulesGroupHandler implements BulkDeleteTaxRulesGroupHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotBulkDeleteTaxRulesGroupException - */ - public function handle(BulkDeleteTaxRulesGroupCommand $command): void - { - $errors = []; - - foreach ($command->getTaxRulesGroupIds() as $taxRulesGroupId) { - try { - $taxRulesGroup = $this->getTaxRulesGroup($taxRulesGroupId); - - if (!$this->deleteTaxRulesGroup($taxRulesGroup)) { - $errors[] = $taxRulesGroup->id; - } - } catch (TaxRulesGroupException $e) { - $errors[] = $taxRulesGroupId->getValue(); - } - } - - if (!empty($errors)) { - throw new CannotBulkDeleteTaxRulesGroupException($errors, 'Failed to delete all tax rules groups without errors'); - } - } -} diff --git a/src/Adapter/TaxRulesGroup/CommandHandler/BulkSetTaxRulesGroupStatusHandler.php b/src/Adapter/TaxRulesGroup/CommandHandler/BulkSetTaxRulesGroupStatusHandler.php deleted file mode 100644 index 9a27e228..00000000 --- a/src/Adapter/TaxRulesGroup/CommandHandler/BulkSetTaxRulesGroupStatusHandler.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\TaxRulesGroup\AbstractTaxRulesGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkSetTaxRulesGroupStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler\BulkToggleTaxRulesGroupStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotBulkUpdateTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupException; - -/** - * Handles toggling of multiple tax rules groups statuses - */ -final class BulkSetTaxRulesGroupStatusHandler extends AbstractTaxRulesGroupHandler implements BulkToggleTaxRulesGroupStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotBulkUpdateTaxRulesGroupException - */ - public function handle(BulkSetTaxRulesGroupStatusCommand $command): void - { - $errors = []; - - foreach ($command->getTaxRulesGroupIds() as $taxRuleGroupId) { - try { - $taxRuleGroup = $this->getTaxRulesGroup($taxRuleGroupId); - - if (!$this->setTaxRulesGroupStatus($taxRuleGroup, $command->getExpectedStatus())) { - $errors[] = $taxRuleGroup->id; - } - } catch (TaxRulesGroupException $e) { - $errors[] = $taxRuleGroupId->getValue(); - } - } - - if (!empty($errors)) { - throw new CannotBulkUpdateTaxRulesGroupException($errors, 'Failed to set all tax rules groups statuses without errors'); - } - } -} diff --git a/src/Adapter/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandler.php b/src/Adapter/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandler.php deleted file mode 100644 index af80ae7f..00000000 --- a/src/Adapter/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandler.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\TaxRulesGroup\AbstractTaxRulesGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\DeleteTaxRulesGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler\DeleteTaxRulesGroupHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotDeleteTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupNotFoundException; - -/** - * Handles deletion of single tax rules group - */ -final class DeleteTaxRulesGroupHandler extends AbstractTaxRulesGroupHandler implements DeleteTaxRulesGroupHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotDeleteTaxRulesGroupException - * @throws TaxRulesGroupNotFoundException - */ - public function handle(DeleteTaxRulesGroupCommand $command): void - { - $taxRulesGroup = $this->getTaxRulesGroup($command->getTaxRulesGroupId()); - - if (!$this->deleteTaxRulesGroup($taxRulesGroup)) { - throw new CannotDeleteTaxRulesGroupException(sprintf('Cannot delete tax rules group object with id "%s".', $taxRulesGroup->id)); - } - } -} diff --git a/src/Adapter/TaxRulesGroup/CommandHandler/SetTaxRulesGroupStatusHandler.php b/src/Adapter/TaxRulesGroup/CommandHandler/SetTaxRulesGroupStatusHandler.php deleted file mode 100644 index 2fb82ace..00000000 --- a/src/Adapter/TaxRulesGroup/CommandHandler/SetTaxRulesGroupStatusHandler.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\TaxRulesGroup\AbstractTaxRulesGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\SetTaxRulesGroupStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler\ToggleTaxRulesGroupStatusHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotUpdateTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupNotFoundException; - -/** - * Handles tax rules group status toggling - */ -final class SetTaxRulesGroupStatusHandler extends AbstractTaxRulesGroupHandler implements ToggleTaxRulesGroupStatusHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws CannotUpdateTaxRulesGroupException - * @throws TaxRulesGroupException - * @throws TaxRulesGroupNotFoundException - */ - public function handle(SetTaxRulesGroupStatusCommand $command): void - { - $taxRulesGroup = $this->getTaxRulesGroup($command->getTaxRulesGroupId()); - - if (!$this->setTaxRulesGroupStatus($taxRulesGroup, $command->getExpectedStatus())) { - throw new CannotUpdateTaxRulesGroupException(sprintf('Unable to toggle tax rules group status with id "%s"', $taxRulesGroup->id), CannotUpdateTaxRulesGroupException::FAILED_TOGGLE_STATUS); - } - } -} diff --git a/src/Adapter/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandler.php b/src/Adapter/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandler.php deleted file mode 100644 index 2795e5c4..00000000 --- a/src/Adapter/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandler.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\TaxRulesGroup\QueryHandler; - -use PrestaShop\PrestaShop\Adapter\TaxRulesGroup\AbstractTaxRulesGroupHandler; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Query\GetTaxRulesGroupForEditing; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryHandler\GetTaxRulesGroupForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryResult\EditableTaxRulesGroup; - -/** - * Handles query which gets tax rules group for editing - */ -final class GetTaxRulesGroupForEditingHandler extends AbstractTaxRulesGroupHandler implements GetTaxRulesGroupForEditingHandlerInterface -{ - /** - * {@inheritdoc} - * - * @throws TaxRulesGroupNotFoundException - */ - public function handle(GetTaxRulesGroupForEditing $query): EditableTaxRulesGroup - { - $taxRulesGroupId = $query->getTaxRulesGroupId(); - $taxRulesGroup = $this->getTaxRulesGroup($taxRulesGroupId); - - return new EditableTaxRulesGroup($taxRulesGroupId, (bool) $taxRulesGroup->active); - } -} diff --git a/src/Adapter/Theme/ThemeMultiStoreSettingsFormDataProvider.php b/src/Adapter/Theme/ThemeMultiStoreSettingsFormDataProvider.php deleted file mode 100644 index 4af534e5..00000000 --- a/src/Adapter/Theme/ThemeMultiStoreSettingsFormDataProvider.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Theme; - -use Configuration; -use PrestaShop\PrestaShop\Core\Form\MultiStoreSettingsFormDataProviderInterface; - -/** - * This class is used to retrieve data which is used in settings form to render multi store fields - its used in - * Theme & logo page. - * - * @internal - */ -final class ThemeMultiStoreSettingsFormDataProvider implements MultiStoreSettingsFormDataProviderInterface -{ - /** - * @var bool - */ - private $isShopFeatureUsed; - - /** - * @var bool - */ - private $isSingleShopContext; - - /** - * @param bool $isShopFeatureUsed - * @param bool $isSingleShopContext - */ - public function __construct( - $isShopFeatureUsed, - $isSingleShopContext - ) { - $this->isShopFeatureUsed = $isShopFeatureUsed; - $this->isSingleShopContext = $isSingleShopContext; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - $isValidShopRestriction = $this->isShopFeatureUsed && $this->isSingleShopContext; - - $isHeaderLogoRestricted = $this->doesConfigurationExistInSingleShopContext('PS_LOGO'); - $isMailRestricted = $this->doesConfigurationExistInSingleShopContext('PS_LOGO_MAIL'); - $isInvoiceLogoRestricted = $this->doesConfigurationExistInSingleShopContext('PS_LOGO_INVOICE'); - $isFaviconRestricted = $this->doesConfigurationExistInSingleShopContext('PS_FAVICON'); - - return [ - 'header_logo_is_restricted_to_shop' => $isValidShopRestriction && $isHeaderLogoRestricted, - 'mail_logo_is_restricted_to_shop' => $isValidShopRestriction && $isMailRestricted, - 'invoice_logo_is_restricted_to_shop' => $isValidShopRestriction && $isInvoiceLogoRestricted, - 'favicon_is_restricted_to_shop' => $isValidShopRestriction && $isFaviconRestricted, - ]; - } - - /** - * Checks if the configuration exists for specific shop context. - * - * @param $configurationKey - * - * @return bool - */ - private function doesConfigurationExistInSingleShopContext($configurationKey) - { - return Configuration::isOverridenByCurrentContext($configurationKey); - } -} diff --git a/src/Adapter/Tools.php b/src/Adapter/Tools.php deleted file mode 100644 index 544e1ce3..00000000 --- a/src/Adapter/Tools.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Adapter\File\HtaccessFileGenerator; -use Tools as LegacyTools; - -/** - * This adapter will complete the new architecture Tools. - * - * Please put only wrappers and equivalents from Legacy \Tools class. - * (only for this purpose, this is not here to put new utils functions). - */ -class Tools -{ - /** - * Return the friendly url from the provided string. - * - * @deprecated use linkRewrite - * - * @param string $str - * @param bool $utf8Decode (deprecated) - * - * @return string - */ - public function link_rewrite($str, $utf8Decode = null) - { - return $this->linkRewrite($str, $utf8Decode); - } - - /** - * Return the friendly url from the provided string. - * - * @param string $str - * @param bool $utf8Decode (deprecated) - * - * @return string - */ - public function linkRewrite($str, $utf8Decode = null) - { - if ($utf8Decode !== null) { - LegacyTools::displayParameterAsDeprecated('utf8_decode'); - } - - return LegacyTools::str2url($str); - } - - /** - * Polyfill for bcadd if BC Math extension is not installed. - * - * @deprecated since 1.7.2.2 - Use PrestaShop\Decimal\Number instead - */ - public function bcadd($left_operand, $right_operand, $scale = null) - { - $result = (new Number((string) $left_operand)) - ->plus(new Number((string) $right_operand)); - - if (null === $scale) { - return (string) $result; - } - - return (string) $result->toPrecision($scale); - } - - /** - * @param string $html - * @param string|null $uri_unescape - * @param bool $allow_style - * - * @return string - */ - public function purifyHTML($html, $uri_unescape = null, $allow_style = false) - { - return LegacyTools::purifyHTML($html, $uri_unescape, $allow_style); - } - - /** - * @see LegacyTools::refreshCACertFile() - */ - public function refreshCaCertFile() - { - LegacyTools::refreshCACertFile(); - } - - /** - * @see LegacyTools::generateRobotsFile() - * - * @return bool - */ - public function generateHtaccess() - { - return LegacyTools::generateHtaccess(); - } - - /** - * @see HtaccessFileGenerator::generateFile() - * - * @param bool $disableMultiView enable/disable Multiviews option - * - * @return bool - */ - private function generateHtaccessOnMultiViews($disableMultiView = false) - { - return LegacyTools::generateHtaccess( - null, - null, - null, - '', - $disableMultiView - ); - } - - /** - * @see HtaccessFileGenerator::generateFile() - * - * @return bool - */ - public function generateHtaccessWithMultiViews() - { - return LegacyTools::generateHtaccess( - null, - null, - null, - '', - true - ); - } - - /** - * @see HtaccessFileGenerator::generateFile() - * - * @return bool - */ - public function generateHtaccessWithoutMultiViews() - { - return LegacyTools::generateHtaccess( - null, - null, - null, - '', - false - ); - } - - /** - * returns the rounded value of $value to specified precision, according to your configuration;. - * - * @note : PHP 5.3.0 introduce a 3rd parameter mode in round function - * - * @param float $value - * @param int $precision - * - * @return float - */ - public function round($value, $precision = 0, $round_mode = null) - { - return LegacyTools::ps_round($value, $precision, $round_mode); - } - - /** - * Return domain name according to configuration and depending on ssl activation. - * - * @param bool $http if true, return domain name with protocol - * @param bool $entities if true, convert special chars to HTML entities - * - * @return string domain - */ - public function getShopDomainSsl($http = false, $entities = false) - { - return LegacyTools::getShopDomainSsl($http, $entities); - } - - /** - * Checks if apache mod exists for mod_rewrite or the server has HTTP_MOD_REWRITE enabled. - * - * @return bool - */ - public function isModRewriteActive() - { - return LegacyTools::modRewriteActive(); - } - - /** - * Copy content. - * - * @param string $source - * @param string $destination - * @param resource|null $streamContext - * - * @return bool|int - */ - public function copy($source, $destination, $streamContext = null) - { - return LegacyTools::copy($source, $destination, $streamContext); - } - - /** - * Sanitize a string. - * - * @param string $value - * @param bool $allowHtml - * - * @return string - */ - public function sanitize($value, $allowHtml = false) - { - return LegacyTools::safeOutput($value, $allowHtml); - } - - /** - * Get a valid image URL to use from BackOffice. - * - * @param string $fileName image file name - * @param bool $escapeHtmlEntities if true - escape html entities on file name argument - * - * @return string image URL - */ - public function getAdminImageUrl($fileName, $escapeHtmlEntities = false) - { - return LegacyTools::getAdminImageUrl($fileName, $escapeHtmlEntities); - } - - /** - * Delete unicode class from regular expression patterns. - * - * @param string $pattern - * - * @return string pattern - */ - public function cleanNonUnicodeSupport($pattern) - { - return LegacyTools::cleanNonUnicodeSupport($pattern); - } - - /** - * @see LegacyTools::displayDate() - * - * @return string - * - * @throws \PrestaShopException - */ - public function displayDate($date, $id_lang = null, $full = false, $separator = null) - { - return LegacyTools::displayDate($date, $id_lang, $full, $separator); - } - - /** - * @see LegacyTools::truncateString() - * - * @return bool|string - */ - public function truncateString($text, $length = 120, $options = []) - { - return LegacyTools::truncateString($text, $length, $options); - } -} diff --git a/src/Adapter/Translations/TranslationRouteFinder.php b/src/Adapter/Translations/TranslationRouteFinder.php deleted file mode 100644 index b75f803d..00000000 --- a/src/Adapter/Translations/TranslationRouteFinder.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Translations; - -use Link; -use Module; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepositoryInterface; -use PrestaShopBundle\Exception\InvalidModuleException; -use PrestaShopBundle\Service\TranslationService; -use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\PropertyAccess\PropertyAccess; - -/** - * Class TranslationRouteFinder finds the correct route for translations. - */ -class TranslationRouteFinder -{ - /** - * Mails translations type. - */ - const MAILS = 'mails'; - - /** - * Modules translations type. - */ - const MODULES = 'modules'; - - /** - * Email body translations type. - */ - const BODY = 'body'; - - /** - * Themes translations type. - */ - const THEMES = 'themes'; - - /** - * @var TranslationService - */ - private $translationService; - - /** - * @var Link - */ - private $link; - - /** - * @var ModuleRepositoryInterface - */ - private $moduleRepository; - - /** - * @param TranslationService $translationService - * @param Link $link - * @param ModuleRepositoryInterface $moduleRepository - */ - public function __construct( - TranslationService $translationService, - Link $link, - ModuleRepositoryInterface $moduleRepository - ) { - $this->translationService = $translationService; - $this->link = $link; - $this->moduleRepository = $moduleRepository; - } - - /** - * Finds the correct translation route out of given query. - * - * @param ParameterBag $query - * - * @return string - */ - public function findRoute(ParameterBag $query) - { - $routeProperties = $query->get('form'); - $propertyAccessor = PropertyAccess::createPropertyAccessor(); - $route = 'admin_international_translation_overview'; - - switch ($propertyAccessor->getValue($routeProperties, '[translation_type]')) { - case self::MAILS: - if (self::BODY === $propertyAccessor->getValue($routeProperties, '[email_content_type]')) { - $language = $propertyAccessor->getValue($routeProperties, '[language]'); - $route = $this->link->getAdminLink( - 'AdminTranslations', - true, - [], - [ - 'lang' => $language, - 'type' => self::MAILS, - 'selected-emails' => self::BODY, - 'selected-theme' => $propertyAccessor->getValue($routeProperties, '[theme]'), - 'locale' => $this->translationService->langToLocale($language), - ] - ); - } - - break; - - case self::MODULES: - $moduleName = $propertyAccessor->getValue($routeProperties, '[module]'); - - // If module is not using the new translation system - - // generate a legacy link for it - if (!$this->isModuleUsingNewTranslationSystem($moduleName)) { - $language = $propertyAccessor->getValue($routeProperties, '[language]'); - $route = $this->link->getAdminLink( - 'AdminTranslations', - true, - [], - [ - 'type' => self::MODULES, - 'module' => $moduleName, - 'lang' => $language, - ] - ); - } - - break; - } - - return $route; - } - - /** - * Finds parameters for translation route out of given query. - * - * @param ParameterBag $query - * - * @return array of route parameters - */ - public function findRouteParameters(ParameterBag $query) - { - $routeProperties = $query->get('form'); - $propertyAccessor = PropertyAccess::createPropertyAccessor(); - $language = $propertyAccessor->getValue($routeProperties, '[language]'); - - $parameters = [ - 'lang' => $language, - 'type' => $propertyAccessor->getValue($routeProperties, '[translation_type]'), - 'locale' => $this->translationService->langToLocale($language), - ]; - - switch ($propertyAccessor->getValue($routeProperties, '[translation_type]')) { - case self::THEMES: - $parameters['selected'] = $propertyAccessor->getValue($routeProperties, '[theme]'); - - break; - - case self::MAILS: - $emailContentType = $propertyAccessor->getValue($routeProperties, '[email_content_type]'); - - if (self::BODY === $emailContentType) { - $parameters = []; - } - - break; - - case self::MODULES: - $moduleName = $propertyAccessor->getValue($routeProperties, '[module]'); - $parameters['selected'] = $moduleName; - - if (!$this->isModuleUsingNewTranslationSystem($moduleName)) { - $parameters = []; - } - - break; - } - - return $parameters; - } - - /** - * Checks if module is using the new translation system. - * - * @param string $moduleName - * - * @return bool - */ - private function isModuleUsingNewTranslationSystem($moduleName) - { - $module = $this->moduleRepository->getInstanceByName($moduleName); - - if (!($module instanceof Module)) { - throw new InvalidModuleException($moduleName); - } - - return $module->isUsingNewTranslationSystem(); - } -} diff --git a/src/Adapter/Twig/LocaleExtension.php b/src/Adapter/Twig/LocaleExtension.php deleted file mode 100644 index 67f4d8e0..00000000 --- a/src/Adapter/Twig/LocaleExtension.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Twig; - -use DateTime; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFunction; - -/** - * Provides helper functions in Twig for formatting data using context locale - */ -final class LocaleExtension extends AbstractExtension -{ - /** - * @var string - */ - private $contextDateFormatLite; - - /** - * @param string $contextDateFormatLite - */ - public function __construct($contextDateFormatLite) - { - $this->contextDateFormatLite = $contextDateFormatLite; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new Twig_SimpleFunction( - 'format_date', - function ($date) { - return (new DateTime($date))->format($this->contextDateFormatLite); - } - ), - ]; - } -} diff --git a/src/Adapter/Upload/UploadQuotaConfiguration.php b/src/Adapter/Upload/UploadQuotaConfiguration.php deleted file mode 100644 index a0411c8f..00000000 --- a/src/Adapter/Upload/UploadQuotaConfiguration.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Upload; - -use Exception; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Manages the configuration data about upload quota options. - */ -class UploadQuotaConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'max_size_attached_files' => $this->configuration->get('PS_ATTACHMENT_MAXIMUM_SIZE'), - 'max_size_downloadable_product' => $this->configuration->get('PS_LIMIT_UPLOAD_FILE_VALUE'), - 'max_size_product_image' => $this->configuration->get('PS_LIMIT_UPLOAD_IMAGE_VALUE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - $errors = $this->updateFileUploadConfiguration($configuration); - } - - return $errors; - } - - /** - * Update the file upload limit if possible. - * - * @return array the errors list during the update operation - * - * @throws Exception - */ - private function updateFileUploadConfiguration(array $configuration) - { - $uploadMaxSize = (int) str_replace('M', '', ini_get('upload_max_filesize')); - $sizes = [ - 'max_size_attached_files' => $uploadMaxSize, - 'max_size_downloadable_product' => (int) str_replace('M', '', ini_get('post_max_size')), - 'max_size_product_image' => $uploadMaxSize, - ]; - - $errors = []; - foreach ($configuration as $configurationKey => $configurationValue) { - if (array_key_exists($configurationKey, $this->getConfiguration())) { - if ((int) $configurationValue > $sizes[$configurationKey]) { - $errors[] = [ - 'key' => 'The limit chosen is larger than the server\'s maximum upload limit. Please increase the limits of your server.', - 'domain' => 'Admin.Advparameters.Notification', - 'parameters' => [], - ]; - } - - $this->configuration->set( - $this->getConfigurationKey($configurationKey), - max((int) $configurationValue, 1) - ); - } - } - - return $errors; - } - - /** - * Map array key to the related configuration property. - * - * @param string the array key - * - * @return string the related configuration key - */ - private function getConfigurationKey($key) - { - $properties = [ - 'max_size_attached_files' => 'PS_ATTACHMENT_MAXIMUM_SIZE', - 'max_size_downloadable_product' => 'PS_LIMIT_UPLOAD_FILE_VALUE', - 'max_size_product_image' => 'PS_LIMIT_UPLOAD_IMAGE_VALUE', - ]; - - return $properties[$key]; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['max_size_attached_files'], - $configuration['max_size_downloadable_product'], - $configuration['max_size_product_image'] - ); - } -} diff --git a/src/Adapter/Validate.php b/src/Adapter/Validate.php deleted file mode 100644 index c4c51427..00000000 --- a/src/Adapter/Validate.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter; - -use Validate as ValidateLegacy; - -/** - * Adapter for Validate Legacy class. - */ -class Validate -{ - /** - * @param mixed $way - * - * @return bool - */ - public static function isOrderWay($way) - { - return ValidateLegacy::isOrderWay($way); - } - - /** - * @param mixed $order - * - * @return bool - */ - public static function isOrderBy($order) - { - return ValidateLegacy::isOrderBy($order); - } - - /** - * @param mixed $date - * - * @return bool - */ - public static function isDate($date) - { - return ValidateLegacy::isDate($date); - } - - /** - * Check if HTML content is clean. - * - * @param string $html - * @param bool $allowIframe - * - * @return bool - */ - public function isCleanHtml($html, $allowIframe = false) - { - return ValidateLegacy::isCleanHtml($html, $allowIframe); - } - - /** - * Check for module name validity. - * - * @param string $name Module name to validate - * - * @return bool - */ - public function isModuleName($name) - { - return ValidateLegacy::isModuleName($name); - } - - /** - * Check if object has been correctly loaded. - * - * @param object $object Object to validate - * - * @return bool Validity is ok or not - */ - public static function isLoadedObject($object) - { - return ValidateLegacy::isLoadedObject($object); - } - - /** - * Check for Language Iso Code. - * - * @param string $isoCode - * - * @return bool - */ - public function isLangIsoCode($isoCode) - { - return ValidateLegacy::isLangIsoCode($isoCode); - } - - /** - * Check for an integer validity (unsigned). - * - * @param int $value Integer to validate - * - * @return bool - */ - public function isUnsignedInt($value) - { - return ValidateLegacy::isUnsignedInt($value); - } - - /** - * Check for a rewritten url validity. - * - * @param string $value - * - * @return bool - */ - public function isLinkRewrite($value) - { - return ValidateLegacy::isLinkRewrite($value); - } -} diff --git a/src/Adapter/Warehouse/WarehouseDataProvider.php b/src/Adapter/Warehouse/WarehouseDataProvider.php deleted file mode 100644 index 8086f372..00000000 --- a/src/Adapter/Warehouse/WarehouseDataProvider.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Warehouse; - -use Warehouse; -use WarehouseProductLocation; - -/** - * This class will provide data from DB / ORM about Warehouse. - */ -class WarehouseDataProvider -{ - /** - * Get product warehouses. - * - * @param int $id_product - * - * @return array Warehouses - */ - public function getWarehouseProductLocations($id_product) - { - $collection = WarehouseProductLocation::getCollection($id_product); - - return $collection->getResults(); - } - - /** - * Get all warehouses. - * - * @param bool $ignore_shop Optional, false by default - Allows to get only the warehouses that are associated to one/some shops (@see $id_shop) - * @param int $id_shop optional, Context::shop::Id by default - Allows to define a specific shop to filter - * - * @return array Warehouses (ID, reference/name concatenated) - */ - public function getWarehouses($ignore_shop = false, $id_shop = null) - { - return Warehouse::getWarehouses($ignore_shop, $id_shop); - } - - /** - * For a given product and warehouse, gets the product warehouse data. - * - * @param int $id_product - * @param int $id_product_attribute - * @param int $id_warehouse - * - * @return array - */ - public function getWarehouseProductLocationData($id_product, $id_product_attribute, $id_warehouse) - { - $location = WarehouseProductLocation::getProductLocation($id_product, $id_product_attribute, $id_warehouse); - // for 'activated', we test if $location is ===false or ==="", that's the only difference to know it... - return ['location' => $location, 'activated' => ($location !== false), 'product_id' => $id_product]; - } -} diff --git a/src/Adapter/Webservice/CommandHandler/AbstractWebserviceKeyHandler.php b/src/Adapter/Webservice/CommandHandler/AbstractWebserviceKeyHandler.php deleted file mode 100644 index 486468ed..00000000 --- a/src/Adapter/Webservice/CommandHandler/AbstractWebserviceKeyHandler.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice\CommandHandler; - -use PrestaShop\PrestaShop\Adapter\Domain\AbstractObjectModelHandler; -use Tools; -use WebserviceKey; - -/** - * Encapsulates common legacy behavior for adding/editing WebserviceKey - * - * @internal - */ -abstract class AbstractWebserviceKeyHandler extends AbstractObjectModelHandler -{ - /** - * @param WebserviceKey $webserviceKey - * @param array $permissions - */ - protected function setPermissionsForWebserviceKey(WebserviceKey $webserviceKey, array $permissions) - { - Tools::generateHtaccess(); - - $legacyPermissionsStructure = []; - - foreach ($permissions as $permission => $resources) { - foreach ($resources as $resource) { - $legacyPermissionsStructure[$resource][$permission] = 'on'; - } - } - - WebserviceKey::setPermissionForAccount($webserviceKey->id, $legacyPermissionsStructure); - } -} diff --git a/src/Adapter/Webservice/CommandHandler/AddWebserviceKeyHandler.php b/src/Adapter/Webservice/CommandHandler/AddWebserviceKeyHandler.php deleted file mode 100644 index 69dcc28b..00000000 --- a/src/Adapter/Webservice/CommandHandler/AddWebserviceKeyHandler.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\AddWebserviceKeyCommand; -use PrestaShop\PrestaShop\Core\Domain\Webservice\CommandHandler\AddWebserviceKeyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\DuplicateWebserviceKeyException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\Key; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; -use WebserviceKey; - -/** - * Handles command that adds new webservice key for PrestaShop's API - * - * @internal - */ -final class AddWebserviceKeyHandler extends AbstractWebserviceKeyHandler implements AddWebserviceKeyHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(AddWebserviceKeyCommand $command) - { - $this->assertWebserviceKeyIsNotDuplicate($command->getKey()); - - $webserviceKey = $this->createLegacyWebserviceKeyFromCommand($command); - - $this->associateWithShops($webserviceKey, $command->getAssociatedShops()); - $this->setPermissionsForWebserviceKey($webserviceKey, $command->getPermissions()); - - return new WebserviceKeyId((int) $webserviceKey->id); - } - - /** - * Asserts that new webservice key does not duplicate already existing keys - * - * @param Key $key - */ - private function assertWebserviceKeyIsNotDuplicate(Key $key) - { - if (WebserviceKey::keyExists($key->getValue())) { - throw new DuplicateWebserviceKeyException(sprintf('Webservice key "%s" already exists', $key->getValue())); - } - } - - /** - * @param AddWebserviceKeyCommand $command - * - * @return WebserviceKey - */ - private function createLegacyWebserviceKeyFromCommand(AddWebserviceKeyCommand $command) - { - $webserviceKey = new WebserviceKey(); - $webserviceKey->key = $command->getKey()->getValue(); - $webserviceKey->description = $command->getDescription(); - $webserviceKey->active = $command->getStatus(); - - if (false === $webserviceKey->validateFields(false)) { - throw new WebserviceConstraintException('One or more fields are invalid in WebserviceKey'); - } - - if (false === $webserviceKey->add()) { - throw new WebserviceException('Failed to add WebserviceKey'); - } - - return $webserviceKey; - } -} diff --git a/src/Adapter/Webservice/CommandHandler/EditWebserviceKeyHandler.php b/src/Adapter/Webservice/CommandHandler/EditWebserviceKeyHandler.php deleted file mode 100644 index fc21d49b..00000000 --- a/src/Adapter/Webservice/CommandHandler/EditWebserviceKeyHandler.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\EditWebserviceKeyCommand; -use PrestaShop\PrestaShop\Core\Domain\Webservice\CommandHandler\EditWebserviceKeyHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceKeyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; -use WebserviceKey; - -/** - * Handles command that edits legacy WebserviceKey - * - * @internal - */ -final class EditWebserviceKeyHandler extends AbstractWebserviceKeyHandler implements EditWebserviceKeyHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(EditWebserviceKeyCommand $command) - { - $webserviceKey = $this->getLegacyWebserviceKey($command->getWebserviceKeyId()); - - $this->updateLegacyWebserviceKeyWithCommandData($webserviceKey, $command); - } - - /** - * @param WebserviceKeyId $webserviceKeyId - * - * @return WebserviceKey - */ - private function getLegacyWebserviceKey(WebserviceKeyId $webserviceKeyId) - { - $webserviceKey = new WebserviceKey($webserviceKeyId->getValue()); - - if ($webserviceKeyId->getValue() !== $webserviceKey->id) { - throw new WebserviceKeyNotFoundException(sprintf('Webservice key with id "%s was not found', $webserviceKeyId->getValue())); - } - - return $webserviceKey; - } - - /** - * @param WebserviceKey $webserviceKey - * @param EditWebserviceKeyCommand $command - */ - private function updateLegacyWebserviceKeyWithCommandData( - WebserviceKey $webserviceKey, - EditWebserviceKeyCommand $command - ) { - if (null !== $command->getKey()) { - $webserviceKey->key = $command->getKey()->getValue(); - } - - if (null !== $command->getDescription()) { - $webserviceKey->description = $command->getDescription(); - } - - if (null !== $command->getStatus()) { - $webserviceKey->active = $command->getStatus(); - } - - if (false === $webserviceKey->validateFields(false)) { - throw new WebserviceConstraintException('One or more fields are invalid in WebserviceKey'); - } - - if (false === $webserviceKey->update()) { - throw new WebserviceException(sprintf('Failed to update WebserviceKey with id "%s"', $webserviceKey->id)); - } - - if (null !== $command->getShopAssociation()) { - $this->associateWithShops($webserviceKey, $command->getShopAssociation()); - } - - if (null !== $command->getPermissions()) { - $this->setPermissionsForWebserviceKey($webserviceKey, $command->getPermissions()); - } - } -} diff --git a/src/Adapter/Webservice/QueryHandler/GetWebserviceKeyForEditingHandler.php b/src/Adapter/Webservice/QueryHandler/GetWebserviceKeyForEditingHandler.php deleted file mode 100644 index 807d7ce4..00000000 --- a/src/Adapter/Webservice/QueryHandler/GetWebserviceKeyForEditingHandler.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceKeyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Query\GetWebserviceKeyForEditing; -use PrestaShop\PrestaShop\Core\Domain\Webservice\QueryHandler\GetWebserviceKeyForEditingHandlerInterface; -use PrestaShop\PrestaShop\Core\Domain\Webservice\QueryResult\EditableWebserviceKey; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; -use WebserviceKey; - -/** - * Handles command that gets webservice key data for editing - * - * @internal - */ -final class GetWebserviceKeyForEditingHandler implements GetWebserviceKeyForEditingHandlerInterface -{ - /** - * {@inheritdoc} - */ - public function handle(GetWebserviceKeyForEditing $query) - { - $webserviceKey = $this->getLegacyWebserviceKeyObject($query->getWebserviceKeyId()); - - return new EditableWebserviceKey( - $query->getWebserviceKeyId(), - $webserviceKey->key, - $webserviceKey->description, - $webserviceKey->active, - WebserviceKey::getPermissionForAccount($webserviceKey->key), - $webserviceKey->getAssociatedShops() - ); - } - - /** - * @param WebserviceKeyId $webserviceKeyId - * - * @return WebserviceKey - */ - private function getLegacyWebserviceKeyObject(WebserviceKeyId $webserviceKeyId) - { - $webserviceKey = new WebserviceKey($webserviceKeyId->getValue()); - - if ($webserviceKey->id !== $webserviceKeyId->getValue()) { - throw new WebserviceKeyNotFoundException(sprintf('Webservice key with id "%s" was not found', $webserviceKeyId)); - } - - return $webserviceKey; - } -} diff --git a/src/Adapter/Webservice/WebserviceConfiguration.php b/src/Adapter/Webservice/WebserviceConfiguration.php deleted file mode 100644 index 33f53336..00000000 --- a/src/Adapter/Webservice/WebserviceConfiguration.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; - -/** - * Manages the configuration data about upload quota options. - */ -final class WebserviceConfiguration implements DataConfigurationInterface -{ - /** - * @var Configuration - */ - private $configuration; - - /** - * @param Configuration $configuration - */ - public function __construct(Configuration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_webservice' => $this->configuration->getBoolean('PS_WEBSERVICE'), - 'enable_cgi' => $this->configuration->getBoolean('PS_WEBSERVICE_CGI_HOST'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_WEBSERVICE', $configuration['enable_webservice']); - $this->configuration->set('PS_WEBSERVICE_CGI_HOST', $configuration['enable_cgi']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - $enableWebserviceisValid = (isset($configuration['enable_webservice']) && (is_bool($configuration['enable_webservice']))); - $enableCGI = (isset($configuration['enable_webservice']) && (is_bool($configuration['enable_webservice']))); - - return $enableWebserviceisValid && $enableCGI; - } -} diff --git a/src/Adapter/Webservice/WebserviceKeyEraser.php b/src/Adapter/Webservice/WebserviceKeyEraser.php deleted file mode 100644 index c5e1e504..00000000 --- a/src/Adapter/Webservice/WebserviceKeyEraser.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice; - -use PrestaShopCollection; -use WebserviceKey; - -/** - * Class WebserviceKeyEraser is responsible for deleting the records from webservice account table. - */ -final class WebserviceKeyEraser -{ - /** - * Erase given webservice accounts. - * - * @param int[] $webServiceKeyIds - * - * @return string[] - array of errors. If array is empty then erase operation succeeded. - * - * @throws \PrestaShopException - */ - public function erase(array $webServiceKeyIds) - { - $errors = []; - - if (empty($webServiceKeyIds)) { - $errors[] = [ - 'key' => 'You must select at least one element to delete.', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Error', - ]; - - return $errors; - } - - $webserviceKeys = new PrestaShopCollection(WebserviceKey::class); - $webserviceKeys->where('id_webservice_account', 'in', $webServiceKeyIds); - - /** @var WebserviceKey $webserviceKey */ - foreach ($webserviceKeys->getResults() as $webserviceKey) { - if (!$webserviceKey->delete()) { - $errors[] = [ - 'key' => 'Can\'t delete #%id%', - 'parameters' => [ - '%id%' => $webserviceKey->id, - ], - 'domain' => 'Admin.Notifications.Error', - ]; - - continue; - } - } - - return $errors; - } -} diff --git a/src/Adapter/Webservice/WebserviceKeyStatusModifier.php b/src/Adapter/Webservice/WebserviceKeyStatusModifier.php deleted file mode 100644 index 880c59e3..00000000 --- a/src/Adapter/Webservice/WebserviceKeyStatusModifier.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Adapter\Webservice; - -use Symfony\Component\Translation\TranslatorInterface; -use Validate; -use WebserviceKey; - -/** - * Class WebserviceKeyStatusModifier is responsible for modifying webservice account status. - */ -final class WebserviceKeyStatusModifier -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * WebserviceKeyStatusModifier constructor. - * - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * Toggles status for webservice key entity. - * - * @param int $columnId - an id which identifies the required entity to be modified - * - * @return string[] - if empty when process of status change was successful - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - public function toggleStatus($columnId) - { - $webserviceKey = new WebserviceKey($columnId); - - if (!Validate::isLoadedObject($webserviceKey)) { - $error = $this->translator - ->trans( - 'An error occurred while updating the status for an object.', - [], - 'Admin.Notifications.Error' - ) . - WebserviceKey::$definition['table'] . - $this->translator->trans('(cannot load object)', [], 'Admin.Notifications.Error'); - - return [$error]; - } - - if (!$webserviceKey->toggleStatus()) { - $error = $this->translator - ->trans('An error occurred while updating the status.', [], 'Admin.Notifications.Error'); - - return [$error]; - } - - return []; - } - - /** - * Updates status for multiple fields. - * - * @param array $columnIds - * @param int $status - * - * @return bool - * - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - public function setStatus(array $columnIds, $status) - { - $result = true; - foreach ($columnIds as $columnId) { - $webserviceKey = new WebserviceKey($columnId); - $webserviceKey->active = $status; - $result &= $webserviceKey->update(); - } - - return $result; - } -} diff --git a/src/Core/Addon/AddonInterface.php b/src/Core/Addon/AddonInterface.php deleted file mode 100644 index 76482128..00000000 --- a/src/Core/Addon/AddonInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -interface AddonInterface -{ - public function onInstall(); - - public function onUninstall(); - - public function onEnable(); - - public function onDisable(); - - public function onReset(); - - public function onUpgrade($version); -} diff --git a/src/Core/Addon/AddonListFilter.php b/src/Core/Addon/AddonListFilter.php deleted file mode 100644 index ce6bf34c..00000000 --- a/src/Core/Addon/AddonListFilter.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -class AddonListFilter -{ - /** - * @var int AddonListFilterType Specify the addon type like theme only or module only or all - */ - public $type = AddonListFilterType::ALL; - - /** - * @var int AddonListFilterStatus Specify if you want enabled only, disabled only or all addons - */ - public $status = AddonListFilterStatus::ALL; - - /** - * @var int AddonListFilterOrigin Specify if you want an addon from a specific source - */ - public $origin = AddonListFilterOrigin::ALL; - - /** - * @var array Names of all the addons to exclude from result - */ - public $exclude = []; - - /** - * @param int $origin - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function addOrigin($origin) - { - $this->origin &= $origin; - - return $this; - } - - /** - * @param int $status - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function addStatus($status) - { - $this->status &= $status; - - return $this; - } - - /** - * @param int $type - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function addType($type) - { - $this->type &= $type; - - return $this; - } - - /** - * @param int $origin - * - * @return bool - */ - public function hasOrigin($origin) - { - return $this->origin & $origin; - } - - /** - * @param int $status - * - * @return bool - */ - public function hasStatus($status) - { - return $this->status & $status; - } - - /** - * @param int $type - * - * @return bool - */ - public function hasType($type) - { - return $this->type & $type; - } - - /** - * @param int $origin - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function removeOrigin($origin) - { - return $this->addOrigin(~$origin); - } - - /** - * @param int $status - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function removeStatus($status) - { - return $this->addStatus(~$status); - } - - /** - * @param int $type - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function removeType($type) - { - return $this->addType(~$type); - } - - /** - * @param int $origin - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function setOrigin($origin) - { - $this->origin = $origin; - - return $this; - } - - /** - * @param int $type - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * @param int $status - * - * @return \PrestaShop\PrestaShop\Core\Addon\AddonListFilter - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - public function setExclude(array $exclude) - { - $this->exclude = $exclude; - - return $this; - } -} diff --git a/src/Core/Addon/AddonListFilterOrigin.php b/src/Core/Addon/AddonListFilterOrigin.php deleted file mode 100644 index 4eb26138..00000000 --- a/src/Core/Addon/AddonListFilterOrigin.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -class AddonListFilterOrigin -{ - /* Bitwise operators */ - const DISK = 1; - const ADDONS_MUST_HAVE = 2; - const ADDONS_SERVICE = 4; - const ADDONS_NATIVE = 8; - const ADDONS_NATIVE_ALL = 16; - const ADDONS_CUSTOMER = 32; - const ADDONS_ALL = 62; - - const ALL = 63; -} diff --git a/src/Core/Addon/AddonListFilterStatus.php b/src/Core/Addon/AddonListFilterStatus.php deleted file mode 100644 index 8651a383..00000000 --- a/src/Core/Addon/AddonListFilterStatus.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -class AddonListFilterStatus -{ - const NOT_ON_DISK = 1; - const ON_DISK = 2; // = Present on disk but not installed - const UNINSTALLED = 4; - const INSTALLED = 8; // = Installed - const DISABLED = 16; - const ENABLED = 32; - - const ALL = 63; -} diff --git a/src/Core/Addon/AddonListFilterType.php b/src/Core/Addon/AddonListFilterType.php deleted file mode 100644 index a1d337fe..00000000 --- a/src/Core/Addon/AddonListFilterType.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -class AddonListFilterType -{ - /* Bitwise operator */ - const THEME = 1; - const MODULE = 2; - const SERVICE = 4; - - const ALL = 7; /* = 1 | 2 | 4 */ -} diff --git a/src/Core/Addon/AddonListItem.php b/src/Core/Addon/AddonListItem.php deleted file mode 100644 index d47108aa..00000000 --- a/src/Core/Addon/AddonListItem.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -class AddonListItem -{ - public $name; - public $displayName; - public $type; - public $author; - public $version; - public $isEnabled; -} diff --git a/src/Core/Addon/AddonManagerInterface.php b/src/Core/Addon/AddonManagerInterface.php deleted file mode 100644 index b3dbe445..00000000 --- a/src/Core/Addon/AddonManagerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -interface AddonManagerInterface -{ - public function install($source); - - public function uninstall($name); - - public function upgrade($name, $version, $source = null); - - public function enable($name); - - public function disable($name); - - public function reset($name); - - public function getError($name); -} diff --git a/src/Core/Addon/AddonRepositoryInterface.php b/src/Core/Addon/AddonRepositoryInterface.php deleted file mode 100644 index eb880d27..00000000 --- a/src/Core/Addon/AddonRepositoryInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -interface AddonRepositoryInterface -{ - /** - * @param string $name theme name - * - * @return AddonInterface the theme or module - */ - public function getInstanceByName($name); - - /** - * @param AddonListFilter $filter - * - * @return AddonInterface[] retrieve a list of addons, regarding the $filter used - */ - public function getFilteredList(AddonListFilter $filter); - - /** - * @return AddonInterface[] retrieve a list of addons, regardless any $filter - */ - public function getList(); -} diff --git a/src/Core/Addon/AddonsCollection.php b/src/Core/Addon/AddonsCollection.php deleted file mode 100644 index 75181b5f..00000000 --- a/src/Core/Addon/AddonsCollection.php +++ /dev/null @@ -1,269 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon; - -use ArrayAccess; -use ArrayIterator; -use Countable; -use IteratorAggregate; -use PrestaShop\PrestaShop\Adapter\Module\Module as Addon; - -/** - * An ArrayCollection is a Collection implementation that wraps a regular PHP array. - */ -class AddonsCollection implements ArrayAccess, Countable, IteratorAggregate -{ - /** - * An array containing the addons of this collection. - * - * @var array - */ - private $addons; - - /** - * Initializes a new AddonsCollection. - * - * @param array $addons - */ - public function __construct(array $addons = []) - { - $this->addons = $addons; - } - - /** - * Creates a new instance from the specified elements. - * - * This method is provided for derived classes to specify how a new - * instance should be created when constructor semantics have changed. - * - * @param array $addons elements - * - * @return static - */ - public static function createFrom(array $addons) - { - return new static($addons); - } - - /** - * Gets a native PHP array representation of the collection. - * - * @return array - */ - public function toArray() - { - return $this->addons; - } - - /** - * @return ArrayIterator|\Traversable - */ - public function getIterator() - { - return new ArrayIterator($this->addons); - } - - /** - * {@inheritdoc} - */ - public function offsetExists($offset) - { - return $this->containsKey($offset); - } - - /** - * {@inheritdoc} - */ - public function offsetGet($offset) - { - return $this->get($offset); - } - - /** - * Required by ArrayAccess interface. - * - * {@inheritdoc} - */ - public function offsetSet($offset, $addon) - { - if (!isset($offset)) { - $this->add($addon); - - return; - } - - $this->set($offset, $addon); - } - - /** - * Required by interface ArrayAccess. - * - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - $this->remove($offset); - } - - /** - * Returns true if the key is found in the collection. - * - * @param mixed $key the key, can be integer or string - * - * @return bool - */ - public function containsKey($key) - { - return isset($this->addons[$key]) || array_key_exists($key, $this->addons); - } - - /** - * Returns true if the addon is found in the collection. - * - * @param Addon $addon the addon - * - * @return bool - */ - public function contains(Addon $addon) - { - return in_array($addon, $this->addons, true); - } - - /** - * {@inheritdoc} - */ - public function indexOf(Addon $addon) - { - return array_search($addon, $this->addons, true); - } - - /** - * {@inheritdoc} - */ - public function get($key) - { - return $this->addons[$key] ? $this->addons[$key] : null; - } - - /** - * {@inheritdoc} - */ - public function getKeys() - { - return array_keys($this->addons); - } - - /** - * {@inheritdoc} - */ - public function getValues() - { - return array_values($this->addons); - } - - /** - * Add an Addon with a specified key in the collection. - * - * @param mixed $key the key - * @param Addon $addon the specified addon - */ - public function set($key, Addon $addon) - { - $this->addons[$key] = $addon; - } - - /** - * Add an Addon in the collection. - * - * @param Addon $addon the specified addon - * - * @return bool - */ - public function add(Addon $addon) - { - $this->addons[] = $addon; - - return true; - } - - /** - * Remove an addon from the collection by key. - * - * @param mixed the key (can be int or string) - * - * @return bool true if the addon has been found and removed - */ - public function removeByKey($key) - { - if (!isset($this->addons[$key]) && !array_key_exists($key, $this->addons)) { - return null; - } - - $removed = $this->addons[$key]; - unset($this->addons[$key]); - - return $removed; - } - - /** - * Remove an addon from the collection by key. - * - * @param Addon $addon the addon to be removed - * - * @return bool true if the addon has been found and removed - */ - public function remove(Addon $addon) - { - $key = array_search($addon, $this->addons, true); - - if ($key === false) { - return false; - } - - unset($this->addons[$key]); - - return true; - } - - /** - * {@inheritdoc} - */ - public function isEmpty() - { - return empty($this->addons); - } - - /** - * Gets the sum of addons of the collection. - * - * @return int - */ - public function count() - { - return count($this->addons); - } -} diff --git a/src/Core/Addon/Module/AddonListFilterDeviceStatus.php b/src/Core/Addon/Module/AddonListFilterDeviceStatus.php deleted file mode 100644 index 4f172362..00000000 --- a/src/Core/Addon/Module/AddonListFilterDeviceStatus.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -class AddonListFilterDeviceStatus -{ - const DEVICE_COMPUTER = 1; - const DEVICE_TABLET = 2; - const DEVICE_MOBILE = 4; - - const ALL = 7; -} diff --git a/src/Core/Addon/Module/Exception/UnconfirmedModuleActionException.php b/src/Core/Addon/Module/Exception/UnconfirmedModuleActionException.php deleted file mode 100644 index 69544e1d..00000000 --- a/src/Core/Addon/Module/Exception/UnconfirmedModuleActionException.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module\Exception; - -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * This class is used for the module page, which allows to ask for a confirmation from the employee. - */ -class UnconfirmedModuleActionException extends CoreException -{ - /** - * Concerned module by the exception. - * - * @var Module - */ - protected $module; - - /** - * Action requested by the employee. - * - * @var string - */ - protected $action; - - /** - * Subject to send in order to confirm. - * - * @var string - */ - protected $subject; - - /** - * Module getter. - * - * @return Module - */ - public function getModule() - { - return $this->module; - } - - /** - * Action getter (install, uninstall, reset ...). - * - * @return string - */ - public function getAction() - { - return $this->action; - } - - /** - * Subject getter (PrestaTrust...). - * - * @return string - */ - public function getSubject() - { - return $this->subject; - } - - /** - * Module setter. - * - * @param Module $module - * - * @return $this - */ - public function setModule(Module $module) - { - $this->module = $module; - - return $this; - } - - /** - * Action setter. - * - * @param string $action - * - * @return $this - */ - public function setAction($action) - { - $this->action = $action; - - return $this; - } - - /** - * Subject setter. - * - * @param string $subject - * - * @return $this - */ - public function setSubject($subject) - { - $this->subject = $subject; - - return $this; - } -} diff --git a/src/Core/Addon/Module/ModuleInterface.php b/src/Core/Addon/Module/ModuleInterface.php deleted file mode 100644 index bbf211e5..00000000 --- a/src/Core/Addon/Module/ModuleInterface.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -use PrestaShop\PrestaShop\Core\Addon\AddonInterface; - -interface ModuleInterface extends AddonInterface -{ - public function onInstall(); - - public function onUninstall(); - - /** - * Called when switching the current theme of the selected shop. - * You can update configuration, enable/disable modules... - * - * @return bool true for success - */ - public function onEnable(); - - /** - * Not necessarily the opposite of enable. Use this method if - * something must be done when switching to another theme (like uninstall - * very specific modules for example). - * - * @return bool true for success - */ - public function onDisable(); - - /** - * @return bool - */ - public function onMobileEnable(); - - /** - * @return bool - */ - public function onMobileDisable(); - - /** - * @return bool - */ - public function onReset(); - - /** - * Execute up files. You can update configuration, update sql schema. - * No file modification. - * - * @return bool true for success - */ - public function onUpgrade($version); -} diff --git a/src/Core/Addon/Module/ModuleManager.php b/src/Core/Addon/Module/ModuleManager.php deleted file mode 100644 index b1265756..00000000 --- a/src/Core/Addon/Module/ModuleManager.php +++ /dev/null @@ -1,701 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -use Exception; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater; -use PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager; -use PrestaShop\PrestaShop\Core\Addon\AddonManagerInterface; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShop\PrestaShop\Core\Addon\Module\Exception\UnconfirmedModuleActionException; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShopBundle\Event\ModuleManagementEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\Translation\TranslatorInterface; - -class ModuleManager implements AddonManagerInterface -{ - /** - * Admin Module Data Provider. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider - */ - private $adminModuleProvider; - /** - * Module Data Provider. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider - */ - private $moduleProvider; - /** - * Module Data Provider. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater - */ - private $moduleUpdater; - - /** - * Module Repository. - * - * @var \PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository - */ - private $moduleRepository; - - /** - * Module Zip Manager. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager - */ - private $moduleZipManager; - - /** - * Translator. - * - * @var \Symfony\Component\Translation\TranslatorInterface - */ - private $translator; - - /** - * @var EventDispatcherInterface - */ - private $eventDispatcher; - - /** - * Additionnal data used for module actions. - * - * @var ParameterBag - */ - private $actionParams; - - /** - * @var CacheClearerInterface - */ - private $symfonyCacheClearer; - - /** - * Used to check if the cache has already been cleaned. - * - * @var bool - */ - private $cacheCleared = false; - - /** - * @param AdminModuleDataProvider $adminModuleProvider - * @param ModuleDataProvider $modulesProvider - * @param ModuleDataUpdater $modulesUpdater - * @param ModuleRepository $moduleRepository - * @param ModuleZipManager $moduleZipManager - * @param TranslatorInterface $translator - * @param EventDispatcherInterface $eventDispatcher - * @param CacheClearerInterface $symfonyCacheClearer - */ - public function __construct( - AdminModuleDataProvider $adminModuleProvider, - ModuleDataProvider $modulesProvider, - ModuleDataUpdater $modulesUpdater, - ModuleRepository $moduleRepository, - ModuleZipManager $moduleZipManager, - TranslatorInterface $translator, - EventDispatcherInterface $eventDispatcher, - CacheClearerInterface $symfonyCacheClearer - ) { - $this->adminModuleProvider = $adminModuleProvider; - $this->moduleProvider = $modulesProvider; - $this->moduleUpdater = $modulesUpdater; - $this->moduleRepository = $moduleRepository; - $this->moduleZipManager = $moduleZipManager; - $this->translator = $translator; - $this->eventDispatcher = $eventDispatcher; - $this->symfonyCacheClearer = $symfonyCacheClearer; - $this->actionParams = new ParameterBag(); - } - - /** - * For some actions, you may need to add params like confirmation details. - * This setter is the way to register them in the manager. - * - * @param array $actionParams - * - * @return $this - */ - public function setActionParams(array $actionParams) - { - $this->actionParams->replace($actionParams); - - return $this; - } - - /** - * @param callable $modulesPresenter - * - * @return object - */ - public function getModulesWithNotifications(callable $modulesPresenter) - { - $modules = $this->groupModulesByInstallationProgress(); - - $modulesProvider = $this->adminModuleProvider; - foreach ($modules as $moduleLabel => $modulesPart) { - $collection = AddonsCollection::createFrom($modulesPart); - $modulesProvider->generateAddonsUrls($collection, str_replace('to_', '', $moduleLabel)); - $modules->{$moduleLabel} = $modulesPresenter($collection); - } - - return $modules; - } - - /** - * Returns the total of module notifications - * Not used anymore, but kept for backward compatibility. - * - * @return int - * - * @deprecated since 1.7.5.0 - */ - public function countModulesWithNotifications() - { - $modules = (array) $this->groupModulesByInstallationProgress(); - - return array_reduce($modules, function ($carry, $item) { - return $carry + count($item); - }, 0); - } - - /** - * Detailed array of number of modules per notification type. - * - * @return array - */ - public function countModulesWithNotificationsDetailed() - { - $notificationCounts = [ - 'count' => 0, - ]; - - foreach ((array) $this->groupModulesByInstallationProgress() as $key => $modules) { - $count = count($modules); - $notificationCounts[$key] = $count; - $notificationCounts['count'] += $count; - } - - return $notificationCounts; - } - - /** - * @return object - */ - protected function groupModulesByInstallationProgress() - { - $installedProducts = $this->moduleRepository->getInstalledModules(); - - $modules = (object) [ - 'to_configure' => [], - 'to_update' => [], - ]; - - /* - * @var \PrestaShop\PrestaShop\Adapter\Module\Module - */ - foreach ($installedProducts as $installedProduct) { - if ($this->shouldRecommendConfigurationForModule($installedProduct)) { - $modules->to_configure[] = (object) $installedProduct; - } - - if ($installedProduct->canBeUpgraded()) { - $modules->to_update[] = (object) $installedProduct; - } - } - - return $modules; - } - - /** - * @param Module $installedProduct - * - * @return bool - */ - protected function shouldRecommendConfigurationForModule(Module $installedProduct) - { - $warnings = $this->getModuleInstallationWarnings($installedProduct); - - return !empty($warnings); - } - - /** - * @param Module $installedProduct - * - * @return array - */ - protected function getModuleInstallationWarnings(Module $installedProduct) - { - if ($installedProduct->hasValidInstance()) { - return $installedProduct->getInstance()->warning; - } - - return []; - } - - /** - * Add new module from zipball. This will unzip the file and move the content - * to the right locations. - * A theme can bundle modules, resources, documentation, email templates and so on. - * - * @param string $source The source can be a module name (installed from either local disk or addons.prestashop.com). - * or a location (url or path to the zip file) - * - * @return bool true for success - */ - public function install($source) - { - // in CLI mode, there is no employee set up - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__)) { - throw new Exception($this->translator->trans('You are not allowed to install modules.', [], 'Admin.Modules.Notification')); - } - - if (is_file($source)) { - $name = $this->moduleZipManager->getName($source); - } else { - $name = $source; - $source = null; - } - - if ($this->moduleProvider->isInstalled($name)) { - return $this->upgrade($name, 'latest', $source); - } - - if (!empty($source)) { - $this->moduleZipManager->storeInModulesFolder($source); - } elseif (!$this->moduleProvider->isOnDisk($name)) { - $this->moduleUpdater->setModuleOnDiskFromAddons($name); - } - - $module = $this->moduleRepository->getModule($name); - $this->checkConfirmationGiven(__FUNCTION__, $module); - $result = $module->onInstall(); - - $this->checkAndClearCache($result); - $this->dispatch(ModuleManagementEvent::INSTALL, $module); - - return $result; - } - - /** - * Remove all theme files, resources, documentation and specific modules. - * - * @param string $name The source can be a module name (installed from either local disk or addons.prestashop.com). - * or a location (url or path to the zip file) - * - * @return bool true for success - */ - public function uninstall($name) - { - // Check permissions: - // * Employee can delete - // * Employee can delete this specific module - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to uninstall the module %module%.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - // Get module instance and uninstall it - $module = $this->moduleRepository->getModule($name); - $result = $module->onUninstall(); - - if ($result && $this->actionParams->get('deletion', false)) { - $result = $result && $this->removeModuleFromDisk($name); - } - - $this->checkAndClearCache($result); - $this->dispatch(ModuleManagementEvent::UNINSTALL, $module); - - return $result; - } - - /** - * Download new files from source, backup old files, replace files with new ones - * and execute all necessary migration scripts form current version to the new one. - * - * @param Addon $name the theme you want to upgrade - * @param string $version the version you want to up upgrade to - * @param string $source if the upgrade is not coming from addons, you need to specify the path to the zipball - * - * @return bool true for success - */ - public function upgrade($name, $version = 'latest', $source = null) - { - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to upgrade the module %module%.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - $module = $this->moduleRepository->getModule($name); - - // Get new module - // 1- From source - if ($source != null) { - $this->moduleZipManager->storeInModulesFolder($source); - } elseif ($module->canBeUpgradedFromAddons()) { - // 2- From Addons - // This step is not mandatory (in case of local module), - // we do not check the result - $this->moduleUpdater->setModuleOnDiskFromAddons($name); - } - - // Load and execute upgrade files - $result = $this->moduleUpdater->upgrade($name) && $module->onUpgrade($version); - - $this->checkAndClearCache($result); - $this->dispatch(ModuleManagementEvent::UPGRADE, $module); - - return $result; - } - - /** - * Disable a module without uninstalling it. - * Allows the merchant to temporarly remove a module without uninstalling it. - * - * @param string $name The module name to disable - * - * @return bool True for success - */ - public function disable($name) - { - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to disable the module %module%.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - $module = $this->moduleRepository->getModule($name); - - try { - $result = $module->onDisable(); - } catch (Exception $e) { - throw new Exception($this->translator->trans('Error when disabling module %module%. %error_details%.', ['%module%' => $name, '%error_details%' => $e->getMessage()], 'Admin.Modules.Notification'), 0, $e); - } - - $this->checkAndClearCache($result); - $this->dispatch(ModuleManagementEvent::DISABLE, $module); - - return $result; - } - - /** - * Enable a module previously disabled. - * - * @param string $name The module name to enable - * - * @return bool True for success - */ - public function enable($name) - { - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to enable the module %module%.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - $module = $this->moduleRepository->getModule($name); - - try { - $result = $module->onEnable(); - } catch (Exception $e) { - throw new Exception($this->translator->trans('Error when enabling module %module%. %error_details%.', ['%module%' => $name, '%error_details%' => $e->getMessage()], 'Admin.Modules.Notification'), 0, $e); - } - - $this->checkAndClearCache($result); - $this->dispatch(ModuleManagementEvent::ENABLE, $module); - - return $result; - } - - /** - * Disable a module specifically on mobile. - * Not written in camel case because the route and the displayed action in the template - * are related to this function name. - * - * @deprecated use disableMobile() - * - * @param string $name The module name to disable - * - * @return bool True for success - */ - public function disable_mobile($name) - { - return $this->disableMobile($name); - } - - /** - * Disable a module specifically on mobile. - * - * @param string $name The module name to disable - * - * @return bool True for success - */ - public function disableMobile($name) - { - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to disable the module %module% on mobile.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - $module = $this->moduleRepository->getModule($name); - - try { - $result = $module->onMobileDisable(); - } catch (Exception $e) { - throw new Exception($this->translator->trans('Error when disabling module %module% on mobile. %error_details%', ['%module%' => $name, '%error_details%' => $e->getMessage()], 'Admin.Modules.Notification'), 0, $e); - } - - $this->checkAndClearCache($result); - - return $result; - } - - /** - * Enable a module previously disabled on mobile - * Not written in camel case because the route and the displayed action in the template - * are related to this function name. - * - * @deprecated use enableMobile - * - * @param string $name The module name to enable - * - * @return bool True for success - */ - public function enable_mobile($name) - { - return $this->enableMobile($name); - } - - /** - * Enable a module previously disabled on mobile. - * - * @param string $name The module name to enable - * - * @return bool True for success - */ - public function enableMobile($name) - { - if (!$this->adminModuleProvider->isAllowedAccess(__FUNCTION__, $name)) { - throw new Exception($this->translator->trans('You are not allowed to enable the module %module% on mobile.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - $module = $this->moduleRepository->getModule($name); - - try { - $result = $module->onMobileEnable(); - } catch (Exception $e) { - throw new Exception($this->translator->trans('Error when enabling module %module% on mobile. %error_details%', ['%module%' => $name, '%error_details%' => $e->getMessage()], 'Admin.Modules.Notification'), 0, $e); - } - - $this->checkAndClearCache($result); - - return $result; - } - - /** - * Actions to perform to restaure default settings. - * - * @param string $name The theme name to reset - * - * @return bool True for success - */ - public function reset($name, $keep_data = false) - { - if (!$this->adminModuleProvider->isAllowedAccess('install') || !$this->adminModuleProvider->isAllowedAccess('uninstall', $name)) { - throw new Exception($this->translator->trans('You are not allowed to reset the module %module%.', ['%module%' => $name], 'Admin.Modules.Notification')); - } - - $this->checkIsInstalled($name); - - $module = $this->moduleRepository->getModule($name); - - try { - if ((bool) $keep_data && method_exists($module->getInstance(), 'reset')) { - $this->dispatch(ModuleManagementEvent::UNINSTALL, $module); - $status = $module->onReset(); - $this->dispatch(ModuleManagementEvent::INSTALL, $module); - } else { - $status = ($this->uninstall($name) && $this->install($name)); - } - } catch (Exception $e) { - throw new Exception($this->translator->trans('Error when resetting module %module%. %error_details%', ['%module%' => $name, '%error_details%' => $e->getMessage()], 'Admin.Modules.Notification'), 0, $e); - } - - return $status; - } - - /** - * Shortcut to the module data provider in order to know if a module is enabled. - * - * @param string $name The technical module name - * - * @return bool - */ - public function isEnabled($name) - { - return $this->moduleProvider->isEnabled($name); - } - - /** - * Shortcut to the module data provider in order to know if a module is installed. - * - * @param string $name The technical module name - * - * @return bool True is installed - */ - public function isInstalled($name) - { - return $this->moduleProvider->isInstalled($name); - } - - /** - * Shortcut to the module data provider in order to know the module id depends - * on its name. - * - * @param string $name The technical module name - * - * @return int the Module Id, or 0 if not found - */ - public function getModuleIdByName($name) - { - return $this->moduleProvider->getModuleIdByName($name); - } - - /** - * Shortcut to the module data updater to remove the module from the disk. - * - * @param string $name The technical module name - * - * @return bool True if files were properly removed - */ - public function removeModuleFromDisk($name) - { - return $this->moduleUpdater->removeModuleFromDisk($name); - } - - /** - * Returns the last error, if found. - * - * @param string $name The technical module name - * - * @return string|null The last error added to the module if found - */ - public function getError($name) - { - $message = null; - $module = $this->moduleRepository->getModule($name); - if ($module->hasValidInstance()) { - $errors = $module->getInstance()->getErrors(); - $message = array_pop($errors); - } else { - // Invalid instance: Missing or with syntax error - $message = $this->translator->trans( - 'The module is invalid and cannot be loaded.', - [], - 'Admin.Modules.Notification' - ); - } - - if (empty($message)) { - $message = $this->translator->trans( - 'Unfortunately, the module did not return additional details.', - [], - 'Admin.Modules.Notification' - ); - } - - return $message; - } - - /** - * This function is a refacto of the event dispatching. - * - * @param string $event - * @param \PrestaShop\PrestaShop\Core\Addon\Module\Module $module - */ - private function dispatch($event, $module) - { - $this->eventDispatcher->dispatch($event, new ModuleManagementEvent($module)); - } - - private function checkIsInstalled($name) - { - if (!$this->moduleProvider->isInstalled($name)) { - throw new Exception($this->translator->trans('The module %module% must be installed first', ['%module%' => $name], 'Admin.Modules.Notification')); - } - } - - /** - * We check the module does not ask for pre-requisites to be respected prior the action being executed. - * - * @param string $action - * @param Module $module - * - * @throws UnconfirmedModuleActionException - */ - private function checkConfirmationGiven($action, Module $module) - { - if ($action === 'install') { - if ($module->attributes->has('prestatrust') && !$this->actionParams->has('confirmPrestaTrust')) { - throw (new UnconfirmedModuleActionException())->setModule($module)->setAction($action)->setSubject('PrestaTrust'); - } - } - } - - /** - * @param bool $result - */ - private function checkAndClearCache($result) - { - if ($result && $this->actionParams->get('cacheClearEnabled', true)) { - $this->clearCache(); - } - } - - /** - * Clear smarty and Symfony cache (the sf2 cache is remove on the process shutdown). - */ - private function clearCache() - { - if ($this->cacheCleared) { - return; - } - - $this->symfonyCacheClearer->clear(); - $this->cacheCleared = true; - } -} diff --git a/src/Core/Addon/Module/ModuleManagerBuilder.php b/src/Core/Addon/Module/ModuleManagerBuilder.php deleted file mode 100644 index 8f267264..00000000 --- a/src/Core/Addon/Module/ModuleManagerBuilder.php +++ /dev/null @@ -1,256 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -use Context; -use Db; -use Doctrine\Common\Cache\FilesystemCache; -use GuzzleHttp\Client; -use PrestaShop\PrestaShop\Adapter\Addons\AddonsDataProvider; -use PrestaShop\PrestaShop\Adapter\Cache\Clearer; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Adapter\LegacyLogger; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater; -use PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager; -use PrestaShop\PrestaShop\Adapter\SymfonyContainer; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder; -use PrestaShop\PrestaShop\Core\Util\File\YamlParser; -use PrestaShopBundle\Event\Dispatcher\NullDispatcher; -use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider; -use PrestaShopBundle\Service\DataProvider\Marketplace\ApiClient; -use Symfony\Component\Config\FileLocator; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Routing\Loader\YamlFileLoader; -use Symfony\Component\Routing\Router; - -class ModuleManagerBuilder -{ - /** - * Singleton of ModuleRepository. - * - * @var ModuleRepository - */ - public static $modulesRepository = null; - /** - * Singleton of ModuleManager. - * - * @var ModuleManager - */ - public static $moduleManager = null; - public static $adminModuleDataProvider = null; - public static $lecacyContext; - public static $legacyLogger = null; - public static $moduleDataProvider = null; - public static $moduleDataUpdater = null; - public static $moduleZipManager = null; - public static $translator = null; - public static $addonsDataProvider = null; - public static $categoriesProvider = null; - public static $instance = null; - public static $cacheProvider = null; - - /** - * @return ModuleManagerBuilder|null - */ - public static function getInstance() - { - if (self::$instance == null) { - self::$instance = new self(); - } - - return self::$instance; - } - - /** - * Returns an instance of ModuleManager. - * - * @return ModuleManager - */ - public function build() - { - if (null === self::$moduleManager) { - $sfContainer = SymfonyContainer::getInstance(); - if (null !== $sfContainer) { - self::$moduleManager = $sfContainer->get('prestashop.module.manager'); - } else { - self::$moduleManager = new ModuleManager( - self::$adminModuleDataProvider, - self::$moduleDataProvider, - self::$moduleDataUpdater, - $this->buildRepository(), - self::$moduleZipManager, - self::$translator, - new NullDispatcher(), - new Clearer\SymfonyCacheClearer() - ); - } - } - - return self::$moduleManager; - } - - /** - * Returns an instance of ModuleRepository. - * - * @return ModuleRepository - */ - public function buildRepository() - { - if (null === self::$modulesRepository) { - $sfContainer = SymfonyContainer::getInstance(); - if (null !== $sfContainer) { - self::$modulesRepository = $sfContainer->get('prestashop.core.admin.module.repository'); - } else { - self::$modulesRepository = new ModuleRepository( - self::$adminModuleDataProvider, - self::$moduleDataProvider, - self::$moduleDataUpdater, - self::$legacyLogger, - self::$translator, - _PS_MODULE_DIR_, - self::$cacheProvider - ); - } - } - - return self::$modulesRepository; - } - - private function __construct() - { - /** - * If the Symfony container is available, it will be used for the other methods - * build & buildRepository. No need to init manually all the dependancies. - */ - $sfContainer = SymfonyContainer::getInstance(); - if (null !== $sfContainer) { - return; - } - - $yamlParser = new YamlParser((new Configuration())->get('_PS_CACHE_DIR_')); - - $config = $yamlParser->parse($this->getConfigDir() . '/config.yml'); - $prestashopAddonsConfig = - $yamlParser->parse($this->getConfigDir() . '/addons/categories.yml'); - - $clientConfig = $config['csa_guzzle']['clients']['addons_api']['config']; - - self::$translator = Context::getContext()->getTranslator(); - - $marketPlaceClient = new ApiClient( - new Client($clientConfig), - self::$translator->getLocale(), - $this->getCountryIso(), - new Tools(), - (new Configuration())->get('_PS_BASE_URL_'), - \AppKernel::VERSION - ); - - $marketPlaceClient->setSslVerification(_PS_CACHE_CA_CERT_FILE_); - if (file_exists($this->getConfigDir() . '/parameters.php')) { - $parameters = require $this->getConfigDir() . '/parameters.php'; - if (array_key_exists('addons.api_client.verify_ssl', $parameters['parameters'])) { - $marketPlaceClient->setSslVerification($parameters['parameters']['addons.api_client.verify_ssl']); - } - } - - self::$moduleZipManager = new ModuleZipManager(new Filesystem(), self::$translator, new NullDispatcher()); - self::$addonsDataProvider = new AddonsDataProvider($marketPlaceClient, self::$moduleZipManager); - - $kernelDir = realpath($this->getConfigDir() . '/../../var'); - self::$addonsDataProvider->cacheDir = $kernelDir . '/cache/prod'; - if (_PS_MODE_DEV_) { - self::$addonsDataProvider->cacheDir = $kernelDir . '/cache/dev'; - } - - self::$cacheProvider = new FilesystemCache(self::$addonsDataProvider->cacheDir . '/doctrine'); - - $themeManagerBuilder = new ThemeManagerBuilder(Context::getContext(), Db::getInstance()); - $themeName = Context::getContext()->shop->theme_name; - $themeModules = $themeName ? - $themeManagerBuilder->buildRepository()->getInstanceByName($themeName)->getModulesToEnable() : - []; - - self::$legacyLogger = new LegacyLogger(); - self::$categoriesProvider = new CategoriesProvider( - $prestashopAddonsConfig['prestashop']['addons']['categories'], - $themeModules - ); - self::$lecacyContext = new LegacyContext(); - - if (null === self::$adminModuleDataProvider) { - self::$moduleDataProvider = new ModuleDataProvider(self::$legacyLogger, self::$translator); - self::$adminModuleDataProvider = new AdminModuleDataProvider( - self::$translator, - self::$legacyLogger, - self::$addonsDataProvider, - self::$categoriesProvider, - self::$moduleDataProvider, - self::$cacheProvider, - Context::getContext()->employee - ); - self::$adminModuleDataProvider->setRouter($this->getSymfonyRouter()); - - self::$translator = Context::getContext()->getTranslator(); - self::$moduleDataUpdater = new ModuleDataUpdater(self::$addonsDataProvider, self::$adminModuleDataProvider); - } - } - - /** - * Returns an instance of \Symfony\Component\Routing\Router from Symfony scope into Legacy. - * - * @return \Symfony\Component\Routing\Router - */ - private function getSymfonyRouter() - { - // get the environment to load the good routing file - $routeFileName = _PS_MODE_DEV_ === true ? 'routing_dev.yml' : 'routing.yml'; - $routesDirectory = $this->getConfigDir(); - $locator = new FileLocator([$routesDirectory]); - $loader = new YamlFileLoader($locator); - - return new Router($loader, $routeFileName); - } - - protected function getConfigDir() - { - return _PS_ROOT_DIR_ . '/app/config'; - } - - /** - * Returns country iso from context. - */ - private function getCountryIso() - { - return \CountryCore::getIsoById(\Configuration::get('PS_COUNTRY_DEFAULT')); - } -} diff --git a/src/Core/Addon/Module/ModuleRepository.php b/src/Core/Addon/Module/ModuleRepository.php deleted file mode 100644 index 3de308f7..00000000 --- a/src/Core/Addon/Module/ModuleRepository.php +++ /dev/null @@ -1,645 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -use Doctrine\Common\Cache\ArrayCache; -use Doctrine\Common\Cache\CacheProvider; -use Exception; -use Module as LegacyModule; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater; -use PrestaShop\PrestaShop\Adapter\Module\PrestaTrust\PrestaTrustChecker; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterOrigin; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use Psr\Log\LoggerInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\TranslatorInterface; - -class ModuleRepository implements ModuleRepositoryInterface -{ - const NATIVE_AUTHOR = 'PrestaShop'; - - const PARTNER_AUTHOR = 'PrestaShop Partners'; - - /** - * Admin Module Data Provider. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider - */ - private $adminModuleProvider; - - /** - * Logger. - * - * @var \Psr\Log\LoggerInterface - */ - private $logger; - - /** - * Module Data Provider. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider - */ - private $moduleProvider; - - /** - * Module Data Updater. - * - * @var \PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater - */ - private $moduleUpdater; - - /** - * Translator. - * - * @var \Symfony\Component\Translation\TranslatorInterface - */ - private $translator; - - /** - * Path to the module directory, coming from Confiuration class. - * - * @var string - */ - private $modulePath; - - /** - * @var PrestaTrustChecker - */ - private $prestaTrustChecker = null; - - //### CACHE PROPERTIES #### - - /** - * Key of the cache content. - * - * @var string - */ - private $cacheFilePath; - - /** - * Contains data from cache file about modules on disk. - * - * @var array - */ - private $cache = []; - - /** - * Optionnal Doctrine cache provider. - * - * @var \Doctrine\Common\Cache\CacheProvider - */ - private $cacheProvider; - - /** - * Keep loaded modules in cache. - * - * @var ArrayCache - */ - private $loadedModules; - - //### END OF CACHE PROPERTIES #### - - public function __construct( - AdminModuleDataProvider $adminModulesProvider, - ModuleDataProvider $modulesProvider, - ModuleDataUpdater $modulesUpdater, - LoggerInterface $logger, - TranslatorInterface $translator, - $modulePath, - CacheProvider $cacheProvider = null - ) { - $this->adminModuleProvider = $adminModulesProvider; - $this->logger = $logger; - $this->moduleProvider = $modulesProvider; - $this->moduleUpdater = $modulesUpdater; - $this->translator = $translator; - $this->finder = new Finder(); - $this->modulePath = $modulePath; - - list($isoLang) = explode('-', $translator->getLocale()); - - // Cache related variables - $this->cacheFilePath = $isoLang . '_local_modules'; - $this->cacheProvider = $cacheProvider; - $this->loadedModules = new ArrayCache(); - - if ($this->cacheProvider && $this->cacheProvider->contains($this->cacheFilePath)) { - $this->cache = $this->cacheProvider->fetch($this->cacheFilePath); - } - } - - /** - * Setter for the optional PrestaTrust checker. - * - * @param PrestaTrustChecker $checker - * - * @return $this - */ - public function setPrestaTrustChecker(PrestaTrustChecker $checker) - { - $this->prestaTrustChecker = $checker; - - return $this; - } - - public function __destruct() - { - if ($this->cacheProvider) { - $this->cacheProvider->save($this->cacheFilePath, $this->cache); - } - } - - public function clearCache() - { - if ($this->cacheProvider) { - $this->cacheProvider->delete($this->cacheFilePath); - } - $this->cache = []; - } - - /** - * Get the **Legacy** Module object from its name. - * - * @param string $name The technical module name to instanciate - * - * @return \Module|null Instance of legacy Module, if valid - */ - public function getInstanceByName($name) - { - // Return legacy instance ! - return $this->getModule($name)->getInstance(); - } - - /** - * @param AddonListFilter $filter - * @param bool $skip_main_class_attributes - * - * @return AddonInterface[] retrieve a list of addons, regarding the $filter used - */ - public function getFilteredList(AddonListFilter $filter, $skip_main_class_attributes = false) - { - if ($filter->status >= AddonListFilterStatus::ON_DISK - && $filter->status != AddonListFilterStatus::ALL) { - $modules = $this->getModulesOnDisk($skip_main_class_attributes); - } else { - $modules = $this->getList(); - } - - foreach ($modules as $key => &$module) { - // Part One : Removing addons not related to the selected product type - if ($filter->type != AddonListFilterType::ALL) { - if ($module->attributes->get('productType') == 'module') { - $productType = AddonListFilterType::MODULE; - } - if ($module->attributes->get('productType') == 'service') { - $productType = AddonListFilterType::SERVICE; - } - if (!isset($productType) || $productType & ~$filter->type) { - unset($modules[$key]); - - continue; - } - } - - // Part Two : Remove module not installed if specified - if ($filter->status != AddonListFilterStatus::ALL) { - if ($module->database->get('installed') == 1 - && ($filter->hasStatus(AddonListFilterStatus::UNINSTALLED) - || !$filter->hasStatus(AddonListFilterStatus::INSTALLED))) { - unset($modules[$key]); - - continue; - } - - if ($module->database->get('installed') == 0 - && (!$filter->hasStatus(AddonListFilterStatus::UNINSTALLED) - || $filter->hasStatus(AddonListFilterStatus::INSTALLED))) { - unset($modules[$key]); - - continue; - } - - if ($module->database->get('installed') == 1 - && $module->database->get('active') == 1 - && !$filter->hasStatus(AddonListFilterStatus::DISABLED) - && $filter->hasStatus(AddonListFilterStatus::ENABLED)) { - unset($modules[$key]); - - continue; - } - - if ($module->database->get('installed') == 1 - && $module->database->get('active') == 0 - && !$filter->hasStatus(AddonListFilterStatus::ENABLED) - && $filter->hasStatus(AddonListFilterStatus::DISABLED)) { - unset($modules[$key]); - - continue; - } - } - - // Part Three : Remove addons not related to the proper source (ex Addons) - if ($filter->origin != AddonListFilterOrigin::ALL) { - if (!$module->attributes->has('origin_filter_value') && - !$filter->hasOrigin(AddonListFilterOrigin::DISK) - ) { - unset($modules[$key]); - - continue; - } - if ($module->attributes->has('origin_filter_value') && - !$filter->hasOrigin($module->attributes->get('origin_filter_value')) - ) { - unset($modules[$key]); - - continue; - } - } - } - - return $modules; - } - - /** - * @return AddonInterface[] retrieve the universe of Modules - */ - public function getList() - { - return array_merge( - $this->getAddonsCatalogModules(), - $this->getModulesOnDisk() - ); - } - - /** - * @return AddonInterface[] retrieve the list of native modules - */ - public function getNativeModules() - { - static $nativeModules = null; - - if (null === $nativeModules) { - $filter = new AddonListFilter(); - $filter->setOrigin(AddonListFilterOrigin::ADDONS_NATIVE); - - $nativeModules = $this->getFilteredList($filter); - - foreach ($nativeModules as $key => $module) { - $moduleAuthor = $module->attributes->get('author'); - if (self::NATIVE_AUTHOR !== $moduleAuthor) { - unset($nativeModules[$key]); - } - } - } - - return $nativeModules; - } - - /** - * @return AddonInterface[] retrieve the list of partners modules - */ - public function getPartnersModules() - { - $filter = new AddonListFilter(); - $filter->setOrigin(AddonListFilterOrigin::ADDONS_NATIVE); - - $partnersModules = $this->getFilteredList($filter); - - foreach ($partnersModules as $key => $module) { - $moduleAuthor = $module->attributes->get('author'); - if (self::PARTNER_AUTHOR !== $moduleAuthor) { - unset($partnersModules[$key]); - } - } - - return $partnersModules; - } - - /** - * @return AddonInterface[] get the list of installed partners modules - */ - public function getInstalledPartnersModules() - { - $partnersModules = $this->getPartnersModules(); - - foreach ($partnersModules as $key => $module) { - if (1 !== $module->database->get('installed')) { - unset($partnersModules[$key]); - } - } - - return $partnersModules; - } - - /** - * @return AddonInterface[] get the list of not installed partners modules - */ - public function getNotInstalledPartnersModules() - { - $partnersModules = $this->getPartnersModules(); - - foreach ($partnersModules as $key => $module) { - if (0 !== $module->database->get('installed')) { - unset($partnersModules[$key]); - } - } - - return $partnersModules; - } - - private function getAddonsCatalogModules() - { - $modules = []; - foreach ($this->adminModuleProvider->getCatalogModulesNames() as $name) { - try { - $module = $this->getModule($name); - if ($module instanceof Module) { - $modules[$name] = $module; - } - } catch (\ParseError $e) { - $this->logger->critical( - $this->translator->trans( - 'Parse error on module %module%. %error_details%', - [ - '%module%' => $name, - '%error_details%' => $e->getMessage(), - ], - 'Admin.Modules.Notification' - ) - ); - } catch (Exception $e) { - $this->logger->critical( - $this->translator->trans( - 'Unexpected exception on module %module%. %error_details%', - [ - '%module%' => $name, - '%error_details%' => $e->getMessage(), - ], - 'Admin.Modules.Notification' - ) - ); - } - } - - return $modules; - } - - /** - * Get the new module presenter class of the specified name provided. - * It contains data from its instance, the disk, the database and from the marketplace if exists. - * - * @param string $name The technical name of the module - * @param bool $skip_main_class_attributes - * - * @return Module - */ - public function getModule($name, $skip_main_class_attributes = false) - { - if ($this->loadedModules->contains($name)) { - return $this->loadedModules->fetch($name); - } - - $path = $this->modulePath . $name; - $php_file_path = $path . '/' . $name . '.php'; - - /* Data which design the module class */ - $attributes = ['name' => $name]; - - // Get filemtime of module main class (We do this directly with an error suppressor to go faster) - $current_filemtime = (int) @filemtime($php_file_path); - - // We check that we have data from the marketplace - try { - $module_catalog_data = $this->adminModuleProvider->getCatalogModules(['name' => $name]); - $attributes = array_merge( - $attributes, - (array) array_shift($module_catalog_data) - ); - } catch (Exception $e) { - $this->logger->alert( - $this->translator->trans( - 'Loading data from Addons failed. %error_details%', - ['%error_details%' => $e->getMessage()], - 'Admin.Modules.Notification' - ) - ); - } - - // Now, we check that cache is up to date - if (isset($this->cache[$name]['disk']['filemtime']) && - $this->cache[$name]['disk']['filemtime'] === $current_filemtime - ) { - // OK, cache can be loaded and used directly - - $attributes = array_merge($attributes, $this->cache[$name]['attributes']); - $disk = $this->cache[$name]['disk']; - } else { - // NOPE, we have to fulfil the cache with the module data - - $disk = [ - 'filemtime' => $current_filemtime, - 'is_present' => (int) $this->moduleProvider->isOnDisk($name), - 'is_valid' => 0, - 'version' => null, - 'path' => $path, - ]; - $main_class_attributes = []; - - if (!$skip_main_class_attributes && $this->moduleProvider->isModuleMainClassValid($name)) { - // We load the main class of the module, and get its properties - $tmp_module = LegacyModule::getInstanceByName($name); - foreach (['warning', 'name', 'tab', 'displayName', 'description', 'author', 'author_address', - 'limited_countries', 'need_instance', 'confirmUninstall', ] as $data_to_get) { - if (isset($tmp_module->{$data_to_get})) { - $main_class_attributes[$data_to_get] = $tmp_module->{$data_to_get}; - } - } - - $main_class_attributes['parent_class'] = get_parent_class($name); - $main_class_attributes['is_paymentModule'] = is_subclass_of($name, 'PaymentModule'); - $main_class_attributes['is_configurable'] = (int) method_exists($tmp_module, 'getContent'); - - $disk['is_valid'] = 1; - $disk['version'] = $tmp_module->version; - - $attributes = array_merge($attributes, $main_class_attributes); - } elseif (!$skip_main_class_attributes) { - $main_class_attributes['warning'] = 'Invalid module class'; - } else { - $disk['is_valid'] = 1; - } - - $this->cache[$name]['attributes'] = $main_class_attributes; - $this->cache[$name]['disk'] = $disk; - } - - // Get data from database - $database = $this->moduleProvider->findByName($name); - - $module = new Module($attributes, $disk, $database); - $this->loadedModules->save($name, $module); - if ($this->prestaTrustChecker) { - $this->prestaTrustChecker->loadDetailsIntoModule($module); - } - - return $module; - } - - public function getModuleAttributes($name) - { - $module = $this->getModule($name); - - return $module->attributes; - } - - /** - * Send request to get module details on the marketplace, then merge the data received in Module instance. - * - * @param $moduleId - * - * @return Module - */ - public function getModuleById($moduleId) - { - $moduleAttributes = $this->adminModuleProvider->getModuleAttributesById($moduleId); - - $module = $this->getModule($moduleAttributes['name']); - - foreach ($moduleAttributes as $name => $value) { - if (!$module->attributes->has($name)) { - $module->attributes->set($name, $value); - } - } - - return $module; - } - - /** - * Instanciate every module present in the modules folder. - * - * @param bool $skip_main_class_attributes - * - * @return \PrestaShop\PrestaShop\Adapter\Module\Module[] - */ - private function getModulesOnDisk($skip_main_class_attributes = false) - { - $modules = []; - $modulesDirsList = $this->finder->directories() - ->in($this->modulePath) - ->depth('== 0') - ->exclude(['__MACOSX']) - ->ignoreVCS(true); - - foreach ($modulesDirsList as $moduleDir) { - $moduleName = $moduleDir->getFilename(); - if (!file_exists($this->modulePath . $moduleName . '/' . $moduleName . '.php')) { - continue; - } - - try { - $module = $this->getModule($moduleName, $skip_main_class_attributes); - if ($module instanceof Module) { - $modules[$moduleName] = $module; - } - } catch (\ParseError $e) { - $this->logger->critical( - $this->translator->trans( - 'Parse error detected in module %module%. %error_details%.', - [ - '%module%' => $moduleName, - '%error_details%' => $e->getMessage(), ], - 'Admin.Modules.Notification' - ) - ); - } catch (Exception $e) { - $this->logger->critical( - $this->translator->trans( - 'Exception detected while loading module %module%. %error_details%.', - [ - '%module%' => $moduleName, - '%error_details%' => $e->getMessage(), ], - 'Admin.Modules.Notification' - ) - ); - } - } - - return $modules; - } - - /** - * Function loading all installed modules on the shop. Can be used as example for AddonListFilter use. - * - * @return array - */ - public function getInstalledModules() - { - $filters = new AddonListFilter(); - $filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE) - ->setStatus(AddonListFilterStatus::INSTALLED); - - return $this->getFilteredList($filters); - } - - /** - * Gets all installed modules as a collection. - * - * @return AddonsCollection - */ - public function getInstalledModulesCollection() - { - $installedModules = $this->getInstalledModules(); - - return AddonsCollection::createFrom($installedModules); - } - - /** - * Returns installed module filepaths. - * - * @return array - */ - public function getInstalledModulesPaths() - { - $paths = []; - $modulesFiles = Finder::create()->directories()->in(__DIR__ . '/../../../../modules')->depth(0); - $installedModules = array_keys($this->getInstalledModules()); - - foreach ($modulesFiles as $moduleFile) { - if (in_array($moduleFile->getFilename(), $installedModules)) { - $paths[] = $moduleFile->getPathname(); - } - } - - return $paths; - } -} diff --git a/src/Core/Addon/Module/ModuleRepositoryInterface.php b/src/Core/Addon/Module/ModuleRepositoryInterface.php deleted file mode 100644 index 3712c2fa..00000000 --- a/src/Core/Addon/Module/ModuleRepositoryInterface.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Module; - -use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; -use PrestaShop\PrestaShop\Core\Addon\AddonRepositoryInterface; - -interface ModuleRepositoryInterface extends AddonRepositoryInterface -{ - /** - * Get the **Legacy** Module object from its name - * Used for retrocompatibility. - * - * @param string $name The technical module name to instanciate - * - * @return \Module|null Instance of legacy Module, if valid - */ - public function getInstanceByName($name); - - /** - * @param AddonListFilter $filter - * - * @return AddonInterface[] retrieve a list of addons, regarding the $filter used - */ - public function getFilteredList(AddonListFilter $filter); - - /** - * @return AddonInterface[] retrieve a list of addons, regardless any $filter - */ - public function getList(); - - /** - * Get the new module presenter class of the specified name provided. - * It contains data from its instance, the disk, the database and from the marketplace if exists. - * - * @param string $name The technical name of the module - * - * @return \PrestaShop\PrestaShop\Adapter\Module\Module - */ - public function getModule($name); -} diff --git a/src/Core/Addon/Theme/Exception/ThemeAlreadyExistsException.php b/src/Core/Addon/Theme/Exception/ThemeAlreadyExistsException.php deleted file mode 100644 index 59c52d64..00000000 --- a/src/Core/Addon/Theme/Exception/ThemeAlreadyExistsException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class ThemeAlreadyExistsException - */ -class ThemeAlreadyExistsException extends CoreException -{ - /** - * @var string - */ - private $themeName; - - /** - * @param string $themeName - * @param string $message - * @param int $code - * @param null $previous - */ - public function __construct($themeName, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->themeName = $themeName; - } - - /** - * @return string - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Addon/Theme/Exception/ThemeUploadException.php b/src/Core/Addon/Theme/Exception/ThemeUploadException.php deleted file mode 100644 index 1c4fedda..00000000 --- a/src/Core/Addon/Theme/Exception/ThemeUploadException.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class ThemeUploadException - */ -class ThemeUploadException extends CoreException -{ - const FILE_SIZE_EXCEEDED_ERROR = 1; - const UNKNOWN_ERROR = 2; - const INVALID_MIME_TYPE = 3; - const FAILED_TO_MOVE_FILE = 4; -} diff --git a/src/Core/Addon/Theme/Theme.php b/src/Core/Addon/Theme/Theme.php deleted file mode 100644 index bc8e1c54..00000000 --- a/src/Core/Addon/Theme/Theme.php +++ /dev/null @@ -1,257 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use AbstractAssetManager; -use PrestaShop\PrestaShop\Core\Addon\AddonInterface; -use Shudrum\Component\ArrayFinder\ArrayFinder; -use Symfony\Component\Yaml\Yaml; - -class Theme implements AddonInterface -{ - private $attributes; - - public function __construct(array $attributes) - { - if (isset($attributes['parent'])) { - $parentAttributes = Yaml::parse(file_get_contents(_PS_ALL_THEMES_DIR_ . '/' . $attributes['parent'] . '/config/theme.yml')); - $parentAttributes['preview'] = 'themes/' . $attributes['parent'] . '/preview.png'; - $parentAttributes['parent_directory'] = rtrim($attributes['directory'], '/') . '/'; - $attributes = array_merge($parentAttributes, $attributes); - } - - $attributes['directory'] = rtrim($attributes['directory'], '/') . '/'; - - if (file_exists(_PS_ALL_THEMES_DIR_ . $attributes['name'] . '/preview.png')) { - $attributes['preview'] = 'themes/' . $attributes['name'] . '/preview.png'; - } - - $this->attributes = new ArrayFinder($attributes); - } - - public function get($attr = null, $default = null) - { - return $this->attributes->get($attr, $default); - } - - public function has($attr) - { - return $this->attributes->offsetExists($attr); - } - - public function getName() - { - return $this->attributes->get('name'); - } - - public function getDirectory() - { - return $this->attributes->get('directory'); - } - - public function getModulesToEnable() - { - $modulesToEnable = $this->get('global_settings.modules.to_enable', []); - $modulesToHook = $this->get('global_settings.hooks.modules_to_hook', []); - - foreach ($modulesToHook as $hookName => $modules) { - if (is_array($modules)) { - foreach (array_values($modules) as $module) { - if (is_array($module)) { - $module = key($module); - } - if (null !== $module && !in_array($module, $modulesToEnable)) { - $modulesToEnable[] = $module; - } - } - } - } - - return $modulesToEnable; - } - - public function getModulesToDisable() - { - return $this->get('dependencies.modules', []); - } - - public function getPageSpecificAssets($pageId) - { - return [ - 'css' => $this->getPageSpecificCss($pageId), - 'js' => $this->getPageSpecificJs($pageId), - ]; - } - - public function onInstall() - { - return true; - } - - public function onUninstall() - { - return true; - } - - /** - * Execute up files. You can update configuration, update sql schema. - * No file modification. - * - * @return bool true for success - */ - public function onUpgrade($version) - { - return true; - } - - /** - * Called when switching the current theme of the selected shop. - * You can update configuration, enable/disable modules... - * - * @return bool true for success - */ - public function onEnable() - { - return true; - } - - /** - * Not necessarily the opposite of enable. Use this method if - * something must be done when switching to another theme (like uninstall - * very specific modules for example). - * - * @return bool true for success - */ - public function onDisable() - { - return true; - } - - public function onReset() - { - return true; - } - - public function setPageLayouts(array $layouts) - { - $this->attributes->set('theme_settings.layouts', $layouts); - } - - public function getDefaultLayout() - { - $availableLayouts = $this->getAvailableLayouts(); - $defaultLayoutIdentifier = $this->attributes->get('theme_settings.default_layout'); - $defaultLayout = $availableLayouts[$defaultLayoutIdentifier]; - - $defaultLayout['key'] = $defaultLayoutIdentifier; - - return $defaultLayout; - } - - public function getPageLayouts() - { - return $this->attributes->get('theme_settings.layouts'); - } - - public function getAvailableLayouts() - { - return $this->attributes->get('meta.available_layouts'); - } - - public function getLayoutNameForPage($page) - { - $layout_name = $this->get('theme_settings.default_layout'); - if (isset($this->attributes['theme_settings']['layouts'][$page]) - && $this->attributes['theme_settings']['layouts'][$page]) { - $layout_name = $this->attributes['theme_settings']['layouts'][$page]; - } - - return $layout_name; - } - - public function getLayoutRelativePathForPage($page) - { - return 'layouts/' . $this->getLayoutNameForPage($page) . '.tpl'; - } - - private function getPageSpecificCss($pageId) - { - $css = array_merge( - (array) $this->get('assets.css.all'), - (array) $this->get('assets.css.' . $pageId) - ); - foreach ($css as $key => &$entry) { - // Required parameters - if (!isset($entry['id']) || !isset($entry['path'])) { - unset($css[$key]); - - continue; - } - if (!isset($entry['media'])) { - $entry['media'] = AbstractAssetManager::DEFAULT_MEDIA; - } - if (!isset($entry['priority'])) { - $entry['priority'] = AbstractAssetManager::DEFAULT_PRIORITY; - } - if (!isset($entry['inline'])) { - $entry['inline'] = false; - } - } - - return $css; - } - - private function getPageSpecificJs($pageId) - { - $js = array_merge( - (array) $this->get('assets.js.all'), - (array) $this->get('assets.js.' . $pageId) - ); - foreach ($js as $key => &$entry) { - // Required parameters - if (!isset($entry['id']) || !isset($entry['path'])) { - unset($js[$key]); - - continue; - } - if (!isset($entry['position'])) { - $entry['position'] = AbstractAssetManager::DEFAULT_JS_POSITION; - } - if (!isset($entry['priority'])) { - $entry['priority'] = AbstractAssetManager::DEFAULT_PRIORITY; - } - if (!isset($entry['inline'])) { - $entry['inline'] = false; - } - if (!isset($entry['attribute'])) { - $entry['attribute'] = false; - } - } - - return $js; - } -} diff --git a/src/Core/Addon/Theme/ThemeCollection.php b/src/Core/Addon/Theme/ThemeCollection.php deleted file mode 100644 index ae969796..00000000 --- a/src/Core/Addon/Theme/ThemeCollection.php +++ /dev/null @@ -1,269 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use ArrayAccess; -use ArrayIterator; -use Countable; -use IteratorAggregate; -use PrestaShop\PrestaShop\Core\Addon\Theme as Addon; - -/** - * An ArrayCollection is a Collection implementation that wraps a regular PHP array. - */ -class ThemeCollection implements ArrayAccess, Countable, IteratorAggregate -{ - /** - * An array containing the addons of this collection. - * - * @var array - */ - private $addons; - - /** - * Initializes a new AddonsCollection. - * - * @param array $addons - */ - public function __construct(array $addons = []) - { - $this->addons = $addons; - } - - /** - * Creates a new instance from the specified elements. - * - * This method is provided for derived classes to specify how a new - * instance should be created when constructor semantics have changed. - * - * @param array $addons elements - * - * @return static - */ - public static function createFrom(array $addons) - { - return new static($addons); - } - - /** - * Gets a native PHP array representation of the collection. - * - * @return array - */ - public function toArray() - { - return $this->addons; - } - - /** - * @return ArrayIterator|\Traversable - */ - public function getIterator() - { - return new ArrayIterator($this->addons); - } - - /** - * {@inheritdoc} - */ - public function offsetExists($offset) - { - return $this->containsKey($offset); - } - - /** - * {@inheritdoc} - */ - public function offsetGet($offset) - { - return $this->get($offset); - } - - /** - * Required by ArrayAccess interface. - * - * {@inheritdoc} - */ - public function offsetSet($offset, $addon) - { - if (!isset($offset)) { - $this->add($addon); - - return; - } - - $this->set($offset, $addon); - } - - /** - * Required by interface ArrayAccess. - * - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - $this->remove($offset); - } - - /** - * Returns true if the key is found in the collection. - * - * @param mixed $key the key, can be integer or string - * - * @return bool - */ - public function containsKey($key) - { - return isset($this->addons[$key]) || array_key_exists($key, $this->addons); - } - - /** - * Returns true if the addon is found in the collection. - * - * @param Addon $addon the addon - * - * @return bool - */ - public function contains(Addon $addon) - { - return in_array($addon, $this->addons, true); - } - - /** - * {@inheritdoc} - */ - public function indexOf(Addon $addon) - { - return array_search($addon, $this->addons, true); - } - - /** - * {@inheritdoc} - */ - public function get($key) - { - return $this->addons[$key] ? $this->addons[$key] : null; - } - - /** - * {@inheritdoc} - */ - public function getKeys() - { - return array_keys($this->addons); - } - - /** - * {@inheritdoc} - */ - public function getValues() - { - return array_values($this->addons); - } - - /** - * Add an Addon with a specified key in the collection. - * - * @param mixed $key the key - * @param Addon $addon the specified addon - */ - public function set($key, Addon $addon) - { - $this->addons[$key] = $addon; - } - - /** - * Add an Addon in the collection. - * - * @param Addon $addon the specified addon - * - * @return bool - */ - public function add(Addon $addon) - { - $this->addons[] = $addon; - - return true; - } - - /** - * Remove an addon from the collection by key. - * - * @param mixed the key (can be int or string) - * - * @return bool true if the addon has been found and removed - */ - public function removeByKey($key) - { - if (!isset($this->addons[$key]) && !array_key_exists($key, $this->addons)) { - return null; - } - - $removed = $this->addons[$key]; - unset($this->addons[$key]); - - return $removed; - } - - /** - * Remove an addon from the collection by key. - * - * @param Addon $addon the addon to be removed - * - * @return bool true if the addon has been found and removed - */ - public function remove(Addon $addon) - { - $key = array_search($addon, $this->addons, true); - - if ($key === false) { - return false; - } - - unset($this->addons[$key]); - - return true; - } - - /** - * {@inheritdoc} - */ - public function isEmpty() - { - return empty($this->addons); - } - - /** - * Gets the sum of addons of the collection. - * - * @return int - */ - public function count() - { - return count($this->addons); - } -} diff --git a/src/Core/Addon/Theme/ThemeExporter.php b/src/Core/Addon/Theme/ThemeExporter.php deleted file mode 100644 index cc14c122..00000000 --- a/src/Core/Addon/Theme/ThemeExporter.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShopBundle\Entity\Repository\LangRepository; -use PrestaShopBundle\Translation\Exporter\ThemeExporter as TranslationsExporter; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use ZipArchive; - -class ThemeExporter -{ - protected $configuration; - protected $fileSystem; - protected $langRepository; - protected $translationsExporter; - - public function __construct( - ConfigurationInterface $configuration, - Filesystem $fileSystem, - LangRepository $langRepository, - TranslationsExporter $translationsExporter - ) { - $this->configuration = $configuration; - $this->fileSystem = $fileSystem; - $this->langRepository = $langRepository; - $this->translationsExporter = $translationsExporter; - } - - public function export(Theme $theme) - { - $cacheDir = $this->configuration->get('_PS_CACHE_DIR_') . 'export-' . $theme->getName() . '-' . time() . DIRECTORY_SEPARATOR; - - $this->copyTheme($theme->getDirectory(), $cacheDir); - $this->copyModuleDependencies((array) $theme->get('dependencies.modules'), $cacheDir); - $this->copyTranslations($theme, $cacheDir); - - $finalFile = $this->configuration->get('_PS_ALL_THEMES_DIR_') . DIRECTORY_SEPARATOR . $theme->getName() . '.zip'; - $this->createZip($cacheDir, $finalFile); - - $this->fileSystem->remove($cacheDir); - - return realpath($finalFile); - } - - private function copyTheme($themeDir, $cacheDir) - { - $fileList = Finder::create() - ->files() - ->in($themeDir) - ->exclude(['node_modules']); - - $this->fileSystem->mirror($themeDir, $cacheDir, $fileList); - } - - private function copyModuleDependencies(array $moduleList, $cacheDir) - { - if (empty($moduleList)) { - return; - } - - $dependencyDir = $cacheDir . '/dependencies/modules/'; - $this->fileSystem->mkdir($dependencyDir); - $moduleDir = $this->configuration->get('_PS_MODULE_DIR_'); - - foreach ($moduleList as $moduleName) { - $this->fileSystem->mirror($moduleDir . $moduleName, $dependencyDir . $moduleName); - } - } - - /** - * @param Theme $theme - * @param $cacheDir - */ - protected function copyTranslations(Theme $theme, $cacheDir) - { - $translationsDir = $cacheDir . 'translations'; - - $this->fileSystem->remove($translationsDir); - $this->fileSystem->mkdir($translationsDir); - - $languages = $this->langRepository->findAll(); - if (count($languages) > 0) { - /* - * @var \PrestaShopBundle\Entity\Lang - */ - foreach ($languages as $lang) { - $locale = $lang->getLocale(); - $catalogueDir = $this->translationsExporter->exportCatalogues($theme->getName(), $locale); - } - - $catalogueDirParts = explode(DIRECTORY_SEPARATOR, $catalogueDir); - array_pop($catalogueDirParts); // Remove locale - - $cataloguesDir = implode(DIRECTORY_SEPARATOR, $catalogueDirParts); - $this->fileSystem->mirror($cataloguesDir, $translationsDir); - } - } - - private function createZip($sourceDir, $destinationFileName) - { - $zip = new ZipArchive(); - $zip->open($destinationFileName, ZipArchive::CREATE); - - $files = Finder::create() - ->files() - ->in($sourceDir) - ->exclude(['node_modules']); - - foreach ($files as $file) { - $zip->addFile($file->getRealpath(), $file->getRelativePathName()); - } - - return $zip->close(); - } -} diff --git a/src/Core/Addon/Theme/ThemeManager.php b/src/Core/Addon/Theme/ThemeManager.php deleted file mode 100644 index 2bc9a12c..00000000 --- a/src/Core/Addon/Theme/ThemeManager.php +++ /dev/null @@ -1,603 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use Employee; -use ErrorException; -use Exception; -use Language; -use PrestaShop\PrestaShop\Core\Addon\AddonManagerInterface; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder; -use PrestaShop\PrestaShop\Core\Addon\Theme\Exception\ThemeAlreadyExistsException; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\FailedToEnableThemeModuleException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ThemeConstraintException; -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem as PsFileSystem; -use PrestaShop\PrestaShop\Core\Image\ImageTypeRepository; -use PrestaShop\PrestaShop\Core\Module\HookConfigurator; -use PrestaShopBundle\Service\TranslationService; -use PrestaShopBundle\Translation\Provider\TranslationFinder; -use PrestaShopLogger; -use Shop; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Yaml\Parser; -use Tools; - -class ThemeManager implements AddonManagerInterface -{ - /** - * @var HookConfigurator - */ - private $hookConfigurator; - - /** - * @var Shop - */ - private $shop; - - /** - * @var Employee - */ - private $employee; - - /** - * @var ThemeValidator - */ - private $themeValidator; - - /** - * @var ConfigurationInterface - */ - private $appConfiguration; - - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var Finder - */ - private $finder; - - /** - * @var ThemeRepository - */ - private $themeRepository; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ImageTypeRepository - */ - private $imageTypeRepository; - - /** - * @var TranslationFinder - */ - private $translationFinder; - - public function __construct( - Shop $shop, - ConfigurationInterface $configuration, - ThemeValidator $themeValidator, - TranslatorInterface $translator, - Employee $employee, - Filesystem $filesystem, - Finder $finder, - HookConfigurator $hookConfigurator, - ThemeRepository $themeRepository, - ImageTypeRepository $imageTypeRepository - ) { - $this->translationFinder = new TranslationFinder(); - $this->shop = $shop; - $this->appConfiguration = $configuration; - $this->themeValidator = $themeValidator; - $this->translator = $translator; - $this->employee = $employee; - $this->filesystem = $filesystem; - $this->finder = $finder; - $this->hookConfigurator = $hookConfigurator; - $this->themeRepository = $themeRepository; - $this->imageTypeRepository = $imageTypeRepository; - } - - /** - * Add new theme from zipball. This will unzip the file and move the content - * to the right locations. - * A theme can bundle modules, resources, documentation, email templates and so on. - * - * @param string $source The source can be a module name (installed from either local disk or addons.prestashop.com). - * or a location (url or path to the zip file) - * - * @return bool true for success - */ - public function install($source) - { - if ((filter_var($source, FILTER_VALIDATE_URL))) { - $source = Tools::createFileFromUrl($source); - } - if (preg_match('/\.zip$/', $source)) { - $this->installFromZip($source); - } - - return true; - } - - /** - * Remove all theme files, resources, documentation and specific modules. - * - * @param $name The source can be a module name (installed from either local disk or addons.prestashop.com). - * or a location (url or path to the zip file) - * - * @return bool true for success - */ - public function uninstall($name) - { - if (!$this->employee->can('delete', 'AdminThemes')) { - return false; - } - - $theme = $this->themeRepository->getInstanceByName($name); - $theme->onUninstall(); - - $this->filesystem->remove($theme->getDirectory()); - - return true; - } - - /** - * Download new files from source, backup old files, replace files with new ones - * and execute all necessary migration scripts form current version to the new one. - * - * @param string $name - * @param string $version the version you want to up upgrade to - * @param string $source if the upgrade is not coming from addons, you need to specify the path to the zipball - * - * @return bool true for success - */ - public function upgrade($name, $version, $source = null) - { - return true; - } - - /** - * Actions to perform when switching from another theme to this one. - * Example: - * - update configuration - * - enable/disable modules. - * - * @param string $name The theme name to enable - * @param bool $force bypass user privilege checks - * - * @return bool True for success - */ - public function enable($name, $force = false) - { - if (!$force && !$this->employee->can('edit', 'AdminThemes')) { - return false; - } - - /* if file exits, remove it and use YAML configuration file instead */ - @unlink($this->appConfiguration->get('_PS_CONFIG_DIR_') . 'themes/' . $name . '/shop' . $this->shop->id . '.json'); - - $theme = $this->themeRepository->getInstanceByName($name); - if (!$this->themeValidator->isValid($theme)) { - return false; - } - - $this->disable($this->shop->theme_name); - - $this->doCreateCustomHooks($theme->get('global_settings.hooks.custom_hooks', [])) - ->doApplyConfiguration($theme->get('global_settings.configuration', [])) - ->doDisableModules($theme->get('global_settings.modules.to_disable', [])) - ->doEnableModules($theme->getModulesToEnable()) - ->doResetModules($theme->get('global_settings.modules.to_reset', [])) - ->doApplyImageTypes($theme->get('global_settings.image_types')) - ->doHookModules($theme->get('global_settings.hooks.modules_to_hook')); - - $theme->onEnable(); - - $this->shop->theme_name = $theme->getName(); - $this->shop->update(); - - $this->saveTheme($theme); - - return $this; - } - - /** - * Actions to perform when switching from this theme to another one. - * - * @param string $name The theme name to enable - * - * @return bool True for success - */ - public function disable($name) - { - $theme = $this->themeRepository->getInstanceByName($name); - $theme->getModulesToDisable(); - - $this->doDisableModules($theme->getModulesToDisable()); - - @unlink($this->appConfiguration->get('_PS_CONFIG_DIR_') . 'themes/' . $name . '/shop' . $this->shop->id . '.json'); - - return true; - } - - /** - * Actions to perform to restore default settings. - * - * @param string $themeName The theme name to reset - * - * @return bool True for success - */ - public function reset($themeName) - { - return $this->disable($themeName) && $this->enable($themeName); - } - - /** - * Returns the last error, if found. - * - * @param string $themeName The technical theme name - * - * @return string|null The last error if found - */ - public function getError($themeName) - { - } - - /** - * Get all errors of theme install. - * - * @param string $themeName The technical theme name - * - * @return array|string|bool - */ - public function getErrors($themeName) - { - return $this->themeValidator->getErrors($themeName); - } - - private function doCreateCustomHooks(array $hooks) - { - foreach ($hooks as $hook) { - $this->hookConfigurator->addHook( - $hook['name'], - $hook['title'], - $hook['description'] - ); - } - - return $this; - } - - private function doApplyConfiguration(array $configuration) - { - foreach ($configuration as $key => $value) { - $this->appConfiguration->set($key, $value); - } - - return $this; - } - - private function doDisableModules(array $modules) - { - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManager = $moduleManagerBuilder->build(); - - foreach ($modules as $key => $moduleName) { - if ($moduleManager->isInstalled($moduleName) && $moduleManager->isEnabled($moduleName)) { - $moduleManager->disable($moduleName); - } - } - - return $this; - } - - /** - * @param array $modules - * - * @return $this - * - * @throws FailedToEnableThemeModuleException - */ - private function doEnableModules(array $modules) - { - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManager = $moduleManagerBuilder->build()->setActionParams(['confirmPrestaTrust' => true]); - - foreach ($modules as $key => $moduleName) { - if (!$moduleManager->isInstalled($moduleName) - && !$moduleManager->install($moduleName) - ) { - throw new FailedToEnableThemeModuleException($moduleName, $moduleManager->getError($moduleName)); - } - if (!$moduleManager->isEnabled($moduleName)) { - $moduleManager->enable($moduleName); - } - } - - return $this; - } - - /** - * Reset the modules received in parameters if they are installed and enabled. - * - * @param string[] $modules - * - * @return $this - */ - private function doResetModules(array $modules) - { - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManager = $moduleManagerBuilder->build(); - - foreach ($modules as $moduleName) { - if ($moduleManager->isInstalled($moduleName)) { - $moduleManager->reset($moduleName); - } - } - - return $this; - } - - private function doHookModules(array $hooks) - { - $this->hookConfigurator->setHooksConfiguration($hooks); - - return $this; - } - - private function doApplyImageTypes(array $types) - { - $this->imageTypeRepository->setTypes($types); - - return $this; - } - - /** - * @param $source - * - * @throws ThemeAlreadyExistsException - * @throws ThemeConstraintException - */ - private function installFromZip($source) - { - /** @var Finder $finderClass */ - $finderClass = get_class($this->finder); - $this->finder = $finderClass::create(); - - $sandboxPath = $this->getSandboxPath(); - Tools::ZipExtract($source, $sandboxPath); - - $themeConfigurationFile = $sandboxPath . '/config/theme.yml'; - - if (!file_exists($themeConfigurationFile)) { - throw new ThemeConstraintException('Missing theme configuration file which should be in located in /config/theme.yml', ThemeConstraintException::MISSING_CONFIGURATION_FILE); - } - - $theme_data = (new Parser())->parse(file_get_contents($themeConfigurationFile)); - - $theme_data['directory'] = $sandboxPath; - - try { - $theme = new Theme($theme_data); - } catch (ErrorException $exception) { - throw new ThemeConstraintException(sprintf('Theme data %s is not valid', var_export($theme_data, true)), ThemeConstraintException::INVALID_DATA, $exception); - } - - if (!$this->themeValidator->isValid($theme)) { - $this->filesystem->remove($sandboxPath); - - $this->themeValidator->getErrors($theme->getName()); - - throw new ThemeConstraintException(sprintf('Theme configuration file is not valid - %s', var_export($this->themeValidator->getErrors($theme->getName()), true)), ThemeConstraintException::INVALID_CONFIGURATION); - } - - $module_root_dir = $this->appConfiguration->get('_PS_MODULE_DIR_'); - $modules_parent_dir = $sandboxPath . '/dependencies/modules'; - if ($this->filesystem->exists($modules_parent_dir)) { - $module_dirs = $this->finder->directories() - ->in($modules_parent_dir) - ->depth('== 0'); - /** @var SplFileInfo $dir */ - foreach (iterator_to_array($module_dirs) as $dir) { - $destination = $module_root_dir . basename($dir->getFileName()); - if (!$this->filesystem->exists($destination)) { - $this->filesystem->mkdir($destination); - } - $this->filesystem->mirror($dir->getPathName(), $destination); - } - $this->filesystem->remove($modules_parent_dir); - } - - $themePath = $this->appConfiguration->get('_PS_ALL_THEMES_DIR_') . $theme->getName(); - if ($this->filesystem->exists($themePath)) { - throw new ThemeAlreadyExistsException($theme->getName(), $this->translator->trans('There is already a theme named ' . $theme->getName() . ' in your themes/ folder. Remove it if you want to continue.', [], 'Admin.Design.Notification')); - } - - $this->filesystem->mkdir($themePath); - $this->filesystem->mirror($sandboxPath, $themePath); - - $this->importTranslationToDatabase($theme); - - $this->filesystem->remove($sandboxPath); - } - - private function getSandboxPath() - { - if (!isset($this->sandbox)) { - $this->sandbox = $this->appConfiguration->get('_PS_CACHE_DIR_') . 'sandbox/' . uniqid() . '/'; - $this->filesystem->mkdir($this->sandbox, PsFileSystem::DEFAULT_MODE_FOLDER); - } - - return $this->sandbox; - } - - /** - * @param Theme $theme - */ - public function saveTheme($theme) - { - $jsonConfigFolder = $this->appConfiguration->get('_PS_CONFIG_DIR_') . 'themes/' . $theme->getName(); - if (!$this->filesystem->exists($jsonConfigFolder) && !is_dir($jsonConfigFolder)) { - mkdir($jsonConfigFolder, PsFileSystem::DEFAULT_MODE_FOLDER, true); - } - - file_put_contents( - $jsonConfigFolder . '/shop' . $this->shop->id . '.json', - json_encode($theme->get(null)) - ); - } - - /** - * Import translation from Theme to Database. - * - * @param Theme $theme - */ - private function importTranslationToDatabase(Theme $theme) - { - global $kernel; // sf kernel - - if (!(null !== $kernel && $kernel instanceof \Symfony\Component\HttpKernel\KernelInterface)) { - return; - } - - $translationService = $kernel->getContainer()->get('prestashop.service.translation'); - $themeProvider = $kernel->getContainer()->get('prestashop.translation.theme_provider'); - - $themeName = $theme->getName(); - $themePath = $this->appConfiguration->get('_PS_ALL_THEMES_DIR_') . $themeName; - $translationFolder = $themePath . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR; - - $languages = Language::getLanguages(); - foreach ($languages as $language) { - $locale = $language['locale']; - - // retrieve Lang doctrine entity - try { - $lang = $translationService->findLanguageByLocale($locale); - } catch (Exception $exception) { - PrestaShopLogger::addLog('ThemeManager->importTranslationToDatabase() - Locale ' . $locale . ' does not exists'); - - continue; - } - - // check if translation dir for this lang exists - if (!is_dir($translationFolder . $locale)) { - continue; - } - - try { - // construct a new catalog for this lang and import in database if key and message are different - $messageCatalog = $this->translationFinder->getCatalogueFromPaths( - $translationFolder . $locale, - $locale - ); - - // get all default domain from catalog - $allDomains = $this->getDefaultDomains($locale, $themeProvider); - - // do the import - $this->handleImport($translationService, $messageCatalog, $allDomains, $lang, $locale, $themeName); - } catch (FileNotFoundException $e) { - // if the directory is there but there are no files, do nothing - } - } - } - - /** - * Get all default domain from catalog. - * - * @param string $locale - * @param \PrestaShopBundle\Translation\Provider\ThemeProvider $themeProvider - * - * @return array - */ - private function getDefaultDomains($locale, $themeProvider) - { - $allDomains = []; - - $defaultCatalogue = $themeProvider - ->setLocale($locale) - ->getDefaultCatalogue(); - - if (empty($defaultCatalogue)) { - return $allDomains; - } - - $defaultCatalogue = $defaultCatalogue->all(); - - if (empty($defaultCatalogue)) { - return $allDomains; - } - - foreach (array_keys($defaultCatalogue) as $domain) { - // AdminCatalogFeature.fr-FR to AdminCatalogFeature - $domain = str_replace('.' . $locale, '', $domain); - - $allDomains[] = $domain; - } - - return $allDomains; - } - - /** - * @param TranslationService $translationService - * @param MessageCatalogue $messageCatalog - * @param array $allDomains - * @param \PrestaShopBundle\Entity\Lang $lang - * @param string $locale - * @param string $themeName - */ - private function handleImport(TranslationService $translationService, MessageCatalogue $messageCatalog, $allDomains, $lang, $locale, $themeName) - { - foreach ($messageCatalog->all() as $domain => $messages) { - $domain = str_replace('.' . $locale, '', $domain); - - if (in_array($domain, $allDomains)) { - continue; - } - - foreach ($messages as $key => $message) { - if ($key !== $message) { - $translationService->saveTranslationMessage($lang, $domain, $key, $message, $themeName); - } - } - } - } -} diff --git a/src/Core/Addon/Theme/ThemeManagerBuilder.php b/src/Core/Addon/Theme/ThemeManagerBuilder.php deleted file mode 100644 index c5a9e99c..00000000 --- a/src/Core/Addon/Theme/ThemeManagerBuilder.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use Context; -use Db; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Hook\HookInformationProvider; -use PrestaShop\PrestaShop\Core\Image\ImageTypeRepository; -use PrestaShop\PrestaShop\Core\Module\HookConfigurator; -use PrestaShop\PrestaShop\Core\Module\HookRepository; -use Shop; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; - -class ThemeManagerBuilder -{ - private $context; - private $db; - - public function __construct(Context $context, Db $db) - { - $this->context = $context; - $this->db = $db; - } - - public function build() - { - $configuration = new Configuration(); - $configuration->restrictUpdatesTo($this->context->shop); - - return new ThemeManager( - $this->context->shop, - $configuration, - new ThemeValidator($this->context->getTranslator(), new Configuration()), - $this->context->getTranslator(), - $this->context->employee, - new Filesystem(), - new Finder(), - new HookConfigurator( - new HookRepository( - new HookInformationProvider(), - $this->context->shop, - $this->db - ) - ), - $this->buildRepository($this->context->shop), - new ImageTypeRepository( - $this->context->shop, - $this->db - ) - ); - } - - public function buildRepository(Shop $shop = null) - { - if (!$shop instanceof Shop) { - $shop = $this->context->shop; - } - - $configuration = new Configuration(); - $configuration->restrictUpdatesTo($shop); - - return new ThemeRepository( - $configuration, - new Filesystem(), - $shop - ); - } -} diff --git a/src/Core/Addon/Theme/ThemePageLayoutsCustomizer.php b/src/Core/Addon/Theme/ThemePageLayoutsCustomizer.php deleted file mode 100644 index 27f8a0fa..00000000 --- a/src/Core/Addon/Theme/ThemePageLayoutsCustomizer.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; - -/** - * Class PagesLayoutCustomizer customizes pages layout for shop's Front Office theme. - */ -final class ThemePageLayoutsCustomizer implements ThemePageLayoutsCustomizerInterface -{ - /** - * @var Theme - */ - private $theme; - - /** - * @var ThemeManager - */ - private $themeManager; - - /** - * @var CacheClearerInterface - */ - private $smartyCacheClearer; - - /** - * @param Theme $theme - * @param ThemeManager $themeManager - * @param CacheClearerInterface $smartyCacheClearer - */ - public function __construct(Theme $theme, ThemeManager $themeManager, CacheClearerInterface $smartyCacheClearer) - { - $this->theme = $theme; - $this->themeManager = $themeManager; - $this->smartyCacheClearer = $smartyCacheClearer; - } - - /** - * {@inheritdoc} - */ - public function customize(array $pageLayouts) - { - $this->theme->setPageLayouts($pageLayouts); - $this->themeManager->saveTheme($this->theme); - - $this->smartyCacheClearer->clear(); - } -} diff --git a/src/Core/Addon/Theme/ThemePageLayoutsCustomizerInterface.php b/src/Core/Addon/Theme/ThemePageLayoutsCustomizerInterface.php deleted file mode 100644 index 891d9c15..00000000 --- a/src/Core/Addon/Theme/ThemePageLayoutsCustomizerInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -/** - * Interface PageLayoutCustomizerInterface. - */ -interface ThemePageLayoutsCustomizerInterface -{ - /** - * @param array $pageLayouts Customized layouts for pages - */ - public function customize(array $pageLayouts); -} diff --git a/src/Core/Addon/Theme/ThemeProvider.php b/src/Core/Addon/Theme/ThemeProvider.php deleted file mode 100644 index 453333c9..00000000 --- a/src/Core/Addon/Theme/ThemeProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -/** - * Class ThemeProvider - */ -final class ThemeProvider implements ThemeProviderInterface -{ - /** - * @var ThemeRepository - */ - private $themeRepository; - - /** - * @var Theme - */ - private $theme; - - /** - * @param ThemeRepository $themeRepository - * @param Theme $theme - */ - public function __construct(ThemeRepository $themeRepository, Theme $theme) - { - $this->themeRepository = $themeRepository; - $this->theme = $theme; - } - - /** - * {@inheritdoc} - */ - public function getCurrentlyUsedTheme() - { - return $this->theme; - } - - /** - * {@inheritdoc} - */ - public function getNotUsedThemes() - { - return $this->themeRepository->getListExcluding([ - $this->getCurrentlyUsedTheme()->getName(), - ]); - } -} diff --git a/src/Core/Addon/Theme/ThemeProviderInterface.php b/src/Core/Addon/Theme/ThemeProviderInterface.php deleted file mode 100644 index 1696ad43..00000000 --- a/src/Core/Addon/Theme/ThemeProviderInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -/** - * Interface ThemeProviderInterface - */ -interface ThemeProviderInterface -{ - /** - * Get currently used theme for context shop. - * - * @return Theme - */ - public function getCurrentlyUsedTheme(); - - /** - * Get not used themes for context shop. - * - * @return Theme[] - */ - public function getNotUsedThemes(); -} diff --git a/src/Core/Addon/Theme/ThemeRepository.php b/src/Core/Addon/Theme/ThemeRepository.php deleted file mode 100644 index 22c278c7..00000000 --- a/src/Core/Addon/Theme/ThemeRepository.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; -use PrestaShop\PrestaShop\Core\Addon\AddonRepositoryInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem as PsFileSystem; -use PrestaShopException; -use Shop; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Yaml\Parser; - -class ThemeRepository implements AddonRepositoryInterface -{ - private $appConfiguration; - private $filesystem; - private $shop; - - public function __construct(ConfigurationInterface $configuration, Filesystem $filesystem, Shop $shop = null) - { - $this->appConfiguration = $configuration; - $this->filesystem = $filesystem; - $this->shop = $shop; - } - - public function getInstanceByName($name) - { - $dir = $this->appConfiguration->get('_PS_ALL_THEMES_DIR_') . $name; - - $confDir = $this->appConfiguration->get('_PS_CONFIG_DIR_') . 'themes/' . $name; - $jsonConf = $confDir . '/theme.json'; - if ($this->shop) { - $jsonConf = $confDir . '/shop' . $this->shop->id . '.json'; - } - - if ($this->filesystem->exists($jsonConf)) { - $data = $this->getConfigFromFile($jsonConf); - } else { - $data = $this->getConfigFromFile($dir . '/config/theme.yml'); - - // Write parsed yml data into json conf (faster parsing next time) - $this->filesystem->dumpFile($jsonConf, json_encode($data), PsFileSystem::DEFAULT_MODE_FILE); - } - - $data['directory'] = $dir; - - return new Theme($data); - } - - public function getList() - { - if (!isset($this->themes)) { - $this->themes = $this->getFilteredList(new AddonListFilter()); - } - - return $this->themes; - } - - /** - * Gets list of themes as a collection. - * - * @return ThemeCollection - */ - public function getListAsCollection() - { - $list = $this->getList(); - - return ThemeCollection::createFrom($list); - } - - public function getListExcluding(array $exclude) - { - $filter = (new AddonListFilter()) - ->setExclude($exclude); - - return $this->getFilteredList($filter); - } - - public function getFilteredList(AddonListFilter $filter) - { - $filter->setType(AddonListFilterType::THEME); - - if (!isset($filter->status)) { - $filter->setStatus(AddonListFilterStatus::ALL); - } - - $themes = $this->getThemesOnDisk(); - - if (count($filter->exclude) > 0) { - foreach ($filter->exclude as $name) { - unset($themes[$name]); - } - } - - return $themes; - } - - private function getThemesOnDisk() - { - $suffix = 'config/theme.yml'; - $themeDirectories = glob($this->appConfiguration->get('_PS_ALL_THEMES_DIR_') . '*/' . $suffix, GLOB_NOSORT); - - $themes = []; - foreach ($themeDirectories as $directory) { - $name = basename(substr($directory, 0, -strlen($suffix))); - $theme = $this->getInstanceByName($name); - if (isset($theme)) { - $themes[$name] = $theme; - } - } - - return $themes; - } - - private function getConfigFromFile($file) - { - if (!$this->filesystem->exists($file)) { - throw new PrestaShopException(sprintf('[ThemeRepository] Theme configuration file not found for theme at `%s`.', $file)); - } - - $content = file_get_contents($file); - - if (preg_match('/.\.(yml|yaml)$/', $file)) { - return (new Parser())->parse($content); - } elseif (preg_match('/.\.json$/', $file)) { - return json_decode($content, true); - } - } -} diff --git a/src/Core/Addon/Theme/ThemeUploaderInterface.php b/src/Core/Addon/Theme/ThemeUploaderInterface.php deleted file mode 100644 index 64694ced..00000000 --- a/src/Core/Addon/Theme/ThemeUploaderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Interface ThemeUploaderInterface - */ -interface ThemeUploaderInterface -{ - /** - * @param UploadedFile $uploadedTheme - * - * @return string Path to uploaded theme - */ - public function upload(UploadedFile $uploadedTheme); -} diff --git a/src/Core/Addon/Theme/ThemeValidator.php b/src/Core/Addon/Theme/ThemeValidator.php deleted file mode 100644 index be15933f..00000000 --- a/src/Core/Addon/Theme/ThemeValidator.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\Translation\TranslatorInterface; - -class ThemeValidator -{ - /** - * Translator. - * - * @var \Symfony\Component\Translation\TranslatorInterface - */ - private $translator; - private $appConfiguration; - - private $errors = []; - - public function __construct(TranslatorInterface $translator, ConfigurationInterface $configuration) - { - $this->translator = $translator; - $this->appConfiguration = $configuration; - } - - public function getErrors($themeName) - { - return array_key_exists($themeName, $this->errors) ? $this->errors[$themeName] : false; - } - - public function isValid(Theme $theme) - { - return $this->hasRequiredFiles($theme) - && $this->hasRequiredProperties($theme); - } - - private function hasRequiredProperties(Theme $theme) - { - $themeName = $theme->getName(); - - foreach ($this->getRequiredProperties() as $prop) { - if (!$theme->has($prop)) { - if (!array_key_exists($themeName, $this->errors)) { - $this->errors[$themeName] = []; - } - - $this->errors[$themeName] = $this->translator->trans( - 'An error occurred. The information "%s" is missing.', - [$prop], - 'Admin.Design.Notification' - ); - } - } - - return !array_key_exists($themeName, $this->errors); - } - - public function getRequiredProperties() - { - return [ - 'name', - 'display_name', - 'version', - 'author.name', - 'meta.compatibility.from', - 'meta.available_layouts', - 'global_settings.image_types.cart_default', - 'global_settings.image_types.small_default', - 'global_settings.image_types.medium_default', - 'global_settings.image_types.large_default', - 'global_settings.image_types.home_default', - 'global_settings.image_types.category_default', - 'theme_settings.default_layout', - ]; - } - - private function hasRequiredFiles(Theme $theme) - { - $themeName = $theme->getName(); - $parentDir = realpath($this->appConfiguration->get('_PS_ALL_THEMES_DIR_') . $theme->get('parent')) . '/'; - $parentFile = false; - - foreach ($this->getRequiredFiles() as $file) { - $childFile = $theme->getDirectory() . $file; - if ($theme->get('parent')) { - $parentFile = $parentDir . $file; - } - - if (!file_exists($childFile) && !file_exists($parentFile)) { - if (!array_key_exists($themeName, $this->errors)) { - $this->errors[$themeName] = []; - } - - $this->errors[$themeName] = $this->translator->trans('An error occurred. The template "%s" is missing.', [$file], 'Admin.Design.Notification'); - } - } - - return !array_key_exists($themeName, $this->errors); - } - - public function getRequiredFiles() - { - return [ - 'preview.png', - 'config/theme.yml', - 'assets/js/theme.js', - 'assets/css/theme.css', - // Templates - 'templates/_partials/form-fields.tpl', - 'templates/catalog/product.tpl', - 'templates/catalog/listing/product-list.tpl', - 'templates/checkout/cart.tpl', - 'templates/checkout/checkout.tpl', - 'templates/cms/category.tpl', - 'templates/cms/page.tpl', - 'templates/customer/address.tpl', - 'templates/customer/addresses.tpl', - 'templates/customer/guest-tracking.tpl', - 'templates/customer/guest-login.tpl', - 'templates/customer/history.tpl', - 'templates/customer/identity.tpl', - 'templates/index.tpl', - 'templates/customer/my-account.tpl', - 'templates/checkout/order-confirmation.tpl', - 'templates/customer/order-detail.tpl', - 'templates/customer/order-follow.tpl', - 'templates/customer/order-return.tpl', - 'templates/customer/order-slip.tpl', - 'templates/errors/404.tpl', - 'templates/errors/forbidden.tpl', - 'templates/checkout/cart-empty.tpl', - 'templates/cms/sitemap.tpl', - 'templates/cms/stores.tpl', - 'templates/customer/authentication.tpl', - 'templates/customer/registration.tpl', - 'templates/contact.tpl', - ]; - } -} diff --git a/src/Core/Addon/Theme/ThemeZipUploader.php b/src/Core/Addon/Theme/ThemeZipUploader.php deleted file mode 100644 index dfae9b04..00000000 --- a/src/Core/Addon/Theme/ThemeZipUploader.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Addon\Theme; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Exception\ThemeUploadException; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class ThemeZipUploader uploads theme to local filesystem. - */ -final class ThemeZipUploader implements ThemeUploaderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function upload(UploadedFile $uploadedTheme) - { - $this->assertThemeWasUploadedWithoutErrors($uploadedTheme); - $this->assertUploadedFileIsZip($uploadedTheme); - - $themesDir = $this->configuration->get('_PS_ALL_THEMES_DIR_'); - $destination = $themesDir . $uploadedTheme->getClientOriginalName(); - - if (!preg_match('/^[a-zA-Z0-9_.-]+$/', $uploadedTheme->getClientOriginalName())) { - $destination = $themesDir . sha1_file($uploadedTheme->getPathname()) . '.zip'; - } - - move_uploaded_file( - $uploadedTheme->getPathname(), - $destination - ); - - return $destination; - } - - /** - * @param UploadedFile $uploadedTheme - * - * @throws ThemeUploadException - */ - private function assertThemeWasUploadedWithoutErrors(UploadedFile $uploadedTheme) - { - if (UPLOAD_ERR_OK === $uploadedTheme->getError()) { - return; - } - - if (in_array($uploadedTheme->getError(), [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE])) { - throw new ThemeUploadException('Allowed file size exceeded for uploaded theme.', ThemeUploadException::FILE_SIZE_EXCEEDED_ERROR); - } - - throw new ThemeUploadException(sprintf('Unknown error "%s" occurred while uploading theme.', $uploadedTheme->getError()), ThemeUploadException::UNKNOWN_ERROR); - } - - /** - * @param UploadedFile $uploadedTheme - * - * @throws ThemeUploadException - */ - private function assertUploadedFileIsZip(UploadedFile $uploadedTheme) - { - preg_match('#application/zip#', $uploadedTheme->getMimeType(), $matches); - - if (empty($matches)) { - throw new ThemeUploadException('Invalid mime type of theme zip. Allowed mime type is application/zip.', ThemeUploadException::INVALID_MIME_TYPE); - } - } -} diff --git a/src/Core/AttributeGroup/AttributeGroupViewDataProviderInterface.php b/src/Core/AttributeGroup/AttributeGroupViewDataProviderInterface.php deleted file mode 100644 index d00e3152..00000000 --- a/src/Core/AttributeGroup/AttributeGroupViewDataProviderInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\AttributeGroup; - -/** - * Defines contract for services that provides attribute group view action data - */ -interface AttributeGroupViewDataProviderInterface -{ - /** - * @param int $attributeGroupId - * - * @return bool - */ - public function isColorGroup($attributeGroupId); - - /** - * Provides the name of attribute group by its id - * - * @param int $attributeGroupId - * - * @return string - */ - public function getAttributeGroupNameById($attributeGroupId); -} diff --git a/src/Core/B2b/B2bFeature.php b/src/Core/B2b/B2bFeature.php deleted file mode 100644 index 7b8b7f3c..00000000 --- a/src/Core/B2b/B2bFeature.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\B2b; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; - -/** - * Class B2bFeature checks manages B2B status. - */ -final class B2bFeature implements FeatureInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isUsed() - { - return $this->isActive(); - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return (bool) $this->configuration->get('PS_B2B_ENABLE'); - } - - /** - * {@inheritdoc} - */ - public function enable() - { - $this->configuration->set('PS_B2B_ENABLE', 1); - } - - /** - * {@inheritdoc} - */ - public function disable() - { - $this->configuration->set('PS_B2B_ENABLE', 0); - } - - /** - * {@inheritdoc} - */ - public function update($status) - { - $status ? $this->enable() : $this->disable(); - } -} diff --git a/src/Core/Backup/BackupCollection.php b/src/Core/Backup/BackupCollection.php deleted file mode 100644 index 0f93c955..00000000 --- a/src/Core/Backup/BackupCollection.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup; - -final class BackupCollection implements BackupCollectionInterface -{ - /** - * @var BackupInterface[] - */ - private $backups = []; - - /** - * {@inheritdoc} - */ - public function add(BackupInterface $backup) - { - $this->backups[] = $backup; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function all() - { - return $this->backups; - } -} diff --git a/src/Core/Backup/BackupCollectionInterface.php b/src/Core/Backup/BackupCollectionInterface.php deleted file mode 100644 index 493d4ea0..00000000 --- a/src/Core/Backup/BackupCollectionInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup; - -/** - * Interface BackupCollectionInterface defines contract for backup collection. - */ -interface BackupCollectionInterface -{ - /** - * Add backup to collection. - * - * @param BackupInterface $backup - * - * @return self - */ - public function add(BackupInterface $backup); - - /** - * Get all backups. - * - * @return BackupInterface[] - */ - public function all(); -} diff --git a/src/Core/Backup/BackupInterface.php b/src/Core/Backup/BackupInterface.php deleted file mode 100644 index 113f406c..00000000 --- a/src/Core/Backup/BackupInterface.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup; - -use DateTimeInterface; - -/** - * Interface BackupInterface defines contract for backup. - */ -interface BackupInterface -{ - /** - * Get backup filename. - * - * @return string - */ - public function getFileName(); - - /** - * Get complete path to the backup file. - * - * @return string - */ - public function getFilePath(); - - /** - * Get URL to backup. - * - * @return string - */ - public function getUrl(); - - /** - * Get backup file size in bytes. - * - * @return string - */ - public function getSize(); - - /** - * Get backup age in seconds. - * - * @return int - */ - public function getAge(); - - /** - * Get backup creation date. - * - * @return DateTimeInterface - */ - public function getDate(); -} diff --git a/src/Core/Backup/Comparator/BackupByDateComparator.php b/src/Core/Backup/Comparator/BackupByDateComparator.php deleted file mode 100644 index b5d143c5..00000000 --- a/src/Core/Backup/Comparator/BackupByDateComparator.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Comparator; - -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; - -/** - * Class BackupByDateComparator compares 2 backups by creation date. - */ -final class BackupByDateComparator implements BackupComparatorInterface -{ - /** - * {@inheritdoc} - */ - public function compare(BackupInterface $backup1, BackupInterface $backup2) - { - return $backup2->getDate()->getTimestamp() - $backup1->getDate()->getTimestamp(); - } -} diff --git a/src/Core/Backup/Comparator/BackupComparatorInterface.php b/src/Core/Backup/Comparator/BackupComparatorInterface.php deleted file mode 100644 index 44568223..00000000 --- a/src/Core/Backup/Comparator/BackupComparatorInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Comparator; - -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; - -/** - * Interface BackupComparatorInterface defines contract for backups comparator. - */ -interface BackupComparatorInterface -{ - /** - * Compare 2 backups. - * - * @param BackupInterface $backup1 - * @param BackupInterface $backup2 - * - * @return int - */ - public function compare(BackupInterface $backup1, BackupInterface $backup2); -} diff --git a/src/Core/Backup/Configuration/BackupOptionsConfiguration.php b/src/Core/Backup/Configuration/BackupOptionsConfiguration.php deleted file mode 100644 index 7ee27aff..00000000 --- a/src/Core/Backup/Configuration/BackupOptionsConfiguration.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Configuration; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class BackupOptionsConfigurator configures backup options. - */ -final class BackupOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'backup_all' => (bool) $this->configuration->get('PS_BACKUP_ALL'), - 'backup_drop_tables' => (bool) $this->configuration->get('PS_BACKUP_DROP_TABLE'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_BACKUP_ALL', $config['backup_all']); - $this->configuration->set('PS_BACKUP_DROP_TABLE', $config['backup_drop_tables']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['backup_all'], - $config['backup_drop_tables'] - ); - } -} diff --git a/src/Core/Backup/Exception/BackupException.php b/src/Core/Backup/Exception/BackupException.php deleted file mode 100644 index b613e352..00000000 --- a/src/Core/Backup/Exception/BackupException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class BackupException is thrown whenever backup fails. - */ -class BackupException extends CoreException -{ -} diff --git a/src/Core/Backup/Exception/DirectoryIsNotWritableException.php b/src/Core/Backup/Exception/DirectoryIsNotWritableException.php deleted file mode 100644 index 182b44f1..00000000 --- a/src/Core/Backup/Exception/DirectoryIsNotWritableException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Exception; - -/** - * Class DirectoryIsNotWritableException is thrown when backup directory is not writable. - */ -class DirectoryIsNotWritableException extends BackupException -{ -} diff --git a/src/Core/Backup/Listing/BackupGridDataFactory.php b/src/Core/Backup/Listing/BackupGridDataFactory.php deleted file mode 100644 index eb546c5c..00000000 --- a/src/Core/Backup/Listing/BackupGridDataFactory.php +++ /dev/null @@ -1,157 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Listing; - -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; -use PrestaShop\PrestaShop\Core\Backup\Comparator\BackupComparatorInterface; -use PrestaShop\PrestaShop\Core\Backup\Repository\BackupRepositoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Util\DateTime\TimeDefinition; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * This class provides backups for listing in grid. - */ -final class BackupGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var BackupRepositoryInterface - */ - private $backupRepository; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var string - */ - private $languageDateTimeFormat; - - /** - * @var BackupComparatorInterface - */ - private $backupByDateComparator; - - /** - * @param BackupRepositoryInterface $backupRepository - * @param BackupComparatorInterface $backupByDateComparator - * @param TranslatorInterface $translator - * @param string $languageDateTimeFormat - */ - public function __construct( - BackupRepositoryInterface $backupRepository, - BackupComparatorInterface $backupByDateComparator, - TranslatorInterface $translator, - $languageDateTimeFormat - ) { - $this->backupRepository = $backupRepository; - $this->translator = $translator; - $this->languageDateTimeFormat = $languageDateTimeFormat; - $this->backupByDateComparator = $backupByDateComparator; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $backups = $this->backupRepository->retrieveBackups()->all(); - usort($backups, [$this->backupByDateComparator, 'compare']); - - $paginatedBackups = null !== $searchCriteria->getOffset() && null !== $searchCriteria->getLimit() ? - array_slice($backups, $searchCriteria->getOffset(), $searchCriteria->getLimit()) : - $backups; - - $backupsArray = []; - - foreach ($paginatedBackups as $backup) { - $backupsArray[] = [ - 'file_name' => $backup->getFileName(), - 'file_size' => $backup->getSize(), - 'date' => $backup->getDate(), - 'age' => $backup->getAge(), - 'age_formatted' => $this->getFormattedAge($backup), - 'date_formatted' => date($this->languageDateTimeFormat, $backup->getDate()->getTimestamp()), - 'file_size_formatted' => $this->getFormattedSize($backup), - ]; - } - - $backupCollection = new RecordCollection($backupsArray); - - return new GridData( - $backupCollection, - count($backups) - ); - } - - /** - * Get formatted age. - * - * @param BackupInterface $backup - * - * @return string - */ - private function getFormattedAge(BackupInterface $backup) - { - if (TimeDefinition::HOUR_IN_SECONDS > $backup->getAge()) { - return sprintf('< 1 %s', $this->translator->trans('Hour', [], 'Admin.Global')); - } - - if (TimeDefinition::DAY_IN_SECONDS > $backup->getAge()) { - $hours = (int) floor($backup->getAge() / TimeDefinition::HOUR_IN_SECONDS); - $label = 1 === $hours ? - $this->translator->trans('Hour', [], 'Admin.Global') : - $this->translator->trans('Hours', [], 'Admin.Global'); - - return sprintf('%s %s', $hours, $label); - } - - $days = (int) floor($backup->getAge() / TimeDefinition::DAY_IN_SECONDS); - $label = 1 === $days ? - $this->translator->trans('Day', [], 'Admin.Global') : - $this->translator->trans('Days', [], 'Admin.Global'); - - return sprintf('%s %s', $days, $label); - } - - /** - * Get formatted backup size. - * - * @param BackupInterface $backup - * - * @return string - */ - private function getFormattedSize(BackupInterface $backup) - { - return sprintf('%s Kb', number_format($backup->getSize() / 1000, 2)); - } -} diff --git a/src/Core/Backup/Manager/BackupCreatorInterface.php b/src/Core/Backup/Manager/BackupCreatorInterface.php deleted file mode 100644 index 61d12630..00000000 --- a/src/Core/Backup/Manager/BackupCreatorInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Manager; - -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; - -/** - * Interface BackupCreatorInterface defines contract for backup creator. - */ -interface BackupCreatorInterface -{ - /** - * Create new backup. - * - * @return BackupInterface - */ - public function createBackup(); -} diff --git a/src/Core/Backup/Manager/BackupRemoverInterface.php b/src/Core/Backup/Manager/BackupRemoverInterface.php deleted file mode 100644 index aaa83976..00000000 --- a/src/Core/Backup/Manager/BackupRemoverInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Manager; - -use PrestaShop\PrestaShop\Core\Backup\BackupInterface; - -/** - * Interface BackupRemoverInterface defines contract for backup remover. - */ -interface BackupRemoverInterface -{ - /** - * @param BackupInterface $backup - * - * @return bool True if backup were removed successfully or False otherwise - */ - public function remove(BackupInterface $backup); -} diff --git a/src/Core/Backup/Repository/BackupRepositoryInterface.php b/src/Core/Backup/Repository/BackupRepositoryInterface.php deleted file mode 100644 index 4ff66287..00000000 --- a/src/Core/Backup/Repository/BackupRepositoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Backup\Repository; - -use PrestaShop\PrestaShop\Core\Backup\BackupCollectionInterface; - -/** - * Interface BackupRepositoryInterface defines contract for backup repository. - */ -interface BackupRepositoryInterface -{ - /** - * Get available backups. - * - * @return BackupCollectionInterface - */ - public function retrieveBackups(); -} diff --git a/src/Core/CMS/CMSRepository.php b/src/Core/CMS/CMSRepository.php deleted file mode 100644 index cd0b6ef1..00000000 --- a/src/Core/CMS/CMSRepository.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CMS; - -class CMSRepository extends \PrestaShop\PrestaShop\Core\Foundation\Database\EntityRepository -{ - /** - * Return all CMSRepositories depending on $id_lang/$id_shop tuple. - * - * @param $id_lang - * @param $id_shop - * - * @return array|null - */ - public function i10nFindAll($id_lang, $id_shop) - { - $sql = ' - SELECT * - FROM `' . $this->getTableNameWithPrefix() . '` c - JOIN `' . $this->getPrefix() . 'cms_lang` cl ON c.`id_cms`= cl.`id_cms` - WHERE cl.`id_lang` = ' . (int) $id_lang . ' - AND cl.`id_shop` = ' . (int) $id_shop . ' - - '; - - return $this->hydrateMany($this->db->select($sql)); - } - - /** - * Return all CMSRepositories depending on $id_lang/$id_shop tuple. - * - * @param $id_cms - * @param $id_lang - * @param $id_shop - * - * @return CMS|null - * - * @throws \PrestaShop\PrestaShop\Core\Foundation\Database\Exception - */ - public function i10nFindOneById($id_cms, $id_lang, $id_shop) - { - $sql = ' - SELECT * - FROM `' . $this->getTableNameWithPrefix() . '` c - JOIN `' . $this->getPrefix() . 'cms_lang` cl ON c.`id_cms`= cl.`id_cms` - WHERE c.`id_cms` = ' . (int) $id_cms . ' - AND cl.`id_lang` = ' . (int) $id_lang . ' - AND cl.`id_shop` = ' . (int) $id_shop . ' - LIMIT 0 , 1 - '; - - return $this->hydrateOne($this->db->select($sql)); - } -} diff --git a/src/Core/CMS/CMSRoleRepository.php b/src/Core/CMS/CMSRoleRepository.php deleted file mode 100644 index 29f166ea..00000000 --- a/src/Core/CMS/CMSRoleRepository.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CMS; - -class CMSRoleRepository extends \PrestaShop\PrestaShop\Core\Foundation\Database\EntityRepository -{ - /** - * Return all CMSRoles which are already associated. - * - * @return array|null - */ - public function getCMSRolesAssociated() - { - $sql = ' - SELECT * - FROM `' . $this->getTableNameWithPrefix() . '` - WHERE `id_cms` != 0'; - - return $this->hydrateMany($this->db->select($sql)); - } -} diff --git a/src/Core/CMS/CmsPageViewDataProvider.php b/src/Core/CMS/CmsPageViewDataProvider.php deleted file mode 100644 index 8e380a8d..00000000 --- a/src/Core/CMS/CmsPageViewDataProvider.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CMS; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoriesForBreadcrumb; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\Breadcrumb; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class CmsPageViewDataProvider provides cms page view data for cms listing page. - */ -final class CmsPageViewDataProvider implements CmsPageViewDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function getView($cmsCategoryParentId) - { - return [ - 'root_category_id' => CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID, - 'breadcrumb_tree' => $this->getBreadcrumbTree($cmsCategoryParentId), - ]; - } - - /** - * Gets breadcrumb tree which contains cms page categories. If the exception is raised when it returns empty array. - * - * @param int $cmsCategoryParentId - * - * @return Breadcrumb|array - * - * @throws CmsPageCategoryException - */ - private function getBreadcrumbTree($cmsCategoryParentId) - { - return $this->queryBus->handle(new GetCmsPageCategoriesForBreadcrumb($cmsCategoryParentId)); - } -} diff --git a/src/Core/CMS/CmsPageViewDataProviderInterface.php b/src/Core/CMS/CmsPageViewDataProviderInterface.php deleted file mode 100644 index 0383be58..00000000 --- a/src/Core/CMS/CmsPageViewDataProviderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CMS; - -/** - * Interface CmsPageViewDataProviderInterface defines contract for CmsPageViewDataProvider. - */ -interface CmsPageViewDataProviderInterface -{ - /** - * Gets data required for rendering the view. - * - * @param int $cmsCategoryParentId - * - * @return array - */ - public function getView($cmsCategoryParentId); -} diff --git a/src/Core/Cache/Clearer/CacheClearerChain.php b/src/Core/Cache/Clearer/CacheClearerChain.php deleted file mode 100644 index fbba8a55..00000000 --- a/src/Core/Cache/Clearer/CacheClearerChain.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cache\Clearer; - -/** - * Class CacheClearerChain clears entire PrestaShop cache. - */ -final class CacheClearerChain implements CacheClearerInterface -{ - /** - * @var CacheClearerInterface[] - */ - private $cacheClearers; - - /** - * @param CacheClearerInterface ...$cacheClearers - */ - public function __construct(CacheClearerInterface ...$cacheClearers) - { - $this->cacheClearers = $cacheClearers; - } - - /** - * {@inheritdoc} - */ - public function clear() - { - foreach ($this->cacheClearers as $cacheClearer) { - $cacheClearer->clear(); - } - } -} diff --git a/src/Core/Cache/Clearer/CacheClearerInterface.php b/src/Core/Cache/Clearer/CacheClearerInterface.php deleted file mode 100644 index c06c509a..00000000 --- a/src/Core/Cache/Clearer/CacheClearerInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cache\Clearer; - -/** - * Interface CacheClearerInterface. - */ -interface CacheClearerInterface -{ - /** - * Clear cache. - */ - public function clear(); -} diff --git a/src/Core/Cart/AmountImmutable.php b/src/Core/Cart/AmountImmutable.php deleted file mode 100644 index 594dc45c..00000000 --- a/src/Core/Cart/AmountImmutable.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -/** - * provide objects dealing with tax ex/in-cluded amounts - * aims to avoid using multiple values into calculation processes. - * - * this class is IMMUTABLE - */ -class AmountImmutable -{ - /** - * @var float - */ - protected $taxIncluded = 0.0; - - /** - * @var float - */ - protected $taxExcluded = 0.0; - - public function __construct($taxIncluded = 0.0, $taxExcluded = 0.0) - { - $this->setTaxIncluded($taxIncluded); - $this->setTaxExcluded($taxExcluded); - } - - /** - * @return float - */ - public function getTaxIncluded() - { - return $this->taxIncluded; - } - - /** - * @param float $taxIncluded - * - * @return AmountImmutable - */ - protected function setTaxIncluded($taxIncluded) - { - $this->taxIncluded = (float) $taxIncluded; - - return $this; - } - - /** - * @return float - */ - public function getTaxExcluded() - { - return $this->taxExcluded; - } - - /** - * @param float $taxExcluded - * - * @return AmountImmutable - */ - protected function setTaxExcluded($taxExcluded) - { - $this->taxExcluded = (float) $taxExcluded; - - return $this; - } - - /** - * sums another amount object. - * - * @param \PrestaShop\PrestaShop\Core\Cart\AmountImmutable $amount - * - * @return \PrestaShop\PrestaShop\Core\Cart\AmountImmutable - */ - public function add(AmountImmutable $amount) - { - return new static( - $this->getTaxIncluded() + $amount->getTaxIncluded(), - $this->getTaxExcluded() + $amount->getTaxExcluded() - ); - } - - /** - * substract another amount object. - * - * @param \PrestaShop\PrestaShop\Core\Cart\AmountImmutable $amount - * - * @return \PrestaShop\PrestaShop\Core\Cart\AmountImmutable - */ - public function sub(AmountImmutable $amount) - { - return new static( - $this->getTaxIncluded() - $amount->getTaxIncluded(), - $this->getTaxExcluded() - $amount->getTaxExcluded() - ); - } -} diff --git a/src/Core/Cart/Calculator.php b/src/Core/Cart/Calculator.php deleted file mode 100644 index 4155036e..00000000 --- a/src/Core/Cart/Calculator.php +++ /dev/null @@ -1,378 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -use Cart; -use Currency; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use Tools; - -/** - * provides methods to process cart calculation. - */ -class Calculator -{ - /** - * @var \Cart - */ - protected $cart; - - /** - * @var int - */ - protected $id_carrier; - - /** - * @var int|null - */ - protected $orderId; - - /** - * @var CartRowCollection collection of cart content row (product+qty) - */ - protected $cartRows; - - /** - * @var CartRuleCollection - */ - protected $cartRules; - - /** - * @var Fees - */ - protected $fees; - - /** - * @var CartRuleCalculator - */ - protected $cartRuleCalculator; - - /** - * indicates if cart was already processed. - * - * @var bool - */ - protected $isProcessed = false; - - /** - * @var int|null - */ - protected $computePrecision; - - /** - * @param Cart $cart - * @param $carrierId - * @param int|null $computePrecision - * @param int|null $orderId - */ - public function __construct(Cart $cart, $carrierId, ?int $computePrecision = null, ?int $orderId = null) - { - $this->setCart($cart); - $this->setCarrierId($carrierId); - $this->orderId = $orderId; - $this->cartRows = new CartRowCollection(); - $this->fees = new Fees($this->orderId); - $this->cartRules = new CartRuleCollection(); - $this->cartRuleCalculator = new CartRuleCalculator(); - - if (null === $computePrecision) { - $currency = new Currency((int) $cart->id_currency); - $computePrecision = (new ComputingPrecision())->getPrecision($currency->precision); - } - $this->computePrecision = $computePrecision; - } - - /** - * insert a new cart row in the calculator. - * - * @param CartRow $cartRow cart item row (product+qty informations) - * - * @return $this - */ - public function addCartRow(CartRow $cartRow) - { - // reset state - $this->isProcessed = false; - - $this->cartRows->addCartRow($cartRow); - - return $this; - } - - /** - * insert a new cart rule in the calculator. - * - * @param \PrestaShop\PrestaShop\Core\Cart\CartRuleData $cartRule - * - * @return $this - */ - public function addCartRule(CartRuleData $cartRule) - { - // reset state - $this->isProcessed = false; - - $this->cartRules->addCartRule($cartRule); - - return $this; - } - - /** - * run the whole calculation process: calculate rows, discounts, fees. - * - * @param int $computePrecision Not used since 1.7.7.0, kept for backward compatibility - * - * @return $this - */ - public function processCalculation($computePrecision = null) - { - // calculate product rows - $this->calculateRows(); - // calculate fees - $this->calculateFees(); - // calculate discounts - $this->calculateCartRules(); - // store state - $this->isProcessed = true; - - return $this; - } - - /** - * @param bool $ignoreProcessedFlag force getting total even if calculation was not made internaly - * - * @return AmountImmutable - * - * @throws \Exception - */ - public function getTotal($ignoreProcessedFlag = false) - { - if (!$this->isProcessed && !$ignoreProcessedFlag) { - throw new \Exception('Cart must be processed before getting its total'); - } - - $amount = $this->getRowTotalWithoutDiscount(); - $amount = $amount->sub($this->rounded($this->getDiscountTotal(), $this->computePrecision)); - $shippingFees = $this->fees->getInitialShippingFees(); - if (null !== $shippingFees) { - $amount = $amount->add($this->rounded($shippingFees, $this->computePrecision)); - } - $wrappingFees = $this->fees->getFinalWrappingFees(); - if (null !== $wrappingFees) { - $amount = $amount->add($this->rounded($wrappingFees, $this->computePrecision)); - } - - return $amount; - } - - /** - * @return AmountImmutable - * - * @throws \Exception - */ - public function getRowTotal() - { - $amount = new AmountImmutable(); - foreach ($this->cartRows as $cartRow) { - $amount = $amount->add($cartRow->getFinalTotalPrice()); - } - - return $amount; - } - - /** - * @return AmountImmutable - * - * @throws \Exception - */ - public function getRowTotalWithoutDiscount() - { - $amount = new AmountImmutable(); - foreach ($this->cartRows as $cartRow) { - $amount = $amount->add($cartRow->getInitialTotalPrice()); - } - - return $amount; - } - - /** - * @return AmountImmutable - * - * @throws \Exception - */ - public function getDiscountTotal() - { - $amount = new AmountImmutable(); - $isFreeShippingAppliedToAmount = false; - foreach ($this->cartRules as $cartRule) { - if ((bool) $cartRule->getRuleData()['free_shipping']) { - if ($isFreeShippingAppliedToAmount) { - $initialShippingFees = $this->getFees()->getInitialShippingFees(); - $amount = $amount->sub($initialShippingFees); - } - $isFreeShippingAppliedToAmount = true; - } - $amount = $amount->add($cartRule->getDiscountApplied()); - } - - $allowedMaxDiscount = $this->getRowTotalWithoutDiscount(); - - if (null !== $this->getFees()->getInitialShippingFees() && null !== $this->getFees()->getFinalShippingFees()) { - $shippingDiscount = (new AmountImmutable()) - ->add($this->getFees()->getInitialShippingFees()) - ->sub($this->getFees()->getFinalShippingFees()) - ; - $allowedMaxDiscount = $allowedMaxDiscount->add($shippingDiscount); - } - // discount cannot be above total cart price - if ($amount > $allowedMaxDiscount) { - $amount = $allowedMaxDiscount; - } - - return $amount; - } - - /** - * @param \CartCore $cart - * - * @return Calculator - */ - protected function setCart($cart) - { - // reset state - $this->isProcessed = false; - - $this->cart = $cart; - - return $this; - } - - /** - * @param mixed $id_carrier - * - * @return Calculator - */ - protected function setCarrierId($id_carrier) - { - // reset state - $this->isProcessed = false; - - $this->id_carrier = $id_carrier; - - return $this; - } - - /** - * @return \PrestaShop\PrestaShop\Core\Cart\Fees - */ - public function getFees() - { - return $this->fees; - } - - /** - * @return \Cart - */ - public function getCart() - { - return $this->cart; - } - - /** - * Calculate row total. - * - * @param CartRow $cartRow - */ - protected function calculateRowTotal(CartRow $cartRow) - { - $cartRow->processCalculation($this->cart); - } - - /** - * calculate only product rows. - */ - public function calculateRows() - { - foreach ($this->cartRows as $cartRow) { - $this->calculateRowTotal($cartRow); - } - } - - /** - * calculate only cart rules (rows and fees have to be calculated first). - */ - public function calculateCartRules() - { - $this->cartRuleCalculator->setCartRules($this->cartRules) - ->setCartRows($this->cartRows) - ->setCalculator($this) - ->applyCartRules(); - } - - /** - * calculate only cart rules (rows and fees have to be calculated first), but don't process free-shipping discount - * (avoid loop on shipping calculation) - */ - public function calculateCartRulesWithoutFreeShipping() - { - $this->cartRuleCalculator->setCartRules($this->cartRules) - ->setCartRows($this->cartRows) - ->setCalculator($this) - ->applyCartRulesWithoutFreeShipping(); - } - - /** - * calculate wrapping and shipping fees (rows have to be calculated first). - * - * @param int|null $computePrecision Not used since 1.7.7.0, kept for backward compatibility - */ - public function calculateFees($computePrecision = null) - { - $this->fees->processCalculation($this->cart, $this->cartRows, $this->computePrecision, $this->id_carrier); - } - - /** - * @return CartRuleCollection - */ - public function getCartRulesData() - { - return $this->cartRuleCalculator->getCartRulesData(); - } - - /** - * @param AmountImmutable $amount - * @param int $computePrecision - * - * @return AmountImmutable - */ - private function rounded(AmountImmutable $amount, int $computePrecision) - { - return new AmountImmutable( - Tools::ps_round($amount->getTaxIncluded(), $computePrecision), - Tools::ps_round($amount->getTaxExcluded(), $computePrecision) - ); - } -} diff --git a/src/Core/Cart/CartRow.php b/src/Core/Cart/CartRow.php deleted file mode 100644 index 39bca200..00000000 --- a/src/Core/Cart/CartRow.php +++ /dev/null @@ -1,514 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -use Cart; -use PrestaShop\PrestaShop\Adapter\AddressFactory; -use PrestaShop\PrestaShop\Adapter\Cache\CacheAdapter; -use PrestaShop\PrestaShop\Adapter\CoreException; -use PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider; -use PrestaShop\PrestaShop\Adapter\Database; -use PrestaShop\PrestaShop\Adapter\Group\GroupDataProvider; -use PrestaShop\PrestaShop\Adapter\Product\PriceCalculator; -use PrestaShop\PrestaShop\Adapter\Tools; - -/** - * represent a cart row, ie a product and a quantity, and some post-process data like cart rule applied. - */ -class CartRow -{ - /** - * row round mode by item. - */ - const ROUND_MODE_ITEM = 'item'; - - /** - * row round mode by line. - */ - const ROUND_MODE_LINE = 'line'; - - /** - * row round mode by all lines. - */ - const ROUND_MODE_TOTAL = 'total'; - - /** - * static cache key pattern. - */ - const PRODUCT_PRICE_CACHE_ID_PATTERN = 'Product::getPriceStatic_%d-%d'; - - /** - * @var PriceCalculator adapter to calculate price - */ - protected $priceCalculator; - - /** - * @var AddressFactory adapter to get address informations - */ - protected $addressFactory; - - /** - * @var CustomerDataProvider adapter to get customer informations - */ - protected $customerDataProvider; - - /** - * @var GroupDataProvider adapter to get group informations - */ - protected $groupDataProvider; - - /** - * @var Database adapter to get database - */ - protected $databaseAdapter; - - /** - * @var CacheAdapter adapter to get cache - */ - protected $cacheAdapter; - - /** - * @var bool calculation will use ecotax - */ - protected $useEcotax; - - /** - * @var int calculation precision (decimals count) - */ - protected $precision; - - /** - * @var string round mode : see self::ROUND_MODE_xxx - */ - protected $roundType; - - /** - * @var int|null - */ - protected $orderId; - - /** - * @var array previous data for product: array given by Cart::getProducts() - */ - protected $rowData = []; - - /** - * @var AmountImmutable - */ - protected $initialUnitPrice; - - /** - * @var AmountImmutable - */ - protected $initialTotalPrice; - - /** - * @var AmountImmutable - */ - protected $finalUnitPrice; - - /** - * @var AmountImmutable - */ - protected $finalTotalPrice; - - /** - * @var bool indicates if the calculation was triggered (reset on data changes) - */ - protected $isProcessed = false; - - /** - * @param array $rowData array item given by Cart::getProducts() - * @param PriceCalculator $priceCalculator - * @param AddressFactory $addressFactory - * @param CustomerDataProvider $customerDataProvider - * @param CacheAdapter $cacheAdapter - * @param GroupDataProvider $groupDataProvider - * @param Database $databaseAdapter - * @param bool $useEcotax - * @param int $precision - * @param string $roundType see self::ROUND_MODE_* - * @param int|null $orderId If order ID is specified the product price is fetched from associated OrderDetail value - */ - public function __construct( - $rowData, - PriceCalculator $priceCalculator, - AddressFactory $addressFactory, - CustomerDataProvider $customerDataProvider, - CacheAdapter $cacheAdapter, - GroupDataProvider $groupDataProvider, - Database $databaseAdapter, - $useEcotax, - $precision, - $roundType, - $orderId = null - ) { - $this->setRowData($rowData); - $this->priceCalculator = $priceCalculator; - $this->addressFactory = $addressFactory; - $this->customerDataProvider = $customerDataProvider; - $this->cacheAdapter = $cacheAdapter; - $this->groupDataProvider = $groupDataProvider; - $this->databaseAdapter = $databaseAdapter; - $this->useEcotax = $useEcotax; - $this->precision = $precision; - $this->roundType = $roundType; - $this->orderId = $orderId; - } - - /** - * @param array $rowData - * - * @return CartRow - */ - public function setRowData($rowData) - { - $this->rowData = $rowData; - - return $this; - } - - /** - * @return array - */ - public function getRowData() - { - return $this->rowData; - } - - /** - * Returns the initial unit price (ie without applying cart rules). - * - * @return AmountImmutable - * - * @throws \Exception - */ - public function getInitialUnitPrice() - { - if (!$this->isProcessed) { - throw new \Exception('Row must be processed before getting its total'); - } - - return $this->initialUnitPrice; - } - - /** - * Returns the initial total price (ie without applying cart rules). - * - * @return AmountImmutable - * - * @throws \Exception - */ - public function getInitialTotalPrice() - { - if (!$this->isProcessed) { - throw new \Exception('Row must be processed before getting its total'); - } - - return $this->initialTotalPrice; - } - - /** - * return final price: initial minus the cart rule discounts. - * - * @return AmountImmutable - * - * @throws \Exception - */ - public function getFinalUnitPrice() - { - if (!$this->isProcessed) { - throw new \Exception('Row must be processed before getting its total'); - } - - return $this->finalUnitPrice; - } - - /** - * return final price: initial minus the cart rule discounts. - * - * @return AmountImmutable - * - * @throws \Exception - */ - public function getFinalTotalPrice() - { - if (!$this->isProcessed) { - throw new \Exception('Row must be processed before getting its total'); - } - - return $this->finalTotalPrice; - } - - /** - * run initial row calculation. - * - * @param Cart $cart - * - * @throws CoreException - */ - public function processCalculation(Cart $cart) - { - $rowData = $this->getRowData(); - $quantity = (int) $rowData['cart_quantity']; - $this->initialUnitPrice = $this->getProductPrice($cart, $rowData); - - // store not rounded values, except in round_mode_item, we still need to round individual items - if ($this->roundType == self::ROUND_MODE_ITEM) { - $tools = new Tools(); - $this->initialTotalPrice = new AmountImmutable( - $tools->round($this->initialUnitPrice->getTaxIncluded(), $this->precision) * $quantity, - $tools->round($this->initialUnitPrice->getTaxExcluded(), $this->precision) * $quantity - ); - } else { - $this->initialTotalPrice = new AmountImmutable( - $this->initialUnitPrice->getTaxIncluded() * $quantity, - $this->initialUnitPrice->getTaxExcluded() * $quantity - ); - } - - $this->finalTotalPrice = clone $this->initialTotalPrice; - $this->applyRound(); - // store state - $this->isProcessed = true; - } - - protected function getProductPrice(Cart $cart, $rowData) - { - $productId = (int) $rowData['id_product']; - $quantity = (int) $rowData['cart_quantity']; - - $addressId = $cart->getProductAddressId($rowData); - if (!$addressId) { - $addressId = $cart->getTaxAddressId(); - } - $address = $this->addressFactory->findOrCreate($addressId, true); - $countryId = (int) $address->id_country; - $stateId = (int) $address->id_state; - $zipCode = $address->postcode; - - $shopId = (int) $rowData['id_shop']; - $currencyId = (int) $cart->id_currency; - - $groupId = null; - if ($cart->id_customer) { - $groupId = $this->customerDataProvider->getDefaultGroupId((int) $cart->id_customer); - } - if (!$groupId) { - $groupId = (int) $this->groupDataProvider->getCurrent()->id; - } - - $cartQuantity = 0; - if ((int) $cart->id) { - $cacheId = sprintf(self::PRODUCT_PRICE_CACHE_ID_PATTERN, (int) $productId, (int) $cart->id); - if (!$this->cacheAdapter->isStored($cacheId) - || ($cartQuantity = $this->cacheAdapter->retrieve($cacheId) - != (int) $quantity)) { - $sql = 'SELECT SUM(`quantity`) - FROM `' . _DB_PREFIX_ . 'cart_product` - WHERE `id_product` = ' . (int) $productId . ' - AND `id_cart` = ' . (int) $cart->id; - $cartQuantity = (int) $this->databaseAdapter->getValue($sql, _PS_USE_SQL_SLAVE_); - $this->cacheAdapter->store($cacheId, $cartQuantity); - } else { - $cartQuantity = $this->cacheAdapter->retrieve($cacheId); - } - } - - // The $null variable below is not used, - // but it is necessary to pass it to getProductPrice because - // it expects a reference. - $specificPriceOutput = null; - - $productPrices = [ - 'price_tax_included' => [ - 'withTaxes' => true, - ], - 'price_tax_excluded' => [ - 'withTaxes' => false, - ], - ]; - foreach ($productPrices as $productPrice => $computationParameters) { - $productPrices[$productPrice]['value'] = null; - if (null !== $this->orderId) { - $productPrices[$productPrice]['value'] = $this->priceCalculator->getOrderPrice( - $this->orderId, - (int) $productId, - (int) $rowData['id_product_attribute'], - $computationParameters['withTaxes'], - true, - $this->useEcotax - ); - } - if (null === $productPrices[$productPrice]['value']) { - $productPrices[$productPrice]['value'] = $this->priceCalculator->priceCalculation( - $shopId, - (int) $productId, - (int) $rowData['id_product_attribute'], - $countryId, - $stateId, - $zipCode, - $currencyId, - $groupId, - $quantity, - $computationParameters['withTaxes'], - 6, - false, - true, - $this->useEcotax, - $specificPriceOutput, - true, - (int) $cart->id_customer ? (int) $cart->id_customer : null, - true, - (int) $cart->id, - $cartQuantity, - (int) $rowData['id_customization'] - ); - } - } - - return new AmountImmutable( - $productPrices['price_tax_included']['value'], - $productPrices['price_tax_excluded']['value'] - ); - } - - /** - * depending on attribute roundType, rounds the item/line value. - */ - protected function applyRound() - { - // ROUNDING MODE - $this->finalUnitPrice = clone $this->initialUnitPrice; - - $rowData = $this->getRowData(); - $quantity = (int) $rowData['cart_quantity']; - $tools = new Tools(); - switch ($this->roundType) { - case self::ROUND_MODE_TOTAL: - // do not round the line - $this->finalTotalPrice = new AmountImmutable( - $this->initialUnitPrice->getTaxIncluded() * $quantity, - $this->initialUnitPrice->getTaxExcluded() * $quantity - ); - - break; - case self::ROUND_MODE_LINE: - // round line result - $this->finalTotalPrice = new AmountImmutable( - $tools->round($this->initialUnitPrice->getTaxIncluded() * $quantity, $this->precision), - $tools->round($this->initialUnitPrice->getTaxExcluded() * $quantity, $this->precision) - ); - - break; - - case self::ROUND_MODE_ITEM: - default: - // round each item - $this->initialUnitPrice = new AmountImmutable( - $tools->round($this->initialUnitPrice->getTaxIncluded(), $this->precision), - $tools->round($this->initialUnitPrice->getTaxExcluded(), $this->precision) - ); - $this->finalTotalPrice = new AmountImmutable( - $this->initialUnitPrice->getTaxIncluded() * $quantity, - $this->initialUnitPrice->getTaxExcluded() * $quantity - ); - break; - } - } - - /** - * substract discount from the row - * if discount exceeds amount, we keep 0 (no use of negative amounts). - * - * @param AmountImmutable $amount - */ - public function applyFlatDiscount(AmountImmutable $amount) - { - $taxIncluded = $this->finalTotalPrice->getTaxIncluded() - $amount->getTaxIncluded(); - $taxExcluded = $this->finalTotalPrice->getTaxExcluded() - $amount->getTaxExcluded(); - if ($taxIncluded < 0) { - $taxIncluded = 0; - } - if ($taxExcluded < 0) { - $taxExcluded = 0; - } - $this->finalTotalPrice = new AmountImmutable( - $taxIncluded, - $taxExcluded - ); - - $this->updateFinalUnitPrice(); - } - - /** - * @param float $percent 0-100 - * - * @return AmountImmutable - */ - public function applyPercentageDiscount($percent) - { - $percent = (float) $percent; - if ($percent < 0 || $percent > 100) { - throw new \Exception('Invalid percentage discount given: ' . $percent); - } - $discountTaxIncluded = $this->finalTotalPrice->getTaxIncluded() * $percent / 100; - $discountTaxExcluded = $this->finalTotalPrice->getTaxExcluded() * $percent / 100; - $amount = new AmountImmutable($discountTaxIncluded, $discountTaxExcluded); - $this->applyFlatDiscount($amount); - - return $amount; - } - - /** - * when final row price is calculated, we need to update unit price. - */ - protected function updateFinalUnitPrice() - { - $rowData = $this->getRowData(); - $quantity = (int) $rowData['cart_quantity']; - $taxIncluded = $this->finalTotalPrice->getTaxIncluded(); - $taxExcluded = $this->finalTotalPrice->getTaxExcluded(); - // Avoid division by zero - if (0 === $quantity) { - $this->finalUnitPrice = new AmountImmutable(0, 0); - } else { - $this->finalUnitPrice = new AmountImmutable( - $taxIncluded / $quantity, - $taxExcluded / $quantity - ); - } - } - - /** - * @return string - */ - public function getRoundType() - { - return $this->roundType; - } -} diff --git a/src/Core/Cart/CartRowCollection.php b/src/Core/Cart/CartRowCollection.php deleted file mode 100644 index 45e6d98d..00000000 --- a/src/Core/Cart/CartRowCollection.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -class CartRowCollection implements \Iterator, \Countable -{ - /** - * @var CartRow[] - */ - protected $cartRows = []; - protected $iteratorPosition = 0; - - public function addCartRow(CartRow $cartRow) - { - $this->cartRows[] = $cartRow; - } - - public function rewind() - { - $this->iteratorPosition = 0; - } - - /** - * @return CartRow - */ - public function current() - { - return $this->cartRows[$this->getKey($this->iteratorPosition)]; - } - - public function key() - { - return $this->getKey($this->iteratorPosition); - } - - public function next() - { - ++$this->iteratorPosition; - } - - public function valid() - { - return $this->getKey($this->iteratorPosition) !== null - && array_key_exists( - $this->getKey($this->iteratorPosition), - $this->cartRows - ); - } - - protected function getKey($iteratorPosition) - { - $keys = array_keys($this->cartRows); - if (!isset($keys[$iteratorPosition])) { - return null; - } else { - return $keys[$iteratorPosition]; - } - } - - public function count() - { - return count($this->cartRows); - } - - /** - * return product data as array. - * - * @return array - */ - public function getProducts() - { - $products = []; - foreach ($this->cartRows as $cartRow) { - $products[] = $cartRow->getRowData(); - } - - return $products; - } -} diff --git a/src/Core/Cart/CartRuleCalculator.php b/src/Core/Cart/CartRuleCalculator.php deleted file mode 100644 index a1e74653..00000000 --- a/src/Core/Cart/CartRuleCalculator.php +++ /dev/null @@ -1,312 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -use Cart; - -class CartRuleCalculator -{ - /** - * @var Calculator - */ - protected $calculator; - - /** - * @var CartRowCollection - */ - protected $cartRows; - - /** - * @var CartRuleCollection - */ - protected $cartRules; - - /** - * @var Fees - */ - protected $fees; - - /** - * process cartrules calculation - */ - public function applyCartRules() - { - foreach ($this->cartRules as $cartRule) { - $this->applyCartRule($cartRule); - } - } - - /** - * process cartrules calculation, excluding free-shipping processing - */ - public function applyCartRulesWithoutFreeShipping() - { - foreach ($this->cartRules as $cartRule) { - $this->applyCartRule($cartRule, false); - } - } - - /** - * @param \PrestaShop\PrestaShop\Core\Cart\CartRuleCollection $cartRules - * - * @return CartRuleCalculator - */ - public function setCartRules($cartRules) - { - $this->cartRules = $cartRules; - - return $this; - } - - /** - * @param CartRuleData $cartRuleData - * @param bool $withFreeShipping used to calculate free shipping discount (avoid loop on shipping calculation) - * - * @throws \PrestaShopDatabaseException - */ - protected function applyCartRule(CartRuleData $cartRuleData, $withFreeShipping = true) - { - $cartRule = $cartRuleData->getCartRule(); - $cart = $this->calculator->getCart(); - - if (!\CartRule::isFeatureActive()) { - return; - } - - // Free shipping on selected carriers - if ($cartRule->free_shipping && $withFreeShipping) { - $initialShippingFees = $this->calculator->getFees()->getInitialShippingFees(); - $this->calculator->getFees()->subDiscountValueShipping($initialShippingFees); - $cartRuleData->addDiscountApplied($initialShippingFees); - } - - // Free gift - if ((int) $cartRule->gift_product) { - foreach ($this->cartRows as $cartRow) { - $product = $cartRow->getRowData(); - if ($product['id_product'] == $cartRule->gift_product - && ($product['id_product_attribute'] == $cartRule->gift_product_attribute - || !(int) $cartRule->gift_product_attribute) - ) { - $cartRuleData->addDiscountApplied($cartRow->getInitialUnitPrice()); - $cartRow->applyFlatDiscount($cartRow->getInitialUnitPrice()); - } - } - } - - // Discount (%) on the whole order - if ((float) $cartRule->reduction_percent > 0) { - if ($cartRule->reduction_product == 0) { - foreach ($this->cartRows as $cartRow) { - $product = $cartRow->getRowData(); - if ( - array_key_exists('product_quantity', $product) && - 0 === (int) $product['product_quantity'] - ) { - $cartRuleData->addDiscountApplied(new AmountImmutable(0.0, 0.0)); - } elseif ((($cartRule->reduction_exclude_special && !$product['reduction_applies']) - || !$cartRule->reduction_exclude_special)) { - $amount = $cartRow->applyPercentageDiscount($cartRule->reduction_percent); - $cartRuleData->addDiscountApplied($amount); - } - } - } - - // Discount (%) on a specific product - if ($cartRule->reduction_product > 0) { - foreach ($this->cartRows as $cartRow) { - if ($cartRow->getRowData()['id_product'] == $cartRule->reduction_product) { - $amount = $cartRow->applyPercentageDiscount($cartRule->reduction_percent); - $cartRuleData->addDiscountApplied($amount); - } - } - } - - // Discount (%) on the cheapest product - if ($cartRule->reduction_product == -1) { - /** @var CartRow|null $cartRowCheapest */ - $cartRowCheapest = null; - foreach ($this->cartRows as $cartRow) { - $product = $cartRow->getRowData(); - if (((($cartRule->reduction_exclude_special && !$product['reduction_applies']) - || !$cartRule->reduction_exclude_special)) && ($cartRowCheapest === null - || $cartRowCheapest->getInitialUnitPrice()->getTaxIncluded() > $cartRow->getInitialUnitPrice() - ->getTaxIncluded()) - ) { - $cartRowCheapest = $cartRow; - } - } - if ($cartRowCheapest !== null) { - // apply only on one product of the cheapest row - $discountTaxIncluded = $cartRowCheapest->getInitialUnitPrice()->getTaxIncluded() - * $cartRule->reduction_percent / 100; - $discountTaxExcluded = $cartRowCheapest->getInitialUnitPrice()->getTaxExcluded() - * $cartRule->reduction_percent / 100; - $amount = new AmountImmutable($discountTaxIncluded, $discountTaxExcluded); - $cartRowCheapest->applyFlatDiscount($amount); - $cartRuleData->addDiscountApplied($amount); - } - } - - // Discount (%) on the selection of products - if ($cartRule->reduction_product == -2) { - $selected_products = $cartRule->checkProductRestrictionsFromCart($cart, true); - if (is_array($selected_products)) { - foreach ($this->cartRows as $cartRow) { - $product = $cartRow->getRowData(); - if ((in_array($product['id_product'] . '-' . $product['id_product_attribute'], $selected_products) - || in_array($product['id_product'] . '-0', $selected_products)) - && (($cartRule->reduction_exclude_special && !$product['reduction_applies']) - || !$cartRule->reduction_exclude_special)) { - $amount = $cartRow->applyPercentageDiscount($cartRule->reduction_percent); - $cartRuleData->addDiscountApplied($amount); - } - } - } - } - } - - // Discount (¤) : weighted calculation on all concerned rows - // weight factor got from price with same tax (incl/excl) as voucher - if ((float) $cartRule->reduction_amount > 0) { - $concernedRows = new CartRowCollection(); - if ($cartRule->reduction_product > 0) { - // discount on single product - foreach ($this->cartRows as $cartRow) { - if ($cartRow->getRowData()['id_product'] == $cartRule->reduction_product) { - $concernedRows->addCartRow($cartRow); - } - } - } elseif ($cartRule->reduction_product == 0) { - // Discount (¤) on the whole order - $concernedRows = $this->cartRows; - } - /* - * Reduction on the cheapest or on the selection is not really meaningful and has been disabled in the backend - * Please keep this code, so it won't be considered as a bug - * elseif ($this->reduction_product == -1) - * elseif ($this->reduction_product == -2) - */ - - // currency conversion - $discountConverted = $this->convertAmountBetweenCurrencies( - $cartRule->reduction_amount, - new \Currency($cartRule->reduction_currency), - new \Currency($cart->id_currency) - ); - - // get total of concerned rows - $totalTaxIncl = $totalTaxExcl = 0; - foreach ($concernedRows as $concernedRow) { - $totalTaxIncl += $concernedRow->getFinalTotalPrice()->getTaxIncluded(); - $totalTaxExcl += $concernedRow->getFinalTotalPrice()->getTaxExcluded(); - } - - // The reduction cannot exceed the products total, except when we do not want it to be limited (for the partial use calculation) - $discountConverted = min($discountConverted, $cartRule->reduction_tax ? $totalTaxIncl : $totalTaxExcl); - - // apply weighted discount : - // on each line we apply a part of the discount corresponding to discount*rowWeight/total - foreach ($concernedRows as $concernedRow) { - // get current line tax rate - $taxRate = 0; - if ($concernedRow->getFinalTotalPrice()->getTaxExcluded() != 0) { - $taxRate = ($concernedRow->getFinalTotalPrice()->getTaxIncluded() - - $concernedRow->getFinalTotalPrice()->getTaxExcluded()) - / $concernedRow->getFinalTotalPrice()->getTaxExcluded(); - } - $weightFactor = 0; - if ($cartRule->reduction_tax) { - // if cart rule amount is set tax included : calculate weight tax included - if ($totalTaxIncl != 0) { - $weightFactor = $concernedRow->getFinalTotalPrice()->getTaxIncluded() / $totalTaxIncl; - } - $discountAmountTaxIncl = $discountConverted * $weightFactor; - // recalculate tax included - $discountAmountTaxExcl = $discountAmountTaxIncl / (1 + $taxRate); - } else { - // if cart rule amount is set tax excluded : calculate weight tax excluded - if ($totalTaxExcl != 0) { - $weightFactor = $concernedRow->getFinalTotalPrice()->getTaxExcluded() / $totalTaxExcl; - } - $discountAmountTaxExcl = $discountConverted * $weightFactor; - // recalculate tax excluded - $discountAmountTaxIncl = $discountAmountTaxExcl * (1 + $taxRate); - } - $amount = new AmountImmutable($discountAmountTaxIncl, $discountAmountTaxExcl); - $concernedRow->applyFlatDiscount($amount); - $cartRuleData->addDiscountApplied($amount); - } - } - } - - /** - * @param \PrestaShop\PrestaShop\Core\Cart\Calculator $calculator - * - * @return CartRuleCalculator - */ - public function setCalculator($calculator) - { - $this->calculator = $calculator; - - return $this; - } - - protected function convertAmountBetweenCurrencies($amount, \Currency $currencyFrom, \Currency $currencyTo) - { - if ($amount == 0 || $currencyFrom->conversion_rate == 0) { - return 0; - } - - // convert to default currency - $amount /= $currencyFrom->conversion_rate; - // convert to destination currency - $amount *= $currencyTo->conversion_rate; - - return $amount; - } - - /** - * @param \PrestaShop\PrestaShop\Core\Cart\CartRowCollection $cartRows - * - * @return CartRuleCalculator - */ - public function setCartRows($cartRows) - { - $this->cartRows = $cartRows; - - return $this; - } - - /** - * @return CartRuleCollection - */ - public function getCartRulesData() - { - return $this->cartRules; - } -} diff --git a/src/Core/Cart/CartRuleCollection.php b/src/Core/Cart/CartRuleCollection.php deleted file mode 100644 index 6c6f0c96..00000000 --- a/src/Core/Cart/CartRuleCollection.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -class CartRuleCollection implements \Iterator -{ - /** - * @var CartRuleData[] - */ - protected $cartRules = []; - protected $iteratorPosition = 0; - - public function addCartRule(CartRuleData $cartRule) - { - $this->cartRules[] = $cartRule; - } - - public function rewind() - { - $this->iteratorPosition = 0; - } - - /** - * @return CartRuleData - */ - public function current() - { - return $this->cartRules[$this->getKey($this->iteratorPosition)]; - } - - public function key() - { - return $this->getKey($this->iteratorPosition); - } - - public function next() - { - ++$this->iteratorPosition; - } - - public function valid() - { - return $this->getKey($this->iteratorPosition) !== null - && array_key_exists( - $this->getKey($this->iteratorPosition), - $this->cartRules - ); - } - - protected function getKey($iteratorPosition) - { - $keys = array_keys($this->cartRules); - if (!isset($keys[$iteratorPosition])) { - return null; - } else { - return $keys[$iteratorPosition]; - } - } -} diff --git a/src/Core/Cart/CartRuleData.php b/src/Core/Cart/CartRuleData.php deleted file mode 100644 index 0502087f..00000000 --- a/src/Core/Cart/CartRuleData.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -class CartRuleData -{ - protected $ruleData = []; - - /** - * @var AmountImmutable - */ - protected $discountApplied; - - public function __construct($rowData) - { - $this->setRuleData($rowData); - $this->discountApplied = new AmountImmutable(); - } - - /** - * @param array $ruleData - * - * @return static - */ - public function setRuleData($ruleData) - { - $this->ruleData = $ruleData; - - return $this; - } - - /** - * @return array - */ - public function getRuleData() - { - return $this->ruleData; - } - - /** - * @return \CartRule - */ - public function getCartRule() - { - $cartRuleData = $this->getRuleData(); - - return $cartRuleData['obj']; - } - - public function addDiscountApplied(AmountImmutable $amount) - { - $this->discountApplied = $this->discountApplied->add($amount); - } - - /** - * @return AmountImmutable - */ - public function getDiscountApplied() - { - return $this->discountApplied; - } -} diff --git a/src/Core/Cart/Fees.php b/src/Core/Cart/Fees.php deleted file mode 100644 index 41562d85..00000000 --- a/src/Core/Cart/Fees.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Cart; - -use Cart; -use Currency; -use Tools; - -class Fees -{ - /** - * @var Cart - */ - protected $cart; - - /** - * @var AmountImmutable - */ - protected $shippingFees; - - /** - * @var AmountImmutable - */ - protected $finalShippingFees; - - /** - * @var AmountImmutable - */ - protected $wrappingFees; - - /** - * @var AmountImmutable - */ - protected $finalWrappingFees; - - /** - * indicates if cart was already processed. - * - * @var bool - */ - protected $isProcessed = false; - - /** - * @var int|null - */ - protected $orderId; - - /** - * @param int|null $orderId - */ - public function __construct(?int $orderId = null) - { - $this->shippingFees = new AmountImmutable(); - $this->orderId = $orderId; - } - - /** - * @param Cart $cart - * @param CartRowCollection $cartRowCollection - * @param int $computePrecision - * @param int $id_carrier - */ - public function processCalculation( - Cart $cart, - CartRowCollection $cartRowCollection, - $computePrecision, - $id_carrier = null - ) { - if ($id_carrier === null) { - $this->shippingFees = new AmountImmutable( - $cart->getTotalShippingCost(null, true), - $cart->getTotalShippingCost(null, false) - ); - } else { - $products = $cartRowCollection->getProducts(); - $this->shippingFees = new AmountImmutable( - $cart->getPackageShippingCost( - (int) $id_carrier, - true, - null, - $products, - null, - null !== $this->orderId - ), - $cart->getPackageShippingCost( - (int) $id_carrier, - false, - null, - $products, - null, - null !== $this->orderId - ) - ); - } - $this->finalShippingFees = clone $this->shippingFees; - - // wrapping fees - if ($cart->gift) { - $this->wrappingFees = new AmountImmutable( - Tools::convertPrice( - Tools::ps_round( - $cart->getGiftWrappingPrice(true), - $computePrecision - ), - Currency::getCurrencyInstance((int) $cart->id_currency) - ), - Tools::convertPrice( - Tools::ps_round( - $cart->getGiftWrappingPrice(false), - $computePrecision - ), - Currency::getCurrencyInstance((int) $cart->id_currency) - ) - ); - } else { - $this->wrappingFees = new AmountImmutable(); - } - $this->finalWrappingFees = clone $this->wrappingFees; - $this->isProcessed = true; - } - - /** - * @param Cart $cart - * - * @return Fees - */ - public function setCart($cart) - { - $this->cart = $cart; - - return $this; - } - - /** - * @return AmountImmutable - */ - public function getInitialShippingFees() - { - return $this->shippingFees; - } - - /** - * @return AmountImmutable - */ - public function getFinalShippingFees() - { - return $this->finalShippingFees; - } - - /** - * @return AmountImmutable - */ - public function getFinalWrappingFees() - { - return $this->finalWrappingFees; - } - - /** - * @return AmountImmutable - */ - public function getInitialWrappingFees() - { - return $this->wrappingFees; - } - - public function subDiscountValueShipping(AmountImmutable $amount) - { - $taxIncluded = $this->finalShippingFees->getTaxIncluded() - $amount->getTaxIncluded(); - $taxExcluded = $this->finalShippingFees->getTaxExcluded() - $amount->getTaxExcluded(); - if ($taxIncluded < 0) { - $taxIncluded = 0; - } - if ($taxExcluded < 0) { - $taxExcluded = 0; - } - $this->finalShippingFees = new AmountImmutable( - $taxIncluded, - $taxExcluded - ); - } -} diff --git a/src/Core/Checkout/TermsAndConditions.php b/src/Core/Checkout/TermsAndConditions.php deleted file mode 100644 index f79293f5..00000000 --- a/src/Core/Checkout/TermsAndConditions.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Checkout; - -/** - * TermsAndConditions object is used to render "terms and conditions" text sections with links in it - * - * @todo: refactor this class to make it stateless - */ -class TermsAndConditions -{ - /** - * CSS identifier used to build the tag ID - * - * @var string - */ - private $identifier; - - /** - * List of URLs to use, following a numerical index - * - * @var string[] - */ - private $links; - - /** - * @var string - */ - private $rawText; - - /** - * @param string $identifier - * - * @return $this - */ - public function setIdentifier($identifier) - { - $this->identifier = $identifier; - - return $this; - } - - /** - * This function expects more than 1 argument: additionnal arguments - * are used as links - * - * Exemple : $terms->setText('hello [world] [new]', 'http://www.world.com', 'http://new.com'); - * - * @param string $rawText - * - * @return $this - */ - public function setText($rawText) - { - $links = func_get_args(); - array_shift($links); - - $this->links = $links; - $this->rawText = $rawText; - - return $this; - } - - /** - * Parses given raw text, replacing all [something] statements with tags, - * using URLs from $this->links - * - * @return string formatted text, which now contains HTML tags - */ - public function format() - { - $index = 0; - - $formattedText = preg_replace_callback('/\[(.*?)\]/', function (array $match) use (&$index) { - $textToReplace = $match[1]; - - $thereIsAMatchingLink = isset($this->links[$index]); - if ($thereIsAMatchingLink === false) { - return $textToReplace; - } - - $replacement = sprintf( - '%s', - $this->links[$index], - $this->createLinkId($index), - $textToReplace - ); - - ++$index; - - return $replacement; - }, $this->rawText); - - return $formattedText; - } - - /** - * @return string - */ - public function getIdentifier() - { - return $this->identifier; - } - - /** - * @param int $index - * - * @return string - */ - protected function createLinkId($index) - { - return 'cta-' . $this->getIdentifier() . '-' . $index; - } -} diff --git a/src/Core/CommandBus/CommandBusInterface.php b/src/Core/CommandBus/CommandBusInterface.php deleted file mode 100644 index a88e4c82..00000000 --- a/src/Core/CommandBus/CommandBusInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus; - -/** - * Interface CommandBusInterface defines contract for Commands bus. - */ -interface CommandBusInterface -{ - /** - * Handle command. - * - * @param object $command - */ - public function handle($command); -} diff --git a/src/Core/CommandBus/ExecutedCommandRegistry.php b/src/Core/CommandBus/ExecutedCommandRegistry.php deleted file mode 100644 index 7e86d1a8..00000000 --- a/src/Core/CommandBus/ExecutedCommandRegistry.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\CommandBus; - -use PrestaShop\PrestaShop\Core\CommandBus\Parser\CommandTypeParser; - -/** - * Stores information about executed commands/queries - */ -final class ExecutedCommandRegistry -{ - private const BACKTRACE_LIMIT = 10; - - /** - * @var array - */ - private $registry = [ - 'commands' => [], - 'queries' => [], - ]; - - /** - * @var CommandTypeParser - */ - private $commandTypeParser; - - /** - * @param CommandTypeParser $commandTypeParser - */ - public function __construct(CommandTypeParser $commandTypeParser) - { - $this->commandTypeParser = $commandTypeParser; - } - - /** - * @param object $command - * @param object $handler - */ - public function register($command, $handler): void - { - $commandClass = get_class($command); - $handlerClass = get_class($handler); - - $type = $this->commandTypeParser->parse($commandClass); - - $trace = $this->getTrace(); - - switch ($type) { - case 'Command': - $this->registry['commands'][] = [ - 'command' => $commandClass, - 'command_handler' => $handlerClass, - 'trace' => $trace, - ]; - break; - case 'Query': - $this->registry['queries'][] = [ - 'query' => $commandClass, - 'query_handler' => $handlerClass, - 'trace' => $trace, - ]; - break; - } - } - - /** - * @return array - */ - public function getExecutedCommands(): array - { - return $this->registry['commands']; - } - - /** - * @return array - */ - public function getExecutedQueries(): array - { - return $this->registry['queries']; - } - - /** - * Returns the file and line that invoked the handle method - * - * @return array - */ - private function getTrace(): array - { - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, self::BACKTRACE_LIMIT); - - foreach ($trace as $step) { - if ($step['class'] === TacticianCommandBusAdapter::class - && $step['function'] === 'handle' - ) { - return [ - 'file' => $step['file'], - 'line' => $step['line'], - ]; - } - } - - return [ - 'file' => 'Unknown', - 'line' => 0, - ]; - } -} diff --git a/src/Core/CommandBus/Middleware/CommandRegisterMiddleware.php b/src/Core/CommandBus/Middleware/CommandRegisterMiddleware.php deleted file mode 100644 index 476af167..00000000 --- a/src/Core/CommandBus/Middleware/CommandRegisterMiddleware.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus\Middleware; - -use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor; -use League\Tactician\Handler\Locator\HandlerLocator; -use League\Tactician\Middleware; -use PrestaShop\PrestaShop\Core\CommandBus\ExecutedCommandRegistry; - -/** - * Registers every command that was executed in system - */ -final class CommandRegisterMiddleware implements Middleware -{ - /** - * @var HandlerLocator - */ - private $handlerLocator; - - /** - * @var CommandNameExtractor - */ - private $commandNameExtractor; - - /** - * @var ExecutedCommandRegistry - */ - private $executedCommandRegistry; - - /** - * @param HandlerLocator $handlerLocator - * @param CommandNameExtractor $commandNameExtractor - * @param ExecutedCommandRegistry $executedCommandRegistry - */ - public function __construct( - HandlerLocator $handlerLocator, - CommandNameExtractor $commandNameExtractor, - ExecutedCommandRegistry $executedCommandRegistry - ) { - $this->handlerLocator = $handlerLocator; - $this->commandNameExtractor = $commandNameExtractor; - $this->executedCommandRegistry = $executedCommandRegistry; - } - - /** - * {@inheritdoc} - */ - public function execute($command, callable $next) - { - $commandName = $this->commandNameExtractor->extract($command); - $handler = $this->handlerLocator->getHandlerForCommand($commandName); - - $this->executedCommandRegistry->register($command, $handler); - - return $next($command); - } -} diff --git a/src/Core/CommandBus/Parser/CommandDefinition.php b/src/Core/CommandBus/Parser/CommandDefinition.php deleted file mode 100644 index da99249d..00000000 --- a/src/Core/CommandBus/Parser/CommandDefinition.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus\Parser; - -/** - * Transfers commands and queries definition data - */ -class CommandDefinition -{ - /** - * @var string - */ - private $className; - - /** - * @var string - */ - private $commandType; - - /** - * @var string - */ - private $description; - - /** - * @param string $className - * @param string $commandType - * @param string $description - */ - public function __construct($className, $commandType, $description) - { - $this->className = $className; - $this->commandType = $commandType; - $this->description = $description; - } - - /** - * @return string - */ - public function getClassName() - { - return $this->className; - } - - /** - * @return string - */ - public function getCommandType() - { - return $this->commandType; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->description; - } -} diff --git a/src/Core/CommandBus/Parser/CommandDefinitionParser.php b/src/Core/CommandBus/Parser/CommandDefinitionParser.php deleted file mode 100644 index 8e4a5d9b..00000000 --- a/src/Core/CommandBus/Parser/CommandDefinitionParser.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus\Parser; - -use ReflectionClass; -use ReflectionException; - -/** - * Parses commands and queries definitions - */ -final class CommandDefinitionParser -{ - /** - * @param string $commandName - * - * @return CommandDefinition - * - * @throws ReflectionException - */ - public function parseDefinition($commandName) - { - return new CommandDefinition( - $commandName, - $this->parseType($commandName), - $this->parseDescription($commandName) - ); - } - - /** - * Checks whether the command is of type Query or Command by provided name - * - * @param string $commandName - * - * @return string - */ - private function parseType($commandName) - { - if (strpos($commandName, '\Command\\')) { - return 'Command'; - } - - return 'Query'; - } - - /** - * @param string $commandName - * - * @return string - * - * @throws ReflectionException - */ - private function parseDescription($commandName) - { - /** - * Removes comment symbols, annotations, and line breaks. - */ - $commandName = preg_replace("/\/+\*\*|\*+\/|\*|@(\w+)\b(.*)|\n/", - '', - (new ReflectionClass($commandName))->getDocComment() - ); - - /** - * Replaces multiple spaces to single space - */ - $commandName = preg_replace('/ +/', ' ', $commandName); - - /* - * Strips whitespace from the beginning and end - */ - return trim($commandName); - } -} diff --git a/src/Core/CommandBus/Parser/CommandTypeParser.php b/src/Core/CommandBus/Parser/CommandTypeParser.php deleted file mode 100644 index 42c9a094..00000000 --- a/src/Core/CommandBus/Parser/CommandTypeParser.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus\Parser; - -final class CommandTypeParser -{ - /** - * @param string $commandName Fully-qualified class name of command - * - * @return string - */ - public function parse($commandName) - { - if (strpos($commandName, '\Command\\')) { - return 'Command'; - } - - return 'Query'; - } -} diff --git a/src/Core/CommandBus/TacticianCommandBusAdapter.php b/src/Core/CommandBus/TacticianCommandBusAdapter.php deleted file mode 100644 index 275b0cfa..00000000 --- a/src/Core/CommandBus/TacticianCommandBusAdapter.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CommandBus; - -use League\Tactician\CommandBus; - -/** - * Class TacticianCommandBusAdapter is Tactician's CommandsBus implementation for PrestaShop's contract. - */ -final class TacticianCommandBusAdapter implements CommandBusInterface -{ - /** - * @var CommandBus - */ - private $bus; - - /** - * @param CommandBus $bus - */ - public function __construct(CommandBus $bus) - { - $this->bus = $bus; - } - - /** - * {@inheritdoc} - */ - public function handle($command) - { - return $this->bus->handle($command); - } -} diff --git a/src/Core/Configuration/DataConfigurationInterface.php b/src/Core/Configuration/DataConfigurationInterface.php deleted file mode 100644 index 19a14bd2..00000000 --- a/src/Core/Configuration/DataConfigurationInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -/** - * Retrieve and Manage configuration (used to manage forms in "Configure" section of back office). - */ -interface DataConfigurationInterface -{ - /** - * @return array - */ - public function getConfiguration(); - - /** - * @param array $configuration - * - * @return array if not empty, populated by validation errors - */ - public function updateConfiguration(array $configuration); - - /** - * Ensure the parameters passed are valid. - * - * @param array $configuration - * - * @return bool Returns true if no exception are thrown - */ - public function validateConfiguration(array $configuration); -} diff --git a/src/Core/Configuration/IniConfiguration.php b/src/Core/Configuration/IniConfiguration.php deleted file mode 100644 index 26ce1e6f..00000000 --- a/src/Core/Configuration/IniConfiguration.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -/** - * Gets ini configuration. - */ -class IniConfiguration -{ - /** - * Get max post max size from ini configuration in bytes. - * - * @return int - */ - public function getPostMaxSizeInBytes() - { - return $this->convertToBytes(ini_get('post_max_size')); - } - - /** - * Get maximum upload size allowed by the server in bytes. - * - * @return int - */ - public function getUploadMaxSizeInBytes() - { - return min( - $this->convertToBytes(ini_get('upload_max_filesize')), - $this->getPostMaxSizeInBytes() - ); - } - - /** - * Convert a numeric value to bytes. - * - * @param int $value - * - * @return int - */ - private function convertToBytes($value) - { - $bytes = (int) trim($value); - $last = strtolower($value[strlen($value) - 1]); - - switch ($last) { - case 'g': - $bytes *= 1024; - // no break to fall-through - case 'm': - $bytes *= 1024; - // no break to fall-through - case 'k': - $bytes *= 1024; - } - - return $bytes; - } -} diff --git a/src/Core/Configuration/PhpExtensionChecker.php b/src/Core/Configuration/PhpExtensionChecker.php deleted file mode 100644 index ef6632aa..00000000 --- a/src/Core/Configuration/PhpExtensionChecker.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -/** - * Class PhpExtensionChecker provides object-oriented way to check if PHP extensions are loaded. - */ -final class PhpExtensionChecker implements PhpExtensionCheckerInterface -{ - /** - * {@inheritdoc} - */ - public function loaded($extension) - { - return extension_loaded($extension); - } -} diff --git a/src/Core/Configuration/PhpExtensionCheckerInterface.php b/src/Core/Configuration/PhpExtensionCheckerInterface.php deleted file mode 100644 index 11ee4692..00000000 --- a/src/Core/Configuration/PhpExtensionCheckerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -/** - * Interface PhpExtensionCheckerInterface. - */ -interface PhpExtensionCheckerInterface -{ - /** - * Check if PHP extension is loaded or not. - * - * @param string $extension - * - * @return bool - */ - public function loaded($extension); -} diff --git a/src/Core/Configuration/UploadSizeConfiguration.php b/src/Core/Configuration/UploadSizeConfiguration.php deleted file mode 100644 index 606db134..00000000 --- a/src/Core/Configuration/UploadSizeConfiguration.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -class UploadSizeConfiguration implements UploadSizeConfigurationInterface -{ - /** - * @var IniConfiguration - */ - private $iniConfiguration; - - /** - * @param IniConfiguration $iniConfiguration - */ - public function __construct(IniConfiguration $iniConfiguration) - { - $this->iniConfiguration = $iniConfiguration; - } - - /** - * {@inheritdoc} - */ - public function getMaxUploadSizeInBytes(): int - { - return $this->iniConfiguration->getUploadMaxSizeInBytes(); - } - - /** - * {@inheritdoc} - */ - public function getPostMaxSizeInBytes(): int - { - return $this->iniConfiguration->getPostMaxSizeInBytes(); - } -} diff --git a/src/Core/Configuration/UploadSizeConfigurationInterface.php b/src/Core/Configuration/UploadSizeConfigurationInterface.php deleted file mode 100644 index e55e269f..00000000 --- a/src/Core/Configuration/UploadSizeConfigurationInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Configuration; - -interface UploadSizeConfigurationInterface -{ - /** - * @return int - */ - public function getMaxUploadSizeInBytes(): int; - - /** - * @return int - */ - public function getPostMaxSizeInBytes(): int; -} diff --git a/src/Core/ConfigurationInterface.php b/src/Core/ConfigurationInterface.php deleted file mode 100644 index 415d7453..00000000 --- a/src/Core/ConfigurationInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core; - -interface ConfigurationInterface -{ - public function get($key); - - public function set($key, $value); -} diff --git a/src/Core/ConstraintValidator/AddressDniRequiredValidator.php b/src/Core/ConstraintValidator/AddressDniRequiredValidator.php deleted file mode 100644 index 83ddb89c..00000000 --- a/src/Core/ConstraintValidator/AddressDniRequiredValidator.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\Country\CountryRequiredFieldsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\ConstraintViolationInterface; - -/** - * Validates address DNI according to the country value and fields requirement - */ -class AddressDniRequiredValidator extends ConstraintValidator -{ - /** - * @var CountryRequiredFieldsProviderInterface - */ - private $countryRequiredFieldsProvider; - - /** - * @param CountryRequiredFieldsProviderInterface $countryRequiredFieldsProvider - */ - public function __construct(CountryRequiredFieldsProviderInterface $countryRequiredFieldsProvider) - { - $this->countryRequiredFieldsProvider = $countryRequiredFieldsProvider; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - $countryId = new CountryId((int) $constraint->id_country); - - if ($this->countryRequiredFieldsProvider->isDniRequired($countryId) || $constraint->required) { - $constraints = [new NotBlank([ - 'message' => $constraint->message, - ])]; - - /** @var ConstraintViolationInterface[] $violations */ - $violations = $this->context->getValidator()->validate($value, $constraints); - foreach ($violations as $violation) { - $this->context->buildViolation($violation->getMessage()) - ->setTranslationDomain('Admin.Notifications.Error') - ->addViolation(); - } - } - } -} diff --git a/src/Core/ConstraintValidator/AddressStateRequiredValidator.php b/src/Core/ConstraintValidator/AddressStateRequiredValidator.php deleted file mode 100644 index 282fdf6d..00000000 --- a/src/Core/ConstraintValidator/AddressStateRequiredValidator.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\Country\CountryRequiredFieldsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\ConstraintViolationInterface; - -/** - * Validates address state choice by selected country value - */ -class AddressStateRequiredValidator extends ConstraintValidator -{ - /** - * @var CountryRequiredFieldsProviderInterface - */ - private $countryRequiredFieldsProvider; - - /** - * @param CountryRequiredFieldsProviderInterface $countryRequiredFieldsProvider - */ - public function __construct(CountryRequiredFieldsProviderInterface $countryRequiredFieldsProvider) - { - $this->countryRequiredFieldsProvider = $countryRequiredFieldsProvider; - } - - /** - * {@inheritdoc} - * - * @throws CountryConstraintException - */ - public function validate($value, Constraint $constraint) - { - $countryId = new CountryId((int) $constraint->id_country); - - if ($this->countryRequiredFieldsProvider->isStatesRequired($countryId)) { - $constraints = [new NotBlank([ - 'message' => $constraint->message, - ])]; - - /** @var ConstraintViolationInterface[] $violations */ - $violations = $this->context->getValidator()->validate($value, $constraints); - foreach ($violations as $violation) { - $this->context->buildViolation($violation->getMessage()) - ->setTranslationDomain('Admin.Notifications.Error') - ->addViolation(); - } - } - } -} diff --git a/src/Core/ConstraintValidator/AddressZipCodeValidator.php b/src/Core/ConstraintValidator/AddressZipCodeValidator.php deleted file mode 100644 index 4b63b6de..00000000 --- a/src/Core/ConstraintValidator/AddressZipCodeValidator.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\Country\CountryZipCodeRequirements; -use PrestaShop\PrestaShop\Core\Country\CountryZipCodeRequirementsProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\ConstraintViolationInterface; - -/** - * Validator for address zip code value - */ -final class AddressZipCodeValidator extends ConstraintValidator -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var CountryZipCodeRequirementsProviderInterface - */ - private $requirementsProvider; - - /** - * @param TranslatorInterface $translator - * @param CountryZipCodeRequirementsProviderInterface $requirementsProvider - */ - public function __construct( - TranslatorInterface $translator, - CountryZipCodeRequirementsProviderInterface $requirementsProvider - ) { - $this->translator = $translator; - $this->requirementsProvider = $requirementsProvider; - } - - /** - * {@inheritdoc} - * - * @throws CountryConstraintException - */ - public function validate($value, Constraint $constraint) - { - $countryId = (int) $constraint->id_country; - - /** @var CountryZipCodeRequirements $requirements */ - $requirements = $this->requirementsProvider->getCountryZipCodeRequirements(new CountryId($countryId)); - - if ($requirements->isRequired() || $constraint->required) { - $constraints = [new NotBlank([ - 'message' => $constraint->requiredMessage, - ])]; - - /** @var ConstraintViolationInterface[] $violations */ - $violations = $this->context->getValidator()->validate($value, $constraints); - foreach ($violations as $violation) { - $this->context->buildViolation($violation->getMessage()) - ->setTranslationDomain('Admin.Notifications.Error') - ->addViolation(); - } - } - - if (null !== $requirements->getPattern() && !(bool) preg_match($requirements->getPattern(), $value)) { - $message = $this->translator->trans('Your Zip/postal code is incorrect.', [], 'Admin.Notifications.Error') . - ' ' . - $this->translator->trans('It must be entered as follows:', [], 'Admin.Notifications.Error') . ' ' . - $requirements->getHumanReadablePattern() - ; - - $this->context->buildViolation($message)->addViolation(); - } - } -} diff --git a/src/Core/ConstraintValidator/CleanHtmlValidator.php b/src/Core/ConstraintValidator/CleanHtmlValidator.php deleted file mode 100644 index d9f4f339..00000000 --- a/src/Core/ConstraintValidator/CleanHtmlValidator.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Class CleanHtmlValidator is responsible for validating the html content to prevent from having javascript events - * or script tags. - */ -final class CleanHtmlValidator extends ConstraintValidator -{ - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof CleanHtml) { - throw new UnexpectedTypeException($constraint, CleanHtml::class); - } - - if (!$value) { - return; - } - - if (!is_string($value)) { - throw new UnexpectedTypeException($value, 'string'); - } - - $containsScriptTags = preg_match('/<[\s]*script/ims', $value) || preg_match('/.*script\:/ims', $value); - $containsJavascriptEvents = preg_match('/(' . $this->getJavascriptEvents() . ')[\s]*=/ims', $value); - - if ($containsScriptTags || $containsJavascriptEvents) { - $this->context->buildViolation($constraint->message) - ->setTranslationDomain('Admin.Notifications.Error') - ->setParameter('%s', $this->formatValue($value)) - ->addViolation() - ; - } - } - - /** - * Gets javascript events separated by pipeline which are used in preg match pattern to determine if string - * contains a javascript event. E.g onchange= is valid call for js event. - * - * @return string - */ - private function getJavascriptEvents() - { - $events = 'onmousedown|onmousemove|onmmouseup|onmouseover|onmouseout|onload|onunload|onfocus|onblur|onchange'; - $events .= '|onsubmit|ondblclick|onclick|onkeydown|onkeyup|onkeypress|onmouseenter|onmouseleave|onerror|onselect|onreset|onabort|ondragdrop|onresize|onactivate|onafterprint|onmoveend'; - $events .= '|onafterupdate|onbeforeactivate|onbeforecopy|onbeforecut|onbeforedeactivate|onbeforeeditfocus|onbeforepaste|onbeforeprint|onbeforeunload|onbeforeupdate|onmove'; - $events .= '|onbounce|oncellchange|oncontextmenu|oncontrolselect|oncopy|oncut|ondataavailable|ondatasetchanged|ondatasetcomplete|ondeactivate|ondrag|ondragend|ondragenter|onmousewheel'; - $events .= '|ondragleave|ondragover|ondragstart|ondrop|onerrorupdate|onfilterchange|onfinish|onfocusin|onfocusout|onhashchange|onhelp|oninput|onlosecapture|onmessage|onmouseup|onmovestart'; - $events .= '|onoffline|ononline|onpaste|onpropertychange|onreadystatechange|onresizeend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onsearch|onselectionchange'; - $events .= '|onselectstart|onstart|onstop'; - - return $events; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/AddressDniRequired.php b/src/Core/ConstraintValidator/Constraints/AddressDniRequired.php deleted file mode 100644 index 2f491287..00000000 --- a/src/Core/ConstraintValidator/Constraints/AddressDniRequired.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\AddressDniRequiredValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Validation constraint for address DNI according to the country value and fields requirement - */ -class AddressDniRequired extends Constraint -{ - public $message = 'This field cannot be empty'; - - public $id_country; - - public $required; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return AddressDniRequiredValidator::class; - } - - public function getRequiredOptions() - { - return ['id_country', 'required']; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/AddressStateRequired.php b/src/Core/ConstraintValidator/Constraints/AddressStateRequired.php deleted file mode 100644 index d289ac34..00000000 --- a/src/Core/ConstraintValidator/Constraints/AddressStateRequired.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\AddressStateRequiredValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Validation constraint for address state choice by selected country value - */ -class AddressStateRequired extends Constraint -{ - public $message = 'An address located in a country containing states must have a state selected.'; - - public $id_country; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return AddressStateRequiredValidator::class; - } - - public function getRequiredOptions() - { - return ['id_country']; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/AddressZipCode.php b/src/Core/ConstraintValidator/Constraints/AddressZipCode.php deleted file mode 100644 index 552af23a..00000000 --- a/src/Core/ConstraintValidator/Constraints/AddressZipCode.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\AddressZipCodeValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Address zip code validation constraint - */ -class AddressZipCode extends Constraint -{ - public $requiredMessage = 'A Zip/postal code is required.'; - - public $id_country; - - public $required; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return AddressZipCodeValidator::class; - } - - public function getRequiredOptions() - { - return ['id_country', 'required']; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/CleanHtml.php b/src/Core/ConstraintValidator/Constraints/CleanHtml.php deleted file mode 100644 index d9eb6da1..00000000 --- a/src/Core/ConstraintValidator/Constraints/CleanHtml.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\CleanHtmlValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Class CleanHtml is responsible for validating the html content to prevent from having javascript events - * or script tags. - */ -final class CleanHtml extends Constraint -{ - public $message = '%s is invalid.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return CleanHtmlValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/CustomerName.php b/src/Core/ConstraintValidator/Constraints/CustomerName.php deleted file mode 100644 index dd83c812..00000000 --- a/src/Core/ConstraintValidator/Constraints/CustomerName.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\CustomerNameValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Class CustomerName is responsible of validating customer name according to several patterns. - */ -final class CustomerName extends Constraint -{ - public $message = 'The %s field is invalid.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return CustomerNameValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/DateRange.php b/src/Core/ConstraintValidator/Constraints/DateRange.php deleted file mode 100644 index 798eec64..00000000 --- a/src/Core/ConstraintValidator/Constraints/DateRange.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\DateRangeValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Provides date range validation - */ -class DateRange extends Constraint -{ - public $message = 'The selected date range is not valid.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return DateRangeValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/DefaultLanguage.php b/src/Core/ConstraintValidator/Constraints/DefaultLanguage.php deleted file mode 100644 index 06bb13e1..00000000 --- a/src/Core/ConstraintValidator/Constraints/DefaultLanguage.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\DefaultLanguageValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Class DefaultLanguage is responsible for checking if the array contains default language id - its common to require - * default language to be presented when saving required multi-language fields. - */ -class DefaultLanguage extends Constraint -{ - public $message = 'The field %field_name% is required at least in your default language.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return DefaultLanguageValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/ExistingCustomerEmail.php b/src/Core/ConstraintValidator/Constraints/ExistingCustomerEmail.php deleted file mode 100644 index 317e43af..00000000 --- a/src/Core/ConstraintValidator/Constraints/ExistingCustomerEmail.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\ExistingCustomerEmailValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Validation constraint for checking if customer with given email exists in current shop context - */ -class ExistingCustomerEmail extends Constraint -{ - public $message = 'This email address is not registered.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return ExistingCustomerEmailValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/IsUrlRewrite.php b/src/Core/ConstraintValidator/Constraints/IsUrlRewrite.php deleted file mode 100644 index e5e2cbfb..00000000 --- a/src/Core/ConstraintValidator/Constraints/IsUrlRewrite.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\IsUrlRewriteValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Class IsUrlRewrite is responsible of validating url rewrites according to several patterns - * which differ when ascending urls are enabled or not. - * - * @Annotation - */ -class IsUrlRewrite extends Constraint -{ - public $message = '%s is invalid.'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return IsUrlRewriteValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/NotBlankWhenRequired.php b/src/Core/ConstraintValidator/Constraints/NotBlankWhenRequired.php deleted file mode 100644 index c47708fb..00000000 --- a/src/Core/ConstraintValidator/Constraints/NotBlankWhenRequired.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\NotBlankWhenRequiredValidator; -use Symfony\Component\Validator\Constraints\NotBlank; - -class NotBlankWhenRequired extends NotBlank -{ - public $required; - - public function validatedBy() - { - return NotBlankWhenRequiredValidator::class; - } - - public function getRequiredOptions() - { - return ['required']; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/Reduction.php b/src/Core/ConstraintValidator/Constraints/Reduction.php deleted file mode 100644 index c1031af3..00000000 --- a/src/Core/ConstraintValidator/Constraints/Reduction.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\ReductionValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Constraint for validating reduction - */ -final class Reduction extends Constraint -{ - public $invalidTypeMessage = 'Reduction type "%type%" is invalid. Allowed types are: %types%.'; - - public $invalidAmountValueMessage = 'Reduction value "%value%" is invalid. Value cannot be negative'; - - public $invalidPercentageValueMessage = 'Reduction value "%value%" is invalid. Allowed values from 0 to %max%'; - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return ReductionValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/Constraints/TypedRegex.php b/src/Core/ConstraintValidator/Constraints/TypedRegex.php deleted file mode 100644 index e9b0cc12..00000000 --- a/src/Core/ConstraintValidator/Constraints/TypedRegex.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\TypedRegexValidator; -use Symfony\Component\Validator\Constraint; - -/** - * Provides regex validation by type - */ -class TypedRegex extends Constraint -{ - /** - * Available types - */ - const TYPE_NAME = 'name'; - const TYPE_CATALOG_NAME = 'catalog_name'; - const TYPE_GENERIC_NAME = 'generic_name'; - const TYPE_CITY_NAME = 'city_name'; - const TYPE_ADDRESS = 'address'; - const TYPE_POST_CODE = 'post_code'; - const TYPE_PHONE_NUMBER = 'phone_number'; - const TYPE_MESSAGE = 'message'; - const TYPE_LANGUAGE_ISO_CODE = 'language_iso_code'; - const TYPE_LANGUAGE_CODE = 'language_code'; - const TYPE_CURRENCY_ISO_CODE = 'currency_iso_code'; - const TYPE_FILE_NAME = 'file_name'; - const TYPE_DNI_LITE = 'dni_lite'; - - /** - * @var string - */ - public $message = '%s is invalid'; - - /** - * @var string - */ - public $type; - - /** - * {@inheritdoc} - */ - public function getRequiredOptions() - { - return ['type']; - } - - /** - * {@inheritdoc} - */ - public function validatedBy() - { - return TypedRegexValidator::class; - } -} diff --git a/src/Core/ConstraintValidator/CustomerNameValidator.php b/src/Core/ConstraintValidator/CustomerNameValidator.php deleted file mode 100644 index 80bd6948..00000000 --- a/src/Core/ConstraintValidator/CustomerNameValidator.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CustomerName; -use PrestaShop\PrestaShop\Core\String\CharacterCleaner; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Class CustomerNameValidator is responsilbe for doing the actual validation under CustomerName constraint. - */ -class CustomerNameValidator extends ConstraintValidator -{ - const PATTERN_NAME = '/^(?!\s*$)(?:[^0-9!<>,;?=+()\/\\\\@#"°*`{}_^$%:¤\[\]|\.。]|[。\.](?:\s|$))*$/u'; - const PATTERN_DOT_SPACED = '/[\.。](\s{1}[^\ ]|$)/'; - - /** - * @var CharacterCleaner - */ - private $characterCleaner; - - /** - * @param CharacterCleaner $characterCleaner - */ - public function __construct(CharacterCleaner $characterCleaner) - { - $this->characterCleaner = $characterCleaner; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof CustomerName) { - throw new UnexpectedTypeException($constraint, CustomerName::class); - } - - if (!is_string($value)) { - throw new UnexpectedTypeException($value, 'string'); - } - - if (!$this->isNameValid($value) || !$this->isPointSpacedValid($value)) { - $this->context->buildViolation($constraint->message) - ->addViolation() - ; - } - } - - /** - * Validates url rewrite according a specific pattern. - * - * @param string $name - * - * @return bool - */ - private function isNameValid($name) - { - $pattern = $this->characterCleaner->cleanNonUnicodeSupport(self::PATTERN_NAME); - - return (bool) preg_match($pattern, $name); - } - - /** - * Check if there is not more one space after point - * - * @param string $name - * - * @return bool - */ - private function isPointSpacedValid($name) - { - if (mb_strpos($name, '.') === false && mb_strpos($name, '。') === false) { - return true; - } - $pattern = $this->characterCleaner->cleanNonUnicodeSupport(self::PATTERN_DOT_SPACED); - - return (bool) preg_match($pattern, $name); - } -} diff --git a/src/Core/ConstraintValidator/DateRangeValidator.php b/src/Core/ConstraintValidator/DateRangeValidator.php deleted file mode 100644 index 475709b5..00000000 --- a/src/Core/ConstraintValidator/DateRangeValidator.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use DateTime; -use Exception; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DateRange; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Validates ranges of date range - */ -class DateRangeValidator extends ConstraintValidator -{ - /** - * {@inheritdoc} - * - * @throws Exception - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof DateRange) { - throw new UnexpectedTypeException($constraint, DateRange::class); - } - - if (!is_array($value)) { - throw new UnexpectedTypeException($value, 'array'); - } - - if (!empty($value['from']) && !empty($value['to'])) { - $this->validateRange(new DateTime($value['from']), new DateTime($value['to']), $constraint->message); - } - } - - /** - * Validate that date range is not inverted. (the 'from' value is not higher than 'to') - * - * @param DateTime $from - * @param DateTime $to - * @param $message - */ - private function validateRange(DateTime $from, DateTime $to, $message) - { - if ($from->diff($to)->invert) { - $this->context->buildViolation($message) - ->atPath('[to]') - ->setTranslationDomain('Admin.Notifications.Error') - ->addViolation() - ; - } - } -} diff --git a/src/Core/ConstraintValidator/DefaultLanguageValidator.php b/src/Core/ConstraintValidator/DefaultLanguageValidator.php deleted file mode 100644 index 984417e2..00000000 --- a/src/Core/ConstraintValidator/DefaultLanguageValidator.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Class DefaultLanguageValidator is responsilbe for doing the actual validation under DefaultLanguage constraint. - */ -class DefaultLanguageValidator extends ConstraintValidator -{ - /** - * @var int - */ - private $defaultLanguageId; - - /** - * @param int $defaultLanguageId - */ - public function __construct($defaultLanguageId) - { - $this->defaultLanguageId = $defaultLanguageId; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof DefaultLanguage) { - throw new UnexpectedTypeException($constraint, DefaultLanguage::class); - } - - if (!is_array($value)) { - throw new UnexpectedTypeException($value, 'array'); - } - - if (empty($value[$this->defaultLanguageId])) { - $this->context->buildViolation($constraint->message) - ->setTranslationDomain('Admin.Notifications.Error') - ->setParameter( - '%field_name%', - $this->context->getObject() ? $this->context->getObject()->getName() : '' - ) - ->addViolation() - ; - } - } -} diff --git a/src/Core/ConstraintValidator/ExistingCustomerEmailValidator.php b/src/Core/ConstraintValidator/ExistingCustomerEmailValidator.php deleted file mode 100644 index b205e056..00000000 --- a/src/Core/ConstraintValidator/ExistingCustomerEmailValidator.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\ExistingCustomerEmail; -use PrestaShop\PrestaShop\Core\Customer\CustomerDataSourceInterface; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Validator for checking if customer with given email exists in current shop context - */ -final class ExistingCustomerEmailValidator extends ConstraintValidator -{ - /** - * @var CustomerDataSourceInterface - */ - private $customerDataSource; - - /** - * @param CustomerDataSourceInterface $customerDataSource - */ - public function __construct(CustomerDataSourceInterface $customerDataSource) - { - $this->customerDataSource = $customerDataSource; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof ExistingCustomerEmail) { - throw new UnexpectedTypeException($constraint, ExistingCustomerEmail::class); - } - - if (!$this->customerDataSource->hasCustomerWithEmail($value)) { - $this->context->buildViolation($constraint->message) - ->setTranslationDomain('Admin.Orderscustomers.Notification') - ->addViolation() - ; - } - } -} diff --git a/src/Core/ConstraintValidator/Factory/CustomerNameValidatorFactory.php b/src/Core/ConstraintValidator/Factory/CustomerNameValidatorFactory.php deleted file mode 100644 index b9516194..00000000 --- a/src/Core/ConstraintValidator/Factory/CustomerNameValidatorFactory.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator\Factory; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\CustomerNameValidator; -use PrestaShop\PrestaShop\Core\String\CharacterCleaner; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; -use Symfony\Component\Validator\ConstraintValidatorInterface; - -class CustomerNameValidatorFactory implements ConstraintValidatorFactoryInterface -{ - /** - * @var CharacterCleaner - */ - private $characterCleaner; - - /** - * CustomerNameValidatorFactory constructor. - * - * @param CharacterCleaner $characterCleaner - */ - public function __construct(CharacterCleaner $characterCleaner) - { - $this->characterCleaner = $characterCleaner; - } - - /** - * @param Constraint $constraint - * - * @return ConstraintValidatorInterface - */ - public function getInstance(Constraint $constraint) - { - return new CustomerNameValidator($this->characterCleaner); - } -} diff --git a/src/Core/ConstraintValidator/IsUrlRewriteValidator.php b/src/Core/ConstraintValidator/IsUrlRewriteValidator.php deleted file mode 100644 index fdec4721..00000000 --- a/src/Core/ConstraintValidator/IsUrlRewriteValidator.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\IsUrlRewrite; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Class IsUrlRewriteValidator is responsible of validating url rewrites according to several patterns - * which differ when ascending urls are enabled or not. - */ -class IsUrlRewriteValidator extends ConstraintValidator -{ - /** - * @var ConfigurationInterface|bool - */ - private $accentedCharsConfiguration; - - /** - * this constructor can accept boolean value of already predefined accented chars allowance configuration to not - * introduce BC break. The recommended approach is to pass - * PrestaShop\PrestaShop\Adapter\Configuration as a service instead to avoid keeping cached scalar value. - * - * @param ConfigurationInterface|bool $accentedCharsConfiguration - */ - public function __construct($accentedCharsConfiguration) - { - $this->accentedCharsConfiguration = $accentedCharsConfiguration; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof IsUrlRewrite) { - throw new UnexpectedTypeException($constraint, IsUrlRewrite::class); - } - - if (null === $value || '' === $value) { - return; - } - - if (!is_string($value)) { - throw new UnexpectedTypeException($value, 'string'); - } - - if (!$this->isUrlRewriteValid($value)) { - $this->context->buildViolation($constraint->message) - ->setTranslationDomain('Admin.Notifications.Error') - ->setParameter('%s', $this->formatValue($value)) - ->addViolation() - ; - } - } - - /** - * Validates url rewrite according the patterns which vary based on ascented chars allowed setting. - * - * @param string $urlRewrite - * - * @return false|int - */ - private function isUrlRewriteValid($urlRewrite) - { - $pattern = '/^[_a-zA-Z0-9\-]+$/'; - - if ($this->getAllowAccentedCharsSetting()) { - $pattern = '/^[_a-zA-Z0-9\pL\pS-]+$/u'; - } - - return preg_match($pattern, $urlRewrite); - } - - /** - * Gets the accented chars url setting. - * - * @return bool - */ - private function getAllowAccentedCharsSetting() - { - if ($this->accentedCharsConfiguration instanceof ConfigurationInterface) { - return $this->accentedCharsConfiguration->get('PS_ALLOW_ACCENTED_CHARS_URL'); - } - - return $this->accentedCharsConfiguration; - } -} diff --git a/src/Core/ConstraintValidator/NotBlankWhenRequiredValidator.php b/src/Core/ConstraintValidator/NotBlankWhenRequiredValidator.php deleted file mode 100644 index 7e2a5e35..00000000 --- a/src/Core/ConstraintValidator/NotBlankWhenRequiredValidator.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Constraints\NotBlankValidator; - -class NotBlankWhenRequiredValidator extends NotBlankValidator -{ - public function validate($value, Constraint $constraint) - { - if (true === $constraint->required) { - parent::validate($value, $constraint); - } - } -} diff --git a/src/Core/ConstraintValidator/ReductionValidator.php b/src/Core/ConstraintValidator/ReductionValidator.php deleted file mode 100644 index e353fac7..00000000 --- a/src/Core/ConstraintValidator/ReductionValidator.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\Reduction as ReductionConstraint; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Validates reduction type and value - */ -final class ReductionValidator extends ConstraintValidator -{ - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof ReductionConstraint) { - throw new UnexpectedTypeException($constraint, ReductionConstraint::class); - } - - if (null === $value || '' === $value) { - return; - } - - if (!is_array($value)) { - throw new UnexpectedTypeException($value, 'array'); - } - - if (!$this->isAllowedType($value['type'])) { - $this->buildViolation( - $constraint->invalidTypeMessage, - [ - '%type%' => $value['type'], - '%types%' => implode(', ', [Reduction::TYPE_PERCENTAGE, Reduction::TYPE_AMOUNT]), - ], - '[type]' - ); - } - - if (Reduction::TYPE_AMOUNT === $value['type']) { - if (!$this->assertIsValidAmount($value['value'])) { - $this->buildViolation( - $constraint->invalidAmountValueMessage, - ['%value%' => $value['value']], - '[value]' - ); - } - } elseif (Reduction::TYPE_PERCENTAGE === $value['type']) { - if (!$this->assertIsValidPercentage($value['value'])) { - $this->buildViolation( - $constraint->invalidPercentageValueMessage, - [ - '%value%' => $value['value'], - '%max%' => Reduction::MAX_ALLOWED_PERCENTAGE, - ], - '[value]' - ); - } - } - } - - /** - * Returns true if type is defined in allowed types, false otherwise - * - * @param string $type - * - * @return bool - */ - private function isAllowedType(string $type): bool - { - return in_array($type, Reduction::ALLOWED_TYPES, true); - } - - /** - * Returns true is percentage is considered valid - * - * @param float $value - * - * @return bool - */ - private function assertIsValidPercentage(float $value) - { - return 0 <= $value && Reduction::MAX_ALLOWED_PERCENTAGE >= $value; - } - - /** - * Returns true if amount value is considered valid - * - * @param float $value - * - * @return bool - */ - private function assertIsValidAmount(float $value) - { - return 0 <= $value; - } - - /** - * Builds violation dependent from exception code - * - * @param string $message - * @param array $params - * @param string $errorPath - */ - private function buildViolation(string $message, array $params, string $errorPath) - { - $this->context->buildViolation($message, $params) - ->setTranslationDomain('Admin.Notifications.Error') - ->atPath($errorPath) - ->setParameters($params) - ->addViolation() - ; - } -} diff --git a/src/Core/ConstraintValidator/TypedRegexValidator.php b/src/Core/ConstraintValidator/TypedRegexValidator.php deleted file mode 100644 index a5b34fb3..00000000 --- a/src/Core/ConstraintValidator/TypedRegexValidator.php +++ /dev/null @@ -1,157 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\ConstraintValidator; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\Address\Configuration\AddressConstraint; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\String\CharacterCleaner; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\InvalidArgumentException; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -/** - * Validates specific regex pattern for provided type - */ -class TypedRegexValidator extends ConstraintValidator -{ - /** - * @var CharacterCleaner - */ - private $characterCleaner; - - /** - * @param CharacterCleaner $characterCleaner - */ - public function __construct(CharacterCleaner $characterCleaner) - { - $this->characterCleaner = $characterCleaner; - } - - /** - * {@inheritdoc} - */ - public function validate($value, Constraint $constraint) - { - if (!$constraint instanceof TypedRegex) { - throw new UnexpectedTypeException($constraint, TypedRegex::class); - } - - if (null === $value || '' === $value) { - return; - } - - if (!is_string($value)) { - throw new UnexpectedTypeException($value, 'string'); - } - - $pattern = $this->getPattern($constraint->type); - $value = $this->sanitize($value, $constraint->type); - - if (!$this->match($pattern, $constraint->type, $value)) { - $this->context->buildViolation($constraint->message) - ->setTranslationDomain('Admin.Notifications.Error') - ->setParameter('%s', $this->formatValue($value)) - ->addViolation() - ; - } - } - - /** - * Returns regex pattern that depends on type - * - * @param string $type - * - * @return string - */ - private function getPattern($type) - { - $typePatterns = [ - TypedRegex::TYPE_NAME => $this->characterCleaner->cleanNonUnicodeSupport('/^[^0-9!<>,;?=+()@#"°{}_$%:¤|]*$/u'), - TypedRegex::TYPE_CATALOG_NAME => $this->characterCleaner->cleanNonUnicodeSupport('/^[^<>;=#{}]*$/u'), - TypedRegex::TYPE_GENERIC_NAME => $this->characterCleaner->cleanNonUnicodeSupport('/^[^<>={}]*$/u'), - TypedRegex::TYPE_CITY_NAME => $this->characterCleaner->cleanNonUnicodeSupport('/^[^!<>;?=+@#"°{}_$%]*$/u'), - TypedRegex::TYPE_ADDRESS => $this->characterCleaner->cleanNonUnicodeSupport('/^[^!<>?=+@{}_$%]*$/u'), - TypedRegex::TYPE_POST_CODE => '/^[a-zA-Z 0-9-]+$/', - TypedRegex::TYPE_PHONE_NUMBER => '/^[+0-9. ()\/-]*$/', - TypedRegex::TYPE_MESSAGE => '/[<>{}]/i', - TypedRegex::TYPE_LANGUAGE_ISO_CODE => IsoCode::PATTERN, - TypedRegex::TYPE_LANGUAGE_CODE => '/^[a-zA-Z]{2}(-[a-zA-Z]{2})?$/', - TypedRegex::TYPE_CURRENCY_ISO_CODE => AlphaIsoCode::PATTERN, - TypedRegex::TYPE_FILE_NAME => '/^[a-zA-Z0-9_.-]+$/', - TypedRegex::TYPE_DNI_LITE => AddressConstraint::DNI_LITE_PATTERN, - ]; - - if (isset($typePatterns[$type])) { - return $typePatterns[$type]; - } - - throw new InvalidArgumentException(sprintf('Type "%s" is not defined. Defined types are: %s', $type, implode(',', array_keys($typePatterns)))); - } - - /** - * Responsible for sanitizing the string depending on type. (eg. applying stripslashes()) - * - * @param string $value - * @param string $type - * - * @return string - */ - private function sanitize($value, $type) - { - if ($type === 'name') { - $value = stripslashes($value); - } - - return $value; - } - - /** - * Responsible for applying preg_match depending on type. - * preg_match returns 1 if the pattern - * matches given subject, 0 if it does not, or FALSE - * if an error occurred. - * - * @param $pattern - * @param $type - * @param $value - * - * @return false|int - */ - private function match($pattern, $type, $value) - { - $typesToInverseMatching = ['message']; - - if (in_array($type, $typesToInverseMatching, true)) { - return !preg_match($pattern, $value); - } - - return preg_match($pattern, $value); - } -} diff --git a/src/Core/ContainerBuilder.php b/src/Core/ContainerBuilder.php deleted file mode 100644 index 7c1d88d0..00000000 --- a/src/Core/ContainerBuilder.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core; - -use PrestaShop\PrestaShop\Core\Foundation\IoC\Container; - -class ContainerBuilder -{ - /** - * Construct PrestaShop Core Service container. - * - * @return \PrestaShop\PrestaShop\Core\Foundation\IoC\Container - * - * @throws \PrestaShop\PrestaShop\Core\Foundation\IoC\Exception - */ - public function build() - { - $container = new Container(); - - $container->bind('\\PrestaShop\\PrestaShop\\Core\\ConfigurationInterface', '\\PrestaShop\\PrestaShop\\Adapter\\Configuration', true); - $container->bind('PrestaShop\\PrestaShop\\Core\\ConfigurationInterface', '\\PrestaShop\\PrestaShop\\Adapter\\Configuration', true); - $container->bind('\\PrestaShop\\PrestaShop\\Core\\Foundation\\Database\\DatabaseInterface', '\\PrestaShop\\PrestaShop\\Adapter\\Database', true); - $container->bind('PrestaShop\\PrestaShop\\Core\\Foundation\\Database\\DatabaseInterface', '\\PrestaShop\\PrestaShop\\Adapter\\Database', true); - - return $container; - } -} diff --git a/src/Core/Country/CountryRequiredFieldsProviderInterface.php b/src/Core/Country/CountryRequiredFieldsProviderInterface.php deleted file mode 100644 index ad737e36..00000000 --- a/src/Core/Country/CountryRequiredFieldsProviderInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Country; - -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; - -interface CountryRequiredFieldsProviderInterface -{ - /** - * @param CountryId $countryId - * - * @return bool - */ - public function isStatesRequired(CountryId $countryId): bool; - - /** - * @param CountryId $countryId - * - * @return bool - */ - public function isDniRequired(CountryId $countryId): bool; -} diff --git a/src/Core/Country/CountryZipCodeRequirements.php b/src/Core/Country/CountryZipCodeRequirements.php deleted file mode 100644 index 2f335da7..00000000 --- a/src/Core/Country/CountryZipCodeRequirements.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Country; - -/** - * Holds information about country zip code requirements - */ -class CountryZipCodeRequirements -{ - /** - * @var bool - */ - private $isRequired; - - /** - * @var string|null - */ - private $pattern; - - /** - * @var string|null - */ - private $humanReadablePattern; - - /** - * @var string|null - */ - private $countryName; - - /** - * @param bool $isRequired - */ - public function __construct(bool $isRequired) - { - $this->isRequired = $isRequired; - } - - /** - * @return bool - */ - public function isRequired(): bool - { - return $this->isRequired; - } - - /** - * @return string|null - */ - public function getPattern(): ?string - { - return $this->pattern; - } - - /** - * @param string $pattern - * @param string $humanReadablePattern - * - * @return CountryZipCodeRequirements - */ - public function setPatterns(string $pattern, string $humanReadablePattern): CountryZipCodeRequirements - { - $this->pattern = $pattern; - $this->humanReadablePattern = $humanReadablePattern; - - return $this; - } - - /** - * @return string|null - */ - public function getHumanReadablePattern(): ?string - { - return $this->humanReadablePattern; - } - - /** - * @return string|null - */ - public function getCountryName(): ?string - { - return $this->countryName; - } - - /** - * @param string $countryName - * - * @return CountryZipCodeRequirements - */ - public function setCountryName(string $countryName): CountryZipCodeRequirements - { - $this->countryName = $countryName; - - return $this; - } -} diff --git a/src/Core/Country/CountryZipCodeRequirementsProviderInterface.php b/src/Core/Country/CountryZipCodeRequirementsProviderInterface.php deleted file mode 100644 index b8567354..00000000 --- a/src/Core/Country/CountryZipCodeRequirementsProviderInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Country; - -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; - -interface CountryZipCodeRequirementsProviderInterface -{ - /** - * @param CountryId $countryId - * - * @return CountryZipCodeRequirements - */ - public function getCountryZipCodeRequirements(CountryId $countryId): CountryZipCodeRequirements; -} diff --git a/src/Core/CreditSlip/CreditSlipOptionsConfiguration.php b/src/Core/CreditSlip/CreditSlipOptionsConfiguration.php deleted file mode 100644 index 0d98b9bd..00000000 --- a/src/Core/CreditSlip/CreditSlipOptionsConfiguration.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\CreditSlip; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Responsible for saving configuration options for credit slip - */ -final class CreditSlipOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'slip_prefix' => $this->configuration->get('PS_CREDIT_SLIP_PREFIX'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_CREDIT_SLIP_PREFIX', $configuration['slip_prefix']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset($configuration['slip_prefix']); - } -} diff --git a/src/Core/Crypto/Hashing.php b/src/Core/Crypto/Hashing.php deleted file mode 100644 index 3a324d3d..00000000 --- a/src/Core/Crypto/Hashing.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Crypto; - -/** - * Class Hashing to manage hash and crypto of user (clients/merchants) passwords. - */ -class Hashing -{ - /** @var array should contain hashing methods */ - private $hashMethods = []; - - /** - * Check if it's the first function of the array that was used for hashing. - * - * @param string $passwd The password you want to check - * @param string $hash The hash you want to check - * @param string $staticSalt A static salt - * - * @return bool Result of the verify function - */ - public function isFirstHash($passwd, $hash, $staticSalt = _COOKIE_KEY_) - { - if (!count($this->hashMethods)) { - $this->initHashMethods(); - } - - $closure = reset($this->hashMethods); - - return $closure['verify']($passwd, $hash, $staticSalt); - } - - /** - * Iterate on hash_methods array and return true if it matches. - * - * @param string $passwd The password you want to check - * @param string $hash The hash you want to check - * @param string $staticSalt A static salt - * - * @return bool `true` is returned if the function find a match else false - */ - public function checkHash($passwd, $hash, $staticSalt = _COOKIE_KEY_) - { - if (!count($this->hashMethods)) { - $this->initHashMethods(); - } - - foreach ($this->hashMethods as $closure) { - if ($closure['verify']($passwd, $hash, $staticSalt)) { - return true; - } - } - - return false; - } - - /** - * Hash the `$plaintextPassword` string and return the result of the 1st hashing method - * contained in PrestaShop\PrestaShop\Core\Crypto\Hashing::hash_methods. - * - * @param string $plaintextPassword The password you want to hash - * @param string $staticSalt The static salt - * - * @return string - */ - public function hash($plaintextPassword, $staticSalt = _COOKIE_KEY_) - { - if (!count($this->hashMethods)) { - $this->initHashMethods(); - } - - $closure = reset($this->hashMethods); - - return $closure['hash']($plaintextPassword, $staticSalt, $closure['option']); - } - - /** - * Init $hash_methods. - */ - private function initHashMethods() - { - $this->hashMethods = [ - 'bcrypt' => [ - 'option' => [], - 'hash' => function ($passwd, $staticSalt, $option) { - return password_hash($passwd, PASSWORD_BCRYPT); - }, - 'verify' => function ($passwd, $hash, $staticSalt) { - /* - * Prevent enumeration because nothing happens - * when there is no, or an invalid hash. - * Also, change the password to be sure it's not maching - * the new hash. - * The new hash is equal to 'test' in BCRYPT context. - */ - if (empty($hash)) { - $hash = '$2y$10$azRqq.pN0OlWjeVfVMZXOOwqYAx1hMfme6ZnDV.27grGOEZvG.uAO'; - $passwd = 'wrongPassword'; - } - - return password_verify($passwd, $hash); - }, - ], - 'md5' => [ - 'option' => [], - 'hash' => function ($passwd, $staticSalt, $option) { - return md5($staticSalt . $passwd); - }, - 'verify' => function ($passwd, $hash, $staticSalt) { - return md5($staticSalt . $passwd) === $hash; - }, - ], - ]; - } -} diff --git a/src/Core/Currency/CurrencyDataProviderInterface.php b/src/Core/Currency/CurrencyDataProviderInterface.php deleted file mode 100644 index a9aab1d4..00000000 --- a/src/Core/Currency/CurrencyDataProviderInterface.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Currency; - -use Currency; -use Exception; -use PrestaShopException; - -/** - * This class will provide data from DB / ORM about Currency. - */ -interface CurrencyDataProviderInterface -{ - /** - * Return available currencies. - * - * @param bool $object - * @param bool $active - * @param bool $group_by - * - * @return array Currencies - */ - public function getCurrencies($object = false, $active = true, $group_by = false); - - /** - * Return raw currencies data from the database (not deleted + active currencies). - * - * @param bool $currentShopOnly If true returns only currencies associated to current shop - * - * @return array[] Available currencies - */ - public function findAll($currentShopOnly = true); - - /** - * Return raw data of all installed currencies in the database (regardless of their active or soft deleted status). - * - * @return array[] Currencies installed in database - */ - public function findAllInstalled(); - - /** - * Get a Currency entity instance by ISO code. - * - * @param string $isoCode - * An ISO 4217 currency code - * @param int|null $idLang - * Set this parameter if you want the currency in a specific language. - * If null, default language will be used - * - * @return currency|null - * The asked Currency object, or null if not found - */ - public function getCurrencyByIsoCode($isoCode, $idLang = null); - - /** - * Get a Currency entity instance. - * If the passed ISO code is known, this Currency entity will be loaded with known data. - * - * @param string $isoCode - * An ISO 4217 currency code - * @param int|null $idLang - * Set this parameter if you want the currency in a specific language. - * If null, default language will be used - * - * @return currency - * The asked Currency object, loaded with relevant data if passed ISO code is known - */ - public function getCurrencyByIsoCodeOrCreate($isoCode, $idLang = null); - - /** - * Persists a Currency entity into DB. - * If this entity already exists in DB (has a known currency_id), it will be updated. - * - * @param Currency $currencyEntity - * Currency object model to save - * - * @throws PrestaShopException - * If something wrong happened with DB when saving $currencyEntity - * @throws Exception - * If an unexpected result is retrieved when saving $currencyEntity - */ - public function saveCurrency(Currency $currencyEntity); - - /** - * Gets a legacy Currency instance by ID. - * - * @param int $currencyId - * - * @return Currency - */ - public function getCurrencyById($currencyId); - - /** - * Get Default currency Iso code. - */ - public function getDefaultCurrencyIsoCode(); -} diff --git a/src/Core/Currency/CurrencyGridDataFactory.php b/src/Core/Currency/CurrencyGridDataFactory.php deleted file mode 100644 index 998b7cb3..00000000 --- a/src/Core/Currency/CurrencyGridDataFactory.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Currency; - -use PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CurrencyGridDataFactory is responsible for providing modified currency list grid data. - */ -final class CurrencyGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $gridDataFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * CurrencyGridDataFactory constructor. - * - * @param GridDataFactoryInterface $gridDataFactory - * @param TranslatorInterface $translator - */ - public function __construct( - GridDataFactoryInterface $gridDataFactory, - TranslatorInterface $translator - ) { - $this->gridDataFactory = $gridDataFactory; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $gridData = $this->gridDataFactory->getData($searchCriteria); - - $records = $gridData->getRecords(); - - return new GridData( - $this->getModifiedRecords($records), - $gridData->getRecordsTotal(), - $gridData->getQuery() - ); - } - - /** - * Gets record collection with extra and modified rows. - * - * @param RecordCollectionInterface $records - * - * @return RecordCollection - */ - private function getModifiedRecords(RecordCollectionInterface $records) - { - $result = []; - foreach ($records as $key => $record) { - $result[$key] = $record; - $result[$key]['currency'] = $this->buildCurrencyName($result[$key]); - } - - return new RecordCollection($result); - } - - /** - * @param array $currency - * - * @return string - */ - private function buildCurrencyName(array $currency) - { - $currencyName = mb_ucfirst($currency['name']); - - if (!empty($currency['unofficial'])) { - return sprintf( - '%s %s', - $currencyName, - 'person' - ); - } - - if (!empty($currency['modified'])) { - return sprintf( - '%s (%s)', - $currencyName, - $this->translator->trans('Edited', [], 'Admin.International.Feature') - ); - } - - return $currencyName; - } -} diff --git a/src/Core/Currency/Exception/CurrencyFeedException.php b/src/Core/Currency/Exception/CurrencyFeedException.php deleted file mode 100644 index a3cfa22f..00000000 --- a/src/Core/Currency/Exception/CurrencyFeedException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Currency\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Thrown when an error occurred while fetching a currency exchange rate (network issue, invalid response, ...) - * - * @see ExchangeRateProvider - */ -class CurrencyFeedException extends CoreException -{ -} diff --git a/src/Core/Currency/ExchangeRateProvider.php b/src/Core/Currency/ExchangeRateProvider.php deleted file mode 100644 index 0fe677e2..00000000 --- a/src/Core/Currency/ExchangeRateProvider.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Currency; - -use PrestaShop\CircuitBreaker\Contract\CircuitBreakerInterface; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Currency\Exception\CurrencyFeedException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\ExchangeRate; -use SimpleXMLElement; -use Symfony\Component\Cache\Adapter\AdapterInterface as CacheInterface; - -/** - * Retrieves the exchange rate of a currency (based on the default currency). It uses a circuit breaker - * to avoid being blocked in case of network problems and it saves each of its request in a cache to be - * able to have a fallback response. - */ -class ExchangeRateProvider -{ - /** - * This url was set in the _PS_CURRENCY_FEED_URL_ const but it is not accessible in every - * context because it is weirdly defined in defines_uri.inc.php So it is safer to define - * it properly here. - */ - const CURRENCY_FEED_URL = 'http://api.prestashop.com/xml/currencies.xml'; - - const CLOSED_ALLOWED_FAILURES = 3; - const CLOSED_TIMEOUT_SECONDS = 1; - - const OPEN_ALLOWED_FAILURES = 3; - const OPEN_TIMEOUT_SECONDS = 2; - const OPEN_THRESHOLD_SECONDS = 3600; // 1 hour - - const CACHE_KEY_XML = 'currency_feed.xml'; - - /** @var string */ - private $currencyFeedUrl; - - /** @var string */ - private $defaultCurrencyIsoCode; - - /** @var CircuitBreakerInterface */ - private $remoteServiceProvider; - - /** @var CacheInterface */ - private $cache; - - /** @var string */ - private $sourceIsoCode; - - /** @var array */ - private $currencies = []; - - /** - * @param string $currencyFeedUrl - * @param string $defaultCurrencyIsoCode - * @param CircuitBreakerInterface $remoteServiceProvider - * @param CacheInterface $cache - */ - public function __construct( - $currencyFeedUrl, - $defaultCurrencyIsoCode, - CircuitBreakerInterface $remoteServiceProvider, - CacheInterface $cache - ) { - $this->currencyFeedUrl = $currencyFeedUrl; - $this->defaultCurrencyIsoCode = $defaultCurrencyIsoCode; - $this->remoteServiceProvider = $remoteServiceProvider; - $this->cache = $cache; - } - - /** - * @param string $currencyIsoCode - * - * @return Number - * - * @throws CurrencyFeedException - */ - public function getExchangeRate($currencyIsoCode) - { - $this->fetchCurrencyFeed(); - - // Default feed currency (usually EUR) - if ($this->defaultCurrencyIsoCode == $currencyIsoCode) { - return ExchangeRate::getDefaultExchangeRate(); - } - - /* - * Search for the currency rate in the source feed, this represents the rate - * relative to the source feed (compared to the feed default currency) - */ - $sourceRate = $this->getExchangeRateFromFeed($currencyIsoCode); - - /* - * Fetch the exchange rate of the default currency (compared to the source currency) - * and finally compute the asked currency rate compared to the shop default currency rate - */ - $defaultExchangeRate = $this->getExchangeRateFromFeed($this->defaultCurrencyIsoCode); - - return $sourceRate->dividedBy($defaultExchangeRate); - } - - /** - * @param string $currencyIsoCode - * - * @return Number - * - * @throws CurrencyFeedException - */ - private function getExchangeRateFromFeed(string $currencyIsoCode) - { - if ($this->sourceIsoCode == $currencyIsoCode) { - return new Number('1.0'); - } - - if (!isset($this->currencies[$currencyIsoCode])) { - throw new CurrencyFeedException(sprintf('Exchange rate for currency with ISO code %s was not found', $currencyIsoCode)); - } - - return $this->currencies[$currencyIsoCode]; - } - - /** - * Fetch the currency from its url using circuit breaker, if no content was fetched - * fallback on the cache file. This is only performed once per process, if the currencies - * are already present then there is nothing to do. - * - * @throws CurrencyFeedException - */ - private function fetchCurrencyFeed() - { - if (!empty($this->currencies)) { - return; - } - - $remoteFeedData = $this->remoteServiceProvider->call($this->currencyFeedUrl); - $cachedFeedData = $this->getCachedCurrencyFeed(); - if (empty($remoteFeedData) && empty($cachedFeedData)) { - throw new CurrencyFeedException('Currency feed could not be fetched'); - } - - $xmlFeed = $this->parseAndSaveXMLFeed($remoteFeedData); - if (null === $xmlFeed) { - $xmlFeed = $this->parseAndSaveXMLFeed($cachedFeedData); - } - - if (null === $xmlFeed) { - throw new CurrencyFeedException('Invalid currency XML feed'); - } - - $this->parseXmlFeed($xmlFeed); - } - - /** - * @param string $feedContent - * - * @return SimpleXMLElement|null - */ - private function parseAndSaveXMLFeed($feedContent) - { - $xmlFeed = @simplexml_load_string($feedContent); - if (!$xmlFeed || !$this->isValidXMLFeed($xmlFeed)) { - return null; - } - - //Cache the feed - $cacheItem = $this->cache->getItem(self::CACHE_KEY_XML); - $cacheItem->set($feedContent); - $this->cache->save($cacheItem); - - return $xmlFeed; - } - - /** - * @param SimpleXMLElement $xmlFeed - */ - private function parseXmlFeed($xmlFeed) - { - $xmlCurrencies = $xmlFeed->list->currency; - - $this->sourceIsoCode = (string) ($xmlFeed->source['iso_code']); - foreach ($xmlCurrencies as $currency) { - $this->currencies[(string) $currency['iso_code']] = new Number((string) $currency['rate']); - } - } - - /** - * @return string - */ - private function getCachedCurrencyFeed() - { - $cacheItem = $this->cache->getItem(self::CACHE_KEY_XML); - if (!$cacheItem->isHit()) { - return ''; - } - - $feedContent = $cacheItem->get(); - - return !empty($feedContent) ? $feedContent : ''; - } - - /** - * @param SimpleXMLElement $xmlFeed - * - * @return bool - */ - private function isValidXMLFeed(SimpleXMLElement $xmlFeed) - { - return $xmlFeed && $xmlFeed->list && count($xmlFeed->list->currency) && $xmlFeed->source; - } -} diff --git a/src/Core/Customer/CustomerDataSourceInterface.php b/src/Core/Customer/CustomerDataSourceInterface.php deleted file mode 100644 index c5dbd697..00000000 --- a/src/Core/Customer/CustomerDataSourceInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Customer; - -interface CustomerDataSourceInterface -{ - /** - * @param string $email - * - * @return bool - */ - public function hasCustomerWithEmail(string $email): bool; -} diff --git a/src/Core/Data/AbstractTypedCollection.php b/src/Core/Data/AbstractTypedCollection.php deleted file mode 100644 index bf9e06d7..00000000 --- a/src/Core/Data/AbstractTypedCollection.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Data; - -use Doctrine\Common\Collections\ArrayCollection; -use PrestaShop\PrestaShop\Core\Exception\TypeException; - -/** - * Class AbstractTypedCollection is an abstract collection class which checks - * that the inserted elements match the requested type. - */ -abstract class AbstractTypedCollection extends ArrayCollection -{ - /** - * Define the type of the elements contained in the collection. - * Example: for a ProductCollection you need to return Product::class - * - * @return string - */ - abstract protected function getType(); - - /** - * AbstractTypedCollection constructor. - * - * @param array $elements - * - * @throws TypeException - */ - public function __construct(array $elements = []) - { - $this->checkElementsType($elements); - parent::__construct($elements); - } - - /** - * @param mixed $element - * - * @return bool - * - * @throws TypeException - */ - public function removeElement($element) - { - $this->checkElementType($element); - - return parent::removeElement($element); - } - - /** - * @param mixed $offset - * @param mixed $value - * - * @return bool|void - * - * @throws TypeException - */ - public function offsetSet($offset, $value) - { - $this->checkElementType($value); - - return parent::offsetSet($offset, $value); - } - - /** - * @param mixed $element - * - * @return bool - * - * @throws TypeException - */ - public function contains($element) - { - $this->checkElementType($element); - - return parent::contains($element); - } - - /** - * @param mixed $element - * - * @return bool|false|int|string - * - * @throws TypeException - */ - public function indexOf($element) - { - $this->checkElementType($element); - - return parent::indexOf($element); - } - - /** - * @param mixed $key - * @param mixed $value - * - * @throws TypeException - */ - public function set($key, $value) - { - $this->checkElementType($value); - - parent::set($key, $value); - } - - /** - * @param mixed $element - * - * @return bool - * - * @throws TypeException - */ - public function add($element) - { - $this->checkElementType($element); - - return parent::add($element); - } - - /** - * @param array $elements - * - * @throws TypeException - */ - private function checkElementsType(array $elements) - { - foreach ($elements as $element) { - $this->checkElementType($element); - } - } - - /** - * @param mixed $element - * - * @throws TypeException - */ - private function checkElementType($element) - { - $expectedType = $this->getType(); - if (!($element instanceof $expectedType)) { - throw new TypeException(sprintf('Invalid element type %s, expected %s', is_object($element) ? get_class($element) : gettype($element), $expectedType)); - } - } -} diff --git a/src/Core/Data/Layer/AbstractDataLayer.php b/src/Core/Data/Layer/AbstractDataLayer.php deleted file mode 100644 index 3badbee6..00000000 --- a/src/Core/Data/Layer/AbstractDataLayer.php +++ /dev/null @@ -1,296 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Data\Layer; - -use Exception; - -/** - * Abstract data layer class - * Provides common behavior to any data layer. - * - * A data layer acts as a middleware, chained to other data layers, and is meant to - * read/write data from/to it's data source but also from/to other data layers - * - * A data layer knows only the next (lower) layer for read/write chaining. - */ -abstract class AbstractDataLayer -{ - /** - * The lower data layer to communicate with (read/write). - * - * @var AbstractDataLayer|null - */ - protected $lowerDataLayer; - - /** - * Is this data layer writable ? - * - * If it is writable, then it will be allowed to insert/update into its data source. - * Read/write propagation is NOT affected by this property. - * - * A read-only data layer can only hydrate data from lower layers, and return it to the upper layer. - * Data present in a read-only data layer is very likely to be incomplete and can be used only to hydrate data - * from lower layers (unless this is the very last layer containing comprehensive reference data). - * - * @var bool - */ - protected $isWritable = true; - - /** - * Is this data layer writable ? - * - * @return bool - * True if writable. False if read-only layer. - */ - public function isWritable() - { - return $this->isWritable; - } - - /** - * Read a data object, by identifier. - * - * Lower layer might be called if nothing found in current layer - * - * @param mixed $id - * The data object identifier - * - * @return mixed|null - * A data object. Null if not found. - * - * @throws DataLayerException - */ - public function read($id) - { - $data = $this->doRead($id); - - // If nothing found, ask lower layer - if (null === $data) { - $data = $this->propagateRead($id); - - // If nothing was found deeper, there is nothing more to do - if (null === $data) { - return null; - } - - // Save result for next Read requests - $this->saveReadPropagationResult($id, $data); - } - - return $data; - } - - /** - * Write a data object. - * - * Write request is propagated to lower layer, and the propagation result is actually written in - * current layer (because lower layer might hydrate/update the data object). - * - * @param mixed $id - * The data object identifier - * @param mixed $data - * The data object to write - * - * @return mixed - * The data object to be written by the upper data layer - * (each layer might hydrate/update the data object for upper layers) - * - * @throws DataLayerException - * When write fails - */ - public function write($id, $data) - { - // First, write $data in lower layers and store the (probably hydrated/updated) result - $data = $this->propagateWrite($id, $data); - - // Then write this result in current layer - $data = $this->saveWritePropagationResult($id, $data); - - return $data; - } - - /** - * Propagate read to the lower layer. - * - * @param $field - * The field to read - * - * @return mixed|null - * - * @throws DataLayerException - */ - protected function propagateRead($field) - { - if (isset($this->lowerDataLayer)) { - return $this->lowerDataLayer->read($field); - } - - return null; - } - - /** - * Propagate write to lower layer. - * - * @param mixed $id - * The data object identifier - * @param mixed $data - * The data object to write into this field - * - * @return mixed - * The data object to be written by the upper data layer - * - * @throws DataLayerException - * When write fails - */ - protected function propagateWrite($id, $data) - { - if (isset($this->lowerDataLayer)) { - return $this->lowerDataLayer->write($id, $data); - } - - return $data; - } - - /** - * Save data object received from lower layers after a Read request. - * - * This data object is written in the current layer to avoid read propagation next time. - * - * @param mixed $id - * Data object identifier - * @param mixed $data - * Data object received from lower layers - * - * @throws DataLayerException - * When write failed - */ - protected function saveReadPropagationResult($id, $data) - { - if ($this->isWritable()) { - try { - $this->doWrite($id, $data); - } catch (Exception $e) { - throw new DataLayerException('Unable to write into "' . $id . '"" (data layer : "' . get_class($this) . '")', 0, $e); - } - } - } - - /** - * Save data object received from lower layers after a Write request. - * - * This data object is written in the current layer after lower layers have hydrated/updated (and written) it - * - * @param mixed $id - * Data object identifier - * @param mixed $data - * Data object received from lower layers - * - * @return mixed - * Data object to be written by upper layer - * - * @throws DataLayerException - * When write failed - */ - protected function saveWritePropagationResult($id, $data) - { - if ($this->isWritable()) { - // If update needed before write - $data = $this->beforeWrite($data); - - try { - $this->doWrite($id, $data); - } catch (Exception $e) { - throw new DataLayerException('Unable to write into "' . $id . '" (data layer "' . get_class($this) . '")', 0, $e); - } - - // If update needed after write - $data = $this->afterWrite($data); - } - - return $data; - } - - /** - * Process some updates on $data before writing it in the current layer. - * - * @param mixed $data - * Data object to be updated before write - * - * @return mixed - * The updated data object - */ - protected function beforeWrite($data) - { - return $data; - } - - /** - * Process some updates on $data after writing it in the current layer. - * - * @param mixed $data - * Data object to be updated after write - * - * @return mixed - * The updated data object - */ - protected function afterWrite($data) - { - return $data; - } - - /** - * Actually read a data object into the current layer. - * - * Might be a file access, cache read, DB select... - * - * @param mixed $id - * The data object identifier - * - * @return mixed|null - * The wanted data object (null if not found) - * - * @throws DataLayerException - * When read fails - */ - abstract protected function doRead($id); - - /** - * Actually write a data object into the current layer. - * - * Might be a file edit, cache update, DB insert/update... - * - * @param mixed $id - * The data object identifier - * @param mixed $data - * The data object to be written - * - * @throws DataLayerException - * When write fails - */ - abstract protected function doWrite($id, $data); -} diff --git a/src/Core/Data/Layer/DataLayerException.php b/src/Core/Data/Layer/DataLayerException.php deleted file mode 100644 index 568a4689..00000000 --- a/src/Core/Data/Layer/DataLayerException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Data\Layer; - -use Exception; - -class DataLayerException extends Exception -{ -} diff --git a/src/Core/Domain/Address/AddressSettings.php b/src/Core/Domain/Address/AddressSettings.php deleted file mode 100644 index 48e0ab1a..00000000 --- a/src/Core/Domain/Address/AddressSettings.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address; - -/** - * Defines settings for addresses - */ -final class AddressSettings -{ - /** - * Maximum allowed length of symbols for 'firstname' and 'lastname' fields - */ - const MAX_NAME_LENGTH = 255; - - /** - * Maximum allowed length of symbols for phone number (both phone and mobile_phone) - */ - const MAX_PHONE_LENGTH = 32; - - /** - * Maximum allowed length of symbols for address - */ - const MAX_ADDRESS_LENGTH = 128; - - /** - * Maximum allowed length of symbols for post code - */ - const MAX_POST_CODE_LENGTH = 12; - - /** - * Maximum allowed length of symbols for city name - */ - const MAX_CITY_NAME_LENGTH = 64; - - /** - * Maximum allowed length of symbols for field named 'other' - */ - const MAX_OTHER_LENGTH = 300; -} diff --git a/src/Core/Domain/Address/Command/AbstractEditAddressCommand.php b/src/Core/Domain/Address/Command/AbstractEditAddressCommand.php deleted file mode 100644 index 713c0355..00000000 --- a/src/Core/Domain/Address/Command/AbstractEditAddressCommand.php +++ /dev/null @@ -1,415 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShop\PrestaShop\Core\Domain\State\ValueObject\StateId; - -class AbstractEditAddressCommand -{ - /** - * @var string|null - */ - protected $addressAlias; - - /** - * @var string|null - */ - protected $firstName; - - /** - * @var string|null - */ - protected $lastName; - - /** - * @var string|null - */ - protected $address; - - /** - * @var string|null - */ - protected $city; - - /** - * @var string|null - */ - protected $postCode; - - /** - * @var CountryId|null - */ - protected $countryId; - - /** - * @var string|null - */ - protected $dni; - - /** - * @var string|null - */ - protected $company; - - /** - * @var string|null - */ - protected $vatNumber; - - /** - * @var string|null - */ - protected $address2; - - /** - * @var StateId|null - */ - protected $stateId; - - /** - * @var string|null - */ - protected $homePhone; - - /** - * @var string|null - */ - protected $mobilePhone; - - /** - * @var string|null - */ - protected $other; - - /** - * @return string|null - */ - public function getAddressAlias(): ?string - { - return $this->addressAlias; - } - - /** - * @param string $addressAlias - * - * @return self - */ - public function setAddressAlias(string $addressAlias): self - { - $this->addressAlias = $addressAlias; - - return $this; - } - - /** - * @return string|null - */ - public function getFirstName(): ?string - { - return $this->firstName; - } - - /** - * @param string $firstName - * - * @return self - */ - public function setFirstName(string $firstName): self - { - $this->firstName = $firstName; - - return $this; - } - - /** - * @return string|null - */ - public function getLastName(): ?string - { - return $this->lastName; - } - - /** - * @param string $lastName - * - * @return self - */ - public function setLastName(string $lastName): self - { - $this->lastName = $lastName; - - return $this; - } - - /** - * @return string|null - */ - public function getAddress(): ?string - { - return $this->address; - } - - /** - * @param string $address - * - * @return self - */ - public function setAddress(string $address): self - { - $this->address = $address; - - return $this; - } - - /** - * @return string|null - */ - public function getCity(): ?string - { - return $this->city; - } - - /** - * @param string $city - * - * @return self - */ - public function setCity(string $city): self - { - $this->city = $city; - - return $this; - } - - /** - * @return string|null - */ - public function getPostCode(): ?string - { - return $this->postCode; - } - - /** - * @param string $postCode - * - * @return self - */ - public function setPostCode(string $postCode): self - { - $this->postCode = $postCode; - - return $this; - } - - /** - * @return CountryId|null - */ - public function getCountryId(): ?CountryId - { - return $this->countryId; - } - - /** - * @param int|null $countryId - * - * @return self - * - * @throws CountryConstraintException - */ - public function setCountryId(int $countryId): self - { - $this->countryId = new CountryId($countryId); - - return $this; - } - - /** - * @return string|null - */ - public function getDni(): ?string - { - return $this->dni; - } - - /** - * @param string $dni - * - * @return self - */ - public function setDni(string $dni): self - { - $this->dni = $dni; - - return $this; - } - - /** - * @return string|null - */ - public function getCompany(): ?string - { - return $this->company; - } - - /** - * @param string $company - * - * @return self - */ - public function setCompany(string $company): self - { - $this->company = $company; - - return $this; - } - - /** - * @return string|null - */ - public function getVatNumber(): ?string - { - return $this->vatNumber; - } - - /** - * @param string $vatNumber - * - * @return self - */ - public function setVatNumber(string $vatNumber): self - { - $this->vatNumber = $vatNumber; - - return $this; - } - - /** - * @return string|null - */ - public function getAddress2(): ?string - { - return $this->address2; - } - - /** - * @param string $address2 - * - * @return self - */ - public function setAddress2(string $address2): self - { - $this->address2 = $address2; - - return $this; - } - - /** - * @return StateId|null - */ - public function getStateId(): ?StateId - { - return $this->stateId; - } - - /** - * @param int $stateId - * - * @return self - * - * @throws StateConstraintException - */ - public function setStateId(int $stateId): self - { - $this->stateId = new StateId($stateId); - - return $this; - } - - /** - * @return string|null - */ - public function getHomePhone(): ?string - { - return $this->homePhone; - } - - /** - * @param string|null $homePhone - * - * @return self - */ - public function setHomePhone(string $homePhone): self - { - $this->homePhone = $homePhone; - - return $this; - } - - /** - * @return string|null - */ - public function getMobilePhone(): ?string - { - return $this->mobilePhone; - } - - /** - * @param string $mobilePhone - * - * @return self - */ - public function setMobilePhone(string $mobilePhone): self - { - $this->mobilePhone = $mobilePhone; - - return $this; - } - - /** - * @return string|null - */ - public function getOther(): ?string - { - return $this->other; - } - - /** - * @param string $other - * - * @return self - */ - public function setOther(string $other): self - { - $this->other = $other; - - return $this; - } -} diff --git a/src/Core/Domain/Address/Command/AddCustomerAddressCommand.php b/src/Core/Domain/Address/Command/AddCustomerAddressCommand.php deleted file mode 100644 index c2d8afb0..00000000 --- a/src/Core/Domain/Address/Command/AddCustomerAddressCommand.php +++ /dev/null @@ -1,304 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShop\PrestaShop\Core\Domain\State\ValueObject\StateId; - -/** - * Adds new customer address - */ -class AddCustomerAddressCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var string - */ - private $addressAlias; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var string|null - */ - private $postCode; - - /** - * @var CountryId - */ - private $countryId; - - /** - * @var string|null - */ - private $dni; - - /** - * @var string|null - */ - private $company; - - /** - * @var string|null - */ - private $vatNumber; - - /** - * @var string|null - */ - private $address2; - - /** - * @var StateId|null - */ - private $stateId; - - /** - * @var string|null - */ - private $homePhone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string|null - */ - private $other; - - /** - * @param int $customerId - * @param string $addressAlias - * @param string $firstName - * @param string $lastName - * @param string $address - * @param string $city - * @param int $countryId - * @param string $postcode - * @param string $dni - * @param string $company - * @param string $vat_number - * @param string $address2 - * @param int $id_state - * @param string $phone - * @param string $phone_mobile - * @param string $other - * - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function __construct( - int $customerId, - string $addressAlias, - string $firstName, - string $lastName, - string $address, - string $city, - int $countryId, - string $postcode, - string $dni = null, - string $company = null, - string $vat_number = null, - string $address2 = null, - int $id_state = 0, - string $phone = null, - ?string $phone_mobile = null, - string $other = null - ) { - $this->customerId = new CustomerId($customerId); - $this->addressAlias = $addressAlias; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->address = $address; - $this->city = $city; - $this->countryId = new CountryId($countryId); - $this->postCode = $postcode; - $this->dni = $dni; - $this->company = $company; - $this->vatNumber = $vat_number; - $this->address2 = $address2; - $this->stateId = new StateId($id_state); - $this->homePhone = $phone; - $this->mobilePhone = $phone_mobile; - $this->other = $other; - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } - - /** - * @return string - */ - public function getAddressAlias(): string - { - return $this->addressAlias; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string - */ - public function getAddress(): string - { - return $this->address; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string|null - */ - public function getPostCode(): ?string - { - return $this->postCode; - } - - /** - * @return CountryId - */ - public function getCountryId(): CountryId - { - return $this->countryId; - } - - /** - * @return string|null - */ - public function getDni(): ?string - { - return $this->dni; - } - - /** - * @return string|null - */ - public function getCompany(): ?string - { - return $this->company; - } - - /** - * @return string|null - */ - public function getVatNumber(): ?string - { - return $this->vatNumber; - } - - /** - * @return string|null - */ - public function getAddress2(): ?string - { - return $this->address2; - } - - /** - * @return StateId|null - */ - public function getStateId(): ?StateId - { - return $this->stateId; - } - - /** - * @return string|null - */ - public function getHomePhone(): ?string - { - return $this->homePhone; - } - - /** - * @return string|null - */ - public function getMobilePhone(): ?string - { - return $this->mobilePhone; - } - - /** - * @return string|null - */ - public function getOther(): ?string - { - return $this->other; - } -} diff --git a/src/Core/Domain/Address/Command/AddManufacturerAddressCommand.php b/src/Core/Domain/Address/Command/AddManufacturerAddressCommand.php deleted file mode 100644 index e26b2c85..00000000 --- a/src/Core/Domain/Address/Command/AddManufacturerAddressCommand.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; - -/** - * Adds new address - */ -class AddManufacturerAddressCommand -{ - /** - * @var int|null - */ - private $manufacturerId; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var string|null - */ - private $address2; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var string|null - */ - private $postCode; - - /** - * @var int|null - */ - private $stateId; - - /** - * @var string|null - */ - private $homePhone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string|null - */ - private $other; - - /** - * @var string|null - */ - private $dni; - - /** - * @param string $lastName - * @param string $firstName - * @param string $address - * @param int|null $countryId - * @param string $city - * @param int - * @param string|null $address2 - * @param string|null $postCode - * @param int|null $stateId - * @param string|null $homePhone - * @param string $mobilePhone - * @param string|null $other - * @param string|null $dni - * - * @throws AddressConstraintException - */ - public function __construct( - $lastName, - $firstName, - $address, - $countryId, - $city, - $manufacturerId = null, - $address2 = null, - $postCode = null, - $stateId = null, - $homePhone = null, - $mobilePhone = null, - $other = null, - $dni = null - ) { - $this->assertIsNullOrNonNegativeInt($manufacturerId); - $this->manufacturerId = $manufacturerId; - $this->lastName = $lastName; - $this->firstName = $firstName; - $this->address = $address; - $this->countryId = $countryId; - $this->city = $city; - $this->address2 = $address2; - $this->postCode = $postCode; - $this->stateId = $stateId; - $this->homePhone = $homePhone; - $this->mobilePhone = $mobilePhone; - $this->other = $other; - $this->dni = $dni; - } - - /** - * @return int - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return string - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return string - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return string - */ - public function getAddress() - { - return $this->address; - } - - /** - * @return string - */ - public function getCity() - { - return $this->city; - } - - /** - * @return string|null - */ - public function getAddress2() - { - return $this->address2; - } - - /** - * @return int - */ - public function getCountryId() - { - return $this->countryId; - } - - /** - * @return string|null - */ - public function getPostCode() - { - return $this->postCode; - } - - /** - * @return int|null - */ - public function getStateId() - { - return $this->stateId; - } - - /** - * @return string|null - */ - public function getHomePhone() - { - return $this->homePhone; - } - - /** - * @return string|null - */ - public function getMobilePhone() - { - return $this->mobilePhone; - } - - /** - * @return string|null - */ - public function getOther() - { - return $this->other; - } - - /** - * @return string|null - */ - public function getDni() - { - return $this->dni; - } - - /** - * @param $value - * - * @throws AddressConstraintException - */ - private function assertIsNullOrNonNegativeInt($value) - { - if (null === $value || is_int($value) || 0 <= $value) { - return; - } - - throw new AddressConstraintException(sprintf('Invalid manufacturer id "%s" provided for address.', var_export($value, true)), AddressConstraintException::INVALID_MANUFACTURER_ID); - } -} diff --git a/src/Core/Domain/Address/Command/BulkDeleteAddressCommand.php b/src/Core/Domain/Address/Command/BulkDeleteAddressCommand.php deleted file mode 100644 index 78d3354e..00000000 --- a/src/Core/Domain/Address/Command/BulkDeleteAddressCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Deletes addresses in bulk action - */ -class BulkDeleteAddressCommand -{ - /** - * @var AddressId[] - */ - private $addressIds; - - /** - * @param int[] $addressIds - * - * @throws AddressConstraintException - */ - public function __construct($addressIds) - { - $this->setAddressIds($addressIds); - } - - /** - * @return AddressId[] - */ - public function getAdressIds() - { - return $this->addressIds; - } - - /** - * @param int[] $addressIds - * - * @throws AddressConstraintException - */ - private function setAddressIds(array $addressIds) - { - foreach ($addressIds as $addressId) { - $this->addressIds[] = new AddressId($addressId); - } - } -} diff --git a/src/Core/Domain/Address/Command/DeleteAddressCommand.php b/src/Core/Domain/Address/Command/DeleteAddressCommand.php deleted file mode 100644 index da353e72..00000000 --- a/src/Core/Domain/Address/Command/DeleteAddressCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Deletes Address - */ -class DeleteAddressCommand -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct($addressId) - { - $this->addressId = new AddressId($addressId); - } - - /** - * @return AddressId - */ - public function getAddressId() - { - return $this->addressId; - } -} diff --git a/src/Core/Domain/Address/Command/EditCartAddressCommand.php b/src/Core/Domain/Address/Command/EditCartAddressCommand.php deleted file mode 100644 index cadb39f3..00000000 --- a/src/Core/Domain/Address/Command/EditCartAddressCommand.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\CartAddressType; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\InvalidAddressTypeException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Class EditCartAddressCommand used to edit a cart address and then update the related field - * so that it uses the new duplicated address. - */ -class EditCartAddressCommand extends AbstractEditAddressCommand -{ - const ALLOWED_ADDRESS_TYPES = [ - CartAddressType::INVOICE_ADDRESS_TYPE, - CartAddressType::DELIVERY_ADDRESS_TYPE, - ]; - - /** - * @var CartId - */ - private $cartId; - - /** - * @var - */ - private $addressType; - - /** - * @param int $cartId - * @param string $addressType - * - * @throws InvalidAddressTypeException - * @throws CartConstraintException - */ - public function __construct( - int $cartId, - string $addressType - ) { - $this->cartId = new CartId($cartId); - $this->setAddressType($addressType); - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return string - */ - public function getAddressType(): string - { - return $this->addressType; - } - - /** - * @param string $addressType - * - * @throws InvalidAddressTypeException - */ - private function setAddressType(string $addressType): void - { - if (!in_array($addressType, self::ALLOWED_ADDRESS_TYPES)) { - throw new InvalidAddressTypeException(sprintf( - 'Invalid address type %s, allowed values are: %s', - $addressType, - implode(',', self::ALLOWED_ADDRESS_TYPES) - )); - } - - $this->addressType = $addressType; - } -} diff --git a/src/Core/Domain/Address/Command/EditCustomerAddressCommand.php b/src/Core/Domain/Address/Command/EditCustomerAddressCommand.php deleted file mode 100644 index b0d095e0..00000000 --- a/src/Core/Domain/Address/Command/EditCustomerAddressCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Command responsible for holding edits customer address data - */ -class EditCustomerAddressCommand extends AbstractEditAddressCommand -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct(int $addressId) - { - $this->addressId = new AddressId($addressId); - } - - /** - * @return AddressId - */ - public function getAddressId(): AddressId - { - return $this->addressId; - } -} diff --git a/src/Core/Domain/Address/Command/EditManufacturerAddressCommand.php b/src/Core/Domain/Address/Command/EditManufacturerAddressCommand.php deleted file mode 100644 index f85b727d..00000000 --- a/src/Core/Domain/Address/Command/EditManufacturerAddressCommand.php +++ /dev/null @@ -1,356 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Edits manufacturer address - */ -class EditManufacturerAddressCommand -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @var int|null - */ - private $manufacturerId; - - /** - * @var string|null - */ - private $lastName; - - /** - * @var string|null - */ - private $firstName; - - /** - * @var string|null - */ - private $address; - - /** - * @var string|null - */ - private $city; - - /** - * @var string|null - */ - private $address2; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var string|null - */ - private $postCode; - - /** - * @var int|null - */ - private $stateId; - - /** - * @var string|null - */ - private $homePhone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string|null - */ - private $other; - - /** - * @var string|null - */ - private $dni; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct($addressId) - { - $this->addressId = new AddressId($addressId); - } - - /** - * @return AddressId - */ - public function getAddressId() - { - return $this->addressId; - } - - /** - * @param AddressId $addressId - */ - public function setAddressId($addressId) - { - $this->addressId = $addressId; - } - - /** - * @return int|null - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @param int $manufacturerId - * - * @throws AddressConstraintException - */ - public function setManufacturerId($manufacturerId) - { - $this->assertIsNullOrNonNegativeInt($manufacturerId); - $this->manufacturerId = $manufacturerId; - } - - /** - * @return string|null - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @param string|null $lastName - */ - public function setLastName($lastName) - { - $this->lastName = $lastName; - } - - /** - * @return string|null - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @param string|null $firstName - */ - public function setFirstName($firstName) - { - $this->firstName = $firstName; - } - - /** - * @return string|null - */ - public function getAddress() - { - return $this->address; - } - - /** - * @param string|null $address - */ - public function setAddress($address) - { - $this->address = $address; - } - - /** - * @return string|null - */ - public function getCity() - { - return $this->city; - } - - /** - * @param string|null $city - */ - public function setCity($city) - { - $this->city = $city; - } - - /** - * @return string|null - */ - public function getAddress2() - { - return $this->address2; - } - - /** - * @param string|null $address2 - */ - public function setAddress2($address2) - { - $this->address2 = $address2; - } - - /** - * @return int|null - */ - public function getCountryId() - { - return $this->countryId; - } - - /** - * @param int|null $countryId - */ - public function setCountryId($countryId) - { - $this->countryId = $countryId; - } - - /** - * @return string|null - */ - public function getPostCode() - { - return $this->postCode; - } - - /** - * @param string|null $postCode - */ - public function setPostCode($postCode) - { - $this->postCode = $postCode; - } - - /** - * @return int|null - */ - public function getStateId() - { - return $this->stateId; - } - - /** - * @param int|null $stateId - */ - public function setStateId($stateId) - { - $this->stateId = $stateId; - } - - /** - * @return string|null - */ - public function getHomePhone() - { - return $this->homePhone; - } - - /** - * @param string|null $homePhone - */ - public function setHomePhone($homePhone) - { - $this->homePhone = $homePhone; - } - - /** - * @return string|null - */ - public function getMobilePhone() - { - return $this->mobilePhone; - } - - /** - * @param string|null $mobilePhone - */ - public function setMobilePhone($mobilePhone) - { - $this->mobilePhone = $mobilePhone; - } - - /** - * @return string|null - */ - public function getOther() - { - return $this->other; - } - - /** - * @param string|null $other - */ - public function setOther($other) - { - $this->other = $other; - } - - /** - * @return string|null - */ - public function getDni() - { - return $this->dni; - } - - /** - * @param string|null $dni - */ - public function setDni($dni) - { - $this->dni = $dni; - } - - /** - * @param $value - * - * @throws AddressConstraintException - */ - private function assertIsNullOrNonNegativeInt($value) - { - if (null === $value || is_int($value) || 0 <= $value) { - return; - } - throw new AddressConstraintException(sprintf('Invalid manufacturer id "%s" provided for address.', var_export($value, true)), AddressConstraintException::INVALID_MANUFACTURER_ID); - } -} diff --git a/src/Core/Domain/Address/Command/EditOrderAddressCommand.php b/src/Core/Domain/Address/Command/EditOrderAddressCommand.php deleted file mode 100644 index 3f184d14..00000000 --- a/src/Core/Domain/Address/Command/EditOrderAddressCommand.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAddressTypeException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderAddressType; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Class EditOrderAddressCommand used to edit an order address and then update the related field - * so that it uses the new duplicated address. - */ -class EditOrderAddressCommand extends AbstractEditAddressCommand -{ - const ALLOWED_ADDRESS_TYPES = [ - OrderAddressType::INVOICE_ADDRESS_TYPE, - OrderAddressType::DELIVERY_ADDRESS_TYPE, - ]; - - /** - * @var OrderId - */ - private $orderId; - - /** - * @var - */ - private $addressType; - - /** - * @param int $orderId - * @param string $addressType - * - * @throws InvalidAddressTypeException - * @throws OrderException - */ - public function __construct( - int $orderId, - string $addressType - ) { - $this->orderId = new OrderId($orderId); - $this->setAddressType($addressType); - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return mixed - */ - public function getAddressType() - { - return $this->addressType; - } - - /** - * @param string $addressType - * - * @throws InvalidAddressTypeException - */ - private function setAddressType(string $addressType): void - { - if (!in_array($addressType, self::ALLOWED_ADDRESS_TYPES)) { - throw new InvalidAddressTypeException(sprintf( - 'Invalid address type %s, allowed values are: %s', - $addressType, - implode(',', self::ALLOWED_ADDRESS_TYPES) - )); - } - - $this->addressType = $addressType; - } -} diff --git a/src/Core/Domain/Address/Command/SetRequiredFieldsForAddressCommand.php b/src/Core/Domain/Address/Command/SetRequiredFieldsForAddressCommand.php deleted file mode 100644 index fc37e54c..00000000 --- a/src/Core/Domain/Address/Command/SetRequiredFieldsForAddressCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\RequiredFields; - -/** - * Sets required fields for new address when adding - */ -class SetRequiredFieldsForAddressCommand -{ - /** - * @var string[] - */ - private $requiredFields; - - /** - * @param string[] $requiredFields - */ - public function __construct(array $requiredFields) - { - $this->assertContainsOnlyAllowedFields($requiredFields); - - $this->requiredFields = $requiredFields; - } - - /** - * @return string[] - */ - public function getRequiredFields() - { - return $this->requiredFields; - } - - /** - * Check that all provided fields are allowed. - * - * @param string[] $requiredFields - */ - private function assertContainsOnlyAllowedFields(array $requiredFields) - { - if (empty($requiredFields)) { - return; - } - - foreach ($requiredFields as $requiredField) { - if (!in_array($requiredField, RequiredFields::ALLOWED_REQUIRED_FIELDS)) { - throw new AddressConstraintException(sprintf('Required field %s is invalid. Allowed fields are: %s', $requiredField, implode(',', RequiredFields::ALLOWED_REQUIRED_FIELDS)), AddressConstraintException::INVALID_REQUIRED_FIELDS); - } - } - } -} diff --git a/src/Core/Domain/Address/CommandHandler/AddCustomerAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/AddCustomerAddressHandlerInterface.php deleted file mode 100644 index c57e9045..00000000 --- a/src/Core/Domain/Address/CommandHandler/AddCustomerAddressHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Interface for service that handles command which adds new customer address - */ -interface AddCustomerAddressHandlerInterface -{ - /** - * @param AddCustomerAddressCommand $command - * - * @return AddressId - */ - public function handle(AddCustomerAddressCommand $command): AddressId; -} diff --git a/src/Core/Domain/Address/CommandHandler/AddManufacturerAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/AddManufacturerAddressHandlerInterface.php deleted file mode 100644 index 019c54da..00000000 --- a/src/Core/Domain/Address/CommandHandler/AddManufacturerAddressHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddManufacturerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Interface for services that handles command which adds new manufacturer address - */ -interface AddManufacturerAddressHandlerInterface -{ - /** - * @param AddManufacturerAddressCommand $command - * - * @return AddressId - */ - public function handle(AddManufacturerAddressCommand $command); -} diff --git a/src/Core/Domain/Address/CommandHandler/BulkDeleteAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/BulkDeleteAddressHandlerInterface.php deleted file mode 100644 index 4bb35547..00000000 --- a/src/Core/Domain/Address/CommandHandler/BulkDeleteAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\BulkDeleteAddressCommand; - -/** - * Defines contract for BulkDeleteAddressHandler - */ -interface BulkDeleteAddressHandlerInterface -{ - /** - * @param BulkDeleteAddressCommand $command - */ - public function handle(BulkDeleteAddressCommand $command); -} diff --git a/src/Core/Domain/Address/CommandHandler/DeleteAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/DeleteAddressHandlerInterface.php deleted file mode 100644 index 6b956784..00000000 --- a/src/Core/Domain/Address/CommandHandler/DeleteAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\DeleteAddressCommand; - -/** - * Defines contract for DeleteAddressHandler - */ -interface DeleteAddressHandlerInterface -{ - /** - * @param DeleteAddressCommand $command - */ - public function handle(DeleteAddressCommand $command); -} diff --git a/src/Core/Domain/Address/CommandHandler/EditCartAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/EditCartAddressHandlerInterface.php deleted file mode 100644 index 89f0df5c..00000000 --- a/src/Core/Domain/Address/CommandHandler/EditCartAddressHandlerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCartAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Interface for services that handles command which edits cart address - */ -interface EditCartAddressHandlerInterface -{ - /** - * @param EditCartAddressCommand $command - * - * @return AddressId The newly created address id - */ - public function handle(EditCartAddressCommand $command): AddressId; -} diff --git a/src/Core/Domain/Address/CommandHandler/EditCustomerAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/EditCustomerAddressHandlerInterface.php deleted file mode 100644 index f27e9940..00000000 --- a/src/Core/Domain/Address/CommandHandler/EditCustomerAddressHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Interface for services that handles command which edits customer address - */ -interface EditCustomerAddressHandlerInterface -{ - /** - * @param EditCustomerAddressCommand $command - * - * @return AddressId The (potentially) newly created address id - */ - public function handle(EditCustomerAddressCommand $command): AddressId; -} diff --git a/src/Core/Domain/Address/CommandHandler/EditManufacturerAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/EditManufacturerAddressHandlerInterface.php deleted file mode 100644 index 37fa08ba..00000000 --- a/src/Core/Domain/Address/CommandHandler/EditManufacturerAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditManufacturerAddressCommand; - -/** - * Interface for services that handles command which edits manufacturer address - */ -interface EditManufacturerAddressHandlerInterface -{ - /** - * @param EditManufacturerAddressCommand $command - */ - public function handle(EditManufacturerAddressCommand $command); -} diff --git a/src/Core/Domain/Address/CommandHandler/EditOrderAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/EditOrderAddressHandlerInterface.php deleted file mode 100644 index 46d161fe..00000000 --- a/src/Core/Domain/Address/CommandHandler/EditOrderAddressHandlerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditOrderAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Interface for services that handles command which edits order address - */ -interface EditOrderAddressHandlerInterface -{ - /** - * @param EditOrderAddressCommand $command - * - * @return AddressId The newly created address id - */ - public function handle(EditOrderAddressCommand $command): AddressId; -} diff --git a/src/Core/Domain/Address/CommandHandler/SetRequiredFieldsForAddressHandlerInterface.php b/src/Core/Domain/Address/CommandHandler/SetRequiredFieldsForAddressHandlerInterface.php deleted file mode 100644 index 5ab33f81..00000000 --- a/src/Core/Domain/Address/CommandHandler/SetRequiredFieldsForAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Command\SetRequiredFieldsForAddressCommand; - -/** - * Defines interface for services that handles setting required fields for address command. - */ -interface SetRequiredFieldsForAddressHandlerInterface -{ - /** - * @param SetRequiredFieldsForAddressCommand $command - */ - public function handle(SetRequiredFieldsForAddressCommand $command); -} diff --git a/src/Core/Domain/Address/Configuration/AddressConstraint.php b/src/Core/Domain/Address/Configuration/AddressConstraint.php deleted file mode 100644 index 2d56d755..00000000 --- a/src/Core/Domain/Address/Configuration/AddressConstraint.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Configuration; - -/** - * Stores address form constraints configuration values - */ -final class AddressConstraint -{ - /** - * Maximum length for address alias (value is constrained by database) - */ - const MAX_ALIAS_LENGTH = 32; - - /** - * Maximum length for company name (value is constrained by database) - */ - const MAX_COMPANY_LENGTH = 255; - - /** - * Maximum length for last name (value is constrained by database) - */ - const MAX_LAST_NAME_LENGTH = 255; - - /** - * Maximum length for first name (value is constrained by database) - */ - const MAX_FIRST_NAME_LENGTH = 255; - - /** - * Maximum length for address (value is constrained by database) - */ - const MAX_ADDRESS_LENGTH = 255; - - /** - * Maximum length for post code (value is constrained by database) - */ - const MAX_POSTCODE_LENGTH = 12; - - /** - * Maximum length for city name (value is constrained by database) - */ - const MAX_CITY_LENGTH = 64; - - /** - * Maximum length for other information - */ - const MAX_OTHER_LENGTH = 300; - - /** - * Maximum length for phone number (value is constrained by database) - */ - const MAX_PHONE_LENGTH = 32; - - /** - * Maximum length for VAT number (value is constrained by database) - */ - const MAX_VAT_LENGTH = 32; - - /** - * Maximum length for identification number (value is constrained by database) - */ - const MAX_DNI_LENGTH = 16; - - /** - * DNI field value regexp validation pattern - */ - const DNI_LITE_PATTERN = '/^[0-9A-Za-z-.]{1,16}$/U'; - - /** - * Prevents class to be instantiated - */ - private function __construct() - { - } -} diff --git a/src/Core/Domain/Address/Exception/AddressConstraintException.php b/src/Core/Domain/Address/Exception/AddressConstraintException.php deleted file mode 100644 index 8f50c8e2..00000000 --- a/src/Core/Domain/Address/Exception/AddressConstraintException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Is thrown when address constraint is violated - */ -class AddressConstraintException extends AddressException -{ - /** - * When address id is not valid - */ - const INVALID_ID = 10; - - /** - * When manufacturer id provided for address is not valid - */ - const INVALID_MANUFACTURER_ID = 20; - - /** - * When one or more unspecified fields in address are invalid - */ - const INVALID_REQUIRED_FIELDS = 30; -} diff --git a/src/Core/Domain/Address/Exception/AddressException.php b/src/Core/Domain/Address/Exception/AddressException.php deleted file mode 100644 index 8885c72a..00000000 --- a/src/Core/Domain/Address/Exception/AddressException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for address sub-domain - */ -class AddressException extends DomainException -{ -} diff --git a/src/Core/Domain/Address/Exception/AddressNotFoundException.php b/src/Core/Domain/Address/Exception/AddressNotFoundException.php deleted file mode 100644 index 25b01c05..00000000 --- a/src/Core/Domain/Address/Exception/AddressNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Is thrown when address is not found - */ -class AddressNotFoundException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/BulkDeleteAddressException.php b/src/Core/Domain/Address/Exception/BulkDeleteAddressException.php deleted file mode 100644 index 35daa74f..00000000 --- a/src/Core/Domain/Address/Exception/BulkDeleteAddressException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -use Exception; - -/** - * Thrown on failure to delete all selected addresses without errors - */ -class BulkDeleteAddressException extends AddressException -{ - /** - * @var int[] - */ - private $addressIds; - - /** - * @param int[] $addressIds - * @param string $message - * @param int $code - * @param Exception $previous - */ - public function __construct(array $addressIds, $message = '', $code = 0, Exception $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->addressIds = $addressIds; - } - - /** - * @return int[] - */ - public function getAddressIds(): array - { - return $this->addressIds; - } -} diff --git a/src/Core/Domain/Address/Exception/CannotAddAddressException.php b/src/Core/Domain/Address/Exception/CannotAddAddressException.php deleted file mode 100644 index 71f29fa1..00000000 --- a/src/Core/Domain/Address/Exception/CannotAddAddressException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Thrown on failure to create address - */ -class CannotAddAddressException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/CannotSetRequiredFieldsForAddressException.php b/src/Core/Domain/Address/Exception/CannotSetRequiredFieldsForAddressException.php deleted file mode 100644 index 1c32a550..00000000 --- a/src/Core/Domain/Address/Exception/CannotSetRequiredFieldsForAddressException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Exception thrown on failure to update address required fields - */ -class CannotSetRequiredFieldsForAddressException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/CannotUpdateAddressException.php b/src/Core/Domain/Address/Exception/CannotUpdateAddressException.php deleted file mode 100644 index 7a76bf38..00000000 --- a/src/Core/Domain/Address/Exception/CannotUpdateAddressException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Thrown on failure to update address - */ -class CannotUpdateAddressException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/CannotUpdateCartAddressException.php b/src/Core/Domain/Address/Exception/CannotUpdateCartAddressException.php deleted file mode 100644 index 7fc6a7ed..00000000 --- a/src/Core/Domain/Address/Exception/CannotUpdateCartAddressException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Thrown on failure to update address - */ -class CannotUpdateCartAddressException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/CannotUpdateOrderAddressException.php b/src/Core/Domain/Address/Exception/CannotUpdateOrderAddressException.php deleted file mode 100644 index db241386..00000000 --- a/src/Core/Domain/Address/Exception/CannotUpdateOrderAddressException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Thrown on failure to update address - */ -class CannotUpdateOrderAddressException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/DeleteAddressException.php b/src/Core/Domain/Address/Exception/DeleteAddressException.php deleted file mode 100644 index 2581a1ca..00000000 --- a/src/Core/Domain/Address/Exception/DeleteAddressException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Is thrown when address or addresses cannot be deleted - */ -class DeleteAddressException extends AddressException -{ - /** - * When fails to delete single address - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete address in bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/Address/Exception/InvalidAddressFieldException.php b/src/Core/Domain/Address/Exception/InvalidAddressFieldException.php deleted file mode 100644 index a1af8407..00000000 --- a/src/Core/Domain/Address/Exception/InvalidAddressFieldException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Is thrown when address has invalid fields on saving/updating - */ -class InvalidAddressFieldException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Exception/InvalidAddressRequiredFieldsException.php b/src/Core/Domain/Address/Exception/InvalidAddressRequiredFieldsException.php deleted file mode 100644 index 759064a2..00000000 --- a/src/Core/Domain/Address/Exception/InvalidAddressRequiredFieldsException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Exception; - -/** - * Thrown when invalid address required fields provided for saving - */ -class InvalidAddressRequiredFieldsException extends AddressException -{ -} diff --git a/src/Core/Domain/Address/Query/GetCustomerAddressForEditing.php b/src/Core/Domain/Address/Query/GetCustomerAddressForEditing.php deleted file mode 100644 index 94104c20..00000000 --- a/src/Core/Domain/Address/Query/GetCustomerAddressForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Query; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Gets customer address for editing - */ -class GetCustomerAddressForEditing -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct($addressId) - { - $this->addressId = new AddressId($addressId); - } - - /** - * @return AddressId - */ - public function getAddressId() - { - return $this->addressId; - } -} diff --git a/src/Core/Domain/Address/Query/GetManufacturerAddressForEditing.php b/src/Core/Domain/Address/Query/GetManufacturerAddressForEditing.php deleted file mode 100644 index b1f210d0..00000000 --- a/src/Core/Domain/Address/Query/GetManufacturerAddressForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Query; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Gets manufacturer address for editing - */ -class GetManufacturerAddressForEditing -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct($addressId) - { - $this->addressId = new AddressId($addressId); - } - - /** - * @return AddressId - */ - public function getAddressId() - { - return $this->addressId; - } -} diff --git a/src/Core/Domain/Address/Query/GetRequiredFieldsForAddress.php b/src/Core/Domain/Address/Query/GetRequiredFieldsForAddress.php deleted file mode 100644 index 0a0bda60..00000000 --- a/src/Core/Domain/Address/Query/GetRequiredFieldsForAddress.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\Query; - -/** - * Gets fields that are required for address - */ -class GetRequiredFieldsForAddress -{ -} diff --git a/src/Core/Domain/Address/QueryHandler/GetCustomerAddressForEditingHandlerInterface.php b/src/Core/Domain/Address/QueryHandler/GetCustomerAddressForEditingHandlerInterface.php deleted file mode 100644 index 97135405..00000000 --- a/src/Core/Domain/Address/QueryHandler/GetCustomerAddressForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableCustomerAddress; - -/** - * Interface for services that handles query which gets customer address for editing - */ -interface GetCustomerAddressForEditingHandlerInterface -{ - /** - * @param GetCustomerAddressForEditing $query - * - * @return EditableCustomerAddress - */ - public function handle(GetCustomerAddressForEditing $query): EditableCustomerAddress; -} diff --git a/src/Core/Domain/Address/QueryHandler/GetManufacturerAddressForEditingHandlerInterface.php b/src/Core/Domain/Address/QueryHandler/GetManufacturerAddressForEditingHandlerInterface.php deleted file mode 100644 index 6222c916..00000000 --- a/src/Core/Domain/Address/QueryHandler/GetManufacturerAddressForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetManufacturerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableManufacturerAddress; - -/** - * Interface for services that handles query which gets manufacturer address for editing - */ -interface GetManufacturerAddressForEditingHandlerInterface -{ - /** - * @param GetManufacturerAddressForEditing $query - * - * @return EditableManufacturerAddress - */ - public function handle(GetManufacturerAddressForEditing $query); -} diff --git a/src/Core/Domain/Address/QueryHandler/GetRequiredFieldsForAddressHandlerInterface.php b/src/Core/Domain/Address/QueryHandler/GetRequiredFieldsForAddressHandlerInterface.php deleted file mode 100644 index 2e41d5a8..00000000 --- a/src/Core/Domain/Address/QueryHandler/GetRequiredFieldsForAddressHandlerInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetRequiredFieldsForAddress; - -interface GetRequiredFieldsForAddressHandlerInterface -{ - /** - * @param GetRequiredFieldsForAddress $query - * - * @return string[] - */ - public function handle(GetRequiredFieldsForAddress $query): array; -} diff --git a/src/Core/Domain/Address/QueryResult/EditableCustomerAddress.php b/src/Core/Domain/Address/QueryResult/EditableCustomerAddress.php deleted file mode 100644 index 7feabc98..00000000 --- a/src/Core/Domain/Address/QueryResult/EditableCustomerAddress.php +++ /dev/null @@ -1,348 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\State\ValueObject\StateId; - -/** - * Transfers customer address data for editing - */ -class EditableCustomerAddress -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var string - */ - private $customerEmail; - - /** - * @var string - */ - private $addressAlias; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var CountryId - */ - private $countryId; - - /** - * @var string|null - */ - private $postCode; - - /** - * @var string|null - */ - private $dni; - - /** - * @var string|null - */ - private $company; - - /** - * @var string|null - */ - private $vatNumber; - - /** - * @var string|null - */ - private $address2; - - /** - * @var StateId|null - */ - private $stateId; - - /** - * @var string|null - */ - private $homePhone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string|null - */ - private $other; - - /** - * @var string[] - */ - private $requiredFields; - - /** - * @param AddressId $addressId - * @param CustomerId $customerId - * @param string $customerEmail - * @param string $addressAlias - * @param string $firstName - * @param string $lastName - * @param string $address - * @param string $city - * @param CountryId $countryId - * @param string $postCode - * @param string $dni - * @param string $company - * @param string $vatNumber - * @param string $address2 - * @param StateId $stateId - * @param string $homePhone - * @param string $mobilePhone - * @param string $other - * @param string[] $requiredFields - */ - public function __construct( - AddressId $addressId, - CustomerId $customerId, - string $customerEmail, - string $addressAlias, - string $firstName, - string $lastName, - string $address, - string $city, - CountryId $countryId, - string $postCode, - string $dni, - string $company, - string $vatNumber, - string $address2, - StateId $stateId, - string $homePhone, - string $mobilePhone, - string $other, - array $requiredFields - ) { - $this->addressId = $addressId; - $this->customerId = $customerId; - $this->customerEmail = $customerEmail; - $this->addressAlias = $addressAlias; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->address = $address; - $this->city = $city; - $this->countryId = $countryId; - $this->postCode = $postCode; - $this->dni = $dni; - $this->company = $company; - $this->vatNumber = $vatNumber; - $this->address2 = $address2; - $this->stateId = $stateId; - $this->homePhone = $homePhone; - $this->mobilePhone = $mobilePhone; - $this->other = $other; - $this->requiredFields = $requiredFields; - } - - /** - * @return AddressId - */ - public function getAddressId(): AddressId - { - return $this->addressId; - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } - - /** - * @return string - */ - public function getCustomerEmail(): string - { - return $this->customerEmail; - } - - /** - * @return string - */ - public function getAddressAlias(): string - { - return $this->addressAlias; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string - */ - public function getAddress(): string - { - return $this->address; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return CountryId - */ - public function getCountryId(): CountryId - { - return $this->countryId; - } - - /** - * @return string[] - */ - public function getRequiredFields(): array - { - return $this->requiredFields; - } - - /** - * @return string|null - */ - public function getPostCode(): ?string - { - return $this->postCode; - } - - /** - * @return string|null - */ - public function getDni(): ?string - { - return $this->dni; - } - - /** - * @return string|null - */ - public function getCompany(): ?string - { - return $this->company; - } - - /** - * @return string|null - */ - public function getVatNumber(): ?string - { - return $this->vatNumber; - } - - /** - * @return string|null - */ - public function getAddress2(): ?string - { - return $this->address2; - } - - /** - * @return StateId|null - */ - public function getStateId(): ?StateId - { - return $this->stateId; - } - - /** - * @return string|null - */ - public function getHomePhone(): ?string - { - return $this->homePhone; - } - - /** - * @return string|null - */ - public function getMobilePhone(): ?string - { - return $this->mobilePhone; - } - - /** - * @return string|null - */ - public function getOther(): ?string - { - return $this->other; - } -} diff --git a/src/Core/Domain/Address/QueryResult/EditableManufacturerAddress.php b/src/Core/Domain/Address/QueryResult/EditableManufacturerAddress.php deleted file mode 100644 index 5514d0ca..00000000 --- a/src/Core/Domain/Address/QueryResult/EditableManufacturerAddress.php +++ /dev/null @@ -1,265 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Transfers manufacturer address data for editing - */ -class EditableManufacturerAddress -{ - /** - * @var AddressId - */ - private $addressId; - - /** - * @var int - */ - private $manufacturerId; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var string - */ - private $address2; - - /** - * @var int - */ - private $countryId; - - /** - * @var string - */ - private $postCode; - - /** - * @var int - */ - private $stateId; - - /** - * @var string - */ - private $homePhone; - - /** - * @var string - */ - private $mobilePhone; - - /** - * @var string - */ - private $other; - - /** - * @var string - */ - private $dni; - - /** - * @param AddressId $addressId - * @param string $lastName - * @param string $firstName - * @param string $address - * @param string $city - * @param int $manufacturerId - * @param int $countryId - * @param string $address2 - * @param string $postCode - * @param int $stateId - * @param string $homePhone - * @param string $mobilePhone - * @param string $other - * @param string $dni - */ - public function __construct( - AddressId $addressId, - $lastName, - $firstName, - $address, - $city, - $manufacturerId, - $countryId, - $address2 = null, - $postCode = null, - $stateId = null, - $homePhone = null, - $mobilePhone = null, - $other = null, - $dni = null - ) { - $this->addressId = $addressId; - $this->lastName = $lastName; - $this->firstName = $firstName; - $this->address = $address; - $this->city = $city; - $this->manufacturerId = $manufacturerId; - $this->countryId = $countryId; - $this->address2 = $address2; - $this->postCode = $postCode; - $this->stateId = $stateId; - $this->homePhone = $homePhone; - $this->mobilePhone = $mobilePhone; - $this->other = $other; - $this->dni = $dni; - } - - /** - * @return AddressId - */ - public function getAddressId() - { - return $this->addressId; - } - - /** - * @return int - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return string - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return string - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return string - */ - public function getAddress() - { - return $this->address; - } - - /** - * @return string - */ - public function getCity() - { - return $this->city; - } - - /** - * @return string - */ - public function getAddress2() - { - return $this->address2; - } - - /** - * @return int - */ - public function getCountryId() - { - return $this->countryId; - } - - /** - * @return string - */ - public function getPostCode() - { - return $this->postCode; - } - - /** - * @return int - */ - public function getStateId() - { - return $this->stateId; - } - - /** - * @return string - */ - public function getHomePhone() - { - return $this->homePhone; - } - - /** - * @return string - */ - public function getMobilePhone() - { - return $this->mobilePhone; - } - - /** - * @return string - */ - public function getOther() - { - return $this->other; - } - - /** - * @return string - */ - public function getDni() - { - return $this->dni; - } -} diff --git a/src/Core/Domain/Address/ValueObject/AddressId.php b/src/Core/Domain/Address/ValueObject/AddressId.php deleted file mode 100644 index c02ba35d..00000000 --- a/src/Core/Domain/Address/ValueObject/AddressId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; - -/** - * Provides address id - */ -class AddressId -{ - /** - * @var int - */ - private $addressId; - - /** - * @param int $addressId - * - * @throws AddressConstraintException - */ - public function __construct($addressId) - { - $this->assertIsIntegerGreaterThanZero($addressId); - $this->addressId = $addressId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->addressId; - } - - /** - * Validates that the value is integer and is greater than zero - * - * @param $value - * - * @throws AddressConstraintException - */ - private function assertIsIntegerGreaterThanZero($value) - { - if (!is_int($value) || 0 >= $value) { - throw new AddressConstraintException(sprintf('Invalid address id "%s".', var_export($value, true)), AddressConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Address/ValueObject/RequiredFields.php b/src/Core/Domain/Address/ValueObject/RequiredFields.php deleted file mode 100644 index fd107245..00000000 --- a/src/Core/Domain/Address/ValueObject/RequiredFields.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Address\ValueObject; - -/** - * Stores configurable required field values for address. - */ -class RequiredFields -{ - const REQUIRED_FIELD_COMPANY = 'company'; - const REQUIRED_FIELD_ADDRESS_2 = 'address2'; - const REQUIRED_FIELD_POST_CODE = 'postcode'; - const REQUIRED_FIELD_OTHER = 'other'; - const REQUIRED_FIELD_PHONE = 'phone'; - const REQUIRED_FIELD_PHONE_MOBILE = 'phone_mobile'; - const REQUIRED_FIELD_VAT_NUMBER = 'vat_number'; - const REQUIRED_FIELD_DNI = 'dni'; - - /** - * Stores all allowed required fields to be configured for address - */ - const ALLOWED_REQUIRED_FIELDS = [ - self::REQUIRED_FIELD_COMPANY, - self::REQUIRED_FIELD_ADDRESS_2, - self::REQUIRED_FIELD_POST_CODE, - self::REQUIRED_FIELD_OTHER, - self::REQUIRED_FIELD_PHONE, - self::REQUIRED_FIELD_PHONE_MOBILE, - self::REQUIRED_FIELD_VAT_NUMBER, - self::REQUIRED_FIELD_DNI, - ]; -} diff --git a/src/Core/Domain/Attachment/AttachmentFileUploaderInterface.php b/src/Core/Domain/Attachment/AttachmentFileUploaderInterface.php deleted file mode 100644 index 142d6087..00000000 --- a/src/Core/Domain/Attachment/AttachmentFileUploaderInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment; - -interface AttachmentFileUploaderInterface -{ - /** - * @param string $filePath - * @param string $uniqueFileName - * @param int $fileSize - * @param int|null $id - */ - public function upload(string $filePath, string $uniqueFileName, int $fileSize, int $id = null): void; -} diff --git a/src/Core/Domain/Attachment/Command/AddAttachmentCommand.php b/src/Core/Domain/Attachment/Command/AddAttachmentCommand.php deleted file mode 100644 index 9ad58193..00000000 --- a/src/Core/Domain/Attachment/Command/AddAttachmentCommand.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Command; - -/** - * Attachment creation command - */ -class AddAttachmentCommand -{ - /** - * @var string|null - */ - private $pathName; - - /** - * @var int|null - */ - private $fileSize; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var string[] - */ - private $localizedDescriptions = []; - - /** - * @var string|null - */ - private $mimeType; - - /** - * @var string|null - */ - private $originalName; - - /** - * @param array $localizedNames - * @param array $localizedDescriptions - */ - public function __construct( - array $localizedNames, - array $localizedDescriptions - ) { - $this->localizedNames = $localizedNames; - $this->localizedDescriptions = $localizedDescriptions; - } - - /** - * @param string $pathName - * @param int $fileSize - * @param string $mimeType - * @param string $originalName - */ - public function setFileInformation( - string $pathName, - int $fileSize, - string $mimeType, - string $originalName - ): void { - $this->pathName = $pathName; - $this->fileSize = $fileSize; - $this->mimeType = $mimeType; - $this->originalName = $originalName; - } - - /** - * @return string|null - */ - public function getFilePathName(): ?string - { - return $this->pathName; - } - - /** - * @return int|null - */ - public function getFileSize(): ?int - { - return $this->fileSize; - } - - /** - * @return string[] - */ - public function getLocalizedNames(): array - { - return $this->localizedNames; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions(): array - { - return $this->localizedDescriptions; - } - - /** - * @return string|null - */ - public function getMimeType(): ?string - { - return $this->mimeType; - } - - /** - * @return string|null - */ - public function getOriginalName(): ?string - { - return $this->originalName; - } -} diff --git a/src/Core/Domain/Attachment/Command/BulkDeleteAttachmentsCommand.php b/src/Core/Domain/Attachment/Command/BulkDeleteAttachmentsCommand.php deleted file mode 100644 index ed5fbcaa..00000000 --- a/src/Core/Domain/Attachment/Command/BulkDeleteAttachmentsCommand.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Command; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -/** - * Bulk delete attachment command is responsible for deleting Attachment - */ -class BulkDeleteAttachmentsCommand -{ - /** - * @var AttachmentId[] - */ - private $attachmentIds; - - /** - * @param int[] $attachmentIds - */ - public function __construct(array $attachmentIds) - { - $this->setAttachmentIds($attachmentIds); - } - - /** - * @return AttachmentId[] - */ - public function getAttachmentIds(): array - { - return $this->attachmentIds; - } - - /** - * @param array $attachmentIds - */ - private function setAttachmentIds(array $attachmentIds) - { - foreach ($attachmentIds as $attachmentId) { - $this->attachmentIds[] = new AttachmentId($attachmentId); - } - } -} diff --git a/src/Core/Domain/Attachment/Command/DeleteAttachmentCommand.php b/src/Core/Domain/Attachment/Command/DeleteAttachmentCommand.php deleted file mode 100644 index fa45ad37..00000000 --- a/src/Core/Domain/Attachment/Command/DeleteAttachmentCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Command; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -/** - * Delete attachment command is responsible for deleting Attachment - */ -class DeleteAttachmentCommand -{ - /** - * @var AttachmentId - */ - private $attachmentId; - - /** - * @param int $attachmentId - */ - public function __construct(int $attachmentId) - { - $this->attachmentId = new AttachmentId($attachmentId); - } - - /** - * @return AttachmentId - */ - public function getAttachmentId(): AttachmentId - { - return $this->attachmentId; - } -} diff --git a/src/Core/Domain/Attachment/Command/EditAttachmentCommand.php b/src/Core/Domain/Attachment/Command/EditAttachmentCommand.php deleted file mode 100644 index 164cb96a..00000000 --- a/src/Core/Domain/Attachment/Command/EditAttachmentCommand.php +++ /dev/null @@ -1,180 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Command; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -/** - * Attachment editing command - */ -class EditAttachmentCommand -{ - /** - * @var AttachmentId - */ - private $attachmentId; - - /** - * @var string|null - */ - private $pathName; - - /** - * @var string|null - */ - private $originalFileName; - - /** - * @var string|null - */ - private $mimeType; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var string[]|null - */ - private $localizedDescriptions; - - /** - * @var string|null - */ - private $fileSize; - - /** - * @param AttachmentId $attachmentId - */ - public function __construct(AttachmentId $attachmentId) - { - $this->attachmentId = $attachmentId; - } - - /** - * @return AttachmentId - */ - public function getAttachmentId(): AttachmentId - { - return $this->attachmentId; - } - - /** - * @return string|null - */ - public function getPathName(): ?string - { - return $this->pathName; - } - - /** - * @param string|null $pathName - * @param string $mimeType - * @param string $originalFileName - * @param int $fileSize - * - * @return EditAttachmentCommand - */ - public function setFileInfo( - string $pathName, - string $mimeType, - string $originalFileName, - int $fileSize - ): EditAttachmentCommand { - $this->pathName = $pathName; - $this->mimeType = $mimeType; - $this->originalFileName = $originalFileName; - $this->fileSize = $fileSize; - - return $this; - } - - /** - * @return string|null - */ - public function getOriginalFileName(): ?string - { - return $this->originalFileName; - } - - /** - * @return string|null - */ - public function getMimeType(): ?string - { - return $this->mimeType; - } - - /** - * @return string[] - */ - public function getLocalizedNames(): array - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return EditAttachmentCommand - */ - public function setLocalizedNames(array $localizedNames): EditAttachmentCommand - { - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedDescriptions(): ?array - { - return $this->localizedDescriptions; - } - - /** - * @param string[]|null $localizedDescriptions - * - * @return EditAttachmentCommand - */ - public function setLocalizedDescriptions(?array $localizedDescriptions): EditAttachmentCommand - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return int|null - */ - public function getFileSize(): ?int - { - return $this->fileSize; - } -} diff --git a/src/Core/Domain/Attachment/CommandHandler/AddAttachmentHandlerInterface.php b/src/Core/Domain/Attachment/CommandHandler/AddAttachmentHandlerInterface.php deleted file mode 100644 index a5fe0c0f..00000000 --- a/src/Core/Domain/Attachment/CommandHandler/AddAttachmentHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\AddAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -interface AddAttachmentHandlerInterface -{ - /** - * @param AddAttachmentCommand $command - * - * @return AttachmentId - */ - public function handle(AddAttachmentCommand $command): AttachmentId; -} diff --git a/src/Core/Domain/Attachment/CommandHandler/BulkDeleteAttachmentsHandlerInterface.php b/src/Core/Domain/Attachment/CommandHandler/BulkDeleteAttachmentsHandlerInterface.php deleted file mode 100644 index fe31edc7..00000000 --- a/src/Core/Domain/Attachment/CommandHandler/BulkDeleteAttachmentsHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\BulkDeleteAttachmentsCommand; - -/** - * Defines contract for bulk delete attachments handler - */ -interface BulkDeleteAttachmentsHandlerInterface -{ - /** - * @param BulkDeleteAttachmentsCommand $command - */ - public function handle(BulkDeleteAttachmentsCommand $command); -} diff --git a/src/Core/Domain/Attachment/CommandHandler/DeleteAttachmentHandlerInterface.php b/src/Core/Domain/Attachment/CommandHandler/DeleteAttachmentHandlerInterface.php deleted file mode 100644 index 9a43296a..00000000 --- a/src/Core/Domain/Attachment/CommandHandler/DeleteAttachmentHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\DeleteAttachmentCommand; - -/** - * Defines contract for DeleteAttachmentHandler - */ -interface DeleteAttachmentHandlerInterface -{ - /** - * @param DeleteAttachmentCommand $command - */ - public function handle(DeleteAttachmentCommand $command); -} diff --git a/src/Core/Domain/Attachment/CommandHandler/EditAttachmentHandlerInterface.php b/src/Core/Domain/Attachment/CommandHandler/EditAttachmentHandlerInterface.php deleted file mode 100644 index 71bca86e..00000000 --- a/src/Core/Domain/Attachment/CommandHandler/EditAttachmentHandlerInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\EditAttachmentCommand; - -interface EditAttachmentHandlerInterface -{ - /** - * @param EditAttachmentCommand $command - */ - public function handle(EditAttachmentCommand $command); -} diff --git a/src/Core/Domain/Attachment/Configuration/AttachmentConstraint.php b/src/Core/Domain/Attachment/Configuration/AttachmentConstraint.php deleted file mode 100644 index 8e82219c..00000000 --- a/src/Core/Domain/Attachment/Configuration/AttachmentConstraint.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Configuration; - -/** - * Stores attachment validation configuration values - */ -final class AttachmentConstraint -{ - /** - * Maximum length for name (value is constrained by database) - */ - const MAX_NAME_LENGTH = 32; - - /** - * Prevents class to be instantiated - */ - private function __construct() - { - } -} diff --git a/src/Core/Domain/Attachment/Exception/AttachmentConstraintException.php b/src/Core/Domain/Attachment/Exception/AttachmentConstraintException.php deleted file mode 100644 index 33aa5c2d..00000000 --- a/src/Core/Domain/Attachment/Exception/AttachmentConstraintException.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Exception is thrown when Attachment constraint is violated - */ -class AttachmentConstraintException extends AttachmentException -{ - const INVALID_ID = 1; - - const INVALID_FILE_SIZE = 2; - - const EMPTY_NAME = 3; - - const EMPTY_DESCRIPTION = 4; - - const INVALID_FIELDS = 5; - - const INVALID_DESCRIPTION = 6; - - const MISSING_NAME_IN_DEFAULT_LANGUAGE = 7; -} diff --git a/src/Core/Domain/Attachment/Exception/AttachmentException.php b/src/Core/Domain/Attachment/Exception/AttachmentException.php deleted file mode 100644 index 9052d9cd..00000000 --- a/src/Core/Domain/Attachment/Exception/AttachmentException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for Attachment subdomain - */ -class AttachmentException extends DomainException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/AttachmentNotFoundException.php b/src/Core/Domain/Attachment/Exception/AttachmentNotFoundException.php deleted file mode 100644 index 5266438c..00000000 --- a/src/Core/Domain/Attachment/Exception/AttachmentNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Attachment not found exception - */ -class AttachmentNotFoundException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/AttachmentUploadFailedException.php b/src/Core/Domain/Attachment/Exception/AttachmentUploadFailedException.php deleted file mode 100644 index d28ceb65..00000000 --- a/src/Core/Domain/Attachment/Exception/AttachmentUploadFailedException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Thrown when upload error occurs - */ -class AttachmentUploadFailedException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/BulkDeleteAttachmentsException.php b/src/Core/Domain/Attachment/Exception/BulkDeleteAttachmentsException.php deleted file mode 100644 index 3550b6ea..00000000 --- a/src/Core/Domain/Attachment/Exception/BulkDeleteAttachmentsException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -use Exception; - -/** - * Exception is thrown on attachments bulk delete failure - */ -class BulkDeleteAttachmentsException extends AttachmentException -{ - /** - * @var int[] - */ - private $attachmentIds; - - /** - * @param int[] $attachmentIds - * @param string $message - * @param int $code - * @param Exception $previous - */ - public function __construct(array $attachmentIds, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->attachmentIds = $attachmentIds; - } - - /** - * @return int[] - */ - public function getAttachmentIds(): array - { - return $this->attachmentIds; - } -} diff --git a/src/Core/Domain/Attachment/Exception/CannotAddAttachmentException.php b/src/Core/Domain/Attachment/Exception/CannotAddAttachmentException.php deleted file mode 100644 index e1bf5119..00000000 --- a/src/Core/Domain/Attachment/Exception/CannotAddAttachmentException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Attachment can not be added exception - */ -class CannotAddAttachmentException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/CannotUnlinkAttachmentException.php b/src/Core/Domain/Attachment/Exception/CannotUnlinkAttachmentException.php deleted file mode 100644 index 0802b6ed..00000000 --- a/src/Core/Domain/Attachment/Exception/CannotUnlinkAttachmentException.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -use Throwable; - -/** - * Thrown when file unlink fails - */ -class CannotUnlinkAttachmentException extends AttachmentException -{ - /** - * @var string - */ - private $filePath = ''; - - /** - * @param string $message - * @param int $code - */ - public function __construct($message = '', $code = 0, Throwable $previous = null, string $filePath = '') - { - parent::__construct($message, $code, $previous); - $this->filePath = $filePath; - } - - public function getFilePath(): string - { - return $this->filePath; - } -} diff --git a/src/Core/Domain/Attachment/Exception/CannotUpdateAttachmentException.php b/src/Core/Domain/Attachment/Exception/CannotUpdateAttachmentException.php deleted file mode 100644 index 500bd035..00000000 --- a/src/Core/Domain/Attachment/Exception/CannotUpdateAttachmentException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Is thrown when error occurred on attachment update - */ -class CannotUpdateAttachmentException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/DeleteAttachmentException.php b/src/Core/Domain/Attachment/Exception/DeleteAttachmentException.php deleted file mode 100644 index a4efa6f7..00000000 --- a/src/Core/Domain/Attachment/Exception/DeleteAttachmentException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Exception is thrown when attachment or attachments cannot be deleted - */ -class DeleteAttachmentException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Exception/EmptyFileException.php b/src/Core/Domain/Attachment/Exception/EmptyFileException.php deleted file mode 100644 index 46aeee8f..00000000 --- a/src/Core/Domain/Attachment/Exception/EmptyFileException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Exception; - -/** - * Thrown on trying to upload empty file - */ -class EmptyFileException extends AttachmentException -{ -} diff --git a/src/Core/Domain/Attachment/Query/GetAttachment.php b/src/Core/Domain/Attachment/Query/GetAttachment.php deleted file mode 100644 index d4605538..00000000 --- a/src/Core/Domain/Attachment/Query/GetAttachment.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Query; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -/** - * Get attachment query - */ -class GetAttachment -{ - /** - * @var AttachmentId - */ - private $attachmentId; - - /** - * @param int $attachmentId - */ - public function __construct(int $attachmentId) - { - $this->attachmentId = new AttachmentId($attachmentId); - } - - /** - * @return AttachmentId - */ - public function getAttachmentId(): AttachmentId - { - return $this->attachmentId; - } -} diff --git a/src/Core/Domain/Attachment/Query/GetAttachmentForEditing.php b/src/Core/Domain/Attachment/Query/GetAttachmentForEditing.php deleted file mode 100644 index f1b41e6c..00000000 --- a/src/Core/Domain/Attachment/Query/GetAttachmentForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\Query; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; - -/** - * Gets attachment information for editing. - */ -class GetAttachmentForEditing -{ - /** - * @var AttachmentId - */ - private $attachmentId; - - /** - * @param int $attachmentIdValue - * - * @throws AttachmentConstraintException - */ - public function __construct(int $attachmentIdValue) - { - $this->attachmentId = new AttachmentId($attachmentIdValue); - } - - /** - * @return AttachmentId - */ - public function getAttachmentId(): AttachmentId - { - return $this->attachmentId; - } -} diff --git a/src/Core/Domain/Attachment/QueryHandler/GetAttachmentForEditingHandlerInterface.php b/src/Core/Domain/Attachment/QueryHandler/GetAttachmentForEditingHandlerInterface.php deleted file mode 100644 index 04c1e418..00000000 --- a/src/Core/Domain/Attachment/QueryHandler/GetAttachmentForEditingHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachmentForEditing; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\EditableAttachment; - -interface GetAttachmentForEditingHandlerInterface -{ - /** - * @param GetAttachmentForEditing $query - * - * @return EditableAttachment - */ - public function handle(GetAttachmentForEditing $query): EditableAttachment; -} diff --git a/src/Core/Domain/Attachment/QueryHandler/GetAttachmentHandlerInterface.php b/src/Core/Domain/Attachment/QueryHandler/GetAttachmentHandlerInterface.php deleted file mode 100644 index 66389822..00000000 --- a/src/Core/Domain/Attachment/QueryHandler/GetAttachmentHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachment; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\Attachment; - -/** - * Defines contract for get attachment handler - */ -interface GetAttachmentHandlerInterface -{ - /** - * @param GetAttachment $query - * - * @return Attachment - */ - public function handle(GetAttachment $query): Attachment; -} diff --git a/src/Core/Domain/Attachment/QueryResult/Attachment.php b/src/Core/Domain/Attachment/QueryResult/Attachment.php deleted file mode 100644 index a1fbcd8c..00000000 --- a/src/Core/Domain/Attachment/QueryResult/Attachment.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult; - -/** - * Stores attachment path and original name information. - */ -class Attachment -{ - /** - * @var string - */ - private $path; - - /** - * @var string - */ - private $name; - - /** - * @param string $path - * @param string $name - */ - public function __construct(string $path, string $name) - { - $this->path = $path; - $this->name = $name; - } - - /** - * @return string - */ - public function getPath(): string - { - return $this->path; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } -} diff --git a/src/Core/Domain/Attachment/QueryResult/EditableAttachment.php b/src/Core/Domain/Attachment/QueryResult/EditableAttachment.php deleted file mode 100644 index 75467cff..00000000 --- a/src/Core/Domain/Attachment/QueryResult/EditableAttachment.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult; - -use SplFileInfo; - -/** - * Stores editable data for attachment - */ -class EditableAttachment -{ - /** - * @var string - */ - private $fileName; - - /** - * @var string[] - */ - private $name; - - /** - * @var string[]|null - */ - private $description; - - /** - * @var SplFileInfo|null - */ - private $file; - - /** - * @param string $fileName - * @param string[] $name - * @param string[]|null $description - */ - public function __construct( - string $fileName, - array $name, - array $description - ) { - $this->fileName = $fileName; - $this->name = $name; - $this->description = $description; - } - - /** - * @return string - */ - public function getFileName(): string - { - return $this->fileName; - } - - /** - * @return string[] - */ - public function getName(): array - { - return $this->name; - } - - /** - * @return string[]|null - */ - public function getDescription(): ?array - { - return $this->description; - } - - /** - * @return SplFileInfo|null - */ - public function getFile(): ?SplFileInfo - { - return $this->file; - } - - /** - * @param SplFileInfo|null $file - * - * @return EditableAttachment - */ - public function setFile(?SplFileInfo $file): EditableAttachment - { - $this->file = $file; - - return $this; - } -} diff --git a/src/Core/Domain/Attachment/ValueObject/AttachmentId.php b/src/Core/Domain/Attachment/ValueObject/AttachmentId.php deleted file mode 100644 index 1a73c762..00000000 --- a/src/Core/Domain/Attachment/ValueObject/AttachmentId.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; - -/** - * Class provides attachment id - */ -class AttachmentId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - * - * @throws AttachmentConstraintException] - */ - public function __construct(int $id) - { - $this->assertIsValidId($id); - - $this->id = $id; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->id; - } - - /** - * @param int $attachmentId - * - * @throws AttachmentConstraintException - */ - private function assertIsValidId(int $attachmentId): void - { - if (0 >= $attachmentId) { - throw new AttachmentConstraintException(sprintf('Invalid Attachment id %s supplied', var_export($attachmentId, true)), AttachmentConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Cart/CartAddressType.php b/src/Core/Domain/Cart/CartAddressType.php deleted file mode 100644 index 400f3ebe..00000000 --- a/src/Core/Domain/Cart/CartAddressType.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Cart; - -/** - * Used to identity which type of address has to be edited - */ -class CartAddressType -{ - const DELIVERY_ADDRESS_TYPE = 'delivery_address'; - - const INVOICE_ADDRESS_TYPE = 'invoice_address'; -} diff --git a/src/Core/Domain/Cart/Command/AddCartRuleToCartCommand.php b/src/Core/Domain/Cart/Command/AddCartRuleToCartCommand.php deleted file mode 100644 index 377ba6e6..00000000 --- a/src/Core/Domain/Cart/Command/AddCartRuleToCartCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleId; - -/** - * Adds cart rule to given cart. - */ -class AddCartRuleToCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var CartRuleId - */ - private $cartRuleId; - - /** - * @param int $cartId - * @param int $cartRuleId - */ - public function __construct($cartId, $cartRuleId) - { - $this->cartId = new CartId($cartId); - $this->cartRuleId = new CartRuleId($cartRuleId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return CartRuleId - */ - public function getCartRuleId() - { - return $this->cartRuleId; - } -} diff --git a/src/Core/Domain/Cart/Command/AddCustomizationCommand.php b/src/Core/Domain/Cart/Command/AddCustomizationCommand.php deleted file mode 100644 index 0f4aee62..00000000 --- a/src/Core/Domain/Cart/Command/AddCustomizationCommand.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Adds product customization - */ -class AddCustomizationCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var array key - value pairs where key is the id of customization field and the value is the customization value - */ - private $customizationValuesByFieldIds; - - /** - * @param int $cartId - * @param int $productId - * @param array $customizationValuesByFieldIds - * - * @throws CartConstraintException - */ - public function __construct(int $cartId, int $productId, array $customizationValuesByFieldIds) - { - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - $this->customizationValuesByFieldIds = $customizationValuesByFieldIds; - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return array - */ - public function getCustomizationValuesByFieldIds(): array - { - return $this->customizationValuesByFieldIds; - } -} diff --git a/src/Core/Domain/Cart/Command/AddProductToCartCommand.php b/src/Core/Domain/Cart/Command/AddProductToCartCommand.php deleted file mode 100644 index 01c887c7..00000000 --- a/src/Core/Domain/Cart/Command/AddProductToCartCommand.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\Combination\ValueObject\CombinationId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Responsible for adding product to cart - */ -class AddProductToCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var int - */ - private $quantity; - - /** - * @var CombinationId|null - */ - private $combinationId; - - /** - * @var array key-value pairs where key is customizationFieldId and value is customization field value - */ - private $customizationsByFieldIds; - - /** - * @param int $cartId - * @param int $productId - * @param int $quantity - * @param int|null $combinationId - * @param array $customizationsByFieldIds - * - * @throws CartConstraintException - */ - public function __construct( - int $cartId, - int $productId, - int $quantity, - ?int $combinationId = null, - array $customizationsByFieldIds = [] - ) { - $this->assertQtyIsPositive($quantity); - $this->setCombinationId($combinationId); - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - $this->quantity = $quantity; - $this->customizationsByFieldIds = $customizationsByFieldIds; - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return int - */ - public function getQuantity(): int - { - return $this->quantity; - } - - /** - * @return CombinationId|null - */ - public function getCombinationId(): ?CombinationId - { - return $this->combinationId; - } - - /** - * @return array - */ - public function getCustomizationsByFieldIds(): array - { - return $this->customizationsByFieldIds; - } - - /** - * @param int $qty - * - * @throws CartConstraintException - */ - private function assertQtyIsPositive(int $qty) - { - if (0 >= $qty) { - throw new CartConstraintException(sprintf('Quantity must be positive integer. "%s" given.', $qty), CartConstraintException::INVALID_QUANTITY); - } - } - - /** - * @param int|null $combinationId - */ - private function setCombinationId(?int $combinationId) - { - if (null !== $combinationId) { - $combinationId = new CombinationId($combinationId); - } - - $this->combinationId = $combinationId; - } -} diff --git a/src/Core/Domain/Cart/Command/CreateEmptyCustomerCartCommand.php b/src/Core/Domain/Cart/Command/CreateEmptyCustomerCartCommand.php deleted file mode 100644 index c5338ab6..00000000 --- a/src/Core/Domain/Cart/Command/CreateEmptyCustomerCartCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Creates empty cart for given customer. - */ -class CreateEmptyCustomerCartCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId Customer for which cart is being created - */ - public function __construct($customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Cart/Command/RemoveCartRuleFromCartCommand.php b/src/Core/Domain/Cart/Command/RemoveCartRuleFromCartCommand.php deleted file mode 100644 index 34b67b57..00000000 --- a/src/Core/Domain/Cart/Command/RemoveCartRuleFromCartCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleId; - -/** - * Removes given cart rule from cart. - */ -class RemoveCartRuleFromCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var CartRuleId - */ - private $cartRuleId; - - /** - * @param $cartId - * @param $cartRuleId - */ - public function __construct(int $cartId, int $cartRuleId) - { - $this->cartId = new CartId($cartId); - $this->cartRuleId = new CartRuleId($cartRuleId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return CartRuleId - */ - public function getCartRuleId() - { - return $this->cartRuleId; - } -} diff --git a/src/Core/Domain/Cart/Command/RemoveProductFromCartCommand.php b/src/Core/Domain/Cart/Command/RemoveProductFromCartCommand.php deleted file mode 100644 index 62066dd9..00000000 --- a/src/Core/Domain/Cart/Command/RemoveProductFromCartCommand.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Removes given product from cart. - */ -class RemoveProductFromCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var int|null - */ - private $combinationId; - - /** - * @var int|null - */ - private $customizationId; - - /** - * @param int $cartId - * @param int $productId - * @param int|null $combinationId - * @param int|null $customizationId - * - * @throws CartConstraintException - */ - public function __construct( - int $cartId, - int $productId, - int $combinationId = null, - int $customizationId = null - ) { - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - $this->combinationId = $combinationId; - $this->customizationId = $customizationId; - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId() - { - return $this->productId; - } - - /** - * @return int|null - */ - public function getCombinationId() - { - return $this->combinationId; - } - - /** - * @return int|null - */ - public function getCustomizationId() - { - return $this->customizationId; - } -} diff --git a/src/Core/Domain/Cart/Command/SendCartToCustomerCommand.php b/src/Core/Domain/Cart/Command/SendCartToCustomerCommand.php deleted file mode 100644 index 071f0cee..00000000 --- a/src/Core/Domain/Cart/Command/SendCartToCustomerCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Sends email to the customer to process the payment for cart. - */ -class SendCartToCustomerCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @param int $cartId - */ - public function __construct($cartId) - { - $this->cartId = new CartId($cartId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateCartAddressesCommand.php b/src/Core/Domain/Cart/Command/UpdateCartAddressesCommand.php deleted file mode 100644 index 6f52f0da..00000000 --- a/src/Core/Domain/Cart/Command/UpdateCartAddressesCommand.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -class UpdateCartAddressesCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var AddressId - */ - private $newDeliveryAddressId; - - /** - * @var AddressId - */ - private $newInvoiceAddressId; - - /** - * @param int $cartId - * @param int $newDeliveryAddressId - * @param int $newInvoiceAddressId - * - * @throws AddressConstraintException - * @throws CartConstraintException - */ - public function __construct(int $cartId, int $newDeliveryAddressId, int $newInvoiceAddressId) - { - $this->cartId = new CartId($cartId); - $this->setNewDeliveryAddressId($newDeliveryAddressId); - $this->setNewInvoiceAddressId($newInvoiceAddressId); - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return AddressId - */ - public function getNewDeliveryAddressId(): AddressId - { - return $this->newDeliveryAddressId; - } - - /** - * @return AddressId - */ - public function getNewInvoiceAddressId(): AddressId - { - return $this->newInvoiceAddressId; - } - - /** - * @param int $newDeliveryAddressId - * - * @throws AddressConstraintException - */ - private function setNewDeliveryAddressId(int $newDeliveryAddressId): void - { - $this->newDeliveryAddressId = new AddressId($newDeliveryAddressId); - } - - /** - * @param int $newInvoiceAddressId - * - * @throws AddressConstraintException - */ - private function setNewInvoiceAddressId(int $newInvoiceAddressId): void - { - $this->newInvoiceAddressId = new AddressId($newInvoiceAddressId); - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateCartCarrierCommand.php b/src/Core/Domain/Cart/Command/UpdateCartCarrierCommand.php deleted file mode 100644 index b36f432d..00000000 --- a/src/Core/Domain/Cart/Command/UpdateCartCarrierCommand.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Updates cart carrier (a.k.a delivery option) with new one. - */ -class UpdateCartCarrierCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var int - */ - private $newCarrierId; - - /** - * @param int $cartId - * @param $newCarrierId - * - * @throws CartConstraintException - */ - public function __construct($cartId, $newCarrierId) - { - $this->cartId = new CartId($cartId); - $this->newCarrierId = $newCarrierId; - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return int - */ - public function getNewCarrierId(): int - { - return $this->newCarrierId; - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateCartCurrencyCommand.php b/src/Core/Domain/Cart/Command/UpdateCartCurrencyCommand.php deleted file mode 100644 index 3bf001cb..00000000 --- a/src/Core/Domain/Cart/Command/UpdateCartCurrencyCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Updates cart currency - */ -class UpdateCartCurrencyCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var CurrencyId - */ - private $newCurrencyId; - - /** - * @param int $cartId - * @param int $newCurrencyId - */ - public function __construct($cartId, $newCurrencyId) - { - $this->cartId = new CartId($cartId); - $this->newCurrencyId = new CurrencyId($newCurrencyId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return CurrencyId - */ - public function getNewCurrencyId() - { - return $this->newCurrencyId; - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateCartDeliverySettingsCommand.php b/src/Core/Domain/Cart/Command/UpdateCartDeliverySettingsCommand.php deleted file mode 100644 index 59dd5669..00000000 --- a/src/Core/Domain/Cart/Command/UpdateCartDeliverySettingsCommand.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -class UpdateCartDeliverySettingsCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var bool - */ - private $allowFreeShipping; - - /** - * @var bool - */ - private $isAGift; - - /** - * @var bool - */ - private $useRecycledPackaging; - - /** - * @var string - */ - private $giftMessage; - - /** - * @param int $cartId - * @param bool $allowFreeShipping - * @param bool|null $isAGift - * @param bool|null $useRecycledPackaging - * @param string|null $giftMessage - */ - public function __construct( - int $cartId, - bool $allowFreeShipping, - ?bool $isAGift = null, - ?bool $useRecycledPackaging = null, - ?string $giftMessage = null - ) { - $this->cartId = new CartId($cartId); - $this->allowFreeShipping = $allowFreeShipping; - $this->isAGift = $isAGift; - $this->useRecycledPackaging = $useRecycledPackaging; - $this->giftMessage = $giftMessage; - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return bool - */ - public function allowFreeShipping(): bool - { - return $this->allowFreeShipping; - } - - /** - * @return bool|null - */ - public function isAGift(): ?bool - { - return $this->isAGift; - } - - /** - * @return bool|null - */ - public function useRecycledPackaging(): ?bool - { - return $this->useRecycledPackaging; - } - - /** - * @return string|null - */ - public function getGiftMessage(): ?string - { - return $this->giftMessage; - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateCartLanguageCommand.php b/src/Core/Domain/Cart/Command/UpdateCartLanguageCommand.php deleted file mode 100644 index ed1db92f..00000000 --- a/src/Core/Domain/Cart/Command/UpdateCartLanguageCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Updates language for given cart - */ -class UpdateCartLanguageCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var LanguageId - */ - private $newLanguageId; - - /** - * @param int $cartId - * @param int $newLanguageId - */ - public function __construct($cartId, $newLanguageId) - { - $this->cartId = new CartId($cartId); - $this->newLanguageId = new LanguageId($newLanguageId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return LanguageId - */ - public function getNewLanguageId() - { - return $this->newLanguageId; - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateProductPriceInCartCommand.php b/src/Core/Domain/Cart/Command/UpdateProductPriceInCartCommand.php deleted file mode 100644 index c51c2c3b..00000000 --- a/src/Core/Domain/Cart/Command/UpdateProductPriceInCartCommand.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Updates cart product price - */ -class UpdateProductPriceInCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var int - */ - private $combinationId; - - /** - * @var float - */ - private $price; - - /** - * @param int $cartId - * @param int $productId - * @param int $combinationId - * @param float $price - */ - public function __construct($cartId, $productId, $combinationId, $price) - { - $this->assertPriceIsPositiveFloat($price); - - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - $this->combinationId = $combinationId; - $this->price = $price; - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId() - { - return $this->productId; - } - - /** - * @return int - */ - public function getCombinationId() - { - return $this->combinationId; - } - - /** - * @return float - */ - public function getPrice() - { - return $this->price; - } - - /** - * @param float $price - */ - private function assertPriceIsPositiveFloat($price) - { - if (!is_float($price) || 0 > $price) { - throw new CartException(sprintf('Price %s is invalid. Price must be float greater than zero.', var_export($price, true))); - } - } -} diff --git a/src/Core/Domain/Cart/Command/UpdateProductQuantityInCartCommand.php b/src/Core/Domain/Cart/Command/UpdateProductQuantityInCartCommand.php deleted file mode 100644 index cb3e85d1..00000000 --- a/src/Core/Domain/Cart/Command/UpdateProductQuantityInCartCommand.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\Combination\ValueObject\CombinationId; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\ValueObject\CustomizationId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Updates product quantity in cart - * Quantity given must include gift product - */ -class UpdateProductQuantityInCartCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var int - */ - private $newQuantity; - - /** - * @var CombinationId|null - */ - private $combinationId; - - /** - * @var CustomizationId|null - */ - private $customizationId; - - /** - * @param int $cartId - * @param int $productId - * @param int $quantity - * @param int|null $combinationId - * @param int|null $customizationId - * - * @throws CartConstraintException - * @throws CartException - */ - public function __construct( - $cartId, - $productId, - $quantity, - $combinationId = null, - $customizationId = null - ) { - $this->setCombinationId($combinationId); - $this->setCustomizationId($customizationId); - $this->assertQuantityIsPositive($quantity); - - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - $this->newQuantity = $quantity; - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId() - { - return $this->productId; - } - - /** - * @return int - */ - public function getNewQuantity() - { - return $this->newQuantity; - } - - /** - * @return CombinationId|null - */ - public function getCombinationId(): ?CombinationId - { - return $this->combinationId; - } - - /** - * @return CustomizationId|null - */ - public function getCustomizationId(): ?CustomizationId - { - return $this->customizationId; - } - - /** - * @param int|null $combinationId - */ - private function setCombinationId(?int $combinationId) - { - if (null !== $combinationId) { - $combinationId = new CombinationId($combinationId); - } - - $this->combinationId = $combinationId; - } - - /** - * @param int|null $customizationId - */ - private function setCustomizationId(?int $customizationId) - { - if (null !== $customizationId) { - $customizationId = new CustomizationId($customizationId); - } - - $this->customizationId = $customizationId; - } - - /** - * @param int $qty - * - * @throws CartConstraintException - */ - private function assertQuantityIsPositive(int $qty) - { - if (0 >= $qty) { - throw new CartConstraintException(sprintf('Quantity must be positive integer. "%s" given.', $qty), CartConstraintException::INVALID_QUANTITY); - } - } -} diff --git a/src/Core/Domain/Cart/CommandHandler/AddCartRuleToCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/AddCartRuleToCartHandlerInterface.php deleted file mode 100644 index f99e1d06..00000000 --- a/src/Core/Domain/Cart/CommandHandler/AddCartRuleToCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCartRuleToCartCommand; - -/** - * Interface for service that handles adding cart rule to cart. - */ -interface AddCartRuleToCartHandlerInterface -{ - /** - * @param AddCartRuleToCartCommand $command - */ - public function handle(AddCartRuleToCartCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/AddCustomizationHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/AddCustomizationHandlerInterface.php deleted file mode 100644 index f00baa52..00000000 --- a/src/Core/Domain/Cart/CommandHandler/AddCustomizationHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCustomizationCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\ValueObject\CustomizationId; - -/** - * Defines contract to handle @var AddCustomizationCommand - */ -interface AddCustomizationHandlerInterface -{ - /** - * @param AddCustomizationCommand $command - * - * @return CustomizationId|null customizationId - */ - public function handle(AddCustomizationCommand $command): ?CustomizationId; -} diff --git a/src/Core/Domain/Cart/CommandHandler/AddProductToCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/AddProductToCartHandlerInterface.php deleted file mode 100644 index 213bf2f9..00000000 --- a/src/Core/Domain/Cart/CommandHandler/AddProductToCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddProductToCartCommand; - -/** - * Interface for handling addProductToCart command - */ -interface AddProductToCartHandlerInterface -{ - /** - * @param AddProductToCartCommand $command - */ - public function handle(AddProductToCartCommand $command): void; -} diff --git a/src/Core/Domain/Cart/CommandHandler/CreateEmptyCustomerCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/CreateEmptyCustomerCartHandlerInterface.php deleted file mode 100644 index f85eb2a2..00000000 --- a/src/Core/Domain/Cart/CommandHandler/CreateEmptyCustomerCartHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\CreateEmptyCustomerCartCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Interface for service that handles creating empty customer cart. - */ -interface CreateEmptyCustomerCartHandlerInterface -{ - /** - * @param CreateEmptyCustomerCartCommand $command - * - * @return CartId - */ - public function handle(CreateEmptyCustomerCartCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/RemoveCartRuleFromCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/RemoveCartRuleFromCartHandlerInterface.php deleted file mode 100644 index fabde6b6..00000000 --- a/src/Core/Domain/Cart/CommandHandler/RemoveCartRuleFromCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveCartRuleFromCartCommand; - -/** - * Interface for service that handling removing cart rule from cart. - */ -interface RemoveCartRuleFromCartHandlerInterface -{ - /** - * @param RemoveCartRuleFromCartCommand $command - */ - public function handle(RemoveCartRuleFromCartCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/RemoveProductFromCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/RemoveProductFromCartHandlerInterface.php deleted file mode 100644 index ea9b8268..00000000 --- a/src/Core/Domain/Cart/CommandHandler/RemoveProductFromCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveProductFromCartCommand; - -/** - * Interface for service that handles product removing from cart. - */ -interface RemoveProductFromCartHandlerInterface -{ - /** - * @param RemoveProductFromCartCommand $command - */ - public function handle(RemoveProductFromCartCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/SendCartToCustomerHanlderInterface.php b/src/Core/Domain/Cart/CommandHandler/SendCartToCustomerHanlderInterface.php deleted file mode 100644 index a1288fcb..00000000 --- a/src/Core/Domain/Cart/CommandHandler/SendCartToCustomerHanlderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\SendCartToCustomerCommand; - -/** - * Interface for service that handles sending cart to customer. - */ -interface SendCartToCustomerHanlderInterface -{ - /** - * @param SendCartToCustomerCommand $command - */ - public function handle(SendCartToCustomerCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateCartAddressesHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateCartAddressesHandlerInterface.php deleted file mode 100644 index 32be4da2..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateCartAddressesHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartAddressesCommand; - -/** - * Interface for service that updates addresses for given cart - */ -interface UpdateCartAddressesHandlerInterface -{ - /** - * @param UpdateCartAddressesCommand $command - */ - public function handle(UpdateCartAddressesCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateCartCarrierHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateCartCarrierHandlerInterface.php deleted file mode 100644 index bcb3f987..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateCartCarrierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCarrierCommand; - -/** - * Interface for service that updates delivery options for cart - */ -interface UpdateCartCarrierHandlerInterface -{ - /** - * @param UpdateCartCarrierCommand $command - */ - public function handle(UpdateCartCarrierCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateCartCurrencyHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateCartCurrencyHandlerInterface.php deleted file mode 100644 index e6f9d1e8..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateCartCurrencyHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCurrencyCommand; - -/** - * Interface for service that handles cart currency updating - */ -interface UpdateCartCurrencyHandlerInterface -{ - /** - * @param UpdateCartCurrencyCommand $command - */ - public function handle(UpdateCartCurrencyCommand $command): void; -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateCartDeliverySettingsHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateCartDeliverySettingsHandlerInterface.php deleted file mode 100644 index 80dc9da6..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateCartDeliverySettingsHandlerInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartDeliverySettingsCommand; - -interface UpdateCartDeliverySettingsHandlerInterface -{ - /** - * @param UpdateCartDeliverySettingsCommand $command - */ - public function handle(UpdateCartDeliverySettingsCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateCartLanguageHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateCartLanguageHandlerInterface.php deleted file mode 100644 index 02ddc592..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateCartLanguageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartLanguageCommand; - -/** - * Interface for service that updates cart language - */ -interface UpdateCartLanguageHandlerInterface -{ - /** - * @param UpdateCartLanguageCommand $command - */ - public function handle(UpdateCartLanguageCommand $command): void; -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateProductPriceInCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateProductPriceInCartHandlerInterface.php deleted file mode 100644 index 8e023357..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateProductPriceInCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductPriceInCartCommand; - -/** - * Interface for service that updates product price in cart. - */ -interface UpdateProductPriceInCartHandlerInterface -{ - /** - * @param UpdateProductPriceInCartCommand $command - */ - public function handle(UpdateProductPriceInCartCommand $command); -} diff --git a/src/Core/Domain/Cart/CommandHandler/UpdateProductQuantityInCartHandlerInterface.php b/src/Core/Domain/Cart/CommandHandler/UpdateProductQuantityInCartHandlerInterface.php deleted file mode 100644 index 60ee84af..00000000 --- a/src/Core/Domain/Cart/CommandHandler/UpdateProductQuantityInCartHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductQuantityInCartCommand; - -/** - * Interface for service that updates (increases or decreases) product quantity in cart - */ -interface UpdateProductQuantityInCartHandlerInterface -{ - /** - * @param UpdateProductQuantityInCartCommand $command - */ - public function handle(UpdateProductQuantityInCartCommand $command); -} diff --git a/src/Core/Domain/Cart/Exception/CannotUpdateCartException.php b/src/Core/Domain/Cart/Exception/CannotUpdateCartException.php deleted file mode 100644 index 92f7abe5..00000000 --- a/src/Core/Domain/Cart/Exception/CannotUpdateCartException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -/** - * Thrown on failure to update cart - */ -class CannotUpdateCartException extends CartException -{ -} diff --git a/src/Core/Domain/Cart/Exception/CartConstraintException.php b/src/Core/Domain/Cart/Exception/CartConstraintException.php deleted file mode 100644 index 0d8f6c21..00000000 --- a/src/Core/Domain/Cart/Exception/CartConstraintException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -/** - * Thrown when cart constraints are violated - */ -class CartConstraintException extends CartException -{ - /** - * When cart product quantity is invalid - */ - const INVALID_QUANTITY = 1; - - /** - * When cart product quantity is already correct - */ - const UNCHANGED_QUANTITY = 2; - - /** - * When carrier is not found or inactive - */ - const INVALID_CARRIER = 3; -} diff --git a/src/Core/Domain/Cart/Exception/CartException.php b/src/Core/Domain/Cart/Exception/CartException.php deleted file mode 100644 index f8326140..00000000 --- a/src/Core/Domain/Cart/Exception/CartException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Is base exception for Cart subdomain - */ -class CartException extends DomainException -{ -} diff --git a/src/Core/Domain/Cart/Exception/CartNotFoundException.php b/src/Core/Domain/Cart/Exception/CartNotFoundException.php deleted file mode 100644 index db5739b2..00000000 --- a/src/Core/Domain/Cart/Exception/CartNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -/** - * Is thrown when cart is not found - */ -class CartNotFoundException extends CartException -{ -} diff --git a/src/Core/Domain/Cart/Exception/InvalidAddressTypeException.php b/src/Core/Domain/Cart/Exception/InvalidAddressTypeException.php deleted file mode 100644 index 5d96b234..00000000 --- a/src/Core/Domain/Cart/Exception/InvalidAddressTypeException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -/** - * Class InvalidAddressTypeException - */ -class InvalidAddressTypeException extends CartException -{ -} diff --git a/src/Core/Domain/Cart/Exception/InvalidGiftMessageException.php b/src/Core/Domain/Cart/Exception/InvalidGiftMessageException.php deleted file mode 100644 index 44840132..00000000 --- a/src/Core/Domain/Cart/Exception/InvalidGiftMessageException.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -class InvalidGiftMessageException extends CartException -{ -} diff --git a/src/Core/Domain/Cart/Exception/MinimalQuantityException.php b/src/Core/Domain/Cart/Exception/MinimalQuantityException.php deleted file mode 100644 index afb6a76c..00000000 --- a/src/Core/Domain/Cart/Exception/MinimalQuantityException.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Exception; - -use Throwable; - -/** - * Thrown when minimal product - */ -class MinimalQuantityException extends CartException -{ - /** - * @var int - */ - protected $minimalQuantity; - - /** - * @param string $message - * @param int $minimalQuantity - * @param int $code - * @param Throwable|null $previous - */ - public function __construct(string $message, int $minimalQuantity, int $code = 0, Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->minimalQuantity = $minimalQuantity; - } - - /** - * @return int - */ - public function getMinimalQuantity(): int - { - return $this->minimalQuantity; - } -} diff --git a/src/Core/Domain/Cart/Query/GetCartForOrderCreation.php b/src/Core/Domain/Cart/Query/GetCartForOrderCreation.php deleted file mode 100644 index 7bbb133f..00000000 --- a/src/Core/Domain/Cart/Query/GetCartForOrderCreation.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Query; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Query for getting cart information - */ -class GetCartForOrderCreation -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var bool - */ - private $hideDiscounts = false; - - /** - * @param int $cartId - * - * @throws CartConstraintException - */ - public function __construct(int $cartId) - { - $this->cartId = new CartId($cartId); - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return bool - */ - public function hideDiscounts(): bool - { - return $this->hideDiscounts; - } - - /** - * When hideDiscounts is set to TRUE, - * Gift products are in a separate line from other products which are charged for - * The price of any gift products is not included in the overall discounts, total products and cart total - * Shipping is set to 0 if there is a free_shipping cart rule - * - * Otherwise, - * There is one line per product type, any gift products will be included in the quantity of charged products, but the price of gift products will appear as a discount - * Shipping has its original price, and if it's free, the shipping value will be added as a discount - * - * @param bool $hideDiscounts - * - * @return GetCartForOrderCreation - */ - public function setHideDiscounts(bool $hideDiscounts): self - { - $this->hideDiscounts = $hideDiscounts; - - return $this; - } -} diff --git a/src/Core/Domain/Cart/Query/GetCartForViewing.php b/src/Core/Domain/Cart/Query/GetCartForViewing.php deleted file mode 100644 index 6711eeb1..00000000 --- a/src/Core/Domain/Cart/Query/GetCartForViewing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Query; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Get cart for viewing in Back Office - */ -class GetCartForViewing -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @param int $cartId - */ - public function __construct($cartId) - { - $this->cartId = new CartId($cartId); - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } -} diff --git a/src/Core/Domain/Cart/Query/GetLastEmptyCustomerCart.php b/src/Core/Domain/Cart/Query/GetLastEmptyCustomerCart.php deleted file mode 100644 index 8a6970ad..00000000 --- a/src/Core/Domain/Cart/Query/GetLastEmptyCustomerCart.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Query for retrieving last empty cart for customer - */ -class GetLastEmptyCustomerCart -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct(int $customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Cart/QueryHandler/GetCartForOrderCreationHandlerInterface.php b/src/Core/Domain/Cart/QueryHandler/GetCartForOrderCreationHandlerInterface.php deleted file mode 100644 index b8adb320..00000000 --- a/src/Core/Domain/Cart/QueryHandler/GetCartForOrderCreationHandlerInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForOrderCreation; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Interface for handling GetCartForOrderCreation query - */ -interface GetCartForOrderCreationHandlerInterface -{ - public function handle(GetCartForOrderCreation $query): CartForOrderCreation; -} diff --git a/src/Core/Domain/Cart/QueryHandler/GetCartForViewingHandlerInterface.php b/src/Core/Domain/Cart/QueryHandler/GetCartForViewingHandlerInterface.php deleted file mode 100644 index 5f422f44..00000000 --- a/src/Core/Domain/Cart/QueryHandler/GetCartForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForViewing; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartView; - -/** - * Interface for service that gets cart for viewing - */ -interface GetCartForViewingHandlerInterface -{ - /** - * @param GetCartForViewing $query - * - * @return CartView - */ - public function handle(GetCartForViewing $query); -} diff --git a/src/Core/Domain/Cart/QueryHandler/GetLastEmptyCustomerCartHandlerInterface.php b/src/Core/Domain/Cart/QueryHandler/GetLastEmptyCustomerCartHandlerInterface.php deleted file mode 100644 index deb37b22..00000000 --- a/src/Core/Domain/Cart/QueryHandler/GetLastEmptyCustomerCartHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetLastEmptyCustomerCart; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Interface for handling GetLastEmptyCustomerCart query - */ -interface GetLastEmptyCustomerCartHandlerInterface -{ - /** - * @param GetLastEmptyCustomerCart $query - * - * @return CartId - */ - public function handle(GetLastEmptyCustomerCart $query): CartId; -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation.php deleted file mode 100644 index 2abd7847..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartAddress; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartProduct; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartRule; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartShipping; -use PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation\CartSummary; - -/** - * Holds cart information data - */ -class CartForOrderCreation -{ - /** - * @var int - */ - private $cartId; - - /** - * @var CartProduct[] - */ - private $products; - - /** - * @var int - */ - private $currencyId; - - /** - * @var int - */ - private $langId; - - /** - * @var CartRule[] - */ - private $cartRules; - - /** - * @var CartAddress[] - */ - private $addresses; - - /** - * @var CartShipping|null - */ - private $shipping; - - /** - * @var CartSummary - */ - private $summary; - - /** - * @param int $cartId - * @param array $products - * @param int $currencyId - * @param int $langId - * @param CartRule[] $cartRules - * @param CartAddress[] $addresses - * @param CartSummary $summary - * @param CartShipping $shipping - */ - public function __construct( - int $cartId, - array $products, - int $currencyId, - int $langId, - array $cartRules, - array $addresses, - CartSummary $summary, - CartShipping $shipping = null - ) { - $this->cartId = $cartId; - $this->products = $products; - $this->currencyId = $currencyId; - $this->langId = $langId; - $this->cartRules = $cartRules; - $this->addresses = $addresses; - $this->shipping = $shipping; - $this->summary = $summary; - } - - /** - * @return int - */ - public function getCartId(): int - { - return $this->cartId; - } - - /** - * @return CartProduct[] - */ - public function getProducts(): array - { - return $this->products; - } - - /** - * @return int - */ - public function getCurrencyId(): int - { - return $this->currencyId; - } - - /** - * @return int - */ - public function getLangId(): int - { - return $this->langId; - } - - /** - * @return CartRule[] - */ - public function getCartRules(): array - { - return $this->cartRules; - } - - /** - * @return CartAddress[] - */ - public function getAddresses(): array - { - return $this->addresses; - } - - /** - * @return CartShipping|null - */ - public function getShipping(): ?CartShipping - { - return $this->shipping; - } - - /** - * @return CartSummary - */ - public function getSummary(): CartSummary - { - return $this->summary; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartAddress.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartAddress.php deleted file mode 100644 index 68ac411a..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartAddress.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds address data for cart information - */ -class CartAddress -{ - /** - * @var int - */ - private $addressId; - - /** - * @var string - */ - private $alias; - - /** - * @var string - */ - private $formattedAddress; - - /** - * @var bool is it used as delivery address - */ - private $delivery; - - /** - * @var bool is it used as invoice address - */ - private $invoice; - - /** - * @param int $addressId - * @param string $alias - * @param string $formattedAddress - * @param bool $delivery - * @param bool $invoice - */ - public function __construct( - int $addressId, - string $alias, - string $formattedAddress, - bool $delivery, - bool $invoice - ) { - $this->addressId = $addressId; - $this->alias = $alias; - $this->formattedAddress = $formattedAddress; - $this->delivery = $delivery; - $this->invoice = $invoice; - } - - /** - * @return int - */ - public function getAddressId(): int - { - return $this->addressId; - } - - /** - * @return string - */ - public function getAlias(): string - { - return $this->alias; - } - - /** - * @return string - */ - public function getFormattedAddress(): string - { - return $this->formattedAddress; - } - - /** - * @return bool - */ - public function isDelivery(): bool - { - return $this->delivery; - } - - /** - * @return bool - */ - public function isInvoice(): bool - { - return $this->invoice; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartDeliveryOption.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartDeliveryOption.php deleted file mode 100644 index 735f2af1..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartDeliveryOption.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds data of cart delivery option - */ -class CartDeliveryOption -{ - /** - * @var int - */ - private $carrierId; - - /** - * @var string - */ - private $carrierName; - - /** - * @var string - */ - private $carrierDelay; - - /** - * @param $carrierId - * @param $carrierName - * @param $carrierDelay - */ - public function __construct(int $carrierId, string $carrierName, string $carrierDelay) - { - $this->carrierId = $carrierId; - $this->carrierName = $carrierName; - $this->carrierDelay = $carrierDelay; - } - - /** - * @return int - */ - public function getCarrierId(): int - { - return $this->carrierId; - } - - /** - * @return string - */ - public function getCarrierName(): string - { - return $this->carrierName; - } - - /** - * @return string - */ - public function getCarrierDelay(): string - { - return $this->carrierDelay; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartProduct.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartProduct.php deleted file mode 100644 index ce8f4895..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartProduct.php +++ /dev/null @@ -1,216 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds data of cart product information - */ -class CartProduct -{ - /** - * @var int - */ - private $productId; - - /** - * @var int - */ - private $attributeId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $attribute; - - /** - * @var string - */ - private $reference; - - /** - * @var string - */ - private $unitPrice; - - /** - * @var int - */ - private $quantity; - - /** - * @var string - */ - private $price; - /** - * @var string - */ - private $imageLink; - - /** - * @var Customization|null - */ - private $customization; - - /** - * @var bool - */ - private $isGift; - - /** - * CartProduct constructor. - * - * @param int $productId - * @param int $attributeId - * @param string $name - * @param string $attribute - * @param string $reference - * @param string $unitPrice - * @param int $quantity - * @param string $price - * @param string $imageLink - * @param Customization|null $customization - * @param bool $isGift - */ - public function __construct( - int $productId, - int $attributeId, - string $name, - string $attribute, - string $reference, - string $unitPrice, - int $quantity, - string $price, - string $imageLink, - ?Customization $customization, - bool $isGift = false - ) { - $this->productId = $productId; - $this->attributeId = $attributeId; - $this->name = $name; - $this->attribute = $attribute; - $this->reference = $reference; - $this->unitPrice = $unitPrice; - $this->quantity = $quantity; - $this->price = $price; - $this->imageLink = $imageLink; - $this->customization = $customization; - $this->isGift = $isGift; - } - - /** - * @return int - */ - public function getProductId(): int - { - return $this->productId; - } - - /** - * @return string - */ - public function getReference(): string - { - return $this->reference; - } - - /** - * @return string - */ - public function getUnitPrice(): string - { - return $this->unitPrice; - } - - /** - * @return int - */ - public function getQuantity(): int - { - return $this->quantity; - } - - /** - * @return string - */ - public function getPrice(): string - { - return $this->price; - } - - /** - * @return string - */ - public function getImageLink(): string - { - return $this->imageLink; - } - - /** - * @return int - */ - public function getAttributeId(): int - { - return $this->attributeId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getAttribute(): string - { - return $this->attribute; - } - - /** - * @return Customization|null - */ - public function getCustomization(): ?Customization - { - return $this->customization; - } - - /** - * @return bool - */ - public function isGift(): bool - { - return $this->isGift; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartRule.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartRule.php deleted file mode 100644 index a39b988e..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartRule.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds cart rule (a.k.a voucher) data for cart information - */ -class CartRule -{ - /** - * @var int - */ - private $cartRuleId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $description; - - /** - * @var string - */ - private $value; - - /** - * @param int $cartRuleId - * @param string $name - * @param string $description - * @param string $value - */ - public function __construct( - int $cartRuleId, - string $name, - string $description, - string $value - ) { - $this->cartRuleId = $cartRuleId; - $this->name = $name; - $this->description = $description; - $this->value = $value; - } - - /** - * @return int - */ - public function getCartRuleId(): int - { - return $this->cartRuleId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getDescription(): string - { - return $this->description; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->value; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartShipping.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartShipping.php deleted file mode 100644 index 44df023d..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartShipping.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds data for cart shipping information - */ -class CartShipping -{ - /** - * @var ?int - */ - private $selectedCarrierId; - - /** - * @var string - */ - private $shippingPrice; - - /** - * @var bool - */ - private $freeShipping; - - /** - * @var CartDeliveryOption[] - */ - private $deliveryOptions; - - /** - * @var bool - */ - private $isRecycledPackaging; - - /** - * @var bool - */ - private $isGift; - - /** - * @var string - */ - private $giftMessage; - - /** - * @param string $shippingPrice - * @param bool $freeShipping - * @param CartDeliveryOption[] $deliveryOptions - * @param int|null $selectedCarrierId - * @param bool $isGift - * @param bool $isRecycledPackaging - * @param string $giftMessage - */ - public function __construct( - string $shippingPrice, - bool $freeShipping, - array $deliveryOptions, - ?int $selectedCarrierId, - bool $isGift, - bool $isRecycledPackaging, - string $giftMessage - ) { - $this->shippingPrice = $shippingPrice; - $this->freeShipping = $freeShipping; - $this->deliveryOptions = $deliveryOptions; - $this->selectedCarrierId = $selectedCarrierId; - $this->isGift = $isGift; - $this->isRecycledPackaging = $isRecycledPackaging; - $this->giftMessage = $giftMessage; - } - - /** - * @return string - */ - public function getShippingPrice(): string - { - return $this->shippingPrice; - } - - /** - * @return bool - */ - public function isFreeShipping(): bool - { - return $this->freeShipping; - } - - /** - * @return CartDeliveryOption[] - */ - public function getDeliveryOptions(): array - { - return $this->deliveryOptions; - } - - /** - * @return mixed - */ - public function getSelectedCarrierId() - { - return $this->selectedCarrierId; - } - - /** - * @return bool - */ - public function isRecycledPackaging(): bool - { - return $this->isRecycledPackaging; - } - - /** - * @return bool - */ - public function isGift(): bool - { - return $this->isGift; - } - - /** - * @return string - */ - public function getGiftMessage(): string - { - return $this->giftMessage; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartSummary.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartSummary.php deleted file mode 100644 index d63d7e65..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CartSummary.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds cart summary data - */ -class CartSummary -{ - /** - * @var string - */ - private $totalProductsPrice; - - /** - * @var string - */ - private $totalDiscount; - - /** - * @var string - */ - private $totalShippingPrice; - - /** - * @var string - */ - private $totalShippingWithoutTaxes; - - /** - * @var string - */ - private $totalTaxes; - - /** - * @var string - */ - private $totalPriceWithTaxes; - - /** - * @var string - */ - private $totalPriceWithoutTaxes; - - /** - * @var string - */ - private $orderMessage; - - /** - * @var string - */ - private $processOrderLink; - - /** - * @param string $totalProductsPrice - * @param string $totalDiscount - * @param string $totalShippingPrice - * @param string $totalShippingWithoutTaxes - * @param string $totalTaxes - * @param string $totalPriceWithTaxes - * @param string $totalPriceWithoutTaxes - * @param string $orderMessage - * @param string $processOrderLink - */ - public function __construct( - string $totalProductsPrice, - string $totalDiscount, - string $totalShippingPrice, - string $totalShippingWithoutTaxes, - string $totalTaxes, - string $totalPriceWithTaxes, - string $totalPriceWithoutTaxes, - string $orderMessage, - string $processOrderLink - ) { - $this->totalProductsPrice = $totalProductsPrice; - $this->totalDiscount = $totalDiscount; - $this->totalShippingPrice = $totalShippingPrice; - $this->totalShippingWithoutTaxes = $totalShippingWithoutTaxes; - $this->totalTaxes = $totalTaxes; - $this->totalPriceWithTaxes = $totalPriceWithTaxes; - $this->totalPriceWithoutTaxes = $totalPriceWithoutTaxes; - $this->processOrderLink = $processOrderLink; - $this->orderMessage = $orderMessage; - } - - /** - * @return string - */ - public function getTotalProductsPrice(): string - { - return $this->totalProductsPrice; - } - - /** - * @return string - */ - public function getTotalDiscount(): string - { - return $this->totalDiscount; - } - - /** - * @return string - */ - public function getTotalShippingPrice(): string - { - return $this->totalShippingPrice; - } - - /** - * @return string - */ - public function getTotalShippingWithoutTaxes(): string - { - return $this->totalShippingWithoutTaxes; - } - - /** - * @return string - */ - public function getTotalTaxes(): string - { - return $this->totalTaxes; - } - - /** - * @return string - */ - public function getTotalPriceWithTaxes(): string - { - return $this->totalPriceWithTaxes; - } - - /** - * @return string - */ - public function getTotalPriceWithoutTaxes(): string - { - return $this->totalPriceWithoutTaxes; - } - - /** - * @return string - */ - public function getProcessOrderLink(): string - { - return $this->processOrderLink; - } - - /** - * @return string - */ - public function getOrderMessage(): string - { - return $this->orderMessage; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/Customization.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/Customization.php deleted file mode 100644 index 0cee4cb1..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/Customization.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds product customization data along with its custom fields data - */ -class Customization -{ - /** - * @var int - */ - private $customizationId; - - /** - * @var CustomizationFieldData[] - */ - private $customizationFieldsData; - - public function __construct( - int $customizationId, - array $customizationFieldsData - ) { - $this->customizationId = $customizationId; - $this->customizationFieldsData = $customizationFieldsData; - } - - /** - * @return int - */ - public function getCustomizationId(): int - { - return $this->customizationId; - } - - /** - * @return CustomizationFieldData[] - */ - public function getCustomizationFieldsData(): array - { - return $this->customizationFieldsData; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CustomizationFieldData.php b/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CustomizationFieldData.php deleted file mode 100644 index 155c1cf9..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartForOrderCreation/CustomizationFieldData.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult\CartForOrderCreation; - -/** - * Holds product customized data of customization field - */ -class CustomizationFieldData -{ - /** - * @var int - */ - private $type; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $value; - - public function __construct( - int $type, - string $name, - string $value - ) { - $this->type = $type; - $this->name = $name; - $this->value = $value; - } - - /** - * @return int - */ - public function getType(): int - { - return $this->type; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->value; - } -} diff --git a/src/Core/Domain/Cart/QueryResult/CartView.php b/src/Core/Domain/Cart/QueryResult/CartView.php deleted file mode 100644 index b5c113ff..00000000 --- a/src/Core/Domain/Cart/QueryResult/CartView.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\QueryResult; - -class CartView -{ - /** - * @var array - */ - private $customerInformation; - - /** - * @var array - */ - private $orderInformation; - - /** - * @var int - */ - private $cartId; - - /** - * @var array - */ - private $cartSummary; - - /** - * @var int - */ - private $currencyId; - - /** - * @param int $cartId - * @param int $currencyId - * @param array $customerInformation - * @param array $orderInformation - * @param array $cartSummary - */ - public function __construct( - $cartId, - $currencyId, - array $customerInformation, - array $orderInformation, - array $cartSummary - ) { - $this->customerInformation = $customerInformation; - $this->orderInformation = $orderInformation; - $this->cartId = $cartId; - $this->cartSummary = $cartSummary; - $this->currencyId = $currencyId; - } - - /** - * @return array - */ - public function getCustomerInformation() - { - return $this->customerInformation; - } - - /** - * @return array - */ - public function getOrderInformation() - { - return $this->orderInformation; - } - - /** - * @return int - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return int - */ - public function getCartCurrencyId() - { - return $this->currencyId; - } - - /** - * @return array - */ - public function getCartSummary() - { - return $this->cartSummary; - } -} diff --git a/src/Core/Domain/Cart/ValueObject/CartId.php b/src/Core/Domain/Cart/ValueObject/CartId.php deleted file mode 100644 index 0bcf9798..00000000 --- a/src/Core/Domain/Cart/ValueObject/CartId.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; - -/** - * Cart identity - */ -class CartId -{ - /** - * @var int - */ - private $cartId; - - /** - * @param int $cartId - * - * @throws CartConstraintException if cart id is not valid - */ - public function __construct($cartId) - { - if (!is_int($cartId) || 0 >= $cartId) { - throw new CartConstraintException(sprintf('Cart id must be integer greater than zero, but %s given.', var_export($cartId, true))); - } - - $this->cartId = $cartId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->cartId; - } -} diff --git a/src/Core/Domain/CartRule/Command/AddCartRuleCommand.php b/src/Core/Domain/CartRule/Command/AddCartRuleCommand.php deleted file mode 100644 index 120a3337..00000000 --- a/src/Core/Domain/CartRule/Command/AddCartRuleCommand.php +++ /dev/null @@ -1,621 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Command; - -use DateTime; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction\CartRuleActionInterface; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\DiscountApplicationType; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Money; - -/** - * Adds new cart rule - */ -class AddCartRuleCommand -{ - /** - * @var string - */ - private $description; - - /** - * @var string - */ - private $code; - - /** - * @var MoneyAmountCondition - */ - private $minimumAmountCondition; - - /** - * @var CustomerId|null - */ - private $customerId; - - /** - * @var bool - */ - private $hasCountryRestriction = false; - - /** - * @var bool - */ - private $hasCarrierRestriction = false; - - /** - * @var bool - */ - private $hasGroupRestriction = false; - - /** - * @var bool - */ - private $hasCartRuleRestriction = false; - - /** - * @var bool - */ - private $hasProductRestriction = false; - - /** - * @var bool - */ - private $hasShopRestriction = false; - - /** - * @var array - */ - private $localizedNames; - - /** - * @var bool - */ - private $highlightInCart; - - /** - * @var bool - */ - private $allowPartialUse; - - /** - * @var int - */ - private $priority; - - /** - * @var bool - */ - private $isActive; - - /** - * @var DateTime - */ - private $validFrom; - - /** - * @var DateTime - */ - private $validTo; - - /** - * @var int - */ - private $totalQuantity; - - /** - * @var int - */ - private $quantityPerUser; - - /** - * @var CartRuleActionInterface - */ - private $cartRuleAction; - - /** - * Discount application type indicates what the discount should be applied to. - * E.g. to whole order, to a specific product, to cheapest product. - * - * @var DiscountApplicationType|null - */ - private $discountApplicationType; - - /** - * This is the product to which discount is applied, when discount application type is "specific product". - * - * @var ProductId|null - */ - private $discountProductId; - - /** - * @param array $localizedNames - * @param bool $highlightInCart - * @param bool $allowPartialUse - * @param int $priority - * @param bool $isActive - * @param DateTime $validFrom - * @param DateTime $validTo - * @param int $totalQuantity - * @param int $quantityPerUser - * @param CartRuleActionInterface $cartRuleAction - * @param float $minimumAmount - * @param int $minimumAmountCurrencyId - * @param bool $isMinimumAmountTaxExcluded - * @param bool $isMinimumAmountShippingExcluded - * - * @throws CartRuleConstraintException - * @throws DomainConstraintException - */ - public function __construct( - array $localizedNames, - bool $highlightInCart, - bool $allowPartialUse, - int $priority, - bool $isActive, - DateTime $validFrom, - DateTime $validTo, - int $totalQuantity, - int $quantityPerUser, - CartRuleActionInterface $cartRuleAction, - float $minimumAmount, - int $minimumAmountCurrencyId, - bool $isMinimumAmountTaxExcluded, - bool $isMinimumAmountShippingExcluded - ) { - $this->assertDateRangeIsValid($validFrom, $validTo); - $this->setLocalizedNames($localizedNames); - $this->setPriority($priority); - $this->setTotalQuantity($totalQuantity); - $this->setQuantityPerUser($quantityPerUser); - $this->minimumAmountCondition = new MoneyAmountCondition( - new Money(new Number((string) $minimumAmount), new CurrencyId($minimumAmountCurrencyId)), - $isMinimumAmountTaxExcluded, - $isMinimumAmountShippingExcluded - ); - $this->highlightInCart = $highlightInCart; - $this->allowPartialUse = $allowPartialUse; - $this->isActive = $isActive; - $this->validFrom = $validFrom; - $this->validTo = $validTo; - $this->cartRuleAction = $cartRuleAction; - } - - /** - * @return DiscountApplicationType|null - */ - public function getDiscountApplicationType(): ?DiscountApplicationType - { - return $this->discountApplicationType; - } - - /** - * @param string $discountApplicationType - * - * @return AddCartRuleCommand - * - * @throws CartRuleConstraintException - */ - public function setDiscountApplicationType(string $discountApplicationType): AddCartRuleCommand - { - $this->discountApplicationType = new DiscountApplicationType($discountApplicationType); - - return $this; - } - - /** - * @return ProductId|null - */ - public function getDiscountProductId(): ?ProductId - { - return $this->discountProductId; - } - - /** - * @param int $discountProductId - * - * @return AddCartRuleCommand - */ - public function setDiscountProductId(int $discountProductId): AddCartRuleCommand - { - $this->discountProductId = new ProductId($discountProductId); - - return $this; - } - - /** - * @return string - */ - public function getDescription(): string - { - return $this->description; - } - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @return MoneyAmountCondition - */ - public function getMinimumAmountCondition(): MoneyAmountCondition - { - return $this->minimumAmountCondition; - } - - /** - * @return CustomerId|null - */ - public function getCustomerId(): ?CustomerId - { - return $this->customerId; - } - - /** - * @return bool - */ - public function hasCountryRestriction(): bool - { - return $this->hasCountryRestriction; - } - - /** - * @return bool - */ - public function hasCarrierRestriction(): bool - { - return $this->hasCarrierRestriction; - } - - /** - * @return bool - */ - public function hasGroupRestriction(): bool - { - return $this->hasGroupRestriction; - } - - /** - * @return bool - */ - public function hasCartRuleRestriction(): bool - { - return $this->hasCartRuleRestriction; - } - - /** - * @return bool - */ - public function hasProductRestriction(): bool - { - return $this->hasProductRestriction; - } - - /** - * @return bool - */ - public function hasShopRestriction(): bool - { - return $this->hasShopRestriction; - } - - /** - * @return array - */ - public function getLocalizedNames(): array - { - return $this->localizedNames; - } - - /** - * @return bool - */ - public function isHighlightInCart(): bool - { - return $this->highlightInCart; - } - - /** - * @return bool - */ - public function isAllowPartialUse(): bool - { - return $this->allowPartialUse; - } - - /** - * @return int - */ - public function getPriority(): int - { - return $this->priority; - } - - /** - * @return bool - */ - public function isActive(): bool - { - return $this->isActive; - } - - /** - * @return DateTime - */ - public function getValidFrom(): DateTime - { - return $this->validFrom; - } - - /** - * @return DateTime - */ - public function getValidTo(): DateTime - { - return $this->validTo; - } - - /** - * @return int - */ - public function getTotalQuantity(): int - { - return $this->totalQuantity; - } - - /** - * @return int - */ - public function getQuantityPerUser(): int - { - return $this->quantityPerUser; - } - - /** - * @return CartRuleActionInterface - */ - public function getCartRuleAction(): CartRuleActionInterface - { - return $this->cartRuleAction; - } - - /** - * @param string $description - * - * @return AddCartRuleCommand - */ - public function setDescription(string $description): AddCartRuleCommand - { - $this->description = $description; - - return $this; - } - - /** - * @param string $code - * - * @return AddCartRuleCommand - */ - public function setCode(string $code): AddCartRuleCommand - { - $this->code = $code; - - return $this; - } - - /** - * @param int $customerId - * - * @return AddCartRuleCommand - */ - public function setCustomerId(int $customerId): AddCartRuleCommand - { - $this->customerId = new CustomerId($customerId); - - return $this; - } - - /** - * @param bool $hasCountryRestriction - * - * @return AddCartRuleCommand - */ - public function setHasCountryRestriction(bool $hasCountryRestriction): AddCartRuleCommand - { - $this->hasCountryRestriction = $hasCountryRestriction; - - return $this; - } - - /** - * @param bool $hasCarrierRestriction - * - * @return AddCartRuleCommand - */ - public function setHasCarrierRestriction(bool $hasCarrierRestriction): AddCartRuleCommand - { - $this->hasCarrierRestriction = $hasCarrierRestriction; - - return $this; - } - - /** - * @param bool $hasGroupRestriction - * - * @return AddCartRuleCommand - */ - public function setHasGroupRestriction(bool $hasGroupRestriction): AddCartRuleCommand - { - $this->hasGroupRestriction = $hasGroupRestriction; - - return $this; - } - - /** - * @param bool $hasCartRuleRestriction - * - * @return AddCartRuleCommand - */ - public function setHasCartRuleRestriction(bool $hasCartRuleRestriction): AddCartRuleCommand - { - $this->hasCartRuleRestriction = $hasCartRuleRestriction; - - return $this; - } - - /** - * @param bool $hasProductRestriction - * - * @return AddCartRuleCommand - */ - public function setHasProductRestriction(bool $hasProductRestriction): AddCartRuleCommand - { - $this->hasProductRestriction = $hasProductRestriction; - - return $this; - } - - /** - * @param bool $hasShopRestriction - * - * @return AddCartRuleCommand - */ - public function setHasShopRestriction(bool $hasShopRestriction): AddCartRuleCommand - { - $this->hasShopRestriction = $hasShopRestriction; - - return $this; - } - - /** - * @param array $localizedNames - * - * @return AddCartRuleCommand - * - * @throws CartRuleConstraintException - */ - private function setLocalizedNames(array $localizedNames): AddCartRuleCommand - { - $this->assertAtLeastOneNameIsPresent($localizedNames); - - foreach ($localizedNames as $languageId => $name) { - $this->localizedNames[(new LanguageId($languageId))->getValue()] = $name; - } - - return $this; - } - - /** - * @param int $priority - * - * @return AddCartRuleCommand - * - * @throws CartRuleConstraintException - */ - private function setPriority(int $priority): AddCartRuleCommand - { - if (0 >= $priority) { - throw new CartRuleConstraintException(sprintf('Invalid cart rule priority "%s". Must be a positive integer.', var_export($priority, true)), CartRuleConstraintException::INVALID_PRIORITY); - } - - $this->priority = $priority; - - return $this; - } - - /** - * @param int $quantity - * - * @return AddCartRuleCommand - * - * @throws CartRuleConstraintException - */ - private function setTotalQuantity(int $quantity): AddCartRuleCommand - { - if (0 > $quantity) { - throw new CartRuleConstraintException(sprintf('Quantity cannot be lower than zero, %d given', $quantity), CartRuleConstraintException::INVALID_QUANTITY); - } - - $this->totalQuantity = $quantity; - - return $this; - } - - /** - * @param int $quantity - * - * @return AddCartRuleCommand - * - * @throws CartRuleConstraintException - */ - private function setQuantityPerUser(int $quantity): AddCartRuleCommand - { - if (0 > $quantity) { - throw new CartRuleConstraintException(sprintf('Quantity per user cannot be lower than zero, %d given', $quantity), CartRuleConstraintException::INVALID_QUANTITY_PER_USER); - } - - $this->quantityPerUser = $quantity; - - return $this; - } - - /** - * @param array $names - * - * @throws CartRuleConstraintException - */ - private function assertAtLeastOneNameIsPresent(array $names): void - { - if (empty($names)) { - throw new CartRuleConstraintException('Cart rule name is mandatory in at least one language', CartRuleConstraintException::EMPTY_NAME); - } - } - - /** - * @param DateTime $dateFrom - * @param DateTime $dateTo - * - * @throws CartRuleConstraintException - */ - private function assertDateRangeIsValid(DateTime $dateFrom, DateTime $dateTo): void - { - if ($dateFrom > $dateTo) { - throw new CartRuleConstraintException('Date from cannot be greater than date to.', CartRuleConstraintException::DATE_FROM_GREATER_THAN_DATE_TO); - } - } -} diff --git a/src/Core/Domain/CartRule/CommandHandler/AddCartRuleHandlerInterface.php b/src/Core/Domain/CartRule/CommandHandler/AddCartRuleHandlerInterface.php deleted file mode 100644 index 08560e63..00000000 --- a/src/Core/Domain/CartRule/CommandHandler/AddCartRuleHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Command\AddCartRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleId; - -/** - * Interface for service that handles adding new cart rule. - */ -interface AddCartRuleHandlerInterface -{ - /** - * @param AddCartRuleCommand $command - * - * @return CartRuleId - */ - public function handle(AddCartRuleCommand $command): CartRuleId; -} diff --git a/src/Core/Domain/CartRule/Exception/CannotDeleteCartRuleException.php b/src/Core/Domain/CartRule/Exception/CannotDeleteCartRuleException.php deleted file mode 100644 index 2f88a0e2..00000000 --- a/src/Core/Domain/CartRule/Exception/CannotDeleteCartRuleException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -class CannotDeleteCartRuleException extends CartRuleException -{ -} diff --git a/src/Core/Domain/CartRule/Exception/CartRuleConstraintException.php b/src/Core/Domain/CartRule/Exception/CartRuleConstraintException.php deleted file mode 100644 index 60187cfc..00000000 --- a/src/Core/Domain/CartRule/Exception/CartRuleConstraintException.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -/** - * Thrown when validating cart rule's data - */ -class CartRuleConstraintException extends CartRuleException -{ - /** - * Used when cart rule is using an invalid discount application type - */ - const INVALID_DISCOUNT_APPLICATION_TYPE = 1; - - /** - * Used when cart rule name is empty - */ - const EMPTY_NAME = 2; - - /** - * Used when cart rule's priority is invalid - */ - const INVALID_PRIORITY = 3; - - /** - * Used when cart rule's date from is greater than date to - */ - const DATE_FROM_GREATER_THAN_DATE_TO = 4; - - /** - * Used when cart rule's quantity is invalid - */ - const INVALID_QUANTITY = 5; - - /** - * Used when quantity per user is invalid - */ - const INVALID_QUANTITY_PER_USER = 6; - - /** - * Used when percentage discount is invalid - */ - const INVALID_PERCENTAGE = 7; - - /** - * Used when cart rule has invalid gift product assigned - */ - const INVALID_GIFT_PRODUCT = 8; - - /** - * Used when cart rule has invalid gift product attribute - */ - const INVALID_GIFT_PRODUCT_ATTRIBUTE = 9; - - /** - * Used when cart rule has incompatible actions, - * e.g. both amount and percentage discounts at the same time. - */ - const INCOMPATIBLE_CART_RULE_ACTIONS = 10; - - /** - * Used when cart rule is missing an action. - */ - const MISSING_ACTION = 11; - - /** - * Used when discount is applied to specific product, but that product is not set. - */ - const MISSING_DISCOUNT_APPLICATION_PRODUCT = 12; - - /** - * Used when cart rule id constraints are violated - */ - const INVALID_ID = 13; -} diff --git a/src/Core/Domain/CartRule/Exception/CartRuleException.php b/src/Core/Domain/CartRule/Exception/CartRuleException.php deleted file mode 100644 index 62432b1f..00000000 --- a/src/Core/Domain/CartRule/Exception/CartRuleException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Thrown in cart rules context - */ -class CartRuleException extends DomainException -{ -} diff --git a/src/Core/Domain/CartRule/Exception/CartRuleValidityException.php b/src/Core/Domain/CartRule/Exception/CartRuleValidityException.php deleted file mode 100644 index 989d38ca..00000000 --- a/src/Core/Domain/CartRule/Exception/CartRuleValidityException.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -use PrestaShop\PrestaShop\Core\Exception\TranslatedException; - -/** - * Thrown when cart rule validation fails. - * This exception must contain already translated error message, which can be displayed to end-user - */ -class CartRuleValidityException extends TranslatedException -{ -} diff --git a/src/Core/Domain/CartRule/Exception/InvalidCartRuleDiscountValueException.php b/src/Core/Domain/CartRule/Exception/InvalidCartRuleDiscountValueException.php deleted file mode 100644 index 0d0945ba..00000000 --- a/src/Core/Domain/CartRule/Exception/InvalidCartRuleDiscountValueException.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -/** - * Thrown when a discount is added with an invalid amount/percentage - */ -class InvalidCartRuleDiscountValueException extends InvalidCartRuleValueException -{ - /** - * Code used when an invalid percent value is under min value - */ - const INVALID_MIN_PERCENT = 10; - - /** - * Code used when an invalid percent value is above max value - */ - const INVALID_MAX_PERCENT = 20; - - /** - * Code used when the specified amount is under min value - */ - const INVALID_MIN_AMOUNT = 30; - - /** - * Code used when the specified amount is above max value - */ - const INVALID_MAX_AMOUNT = 40; - - /** - * Code used when free shipping cannot be applied - */ - const INVALID_FREE_SHIPPING = 50; -} diff --git a/src/Core/Domain/CartRule/Exception/InvalidCartRuleValueException.php b/src/Core/Domain/CartRule/Exception/InvalidCartRuleValueException.php deleted file mode 100644 index 670d73d7..00000000 --- a/src/Core/Domain/CartRule/Exception/InvalidCartRuleValueException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Exception; - -/** - * Thrown when a value is invalid - */ -class InvalidCartRuleValueException extends CartRuleException -{ -} diff --git a/src/Core/Domain/CartRule/Query/SearchCartRules.php b/src/Core/Domain/CartRule/Query/SearchCartRules.php deleted file mode 100644 index e7278be7..00000000 --- a/src/Core/Domain/CartRule/Query/SearchCartRules.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\Query; - -/** - * Searches for cart rules - */ -class SearchCartRules -{ - /** - * @var string - */ - private $searchPhrase; - - /** - * @param string $searchPhrase - */ - public function __construct(string $searchPhrase) - { - $this->searchPhrase = $searchPhrase; - } - - /** - * @return string - */ - public function getSearchPhrase(): string - { - return $this->searchPhrase; - } -} diff --git a/src/Core/Domain/CartRule/QueryHandler/SearchCartRulesHandlerInterface.php b/src/Core/Domain/CartRule/QueryHandler/SearchCartRulesHandlerInterface.php deleted file mode 100644 index acc962d7..00000000 --- a/src/Core/Domain/CartRule/QueryHandler/SearchCartRulesHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Query\SearchCartRules; -use PrestaShop\PrestaShop\Core\Domain\CartRule\QueryResult\FoundCartRule; - -/** - * Interface for handling SearchCartRules query - */ -interface SearchCartRulesHandlerInterface -{ - /** - * @param SearchCartRules $query - * - * @return FoundCartRule[] - */ - public function handle(SearchCartRules $query): array; -} diff --git a/src/Core/Domain/CartRule/QueryResult/FoundCartRule.php b/src/Core/Domain/CartRule/QueryResult/FoundCartRule.php deleted file mode 100644 index c9061071..00000000 --- a/src/Core/Domain/CartRule/QueryResult/FoundCartRule.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\QueryResult; - -/** - * Holds data for cart rule found after search operation - */ -class FoundCartRule -{ - /** - * @var int - */ - private $cartRuleId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $code; - - /** - * @param int $cartRuleId - * @param string $name - * @param string $code - */ - public function __construct( - int $cartRuleId, - string $name, - string $code - ) { - $this->cartRuleId = $cartRuleId; - $this->name = $name; - $this->code = $code; - } - - /** - * @return int - */ - public function getCartRuleId(): int - { - return $this->cartRuleId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/AmountDiscountAction.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/AmountDiscountAction.php deleted file mode 100644 index f126a610..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/AmountDiscountAction.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Cart rule action that gives amount discount. - * Amount discount must have a money amount and currency. - * It can optionally have free shipping and gift product. - * It cannot have percentage discount. - */ -final class AmountDiscountAction implements CartRuleActionInterface -{ - /** - * @var MoneyAmountCondition - */ - private $moneyAmountCondition; - - /** - * @var bool - */ - private $isFreeShipping; - - /** - * @var GiftProduct|null - */ - private $giftProduct; - - /** - * @param MoneyAmountCondition $moneyAmountCondition - * @param bool $isFreeShipping - * @param GiftProduct|null $giftProduct - */ - public function __construct( - MoneyAmountCondition $moneyAmountCondition, - bool $isFreeShipping, - GiftProduct $giftProduct = null - ) { - $this->moneyAmountCondition = $moneyAmountCondition; - $this->isFreeShipping = $isFreeShipping; - $this->giftProduct = $giftProduct; - } - - /** - * {@inheritdoc} - */ - public function isFreeShipping(): bool - { - return $this->isFreeShipping; - } - - /** - * {@inheritdoc} - */ - public function getPercentageDiscount(): ?PercentageDiscount - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getAmountDiscount(): ?MoneyAmountCondition - { - return $this->moneyAmountCondition; - } - - /** - * {@inheritdoc} - */ - public function getGiftProduct(): ?GiftProduct - { - return $this->giftProduct; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilder.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilder.php deleted file mode 100644 index 7dcb44cb..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilder.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Builds cart rule actions. - */ -final class CartRuleActionBuilder implements CartRuleActionBuilderInterface -{ - /** - * @var bool - */ - private $isFreeShipping = false; - - /** - * @var PercentageDiscount|null - */ - private $percentageDiscount; - - /** - * @var MoneyAmountCondition|null - */ - private $amountDiscount; - - /** - * @var GiftProduct|null - */ - private $giftProduct; - - /** - * {@inheritdoc} - */ - public function setFreeShipping(bool $isFreeShipping): CartRuleActionBuilderInterface - { - $this->isFreeShipping = $isFreeShipping; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setPercentageDiscount(PercentageDiscount $percentageDiscount): CartRuleActionBuilderInterface - { - $this->percentageDiscount = $percentageDiscount; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setAmountDiscount(MoneyAmountCondition $amount): CartRuleActionBuilderInterface - { - $this->amountDiscount = $amount; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setGiftProduct(GiftProduct $giftProduct): CartRuleActionBuilderInterface - { - $this->giftProduct = $giftProduct; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function build(): CartRuleActionInterface - { - $this->assertCartRuleActionsAreValid(); - - if (null !== $this->percentageDiscount) { - $action = new PercentageDiscountAction( - $this->percentageDiscount, - $this->isFreeShipping, - $this->giftProduct - ); - } elseif (null !== $this->amountDiscount) { - $action = new AmountDiscountAction( - $this->amountDiscount, - $this->isFreeShipping, - $this->giftProduct - ); - } elseif (true === $this->isFreeShipping) { - $action = new FreeShippingAction($this->giftProduct); - } else { - $action = new GiftProductAction($this->giftProduct); - } - - return $action; - } - - /** - * @throws CartRuleConstraintException - */ - private function assertCartRuleActionsAreValid() - { - if (null !== $this->percentageDiscount && null !== $this->amountDiscount) { - throw new CartRuleConstraintException('Cart rule cannot have both percentage and amount discount actions.', CartRuleConstraintException::INCOMPATIBLE_CART_RULE_ACTIONS); - } - - if (null === $this->percentageDiscount && - null === $this->amountDiscount && - null === $this->giftProduct && - false === $this->isFreeShipping - ) { - throw new CartRuleConstraintException('Cart rule must have at least one action', CartRuleConstraintException::MISSING_ACTION); - } - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilderInterface.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilderInterface.php deleted file mode 100644 index 392212db..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionBuilderInterface.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Describes a builder which builds cart rule actions. - */ -interface CartRuleActionBuilderInterface -{ - /** - * Set free shipping for cart rule action. - * - * @param bool $freeShipping - * - * @return CartRuleActionBuilderInterface - */ - public function setFreeShipping(bool $freeShipping): CartRuleActionBuilderInterface; - - /** - * Set percentage discount for cart rule action. - * - * @param PercentageDiscount $percentageDiscount - * - * @return CartRuleActionBuilderInterface - */ - public function setPercentageDiscount(PercentageDiscount $percentageDiscount): CartRuleActionBuilderInterface; - - /** - * Set amount discount for cart rule action. - * - * @param MoneyAmountCondition $amount - * - * @return CartRuleActionBuilderInterface - */ - public function setAmountDiscount(MoneyAmountCondition $amount): CartRuleActionBuilderInterface; - - /** - * Set the gift product for cart rule action. - * - * @param GiftProduct $giftProduct - * - * @return CartRuleActionBuilderInterface - */ - public function setGiftProduct(GiftProduct $giftProduct): CartRuleActionBuilderInterface; - - /** - * Build the cart rule action. - * - * @return CartRuleActionInterface - */ - public function build(): CartRuleActionInterface; -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionInterface.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionInterface.php deleted file mode 100644 index f63f7a99..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/CartRuleActionInterface.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Describes a cart rule action. - */ -interface CartRuleActionInterface -{ - /** - * Check if this cart rule is giving free shipping. - * - * @return bool - */ - public function isFreeShipping(): bool; - - /** - * Get the amount discount, which this cart rule action is giving. - * - * @return MoneyAmountCondition|null - */ - public function getAmountDiscount(): ?MoneyAmountCondition; - - /** - * Get the percentage discount, which this cart rule action is giving. - * - * @return PercentageDiscount|null - */ - public function getPercentageDiscount(): ?PercentageDiscount; - - /** - * Get the gift product, which this cart rule action is giving. - * - * @return GiftProduct|null returns null when not applicable - */ - public function getGiftProduct(): ?GiftProduct; -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/FreeShippingAction.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/FreeShippingAction.php deleted file mode 100644 index 195254c4..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/FreeShippingAction.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Cart rule action that gives free shipping. - * It cannot have percentage or amount discount. - * It can optionally have gift product. - */ -final class FreeShippingAction implements CartRuleActionInterface -{ - /** - * @var GiftProduct|null - */ - private $giftProduct; - - /** - * @param GiftProduct|null $giftProduct - */ - public function __construct(GiftProduct $giftProduct = null) - { - $this->giftProduct = $giftProduct; - } - - /** - * {@inheritdoc} - */ - public function isFreeShipping(): bool - { - return true; - } - - /** - * {@inheritdoc} - */ - public function getPercentageDiscount(): ?PercentageDiscount - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getAmountDiscount(): ?MoneyAmountCondition - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getGiftProduct(): ?GiftProduct - { - return $this->giftProduct; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/GiftProductAction.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/GiftProductAction.php deleted file mode 100644 index 53fb63e8..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/GiftProductAction.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Cart rule action that gives gift product. - * It cannot have percentage or amount discount, or free shipping. - */ -final class GiftProductAction implements CartRuleActionInterface -{ - /** - * @var GiftProduct - */ - private $giftProduct; - - /** - * @param GiftProduct $giftProduct - */ - public function __construct(GiftProduct $giftProduct) - { - $this->giftProduct = $giftProduct; - } - - /** - * {@inheritdoc} - */ - public function isFreeShipping(): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - public function getPercentageDiscount(): ?PercentageDiscount - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getAmountDiscount(): ?MoneyAmountCondition - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getGiftProduct(): ?GiftProduct - { - return $this->giftProduct; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/PercentageDiscountAction.php b/src/Core/Domain/CartRule/ValueObject/CartRuleAction/PercentageDiscountAction.php deleted file mode 100644 index 38191568..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleAction/PercentageDiscountAction.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\CartRuleAction; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\GiftProduct; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\MoneyAmountCondition; -use PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject\PercentageDiscount; - -/** - * Cart rule action that gives percentage discount. - * Percentage discount must have a percentage set. - * It can optionally have free shipping and gift product. - * It cannot have amount discount. - */ -final class PercentageDiscountAction implements CartRuleActionInterface -{ - /** - * @var PercentageDiscount - */ - private $percentageDiscount; - - /** - * @var bool - */ - private $isFreeShipping; - - /** - * @var GiftProduct|null - */ - private $giftProduct; - - /** - * @param PercentageDiscount $percentageDiscount - * @param bool $isFreeShipping - * @param GiftProduct|null $giftProduct - */ - public function __construct( - PercentageDiscount $percentageDiscount, - bool $isFreeShipping, - GiftProduct $giftProduct = null - ) { - $this->percentageDiscount = $percentageDiscount; - $this->isFreeShipping = $isFreeShipping; - $this->giftProduct = $giftProduct; - } - - /** - * {@inheritdoc} - */ - public function isFreeShipping(): bool - { - return $this->isFreeShipping; - } - - /** - * {@inheritdoc} - */ - public function getPercentageDiscount(): ?PercentageDiscount - { - return $this->percentageDiscount; - } - - /** - * {@inheritdoc} - */ - public function getAmountDiscount(): ?MoneyAmountCondition - { - return null; - } - - /** - * {@inheritdoc} - */ - public function getGiftProduct(): ?GiftProduct - { - return $this->giftProduct; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/CartRuleId.php b/src/Core/Domain/CartRule/ValueObject/CartRuleId.php deleted file mode 100644 index 981610a4..00000000 --- a/src/Core/Domain/CartRule/ValueObject/CartRuleId.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; - -/** - * Cart rule identity. - */ -class CartRuleId -{ - /** - * @var int - */ - private $cartRuleId; - - /** - * @param int $cartRuleId - */ - public function __construct(int $cartRuleId) - { - $this->assertIsPositiveInt($cartRuleId); - $this->cartRuleId = $cartRuleId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->cartRuleId; - } - - /** - * @param int $value - * - * @throws CartRuleConstraintException - */ - private function assertIsPositiveInt(int $value): void - { - if (0 > $value) { - throw new CartRuleConstraintException(sprintf('Invalid cart rule id "%s".', $value), CartRuleConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/DiscountApplicationType.php b/src/Core/Domain/CartRule/ValueObject/DiscountApplicationType.php deleted file mode 100644 index 4acecd2d..00000000 --- a/src/Core/Domain/CartRule/ValueObject/DiscountApplicationType.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; - -/** - * Discount application type - */ -class DiscountApplicationType -{ - /** - * Discount will be applied to order without shipping - */ - public const ORDER_WITHOUT_SHIPPING = 'order_without_shipping'; - - /** - * Discount will be applied to specifically selected product - */ - public const SPECIFIC_PRODUCT = 'specific_product'; - - /** - * Discount will be applied to cheapest product of the cart - */ - public const CHEAPEST_PRODUCT = 'cheapest_product'; - - /** - * Discount will be applied to products selection from cart rule's conditions. - */ - public const SELECTED_PRODUCTS = 'selected_products'; - - private const AVAILABLE_TYPES = [ - self::ORDER_WITHOUT_SHIPPING, - self::SPECIFIC_PRODUCT, - self::CHEAPEST_PRODUCT, - self::SELECTED_PRODUCTS, - ]; - - /** - * @var string - */ - private $type; - - /** - * @param string $type - */ - public function __construct(string $type) - { - if (!in_array($type, self::AVAILABLE_TYPES)) { - throw new CartRuleConstraintException(sprintf('Invalid cart rule discount application type %s. Available types are: %s', var_export($type, true), implode(', ', self::AVAILABLE_TYPES)), CartRuleConstraintException::INVALID_DISCOUNT_APPLICATION_TYPE); - } - - $this->type = $type; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->type; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/GiftProduct.php b/src/Core/Domain/CartRule/ValueObject/GiftProduct.php deleted file mode 100644 index 579e7e45..00000000 --- a/src/Core/Domain/CartRule/ValueObject/GiftProduct.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Gift product VO - */ -class GiftProduct -{ - /** - * @var ProductId - */ - private $productId; - /** - * @var int - */ - private $productAttributeId; - - /** - * @param int $productId - * @param int|null $productAttributeId - * - * @throws CartRuleConstraintException - */ - public function __construct(int $productId, int $productAttributeId = null) - { - $this->assertGiftProductIsValid($productId, $productAttributeId); - - $this->productId = new ProductId($productId); - $this->productAttributeId = $productAttributeId; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return int|null - */ - public function getProductAttributeId(): ?int - { - return $this->productAttributeId; - } - - /** - * @param int $productId - * @param int|null $productAttributeId - * - * @throws CartRuleConstraintException - */ - private function assertGiftProductIsValid(int $productId, ?int $productAttributeId): void - { - if (0 >= $productId) { - throw new CartRuleConstraintException('Gift product ID must be a positive integer', CartRuleConstraintException::INVALID_GIFT_PRODUCT); - } - - if (null !== $productAttributeId && 0 >= $productAttributeId) { - throw new CartRuleConstraintException('Gift product attribute ID must be a positive integer', CartRuleConstraintException::INVALID_GIFT_PRODUCT_ATTRIBUTE); - } - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/MoneyAmountCondition.php b/src/Core/Domain/CartRule/ValueObject/MoneyAmountCondition.php deleted file mode 100644 index d35cbba6..00000000 --- a/src/Core/Domain/CartRule/ValueObject/MoneyAmountCondition.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Money; - -/** - * A cart rule condition for amount of money - */ -class MoneyAmountCondition -{ - /** - * @var Money - */ - private $money; - - /** - * @var bool - */ - private $taxExcluded; - - /** - * @var bool|null - */ - private $shippingExcluded; - - /** - * @param Money $money - * @param bool $taxExcluded - * @param bool|null $shippingExcluded - */ - public function __construct(Money $money, bool $taxExcluded, bool $shippingExcluded = null) - { - $this->money = $money; - $this->taxExcluded = $taxExcluded; - $this->shippingExcluded = $shippingExcluded; - } - - /** - * @return Money - */ - public function getMoneyAmount(): Money - { - return $this->money; - } - - /** - * @return bool - */ - public function isTaxExcluded(): bool - { - return $this->taxExcluded; - } - - /** - * @return bool|null - */ - public function isShippingExcluded(): ?bool - { - return $this->shippingExcluded; - } -} diff --git a/src/Core/Domain/CartRule/ValueObject/PercentageDiscount.php b/src/Core/Domain/CartRule/ValueObject/PercentageDiscount.php deleted file mode 100644 index b1e7ce69..00000000 --- a/src/Core/Domain/CartRule/ValueObject/PercentageDiscount.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CartRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CartRule\Exception\CartRuleConstraintException; - -/** - * Percentage discount - */ -class PercentageDiscount -{ - /** - * @var float - */ - private $percentage; - - /** - * @var bool - */ - private $appliesToDiscountedProducts; - - /** - * @param float $percentage - * @param bool $appliesToDiscountedProducts - */ - public function __construct(float $percentage, bool $appliesToDiscountedProducts) - { - if ($percentage <= 0 || $percentage > 100) { - throw new CartRuleConstraintException('Percentage must be greater than 0 and not greater than 100', CartRuleConstraintException::INVALID_PERCENTAGE); - } - - $this->percentage = $percentage; - $this->appliesToDiscountedProducts = $appliesToDiscountedProducts; - } - - /** - * @return float - */ - public function getPercentage(): float - { - return $this->percentage; - } - - /** - * @return bool - */ - public function appliesToDiscountedProducts(): bool - { - return $this->appliesToDiscountedProducts; - } -} diff --git a/src/Core/Domain/CatalogPriceRule/Command/AddCatalogPriceRuleCommand.php b/src/Core/Domain/CatalogPriceRule/Command/AddCatalogPriceRuleCommand.php deleted file mode 100644 index f1459ab2..00000000 --- a/src/Core/Domain/CatalogPriceRule/Command/AddCatalogPriceRuleCommand.php +++ /dev/null @@ -1,256 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command; - -use DateTime; -use Exception; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; - -/** - * Adds new catalog price rule with provided data - */ -class AddCatalogPriceRuleCommand -{ - /** - * @var string - */ - private $name; - - /** - * @var int - */ - private $shopId; - - /** - * @var int - */ - private $currencyId; - - /** - * @var int - */ - private $countryId; - - /** - * @var int - */ - private $groupId; - - /** - * @var int - */ - private $fromQuantity; - - /** - * @var Reduction - */ - private $reduction; - - /** - * @var bool - */ - private $includeTax; - - /** - * @var Number - */ - private $price; - - /** - * @var DateTime|null - */ - private $dateTimeFrom; - - /** - * @var DateTime|null - */ - private $dateTimeTo; - - /** - * @param string $name - * @param int $currencyId - * @param int $countryId - * @param int $groupId - * @param int $fromQuantity - * @param string $reductionType - * @param float $reductionValue - * @param int $shopId - * @param bool $includeTax - * @param float $price - * - * @throws DomainConstraintException - */ - public function __construct( - string $name, - int $currencyId, - int $countryId, - int $groupId, - int $fromQuantity, - string $reductionType, - float $reductionValue, - int $shopId, - bool $includeTax, - float $price - ) { - $this->name = $name; - $this->currencyId = $currencyId; - $this->countryId = $countryId; - $this->groupId = $groupId; - $this->fromQuantity = $fromQuantity; - $this->reduction = new Reduction($reductionType, $reductionValue); - $this->shopId = $shopId; - $this->price = new Number((string) $price); - $this->includeTax = $includeTax; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return int - */ - public function getShopId(): int - { - return $this->shopId; - } - - /** - * @return int - */ - public function getCurrencyId(): int - { - return $this->currencyId; - } - - /** - * @return int - */ - public function getCountryId(): int - { - return $this->countryId; - } - - /** - * @return int - */ - public function getGroupId(): int - { - return $this->groupId; - } - - /** - * @return int - */ - public function getFromQuantity(): int - { - return $this->fromQuantity; - } - - /** - * @return Reduction - */ - public function getReduction(): Reduction - { - return $this->reduction; - } - - /** - * @return Number - */ - public function getPrice(): Number - { - return $this->price; - } - - /** - * @return DateTime|null - */ - public function getDateTimeFrom(): ?DateTime - { - return $this->dateTimeFrom; - } - - /** - * @return DateTime|null - */ - public function getDateTimeTo(): ?DateTime - { - return $this->dateTimeTo; - } - - /** - * @return bool - */ - public function isTaxIncluded(): bool - { - return $this->includeTax; - } - - /** - * @param string $dateTimeFrom - * - * @throws CatalogPriceRuleConstraintException - */ - public function setDateTimeFrom(string $dateTimeFrom) - { - $this->dateTimeFrom = $this->createDateTime($dateTimeFrom); - } - - /** - * @param string $dateTimeTo - * - * @throws CatalogPriceRuleConstraintException - */ - public function setDateTimeTo(string $dateTimeTo) - { - $this->dateTimeTo = $this->createDateTime($dateTimeTo); - } - - /** - * @param string $dateTime - * - * @return DateTime - * - * @throws CatalogPriceRuleConstraintException - */ - private function createDateTime(string $dateTime): DateTime - { - try { - return new DateTime($dateTime); - } catch (Exception $e) { - throw new CatalogPriceRuleConstraintException('An error occured when creating DateTime object for catalog price rule', CatalogPriceRuleConstraintException::INVALID_DATETIME, $e); - } - } -} diff --git a/src/Core/Domain/CatalogPriceRule/Command/BulkDeleteCatalogPriceRuleCommand.php b/src/Core/Domain/CatalogPriceRule/Command/BulkDeleteCatalogPriceRuleCommand.php deleted file mode 100644 index a733eb4b..00000000 --- a/src/Core/Domain/CatalogPriceRule/Command/BulkDeleteCatalogPriceRuleCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; - -/** - * Deletes catalog price rules in bulk acton - */ -class BulkDeleteCatalogPriceRuleCommand -{ - /** - * @var CatalogPriceRuleId[] - */ - private $catalogPriceRuleIds; - - /** - * @param int[] $catalogPriceRuleIds - * - * @throws CatalogPriceRuleConstraintException - */ - public function __construct(array $catalogPriceRuleIds) - { - $this->setCatalogPriceRuleIds($catalogPriceRuleIds); - } - - /** - * @return CatalogPriceRuleId[] - */ - public function getCatalogPriceRuleIds() - { - return $this->catalogPriceRuleIds; - } - - /** - * @param int[] $catalogPriceRuleIds - * - * @throws CatalogPriceRuleConstraintException - */ - private function setCatalogPriceRuleIds(array $catalogPriceRuleIds) - { - foreach ($catalogPriceRuleIds as $catalogPriceRuleId) { - $this->catalogPriceRuleIds[] = new CatalogPriceRuleId($catalogPriceRuleId); - } - } -} diff --git a/src/Core/Domain/CatalogPriceRule/Command/DeleteCatalogPriceRuleCommand.php b/src/Core/Domain/CatalogPriceRule/Command/DeleteCatalogPriceRuleCommand.php deleted file mode 100644 index 0825a784..00000000 --- a/src/Core/Domain/CatalogPriceRule/Command/DeleteCatalogPriceRuleCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; - -/** - * Deletes catalog price rule - */ -class DeleteCatalogPriceRuleCommand -{ - /** - * @var CatalogPriceRuleId - */ - private $catalogPriceRuleId; - - /** - * @param int $catalogPriceRuleId - * - * @throws CatalogPriceRuleConstraintException - */ - public function __construct($catalogPriceRuleId) - { - $this->catalogPriceRuleId = new CatalogPriceRuleId($catalogPriceRuleId); - } - - /** - * @return CatalogPriceRuleId - */ - public function getCatalogPriceRuleId() - { - return $this->catalogPriceRuleId; - } -} diff --git a/src/Core/Domain/CatalogPriceRule/Command/EditCatalogPriceRuleCommand.php b/src/Core/Domain/CatalogPriceRule/Command/EditCatalogPriceRuleCommand.php deleted file mode 100644 index 74d072a6..00000000 --- a/src/Core/Domain/CatalogPriceRule/Command/EditCatalogPriceRuleCommand.php +++ /dev/null @@ -1,312 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command; - -use DateTime; -use Exception; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; - -/** - * Edits catalog price rule with given data - */ -class EditCatalogPriceRuleCommand -{ - /** - * @var CatalogPriceRuleId - */ - private $catalogPriceRuleId; - - /** - * @var string|null - */ - private $name; - - /** - * @var int|null - */ - private $shopId; - - /** - * @var int|null - */ - private $currencyId; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var int|null - */ - private $groupId; - - /** - * @var int|null - */ - private $fromQuantity; - - /** - * @var float|null - */ - private $price; - - /** - * @var DateTime|null - */ - private $dateTimeFrom; - - /** - * @var DateTime|null - */ - private $dateTimeTo; - - /** - * @var bool|null - */ - private $includeTax; - - /** - * @var Reduction - */ - private $reduction; - - /** - * @param int $catalogPriceRuleId - * - * @throws CatalogPriceRuleConstraintException - */ - public function __construct(int $catalogPriceRuleId) - { - $this->catalogPriceRuleId = new CatalogPriceRuleId($catalogPriceRuleId); - } - - /** - * @return CatalogPriceRuleId - */ - public function getCatalogPriceRuleId(): CatalogPriceRuleId - { - return $this->catalogPriceRuleId; - } - - /** - * @return string|null - */ - public function getName(): ?string - { - return $this->name; - } - - /** - * @param string $name - */ - public function setName(string $name) - { - $this->name = $name; - } - - /** - * @return int|null - */ - public function getShopId(): ?int - { - return $this->shopId; - } - - /** - * @param int $shopId - */ - public function setShopId(int $shopId) - { - $this->shopId = $shopId; - } - - /** - * @return int|null - */ - public function getCurrencyId(): ?int - { - return $this->currencyId; - } - - /** - * @param int $currencyId - */ - public function setCurrencyId(int $currencyId) - { - $this->currencyId = $currencyId; - } - - /** - * @return int|null - */ - public function getCountryId(): ?int - { - return $this->countryId; - } - - /** - * @param int $countryId - */ - public function setCountryId(int $countryId) - { - $this->countryId = $countryId; - } - - /** - * @return int|null - */ - public function getGroupId(): ?int - { - return $this->groupId; - } - - /** - * @param int $groupId - */ - public function setGroupId(int $groupId) - { - $this->groupId = $groupId; - } - - /** - * @return int|null - */ - public function getFromQuantity(): ?int - { - return $this->fromQuantity; - } - - /** - * @param int $fromQuantity - */ - public function setFromQuantity(int $fromQuantity) - { - $this->fromQuantity = $fromQuantity; - } - - /** - * @return float|null - */ - public function getPrice(): ?float - { - return $this->price; - } - - /** - * @param float $price - */ - public function setPrice(float $price) - { - $this->price = $price; - } - - /** - * @return DateTime|null - */ - public function getDateTimeFrom(): ?DateTime - { - return $this->dateTimeFrom; - } - - /** - * @param string $dateTimeFrom - * - * @throws CatalogPriceRuleConstraintException - */ - public function setDateTimeFrom(string $dateTimeFrom) - { - $this->dateTimeFrom = $this->createDateTime($dateTimeFrom); - } - - /** - * @return DateTime|null - */ - public function getDateTimeTo(): ?DateTime - { - return $this->dateTimeTo; - } - - /** - * @param string $dateTimeTo - * - * @throws CatalogPriceRuleConstraintException - */ - public function setDateTimeTo(string $dateTimeTo) - { - $this->dateTimeTo = $this->createDateTime($dateTimeTo); - } - - /** - * @return bool|null - */ - public function isTaxIncluded(): ?bool - { - return $this->includeTax; - } - - /** - * @param bool $includeTax - */ - public function setIncludeTax(bool $includeTax) - { - $this->includeTax = $includeTax; - } - - /** - * @return Reduction|null - */ - public function getReduction(): ?Reduction - { - return $this->reduction; - } - - /** - * @param string $type - * @param float $value - */ - public function setReduction(string $type, float $value) - { - $this->reduction = new Reduction($type, $value); - } - - /** - * @param string $dateTime - * - * @return DateTime - */ - private function createDateTime(string $dateTime) - { - try { - return new DateTime($dateTime); - } catch (Exception $e) { - throw new CatalogPriceRuleConstraintException('Invalid date time format', CatalogPriceRuleConstraintException::INVALID_DATETIME, $e); - } - } -} diff --git a/src/Core/Domain/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandlerInterface.php b/src/Core/Domain/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandlerInterface.php deleted file mode 100644 index 59054bf2..00000000 --- a/src/Core/Domain/CatalogPriceRule/CommandHandler/AddCatalogPriceRuleHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\AddCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; - -/** - * Interface for handling addCatalogPriceRule command - */ -interface AddCatalogPriceRuleHandlerInterface -{ - /** - * @param AddCatalogPriceRuleCommand $command - * - * @return CatalogPriceRuleId - */ - public function handle(AddCatalogPriceRuleCommand $command): CatalogPriceRuleId; -} diff --git a/src/Core/Domain/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandlerInterface.php b/src/Core/Domain/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandlerInterface.php deleted file mode 100644 index f410403c..00000000 --- a/src/Core/Domain/CatalogPriceRule/CommandHandler/BulkDeleteCatalogPriceRuleHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\BulkDeleteCatalogPriceRuleCommand; - -/** - * Defines contract for BulkDeleteCatalogPriceRuleHandler - */ -interface BulkDeleteCatalogPriceRuleHandlerInterface -{ - /** - * @param BulkDeleteCatalogPriceRuleCommand $command - */ - public function handle(BulkDeleteCatalogPriceRuleCommand $command); -} diff --git a/src/Core/Domain/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandlerInterface.php b/src/Core/Domain/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandlerInterface.php deleted file mode 100644 index 5b7508ca..00000000 --- a/src/Core/Domain/CatalogPriceRule/CommandHandler/DeleteCatalogPriceRuleHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\DeleteCatalogPriceRuleCommand; - -/** - * Defines contract for delete catalog price rule handler - */ -interface DeleteCatalogPriceRuleHandlerInterface -{ - /** - * @param DeleteCatalogPriceRuleCommand $command - */ - public function handle(DeleteCatalogPriceRuleCommand $command); -} diff --git a/src/Core/Domain/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandlerInterface.php b/src/Core/Domain/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandlerInterface.php deleted file mode 100644 index be0dc602..00000000 --- a/src/Core/Domain/CatalogPriceRule/CommandHandler/EditCatalogPriceRuleHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\EditCatalogPriceRuleCommand; - -/** - * Defines contract for CatalogPriceRuleHandler - */ -interface EditCatalogPriceRuleHandlerInterface -{ - /** - * @param EditCatalogPriceRuleCommand $command - */ - public function handle(EditCatalogPriceRuleCommand $command); -} diff --git a/src/Core/Domain/CatalogPriceRule/Exception/CannotDeleteCatalogPriceRuleException.php b/src/Core/Domain/CatalogPriceRule/Exception/CannotDeleteCatalogPriceRuleException.php deleted file mode 100644 index 22d246b0..00000000 --- a/src/Core/Domain/CatalogPriceRule/Exception/CannotDeleteCatalogPriceRuleException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception; - -/** - * Is thrown when catalog price rule cannot be deleted - */ -class CannotDeleteCatalogPriceRuleException extends CatalogPriceRuleException -{ - /** - * When fails to delete single catalog price rule - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete catalog price rule in bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/CatalogPriceRule/Exception/CannotUpdateCatalogPriceRuleException.php b/src/Core/Domain/CatalogPriceRule/Exception/CannotUpdateCatalogPriceRuleException.php deleted file mode 100644 index 3362a1aa..00000000 --- a/src/Core/Domain/CatalogPriceRule/Exception/CannotUpdateCatalogPriceRuleException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception; - -/** - * Thrown when unable to update catalog price rule - */ -class CannotUpdateCatalogPriceRuleException extends CatalogPriceRuleException -{ -} diff --git a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleConstraintException.php b/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleConstraintException.php deleted file mode 100644 index aa707d1b..00000000 --- a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleConstraintException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception; - -/** - * Thrown when catalog price rule constraints are violated - */ -class CatalogPriceRuleConstraintException extends CatalogPriceRuleException -{ - /** - * When catalog price rule id is not valid - */ - const INVALID_ID = 10; - - /** - * When date-time format is invalid - */ - const INVALID_DATETIME = 20; - - /** - * When date range is not valid - */ - const INVALID_DATE_RANGE = 30; -} diff --git a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleException.php b/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleException.php deleted file mode 100644 index c02fca79..00000000 --- a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for CatalogPriceRule subdomain - */ -class CatalogPriceRuleException extends DomainException -{ -} diff --git a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleNotFoundException.php b/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleNotFoundException.php deleted file mode 100644 index 099dded7..00000000 --- a/src/Core/Domain/CatalogPriceRule/Exception/CatalogPriceRuleNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception; - -/** - * Thrown when cannot find required catalog price rule - */ -class CatalogPriceRuleNotFoundException extends CatalogPriceRuleException -{ -} diff --git a/src/Core/Domain/CatalogPriceRule/Query/GetCatalogPriceRuleForEditing.php b/src/Core/Domain/CatalogPriceRule/Query/GetCatalogPriceRuleForEditing.php deleted file mode 100644 index 21103773..00000000 --- a/src/Core/Domain/CatalogPriceRule/Query/GetCatalogPriceRuleForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; - -/** - * Provides data transfer object for editing CatalogPriceRule - */ -class GetCatalogPriceRuleForEditing -{ - /** - * @var CatalogPriceRuleId - */ - private $catalogPriceRuleId; - - /** - * @param int $catalogPriceRuleId - * - * @throws CatalogPriceRuleConstraintException - */ - public function __construct($catalogPriceRuleId) - { - $this->catalogPriceRuleId = new CatalogPriceRuleId($catalogPriceRuleId); - } - - /** - * @return CatalogPriceRuleId - */ - public function getCatalogPriceRuleId(): CatalogPriceRuleId - { - return $this->catalogPriceRuleId; - } -} diff --git a/src/Core/Domain/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandlerInterface.php b/src/Core/Domain/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandlerInterface.php deleted file mode 100644 index 02faea0e..00000000 --- a/src/Core/Domain/CatalogPriceRule/QueryHandler/GetCatalogPriceRuleForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query\GetCatalogPriceRuleForEditing; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryResult\EditableCatalogPriceRule; - -/** - * Defines contract for GetCatalogPriceRuleForEditingHandler - */ -interface GetCatalogPriceRuleForEditingHandlerInterface -{ - /** - * @param GetCatalogPriceRuleForEditing $query - * - * @return EditableCatalogPriceRule - */ - public function handle(GetCatalogPriceRuleForEditing $query); -} diff --git a/src/Core/Domain/CatalogPriceRule/QueryResult/EditableCatalogPriceRule.php b/src/Core/Domain/CatalogPriceRule/QueryResult/EditableCatalogPriceRule.php deleted file mode 100644 index 255870e2..00000000 --- a/src/Core/Domain/CatalogPriceRule/QueryResult/EditableCatalogPriceRule.php +++ /dev/null @@ -1,236 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryResult; - -use DateTime; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; - -/** - * Provides data for editing CatalogPriceRule - */ -class EditableCatalogPriceRule -{ - /** - * @var CatalogPriceRuleId - */ - private $catalogPriceRuleId; - - /** - * @var string - */ - private $name; - - /** - * @var int - */ - private $shopId; - - /** - * @var int - */ - private $currencyId; - - /** - * @var int - */ - private $countryId; - - /** - * @var int - */ - private $groupId; - - /** - * @var int - */ - private $fromQuantity; - - /** - * @var Number - */ - private $price; - - /** - * @var ?DateTime - */ - private $from; - - /** - * @var ?DateTime - */ - private $to; - - /** - * @var bool - */ - private $includeTax; - - /** - * @var Reduction - */ - private $reduction; - - /** - * @param CatalogPriceRuleId $catalogPriceRuleId - * @param string $name - * @param int $shopId - * @param int $currencyId - * @param int $countryId - * @param int $groupId - * @param int $fromQuantity - * @param Number $price - * @param Reduction $reduction - * @param bool $includeTax - * @param DateTime|null $from - * @param DateTime|null $to - */ - public function __construct( - CatalogPriceRuleId $catalogPriceRuleId, - string $name, - int $shopId, - int $currencyId, - int $countryId, - int $groupId, - int $fromQuantity, - Number $price, - Reduction $reduction, - bool $includeTax, - ?DateTime $from, - ?DateTime $to - ) { - $this->catalogPriceRuleId = $catalogPriceRuleId; - $this->name = $name; - $this->shopId = $shopId; - $this->currencyId = $currencyId; - $this->countryId = $countryId; - $this->groupId = $groupId; - $this->fromQuantity = $fromQuantity; - $this->price = $price; - $this->from = $from; - $this->to = $to; - $this->reduction = $reduction; - $this->includeTax = $includeTax; - } - - /** - * @return CatalogPriceRuleId - */ - public function getCatalogPriceRuleId(): CatalogPriceRuleId - { - return $this->catalogPriceRuleId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return int - */ - public function getShopId(): int - { - return $this->shopId; - } - - /** - * @return int - */ - public function getCurrencyId(): int - { - return $this->currencyId; - } - - /** - * @return int - */ - public function getCountryId(): int - { - return $this->countryId; - } - - /** - * @return int - */ - public function getGroupId(): int - { - return $this->groupId; - } - - /** - * @return int - */ - public function getFromQuantity(): int - { - return $this->fromQuantity; - } - - /** - * @return Number - */ - public function getPrice(): Number - { - return $this->price; - } - - /** - * @return DateTime|null - */ - public function getFrom(): ?DateTime - { - return $this->from; - } - - /** - * @return DateTime|null - */ - public function getTo(): ?DateTime - { - return $this->to; - } - - /** - * @return Reduction - */ - public function getReduction(): Reduction - { - return $this->reduction; - } - - /** - * @return bool - */ - public function isTaxIncluded(): bool - { - return $this->includeTax; - } -} diff --git a/src/Core/Domain/CatalogPriceRule/ValueObject/CatalogPriceRuleId.php b/src/Core/Domain/CatalogPriceRule/ValueObject/CatalogPriceRuleId.php deleted file mode 100644 index f5fe7c12..00000000 --- a/src/Core/Domain/CatalogPriceRule/ValueObject/CatalogPriceRuleId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleConstraintException; - -/** - * Provides catalog price rule id - */ -final class CatalogPriceRuleId -{ - /** - * @var int - */ - private $catalogPriceRuleId; - - /** - * @param int $catalogPriceRuleId - * - * @throws CatalogPriceRuleConstraintException - */ - public function __construct(int $catalogPriceRuleId) - { - $this->assertIsGreaterThanZero($catalogPriceRuleId); - $this->catalogPriceRuleId = $catalogPriceRuleId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->catalogPriceRuleId; - } - - /** - * Validates that the value is greater than zero - * - * @param int $value - * - * @throws CatalogPriceRuleConstraintException - */ - private function assertIsGreaterThanZero(int $value) - { - if (0 >= $value) { - throw new CatalogPriceRuleConstraintException(sprintf('Invalid catalog price rule id "%s".', $value), CatalogPriceRuleConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Category/Command/AddCategoryCommand.php b/src/Core/Domain/Category/Command/AddCategoryCommand.php deleted file mode 100644 index 50a93af5..00000000 --- a/src/Core/Domain/Category/Command/AddCategoryCommand.php +++ /dev/null @@ -1,326 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; - -/** - * Class AddCategoryCommand adds new category. - */ -class AddCategoryCommand -{ - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var int - */ - private $parentCategoryId; - - /** - * @var string[] - */ - private $localizedLinkRewrites; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var bool - */ - private $isActive; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var int[] - */ - private $associatedGroupIds; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param string[] $localizedNames - * @param string[] $localizedLinkRewrites - * @param bool $isActive - * @param int $parentCategoryId - * - * @throws CategoryConstraintException - */ - public function __construct(array $localizedNames, array $localizedLinkRewrites, $isActive, $parentCategoryId) - { - $this - ->setLocalizedNames($localizedNames) - ->setLocalizedLinkRewrites($localizedLinkRewrites) - ->setIsActive($isActive) - ->setParentCategoryId($parentCategoryId); - } - - /** - * @return int - */ - public function getParentCategoryId() - { - return $this->parentCategoryId; - } - - /** - * @param int $parentCategoryId - * - * @return self - * - * @throws CategoryConstraintException - */ - public function setParentCategoryId($parentCategoryId) - { - if (!is_int($parentCategoryId) || 0 >= $parentCategoryId) { - throw new CategoryConstraintException(sprintf('Invalid Category parent id %s supplied', var_export($parentCategoryId, true)), CategoryConstraintException::INVALID_PARENT_ID); - } - - $this->parentCategoryId = $parentCategoryId; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedNames(array $localizedNames) - { - if (empty($localizedNames)) { - throw new CategoryConstraintException('Category name cannot be empty', CategoryConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedLinkRewrites() - { - return $this->localizedLinkRewrites; - } - - /** - * @param string[] $localizedLinkRewrites - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedLinkRewrites(array $localizedLinkRewrites) - { - if (empty($localizedLinkRewrites)) { - throw new CategoryConstraintException('Category link rewrite cannot be empty', CategoryConstraintException::EMPTY_LINK_REWRITE); - } - - $this->localizedLinkRewrites = $localizedLinkRewrites; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @param string[] $localizedDescriptions - * - * @return $this - */ - public function setLocalizedDescriptions(array $localizedDescriptions) - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setIsActive($isActive) - { - if (!is_bool($isActive)) { - throw new CategoryConstraintException('Invalid Category status supplied', CategoryConstraintException::INVALID_STATUS); - } - - $this->isActive = $isActive; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @param string[] $localizedMetaTitles - * - * @return $this - */ - public function setLocalizedMetaTitles(array $localizedMetaTitles) - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[] $localizedMetaDescriptions - * - * @return $this - */ - public function setLocalizedMetaDescriptions(array $localizedMetaDescriptions) - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[] $localizedMetaKeywords - * - * @return $this - */ - public function setLocalizedMetaKeywords(array $localizedMetaKeywords) - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedGroupIds() - { - return $this->associatedGroupIds; - } - - /** - * @param int[] $associatedGroupIds - * - * @return $this - */ - public function setAssociatedGroupIds(array $associatedGroupIds) - { - $this->associatedGroupIds = $associatedGroupIds; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } - - /** - * @param int[] $associatedShopIds - * - * @return $this - */ - public function setAssociatedShopIds(array $associatedShopIds) - { - $this->associatedShopIds = $associatedShopIds; - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/AddRootCategoryCommand.php b/src/Core/Domain/Category/Command/AddRootCategoryCommand.php deleted file mode 100644 index 49bb12e2..00000000 --- a/src/Core/Domain/Category/Command/AddRootCategoryCommand.php +++ /dev/null @@ -1,293 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; - -/** - * Class AddRootCategoryCommand adds new root category. - */ -class AddRootCategoryCommand -{ - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var string[] - */ - private $localizedLinkRewrites; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var bool - */ - private $isActive; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var int[] - */ - private $associatedGroupIds; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param string[] $name - * @param string[] $linkRewrite - * @param bool $isActive - * - * @throws CategoryConstraintException - */ - public function __construct(array $name, array $linkRewrite, $isActive) - { - $this - ->setLocalizedNames($name) - ->setLocalizedLinkRewrites($linkRewrite) - ->setIsActive($isActive); - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedNames(array $localizedNames) - { - if (empty($localizedNames)) { - throw new CategoryConstraintException('Category name cannot be empty', CategoryConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedLinkRewrites() - { - return $this->localizedLinkRewrites; - } - - /** - * @param string[] $localizedLinkRewrites - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedLinkRewrites(array $localizedLinkRewrites) - { - if (empty($localizedLinkRewrites)) { - throw new CategoryConstraintException('Category link rewrite cannot be empty', CategoryConstraintException::EMPTY_LINK_REWRITE); - } - - $this->localizedLinkRewrites = $localizedLinkRewrites; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @param string[] $localizedDescriptions - * - * @return $this - */ - public function setLocalizedDescriptions(array $localizedDescriptions) - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setIsActive($isActive) - { - if (!is_bool($isActive)) { - throw new CategoryConstraintException('Invalid Category status supplied', CategoryConstraintException::INVALID_STATUS); - } - - $this->isActive = $isActive; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @param string[] $localizedMetaTitles - * - * @return $this - */ - public function setLocalizedMetaTitles(array $localizedMetaTitles) - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[] $localizedMetaDescriptions - * - * @return $this - */ - public function setLocalizedMetaDescriptions(array $localizedMetaDescriptions) - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[] $localizedMetaKeywords - * - * @return $this - */ - public function setLocalizedMetaKeywords(array $localizedMetaKeywords) - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedGroupIds() - { - return $this->associatedGroupIds; - } - - /** - * @param int[] $associatedGroupIds - * - * @return $this - */ - public function setAssociatedGroupIds(array $associatedGroupIds) - { - $this->associatedGroupIds = $associatedGroupIds; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } - - /** - * @param int[] $associatedShopIds - * - * @return $this - */ - public function setAssociatedShopIds(array $associatedShopIds) - { - $this->associatedShopIds = $associatedShopIds; - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/BulkDeleteCategoriesCommand.php b/src/Core/Domain/Category/Command/BulkDeleteCategoriesCommand.php deleted file mode 100644 index 6ab7b2a7..00000000 --- a/src/Core/Domain/Category/Command/BulkDeleteCategoriesCommand.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryDeleteMode; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class BulkDeleteCategoriesCommand. - */ -class BulkDeleteCategoriesCommand -{ - /** - * @var CategoryId[] - */ - private $categoryIds; - - /** - * @var CategoryDeleteMode - */ - private $deleteMode; - - /** - * @param int[] $categoryIds - * @param string $deleteMode - * - * @throws CategoryConstraintException - * @throws CategoryException - */ - public function __construct(array $categoryIds, $deleteMode) - { - $this - ->setCategoryIds($categoryIds) - ->setDeleteMode($deleteMode) - ; - } - - /** - * @return CategoryId[] - */ - public function getCategoryIds() - { - return $this->categoryIds; - } - - /** - * @return CategoryDeleteMode - */ - public function getDeleteMode() - { - return $this->deleteMode; - } - - /** - * @param string $mode - * - * @return self - */ - private function setDeleteMode($mode) - { - $this->deleteMode = new CategoryDeleteMode($mode); - - return $this; - } - - /** - * @param int[] $categoryIds - * - * @throws CategoryConstraintException - * @throws CategoryException - * - * @return self - */ - private function setCategoryIds(array $categoryIds) - { - if (empty($categoryIds)) { - throw new CategoryConstraintException('Missing Category data for bulk deleting', CategoryConstraintException::EMPTY_BULK_DELETE_DATA); - } - - foreach ($categoryIds as $categoryId) { - $this->categoryIds[] = new CategoryId((int) $categoryId); - } - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/BulkDisableCategoriesCommand.php b/src/Core/Domain/Category/Command/BulkDisableCategoriesCommand.php deleted file mode 100644 index 3b093b81..00000000 --- a/src/Core/Domain/Category/Command/BulkDisableCategoriesCommand.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; - -/** - * Class DisableCategoriesCommand disables provided categories. - */ -class BulkDisableCategoriesCommand extends BulkUpdateCategoriesStatusCommand -{ - /** - * @param int[] $categoryIds - * - * @throws CategoryConstraintException - */ - public function __construct(array $categoryIds) - { - parent::__construct($categoryIds, false); - } -} diff --git a/src/Core/Domain/Category/Command/BulkEnableCategoriesCommand.php b/src/Core/Domain/Category/Command/BulkEnableCategoriesCommand.php deleted file mode 100644 index 67b307f8..00000000 --- a/src/Core/Domain/Category/Command/BulkEnableCategoriesCommand.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; - -/** - * Enables given categories - */ -class BulkEnableCategoriesCommand extends BulkUpdateCategoriesStatusCommand -{ - /** - * @param int[] $categoryIds - * - * @throws CategoryConstraintException - * @throws CategoryException - */ - public function __construct(array $categoryIds) - { - parent::__construct($categoryIds, true); - } -} diff --git a/src/Core/Domain/Category/Command/BulkUpdateCategoriesStatusCommand.php b/src/Core/Domain/Category/Command/BulkUpdateCategoriesStatusCommand.php deleted file mode 100644 index be7343a1..00000000 --- a/src/Core/Domain/Category/Command/BulkUpdateCategoriesStatusCommand.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Updates provided categories to new status - */ -class BulkUpdateCategoriesStatusCommand -{ - /** - * @var CategoryId[] - */ - private $categoryIds; - - /** - * @var bool - */ - private $newStatus; - - /** - * @param int[] $categoryIds - * @param bool $newStatus - * - * @throws CategoryConstraintException - * @throws CategoryException - */ - public function __construct(array $categoryIds, $newStatus) - { - $this - ->setCategoryIds($categoryIds) - ->setNewStatus($newStatus) - ; - } - - /** - * @return CategoryId[] - */ - public function getCategoryIds() - { - return $this->categoryIds; - } - - /** - * @return bool - */ - public function getNewStatus() - { - return $this->newStatus; - } - - /** - * @param int[] $categoryIds - * - * @return self - * - * @throws CategoryConstraintException - * @throws CategoryException - */ - private function setCategoryIds(array $categoryIds) - { - if (empty($categoryIds)) { - throw new CategoryConstraintException('Missing categories data for status change'); - } - - foreach ($categoryIds as $categoryId) { - $this->categoryIds[] = new CategoryId((int) $categoryId); - } - - return $this; - } - - /** - * @param bool $newStatus - * - * @return self - */ - private function setNewStatus($newStatus) - { - if (!is_bool($newStatus)) { - throw new CategoryConstraintException(sprintf('Category status %s is invalid. Status must be of type "bool".', var_export($newStatus, true)), CategoryConstraintException::INVALID_STATUS); - } - - $this->newStatus = $newStatus; - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/DeleteCategoryCommand.php b/src/Core/Domain/Category/Command/DeleteCategoryCommand.php deleted file mode 100644 index 81b4403a..00000000 --- a/src/Core/Domain/Category/Command/DeleteCategoryCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryDeleteMode; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class DeleteCategoryCommand deletes provided category. - */ -class DeleteCategoryCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var CategoryDeleteMode - */ - private $deleteMode; - - /** - * @param int $categoryId - * @param string $mode - */ - public function __construct($categoryId, $mode) - { - $this->categoryId = new CategoryId($categoryId); - $this->deleteMode = new CategoryDeleteMode($mode); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return CategoryDeleteMode - */ - public function getDeleteMode() - { - return $this->deleteMode; - } -} diff --git a/src/Core/Domain/Category/Command/DeleteCategoryCoverImageCommand.php b/src/Core/Domain/Category/Command/DeleteCategoryCoverImageCommand.php deleted file mode 100644 index 3d98592c..00000000 --- a/src/Core/Domain/Category/Command/DeleteCategoryCoverImageCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Deletes cover image for given category. - */ -class DeleteCategoryCoverImageCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->categoryId = new CategoryId($categoryId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } -} diff --git a/src/Core/Domain/Category/Command/DeleteCategoryMenuThumbnailImageCommand.php b/src/Core/Domain/Category/Command/DeleteCategoryMenuThumbnailImageCommand.php deleted file mode 100644 index 4e495e9f..00000000 --- a/src/Core/Domain/Category/Command/DeleteCategoryMenuThumbnailImageCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\MenuThumbnailId; - -/** - * Deletes given menu thumbnail for category. - */ -class DeleteCategoryMenuThumbnailImageCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var MenuThumbnailId - */ - private $menuThumbnailId; - - /** - * @param int $categoryId - * @param int $menuThumbnailId - */ - public function __construct($categoryId, $menuThumbnailId) - { - $this->categoryId = new CategoryId($categoryId); - $this->menuThumbnailId = new MenuThumbnailId($menuThumbnailId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return MenuThumbnailId - */ - public function getMenuThumbnailId() - { - return $this->menuThumbnailId; - } -} diff --git a/src/Core/Domain/Category/Command/EditCategoryCommand.php b/src/Core/Domain/Category/Command/EditCategoryCommand.php deleted file mode 100644 index b18fd31e..00000000 --- a/src/Core/Domain/Category/Command/EditCategoryCommand.php +++ /dev/null @@ -1,335 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class EditCategoryCommand edits given category. - */ -class EditCategoryCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var int - */ - private $parentCategoryId; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var string[] - */ - private $localizedLinkRewrites; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var bool - */ - private $isActive; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var int[] - */ - private $associatedGroupIds; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->categoryId = new CategoryId($categoryId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return int - */ - public function getParentCategoryId() - { - return $this->parentCategoryId; - } - - /** - * @param int $parentCategoryId - * - * @return self - * - * @throws CategoryConstraintException - */ - public function setParentCategoryId($parentCategoryId) - { - if (!is_numeric($parentCategoryId) || 0 >= $parentCategoryId) { - throw new CategoryConstraintException(sprintf('Invalid Category parent id %s supplied', var_export($parentCategoryId, true)), CategoryConstraintException::INVALID_PARENT_ID); - } - - if ($this->categoryId->isEqual(new CategoryId((int) $parentCategoryId))) { - throw new CategoryConstraintException('Category cannot be parent of itself.'); - } - - $this->parentCategoryId = $parentCategoryId; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedNames(array $localizedNames) - { - if (empty($localizedNames)) { - throw new CategoryConstraintException('Category name cannot be empty', CategoryConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedLinkRewrites() - { - return $this->localizedLinkRewrites; - } - - /** - * @param string[] $localizedLinkRewrites - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedLinkRewrites(array $localizedLinkRewrites) - { - if (empty($localizedLinkRewrites)) { - throw new CategoryConstraintException('Category link rewrite cannot be empty', CategoryConstraintException::EMPTY_LINK_REWRITE); - } - - $this->localizedLinkRewrites = $localizedLinkRewrites; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @param string[] $localizedDescriptions - * - * @return $this - */ - public function setLocalizedDescriptions(array $localizedDescriptions) - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setIsActive($isActive) - { - if (!is_bool($isActive)) { - throw new CategoryConstraintException('Invalid Category status supplied', CategoryConstraintException::INVALID_STATUS); - } - - $this->isActive = $isActive; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @param string[] $localizedMetaTitles - * - * @return $this - */ - public function setLocalizedMetaTitles(array $localizedMetaTitles) - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[] $localizedMetaDescriptions - * - * @return $this - */ - public function setLocalizedMetaDescriptions(array $localizedMetaDescriptions) - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[] $localizedMetaKeywords - * - * @return $this - */ - public function setLocalizedMetaKeywords(array $localizedMetaKeywords) - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedGroupIds() - { - return $this->associatedGroupIds; - } - - /** - * @param int[] $associatedGroupIds - * - * @return $this - */ - public function setAssociatedGroupIds(array $associatedGroupIds) - { - $this->associatedGroupIds = $associatedGroupIds; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } - - /** - * @param int[] $associatedShopIds - * - * @return $this - */ - public function setAssociatedShopIds(array $associatedShopIds) - { - $this->associatedShopIds = $associatedShopIds; - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/EditRootCategoryCommand.php b/src/Core/Domain/Category/Command/EditRootCategoryCommand.php deleted file mode 100644 index 5d297441..00000000 --- a/src/Core/Domain/Category/Command/EditRootCategoryCommand.php +++ /dev/null @@ -1,300 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class EditRootCategoryCommand edits given root category. - */ -class EditRootCategoryCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var string[] - */ - private $localizedLinkRewrites; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var bool - */ - private $isActive; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var int[] - */ - private $associatedGroupIds; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->categoryId = new CategoryId($categoryId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedNames(array $localizedNames) - { - if (empty($localizedNames)) { - throw new CategoryConstraintException('Category name cannot be empty', CategoryConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedLinkRewrites() - { - return $this->localizedLinkRewrites; - } - - /** - * @param string[] $localizedLinkRewrites - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setLocalizedLinkRewrites(array $localizedLinkRewrites) - { - if (empty($localizedLinkRewrites)) { - throw new CategoryConstraintException('Category link rewrite cannot be empty', CategoryConstraintException::EMPTY_LINK_REWRITE); - } - - $this->localizedLinkRewrites = $localizedLinkRewrites; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @param string[] $localizedDescriptions - * - * @return $this - */ - public function setLocalizedDescriptions(array $localizedDescriptions) - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - * - * @return $this - * - * @throws CategoryConstraintException - */ - public function setIsActive($isActive) - { - if (!is_bool($isActive)) { - throw new CategoryConstraintException('Invalid Category status supplied', CategoryConstraintException::INVALID_STATUS); - } - - $this->isActive = $isActive; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @param string[] $localizedMetaTitles - * - * @return $this - */ - public function setLocalizedMetaTitles(array $localizedMetaTitles) - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[] $localizedMetaDescriptions - * - * @return $this - */ - public function setLocalizedMetaDescriptions(array $localizedMetaDescriptions) - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[] $localizedMetaKeywords - * - * @return $this - */ - public function setLocalizedMetaKeywords(array $localizedMetaKeywords) - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedGroupIds() - { - return $this->associatedGroupIds; - } - - /** - * @param int[] $associatedGroupIds - * - * @return $this - */ - public function setAssociatedGroupIds(array $associatedGroupIds) - { - $this->associatedGroupIds = $associatedGroupIds; - - return $this; - } - - /** - * @return int[] - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } - - /** - * @param int[] $associatedShopIds - * - * @return $this - */ - public function setAssociatedShopIds(array $associatedShopIds) - { - $this->associatedShopIds = $associatedShopIds; - - return $this; - } -} diff --git a/src/Core/Domain/Category/Command/SetCategoryIsEnabledCommand.php b/src/Core/Domain/Category/Command/SetCategoryIsEnabledCommand.php deleted file mode 100644 index a77376cb..00000000 --- a/src/Core/Domain/Category/Command/SetCategoryIsEnabledCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class ToggleCategoryStatusCommand toggles given category status. - */ -class SetCategoryIsEnabledCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var bool - */ - private $isEnabled; - - /** - * @param int $categoryId - * @param bool $isEnabled - */ - public function __construct($categoryId, $isEnabled) - { - $this->categoryId = new CategoryId($categoryId); - $this->isEnabled = $isEnabled; - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } -} diff --git a/src/Core/Domain/Category/Command/UpdateCategoryPositionCommand.php b/src/Core/Domain/Category/Command/UpdateCategoryPositionCommand.php deleted file mode 100644 index aef332cb..00000000 --- a/src/Core/Domain/Category/Command/UpdateCategoryPositionCommand.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Updates category position - */ -class UpdateCategoryPositionCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var CategoryId - */ - private $parentCategoryId; - - /** - * @var int - */ - private $way; - - /** - * @var array - */ - private $positions; - - /** - * @var bool - */ - private $foundFirst; - - /** - * @param int $categoryId - * @param int $parentCategoryId - * @param int $way - * @param array $positions - * @param bool $foundFirst - */ - public function __construct($categoryId, $parentCategoryId, $way, array $positions, $foundFirst) - { - $this->categoryId = new CategoryId($categoryId); - $this->parentCategoryId = new CategoryId($parentCategoryId); - $this->way = $way; - $this->positions = $positions; - $this->foundFirst = $foundFirst; - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } - - /** - * @return CategoryId - */ - public function getParentCategoryId() - { - return $this->parentCategoryId; - } - - /** - * @return int - */ - public function getWay() - { - return $this->way; - } - - /** - * @return array - */ - public function getPositions() - { - return $this->positions; - } - - /** - * @return bool - */ - public function isFoundFirst() - { - return $this->foundFirst; - } -} diff --git a/src/Core/Domain/Category/CommandHandler/AddCategoryHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/AddCategoryHandlerInterface.php deleted file mode 100644 index 29945f17..00000000 --- a/src/Core/Domain/Category/CommandHandler/AddCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand; - -/** - * Interface AddCategoryHandlerInterface. - */ -interface AddCategoryHandlerInterface -{ - /** - * @param AddCategoryCommand $command - */ - public function handle(AddCategoryCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/AddRootCategoryHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/AddRootCategoryHandlerInterface.php deleted file mode 100644 index 198e178a..00000000 --- a/src/Core/Domain/Category/CommandHandler/AddRootCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddRootCategoryCommand; - -/** - * Interface AddRootCategoryHandler. - */ -interface AddRootCategoryHandlerInterface -{ - /** - * @param AddRootCategoryCommand $command - */ - public function handle(AddRootCategoryCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/BulkDeleteCategoriesHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/BulkDeleteCategoriesHandlerInterface.php deleted file mode 100644 index 2dafc03f..00000000 --- a/src/Core/Domain/Category/CommandHandler/BulkDeleteCategoriesHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDeleteCategoriesCommand; - -/** - * Interface BulkDeleteCategoriesHandlerInterface. - */ -interface BulkDeleteCategoriesHandlerInterface -{ - /** - * @param BulkDeleteCategoriesCommand $command - */ - public function handle(BulkDeleteCategoriesCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/BulkUpdateCategoriesStatusHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/BulkUpdateCategoriesStatusHandlerInterface.php deleted file mode 100644 index bf2e78d2..00000000 --- a/src/Core/Domain/Category/CommandHandler/BulkUpdateCategoriesStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkUpdateCategoriesStatusCommand; - -/** - * Interface UpdateCategoriesStatusHandlerInterface. - */ -interface BulkUpdateCategoriesStatusHandlerInterface -{ - /** - * @param BulkUpdateCategoriesStatusCommand $command - */ - public function handle(BulkUpdateCategoriesStatusCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/DeleteCategoryCoverImageHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/DeleteCategoryCoverImageHandlerInterface.php deleted file mode 100644 index eaefef74..00000000 --- a/src/Core/Domain/Category/CommandHandler/DeleteCategoryCoverImageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCoverImageCommand; - -/** - * Defines contract for service which handles cover image delete command. - */ -interface DeleteCategoryCoverImageHandlerInterface -{ - /** - * @param DeleteCategoryCoverImageCommand $command - */ - public function handle(DeleteCategoryCoverImageCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/DeleteCategoryHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/DeleteCategoryHandlerInterface.php deleted file mode 100644 index d90a628f..00000000 --- a/src/Core/Domain/Category/CommandHandler/DeleteCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCommand; - -/** - * Interface DeleteCategoryHandlerInterface. - */ -interface DeleteCategoryHandlerInterface -{ - /** - * @param DeleteCategoryCommand $command - */ - public function handle(DeleteCategoryCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandlerInterface.php deleted file mode 100644 index 6883ef90..00000000 --- a/src/Core/Domain/Category/CommandHandler/DeleteCategoryMenuThumbnailImageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryMenuThumbnailImageCommand; - -/** - * Defines contract for service that handles category menu thumbnail deleting command. - */ -interface DeleteCategoryMenuThumbnailImageHandlerInterface -{ - /** - * @param DeleteCategoryMenuThumbnailImageCommand $command - */ - public function handle(DeleteCategoryMenuThumbnailImageCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/EditCategoryHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/EditCategoryHandlerInterface.php deleted file mode 100644 index b3e836d7..00000000 --- a/src/Core/Domain/Category/CommandHandler/EditCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditCategoryCommand; - -/** - * Interface EditCategoryHandlerInterface. - */ -interface EditCategoryHandlerInterface -{ - /** - * @param EditCategoryCommand $command - */ - public function handle(EditCategoryCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/EditRootCategoryHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/EditRootCategoryHandlerInterface.php deleted file mode 100644 index 02fa2ebc..00000000 --- a/src/Core/Domain/Category/CommandHandler/EditRootCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditRootCategoryCommand; - -/** - * Interface EditRootCategoryHandlerInterface. - */ -interface EditRootCategoryHandlerInterface -{ - /** - * @param EditRootCategoryCommand $command - */ - public function handle(EditRootCategoryCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/SetCategoryIsEnabledHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/SetCategoryIsEnabledHandlerInterface.php deleted file mode 100644 index e949b337..00000000 --- a/src/Core/Domain/Category/CommandHandler/SetCategoryIsEnabledHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\SetCategoryIsEnabledCommand; - -/** - * Interface for service that set category to be enabled or disabled. - */ -interface SetCategoryIsEnabledHandlerInterface -{ - /** - * @param SetCategoryIsEnabledCommand $command - */ - public function handle(SetCategoryIsEnabledCommand $command); -} diff --git a/src/Core/Domain/Category/CommandHandler/UpdateCategoryPositionHandlerInterface.php b/src/Core/Domain/Category/CommandHandler/UpdateCategoryPositionHandlerInterface.php deleted file mode 100644 index fba00be3..00000000 --- a/src/Core/Domain/Category/CommandHandler/UpdateCategoryPositionHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\UpdateCategoryPositionCommand; - -/** - * Interface for service that updates category position - */ -interface UpdateCategoryPositionHandlerInterface -{ - /** - * @param UpdateCategoryPositionCommand $command - */ - public function handle(UpdateCategoryPositionCommand $command); -} diff --git a/src/Core/Domain/Category/Exception/CannotAddCategoryException.php b/src/Core/Domain/Category/Exception/CannotAddCategoryException.php deleted file mode 100644 index 8a575df4..00000000 --- a/src/Core/Domain/Category/Exception/CannotAddCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Class CannotAddCategoryException is throw when adding category fails. - */ -class CannotAddCategoryException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Exception/CannotDeleteImageException.php b/src/Core/Domain/Category/Exception/CannotDeleteImageException.php deleted file mode 100644 index ae1ef720..00000000 --- a/src/Core/Domain/Category/Exception/CannotDeleteImageException.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Thrown when category image was attempted to delete but failed. - */ -class CannotDeleteImageException extends CategoryException -{ - /** - * Error codes to specify which type of image were not deleted. - */ - const COVER_IMAGE = 1; - const THUMBNAIL_IMAGE = 2; - const MENU_THUMBNAIL_IMAGE = 3; -} diff --git a/src/Core/Domain/Category/Exception/CannotDeleteRootCategoryForShopException.php b/src/Core/Domain/Category/Exception/CannotDeleteRootCategoryForShopException.php deleted file mode 100644 index 91026a95..00000000 --- a/src/Core/Domain/Category/Exception/CannotDeleteRootCategoryForShopException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Is thrown when trying to delete a root category for current shop context - */ -class CannotDeleteRootCategoryForShopException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Exception/CannotEditCategoryException.php b/src/Core/Domain/Category/Exception/CannotEditCategoryException.php deleted file mode 100644 index 6fe79130..00000000 --- a/src/Core/Domain/Category/Exception/CannotEditCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Class CannotEditCategoryException is thrown when editing category fails. - */ -class CannotEditCategoryException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Exception/CannotUpdateCategoryStatusException.php b/src/Core/Domain/Category/Exception/CannotUpdateCategoryStatusException.php deleted file mode 100644 index 796c69a0..00000000 --- a/src/Core/Domain/Category/Exception/CannotUpdateCategoryStatusException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Class CannotUpdateCategoryStatusException is thrown when Category status update failed. - */ -class CannotUpdateCategoryStatusException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Exception/CategoryConstraintException.php b/src/Core/Domain/Category/Exception/CategoryConstraintException.php deleted file mode 100644 index 60ba4c3a..00000000 --- a/src/Core/Domain/Category/Exception/CategoryConstraintException.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Class CategoryConstraintException. - */ -class CategoryConstraintException extends CategoryException -{ - /** - * Code is used when category does not have name. - */ - const EMPTY_NAME = 1; - - /** - * Code is used when category does not have link rewrite. - */ - const EMPTY_LINK_REWRITE = 2; - - /** - * Code is used when invalid status is set to category. - */ - const INVALID_STATUS = 4; - - /** - * Code is used when invalid delete mode is used to delete a category. - */ - const INVALID_DELETE_MODE = 5; - - /** - * Code is used when invalid parent id is supplied. - */ - const INVALID_PARENT_ID = 6; - - /** - * Code is used when too many menu thumbnails is being set for category. - */ - const TOO_MANY_MENU_THUMBNAILS = 8; - - /** - * Code is used when invalid id is supplied. - */ - const INVALID_ID = 10; - - /** - * Code is used when performing bulk delete of categories with empty data. - */ - const EMPTY_BULK_DELETE_DATA = 12; -} diff --git a/src/Core/Domain/Category/Exception/CategoryException.php b/src/Core/Domain/Category/Exception/CategoryException.php deleted file mode 100644 index 89ee3338..00000000 --- a/src/Core/Domain/Category/Exception/CategoryException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class CategoryException is base exception for Category bounded context. - */ -class CategoryException extends DomainException -{ -} diff --git a/src/Core/Domain/Category/Exception/CategoryNotFoundException.php b/src/Core/Domain/Category/Exception/CategoryNotFoundException.php deleted file mode 100644 index 2852fe1a..00000000 --- a/src/Core/Domain/Category/Exception/CategoryNotFoundException.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class CategoryNotFoundException. - */ -class CategoryNotFoundException extends CategoryException -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @param CategoryId $categoryId - * @param string $message - * @param int $code - * @param Exception $previous - */ - public function __construct(CategoryId $categoryId, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->categoryId = $categoryId; - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } -} diff --git a/src/Core/Domain/Category/Exception/FailedToDeleteCategoryException.php b/src/Core/Domain/Category/Exception/FailedToDeleteCategoryException.php deleted file mode 100644 index d7cbf6dc..00000000 --- a/src/Core/Domain/Category/Exception/FailedToDeleteCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Is thrown when unable to delete category - */ -class FailedToDeleteCategoryException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Exception/MenuThumbnailsLimitException.php b/src/Core/Domain/Category/Exception/MenuThumbnailsLimitException.php deleted file mode 100644 index 746b18e3..00000000 --- a/src/Core/Domain/Category/Exception/MenuThumbnailsLimitException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Exception; - -/** - * Class MenuThumbnailsLimitException is thrown when maximum number of thumbnail images is reached. - */ -class MenuThumbnailsLimitException extends CategoryException -{ -} diff --git a/src/Core/Domain/Category/Query/GetCategoryForEditing.php b/src/Core/Domain/Category/Query/GetCategoryForEditing.php deleted file mode 100644 index 22b119ae..00000000 --- a/src/Core/Domain/Category/Query/GetCategoryForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Query; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Class GetCategoryForEditing retrieves category data for editing. - */ -class GetCategoryForEditing -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->categoryId = new CategoryId($categoryId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } -} diff --git a/src/Core/Domain/Category/Query/GetCategoryIsEnabled.php b/src/Core/Domain/Category/Query/GetCategoryIsEnabled.php deleted file mode 100644 index 750a6f69..00000000 --- a/src/Core/Domain/Category/Query/GetCategoryIsEnabled.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\Query; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; - -/** - * Get current status (enabled/disabled) for given category. - */ -class GetCategoryIsEnabled -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->categoryId = new CategoryId($categoryId); - } - - /** - * @return CategoryId - */ - public function getCategoryId() - { - return $this->categoryId; - } -} diff --git a/src/Core/Domain/Category/QueryHandler/GetCategoryForEditingHandlerInterface.php b/src/Core/Domain/Category/QueryHandler/GetCategoryForEditingHandlerInterface.php deleted file mode 100644 index e513e054..00000000 --- a/src/Core/Domain/Category/QueryHandler/GetCategoryForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryResult\EditableCategory; - -/** - * Interface GetCategoryForEditingHandlerInterface. - */ -interface GetCategoryForEditingHandlerInterface -{ - /** - * @param GetCategoryForEditing $query - * - * @return EditableCategory - */ - public function handle(GetCategoryForEditing $query); -} diff --git a/src/Core/Domain/Category/QueryHandler/GetCategoryIsEnabledHandlerInterface.php b/src/Core/Domain/Category/QueryHandler/GetCategoryIsEnabledHandlerInterface.php deleted file mode 100644 index 4e50fa60..00000000 --- a/src/Core/Domain/Category/QueryHandler/GetCategoryIsEnabledHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryIsEnabled; - -/** - * Interface for service that handles getting category status. - */ -interface GetCategoryIsEnabledHandlerInterface -{ - /** - * @param GetCategoryIsEnabled $query - * - * @return bool - */ - public function handle(GetCategoryIsEnabled $query); -} diff --git a/src/Core/Domain/Category/QueryResult/EditableCategory.php b/src/Core/Domain/Category/QueryResult/EditableCategory.php deleted file mode 100644 index 9a507af9..00000000 --- a/src/Core/Domain/Category/QueryResult/EditableCategory.php +++ /dev/null @@ -1,306 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\MenuThumbnailId; - -/** - * Stores category data needed for editing. - */ -class EditableCategory -{ - /** - * @var CategoryId - */ - private $id; - - /** - * @var string[] - */ - private $name; - - /** - * @var bool - */ - private $isActive; - - /** - * @var string[] - */ - private $description; - - /** - * @var int - */ - private $parentId; - - /** - * @var string[] - */ - private $metaTitle; - - /** - * @var string[] - */ - private $metaDescription; - - /** - * @var string[] - */ - private $metaKeywords; - - /** - * @var string[] - */ - private $linkRewrite; - - /** - * @var int[] - */ - private $groupAssociationIds; - - /** - * @var int[] - */ - private $shopAssociationIds; - - /** - * @var mixed - */ - private $thumbnailImage; - - /** - * @var null - */ - private $coverImage; - - /** - * @var array - */ - private $menuThumbnailImages; - - /** - * @var bool - */ - private $isRootCategory; - - /** - * @var array - */ - private $subCategories; - - /** - * @param CategoryId $id - * @param string[] $name - * @param bool $isActive - * @param string[] $description - * @param int $parentId - * @param string[] $metaTitle - * @param string[] $metaDescription - * @param string[] $metaKeywords - * @param string[] $linkRewrite - * @param int[] $groupAssociationIds - * @param int[] $shopAssociationIds - * @param bool $isRootCategory - * @param mixed $coverImage - * @param mixed $thumbnailImage - * @param array $menuThumbnailImages - * @param array $subCategories - */ - public function __construct( - CategoryId $id, - array $name, - $isActive, - array $description, - $parentId, - array $metaTitle, - array $metaDescription, - array $metaKeywords, - array $linkRewrite, - array $groupAssociationIds, - array $shopAssociationIds, - $isRootCategory, - $coverImage = null, - $thumbnailImage = null, - array $menuThumbnailImages = [], - array $subCategories = [] - ) { - $this->id = $id; - $this->name = $name; - $this->isActive = $isActive; - $this->description = $description; - $this->parentId = $parentId; - $this->metaTitle = $metaTitle; - $this->metaDescription = $metaDescription; - $this->metaKeywords = $metaKeywords; - $this->linkRewrite = $linkRewrite; - $this->groupAssociationIds = $groupAssociationIds; - $this->shopAssociationIds = $shopAssociationIds; - $this->thumbnailImage = $thumbnailImage; - $this->coverImage = $coverImage; - $this->menuThumbnailImages = $menuThumbnailImages; - $this->isRootCategory = $isRootCategory; - $this->subCategories = $subCategories; - } - - /** - * @return CategoryId - */ - public function getId() - { - return $this->id; - } - - /** - * @return string[] - */ - public function getName() - { - return $this->name; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @return string[] - */ - public function getDescription() - { - return $this->description; - } - - /** - * @return int - */ - public function getParentId() - { - return $this->parentId; - } - - /** - * @return string[] - */ - public function getMetaTitle() - { - return $this->metaTitle; - } - - /** - * @return string[] - */ - public function getMetaDescription() - { - return $this->metaDescription; - } - - /** - * @return string[] - */ - public function getMetaKeywords() - { - return $this->metaKeywords; - } - - /** - * @return string[] - */ - public function getLinkRewrite() - { - return $this->linkRewrite; - } - - /** - * @return int[] - */ - public function getGroupAssociationIds() - { - return $this->groupAssociationIds; - } - - /** - * @return int[] - */ - public function getShopAssociationIds() - { - return $this->shopAssociationIds; - } - - /** - * @return mixed - */ - public function getCoverImage() - { - return $this->coverImage; - } - - /** - * @return mixed - */ - public function getThumbnailImage() - { - return $this->thumbnailImage; - } - - /** - * @return array - */ - public function getMenuThumbnailImages() - { - return $this->menuThumbnailImages; - } - - /** - * @return bool - */ - public function isRootCategory() - { - return $this->isRootCategory; - } - - /** - * @return bool - */ - public function canContainMoreMenuThumbnails() - { - return count($this->getMenuThumbnailImages()) < count(MenuThumbnailId::ALLOWED_ID_VALUES); - } - - /** - * @return array - */ - public function getSubCategories() - { - return $this->subCategories; - } -} diff --git a/src/Core/Domain/Category/SeoSettings.php b/src/Core/Domain/Category/SeoSettings.php deleted file mode 100644 index 06abb13d..00000000 --- a/src/Core/Domain/Category/SeoSettings.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category; - -/** - * Defines settings for Category's SEO - */ -final class SeoSettings -{ - /** - * Maximum length of SEO title (value is constrained by database) - */ - const MAX_TITLE_LENGTH = 255; - - /** - * Recommended length of SEO title - */ - const RECOMMENDED_TITLE_LENGTH = 70; - - /** - * Maximum length of SEO description (value is constrained by database) - */ - const MAX_DESCRIPTION_LENGTH = 512; - - /** - * Recommended length of SEO description - */ - const RECOMMENDED_DESCRIPTION_LENGTH = 160; -} diff --git a/src/Core/Domain/Category/ValueObject/CategoryDeleteMode.php b/src/Core/Domain/Category/ValueObject/CategoryDeleteMode.php deleted file mode 100644 index 2caa469d..00000000 --- a/src/Core/Domain/Category/ValueObject/CategoryDeleteMode.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; - -/** - * Class CategoryDeleteMode stores mode for category deletion. - */ -class CategoryDeleteMode -{ - /** - * Associate products with parent category and disable them. - */ - const ASSOCIATE_PRODUCTS_WITH_PARENT_AND_DISABLE = 'associate_and_disable'; - - /** - * Associate products with parent and do not change their status. - */ - const ASSOCIATE_PRODUCTS_WITH_PARENT_ONLY = 'associate_only'; - - /** - * Remove products that are associated only with category that is being deleted. - */ - const REMOVE_ASSOCIATED_PRODUCTS = 'remove_associated'; - - /** - * @internal - */ - const AVAILABLE_MODES = [ - self::ASSOCIATE_PRODUCTS_WITH_PARENT_AND_DISABLE, - self::ASSOCIATE_PRODUCTS_WITH_PARENT_ONLY, - self::REMOVE_ASSOCIATED_PRODUCTS, - ]; - - /** - * @var string - */ - private $mode; - - /** - * @param string $mode - * - * @throws CategoryConstraintException - */ - public function __construct($mode) - { - $this->setMode($mode); - } - - /** - * @param string $mode - * - * @throws CategoryConstraintException - */ - private function setMode($mode) - { - if (!in_array($mode, self::AVAILABLE_MODES)) { - throw new CategoryConstraintException(sprintf('Invalid Category delete mode %s supplied. Available delete modes are: "%s"', var_export($mode, true), implode(',', self::AVAILABLE_MODES)), CategoryConstraintException::INVALID_DELETE_MODE); - } - - $this->mode = $mode; - } - - /** - * Whether products associated with category should be removed. - * - * @return bool - */ - public function shouldRemoveProducts() - { - return self::REMOVE_ASSOCIATED_PRODUCTS === $this->mode; - } - - /** - * Whether products should be disabled when category is deleted. - * - * @return bool - */ - public function shouldDisableProducts() - { - return self::ASSOCIATE_PRODUCTS_WITH_PARENT_AND_DISABLE === $this->mode; - } -} diff --git a/src/Core/Domain/Category/ValueObject/CategoryId.php b/src/Core/Domain/Category/ValueObject/CategoryId.php deleted file mode 100644 index 7f665f71..00000000 --- a/src/Core/Domain/Category/ValueObject/CategoryId.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; - -/** - * Class CategoryId. - */ -class CategoryId -{ - /** - * @var int - */ - private $categoryId; - - /** - * @param int $categoryId - */ - public function __construct($categoryId) - { - $this->setCategoryId($categoryId); - } - - /** - * @return int - */ - public function getValue() - { - return $this->categoryId; - } - - /** - * @param CategoryId $categoryId - * - * @return bool - */ - public function isEqual(CategoryId $categoryId) - { - return $this->getValue() === $categoryId->getValue(); - } - - /** - * @param int $categoryId - */ - private function setCategoryId($categoryId) - { - if (!is_int($categoryId) || 0 >= $categoryId) { - throw new CategoryException(sprintf('Invalid Category id %s supplied', var_export($categoryId, true))); - } - - $this->categoryId = $categoryId; - } -} diff --git a/src/Core/Domain/Category/ValueObject/MenuThumbnailId.php b/src/Core/Domain/Category/ValueObject/MenuThumbnailId.php deleted file mode 100644 index 2e9a597a..00000000 --- a/src/Core/Domain/Category/ValueObject/MenuThumbnailId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Category\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; - -/** - * Stores id for category's menu thumbnail image. - */ -class MenuThumbnailId -{ - /** - * @var array category is of having maximum of 3 menu thumbnails with defined Ids - */ - const ALLOWED_ID_VALUES = [0, 1, 2]; - - /** - * @var int - */ - private $menuThumbnailId; - - /** - * @param int $menuThumbnailId - */ - public function __construct($menuThumbnailId) - { - $this->assertMenuThumbnailIsWithinAllowedValueRange($menuThumbnailId); - - $this->menuThumbnailId = $menuThumbnailId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->menuThumbnailId; - } - - /** - * @param int $menuThumbnailId - */ - private function assertMenuThumbnailIsWithinAllowedValueRange($menuThumbnailId) - { - if (!is_int($menuThumbnailId) || !in_array($menuThumbnailId, self::ALLOWED_ID_VALUES)) { - throw new CategoryException(sprintf('Category menu thumbnail id "%s" invalid. Available values are: %s', var_export($menuThumbnailId, true), implode(',', self::ALLOWED_ID_VALUES))); - } - } -} diff --git a/src/Core/Domain/CmsPage/Command/AddCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/AddCmsPageCommand.php deleted file mode 100644 index 14d11567..00000000 --- a/src/Core/Domain/CmsPage/Command/AddCmsPageCommand.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Adds new cms page - */ -class AddCmsPageCommand -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @var string[] - */ - private $localizedTitle; - - /** - * @var string[] - */ - private $localizedMetaTitle; - - /** - * @var string[] - */ - private $localizedMetaDescription; - - /** - * @var string[] - */ - private $LocalizedMetaKeyword; - - /** - * @var string[] - */ - private $localizedFriendlyUrl; - - /** - * @var string[] - */ - private $localizedContent; - - /** - * @var bool - */ - private $indexedForSearch; - - /** - * @var bool - */ - private $displayed; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @param int $cmsPageCategoryId - * @param string[] $localizedTitle - * @param string[] $localizedMetaTitle - * @param string[] $localizedMetaDescription - * @param string[] $LocalizedMetaKeyword - * @param string[] $localizedFriendlyUrl - * @param string[] $localizedContent - * @param bool $indexedForSearch - * @param bool $displayed - * @param array $shopAssociation - * - * @throws CmsPageCategoryException - */ - public function __construct( - $cmsPageCategoryId, - array $localizedTitle, - array $localizedMetaTitle, - array $localizedMetaDescription, - array $LocalizedMetaKeyword, - array $localizedFriendlyUrl, - array $localizedContent, - $indexedForSearch, - $displayed, - array $shopAssociation - ) { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - $this->localizedTitle = $localizedTitle; - $this->localizedMetaTitle = $localizedMetaTitle; - $this->localizedMetaDescription = $localizedMetaDescription; - $this->LocalizedMetaKeyword = $LocalizedMetaKeyword; - $this->localizedFriendlyUrl = $localizedFriendlyUrl; - $this->localizedContent = $localizedContent; - $this->indexedForSearch = $indexedForSearch; - $this->displayed = $displayed; - $this->shopAssociation = $shopAssociation; - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategory() - { - return $this->cmsPageCategoryId; - } - - /** - * @return string[] - */ - public function getLocalizedTitle() - { - return $this->localizedTitle; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitle() - { - return $this->localizedMetaTitle; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescription() - { - return $this->localizedMetaDescription; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeyword() - { - return $this->LocalizedMetaKeyword; - } - - /** - * @return string[] - */ - public function getLocalizedFriendlyUrl() - { - return $this->localizedFriendlyUrl; - } - - /** - * @return string[] - */ - public function getLocalizedContent() - { - return $this->localizedContent; - } - - /** - * @return bool - */ - public function isIndexedForSearch() - { - return $this->indexedForSearch; - } - - /** - * @return bool - */ - public function isDisplayed() - { - return $this->displayed; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } -} diff --git a/src/Core/Domain/CmsPage/Command/BulkDeleteCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/BulkDeleteCmsPageCommand.php deleted file mode 100644 index 0c3e0ca2..00000000 --- a/src/Core/Domain/CmsPage/Command/BulkDeleteCmsPageCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Deletes multiple cms pages according to given array. - */ -class BulkDeleteCmsPageCommand -{ - /** - * @var CmsPageId[] - */ - private $cmsPages; - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - public function __construct(array $cmsPageIds) - { - $this->setCmsPages($cmsPageIds); - } - - /** - * @return CmsPageId[] - */ - public function getCmsPages() - { - return $this->cmsPages; - } - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - private function setCmsPages(array $cmsPageIds) - { - foreach ($cmsPageIds as $cmsPageId) { - $this->cmsPages[] = new CmsPageId($cmsPageId); - } - } -} diff --git a/src/Core/Domain/CmsPage/Command/BulkDisableCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/BulkDisableCmsPageCommand.php deleted file mode 100644 index e0899ea3..00000000 --- a/src/Core/Domain/CmsPage/Command/BulkDisableCmsPageCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Disables multiple cms pages. - */ -class BulkDisableCmsPageCommand -{ - /** - * @var CmsPageId[] - */ - private $cmsPages; - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - public function __construct(array $cmsPageIds) - { - $this->setCmsPages($cmsPageIds); - } - - /** - * @return CmsPageId[] - */ - public function getCmsPages() - { - return $this->cmsPages; - } - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - private function setCmsPages(array $cmsPageIds) - { - foreach ($cmsPageIds as $cmsPageId) { - $this->cmsPages[] = new CmsPageId($cmsPageId); - } - } -} diff --git a/src/Core/Domain/CmsPage/Command/BulkEnableCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/BulkEnableCmsPageCommand.php deleted file mode 100644 index ce20f32e..00000000 --- a/src/Core/Domain/CmsPage/Command/BulkEnableCmsPageCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Enables multiple cms pages. - */ -class BulkEnableCmsPageCommand -{ - /** - * @var CmsPageId[] - */ - private $cmsPages; - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - public function __construct(array $cmsPageIds) - { - $this->setCmsPages($cmsPageIds); - } - - /** - * @return CmsPageId[] - */ - public function getCmsPages() - { - return $this->cmsPages; - } - - /** - * @param array $cmsPageIds - * - * @throws CmsPageException - */ - private function setCmsPages(array $cmsPageIds) - { - foreach ($cmsPageIds as $cmsPageId) { - $this->cmsPages[] = new CmsPageId($cmsPageId); - } - } -} diff --git a/src/Core/Domain/CmsPage/Command/DeleteCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/DeleteCmsPageCommand.php deleted file mode 100644 index 06e89b82..00000000 --- a/src/Core/Domain/CmsPage/Command/DeleteCmsPageCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Deletes given cms page. - */ -class DeleteCmsPageCommand -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @param $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->cmsPageId = new CmsPageId($cmsPageId); - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } -} diff --git a/src/Core/Domain/CmsPage/Command/EditCmsPageCommand.php b/src/Core/Domain/CmsPage/Command/EditCmsPageCommand.php deleted file mode 100644 index be58ed2a..00000000 --- a/src/Core/Domain/CmsPage/Command/EditCmsPageCommand.php +++ /dev/null @@ -1,313 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Edits cms page - */ -class EditCmsPageCommand -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @var CmsPageCategoryId|null - */ - private $cmsPageCategoryId; - - /** - * @var string[]|null - */ - private $localizedTitle; - - /** - * @var string[]|null - */ - private $localizedMetaTitle; - - /** - * @var string[]|null - */ - private $localizedMetaDescription; - - /** - * @var string[]|null - */ - private $LocalizedMetaKeyword; - - /** - * @var string[]|null - */ - private $localizedFriendlyUrl; - - /** - * @var string[]|null - */ - private $localizedContent; - - /** - * @var bool|null - */ - private $isIndexedForSearch; - - /** - * @var bool|null - */ - private $isDisplayed; - - /** - * @var array|null - */ - private $shopAssociation; - - /** - * @param int $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->cmsPageId = new CmsPageId($cmsPageId); - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } - - /** - * @return CmsPageCategoryId|null - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } - - /** - * @param int|null $cmsPageCategoryId - * - * @return self - * - * @throws CmsPageCategoryException - */ - public function setCmsPageCategoryId($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedTitle() - { - return $this->localizedTitle; - } - - /** - * @param string[]|null $localizedTitle - * - * @return self - */ - public function setLocalizedTitle(array $localizedTitle) - { - $this->localizedTitle = $localizedTitle; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaTitle() - { - return $this->localizedMetaTitle; - } - - /** - * @param string[]|null $localizedMetaTitle - * - * @return self - */ - public function setLocalizedMetaTitle(array $localizedMetaTitle) - { - $this->localizedMetaTitle = $localizedMetaTitle; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaDescription() - { - return $this->localizedMetaDescription; - } - - /** - * @param string[]|null $localizedMetaDescription - * - * @return self - */ - public function setLocalizedMetaDescription(array $localizedMetaDescription) - { - $this->localizedMetaDescription = $localizedMetaDescription; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaKeyword() - { - return $this->LocalizedMetaKeyword; - } - - /** - * @param string[]|null $LocalizedMetaKeyword - * - * @return self - */ - public function setLocalizedMetaKeyword(array $LocalizedMetaKeyword) - { - $this->LocalizedMetaKeyword = $LocalizedMetaKeyword; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedFriendlyUrl() - { - return $this->localizedFriendlyUrl; - } - - /** - * @param string[]|null $localizedFriendlyUrl - * - * @return self - */ - public function setLocalizedFriendlyUrl(array $localizedFriendlyUrl) - { - $this->localizedFriendlyUrl = $localizedFriendlyUrl; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedContent() - { - return $this->localizedContent; - } - - /** - * @param string[]|null $localizedContent - * - * @return self - */ - public function setLocalizedContent(array $localizedContent) - { - $this->localizedContent = $localizedContent; - - return $this; - } - - /** - * @return bool|null - */ - public function isIndexedForSearch() - { - return $this->isIndexedForSearch; - } - - /** - * @param bool|null $isIndexedForSearch - * - * @return self - */ - public function setIsIndexedForSearch($isIndexedForSearch) - { - $this->isIndexedForSearch = $isIndexedForSearch; - - return $this; - } - - /** - * @return bool|null - */ - public function isDisplayed() - { - return $this->isDisplayed; - } - - /** - * @param bool|null $isDisplayed - * - * @return self - */ - public function setIsDisplayed($isDisplayed) - { - $this->isDisplayed = $isDisplayed; - - return $this; - } - - /** - * @return array|null - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param array|null $shopAssociation - * - * @return self - */ - public function setShopAssociation(array $shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/CmsPage/Command/ToggleCmsPageStatusCommand.php b/src/Core/Domain/CmsPage/Command/ToggleCmsPageStatusCommand.php deleted file mode 100644 index f445ebc2..00000000 --- a/src/Core/Domain/CmsPage/Command/ToggleCmsPageStatusCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Changes the status of cms page. - */ -class ToggleCmsPageStatusCommand -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @param int $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->cmsPageId = new CmsPageId($cmsPageId); - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/AddCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/AddCmsPageHandlerInterface.php deleted file mode 100644 index 38f0b2fb..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/AddCmsPageHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\AddCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Interface for services that handles AddCmsPageCommand - */ -interface AddCmsPageHandlerInterface -{ - /** - * @param AddCmsPageCommand $command - * - * @return CmsPageId - */ - public function handle(AddCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/BulkDeleteCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/BulkDeleteCmsPageHandlerInterface.php deleted file mode 100644 index ba9cdd70..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/BulkDeleteCmsPageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDeleteCmsPageCommand; - -/** - * Defines contract for BulkDeleteCmsPageHandler. - */ -interface BulkDeleteCmsPageHandlerInterface -{ - /** - * @param BulkDeleteCmsPageCommand $command - */ - public function handle(BulkDeleteCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/BulkDisableCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/BulkDisableCmsPageHandlerInterface.php deleted file mode 100644 index 79a23437..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/BulkDisableCmsPageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDisableCmsPageCommand; - -/** - * Defines contract for BulkDisableCmsPageHandler. - */ -interface BulkDisableCmsPageHandlerInterface -{ - /** - * @param BulkDisableCmsPageCommand $command - */ - public function handle(BulkDisableCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/BulkEnableCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/BulkEnableCmsPageHandlerInterface.php deleted file mode 100644 index b40f4b55..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/BulkEnableCmsPageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkEnableCmsPageCommand; - -/** - * Defines contract for BulkEnableCmsPageHandler. - */ -interface BulkEnableCmsPageHandlerInterface -{ - /** - * @param BulkEnableCmsPageCommand $command - */ - public function handle(BulkEnableCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/DeleteCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/DeleteCmsPageHandlerInterface.php deleted file mode 100644 index f47e1740..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/DeleteCmsPageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\DeleteCmsPageCommand; - -/** - * Defines contract for DeleteCmsPageHandler. - */ -interface DeleteCmsPageHandlerInterface -{ - /** - * @param DeleteCmsPageCommand $command - */ - public function handle(DeleteCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/EditCmsPageHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/EditCmsPageHandlerInterface.php deleted file mode 100644 index 76f611c3..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/EditCmsPageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\EditCmsPageCommand; - -/** - * Defines contract for EditCmsPageHandler. - */ -interface EditCmsPageHandlerInterface -{ - /** - * @param EditCmsPageCommand $command - */ - public function handle(EditCmsPageCommand $command); -} diff --git a/src/Core/Domain/CmsPage/CommandHandler/ToggleCmsPageStatusHandlerInterface.php b/src/Core/Domain/CmsPage/CommandHandler/ToggleCmsPageStatusHandlerInterface.php deleted file mode 100644 index 824847f0..00000000 --- a/src/Core/Domain/CmsPage/CommandHandler/ToggleCmsPageStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\ToggleCmsPageStatusCommand; - -/** - * Defines contract for ToggleCmsPageStatusHandler. - */ -interface ToggleCmsPageStatusHandlerInterface -{ - /** - * @param ToggleCmsPageStatusCommand $command - */ - public function handle(ToggleCmsPageStatusCommand $command); -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotAddCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotAddCmsPageException.php deleted file mode 100644 index 981bb56c..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotAddCmsPageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Thrown on failure when adding new cms page - */ -class CannotAddCmsPageException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotDeleteCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotDeleteCmsPageException.php deleted file mode 100644 index df9cedca..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotDeleteCmsPageException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown on failure when deleting cms page - */ -class CannotDeleteCmsPageException extends CmsPageException -{ - /** - * When fails to delete single cms page - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete cms pages on bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotDisableCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotDisableCmsPageException.php deleted file mode 100644 index e41f8c9d..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotDisableCmsPageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown when cms page cannot be disabled - */ -class CannotDisableCmsPageException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotEditCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotEditCmsPageException.php deleted file mode 100644 index b48f19dc..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotEditCmsPageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown when cms page cannot be edited - */ -class CannotEditCmsPageException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotEnableCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotEnableCmsPageException.php deleted file mode 100644 index 79e41154..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotEnableCmsPageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown when cms page cannot be enabled - */ -class CannotEnableCmsPageException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CannotToggleCmsPageException.php b/src/Core/Domain/CmsPage/Exception/CannotToggleCmsPageException.php deleted file mode 100644 index ffd81e0d..00000000 --- a/src/Core/Domain/CmsPage/Exception/CannotToggleCmsPageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown when cms page cannot be enabled or disabled in toggling action - */ -class CannotToggleCmsPageException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CmsPageException.php b/src/Core/Domain/CmsPage/Exception/CmsPageException.php deleted file mode 100644 index 9b521657..00000000 --- a/src/Core/Domain/CmsPage/Exception/CmsPageException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for cms page sub-domain - */ -class CmsPageException extends DomainException -{ -} diff --git a/src/Core/Domain/CmsPage/Exception/CmsPageNotFoundException.php b/src/Core/Domain/CmsPage/Exception/CmsPageNotFoundException.php deleted file mode 100644 index 6994df9c..00000000 --- a/src/Core/Domain/CmsPage/Exception/CmsPageNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception; - -/** - * Is thrown when required cms page is not found - */ -class CmsPageNotFoundException extends CmsPageException -{ -} diff --git a/src/Core/Domain/CmsPage/Query/GetCmsCategoryIdForRedirection.php b/src/Core/Domain/CmsPage/Query/GetCmsCategoryIdForRedirection.php deleted file mode 100644 index ca035759..00000000 --- a/src/Core/Domain/CmsPage/Query/GetCmsCategoryIdForRedirection.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Query; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * This class is used for getting the id which is used later on to redirect to the right page after certain controller - * actions. - */ -class GetCmsCategoryIdForRedirection -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @param $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->cmsPageId = new CmsPageId($cmsPageId); - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } -} diff --git a/src/Core/Domain/CmsPage/Query/GetCmsPageForEditing.php b/src/Core/Domain/CmsPage/Query/GetCmsPageForEditing.php deleted file mode 100644 index 3495ac25..00000000 --- a/src/Core/Domain/CmsPage/Query/GetCmsPageForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\Query; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; - -/** - * Gets object which transfers cms page data for editing - */ -class GetCmsPageForEditing -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @param int $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->cmsPageId = new CmsPageId($cmsPageId); - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } -} diff --git a/src/Core/Domain/CmsPage/QueryHandler/GetCmsCategoryIdHandlerForRedirectionInterface.php b/src/Core/Domain/CmsPage/QueryHandler/GetCmsCategoryIdHandlerForRedirectionInterface.php deleted file mode 100644 index 04e9629d..00000000 --- a/src/Core/Domain/CmsPage/QueryHandler/GetCmsCategoryIdHandlerForRedirectionInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Defines contract for GetCmsCategoryIdHandlerForRedirection. - */ -interface GetCmsCategoryIdHandlerForRedirectionInterface -{ - /** - * @param GetCmsCategoryIdForRedirection $query - * - * @return CmsPageCategoryId - */ - public function handle(GetCmsCategoryIdForRedirection $query); -} diff --git a/src/Core/Domain/CmsPage/QueryHandler/GetCmsPageForEditingHandlerInterface.php b/src/Core/Domain/CmsPage/QueryHandler/GetCmsPageForEditingHandlerInterface.php deleted file mode 100644 index 744d5df8..00000000 --- a/src/Core/Domain/CmsPage/QueryHandler/GetCmsPageForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsPageForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryResult\EditableCmsPage; - -/** - * Interface for service that handles getCmsPageForEditing query - */ -interface GetCmsPageForEditingHandlerInterface -{ - /** - * @param GetCmsPageForEditing $query - * - * @return EditableCmsPage - */ - public function handle(GetCmsPageForEditing $query); -} diff --git a/src/Core/Domain/CmsPage/QueryResult/EditableCmsPage.php b/src/Core/Domain/CmsPage/QueryResult/EditableCmsPage.php deleted file mode 100644 index 4df3212e..00000000 --- a/src/Core/Domain/CmsPage/QueryResult/EditableCmsPage.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Transfers cms page data for editing - */ -class EditableCmsPage -{ - /** - * @var CmsPageId - */ - private $cmsPageId; - - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @var string[] - */ - private $localizedTitle; - - /** - * @var string[] - */ - private $localizedMetaTitle; - - /** - * @var string[] - */ - private $localizedMetaDescription; - - /** - * @var string[] - */ - private $localizedMetaKeyword; - - /** - * @var string[] - */ - private $localizedFriendlyUrl; - - /** - * @var string[] - */ - private $localizedContent; - - /** - * @var bool - */ - private $indexedForSearch; - - /** - * @var bool - */ - private $displayed; - - /** - * @var array - */ - private $shopAssociation; - - /** - * Url for opening FO page on save and preview action - * - * @var string - */ - private $previewUrl; - - /** - * @param int $cmsPageId - * @param int $cmsPageCategoryId - * @param string[] $localizedTitle - * @param string[] $localizedMetaTitle - * @param string[] $localizedMetaDescription - * @param string[] $localizedMetaKeyword - * @param string[] $localizedFriendlyUrl - * @param string[] $localizedContent - * @param bool $indexedForSearch - * @param bool $displayed - * @param array $shopAssociation - * @param string $previewUrl - * - * @throws CmsPageCategoryException - * @throws CmsPageException - */ - public function __construct( - $cmsPageId, - $cmsPageCategoryId, - array $localizedTitle, - array $localizedMetaTitle, - array $localizedMetaDescription, - array $localizedMetaKeyword, - array $localizedFriendlyUrl, - array $localizedContent, - $indexedForSearch, - $displayed, - array $shopAssociation, - $previewUrl - ) { - $this->cmsPageId = new CmsPageId($cmsPageId); - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - $this->localizedTitle = $localizedTitle; - $this->localizedMetaTitle = $localizedMetaTitle; - $this->localizedMetaDescription = $localizedMetaDescription; - $this->localizedMetaKeyword = $localizedMetaKeyword; - $this->localizedFriendlyUrl = $localizedFriendlyUrl; - $this->localizedContent = $localizedContent; - $this->indexedForSearch = $indexedForSearch; - $this->displayed = $displayed; - $this->shopAssociation = $shopAssociation; - $this->previewUrl = $previewUrl; - } - - /** - * @return CmsPageId - */ - public function getCmsPageId() - { - return $this->cmsPageId; - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } - - /** - * @return string[] - */ - public function getLocalizedTitle() - { - return $this->localizedTitle; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitle() - { - return $this->localizedMetaTitle; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescription() - { - return $this->localizedMetaDescription; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeyword() - { - return $this->localizedMetaKeyword; - } - - /** - * @return string[] - */ - public function getLocalizedFriendlyUrl() - { - return $this->localizedFriendlyUrl; - } - - /** - * @return string[] - */ - public function getLocalizedContent() - { - return $this->localizedContent; - } - - /** - * @return bool - */ - public function isIndexedForSearch() - { - return $this->indexedForSearch; - } - - /** - * @return bool - */ - public function isDisplayed() - { - return $this->displayed; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @return string - */ - public function getPreviewUrl() - { - return $this->previewUrl; - } -} diff --git a/src/Core/Domain/CmsPage/ValueObject/CmsPageId.php b/src/Core/Domain/CmsPage/ValueObject/CmsPageId.php deleted file mode 100644 index d2944d90..00000000 --- a/src/Core/Domain/CmsPage/ValueObject/CmsPageId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; - -/** - * Class which holds the cms page id value. - */ -class CmsPageId -{ - /** - * @var int - */ - private $cmsPageId; - - /** - * @param int $cmsPageId - * - * @throws CmsPageException - */ - public function __construct($cmsPageId) - { - $this->assertIsIntegerGreaterThanZero($cmsPageId); - $this->cmsPageId = $cmsPageId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->cmsPageId; - } - - /** - * Validates that the value is integer and is greater than zero. - * - * @param int $cmsPageId - * - * @throws CmsPageException - */ - private function assertIsIntegerGreaterThanZero($cmsPageId) - { - if (!is_int($cmsPageId) || 0 >= $cmsPageId) { - throw new CmsPageException(sprintf('Invalid cms page id %s supplied', var_export($cmsPageId, true))); - } - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/AbstractBulkCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/AbstractBulkCmsPageCategoryCommand.php deleted file mode 100644 index e1de1468..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/AbstractBulkCmsPageCategoryCommand.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -/** - * Class AbstractBulkCmsPageCategoryCommand is responsible for providing shared logic between all bulk actions - * in cms page category listing. - */ -abstract class AbstractBulkCmsPageCategoryCommand -{ - /** - * @param array $ids - * - * @return bool - */ - protected function assertIsEmptyOrContainsNonIntegerValues(array $ids) - { - return empty($ids) || $ids !== array_filter($ids, 'is_int'); - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/AbstractCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/AbstractCmsPageCategoryCommand.php deleted file mode 100644 index b091d1d5..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/AbstractCmsPageCategoryCommand.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; - -/** - * Class AbstractCmsPageCategoryCommand - */ -abstract class AbstractCmsPageCategoryCommand -{ - const CATEGORY_NAME_REGEX_PATTERN = '/^[^<>;=#{}]*$/u'; - const GENERIC_NAME_REGEX_PATTERN = '/^[^<>={}]*$/u'; - - /** - * Checks if given names matches pattern. - * - * @param array $names - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertCategoryName(array $names) - { - foreach ($names as $name) { - if (!preg_match(self::CATEGORY_NAME_REGEX_PATTERN, $name)) { - throw new CmsPageCategoryConstraintException(sprintf('Given category name "%s" does not match pattern "%s"', $name, self::CATEGORY_NAME_REGEX_PATTERN), CmsPageCategoryConstraintException::INVALID_CATEGORY_NAME); - } - } - } - - /** - * @param array $localisedMetaTitles - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertIsGenericNameForMetaTitle(array $localisedMetaTitles) - { - $assertionResult = $this->assertIsGenericName($localisedMetaTitles); - - if (true !== $assertionResult) { - throw new CmsPageCategoryConstraintException(sprintf('Given meta title "%s" does not match pattern "%s"', $assertionResult, self::GENERIC_NAME_REGEX_PATTERN), CmsPageCategoryConstraintException::INVALID_META_TITLE); - } - } - - /** - * @param array $localisedMetaDescription - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertIsGenericNameForMetaDescription(array $localisedMetaDescription) - { - $assertionResult = $this->assertIsGenericName($localisedMetaDescription); - - if (true !== $assertionResult) { - throw new CmsPageCategoryConstraintException(sprintf('Given meta description "%s" does not match pattern "%s"', $assertionResult, self::GENERIC_NAME_REGEX_PATTERN), CmsPageCategoryConstraintException::INVALID_META_DESCRIPTION); - } - } - - /** - * @param array $localisedMetaKeywords - * - * @throws CmsPageCategoryConstraintException - */ - protected function assertIsGenericNameForMetaKeywords(array $localisedMetaKeywords) - { - $assertionResult = $this->assertIsGenericName($localisedMetaKeywords); - - if (true !== $assertionResult) { - throw new CmsPageCategoryConstraintException(sprintf('Given meta keyword "%s" does not match pattern "%s"', $assertionResult, self::GENERIC_NAME_REGEX_PATTERN), CmsPageCategoryConstraintException::INVALID_META_KEYWORDS); - } - } - - /** - * @param array $localisedNames - * - * @return bool|string - */ - private function assertIsGenericName(array $localisedNames) - { - foreach ($localisedNames as $localisedName) { - if (!preg_match(self::GENERIC_NAME_REGEX_PATTERN, $localisedName)) { - return $localisedName; - } - } - - return true; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/AddCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/AddCmsPageCategoryCommand.php deleted file mode 100644 index 34f49f08..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/AddCmsPageCategoryCommand.php +++ /dev/null @@ -1,245 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class AddCmsPageCategoryCommand is responsible for adding cms page category. - */ -class AddCmsPageCategoryCommand extends AbstractCmsPageCategoryCommand -{ - /** - * @var array - */ - private $localisedName; - - /** - * @var array - */ - private $localisedFriendlyUrl; - - /** - * @var CmsPageCategoryId - */ - private $parentId; - - /** - * @var bool - */ - private $isDisplayed; - - /** - * @var string[] - */ - private $localisedDescription; - - /** - * @var string[] - */ - private $localisedMetaTitle; - - /** - * @var string[] - */ - private $localisedMetaDescription; - - /** - * @var string[] - */ - private $localisedMetaKeywords; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param array $localisedName - * @param array $localisedFriendlyUrl - * @param int $parentId - * @param bool $isDisplayed - * - * @throws CmsPageCategoryException - */ - public function __construct( - array $localisedName, - array $localisedFriendlyUrl, - $parentId, - $isDisplayed - ) { - $this->assertCategoryName($localisedName); - - $this->localisedName = $localisedName; - $this->localisedFriendlyUrl = $localisedFriendlyUrl; - $this->parentId = new CmsPageCategoryId($parentId); - $this->isDisplayed = $isDisplayed; - } - - /** - * @return array - */ - public function getLocalisedName() - { - return $this->localisedName; - } - - /** - * @return array - */ - public function getLocalisedFriendlyUrl() - { - return $this->localisedFriendlyUrl; - } - - /** - * @return CmsPageCategoryId - */ - public function getParentId() - { - return $this->parentId; - } - - /** - * @return bool - */ - public function isDisplayed() - { - return $this->isDisplayed; - } - - /** - * @return string[] - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @param string[] $localisedDescription - * - * @return self - */ - public function setLocalisedDescription(array $localisedDescription) - { - $this->localisedDescription = $localisedDescription; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaTitle() - { - return $this->localisedMetaTitle; - } - - /** - * @param string[] $localisedMetaTitle - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaTitle(array $localisedMetaTitle) - { - $this->assertIsGenericNameForMetaTitle($localisedMetaTitle); - $this->localisedMetaTitle = $localisedMetaTitle; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaDescription() - { - return $this->localisedMetaDescription; - } - - /** - * @param string[] $localisedMetaDescription - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaDescription(array $localisedMetaDescription) - { - $this->assertIsGenericNameForMetaDescription($localisedMetaDescription); - $this->localisedMetaDescription = $localisedMetaDescription; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @param string[] $localisedMetaKeywords - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaKeywords(array $localisedMetaKeywords) - { - $this->assertIsGenericNameForMetaKeywords($localisedMetaKeywords); - $this->localisedMetaKeywords = $localisedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - */ - public function setShopAssociation(array $shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/BulkDeleteCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/BulkDeleteCmsPageCategoryCommand.php deleted file mode 100644 index 97512184..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/BulkDeleteCmsPageCategoryCommand.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class BulkDeleteCmsPageCategoryCommand is responsible for deleting multiple cms page categories. - */ -class BulkDeleteCmsPageCategoryCommand extends AbstractBulkCmsPageCategoryCommand -{ - /** - * @var CmsPageCategoryId[] - */ - private $cmsPageCategoryIds; - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryException - */ - public function __construct(array $cmsPageCategoryIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($cmsPageCategoryIds)) { - throw new CmsPageCategoryConstraintException(sprintf('Missing cms page category data or array %s contains non integer values for bulk deleting', var_export($cmsPageCategoryIds, true)), CmsPageCategoryConstraintException::INVALID_BULK_DATA); - } - - $this->setCmsPageCategoryIds($cmsPageCategoryIds); - } - - /** - * @return CmsPageCategoryId[] - */ - public function getCmsPageCategoryIds() - { - return $this->cmsPageCategoryIds; - } - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryException - */ - private function setCmsPageCategoryIds(array $cmsPageCategoryIds) - { - foreach ($cmsPageCategoryIds as $id) { - $this->cmsPageCategoryIds[] = new CmsPageCategoryId($id); - } - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/BulkDisableCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/BulkDisableCmsPageCategoryCommand.php deleted file mode 100644 index cd6f1604..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/BulkDisableCmsPageCategoryCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class BulkDisableCmsPageCategoryCommand is responsible for disabling cms category pages. - */ -class BulkDisableCmsPageCategoryCommand extends AbstractBulkCmsPageCategoryCommand -{ - /** - * @var CmsPageCategoryId[] - */ - private $cmsPageCategoryIds; - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryConstraintException - * @throws CmsPageCategoryException - */ - public function __construct(array $cmsPageCategoryIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($cmsPageCategoryIds)) { - throw new CmsPageCategoryConstraintException(sprintf('Missing cms page category data or array %s contains non integer values for bulk disabling', var_export($cmsPageCategoryIds, true)), CmsPageCategoryConstraintException::INVALID_BULK_DATA); - } - - $this->setCmsPageCategoryIds($cmsPageCategoryIds); - } - - /** - * @return CmsPageCategoryId[] - */ - public function getCmsPageCategoryIds() - { - return $this->cmsPageCategoryIds; - } - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryException - */ - private function setCmsPageCategoryIds(array $cmsPageCategoryIds) - { - foreach ($cmsPageCategoryIds as $id) { - $this->cmsPageCategoryIds[] = new CmsPageCategoryId($id); - } - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/BulkEnableCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/BulkEnableCmsPageCategoryCommand.php deleted file mode 100644 index 1241e802..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/BulkEnableCmsPageCategoryCommand.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class BulkEnableCmsPageCategoryCommand is responsible for enabling cms category pages. - */ -class BulkEnableCmsPageCategoryCommand extends AbstractBulkCmsPageCategoryCommand -{ - /** - * @var CmsPageCategoryId[] - */ - private $cmsPageCategoryIds; - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryException - */ - public function __construct(array $cmsPageCategoryIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($cmsPageCategoryIds)) { - throw new CmsPageCategoryConstraintException(sprintf('Missing cms page category data or array %s contains non integer values for bulk enabling', var_export($cmsPageCategoryIds, true)), CmsPageCategoryConstraintException::INVALID_BULK_DATA); - } - - $this->setCmsPageCategoryIds($cmsPageCategoryIds); - } - - /** - * @return CmsPageCategoryId[] - */ - public function getCmsPageCategoryIds() - { - return $this->cmsPageCategoryIds; - } - - /** - * @param int[] $cmsPageCategoryIds - * - * @throws CmsPageCategoryException - */ - private function setCmsPageCategoryIds(array $cmsPageCategoryIds) - { - foreach ($cmsPageCategoryIds as $id) { - $this->cmsPageCategoryIds[] = new CmsPageCategoryId($id); - } - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/DeleteCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/DeleteCmsPageCategoryCommand.php deleted file mode 100644 index 59f4aad5..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/DeleteCmsPageCategoryCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class DeleteCmsPageCategoryCommand is responsible for deleting cms page category. - */ -class DeleteCmsPageCategoryCommand -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/EditCmsPageCategoryCommand.php b/src/Core/Domain/CmsPageCategory/Command/EditCmsPageCategoryCommand.php deleted file mode 100644 index 0025d975..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/EditCmsPageCategoryCommand.php +++ /dev/null @@ -1,299 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Edits cms page category. - */ -class EditCmsPageCategoryCommand extends AbstractCmsPageCategoryCommand -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @var array - */ - private $localisedName; - - /** - * @var array - */ - private $localisedFriendlyUrl; - - /** - * @var CmsPageCategoryId - */ - private $parentId; - - /** - * @var bool - */ - private $isDisplayed; - - /** - * @var string[] - */ - private $localisedDescription; - - /** - * @var string[] - */ - private $localisedMetaTitle; - - /** - * @var string[] - */ - private $localisedMetaDescription; - - /** - * @var string[] - */ - private $localisedMetaKeywords; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } - - /** - * @return array - */ - public function getLocalisedName() - { - return $this->localisedName; - } - - /** - * @param array $localisedName - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedName(array $localisedName) - { - $this->assertCategoryName($localisedName); - $this->localisedName = $localisedName; - - return $this; - } - - /** - * @return array - */ - public function getLocalisedFriendlyUrl() - { - return $this->localisedFriendlyUrl; - } - - /** - * @param array $localisedFriendlyUrl - * - * @return self - */ - public function setLocalisedFriendlyUrl(array $localisedFriendlyUrl) - { - $this->localisedFriendlyUrl = $localisedFriendlyUrl; - - return $this; - } - - /** - * @return CmsPageCategoryId - */ - public function getParentId() - { - return $this->parentId; - } - - /** - * @param int $parentId - * - * @return self - * - * @throws CmsPageCategoryException - */ - public function setParentId($parentId) - { - $this->parentId = new CmsPageCategoryId($parentId); - - return $this; - } - - /** - * @return bool - */ - public function isDisplayed() - { - return $this->isDisplayed; - } - - /** - * @param bool $isDisplayed - * - * @return self - */ - public function setIsDisplayed($isDisplayed) - { - $this->isDisplayed = $isDisplayed; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @param string[] $localisedDescription - * - * @return self - */ - public function setLocalisedDescription(array $localisedDescription) - { - $this->localisedDescription = $localisedDescription; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaTitle() - { - return $this->localisedMetaTitle; - } - - /** - * @param string[] $localisedMetaTitle - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaTitle(array $localisedMetaTitle) - { - $this->assertIsGenericNameForMetaTitle($localisedMetaTitle); - $this->localisedMetaTitle = $localisedMetaTitle; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaDescription() - { - return $this->localisedMetaDescription; - } - - /** - * @param string[] $localisedMetaDescription - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaDescription(array $localisedMetaDescription) - { - $this->assertIsGenericNameForMetaDescription($localisedMetaDescription); - $this->localisedMetaDescription = $localisedMetaDescription; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @param string[] $localisedMetaKeywords - * - * @return self - * - * @throws CmsPageCategoryConstraintException - */ - public function setLocalisedMetaKeywords(array $localisedMetaKeywords) - { - $this->assertIsGenericNameForMetaKeywords($localisedMetaKeywords); - $this->localisedMetaKeywords = $localisedMetaKeywords; - - return $this; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - */ - public function setShopAssociation(array $shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Command/ToggleCmsPageCategoryStatusCommand.php b/src/Core/Domain/CmsPageCategory/Command/ToggleCmsPageCategoryStatusCommand.php deleted file mode 100644 index 7abba327..00000000 --- a/src/Core/Domain/CmsPageCategory/Command/ToggleCmsPageCategoryStatusCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class ToggleCmsPageCategoryStatusCommand is responsible for turning on and off cms page category status. - */ -class ToggleCmsPageCategoryStatusCommand -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/AddCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/AddCmsPageCategoryHandlerInterface.php deleted file mode 100644 index 3139179c..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/AddCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\AddCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Interface AddCmsPageCategoryHandlerInterface defines contract for AddCmsPageCategoryHandler. - */ -interface AddCmsPageCategoryHandlerInterface -{ - /** - * @param AddCmsPageCategoryCommand $command - * - * @return CmsPageCategoryId - */ - public function handle(AddCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandlerInterface.php deleted file mode 100644 index a100084a..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDeleteCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDeleteCmsPageCategoryCommand; - -/** - * Interface BulkDeleteCmsPageCategoryHandlerInterface defines contract for BulkDeleteCmsPageCategoryHandler. - */ -interface BulkDeleteCmsPageCategoryHandlerInterface -{ - /** - * @param BulkDeleteCmsPageCategoryCommand $command - */ - public function handle(BulkDeleteCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDisableCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDisableCmsPageCategoryHandlerInterface.php deleted file mode 100644 index c20a3549..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkDisableCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDisableCmsPageCategoryCommand; - -/** - * Interface BulkDisableCmsPageCategoryHandlerInterface defines contract for BulkDisableCmsPageCategoryHandler. - */ -interface BulkDisableCmsPageCategoryHandlerInterface -{ - /** - * @param BulkDisableCmsPageCategoryCommand $command - */ - public function handle(BulkDisableCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkEnableCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/BulkEnableCmsPageCategoryHandlerInterface.php deleted file mode 100644 index 49a087c1..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/BulkEnableCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkEnableCmsPageCategoryCommand; - -/** - * Interface BulkEnableCmsPageCategoryHandlerInterface defines contract for BulkEnableCmsPageCategoryHandler. - */ -interface BulkEnableCmsPageCategoryHandlerInterface -{ - /** - * @param BulkEnableCmsPageCategoryCommand $command - */ - public function handle(BulkEnableCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/DeleteCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/DeleteCmsPageCategoryHandlerInterface.php deleted file mode 100644 index 1c5c7968..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/DeleteCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\DeleteCmsPageCategoryCommand; - -/** - * Interface DeleteCmsPageCategoryHandlerInterface defines contract for DeleteCmsPageCategoryHandler. - */ -interface DeleteCmsPageCategoryHandlerInterface -{ - /** - * @param DeleteCmsPageCategoryCommand $command - */ - public function handle(DeleteCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/EditCmsPageCategoryHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/EditCmsPageCategoryHandlerInterface.php deleted file mode 100644 index 60a663e6..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/EditCmsPageCategoryHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\EditCmsPageCategoryCommand; - -/** - * Defines contract for EditCmsPageCategoryHandler. - */ -interface EditCmsPageCategoryHandlerInterface -{ - /** - * @param EditCmsPageCategoryCommand $command - */ - public function handle(EditCmsPageCategoryCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandlerInterface.php b/src/Core/Domain/CmsPageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandlerInterface.php deleted file mode 100644 index aa9f98ff..00000000 --- a/src/Core/Domain/CmsPageCategory/CommandHandler/ToggleCmsPageCategoryStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\ToggleCmsPageCategoryStatusCommand; - -/** - * Interface ToggleCmsPageCategoryStatusHandlerInterface defines contract for ToggleCmsPageCategoryStatusHandler. - */ -interface ToggleCmsPageCategoryStatusHandlerInterface -{ - /** - * @param ToggleCmsPageCategoryStatusCommand $command - */ - public function handle(ToggleCmsPageCategoryStatusCommand $command); -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotAddCmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotAddCmsPageCategoryException.php deleted file mode 100644 index afcc7694..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotAddCmsPageCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown on failure when adding new cms page - */ -class CannotAddCmsPageCategoryException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotDeleteCmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotDeleteCmsPageCategoryException.php deleted file mode 100644 index e7f76282..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotDeleteCmsPageCategoryException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown on failure when deleting a cms page category - */ -class CannotDeleteCmsPageCategoryException extends CmsPageCategoryException -{ - /** - * When fails to delete single cms page category - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete cms page categories on bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotDisableCmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotDisableCmsPageCategoryException.php deleted file mode 100644 index 612d086a..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotDisableCmsPageCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown when cms page category cannot be disabled - */ -class CannotDisableCmsPageCategoryException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotEnableCmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotEnableCmsPageCategoryException.php deleted file mode 100644 index d725c60a..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotEnableCmsPageCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown when cms page category cannot be enabled - */ -class CannotEnableCmsPageCategoryException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotToggleCmsPageCategoryStatusException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotToggleCmsPageCategoryStatusException.php deleted file mode 100644 index 1a10cc58..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotToggleCmsPageCategoryStatusException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown when cms page category cannot be enabled or disabled in toggling action - */ -class CannotToggleCmsPageCategoryStatusException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CannotUpdateCmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CannotUpdateCmsPageCategoryException.php deleted file mode 100644 index c3b145cc..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CannotUpdateCmsPageCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown when cms page category cannot be updated - */ -class CannotUpdateCmsPageCategoryException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryConstraintException.php b/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryConstraintException.php deleted file mode 100644 index d5f0abd5..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryConstraintException.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Is thrown when cms page category constraints are violated - */ -class CmsPageCategoryConstraintException extends CmsPageCategoryException -{ - /** - * @var int is used when incorrect values supplied for bulk cms categories operations - */ - const INVALID_BULK_DATA = 1; - - /** - * @var int is used when cms page category is moved to the same category as it is - * or if it is moved to its child category - */ - const CANNOT_MOVE_CATEGORY_TO_PARENT = 2; - - /** - * @var int is used to raise an error when default language is missing for the field - */ - const MISSING_DEFAULT_LANGUAGE_FOR_NAME = 3; - - /** - * @var int is used to raise an error when friendly url is missing for the field - */ - const MISSING_DEFAULT_LANGUAGE_FOR_FRIENDLY_URL = 4; - - /** - * @var int is used to validate category name to match the specific pattern - */ - const INVALID_CATEGORY_NAME = 5; - - /** - * @var int is used to validate link rewrite that matches specific regex pattern - */ - const INVALID_LINK_REWRITE = 6; - - /** - * @var int is used to validate meta title for specific regex pattern - */ - const INVALID_META_TITLE = 7; - - /** - * @var int Is used to validate meta description for specific regex pattern - */ - const INVALID_META_DESCRIPTION = 8; - - /** - * @var int is used to validate meta keywords for specific regex pattern - */ - const INVALID_META_KEYWORDS = 9; - - /** - * @var int Is used to validate description according to clean html standard/ - */ - const INVALID_DESCRIPTION = 10; -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryException.php b/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryException.php deleted file mode 100644 index 70a788d1..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for CmsPageCategory sub-domain - */ -class CmsPageCategoryException extends DomainException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryNotFoundException.php b/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryNotFoundException.php deleted file mode 100644 index 202d0c2c..00000000 --- a/src/Core/Domain/CmsPageCategory/Exception/CmsPageCategoryNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception; - -/** - * Thrown when unable to find required cms page category - */ -class CmsPageCategoryNotFoundException extends CmsPageCategoryException -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoriesForBreadcrumb.php b/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoriesForBreadcrumb.php deleted file mode 100644 index 534f9783..00000000 --- a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoriesForBreadcrumb.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class GetCmsPageCategoriesForBreadcrumb is responsible for providing required data for displaying cms page category - * breadcrumbs. - */ -class GetCmsPageCategoriesForBreadcrumb -{ - /** - * @var CmsPageCategoryId - */ - private $currentCategoryId; - - /** - * @param int $currentCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($currentCategoryId) - { - $this->currentCategoryId = new CmsPageCategoryId($currentCategoryId); - } - - /** - * Gets current category id. - * - * @return CmsPageCategoryId - */ - public function getCurrentCategoryId() - { - return $this->currentCategoryId; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryForEditing.php b/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryForEditing.php deleted file mode 100644 index 7a51f996..00000000 --- a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class GetCmsPageCategoryForEditing is responsible for retrieving cms page category form data. - */ -class GetCmsPageCategoryForEditing -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } -} diff --git a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryNameForListing.php b/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryNameForListing.php deleted file mode 100644 index ca63809d..00000000 --- a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageCategoryNameForListing.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query; - -/** - * Gets name by cms category which are used for display in cms listing. - */ -class GetCmsPageCategoryNameForListing -{ -} diff --git a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageParentCategoryIdForRedirection.php b/src/Core/Domain/CmsPageCategory/Query/GetCmsPageParentCategoryIdForRedirection.php deleted file mode 100644 index ebed1c78..00000000 --- a/src/Core/Domain/CmsPageCategory/Query/GetCmsPageParentCategoryIdForRedirection.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class GetCmsPageParentCategoryIdForRedirection is responsible for providing cms page categories parent id - * for redirecting to the right controller after create, edit, delete, toggle actions. - */ -class GetCmsPageParentCategoryIdForRedirection -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } -} diff --git a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandlerInterface.php b/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandlerInterface.php deleted file mode 100644 index 47de5b69..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoriesForBreadcrumbHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoriesForBreadcrumb; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\Breadcrumb; - -/** - * Interface GetCmsPageCategoriesForBreadcrumbHandlerInterface defines contract for GetCmsPageCategoriesForBreadcrumbHandlerInterface. - */ -interface GetCmsPageCategoriesForBreadcrumbHandlerInterface -{ - /** - * @param GetCmsPageCategoriesForBreadcrumb $query - * - * @return Breadcrumb - */ - public function handle(GetCmsPageCategoriesForBreadcrumb $query); -} diff --git a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryForEditingHandlerInterface.php b/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryForEditingHandlerInterface.php deleted file mode 100644 index e6530b4d..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\EditableCmsPageCategory; - -/** - * Interface GetCmsPageCategoryForEditingHandlerInterface defines contract for GetCmsPageCategoryForEditingHandler. - */ -interface GetCmsPageCategoryForEditingHandlerInterface -{ - /** - * @param GetCmsPageCategoryForEditing $query - * - * @return EditableCmsPageCategory - */ - public function handle(GetCmsPageCategoryForEditing $query); -} diff --git a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandlerInterface.php b/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandlerInterface.php deleted file mode 100644 index dad54d91..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageCategoryNameForListingHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryNameForListing; - -/** - * Defines contract for GetCmsPageCategoryNameForListingHandler. - */ -interface GetCmsPageCategoryNameForListingHandlerInterface -{ - /** - * @param GetCmsPageCategoryNameForListing $query - * - * @return string - */ - public function handle(GetCmsPageCategoryNameForListing $query); -} diff --git a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandlerInterface.php b/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandlerInterface.php deleted file mode 100644 index 7554b634..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryHandler/GetCmsPageParentCategoryIdForRedirectionHandlerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageParentCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Interface GetCmsPageParentCategoryIdForRedirectionHandlerInterface defines contract - * for GetCmsPageParentCategoryIdForRedirectionHandler. - */ -interface GetCmsPageParentCategoryIdForRedirectionHandlerInterface -{ - /** - * @param GetCmsPageParentCategoryIdForRedirection $query - * - * @return CmsPageCategoryId - */ - public function handle(GetCmsPageParentCategoryIdForRedirection $query); -} diff --git a/src/Core/Domain/CmsPageCategory/QueryResult/Breadcrumb.php b/src/Core/Domain/CmsPageCategory/QueryResult/Breadcrumb.php deleted file mode 100644 index 89dde026..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryResult/Breadcrumb.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult; - -use ArrayIterator; -use IteratorAggregate; - -/** - * Transfers CMS Page Categories used for breadrumb - */ -class Breadcrumb implements IteratorAggregate -{ - /** - * @var BreadcrumbItem[] - */ - private $cmsPageCategories; - - /** - * @param BreadcrumbItem[] $cmsPageCategories - */ - public function __construct(array $cmsPageCategories) - { - $this->cmsPageCategories = $cmsPageCategories; - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - return new ArrayIterator($this->cmsPageCategories); - } -} diff --git a/src/Core/Domain/CmsPageCategory/QueryResult/BreadcrumbItem.php b/src/Core/Domain/CmsPageCategory/QueryResult/BreadcrumbItem.php deleted file mode 100644 index cd767617..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryResult/BreadcrumbItem.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class CmsPageCategory is responsible for providing cms page id and name combination. - */ -class BreadcrumbItem -{ - /** - * @var CmsPageCategoryId - */ - private $cmsPageCategoryId; - - /** - * @var string - */ - private $name; - - /** - * @param int $cmsPageCategoryId - * @param string $name - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId, $name) - { - $this->cmsPageCategoryId = new CmsPageCategoryId($cmsPageCategoryId); - $this->name = $name; - } - - /** - * @return CmsPageCategoryId - */ - public function getCmsPageCategoryId() - { - return $this->cmsPageCategoryId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } -} diff --git a/src/Core/Domain/CmsPageCategory/QueryResult/EditableCmsPageCategory.php b/src/Core/Domain/CmsPageCategory/QueryResult/EditableCmsPageCategory.php deleted file mode 100644 index 4f22f3df..00000000 --- a/src/Core/Domain/CmsPageCategory/QueryResult/EditableCmsPageCategory.php +++ /dev/null @@ -1,186 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class EditableCmsPageCategory - */ -class EditableCmsPageCategory -{ - /** - * @var array - */ - private $localisedName; - - /** - * @var bool - */ - private $isDisplayed; - - /** - * @var CmsPageCategoryId - */ - private $parentId; - - /** - * @var array - */ - private $localisedDescription; - - /** - * @var array - */ - private $localisedMetaDescription; - - /** - * @var array - */ - private $localisedMetaKeywords; - - /** - * @var array - */ - private $localisedFriendlyUrl; - /** - * @var array - */ - private $metaTitle; - /** - * @var array - */ - private $shopIds; - - /** - * @param array $localisedName - * @param bool $isDisplayed - * @param int $parentId - * @param array $localisedDescription - * @param array $localisedMetaDescription - * @param array $localisedMetaKeywords - * @param array $metaTitle - * @param array $localisedFriendlyUrl - * @param array $shopIds - * - * @throws CmsPageCategoryException - */ - public function __construct( - array $localisedName, - $isDisplayed, - $parentId, - array $localisedDescription, - array $localisedMetaDescription, - array $localisedMetaKeywords, - array $metaTitle, - array $localisedFriendlyUrl, - array $shopIds - ) { - $this->localisedName = $localisedName; - $this->isDisplayed = $isDisplayed; - $this->parentId = new CmsPageCategoryId($parentId); - $this->localisedDescription = $localisedDescription; - $this->localisedMetaDescription = $localisedMetaDescription; - $this->localisedMetaKeywords = $localisedMetaKeywords; - $this->localisedFriendlyUrl = $localisedFriendlyUrl; - $this->metaTitle = $metaTitle; - $this->shopIds = $shopIds; - } - - /** - * @return array - */ - public function getLocalisedName() - { - return $this->localisedName; - } - - /** - * @return bool - */ - public function isDisplayed() - { - return $this->isDisplayed; - } - - /** - * @return CmsPageCategoryId - */ - public function getParentId() - { - return $this->parentId; - } - - /** - * @return array - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @return array - */ - public function getLocalisedMetaDescription() - { - return $this->localisedMetaDescription; - } - - /** - * @return array - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @return array - */ - public function getMetaTitle() - { - return $this->metaTitle; - } - - /** - * @return array - */ - public function getLocalisedFriendlyUrl() - { - return $this->localisedFriendlyUrl; - } - - /** - * @return array - */ - public function getShopIds() - { - return $this->shopIds; - } -} diff --git a/src/Core/Domain/CmsPageCategory/ValueObject/CmsPageCategoryId.php b/src/Core/Domain/CmsPageCategory/ValueObject/CmsPageCategoryId.php deleted file mode 100644 index 2d743aee..00000000 --- a/src/Core/Domain/CmsPageCategory/ValueObject/CmsPageCategoryId.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; - -/** - * Class CmsPageCategoryId is responsible for providing identificator for cms page category - */ -class CmsPageCategoryId -{ - /** - * ID for the topmost Cms Page category - */ - const ROOT_CMS_PAGE_CATEGORY_ID = 1; - - /** - * @var int - */ - private $cmsPageCategoryId; - - /** - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - public function __construct($cmsPageCategoryId) - { - $this->assertIsIntegerGreaterThanZero($cmsPageCategoryId); - $this->cmsPageCategoryId = $cmsPageCategoryId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->cmsPageCategoryId; - } - - /** - * Validates that the value is integer and is greater than zero. - * - * @param int $cmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - private function assertIsIntegerGreaterThanZero($cmsPageCategoryId) - { - if (!is_int($cmsPageCategoryId) || 0 >= $cmsPageCategoryId) { - throw new CmsPageCategoryException(sprintf('Invalid cms page category id %s', var_export($cmsPageCategoryId, true))); - } - } -} diff --git a/src/Core/Domain/Configuration/Command/SwitchDebugModeCommand.php b/src/Core/Domain/Configuration/Command/SwitchDebugModeCommand.php deleted file mode 100644 index 50fc64b9..00000000 --- a/src/Core/Domain/Configuration/Command/SwitchDebugModeCommand.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Configuration\Command; - -/** - * Switches debug mode on/off - */ -class SwitchDebugModeCommand -{ - /** - * @var bool - */ - private $enableDebugMode; - - /** - * @param bool $enableDebugMode - */ - public function __construct($enableDebugMode) - { - $this->enableDebugMode = $enableDebugMode; - } - - /** - * @return bool - */ - public function enableDebugMode() - { - return true === $this->enableDebugMode; - } -} diff --git a/src/Core/Domain/Configuration/CommandHandler/SwitchDebugModeHandlerInterface.php b/src/Core/Domain/Configuration/CommandHandler/SwitchDebugModeHandlerInterface.php deleted file mode 100644 index 5eb45264..00000000 --- a/src/Core/Domain/Configuration/CommandHandler/SwitchDebugModeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Configuration\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Configuration\Command\SwitchDebugModeCommand; - -/** - * Interface for service that implements debug mode switching - */ -interface SwitchDebugModeHandlerInterface -{ - /** - * @param SwitchDebugModeCommand $command - */ - public function handle(SwitchDebugModeCommand $command); -} diff --git a/src/Core/Domain/Configuration/ShopConfigurationInterface.php b/src/Core/Domain/Configuration/ShopConfigurationInterface.php deleted file mode 100644 index a36e1e58..00000000 --- a/src/Core/Domain/Configuration/ShopConfigurationInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Configuration; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject\ShopConstraint; - -interface ShopConfigurationInterface extends ConfigurationInterface -{ - /** - * @param string $key - * @param mixed|null $default - * @param ShopConstraint|null $shopConstraint - * - * @return mixed - */ - public function get($key, $default = null, ShopConstraint $shopConstraint = null); - - /** - * @param string $key - * @param mixed $value - * @param ShopConstraint|null $shopConstraint - * - * @return ShopConfigurationInterface - */ - public function set($key, $value, ShopConstraint $shopConstraint = null); - - /** - * @param string $key - * @param ShopConstraint|null $shopConstraint - * - * @return bool - */ - public function has($key, ShopConstraint $shopConstraint = null); -} diff --git a/src/Core/Domain/Contact/Command/AbstractContactCommand.php b/src/Core/Domain/Contact/Command/AbstractContactCommand.php deleted file mode 100644 index 8d9e2a8f..00000000 --- a/src/Core/Domain/Contact/Command/AbstractContactCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Command; - -/** - * Class AbstractContactCommand is responsible for providing common behavior for AddContactCommand and EditContactCommand. - */ -abstract class AbstractContactCommand -{ - /** - * @param array $values - * - * @return bool - */ - protected function assertIsNotEmptyAndContainsAllNonEmptyStringValues(array $values) - { - $filterNonEmptyStrings = function ($value) { - return is_string($value) && $value; - }; - - return !empty($values) && count($values) === count(array_filter($values, $filterNonEmptyStrings)); - } - - /** - * @param $value - * - * @return false|int - */ - protected function assertIsGenericName($value) - { - return preg_match('/^[^<>={}]*$/u', $value); - } - - /** - * @param array $values - * - * @return bool - */ - protected function assertArrayContainsAllIntegerValues(array $values) - { - $filterAllIntegers = function ($value) { - return is_int($value); - }; - - return !empty($values) && count($values) === count(array_filter($values, $filterAllIntegers)); - } -} diff --git a/src/Core/Domain/Contact/Command/AddContactCommand.php b/src/Core/Domain/Contact/Command/AddContactCommand.php deleted file mode 100644 index 090a1f74..00000000 --- a/src/Core/Domain/Contact/Command/AddContactCommand.php +++ /dev/null @@ -1,178 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Command; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Class AddContactCommand is responsible for adding the contact data. - */ -class AddContactCommand extends AbstractContactCommand -{ - /** - * @var string[] - */ - private $localisedTitles; - - /** - * @var bool - */ - private $isMessageSavingEnabled; - - /** - * @var Email - */ - private $email; - - /** - * @var string[] - */ - private $localisedDescription; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param string[] $localisedTitles - sample: [$langId => $title] - * @param bool $isMessageSavingEnabled - * - * @throws ContactConstraintException - */ - public function __construct(array $localisedTitles, $isMessageSavingEnabled) - { - $this->assertIsLocalisedTitleValid($localisedTitles); - - $this->localisedTitles = $localisedTitles; - $this->isMessageSavingEnabled = $isMessageSavingEnabled; - } - - /** - * @return string[] - */ - public function getLocalisedTitles() - { - return $this->localisedTitles; - } - - /** - * @return bool - */ - public function isMessageSavingEnabled() - { - return $this->isMessageSavingEnabled; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - * - * @return self - * - * @throws DomainConstraintException - */ - public function setEmail($email) - { - $this->email = new Email($email); - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @param string[] $localisedDescription - * - * @return self - */ - public function setLocalisedDescription(array $localisedDescription) - { - $this->localisedDescription = $localisedDescription; - - return $this; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - * - * @throws ContactConstraintException - */ - public function setShopAssociation(array $shopAssociation) - { - if (!$this->assertArrayContainsAllIntegerValues($shopAssociation)) { - throw new ContactConstraintException(sprintf('Given shop association %s must contain all integer values', var_export($shopAssociation, true)), ContactConstraintException::INVALID_SHOP_ASSOCIATION); - } - - $this->shopAssociation = $shopAssociation; - - return $this; - } - - /** - * @param array $localisedTitles - * - * @throws ContactConstraintException - */ - private function assertIsLocalisedTitleValid(array $localisedTitles) - { - if (!$this->assertIsNotEmptyAndContainsAllNonEmptyStringValues($localisedTitles)) { - throw new ContactConstraintException(sprintf('Expected to have not empty titles array but received %s', var_export($localisedTitles, true)), ContactConstraintException::INVALID_TITLE); - } - - foreach ($localisedTitles as $title) { - if (!$this->assertIsGenericName($title)) { - throw new ContactConstraintException(sprintf('Expected value %s to match given regex /^[^<>={}]*$/u but failed', var_export($title, true)), ContactConstraintException::INVALID_TITLE); - } - } - } -} diff --git a/src/Core/Domain/Contact/Command/EditContactCommand.php b/src/Core/Domain/Contact/Command/EditContactCommand.php deleted file mode 100644 index fb7a43cf..00000000 --- a/src/Core/Domain/Contact/Command/EditContactCommand.php +++ /dev/null @@ -1,207 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Command; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Class EditContactCommand is responsible for editing contact data. - */ -class EditContactCommand extends AbstractContactCommand -{ - /** - * @var ContactId - */ - private $contactId; - - /** - * @var string[] - */ - private $localisedTitles; - - /** - * @var Email - */ - private $email; - - /** - * @var bool - */ - private $isMessagesSavingEnabled; - - /** - * @var string[] - */ - private $localisedDescription; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param int $contactId - * - * @throws ContactException - */ - public function __construct($contactId) - { - $this->contactId = new ContactId($contactId); - } - - /** - * @return ContactId - */ - public function getContactId() - { - return $this->contactId; - } - - /** - * @return string[] - */ - public function getLocalisedTitles() - { - return $this->localisedTitles; - } - - /** - * @param string[] $localisedTitles - * - * @return self - * - * @throws ContactConstraintException - */ - public function setLocalisedTitles(array $localisedTitles) - { - if (!$this->assertIsNotEmptyAndContainsAllNonEmptyStringValues($localisedTitles)) { - throw new ContactConstraintException(sprintf('Expected to have not empty titles array but received %s', var_export($localisedTitles, true)), ContactConstraintException::INVALID_TITLE); - } - - foreach ($localisedTitles as $title) { - if (!$this->assertIsGenericName($title)) { - throw new ContactConstraintException(sprintf('Expected value %s to match given regex /^[^<>={}]*$/u but failed', var_export($title, true)), ContactConstraintException::INVALID_TITLE); - } - } - - $this->localisedTitles = $localisedTitles; - - return $this; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - * - * @return self - * - * @throws DomainConstraintException - */ - public function setEmail($email) - { - $this->email = new Email($email); - - return $this; - } - - /** - * @return bool - */ - public function isMessagesSavingEnabled() - { - return $this->isMessagesSavingEnabled; - } - - /** - * @param bool $isMessagesSavingEnabled - * - * @return self - */ - public function setIsMessagesSavingEnabled($isMessagesSavingEnabled) - { - $this->isMessagesSavingEnabled = $isMessagesSavingEnabled; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @param string[] $localisedDescription - * - * @return self - */ - public function setLocalisedDescription(array $localisedDescription) - { - $this->localisedDescription = $localisedDescription; - - return $this; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - * - * @throws ContactConstraintException - */ - public function setShopAssociation(array $shopAssociation) - { - if (!$this->assertArrayContainsAllIntegerValues($shopAssociation)) { - throw new ContactConstraintException(sprintf('Given shop association %s must contain all integer values', var_export($shopAssociation, true)), ContactConstraintException::INVALID_SHOP_ASSOCIATION); - } - - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/Contact/CommandHandler/AddContactHandlerInterface.php b/src/Core/Domain/Contact/CommandHandler/AddContactHandlerInterface.php deleted file mode 100644 index 8bb1cdc0..00000000 --- a/src/Core/Domain/Contact/CommandHandler/AddContactHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\AddContactCommand; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; - -/** - * Interface AddContactHandlerInterface defines contract for AddContactHandler. - */ -interface AddContactHandlerInterface -{ - /** - * @param AddContactCommand $command - * - * @return ContactId - */ - public function handle(AddContactCommand $command); -} diff --git a/src/Core/Domain/Contact/CommandHandler/EditContactHandlerInterface.php b/src/Core/Domain/Contact/CommandHandler/EditContactHandlerInterface.php deleted file mode 100644 index e434a90b..00000000 --- a/src/Core/Domain/Contact/CommandHandler/EditContactHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\EditContactCommand; - -/** - * Interface EditContactHandlerInterface defines contract for EditContactHandler. - */ -interface EditContactHandlerInterface -{ - /** - * @param EditContactCommand $command - */ - public function handle(EditContactCommand $command); -} diff --git a/src/Core/Domain/Contact/Exception/CannotAddContactException.php b/src/Core/Domain/Contact/Exception/CannotAddContactException.php deleted file mode 100644 index cd4d6560..00000000 --- a/src/Core/Domain/Contact/Exception/CannotAddContactException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Exception; - -/** - * Raised when failed to add contact entity. - */ -class CannotAddContactException extends ContactException -{ -} diff --git a/src/Core/Domain/Contact/Exception/CannotUpdateContactException.php b/src/Core/Domain/Contact/Exception/CannotUpdateContactException.php deleted file mode 100644 index 10eb5b16..00000000 --- a/src/Core/Domain/Contact/Exception/CannotUpdateContactException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Exception; - -/** - * Raised when failed to update contact entity. - */ -class CannotUpdateContactException extends ContactException -{ -} diff --git a/src/Core/Domain/Contact/Exception/ContactConstraintException.php b/src/Core/Domain/Contact/Exception/ContactConstraintException.php deleted file mode 100644 index d4cfbb0b..00000000 --- a/src/Core/Domain/Contact/Exception/ContactConstraintException.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Exception; - -/** - * holds all validation constraints that are used together with contact entity. - */ -class ContactConstraintException extends ContactException -{ - /** - * @var int - error is raised when preg match fails to validate according to regex /^[^<>={}]*$/u - */ - const INVALID_TITLE = 1; - - /** - * @var int - error is raised when a value in array is not integer type - */ - const INVALID_SHOP_ASSOCIATION = 2; - - /** - * @var int - error is raised when CleanHtml constraint validation fails - */ - const INVALID_DESCRIPTION = 3; - - /** - * @var int - error is raised when an array does not have the default language value. It might not exist or is empty. - * DefaultLanguage constraint is used here. - */ - const MISSING_TITLE_FOR_DEFAULT_LANGUAGE = 4; -} diff --git a/src/Core/Domain/Contact/Exception/ContactException.php b/src/Core/Domain/Contact/Exception/ContactException.php deleted file mode 100644 index b6872245..00000000 --- a/src/Core/Domain/Contact/Exception/ContactException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * An abstraction for all contact related exceptions. Use this one in catch clause to detect all related exceptions. - */ -class ContactException extends DomainException -{ -} diff --git a/src/Core/Domain/Contact/Exception/ContactNotFoundException.php b/src/Core/Domain/Contact/Exception/ContactNotFoundException.php deleted file mode 100644 index f6a4f9ef..00000000 --- a/src/Core/Domain/Contact/Exception/ContactNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Exception; - -/** - * Raised when contact was not found. - */ -class ContactNotFoundException extends ContactException -{ -} diff --git a/src/Core/Domain/Contact/Query/GetContactForEditing.php b/src/Core/Domain/Contact/Query/GetContactForEditing.php deleted file mode 100644 index 5b00ce6e..00000000 --- a/src/Core/Domain/Contact/Query/GetContactForEditing.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\Query; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; - -/** - * Class GetContactForEditing is responsible for getting the data related with contact entity. - */ -class GetContactForEditing -{ - /** @var ContactId */ - private $contactId; - - /** - * @param int $contactId - * - * @throws ContactException - */ - public function __construct($contactId) - { - $this->contactId = new ContactId($contactId); - } - - /** - * @return ContactId - */ - public function getContactId() - { - return $this->contactId; - } -} diff --git a/src/Core/Domain/Contact/QueryHandler/GetContactForEditingHandlerInterface.php b/src/Core/Domain/Contact/QueryHandler/GetContactForEditingHandlerInterface.php deleted file mode 100644 index d2a1996c..00000000 --- a/src/Core/Domain/Contact/QueryHandler/GetContactForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Query\GetContactForEditing; -use PrestaShop\PrestaShop\Core\Domain\Contact\QueryResult\EditableContact; - -/** - * Interface GetContactForEditingHandlerInterface defines contract for GetContactForEditingHandler - */ -interface GetContactForEditingHandlerInterface -{ - /** - * @param GetContactForEditing $query - * - * @return EditableContact - */ - public function handle(GetContactForEditing $query); -} diff --git a/src/Core/Domain/Contact/QueryResult/EditableContact.php b/src/Core/Domain/Contact/QueryResult/EditableContact.php deleted file mode 100644 index 0fd1bffb..00000000 --- a/src/Core/Domain/Contact/QueryResult/EditableContact.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Transfers contact data for editing. - */ -class EditableContact -{ - /** - * @var ContactId - */ - private $contactId; - - /** - * @var array|string[] - */ - private $localisedTitles; - - /** - * @var Email|null - */ - private $email; - - /** - * @var bool - */ - private $isMessagesSavingEnabled; - - /** - * @var string[] - */ - private $localisedDescription; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param int $contactId - * @param string[] $localisedTitles - * @param string $email - * @param bool $isMessagesSavingEnabled - * @param string[] $localisedDescription - * @param int[] $shopAssociation - * - * @throws ContactException - * @throws DomainConstraintException - */ - public function __construct( - $contactId, - array $localisedTitles, - $email, - $isMessagesSavingEnabled, - $localisedDescription, - array $shopAssociation - ) { - $this->contactId = new ContactId($contactId); - $this->localisedTitles = $localisedTitles; - $this->isMessagesSavingEnabled = $isMessagesSavingEnabled; - $this->localisedDescription = $localisedDescription; - $this->contactId = $contactId; - $this->shopAssociation = $shopAssociation; - $this->email = $email ? new Email($email) : null; - } - - /** - * @return ContactId - */ - public function getContactId() - { - return $this->contactId; - } - - /** - * @return string[] - */ - public function getLocalisedTitles() - { - return $this->localisedTitles; - } - - /** - * @return Email|null - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return bool - */ - public function isMessagesSavingEnabled() - { - return $this->isMessagesSavingEnabled; - } - - /** - * @return string[] - */ - public function getLocalisedDescription() - { - return $this->localisedDescription; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } -} diff --git a/src/Core/Domain/Contact/ValueObject/ContactId.php b/src/Core/Domain/Contact/ValueObject/ContactId.php deleted file mode 100644 index 54a9144a..00000000 --- a/src/Core/Domain/Contact/ValueObject/ContactId.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; - -/** - * Class ContactId - */ -class ContactId -{ - /** - * @var int - */ - private $contactId; - - /** - * @param int $contactId - * - * @throws ContactException - */ - public function __construct($contactId) - { - $this->assertIsIntegerOrMoreThanZero($contactId); - - $this->contactId = $contactId; - } - - /** - * @param $contactId - * - * @throws ContactException - */ - private function assertIsIntegerOrMoreThanZero($contactId) - { - if (!is_int($contactId) || 0 >= $contactId) { - throw new ContactException(sprintf('Invalid Contact id: %s', var_export($contactId, true))); - } - } - - /** - * @return int - */ - public function getValue() - { - return $this->contactId; - } -} diff --git a/src/Core/Domain/Country/Exception/CountryConstraintException.php b/src/Core/Domain/Country/Exception/CountryConstraintException.php deleted file mode 100644 index b3dcab0e..00000000 --- a/src/Core/Domain/Country/Exception/CountryConstraintException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\Exception; - -/** - * Is thrown when country constraint is violated - */ -class CountryConstraintException extends CountryException -{ - public const INVALID_ID = 1; -} diff --git a/src/Core/Domain/Country/Exception/CountryException.php b/src/Core/Domain/Country/Exception/CountryException.php deleted file mode 100644 index b9143192..00000000 --- a/src/Core/Domain/Country/Exception/CountryException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for countries subdomain - */ -class CountryException extends DomainException -{ -} diff --git a/src/Core/Domain/Country/Exception/CountryNotFoundException.php b/src/Core/Domain/Country/Exception/CountryNotFoundException.php deleted file mode 100644 index 4c2e8e50..00000000 --- a/src/Core/Domain/Country/Exception/CountryNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\Exception; - -/** - * Is thrown on failure to find existing country - */ -class CountryNotFoundException extends CountryException -{ -} diff --git a/src/Core/Domain/Country/Query/GetCountryRequiredFields.php b/src/Core/Domain/Country/Query/GetCountryRequiredFields.php deleted file mode 100644 index 1cd90077..00000000 --- a/src/Core/Domain/Country/Query/GetCountryRequiredFields.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\Query; - -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId; - -/** - * Query for getting country required fields - */ -class GetCountryRequiredFields -{ - /** - * @var CountryId - */ - private $countryId; - - /** - * @param int $countryId - * - * @throws CountryConstraintException - */ - public function __construct(int $countryId) - { - $this->countryId = new CountryId($countryId); - } - - /** - * @return CountryId - */ - public function getCountryId(): CountryId - { - return $this->countryId; - } -} diff --git a/src/Core/Domain/Country/QueryHandler/GetCountryRequiredFieldsHandlerInterface.php b/src/Core/Domain/Country/QueryHandler/GetCountryRequiredFieldsHandlerInterface.php deleted file mode 100644 index db1d0cfe..00000000 --- a/src/Core/Domain/Country/QueryHandler/GetCountryRequiredFieldsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Country\Query\GetCountryRequiredFields; -use PrestaShop\PrestaShop\Core\Domain\Country\QueryResult\CountryRequiredFields; - -/** - * Defines contract for country required fields handler - */ -interface GetCountryRequiredFieldsHandlerInterface -{ - /** - * @param GetCountryRequiredFields $query - * - * @return CountryRequiredFields - */ - public function handle(GetCountryRequiredFields $query): CountryRequiredFields; -} diff --git a/src/Core/Domain/Country/QueryResult/CountryRequiredFields.php b/src/Core/Domain/Country/QueryResult/CountryRequiredFields.php deleted file mode 100644 index bd6fdaa8..00000000 --- a/src/Core/Domain/Country/QueryResult/CountryRequiredFields.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\QueryResult; - -/** - * Stores data about address fields which are required by country - */ -class CountryRequiredFields -{ - /** @var bool */ - private $stateRequired; - - /** @var bool */ - private $dniRequired; - - /** - * @param bool $stateRequired - * @param bool $dniRequired - */ - public function __construct(bool $stateRequired, bool $dniRequired) - { - $this->stateRequired = $stateRequired; - $this->dniRequired = $dniRequired; - } - - /** - * @return bool - */ - public function isStateRequired(): bool - { - return $this->stateRequired; - } - - /** - * @return bool - */ - public function isDniRequired(): bool - { - return $this->dniRequired; - } -} diff --git a/src/Core/Domain/Country/ValueObject/CountryId.php b/src/Core/Domain/Country/ValueObject/CountryId.php deleted file mode 100644 index 50740d32..00000000 --- a/src/Core/Domain/Country/ValueObject/CountryId.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; - -/** - * Provides country id value - */ -class CountryId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - * - * @throws CountryConstraintException - */ - public function __construct(int $id) - { - $this->assertPositiveInt($id); - $this->id = $id; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->id; - } - - /** - * @param int $value - * - * @throws CountryConstraintException - */ - private function assertPositiveInt(int $value) - { - if (0 > $value) { - throw new CountryConstraintException(sprintf('Invalid country id "%s".', var_export($value, true)), CountryConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Country/ZipCodePatternResolver.php b/src/Core/Domain/Country/ZipCodePatternResolver.php deleted file mode 100644 index abfd371a..00000000 --- a/src/Core/Domain/Country/ZipCodePatternResolver.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country; - -/** - * Call responsible for resolving country zip code format and returning it as other usable patterns - */ -final class ZipCodePatternResolver implements ZipCodePatternResolverInterface -{ - /** - * @param string $format - * @param string $isoCode - * - * @return string - */ - public function getRegexPattern(string $format, string $isoCode): string - { - return str_replace(['N', 'L', 'C'], ['[0-9]', '[a-zA-Z]', $isoCode], '/^' . $format . '$/ui'); - } - - /** - * @param string $format - * @param string $isoCode - * - * @return string - */ - public function getHumanReadablePattern(string $format, string $isoCode): string - { - return str_replace(['N', 'L', 'C'], ['0', 'A', $isoCode], $format); - } -} diff --git a/src/Core/Domain/Country/ZipCodePatternResolverInterface.php b/src/Core/Domain/Country/ZipCodePatternResolverInterface.php deleted file mode 100644 index eb2f23ca..00000000 --- a/src/Core/Domain/Country/ZipCodePatternResolverInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Country; - -/** - * Call responsible for resolving country zip code format and returning it as other usable patterns - */ -interface ZipCodePatternResolverInterface -{ - /** - * @param string $format - * @param string $isoCode - * - * @return string - */ - public function getRegexPattern(string $format, string $isoCode): string; - - /** - * @param string $format - * @param string $isoCode - * - * @return string - */ - public function getHumanReadablePattern(string $format, string $isoCode): string; -} diff --git a/src/Core/Domain/CreditSlip/Exception/CreditSlipConstraintException.php b/src/Core/Domain/CreditSlip/Exception/CreditSlipConstraintException.php deleted file mode 100644 index deaa0582..00000000 --- a/src/Core/Domain/CreditSlip/Exception/CreditSlipConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception; - -/** - * Is thrown when credit slip constraints are violated - */ -class CreditSlipConstraintException extends CreditSlipException -{ - /** - * When id value is not valid - */ - const INVALID_ID = 10; -} diff --git a/src/Core/Domain/CreditSlip/Exception/CreditSlipException.php b/src/Core/Domain/CreditSlip/Exception/CreditSlipException.php deleted file mode 100644 index 1e7b48ab..00000000 --- a/src/Core/Domain/CreditSlip/Exception/CreditSlipException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base class for CreditSlip subdomain - */ -class CreditSlipException extends DomainException -{ -} diff --git a/src/Core/Domain/CreditSlip/Exception/CreditSlipNotFoundException.php b/src/Core/Domain/CreditSlip/Exception/CreditSlipNotFoundException.php deleted file mode 100644 index 02459a46..00000000 --- a/src/Core/Domain/CreditSlip/Exception/CreditSlipNotFoundException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception; - -/** - * Thrown when requested credit slip/slips are not found - */ -class CreditSlipNotFoundException extends CreditSlipException -{ - /** - * Thrown when no credit slips are found when querying by specific date range - */ - const BY_DATE_RANGE = 1; -} diff --git a/src/Core/Domain/CreditSlip/Query/GetCreditSlipIdsByDateRange.php b/src/Core/Domain/CreditSlip/Query/GetCreditSlipIdsByDateRange.php deleted file mode 100644 index e42b5074..00000000 --- a/src/Core/Domain/CreditSlip/Query/GetCreditSlipIdsByDateRange.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\Query; - -use DateTime; - -/** - * Gets CreditSlipIds for provided date range - */ -final class GetCreditSlipIdsByDateRange -{ - /** - * @var DateTime - */ - private $dateTimeFrom; - - /** - * @var DateTime - */ - private $dateTimeTo; - - /** - * @param DateTime $dateTimeFrom - * @param DateTime $dateTimeTo - */ - public function __construct(DateTime $dateTimeFrom, DateTime $dateTimeTo) - { - $this->dateTimeFrom = $dateTimeFrom; - $this->dateTimeTo = $dateTimeTo; - } - - /** - * @return DateTime - */ - public function getDateTimeFrom() - { - return $this->dateTimeFrom; - } - - /** - * @return DateTime - */ - public function getDateTimeTo() - { - return $this->dateTimeTo; - } -} diff --git a/src/Core/Domain/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandlerInterface.php b/src/Core/Domain/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandlerInterface.php deleted file mode 100644 index c10370c5..00000000 --- a/src/Core/Domain/CreditSlip/QueryHandler/GetCreditSlipIdsByDateRangeHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\Query\GetCreditSlipIdsByDateRange; -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\ValueObject\CreditSlipId; - -/** - * Interface for handling GetCreditSlipIdsByDateRange query - */ -interface GetCreditSlipIdsByDateRangeHandlerInterface -{ - /** - * @param GetCreditSlipIdsByDateRange $query - * - * @return CreditSlipId[] - */ - public function handle(GetCreditSlipIdsByDateRange $query); -} diff --git a/src/Core/Domain/CreditSlip/ValueObject/CreditSlipId.php b/src/Core/Domain/CreditSlip/ValueObject/CreditSlipId.php deleted file mode 100644 index 3700f81d..00000000 --- a/src/Core/Domain/CreditSlip/ValueObject/CreditSlipId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CreditSlip\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CreditSlip\Exception\CreditSlipConstraintException; - -/** - * Provides identification data for Credit slip - */ -final class CreditSlipId -{ - /** - * @var int - */ - private $creditSlipId; - - /** - * @param int $creditSlipId - * - * @throws CreditSlipConstraintException - */ - public function __construct($creditSlipId) - { - $this->assertIsIntegerGreaterThanZero($creditSlipId); - $this->creditSlipId = $creditSlipId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->creditSlipId; - } - - /** - * Validates that the value is integer and is greater than zero - * - * @param $value - * - * @throws CreditSlipConstraintException - */ - private function assertIsIntegerGreaterThanZero($value) - { - if (!is_int($value) || 0 >= $value) { - throw new CreditSlipConstraintException(sprintf('Invalid credit slip id "%s".', var_export($value, true))); - } - } -} diff --git a/src/Core/Domain/Currency/Command/AddCurrencyCommand.php b/src/Core/Domain/Currency/Command/AddCurrencyCommand.php deleted file mode 100644 index c1a1ea7c..00000000 --- a/src/Core/Domain/Currency/Command/AddCurrencyCommand.php +++ /dev/null @@ -1,235 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\ExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\Precision; - -/** - * Class AddCurrencyCommand used to add an official currency - */ -class AddCurrencyCommand -{ - /** - * @var AlphaIsoCode - */ - protected $isoCode; - - /** - * @var ExchangeRate - */ - protected $exchangeRate; - - /** - * @var Precision|null - */ - protected $precision; - - /** - * @var string[] - */ - protected $localizedNames = []; - - /** - * @var string[] - */ - protected $localizedSymbols = []; - - /** - * @var bool - */ - protected $isEnabled; - - /** - * @var int[] - */ - protected $shopIds = []; - - /** - * @var string[] - */ - protected $localizedTransformations = []; - - /** - * @param string $isoCode - * @param float $exchangeRate - * @param bool $isEnabled - * - * @throws CurrencyConstraintException - */ - public function __construct( - $isoCode, - $exchangeRate, - $isEnabled - ) { - $this->isoCode = new AlphaIsoCode($isoCode); - $this->exchangeRate = new ExchangeRate($exchangeRate); - $this->isEnabled = $isEnabled; - } - - /** - * @return AlphaIsoCode - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @return Precision|null - */ - public function getPrecision(): ?Precision - { - return $this->precision; - } - - /** - * @param int|string $precision - * - * @return self - * - * @throws CurrencyConstraintException - */ - public function setPrecision($precision): AddCurrencyCommand - { - $this->precision = new Precision($precision); - - return $this; - } - - /** - * @return ExchangeRate - */ - public function getExchangeRate() - { - return $this->exchangeRate; - } - - /** - * @return string[] - */ - public function getLocalizedNames(): array - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames currency's localized names, indexed by language id - * - * @return $this - * - * @throws CurrencyConstraintException - */ - public function setLocalizedNames(array $localizedNames): AddCurrencyCommand - { - if (empty($localizedNames)) { - throw new CurrencyConstraintException('Currency name cannot be empty', CurrencyConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedSymbols(): array - { - return $this->localizedSymbols; - } - - /** - * @param string[] $localizedSymbols currency's localized symbols, indexed by language id - * - * @return $this - * - * @throws CurrencyConstraintException - */ - public function setLocalizedSymbols(array $localizedSymbols): AddCurrencyCommand - { - if (empty($localizedSymbols)) { - throw new CurrencyConstraintException('Currency symbol cannot be empty', CurrencyConstraintException::EMPTY_SYMBOL); - } - - $this->localizedSymbols = $localizedSymbols; - - return $this; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * @return int[] - */ - public function getShopIds() - { - return $this->shopIds; - } - - /** - * @param int[] $shopIds - * - * @return self - */ - public function setShopIds(array $shopIds) - { - $this->shopIds = $shopIds; - - return $this; - } - - /** - * Returns the currency's localized transformations, indexed by language id - * - * @return string[] - */ - public function getLocalizedTransformations(): array - { - return $this->localizedTransformations; - } - - /** - * @param string[] $localizedTransformations currency's localized transformations, indexed by language id - * - * @return $this - */ - public function setLocalizedTransformations(array $localizedTransformations): AddCurrencyCommand - { - $this->localizedTransformations = $localizedTransformations; - - return $this; - } -} diff --git a/src/Core/Domain/Currency/Command/AddUnofficialCurrencyCommand.php b/src/Core/Domain/Currency/Command/AddUnofficialCurrencyCommand.php deleted file mode 100644 index 5cca9920..00000000 --- a/src/Core/Domain/Currency/Command/AddUnofficialCurrencyCommand.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -/** - * Class AddUnofficialCurrencyCommand used to add an alternative currency - */ -class AddUnofficialCurrencyCommand extends AddCurrencyCommand -{ -} diff --git a/src/Core/Domain/Currency/Command/DeleteCurrencyCommand.php b/src/Core/Domain/Currency/Command/DeleteCurrencyCommand.php deleted file mode 100644 index b656734f..00000000 --- a/src/Core/Domain/Currency/Command/DeleteCurrencyCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Class DeleteCurrencyCommand is responsible for deleting Currency. - */ -class DeleteCurrencyCommand -{ - /** - * @var CurrencyId - */ - private $currencyId; - - /** - * @param int $currencyId - * - * @throws CurrencyException - */ - public function __construct($currencyId) - { - $this->currencyId = new CurrencyId($currencyId); - } - - /** - * @return CurrencyId - */ - public function getCurrencyId() - { - return $this->currencyId; - } -} diff --git a/src/Core/Domain/Currency/Command/EditCurrencyCommand.php b/src/Core/Domain/Currency/Command/EditCurrencyCommand.php deleted file mode 100644 index b2b33250..00000000 --- a/src/Core/Domain/Currency/Command/EditCurrencyCommand.php +++ /dev/null @@ -1,255 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\ExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\Precision; - -/** - * Class EditCurrencyCommand - */ -class EditCurrencyCommand -{ - /** - * @var CurrencyId - */ - protected $currencyId; - - /** - * @var ExchangeRate|null - */ - protected $exchangeRate; - - /** - * @var Precision|null - */ - protected $precision; - - /** - * @var string[] - */ - protected $localizedNames = []; - - /** - * @var string[] - */ - protected $localizedSymbols = []; - - /** - * @var bool - */ - protected $isEnabled; - - /** - * @var int[] - */ - protected $shopIds = []; - - /** - * @var string[] - */ - protected $localizedTransformations = []; - - /** - * @param int $currencyId - * - * @throws CurrencyException - */ - public function __construct($currencyId) - { - $this->currencyId = new CurrencyId($currencyId); - } - - /** - * @return CurrencyId - */ - public function getCurrencyId() - { - return $this->currencyId; - } - - /** - * @return ExchangeRate|null - */ - public function getExchangeRate() - { - return $this->exchangeRate; - } - - /** - * @param float $exchangeRate - * - * @return self - * - * @throws CurrencyConstraintException - */ - public function setExchangeRate($exchangeRate) - { - $this->exchangeRate = new ExchangeRate($exchangeRate); - - return $this; - } - - /** - * @return Precision|null - */ - public function getPrecision(): ?Precision - { - return $this->precision; - } - - /** - * @param int|string $precision - * - * @return self - * - * @throws CurrencyConstraintException - */ - public function setPrecision($precision): EditCurrencyCommand - { - $this->precision = new Precision($precision); - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedNames(): array - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames currency's localized names, indexed by language id - * - * @return $this - * - * @throws CurrencyConstraintException - */ - public function setLocalizedNames(array $localizedNames): EditCurrencyCommand - { - if (empty($localizedNames)) { - throw new CurrencyConstraintException('Currency name cannot be empty', CurrencyConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalizedSymbols() - { - return $this->localizedSymbols; - } - - /** - * @param string[] $localizedSymbols currency's localized symbols, indexed by language id - * - * @return $this - * - * @throws CurrencyConstraintException - */ - public function setLocalizedSymbols(array $localizedSymbols): EditCurrencyCommand - { - if (empty($localizedSymbols)) { - throw new CurrencyConstraintException('Currency symbol cannot be empty', CurrencyConstraintException::EMPTY_SYMBOL); - } - - $this->localizedSymbols = $localizedSymbols; - - return $this; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * @param bool $isEnabled - * - * @return self - */ - public function setIsEnabled($isEnabled) - { - $this->isEnabled = $isEnabled; - - return $this; - } - - /** - * @return int[] - */ - public function getShopIds() - { - return $this->shopIds; - } - - /** - * @param int[] $shopIds - * - * @return self - */ - public function setShopIds(array $shopIds) - { - $this->shopIds = $shopIds; - - return $this; - } - - /** - * Returns the currency's localized transformations, indexed by language id - * - * @return string[] - */ - public function getLocalizedTransformations(): array - { - return $this->localizedTransformations; - } - - /** - * @param string[] $localizedTransformations currency's localized transformations, indexed by language id - * - * @return $this - */ - public function setLocalizedTransformations(array $localizedTransformations): EditCurrencyCommand - { - $this->localizedTransformations = $localizedTransformations; - - return $this; - } -} diff --git a/src/Core/Domain/Currency/Command/EditUnofficialCurrencyCommand.php b/src/Core/Domain/Currency/Command/EditUnofficialCurrencyCommand.php deleted file mode 100644 index 8b029b81..00000000 --- a/src/Core/Domain/Currency/Command/EditUnofficialCurrencyCommand.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; - -class EditUnofficialCurrencyCommand extends EditCurrencyCommand -{ - /** - * @var AlphaIsoCode|null - */ - private $isoCode; - - /** - * @return AlphaIsoCode|null - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - * - * @return self - * - * @throws CurrencyConstraintException - */ - public function setIsoCode($isoCode) - { - $this->isoCode = new AlphaIsoCode($isoCode); - - return $this; - } -} diff --git a/src/Core/Domain/Currency/Command/RefreshExchangeRatesCommand.php b/src/Core/Domain/Currency/Command/RefreshExchangeRatesCommand.php deleted file mode 100644 index 9d89554f..00000000 --- a/src/Core/Domain/Currency/Command/RefreshExchangeRatesCommand.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -/** - * Class RefreshExchangeRatesCommand - */ -class RefreshExchangeRatesCommand -{ -} diff --git a/src/Core/Domain/Currency/Command/ToggleCurrencyStatusCommand.php b/src/Core/Domain/Currency/Command/ToggleCurrencyStatusCommand.php deleted file mode 100644 index 336d2351..00000000 --- a/src/Core/Domain/Currency/Command/ToggleCurrencyStatusCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Class ToggleCurrencyStatusCommand is responsible for changing the status of the currency. - */ -class ToggleCurrencyStatusCommand -{ - /** - * @var CurrencyId - */ - private $currencyId; - - /** - * @param int $currencyId - * - * @throws CurrencyException - */ - public function __construct($currencyId) - { - $this->currencyId = new CurrencyId($currencyId); - } - - /** - * @return CurrencyId - */ - public function getCurrencyId() - { - return $this->currencyId; - } -} diff --git a/src/Core/Domain/Currency/Command/ToggleExchangeRateAutomatizationCommand.php b/src/Core/Domain/Currency/Command/ToggleExchangeRateAutomatizationCommand.php deleted file mode 100644 index a61467ce..00000000 --- a/src/Core/Domain/Currency/Command/ToggleExchangeRateAutomatizationCommand.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; - -/** - * Class ToggleExchangeRateAutomatizationCommand is responsible for turning on or off the setting - if its on then - * in CronJobs module it creates new record with url which points to the script which is being executed at certain time - * of period. If the setting is off then it removes that record. - */ -class ToggleExchangeRateAutomatizationCommand -{ - /** - * @var bool - */ - private $exchangeRateStatus; - - /** - * @param bool $exchangeRateStatus - * - * @throws CurrencyConstraintException - */ - public function __construct($exchangeRateStatus) - { - $this->assertIsBool($exchangeRateStatus); - - $this->exchangeRateStatus = $exchangeRateStatus; - } - - /** - * @return bool - */ - public function exchangeRateStatus() - { - return $this->exchangeRateStatus; - } - - /** - * @param bool $isExchangeRateEnabled - * - * @throws CurrencyConstraintException - */ - private function assertIsBool($isExchangeRateEnabled) - { - if (!is_bool($isExchangeRateEnabled)) { - throw new CurrencyConstraintException(sprintf('Unexpected type of live exchange rates. Expected bool, got "%s"', var_export($isExchangeRateEnabled, true)), CurrencyConstraintException::INVALID_LIVE_EXCHANGE_RATES); - } - } -} diff --git a/src/Core/Domain/Currency/CommandHandler/AddCurrencyHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/AddCurrencyHandlerInterface.php deleted file mode 100644 index b4084068..00000000 --- a/src/Core/Domain/Currency/CommandHandler/AddCurrencyHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Interface AddCurrencyHandlerInterface defines contract for AddOfficialCurrencyHandler - */ -interface AddCurrencyHandlerInterface -{ - /** - * @param AddCurrencyCommand $command - * - * @return CurrencyId - */ - public function handle(AddCurrencyCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/AddUnofficialCurrencyHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/AddUnofficialCurrencyHandlerInterface.php deleted file mode 100644 index 25c1f0b0..00000000 --- a/src/Core/Domain/Currency/CommandHandler/AddUnofficialCurrencyHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddUnofficialCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Interface AddUnofficialCurrencyHandlerInterface defines contract for AddUnofficialCurrencyHandler - */ -interface AddUnofficialCurrencyHandlerInterface -{ - /** - * @param AddUnofficialCurrencyCommand $command - * - * @return CurrencyId - */ - public function handle(AddUnofficialCurrencyCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/DeleteCurrencyHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/DeleteCurrencyHandlerInterface.php deleted file mode 100644 index e8d7a6dc..00000000 --- a/src/Core/Domain/Currency/CommandHandler/DeleteCurrencyHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\DeleteCurrencyCommand; - -/** - * Interface DeleteCurrencyHandlerInterface defines contract for DeleteCurrencyHandler. - */ -interface DeleteCurrencyHandlerInterface -{ - /** - * Handles the deletion logic of currency. - * - * @param DeleteCurrencyCommand $command - */ - public function handle(DeleteCurrencyCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/EditCurrencyHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/EditCurrencyHandlerInterface.php deleted file mode 100644 index 11c3e2d0..00000000 --- a/src/Core/Domain/Currency/CommandHandler/EditCurrencyHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand; - -/** - * Interface EditCurrencyHandlerInterface defines contract for UpdateCurrencyHandler. - */ -interface EditCurrencyHandlerInterface -{ - /** - * @param EditCurrencyCommand $command - */ - public function handle(EditCurrencyCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/EditUnofficialCurrencyHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/EditUnofficialCurrencyHandlerInterface.php deleted file mode 100644 index 93039723..00000000 --- a/src/Core/Domain/Currency/CommandHandler/EditUnofficialCurrencyHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditUnofficialCurrencyCommand; - -/** - * Interface EditUnofficialCurrencyHandlerInterface defines contract for UpdateCurrencyHandler. - */ -interface EditUnofficialCurrencyHandlerInterface -{ - /** - * @param EditUnofficialCurrencyCommand $command - */ - public function handle(EditUnofficialCurrencyCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/RefreshExchangeRatesHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/RefreshExchangeRatesHandlerInterface.php deleted file mode 100644 index 91744c27..00000000 --- a/src/Core/Domain/Currency/CommandHandler/RefreshExchangeRatesHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\RefreshExchangeRatesCommand; - -/** - * Interface RefreshExchangeRatesHandlerInterface defines contract for UpdateExchangeRatesHandler. - */ -interface RefreshExchangeRatesHandlerInterface -{ - /** - * @param RefreshExchangeRatesCommand $command - */ - public function handle(RefreshExchangeRatesCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/ToggleCurrencyStatusHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/ToggleCurrencyStatusHandlerInterface.php deleted file mode 100644 index ae9f6ef5..00000000 --- a/src/Core/Domain/Currency/CommandHandler/ToggleCurrencyStatusHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleCurrencyStatusCommand; - -/** - * Interface ToggleCurrencyStatusHandlerInterface defines contract for ToggleCurrencyStatusHandler. - */ -interface ToggleCurrencyStatusHandlerInterface -{ - /** - * Handles currency status toggling logic. - * - * @param ToggleCurrencyStatusCommand $command - */ - public function handle(ToggleCurrencyStatusCommand $command); -} diff --git a/src/Core/Domain/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandlerInterface.php b/src/Core/Domain/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandlerInterface.php deleted file mode 100644 index bcd60a6c..00000000 --- a/src/Core/Domain/Currency/CommandHandler/ToggleExchangeRateAutomatizationHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleExchangeRateAutomatizationCommand; - -/** - * Interface ToggleExchangeRateAutomatizationHandlerInterface defines contract for UpdateLiveExchangeRatesHandler. - */ -interface ToggleExchangeRateAutomatizationHandlerInterface -{ - /** - * @param ToggleExchangeRateAutomatizationCommand $command - */ - public function handle(ToggleExchangeRateAutomatizationCommand $command); -} diff --git a/src/Core/Domain/Currency/Exception/AutomateExchangeRatesUpdateException.php b/src/Core/Domain/Currency/Exception/AutomateExchangeRatesUpdateException.php deleted file mode 100644 index 646e8372..00000000 --- a/src/Core/Domain/Currency/Exception/AutomateExchangeRatesUpdateException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Thrown on currency exchange rates automatic update failure - */ -class AutomateExchangeRatesUpdateException extends CurrencyException -{ - const CRON_TASK_CREATION_FAILED = 1; - const CRON_TASK_MANAGER_MODULE_NOT_INSTALLED = 2; -} diff --git a/src/Core/Domain/Currency/Exception/CannotCreateCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotCreateCurrencyException.php deleted file mode 100644 index ab0976a8..00000000 --- a/src/Core/Domain/Currency/Exception/CannotCreateCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when new currency cannot be created - */ -class CannotCreateCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotDeleteCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotDeleteCurrencyException.php deleted file mode 100644 index 0e3bc339..00000000 --- a/src/Core/Domain/Currency/Exception/CannotDeleteCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown on failure while deleting currency - */ -class CannotDeleteCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotDeleteDefaultCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotDeleteDefaultCurrencyException.php deleted file mode 100644 index 0083d117..00000000 --- a/src/Core/Domain/Currency/Exception/CannotDeleteDefaultCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when currency cannot be deleted because it is default - */ -class CannotDeleteDefaultCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotDisableDefaultCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotDisableDefaultCurrencyException.php deleted file mode 100644 index 4ca12731..00000000 --- a/src/Core/Domain/Currency/Exception/CannotDisableDefaultCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when currency cannot be disabled because it is default - */ -class CannotDisableDefaultCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotRefreshExchangeRatesException.php b/src/Core/Domain/Currency/Exception/CannotRefreshExchangeRatesException.php deleted file mode 100644 index ffe30cbe..00000000 --- a/src/Core/Domain/Currency/Exception/CannotRefreshExchangeRatesException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when refreshing currency exchange rates fails - */ -class CannotRefreshExchangeRatesException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotToggleCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotToggleCurrencyException.php deleted file mode 100644 index d071f706..00000000 --- a/src/Core/Domain/Currency/Exception/CannotToggleCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when toggling currency status fails - */ -class CannotToggleCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CannotUpdateCurrencyException.php b/src/Core/Domain/Currency/Exception/CannotUpdateCurrencyException.php deleted file mode 100644 index 4f0542b3..00000000 --- a/src/Core/Domain/Currency/Exception/CannotUpdateCurrencyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when currency cannot be updated - */ -class CannotUpdateCurrencyException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/CurrencyConstraintException.php b/src/Core/Domain/Currency/Exception/CurrencyConstraintException.php deleted file mode 100644 index 0d4c232b..00000000 --- a/src/Core/Domain/Currency/Exception/CurrencyConstraintException.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when currency constraints are violated - */ -class CurrencyConstraintException extends CurrencyException -{ - /** - * Code used when the ISO code doesn't respect it's appropriate format - * - * @see AlphaIsoCode::PATTERN - */ - const INVALID_ISO_CODE = 1; - - /** - * Code used when an invalid exchange rate is used (positive float expected) - * - * @see ExchangeRate - */ - const INVALID_EXCHANGE_RATE = 2; - - /** - * Code used when trying to insert a currency already in database - */ - const CURRENCY_ALREADY_EXISTS = 3; - - /** - * Code used when an invalid liveExchangeRate is used (boolean expected) - */ - const INVALID_LIVE_EXCHANGE_RATES = 4; - - /** - * Code used when the numeric ISO code doesn't respect it's appropriate format - * - * @see NumericIsoCode::PATTERN - */ - const INVALID_NUMERIC_ISO_CODE = 5; - - /** - * Code used when trying to set an empty array of names - */ - const EMPTY_NAME = 6; - - /** - * Code used when trying to set an empty array of symbols - */ - const EMPTY_SYMBOL = 7; - - /** - * Code used when an invalid precision is used (positive integer expected) - * - * @see Precision - */ - const INVALID_PRECISION = 8; - - /** - * Code used when an invalid name is used - */ - const INVALID_NAME = 9; - - /** - * Code used when an invalid symbol is used - */ - const INVALID_SYMBOL = 10; - - /** - * Code used when an invalid pattern is used - */ - const INVALID_PATTERN = 11; -} diff --git a/src/Core/Domain/Currency/Exception/CurrencyException.php b/src/Core/Domain/Currency/Exception/CurrencyException.php deleted file mode 100644 index a17e248e..00000000 --- a/src/Core/Domain/Currency/Exception/CurrencyException.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for Currency sub-domain - */ -class CurrencyException extends DomainException -{ - /** - * When currency cannot be used because it is disabled - */ - const IS_DISABLED = 1; - - /** - * When currency cannot be used because it is deleted - */ - const IS_DELETED = 2; -} diff --git a/src/Core/Domain/Currency/Exception/CurrencyNotFoundException.php b/src/Core/Domain/Currency/Exception/CurrencyNotFoundException.php deleted file mode 100644 index d33beab9..00000000 --- a/src/Core/Domain/Currency/Exception/CurrencyNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when required currency cannot be found - */ -class CurrencyNotFoundException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/DefaultCurrencyInMultiShopException.php b/src/Core/Domain/Currency/Exception/DefaultCurrencyInMultiShopException.php deleted file mode 100644 index 1499bd38..00000000 --- a/src/Core/Domain/Currency/Exception/DefaultCurrencyInMultiShopException.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Is thrown when action associated with currency is done from multi-shop context - * and that action cannot be done because the currency is set as default in one of shops - */ -class DefaultCurrencyInMultiShopException extends CurrencyException -{ - /** - * When trying to remove default currency in multi-shop context - */ - const CANNOT_REMOVE_CURRENCY = 1; - - /** - * When trying to disable default currency in multi-shop context - */ - const CANNOT_DISABLE_CURRENCY = 2; - - /** - * @var string - */ - private $currencyName; - - /** - * @var string - */ - private $shopName; - - /** - * @param string $currencyName - * @param string $shopName - * @param string $message - * @param int $code - * @param null $previous - */ - public function __construct($currencyName, $shopName, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->currencyName = $currencyName; - $this->shopName = $shopName; - } - - /** - * @return string - */ - public function getCurrencyName() - { - return $this->currencyName; - } - - /** - * @return string - */ - public function getShopName() - { - return $this->shopName; - } -} diff --git a/src/Core/Domain/Currency/Exception/ExchangeRateNotFoundException.php b/src/Core/Domain/Currency/Exception/ExchangeRateNotFoundException.php deleted file mode 100644 index 51f2d9e8..00000000 --- a/src/Core/Domain/Currency/Exception/ExchangeRateNotFoundException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -/** - * Class CannotFindExchangeRateException is thrown if the exchange rate could not be found - * for the required currency. - */ -class ExchangeRateNotFoundException extends CurrencyException -{ -} diff --git a/src/Core/Domain/Currency/Exception/InvalidUnofficialCurrencyException.php b/src/Core/Domain/Currency/Exception/InvalidUnofficialCurrencyException.php deleted file mode 100644 index ce8fbe8b..00000000 --- a/src/Core/Domain/Currency/Exception/InvalidUnofficialCurrencyException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Exception; - -use Throwable; - -/** - * Class InvalidUnofficialCurrencyException is thrown when an invalid currency - * is being added (matching an ISO code from CLDR database) - */ -class InvalidUnofficialCurrencyException extends CurrencyException -{ - /** @var string */ - private $isoCode; - - /** - * @param string $message the Exception message to throw - * @param string $isoCode Invalid currency ISO code - * @param int $code [optional] The Exception code - * @param Throwable $previous [optional] The previous throwable used for the exception chaining - * - * @since 5.1.0 - */ - public function __construct($message, $isoCode, $code = 0, Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - $this->isoCode = $isoCode; - } - - /** - * @return string - */ - public function getIsoCode(): string - { - return $this->isoCode; - } -} diff --git a/src/Core/Domain/Currency/Query/GetCurrencyExchangeRate.php b/src/Core/Domain/Currency/Query/GetCurrencyExchangeRate.php deleted file mode 100644 index b38c128f..00000000 --- a/src/Core/Domain/Currency/Query/GetCurrencyExchangeRate.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Query; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; - -/** - * Retrieves the exchange rate for a currency compared to the shop's default - */ -class GetCurrencyExchangeRate -{ - /** - * @var AlphaIsoCode - */ - private $isoCode; - - /** - * @param string $isoCode Currency ISO code - * - * @throws CurrencyException - */ - public function __construct(string $isoCode) - { - $this->isoCode = new AlphaIsoCode($isoCode); - } - - /** - * @return AlphaIsoCode - */ - public function getIsoCode(): AlphaIsoCode - { - return $this->isoCode; - } -} diff --git a/src/Core/Domain/Currency/Query/GetCurrencyForEditing.php b/src/Core/Domain/Currency/Query/GetCurrencyForEditing.php deleted file mode 100644 index a06b72ee..00000000 --- a/src/Core/Domain/Currency/Query/GetCurrencyForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Query; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Class GetCurrencyForEditing - */ -class GetCurrencyForEditing -{ - /** - * @var CurrencyId - */ - private $currencyId; - - /** - * @param int $currencyId - * - * @throws CurrencyException - */ - public function __construct($currencyId) - { - $this->currencyId = new CurrencyId($currencyId); - } - - /** - * @return CurrencyId - */ - public function getCurrencyId() - { - return $this->currencyId; - } -} diff --git a/src/Core/Domain/Currency/Query/GetReferenceCurrency.php b/src/Core/Domain/Currency/Query/GetReferenceCurrency.php deleted file mode 100644 index 5be7354c..00000000 --- a/src/Core/Domain/Currency/Query/GetReferenceCurrency.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\Query; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; - -/** - * Get reference currency data, which are data from the unicode CLDR database, thus - * only official currencies have one. The result is exposed with a ReferenceCurrency - * object, and if the currency doesn't exist a CurrencyNotFoundException is thrown. - */ -class GetReferenceCurrency -{ - /** - * @var AlphaIsoCode - */ - private $isoCode; - - /** - * @param string $isoCode - * - * @throws CurrencyException - */ - public function __construct(string $isoCode) - { - $this->isoCode = new AlphaIsoCode($isoCode); - } - - /** - * @return AlphaIsoCode - */ - public function getIsoCode(): AlphaIsoCode - { - return $this->isoCode; - } -} diff --git a/src/Core/Domain/Currency/QueryHandler/GetCurrencyExchangeRateHandlerInterface.php b/src/Core/Domain/Currency/QueryHandler/GetCurrencyExchangeRateHandlerInterface.php deleted file mode 100644 index b0dd6d74..00000000 --- a/src/Core/Domain/Currency/QueryHandler/GetCurrencyExchangeRateHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ExchangeRate; - -/** - * Interface GetCurrencyExchangeRateHandlerInterface defines contract for GetCurrencyExchangeRateHandler. - */ -interface GetCurrencyExchangeRateHandlerInterface -{ - /** - * @param GetCurrencyExchangeRate $query - * - * @return ExchangeRate - */ - public function handle(GetCurrencyExchangeRate $query); -} diff --git a/src/Core/Domain/Currency/QueryHandler/GetCurrencyForEditingHandlerInterface.php b/src/Core/Domain/Currency/QueryHandler/GetCurrencyForEditingHandlerInterface.php deleted file mode 100644 index 7dc0b5a7..00000000 --- a/src/Core/Domain/Currency/QueryHandler/GetCurrencyForEditingHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyForEditing; - -/** - * Interface GetCurrencyForEditingHandlerInterface defines contract for GetCurrencyForFormEditingHandler. - */ -interface GetCurrencyForEditingHandlerInterface -{ - /** - * @param GetCurrencyForEditing $query - * - * @return \PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\EditableCurrency - */ - public function handle(GetCurrencyForEditing $query); -} diff --git a/src/Core/Domain/Currency/QueryHandler/GetReferenceCurrencyHandlerInterface.php b/src/Core/Domain/Currency/QueryHandler/GetReferenceCurrencyHandlerInterface.php deleted file mode 100644 index e3416334..00000000 --- a/src/Core/Domain/Currency/QueryHandler/GetReferenceCurrencyHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetReferenceCurrency; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ReferenceCurrency; - -/** - * Interface GetReferenceCurrencyHandlerInterface defines contract for GetReferenceCurrencyHandler. - */ -interface GetReferenceCurrencyHandlerInterface -{ - /** - * @param GetReferenceCurrency $query - * - * @return ReferenceCurrency - */ - public function handle(GetReferenceCurrency $query): ReferenceCurrency; -} diff --git a/src/Core/Domain/Currency/QueryResult/EditableCurrency.php b/src/Core/Domain/Currency/QueryResult/EditableCurrency.php deleted file mode 100644 index b50ee22a..00000000 --- a/src/Core/Domain/Currency/QueryResult/EditableCurrency.php +++ /dev/null @@ -1,222 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Class EditableCurrency - */ -class EditableCurrency -{ - /** - * @var CurrencyId - */ - private $currencyId; - - /** - * @var array - */ - private $names; - - /** - * @var array - */ - private $symbols; - - /** - * @var array - */ - private $transformations; - - /** - * @var string - */ - private $isoCode; - - /** - * @var float - */ - private $exchangeRate; - - /** - * @var int - */ - private $precision; - - /** - * @var bool - */ - private $isEnabled; - - /** - * @var bool - */ - private $isUnofficial; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param int $currencyId - * @param string $isoCode - * @param array $names - * @param array $symbols - * @param array $transformations - * @param float $exchangeRate - * @param int $precision - * @param bool $isEnabled - * @param bool $isUnofficial - * @param int[] $associatedShopIds - * - * @throws CurrencyException - */ - public function __construct( - $currencyId, - $isoCode, - array $names, - array $symbols, - array $transformations, - $exchangeRate, - int $precision, - $isEnabled, - bool $isUnofficial, - array $associatedShopIds - ) { - $this->currencyId = new CurrencyId($currencyId); - $this->isoCode = $isoCode; - $this->names = $names; - $this->symbols = $symbols; - $this->transformations = $transformations; - $this->exchangeRate = $exchangeRate; - $this->precision = $precision; - $this->isEnabled = $isEnabled; - $this->isUnofficial = $isUnofficial; - $this->associatedShopIds = $associatedShopIds; - } - - /** - * @return CurrencyId - */ - public function getCurrencyId() - { - return $this->currencyId; - } - - /** - * Currency ISO code - * - * @return string - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * Currency's names, indexed by language id. - * - * @return array - */ - public function getNames(): array - { - return $this->names; - } - - /** - * Currency's names, indexed by language id. - * - * @return array - */ - public function getSymbols(): array - { - return $this->symbols; - } - - /** - * Currency's transformations, indexed by language id. - * - * @return array - */ - public function getTransformations(): array - { - return $this->transformations; - } - - /** - * Exchange rate of the currency compared to the shop's default one - * - * @return float - */ - public function getExchangeRate() - { - return $this->exchangeRate; - } - - /** - * Currency decimal precision - * - * @return int - */ - public function getPrecision(): int - { - return $this->precision; - } - - /** - * Whether the currency is enabled on the front - * - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * Whether the currency is an unofficial one (custom created) - * - * @return bool - */ - public function isUnofficial(): bool - { - return $this->isUnofficial; - } - - /** - * List of shops that use this currency (shop IDs) - * - * @return int[] - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } -} diff --git a/src/Core/Domain/Currency/QueryResult/ExchangeRate.php b/src/Core/Domain/Currency/QueryResult/ExchangeRate.php deleted file mode 100644 index 3a5b9b7f..00000000 --- a/src/Core/Domain/Currency/QueryResult/ExchangeRate.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult; - -use PrestaShop\Decimal\Number; - -/** - * Class ExchangeRate - */ -class ExchangeRate -{ - /** - * @var Number - */ - private $exchangeRate; - - /** - * @param Number $exchangeRate - */ - public function __construct(Number $exchangeRate) - { - $this->exchangeRate = $exchangeRate; - } - - /** - * @return Number - */ - public function getValue(): Number - { - return $this->exchangeRate; - } -} diff --git a/src/Core/Domain/Currency/QueryResult/ReferenceCurrency.php b/src/Core/Domain/Currency/QueryResult/ReferenceCurrency.php deleted file mode 100644 index c63a286c..00000000 --- a/src/Core/Domain/Currency/QueryResult/ReferenceCurrency.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult; - -class ReferenceCurrency -{ - /** - * @var string[] - */ - private $names; - - /** - * @var string[] - */ - private $symbols; - - /** - * @var string[] - */ - private $patterns; - - /** - * @var string - */ - private $isoCode; - - /** - * @var string|null - */ - private $numericIsoCode; - - /** - * @var int - */ - private $precision; - - /** - * @param string $isoCode - * @param string $numericIsoCode - * @param array $names - * @param array $symbols - * @param array $patterns - * @param int $precision - */ - public function __construct( - string $isoCode, - string $numericIsoCode, - array $names, - array $symbols, - array $patterns, - int $precision - ) { - $this->isoCode = $isoCode; - $this->numericIsoCode = $numericIsoCode; - $this->names = $names; - $this->symbols = $symbols; - $this->patterns = $patterns; - $this->precision = $precision; - } - - /** - * Currency ISO code - * - * @return string - */ - public function getIsoCode(): string - { - return $this->isoCode; - } - - /** - * Currency numeric ISO code - * - * @return string - */ - public function getNumericIsoCode(): string - { - return $this->numericIsoCode; - } - - /** - * Currency's names, indexed by language id. - * - * @return array - */ - public function getNames(): array - { - return $this->names; - } - - /** - * Currency's names, indexed by language id. - * - * @return array - */ - public function getSymbols(): array - { - return $this->symbols; - } - - /** - * Currency's patterns, indexed by language id. - * - * @return array - */ - public function getPatterns(): array - { - return $this->patterns; - } - - /** - * Currency decimal precision - * - * @return int - */ - public function getPrecision(): int - { - return $this->precision; - } -} diff --git a/src/Core/Domain/Currency/ValueObject/AlphaIsoCode.php b/src/Core/Domain/Currency/ValueObject/AlphaIsoCode.php deleted file mode 100644 index bf74bc7d..00000000 --- a/src/Core/Domain/Currency/ValueObject/AlphaIsoCode.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; - -/** - * Class AlphaIsoCode - */ -class AlphaIsoCode -{ - /** - * @var string ISO Code validation pattern - */ - const PATTERN = '/^[a-zA-Z]{2,3}$/'; - - /** - * @var string - */ - private $isoCode; - - /** - * @param string $isoCode - * - * @throws CurrencyConstraintException - */ - public function __construct($isoCode) - { - $this->assertIsValidIsoCode($isoCode); - $this->isoCode = $isoCode; - } - - /** - * @return string - */ - public function getValue() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - * - * @throws CurrencyConstraintException - */ - private function assertIsValidIsoCode($isoCode) - { - if (!is_string($isoCode) || !preg_match(self::PATTERN, $isoCode)) { - throw new CurrencyConstraintException(sprintf('Given iso code "%s" is not valid. It did not matched given regex %s', var_export($isoCode, true), self::PATTERN), CurrencyConstraintException::INVALID_ISO_CODE); - } - } -} diff --git a/src/Core/Domain/Currency/ValueObject/CurrencyId.php b/src/Core/Domain/Currency/ValueObject/CurrencyId.php deleted file mode 100644 index 041803f9..00000000 --- a/src/Core/Domain/Currency/ValueObject/CurrencyId.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; - -/** - * Class CurrencyId is responsible for providing currency id data. - */ -class CurrencyId -{ - /** - * @var int - */ - private $currencyId; - - /** - * @param int $currencyId - * - * @throws CurrencyException - */ - public function __construct($currencyId) - { - if (!is_int($currencyId) || $currencyId <= 0) { - throw new CurrencyException(sprintf('Invalid Currency id: %s', var_export($currencyId, true))); - } - - $this->currencyId = $currencyId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->currencyId; - } -} diff --git a/src/Core/Domain/Currency/ValueObject/ExchangeRate.php b/src/Core/Domain/Currency/ValueObject/ExchangeRate.php deleted file mode 100644 index 9da31983..00000000 --- a/src/Core/Domain/Currency/ValueObject/ExchangeRate.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; - -/** - * Class ExchangeRate - */ -class ExchangeRate -{ - const DEFAULT_RATE = 1.0; - - /** - * Get the default exchange rate as a Number - * - * @return Number - */ - public static function getDefaultExchangeRate(): Number - { - return new Number((string) self::DEFAULT_RATE); - } - - /** - * @var float - */ - private $exchangeRate; - - /** - * @param float $exchangeRate - * - * @throws CurrencyConstraintException - */ - public function __construct($exchangeRate) - { - $this->assertIsNumberAndMoreThanZero($exchangeRate); - $this->exchangeRate = $exchangeRate; - } - - /** - * @return float - */ - public function getValue() - { - return $this->exchangeRate; - } - - /** - * @param float|int $exchangeRate - * - * @throws CurrencyConstraintException - */ - private function assertIsNumberAndMoreThanZero($exchangeRate) - { - $isIntegerOrFloat = is_int($exchangeRate) || is_float($exchangeRate); - - if (!$isIntegerOrFloat || 0 >= $exchangeRate) { - throw new CurrencyConstraintException(sprintf('Given exchange rate %s is not valid. It must be more than 0', var_export($exchangeRate, true)), CurrencyConstraintException::INVALID_EXCHANGE_RATE); - } - } -} diff --git a/src/Core/Domain/Currency/ValueObject/NumericIsoCode.php b/src/Core/Domain/Currency/ValueObject/NumericIsoCode.php deleted file mode 100644 index 4405b32f..00000000 --- a/src/Core/Domain/Currency/ValueObject/NumericIsoCode.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; - -/** - * Class NumericIsoCode - */ -class NumericIsoCode -{ - /** - * @var string Numeric ISO Code validation pattern - */ - const PATTERN = '/^[0-9]{3}$/'; - - /** - * @var string - */ - private $numericIsoCode; - - /** - * @param string $numericIsoCode - * - * @throws CurrencyConstraintException - */ - public function __construct($numericIsoCode) - { - $this->assertIsValidNumericIsoCode($numericIsoCode); - $this->numericIsoCode = $numericIsoCode; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->numericIsoCode; - } - - /** - * @param string $numericIsoCode - * - * @throws CurrencyConstraintException - */ - private function assertIsValidNumericIsoCode($numericIsoCode) - { - if (!is_string($numericIsoCode) || !preg_match(self::PATTERN, $numericIsoCode)) { - throw new CurrencyConstraintException(sprintf('Given numeric iso code "%s" is not valid. It must be a string composed of three digits', var_export($numericIsoCode, true)), CurrencyConstraintException::INVALID_NUMERIC_ISO_CODE); - } - } -} diff --git a/src/Core/Domain/Currency/ValueObject/Precision.php b/src/Core/Domain/Currency/ValueObject/Precision.php deleted file mode 100644 index f0910f6e..00000000 --- a/src/Core/Domain/Currency/ValueObject/Precision.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; - -class Precision -{ - const DEFAULT_PRECISION = 2; - - /** - * @var int - */ - private $precision; - - /** - * @param int $precision - * - * @throws CurrencyConstraintException - */ - public function __construct(int $precision) - { - $this->assertIsPositiveInteger($precision); - $this->precision = $precision; - } - - /** - * @return int - */ - public function getValue() - { - return $this->precision; - } - - /** - * @param int $precision - * - * @throws CurrencyConstraintException - */ - private function assertIsPositiveInteger(int $precision) - { - if ((int) $precision < 0) { - throw new CurrencyConstraintException(sprintf('Given precision "%s" is not valid. It must be a positive integer', var_export($precision, true)), CurrencyConstraintException::INVALID_PRECISION); - } - } -} diff --git a/src/Core/Domain/Customer/Command/AddCustomerCommand.php b/src/Core/Domain/Customer/Command/AddCustomerCommand.php deleted file mode 100644 index 79b4257e..00000000 --- a/src/Core/Domain/Customer/Command/AddCustomerCommand.php +++ /dev/null @@ -1,397 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\ApeCode; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Birthday; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Adds new customer with provided data - */ -class AddCustomerCommand -{ - /** - * @var FirstName - */ - private $firstName; - - /** - * @var LastName - */ - private $lastName; - - /** - * @var Email - */ - private $email; - - /** - * @var Password - */ - private $password; - - /** - * @var int - */ - private $defaultGroupId; - - /** - * @var int[] - */ - private $groupIds; - - /** - * @var int|null - */ - private $genderId; - - /** - * @var bool - */ - private $isEnabled; - - /** - * @var bool - */ - private $isPartnerOffersSubscribed; - - /** - * @var Birthday - */ - private $birthday; - - /** - * @var int - */ - private $shopId; - - /** - * @var string|null Only for B2b customers - */ - private $companyName; - - /** - * @var string|null Only for B2b customers - */ - private $siretCode; - - /** - * @var ApeCode|null Only for B2b customers - */ - private $apeCode; - - /** - * @var string|null Only for B2b customers - */ - private $website; - - /** - * @var float|null Only for B2b customers - */ - private $allowedOutstandingAmount; - - /** - * @var int|null Only for B2b customers - */ - private $maxPaymentDays; - - /** - * @var int|null Only for B2b customers - */ - private $riskId; - - /** - * @param string $firstName - * @param string $lastName - * @param string $email - * @param string $password - * @param int $defaultGroupId - * @param int[] $groupIds - * @param int $shopId - * @param int|null $genderId - * @param bool $isEnabled - * @param bool $isPartnerOffersSubscribed - * @param string|null $birthday - */ - public function __construct( - $firstName, - $lastName, - $email, - $password, - $defaultGroupId, - array $groupIds, - $shopId, - $genderId = null, - $isEnabled = true, - $isPartnerOffersSubscribed = false, - $birthday = null - ) { - $this->firstName = new FirstName($firstName); - $this->lastName = new LastName($lastName); - $this->email = new Email($email); - $this->password = new Password($password); - $this->defaultGroupId = $defaultGroupId; - $this->groupIds = $groupIds; - $this->shopId = $shopId; - $this->genderId = $genderId; - $this->isEnabled = $isEnabled; - $this->isPartnerOffersSubscribed = $isPartnerOffersSubscribed; - $this->birthday = null !== $birthday ? new Birthday($birthday) : Birthday::createEmpty(); - } - - /** - * @return FirstName - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return LastName - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return Password - */ - public function getPassword() - { - return $this->password; - } - - /** - * @return int - */ - public function getDefaultGroupId() - { - return $this->defaultGroupId; - } - - /** - * @return int[] - */ - public function getGroupIds() - { - return $this->groupIds; - } - - /** - * @return int|null - */ - public function getGenderId() - { - return $this->genderId; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * @return bool - */ - public function isPartnerOffersSubscribed() - { - return $this->isPartnerOffersSubscribed; - } - - /** - * @return Birthday - */ - public function getBirthday() - { - return $this->birthday; - } - - /** - * @return int - */ - public function getShopId() - { - return $this->shopId; - } - - /** - * @return string|null - */ - public function getCompanyName() - { - return $this->companyName; - } - - /** - * @param string $companyName - * - * @return self - */ - public function setCompanyName($companyName) - { - $this->companyName = $companyName; - - return $this; - } - - /** - * @return string|null - */ - public function getSiretCode() - { - return $this->siretCode; - } - - /** - * @param string $siretCode - * - * @return self - */ - public function setSiretCode($siretCode) - { - $this->siretCode = $siretCode; - - return $this; - } - - /** - * @return ApeCode|null - */ - public function getApeCode() - { - return $this->apeCode; - } - - /** - * @param string $apeCode - * - * @return self - */ - public function setApeCode($apeCode) - { - $this->apeCode = new ApeCode($apeCode); - - return $this; - } - - /** - * @return string|null - */ - public function getWebsite() - { - return $this->website; - } - - /** - * @param string $website - * - * @return self - */ - public function setWebsite($website) - { - $this->website = $website; - - return $this; - } - - /** - * @return float|null - */ - public function getAllowedOutstandingAmount() - { - return $this->allowedOutstandingAmount; - } - - /** - * @param float $allowedOutstandingAmount - * - * @return self - */ - public function setAllowedOutstandingAmount($allowedOutstandingAmount) - { - $this->allowedOutstandingAmount = $allowedOutstandingAmount; - - return $this; - } - - /** - * @return int|null - */ - public function getMaxPaymentDays() - { - return $this->maxPaymentDays; - } - - /** - * @param int $maxPaymentDays - * - * @return self - */ - public function setMaxPaymentDays($maxPaymentDays) - { - $this->maxPaymentDays = $maxPaymentDays; - - return $this; - } - - /** - * @return int|null - */ - public function getRiskId() - { - return $this->riskId; - } - - /** - * @param int $riskId - * - * @return self - */ - public function setRiskId($riskId) - { - $this->riskId = $riskId; - - return $this; - } -} diff --git a/src/Core/Domain/Customer/Command/BulkDeleteCustomerCommand.php b/src/Core/Domain/Customer/Command/BulkDeleteCustomerCommand.php deleted file mode 100644 index b2f758b7..00000000 --- a/src/Core/Domain/Customer/Command/BulkDeleteCustomerCommand.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerDeleteMethod; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Deletes given customers. - */ -class BulkDeleteCustomerCommand -{ - /** - * @var CustomerId[] - */ - private $customerIds; - - /** - * @var CustomerDeleteMethod - */ - private $deleteMethod; - - /** - * @param int[] $customerIds - * @param string $deleteMethod - */ - public function __construct(array $customerIds, $deleteMethod) - { - $this->setCustomerIds($customerIds); - $this->deleteMethod = new CustomerDeleteMethod($deleteMethod); - } - - /** - * @return CustomerId[] - */ - public function getCustomerIds() - { - return $this->customerIds; - } - - /** - * @return CustomerDeleteMethod - */ - public function getDeleteMethod() - { - return $this->deleteMethod; - } - - /** - * @param int[] $customerIds - */ - private function setCustomerIds(array $customerIds) - { - foreach ($customerIds as $customerId) { - $this->customerIds[] = new CustomerId($customerId); - } - } -} diff --git a/src/Core/Domain/Customer/Command/BulkDisableCustomerCommand.php b/src/Core/Domain/Customer/Command/BulkDisableCustomerCommand.php deleted file mode 100644 index 9bb8720d..00000000 --- a/src/Core/Domain/Customer/Command/BulkDisableCustomerCommand.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Disables customers in bulk action. - */ -class BulkDisableCustomerCommand -{ - /** - * @var CustomerId[] - */ - private $customerIds = []; - - /** - * @param int[] $customerIds - */ - public function __construct(array $customerIds) - { - $this->setCustomerIds($customerIds); - } - - /** - * @return CustomerId[] - */ - public function getCustomerIds() - { - return $this->customerIds; - } - - /** - * @param int[] $customerIds - */ - private function setCustomerIds(array $customerIds) - { - foreach ($customerIds as $customerId) { - $this->customerIds[] = new CustomerId($customerId); - } - } -} diff --git a/src/Core/Domain/Customer/Command/BulkEnableCustomerCommand.php b/src/Core/Domain/Customer/Command/BulkEnableCustomerCommand.php deleted file mode 100644 index a0d2776e..00000000 --- a/src/Core/Domain/Customer/Command/BulkEnableCustomerCommand.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Enables customers in bulk action. - */ -class BulkEnableCustomerCommand -{ - /** - * @var CustomerId[] - */ - private $customerIds = []; - - /** - * @param int[] $customerIds - */ - public function __construct(array $customerIds) - { - $this->setCustomerIds($customerIds); - } - - /** - * @return CustomerId[] - */ - public function getCustomerIds() - { - return $this->customerIds; - } - - /** - * @param int[] $customerIds - */ - private function setCustomerIds(array $customerIds) - { - foreach ($customerIds as $customerId) { - $this->customerIds[] = new CustomerId($customerId); - } - } -} diff --git a/src/Core/Domain/Customer/Command/DeleteCustomerCommand.php b/src/Core/Domain/Customer/Command/DeleteCustomerCommand.php deleted file mode 100644 index c2626633..00000000 --- a/src/Core/Domain/Customer/Command/DeleteCustomerCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerDeleteMethod; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Deletes given customer. - */ -class DeleteCustomerCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var CustomerDeleteMethod - */ - private $deleteMethod; - - /** - * @param int $customerId - * @param string $deleteMethod - */ - public function __construct($customerId, $deleteMethod) - { - $this->customerId = new CustomerId($customerId); - $this->deleteMethod = new CustomerDeleteMethod($deleteMethod); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return CustomerDeleteMethod - */ - public function getDeleteMethod() - { - return $this->deleteMethod; - } -} diff --git a/src/Core/Domain/Customer/Command/EditCustomerCommand.php b/src/Core/Domain/Customer/Command/EditCustomerCommand.php deleted file mode 100644 index 7c624394..00000000 --- a/src/Core/Domain/Customer/Command/EditCustomerCommand.php +++ /dev/null @@ -1,513 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\ApeCode; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Birthday; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Edits provided customer. - * It can edit either all or partial data. - * - * Only not-null values are considered when editing customer. - * For example, if the email is null, then the original value is not modified, - * however, if email is set, then the original value will be overwritten. - */ -class EditCustomerCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var FirstName|null - */ - private $firstName; - - /** - * @var LastName|null - */ - private $lastName; - - /** - * @var Email|null - */ - private $email; - - /** - * @var Password|null - */ - private $password; - - /** - * @var int|null - */ - private $defaultGroupId; - - /** - * @var int[]|null - */ - private $groupIds; - - /** - * @var int|null - */ - private $genderId; - - /** - * @var bool|null - */ - private $isNewsletterSubscribed; - - /** - * @var bool - */ - private $isEnabled; - - /** - * @var bool|null - */ - private $isPartnerOffersSubscribed; - - /** - * @var Birthday|null - */ - private $birthday; - - /** - * @var string|null - */ - private $companyName; - - /** - * @var string|null - */ - private $siretCode; - - /** - * @var ApeCode|null - */ - private $apeCode; - - /** - * @var string|null - */ - private $website; - - /** - * @var float|null - */ - private $allowedOutstandingAmount; - - /** - * @var int|null - */ - private $maxPaymentDays; - - /** - * @var int|null - */ - private $riskId; - - /** - * @param int $customerId - */ - public function __construct($customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return FirstName|null - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @param string $firstName - * - * @return self - */ - public function setFirstName($firstName) - { - $this->firstName = new FirstName($firstName); - - return $this; - } - - /** - * @return LastName|null - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @param string $lastName - * - * @return self - */ - public function setLastName($lastName) - { - $this->lastName = new LastName($lastName); - - return $this; - } - - /** - * @return Email|null - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - * - * @return self - */ - public function setEmail($email) - { - $this->email = new Email($email); - - return $this; - } - - /** - * @return Password|null - */ - public function getPassword() - { - return $this->password; - } - - /** - * @param string $password - * - * @return self - */ - public function setPassword($password) - { - $this->password = new Password($password); - - return $this; - } - - /** - * @return int|null - */ - public function getDefaultGroupId() - { - return $this->defaultGroupId; - } - - /** - * @param int $defaultGroupId - * - * @return self - */ - public function setDefaultGroupId($defaultGroupId) - { - $this->defaultGroupId = $defaultGroupId; - - return $this; - } - - /** - * @return int[]|null - */ - public function getGroupIds() - { - return $this->groupIds; - } - - /** - * @param int[] $groupIds - * - * @return self - */ - public function setGroupIds(array $groupIds) - { - $this->groupIds = $groupIds; - - return $this; - } - - /** - * @return int|null - */ - public function getGenderId() - { - return $this->genderId; - } - - /** - * @param int $genderId - * - * @return self - */ - public function setGenderId($genderId) - { - $this->genderId = $genderId; - - return $this; - } - - /** - * @return bool - */ - public function isNewsletterSubscribed() - { - return $this->isNewsletterSubscribed; - } - - /** - * @param bool $isNewsletterSubscribed - */ - public function setNewsletterSubscribed($isNewsletterSubscribed) - { - $this->isNewsletterSubscribed = $isNewsletterSubscribed; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * @param bool $isEnabled - * - * @return self - */ - public function setIsEnabled($isEnabled) - { - $this->isEnabled = $isEnabled; - - return $this; - } - - /** - * @return bool - */ - public function isPartnerOffersSubscribed() - { - return $this->isPartnerOffersSubscribed; - } - - /** - * @param bool $isPartnerOffersSubscribed - * - * @return self - */ - public function setIsPartnerOffersSubscribed($isPartnerOffersSubscribed) - { - $this->isPartnerOffersSubscribed = $isPartnerOffersSubscribed; - - return $this; - } - - /** - * @return Birthday|null - */ - public function getBirthday() - { - return $this->birthday; - } - - /** - * @param string $birthday - * - * @return self - */ - public function setBirthday($birthday) - { - $this->birthday = new Birthday($birthday); - - return $this; - } - - /** - * @return string|null - */ - public function getCompanyName() - { - return $this->companyName; - } - - /** - * @param string $companyName - * - * @return self - */ - public function setCompanyName($companyName) - { - $this->companyName = $companyName; - - return $this; - } - - /** - * @return string|null - */ - public function getSiretCode() - { - return $this->siretCode; - } - - /** - * @param string $siretCode - * - * @return self - */ - public function setSiretCode($siretCode) - { - $this->siretCode = $siretCode; - - return $this; - } - - /** - * @return ApeCode|null - */ - public function getApeCode() - { - return $this->apeCode; - } - - /** - * @param string $apeCode - * - * @return self - */ - public function setApeCode($apeCode) - { - $this->apeCode = new ApeCode($apeCode); - - return $this; - } - - /** - * @return string|null - */ - public function getWebsite() - { - return $this->website; - } - - /** - * @param string $website - * - * @return self - */ - public function setWebsite($website) - { - $this->website = $website; - - return $this; - } - - /** - * @return float|null - */ - public function getAllowedOutstandingAmount() - { - return $this->allowedOutstandingAmount; - } - - /** - * @param float $allowedOutstandingAmount - * - * @return self - */ - public function setAllowedOutstandingAmount($allowedOutstandingAmount) - { - $this->allowedOutstandingAmount = $allowedOutstandingAmount; - - return $this; - } - - /** - * @return int|null - */ - public function getMaxPaymentDays() - { - return $this->maxPaymentDays; - } - - /** - * @param int $maxPaymentDays - * - * @return self - */ - public function setMaxPaymentDays($maxPaymentDays) - { - $this->maxPaymentDays = $maxPaymentDays; - - return $this; - } - - /** - * @return int|null - */ - public function getRiskId() - { - return $this->riskId; - } - - /** - * @param int $riskId - * - * @return self - */ - public function setRiskId($riskId) - { - $this->riskId = $riskId; - - return $this; - } -} diff --git a/src/Core/Domain/Customer/Command/SetPrivateNoteAboutCustomerCommand.php b/src/Core/Domain/Customer/Command/SetPrivateNoteAboutCustomerCommand.php deleted file mode 100644 index fc899c71..00000000 --- a/src/Core/Domain/Customer/Command/SetPrivateNoteAboutCustomerCommand.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Sets private note about customer that can only be seen in Back Office - */ -class SetPrivateNoteAboutCustomerCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var string - */ - private $privateNote; - - /** - * @param int $customerId - * @param string $privateNote - */ - public function __construct($customerId, $privateNote) - { - $this->assertPrivateNoteIsString($privateNote); - - $this->customerId = new CustomerId($customerId); - $this->privateNote = $privateNote; - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return string - */ - public function getPrivateNote() - { - return $this->privateNote; - } - - /** - * @param string $privateNote - * - * @throws CustomerConstraintException - */ - private function assertPrivateNoteIsString($privateNote) - { - if (!is_string($privateNote)) { - throw new CustomerConstraintException('Invalid private note provided. Private note must be a string.', CustomerConstraintException::INVALID_PRIVATE_NOTE); - } - } -} diff --git a/src/Core/Domain/Customer/Command/SetRequiredFieldsForCustomerCommand.php b/src/Core/Domain/Customer/Command/SetRequiredFieldsForCustomerCommand.php deleted file mode 100644 index 75e8d4da..00000000 --- a/src/Core/Domain/Customer/Command/SetRequiredFieldsForCustomerCommand.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\InvalidCustomerRequiredFieldsException; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\RequiredField; - -/** - * Sets required fields for new customer when signing up in Front Office - */ -class SetRequiredFieldsForCustomerCommand -{ - /** - * @var string[] - */ - private $requiredFields; - - /** - * @param string[] $requiredFields - */ - public function __construct(array $requiredFields) - { - $this->assertContainsOnlyAllowedFields($requiredFields); - - $this->requiredFields = $requiredFields; - } - - /** - * @return string[] - */ - public function getRequiredFields() - { - return $this->requiredFields; - } - - /** - * Check that all provided fields are allowed. - * - * @param string[] $requiredFields - */ - private function assertContainsOnlyAllowedFields(array $requiredFields) - { - if (empty($requiredFields)) { - return; - } - - if (!empty(array_diff($requiredFields, RequiredField::ALLOWED_REQUIRED_FIELDS))) { - throw new InvalidCustomerRequiredFieldsException(sprintf('Invalid customer required fields provided. Allowed fields are: %s', implode(',', RequiredField::ALLOWED_REQUIRED_FIELDS))); - } - } -} diff --git a/src/Core/Domain/Customer/Command/TransformGuestToCustomerCommand.php b/src/Core/Domain/Customer/Command/TransformGuestToCustomerCommand.php deleted file mode 100644 index ec845b4c..00000000 --- a/src/Core/Domain/Customer/Command/TransformGuestToCustomerCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Transforms guest (customer without password) into registered customer account - */ -class TransformGuestToCustomerCommand -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct($customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/CommandHandler/AddCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/AddCustomerHandlerInterface.php deleted file mode 100644 index b5369f81..00000000 --- a/src/Core/Domain/Customer/CommandHandler/AddCustomerHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\AddCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Interface for service that handles command that adds new customer - */ -interface AddCustomerHandlerInterface -{ - /** - * @param AddCustomerCommand $command - * - * @return CustomerId - */ - public function handle(AddCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/BulkDeleteCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/BulkDeleteCustomerHandlerInterface.php deleted file mode 100644 index 9d5b6ceb..00000000 --- a/src/Core/Domain/Customer/CommandHandler/BulkDeleteCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDeleteCustomerCommand; - -/** - * Defines interface for customer bulk delete command handler. - */ -interface BulkDeleteCustomerHandlerInterface -{ - /** - * @param BulkDeleteCustomerCommand $command - */ - public function handle(BulkDeleteCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/BulkDisableCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/BulkDisableCustomerHandlerInterface.php deleted file mode 100644 index 5c9bd359..00000000 --- a/src/Core/Domain/Customer/CommandHandler/BulkDisableCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDisableCustomerCommand; - -/** - * Defines interface for handling command that disables given customers. - */ -interface BulkDisableCustomerHandlerInterface -{ - /** - * @param BulkDisableCustomerCommand $command - */ - public function handle(BulkDisableCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/BulkEnableCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/BulkEnableCustomerHandlerInterface.php deleted file mode 100644 index d12c0abb..00000000 --- a/src/Core/Domain/Customer/CommandHandler/BulkEnableCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkEnableCustomerCommand; - -/** - * Defines interface for handling command that enables given customers. - */ -interface BulkEnableCustomerHandlerInterface -{ - /** - * @param BulkEnableCustomerCommand $command - */ - public function handle(BulkEnableCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/DeleteCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/DeleteCustomerHandlerInterface.php deleted file mode 100644 index 33644f06..00000000 --- a/src/Core/Domain/Customer/CommandHandler/DeleteCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\DeleteCustomerCommand; - -/** - * Defines interface for handling command that deletes given customer. - */ -interface DeleteCustomerHandlerInterface -{ - /** - * @param DeleteCustomerCommand $command - */ - public function handle(DeleteCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/EditCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/EditCustomerHandlerInterface.php deleted file mode 100644 index f06165bb..00000000 --- a/src/Core/Domain/Customer/CommandHandler/EditCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\EditCustomerCommand; - -/** - * Interface for service that handles customer editing command - */ -interface EditCustomerHandlerInterface -{ - /** - * @param EditCustomerCommand $command - */ - public function handle(EditCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandlerInterface.php deleted file mode 100644 index b93ccceb..00000000 --- a/src/Core/Domain/Customer/CommandHandler/SetPrivateNoteAboutCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetPrivateNoteAboutCustomerCommand; - -/** - * Defines interface for service that handles command which sets private note about customer - */ -interface SetPrivateNoteAboutCustomerHandlerInterface -{ - /** - * @param SetPrivateNoteAboutCustomerCommand $command - */ - public function handle(SetPrivateNoteAboutCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/SetRequiredFieldsForCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/SetRequiredFieldsForCustomerHandlerInterface.php deleted file mode 100644 index ac46be49..00000000 --- a/src/Core/Domain/Customer/CommandHandler/SetRequiredFieldsForCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetRequiredFieldsForCustomerCommand; - -/** - * Defines interface for services that handles setting required fields for customer command. - */ -interface SetRequiredFieldsForCustomerHandlerInterface -{ - /** - * @param SetRequiredFieldsForCustomerCommand $command - */ - public function handle(SetRequiredFieldsForCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/CommandHandler/TransformGuestToCustomerHandlerInterface.php b/src/Core/Domain/Customer/CommandHandler/TransformGuestToCustomerHandlerInterface.php deleted file mode 100644 index e9e82f81..00000000 --- a/src/Core/Domain/Customer/CommandHandler/TransformGuestToCustomerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\TransformGuestToCustomerCommand; - -/** - * Defines contract for service that handles command which transforms guest into customer - */ -interface TransformGuestToCustomerHandlerInterface -{ - /** - * @param TransformGuestToCustomerCommand $command - */ - public function handle(TransformGuestToCustomerCommand $command); -} diff --git a/src/Core/Domain/Customer/Exception/CannotSetRequiredFieldsForCustomerException.php b/src/Core/Domain/Customer/Exception/CannotSetRequiredFieldsForCustomerException.php deleted file mode 100644 index 99cb2467..00000000 --- a/src/Core/Domain/Customer/Exception/CannotSetRequiredFieldsForCustomerException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Is thrown when setting required fields for customer fails - */ -class CannotSetRequiredFieldsForCustomerException extends CustomerException -{ -} diff --git a/src/Core/Domain/Customer/Exception/CustomerByEmailNotFoundException.php b/src/Core/Domain/Customer/Exception/CustomerByEmailNotFoundException.php deleted file mode 100644 index 231e7cac..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerByEmailNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Thrown on failure to find customer by email - */ -class CustomerByEmailNotFoundException extends CustomerException -{ -} diff --git a/src/Core/Domain/Customer/Exception/CustomerConstraintException.php b/src/Core/Domain/Customer/Exception/CustomerConstraintException.php deleted file mode 100644 index f760dac6..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerConstraintException.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Is thrown when customer constraint is violated - */ -class CustomerConstraintException extends CustomerException -{ - /** - * @var int Code is used when invalid email is provided for customer - */ - const INVALID_EMAIL = 1; - - /** - * @var int Code is used when invalid first name is provided for customer - */ - const INVALID_FIRST_NAME = 2; - - /** - * @var int Code is used when invalid last name is provided for customer - */ - const INVALID_LAST_NAME = 3; - - /** - * @var int Code is used when invalid password is provided for customer - */ - const INVALID_PASSWORD = 4; - - /** - * @var int Code is used when invalid APE code is provided - */ - const INVALID_APE_CODE = 5; - - /** - * @var int Is used when invalid (not string) private note is provided as private note - */ - const INVALID_PRIVATE_NOTE = 6; - - /** - * @var int Code is used when invalid customer birthday is provided - */ - const INVALID_BIRTHDAY = 7; -} diff --git a/src/Core/Domain/Customer/Exception/CustomerDefaultGroupAccessException.php b/src/Core/Domain/Customer/Exception/CustomerDefaultGroupAccessException.php deleted file mode 100644 index da7e8749..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerDefaultGroupAccessException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Exception is thrown when customer's default groups is not configured as access group. - * This means that default group must also be configured as access group for customer. - */ -class CustomerDefaultGroupAccessException extends CustomerException -{ -} diff --git a/src/Core/Domain/Customer/Exception/CustomerException.php b/src/Core/Domain/Customer/Exception/CustomerException.php deleted file mode 100644 index 3f0e983e..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class CustomerException is base "Customer" context exception - */ -class CustomerException extends DomainException -{ -} diff --git a/src/Core/Domain/Customer/Exception/CustomerNotFoundException.php b/src/Core/Domain/Customer/Exception/CustomerNotFoundException.php deleted file mode 100644 index 5409a7d3..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerNotFoundException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Is thrown when customer is not found - */ -class CustomerNotFoundException extends CustomerException -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param CustomerId $customerId - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct(CustomerId $customerId, $message = '', $code = 0, $previous = null) - { - $this->customerId = $customerId; - - parent::__construct($message, $code, $previous); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/Exception/CustomerTransformationException.php b/src/Core/Domain/Customer/Exception/CustomerTransformationException.php deleted file mode 100644 index 6e9950b8..00000000 --- a/src/Core/Domain/Customer/Exception/CustomerTransformationException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Is thrown when customer transformation error occurs - */ -class CustomerTransformationException extends CustomerException -{ - /** - * @var int Code is used when customer which is not guest is being transformed into customer - */ - const CUSTOMER_IS_NOT_GUEST = 1; - - /** - * @var int Code is used when guest transformation into customer has failed - */ - const TRANSFORMATION_FAILED = 2; -} diff --git a/src/Core/Domain/Customer/Exception/DuplicateCustomerEmailException.php b/src/Core/Domain/Customer/Exception/DuplicateCustomerEmailException.php deleted file mode 100644 index b67e35e2..00000000 --- a/src/Core/Domain/Customer/Exception/DuplicateCustomerEmailException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Exception is thrown when email which already exists is being used to create or update other customer - */ -class DuplicateCustomerEmailException extends CustomerException -{ - /** - * @var Email - */ - private $email; - - /** - * @param Email $email - * @param string $message - * @param int $code - * @param null $previous - */ - public function __construct(Email $email, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->email = $email; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } -} diff --git a/src/Core/Domain/Customer/Exception/InvalidCustomerIdException.php b/src/Core/Domain/Customer/Exception/InvalidCustomerIdException.php deleted file mode 100644 index f2007dc0..00000000 --- a/src/Core/Domain/Customer/Exception/InvalidCustomerIdException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Class InvalidCustomerIdException is thrown when CustomerId with invalid value is being created. - */ -class InvalidCustomerIdException extends CustomerException -{ -} diff --git a/src/Core/Domain/Customer/Exception/InvalidCustomerRequiredFieldsException.php b/src/Core/Domain/Customer/Exception/InvalidCustomerRequiredFieldsException.php deleted file mode 100644 index 10a7057b..00000000 --- a/src/Core/Domain/Customer/Exception/InvalidCustomerRequiredFieldsException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Thrown when trying to set invalid required fields for customer - */ -class InvalidCustomerRequiredFieldsException extends CustomerException -{ -} diff --git a/src/Core/Domain/Customer/Exception/MissingCustomerRequiredFieldsException.php b/src/Core/Domain/Customer/Exception/MissingCustomerRequiredFieldsException.php deleted file mode 100644 index d9352126..00000000 --- a/src/Core/Domain/Customer/Exception/MissingCustomerRequiredFieldsException.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Exception; - -/** - * Is thrown when adding/editing customer with missing required fields - */ -class MissingCustomerRequiredFieldsException extends CustomerException -{ - /** - * @var string[] - */ - private $missingRequiredFields; - - /** - * @param string[] $missingRequiredFields - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct(array $missingRequiredFields, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->missingRequiredFields = $missingRequiredFields; - } - - /** - * @return string[] - */ - public function getMissingRequiredFields() - { - return $this->missingRequiredFields; - } -} diff --git a/src/Core/Domain/Customer/Query/GetCustomerCarts.php b/src/Core/Domain/Customer/Query/GetCustomerCarts.php deleted file mode 100644 index 36c07108..00000000 --- a/src/Core/Domain/Customer/Query/GetCustomerCarts.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Query for getting summarized customer carts - */ -class GetCustomerCarts -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct(int $customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/Query/GetCustomerForAddressCreation.php b/src/Core/Domain/Customer/Query/GetCustomerForAddressCreation.php deleted file mode 100644 index 13b5ed87..00000000 --- a/src/Core/Domain/Customer/Query/GetCustomerForAddressCreation.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -/** - * Gets customer information for address creation. - */ -class GetCustomerForAddressCreation -{ - /** - * @var string - */ - private $customerEmail; - - /** - * Query is used for customer search so email string might not be complete so no email validation - * - * @param string $customerEmail - */ - public function __construct(string $customerEmail) - { - $this->customerEmail = $customerEmail; - } - - /** - * @return string - */ - public function getCustomerEmail(): string - { - return $this->customerEmail; - } -} diff --git a/src/Core/Domain/Customer/Query/GetCustomerForEditing.php b/src/Core/Domain/Customer/Query/GetCustomerForEditing.php deleted file mode 100644 index 781f243f..00000000 --- a/src/Core/Domain/Customer/Query/GetCustomerForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Gets customer information for editing. - */ -class GetCustomerForEditing -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct($customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/Query/GetCustomerForViewing.php b/src/Core/Domain/Customer/Query/GetCustomerForViewing.php deleted file mode 100644 index eb27e187..00000000 --- a/src/Core/Domain/Customer/Query/GetCustomerForViewing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Gets detailed customer information for viewing in Back Office. - */ -class GetCustomerForViewing -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct($customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/Query/GetCustomerOrders.php b/src/Core/Domain/Customer/Query/GetCustomerOrders.php deleted file mode 100644 index 4efd5365..00000000 --- a/src/Core/Domain/Customer/Query/GetCustomerOrders.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Query for getting summarized customer orders - */ -class GetCustomerOrders -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct(int $customerId) - { - $this->customerId = new CustomerId($customerId); - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } -} diff --git a/src/Core/Domain/Customer/Query/GetRequiredFieldsForCustomer.php b/src/Core/Domain/Customer/Query/GetRequiredFieldsForCustomer.php deleted file mode 100644 index 5365b4dd..00000000 --- a/src/Core/Domain/Customer/Query/GetRequiredFieldsForCustomer.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -/** - * Gets fields that are required for customer sign up - */ -class GetRequiredFieldsForCustomer -{ -} diff --git a/src/Core/Domain/Customer/Query/SearchCustomers.php b/src/Core/Domain/Customer/Query/SearchCustomers.php deleted file mode 100644 index 744ca73b..00000000 --- a/src/Core/Domain/Customer/Query/SearchCustomers.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; - -/** - * Searchers for customers by phrases matching customer's first name, last name, email and id - */ -class SearchCustomers -{ - /** - * @var string[] - */ - private $phrases; - - /** - * @param string[] $phrases - */ - public function __construct(array $phrases) - { - $this->assertPhrasesAreNotEmpty($phrases); - - $this->phrases = $phrases; - } - - /** - * @return string[] - */ - public function getPhrases() - { - return $this->phrases; - } - - /** - * @param string[] $phrases - */ - private function assertPhrasesAreNotEmpty(array $phrases) - { - if (empty($phrases)) { - throw new CustomerException('Phrases cannot be empty when searching customers.'); - } - } -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetCustomerCartsHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetCustomerCartsHandlerInterface.php deleted file mode 100644 index a46cd939..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetCustomerCartsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerCarts; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\CartSummary; - -/** - * Interface for handling GetCustomerCarts query - */ -interface GetCustomerCartsHandlerInterface -{ - /** - * @param GetCustomerCarts $query - * - * @return CartSummary[] - */ - public function handle(GetCustomerCarts $query): array; -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetCustomerForAddressCreationHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetCustomerForAddressCreationHandlerInterface.php deleted file mode 100644 index 824af348..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetCustomerForAddressCreationHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForAddressCreation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\AddressCreationCustomerInformation; - -/** - * Defines contract for customer by email search handler - */ -interface GetCustomerForAddressCreationHandlerInterface -{ - /** - * @param GetCustomerForAddressCreation $query - * - * @return AddressCreationCustomerInformation - */ - public function handle(GetCustomerForAddressCreation $query): AddressCreationCustomerInformation; -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetCustomerForEditingHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetCustomerForEditingHandlerInterface.php deleted file mode 100644 index 22bc87e6..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetCustomerForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\EditableCustomer; - -/** - * Interface for service that gets customer data for editing - */ -interface GetCustomerForEditingHandlerInterface -{ - /** - * @param GetCustomerForEditing $query - * - * @return EditableCustomer - */ - public function handle(GetCustomerForEditing $query); -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetCustomerForViewingHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetCustomerForViewingHandlerInterface.php deleted file mode 100644 index 0b882371..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetCustomerForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewableCustomer; - -/** - * Class GetCustomerInformationHandlerInterface. - */ -interface GetCustomerForViewingHandlerInterface -{ - /** - * @param GetCustomerForViewing $query - * - * @return ViewableCustomer - */ - public function handle(GetCustomerForViewing $query); -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetCustomerOrdersHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetCustomerOrdersHandlerInterface.php deleted file mode 100644 index f51ae57f..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetCustomerOrdersHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerOrders; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\OrderSummary; - -/** - * Interface for handling GetCustomerOrders query - */ -interface GetCustomerOrdersHandlerInterface -{ - /** - * @param GetCustomerOrders $query - * - * @return OrderSummary[] - */ - public function handle(GetCustomerOrders $query): array; -} diff --git a/src/Core/Domain/Customer/QueryHandler/GetRequiredFieldsForCustomerHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/GetRequiredFieldsForCustomerHandlerInterface.php deleted file mode 100644 index f587deb6..00000000 --- a/src/Core/Domain/Customer/QueryHandler/GetRequiredFieldsForCustomerHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetRequiredFieldsForCustomer; - -/** - * Defines interface for service that get required fields for customer sign up - */ -interface GetRequiredFieldsForCustomerHandlerInterface -{ - /** - * @param GetRequiredFieldsForCustomer $query - * - * @return string[] - */ - public function handle(GetRequiredFieldsForCustomer $query); -} diff --git a/src/Core/Domain/Customer/QueryHandler/SearchCustomersHandlerInterface.php b/src/Core/Domain/Customer/QueryHandler/SearchCustomersHandlerInterface.php deleted file mode 100644 index 66e0f992..00000000 --- a/src/Core/Domain/Customer/QueryHandler/SearchCustomersHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\SearchCustomers; - -/** - * Interface for service that handles customers searching command - */ -interface SearchCustomersHandlerInterface -{ - /** - * @param SearchCustomers $query - * - * @return array - */ - public function handle(SearchCustomers $query); -} diff --git a/src/Core/Domain/Customer/QueryResult/AddressCreationCustomerInformation.php b/src/Core/Domain/Customer/QueryResult/AddressCreationCustomerInformation.php deleted file mode 100644 index 5a85341a..00000000 --- a/src/Core/Domain/Customer/QueryResult/AddressCreationCustomerInformation.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Provides customer data for address creation - */ -class AddressCreationCustomerInformation -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string|null - */ - private $company; - - /** - * @param int $customerId - * @param string $firstName - * @param string $lastName - */ - public function __construct(int $customerId, string $firstName, string $lastName) - { - $this->customerId = new CustomerId($customerId); - $this->firstName = $firstName; - $this->lastName = $lastName; - } - - /** - * @return CustomerId - */ - public function getCustomerId(): CustomerId - { - return $this->customerId; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string|null - */ - public function getCompany(): ?string - { - return $this->company; - } - - /** - * @param string $company - * - * @return AddressCreationCustomerInformation - */ - public function setCompany(string $company): AddressCreationCustomerInformation - { - $this->company = $company; - - return $this; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/AddressInformation.php b/src/Core/Domain/Customer/QueryResult/AddressInformation.php deleted file mode 100644 index 89bb743f..00000000 --- a/src/Core/Domain/Customer/QueryResult/AddressInformation.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class AddressInformation. - */ -class AddressInformation -{ - /** - * @var string - */ - private $company; - - /** - * @var string - */ - private $fullName; - - /** - * @var string - */ - private $fullAddress; - - /** - * @var string - */ - private $countryName; - - /** - * @var string - */ - private $phone; - - /** - * @var string - */ - private $phoneMobile; - - /** - * @var int - */ - private $addressId; - - /** - * @param int $addressId - * @param string $company - * @param string $fullName - * @param string $fullAddress - * @param string $countryName - * @param string $phone - * @param string $phoneMobile - */ - public function __construct($addressId, $company, $fullName, $fullAddress, $countryName, $phone, $phoneMobile) - { - $this->addressId = $addressId; - $this->company = $company; - $this->fullName = $fullName; - $this->fullAddress = $fullAddress; - $this->countryName = $countryName; - $this->phone = $phone; - $this->phoneMobile = $phoneMobile; - } - - /** - * @return int - */ - public function getAddressId() - { - return $this->addressId; - } - - /** - * @return string - */ - public function getCompany() - { - return $this->company; - } - - /** - * @return string - */ - public function getFullName() - { - return $this->fullName; - } - - /** - * @return string - */ - public function getFullAddress() - { - return $this->fullAddress; - } - - /** - * @return string - */ - public function getCountryName() - { - return $this->countryName; - } - - /** - * @return string - */ - public function getPhone() - { - return $this->phone; - } - - /** - * @return string - */ - public function getPhoneMobile() - { - return $this->phoneMobile; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/BoughtProductInformation.php b/src/Core/Domain/Customer/QueryResult/BoughtProductInformation.php deleted file mode 100644 index 5082ec99..00000000 --- a/src/Core/Domain/Customer/QueryResult/BoughtProductInformation.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class BoughtProductInformation holds information about product that customer has bought. - */ -class BoughtProductInformation -{ - /** - * @var int - */ - private $orderId; - - /** - * @var string - */ - private $boughtDate; - - /** - * @var string - */ - private $productName; - - /** - * @var int - */ - private $boughtQuantity; - - /** - * @param int $orderId - * @param string $boughtDate - * @param string $productName - * @param int $boughtQuantity - */ - public function __construct( - $orderId, - $boughtDate, - $productName, - $boughtQuantity - ) { - $this->orderId = $orderId; - $this->boughtDate = $boughtDate; - $this->productName = $productName; - $this->boughtQuantity = $boughtQuantity; - } - - /** - * @return int - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return string - */ - public function getBoughtDate() - { - return $this->boughtDate; - } - - /** - * @return string - */ - public function getProductName() - { - return $this->productName; - } - - /** - * @return int - */ - public function getBoughtQuantity() - { - return $this->boughtQuantity; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/CartInformation.php b/src/Core/Domain/Customer/QueryResult/CartInformation.php deleted file mode 100644 index badc1969..00000000 --- a/src/Core/Domain/Customer/QueryResult/CartInformation.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class CustomerCartInformation. - */ -class CartInformation -{ - /** - * @var string - */ - private $cartId; - - /** - * @var string - */ - private $cartCreationDate; - - /** - * @var string - */ - private $cartTotal; - - /** - * @var string - */ - private $carrierName; - - /** - * @param string $cartId - * @param string $cartCreationDate - * @param string $cartTotal - * @param string $carrierName - */ - public function __construct( - $cartId, - $cartCreationDate, - $cartTotal, - $carrierName - ) { - $this->cartId = $cartId; - $this->cartCreationDate = $cartCreationDate; - $this->cartTotal = $cartTotal; - $this->carrierName = $carrierName; - } - - /** - * @return string - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return string - */ - public function getCartCreationDate() - { - return $this->cartCreationDate; - } - - /** - * @return string - */ - public function getCartTotal() - { - return $this->cartTotal; - } - - /** - * @return string - */ - public function getCarrierName() - { - return $this->carrierName; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/CartSummary.php b/src/Core/Domain/Customer/QueryResult/CartSummary.php deleted file mode 100644 index 5d7ecf37..00000000 --- a/src/Core/Domain/Customer/QueryResult/CartSummary.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Holds data of summarized cart - */ -class CartSummary -{ - /** - * @var int - */ - private $cartId; - - /** - * @var string - */ - private $creationDate; - - /** - * @var string - */ - private $totalPrice; - - /** - * @param int $cartId - * @param string $creationDate - * @param string $totalPrice - */ - public function __construct( - int $cartId, - string $creationDate, - string $totalPrice - ) { - $this->cartId = $cartId; - $this->creationDate = $creationDate; - $this->totalPrice = $totalPrice; - } - - /** - * @return int - */ - public function getCartId(): int - { - return $this->cartId; - } - - /** - * @return string - */ - public function getCreationDate(): string - { - return $this->creationDate; - } - - /** - * @return string - */ - public function getTotalPrice(): string - { - return $this->totalPrice; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/DiscountInformation.php b/src/Core/Domain/Customer/QueryResult/DiscountInformation.php deleted file mode 100644 index 0c301ba2..00000000 --- a/src/Core/Domain/Customer/QueryResult/DiscountInformation.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class DiscountInformation. - */ -class DiscountInformation -{ - /** - * @var int - */ - private $discountId; - - /** - * @var string - */ - private $code; - - /** - * @var string - */ - private $name; - - /** - * @var bool - */ - private $isActive; - - /** - * @var int - */ - private $availableQuantity; - - /** - * @param int $discountId - * @param string $code - * @param string $name - * @param bool $isActive - * @param int $availableQuantity - */ - public function __construct( - $discountId, - $code, - $name, - $isActive, - $availableQuantity - ) { - $this->discountId = $discountId; - $this->code = $code; - $this->name = $name; - $this->isActive = $isActive; - $this->availableQuantity = $availableQuantity; - } - - /** - * @return int - */ - public function getDiscountId() - { - return $this->discountId; - } - - /** - * @return string - */ - public function getCode() - { - return $this->code; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @return int - */ - public function getAvailableQuantity() - { - return $this->availableQuantity; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/EditableCustomer.php b/src/Core/Domain/Customer/QueryResult/EditableCustomer.php deleted file mode 100644 index e992846b..00000000 --- a/src/Core/Domain/Customer/QueryResult/EditableCustomer.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Birthday; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Stores editable data for customer - */ -class EditableCustomer -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var int - */ - private $genderId; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $email; - - /** - * @var Birthday - */ - private $birthday; - - /** - * @var bool - */ - private $isEnabled; - - /** - * @var bool - */ - private $isPartnerOffersSubscribed; - - /** - * @var bool - */ - private $isNewsletterSubscribed; - - /** - * @var array|int[] - */ - private $groupIds; - - /** - * @var int - */ - private $defaultGroupId; - - /** - * @var string - */ - private $companyName; - - /** - * @var string - */ - private $siretCode; - - /** - * @var string - */ - private $apeCode; - - /** - * @var string - */ - private $website; - - /** - * @var float - */ - private $allowedOutstandingAmount; - - /** - * @var int - */ - private $maxPaymentDays; - - /** - * @var int - */ - private $riskId; - - /** - * @param CustomerId $customerId - * @param int $genderId - * @param FirstName $firstName - * @param LastName $lastName - * @param Email $email - * @param Birthday $birthday - * @param bool $isEnabled - * @param bool $isPartnerOffersSubscribed - * @param bool $isNewsletterSubscribed - * @param int[] $groupIds - * @param int $defaultGroupId - * @param string $companyName - * @param string $siretCode - * @param string $apeCode - * @param string $website - * @param float $allowedOutstandingAmount - * @param int $maxPaymentDays - * @param int $riskId - */ - public function __construct( - CustomerId $customerId, - $genderId, - FirstName $firstName, - LastName $lastName, - Email $email, - Birthday $birthday, - $isEnabled, - $isPartnerOffersSubscribed, - $isNewsletterSubscribed, - array $groupIds, - $defaultGroupId, - $companyName, - $siretCode, - $apeCode, - $website, - $allowedOutstandingAmount, - $maxPaymentDays, - $riskId - ) { - $this->customerId = $customerId; - $this->genderId = $genderId; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->email = $email; - $this->birthday = $birthday; - $this->isEnabled = $isEnabled; - $this->isPartnerOffersSubscribed = $isPartnerOffersSubscribed; - $this->isNewsletterSubscribed = $isNewsletterSubscribed; - $this->groupIds = $groupIds; - $this->defaultGroupId = $defaultGroupId; - $this->companyName = $companyName; - $this->siretCode = $siretCode; - $this->apeCode = $apeCode; - $this->website = $website; - $this->allowedOutstandingAmount = $allowedOutstandingAmount; - $this->maxPaymentDays = $maxPaymentDays; - $this->riskId = $riskId; - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return int - */ - public function getGenderId() - { - return $this->genderId; - } - - /** - * @return FirstName - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return LastName - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return Birthday - */ - public function getBirthday() - { - return $this->birthday; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->isEnabled; - } - - /** - * @return bool - */ - public function isPartnerOffersSubscribed() - { - return $this->isPartnerOffersSubscribed; - } - - /** - * @return array|int[] - */ - public function getGroupIds() - { - return $this->groupIds; - } - - /** - * @return int - */ - public function getDefaultGroupId() - { - return $this->defaultGroupId; - } - - /** - * @return string - */ - public function getCompanyName() - { - return $this->companyName; - } - - /** - * @return string - */ - public function getSiretCode() - { - return $this->siretCode; - } - - /** - * @return string - */ - public function getApeCode() - { - return $this->apeCode; - } - - /** - * @return string - */ - public function getWebsite() - { - return $this->website; - } - - /** - * @return float - */ - public function getAllowedOutstandingAmount() - { - return $this->allowedOutstandingAmount; - } - - /** - * @return int - */ - public function getMaxPaymentDays() - { - return $this->maxPaymentDays; - } - - /** - * @return int - */ - public function getRiskId() - { - return $this->riskId; - } - - /** - * @return bool - */ - public function isNewsletterSubscribed() - { - return $this->isNewsletterSubscribed; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/GeneralInformation.php b/src/Core/Domain/Customer/QueryResult/GeneralInformation.php deleted file mode 100644 index d1cf5620..00000000 --- a/src/Core/Domain/Customer/QueryResult/GeneralInformation.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class GeneralInformation. - */ -class GeneralInformation -{ - /** - * @var string - */ - private $privateNote; - - /** - * @var string - */ - private $customerBySameEmailExists; - - /** - * @param string $privateNote - * @param bool $customerBySameEmailExists - */ - public function __construct($privateNote, $customerBySameEmailExists) - { - $this->privateNote = $privateNote; - $this->customerBySameEmailExists = $customerBySameEmailExists; - } - - /** - * @return string - */ - public function getPrivateNote() - { - return $this->privateNote; - } - - /** - * @return string - */ - public function getCustomerBySameEmailExists() - { - return $this->customerBySameEmailExists; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/GroupInformation.php b/src/Core/Domain/Customer/QueryResult/GroupInformation.php deleted file mode 100644 index 1046371c..00000000 --- a/src/Core/Domain/Customer/QueryResult/GroupInformation.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class GroupInformation holds customer group information. - */ -class GroupInformation -{ - /** - * @var int - */ - private $groupId; - - /** - * @var string - */ - private $name; - - /** - * @param int $groupId - * @param string $name - */ - public function __construct($groupId, $name) - { - $this->groupId = $groupId; - $this->name = $name; - } - - /** - * @return int - */ - public function getGroupId() - { - return $this->groupId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/LastConnectionInformation.php b/src/Core/Domain/Customer/QueryResult/LastConnectionInformation.php deleted file mode 100644 index 68a02e83..00000000 --- a/src/Core/Domain/Customer/QueryResult/LastConnectionInformation.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class LastConnectionInformation holds information about last customer connection to shop. - */ -class LastConnectionInformation -{ - /** - * @var int - */ - private $connectionId; - - /** - * @var string - */ - private $connectionDate; - - /** - * @var int - */ - private $pagesViewed; - - /** - * @var string - */ - private $totalTime; - - /** - * @var string - */ - private $httpReferer; - - /** - * @var string - */ - private $ipAddress; - - /** - * @param int $connectionId - * @param string $connectionDate - * @param int $pagesViewed - * @param string $totalTime - * @param string $httpReferer - * @param string $ipAddress - */ - public function __construct( - $connectionId, - $connectionDate, - $pagesViewed, - $totalTime, - $httpReferer, - $ipAddress - ) { - $this->connectionId = $connectionId; - $this->connectionDate = $connectionDate; - $this->pagesViewed = $pagesViewed; - $this->totalTime = $totalTime; - $this->httpReferer = $httpReferer; - $this->ipAddress = $ipAddress; - } - - /** - * @return int - */ - public function getConnectionId() - { - return $this->connectionId; - } - - /** - * @return string - */ - public function getConnectionDate() - { - return $this->connectionDate; - } - - /** - * @return int - */ - public function getPagesViewed() - { - return $this->pagesViewed; - } - - /** - * @return string - */ - public function getTotalTime() - { - return $this->totalTime; - } - - /** - * @return string - */ - public function getHttpReferer() - { - return $this->httpReferer; - } - - /** - * @return string - */ - public function getIpAddress() - { - return $this->ipAddress; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/MessageInformation.php b/src/Core/Domain/Customer/QueryResult/MessageInformation.php deleted file mode 100644 index 6f4536fd..00000000 --- a/src/Core/Domain/Customer/QueryResult/MessageInformation.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class CustomerMessageInformation holds customer message information. - */ -class MessageInformation -{ - /** - * @var int - */ - private $customerThreadId; - - /** - * @var string - */ - private $message; - - /** - * @var string - */ - private $status; - - /** - * @var string - */ - private $date; - - /** - * @param int $customerThreadId - * @param string $message - * @param string $status - * @param string $date - */ - public function __construct($customerThreadId, $message, $status, $date) - { - $this->customerThreadId = $customerThreadId; - $this->message = $message; - $this->status = $status; - $this->date = $date; - } - - /** - * @return int - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } - - /** - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/OrderInformation.php b/src/Core/Domain/Customer/QueryResult/OrderInformation.php deleted file mode 100644 index caf4bd5b..00000000 --- a/src/Core/Domain/Customer/QueryResult/OrderInformation.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class CustomerOrderInformation. - */ -class OrderInformation -{ - /** - * @var int - */ - private $orderId; - - /** - * @var string - */ - private $orderPlacedDate; - - /** - * @var string - */ - private $paymentMethodName; - - /** - * @var string - */ - private $orderStatus; - - /** - * @var int - */ - private $orderProductsCount; - - /** - * @var string - */ - private $totalPaid; - - /** - * @param int $orderId - * @param string $orderPlacedDate - * @param string $paymentMethodName - * @param string $orderStatus - * @param int $orderProductsCount - * @param string $totalPaid - */ - public function __construct($orderId, $orderPlacedDate, $paymentMethodName, $orderStatus, $orderProductsCount, $totalPaid) - { - $this->orderId = $orderId; - $this->orderPlacedDate = $orderPlacedDate; - $this->paymentMethodName = $paymentMethodName; - $this->orderStatus = $orderStatus; - $this->orderProductsCount = $orderProductsCount; - $this->totalPaid = $totalPaid; - } - - /** - * @return int - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return string - */ - public function getOrderPlacedDate() - { - return $this->orderPlacedDate; - } - - /** - * @return string - */ - public function getPaymentMethodName() - { - return $this->paymentMethodName; - } - - /** - * @return string - */ - public function getOrderStatus() - { - return $this->orderStatus; - } - - /** - * @return int - */ - public function getOrderProductsCount() - { - return $this->orderProductsCount; - } - - /** - * @return string - */ - public function getTotalPaid() - { - return $this->totalPaid; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/OrderSummary.php b/src/Core/Domain/Customer/QueryResult/OrderSummary.php deleted file mode 100644 index 5f9a4959..00000000 --- a/src/Core/Domain/Customer/QueryResult/OrderSummary.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Holds data of summarized order - */ -class OrderSummary -{ - /** - * @var int - */ - private $orderId; - - /** - * @var string - */ - private $orderPlacedDate; - - /** - * @var string - */ - private $paymentMethodName; - - /** - * @var string - */ - private $orderStatus; - - /** - * @var int - */ - private $orderProductsCount; - - /** - * @var string - */ - private $totalPaid; - - /** - * OrderForOrderCreation constructor. - * - * @param int $orderId - * @param string $orderPlacedDate - * @param string $paymentMethodName - * @param string $orderStatus - * @param int $orderProductsCount - * @param string $totalPaid - */ - public function __construct( - int $orderId, string $orderPlacedDate, - string $paymentMethodName, - string $orderStatus, - int $orderProductsCount, - string $totalPaid - ) { - $this->orderId = $orderId; - $this->orderPlacedDate = $orderPlacedDate; - $this->paymentMethodName = $paymentMethodName; - $this->orderStatus = $orderStatus; - $this->orderProductsCount = $orderProductsCount; - $this->totalPaid = $totalPaid; - } - - /** - * @return int - */ - public function getOrderId(): int - { - return $this->orderId; - } - - /** - * @return string - */ - public function getOrderPlacedDate(): string - { - return $this->orderPlacedDate; - } - - /** - * @return string - */ - public function getPaymentMethodName(): string - { - return $this->paymentMethodName; - } - - /** - * @return string - */ - public function getOrderStatus(): string - { - return $this->orderStatus; - } - - /** - * @return int - */ - public function getOrderProductsCount(): int - { - return $this->orderProductsCount; - } - - /** - * @return string - */ - public function getTotalPaid(): string - { - return $this->totalPaid; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/OrdersInformation.php b/src/Core/Domain/Customer/QueryResult/OrdersInformation.php deleted file mode 100644 index fc7ac1cf..00000000 --- a/src/Core/Domain/Customer/QueryResult/OrdersInformation.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class CustomerOrders. - */ -class OrdersInformation -{ - /** - * @var array|OrderInformation[] - */ - private $validOrders; - - /** - * @var array|OrderInformation[] - */ - private $invalidOrders; - - /** - * @var string - */ - private $totalSpent; - - /** - * @param string $totalSpent - * @param OrderInformation[] $validOrders - * @param OrderInformation[] $invalidOrders - */ - public function __construct($totalSpent, array $validOrders, array $invalidOrders) - { - $this->validOrders = $validOrders; - $this->invalidOrders = $invalidOrders; - $this->totalSpent = $totalSpent; - } - - /** - * @return OrderInformation[] - */ - public function getValidOrders() - { - return $this->validOrders; - } - - /** - * @return OrderInformation[] - */ - public function getInvalidOrders() - { - return $this->invalidOrders; - } - - /** - * @return string - */ - public function getTotalSpent() - { - return $this->totalSpent; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/PersonalInformation.php b/src/Core/Domain/Customer/QueryResult/PersonalInformation.php deleted file mode 100644 index 5019deac..00000000 --- a/src/Core/Domain/Customer/QueryResult/PersonalInformation.php +++ /dev/null @@ -1,263 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class PersonalInformation holds personal customer information. - */ -class PersonalInformation -{ - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $email; - - /** - * @var bool - */ - private $isGuest; - - /** - * @var string - */ - private $socialTitle; - - /** - * @var string - */ - private $birthday; - - /** - * @var string - */ - private $registrationDate; - - /** - * @var string - */ - private $lastUpdateDate; - - /** - * @var string - */ - private $lastVisitDate; - - /** - * @var string - */ - private $rankBySales; - - /** - * @var string - */ - private $shopName; - - /** - * @var string - */ - private $languageName; - - /** - * @var Subscriptions - */ - private $subscriptions; - - /** - * @var bool - */ - private $isActive; - - /** - * @param string $firstName - * @param string $lastName - * @param string $email - * @param bool $isGuest - * @param string $socialTitle - * @param string $birthday - * @param string $registrationDate - * @param string $lastUpdateDate - * @param string $lastVisitDate - * @param string $rankBySales - * @param string $shopName - * @param string $languageName - * @param Subscriptions $subscriptions - * @param bool $isActive - */ - public function __construct( - $firstName, - $lastName, - $email, - $isGuest, - $socialTitle, - $birthday, - $registrationDate, - $lastUpdateDate, - $lastVisitDate, - $rankBySales, - $shopName, - $languageName, - Subscriptions $subscriptions, - $isActive - ) { - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->email = $email; - $this->isGuest = $isGuest; - $this->socialTitle = $socialTitle; - $this->birthday = $birthday; - $this->registrationDate = $registrationDate; - $this->lastUpdateDate = $lastUpdateDate; - $this->lastVisitDate = $lastVisitDate; - $this->rankBySales = $rankBySales; - $this->shopName = $shopName; - $this->languageName = $languageName; - $this->subscriptions = $subscriptions; - $this->isActive = $isActive; - } - - /** - * @return string - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return bool - */ - public function isGuest() - { - return $this->isGuest; - } - - /** - * @return string - */ - public function getSocialTitle() - { - return $this->socialTitle; - } - - /** - * @return string - */ - public function getBirthday() - { - return $this->birthday; - } - - /** - * @return string - */ - public function getRegistrationDate() - { - return $this->registrationDate; - } - - /** - * @return string - */ - public function getLastUpdateDate() - { - return $this->lastUpdateDate; - } - - /** - * @return string - */ - public function getLastVisitDate() - { - return $this->lastVisitDate; - } - - /** - * @return string - */ - public function getRankBySales() - { - return $this->rankBySales; - } - - /** - * @return string - */ - public function getShopName() - { - return $this->shopName; - } - - /** - * @return string - */ - public function getLanguageName() - { - return $this->languageName; - } - - /** - * @return Subscriptions - */ - public function getSubscriptions() - { - return $this->subscriptions; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/ProductsInformation.php b/src/Core/Domain/Customer/QueryResult/ProductsInformation.php deleted file mode 100644 index 4dc04522..00000000 --- a/src/Core/Domain/Customer/QueryResult/ProductsInformation.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class CustomerProductsInformation holds information about products that customers has bought and viewed. - */ -class ProductsInformation -{ - /** - * @var BoughtProductInformation[] - */ - private $boughtProductsInformation; - - /** - * @var ViewedProductInformation[] - */ - private $viewedProductsInformation; - - /** - * @param BoughtProductInformation[] $boughtProductsInformation - * @param ViewedProductInformation[] $viewedProductsInformation - */ - public function __construct(array $boughtProductsInformation, array $viewedProductsInformation) - { - $this->boughtProductsInformation = $boughtProductsInformation; - $this->viewedProductsInformation = $viewedProductsInformation; - } - - /** - * @return BoughtProductInformation[] - */ - public function getBoughtProductsInformation() - { - return $this->boughtProductsInformation; - } - - /** - * @return ViewedProductInformation[] - */ - public function getViewedProductsInformation() - { - return $this->viewedProductsInformation; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/ReferrerInformation.php b/src/Core/Domain/Customer/QueryResult/ReferrerInformation.php deleted file mode 100644 index 995cee6a..00000000 --- a/src/Core/Domain/Customer/QueryResult/ReferrerInformation.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class ReferrerInformation holds information about customer referrer. - */ -class ReferrerInformation -{ - /** - * @var string - */ - private $date; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $shop; - - /** - * @param string $date - * @param string $name - * @param string $shop - */ - public function __construct($date, $name, $shop) - { - $this->date = $date; - $this->name = $name; - $this->shop = $shop; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getShop() - { - return $this->shop; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/SentEmailInformation.php b/src/Core/Domain/Customer/QueryResult/SentEmailInformation.php deleted file mode 100644 index 41adedce..00000000 --- a/src/Core/Domain/Customer/QueryResult/SentEmailInformation.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class SentEmailInformation holds information about email sent to customer. - */ -class SentEmailInformation -{ - /** - * @var string - */ - private $date; - - /** - * @var string - */ - private $language; - - /** - * @var string - */ - private $subject; - - /** - * @var string - */ - private $template; - - /** - * @param string $date - * @param string $language - * @param string $subject - * @param string $template - */ - public function __construct($date, $language, $subject, $template) - { - $this->date = $date; - $this->language = $language; - $this->subject = $subject; - $this->template = $template; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } - - /** - * @return string - */ - public function getLanguage() - { - return $this->language; - } - - /** - * @return string - */ - public function getSubject() - { - return $this->subject; - } - - /** - * @return string - */ - public function getTemplate() - { - return $this->template; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/Subscriptions.php b/src/Core/Domain/Customer/QueryResult/Subscriptions.php deleted file mode 100644 index 47be69e3..00000000 --- a/src/Core/Domain/Customer/QueryResult/Subscriptions.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -class Subscriptions -{ - /** - * @var bool - */ - private $isNewsletterSubscribed; - - /** - * @var bool - */ - private $isPartnerOffersSubscribed; - - /** - * @param bool $isNewsletterSubscribed - * @param bool $isPartnerOffersSubscribed - */ - public function __construct($isNewsletterSubscribed, $isPartnerOffersSubscribed) - { - $this->isNewsletterSubscribed = $isNewsletterSubscribed; - $this->isPartnerOffersSubscribed = $isPartnerOffersSubscribed; - } - - /** - * @return bool - */ - public function isNewsletterSubscribed() - { - return $this->isNewsletterSubscribed; - } - - /** - * @return bool - */ - public function isPartnerOffersSubscribed() - { - return $this->isPartnerOffersSubscribed; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/ViewableCustomer.php b/src/Core/Domain/Customer/QueryResult/ViewableCustomer.php deleted file mode 100644 index 1e9aa606..00000000 --- a/src/Core/Domain/Customer/QueryResult/ViewableCustomer.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Class CustomerInformation stores customer information for viewing in Back Office. - */ -class ViewableCustomer -{ - /** - * @var CustomerId - */ - private $customerId; - - /** - * @var PersonalInformation - */ - private $personalInformation; - - /** - * @var OrdersInformation - */ - private $ordersInformation; - - /** - * @var CartInformation[] - */ - private $cartsInformation; - - /** - * @var ProductsInformation - */ - private $productsInformation; - - /** - * @var MessageInformation[] - */ - private $messagesInformation; - - /** - * @var DiscountInformation[] - */ - private $discountsInformation; - - /** - * @var SentEmailInformation[] - */ - private $sentEmailsInformation; - - /** - * @var LastConnectionInformation[] - */ - private $lastConnectionsInformation; - - /** - * @var GroupInformation[] - */ - private $groupsInformation; - - /** - * @var ReferrerInformation[] - */ - private $referrersInformation; - - /** - * @var AddressInformation[] - */ - private $addressesInformation; - - /** - * @var GeneralInformation - */ - private $generalInformation; - - /** - * @param CustomerId $customerId - * @param GeneralInformation $generalInformation - * @param PersonalInformation $personalInformation - * @param OrdersInformation $ordersInformation - * @param CartInformation[] $cartsInformation - * @param ProductsInformation $productsInformation - * @param MessageInformation[] $messagesInformation - * @param DiscountInformation[] $discountsInformation - * @param SentEmailInformation[] $sentEmailsInformation - * @param LastConnectionInformation[] $lastConnectionsInformation - * @param GroupInformation[] $groupsInformation - * @param ReferrerInformation[] $referrersInformation - * @param AddressInformation[] $addressesInformation - */ - public function __construct( - CustomerId $customerId, - GeneralInformation $generalInformation, - PersonalInformation $personalInformation, - OrdersInformation $ordersInformation, - array $cartsInformation, - ProductsInformation $productsInformation, - array $messagesInformation, - array $discountsInformation, - array $sentEmailsInformation, - array $lastConnectionsInformation, - array $groupsInformation, - array $referrersInformation, - array $addressesInformation - ) { - $this->customerId = $customerId; - $this->personalInformation = $personalInformation; - $this->ordersInformation = $ordersInformation; - $this->cartsInformation = $cartsInformation; - $this->productsInformation = $productsInformation; - $this->messagesInformation = $messagesInformation; - $this->discountsInformation = $discountsInformation; - $this->sentEmailsInformation = $sentEmailsInformation; - $this->lastConnectionsInformation = $lastConnectionsInformation; - $this->groupsInformation = $groupsInformation; - $this->referrersInformation = $referrersInformation; - $this->addressesInformation = $addressesInformation; - $this->generalInformation = $generalInformation; - } - - /** - * @return CustomerId - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return PersonalInformation - */ - public function getPersonalInformation() - { - return $this->personalInformation; - } - - /** - * @return OrdersInformation - */ - public function getOrdersInformation() - { - return $this->ordersInformation; - } - - /** - * @return CartInformation[] - */ - public function getCartsInformation() - { - return $this->cartsInformation; - } - - /** - * @return ProductsInformation - */ - public function getProductsInformation() - { - return $this->productsInformation; - } - - /** - * @return MessageInformation[] - */ - public function getMessagesInformation() - { - return $this->messagesInformation; - } - - /** - * @return DiscountInformation[] - */ - public function getDiscountsInformation() - { - return $this->discountsInformation; - } - - /** - * @return SentEmailInformation[] - */ - public function getSentEmailsInformation() - { - return $this->sentEmailsInformation; - } - - /** - * @return LastConnectionInformation[] - */ - public function getLastConnectionsInformation() - { - return $this->lastConnectionsInformation; - } - - /** - * @return GroupInformation[] - */ - public function getGroupsInformation() - { - return $this->groupsInformation; - } - - /** - * @return ReferrerInformation[] - */ - public function getReferrersInformation() - { - return $this->referrersInformation; - } - - /** - * @return AddressInformation[] - */ - public function getAddressesInformation() - { - return $this->addressesInformation; - } - - /** - * @return GeneralInformation - */ - public function getGeneralInformation() - { - return $this->generalInformation; - } -} diff --git a/src/Core/Domain/Customer/QueryResult/ViewedProductInformation.php b/src/Core/Domain/Customer/QueryResult/ViewedProductInformation.php deleted file mode 100644 index ef58c5d0..00000000 --- a/src/Core/Domain/Customer/QueryResult/ViewedProductInformation.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult; - -/** - * Class ViewedProductInformation holds information about product that customer has viewed. - */ -class ViewedProductInformation -{ - /** - * @var int - */ - private $productId; - - /** - * @var string - */ - private $productName; - - /** - * @var string - */ - private $productUrl; - - /** - * @param int $productId - * @param string $productName - * @param string $productUrl - */ - public function __construct($productId, $productName, $productUrl) - { - $this->productId = $productId; - $this->productName = $productName; - $this->productUrl = $productUrl; - } - - /** - * @return int - */ - public function getProductId() - { - return $this->productId; - } - - /** - * @return string - */ - public function getProductName() - { - return $this->productName; - } - - /** - * @return string - */ - public function getProductUrl() - { - return $this->productUrl; - } -} diff --git a/src/Core/Domain/Customer/ValueObject/ApeCode.php b/src/Core/Domain/Customer/ValueObject/ApeCode.php deleted file mode 100644 index 5a018809..00000000 --- a/src/Core/Domain/Customer/ValueObject/ApeCode.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; - -/** - * Every business in France is classified under an activity code - * entitled APE - Activite Principale de l’Entreprise - */ -class ApeCode -{ - /** - * @var string - */ - private $code; - - /** - * @param $code - */ - public function __construct($code) - { - $this->assertIsApeCode($code); - - $this->code = $code; - } - - /** - * @return string - */ - public function getValue() - { - return $this->code; - } - - private function assertIsApeCode($code) - { - if (is_string($code) && empty($code)) { - return; - } - - $isApeCode = is_string($code) && (bool) preg_match('/^\d{3,4}[a-zA-Z]{1}$/', $code); - - if (!$isApeCode) { - throw new CustomerConstraintException(sprintf('Invalid ape code %s provided', var_export($code, true)), CustomerConstraintException::INVALID_APE_CODE); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/Birthday.php b/src/Core/Domain/Customer/ValueObject/Birthday.php deleted file mode 100644 index 0529b5eb..00000000 --- a/src/Core/Domain/Customer/ValueObject/Birthday.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use DateTime; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; - -/** - * Defines rules for customer birthday and stores it's value - */ -class Birthday -{ - /** - * @var string empty birthday value - * - * It is used as a placeholder value when real birthday is not provided - */ - const EMPTY_BIRTHDAY = '0000-00-00'; - - /** - * @var string Date in format of Y-m-d or empty string for non defined birthday - */ - private $birthday; - - /** - * @return Birthday - */ - public static function createEmpty() - { - return new self(self::EMPTY_BIRTHDAY); - } - - /** - * @param string $birthday - */ - public function __construct($birthday) - { - $this->assertBirthdayIsInValidFormat($birthday); - $this->assertBirthdayIsNotAFutureDate($birthday); - - $this->birthday = $birthday; - } - - /** - * @return string - */ - public function getValue() - { - return $this->birthday; - } - - /** - * @return bool - */ - public function isEmpty() - { - return self::EMPTY_BIRTHDAY === $this->birthday; - } - - /** - * Birthday cannot be date in a future - * - * @param string $birthday - */ - private function assertBirthdayIsNotAFutureDate($birthday) - { - if (self::EMPTY_BIRTHDAY === $birthday) { - return; - } - - $birthdayDateTime = new DateTime($birthday); - $now = new DateTime(); - - if ($birthdayDateTime > $now) { - throw new CustomerConstraintException(sprintf('Invalid birthday "%s" provided. Birthday must be a past date.', $birthdayDateTime->format('Y-m-d')), CustomerConstraintException::INVALID_BIRTHDAY); - } - } - - /** - * Assert that birthday is actual date - * - * @param string $birthday - */ - private function assertBirthdayIsInValidFormat($birthday) - { - if (self::EMPTY_BIRTHDAY === $birthday) { - return; - } - - if (!is_string($birthday) || false === strtotime($birthday)) { - throw new CustomerConstraintException(sprintf('Invalid birthday %s value provided.', var_export($birthday, true)), CustomerConstraintException::INVALID_BIRTHDAY); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/CustomerDeleteMethod.php b/src/Core/Domain/Customer/ValueObject/CustomerDeleteMethod.php deleted file mode 100644 index 9b44e207..00000000 --- a/src/Core/Domain/Customer/ValueObject/CustomerDeleteMethod.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; - -/** - * Stores method in which customer can be deleted. - */ -class CustomerDeleteMethod -{ - /** - * If this option is used, then deleted customer can register again using same email. - */ - const ALLOW_CUSTOMER_REGISTRATION = 'allow_registration_after'; - - /** - * If this option is used, then deleted customer won't be able to register again using same email. - */ - const DENY_CUSTOMER_REGISTRATION = 'deny_registration_after'; - - /** - * @var int - */ - private $method; - - /** - * @param $method - */ - public function __construct($method) - { - $this->assertMethodIsDefined($method); - - $this->method = $method; - } - - /** - * Check if customer can register after it's deletion. - */ - public function isAllowedToRegisterAfterDelete() - { - return self::ALLOW_CUSTOMER_REGISTRATION === $this->method; - } - - /** - * @return string[] - */ - public static function getAvailableMethods() - { - return [self::ALLOW_CUSTOMER_REGISTRATION, self::DENY_CUSTOMER_REGISTRATION]; - } - - /** - * @param string $method - */ - private function assertMethodIsDefined($method) - { - $definedMethods = [self::ALLOW_CUSTOMER_REGISTRATION, self::DENY_CUSTOMER_REGISTRATION]; - - if (!in_array($method, $definedMethods)) { - throw new CustomerException(sprintf('Supplied customer delete method "%s" does not exists. Available methods are: %s.', $method, implode(',', $definedMethods))); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/CustomerId.php b/src/Core/Domain/Customer/ValueObject/CustomerId.php deleted file mode 100644 index a22fc489..00000000 --- a/src/Core/Domain/Customer/ValueObject/CustomerId.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; - -/** - * Defines Customer ID with it's constraints - */ -class CustomerId -{ - /** - * @var int - */ - private $customerId; - - /** - * @param int $customerId - */ - public function __construct($customerId) - { - $this->assertIntegerIsGreaterThanZero($customerId); - - $this->customerId = $customerId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->customerId; - } - - /** - * @param int $customerId - */ - private function assertIntegerIsGreaterThanZero($customerId) - { - if (!is_int($customerId) || 0 > $customerId) { - throw new CustomerException(sprintf('Customer id %s is invalid. Customer id must be number that is greater than zero.', var_export($customerId, true))); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/Email.php b/src/Core/Domain/Customer/ValueObject/Email.php deleted file mode 100644 index b147e01f..00000000 --- a/src/Core/Domain/Customer/ValueObject/Email.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email as ValueObjectEmail; - -/** - * @deprecated since version 1.7.6.4 use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email instead - */ -class Email extends ValueObjectEmail -{ - public function __construct($email) - { - @trigger_error(self::class . ' is deprecated. Use ' . ValueObjectEmail::class . ' instead', E_USER_DEPRECATED); - parent::__construct($email); - } -} diff --git a/src/Core/Domain/Customer/ValueObject/FirstName.php b/src/Core/Domain/Customer/ValueObject/FirstName.php deleted file mode 100644 index f00cfd74..00000000 --- a/src/Core/Domain/Customer/ValueObject/FirstName.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; - -/** - * Stores customer's first name - */ -class FirstName -{ - /** - * @var string Maximum allowed length for first name - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $firstName; - - /** - * @param string $firstName - */ - public function __construct($firstName) - { - $this->assertFirstNameDoesNotExceedAllowedLength($firstName); - $this->assertFirstNameIsValid($firstName); - - $this->firstName = $firstName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->firstName; - } - - /** - * @param string $firstName - * - * @throws CustomerConstraintException - */ - private function assertFirstNameIsValid($firstName) - { - $matchesFirstNamePattern = preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:¤|]*$/u', stripslashes($firstName)); - - if (!$matchesFirstNamePattern) { - throw new CustomerConstraintException(sprintf('Customer first name %s is invalid', var_export($firstName, true)), CustomerConstraintException::INVALID_FIRST_NAME); - } - } - - /** - * @param string $firstName - * - * @throws CustomerConstraintException - */ - private function assertFirstNameDoesNotExceedAllowedLength($firstName) - { - $firstName = html_entity_decode($firstName, ENT_COMPAT, 'UTF-8'); - - $length = function_exists('mb_strlen') ? mb_strlen($firstName, 'UTF-8') : strlen($firstName); - if (self::MAX_LENGTH < $length) { - throw new CustomerConstraintException(sprintf('Customer first name is too long. Max allowed length is %s', self::MAX_LENGTH), CustomerConstraintException::INVALID_FIRST_NAME); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/LastName.php b/src/Core/Domain/Customer/ValueObject/LastName.php deleted file mode 100644 index 31794464..00000000 --- a/src/Core/Domain/Customer/ValueObject/LastName.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; - -/** - * Stores customer's last name - */ -class LastName -{ - /** - * @var int Maximum allowed length for customer's last name - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $lastName; - - /** - * @param string $lastName - */ - public function __construct($lastName) - { - $this->assertLastNameDoesNotExceedAllowedLength($lastName); - $this->assertLastNameIsValid($lastName); - - $this->lastName = $lastName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->lastName; - } - - /** - * @param string $lastName - * - * @throws CustomerConstraintException - */ - private function assertLastNameIsValid($lastName) - { - $matchesLastNamePattern = preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:¤|]*$/u', stripslashes($lastName)); - - if (!$matchesLastNamePattern) { - throw new CustomerConstraintException(sprintf('Customer last name %s is invalid', var_export($lastName, true)), CustomerConstraintException::INVALID_LAST_NAME); - } - } - - /** - * @param string $lastName - * - * @throws CustomerConstraintException - */ - private function assertLastNameDoesNotExceedAllowedLength($lastName) - { - $lastName = html_entity_decode($lastName, ENT_COMPAT, 'UTF-8'); - - $length = function_exists('mb_strlen') ? mb_strlen($lastName, 'UTF-8') : strlen($lastName); - if (self::MAX_LENGTH < $length) { - throw new CustomerConstraintException(sprintf('Customer email is too long. Max allowed length is %s', self::MAX_LENGTH), CustomerConstraintException::INVALID_LAST_NAME); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/Password.php b/src/Core/Domain/Customer/ValueObject/Password.php deleted file mode 100644 index bef215eb..00000000 --- a/src/Core/Domain/Customer/ValueObject/Password.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; - -/** - * Stores customer's plain password - */ -class Password -{ - /** - * @var string Minimum required password length for customer - */ - const MIN_LENGTH = 5; - - /** - * @var string Maximum allowed password length for customer. - * - * It's limited to 72 chars because of PASSWORD_BCRYPT algorithm - * used in password_hash() function. - */ - const MAX_LENGTH = 72; - - /** - * @var string - */ - private $password; - - /** - * @param string $password - */ - public function __construct($password) - { - $this->assertPasswordIsWithinAllowedLength($password); - - $this->password = $password; - } - - /** - * @return string - */ - public function getValue() - { - return $this->password; - } - - /** - * @param string $password - */ - private function assertPasswordIsWithinAllowedLength($password) - { - $length = function_exists('mb_strlen') ? mb_strlen($password, 'UTF-8') : strlen($password); - - if (self::MIN_LENGTH > $length || $length > self::MAX_LENGTH) { - throw new CustomerConstraintException(sprintf('Customer password length must be between %s and %s', self::MIN_LENGTH, self::MAX_LENGTH), CustomerConstraintException::INVALID_PASSWORD); - } - } -} diff --git a/src/Core/Domain/Customer/ValueObject/RequiredField.php b/src/Core/Domain/Customer/ValueObject/RequiredField.php deleted file mode 100644 index 10c89ee7..00000000 --- a/src/Core/Domain/Customer/ValueObject/RequiredField.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject; - -/** - * Stores required field values for customer. - */ -class RequiredField -{ - /** - * Partner offers field name - */ - const PARTNER_OFFERS = 'optin'; - - /** - * Newsletter field name - */ - const NEWSLETTER = 'newsletter'; - - /** - * All allowed required fields for customer - */ - const ALLOWED_REQUIRED_FIELDS = [ - self::PARTNER_OFFERS, - self::NEWSLETTER, - ]; -} diff --git a/src/Core/Domain/CustomerMessage/Command/AddOrderCustomerMessageCommand.php b/src/Core/Domain/CustomerMessage/Command/AddOrderCustomerMessageCommand.php deleted file mode 100644 index dbfd72a9..00000000 --- a/src/Core/Domain/CustomerMessage/Command/AddOrderCustomerMessageCommand.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Command; - -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception\CustomerMessageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * This command adds/sends message to the customer related with the order. - */ -class AddOrderCustomerMessageCommand -{ - /** - * @var string - */ - private $message; - - /** - * @var OrderId - */ - private $orderId; - /** - * @var bool - */ - private $isPrivate; - - /** - * @param int $orderId - * @param string $message - * @param bool $isPrivate - * - * @throws OrderException - * @throws CustomerMessageConstraintException - */ - public function __construct(int $orderId, string $message, bool $isPrivate) - { - $this->orderId = new OrderId($orderId); - $this->setMessage($message); - $this->isPrivate = $isPrivate; - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return string - */ - public function getMessage(): string - { - return $this->message; - } - - /** - * @return bool - */ - public function isPrivate(): bool - { - return $this->isPrivate; - } - - /** - * @param string $message - * - * @throws CustomerMessageConstraintException - */ - private function setMessage(string $message): void - { - if (!$message) { - throw new CustomerMessageConstraintException('Missing required message', CustomerMessageConstraintException::MISSING_MESSAGE); - } - - $this->message = $message; - } -} diff --git a/src/Core/Domain/CustomerMessage/CommandHandler/AddOrderCustomerMessageHandlerInterface.php b/src/Core/Domain/CustomerMessage/CommandHandler/AddOrderCustomerMessageHandlerInterface.php deleted file mode 100644 index 3c13ef37..00000000 --- a/src/Core/Domain/CustomerMessage/CommandHandler/AddOrderCustomerMessageHandlerInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerMessage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Command\AddOrderCustomerMessageCommand; - -/** - * Interface AddOrderCustomerMessageHandlerInterface - */ -interface AddOrderCustomerMessageHandlerInterface -{ - public function handle(AddOrderCustomerMessageCommand $command); -} diff --git a/src/Core/Domain/CustomerMessage/Exception/CannotSendEmailException.php b/src/Core/Domain/CustomerMessage/Exception/CannotSendEmailException.php deleted file mode 100644 index 24ade2f9..00000000 --- a/src/Core/Domain/CustomerMessage/Exception/CannotSendEmailException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception; - -class CannotSendEmailException extends CustomerMessageException -{ -} diff --git a/src/Core/Domain/CustomerMessage/Exception/CustomerMessageConstraintException.php b/src/Core/Domain/CustomerMessage/Exception/CustomerMessageConstraintException.php deleted file mode 100644 index aadb8789..00000000 --- a/src/Core/Domain/CustomerMessage/Exception/CustomerMessageConstraintException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception; - -class CustomerMessageConstraintException extends CustomerMessageException -{ - public const MISSING_MESSAGE = 1; - public const INVALID_MESSAGE = 2; -} diff --git a/src/Core/Domain/CustomerMessage/Exception/CustomerMessageException.php b/src/Core/Domain/CustomerMessage/Exception/CustomerMessageException.php deleted file mode 100644 index 6070e8bd..00000000 --- a/src/Core/Domain/CustomerMessage/Exception/CustomerMessageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -class CustomerMessageException extends DomainException -{ - public const ORDER_CUSTOMER_NOT_FOUND = 1; -} diff --git a/src/Core/Domain/CustomerService/Command/ForwardCustomerThreadCommand.php b/src/Core/Domain/CustomerService/Command/ForwardCustomerThreadCommand.php deleted file mode 100644 index 94f9947d..00000000 --- a/src/Core/Domain/CustomerService/Command/ForwardCustomerThreadCommand.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Command; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Forwards customer thread - */ -class ForwardCustomerThreadCommand -{ - /** - * @var EmployeeId|null - */ - private $employeeId; - - /** - * @var CustomerThreadId - */ - private $customerThreadId; - - /** - * @var Email|null - */ - private $email; - - /** - * @var string - */ - private $comment; - - /** - * Creates command for forwarding customer thread for another employee - * - * @param int $customerThreadId - * @param int $employeeId - * @param string $comment - * - * @return self - */ - public static function toAnotherEmployee($customerThreadId, $employeeId, $comment) - { - $command = new self(); - $command->employeeId = new EmployeeId($employeeId); - $command->customerThreadId = new CustomerThreadId($customerThreadId); - $command->comment = $comment; - - return $command; - } - - /** - * Creates command for forwarding customer thread for someone else (not employee) - * - * @param int $customerThreadId - * @param string $email - * @param string $comment - * - * @return ForwardCustomerThreadCommand - */ - public static function toSomeoneElse($customerThreadId, $email, $comment) - { - $command = new self(); - $command->email = new Email($email); - $command->customerThreadId = new CustomerThreadId($customerThreadId); - $command->comment = $comment; - - return $command; - } - - /** - * Command should be created using static factories - */ - private function __construct() - { - } - - /** - * @return EmployeeId|null - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @return CustomerThreadId - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } - - /** - * @return Email|null - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return string - */ - public function getComment() - { - return $this->comment; - } - - /** - * @return bool - */ - public function forwardToEmployee() - { - return null !== $this->employeeId; - } -} diff --git a/src/Core/Domain/CustomerService/Command/ReplyToCustomerThreadCommand.php b/src/Core/Domain/CustomerService/Command/ReplyToCustomerThreadCommand.php deleted file mode 100644 index f567229f..00000000 --- a/src/Core/Domain/CustomerService/Command/ReplyToCustomerThreadCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Command; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; - -/** - * Reply to given customer thread - */ -class ReplyToCustomerThreadCommand -{ - /** - * @var CustomerThreadId - */ - private $customerThreadId; - - /** - * @var string - */ - private $replyMessage; - - /** - * @param int $customerThreadId - * @param string $replyMessage - */ - public function __construct($customerThreadId, $replyMessage) - { - $this->customerThreadId = new CustomerThreadId($customerThreadId); - $this->replyMessage = $replyMessage; - } - - /** - * @return CustomerThreadId - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } - - /** - * @return string - */ - public function getReplyMessage() - { - return $this->replyMessage; - } -} diff --git a/src/Core/Domain/CustomerService/Command/UpdateCustomerThreadStatusCommand.php b/src/Core/Domain/CustomerService/Command/UpdateCustomerThreadStatusCommand.php deleted file mode 100644 index 793d51d3..00000000 --- a/src/Core/Domain/CustomerService/Command/UpdateCustomerThreadStatusCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Command; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadStatus; - -/** - * Updates customer thread with given status - */ -class UpdateCustomerThreadStatusCommand -{ - /** - * @var CustomerThreadId - */ - private $customerThreadId; - - /** - * @var CustomerThreadStatus - */ - private $customerThreadStatus; - - /** - * @param int $customerThreadId - * @param string $newCustomerThreadStatus - */ - public function __construct($customerThreadId, $newCustomerThreadStatus) - { - $this->customerThreadId = new CustomerThreadId($customerThreadId); - $this->customerThreadStatus = new CustomerThreadStatus($newCustomerThreadStatus); - } - - /** - * @return CustomerThreadId - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } - - /** - * @return CustomerThreadStatus - */ - public function getCustomerThreadStatus() - { - return $this->customerThreadStatus; - } -} diff --git a/src/Core/Domain/CustomerService/CommandHandler/ForwardCustomerThreadHandlerInterface.php b/src/Core/Domain/CustomerService/CommandHandler/ForwardCustomerThreadHandlerInterface.php deleted file mode 100644 index 7ae4f05e..00000000 --- a/src/Core/Domain/CustomerService/CommandHandler/ForwardCustomerThreadHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ForwardCustomerThreadCommand; - -/** - * Interface for service that forwards customer thread to another employee - */ -interface ForwardCustomerThreadHandlerInterface -{ - /** - * @param ForwardCustomerThreadCommand $command - */ - public function handle(ForwardCustomerThreadCommand $command); -} diff --git a/src/Core/Domain/CustomerService/CommandHandler/ReplyToCustomerThreadHandlerInterface.php b/src/Core/Domain/CustomerService/CommandHandler/ReplyToCustomerThreadHandlerInterface.php deleted file mode 100644 index ac175e62..00000000 --- a/src/Core/Domain/CustomerService/CommandHandler/ReplyToCustomerThreadHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ReplyToCustomerThreadCommand; - -/** - * Interface for service that handles replying to customer thread - */ -interface ReplyToCustomerThreadHandlerInterface -{ - /** - * @param ReplyToCustomerThreadCommand $command - */ - public function handle(ReplyToCustomerThreadCommand $command); -} diff --git a/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandler.php b/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandler.php deleted file mode 100644 index 1387c847..00000000 --- a/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandler.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler; - -use Doctrine\DBAL\Driver\Connection; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\UpdateCustomerThreadStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerServiceException; - -/** - * @internal - */ -final class UpdateCustomerThreadStatusHandler implements UpdateCustomerThreadStatusHandlerInterface -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @param Connection $connection - * @param string $dbPrefix - */ - public function __construct(Connection $connection, $dbPrefix) - { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - } - - /** - * {@inheritdoc} - */ - public function handle(UpdateCustomerThreadStatusCommand $command) - { - $statement = $this->connection->prepare(' - UPDATE ' . $this->dbPrefix . 'customer_thread - SET status = :status - WHERE id_customer_thread = :id_customer_thread - LIMIT 1 - '); - - $statement->bindValue(':status', $command->getCustomerThreadStatus()->getValue()); - $statement->bindValue(':id_customer_thread', $command->getCustomerThreadId()->getValue()); - - if (false === $statement->execute()) { - throw new CustomerServiceException('Failed to update customer thread status'); - } - } -} diff --git a/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandlerInterface.php b/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandlerInterface.php deleted file mode 100644 index f79a36c6..00000000 --- a/src/Core/Domain/CustomerService/CommandHandler/UpdateCustomerThreadStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\UpdateCustomerThreadStatusCommand; - -/** - * Interface for service that handles updating thread status - */ -interface UpdateCustomerThreadStatusHandlerInterface -{ - /** - * @param UpdateCustomerThreadStatusCommand $command - */ - public function handle(UpdateCustomerThreadStatusCommand $command); -} diff --git a/src/Core/Domain/CustomerService/Exception/CustomerServiceException.php b/src/Core/Domain/CustomerService/Exception/CustomerServiceException.php deleted file mode 100644 index 4e9f8db2..00000000 --- a/src/Core/Domain/CustomerService/Exception/CustomerServiceException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for customer service subdomain - */ -class CustomerServiceException extends DomainException -{ -} diff --git a/src/Core/Domain/CustomerService/Exception/CustomerThreadNotFoundException.php b/src/Core/Domain/CustomerService/Exception/CustomerThreadNotFoundException.php deleted file mode 100644 index 55a0033e..00000000 --- a/src/Core/Domain/CustomerService/Exception/CustomerThreadNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception; - -/** - * Thrown when customer thread is not found - */ -class CustomerThreadNotFoundException extends CustomerServiceException -{ -} diff --git a/src/Core/Domain/CustomerService/Query/GetCustomerServiceSignature.php b/src/Core/Domain/CustomerService/Query/GetCustomerServiceSignature.php deleted file mode 100644 index 1e6f5bab..00000000 --- a/src/Core/Domain/CustomerService/Query/GetCustomerServiceSignature.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Query; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Gets signature for replying in customer thread - */ -class GetCustomerServiceSignature -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @param int $languageId - */ - public function __construct($languageId) - { - $this->languageId = new LanguageId($languageId); - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/CustomerService/Query/GetCustomerThreadForViewing.php b/src/Core/Domain/CustomerService/Query/GetCustomerThreadForViewing.php deleted file mode 100644 index 115d5ffb..00000000 --- a/src/Core/Domain/CustomerService/Query/GetCustomerThreadForViewing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\Query; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; - -/** - * Gets customer thread for viewing - */ -class GetCustomerThreadForViewing -{ - /** - * @var CustomerThreadId - */ - private $customerThreadId; - - /** - * @param int $customerThreadId - */ - public function __construct($customerThreadId) - { - $this->customerThreadId = new CustomerThreadId($customerThreadId); - } - - /** - * @return CustomerThreadId - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } -} diff --git a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandler.php b/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandler.php deleted file mode 100644 index 22107e97..00000000 --- a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandler.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerServiceSignature; - -/** - * @internal - */ -final class GetCustomerServiceSignatureHandler implements GetCustomerServiceSignatureHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(GetCustomerServiceSignature $query) - { - $signature = $this->configuration->get('PS_CUSTOMER_SERVICE_SIGNATURE'); - - return $signature[$query->getLanguageId()->getValue()]; - } -} diff --git a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandlerInterface.php b/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandlerInterface.php deleted file mode 100644 index 71fa6205..00000000 --- a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerServiceSignatureHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerServiceSignature; - -/** - * Interface for service that gets customer service signature - */ -interface GetCustomerServiceSignatureHandlerInterface -{ - /** - * @param GetCustomerServiceSignature $query - * - * @return string - */ - public function handle(GetCustomerServiceSignature $query); -} diff --git a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerThreadForViewingHandlerInterface.php b/src/Core/Domain/CustomerService/QueryHandler/GetCustomerThreadForViewingHandlerInterface.php deleted file mode 100644 index 7b7f5cfd..00000000 --- a/src/Core/Domain/CustomerService/QueryHandler/GetCustomerThreadForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerThreadForViewing; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadView; - -/** - * Interface for service that gets customer thread for viewing - */ -interface GetCustomerThreadForViewingHandlerInterface -{ - /** - * @param GetCustomerThreadForViewing $query - * - * @return CustomerThreadView - */ - public function handle(GetCustomerThreadForViewing $query); -} diff --git a/src/Core/Domain/CustomerService/QueryResult/CustomerInformation.php b/src/Core/Domain/CustomerService/QueryResult/CustomerInformation.php deleted file mode 100644 index 205f29b1..00000000 --- a/src/Core/Domain/CustomerService/QueryResult/CustomerInformation.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult; - -/** - * Carries data about customer for customer thread - */ -class CustomerInformation -{ - /** - * @var int|null - */ - private $customerId; - - /** - * @var string|null - */ - private $firstName; - - /** - * @var string|null - */ - private $lastName; - - /** - * @var string - */ - private $email; - - /** - * @var int - */ - private $validatedOrdersCount; - - /** - * @var string - */ - private $validatedOrdersAmount; - - /** - * @var string|null - */ - private $customerSinceDate; - - /** - * @param string $email - * - * @return self - */ - public static function withEmailOnly($email) - { - return new self(null, null, null, $email, null, null, null); - } - - /** - * @param int|null $customerId - * @param string|null $firstName - * @param string|null $lastName - * @param string $email - * @param int $validatedOrdersCount - * @param string $validatedOrdersAmount - * @param string $customerSinceDate - */ - public function __construct( - $customerId, - $firstName, - $lastName, - $email, - $validatedOrdersCount, - $validatedOrdersAmount, - $customerSinceDate - ) { - $this->customerId = $customerId; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->email = $email; - $this->validatedOrdersCount = $validatedOrdersCount; - $this->validatedOrdersAmount = $validatedOrdersAmount; - $this->customerSinceDate = $customerSinceDate; - } - - /** - * @return int|null - */ - public function getCustomerId() - { - return $this->customerId; - } - - /** - * @return string|null - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return string|null - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return int - */ - public function getValidatedOrdersCount() - { - return $this->validatedOrdersCount; - } - - /** - * @return string - */ - public function getValidatedOrdersAmount() - { - return $this->validatedOrdersAmount; - } - - /** - * @return string|null - */ - public function getCustomerSinceDate() - { - return $this->customerSinceDate; - } -} diff --git a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadMessage.php b/src/Core/Domain/CustomerService/QueryResult/CustomerThreadMessage.php deleted file mode 100644 index 5691ca41..00000000 --- a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadMessage.php +++ /dev/null @@ -1,183 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult; - -/** - * Carries data for single customer thread message - */ -class CustomerThreadMessage -{ - /** - * @var string - */ - private $type; - - /** - * @var string - */ - private $message; - - /** - * @var string - */ - private $date; - - /** - * @var string|null - */ - private $employeeImage; - - /** - * @var string|null - */ - private $employeeName; - - /** - * @var string|null - */ - private $customerName; - - /** - * @var string|null - */ - private $attachmentFile; - - /** - * @var int|null - */ - private $productId; - - /** - * @var string|null - */ - private $productName; - - /** - * @param string $type - * @param string $message - * @param string $date - * @param string|null $employeeImage - * @param string|null $employeeName - * @param string|null $customerName - * @param string|null $attachmentFile - * @param int|null $productId - * @param string|null $productName - */ - public function __construct( - $type, - $message, - $date, - $employeeImage, - $employeeName, - $customerName, - $attachmentFile, - $productId, - $productName - ) { - $this->type = $type; - $this->message = $message; - $this->date = $date; - $this->employeeImage = $employeeImage; - $this->employeeName = $employeeName; - $this->customerName = $customerName; - $this->attachmentFile = $attachmentFile; - $this->productId = $productId; - $this->productName = $productName; - } - - /** - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } - - /** - * @return string|null - */ - public function getEmployeeImage() - { - return $this->employeeImage; - } - - /** - * @return string|null - */ - public function getEmployeeName() - { - return $this->employeeName; - } - - /** - * @return string|null - */ - public function getCustomerName() - { - return $this->customerName; - } - - /** - * @return string|null - */ - public function getAttachmentFile() - { - return $this->attachmentFile; - } - - /** - * @return int|null - */ - public function getProductId() - { - return $this->productId; - } - - /** - * @return string|null - */ - public function getProductName() - { - return $this->productName; - } -} diff --git a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimeline.php b/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimeline.php deleted file mode 100644 index 649c2817..00000000 --- a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimeline.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult; - -/** - * Carries data for customer thread timeline - */ -class CustomerThreadTimeline -{ - /** @var CustomerThreadTimelineItem[] */ - private $timelineItems; - - /** - * @param CustomerThreadTimelineItem[] - */ - public function __construct(array $timelineItems) - { - $this->timelineItems = $timelineItems; - } - - /** - * @return CustomerThreadTimelineItem[] - */ - public function getTimelineItems() - { - return $this->timelineItems; - } -} diff --git a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimelineItem.php b/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimelineItem.php deleted file mode 100644 index 0a02bb29..00000000 --- a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadTimelineItem.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult; - -/** - * Carries data about single timeline item - */ -class CustomerThreadTimelineItem -{ - /** - * @var string - */ - private $content; - - /** - * @var string - */ - private $icon; - - /** - * @var string - */ - private $arrow; - - /** - * @var string - */ - private $date; - - /** - * @var string|null - */ - private $color; - - /** - * @var int|null - */ - private $relatedOrderId; - - /** - * @param string $content - * @param string $icon - * @param string $arrow - * @param string $date - * @param string|null $color - * @param int|null $relatedOrderId - */ - public function __construct( - $content, - $icon, - $arrow, - $date, - $color = null, - $relatedOrderId = null - ) { - $this->content = $content; - $this->icon = $icon; - $this->arrow = $arrow; - $this->date = $date; - $this->color = $color; - $this->relatedOrderId = $relatedOrderId; - } - - /** - * @return string - */ - public function getContent() - { - return $this->content; - } - - /** - * @return string - */ - public function getIcon() - { - return $this->icon; - } - - /** - * @return string - */ - public function getArrow() - { - return $this->arrow; - } - - /** - * @return string - */ - public function getDate() - { - return $this->date; - } - - /** - * @return string|null - */ - public function getColor() - { - return $this->color; - } - - /** - * @return int|null - */ - public function getRelatedOrderId() - { - return $this->relatedOrderId; - } -} diff --git a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadView.php b/src/Core/Domain/CustomerService/QueryResult/CustomerThreadView.php deleted file mode 100644 index 0169fd7e..00000000 --- a/src/Core/Domain/CustomerService/QueryResult/CustomerThreadView.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject\CustomerThreadId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Carries data for customer thread view - */ -class CustomerThreadView -{ - /** - * @var CustomerThreadId - */ - private $customerThreadId; - - /** - * @var array - */ - private $actions; - - /** - * @var CustomerInformation - */ - private $customerInformation; - - /** - * @var string - */ - private $contactName; - - /** - * @var CustomerThreadMessage[] - */ - private $messages; - - /** - * @var LanguageId - */ - private $languageId; - - /** - * @var CustomerThreadTimeline - */ - private $timeline; - - /** - * @param CustomerThreadId $customerThreadId - * @param LanguageId $languageId - * @param array $actions - * @param CustomerInformation $customerInformation - * @param string $contactName - * @param CustomerThreadMessage[] $messages - * @param CustomerThreadTimeline $timeline - */ - public function __construct( - CustomerThreadId $customerThreadId, - LanguageId $languageId, - array $actions, - CustomerInformation $customerInformation, - $contactName, - array $messages, - CustomerThreadTimeline $timeline - ) { - $this->customerThreadId = $customerThreadId; - $this->actions = $actions; - $this->customerInformation = $customerInformation; - $this->contactName = $contactName; - $this->messages = $messages; - $this->languageId = $languageId; - $this->timeline = $timeline; - } - - /** - * @return CustomerThreadId - */ - public function getCustomerThreadId() - { - return $this->customerThreadId; - } - - /** - * @return array - */ - public function getActions() - { - return $this->actions; - } - - /** - * @return CustomerInformation - */ - public function getCustomerInformation() - { - return $this->customerInformation; - } - - /** - * @return string - */ - public function getContactName() - { - return $this->contactName; - } - - /** - * @return CustomerThreadMessage[] - */ - public function getMessages() - { - return $this->messages; - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @return CustomerThreadTimeline - */ - public function getTimeline() - { - return $this->timeline; - } -} diff --git a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadId.php b/src/Core/Domain/CustomerService/ValueObject/CustomerThreadId.php deleted file mode 100644 index 361324a8..00000000 --- a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadId.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerServiceException; - -/** - * Defines customer thread id - */ -class CustomerThreadId -{ - /** - * @var int - */ - private $customerThreadId; - - /** - * @param int $customerThreadId - */ - public function __construct($customerThreadId) - { - if (!is_int($customerThreadId) || 0 > $customerThreadId) { - throw new CustomerServiceException('CustomerThreadId must be of type int and greater than zero.'); - } - - $this->customerThreadId = $customerThreadId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->customerThreadId; - } -} diff --git a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadMessageType.php b/src/Core/Domain/CustomerService/ValueObject/CustomerThreadMessageType.php deleted file mode 100644 index 96ee069c..00000000 --- a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadMessageType.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject; - -/** - * Defines types of thread messages - */ -final class CustomerThreadMessageType -{ - /** - * When message is written by employee - */ - const EMPLOYEE = 'employee'; - - /** - * When message is written by customer - */ - const CUSTOMER = 'customer'; -} diff --git a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadStatus.php b/src/Core/Domain/CustomerService/ValueObject/CustomerThreadStatus.php deleted file mode 100644 index 7a5fe77b..00000000 --- a/src/Core/Domain/CustomerService/ValueObject/CustomerThreadStatus.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\CustomerService\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Exception\CustomerServiceException; - -/** - * Status that customer thread can have - */ -final class CustomerThreadStatus -{ - const OPEN = 'open'; - const CLOSED = 'closed'; - const PENDING_1 = 'pending1'; - const PENDING_2 = 'pending2'; - - /** - * @var string - */ - private $status; - - /** - * @param string $status - */ - public function __construct($status) - { - $availableStatuses = [ - self::OPEN, - self::CLOSED, - self::PENDING_1, - self::PENDING_2, - ]; - - if (!in_array($status, $availableStatuses)) { - throw new CustomerServiceException(sprintf('Customer thread status "%s" is not defined, available statuses are "%s"', $status, implode(',', $availableStatuses))); - } - - $this->status = $status; - } - - /** - * @return string - */ - public function getValue() - { - return $this->status; - } -} diff --git a/src/Core/Domain/Employee/Command/AddEmployeeCommand.php b/src/Core/Domain/Employee/Command/AddEmployeeCommand.php deleted file mode 100644 index 644f5761..00000000 --- a/src/Core/Domain/Employee/Command/AddEmployeeCommand.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Adds new employee with given data - */ -class AddEmployeeCommand -{ - /** - * @var FirstName - */ - private $firstName; - - /** - * @var LastName - */ - private $lastName; - - /** - * @var Email - */ - private $email; - - /** - * @var int - */ - private $defaultPageId; - - /** - * @var int - */ - private $languageId; - - /** - * @var bool - */ - private $active; - - /** - * @var int - */ - private $profileId; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @var Password - */ - private $plainPassword; - - /** - * @param string $firstName - * @param string $lastName - * @param string $email - * @param string $plainPassword - * @param int $defaultPageId - * @param int $languageId - * @param bool $active - * @param int $profileId - * @param array $shopAssociation - */ - public function __construct( - $firstName, - $lastName, - $email, - $plainPassword, - $defaultPageId, - $languageId, - $active, - $profileId, - array $shopAssociation - ) { - $this->firstName = new FirstName($firstName); - $this->lastName = new LastName($lastName); - $this->email = new Email($email); - $this->defaultPageId = $defaultPageId; - $this->languageId = $languageId; - $this->active = $active; - $this->profileId = $profileId; - $this->shopAssociation = $shopAssociation; - $this->plainPassword = new Password($plainPassword); - } - - /** - * @return FirstName - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return LastName - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return int - */ - public function getDefaultPageId() - { - return $this->defaultPageId; - } - - /** - * @return int - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->active; - } - - /** - * @return int - */ - public function getProfileId() - { - return $this->profileId; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @return Password - */ - public function getPlainPassword() - { - return $this->plainPassword; - } -} diff --git a/src/Core/Domain/Employee/Command/BulkDeleteEmployeeCommand.php b/src/Core/Domain/Employee/Command/BulkDeleteEmployeeCommand.php deleted file mode 100644 index 94677e28..00000000 --- a/src/Core/Domain/Employee/Command/BulkDeleteEmployeeCommand.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Class BulkDeleteEmployeeCommand. - */ -class BulkDeleteEmployeeCommand -{ - /** - * @var EmployeeId[] - */ - private $employeeIds; - - /** - * @param int[] $employeeIds - */ - public function __construct(array $employeeIds) - { - $this->setEmployeeIds($employeeIds); - } - - /** - * @return EmployeeId[] - */ - public function getEmployeeIds() - { - return $this->employeeIds; - } - - /** - * @param int[] $employeeIds - */ - private function setEmployeeIds(array $employeeIds) - { - foreach ($employeeIds as $employeeId) { - $this->employeeIds[] = new EmployeeId((int) $employeeId); - } - } -} diff --git a/src/Core/Domain/Employee/Command/BulkUpdateEmployeeStatusCommand.php b/src/Core/Domain/Employee/Command/BulkUpdateEmployeeStatusCommand.php deleted file mode 100644 index febe03f6..00000000 --- a/src/Core/Domain/Employee/Command/BulkUpdateEmployeeStatusCommand.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Class UpdateEmployeesStatusCommand updates employees status. - */ -class BulkUpdateEmployeeStatusCommand -{ - /** - * @var bool - */ - private $status; - - /** - * @var EmployeeId[] - */ - private $employeeIds; - - /** - * @param int[] $employeeIds - * @param bool $status - */ - public function __construct(array $employeeIds, $status) - { - $this->status = $status; - - $this->setEmployeeIds($employeeIds); - } - - /** - * @return bool - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return EmployeeId[] - */ - public function getEmployeeIds() - { - return $this->employeeIds; - } - - /** - * @param int[] $employeeIds - */ - private function setEmployeeIds(array $employeeIds) - { - foreach ($employeeIds as $employeeId) { - $this->employeeIds[] = new EmployeeId((int) $employeeId); - } - } -} diff --git a/src/Core/Domain/Employee/Command/DeleteEmployeeCommand.php b/src/Core/Domain/Employee/Command/DeleteEmployeeCommand.php deleted file mode 100644 index 489650fc..00000000 --- a/src/Core/Domain/Employee/Command/DeleteEmployeeCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Class DeleteEmployeeCommand deletes given employee. - */ -class DeleteEmployeeCommand -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param int $employeeId - */ - public function __construct($employeeId) - { - $this->employeeId = new EmployeeId($employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/Command/EditEmployeeCommand.php b/src/Core/Domain/Employee/Command/EditEmployeeCommand.php deleted file mode 100644 index 10314e18..00000000 --- a/src/Core/Domain/Employee/Command/EditEmployeeCommand.php +++ /dev/null @@ -1,297 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Edit employee with given data. - */ -class EditEmployeeCommand -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @var FirstName - */ - private $firstName; - - /** - * @var LastName - */ - private $lastName; - - /** - * @var Email - */ - private $email; - - /** - * @var int - */ - private $defaultPageId; - - /** - * @var int - */ - private $languageId; - - /** - * @var bool - */ - private $active; - - /** - * @var int - */ - private $profileId; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @var Password - */ - private $plainPassword; - - /** - * @param int $employeeId - */ - public function __construct($employeeId) - { - $this->employeeId = new EmployeeId((int) $employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @param EmployeeId $employeeId - * - * @return EditEmployeeCommand - */ - public function setEmployeeId($employeeId) - { - $this->employeeId = $employeeId; - - return $this; - } - - /** - * @return FirstName - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @param string $firstName - * - * @return EditEmployeeCommand - */ - public function setFirstName($firstName) - { - $this->firstName = new FirstName($firstName); - - return $this; - } - - /** - * @return LastName - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @param string $lastName - * - * @return EditEmployeeCommand - */ - public function setLastName($lastName) - { - $this->lastName = new LastName($lastName); - - return $this; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - * - * @return EditEmployeeCommand - */ - public function setEmail($email) - { - $this->email = new Email($email); - - return $this; - } - - /** - * @return int - */ - public function getDefaultPageId() - { - return $this->defaultPageId; - } - - /** - * @param int $defaultPageId - * - * @return EditEmployeeCommand - */ - public function setDefaultPageId($defaultPageId) - { - $this->defaultPageId = $defaultPageId; - - return $this; - } - - /** - * @return int - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @param int $languageId - * - * @return EditEmployeeCommand - */ - public function setLanguageId($languageId) - { - $this->languageId = $languageId; - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->active; - } - - /** - * @param bool $active - * - * @return EditEmployeeCommand - */ - public function setActive($active) - { - $this->active = $active; - - return $this; - } - - /** - * @return int - */ - public function getProfileId() - { - return $this->profileId; - } - - /** - * @param int $profileId - * - * @return EditEmployeeCommand - */ - public function setProfileId($profileId) - { - $this->profileId = $profileId; - - return $this; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param array $shopAssociation - * - * @return EditEmployeeCommand - */ - public function setShopAssociation($shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } - - /** - * @return Password - */ - public function getPlainPassword() - { - return $this->plainPassword; - } - - /** - * @param string $plainPassword - * - * @return EditEmployeeCommand - */ - public function setPlainPassword($plainPassword) - { - $this->plainPassword = new Password($plainPassword); - - return $this; - } -} diff --git a/src/Core/Domain/Employee/Command/ToggleEmployeeStatusCommand.php b/src/Core/Domain/Employee/Command/ToggleEmployeeStatusCommand.php deleted file mode 100644 index 39fb5d16..00000000 --- a/src/Core/Domain/Employee/Command/ToggleEmployeeStatusCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Command; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Class ToggleEmployeeStatusCommand. - */ -class ToggleEmployeeStatusCommand -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param int $employeeId - */ - public function __construct($employeeId) - { - $this->employeeId = new EmployeeId($employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/CommandHandler/AddEmployeeHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/AddEmployeeHandlerInterface.php deleted file mode 100644 index 72d2a8b6..00000000 --- a/src/Core/Domain/Employee/CommandHandler/AddEmployeeHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\AddEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Interface for services that handle command which adds new employee - */ -interface AddEmployeeHandlerInterface -{ - /** - * @param AddEmployeeCommand $command - * - * @return EmployeeId Added employee's ID - */ - public function handle(AddEmployeeCommand $command); -} diff --git a/src/Core/Domain/Employee/CommandHandler/BulkDeleteEmployeeHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/BulkDeleteEmployeeHandlerInterface.php deleted file mode 100644 index 6a341b71..00000000 --- a/src/Core/Domain/Employee/CommandHandler/BulkDeleteEmployeeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkDeleteEmployeeCommand; - -/** - * Interface BulkDeleteEmployeeHandlerInterface. - */ -interface BulkDeleteEmployeeHandlerInterface -{ - /** - * @param BulkDeleteEmployeeCommand $command - */ - public function handle(BulkDeleteEmployeeCommand $command); -} diff --git a/src/Core/Domain/Employee/CommandHandler/BulkUpdateEmployeeStatusHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/BulkUpdateEmployeeStatusHandlerInterface.php deleted file mode 100644 index 96674576..00000000 --- a/src/Core/Domain/Employee/CommandHandler/BulkUpdateEmployeeStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkUpdateEmployeeStatusCommand; - -/** - * Interface UpdateEmployeeStatusHandlerInterface. - */ -interface BulkUpdateEmployeeStatusHandlerInterface -{ - /** - * @param BulkUpdateEmployeeStatusCommand $command - */ - public function handle(BulkUpdateEmployeeStatusCommand $command); -} diff --git a/src/Core/Domain/Employee/CommandHandler/DeleteEmployeeHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/DeleteEmployeeHandlerInterface.php deleted file mode 100644 index edef70e0..00000000 --- a/src/Core/Domain/Employee/CommandHandler/DeleteEmployeeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\DeleteEmployeeCommand; - -/** - * Interface DeleteEmployeeHandlerInterface. - */ -interface DeleteEmployeeHandlerInterface -{ - /** - * @param DeleteEmployeeCommand $command - */ - public function handle(DeleteEmployeeCommand $command); -} diff --git a/src/Core/Domain/Employee/CommandHandler/EditEmployeeHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/EditEmployeeHandlerInterface.php deleted file mode 100644 index 51f8ec55..00000000 --- a/src/Core/Domain/Employee/CommandHandler/EditEmployeeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\EditEmployeeCommand; - -/** - * Interface for services that handle command which edits employee. - */ -interface EditEmployeeHandlerInterface -{ - /** - * @param EditEmployeeCommand $command - */ - public function handle(EditEmployeeCommand $command); -} diff --git a/src/Core/Domain/Employee/CommandHandler/ToggleEmployeeStatusHandlerInterface.php b/src/Core/Domain/Employee/CommandHandler/ToggleEmployeeStatusHandlerInterface.php deleted file mode 100644 index 2c897c1e..00000000 --- a/src/Core/Domain/Employee/CommandHandler/ToggleEmployeeStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\ToggleEmployeeStatusCommand; - -/** - * Interface ToggleEmployeeStatusHandlerInterface. - */ -interface ToggleEmployeeStatusHandlerInterface -{ - /** - * @param ToggleEmployeeStatusCommand $command - */ - public function handle(ToggleEmployeeStatusCommand $command); -} diff --git a/src/Core/Domain/Employee/Exception/AdminEmployeeException.php b/src/Core/Domain/Employee/Exception/AdminEmployeeException.php deleted file mode 100644 index 723cc94e..00000000 --- a/src/Core/Domain/Employee/Exception/AdminEmployeeException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Class AdminEmployeeException is thrown when last admin of the shop is being disabled or deleted. - */ -class AdminEmployeeException extends EmployeeException -{ - /** - * Code is used when the only admin of the shop is being disabled or deleted. - */ - const CANNOT_CHANGE_LAST_ADMIN = 1; -} diff --git a/src/Core/Domain/Employee/Exception/CannotDeleteEmployeeException.php b/src/Core/Domain/Employee/Exception/CannotDeleteEmployeeException.php deleted file mode 100644 index 30ae4885..00000000 --- a/src/Core/Domain/Employee/Exception/CannotDeleteEmployeeException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Is thrown when employee cannot be deleted - */ -class CannotDeleteEmployeeException extends EmployeeException -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param EmployeeId $employeeId - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct(EmployeeId $employeeId, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->employeeId = $employeeId; - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/Exception/CannotDeleteWarehouseManagerException.php b/src/Core/Domain/Employee/Exception/CannotDeleteWarehouseManagerException.php deleted file mode 100644 index 1460aaf4..00000000 --- a/src/Core/Domain/Employee/Exception/CannotDeleteWarehouseManagerException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Is thrown when warehouse manager cannot be deleted - */ -class CannotDeleteWarehouseManagerException extends EmployeeException -{ -} diff --git a/src/Core/Domain/Employee/Exception/EmailAlreadyUsedException.php b/src/Core/Domain/Employee/Exception/EmailAlreadyUsedException.php deleted file mode 100644 index 4e8b57e7..00000000 --- a/src/Core/Domain/Employee/Exception/EmailAlreadyUsedException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -use Exception; - -/** - * Thrown when employee's email is already used by another employee. - */ -class EmailAlreadyUsedException extends EmployeeException -{ - /** - * @var string - */ - private $email; - - /** - * @param string $email the email that's being used - * @param string $message - * @param int $code - * @param Exception|null $previous - */ - public function __construct($email, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->email = $email; - } - - /** - * @return string - */ - public function getEmail() - { - return $this->email; - } -} diff --git a/src/Core/Domain/Employee/Exception/EmployeeCannotChangeItselfException.php b/src/Core/Domain/Employee/Exception/EmployeeCannotChangeItselfException.php deleted file mode 100644 index 4ebeb6cd..00000000 --- a/src/Core/Domain/Employee/Exception/EmployeeCannotChangeItselfException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Class EmployeeCannotChangeItselfException is thrown when employee is trying to change status or delete itself. - */ -class EmployeeCannotChangeItselfException extends EmployeeException -{ - /** - * Code is used when employee which is logged in tries to change its status. - */ - const CANNOT_CHANGE_STATUS = 1; -} diff --git a/src/Core/Domain/Employee/Exception/EmployeeConstraintException.php b/src/Core/Domain/Employee/Exception/EmployeeConstraintException.php deleted file mode 100644 index 1d922872..00000000 --- a/src/Core/Domain/Employee/Exception/EmployeeConstraintException.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Is thrown when employee constraint is violated - */ -class EmployeeConstraintException extends EmployeeException -{ - /** - * @var int Code is used when invalid email is provided for employee - */ - const INVALID_EMAIL = 1; - - /** - * @var int Code is used when invalid first name is provided for employee - */ - const INVALID_FIRST_NAME = 2; - - /** - * @var int Code is used when invalid last name is provided for employee - */ - const INVALID_LAST_NAME = 3; - - /** - * @var int code is used when password of invalid length is provided for employee - */ - const INVALID_PASSWORD = 4; - - /** - * @var int Code is used when incorrect password is provided for employee - */ - const INCORRECT_PASSWORD = 5; -} diff --git a/src/Core/Domain/Employee/Exception/EmployeeException.php b/src/Core/Domain/Employee/Exception/EmployeeException.php deleted file mode 100644 index 536aba35..00000000 --- a/src/Core/Domain/Employee/Exception/EmployeeException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for employee sub-domain - */ -class EmployeeException extends DomainException -{ -} diff --git a/src/Core/Domain/Employee/Exception/EmployeeNotFoundException.php b/src/Core/Domain/Employee/Exception/EmployeeNotFoundException.php deleted file mode 100644 index 7ecc0e01..00000000 --- a/src/Core/Domain/Employee/Exception/EmployeeNotFoundException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Class EmployeeNotFoundException is thrown when employee cannot be found. - */ -class EmployeeNotFoundException extends EmployeeException -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param EmployeeId $employeeId - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct(EmployeeId $employeeId, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->employeeId = $employeeId; - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/Exception/InvalidEmployeeIdException.php b/src/Core/Domain/Employee/Exception/InvalidEmployeeIdException.php deleted file mode 100644 index 0bce19a8..00000000 --- a/src/Core/Domain/Employee/Exception/InvalidEmployeeIdException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Class InvalidEmployeeIdException is thrown when EmployeeId with invalid value is being created. - */ -class InvalidEmployeeIdException extends EmployeeException -{ -} diff --git a/src/Core/Domain/Employee/Exception/InvalidPasswordException.php b/src/Core/Domain/Employee/Exception/InvalidPasswordException.php deleted file mode 100644 index c11d10b1..00000000 --- a/src/Core/Domain/Employee/Exception/InvalidPasswordException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Class InvalidPasswordException thrown when employee password is invalid. - */ -class InvalidPasswordException extends EmployeeException -{ -} diff --git a/src/Core/Domain/Employee/Exception/InvalidProfileException.php b/src/Core/Domain/Employee/Exception/InvalidProfileException.php deleted file mode 100644 index 162367a4..00000000 --- a/src/Core/Domain/Employee/Exception/InvalidProfileException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Thrown when invalid profile is selected for an employee. - */ -class InvalidProfileException extends EmployeeException -{ -} diff --git a/src/Core/Domain/Employee/Exception/MissingShopAssociationException.php b/src/Core/Domain/Employee/Exception/MissingShopAssociationException.php deleted file mode 100644 index 8d362ca8..00000000 --- a/src/Core/Domain/Employee/Exception/MissingShopAssociationException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Exception; - -/** - * Thrown when shop association is missing for an employee. - */ -class MissingShopAssociationException extends EmployeeException -{ -} diff --git a/src/Core/Domain/Employee/Query/GetEmployeeEmailById.php b/src/Core/Domain/Employee/Query/GetEmployeeEmailById.php deleted file mode 100644 index 20a08b81..00000000 --- a/src/Core/Domain/Employee/Query/GetEmployeeEmailById.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Query; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -class GetEmployeeEmailById -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param int $employeeId - */ - public function __construct(int $employeeId) - { - $this->employeeId = new EmployeeId($employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId(): EmployeeId - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/Query/GetEmployeeForEditing.php b/src/Core/Domain/Employee/Query/GetEmployeeForEditing.php deleted file mode 100644 index 242e5156..00000000 --- a/src/Core/Domain/Employee/Query/GetEmployeeForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\Query; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * Gets employee information for editing. - */ -class GetEmployeeForEditing -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param int $employeeId - */ - public function __construct($employeeId) - { - $this->employeeId = new EmployeeId($employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Employee/QueryHandler/GetEmployeeEmailByIdHandlerInterface.php b/src/Core/Domain/Employee/QueryHandler/GetEmployeeEmailByIdHandlerInterface.php deleted file mode 100644 index 86c670a9..00000000 --- a/src/Core/Domain/Employee/QueryHandler/GetEmployeeEmailByIdHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeEmailById; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -interface GetEmployeeEmailByIdHandlerInterface -{ - /** - * @param GetEmployeeEmailById $query - * - * @return Email - */ - public function handle(GetEmployeeEmailById $query): Email; -} diff --git a/src/Core/Domain/Employee/QueryHandler/GetEmployeeForEditingHandlerInterface.php b/src/Core/Domain/Employee/QueryHandler/GetEmployeeForEditingHandlerInterface.php deleted file mode 100644 index 15e96630..00000000 --- a/src/Core/Domain/Employee/QueryHandler/GetEmployeeForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeForEditing; -use PrestaShop\PrestaShop\Core\Domain\Employee\QueryResult\EditableEmployee; - -/** - * Interface for service that gets employee data for editing - */ -interface GetEmployeeForEditingHandlerInterface -{ - /** - * @param GetEmployeeForEditing $query - * - * @return EditableEmployee - */ - public function handle(GetEmployeeForEditing $query); -} diff --git a/src/Core/Domain/Employee/QueryResult/EditableEmployee.php b/src/Core/Domain/Employee/QueryResult/EditableEmployee.php deleted file mode 100644 index 23384afe..00000000 --- a/src/Core/Domain/Employee/QueryResult/EditableEmployee.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; - -/** - * Stores editable data of an employee. - */ -class EditableEmployee -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @var FirstName - */ - private $firstName; - - /** - * @var LastName - */ - private $lastName; - - /** - * @var Email - */ - private $email; - - /** - * @var int - */ - private $defaultPageId; - - /** - * @var int - */ - private $languageId; - - /** - * @var bool - */ - private $active; - - /** - * @var int - */ - private $profileId; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @var string - */ - private $avatarUrl; - - /** - * @param EmployeeId $employeeId - * @param FirstName $firstName - * @param LastName $lastName - * @param Email $email - * @param string $avatarUrl - * @param int $defaultPageId - * @param int $languageId - * @param bool $active - * @param int $profileId - * @param array $shopAssociation - */ - public function __construct( - EmployeeId $employeeId, - FirstName $firstName, - LastName $lastName, - Email $email, - $avatarUrl, - $defaultPageId, - $languageId, - $active, - $profileId, - array $shopAssociation - ) { - $this->employeeId = $employeeId; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->email = $email; - $this->defaultPageId = $defaultPageId; - $this->languageId = $languageId; - $this->active = $active; - $this->profileId = $profileId; - $this->shopAssociation = $shopAssociation; - $this->avatarUrl = $avatarUrl; - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @return FirstName - */ - public function getFirstName() - { - return $this->firstName; - } - - /** - * @return LastName - */ - public function getLastName() - { - return $this->lastName; - } - - /** - * @return Email - */ - public function getEmail() - { - return $this->email; - } - - /** - * @return int - */ - public function getDefaultPageId() - { - return $this->defaultPageId; - } - - /** - * @return int - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->active; - } - - /** - * @return int - */ - public function getProfileId() - { - return $this->profileId; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @return string - */ - public function getAvatarUrl() - { - return $this->avatarUrl; - } -} diff --git a/src/Core/Domain/Employee/ValueObject/EmployeeId.php b/src/Core/Domain/Employee/ValueObject/EmployeeId.php deleted file mode 100644 index 33d68357..00000000 --- a/src/Core/Domain/Employee/ValueObject/EmployeeId.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidEmployeeIdException; - -/** - * Defines Employee ID with it's constraints. - */ -class EmployeeId -{ - /** - * @var int - */ - private $employeeId; - - /** - * @param int $employeeId - * - * @throws InvalidEmployeeIdException - */ - public function __construct($employeeId) - { - $this->assertIntegerIsGreaterThanZero($employeeId); - - $this->employeeId = $employeeId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->employeeId; - } - - /** - * @param int $employeeId - * - * @throws InvalidEmployeeIdException - */ - private function assertIntegerIsGreaterThanZero($employeeId) - { - if (!is_int($employeeId) || 0 > $employeeId) { - throw new InvalidEmployeeIdException(sprintf('Invalid employee id %s supplied. Employee id must be positive integer.', var_export($employeeId, true))); - } - } -} diff --git a/src/Core/Domain/Employee/ValueObject/FirstName.php b/src/Core/Domain/Employee/ValueObject/FirstName.php deleted file mode 100644 index abaf4589..00000000 --- a/src/Core/Domain/Employee/ValueObject/FirstName.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeConstraintException; - -/** - * Carries employee's first name - */ -class FirstName -{ - /** - * @var string Maximum allowed length for first name - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $firstName; - - /** - * @param string $firstName - */ - public function __construct($firstName) - { - $this->assertFirstNameDoesNotExceedAllowedLength($firstName); - $this->assertFirstNameIsValid($firstName); - - $this->firstName = $firstName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->firstName; - } - - /** - * @param string $firstName - * - * @throws EmployeeConstraintException - */ - private function assertFirstNameIsValid($firstName) - { - $matchesFirstNamePattern = preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:¤|]*$/u', stripslashes($firstName)); - - if (!$matchesFirstNamePattern) { - throw new EmployeeConstraintException(sprintf('Employee first name %s is invalid', var_export($firstName, true)), EmployeeConstraintException::INVALID_FIRST_NAME); - } - } - - /** - * @param string $firstName - * - * @throws EmployeeConstraintException - */ - private function assertFirstNameDoesNotExceedAllowedLength($firstName) - { - $firstName = html_entity_decode($firstName, ENT_COMPAT, 'UTF-8'); - - $length = function_exists('mb_strlen') ? mb_strlen($firstName, 'UTF-8') : strlen($firstName); - if (self::MAX_LENGTH < $length) { - throw new EmployeeConstraintException(sprintf('Employee first name is too long. Max allowed length is %s', self::MAX_LENGTH), EmployeeConstraintException::INVALID_FIRST_NAME); - } - } -} diff --git a/src/Core/Domain/Employee/ValueObject/LastName.php b/src/Core/Domain/Employee/ValueObject/LastName.php deleted file mode 100644 index ab4f43ca..00000000 --- a/src/Core/Domain/Employee/ValueObject/LastName.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeConstraintException; - -/** - * Stores employee's last name - */ -class LastName -{ - /** - * @var string Maximum allowed length for last name - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $lastName; - - /** - * @param string $lastName - */ - public function __construct($lastName) - { - $this->assertLastNameDoesNotExceedAllowedLength($lastName); - $this->assertLastNameIsValid($lastName); - - $this->lastName = $lastName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->lastName; - } - - /** - * @param string $lastName - * - * @throws EmployeeConstraintException - */ - private function assertLastNameIsValid($lastName) - { - $matchesLastNamePattern = preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:¤|]*$/u', stripslashes($lastName)); - - if (!$matchesLastNamePattern) { - throw new EmployeeConstraintException(sprintf('Employee last name %s is invalid', var_export($lastName, true)), EmployeeConstraintException::INVALID_LAST_NAME); - } - } - - /** - * @param string $lastName - * - * @throws EmployeeConstraintException - */ - private function assertLastNameDoesNotExceedAllowedLength($lastName) - { - $lastName = html_entity_decode($lastName, ENT_COMPAT, 'UTF-8'); - - $length = function_exists('mb_strlen') ? mb_strlen($lastName, 'UTF-8') : strlen($lastName); - if (self::MAX_LENGTH < $length) { - throw new EmployeeConstraintException(sprintf('Employee last name is too long. Max allowed length is %s', self::MAX_LENGTH), EmployeeConstraintException::INVALID_LAST_NAME); - } - } -} diff --git a/src/Core/Domain/Employee/ValueObject/Password.php b/src/Core/Domain/Employee/ValueObject/Password.php deleted file mode 100644 index 0fea673a..00000000 --- a/src/Core/Domain/Employee/ValueObject/Password.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeConstraintException; - -/** - * Stores employee's plain password. - */ -class Password -{ - /** - * @var string minimum required password length - */ - const MIN_LENGTH = 8; - - /** - * @var string maximum allowed password length - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $password; - - /** - * @param string $password - */ - public function __construct($password) - { - $this->assertPasswordIsWithinAllowedLength($password); - - $this->password = $password; - } - - /** - * @return string - */ - public function getValue() - { - return $this->password; - } - - /** - * @param string $password - */ - private function assertPasswordIsWithinAllowedLength($password) - { - $length = function_exists('mb_strlen') ? mb_strlen($password, 'UTF-8') : strlen($password); - - if (self::MIN_LENGTH > $length || $length > self::MAX_LENGTH) { - throw new EmployeeConstraintException(sprintf('Employee password length must be between %s and %s', self::MIN_LENGTH, self::MAX_LENGTH), EmployeeConstraintException::INVALID_PASSWORD); - } - } -} diff --git a/src/Core/Domain/Exception/DomainConstraintException.php b/src/Core/Domain/Exception/DomainConstraintException.php deleted file mode 100644 index 88d9b6ed..00000000 --- a/src/Core/Domain/Exception/DomainConstraintException.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Exception; - -/** - * Class DomainConstraintException is responsible for holding exception codes which can be raised in reusable way. - */ -class DomainConstraintException extends DomainException -{ - /** - * @var int - raised when native php email validation fails. E.g filter_var($email, FILTER_VALIDATE_EMAIL) - */ - const INVALID_EMAIL = 1; - - /** - * Used when invalid money amount is provided - */ - const INVALID_MONEY_AMOUNT = 2; - - /** - * When price reduction type is not within defined types - */ - const INVALID_REDUCTION_TYPE = 3; - - /** - * When price reduction percentage value is not valid - */ - const INVALID_REDUCTION_PERCENTAGE = 4; - - /** - * When price reduction amount value is not valid - */ - const INVALID_REDUCTION_AMOUNT = 5; -} diff --git a/src/Core/Domain/Exception/DomainException.php b/src/Core/Domain/Exception/DomainException.php deleted file mode 100644 index 90ed40a4..00000000 --- a/src/Core/Domain/Exception/DomainException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Base class for all domain exceptions - */ -class DomainException extends CoreException -{ -} diff --git a/src/Core/Domain/Exception/FileUploadException.php b/src/Core/Domain/Exception/FileUploadException.php deleted file mode 100644 index bf92238f..00000000 --- a/src/Core/Domain/Exception/FileUploadException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Exception; - -/** - * This exception on success case has code 0 which is equal to constant UPLOAD_ERR_OK. - * On every other case it has one of the following error code constants: - * - * UPLOAD_ERR_INI_SIZE, - * UPLOAD_ERR_FORM_SIZE, - * UPLOAD_ERR_PARTIAL, - * UPLOAD_ERR_NO_FILE, - * UPLOAD_ERR_NO_TMP_DIR, - * UPLOAD_ERR_CANT_WRITE, - * UPLOAD_ERR_EXTENSION - */ -class FileUploadException extends DomainException -{ -} diff --git a/src/Core/Domain/Exception/InvalidSortingException.php b/src/Core/Domain/Exception/InvalidSortingException.php deleted file mode 100644 index 1cce839c..00000000 --- a/src/Core/Domain/Exception/InvalidSortingException.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Sorting parameter not supported - */ -class InvalidSortingException extends CoreException -{ -} diff --git a/src/Core/Domain/Feature/Command/AddFeatureCommand.php b/src/Core/Domain/Feature/Command/AddFeatureCommand.php deleted file mode 100644 index 19098071..00000000 --- a/src/Core/Domain/Feature/Command/AddFeatureCommand.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Command; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureConstraintException; - -/** - * Adds new feature - */ -class AddFeatureCommand -{ - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var int[] - */ - private $shopAssociation; - - /** - * @param string[] $localizedNames - * @param int[] $shopAssociation - */ - public function __construct(array $localizedNames, array $shopAssociation = []) - { - $this->assertNamesAreValid($localizedNames); - - $this->localizedNames = $localizedNames; - $this->shopAssociation = $shopAssociation; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * Asserts that feature names are valid. - * - * @param string[] $names - * - * @throws FeatureConstraintException - */ - private function assertNamesAreValid(array $names) - { - if (empty($names)) { - throw new FeatureConstraintException('Feature name cannot be empty', FeatureConstraintException::EMPTY_NAME); - } - } -} diff --git a/src/Core/Domain/Feature/Command/EditFeatureCommand.php b/src/Core/Domain/Feature/Command/EditFeatureCommand.php deleted file mode 100644 index 04b54fbe..00000000 --- a/src/Core/Domain/Feature/Command/EditFeatureCommand.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Command; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Edit feature with given data. - */ -class EditFeatureCommand -{ - /** - * @var FeatureId - */ - private $featureId; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var int[] - */ - private $associatedShopIds; - - /** - * @param int $featureId - */ - public function __construct($featureId) - { - $this->featureId = new FeatureId($featureId); - } - - /** - * @return FeatureId - */ - public function getFeatureId() - { - return $this->featureId; - } - - /** - * @return string[]|null - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string[] $localizedNames - * - * @return EditFeatureCommand - */ - public function setLocalizedNames(array $localizedNames) - { - if (empty($localizedNames)) { - throw new FeatureConstraintException('Feature name cannot be empty', FeatureConstraintException::EMPTY_NAME); - } - - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return int[]|null - */ - public function getAssociatedShopIds() - { - return $this->associatedShopIds; - } - - /** - * @param int[] $associatedShopIds - * - * @return EditFeatureCommand - */ - public function setAssociatedShopIds($associatedShopIds) - { - $this->associatedShopIds = $associatedShopIds; - - return $this; - } -} diff --git a/src/Core/Domain/Feature/CommandHandler/AddFeatureHandlerInterface.php b/src/Core/Domain/Feature/CommandHandler/AddFeatureHandlerInterface.php deleted file mode 100644 index 755ea2ce..00000000 --- a/src/Core/Domain/Feature/CommandHandler/AddFeatureHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\AddFeatureCommand; -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Describes add feature command handler - */ -interface AddFeatureHandlerInterface -{ - /** - * @param AddFeatureCommand $command - * - * @return FeatureId id of the created feature - */ - public function handle(AddFeatureCommand $command); -} diff --git a/src/Core/Domain/Feature/CommandHandler/EditFeatureHandlerInterface.php b/src/Core/Domain/Feature/CommandHandler/EditFeatureHandlerInterface.php deleted file mode 100644 index 9d410048..00000000 --- a/src/Core/Domain/Feature/CommandHandler/EditFeatureHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\EditFeatureCommand; - -/** - * Describes a service that handles feature edit command. - */ -interface EditFeatureHandlerInterface -{ - /** - * @param EditFeatureCommand $command - */ - public function handle(EditFeatureCommand $command); -} diff --git a/src/Core/Domain/Feature/Exception/CannotAddFeatureException.php b/src/Core/Domain/Feature/Exception/CannotAddFeatureException.php deleted file mode 100644 index 4fc320f2..00000000 --- a/src/Core/Domain/Feature/Exception/CannotAddFeatureException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -/** - * Thrown when feature cannot be added. - */ -class CannotAddFeatureException extends FeatureException -{ -} diff --git a/src/Core/Domain/Feature/Exception/CannotEditFeatureException.php b/src/Core/Domain/Feature/Exception/CannotEditFeatureException.php deleted file mode 100644 index 62ddcf88..00000000 --- a/src/Core/Domain/Feature/Exception/CannotEditFeatureException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -/** - * Thrown when feature cannot be edited. - */ -class CannotEditFeatureException extends FeatureException -{ -} diff --git a/src/Core/Domain/Feature/Exception/FeatureConstraintException.php b/src/Core/Domain/Feature/Exception/FeatureConstraintException.php deleted file mode 100644 index 98b61243..00000000 --- a/src/Core/Domain/Feature/Exception/FeatureConstraintException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -/** - * Thrown when Feature data is not valid. - */ -class FeatureConstraintException extends FeatureException -{ - /** - * Code is used when feature does not have name. - */ - const EMPTY_NAME = 1; - - /** - * Used when feature name is invalid. - */ - const INVALID_NAME = 2; -} diff --git a/src/Core/Domain/Feature/Exception/FeatureException.php b/src/Core/Domain/Feature/Exception/FeatureException.php deleted file mode 100644 index 0443b225..00000000 --- a/src/Core/Domain/Feature/Exception/FeatureException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Thrown in Feature context. - */ -class FeatureException extends DomainException -{ -} diff --git a/src/Core/Domain/Feature/Exception/FeatureNotFoundException.php b/src/Core/Domain/Feature/Exception/FeatureNotFoundException.php deleted file mode 100644 index 23930326..00000000 --- a/src/Core/Domain/Feature/Exception/FeatureNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -/** - * Thrown when feature could not be found - */ -class FeatureNotFoundException extends FeatureException -{ -} diff --git a/src/Core/Domain/Feature/Exception/InvalidFeatureIdException.php b/src/Core/Domain/Feature/Exception/InvalidFeatureIdException.php deleted file mode 100644 index 17528add..00000000 --- a/src/Core/Domain/Feature/Exception/InvalidFeatureIdException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Exception; - -/** - * Thrown when invalid feature id is used - */ -class InvalidFeatureIdException extends FeatureException -{ -} diff --git a/src/Core/Domain/Feature/Query/GetFeatureForEditing.php b/src/Core/Domain/Feature/Query/GetFeatureForEditing.php deleted file mode 100644 index f58611c4..00000000 --- a/src/Core/Domain/Feature/Query/GetFeatureForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\Query; - -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Retrieves feature data for editing - */ -class GetFeatureForEditing -{ - /** - * @var FeatureId - */ - private $featureId; - - /** - * @param int $featureId - */ - public function __construct($featureId) - { - $this->featureId = new FeatureId($featureId); - } - - /** - * @return FeatureId - */ - public function getFeatureId() - { - return $this->featureId; - } -} diff --git a/src/Core/Domain/Feature/QueryHandler/GetFeatureForEditingHandlerInterface.php b/src/Core/Domain/Feature/QueryHandler/GetFeatureForEditingHandlerInterface.php deleted file mode 100644 index 599b3f1a..00000000 --- a/src/Core/Domain/Feature/QueryHandler/GetFeatureForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Query\GetFeatureForEditing; -use PrestaShop\PrestaShop\Core\Domain\Feature\QueryResult\EditableFeature; - -/** - * Describes feature for editing handler. - */ -interface GetFeatureForEditingHandlerInterface -{ - /** - * @param GetFeatureForEditing $query - * - * @return EditableFeature - */ - public function handle(GetFeatureForEditing $query); -} diff --git a/src/Core/Domain/Feature/QueryResult/EditableFeature.php b/src/Core/Domain/Feature/QueryResult/EditableFeature.php deleted file mode 100644 index 5f2d00fb..00000000 --- a/src/Core/Domain/Feature/QueryResult/EditableFeature.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Stores feature data that's needed for editing. - */ -class EditableFeature -{ - /** - * @var FeatureId - */ - private $featureId; - - /** - * @var string[] - */ - private $name; - - /** - * @var int[] - */ - private $shopAssociationIds; - - /** - * @param FeatureId $featureId - * @param string[] $name - * @param int[] $shopAssociationIds - */ - public function __construct(FeatureId $featureId, array $name, array $shopAssociationIds) - { - $this->featureId = $featureId; - $this->name = $name; - $this->shopAssociationIds = $shopAssociationIds; - } - - /** - * @return FeatureId - */ - public function getFeatureId() - { - return $this->featureId; - } - - /** - * @return string[] - */ - public function getName() - { - return $this->name; - } - - /** - * @return int[] - */ - public function getShopAssociationIds() - { - return $this->shopAssociationIds; - } -} diff --git a/src/Core/Domain/Feature/ValueObject/FeatureId.php b/src/Core/Domain/Feature/ValueObject/FeatureId.php deleted file mode 100644 index 4105b8a0..00000000 --- a/src/Core/Domain/Feature/ValueObject/FeatureId.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\InvalidFeatureIdException; - -/** - * Defines Feature ID with it's constraints. - */ -class FeatureId -{ - /** - * @var int - */ - private $featureId; - - /** - * @param int $featureId - */ - public function __construct($featureId) - { - $this->assertIntegerIsGreaterThanZero($featureId); - - $this->featureId = $featureId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->featureId; - } - - /** - * @param int $featureId - * - * @throws InvalidFeatureIdException - */ - private function assertIntegerIsGreaterThanZero($featureId) - { - if (!is_numeric($featureId) || 0 > $featureId) { - throw new InvalidFeatureIdException(sprintf('Invalid feature id %s supplied. Feature id must be positive integer.', var_export($featureId, true))); - } - } -} diff --git a/src/Core/Domain/Language/Command/AddLanguageCommand.php b/src/Core/Domain/Language/Command/AddLanguageCommand.php deleted file mode 100644 index 7bcf2632..00000000 --- a/src/Core/Domain/Language/Command/AddLanguageCommand.php +++ /dev/null @@ -1,204 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; - -/** - * Adds new language with given data - */ -class AddLanguageCommand -{ - /** - * @var string Language's name - */ - private $name; - - /** - * @var IsoCode Two-letter (639-1) language ISO code, e.g. FR, EN - */ - private $isoCode; - - /** - * @var TagIETF IETF language tag, e.g. en-US - */ - private $tagIETF; - - /** - * @var string - */ - private $flagImagePath; - - /** - * @var string Image that is used as fallback image for product, category and brand - * when the actual image is not available. - * Each language has different "No picture" image. - */ - private $noPictureImagePath; - - /** - * @var string Short date format. e.g. Y-m-d - */ - private $shortDateFormat; - - /** - * @var string Full date format, e.g. Y-m-d H:i:s - */ - private $fullDateFormat; - - /** - * @var bool Is language read from right to left - */ - private $isRtl; - - /** - * @var bool - */ - private $isActive; - - /** - * @var int[] ID of shops which are associated with language - */ - private $shopAssociation; - - /** - * @param string $name - * @param string $isoCode - * @param string $tagIETF - * @param string $shortDateFormat - * @param string $fullDateFormat - * @param string $flagImagePath - * @param string $noPictureImagePath - * @param bool $isRtl - * @param bool $isActive - * @param int[] $shopAssociation - */ - public function __construct( - $name, - $isoCode, - $tagIETF, - $shortDateFormat, - $fullDateFormat, - $flagImagePath, - $noPictureImagePath, - $isRtl, - $isActive, - array $shopAssociation - ) { - $this->name = $name; - $this->isoCode = new IsoCode($isoCode); - $this->tagIETF = new TagIETF($tagIETF); - $this->shortDateFormat = $shortDateFormat; - $this->fullDateFormat = $fullDateFormat; - $this->flagImagePath = $flagImagePath; - $this->noPictureImagePath = $noPictureImagePath; - $this->isRtl = $isRtl; - $this->isActive = $isActive; - $this->shopAssociation = $shopAssociation; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return IsoCode - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @return TagIETF - */ - public function getTagIETF() - { - return $this->tagIETF; - } - - /** - * @return string - */ - public function getShortDateFormat() - { - return $this->shortDateFormat; - } - - /** - * @return string - */ - public function getFullDateFormat() - { - return $this->fullDateFormat; - } - - /** - * @return string - */ - public function getFlagImagePath() - { - return $this->flagImagePath; - } - - /** - * @return string - */ - public function getNoPictureImagePath() - { - return $this->noPictureImagePath; - } - - /** - * @return bool - */ - public function isRtl() - { - return $this->isRtl; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @return int[] - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } -} diff --git a/src/Core/Domain/Language/Command/BulkDeleteLanguagesCommand.php b/src/Core/Domain/Language/Command/BulkDeleteLanguagesCommand.php deleted file mode 100644 index 24629e9c..00000000 --- a/src/Core/Domain/Language/Command/BulkDeleteLanguagesCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Deletes given languages - */ -class BulkDeleteLanguagesCommand -{ - /** - * @var LanguageId[] - */ - private $languageIds = []; - - /** - * @param int[] $languageIds - */ - public function __construct(array $languageIds) - { - $this->setLanguageIds($languageIds); - } - - /** - * @return LanguageId[] - */ - public function getLanguageIds() - { - return $this->languageIds; - } - - /** - * @param int[] $languageIds - */ - private function setLanguageIds(array $languageIds) - { - if (empty($languageIds)) { - throw new LanguageConstraintException('At least one language must be provided for deleting', LanguageConstraintException::EMPTY_BULK_DELETE); - } - - foreach ($languageIds as $languageId) { - $this->languageIds[] = new LanguageId($languageId); - } - } -} diff --git a/src/Core/Domain/Language/Command/BulkToggleLanguagesStatusCommand.php b/src/Core/Domain/Language/Command/BulkToggleLanguagesStatusCommand.php deleted file mode 100644 index 82368c35..00000000 --- a/src/Core/Domain/Language/Command/BulkToggleLanguagesStatusCommand.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Enables/disables languages status - */ -class BulkToggleLanguagesStatusCommand -{ - /** - * @var LanguageId[] - */ - private $languageIds = []; - - /** - * @var bool - */ - private $expectedStatus; - - /** - * @param int[] $languageIds - * @param bool $expectedStatus - */ - public function __construct(array $languageIds, $expectedStatus) - { - $this->assertStatusIsBool($expectedStatus); - - $this->setLanguages($languageIds); - $this->expectedStatus = $expectedStatus; - } - - /** - * @return LanguageId[] - */ - public function getLanguageIds() - { - return $this->languageIds; - } - - /** - * @return bool - */ - public function getStatus() - { - return $this->expectedStatus; - } - - /** - * @param int[] $languageIds - */ - private function setLanguages(array $languageIds) - { - if (empty($languageIds)) { - throw new CategoryConstraintException('Languages must be provided in order to toggle their status'); - } - - foreach ($languageIds as $languageId) { - $this->languageIds[] = new LanguageId($languageId); - } - } - - /** - * @param bool $status - * - * @throws LanguageConstraintException - */ - private function assertStatusIsBool($status) - { - if (!is_bool($status)) { - throw new LanguageConstraintException('Invalid status provided, language status must be type of "bool"'); - } - } -} diff --git a/src/Core/Domain/Language/Command/DeleteLanguageCommand.php b/src/Core/Domain/Language/Command/DeleteLanguageCommand.php deleted file mode 100644 index baea27fb..00000000 --- a/src/Core/Domain/Language/Command/DeleteLanguageCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Deletes given languages - */ -class DeleteLanguageCommand -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @param int $languageId - */ - public function __construct($languageId) - { - $this->languageId = new LanguageId($languageId); - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/Language/Command/EditLanguageCommand.php b/src/Core/Domain/Language/Command/EditLanguageCommand.php deleted file mode 100644 index 719e98be..00000000 --- a/src/Core/Domain/Language/Command/EditLanguageCommand.php +++ /dev/null @@ -1,320 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; - -/** - * Edits given language with provided data - */ -class EditLanguageCommand -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @var string|null - */ - private $name; - - /** - * @var IsoCode|null - */ - private $isoCode; - - /** - * @var TagIETF|null - */ - private $tagIETF; - - /** - * @var string|null - */ - private $shortDateFormat; - - /** - * @var string|null - */ - private $fullDateFormat; - - /** - * @var string|null - */ - private $flagImagePath; - - /** - * @var string|null - */ - private $noPictureImagePath; - - /** - * @var bool|null - */ - private $isRtl; - - /** - * @var bool|null - */ - private $isActive; - - /** - * @var int[]|null - */ - private $shopAssociation; - - /** - * @param int $languageId - */ - public function __construct($languageId) - { - $this->languageId = new LanguageId($languageId); - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @param LanguageId $languageId - * - * @return self - */ - public function setLanguageId($languageId) - { - $this->languageId = $languageId; - - return $this; - } - - /** - * @return string|null - */ - public function getName() - { - return $this->name; - } - - /** - * @param string|null $name - * - * @return self - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * @return IsoCode|null - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - * - * @return self - */ - public function setIsoCode($isoCode) - { - $this->isoCode = new IsoCode($isoCode); - - return $this; - } - - /** - * @return TagIETF|null - */ - public function getTagIETF() - { - return $this->tagIETF; - } - - /** - * @param string $tagIETF - * - * @return self - */ - public function setTagIETF($tagIETF) - { - $this->tagIETF = new TagIETF($tagIETF); - - return $this; - } - - /** - * @return string|null - */ - public function getShortDateFormat() - { - return $this->shortDateFormat; - } - - /** - * @param string $shortDateFormat - * - * @return self - */ - public function setShortDateFormat($shortDateFormat) - { - $this->shortDateFormat = $shortDateFormat; - - return $this; - } - - /** - * @return string|null - */ - public function getFullDateFormat() - { - return $this->fullDateFormat; - } - - /** - * @param string $fullDateFormat - * - * @return self - */ - public function setFullDateFormat($fullDateFormat) - { - $this->fullDateFormat = $fullDateFormat; - - return $this; - } - - /** - * @return string|null - */ - public function getFlagImagePath() - { - return $this->flagImagePath; - } - - /** - * @param string $flagImagePath - * - * @return self - */ - public function setFlagImagePath($flagImagePath) - { - $this->flagImagePath = $flagImagePath; - - return $this; - } - - /** - * @return string|null - */ - public function getNoPictureImagePath() - { - return $this->noPictureImagePath; - } - - /** - * @param string $noPictureImagePath - * - * @return self - */ - public function setNoPictureImagePath($noPictureImagePath) - { - $this->noPictureImagePath = $noPictureImagePath; - - return $this; - } - - /** - * @return bool|null - */ - public function isRtl() - { - return $this->isRtl; - } - - /** - * @param bool $isRtl - * - * @return self - */ - public function setIsRtl($isRtl) - { - $this->isRtl = $isRtl; - - return $this; - } - - /** - * @return bool|null - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - * - * @return self - */ - public function setIsActive($isActive) - { - $this->isActive = $isActive; - - return $this; - } - - /** - * @return int[]|null - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - */ - public function setShopAssociation(array $shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/Language/Command/ToggleLanguageStatusCommand.php b/src/Core/Domain/Language/Command/ToggleLanguageStatusCommand.php deleted file mode 100644 index c7e4bf17..00000000 --- a/src/Core/Domain/Language/Command/ToggleLanguageStatusCommand.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Command; - -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Enables or disables language based in given status - */ -class ToggleLanguageStatusCommand -{ - /** - * @var bool - */ - private $expectedStatus; - - /** - * @var int - */ - private $languageId; - - /** - * @param int $languageId - * @param bool $expectedStatus - * - * @throws LanguageConstraintException Is thrown when invalid data is provided - */ - public function __construct($languageId, $expectedStatus) - { - $this->assertStatusIsBool($expectedStatus); - - $this->expectedStatus = $expectedStatus; - $this->languageId = new LanguageId($languageId); - } - - /** - * @return int|LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @return bool - */ - public function getStatus() - { - return $this->expectedStatus; - } - - /** - * @param bool $status - * - * @throws LanguageConstraintException - */ - private function assertStatusIsBool($status) - { - if (!is_bool($status)) { - throw new LanguageConstraintException('Invalid status provided, language status must be type of "bool"'); - } - } -} diff --git a/src/Core/Domain/Language/CommandHandler/AddLanguageHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/AddLanguageHandlerInterface.php deleted file mode 100644 index dd18d15a..00000000 --- a/src/Core/Domain/Language/CommandHandler/AddLanguageHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\AddLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Interface for services that handles command which adds new language - */ -interface AddLanguageHandlerInterface -{ - /** - * @param AddLanguageCommand $command - * - * @return LanguageId Added language's identity - */ - public function handle(AddLanguageCommand $command); -} diff --git a/src/Core/Domain/Language/CommandHandler/BulkDeleteLanguagesHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/BulkDeleteLanguagesHandlerInterface.php deleted file mode 100644 index 9e2626b6..00000000 --- a/src/Core/Domain/Language/CommandHandler/BulkDeleteLanguagesHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkDeleteLanguagesCommand; - -/** - * Interface for service that deletes languages in bulk action - */ -interface BulkDeleteLanguagesHandlerInterface -{ - /** - * @param BulkDeleteLanguagesCommand $command - */ - public function handle(BulkDeleteLanguagesCommand $command); -} diff --git a/src/Core/Domain/Language/CommandHandler/BulkToggleLanguagesStatusHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/BulkToggleLanguagesStatusHandlerInterface.php deleted file mode 100644 index 3a801050..00000000 --- a/src/Core/Domain/Language/CommandHandler/BulkToggleLanguagesStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkToggleLanguagesStatusCommand; - -/** - * Interface for service that toggles status for multiple languages - */ -interface BulkToggleLanguagesStatusHandlerInterface -{ - /** - * @param BulkToggleLanguagesStatusCommand $command - */ - public function handle(BulkToggleLanguagesStatusCommand $command); -} diff --git a/src/Core/Domain/Language/CommandHandler/DeleteLanguageHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/DeleteLanguageHandlerInterface.php deleted file mode 100644 index 8b83ae0a..00000000 --- a/src/Core/Domain/Language/CommandHandler/DeleteLanguageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\DeleteLanguageCommand; - -/** - * Interface for service that deletes language - */ -interface DeleteLanguageHandlerInterface -{ - /** - * @param DeleteLanguageCommand $command - */ - public function handle(DeleteLanguageCommand $command); -} diff --git a/src/Core/Domain/Language/CommandHandler/EditLanguageHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/EditLanguageHandlerInterface.php deleted file mode 100644 index 696374f8..00000000 --- a/src/Core/Domain/Language/CommandHandler/EditLanguageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\EditLanguageCommand; - -/** - * Interface for service that implements edit language command handling - */ -interface EditLanguageHandlerInterface -{ - /** - * @param EditLanguageCommand $command - */ - public function handle(EditLanguageCommand $command); -} diff --git a/src/Core/Domain/Language/CommandHandler/ToggleLanguageStatusHandlerInterface.php b/src/Core/Domain/Language/CommandHandler/ToggleLanguageStatusHandlerInterface.php deleted file mode 100644 index 926d9451..00000000 --- a/src/Core/Domain/Language/CommandHandler/ToggleLanguageStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Command\ToggleLanguageStatusCommand; - -/** - * Interface for service that toggles language's status - */ -interface ToggleLanguageStatusHandlerInterface -{ - /** - * @param ToggleLanguageStatusCommand $command - */ - public function handle(ToggleLanguageStatusCommand $command); -} diff --git a/src/Core/Domain/Language/Exception/CannotDisableDefaultLanguageException.php b/src/Core/Domain/Language/Exception/CannotDisableDefaultLanguageException.php deleted file mode 100644 index eecc3fe3..00000000 --- a/src/Core/Domain/Language/Exception/CannotDisableDefaultLanguageException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -/** - * Exception is thrown when trying to disable default language - */ -class CannotDisableDefaultLanguageException extends LanguageException -{ -} diff --git a/src/Core/Domain/Language/Exception/CopyingNoPictureException.php b/src/Core/Domain/Language/Exception/CopyingNoPictureException.php deleted file mode 100644 index f3f1f593..00000000 --- a/src/Core/Domain/Language/Exception/CopyingNoPictureException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -/** - * Is thrown when error occurs while copying "No picture" for language - */ -class CopyingNoPictureException extends LanguageException -{ - /** - * @var int Code is used when error occurs while copying "No picture" image to products directory - */ - const PRODUCT_IMAGE_COPY_ERROR = 1; - - /** - * @var int Code is used when error occurs while copying "No picture" image to categories directory - */ - const CATEGORY_IMAGE_COPY_ERROR = 2; - - /** - * @var int Code is used when error occurs while copying "No picture" image to brands (manufacturers) directory - */ - const BRAND_IMAGE_COPY_ERROR = 3; -} diff --git a/src/Core/Domain/Language/Exception/DefaultLanguageException.php b/src/Core/Domain/Language/Exception/DefaultLanguageException.php deleted file mode 100644 index 632b7286..00000000 --- a/src/Core/Domain/Language/Exception/DefaultLanguageException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -/** - * Is thrown when error that is related to default language occurs - */ -class DefaultLanguageException extends LanguageException -{ - /** - * @var string Code is used when deleting default language - */ - const CANNOT_DELETE_ERROR = 1; - - /** - * @var string Code is uswed when disabling default language - */ - const CANNOT_DISABLE_ERROR = 2; - - /** - * @var string Code is used when deleting language that is use (e.g. as employee's default language) - */ - const CANNOT_DELETE_IN_USE_ERROR = 3; -} diff --git a/src/Core/Domain/Language/Exception/LanguageConstraintException.php b/src/Core/Domain/Language/Exception/LanguageConstraintException.php deleted file mode 100644 index 786a41ff..00000000 --- a/src/Core/Domain/Language/Exception/LanguageConstraintException.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -/** - * Is thrown when invalid data is supplied for language - */ -class LanguageConstraintException extends LanguageException -{ - /** - * @var int Code is used when invalid language IETF tag is encountered - */ - const INVALID_IETF_TAG = 1; - - /** - * @var int Code is used when invalid language ISO code in encountered - */ - const INVALID_ISO_CODE = 2; - - /** - * @var int Code is used when duplicate language ISO code in encountered when creating new language - */ - const DUPLICATE_ISO_CODE = 3; - - /** - * @var int Code is used when empty data is used when deleting languages - */ - const EMPTY_BULK_DELETE = 4; -} diff --git a/src/Core/Domain/Language/Exception/LanguageException.php b/src/Core/Domain/Language/Exception/LanguageException.php deleted file mode 100644 index fdbfb6b5..00000000 --- a/src/Core/Domain/Language/Exception/LanguageException.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * LanguageException is base exception for language subdomain - */ -class LanguageException extends DomainException -{ - /** - * When language is not active - */ - const NOT_ACTIVE = 1; -} diff --git a/src/Core/Domain/Language/Exception/LanguageImageUploadingException.php b/src/Core/Domain/Language/Exception/LanguageImageUploadingException.php deleted file mode 100644 index 443b06ea..00000000 --- a/src/Core/Domain/Language/Exception/LanguageImageUploadingException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -/** - * Is thrown when error occurs when uploading language image - */ -class LanguageImageUploadingException extends LanguageException -{ - /** - * @var int Code is used when there are less memory than needed to upload image - */ - const MEMORY_LIMIT_RESTRICTION = 1; - - /** - * @var int Code is used when unexpected error occurs while uploading image - */ - const UNEXPECTED_ERROR = 2; -} diff --git a/src/Core/Domain/Language/Exception/LanguageNotFoundException.php b/src/Core/Domain/Language/Exception/LanguageNotFoundException.php deleted file mode 100644 index 3274020b..00000000 --- a/src/Core/Domain/Language/Exception/LanguageNotFoundException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Exception is thrown when language is not found - */ -class LanguageNotFoundException extends LanguageException -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @param LanguageId $languageId - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct(LanguageId $languageId, $message = '', $code = 0, $previous = null) - { - $this->languageId = $languageId; - - parent::__construct($message, $code, $previous); - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/Language/Query/GetLanguageForEditing.php b/src/Core/Domain/Language/Query/GetLanguageForEditing.php deleted file mode 100644 index da0d13d9..00000000 --- a/src/Core/Domain/Language/Query/GetLanguageForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\Query; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; - -/** - * Gets language for editing in Back Office - */ -class GetLanguageForEditing -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @param int $languageId - */ - public function __construct($languageId) - { - $this->languageId = new LanguageId($languageId); - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/Language/QueryHandler/GetLanguageForEditingHandlerInterface.php b/src/Core/Domain/Language/QueryHandler/GetLanguageForEditingHandlerInterface.php deleted file mode 100644 index 38502034..00000000 --- a/src/Core/Domain/Language/QueryHandler/GetLanguageForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; -use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; - -/** - * Interface for service that gets language for editing - */ -interface GetLanguageForEditingHandlerInterface -{ - /** - * @param GetLanguageForEditing $query - * - * @return EditableLanguage - */ - public function handle(GetLanguageForEditing $query); -} diff --git a/src/Core/Domain/Language/QueryResult/EditableLanguage.php b/src/Core/Domain/Language/QueryResult/EditableLanguage.php deleted file mode 100644 index 4f6c6f61..00000000 --- a/src/Core/Domain/Language/QueryResult/EditableLanguage.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\IsoCode; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\TagIETF; - -/** - * Transfers editable language's data - */ -class EditableLanguage -{ - /** - * @var LanguageId - */ - private $languageId; - - /** - * @var string - */ - private $name; - - /** - * @var IsoCode - */ - private $isoCode; - - /** - * @var TagIETF - */ - private $tagIETF; - - /** - * @var string - */ - private $shortDateFormat; - - /** - * @var string - */ - private $fullDateFormat; - - /** - * @var bool - */ - private $isRtl; - - /** - * @var bool - */ - private $isActive; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @param LanguageId $languageId - * @param string $name - * @param IsoCode $isoCode - * @param TagIETF $tagIETF - * @param string $shortDateFormat - * @param string $fullDateFormat - * @param bool $isRtl - * @param bool $isActive - * @param array $shopAssociation - */ - public function __construct( - LanguageId $languageId, - $name, - IsoCode $isoCode, - TagIETF $tagIETF, - $shortDateFormat, - $fullDateFormat, - $isRtl, - $isActive, - array $shopAssociation - ) { - $this->languageId = $languageId; - $this->name = $name; - $this->isoCode = $isoCode; - $this->tagIETF = $tagIETF; - $this->shortDateFormat = $shortDateFormat; - $this->fullDateFormat = $fullDateFormat; - $this->isRtl = $isRtl; - $this->isActive = $isActive; - $this->shopAssociation = $shopAssociation; - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return IsoCode - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @return TagIETF - */ - public function getTagIETF() - { - return $this->tagIETF; - } - - /** - * @return string - */ - public function getShortDateFormat() - { - return $this->shortDateFormat; - } - - /** - * @return string - */ - public function getFullDateFormat() - { - return $this->fullDateFormat; - } - - /** - * @return bool - */ - public function isRtl() - { - return $this->isRtl; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } -} diff --git a/src/Core/Domain/Language/ValueObject/IsoCode.php b/src/Core/Domain/Language/ValueObject/IsoCode.php deleted file mode 100644 index ee1c8937..00000000 --- a/src/Core/Domain/Language/ValueObject/IsoCode.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; - -/** - * Stores language's two-letter (639-1) ISO code - */ -class IsoCode -{ - /** - * @var string ISO Code validation pattern - */ - const PATTERN = '/^[a-zA-Z]{2,3}$/'; - - /** - * @var string - */ - private $isoCode; - - /** - * @param string $isoCode - */ - public function __construct($isoCode) - { - $this->assertIsIsoCode($isoCode); - - $this->isoCode = strtolower($isoCode); - } - - /** - * @return string - */ - public function getValue() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - * - * @throws LanguageException - */ - private function assertIsIsoCode($isoCode) - { - if (!is_string($isoCode) || !preg_match('/^[a-zA-Z]{2,3}$/', $isoCode)) { - throw new LanguageConstraintException(sprintf('Invalid language ISO code %s supplied', var_export($isoCode, true)), LanguageConstraintException::INVALID_ISO_CODE); - } - } -} diff --git a/src/Core/Domain/Language/ValueObject/LanguageId.php b/src/Core/Domain/Language/ValueObject/LanguageId.php deleted file mode 100644 index 651a04fa..00000000 --- a/src/Core/Domain/Language/ValueObject/LanguageId.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; - -/** - * Stores language's identity - */ -class LanguageId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - */ - public function __construct($id) - { - $this->assertIsIntegerGreaterThanZero($id); - - $this->id = $id; - } - - /** - * @return int - */ - public function getValue() - { - return $this->id; - } - - /** - * @param int $id - */ - private function assertIsIntegerGreaterThanZero($id) - { - if (!is_int($id) || 0 >= $id) { - throw new LanguageException(sprintf('Invalid language id %s provided', var_export($id, true))); - } - } -} diff --git a/src/Core/Domain/Language/ValueObject/TagIETF.php b/src/Core/Domain/Language/ValueObject/TagIETF.php deleted file mode 100644 index 64bf06fe..00000000 --- a/src/Core/Domain/Language/ValueObject/TagIETF.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Language\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; - -/** - * Stores IETF tag value (e.g. en-US) - */ -class TagIETF -{ - /** - * @var string - */ - private $tagIETF; - - /** - * @param string $tagIETF - * - * @throws LanguageConstraintException - */ - public function __construct($tagIETF) - { - $this->assertIsTagIETF($tagIETF); - - $this->tagIETF = $tagIETF; - } - - /** - * @return string - */ - public function getValue() - { - return $this->tagIETF; - } - - /** - * @param string $tagIETF - * - * @throws LanguageConstraintException - */ - private function assertIsTagIETF($tagIETF) - { - if (!is_string($tagIETF) || !preg_match('/^[a-zA-Z]{2}(-[a-zA-Z]{2})?$/', $tagIETF)) { - throw new LanguageConstraintException(sprintf('Invalid IETF tag %s provided', var_export($tagIETF, true)), LanguageConstraintException::INVALID_IETF_TAG); - } - } -} diff --git a/src/Core/Domain/MailTemplate/Command/GenerateThemeMailTemplatesCommand.php b/src/Core/Domain/MailTemplate/Command/GenerateThemeMailTemplatesCommand.php deleted file mode 100644 index 366957b1..00000000 --- a/src/Core/Domain/MailTemplate/Command/GenerateThemeMailTemplatesCommand.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command; - -/** - * Class GenerateThemeMailsCommand generates email theme's templates for a specific - * language. If folders are not overridden in the command then MailTemplateGenerator - * will use the default output folders (in mails folder). - */ -class GenerateThemeMailTemplatesCommand -{ - /** @var string */ - private $themeName; - - /** @var string */ - private $language; - - /** @var bool */ - private $overwriteTemplates; - - /** @var string */ - private $coreMailsFolder = ''; - - /** @var string */ - private $modulesMailFolder = ''; - - /** - * @param string $themeName - * @param string $language locale, for example: 'en' - * @param bool $overwriteTemplates - * @param string $coreMailsFolder Output folder for core emails (if left empty the default mails folder will be used) - * @param string $modulesMailFolder Output folder for modules emails (if left empty the module mails folder will be used) - */ - public function __construct( - $themeName, - $language, - $overwriteTemplates = false, - $coreMailsFolder = '', - $modulesMailFolder = '' - ) { - $this->themeName = $themeName; - $this->language = $language; - $this->overwriteTemplates = $overwriteTemplates; - $this->coreMailsFolder = $coreMailsFolder; - $this->modulesMailFolder = $modulesMailFolder; - } - - /** - * @return string - */ - public function getThemeName() - { - return $this->themeName; - } - - /** - * @return string - */ - public function getLanguage() - { - return $this->language; - } - - /** - * @return bool - */ - public function overwriteTemplates() - { - return $this->overwriteTemplates; - } - - /** - * @return string - */ - public function getCoreMailsFolder() - { - return $this->coreMailsFolder; - } - - /** - * @return string - */ - public function getModulesMailFolder() - { - return $this->modulesMailFolder; - } -} diff --git a/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandler.php b/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandler.php deleted file mode 100644 index fb6e15e6..00000000 --- a/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandler.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\MailTemplate\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageRepositoryInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateGenerator; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class GenerateThemeMailTemplatesCommandHandler generates email templates with parameters provided - * by GenerateThemeMailTemplatesCommand. If no output folders are defined by the command its output - * folders are the default ones. - */ -class GenerateThemeMailTemplatesCommandHandler implements GenerateThemeMailTemplatesCommandHandlerInterface -{ - /** @var LanguageRepositoryInterface */ - private $languageRepository; - - /** @var ThemeCatalogInterface */ - private $themeCatalog; - - /** @var MailTemplateGenerator */ - private $generator; - - /** @var TranslatorInterface */ - private $translator; - - /** @var string */ - private $defaultCoreMailsFolder; - - /** @var string */ - private $defaultModulesMailFolder; - - /** - * @param LanguageRepositoryInterface $languageRepository - * @param ThemeCatalogInterface $themeCatalog - * @param MailTemplateGenerator $generator - * @param TranslatorInterface $translator - * @param string $defaultCoreMailsFolder - * @param string $defaultModulesMailFolder - */ - public function __construct( - LanguageRepositoryInterface $languageRepository, - ThemeCatalogInterface $themeCatalog, - MailTemplateGenerator $generator, - TranslatorInterface $translator, - $defaultCoreMailsFolder, - $defaultModulesMailFolder - ) { - $this->languageRepository = $languageRepository; - $this->themeCatalog = $themeCatalog; - $this->generator = $generator; - $this->translator = $translator; - $this->defaultCoreMailsFolder = $defaultCoreMailsFolder; - $this->defaultModulesMailFolder = $defaultModulesMailFolder; - } - - /** - * {@inheritdoc} - */ - public function handle(GenerateThemeMailTemplatesCommand $command) - { - /** @var LanguageInterface $language */ - $language = $this->languageRepository->getOneByLocaleOrIsoCode($command->getLanguage()); - if (null === $language) { - throw new InvalidArgumentException(sprintf('Could not find Language for locale: %s', $command->getLanguage())); - } - - /** @var ThemeInterface $theme */ - $theme = $this->themeCatalog->getByName($command->getThemeName()); - - $coreMailsFolder = $command->getCoreMailsFolder() ?: $this->defaultCoreMailsFolder; - $modulesMailFolder = $command->getModulesMailFolder() ?: $this->defaultModulesMailFolder; - - $this->generator->generateTemplates($theme, $language, $coreMailsFolder, $modulesMailFolder, $command->overwriteTemplates()); - } -} diff --git a/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandlerInterface.php b/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandlerInterface.php deleted file mode 100644 index 1f3737bf..00000000 --- a/src/Core/Domain/MailTemplate/CommandHandler/GenerateThemeMailTemplatesCommandHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\MailTemplate\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; - -/** - * Interface GenerateThemeMailsHandlerInterface - */ -interface GenerateThemeMailTemplatesCommandHandlerInterface -{ - /** - * @param GenerateThemeMailTemplatesCommand $command - */ - public function handle(GenerateThemeMailTemplatesCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/Command/AddManufacturerCommand.php b/src/Core/Domain/Manufacturer/Command/AddManufacturerCommand.php deleted file mode 100644 index 245cf825..00000000 --- a/src/Core/Domain/Manufacturer/Command/AddManufacturerCommand.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -/** - * Creates manufacturer with provided data - */ -class AddManufacturerCommand -{ - /** - * @var string - */ - private $name; - - /** - * @var string[] - */ - private $localizedShortDescriptions; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var bool - */ - private $enabled; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @param string $name - * @param bool $enabled - * @param string[] $localizedShortDescriptions - * @param string[] $localizedDescriptions - * @param string[] $localizedMetaTitles - * @param string[] $localizedMetaDescriptions - * @param string[] $localizedMetaKeywords - * @param array $shopAssociation - */ - public function __construct( - $name, - $enabled, - array $localizedShortDescriptions, - array $localizedDescriptions, - array $localizedMetaTitles, - array $localizedMetaDescriptions, - array $localizedMetaKeywords, - array $shopAssociation - ) { - $this->name = $name; - $this->enabled = $enabled; - $this->localizedShortDescriptions = $localizedShortDescriptions; - $this->localizedDescriptions = $localizedDescriptions; - $this->localizedMetaTitles = $localizedMetaTitles; - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - $this->localizedMetaKeywords = $localizedMetaKeywords; - $this->shopAssociation = $shopAssociation; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string[] - */ - public function getLocalizedShortDescriptions() - { - return $this->localizedShortDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * @return array - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } -} diff --git a/src/Core/Domain/Manufacturer/Command/BulkDeleteManufacturerCommand.php b/src/Core/Domain/Manufacturer/Command/BulkDeleteManufacturerCommand.php deleted file mode 100644 index a7096802..00000000 --- a/src/Core/Domain/Manufacturer/Command/BulkDeleteManufacturerCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Deletes manufacturers in bulk action - */ -class BulkDeleteManufacturerCommand -{ - /** - * @var ManufacturerId[] - */ - private $manufacturerIds; - - /** - * @param int[] $manufacturerIds - * - * @throws ManufacturerConstraintException - */ - public function __construct(array $manufacturerIds) - { - $this->setManufacturerIds($manufacturerIds); - } - - /** - * @return ManufacturerId[] - */ - public function getManufacturerIds() - { - return $this->manufacturerIds; - } - - /** - * @param array $manufacturerIds - * - * @throws ManufacturerConstraintException - */ - private function setManufacturerIds(array $manufacturerIds) - { - foreach ($manufacturerIds as $manufacturerId) { - $this->manufacturerIds[] = new ManufacturerId($manufacturerId); - } - } -} diff --git a/src/Core/Domain/Manufacturer/Command/BulkToggleManufacturerStatusCommand.php b/src/Core/Domain/Manufacturer/Command/BulkToggleManufacturerStatusCommand.php deleted file mode 100644 index 31118486..00000000 --- a/src/Core/Domain/Manufacturer/Command/BulkToggleManufacturerStatusCommand.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Toggles manufacturer status in bulk action - */ -class BulkToggleManufacturerStatusCommand -{ - /** - * @var bool - */ - private $expectedStatus; - - /** - * @var ManufacturerId[] - */ - private $manufacturerIds; - - /** - * @param int[] $manufacturerIds - * @param bool $expectedStatus - * - * @throws ManufacturerConstraintException - * @throws ManufacturerConstraintException - */ - public function __construct(array $manufacturerIds, $expectedStatus) - { - $this->assertIsBool($expectedStatus); - $this->expectedStatus = $expectedStatus; - $this->setManufacturerIds($manufacturerIds); - } - - /** - * @return bool - */ - public function getExpectedStatus() - { - return $this->expectedStatus; - } - - /** - * @return ManufacturerId[] - */ - public function getManufacturerIds() - { - return $this->manufacturerIds; - } - - /** - * @param int[] $manufacturerIds - * - * @throws ManufacturerConstraintException - */ - private function setManufacturerIds(array $manufacturerIds) - { - foreach ($manufacturerIds as $manufacturerId) { - $this->manufacturerIds[] = new ManufacturerId($manufacturerId); - } - } - - /** - * Validates that value is of type boolean - * - * @param $value - * - * @throws ManufacturerConstraintException - */ - private function assertIsBool($value) - { - if (!is_bool($value)) { - throw new ManufacturerConstraintException(sprintf('Status must be of type bool, but given %s', var_export($value, true)), ManufacturerConstraintException::INVALID_STATUS); - } - } -} diff --git a/src/Core/Domain/Manufacturer/Command/DeleteManufacturerCommand.php b/src/Core/Domain/Manufacturer/Command/DeleteManufacturerCommand.php deleted file mode 100644 index ff13de8e..00000000 --- a/src/Core/Domain/Manufacturer/Command/DeleteManufacturerCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Deletes manufacturer - */ -class DeleteManufacturerCommand -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @param int $manufacturerId - * - * @throws ManufacturerConstraintException - */ - public function __construct($manufacturerId) - { - $this->manufacturerId = new ManufacturerId($manufacturerId); - } - - /** - * @return ManufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } -} diff --git a/src/Core/Domain/Manufacturer/Command/EditManufacturerCommand.php b/src/Core/Domain/Manufacturer/Command/EditManufacturerCommand.php deleted file mode 100644 index cf8c611d..00000000 --- a/src/Core/Domain/Manufacturer/Command/EditManufacturerCommand.php +++ /dev/null @@ -1,256 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Edits manufacturer with provided data - */ -class EditManufacturerCommand -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @var string|null - */ - private $name; - - /** - * @var string[]|null - */ - private $localizedShortDescriptions; - - /** - * @var string[]|null - */ - private $localizedDescriptions; - - /** - * @var string[]|null - */ - private $localizedMetaTitles; - - /** - * @var string[]|null - */ - private $localizedMetaDescriptions; - - /** - * @var string[]|null - */ - private $localizedMetaKeywords; - - /** - * @var bool|null - */ - private $enabled; - - /** - * @var array|null - */ - private $associatedShops; - - /** - * @param int $manufacturerId - */ - public function __construct($manufacturerId) - { - $this->manufacturerId = new ManufacturerId($manufacturerId); - } - - /** - * @return ManufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return string|null - */ - public function getName() - { - return $this->name; - } - - /** - * @param string|null $name - * - * @return self - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedShortDescriptions() - { - return $this->localizedShortDescriptions; - } - - /** - * @return string[]|null - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @param string[]|null $localizedDescriptions - * - * @return self - */ - public function setLocalizedDescriptions($localizedDescriptions) - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @param string[]|null $localizedShortDescriptions - * - * @return self - */ - public function setLocalizedShortDescriptions($localizedShortDescriptions) - { - $this->localizedShortDescriptions = $localizedShortDescriptions; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @param string[]|null $localizedMetaTitles - * - * @return self - */ - public function setLocalizedMetaTitles($localizedMetaTitles) - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[]|null $localizedMetaDescriptions - * - * @return self - */ - public function setLocalizedMetaDescriptions($localizedMetaDescriptions) - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[]|null $localizedMetaKeywords - * - * @return self - */ - public function setLocalizedMetaKeywords($localizedMetaKeywords) - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return bool|null - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * @param bool|null $enabled - * - * @return self - */ - public function setEnabled($enabled) - { - $this->enabled = $enabled; - - return $this; - } - - /** - * @return array - */ - public function getAssociatedShops() - { - return $this->associatedShops; - } - - /** - * @param $associatedShops - * - * @return self - */ - public function setAssociatedShops($associatedShops) - { - $this->associatedShops = $associatedShops; - - return $this; - } -} diff --git a/src/Core/Domain/Manufacturer/Command/ToggleManufacturerStatusCommand.php b/src/Core/Domain/Manufacturer/Command/ToggleManufacturerStatusCommand.php deleted file mode 100644 index d2a63543..00000000 --- a/src/Core/Domain/Manufacturer/Command/ToggleManufacturerStatusCommand.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Toggles manufacturer status - */ -class ToggleManufacturerStatusCommand -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @var bool - */ - private $expectedStatus; - - /** - * @param int $manufacturerId - * @param bool $expectedStatus - * - * @throws ManufacturerConstraintException - */ - public function __construct($manufacturerId, $expectedStatus) - { - $this->assertIsBool($expectedStatus); - $this->expectedStatus = $expectedStatus; - $this->manufacturerId = new ManufacturerId($manufacturerId); - } - - /** - * @return ManufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return bool - */ - public function getExpectedStatus() - { - return $this->expectedStatus; - } - - /** - * Validates that value is of type boolean - * - * @param $value - * - * @throws ManufacturerConstraintException - */ - private function assertIsBool($value) - { - if (!is_bool($value)) { - throw new ManufacturerConstraintException(sprintf('Status must be of type bool, but given %s', var_export($value, true)), ManufacturerConstraintException::INVALID_STATUS); - } - } -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/AddManufacturerHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/AddManufacturerHandlerInterface.php deleted file mode 100644 index 48d64d00..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/AddManufacturerHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\AddManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Defines contract for AddManufacturerHandler - */ -interface AddManufacturerHandlerInterface -{ - /** - * @param AddManufacturerCommand $command - * - * @return ManufacturerId - */ - public function handle(AddManufacturerCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/BulkDeleteManufacturerHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/BulkDeleteManufacturerHandlerInterface.php deleted file mode 100644 index e8d916fa..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/BulkDeleteManufacturerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkDeleteManufacturerCommand; - -/** - * Defines contract for BulkDeleteManufacturerHandler - */ -interface BulkDeleteManufacturerHandlerInterface -{ - /** - * @param BulkDeleteManufacturerCommand $command - */ - public function handle(BulkDeleteManufacturerCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandlerInterface.php deleted file mode 100644 index 1ab406e3..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/BulkToggleManufacturerStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkToggleManufacturerStatusCommand; - -/** - * Defines contract for BulkToggleManufacturerStatusHandler - */ -interface BulkToggleManufacturerStatusHandlerInterface -{ - /** - * @param BulkToggleManufacturerStatusCommand $command - */ - public function handle(BulkToggleManufacturerStatusCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/DeleteManufacturerHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/DeleteManufacturerHandlerInterface.php deleted file mode 100644 index 385c0020..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/DeleteManufacturerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\DeleteManufacturerCommand; - -/** - * Defines contract for DeleteManufacturerHandler - */ -interface DeleteManufacturerHandlerInterface -{ - /** - * @param DeleteManufacturerCommand $command - */ - public function handle(DeleteManufacturerCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/EditManufacturerHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/EditManufacturerHandlerInterface.php deleted file mode 100644 index 60e98cd1..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/EditManufacturerHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\EditManufacturerCommand; - -/** - * Defines contract for EditManufacturerHandler - */ -interface EditManufacturerHandlerInterface -{ - /** - * @param EditManufacturerCommand $command - */ - public function handle(EditManufacturerCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/CommandHandler/ToggleManufacturerStatusHandlerInterface.php b/src/Core/Domain/Manufacturer/CommandHandler/ToggleManufacturerStatusHandlerInterface.php deleted file mode 100644 index d169c541..00000000 --- a/src/Core/Domain/Manufacturer/CommandHandler/ToggleManufacturerStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\ToggleManufacturerStatusCommand; - -/** - * Defines contract for ToggleManufacturerStatusHandler - */ -interface ToggleManufacturerStatusHandlerInterface -{ - /** - * @param ToggleManufacturerStatusCommand $command - */ - public function handle(ToggleManufacturerStatusCommand $command); -} diff --git a/src/Core/Domain/Manufacturer/Exception/DeleteManufacturerException.php b/src/Core/Domain/Manufacturer/Exception/DeleteManufacturerException.php deleted file mode 100644 index 8c0dd609..00000000 --- a/src/Core/Domain/Manufacturer/Exception/DeleteManufacturerException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -/** - * Is thrown manufacturer or manufacturers cannot be deleted - */ -class DeleteManufacturerException extends ManufacturerException -{ - /** - * When fails to delete single manufacturer - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete manufacturers in bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/Manufacturer/Exception/ManufacturerConstraintException.php b/src/Core/Domain/Manufacturer/Exception/ManufacturerConstraintException.php deleted file mode 100644 index b55502e5..00000000 --- a/src/Core/Domain/Manufacturer/Exception/ManufacturerConstraintException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -/** - * Is thrown when Manufacturer constraint is violated - */ -class ManufacturerConstraintException extends ManufacturerException -{ - /** - * When manufacturer id is not valid - */ - const INVALID_ID = 10; - - /** - * When manufacturer status is not valid - */ - const INVALID_STATUS = 20; -} diff --git a/src/Core/Domain/Manufacturer/Exception/ManufacturerException.php b/src/Core/Domain/Manufacturer/Exception/ManufacturerException.php deleted file mode 100644 index 84637915..00000000 --- a/src/Core/Domain/Manufacturer/Exception/ManufacturerException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for Manufacturer subdomain - */ -class ManufacturerException extends DomainException -{ -} diff --git a/src/Core/Domain/Manufacturer/Exception/ManufacturerImageUploadingException.php b/src/Core/Domain/Manufacturer/Exception/ManufacturerImageUploadingException.php deleted file mode 100644 index 5b47f4d1..00000000 --- a/src/Core/Domain/Manufacturer/Exception/ManufacturerImageUploadingException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -/** - * Is thrown when error occurs when uploading language image - */ -class ManufacturerImageUploadingException extends ManufacturerException -{ - /** - * @var int Code is used when there are less memory than needed to upload image - */ - const MEMORY_LIMIT_RESTRICTION = 1; - - /** - * @var int Code is used when unexpected error occurs while uploading image - */ - const UNEXPECTED_ERROR = 2; - - /** - * Code is used when image/images cannot be resized - */ - const UNABLE_RESIZE = 3; -} diff --git a/src/Core/Domain/Manufacturer/Exception/ManufacturerNotFoundException.php b/src/Core/Domain/Manufacturer/Exception/ManufacturerNotFoundException.php deleted file mode 100644 index 40e5d5a5..00000000 --- a/src/Core/Domain/Manufacturer/Exception/ManufacturerNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -/** - * Is thrown when manufacturer is not found in Manufacturer subdomain - */ -class ManufacturerNotFoundException extends ManufacturerException -{ -} diff --git a/src/Core/Domain/Manufacturer/Exception/UpdateManufacturerException.php b/src/Core/Domain/Manufacturer/Exception/UpdateManufacturerException.php deleted file mode 100644 index 898e36ff..00000000 --- a/src/Core/Domain/Manufacturer/Exception/UpdateManufacturerException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception; - -/** - * Is thrown when cannot update manufacturer - */ -class UpdateManufacturerException extends ManufacturerException -{ - /** - * When fails to update single manufacturer status - */ - const FAILED_UPDATE_STATUS = 10; - - /** - * When fails to update manufacturers status in bulk action - */ - const FAILED_BULK_UPDATE_STATUS = 20; -} diff --git a/src/Core/Domain/Manufacturer/Query/GetManufacturerForEditing.php b/src/Core/Domain/Manufacturer/Query/GetManufacturerForEditing.php deleted file mode 100644 index 284d3ebd..00000000 --- a/src/Core/Domain/Manufacturer/Query/GetManufacturerForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Gets manufacturer for editing in Back Office - */ -class GetManufacturerForEditing -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @param int $manufacturerId - * - * @throws ManufacturerConstraintException - */ - public function __construct($manufacturerId) - { - $this->manufacturerId = new ManufacturerId($manufacturerId); - } - - /** - * @return ManufacturerId $manufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } -} diff --git a/src/Core/Domain/Manufacturer/Query/GetManufacturerForViewing.php b/src/Core/Domain/Manufacturer/Query/GetManufacturerForViewing.php deleted file mode 100644 index 9b13bfbe..00000000 --- a/src/Core/Domain/Manufacturer/Query/GetManufacturerForViewing.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Get manufacturer information for viewing - */ -class GetManufacturerForViewing -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @var LanguageId Language in which manufacturer is returned - */ - private $languageId; - - /** - * @param int $manufacturerId - * @param int $languageId - */ - public function __construct($manufacturerId, $languageId) - { - $this->manufacturerId = new ManufacturerId($manufacturerId); - $this->languageId = new LanguageId($languageId); - } - - /** - * @return ManufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForEditingHandlerInterface.php b/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForEditingHandlerInterface.php deleted file mode 100644 index f348d079..00000000 --- a/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\EditableManufacturer; - -/** - * Defines contract for GetManufacturerForEditingHandler - */ -interface GetManufacturerForEditingHandlerInterface -{ - /** - * @param GetManufacturerForEditing $query - * - * @return EditableManufacturer - */ - public function handle(GetManufacturerForEditing $query); -} diff --git a/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForViewingHandlerInterface.php b/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForViewingHandlerInterface.php deleted file mode 100644 index 763cf765..00000000 --- a/src/Core/Domain/Manufacturer/QueryHandler/GetManufacturerForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\ViewableManufacturer; - -/** - * Interface for service that handles gettting manufacturer for viewing query - */ -interface GetManufacturerForViewingHandlerInterface -{ - /** - * @param GetManufacturerForViewing $query - * - * @return ViewableManufacturer - */ - public function handle(GetManufacturerForViewing $query); -} diff --git a/src/Core/Domain/Manufacturer/QueryResult/EditableManufacturer.php b/src/Core/Domain/Manufacturer/QueryResult/EditableManufacturer.php deleted file mode 100644 index a4889d25..00000000 --- a/src/Core/Domain/Manufacturer/QueryResult/EditableManufacturer.php +++ /dev/null @@ -1,201 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; - -/** - * Transfers manufacturer data for editing - */ -class EditableManufacturer -{ - /** - * @var ManufacturerId - */ - private $manufacturerId; - - /** - * @var string - */ - private $name; - - /** - * @var string[] - */ - private $localizedShortDescriptions; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var array - */ - private $logoImage; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var bool - */ - private $enabled; - - /** - * @var array - */ - private $associatedShops; - - /** - * @param ManufacturerId $manufacturerId - * @param string $name - * @param bool $enabled - * @param array $localizedShortDescriptions - * @param array $localizedDescriptions - * @param array $localizedMetaTitles - * @param array $localizedMetaDescriptions - * @param array $localizedMetaKeywords - * @param array|null $logoImage - * @param array $associatedShops - */ - public function __construct( - ManufacturerId $manufacturerId, - $name, - $enabled, - array $localizedShortDescriptions, - array $localizedDescriptions, - array $localizedMetaTitles, - array $localizedMetaDescriptions, - array $localizedMetaKeywords, - $logoImage, - array $associatedShops - ) { - $this->manufacturerId = $manufacturerId; - $this->name = $name; - $this->localizedShortDescriptions = $localizedShortDescriptions; - $this->localizedDescriptions = $localizedDescriptions; - $this->logoImage = $logoImage; - $this->localizedMetaTitles = $localizedMetaTitles; - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - $this->localizedMetaKeywords = $localizedMetaKeywords; - $this->enabled = $enabled; - $this->associatedShops = $associatedShops; - } - - /** - * @return ManufacturerId - */ - public function getManufacturerId() - { - return $this->manufacturerId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string[] - */ - public function getLocalizedShortDescriptions() - { - return $this->localizedShortDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions() - { - return $this->localizedDescriptions; - } - - /** - * @return array - */ - public function getLogoImage() - { - return $this->logoImage; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles() - { - return $this->localizedMetaTitles; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions() - { - return $this->localizedMetaDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords() - { - return $this->localizedMetaKeywords; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * @return array - */ - public function getAssociatedShops() - { - return $this->associatedShops; - } -} diff --git a/src/Core/Domain/Manufacturer/QueryResult/ViewableManufacturer.php b/src/Core/Domain/Manufacturer/QueryResult/ViewableManufacturer.php deleted file mode 100644 index 6532ab52..00000000 --- a/src/Core/Domain/Manufacturer/QueryResult/ViewableManufacturer.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult; - -/** - * Stores query result for getting manufacturer for viewing - */ -class ViewableManufacturer -{ - /** - * @var string - */ - private $name; - - /** - * @var array - */ - private $manufacturerAddresses; - - /** - * @var array - */ - private $manufacturerProducts; - - /** - * @param string $name - * @param array $manufacturerAddresses - * @param array $manufacturerProducts - */ - public function __construct($name, array $manufacturerAddresses, array $manufacturerProducts) - { - $this->name = $name; - $this->manufacturerAddresses = $manufacturerAddresses; - $this->manufacturerProducts = $manufacturerProducts; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return array - */ - public function getManufacturerAddresses() - { - return $this->manufacturerAddresses; - } - - /** - * @return array - */ - public function getManufacturerProducts() - { - return $this->manufacturerProducts; - } -} diff --git a/src/Core/Domain/Manufacturer/ValueObject/ManufacturerId.php b/src/Core/Domain/Manufacturer/ValueObject/ManufacturerId.php deleted file mode 100644 index 7a87b990..00000000 --- a/src/Core/Domain/Manufacturer/ValueObject/ManufacturerId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; - -/** - * Provides manufacturer id - */ -class ManufacturerId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - * - * @throws ManufacturerConstraintException - */ - public function __construct($id) - { - $this->assertIsIntegerGreaterThanZero($id); - $this->id = $id; - } - - /** - * @return int - */ - public function getValue() - { - return $this->id; - } - - /** - * Validates that the value is integer and is greater than zero - * - * @param $value - * - * @throws ManufacturerConstraintException - */ - private function assertIsIntegerGreaterThanZero($value) - { - if (!is_int($value) || 0 >= $value) { - throw new ManufacturerConstraintException(sprintf('Invalid manufacturer id "%s".', var_export($value, true))); - } - } -} diff --git a/src/Core/Domain/Meta/Command/AbstractMetaCommand.php b/src/Core/Domain/Meta/Command/AbstractMetaCommand.php deleted file mode 100644 index 0717881e..00000000 --- a/src/Core/Domain/Meta/Command/AbstractMetaCommand.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Command; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; - -/** - * Class AbstractMetaCommand is responsible for defining the abstraction for AddMetaCommand and EditMetaCommand. - */ -abstract class AbstractMetaCommand -{ - /** - * @param int $languageId - * @param string $value - * @param int $constraintErrorCode - * - * @throws MetaConstraintException - */ - protected function assertNameMatchesRegexPattern($languageId, $value, $constraintErrorCode) - { - $regex = '/^[^<>={}]*$/u'; - - if ($value && !preg_match($regex, $value)) { - throw new MetaConstraintException(sprintf('Value "%s" for language id %s did not passed the regex expression: %s', $value, $languageId, $regex), $constraintErrorCode); - } - } -} diff --git a/src/Core/Domain/Meta/Command/AddMetaCommand.php b/src/Core/Domain/Meta/Command/AddMetaCommand.php deleted file mode 100644 index 7d805456..00000000 --- a/src/Core/Domain/Meta/Command/AddMetaCommand.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Command; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\Name; - -/** - * Class AddMetaCommand is responsible for saving meta entities data. - */ -class AddMetaCommand extends AbstractMetaCommand -{ - /** - * @var Name - */ - private $pageName; - - /** - * @var string[] - */ - private $localisedPageTitle; - - /** - * @var string[] - */ - private $localisedMetaDescription; - - /** - * @var string[] - */ - private $localisedMetaKeywords; - - /** - * @var string[] - */ - private $LocalisedRewriteUrls; - - /** - * @param string $pageName - * - * @throws MetaConstraintException - */ - public function __construct($pageName) - { - $this->pageName = new Name($pageName); - } - - /** - * @return Name - */ - public function getPageName() - { - return $this->pageName; - } - - /** - * @return string[] - */ - public function getLocalisedPageTitles() - { - return $this->localisedPageTitle; - } - - /** - * @param string[] $localisedPageTitle - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedPageTitle(array $localisedPageTitle) - { - foreach ($localisedPageTitle as $idLang => $title) { - $this->assertNameMatchesRegexPattern($idLang, $title, MetaConstraintException::INVALID_PAGE_TITLE); - } - - $this->localisedPageTitle = $localisedPageTitle; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaDescription() - { - return $this->localisedMetaDescription; - } - - /** - * @param string[] $localisedMetaDescription - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedMetaDescription(array $localisedMetaDescription) - { - foreach ($localisedMetaDescription as $idLang => $description) { - $this->assertNameMatchesRegexPattern($idLang, $description, MetaConstraintException::INVALID_META_DESCRIPTION); - } - - $this->localisedMetaDescription = $localisedMetaDescription; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @param string[] $localisedMetaKeywords - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedMetaKeywords(array $localisedMetaKeywords) - { - foreach ($localisedMetaKeywords as $idLang => $metaKeyword) { - $this->assertNameMatchesRegexPattern($idLang, $metaKeyword, MetaConstraintException::INVALID_META_KEYWORDS); - } - - $this->localisedMetaKeywords = $localisedMetaKeywords; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedRewriteUrls() - { - return $this->LocalisedRewriteUrls; - } - - /** - * @param string[] $LocalisedRewriteUrls - * - * @return self - */ - public function setLocalisedRewriteUrls(array $LocalisedRewriteUrls) - { - $this->LocalisedRewriteUrls = $LocalisedRewriteUrls; - - return $this; - } -} diff --git a/src/Core/Domain/Meta/Command/EditMetaCommand.php b/src/Core/Domain/Meta/Command/EditMetaCommand.php deleted file mode 100644 index f76e05d9..00000000 --- a/src/Core/Domain/Meta/Command/EditMetaCommand.php +++ /dev/null @@ -1,206 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Command; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\Name; - -/** - * Class EditMetaCommand - */ -class EditMetaCommand extends AbstractMetaCommand -{ - /** - * @var MetaId - */ - private $metaId; - - /** - * @var Name - */ - private $pageName; - - /** - * @var string[] - */ - private $localisedPageTitles; - - /** - * @var string[] - */ - private $localisedMetaDescriptions; - - /** - * @var string[] - */ - private $localisedMetaKeywords; - - /** - * @var string[] - */ - private $localisedRewriteUrls; - - /** - * @param int $metaId - * - * @throws MetaException - */ - public function __construct($metaId) - { - $this->metaId = new MetaId($metaId); - } - - /** - * @return MetaId - */ - public function getMetaId() - { - return $this->metaId; - } - - /** - * @return Name - */ - public function getPageName() - { - return $this->pageName; - } - - /** - * @param string $pageName - * - * @return self - * - * @throws MetaConstraintException - */ - public function setPageName($pageName) - { - $this->pageName = new Name($pageName); - - return $this; - } - - /** - * @param string[] $localisedPageTitles - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedPageTitles(array $localisedPageTitles) - { - foreach ($localisedPageTitles as $idLang => $title) { - $this->assertNameMatchesRegexPattern($idLang, $title, MetaConstraintException::INVALID_PAGE_TITLE); - } - - $this->localisedPageTitles = $localisedPageTitles; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedPageTitles() - { - return $this->localisedPageTitles; - } - - /** - * @param string[] $localisedMetaDescriptions - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedMetaDescriptions(array $localisedMetaDescriptions) - { - foreach ($localisedMetaDescriptions as $idLang => $description) { - $this->assertNameMatchesRegexPattern($idLang, $description, MetaConstraintException::INVALID_META_DESCRIPTION); - } - - $this->localisedMetaDescriptions = $localisedMetaDescriptions; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaDescriptions() - { - return $this->localisedMetaDescriptions; - } - - /** - * @param string[] $localisedMetaKeywords - * - * @return self - * - * @throws MetaConstraintException - */ - public function setLocalisedMetaKeywords(array $localisedMetaKeywords) - { - foreach ($localisedMetaKeywords as $idLang => $metaKeyword) { - $this->assertNameMatchesRegexPattern($idLang, $metaKeyword, MetaConstraintException::INVALID_META_KEYWORDS); - } - - $this->localisedMetaKeywords = $localisedMetaKeywords; - - return $this; - } - - /** - * @return string[] - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @return string[] - */ - public function getLocalisedRewriteUrls() - { - return $this->localisedRewriteUrls; - } - - /** - * @param string[] $localisedRewriteUrls - * - * @return self - */ - public function setLocalisedRewriteUrls(array $localisedRewriteUrls) - { - $this->localisedRewriteUrls = $localisedRewriteUrls; - - return $this; - } -} diff --git a/src/Core/Domain/Meta/CommandHandler/AddMetaHandlerInterface.php b/src/Core/Domain/Meta/CommandHandler/AddMetaHandlerInterface.php deleted file mode 100644 index de9a5098..00000000 --- a/src/Core/Domain/Meta/CommandHandler/AddMetaHandlerInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\AddMetaCommand; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; - -/** - * Interface AddMetaHandlerInterface defines contract for AddMetaHandler. - */ -interface AddMetaHandlerInterface -{ - /** - * Used to handle the logic required for adding meta data. - * - * @param AddMetaCommand $command - * - * @return MetaId - */ - public function handle(AddMetaCommand $command); -} diff --git a/src/Core/Domain/Meta/CommandHandler/EditMetaHandlerInterface.php b/src/Core/Domain/Meta/CommandHandler/EditMetaHandlerInterface.php deleted file mode 100644 index fe40c834..00000000 --- a/src/Core/Domain/Meta/CommandHandler/EditMetaHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\EditMetaCommand; - -/** - * Interface EditMetaHandlerInterface defines contract for EditMetaHandler. - */ -interface EditMetaHandlerInterface -{ - /** - * Handles meta entity editing. - * - * @param EditMetaCommand $command - */ - public function handle(EditMetaCommand $command); -} diff --git a/src/Core/Domain/Meta/Exception/CannotAddMetaException.php b/src/Core/Domain/Meta/Exception/CannotAddMetaException.php deleted file mode 100644 index 5154102a..00000000 --- a/src/Core/Domain/Meta/Exception/CannotAddMetaException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Exception; - -/** - * Is thrown when new meta cannot be added - */ -class CannotAddMetaException extends MetaException -{ -} diff --git a/src/Core/Domain/Meta/Exception/CannotEditMetaException.php b/src/Core/Domain/Meta/Exception/CannotEditMetaException.php deleted file mode 100644 index 402ffa66..00000000 --- a/src/Core/Domain/Meta/Exception/CannotEditMetaException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Exception; - -/** - * Is thrown when meta cannot be edited - */ -class CannotEditMetaException extends MetaException -{ -} diff --git a/src/Core/Domain/Meta/Exception/MetaConstraintException.php b/src/Core/Domain/Meta/Exception/MetaConstraintException.php deleted file mode 100644 index 64f5cf8c..00000000 --- a/src/Core/Domain/Meta/Exception/MetaConstraintException.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Exception; - -/** - * Is thrown when meta constraints are violated - */ -class MetaConstraintException extends MetaException -{ - /** - * When meta page name is invalid - */ - const INVALID_PAGE_NAME = 1; - - /** - * When meta url_rewrite is invalid - */ - const INVALID_URL_REWRITE = 2; - - /** - * When meta page title is invalid - */ - const INVALID_PAGE_TITLE = 3; - - /** - * When meta description is invalid - */ - const INVALID_META_DESCRIPTION = 4; - - /** - * When meta keywords is invalids - */ - const INVALID_META_KEYWORDS = 5; -} diff --git a/src/Core/Domain/Meta/Exception/MetaException.php b/src/Core/Domain/Meta/Exception/MetaException.php deleted file mode 100644 index 2d4498f4..00000000 --- a/src/Core/Domain/Meta/Exception/MetaException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for meta sub-domain - */ -class MetaException extends DomainException -{ -} diff --git a/src/Core/Domain/Meta/Exception/MetaNotFoundException.php b/src/Core/Domain/Meta/Exception/MetaNotFoundException.php deleted file mode 100644 index 0f5004f3..00000000 --- a/src/Core/Domain/Meta/Exception/MetaNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Exception; - -/** - * Is thrown when required meta cannot be found - */ -class MetaNotFoundException extends MetaException -{ -} diff --git a/src/Core/Domain/Meta/Query/GetMetaForEditing.php b/src/Core/Domain/Meta/Query/GetMetaForEditing.php deleted file mode 100644 index b128c406..00000000 --- a/src/Core/Domain/Meta/Query/GetMetaForEditing.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Query; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; - -/** - * Class GetMetaForEditing is responsible for providing required data for GetMetaForEditingHandler to return meta data. - */ -class GetMetaForEditing -{ - /** - * @var MetaId - */ - private $metaId; - - /** - * GetMetaForEditing constructor. - * - * @param int $metaId - * - * @throws MetaException - */ - public function __construct($metaId) - { - $this->metaId = new MetaId($metaId); - } - - /** - * @return MetaId - */ - public function getMetaId() - { - return $this->metaId; - } -} diff --git a/src/Core/Domain/Meta/Query/GetPagesForLayoutCustomization.php b/src/Core/Domain/Meta/Query/GetPagesForLayoutCustomization.php deleted file mode 100644 index b42f6925..00000000 --- a/src/Core/Domain/Meta/Query/GetPagesForLayoutCustomization.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\Query; - -/** - * Gets pages for which theme's layout can be customized. - */ -class GetPagesForLayoutCustomization -{ -} diff --git a/src/Core/Domain/Meta/QueryHandler/GetMetaForEditingHandlerInterface.php b/src/Core/Domain/Meta/QueryHandler/GetMetaForEditingHandlerInterface.php deleted file mode 100644 index 99357b7c..00000000 --- a/src/Core/Domain/Meta/QueryHandler/GetMetaForEditingHandlerInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetMetaForEditing; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult\EditableMeta; - -/** - * Interface GetMetaForEditingHandlerInterface defines contract for GetMetaForEditingHandler. - */ -interface GetMetaForEditingHandlerInterface -{ - /** - * Gets data related with meta entity. - * - * @param GetMetaForEditing $query - * - * @return EditableMeta - */ - public function handle(GetMetaForEditing $query); -} diff --git a/src/Core/Domain/Meta/QueryHandler/GetPagesForLayoutCustomizationHandlerInterface.php b/src/Core/Domain/Meta/QueryHandler/GetPagesForLayoutCustomizationHandlerInterface.php deleted file mode 100644 index ee313d5f..00000000 --- a/src/Core/Domain/Meta/QueryHandler/GetPagesForLayoutCustomizationHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetPagesForLayoutCustomization; - -/** - * Interface GetMetaPagesHandlerInterface. - */ -interface GetPagesForLayoutCustomizationHandlerInterface -{ - /** - * @param GetPagesForLayoutCustomization $query - */ - public function handle(GetPagesForLayoutCustomization $query); -} diff --git a/src/Core/Domain/Meta/QueryResult/EditableMeta.php b/src/Core/Domain/Meta/QueryResult/EditableMeta.php deleted file mode 100644 index 98c9c880..00000000 --- a/src/Core/Domain/Meta/QueryResult/EditableMeta.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\Name; - -/** - * Class EditableMeta is responsible for providing data for meta form. - */ -class EditableMeta -{ - /** - * @var MetaId - */ - private $metaId; - - /** - * @var Name - */ - private $pageName; - - /** - * @var string[] - */ - private $localisedPageTitles; - - /** - * @var string[] - */ - private $localisedMetaDescriptions; - - /** - * @var string[] - */ - private $localisedMetaKeywords; - - /** - * @var string[] - */ - private $localisedUrlRewrites; - - /** - * EditableMeta constructor. - * - * @param int $metaId - * @param string $pageName - * @param string[] $localisedPageTitles - * @param string[] $localisedMetaDescriptions - * @param string[] $localisedMetaKeywords - * @param string[] $localisedUrlRewrites - * - * @throws Exception\MetaConstraintException - * @throws MetaException - */ - public function __construct( - $metaId, - $pageName, - array $localisedPageTitles, - array $localisedMetaDescriptions, - array $localisedMetaKeywords, - array $localisedUrlRewrites - ) { - $this->metaId = new MetaId($metaId); - $this->pageName = new Name($pageName); - $this->localisedPageTitles = $localisedPageTitles; - $this->localisedMetaDescriptions = $localisedMetaDescriptions; - $this->localisedMetaKeywords = $localisedMetaKeywords; - $this->localisedUrlRewrites = $localisedUrlRewrites; - } - - /** - * @return MetaId - */ - public function getMetaId() - { - return $this->metaId; - } - - /** - * @return Name - */ - public function getPageName() - { - return $this->pageName; - } - - /** - * @return string[] - */ - public function getLocalisedPageTitles() - { - return $this->localisedPageTitles; - } - - /** - * @return string[] - */ - public function getLocalisedMetaDescriptions() - { - return $this->localisedMetaDescriptions; - } - - /** - * @return string[] - */ - public function getLocalisedMetaKeywords() - { - return $this->localisedMetaKeywords; - } - - /** - * @return string[] - */ - public function getLocalisedUrlRewrites() - { - return $this->localisedUrlRewrites; - } -} diff --git a/src/Core/Domain/Meta/QueryResult/LayoutCustomizationPage.php b/src/Core/Domain/Meta/QueryResult/LayoutCustomizationPage.php deleted file mode 100644 index 060f85e9..00000000 --- a/src/Core/Domain/Meta/QueryResult/LayoutCustomizationPage.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult; - -/** - * Class LayoutCustomizationPage. - */ -class LayoutCustomizationPage -{ - /** - * @var string - */ - private $page; - - /** - * @var string - */ - private $description; - - /** - * @var string - */ - private $title; - - /** - * @param string $page - * @param string $title - * @param string $description - */ - public function __construct($page, $title, $description) - { - $this->page = $page; - $this->description = $description; - $this->title = $title; - } - - /** - * @return string - */ - public function getPage() - { - return $this->page; - } - - /** - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->description; - } -} diff --git a/src/Core/Domain/Meta/ValueObject/MetaId.php b/src/Core/Domain/Meta/ValueObject/MetaId.php deleted file mode 100644 index 3076e83d..00000000 --- a/src/Core/Domain/Meta/ValueObject/MetaId.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; - -/** - * Class MetaId is responsible for providing id of meta entity. - */ -class MetaId -{ - /** - * @var int - */ - private $id; - - /** - * MetaId constructor. - * - * @param int $metaId - * - * @throws MetaException - */ - public function __construct($metaId) - { - $this->assertIsIntAndLargerThanZero($metaId); - - $this->id = $metaId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->id; - } - - /** - * @param $metaId - * - * @throws MetaException - */ - public function assertIsIntAndLargerThanZero($metaId) - { - if (!is_int($metaId) || $metaId <= 0) { - throw new MetaException(sprintf('Invalid meta id: %s. It must be of type integer and above 0', var_export($metaId, true))); - } - } -} diff --git a/src/Core/Domain/Meta/ValueObject/Name.php b/src/Core/Domain/Meta/ValueObject/Name.php deleted file mode 100644 index 03feb3ca..00000000 --- a/src/Core/Domain/Meta/ValueObject/Name.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; - -/** - * Class Name - */ -class Name -{ - /** - * @var string - */ - private $pageName; - - /** - * @param string $pageName - * - * @throws MetaConstraintException - */ - public function __construct($pageName) - { - $this->assertIsValidPageName($pageName); - - $this->pageName = $pageName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->pageName; - } - - /** - * @param string $pageName - * - * @throws MetaConstraintException - */ - private function assertIsValidPageName($pageName) - { - if (!is_string($pageName) || !$pageName || !preg_match('/^[a-zA-Z0-9_.-]+$/', $pageName)) { - throw new MetaConstraintException(sprintf('Invalid Meta page name %s', var_export($pageName, true)), MetaConstraintException::INVALID_PAGE_NAME); - } - } -} diff --git a/src/Core/Domain/Notification/Command/UpdateEmployeeNotificationLastElementCommand.php b/src/Core/Domain/Notification/Command/UpdateEmployeeNotificationLastElementCommand.php deleted file mode 100644 index 9c44f77e..00000000 --- a/src/Core/Domain/Notification/Command/UpdateEmployeeNotificationLastElementCommand.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\Command; - -use PrestaShop\PrestaShop\Core\Domain\Notification\Exception\TypeException; -use PrestaShop\PrestaShop\Core\Domain\Notification\ValueObject\Type; - -/** - * Updates the last notification element from a given type seen by the employee - */ -class UpdateEmployeeNotificationLastElementCommand -{ - /** - * @var Type - */ - private $type; - - /** - * UpdateEmployeeNotificationLastElementCommand constructor. - * - * @param string $type - * - * @throws TypeException - */ - public function __construct(string $type) - { - $this->type = new Type($type); - } - - /** - * @return Type - */ - public function getType() - { - return $this->type; - } -} diff --git a/src/Core/Domain/Notification/CommandHandler/UpdateEmployeeNotificationLastElementCommandHandlerInterface.php b/src/Core/Domain/Notification/CommandHandler/UpdateEmployeeNotificationLastElementCommandHandlerInterface.php deleted file mode 100644 index 0e94b21f..00000000 --- a/src/Core/Domain/Notification/CommandHandler/UpdateEmployeeNotificationLastElementCommandHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Notification\Command\UpdateEmployeeNotificationLastElementCommand; - -/** - * Interface for service that handles ACK employee notifications last elements - */ -interface UpdateEmployeeNotificationLastElementCommandHandlerInterface -{ - /** - * @param UpdateEmployeeNotificationLastElementCommand $command - */ - public function handle(UpdateEmployeeNotificationLastElementCommand $command); -} diff --git a/src/Core/Domain/Notification/Exception/NotificationException.php b/src/Core/Domain/Notification/Exception/NotificationException.php deleted file mode 100644 index 25cbbe91..00000000 --- a/src/Core/Domain/Notification/Exception/NotificationException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for Notification sub-domain - */ -class NotificationException extends DomainException -{ -} diff --git a/src/Core/Domain/Notification/Query/GetNotificationLastElements.php b/src/Core/Domain/Notification/Query/GetNotificationLastElements.php deleted file mode 100644 index fd2a5051..00000000 --- a/src/Core/Domain/Notification/Query/GetNotificationLastElements.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\Query; - -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidEmployeeIdException; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; - -/** - * This Query return the last Notifications elements - */ -class GetNotificationLastElements -{ - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * GetNotificationLastElements constructor. - * - * @param $employeeId - * - * @throws InvalidEmployeeIdException - */ - public function __construct(int $employeeId) - { - $this->employeeId = new EmployeeId($employeeId); - } - - /** - * @return EmployeeId - */ - public function getEmployeeId(): EmployeeId - { - return $this->employeeId; - } -} diff --git a/src/Core/Domain/Notification/QueryHandler/GetNotificationLastElementsHandlerInterface.php b/src/Core/Domain/Notification/QueryHandler/GetNotificationLastElementsHandlerInterface.php deleted file mode 100644 index 8755a2fe..00000000 --- a/src/Core/Domain/Notification/QueryHandler/GetNotificationLastElementsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Notification\Query\GetNotificationLastElements; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationsResults; - -/** - * Interface for service that handles notifications last elements request - */ -interface GetNotificationLastElementsHandlerInterface -{ - /** - * @param GetNotificationLastElements $query - * - * @return NotificationsResults - */ - public function handle(GetNotificationLastElements $query): NotificationsResults; -} diff --git a/src/Core/Domain/Notification/QueryResult/NotificationResult.php b/src/Core/Domain/Notification/QueryResult/NotificationResult.php deleted file mode 100644 index e1549caa..00000000 --- a/src/Core/Domain/Notification/QueryResult/NotificationResult.php +++ /dev/null @@ -1,233 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult; - -/** - * NotificationResult contains the notification data - */ -class NotificationResult -{ - /** - * @var int - */ - private $orderId; - - /** - * @var int - */ - private $customerId; - - /** - * @var string - */ - private $customerName; - - /** - * @var int - */ - private $customerMessageId; - - /** - * @var int - */ - private $customerThreadId; - - /** - * @var string - */ - private $customerViewUrl; - - /** - * @var string - */ - private $totalPaid; - - /** - * @var string - */ - private $carrier; - - /** - * @var string - */ - private $isoCode; - - /** - * @var string - */ - private $company; - - /** - * @var string - */ - private $status; - - /** - * @var string - */ - private $dateAdd; - - /** - * NotificationResult constructor. - * - * @param int $orderId - * @param int $customerId - * @param string $customerName - * @param int $customerMessageId - * @param int $customerThreadId - * @param string $customerViewUrl - * @param string $totalPaid - * @param string $carrier - * @param string $isoCode - * @param string $company - * @param string $status - * @param string $dateAdd - */ - public function __construct( - int $orderId, - int $customerId, - string $customerName, - int $customerMessageId, - int $customerThreadId, - string $customerViewUrl, - string $totalPaid, - string $carrier, - string $isoCode, - string $company, - string $status, - string $dateAdd - ) { - $this->orderId = $orderId; - $this->customerId = $customerId; - $this->customerName = $customerName; - $this->customerMessageId = $customerMessageId; - $this->customerThreadId = $customerThreadId; - $this->customerViewUrl = $customerViewUrl; - $this->totalPaid = $totalPaid; - $this->carrier = $carrier; - $this->isoCode = $isoCode; - $this->company = $company; - $this->status = $status; - $this->dateAdd = $dateAdd; - } - - /** - * @return int - */ - public function getOrderId(): int - { - return $this->orderId; - } - - /** - * @return int - */ - public function getCustomerId(): int - { - return $this->customerId; - } - - /** - * @return string - */ - public function getCustomerName(): string - { - return $this->customerName; - } - - /** - * @return int - */ - public function getCustomerMessageId(): int - { - return $this->customerMessageId; - } - - /** - * @return int - */ - public function getCustomerThreadId(): int - { - return $this->customerThreadId; - } - - /** - * @return string - */ - public function getCustomerViewUrl(): string - { - return $this->customerViewUrl; - } - - /** - * @return string - */ - public function getTotalPaid(): string - { - return $this->totalPaid; - } - - /** - * @return string - */ - public function getCarrier(): string - { - return $this->carrier; - } - - /** - * @return string - */ - public function getIsoCode(): string - { - return $this->isoCode; - } - - /** - * @return string - */ - public function getCompany(): string - { - return $this->company; - } - - /** - * @return string - */ - public function getStatus(): string - { - return $this->status; - } - - /** - * @return string - */ - public function getDateAdd(): string - { - return $this->dateAdd; - } -} diff --git a/src/Core/Domain/Notification/QueryResult/NotificationsResult.php b/src/Core/Domain/Notification/QueryResult/NotificationsResult.php deleted file mode 100644 index 785e65b7..00000000 --- a/src/Core/Domain/Notification/QueryResult/NotificationsResult.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Notification\Exception\TypeException; -use PrestaShop\PrestaShop\Core\Domain\Notification\ValueObject\Type; - -/** - * NotificationsResult contains a collection of Notifications as well as their type and the total - */ -class NotificationsResult -{ - /** - * @var Type - */ - private $type; - - /** - * @var int - */ - private $total; - - /** - * @var NotificationResult[] - */ - private $notifications = []; - - /** - * NotificationsResult constructor. - * - * @param string $type - * @param int $total - * @param NotificationResult[] $notifications - * - * @throws TypeException - */ - public function __construct(string $type, int $total, array $notifications) - { - $this->type = new Type($type); - $this->total = $total; - $this->notifications = $notifications; - } - - public function getType(): Type - { - return $this->type; - } - - /** - * @return int - */ - public function getTotal(): int - { - return $this->total; - } - - /** - * @return NotificationResult[] - */ - public function getNotifications(): array - { - return $this->notifications; - } -} diff --git a/src/Core/Domain/Notification/QueryResult/NotificationsResults.php b/src/Core/Domain/Notification/QueryResult/NotificationsResults.php deleted file mode 100644 index 0a48eae2..00000000 --- a/src/Core/Domain/Notification/QueryResult/NotificationsResults.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult; - -/** - * NotificationsResults is a collection of NotificationsResult - */ -class NotificationsResults -{ - /** - * @var NotificationsResult[] - */ - private $notifications = []; - - /** - * NotificationsResults constructor. - * - * @param NotificationsResult[] $notifications - */ - public function __construct(array $notifications) - { - $this->notifications = $notifications; - } - - /** - * @return NotificationsResult[] - */ - public function getNotificationsResults() - { - return $this->notifications; - } - - public function getNotificationsResultsForJS() - { - $response = []; - foreach ($this->getNotificationsResults() as $element) { - $notifications = []; - foreach ($element->getNotifications() as $notification) { - $notifications[] = [ - 'id_order' => $notification->getOrderId(), - 'id_customer' => $notification->getCustomerId(), - 'id_customer_message' => $notification->getCustomerMessageId(), - 'id_customer_thread' => $notification->getCustomerThreadId(), - 'total_paid' => $notification->getTotalPaid(), - 'carrier' => $notification->getCarrier(), - 'iso_code' => $notification->getIsoCode(), - 'company' => $notification->getCompany(), - 'status' => $notification->getStatus(), - 'customer_name' => $notification->getCustomerName(), - 'date_add' => $notification->getDateAdd(), - 'customer_view_url' => $notification->getCustomerViewUrl(), - ]; - } - $response[($element->getType()->getValue())] = [ - 'total' => $element->getTotal(), - 'results' => $notifications, - ]; - } - - return $response; - } -} diff --git a/src/Core/Domain/Notification/ValueObject/Type.php b/src/Core/Domain/Notification/ValueObject/Type.php deleted file mode 100644 index 8d284ff3..00000000 --- a/src/Core/Domain/Notification/ValueObject/Type.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Notification\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Notification\Exception\NotificationException; - -/** - * Notifications types - */ -class Type -{ - const ORDER = 'order'; - - const CUSTOMER = 'customer'; - - const CUSTOMER_MESSAGE = 'customer_message'; - - /** - * @var string - */ - private $type; - - /** - * @param string $type - * - * @throws NotificationException - */ - public function __construct(string $type) - { - $this->assertIsValidType($type); - - $this->type = $type; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->type; - } - - /** - * @param string $type - * - * @throws NotificationException - */ - private function assertIsValidType(string $type) - { - $allowedTypes = [self::ORDER, self::CUSTOMER, self::CUSTOMER_MESSAGE]; - if (!in_array($type, $allowedTypes)) { - throw new NotificationException(sprintf('Type %s is invalid. Supported types are: %s', var_export($type, true), implode(', ', $allowedTypes))); - } - } -} diff --git a/src/Core/Domain/Order/CancellationActionType.php b/src/Core/Domain/Order/CancellationActionType.php deleted file mode 100644 index 6be1bcd6..00000000 --- a/src/Core/Domain/Order/CancellationActionType.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -/** - * There are different cancellation action types, they are listed in this class - * - * Class CancellationActionType - */ -class CancellationActionType -{ - const CANCEL_PRODUCT = 0; - - const STANDARD_REFUND = 1; - - const PARTIAL_REFUND = 2; - - const RETURN_PRODUCT = 3; -} diff --git a/src/Core/Domain/Order/Command/AbstractRefundCommand.php b/src/Core/Domain/Order/Command/AbstractRefundCommand.php deleted file mode 100644 index 31df2f52..00000000 --- a/src/Core/Domain/Order/Command/AbstractRefundCommand.php +++ /dev/null @@ -1,178 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use InvalidArgumentException; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Command abstract class for refund commands - */ -abstract class AbstractRefundCommand -{ - /** - * @var OrderId - */ - protected $orderId; - - /** - * @var array - */ - protected $orderDetailRefunds; - - /** - * @var bool - */ - protected $restockRefundedProducts; - - /** - * @var bool - */ - protected $generateCreditSlip; - - /** - * @var bool - */ - protected $generateVoucher; - - /** - * @var int - */ - protected $voucherRefundType; - - /** - * @var Number|null - */ - protected $voucherRefundAmount; - - /** - * @param int $orderId - * @param array $orderDetailRefunds - * @param bool $restockRefundedProducts - * @param bool $generateVoucher - * @param bool $generateCreditSlip - * @param int $voucherRefundType - * @param string|null $voucherRefundAmount - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - public function __construct( - int $orderId, - array $orderDetailRefunds, - bool $restockRefundedProducts, - bool $generateCreditSlip, - bool $generateVoucher, - int $voucherRefundType, - ?string $voucherRefundAmount = null - ) { - $this->orderId = new OrderId($orderId); - $this->restockRefundedProducts = $restockRefundedProducts; - $this->generateCreditSlip = $generateCreditSlip; - $this->generateVoucher = $generateVoucher; - $this->voucherRefundType = $voucherRefundType; - if (null !== $voucherRefundAmount) { - try { - $this->voucherRefundAmount = new Number($voucherRefundAmount); - } catch (InvalidArgumentException $e) { - throw new InvalidAmountException(); - } - } - $this->setOrderDetailRefunds($orderDetailRefunds); - if (!$this->generateCreditSlip && !$this->generateVoucher) { - throw new InvalidCancelProductException(InvalidCancelProductException::NO_GENERATION); - } - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return array - */ - public function getOrderDetailRefunds(): array - { - return $this->orderDetailRefunds; - } - - /** - * @return bool - */ - public function restockRefundedProducts(): bool - { - return $this->restockRefundedProducts; - } - - /** - * @return bool - */ - public function generateCreditSlip(): bool - { - return $this->generateCreditSlip; - } - - /** - * @return bool - */ - public function generateVoucher(): bool - { - return $this->generateVoucher; - } - - /** - * @return int - */ - public function getVoucherRefundType(): int - { - return $this->voucherRefundType; - } - - /** - * @return Number|null - */ - public function getVoucherRefundAmount(): ?Number - { - return $this->voucherRefundAmount; - } - - /** - * @param array $orderDetailRefunds - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - abstract protected function setOrderDetailRefunds(array $orderDetailRefunds); -} diff --git a/src/Core/Domain/Order/Command/AddCartRuleToOrderCommand.php b/src/Core/Domain/Order/Command/AddCartRuleToOrderCommand.php deleted file mode 100644 index d63a0890..00000000 --- a/src/Core/Domain/Order/Command/AddCartRuleToOrderCommand.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\ValueObject\OrderInvoiceId; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderDiscountType; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Adds cart rule to given order. - */ -class AddCartRuleToOrderCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var string - */ - private $cartRuleName; - - /** - * @var int - */ - private $cartRuleType; - - /** - * @var float - */ - private $value; - - /** - * @var int|null - */ - private $orderInvoiceId; - - /** - * @param int $orderId - * @param string $cartRuleName - * @param string $cartRuleType - * @param string|null $value - * @param null $orderInvoiceId - */ - public function __construct( - int $orderId, - string $cartRuleName, - string $cartRuleType, - ?string $value, - $orderInvoiceId = null - ) { - $this->assertCartRuleNameIsNotEmpty($cartRuleName); - $this->assertCartRuleTypeAndValueCombination($cartRuleType, $value); - - $this->orderId = new OrderId($orderId); - $this->cartRuleName = $cartRuleName; - $this->cartRuleType = $cartRuleType; - $this->value = null !== $value ? new Number($value) : null; - $this->orderInvoiceId = $orderInvoiceId ? new OrderInvoiceId($orderInvoiceId) : null; - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return string - */ - public function getCartRuleName(): string - { - return $this->cartRuleName; - } - - /** - * @return int - */ - public function getCartRuleType(): string - { - return $this->cartRuleType; - } - - /** - * @return Number|null - */ - public function getDiscountValue(): ?Number - { - return $this->value; - } - - /** - * @return OrderInvoiceId|null - */ - public function getOrderInvoiceId(): ?OrderInvoiceId - { - return $this->orderInvoiceId; - } - - /** - * @param string $cartRuleName - */ - private function assertCartRuleNameIsNotEmpty($cartRuleName): void - { - if (!is_string($cartRuleName) || empty($cartRuleName)) { - throw new OrderConstraintException('Cart rule name cannot be empty'); - } - } - - private function assertCartRuleTypeAndValueCombination(string $cartRuleType, ?string $value): void - { - $isNullValueAllowed = OrderDiscountType::FREE_SHIPPING === $cartRuleType; - - if (!$isNullValueAllowed && null === $value) { - throw new OrderConstraintException(sprintf('Null values are not allowed for "%s" discount types.', [OrderDiscountType::DISCOUNT_AMOUNT, OrderDiscountType::DISCOUNT_PERCENT])); - } - } -} diff --git a/src/Core/Domain/Order/Command/AddOrderFromBackOfficeCommand.php b/src/Core/Domain/Order/Command/AddOrderFromBackOfficeCommand.php deleted file mode 100644 index cff2ca4e..00000000 --- a/src/Core/Domain/Order/Command/AddOrderFromBackOfficeCommand.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidOrderStateException; -use PrestaShopBundle\Exception\InvalidModuleException; - -/** - * Adds new order from given cart. - */ -class AddOrderFromBackOfficeCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var string - */ - private $orderMessage; - - /** - * @var string - */ - private $paymentModuleName; - - /** - * @var int - */ - private $orderStateId; - - /** - * @var EmployeeId - */ - private $employeeId; - - /** - * @param int $cartId - * @param int $employeeId - * @param string $orderMessage - * @param string $paymentModuleName - * @param int $orderStateId - */ - public function __construct($cartId, $employeeId, $orderMessage, $paymentModuleName, $orderStateId) - { - $this->assertIsModuleName($paymentModuleName); - $this->assertOrderStateIsPositiveInt($orderStateId); - - $this->cartId = new CartId($cartId); - $this->employeeId = new EmployeeId($employeeId); - $this->orderMessage = $orderMessage; - $this->paymentModuleName = $paymentModuleName; - $this->orderStateId = $orderStateId; - } - - /** - * @return CartId - */ - public function getCartId() - { - return $this->cartId; - } - - /** - * @return string - */ - public function getOrderMessage() - { - return $this->orderMessage; - } - - /** - * @return string - */ - public function getPaymentModuleName() - { - return $this->paymentModuleName; - } - - /** - * @return int - */ - public function getOrderStateId() - { - return $this->orderStateId; - } - - /** - * @return EmployeeId - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @param string $moduleName - * - * @throws InvalidModuleException - */ - private function assertIsModuleName($moduleName) - { - if (!is_string($moduleName) || !preg_match('/^[a-zA-Z0-9_-]+$/', $moduleName)) { - throw new InvalidModuleException(); - } - } - - /** - * @param int $orderStateId - * - * @throws InvalidOrderStateException - */ - private function assertOrderStateIsPositiveInt($orderStateId) - { - if (!is_int($orderStateId) || 0 >= $orderStateId) { - throw new InvalidOrderStateException( - InvalidOrderStateException::INVALID_ID, - 'Invalid order state id' - ); - } - } -} diff --git a/src/Core/Domain/Order/Command/BulkChangeOrderStatusCommand.php b/src/Core/Domain/Order/Command/BulkChangeOrderStatusCommand.php deleted file mode 100644 index 39b7dd88..00000000 --- a/src/Core/Domain/Order/Command/BulkChangeOrderStatusCommand.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Changes status for given orders. - */ -class BulkChangeOrderStatusCommand -{ - /** - * @var OrderId[] - */ - private $orderIds; - - /** - * @var int - */ - private $newOrderStatusId; - - /** - * @param int[] $orderIds - * @param int $newOrderStatusId - */ - public function __construct(array $orderIds, $newOrderStatusId) - { - if (!is_int($newOrderStatusId) || 0 >= $newOrderStatusId) { - throw new OrderException(sprintf('Order status Id must be integer greater than 0, but %s given.', var_export($newOrderStatusId, true))); - } - - $this->newOrderStatusId = $newOrderStatusId; - $this->setOrderIds($orderIds); - } - - /** - * @return OrderId[] - */ - public function getOrderIds() - { - return $this->orderIds; - } - - /** - * @return int - */ - public function getNewOrderStatusId() - { - return $this->newOrderStatusId; - } - - /** - * @param int[] $orderIds - */ - private function setOrderIds(array $orderIds) - { - foreach ($orderIds as $orderId) { - $this->orderIds[] = new OrderId($orderId); - } - } -} diff --git a/src/Core/Domain/Order/Command/CancelOrderProductCommand.php b/src/Core/Domain/Order/Command/CancelOrderProductCommand.php deleted file mode 100644 index 5c58e0e4..00000000 --- a/src/Core/Domain/Order/Command/CancelOrderProductCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -class CancelOrderProductCommand -{ - /** - * @var array - * - * key: orderDetailId, value: quantity - */ - private $cancelledProducts; - - /** - * @var OrderId - */ - private $orderId; - - /** - * CancelOrderProductCommand constructor. - * - * @param array $toBeCanceledProducts - * @param int $orderId - */ - public function __construct(array $cancelledProducts, int $orderId) - { - $this->cancelledProducts = $cancelledProducts; - $this->orderId = new OrderId($orderId); - } - - /** - * @return array - */ - public function getCancelledProducts() - { - return $this->cancelledProducts; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } -} diff --git a/src/Core/Domain/Order/Command/ChangeOrderCurrencyCommand.php b/src/Core/Domain/Order/Command/ChangeOrderCurrencyCommand.php deleted file mode 100644 index 49b88cf5..00000000 --- a/src/Core/Domain/Order/Command/ChangeOrderCurrencyCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Changes currency for given order. - */ -class ChangeOrderCurrencyCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var CurrencyId - */ - private $newCurrencyId; - - /** - * @param int $orderId - * @param int $newCurrencyId - */ - public function __construct($orderId, $newCurrencyId) - { - $this->orderId = new OrderId($orderId); - $this->newCurrencyId = new CurrencyId($newCurrencyId); - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return CurrencyId - */ - public function getNewCurrencyId() - { - return $this->newCurrencyId; - } -} diff --git a/src/Core/Domain/Order/Command/ChangeOrderDeliveryAddressCommand.php b/src/Core/Domain/Order/Command/ChangeOrderDeliveryAddressCommand.php deleted file mode 100644 index e9cb393e..00000000 --- a/src/Core/Domain/Order/Command/ChangeOrderDeliveryAddressCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Changes delivery address for given order. - */ -class ChangeOrderDeliveryAddressCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var AddressId - */ - private $newDeliveryAddressId; - - /** - * @param int $orderId - * @param int $newDeliveryAddressId - */ - public function __construct($orderId, $newDeliveryAddressId) - { - $this->orderId = new OrderId($orderId); - $this->newDeliveryAddressId = new AddressId($newDeliveryAddressId); - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return AddressId - */ - public function getNewDeliveryAddressId() - { - return $this->newDeliveryAddressId; - } -} diff --git a/src/Core/Domain/Order/Command/ChangeOrderInvoiceAddressCommand.php b/src/Core/Domain/Order/Command/ChangeOrderInvoiceAddressCommand.php deleted file mode 100644 index e0c9a49b..00000000 --- a/src/Core/Domain/Order/Command/ChangeOrderInvoiceAddressCommand.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Changes invoice address for given order. - */ -class ChangeOrderInvoiceAddressCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var AddressId - */ - private $newInvoiceAddressId; - - /** - * @param int $orderId - * @param int $newInvoiceAddressId - */ - public function __construct($orderId, $newInvoiceAddressId) - { - $this->orderId = new OrderId($orderId); - $this->newInvoiceAddressId = new AddressId($newInvoiceAddressId); - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return AddressId - */ - public function getNewInvoiceAddressId() - { - return $this->newInvoiceAddressId; - } -} diff --git a/src/Core/Domain/Order/Command/DeleteCartRuleFromOrderCommand.php b/src/Core/Domain/Order/Command/DeleteCartRuleFromOrderCommand.php deleted file mode 100644 index e2d19b29..00000000 --- a/src/Core/Domain/Order/Command/DeleteCartRuleFromOrderCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Removes cart rule from given order. - */ -class DeleteCartRuleFromOrderCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $orderCartRuleId; - - /** - * @param int $orderId - * @param int $orderCartRuleId - */ - public function __construct($orderId, $orderCartRuleId) - { - $this->orderId = new OrderId($orderId); - $this->orderCartRuleId = $orderCartRuleId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return int - */ - public function getOrderCartRuleId() - { - return $this->orderCartRuleId; - } -} diff --git a/src/Core/Domain/Order/Command/DuplicateOrderCartCommand.php b/src/Core/Domain/Order/Command/DuplicateOrderCartCommand.php deleted file mode 100644 index 1f6108c4..00000000 --- a/src/Core/Domain/Order/Command/DuplicateOrderCartCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Duplicates cart for given order - */ -class DuplicateOrderCartCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @param int $orderId - */ - public function __construct($orderId) - { - $this->orderId = new OrderId($orderId); - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } -} diff --git a/src/Core/Domain/Order/Command/IssuePartialRefundCommand.php b/src/Core/Domain/Order/Command/IssuePartialRefundCommand.php deleted file mode 100644 index c598dd37..00000000 --- a/src/Core/Domain/Order/Command/IssuePartialRefundCommand.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use InvalidArgumentException; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderDetailRefund; - -/** - * Issues partial refund for given order. - */ -class IssuePartialRefundCommand extends AbstractRefundCommand -{ - /** - * @var Number - */ - private $shippingCostRefundAmount; - - /** - * The expected format for $orderDetailRefunds is an associative array indexed - * by OrderDetail id containing two fields amount and quantity - * - * ex: $orderDetailRefunds = [ - * {orderId} => [ - * 'quantity' => 2, - * 'amount' => 23.56, - * ], - * ]; - * - * @param int $orderId - * @param array $orderDetailRefunds - * @param string $shippingCostRefundAmount - * @param bool $restockRefundedProducts - * @param bool $generateVoucher - * @param bool $generateCreditSlip - * @param int $voucherRefundType - * @param string|null $voucherRefundAmount - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - public function __construct( - int $orderId, - array $orderDetailRefunds, - string $shippingCostRefundAmount, - bool $restockRefundedProducts, - bool $generateCreditSlip, - bool $generateVoucher, - int $voucherRefundType, - ?string $voucherRefundAmount = null - ) { - parent::__construct( - $orderId, - $orderDetailRefunds, - $restockRefundedProducts, - $generateCreditSlip, - $generateVoucher, - $voucherRefundType, - $voucherRefundAmount - ); - try { - $this->shippingCostRefundAmount = new Number($shippingCostRefundAmount); - } catch (InvalidArgumentException $e) { - throw new InvalidAmountException(); - } - } - - /** - * @return Number - */ - public function getShippingCostRefundAmount(): Number - { - return $this->shippingCostRefundAmount; - } - - /** - * {@inheritdoc} - */ - protected function setOrderDetailRefunds(array $orderDetailRefunds) - { - $this->orderDetailRefunds = []; - foreach ($orderDetailRefunds as $orderDetailId => $detailRefund) { - $this->orderDetailRefunds[] = OrderDetailRefund::createPartialRefund( - $orderDetailId, - $detailRefund['quantity'], - $detailRefund['amount'] - ); - } - } -} diff --git a/src/Core/Domain/Order/Command/IssueReturnProductCommand.php b/src/Core/Domain/Order/Command/IssueReturnProductCommand.php deleted file mode 100644 index 2a5fbb6a..00000000 --- a/src/Core/Domain/Order/Command/IssueReturnProductCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Issues return product for given order. - */ -class IssueReturnProductCommand extends IssueStandardRefundCommand -{ - /** - * The expected format for $orderDetailRefunds is an associative array indexed - * by OrderDetail id containing one fields quantity - * - * ex: $orderDetailRefunds = [ - * {orderId} => [ - * 'quantity' => 2, - * ], - * ]; - * - * @param int $orderId - * @param array $orderDetailRefunds - * @param bool $restockRefundedProducts - * @param bool $refundShippingCost - * @param bool $generateCreditSlip - * @param bool $generateVoucher - * @param int $voucherRefundType - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - public function __construct( - int $orderId, - array $orderDetailRefunds, - bool $restockRefundedProducts, - bool $refundShippingCost, - bool $generateCreditSlip, - bool $generateVoucher, - int $voucherRefundType - ) { - parent::__construct( - $orderId, - $orderDetailRefunds, - $refundShippingCost, - $generateCreditSlip, - $generateVoucher, - $voucherRefundType - ); - $this->restockRefundedProducts = $restockRefundedProducts; - } -} diff --git a/src/Core/Domain/Order/Command/IssueStandardRefundCommand.php b/src/Core/Domain/Order/Command/IssueStandardRefundCommand.php deleted file mode 100644 index 3466b278..00000000 --- a/src/Core/Domain/Order/Command/IssueStandardRefundCommand.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderDetailRefund; - -/** - * Issues standard refund for given order. - */ -class IssueStandardRefundCommand extends AbstractRefundCommand -{ - /** - * @var bool - */ - protected $refundShippingCost; - - /** - * The expected format for $orderDetailRefunds is an associative array indexed - * by OrderDetail id containing one fields quantity - * - * ex: $orderDetailRefunds = [ - * {orderId} => [ - * 'quantity' => 2, - * ], - * ]; - * - * @param int $orderId - * @param array $orderDetailRefunds - * @param bool $refundShippingCost - * @param bool $generateCreditSlip - * @param bool $generateVoucher - * @param int $voucherRefundType - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - public function __construct( - int $orderId, - array $orderDetailRefunds, - bool $refundShippingCost, - bool $generateCreditSlip, - bool $generateVoucher, - int $voucherRefundType - ) { - parent::__construct( - $orderId, - $orderDetailRefunds, - true, - $generateCreditSlip, - $generateVoucher, - $voucherRefundType - ); - $this->refundShippingCost = $refundShippingCost; - } - - /** - * @return bool - */ - public function refundShippingCost(): bool - { - return $this->refundShippingCost; - } - - /** - * {@inheritdoc} - */ - protected function setOrderDetailRefunds(array $orderDetailRefunds) - { - $this->orderDetailRefunds = []; - foreach ($orderDetailRefunds as $orderDetailId => $detailRefund) { - $this->orderDetailRefunds[] = OrderDetailRefund::createStandardRefund( - $orderDetailId, - $detailRefund['quantity'] - ); - } - } -} diff --git a/src/Core/Domain/Order/Command/ResendOrderEmailCommand.php b/src/Core/Domain/Order/Command/ResendOrderEmailCommand.php deleted file mode 100644 index beb9aa5a..00000000 --- a/src/Core/Domain/Order/Command/ResendOrderEmailCommand.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -class ResendOrderEmailCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $orderStatusId; - - /** - * @var int - */ - private $orderHistoryId; - - public function __construct(int $orderId, int $orderStatusId, int $orderHistoryId) - { - $this->orderId = new OrderId($orderId); - $this->orderStatusId = $orderStatusId; - $this->orderHistoryId = $orderHistoryId; - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return int - */ - public function getOrderStatusId(): int - { - return $this->orderStatusId; - } - - /** - * @return int - */ - public function getOrderHistoryId(): int - { - return $this->orderHistoryId; - } -} diff --git a/src/Core/Domain/Order/Command/SendProcessOrderEmailCommand.php b/src/Core/Domain/Order/Command/SendProcessOrderEmailCommand.php deleted file mode 100644 index 4eda32fa..00000000 --- a/src/Core/Domain/Order/Command/SendProcessOrderEmailCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; - -/** - * Sends email to customer with link for processing the order from cart - */ -class SendProcessOrderEmailCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @param int $cartId - * - * @throws CartConstraintException - */ - public function __construct(int $cartId) - { - $this->cartId = new CartId($cartId); - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } -} diff --git a/src/Core/Domain/Order/Command/UpdateOrderShippingDetailsCommand.php b/src/Core/Domain/Order/Command/UpdateOrderShippingDetailsCommand.php deleted file mode 100644 index 4d1c2308..00000000 --- a/src/Core/Domain/Order/Command/UpdateOrderShippingDetailsCommand.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Updates shipping details for given order. - */ -class UpdateOrderShippingDetailsCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $newCarrierId; - - /** - * @var string|null - */ - private $trackingNumber; - - /** - * @var int - */ - private $currentOrderCarrierId; - - /** - * @param int $orderId - * @param int $currentOrderCarrierId - * @param int $newCarrierId - * @param string $trackingNumber - */ - public function __construct(int $orderId, int $currentOrderCarrierId, int $newCarrierId, ?string $trackingNumber = '') - { - $this->orderId = new OrderId($orderId); - $this->newCarrierId = $newCarrierId; - $this->trackingNumber = $trackingNumber; - $this->currentOrderCarrierId = $currentOrderCarrierId; - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return int - */ - public function getNewCarrierId(): int - { - return $this->newCarrierId; - } - - /** - * @return string|null - */ - public function getShippingTrackingNumber(): ?string - { - return $this->trackingNumber; - } - - /** - * @return int - */ - public function getCurrentOrderCarrierId(): int - { - return $this->currentOrderCarrierId; - } -} diff --git a/src/Core/Domain/Order/Command/UpdateOrderStatusCommand.php b/src/Core/Domain/Order/Command/UpdateOrderStatusCommand.php deleted file mode 100644 index 9d5884a8..00000000 --- a/src/Core/Domain/Order/Command/UpdateOrderStatusCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Updates order status. - */ -class UpdateOrderStatusCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $newOrderStatusId; - - /** - * @param int $orderId - * @param int $newOrderStatusId - */ - public function __construct($orderId, $newOrderStatusId) - { - $this->orderId = new OrderId($orderId); - $this->newOrderStatusId = $newOrderStatusId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return int - */ - public function getNewOrderStatusId() - { - return $this->newOrderStatusId; - } -} diff --git a/src/Core/Domain/Order/CommandHandler/AddCartRuleToOrderHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/AddCartRuleToOrderHandlerInterface.php deleted file mode 100644 index a1e2471c..00000000 --- a/src/Core/Domain/Order/CommandHandler/AddCartRuleToOrderHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\AddCartRuleToOrderCommand; - -/** - * @internal - */ -interface AddCartRuleToOrderHandlerInterface -{ - /** - * @param AddCartRuleToOrderCommand $command - */ - public function handle(AddCartRuleToOrderCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/AddOrderFromBackOfficeHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/AddOrderFromBackOfficeHandlerInterface.php deleted file mode 100644 index 2dca94a5..00000000 --- a/src/Core/Domain/Order/CommandHandler/AddOrderFromBackOfficeHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\AddOrderFromBackOfficeCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Interface for service that adds new order. - */ -interface AddOrderFromBackOfficeHandlerInterface -{ - /** - * @param AddOrderFromBackOfficeCommand $command - * - * @return OrderId - */ - public function handle(AddOrderFromBackOfficeCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/BulkChangeOrderStatusHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/BulkChangeOrderStatusHandlerInterface.php deleted file mode 100644 index cb60689c..00000000 --- a/src/Core/Domain/Order/CommandHandler/BulkChangeOrderStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\BulkChangeOrderStatusCommand; - -/** - * Interface for service that handles changing orders status - */ -interface BulkChangeOrderStatusHandlerInterface -{ - /** - * @param BulkChangeOrderStatusCommand $command - */ - public function handle(BulkChangeOrderStatusCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/CancelOrderProductHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/CancelOrderProductHandlerInterface.php deleted file mode 100644 index adb4ca72..00000000 --- a/src/Core/Domain/Order/CommandHandler/CancelOrderProductHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\CancelOrderProductCommand; - -/** - * Interface for service that handles issuing cancel product for given order - */ -interface CancelOrderProductHandlerInterface -{ - /** - * @param CancelOrderProductCommand $command - */ - public function handle(CancelOrderProductCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/ChangeOrderCurrencyHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/ChangeOrderCurrencyHandlerInterface.php deleted file mode 100644 index 7c716ddf..00000000 --- a/src/Core/Domain/Order/CommandHandler/ChangeOrderCurrencyHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderCurrencyCommand; - -/** - * Interface for service that handles changing order currency. - */ -interface ChangeOrderCurrencyHandlerInterface -{ - /** - * @param ChangeOrderCurrencyCommand $command - */ - public function handle(ChangeOrderCurrencyCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/ChangeOrderDeliveryAddressHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/ChangeOrderDeliveryAddressHandlerInterface.php deleted file mode 100644 index 4f4338ef..00000000 --- a/src/Core/Domain/Order/CommandHandler/ChangeOrderDeliveryAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderDeliveryAddressCommand; - -/** - * Interface for service that handles changing order delivery address. - */ -interface ChangeOrderDeliveryAddressHandlerInterface -{ - /** - * @param ChangeOrderDeliveryAddressCommand $command - */ - public function handle(ChangeOrderDeliveryAddressCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/ChangeOrderInvoiceAddressHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/ChangeOrderInvoiceAddressHandlerInterface.php deleted file mode 100644 index fd5123cd..00000000 --- a/src/Core/Domain/Order/CommandHandler/ChangeOrderInvoiceAddressHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderInvoiceAddressCommand; - -/** - * Interface for service that handles changing order invoice address. - */ -interface ChangeOrderInvoiceAddressHandlerInterface -{ - /** - * @param ChangeOrderInvoiceAddressCommand $command - */ - public function handle(ChangeOrderInvoiceAddressCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/DeleteCartRuleFromOrderHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/DeleteCartRuleFromOrderHandlerInterface.php deleted file mode 100644 index b6e4421f..00000000 --- a/src/Core/Domain/Order/CommandHandler/DeleteCartRuleFromOrderHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\DeleteCartRuleFromOrderCommand; - -/** - * Interface for service that handles removing cart rule from given order. - */ -interface DeleteCartRuleFromOrderHandlerInterface -{ - /** - * @param DeleteCartRuleFromOrderCommand $command - */ - public function handle(DeleteCartRuleFromOrderCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/DuplicateOrderCartHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/DuplicateOrderCartHandlerInterface.php deleted file mode 100644 index 4ed84cae..00000000 --- a/src/Core/Domain/Order/CommandHandler/DuplicateOrderCartHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\DuplicateOrderCartCommand; - -/** - * Interface for service that handles duplicating order cart - */ -interface DuplicateOrderCartHandlerInterface -{ - /** - * @param DuplicateOrderCartCommand $command - * - * @return CartId Duplicated cart id - */ - public function handle(DuplicateOrderCartCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/IssuePartialRefundHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/IssuePartialRefundHandlerInterface.php deleted file mode 100644 index 5e75b5bc..00000000 --- a/src/Core/Domain/Order/CommandHandler/IssuePartialRefundHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssuePartialRefundCommand; - -/** - * Interface for service that handles issuing partial refund for given order - */ -interface IssuePartialRefundHandlerInterface -{ - /** - * @param IssuePartialRefundCommand $command - */ - public function handle(IssuePartialRefundCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/IssueReturnProductHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/IssueReturnProductHandlerInterface.php deleted file mode 100644 index 8e4a4d49..00000000 --- a/src/Core/Domain/Order/CommandHandler/IssueReturnProductHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueReturnProductCommand; - -/** - * Interface for service that handles issuing return product for given order - */ -interface IssueReturnProductHandlerInterface -{ - /** - * @param IssueReturnProductCommand $command - */ - public function handle(IssueReturnProductCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/IssueStandardRefundHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/IssueStandardRefundHandlerInterface.php deleted file mode 100644 index 20def040..00000000 --- a/src/Core/Domain/Order/CommandHandler/IssueStandardRefundHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueStandardRefundCommand; - -/** - * Interface for service that handles issuing standard refund for given order - */ -interface IssueStandardRefundHandlerInterface -{ - /** - * @param IssueStandardRefundCommand $command - */ - public function handle(IssueStandardRefundCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/ResendOrderEmailHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/ResendOrderEmailHandlerInterface.php deleted file mode 100644 index 47913e9d..00000000 --- a/src/Core/Domain/Order/CommandHandler/ResendOrderEmailHandlerInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\ResendOrderEmailCommand; - -interface ResendOrderEmailHandlerInterface -{ - /** - * @param ResendOrderEmailCommand $command - */ - public function handle(ResendOrderEmailCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/SendProcessOrderEmailHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/SendProcessOrderEmailHandlerInterface.php deleted file mode 100644 index ab200f8a..00000000 --- a/src/Core/Domain/Order/CommandHandler/SendProcessOrderEmailHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\SendProcessOrderEmailCommand; - -/** - * Interface for handling SendProcessOrderEmail command - */ -interface SendProcessOrderEmailHandlerInterface -{ - /** - * @param SendProcessOrderEmailCommand $command - */ - public function handle(SendProcessOrderEmailCommand $command): void; -} diff --git a/src/Core/Domain/Order/CommandHandler/UpdateOrderShippingDetailsHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/UpdateOrderShippingDetailsHandlerInterface.php deleted file mode 100644 index 21e22af0..00000000 --- a/src/Core/Domain/Order/CommandHandler/UpdateOrderShippingDetailsHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderShippingDetailsCommand; - -/** - * Interface for service that handling updating shipping details for given order. - */ -interface UpdateOrderShippingDetailsHandlerInterface -{ - /** - * @param UpdateOrderShippingDetailsCommand $command - */ - public function handle(UpdateOrderShippingDetailsCommand $command); -} diff --git a/src/Core/Domain/Order/CommandHandler/UpdateOrderStatusHandlerInterface.php b/src/Core/Domain/Order/CommandHandler/UpdateOrderStatusHandlerInterface.php deleted file mode 100644 index d4272ac5..00000000 --- a/src/Core/Domain/Order/CommandHandler/UpdateOrderStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderStatusCommand; - -/** - * Interface for service that handles updating order status. - */ -interface UpdateOrderStatusHandlerInterface -{ - /** - * @param UpdateOrderStatusCommand $command - */ - public function handle(UpdateOrderStatusCommand $command); -} diff --git a/src/Core/Domain/Order/Exception/CancelProductFromOrderException.php b/src/Core/Domain/Order/Exception/CancelProductFromOrderException.php deleted file mode 100644 index 55516b6a..00000000 --- a/src/Core/Domain/Order/Exception/CancelProductFromOrderException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when something went wrong during a product cancel action. - */ -class CancelProductFromOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/CannotEditDeliveredOrderProductException.php b/src/Core/Domain/Order/Exception/CannotEditDeliveredOrderProductException.php deleted file mode 100644 index 77405dc4..00000000 --- a/src/Core/Domain/Order/Exception/CannotEditDeliveredOrderProductException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -class CannotEditDeliveredOrderProductException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/CannotFindProductInOrderException.php b/src/Core/Domain/Order/Exception/CannotFindProductInOrderException.php deleted file mode 100644 index 66e97d21..00000000 --- a/src/Core/Domain/Order/Exception/CannotFindProductInOrderException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown on failure to update product in an order - */ -class CannotFindProductInOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/CannotUpdateOrderException.php b/src/Core/Domain/Order/Exception/CannotUpdateOrderException.php deleted file mode 100644 index 0b987f3e..00000000 --- a/src/Core/Domain/Order/Exception/CannotUpdateOrderException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown on failure to update order - */ -class CannotUpdateOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/ChangeOrderStatusException.php b/src/Core/Domain/Order/Exception/ChangeOrderStatusException.php deleted file mode 100644 index 433aa7b7..00000000 --- a/src/Core/Domain/Order/Exception/ChangeOrderStatusException.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Throw when failed changing order status - */ -class ChangeOrderStatusException extends OrderException -{ - /** - * @var OrderId[] - */ - private $ordersWithFailedToUpdateStatus; - - /** - * @var OrderId[] - */ - private $ordersWithFailedToSendEmail; - - /** - * @var OrderId[] - */ - private $ordersWithAssignedStatus; - - /** - * @param OrderId[] $ordersWithFailedToUpdateStatus - * @param OrderId[] $ordersWithFailedToSendEmail - * @param OrderId[] $ordersWithAssignedStatus - * @param string $message - * @param int $code - * @param \Exception|null $previous - */ - public function __construct( - array $ordersWithFailedToUpdateStatus, - array $ordersWithFailedToSendEmail, - array $ordersWithAssignedStatus, - $message = '', - $code = 0, - $previous = null - ) { - $this->ordersWithFailedToUpdateStatus = $ordersWithFailedToUpdateStatus; - $this->ordersWithFailedToSendEmail = $ordersWithFailedToSendEmail; - $this->ordersWithAssignedStatus = $ordersWithAssignedStatus; - - parent::__construct($message, $code, $previous); - } - - /** - * @return OrderId[] - */ - public function getOrdersWithFailedToUpdateStatus() - { - return $this->ordersWithFailedToUpdateStatus; - } - - /** - * @return OrderId[] - */ - public function getOrdersWithFailedToSendEmail() - { - return $this->ordersWithFailedToSendEmail; - } - - /** - * @return OrderId[] - */ - public function getOrdersWithAssignedStatus() - { - return $this->ordersWithAssignedStatus; - } -} diff --git a/src/Core/Domain/Order/Exception/DeleteCustomizedProductFromOrderException.php b/src/Core/Domain/Order/Exception/DeleteCustomizedProductFromOrderException.php deleted file mode 100644 index 69f7a788..00000000 --- a/src/Core/Domain/Order/Exception/DeleteCustomizedProductFromOrderException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when something went wrong while deleting a customized product from an order. - */ -class DeleteCustomizedProductFromOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/DeleteProductFromOrderException.php b/src/Core/Domain/Order/Exception/DeleteProductFromOrderException.php deleted file mode 100644 index 89f21604..00000000 --- a/src/Core/Domain/Order/Exception/DeleteProductFromOrderException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when something went wrong while deleting a product from an order. - */ -class DeleteProductFromOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/DuplicateOrderCartException.php b/src/Core/Domain/Order/Exception/DuplicateOrderCartException.php deleted file mode 100644 index 121d0410..00000000 --- a/src/Core/Domain/Order/Exception/DuplicateOrderCartException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Is thrown when duplicating order cart fails - */ -class DuplicateOrderCartException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/DuplicateProductInOrderException.php b/src/Core/Domain/Order/Exception/DuplicateProductInOrderException.php deleted file mode 100644 index 2175a174..00000000 --- a/src/Core/Domain/Order/Exception/DuplicateProductInOrderException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -class DuplicateProductInOrderException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/DuplicateProductInOrderInvoiceException.php b/src/Core/Domain/Order/Exception/DuplicateProductInOrderInvoiceException.php deleted file mode 100644 index bb8d13bb..00000000 --- a/src/Core/Domain/Order/Exception/DuplicateProductInOrderInvoiceException.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use Throwable; - -/** - * Class DuplicateProductInOrderInvoiceException thrown when we try to add a product in an order invoice that already contains it - */ -class DuplicateProductInOrderInvoiceException extends DuplicateProductInOrderException -{ - /** - * @var string - */ - private $orderInvoiceNumber; - - /** - * @param string $orderInvoiceId - * @param string $message - * @param int $code - * @param Throwable|null $previous - */ - public function __construct(string $orderInvoiceId, $message = '', $code = 0, Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - $this->orderInvoiceNumber = $orderInvoiceId; - } - - /** - * @return string - */ - public function getOrderInvoiceNumber(): string - { - return $this->orderInvoiceNumber; - } -} diff --git a/src/Core/Domain/Order/Exception/InvalidAddressTypeException.php b/src/Core/Domain/Order/Exception/InvalidAddressTypeException.php deleted file mode 100644 index 2a58f751..00000000 --- a/src/Core/Domain/Order/Exception/InvalidAddressTypeException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Class InvalidAddressTypeException - */ -class InvalidAddressTypeException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/InvalidAmountException.php b/src/Core/Domain/Order/Exception/InvalidAmountException.php deleted file mode 100644 index 6eada34f..00000000 --- a/src/Core/Domain/Order/Exception/InvalidAmountException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when the amount format is not valid - */ -class InvalidAmountException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/InvalidCancelProductException.php b/src/Core/Domain/Order/Exception/InvalidCancelProductException.php deleted file mode 100644 index 41260f88..00000000 --- a/src/Core/Domain/Order/Exception/InvalidCancelProductException.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use Throwable; - -/** - * Throw new when a partial refund's is asked without a specified quantity - */ -class InvalidCancelProductException extends OrderException -{ - /** - * @var int - */ - private $refundableQuantity; - - /** - * Used when the quantity refunded is not strictly positive - */ - const INVALID_QUANTITY = 1; - - /** - * Used when the quantity refunded is higher than the remaining quantity - */ - const QUANTITY_TOO_HIGH = 2; - - /** - * Used when the amount refunded is not strictly positive - */ - const INVALID_AMOUNT = 3; - - /** - * Used when no refund details have been supplied (nor products nor shipping refund) - */ - const NO_REFUNDS = 4; - - /** - * Used when no generation is set (no credit slip and no voucher generation) - */ - const NO_GENERATION = 5; - - /** - * @param int $code - * @param int $refundableQuantity - * @param string $message - * @param Throwable|null $previous - */ - public function __construct($code = 0, int $refundableQuantity = 0, $message = '', Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - $this->refundableQuantity = $refundableQuantity; - } - - /** - * @return int - */ - public function getRefundableQuantity(): int - { - return $this->refundableQuantity; - } -} diff --git a/src/Core/Domain/Order/Exception/InvalidOrderStateException.php b/src/Core/Domain/Order/Exception/InvalidOrderStateException.php deleted file mode 100644 index 9a242095..00000000 --- a/src/Core/Domain/Order/Exception/InvalidOrderStateException.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown when the order state is incompatible with an action (ex: standard - * refund on an order not paid yet). - */ -class InvalidOrderStateException extends OrderException -{ - /** - * Used when the order is not paid (and it should be) - */ - const NOT_PAID = 1; - - /** - * Used when the order is already paid (and it should not be) - */ - const ALREADY_PAID = 2; - - /** - * Used when the order has not been delivered (and it should have) - */ - const DELIVERY_NOT_FOUND = 3; - - /** - * Used when the order has been delivered (and it shouldn't have) - */ - const UNEXPECTED_DELIVERY = 4; - /** - * Used when the order state is not found - */ - const INVALID_ID = 5; - - /** - * @param int $code - * @param string $message - * @param Throwable|null $previous - */ - public function __construct($code = 0, $message = '', Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - } -} diff --git a/src/Core/Domain/Order/Exception/InvalidProductQuantityException.php b/src/Core/Domain/Order/Exception/InvalidProductQuantityException.php deleted file mode 100644 index 63fea178..00000000 --- a/src/Core/Domain/Order/Exception/InvalidProductQuantityException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown when trying to add an invalid quantity or a product (<= 0) - */ -class InvalidProductQuantityException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/InvalidRefundException.php b/src/Core/Domain/Order/Exception/InvalidRefundException.php deleted file mode 100644 index 65cdc3e3..00000000 --- a/src/Core/Domain/Order/Exception/InvalidRefundException.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use Throwable; - -/** - * Throw new when a partial refund's is asked without a specified quantity - */ -class InvalidRefundException extends OrderException -{ - /** - * @var int - */ - private $refundableQuantity; - - /** - * Used when the quantity refunded is not strictly positive - */ - const INVALID_QUANTITY = 1; - - /** - * Used when the quantity refunded is higher than the remaining quantity - */ - const QUANTITY_TOO_HIGH = 2; - - /** - * Used when the amount refunded is not strictly positive - */ - const INVALID_AMOUNT = 3; - - /** - * Used when no refund details have been supplied (nor products nor shipping refund) - */ - const NO_REFUNDS = 4; - - /** - * Used when no generation is set (no credit slip and no voucher generation) - */ - const NO_GENERATION = 5; - - /** - * @param int $code - * @param int $refundableQuantity - * @param string $message - * @param Throwable|null $previous - */ - public function __construct($code = 0, int $refundableQuantity = 0, $message = '', Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - $this->refundableQuantity = $refundableQuantity; - } - - /** - * @return int - */ - public function getRefundableQuantity(): int - { - return $this->refundableQuantity; - } -} diff --git a/src/Core/Domain/Order/Exception/NegativePaymentAmountException.php b/src/Core/Domain/Order/Exception/NegativePaymentAmountException.php deleted file mode 100644 index ed8f7f2b..00000000 --- a/src/Core/Domain/Order/Exception/NegativePaymentAmountException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when the payment amount is negative - */ -class NegativePaymentAmountException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/OrderConstraintException.php b/src/Core/Domain/Order/Exception/OrderConstraintException.php deleted file mode 100644 index a42149e6..00000000 --- a/src/Core/Domain/Order/Exception/OrderConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Exception thrown when constraint is violated in Order subdomain. - */ -class OrderConstraintException extends OrderException -{ - /** - * Used in create order from BO when the customer message is invalid. - */ - const INVALID_CUSTOMER_MESSAGE = 1; -} diff --git a/src/Core/Domain/Order/Exception/OrderEmailSendException.php b/src/Core/Domain/Order/Exception/OrderEmailSendException.php deleted file mode 100644 index 7f5da81d..00000000 --- a/src/Core/Domain/Order/Exception/OrderEmailSendException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown when failed to send email associated with order - */ -class OrderEmailSendException extends OrderException -{ - /** - * When order email resending failed - */ - const FAILED_RESEND = 1; - - /** - * When order process email sending failed - */ - const FAILED_SEND_PROCESS_ORDER = 2; -} diff --git a/src/Core/Domain/Order/Exception/OrderException.php b/src/Core/Domain/Order/Exception/OrderException.php deleted file mode 100644 index 1c9a7b5b..00000000 --- a/src/Core/Domain/Order/Exception/OrderException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Is base exception for Order subdomain - */ -class OrderException extends DomainException -{ -} diff --git a/src/Core/Domain/Order/Exception/OrderNotFoundException.php b/src/Core/Domain/Order/Exception/OrderNotFoundException.php deleted file mode 100644 index ae654799..00000000 --- a/src/Core/Domain/Order/Exception/OrderNotFoundException.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Thrown when order is not found - */ -class OrderNotFoundException extends OrderException -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @param OrderId $orderId - * @param string $message - * @param int $code - * @param Exception|null $previous - */ - public function __construct(OrderId $orderId, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->orderId = $orderId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } -} diff --git a/src/Core/Domain/Order/Exception/ReturnProductDisabledException.php b/src/Core/Domain/Order/Exception/ReturnProductDisabledException.php deleted file mode 100644 index af66bded..00000000 --- a/src/Core/Domain/Order/Exception/ReturnProductDisabledException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown when trying to perform a return product operation while it is disabled - */ -class ReturnProductDisabledException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Exception/TransistEmailSendingException.php b/src/Core/Domain/Order/Exception/TransistEmailSendingException.php deleted file mode 100644 index d447c2fd..00000000 --- a/src/Core/Domain/Order/Exception/TransistEmailSendingException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Exception; - -/** - * Thrown when when failed to send email to customer regarding order tracking - */ -class TransistEmailSendingException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Invoice/Command/GenerateInvoiceCommand.php b/src/Core/Domain/Order/Invoice/Command/GenerateInvoiceCommand.php deleted file mode 100644 index df47984b..00000000 --- a/src/Core/Domain/Order/Invoice/Command/GenerateInvoiceCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Generates invoice for given order. - */ -class GenerateInvoiceCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @param int $orderId - */ - public function __construct($orderId) - { - $this->orderId = new OrderId($orderId); - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } -} diff --git a/src/Core/Domain/Order/Invoice/Command/UpdateInvoiceNoteCommand.php b/src/Core/Domain/Order/Invoice/Command/UpdateInvoiceNoteCommand.php deleted file mode 100644 index 4a42b22a..00000000 --- a/src/Core/Domain/Order/Invoice/Command/UpdateInvoiceNoteCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\ValueObject\OrderInvoiceId; - -/** - * Adds note for given invoice. - */ -class UpdateInvoiceNoteCommand -{ - /** - * @var OrderInvoiceId - */ - private $orderInvoiceId; - - /** - * @var string|null - */ - private $note; - - /** - * @param int $orderInvoiceId - * @param string|null $note - */ - public function __construct(int $orderInvoiceId, ?string $note) - { - $this->orderInvoiceId = new OrderInvoiceId($orderInvoiceId); - $this->note = $note; - } - - /** - * @return OrderInvoiceId - */ - public function getOrderInvoiceId(): OrderInvoiceId - { - return $this->orderInvoiceId; - } - - /** - * @return string|null - */ - public function getNote(): ?string - { - return $this->note; - } -} diff --git a/src/Core/Domain/Order/Invoice/CommandHandler/GenerateOrderInvoiceHandlerInterface.php b/src/Core/Domain/Order/Invoice/CommandHandler/GenerateOrderInvoiceHandlerInterface.php deleted file mode 100644 index f10b94ab..00000000 --- a/src/Core/Domain/Order/Invoice/CommandHandler/GenerateOrderInvoiceHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\GenerateInvoiceCommand; - -/** - * Interface for service that handles generating invoice for order. - */ -interface GenerateOrderInvoiceHandlerInterface -{ - /** - * @param GenerateInvoiceCommand $command - */ - public function handle(GenerateInvoiceCommand $command); -} diff --git a/src/Core/Domain/Order/Invoice/CommandHandler/UpdateInvoiceNoteHandlerInterface.php b/src/Core/Domain/Order/Invoice/CommandHandler/UpdateInvoiceNoteHandlerInterface.php deleted file mode 100644 index 805da0ad..00000000 --- a/src/Core/Domain/Order/Invoice/CommandHandler/UpdateInvoiceNoteHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\UpdateInvoiceNoteCommand; - -/** - * Interface for service that handles updating invoice note - */ -interface UpdateInvoiceNoteHandlerInterface -{ - /** - * @param UpdateInvoiceNoteCommand $command - */ - public function handle(UpdateInvoiceNoteCommand $command): void; -} diff --git a/src/Core/Domain/Order/Invoice/Exception/InvoiceException.php b/src/Core/Domain/Order/Invoice/Exception/InvoiceException.php deleted file mode 100644 index 793e6a2c..00000000 --- a/src/Core/Domain/Order/Invoice/Exception/InvoiceException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Base exception for Invoice subdomain - */ -class InvoiceException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Invoice/Exception/InvoiceNotFoundException.php b/src/Core/Domain/Order/Invoice/Exception/InvoiceNotFoundException.php deleted file mode 100644 index 541b6f6f..00000000 --- a/src/Core/Domain/Order/Invoice/Exception/InvoiceNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Exception; - -/** - * Thrown when order invoice is not found - */ -class InvoiceNotFoundException extends InvoiceException -{ -} diff --git a/src/Core/Domain/Order/Invoice/ValueObject/OrderInvoiceId.php b/src/Core/Domain/Order/Invoice/ValueObject/OrderInvoiceId.php deleted file mode 100644 index fcfe8dd8..00000000 --- a/src/Core/Domain/Order/Invoice/ValueObject/OrderInvoiceId.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Invoice\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Exception\InvoiceException; - -/** - * Order invoice identity - */ -class OrderInvoiceId -{ - /** - * @var int - */ - private $orderInvoiceId; - - /** - * @param int $orderInvoiceId - */ - public function __construct($orderInvoiceId) - { - if (!is_int($orderInvoiceId) || 0 >= $orderInvoiceId) { - throw new InvoiceException('Invalid order invoice id supplied.'); - } - - $this->orderInvoiceId = $orderInvoiceId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->orderInvoiceId; - } -} diff --git a/src/Core/Domain/Order/OrderAddressType.php b/src/Core/Domain/Order/OrderAddressType.php deleted file mode 100644 index 02532159..00000000 --- a/src/Core/Domain/Order/OrderAddressType.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -/** - * Used to identity which type of address has to be edited - */ -class OrderAddressType -{ - const DELIVERY_ADDRESS_TYPE = 'delivery_address'; - - const INVOICE_ADDRESS_TYPE = 'invoice_address'; -} diff --git a/src/Core/Domain/Order/OrderConstraints.php b/src/Core/Domain/Order/OrderConstraints.php deleted file mode 100644 index 15dd0eb1..00000000 --- a/src/Core/Domain/Order/OrderConstraints.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -class OrderConstraints -{ - /** - * Number of products that are displayed in order preview - */ - public const PRODUCTS_PREVIEW_LIMIT = 10; -} diff --git a/src/Core/Domain/Order/OrderDiscountType.php b/src/Core/Domain/Order/OrderDiscountType.php deleted file mode 100644 index 9454ca0b..00000000 --- a/src/Core/Domain/Order/OrderDiscountType.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -/** - * Discount types that can be added to an order - */ -final class OrderDiscountType -{ - /** - * Discount type with percent (%) amount - */ - public const DISCOUNT_PERCENT = 'percent'; - - /** - * Discount type with money (EUR, USD & etc) amount - */ - public const DISCOUNT_AMOUNT = 'amount'; - - /** - * Discount type with free shipping - */ - public const FREE_SHIPPING = 'free_shipping'; -} diff --git a/src/Core/Domain/Order/OrderDocumentType.php b/src/Core/Domain/Order/OrderDocumentType.php deleted file mode 100644 index fc81aada..00000000 --- a/src/Core/Domain/Order/OrderDocumentType.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -/** - * Used to identity which type of document the orders has - */ -class OrderDocumentType -{ - const CREDIT_SLIP = 'credit_slip'; - - const DELIVERY_SLIP = 'delivery_slip'; - - const INVOICE = 'invoice'; -} diff --git a/src/Core/Domain/Order/Payment/Command/AddPaymentCommand.php b/src/Core/Domain/Order/Payment/Command/AddPaymentCommand.php deleted file mode 100644 index a5591162..00000000 --- a/src/Core/Domain/Order/Payment/Command/AddPaymentCommand.php +++ /dev/null @@ -1,176 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Payment\Command; - -use DateTimeImmutable; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\NegativePaymentAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Adds payment for given order. - */ -class AddPaymentCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var DateTimeImmutable - */ - private $paymentDate; - - /** - * @var string - */ - private $paymentMethod; - - /** - * @var Number - */ - private $paymentAmount; - - /** - * @var CurrencyId - */ - private $paymentCurrencyId; - - /** - * @var string|null - */ - private $transactionId; - - /** - * @var null - */ - private $orderInvoiceId; - - /** - * @param int $orderId - * @param string $paymentDate - * @param string $paymentMethod - * @param string $paymentAmount - * @param int $paymentCurrencyId - * @param int|null $orderInvoiceId - * @param string|null $transactionId transaction ID, usually payment ID from payment gateway - */ - public function __construct( - int $orderId, - string $paymentDate, - string $paymentMethod, - string $paymentAmount, - int $paymentCurrencyId, - ?int $orderInvoiceId = null, - ?string $transactionId = null - ) { - $amount = new Number($paymentAmount); - $this->assertAmountIsPositive($amount); - $this->assertPaymentMethodIsGenericName($paymentMethod); - - $this->orderId = new OrderId($orderId); - $this->paymentDate = new DateTimeImmutable($paymentDate); - $this->paymentMethod = $paymentMethod; - $this->paymentAmount = $amount; - $this->paymentCurrencyId = new CurrencyId($paymentCurrencyId); - $this->orderInvoiceId = $orderInvoiceId; - $this->transactionId = $transactionId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return DateTimeImmutable - */ - public function getPaymentDate() - { - return $this->paymentDate; - } - - /** - * @return string - */ - public function getPaymentMethod() - { - return $this->paymentMethod; - } - - /** - * @return Number - */ - public function getPaymentAmount() - { - return $this->paymentAmount; - } - - /** - * @return CurrencyId - */ - public function getPaymentCurrencyId() - { - return $this->paymentCurrencyId; - } - - public function getOrderInvoiceId() - { - return $this->orderInvoiceId; - } - - /** - * @return string|null - */ - public function getPaymentTransactionId() - { - return $this->transactionId; - } - - /** - * @param string $paymentMethod - */ - private function assertPaymentMethodIsGenericName($paymentMethod) - { - if (empty($paymentMethod) || !preg_match('/^[^<>={}]*$/u', $paymentMethod)) { - throw new OrderConstraintException('The selected payment method is invalid.'); - } - } - - private function assertAmountIsPositive(Number $amount) - { - if ($amount->isNegative()) { - throw new NegativePaymentAmountException('The amount should be greater than 0.'); - } - } -} diff --git a/src/Core/Domain/Order/Payment/CommandHandler/AddPaymentHandlerInterface.php b/src/Core/Domain/Order/Payment/CommandHandler/AddPaymentHandlerInterface.php deleted file mode 100644 index 3f6a35af..00000000 --- a/src/Core/Domain/Order/Payment/CommandHandler/AddPaymentHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Payment\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Payment\Command\AddPaymentCommand; - -/** - * Interface for service that handles adding payment for order. - */ -interface AddPaymentHandlerInterface -{ - /** - * @param AddPaymentCommand $command - */ - public function handle(AddPaymentCommand $command); -} diff --git a/src/Core/Domain/Order/Payment/Exception/PaymentException.php b/src/Core/Domain/Order/Payment/Exception/PaymentException.php deleted file mode 100644 index 36e187ef..00000000 --- a/src/Core/Domain/Order/Payment/Exception/PaymentException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Payment\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Is base exception for Payment subdomain - */ -class PaymentException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Payment/ValueObject/OrderPaymentId.php b/src/Core/Domain/Order/Payment/ValueObject/OrderPaymentId.php deleted file mode 100644 index 28c717da..00000000 --- a/src/Core/Domain/Order/Payment/ValueObject/OrderPaymentId.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Payment\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Order\Payment\Exception\PaymentException; - -/** - * Order payment identity - */ -class OrderPaymentId -{ - /** - * @var int - */ - private $orderPaymentId; - - /** - * @param int $orderPaymentId - */ - public function __construct($orderPaymentId) - { - if (!is_int($orderPaymentId) || 0 >= $orderPaymentId) { - throw new PaymentException('Invalid order payment id supplied.'); - } - - $this->orderPaymentId = $orderPaymentId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->orderPaymentId; - } -} diff --git a/src/Core/Domain/Order/Product/Command/AddProductToOrderCommand.php b/src/Core/Domain/Order/Product/Command/AddProductToOrderCommand.php deleted file mode 100644 index a89ae9fd..00000000 --- a/src/Core/Domain/Order/Product/Command/AddProductToOrderCommand.php +++ /dev/null @@ -1,271 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\Command; - -use InvalidArgumentException; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidProductQuantityException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Domain\Product\Combination\ValueObject\CombinationId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Adds product to an existing order. - */ -class AddProductToOrderCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var CombinationId|null - */ - private $combinationId; - - /** - * @var Number - */ - private $productPriceTaxIncluded; - - /** - * @var Number - */ - private $productPriceTaxExcluded; - - /** - * @var int - */ - private $productQuantity; - - /** - * @var int|null invoice id or null if new invoice should be created - */ - private $orderInvoiceId; - - /** - * @var bool|null bool if product is being added using new invoice - */ - private $hasFreeShipping; - - /** - * Add product to an order with new invoice. It applies to orders that were already paid and waiting for payment. - * - * @param int $orderId - * @param int $productId - * @param int $combinationId - * @param string $productPriceTaxIncluded - * @param string $productPriceTaxExcluded - * @param int $productQuantity - * @param bool|null $hasFreeShipping - * - * @return self - * - * @throws InvalidProductQuantityException - * @throws InvalidAmountException - * @throws OrderException - */ - public static function withNewInvoice( - int $orderId, - int $productId, - int $combinationId, - string $productPriceTaxIncluded, - string $productPriceTaxExcluded, - int $productQuantity, - ?bool $hasFreeShipping = null - ) { - $command = new self( - $orderId, - $productId, - $combinationId, - $productPriceTaxIncluded, - $productPriceTaxExcluded, - $productQuantity - ); - - $command->hasFreeShipping = $hasFreeShipping; - - return $command; - } - - /** - * Add product to an order using existing invoice. It applies only for orders that were not yet paid. - * - * @param int $orderId - * @param int $orderInvoiceId - * @param int $productId - * @param int $combinationId - * @param string $productPriceTaxIncluded - * @param string $productPriceTaxExcluded - * @param int $productQuantity - * - * @return self - * - * @throws InvalidProductQuantityException - * @throws InvalidAmountException - * @throws OrderException - */ - public static function toExistingInvoice( - int $orderId, - int $orderInvoiceId, - int $productId, - int $combinationId, - string $productPriceTaxIncluded, - string $productPriceTaxExcluded, - int $productQuantity - ) { - $command = new self( - $orderId, - $productId, - $combinationId, - $productPriceTaxIncluded, - $productPriceTaxExcluded, - $productQuantity - ); - - $command->orderInvoiceId = $orderInvoiceId; - - return $command; - } - - /** - * @param int $orderId - * @param int $productId - * @param int $combinationId - * @param string $productPriceTaxIncluded - * @param string $productPriceTaxExcluded - * @param int $productQuantity - * - * @throws InvalidProductQuantityException - * @throws InvalidAmountException - * @throws OrderException - */ - private function __construct( - int $orderId, - int $productId, - int $combinationId, - string $productPriceTaxIncluded, - string $productPriceTaxExcluded, - int $productQuantity - ) { - $this->orderId = new OrderId($orderId); - $this->productId = new ProductId($productId); - $this->combinationId = !empty($combinationId) ? new CombinationId($combinationId) : null; - try { - $this->productPriceTaxIncluded = new Number($productPriceTaxIncluded); - $this->productPriceTaxExcluded = new Number($productPriceTaxExcluded); - } catch (InvalidArgumentException $e) { - throw new InvalidAmountException(); - } - $this->setProductQuantity($productQuantity); - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return CombinationId|null - */ - public function getCombinationId(): ?CombinationId - { - return $this->combinationId; - } - - /** - * @return Number - */ - public function getProductPriceTaxIncluded(): Number - { - return $this->productPriceTaxIncluded; - } - - /** - * @return Number - */ - public function getProductPriceTaxExcluded(): Number - { - return $this->productPriceTaxExcluded; - } - - /** - * @return int - */ - public function getProductQuantity(): int - { - return $this->productQuantity; - } - - /** - * @return int|null - */ - public function getOrderInvoiceId(): ?int - { - return $this->orderInvoiceId; - } - - /** - * @return bool|null - */ - public function hasFreeShipping(): ?bool - { - return $this->hasFreeShipping; - } - - /** - * @param int $productQuantity - * - * @throws InvalidProductQuantityException - */ - private function setProductQuantity(int $productQuantity): void - { - if ($productQuantity <= 0) { - throw new InvalidProductQuantityException('When adding a product quantity must be strictly positive'); - } - $this->productQuantity = $productQuantity; - } -} diff --git a/src/Core/Domain/Order/Product/Command/DeleteProductFromOrderCommand.php b/src/Core/Domain/Order/Product/Command/DeleteProductFromOrderCommand.php deleted file mode 100644 index 4a14f558..00000000 --- a/src/Core/Domain/Order/Product/Command/DeleteProductFromOrderCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\Command; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Deletes product from given order. - */ -class DeleteProductFromOrderCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $orderDetailId; - - /** - * @param int $orderId - * @param int $orderDetailId - */ - public function __construct($orderId, $orderDetailId) - { - $this->orderId = new OrderId($orderId); - $this->orderDetailId = $orderDetailId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return int - */ - public function getOrderDetailId() - { - return $this->orderDetailId; - } -} diff --git a/src/Core/Domain/Order/Product/Command/UpdateProductInOrderCommand.php b/src/Core/Domain/Order/Product/Command/UpdateProductInOrderCommand.php deleted file mode 100644 index eb573273..00000000 --- a/src/Core/Domain/Order/Product/Command/UpdateProductInOrderCommand.php +++ /dev/null @@ -1,158 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\Command; - -use InvalidArgumentException; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidProductQuantityException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -/** - * Updates product in given order. - */ -class UpdateProductInOrderCommand -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int - */ - private $orderDetailId; - - /** - * @var Number - */ - private $priceTaxIncluded; - - /** - * @var Number - */ - private $priceTaxExcluded; - - /** - * @var int - */ - private $quantity; - - /** - * @var int|null - */ - private $orderInvoiceId; - - /** - * @param int $orderId - * @param int $orderDetailId - * @param string $priceTaxIncluded - * @param string $priceTaxExcluded - * @param int $quantity - * @param int|null $orderInvoiceId - */ - public function __construct( - int $orderId, - int $orderDetailId, - string $priceTaxIncluded, - string $priceTaxExcluded, - int $quantity, - ?int $orderInvoiceId = null - ) { - $this->orderId = new OrderId($orderId); - $this->orderDetailId = $orderDetailId; - try { - $this->priceTaxIncluded = new Number($priceTaxIncluded); - $this->priceTaxExcluded = new Number($priceTaxExcluded); - } catch (InvalidArgumentException $e) { - throw new InvalidAmountException(); - } - $this->setQuantity($quantity); - $this->orderInvoiceId = $orderInvoiceId; - } - - /** - * @return OrderId - */ - public function getOrderId() - { - return $this->orderId; - } - - /** - * @return int - */ - public function getOrderDetailId() - { - return $this->orderDetailId; - } - - /** - * @return Number - */ - public function getPriceTaxIncluded() - { - return $this->priceTaxIncluded; - } - - /** - * @return Number - */ - public function getPriceTaxExcluded() - { - return $this->priceTaxExcluded; - } - - /** - * @return int - */ - public function getQuantity() - { - return $this->quantity; - } - - /** - * @return int|null - */ - public function getOrderInvoiceId() - { - return $this->orderInvoiceId; - } - - /** - * @param int $quantity - * - * @throws InvalidProductQuantityException - */ - private function setQuantity(int $quantity): void - { - if ($quantity <= 0) { - throw new InvalidProductQuantityException('When adding a product quantity must be strictly positive'); - } - $this->quantity = $quantity; - } -} diff --git a/src/Core/Domain/Order/Product/CommandHandler/AddProductToOrderHandlerInterface.php b/src/Core/Domain/Order/Product/CommandHandler/AddProductToOrderHandlerInterface.php deleted file mode 100644 index dbfa74cb..00000000 --- a/src/Core/Domain/Order/Product/CommandHandler/AddProductToOrderHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\AddProductToOrderCommand; - -/** - * Interface for service that handles adding product to an exiting order. - */ -interface AddProductToOrderHandlerInterface -{ - /** - * @param AddProductToOrderCommand $command - */ - public function handle(AddProductToOrderCommand $command); -} diff --git a/src/Core/Domain/Order/Product/CommandHandler/DeleteProductFromOrderHandlerInterface.php b/src/Core/Domain/Order/Product/CommandHandler/DeleteProductFromOrderHandlerInterface.php deleted file mode 100644 index 312c81be..00000000 --- a/src/Core/Domain/Order/Product/CommandHandler/DeleteProductFromOrderHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\DeleteProductFromOrderCommand; - -/** - * Interface for service that handles deleting product from order. - */ -interface DeleteProductFromOrderHandlerInterface -{ - /** - * @param DeleteProductFromOrderCommand $command - */ - public function handle(DeleteProductFromOrderCommand $command); -} diff --git a/src/Core/Domain/Order/Product/CommandHandler/UpdateProductInOrderHandlerInterface.php b/src/Core/Domain/Order/Product/CommandHandler/UpdateProductInOrderHandlerInterface.php deleted file mode 100644 index 4baf585c..00000000 --- a/src/Core/Domain/Order/Product/CommandHandler/UpdateProductInOrderHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\UpdateProductInOrderCommand; - -/** - * Interface for service that updates product in given order. - */ -interface UpdateProductInOrderHandlerInterface -{ - /** - * @param UpdateProductInOrderCommand $command - */ - public function handle(UpdateProductInOrderCommand $command); -} diff --git a/src/Core/Domain/Order/Product/Exception/ProductException.php b/src/Core/Domain/Order/Product/Exception/ProductException.php deleted file mode 100644 index 3cdd5f08..00000000 --- a/src/Core/Domain/Order/Product/Exception/ProductException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Product\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Base exception for Order/Product subdomain - */ -class ProductException extends OrderException -{ -} diff --git a/src/Core/Domain/Order/Query/GetOrderForViewing.php b/src/Core/Domain/Order/Query/GetOrderForViewing.php deleted file mode 100644 index 61f6763b..00000000 --- a/src/Core/Domain/Order/Query/GetOrderForViewing.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Query; - -use PrestaShop\PrestaShop\Core\Domain\Exception\InvalidSortingException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\QuerySorting; - -/** - * Get order for view in Back Office - */ -class GetOrderForViewing -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var QuerySorting - */ - private $productsSorting; - - /** - * @param int $orderId - * @param string $productsSorting - * - * @throws OrderException - * @throws InvalidSortingException - */ - public function __construct(int $orderId, string $productsSorting = QuerySorting::ASC) - { - $this->orderId = new OrderId($orderId); - $this->productsSorting = new QuerySorting($productsSorting); - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return QuerySorting - */ - public function getProductsSorting(): QuerySorting - { - return $this->productsSorting; - } -} diff --git a/src/Core/Domain/Order/Query/GetOrderPreview.php b/src/Core/Domain/Order/Query/GetOrderPreview.php deleted file mode 100644 index 29a1b9cf..00000000 --- a/src/Core/Domain/Order/Query/GetOrderPreview.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Query; - -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; - -class GetOrderPreview -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @param int $orderId - */ - public function __construct(int $orderId) - { - $this->orderId = new OrderId($orderId); - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } -} diff --git a/src/Core/Domain/Order/Query/GetOrderProductsForViewing.php b/src/Core/Domain/Order/Query/GetOrderProductsForViewing.php deleted file mode 100644 index 94460a3b..00000000 --- a/src/Core/Domain/Order/Query/GetOrderProductsForViewing.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Query; - -use PrestaShop\PrestaShop\Core\Domain\Exception\InvalidSortingException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\QuerySorting; - -/** - * Query for paginated order products - */ -class GetOrderProductsForViewing -{ - /** - * @var OrderId - */ - private $orderId; - - /** - * @var int|null - */ - private $offset; - - /** - * @var @var null|int - */ - private $limit; - - /** - * @var QuerySorting - */ - private $productsSorting; - - /** - * Builds query for paginated results - * - * @param int $orderId - * @param int $offset - * @param int $limit - * @param string $productsSorting - * - * @return GetOrderProductsForViewing - * - * @throws OrderException - * @throws InvalidSortingException - */ - public static function paginated( - int $orderId, - int $offset, - int $limit, - string $productsSorting = QuerySorting::ASC - ) { - $query = new self(); - - $query->orderId = new OrderId($orderId); - $query->productsSorting = new QuerySorting($productsSorting); - $query->offset = $offset; - $query->limit = $limit; - - return $query; - } - - /** - * Builds query for getting all results - * - * @param int $orderId - * @param string $productsSorting - * - * @return GetOrderProductsForViewing - * - * @throws OrderException - * @throws InvalidSortingException - */ - public static function all(int $orderId, string $productsSorting = QuerySorting::ASC) - { - $query = new self(); - $query->orderId = new OrderId($orderId); - $query->productsSorting = new QuerySorting($productsSorting); - - return $query; - } - - /** - * @return OrderId - */ - public function getOrderId(): OrderId - { - return $this->orderId; - } - - /** - * @return int|null - */ - public function getOffset(): ?int - { - return $this->offset; - } - - /** - * @return int|null - */ - public function getLimit(): ?int - { - return $this->limit; - } - - /** - * @return QuerySorting - */ - public function getProductsSorting(): QuerySorting - { - return $this->productsSorting; - } -} diff --git a/src/Core/Domain/Order/QueryHandler/GetOrderForViewingHandlerInterface.php b/src/Core/Domain/Order/QueryHandler/GetOrderForViewingHandlerInterface.php deleted file mode 100644 index 74d17756..00000000 --- a/src/Core/Domain/Order/QueryHandler/GetOrderForViewingHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderForViewing; - -interface GetOrderForViewingHandlerInterface -{ - /** - * @param GetOrderForViewing $query - * - * @return OrderForViewing - */ - public function handle(GetOrderForViewing $query): OrderForViewing; -} diff --git a/src/Core/Domain/Order/QueryHandler/GetOrderPreviewHandlerInterface.php b/src/Core/Domain/Order/QueryHandler/GetOrderPreviewHandlerInterface.php deleted file mode 100644 index 3a279377..00000000 --- a/src/Core/Domain/Order/QueryHandler/GetOrderPreviewHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderPreview; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderPreview; - -/** - * Defines contract for getOrderPreview query handler - */ -interface GetOrderPreviewHandlerInterface -{ - /** - * @param GetOrderPreview $query - * - * @return OrderPreview - */ - public function handle(GetOrderPreview $query): OrderPreview; -} diff --git a/src/Core/Domain/Order/QueryHandler/GetOrderProductsForViewingHandlerInterface.php b/src/Core/Domain/Order/QueryHandler/GetOrderProductsForViewingHandlerInterface.php deleted file mode 100644 index b76a6297..00000000 --- a/src/Core/Domain/Order/QueryHandler/GetOrderProductsForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderProductsForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderProductsForViewing; - -/** - * Defines contract for GetOrderProductsForViewing query handler - */ -interface GetOrderProductsForViewingHandlerInterface -{ - /** - * @param GetOrderProductsForViewing $query - * - * @return OrderProductsForViewing - */ - public function handle(GetOrderProductsForViewing $query); -} diff --git a/src/Core/Domain/Order/QueryResult/LinkedOrderForViewing.php b/src/Core/Domain/Order/QueryResult/LinkedOrderForViewing.php deleted file mode 100644 index 6ea749e9..00000000 --- a/src/Core/Domain/Order/QueryResult/LinkedOrderForViewing.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -/** - * Used in order page view to display 'linked orders': orders linked - * to the order being displayed - * - * Two orders are linked if they are the result of an Order Split - */ -class LinkedOrderForViewing -{ - /** - * @var int - */ - private $orderId; - - /** - * @var string - */ - private $statusName; - - /** - * @var string - */ - private $amount; - - /** - * @param int $orderId - * @param string $statusName - * @param string $amount - */ - public function __construct(int $orderId, string $statusName, string $amount) - { - $this->orderId = $orderId; - $this->statusName = $statusName; - $this->amount = $amount; - } - - /** - * @return int - */ - public function getOrderId(): int - { - return $this->orderId; - } - - /** - * @return string - */ - public function getStatusName(): string - { - return $this->statusName; - } - - /** - * @return string - */ - public function getAmount(): string - { - return $this->amount; - } -} diff --git a/src/Core/Domain/Order/QueryResult/LinkedOrdersForViewing.php b/src/Core/Domain/Order/QueryResult/LinkedOrdersForViewing.php deleted file mode 100644 index 018b7fb8..00000000 --- a/src/Core/Domain/Order/QueryResult/LinkedOrdersForViewing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class LinkedOrdersForViewing -{ - /** @var LinkedOrderForViewing[] */ - private $linkedOrders = []; - - /** - * @param LinkedOrderForViewing[] $linkedOrders - */ - public function __construct(array $linkedOrders) - { - foreach ($linkedOrders as $order) { - $this->addLinkedOrder($order); - } - } - - /** - * @return LinkedOrderForViewing[] - */ - public function getLinkedOrders(): array - { - return $this->linkedOrders; - } - - /** - * @param LinkedOrderForViewing $order - */ - private function addLinkedOrder(LinkedOrderForViewing $order): void - { - $this->linkedOrders[] = $order; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderCarrierForViewing.php b/src/Core/Domain/Order/QueryResult/OrderCarrierForViewing.php deleted file mode 100644 index 90e3e862..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderCarrierForViewing.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderCarrierForViewing -{ - /** - * @var int - */ - private $orderCarrierId; - - /** - * @var DateTimeImmutable - */ - private $date; - - /** - * @var string - */ - private $name; - - /** - * @var int - */ - private $carrierId; - - /** - * @var string - */ - private $price; - - /** - * @var string|null - */ - private $trackingUrl; - - /** - * @var string|null - */ - private $trackingNumber; - - /** - * @var bool - */ - private $canEdit; - - /** - * @var string - */ - private $weight; - - /** - * @param int $orderCarrierId - * @param DateTimeImmutable $date - * @param string $name Carrier name or null in case of virtual order - * @param string $weight - * @param int $carrierId - * @param string $price Price or null in case of virtual order - * @param string|null $trackingUrl - * @param string|null $trackingNumber - * @param bool $canEdit - */ - public function __construct( - int $orderCarrierId, - DateTimeImmutable $date, - ?string $name, - string $weight, - int $carrierId, - ?string $price, - ?string $trackingUrl, - ?string $trackingNumber, - bool $canEdit - ) { - $this->orderCarrierId = $orderCarrierId; - $this->date = $date; - $this->name = $name; - $this->carrierId = $carrierId; - $this->price = $price; - $this->trackingUrl = $trackingUrl; - $this->trackingNumber = $trackingNumber; - $this->canEdit = $canEdit; - $this->weight = $weight; - } - - /** - * @return int - */ - public function getOrderCarrierId(): int - { - return $this->orderCarrierId; - } - - /** - * @return DateTimeImmutable - */ - public function getDate(): DateTimeImmutable - { - return $this->date; - } - - /** - * @return string - */ - public function getName(): ?string - { - return $this->name; - } - - /** - * @return int - */ - public function getCarrierId(): int - { - return $this->carrierId; - } - - /** - * @return string - */ - public function getPrice(): ?string - { - return $this->price; - } - - /** - * @return string|null - */ - public function getTrackingUrl(): ?string - { - return $this->trackingUrl; - } - - /** - * @return string|null - */ - public function getTrackingNumber(): ?string - { - return $this->trackingNumber; - } - - /** - * @return bool - */ - public function canEdit(): bool - { - return $this->canEdit; - } - - /** - * @return string - */ - public function getWeight(): string - { - return $this->weight; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderCustomerForViewing.php b/src/Core/Domain/Order/QueryResult/OrderCustomerForViewing.php deleted file mode 100644 index debb41ff..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderCustomerForViewing.php +++ /dev/null @@ -1,198 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderCustomerForViewing -{ - /** - * @var int - */ - private $id; - - /** - * @var string - */ - private $firstName; - - /** - * @var string Gender name - */ - private $lastName; - - /** - * @var string - */ - private $gender; - - /** - * @var string - */ - private $email; - - /** - * @var DateTimeImmutable - */ - private $accountRegistrationDate; - - /** - * @var string Formatted price with currency - */ - private $totalSpentSinceRegistration; - - /** - * @var int - */ - private $validOrdersPlaced; - - /** - * @var string - */ - private $privateNote; - - /** - * @var bool - */ - private $isGuest; - - /** - * @param int $id - * @param string $firstName - * @param string $lastName - * @param string $gender - * @param string $email - * @param DateTimeImmutable $accountRegistrationDate - * @param string $totalSpentSinceRegistration - * @param int $validOrdersPlaced - * @param string|null $privateNote - * @param bool $isGuest - */ - public function __construct( - int $id, - string $firstName, - string $lastName, - string $gender, - string $email, - DateTimeImmutable $accountRegistrationDate, - string $totalSpentSinceRegistration, - int $validOrdersPlaced, - ?string $privateNote, - bool $isGuest - ) { - $this->id = $id; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->gender = $gender; - $this->email = $email; - $this->accountRegistrationDate = $accountRegistrationDate; - $this->totalSpentSinceRegistration = $totalSpentSinceRegistration; - $this->validOrdersPlaced = $validOrdersPlaced; - $this->privateNote = $privateNote; - $this->isGuest = $isGuest; - } - - /** - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string - */ - public function getGender(): string - { - return $this->gender; - } - - /** - * @return string - */ - public function getEmail(): string - { - return $this->email; - } - - /** - * @return DateTimeImmutable - */ - public function getAccountRegistrationDate(): DateTimeImmutable - { - return $this->accountRegistrationDate; - } - - /** - * @return string - */ - public function getTotalSpentSinceRegistration(): string - { - return $this->totalSpentSinceRegistration; - } - - /** - * @return int - */ - public function getValidOrdersPlaced(): int - { - return $this->validOrdersPlaced; - } - - /** - * @return string|null - */ - public function getPrivateNote(): ?string - { - return $this->privateNote; - } - - /** - * @return bool - */ - public function isGuest(): bool - { - return $this->isGuest; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderDiscountForViewing.php b/src/Core/Domain/Order/QueryResult/OrderDiscountForViewing.php deleted file mode 100644 index 7dc04906..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderDiscountForViewing.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use PrestaShop\Decimal\Number; - -class OrderDiscountForViewing -{ - /** - * @var int - */ - private $orderCartRuleId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $amountFormatted; - - /** - * @var Number - */ - private $amountRaw; - - public function __construct( - int $orderCartRuleId, - string $name, - Number $amountRaw, - string $amountFormatted - ) { - $this->orderCartRuleId = $orderCartRuleId; - $this->name = $name; - $this->amountFormatted = $amountFormatted; - $this->amountRaw = $amountRaw; - } - - /** - * @return int - */ - public function getOrderCartRuleId(): int - { - return $this->orderCartRuleId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getAmountFormatted(): string - { - return $this->amountFormatted; - } - - /** - * @return Number - */ - public function getAmountRaw(): Number - { - return $this->amountRaw; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderDiscountsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderDiscountsForViewing.php deleted file mode 100644 index 79b022d3..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderDiscountsForViewing.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderDiscountsForViewing -{ - /** @var OrderDiscountForViewing[] */ - private $discounts = []; - - /** - * @param OrderDiscountForViewing[] $discounts - */ - public function __construct(array $discounts) - { - foreach ($discounts as $discount) { - $this->addDiscount($discount); - } - } - - /** - * @return OrderDiscountForViewing[] - */ - public function getDiscounts(): array - { - return $this->discounts; - } - - /** - * @param OrderDiscountForViewing $discount - */ - private function addDiscount(OrderDiscountForViewing $discount): void - { - $this->discounts[] = $discount; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderDocumentForViewing.php b/src/Core/Domain/Order/QueryResult/OrderDocumentForViewing.php deleted file mode 100644 index 438b58ad..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderDocumentForViewing.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderDocumentForViewing -{ - /** - * @var int - */ - private $id; - - /** - * @var string - */ - private $type; - - /** - * @var DateTimeImmutable - */ - private $createdAt; - - /** - * @var string - */ - private $referenceNumber; - - /** - * When eligible, document amount as a number - * - * @var float|null - */ - private $numericalAmount; - - /** - * When eligible, document amount as a string, ready to be displayed - * - * @var string|null - */ - private $amount; - - /** - * @var string|null - */ - private $amountMismatch; - - /** - * @var string - */ - private $note; - - /** - * @var bool - */ - private $isAddPaymentAllowed; - - public function __construct( - int $id, - string $type, - DateTimeImmutable $createdAt, - string $referenceNumber, - ?float $numericalAmount, - ?string $amount, - ?string $amountMismatch, - ?string $note, - bool $isAddPaymentAllowed - ) { - $this->id = $id; - $this->type = $type; - $this->createdAt = $createdAt; - $this->referenceNumber = $referenceNumber; - $this->numericalAmount = $numericalAmount; - $this->amount = $amount; - $this->amountMismatch = $amountMismatch; - $this->note = $note; - $this->isAddPaymentAllowed = $isAddPaymentAllowed; - } - - public function getId(): int - { - return $this->id; - } - - public function getType(): string - { - return $this->type; - } - - public function getCreatedAt(): DateTimeImmutable - { - return $this->createdAt; - } - - /** - * @return string - */ - public function getReferenceNumber(): string - { - return $this->referenceNumber; - } - - /** - * @return string|null - */ - public function getAmount(): ?string - { - return $this->amount; - } - - /** - * @return string|null - */ - public function getAmountMismatch(): ?string - { - return $this->amountMismatch; - } - - /** - * @return string - */ - public function getNote(): ?string - { - return $this->note; - } - - /** - * @return bool - */ - public function isAddPaymentAllowed(): bool - { - return $this->isAddPaymentAllowed; - } - - /** - * @return float|null - */ - public function getNumericalAmount(): ?float - { - return $this->numericalAmount; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderDocumentsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderDocumentsForViewing.php deleted file mode 100644 index d64b56c6..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderDocumentsForViewing.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderDocumentsForViewing -{ - /** - * @var OrderDocumentForViewing[] - */ - private $documents = []; - - /** - * @var bool - */ - private $canGenerateInvoice; - - /** - * @var bool - */ - private $canGenerateDeliverySlip; - - /** - * @param bool $canGenerateInvoice - * @param bool $canGenerateDeliverySlip - * @param OrderDocumentForViewing[] $documents - */ - public function __construct(bool $canGenerateInvoice, bool $canGenerateDeliverySlip, array $documents) - { - foreach ($documents as $document) { - $this->add($document); - } - - $this->canGenerateInvoice = $canGenerateInvoice; - $this->canGenerateDeliverySlip = $canGenerateDeliverySlip; - } - - /** - * @return OrderDocumentForViewing[] - */ - public function getDocuments(): array - { - return $this->documents; - } - - /** - * @return bool - */ - public function canGenerateInvoice(): bool - { - return $this->canGenerateInvoice; - } - - /** - * @return bool - */ - public function canGenerateDeliverySlip(): bool - { - return $this->canGenerateDeliverySlip; - } - - private function add(OrderDocumentForViewing $document): void - { - $this->documents[] = $document; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderForViewing.php b/src/Core/Domain/Order/QueryResult/OrderForViewing.php deleted file mode 100644 index cd19d385..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderForViewing.php +++ /dev/null @@ -1,540 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -/** - * Contains data about order for viewing - */ -class OrderForViewing -{ - /** - * @var int - */ - private $orderId; - - /** - * @var OrderCustomerForViewing - */ - private $customer; - - /** - * @var OrderShippingAddressForViewing - */ - private $shippingAddress; - - /** - * @var OrderInvoiceAddressForViewing - */ - private $invoiceAddress; - /** - * @var string - */ - private $reference; - - /** - * @var OrderProductsForViewing - */ - private $products; - - /** - * @var string - */ - private $taxMethod; - - /** - * @var OrderHistoryForViewing - */ - private $history; - - /** - * @var OrderDocumentsForViewing - */ - private $documents; - - /** - * @var OrderShippingForViewing - */ - private $shipping; - - /** - * @var OrderReturnsForViewing - */ - private $returns; - - /** - * @var OrderPaymentsForViewing - */ - private $payments; - - /** - * @var bool - */ - private $isValid; - - /** - * @var OrderMessagesForViewing - */ - private $messages; - - /** - * @var int - */ - private $currencyId; - - /** - * @var bool - */ - private $isDelivered; - - /** - * @var bool - */ - private $isShipped; - - /** - * @var OrderPricesForViewing - */ - private $prices; - - /** - * @var bool - */ - private $isTaxIncluded; - - /** - * @var bool - */ - private $hasBeenPaid; - - /** - * @var bool - */ - private $hasInvoice; - - /** - * @var OrderDiscountsForViewing - */ - private $discounts; - - /** - * @var LinkedOrdersForViewing - */ - private $linkedOrders; - - /** - * @var DateTimeImmutable - */ - private $createdAt; - - /** - * @var bool - */ - private $isVirtual; - - /** - * @var int - */ - private $carrierId; - - /** - * @var string - */ - private $carrierName; - - /** - * @var int - */ - private $shopId; - - /** - * @var int - */ - private $invoiceManagementIsEnabled; - - /** - * @var OrderSourcesForViewing - */ - private $sources; - - /** - * @param int $orderId - * @param int $currencyId - * @param int $carrierId - * @param string $carrierName - * @param int $shopId - * @param string $reference - * @param bool $isVirtual - * @param string $taxMethod - * @param bool $isTaxIncluded - * @param bool $isValid - * @param bool $hasBeenPaid - * @param bool $hasInvoice - * @param bool $isDelivered - * @param bool $isShipped - * @param bool $invoiceManagementIsEnabled - * @param DateTimeImmutable $createdAt - * @param OrderCustomerForViewing|null $customer - * @param OrderShippingAddressForViewing $shippingAddress - * @param OrderInvoiceAddressForViewing $invoiceAddress - * @param OrderProductsForViewing $products - * @param OrderHistoryForViewing $history - * @param OrderDocumentsForViewing $documents - * @param OrderShippingForViewing $shipping - * @param OrderReturnsForViewing $returns - * @param OrderPaymentsForViewing $payments - * @param OrderMessagesForViewing $messages - * @param OrderPricesForViewing $prices - * @param OrderDiscountsForViewing $discounts - * @param OrderSourcesForViewing $sources - * @param LinkedOrdersForViewing $linkedOrders - */ - public function __construct( - int $orderId, - int $currencyId, - int $carrierId, - string $carrierName, - int $shopId, - string $reference, - bool $isVirtual, - string $taxMethod, - bool $isTaxIncluded, - bool $isValid, - bool $hasBeenPaid, - bool $hasInvoice, - bool $isDelivered, - bool $isShipped, - bool $invoiceManagementIsEnabled, - DateTimeImmutable $createdAt, - ?OrderCustomerForViewing $customer, - OrderShippingAddressForViewing $shippingAddress, - OrderInvoiceAddressForViewing $invoiceAddress, - OrderProductsForViewing $products, - OrderHistoryForViewing $history, - OrderDocumentsForViewing $documents, - OrderShippingForViewing $shipping, - OrderReturnsForViewing $returns, - OrderPaymentsForViewing $payments, - OrderMessagesForViewing $messages, - OrderPricesForViewing $prices, - OrderDiscountsForViewing $discounts, - OrderSourcesForViewing $sources, - LinkedOrdersForViewing $linkedOrders - ) { - $this->reference = $reference; - $this->customer = $customer; - $this->shippingAddress = $shippingAddress; - $this->invoiceAddress = $invoiceAddress; - $this->products = $products; - $this->taxMethod = $taxMethod; - $this->history = $history; - $this->documents = $documents; - $this->shipping = $shipping; - $this->returns = $returns; - $this->payments = $payments; - $this->isValid = $isValid; - $this->messages = $messages; - $this->orderId = $orderId; - $this->currencyId = $currencyId; - $this->isDelivered = $isDelivered; - $this->isShipped = $isShipped; - $this->prices = $prices; - $this->isTaxIncluded = $isTaxIncluded; - $this->hasBeenPaid = $hasBeenPaid; - $this->hasInvoice = $hasInvoice; - $this->discounts = $discounts; - $this->createdAt = $createdAt; - $this->isVirtual = $isVirtual; - $this->carrierId = $carrierId; - $this->carrierName = $carrierName; - $this->shopId = $shopId; - $this->invoiceManagementIsEnabled = $invoiceManagementIsEnabled; - $this->sources = $sources; - $this->linkedOrders = $linkedOrders; - } - - /** - * @return int - */ - public function getId(): int - { - return $this->orderId; - } - - /** - * @return int - */ - public function getCurrencyId(): int - { - return $this->currencyId; - } - - /** - * @return int - */ - public function getCarrierId(): int - { - return $this->carrierId; - } - - public function getCarrierName(): string - { - return $this->carrierName; - } - - /** - * @return int - */ - public function getShopId(): int - { - return $this->shopId; - } - - /** - * @return string - */ - public function getReference(): string - { - return $this->reference; - } - - /** - * @return bool - */ - public function isValid(): bool - { - return $this->isValid; - } - - /** - * @return OrderCustomerForViewing|null - */ - public function getCustomer(): ?OrderCustomerForViewing - { - return $this->customer; - } - - /** - * @return OrderShippingAddressForViewing - */ - public function getShippingAddress(): OrderShippingAddressForViewing - { - return $this->shippingAddress; - } - - /** - * @return OrderInvoiceAddressForViewing - */ - public function getInvoiceAddress(): OrderInvoiceAddressForViewing - { - return $this->invoiceAddress; - } - - /** - * @return OrderProductsForViewing - */ - public function getProducts(): OrderProductsForViewing - { - return $this->products; - } - - /** - * @return string - */ - public function getTaxMethod(): string - { - return $this->taxMethod; - } - - /** - * @return OrderHistoryForViewing - */ - public function getHistory(): OrderHistoryForViewing - { - return $this->history; - } - - /** - * @return OrderDocumentsForViewing - */ - public function getDocuments(): OrderDocumentsForViewing - { - return $this->documents; - } - - /** - * @return OrderShippingForViewing - */ - public function getShipping(): OrderShippingForViewing - { - return $this->shipping; - } - - /** - * @return OrderReturnsForViewing - */ - public function getReturns(): OrderReturnsForViewing - { - return $this->returns; - } - - /** - * @return OrderPaymentsForViewing - */ - public function getPayments(): OrderPaymentsForViewing - { - return $this->payments; - } - - /** - * @return bool - */ - public function hasPayments(): bool - { - return count($this->payments->getPayments()) > 0; - } - - /** - * @return OrderMessagesForViewing - */ - public function getMessages(): OrderMessagesForViewing - { - return $this->messages; - } - - /** - * @return bool - */ - public function isDelivered(): bool - { - return $this->isDelivered; - } - - /** - * @return bool - */ - public function isShipped(): bool - { - return $this->isShipped; - } - - /** - * @return OrderPricesForViewing - */ - public function getPrices(): OrderPricesForViewing - { - return $this->prices; - } - - /** - * @return bool - */ - public function isTaxIncluded(): bool - { - return $this->isTaxIncluded; - } - - /** - * @return bool - */ - public function hasBeenPaid(): bool - { - return $this->hasBeenPaid; - } - - /** - * @return bool - */ - public function hasInvoice(): bool - { - return $this->hasInvoice; - } - - /** - * @return OrderDiscountsForViewing - */ - public function getDiscounts(): OrderDiscountsForViewing - { - return $this->discounts; - } - - /** - * @return LinkedOrdersForViewing - */ - public function getLinkedOrders(): LinkedOrdersForViewing - { - return $this->linkedOrders; - } - - /** - * @return DateTimeImmutable - */ - public function getCreatedAt(): DateTimeImmutable - { - return $this->createdAt; - } - - /** - * @return bool - */ - public function isVirtual(): bool - { - return $this->isVirtual; - } - - /** - * @return bool - */ - public function isInvoiceManagementIsEnabled(): bool - { - return $this->invoiceManagementIsEnabled; - } - - /** - * @return OrderSourcesForViewing - */ - public function getSources(): OrderSourcesForViewing - { - return $this->sources; - } - - /** - * @return bool - */ - public function isRefundable(): bool - { - /** @var OrderProductForViewing $product */ - foreach ($this->products->getProducts() as $product) { - if ($product->getQuantity() > $product->getQuantityRefunded()) { - return true; - } - } - - return $this->prices->getShippingRefundableAmountRaw()->isGreaterThanZero(); - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderHistoryForViewing.php b/src/Core/Domain/Order/QueryResult/OrderHistoryForViewing.php deleted file mode 100644 index 01c400e1..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderHistoryForViewing.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderHistoryForViewing -{ - /** - * @var OrderStatusForViewing[] - */ - private $statuses = []; - - /** - * @var int - */ - private $currentOrderStatusId; - - /** - * @param int $currentOrderStatusId - * @param OrderStatusForViewing[] $statuses - */ - public function __construct(int $currentOrderStatusId, array $statuses) - { - $this->currentOrderStatusId = $currentOrderStatusId; - - foreach ($statuses as $status) { - $this->add($status); - } - } - - /** - * @return OrderStatusForViewing[] - */ - public function getStatuses(): array - { - return $this->statuses; - } - - /** - * @return int - */ - public function getCurrentOrderStatusId(): int - { - return $this->currentOrderStatusId; - } - - /** - * @param OrderStatusForViewing $orderStatusForViewing - */ - private function add(OrderStatusForViewing $orderStatusForViewing): void - { - $this->statuses[] = $orderStatusForViewing; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderInvoiceAddressForViewing.php b/src/Core/Domain/Order/QueryResult/OrderInvoiceAddressForViewing.php deleted file mode 100644 index 045371bd..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderInvoiceAddressForViewing.php +++ /dev/null @@ -1,219 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderInvoiceAddressForViewing -{ - /** - * @var int - */ - private $addressId; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $companyName; - /** - * @var string - */ - private $address1; - - /** - * @var string - */ - private $address2; - - /** - * @var string - */ - private $cityName; - - /** - * @var string - */ - private $stateName; - - /** - * @var string - */ - private $countryName; - - /** - * @var string - */ - private $postCode; - - /** - * @var string - */ - private $phoneNumber; - - /** - * @var string - */ - private $mobilePhoneNumber; - - /** - * @param int $addressId - * @param string $firstName - * @param string $lastName - * @param string $companyName - * @param string $address1 - * @param string $address2 - * @param string $stateName - * @param string $cityName - * @param string $countryName - * @param string $postCode - * @param string $phone - * @param string $phoneMobile - */ - public function __construct( - int $addressId, - string $firstName, - string $lastName, - string $companyName, - string $address1, - string $address2, - string $stateName, - string $cityName, - string $countryName, - string $postCode, - string $phone, - string $phoneMobile - ) { - $this->addressId = $addressId; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->companyName = $companyName; - $this->address1 = $address1; - $this->address2 = $address2; - $this->stateName = $stateName; - $this->cityName = $cityName; - $this->countryName = $countryName; - $this->postCode = $postCode; - $this->phoneNumber = $phone; - $this->mobilePhoneNumber = $phoneMobile; - } - - /** - * @return int - */ - public function getAddressId(): int - { - return $this->addressId; - } - - /** - * @return string - */ - public function getFullName(): string - { - return sprintf('%s %s', $this->firstName, $this->lastName); - } - - /** - * @return string - */ - public function getCompanyName(): string - { - return $this->companyName; - } - - /** - * @return string - */ - public function getAddress1(): string - { - return $this->address1; - } - - /** - * @return string - */ - public function getAddress2(): string - { - return $this->address2; - } - - /** - * @return string - */ - public function getCityName(): string - { - return $this->cityName; - } - - /** - * @return string - */ - public function getStateName(): string - { - return $this->stateName; - } - - /** - * @return string - */ - public function getCountryName(): string - { - return $this->countryName; - } - - /** - * @return string - */ - public function getPostCode(): string - { - return $this->postCode; - } - - /** - * @return string - */ - public function getPhoneNumber(): string - { - return $this->phoneNumber; - } - - /** - * @return string - */ - public function getMobilePhoneNumber(): string - { - return $this->mobilePhoneNumber; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderMessageDateForViewing.php b/src/Core/Domain/Order/QueryResult/OrderMessageDateForViewing.php deleted file mode 100644 index b813f5f9..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderMessageDateForViewing.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -/** - * Used in order page view to display date in wanted format. - */ -class OrderMessageDateForViewing -{ - /** - * @var DateTimeImmutable - */ - private $date; - - /** - * @var string - */ - private $dateFormat; - - public function __construct(DateTimeImmutable $date, string $dateFormat) - { - $this->date = $date; - $this->dateFormat = $dateFormat; - } - - /** - * @return DateTimeImmutable - */ - public function getDate(): DateTimeImmutable - { - return $this->date; - } - - /** - * @return string - */ - public function getFormat(): string - { - return $this->date->format($this->dateFormat); - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderMessageForViewing.php b/src/Core/Domain/Order/QueryResult/OrderMessageForViewing.php deleted file mode 100644 index 2debeb8b..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderMessageForViewing.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderMessageForViewing -{ - /** - * @var int - */ - private $messageId; - - /** - * @var string - */ - private $message; - - /** - * @var DateTimeImmutable - */ - private $messageDate; - - /** - * @var string - */ - private $employeeFirstName; - - /** - * @var string - */ - private $employeeLastName; - - /** - * @var string - */ - private $customerFirstName; - - /** - * @var string - */ - private $customerLastName; - - /** - * @var int - */ - private $employeeId; - /** - * @var bool - */ - private $isPrivate; - /** - * @var bool - */ - private $isCurrentEmployeesMessage; - - /** - * @param int $messageId - * @param string $message - * @param DateTimeImmutable $messageDate - * @param int $employeeId - * @param bool $isCurrentEmployeesMessage - * @param string $employeeFirstName - * @param string $employeeLastName - * @param string $customerFirstName - * @param string $customerLastName - * @param bool $isPrivate - */ - public function __construct( - int $messageId, - string $message, - OrderMessageDateForViewing $messageDate, - int $employeeId, - bool $isCurrentEmployeesMessage, - ?string $employeeFirstName, - ?string $employeeLastName, - string $customerFirstName, - string $customerLastName, - bool $isPrivate - ) { - $this->messageId = $messageId; - $this->message = $message; - $this->messageDate = $messageDate; - $this->employeeFirstName = $employeeFirstName; - $this->employeeLastName = $employeeLastName; - $this->customerFirstName = $customerFirstName; - $this->customerLastName = $customerLastName; - $this->employeeId = $employeeId; - $this->isPrivate = $isPrivate; - $this->isCurrentEmployeesMessage = $isCurrentEmployeesMessage; - } - - /** - * @return int - */ - public function getMessageId(): int - { - return $this->messageId; - } - - /** - * @return string - */ - public function getMessage(): string - { - return $this->message; - } - - /** - * @return OrderMessageDateForViewing - */ - public function getMessageDate(): OrderMessageDateForViewing - { - return $this->messageDate; - } - - /** - * @return string - */ - public function getEmployeeFirstName(): ?string - { - return $this->employeeFirstName; - } - - /** - * @return string - */ - public function getEmployeeLastName(): ?string - { - return $this->employeeLastName; - } - - /** - * @return string - */ - public function getCustomerFirstName(): string - { - return $this->customerFirstName; - } - - /** - * @return string - */ - public function getCustomerLastName(): string - { - return $this->customerLastName; - } - - /** - * @return int - */ - public function getEmployeeId(): int - { - return $this->employeeId; - } - - /** - * @return bool - */ - public function isCurrentEmployeesMessage(): bool - { - return $this->isCurrentEmployeesMessage; - } - - /** - * @return bool - */ - public function isPrivate(): bool - { - return $this->isPrivate; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderMessagesForViewing.php b/src/Core/Domain/Order/QueryResult/OrderMessagesForViewing.php deleted file mode 100644 index b78d8d7c..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderMessagesForViewing.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderMessagesForViewing -{ - /** @var OrderMessageForViewing[] */ - private $messages = []; - - /** - * @var int - */ - private $total; - - /** - * @param OrderMessageForViewing[] $messages - * @param int $total - */ - public function __construct(array $messages, int $total) - { - foreach ($messages as $message) { - $this->add($message); - } - - $this->total = $total; - } - - /** - * @return OrderMessageForViewing[] - */ - public function getMessages(): array - { - return $this->messages; - } - - /** - * @return int - */ - public function getTotal(): int - { - return $this->total; - } - - /** - * @param OrderMessageForViewing $message - */ - private function add(OrderMessageForViewing $message): void - { - $this->messages[] = $message; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPaymentForViewing.php b/src/Core/Domain/Order/QueryResult/OrderPaymentForViewing.php deleted file mode 100644 index 1aab0cec..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPaymentForViewing.php +++ /dev/null @@ -1,198 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderPaymentForViewing -{ - /** - * @var int - */ - private $paymentId; - - /** - * @var DateTimeImmutable - */ - private $date; - - /** - * @var string - */ - private $paymentMethod; - - /** - * @var string - */ - private $transactionId; - - /** - * @var string - */ - private $amount; - - /** - * @var string|null - */ - private $invoiceNumber; - - /** - * @var string - */ - private $cardNumber; - - /** - * @var string - */ - private $cardBrand; - - /** - * @var string - */ - private $cardExpiration; - - /** - * @var string - */ - private $cardHolder; - - /** - * @param int $paymentId - * @param DateTimeImmutable $date - * @param string $paymentMethod - * @param string $transactionId - * @param string $amount - * @param string|null $invoiceNumber - * @param string $cardNumber - * @param string $cardBrand - * @param string $cardExpiration - * @param string $cardHolder - */ - public function __construct( - int $paymentId, - DateTimeImmutable $date, - string $paymentMethod, - string $transactionId, - string $amount, - ?string $invoiceNumber, - string $cardNumber, - string $cardBrand, - string $cardExpiration, - string $cardHolder - ) { - $this->paymentId = $paymentId; - $this->date = $date; - $this->paymentMethod = $paymentMethod; - $this->transactionId = $transactionId; - $this->amount = $amount; - $this->invoiceNumber = $invoiceNumber; - $this->cardNumber = $cardNumber; - $this->cardBrand = $cardBrand; - $this->cardExpiration = $cardExpiration; - $this->cardHolder = $cardHolder; - } - - /** - * @return int - */ - public function getPaymentId(): int - { - return $this->paymentId; - } - - /** - * @return DateTimeImmutable - */ - public function getDate(): DateTimeImmutable - { - return $this->date; - } - - /** - * @return string - */ - public function getPaymentMethod(): string - { - return $this->paymentMethod; - } - - /** - * @return string - */ - public function getTransactionId(): string - { - return $this->transactionId; - } - - /** - * @return string - */ - public function getAmount(): string - { - return $this->amount; - } - - /** - * @return string|null - */ - public function getInvoiceNumber(): ?string - { - return $this->invoiceNumber; - } - - /** - * @return string - */ - public function getCardNumber(): string - { - return $this->cardNumber; - } - - /** - * @return string - */ - public function getCardBrand(): string - { - return $this->cardBrand; - } - - /** - * @return string - */ - public function getCardExpiration(): string - { - return $this->cardExpiration; - } - - /** - * @return string - */ - public function getCardHolder(): string - { - return $this->cardHolder; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPaymentsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderPaymentsForViewing.php deleted file mode 100644 index 7b1dd58d..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPaymentsForViewing.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderPaymentsForViewing -{ - /** - * hint - collection would be better - * - * @var OrderPaymentForViewing[] - */ - private $payments = []; - - /** - * @var string|null - */ - private $amountToPay; - - /** - * @var string|null - */ - private $paidAmount; - - /** - * @var array - */ - private $paymentMismatchOrderIds; - - /** - * @param OrderPaymentForViewing[] $payments - * @param string|null $amountToPay - * @param string|null $paidAmount - * @param int[] $paymentMismatchOrderIds - */ - public function __construct( - array $payments, - ?string $amountToPay, - ?string $paidAmount, - array $paymentMismatchOrderIds - ) { - foreach ($payments as $payment) { - $this->add($payment); - } - - $this->amountToPay = $amountToPay; - $this->paidAmount = $paidAmount; - $this->paymentMismatchOrderIds = $paymentMismatchOrderIds; - } - - /** - * @return OrderPaymentForViewing[] - */ - public function getPayments(): array - { - return $this->payments; - } - - /** - * @return string|null - */ - public function getAmountToPay(): ?string - { - return $this->amountToPay; - } - - /** - * @return string|null - */ - public function getPaidAmount(): ?string - { - return $this->paidAmount; - } - - /** - * @return array - */ - public function getPaymentMismatchOrderIds(): array - { - return $this->paymentMismatchOrderIds; - } - - /** - * @param OrderPaymentForViewing $payment - */ - private function add(OrderPaymentForViewing $payment): void - { - $this->payments[] = $payment; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPreview.php b/src/Core/Domain/Order/QueryResult/OrderPreview.php deleted file mode 100644 index df613989..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPreview.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -/** - * DTO for order preview data - */ -class OrderPreview -{ - /** - * @var OrderPreviewInvoiceDetails - */ - private $invoiceDetails; - - /** - * @var OrderPreviewShippingDetails - */ - private $shippingDetails; - - /** - * @var OrderPreviewProductDetail[] - */ - private $productDetails; - - /** - * @var bool - */ - private $taxIncluded; - - /** - * @var bool - */ - private $isVirtual; - - /** - * @param OrderPreviewInvoiceDetails $invoiceDetails - * @param OrderPreviewShippingDetails $shippingDetails - * @param array $productDetails - * @param bool $isVirtual - * @param bool $taxIncluded - */ - public function __construct( - OrderPreviewInvoiceDetails $invoiceDetails, - OrderPreviewShippingDetails $shippingDetails, - array $productDetails, - bool $isVirtual, - bool $taxIncluded - ) { - $this->invoiceDetails = $invoiceDetails; - $this->shippingDetails = $shippingDetails; - $this->productDetails = $productDetails; - $this->taxIncluded = $taxIncluded; - $this->isVirtual = $isVirtual; - } - - /** - * @return OrderPreviewInvoiceDetails - */ - public function getInvoiceDetails(): OrderPreviewInvoiceDetails - { - return $this->invoiceDetails; - } - - /** - * @return OrderPreviewShippingDetails - */ - public function getShippingDetails(): OrderPreviewShippingDetails - { - return $this->shippingDetails; - } - - /** - * @return OrderPreviewProductDetail[] - */ - public function getProductDetails(): array - { - return $this->productDetails; - } - - /** - * @return bool - */ - public function isTaxIncluded(): bool - { - return $this->taxIncluded; - } - - /** - * @return bool - */ - public function isVirtual(): bool - { - return $this->isVirtual; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPreviewInvoiceDetails.php b/src/Core/Domain/Order/QueryResult/OrderPreviewInvoiceDetails.php deleted file mode 100644 index 062c7b3f..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPreviewInvoiceDetails.php +++ /dev/null @@ -1,233 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -/** - * DTO for order invoice details - */ -class OrderPreviewInvoiceDetails -{ - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $address1; - - /** - * @var string - */ - private $address2; - - /** - * @var string - */ - private $city; - - /** - * @var string - */ - private $country; - - /** - * @var string - */ - private $email; - - /** - * @var string - */ - private $phone; - - /** - * @var string - */ - private $company; - - /** - * @var string|null - */ - private $vatNumber; - - /** - * @var string - */ - private $postalCode; - - /** - * @var string|null - */ - private $stateName; - - /** - * InvoiceDetails constructor. - * - * @param string $firstName - * @param string $lastName - * @param string $company - * @param string|null $vatNumber - * @param string $address1 - * @param string $address2 - * @param string $city - * @param string $postalCode - * @param string|null $stateName - * @param string $country - * @param string|null $email - * @param string $phone - */ - public function __construct( - string $firstName, - string $lastName, - ?string $company, - ?string $vatNumber, - string $address1, - string $address2, - string $city, - string $postalCode, - ?string $stateName, - string $country, - ?string $email, - string $phone - ) { - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->address1 = $address1; - $this->address2 = $address2; - $this->city = $city; - $this->country = $country; - $this->email = $email; - $this->phone = $phone; - $this->company = $company; - $this->vatNumber = $vatNumber; - $this->postalCode = $postalCode; - $this->stateName = $stateName; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string - */ - public function getAddress1(): string - { - return $this->address1; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string - */ - public function getCountry(): string - { - return $this->country; - } - - /** - * @return string|null - */ - public function getEmail(): ?string - { - return $this->email; - } - - /** - * @return string - */ - public function getPhone(): string - { - return $this->phone; - } - - /** - * @return string - */ - public function getAddress2(): string - { - return $this->address2; - } - - /** - * @return string - */ - public function getCompany(): string - { - return $this->company; - } - - /** - * @return string|null - */ - public function getVatNumber(): ?string - { - return $this->vatNumber; - } - - /** - * @return string - */ - public function getPostalCode(): string - { - return $this->postalCode; - } - - /** - * @return string|null - */ - public function getStateName(): ?string - { - return $this->stateName; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPreviewProductDetail.php b/src/Core/Domain/Order/QueryResult/OrderPreviewProductDetail.php deleted file mode 100644 index 594597ab..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPreviewProductDetail.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -/** - * DTO for order product details - */ -class OrderPreviewProductDetail -{ - /** - * @var string - */ - private $name; - - /** - * @var int - */ - private $quantity; - - /** - * @var string - */ - private $unitPrice; - - /** - * @var string - */ - private $totalPrice; - - /** - * @var string - */ - private $totalTax; - - /** - * @var string - */ - private $reference; - - /** - * @var string - */ - private $location; - - /** - * @param string $name - * @param string $reference - * @param string $location - * @param int $quantity - * @param string $unitPrice - * @param string $totalPrice - * @param string $totalTax - */ - public function __construct( - string $name, - string $reference, - string $location, - int $quantity, - string $unitPrice, - string $totalPrice, - string $totalTax - ) { - $this->name = $name; - $this->quantity = $quantity; - $this->unitPrice = $unitPrice; - $this->totalPrice = $totalPrice; - $this->totalTax = $totalTax; - $this->reference = $reference; - $this->location = $location; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getReference(): string - { - return $this->reference; - } - - /** - * @return string - */ - public function getUnitPrice(): string - { - return $this->unitPrice; - } - - /** - * @return string - */ - public function getTotalPrice(): string - { - return $this->totalPrice; - } - - /** - * @return int - */ - public function getQuantity(): int - { - return $this->quantity; - } - - /** - * @return string - */ - public function getTotalTax(): string - { - return $this->totalTax; - } - - /** - * @return string - */ - public function getLocation(): string - { - return $this->location; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPreviewShippingDetails.php b/src/Core/Domain/Order/QueryResult/OrderPreviewShippingDetails.php deleted file mode 100644 index f3808080..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPreviewShippingDetails.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -/** - * DTO for order shipping details - */ -class OrderPreviewShippingDetails -{ - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $address1; - - /** - * @var string - */ - private $address2; - - /** - * @var string - */ - private $city; - - /** - * @var string - */ - private $country; - - /** - * @var string - */ - private $phone; - - /** - * @var string|null - */ - private $carrierName; - - /** - * @var string|null - */ - private $trackingNumber; - - /** - * @var string - */ - private $postalCode; - - /** - * @var string|null - */ - private $stateName; - - /** - * @var string|null - */ - private $company; - - /** - * @var string|null - */ - private $vatNumber; - - /** - * InvoiceDetails constructor. - * - * @param string $firstName - * @param string $lastName - * @param string|null $company - * @param string|null $vatNumber - * @param string $address1 - * @param string $address2 - * @param string $city - * @param string $postalCode - * @param string|null $stateName - * @param string $country - * @param string $phone - * @param string|null $carrierName - * @param string|null $trackingNumber - */ - public function __construct( - string $firstName, - string $lastName, - ?string $company, - ?string $vatNumber, - string $address1, - string $address2, - string $city, - string $postalCode, - ?string $stateName, - string $country, - string $phone, - ?string $carrierName, - ?string $trackingNumber - ) { - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->address1 = $address1; - $this->address2 = $address2; - $this->city = $city; - $this->country = $country; - $this->phone = $phone; - $this->carrierName = $carrierName; - $this->trackingNumber = $trackingNumber; - $this->postalCode = $postalCode; - $this->stateName = $stateName; - $this->company = $company; - $this->vatNumber = $vatNumber; - } - - /** - * @return string - */ - public function getFirstName(): string - { - return $this->firstName; - } - - /** - * @return string - */ - public function getLastName(): string - { - return $this->lastName; - } - - /** - * @return string|null - */ - public function getCompany(): ?string - { - return $this->company; - } - - /** - * @return string|null - */ - public function getVatNumber(): ?string - { - return $this->vatNumber; - } - - /** - * @return string - */ - public function getAddress1(): string - { - return $this->address1; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string - */ - public function getPostalCode(): string - { - return $this->postalCode; - } - - /** - * @return string|null - */ - public function getStateName(): ?string - { - return $this->stateName; - } - - /** - * @return string - */ - public function getCountry(): string - { - return $this->country; - } - - /** - * @return string - */ - public function getPhone(): string - { - return $this->phone; - } - - /** - * @return string - */ - public function getAddress2(): string - { - return $this->address2; - } - - /** - * @return string|null - */ - public function getCarrierName(): ?string - { - return $this->carrierName; - } - - /** - * @return string|null - */ - public function getTrackingNumber(): ?string - { - return $this->trackingNumber; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderPricesForViewing.php b/src/Core/Domain/Order/QueryResult/OrderPricesForViewing.php deleted file mode 100644 index 76f167f1..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderPricesForViewing.php +++ /dev/null @@ -1,245 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use PrestaShop\Decimal\Number; - -class OrderPricesForViewing -{ - /** - * @var string - */ - private $productsPriceFormatted; - - /** - * @var string - */ - private $discountsAmountFormatted; - - /** - * @var string - */ - private $wrappingPriceFormatted; - - /** - * @var string - */ - private $shippingPriceFormatted; - - /** - * @var string - */ - private $shippingRefundableAmountFormatted; - - /** - * @var string - */ - private $taxesAmountFormatted; - - /** - * @var string - */ - private $totalAmountFormatted; - - /** - * @var Number - */ - private $productsPriceRaw; - - /** - * @var Number - */ - private $discountsAmountRaw; - /** - * @var Number - */ - private $wrappingPriceRaw; - - /** - * @var Number - */ - private $shippingPriceRaw; - - /** - * @var Number - */ - private $shippingRefundableAmountRaw; - - /** - * @var Number - */ - private $taxesAmountRaw; - - /** - * @var Number - */ - private $totalAmountRaw; - - public function __construct( - Number $productsPriceRaw, - Number $discountsAmountRaw, - Number $wrappingPriceRaw, - Number $shippingPriceRaw, - Number $shippingRefundableAmountRaw, - Number $taxesAmountRaw, - Number $totalAmountRaw, - string $productsPrice, - string $discountsAmount, - string $wrappingPrice, - string $shippingPrice, - string $shippingRefundableAmount, - string $taxesAmount, - string $totalAmount - ) { - $this->productsPriceFormatted = $productsPrice; - $this->discountsAmountFormatted = $discountsAmount; - $this->wrappingPriceFormatted = $wrappingPrice; - $this->shippingPriceFormatted = $shippingPrice; - $this->shippingRefundableAmountFormatted = $shippingRefundableAmount; - $this->taxesAmountFormatted = $taxesAmount; - $this->totalAmountFormatted = $totalAmount; - $this->productsPriceRaw = $productsPriceRaw; - $this->discountsAmountRaw = $discountsAmountRaw; - $this->wrappingPriceRaw = $wrappingPriceRaw; - $this->shippingPriceRaw = $shippingPriceRaw; - $this->shippingRefundableAmountRaw = $shippingRefundableAmountRaw; - $this->taxesAmountRaw = $taxesAmountRaw; - $this->totalAmountRaw = $totalAmountRaw; - } - - /** - * @return string - */ - public function getProductsPriceFormatted(): string - { - return $this->productsPriceFormatted; - } - - /** - * @return string - */ - public function getDiscountsAmountFormatted(): ?string - { - return $this->discountsAmountFormatted; - } - - /** - * @return string - */ - public function getWrappingPriceFormatted(): ?string - { - return $this->wrappingPriceFormatted; - } - - /** - * @return string - */ - public function getShippingPriceFormatted(): ?string - { - return $this->shippingPriceFormatted; - } - - /** - * @return string - */ - public function getShippingRefundableAmountFormatted(): ?string - { - return $this->shippingRefundableAmountFormatted; - } - - /** - * @return string - */ - public function getTaxesAmountFormatted(): string - { - return $this->taxesAmountFormatted; - } - - /** - * @return string - */ - public function getTotalAmountFormatted(): string - { - return $this->totalAmountFormatted; - } - - /** - * @return Number - */ - public function getProductsPriceRaw(): Number - { - return $this->productsPriceRaw; - } - - /** - * @return Number - */ - public function getDiscountsAmountRaw(): Number - { - return $this->discountsAmountRaw; - } - - /** - * @return Number - */ - public function getWrappingPriceRaw(): Number - { - return $this->wrappingPriceRaw; - } - - /** - * @return Number - */ - public function getShippingPriceRaw(): Number - { - return $this->shippingPriceRaw; - } - - /** - * @return Number - */ - public function getShippingRefundableAmountRaw(): Number - { - return $this->shippingRefundableAmountRaw; - } - - /** - * @return Number - */ - public function getTaxesAmountRaw(): Number - { - return $this->taxesAmountRaw; - } - - /** - * @return Number - */ - public function getTotalAmountRaw(): Number - { - return $this->totalAmountRaw; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderProductCustomizationForViewing.php b/src/Core/Domain/Order/QueryResult/OrderProductCustomizationForViewing.php deleted file mode 100644 index 0dbd73a2..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderProductCustomizationForViewing.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use PrestaShop\PrestaShop\Adapter\Entity\Product; - -class OrderProductCustomizationForViewing -{ - /** - * @var int - */ - private $type; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $value; - - /** - * @var string - */ - private $image; - - /** - * @param int $type - * @param string $name - * @param string $value - */ - public function __construct(int $type, string $name, string $value) - { - $this->type = $type; - $this->name = $name; - $this->value = $value; - if (Product::CUSTOMIZE_FILE === $this->type) { - $this->image = _THEME_PROD_PIC_DIR_ . $this->value . '_small'; - } - } - - /** - * @return int - */ - public function getType(): int - { - return $this->type; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->value; - } - - /** - * @return string|null - */ - public function getImage(): ?string - { - return $this->image; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderProductCustomizationsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderProductCustomizationsForViewing.php deleted file mode 100644 index 26e0f574..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderProductCustomizationsForViewing.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use PrestaShop\PrestaShop\Adapter\Entity\Product; - -class OrderProductCustomizationsForViewing -{ - /** - * @var OrderProductCustomizationForViewing[] - */ - private $textCustomizations = []; - - /** - * @var OrderProductCustomizationForViewing[] - */ - private $fileCustomizations = []; - - /** - * @param OrderProductCustomizationForViewing[] $customizations - */ - public function __construct(array $customizations) - { - foreach ($customizations as $customization) { - $this->addCustomization($customization); - } - } - - /** - * @param OrderProductCustomizationForViewing $customization - */ - private function addCustomization(OrderProductCustomizationForViewing $customization): void - { - if (Product::CUSTOMIZE_FILE === $customization->getType()) { - $this->fileCustomizations[] = $customization; - } else { - $this->textCustomizations[] = $customization; - } - } - - /** - * Returns customizations of type FILE - * - * @return OrderProductCustomizationForViewing[] - */ - public function getFileCustomizations(): array - { - return $this->fileCustomizations; - } - - /** - * Returns customizations of type TEXT - * - * @return OrderProductCustomizationForViewing[] - */ - public function getTextCustomizations(): array - { - return $this->textCustomizations; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderProductForViewing.php b/src/Core/Domain/Order/QueryResult/OrderProductForViewing.php deleted file mode 100644 index 0c6d2577..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderProductForViewing.php +++ /dev/null @@ -1,533 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use JsonSerializable; - -class OrderProductForViewing implements JsonSerializable -{ - const TYPE_PACK = 'pack'; - const TYPE_PRODUCT_WITH_COMBINATIONS = 'product_with_combinations'; - const TYPE_PRODUCT_WITHOUT_COMBINATIONS = 'product_without_combinations'; - - /** - * @var int - */ - private $id; - - /** - * @var int - */ - private $combinationId; - - /** - * @var string - */ - private $location; - - /** - * @var string - */ - private $name; - - /** - * @var OrderProductForViewing[] - */ - private $packItems; - - /** - * @var string - */ - private $reference; - - /** - * @var string - */ - private $supplierReference; - - /** - * @var string - */ - private $type; - - /** - * @var int - */ - private $quantity; - - /** - * @var string - */ - private $unitPrice; - - /** - * @var string - */ - private $totalPrice; - - /** - * @var int - */ - private $availableQuantity; - - /** - * @var string|null - */ - private $imagePath; - - /** - * @var string - */ - private $unitPriceTaxExclRaw; - - /** - * @var string - */ - private $unitPriceTaxInclRaw; - - /** - * @var string - */ - private $taxRate; - - /** - * @var int - */ - private $orderDetailId; - - /** - * @var string - */ - private $amountRefunded; - - /** - * @var int - */ - private $quantityRefunded; - - /** - * @var string - */ - private $amountRefundable; - - /** - * @var string - */ - private $amountRefundableRaw; - - /** - * @var int - */ - private $orderInvoiceId; - - /** - * @var string - */ - private $orderInvoiceNumber; - - /** - * @var bool - */ - private $availableOutOfStock; - - /** - * @var OrderProductCustomizationsForViewing - */ - private $customizations; - - /** - * @param int $orderDetailId - * @param int $id - * @param int $combinationId - * @param string $name - * @param string $reference - * @param string $supplierReference - * @param int $quantity - * @param string $unitPrice - * @param string $totalPrice - * @param int $availableQuantity - * @param string|null $imagePath - * @param string $unitPriceTaxExclRaw - * @param string $unitPriceTaxInclRaw - * @param string $taxRate - * @param string $amountRefunded - * @param int $quantityRefunded - * @param string $amountRefundable - * @param string $amountRefundableRaw - * @param string $location - * @param int|null $orderInvoiceId - * @param string $orderInvoiceNumber - * @param string $type - * @param bool $availableOutOfStock - * @param array $packItems - * @param OrderProductCustomizationsForViewing|null $customizations - */ - public function __construct( - ?int $orderDetailId, - int $id, - int $combinationId, - string $name, - string $reference, - string $supplierReference, - int $quantity, - string $unitPrice, - string $totalPrice, - int $availableQuantity, - ?string $imagePath, - string $unitPriceTaxExclRaw, - string $unitPriceTaxInclRaw, - string $taxRate, - string $amountRefunded, - int $quantityRefunded, - string $amountRefundable, - string $amountRefundableRaw, - string $location, - ?int $orderInvoiceId, - string $orderInvoiceNumber, - string $type, - bool $availableOutOfStock, - array $packItems = [], - ?OrderProductCustomizationsForViewing $customizations = null - ) { - $this->id = $id; - $this->combinationId = $combinationId; - $this->name = $name; - $this->reference = $reference; - $this->supplierReference = $supplierReference; - $this->quantity = $quantity; - $this->unitPrice = $unitPrice; - $this->totalPrice = $totalPrice; - $this->availableQuantity = $availableQuantity; - $this->imagePath = $imagePath; - $this->unitPriceTaxExclRaw = $unitPriceTaxExclRaw; - $this->unitPriceTaxInclRaw = $unitPriceTaxInclRaw; - $this->taxRate = $taxRate; - $this->orderDetailId = $orderDetailId; - $this->amountRefunded = $amountRefunded; - $this->quantityRefunded = $quantityRefunded; - $this->amountRefundable = $amountRefundable; - $this->amountRefundableRaw = $amountRefundableRaw; - $this->location = $location; - $this->orderInvoiceId = $orderInvoiceId; - $this->orderInvoiceNumber = $orderInvoiceNumber; - $this->type = $type; - $this->availableOutOfStock = $availableOutOfStock; - $this->packItems = $packItems; - $this->customizations = $customizations; - } - - /** - * Get product's order detail ID - * - * @return int|null - */ - public function getOrderDetailId(): ?int - { - return $this->orderDetailId; - } - - /** - * Get product ID - * - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @return int - */ - public function getCombinationId(): int - { - return $this->combinationId; - } - - /** - * Get product's name - * - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return OrderProductForViewing[] - */ - public function getPackItems(): array - { - return $this->packItems; - } - - /** - * Product reference - * - * @return string - */ - public function getReference(): string - { - return $this->reference; - } - - /** - * Get product's supplier reference - * - * @return string - */ - public function getSupplierReference(): string - { - return $this->supplierReference; - } - - /** - * get tax rate to be applied on this product - * - * @return string - */ - public function getTaxRate(): string - { - return $this->taxRate; - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * Get product's location - * - * @return string - */ - public function getLocation(): string - { - return $this->location; - } - - /** - * Get product's quantity - * - * @return int - */ - public function getQuantity(): int - { - return $this->quantity; - } - - /** - * Get product's unit price - * - * @return string - */ - public function getUnitPrice(): string - { - return $this->unitPrice; - } - - /** - * Get product's formatted total price - * - * @return string - */ - public function getTotalPrice(): string - { - return $this->totalPrice; - } - - /** - * Get available quantity for this product - * - * @return int - */ - public function getAvailableQuantity(): int - { - return $this->availableQuantity; - } - - /** - * Get image path for this product - * - * @return string|null - */ - public function getImagePath(): ?string - { - return $this->imagePath; - } - - /** - * Get unit price without taxes - * - * @return string - */ - public function getUnitPriceTaxExclRaw(): string - { - return $this->unitPriceTaxExclRaw; - } - - /** - * Get unit price including taxes - * - * @return string - */ - public function getUnitPriceTaxInclRaw(): string - { - return $this->unitPriceTaxInclRaw; - } - - /** - * How much (money) has already been refunded for this product - * - * @return string - */ - public function getAmountRefunded(): string - { - return $this->amountRefunded; - } - - /** - * How many (quantity) of this product has already been refunded - * - * @return int - */ - public function getQuantityRefunded(): int - { - return $this->quantityRefunded; - } - - /** - * How much (money) can be refunded for this product (formatted for display) - * - * @return string - */ - public function getAmountRefundable(): string - { - return $this->amountRefundable; - } - - /** - * How much (money) can be refunded for this product - * - * @return string - */ - public function getAmountRefundableRaw(): string - { - return $this->amountRefundableRaw; - } - - /** - * How many (quantity) of this product can be refunded - * - * @return int - */ - public function getQuantityRefundable(): int - { - return $this->quantity - $this->quantityRefunded; - } - - /** - * Can this product be refunded - * - * @return bool - */ - public function isRefundable(): bool - { - if ($this->quantity <= $this->quantityRefunded) { - return false; - } - - return true; - } - - /** - * Get the id of this product's invoice - * - * @return int - */ - public function getOrderInvoiceId(): ?int - { - return $this->orderInvoiceId; - } - - /** - * Get the number (reference) of this product's invoice - * - * @return string - */ - public function getOrderInvoiceNumber(): string - { - return $this->orderInvoiceNumber; - } - - /** - * Get customizations of this product - * - * @return OrderProductCustomizationsForViewing|null - */ - public function getCustomizations(): ?OrderProductCustomizationsForViewing - { - return $this->customizations; - } - - /** - * @return bool - */ - public function isAvailableOutOfStock(): bool - { - return $this->availableOutOfStock; - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - return [ - 'id' => $this->getId(), - 'orderDetailId' => $this->getOrderDetailId(), - 'name' => $this->getName(), - 'reference' => $this->getReference(), - 'supplierReference' => $this->getSupplierReference(), - 'location' => $this->getLocation(), - 'imagePath' => $this->getImagePath(), - 'quantity' => $this->getQuantity(), - 'availableQuantity' => $this->getAvailableQuantity(), - 'unitPrice' => $this->getUnitPrice(), - 'unitPriceTaxExclRaw' => $this->getUnitPriceTaxExclRaw(), - 'unitPriceTaxInclRaw' => $this->getUnitPriceTaxInclRaw(), - 'totalPrice' => $this->getTotalPrice(), - 'taxRate' => $this->getTaxRate(), - 'type' => $this->getType(), - 'packItems' => $this->getPackItems(), - ]; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderProductsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderProductsForViewing.php deleted file mode 100644 index 08dbadd9..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderProductsForViewing.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderProductsForViewing -{ - /** - * @var OrderProductForViewing[] - */ - private $products = []; - - /** - * @param OrderProductForViewing[] $products - */ - public function __construct(array $products) - { - foreach ($products as $product) { - $this->addProductForViewing($product); - } - } - - /** - * @param OrderProductForViewing $productForViewing - */ - private function addProductForViewing(OrderProductForViewing $productForViewing): void - { - $this->products[] = $productForViewing; - } - - /** - * @return OrderProductForViewing[] - */ - public function getProducts(): array - { - return $this->products; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderReturnForViewing.php b/src/Core/Domain/Order/QueryResult/OrderReturnForViewing.php deleted file mode 100644 index d0776169..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderReturnForViewing.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderReturnForViewing -{ - /** - * @var int - */ - private $orderInvoiceId; - - /** - * @var int - */ - private $carrierId; - - /** - * @var DateTimeImmutable - */ - private $date; - - /** - * @var string - */ - private $type; - - /** - * @var string - */ - private $stateName; - - /** - * @var string|null - */ - private $trackingUrl; - - /** - * @var string|null - */ - private $trackingNumber; - - /** - * @var int - */ - private $idOrderReturn; - - /** - * @param int $idOrderReturn - * @param int $orderInvoiceId - * @param int $carrierId - * @param DateTimeImmutable $date - * @param string $type - * @param string $stateName - * @param string|null $trackingUrl - * @param string|null $trackingNumber - */ - public function __construct( - int $idOrderReturn, - int $orderInvoiceId, - int $carrierId, - DateTimeImmutable $date, - string $type, - string $stateName, - ?string $trackingUrl, - ?string $trackingNumber - ) { - $this->orderInvoiceId = $orderInvoiceId; - $this->carrierId = $carrierId; - $this->date = $date; - $this->type = $type; - $this->stateName = $stateName; - $this->trackingUrl = $trackingUrl; - $this->trackingNumber = $trackingNumber; - $this->idOrderReturn = $idOrderReturn; - } - - /** - * @return int - */ - public function getOrderInvoiceId(): int - { - return $this->orderInvoiceId; - } - - /** - * @return int - */ - public function getCarrierId(): int - { - return $this->carrierId; - } - - /** - * @return DateTimeImmutable - */ - public function getDate(): DateTimeImmutable - { - return $this->date; - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return string - */ - public function getStateName(): string - { - return $this->stateName; - } - - /** - * @return string|null - */ - public function getTrackingUrl(): ?string - { - return $this->trackingUrl; - } - - /** - * @return string|null - */ - public function getTrackingNumber(): ?string - { - return $this->trackingNumber; - } - - /** - * @return int - */ - public function getIdOrderReturn(): int - { - return $this->idOrderReturn; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderReturnsForViewing.php b/src/Core/Domain/Order/QueryResult/OrderReturnsForViewing.php deleted file mode 100644 index 7bbcc3d1..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderReturnsForViewing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderReturnsForViewing -{ - /** @var OrderReturnForViewing[] */ - private $orderReturns = []; - - /** - * @param OrderReturnForViewing[] $orderReturns - */ - public function __construct(array $orderReturns = []) - { - foreach ($orderReturns as $orderReturn) { - $this->add($orderReturn); - } - } - - /** - * @return OrderReturnForViewing[] - */ - public function getOrderReturns(): array - { - return $this->orderReturns; - } - - /** - * @param OrderReturnForViewing $orderReturn - */ - private function add(OrderReturnForViewing $orderReturn): void - { - $this->orderReturns[] = $orderReturn; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderShippingAddressForViewing.php b/src/Core/Domain/Order/QueryResult/OrderShippingAddressForViewing.php deleted file mode 100644 index 5f0cb2f8..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderShippingAddressForViewing.php +++ /dev/null @@ -1,205 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderShippingAddressForViewing -{ - /** - * @var int - */ - private $addressId; - - /** - * @var string - */ - private $firstName; - - /** - * @var string - */ - private $lastName; - - /** - * @var string - */ - private $companyName; - /** - * @var string - */ - private $address1; - - /** - * @var string - */ - private $address2; - - /** - * @var string - */ - private $cityName; - - /** - * @var string - */ - private $stateName; - - /** - * @var string - */ - private $countryName; - - /** - * @var string - */ - private $postCode; - - /** - * @var string - */ - private $phoneNumber; - - /** - * @var string - */ - private $mobilePhoneNumber; - - public function __construct( - int $addressId, - string $firstName, - string $lastName, - string $companyName, - string $address1, - string $address2, - string $stateName, - string $cityName, - string $countryName, - string $postCode, - string $phone, - string $phoneMobile - ) { - $this->addressId = $addressId; - $this->firstName = $firstName; - $this->lastName = $lastName; - $this->companyName = $companyName; - $this->address1 = $address1; - $this->address2 = $address2; - $this->stateName = $stateName; - $this->cityName = $cityName; - $this->countryName = $countryName; - $this->postCode = $postCode; - $this->phoneNumber = $phone; - $this->mobilePhoneNumber = $phoneMobile; - } - - /** - * @return int - */ - public function getAddressId(): int - { - return $this->addressId; - } - - /** - * @return string - */ - public function getFullName(): string - { - return sprintf('%s %s', $this->firstName, $this->lastName); - } - - /** - * @return string - */ - public function getCompanyName(): string - { - return $this->companyName; - } - - /** - * @return string - */ - public function getAddress1(): string - { - return $this->address1; - } - - /** - * @return string - */ - public function getAddress2(): string - { - return $this->address2; - } - - /** - * @return string - */ - public function getCityName(): string - { - return $this->cityName; - } - - /** - * @return string - */ - public function getStateName(): string - { - return $this->stateName; - } - - /** - * @return string - */ - public function getCountryName(): string - { - return $this->countryName; - } - - /** - * @return string - */ - public function getPostCode(): string - { - return $this->postCode; - } - - /** - * @return string - */ - public function getPhoneNumber(): string - { - return $this->phoneNumber; - } - - /** - * @return string - */ - public function getMobilePhoneNumber(): string - { - return $this->mobilePhoneNumber; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderShippingForViewing.php b/src/Core/Domain/Order/QueryResult/OrderShippingForViewing.php deleted file mode 100644 index 470d76c7..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderShippingForViewing.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderShippingForViewing -{ - /** - * @var OrderCarrierForViewing[] - */ - private $carriers = []; - - /** - * @var bool - */ - private $isRecycledPackaging; - - /** - * @var bool - */ - private $isGiftWrapping; - - /** - * @var string|null - */ - private $carrierModuleInfo; - - /** - * @var string|null - */ - private $giftMessage; - - /** - * @param OrderCarrierForViewing[] $carriers - * @param bool $isRecycledPackaging - * @param bool $isGiftWrapping - * @param string|null $giftMessage - * @param string|null $carrierModuleInfo - */ - public function __construct( - array $carriers, - bool $isRecycledPackaging, - bool $isGiftWrapping, - ?string $giftMessage, - ?string $carrierModuleInfo - ) { - foreach ($carriers as $carrier) { - $this->addCarrier($carrier); - } - - $this->isRecycledPackaging = $isRecycledPackaging; - $this->isGiftWrapping = $isGiftWrapping; - $this->carrierModuleInfo = $carrierModuleInfo; - $this->giftMessage = $giftMessage; - } - - /** - * hint - collection of OrderCarrierForViewing objects would be better - * - * @return OrderCarrierForViewing[] - */ - public function getCarriers(): array - { - return $this->carriers; - } - - /** - * @return bool - */ - public function isRecycledPackaging(): bool - { - return $this->isRecycledPackaging; - } - - /** - * @return bool - */ - public function isGiftWrapping(): bool - { - return $this->isGiftWrapping; - } - - /** - * @return string|null - */ - public function getCarrierModuleInfo(): ?string - { - return $this->carrierModuleInfo; - } - - /** - * @return string|null - */ - public function getGiftMessage(): ?string - { - return $this->giftMessage; - } - - /** - * @param OrderCarrierForViewing $carrier - */ - private function addCarrier(OrderCarrierForViewing $carrier): void - { - $this->carriers[] = $carrier; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderSourceForViewing.php b/src/Core/Domain/Order/QueryResult/OrderSourceForViewing.php deleted file mode 100644 index f1e1c685..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderSourceForViewing.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderSourceForViewing -{ - /** - * @var string - */ - private $httpReferer; - - /** - * @var string - */ - private $requestUri; - - /** - * @var DateTimeImmutable - */ - private $addedAt; - - /** - * @var string - */ - private $keywords; - - /** - * @param string $httpReferer - * @param string $requestUri - * @param DateTimeImmutable $addedAt - * @param string $keywords - */ - public function __construct(string $httpReferer, string $requestUri, DateTimeImmutable $addedAt, string $keywords) - { - $this->httpReferer = $httpReferer; - $this->requestUri = $requestUri; - $this->addedAt = $addedAt; - $this->keywords = $keywords; - } - - /** - * @return string - */ - public function getHttpReferer(): string - { - return $this->httpReferer; - } - - /** - * @return string - */ - public function getRequestUri(): string - { - return $this->requestUri; - } - - /** - * @return DateTimeImmutable - */ - public function getAddedAt(): DateTimeImmutable - { - return $this->addedAt; - } - - /** - * @return string - */ - public function getKeywords(): string - { - return $this->keywords; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderSourcesForViewing.php b/src/Core/Domain/Order/QueryResult/OrderSourcesForViewing.php deleted file mode 100644 index c58a23e3..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderSourcesForViewing.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -class OrderSourcesForViewing -{ - /** @var OrderSourceForViewing[] */ - private $sources = []; - - /** - * @param OrderSourceForViewing[] $sources - */ - public function __construct(array $sources) - { - foreach ($sources as $source) { - $this->addSource($source); - } - } - - /** - * @return OrderSourceForViewing[] - */ - public function getSources(): array - { - return $this->sources; - } - - /** - * @param OrderSourceForViewing $source - */ - private function addSource(OrderSourceForViewing $source): void - { - $this->sources[] = $source; - } -} diff --git a/src/Core/Domain/Order/QueryResult/OrderStatusForViewing.php b/src/Core/Domain/Order/QueryResult/OrderStatusForViewing.php deleted file mode 100644 index cbfde865..00000000 --- a/src/Core/Domain/Order/QueryResult/OrderStatusForViewing.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\QueryResult; - -use DateTimeImmutable; - -class OrderStatusForViewing -{ - /** - * @var int - */ - private $orderStatusId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $color; - - /** - * @var DateTimeImmutable - */ - private $createdAt; - - /** - * @var bool - */ - private $withEmail; - - /** - * @var string|null First name of employee who updated order status or null otherwise - */ - private $employeeFirstName; - - /** - * @var string|null Last name of employee who updated order status or null otherwise - */ - private $employeeLastName; - - /** - * @var int - */ - private $orderHistoryId; - - /** - * @param int $orderHistoryId - * @param int $orderStatusId - * @param string $name - * @param string $color - * @param DateTimeImmutable $createdAt - * @param bool $withEmail - * @param string|null $employeeFirstName - * @param string|null $employeeLastName - */ - public function __construct( - int $orderHistoryId, - int $orderStatusId, - string $name, - string $color, - DateTimeImmutable $createdAt, - bool $withEmail, - ?string $employeeFirstName, - ?string $employeeLastName - ) { - $this->orderStatusId = $orderStatusId; - $this->name = $name; - $this->color = $color; - $this->createdAt = $createdAt; - $this->withEmail = $withEmail; - $this->employeeFirstName = $employeeFirstName; - $this->employeeLastName = $employeeLastName; - $this->orderHistoryId = $orderHistoryId; - } - - /** - * @return int - */ - public function getOrderHistoryId(): int - { - return $this->orderHistoryId; - } - - /** - * @return int - */ - public function getOrderStatusId(): int - { - return $this->orderStatusId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getColor(): string - { - return $this->color; - } - - /** - * @return DateTimeImmutable - */ - public function getCreatedAt(): DateTimeImmutable - { - return $this->createdAt; - } - - /** - * @return bool - */ - public function withEmail(): bool - { - return $this->withEmail; - } - - /** - * @return string|null - */ - public function getEmployeeFirstName(): ?string - { - return $this->employeeFirstName; - } - - /** - * @return string|null - */ - public function getEmployeeLastName(): ?string - { - return $this->employeeLastName; - } -} diff --git a/src/Core/Domain/Order/Status/OrderStatusColor.php b/src/Core/Domain/Order/Status/OrderStatusColor.php deleted file mode 100644 index b28c9349..00000000 --- a/src/Core/Domain/Order/Status/OrderStatusColor.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\Status; - -/** - * Defines colors for order statuses - */ -class OrderStatusColor -{ - /** - * Used for statuses that are waiting for customer actions. - * Example statuses: Awaiting bank wire payment, Awaiting check payment, On backorder (not paid). - */ - public const AWAITING_PAYMENT = '#34209E'; - - /** - * Used for statuses when further merchant action is required. - * Example statuses: Processing in progress, On backorder (paid), Payment accepted. - */ - public const ACCEPTED_PAYMENT = '#3498D8'; - - /** - * Used for statuses when no actions are required anymore. - * Example statuses: Shipped, Refunded, Delivered. - */ - public const COMPLETED = '#01b887'; - - /** - * Used for error statuses. - * Example statuses: Payment error. - */ - public const ERROR = '#E74C3C'; - - /** - * Used for statuses with special cases. - * Example statuses: Canceled. - */ - public const SPECIAL = '#2C3E50'; - - /** - * Class is not meant to be initialized. - */ - private function __construct() - { - } -} diff --git a/src/Core/Domain/Order/ValueObject/OrderDetailRefund.php b/src/Core/Domain/Order/ValueObject/OrderDetailRefund.php deleted file mode 100644 index 66b4cb7d..00000000 --- a/src/Core/Domain/Order/ValueObject/OrderDetailRefund.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\ValueObject; - -use InvalidArgumentException; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAmountException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidCancelProductException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Class ProductRefund - */ -class OrderDetailRefund -{ - /** - * @var int - */ - private $orderDetailId; - - /** - * @var int - */ - private $productQuantity; - - /** - * @var float|null - */ - private $refundedAmount; - - /** - * @param int $orderDetailId - * @param int $productQuantity - * @param string $refundedAmount - * - * @return self - * - * @throws InvalidCancelProductException - * @throws OrderException - */ - public static function createPartialRefund(int $orderDetailId, int $productQuantity, string $refundedAmount): self - { - try { - $decimalRefundedAmount = new Number($refundedAmount); - } catch (InvalidArgumentException $e) { - throw new InvalidAmountException(); - } - - if ($decimalRefundedAmount->isLowerOrEqualThanZero()) { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_AMOUNT); - } - - return new self($orderDetailId, $productQuantity, $decimalRefundedAmount); - } - - /** - * @param int $orderDetailId - * @param int $productQuantity - * - * @return self - * - * @throws OrderException - */ - public static function createStandardRefund(int $orderDetailId, int $productQuantity): self - { - return new self($orderDetailId, $productQuantity, null); - } - - /** - * @param int $orderDetailId - * @param int $productQuantity - * @param Number|null $refundedAmount - * - * @throws OrderException - */ - private function __construct(int $orderDetailId, int $productQuantity, ?Number $refundedAmount) - { - $this->assertOrderDetailIdIsGreaterThanZero($orderDetailId); - if (0 >= $productQuantity) { - throw new InvalidCancelProductException(InvalidCancelProductException::INVALID_QUANTITY); - } - $this->orderDetailId = $orderDetailId; - $this->productQuantity = $productQuantity; - $this->refundedAmount = $refundedAmount; - } - - /** - * @return int - */ - public function getOrderDetailId(): int - { - return $this->orderDetailId; - } - - /** - * @return int - */ - public function getProductQuantity(): int - { - return $this->productQuantity; - } - - /** - * @return Number|null - */ - public function getRefundedAmount(): ?Number - { - return $this->refundedAmount; - } - - /** - * @param int $orderDetailId - * - * @throws OrderException - */ - private function assertOrderDetailIdIsGreaterThanZero(int $orderDetailId) - { - if (0 > $orderDetailId) { - throw new OrderException(sprintf('Order detail id %s is invalid. Order detail id must be number that is greater than zero.', var_export($orderDetailId, true))); - } - } -} diff --git a/src/Core/Domain/Order/ValueObject/OrderId.php b/src/Core/Domain/Order/ValueObject/OrderId.php deleted file mode 100644 index 6ae291ab..00000000 --- a/src/Core/Domain/Order/ValueObject/OrderId.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; - -/** - * Order identity - */ -class OrderId -{ - /** - * @var int - */ - private $orderId; - - /** - * @param int $orderId - * - * @throws OrderException - */ - public function __construct($orderId) - { - $this->assertIntegerIsGreaterThanZero($orderId); - - $this->orderId = $orderId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->orderId; - } - - /** - * @param int $orderId - */ - private function assertIntegerIsGreaterThanZero($orderId) - { - if (!is_int($orderId) || 0 > $orderId) { - throw new OrderException(sprintf('Order id %s is invalid. Order id must be number that is greater than zero.', var_export($orderId, true))); - } - } -} diff --git a/src/Core/Domain/Order/VoucherRefundType.php b/src/Core/Domain/Order/VoucherRefundType.php deleted file mode 100644 index b7b50861..00000000 --- a/src/Core/Domain/Order/VoucherRefundType.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Order; - -/** - * When refunding an order that was partially paid with a voucher you have different way - * to refund it. - */ -class VoucherRefundType -{ - /** - * Refund based on product prices (the initial voucher amount is ignored) - */ - const PRODUCT_PRICES_REFUND = 0; - - /** - * Refund based on product prices, but do not refund the voucher amount - */ - const PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND = 1; - - /** - * The refund amount is specified manually - */ - const SPECIFIC_AMOUNT_REFUND = 2; -} diff --git a/src/Core/Domain/OrderMessage/Command/AddOrderMessageCommand.php b/src/Core/Domain/OrderMessage/Command/AddOrderMessageCommand.php deleted file mode 100644 index 4839af28..00000000 --- a/src/Core/Domain/OrderMessage/Command/AddOrderMessageCommand.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageConstraintException; - -/** - * Add new order message - */ -class AddOrderMessageCommand -{ - /** - * @var string[] - */ - private $localizedName; - - /** - * @var string[] - */ - private $localizedMessage; - - /** - * @param string[] $localizedName - * @param string[] $localizedMessage - */ - public function __construct(array $localizedName, array $localizedMessage) - { - if (empty($localizedName)) { - throw new OrderMessageConstraintException('OrderMessage name must not be empty'); - } - - if (empty($localizedMessage)) { - throw new OrderMessageConstraintException('OrderMessage message must not be empty'); - } - - $this->localizedName = $localizedName; - $this->localizedMessage = $localizedMessage; - } - - /** - * @return string[] - */ - public function getLocalizedName(): array - { - return $this->localizedName; - } - - /** - * @return string[] - */ - public function getLocalizedMessage(): array - { - return $this->localizedMessage; - } -} diff --git a/src/Core/Domain/OrderMessage/Command/BulkDeleteOrderMessageCommand.php b/src/Core/Domain/OrderMessage/Command/BulkDeleteOrderMessageCommand.php deleted file mode 100644 index 5adae1ef..00000000 --- a/src/Core/Domain/OrderMessage/Command/BulkDeleteOrderMessageCommand.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Delete given order messages - */ -class BulkDeleteOrderMessageCommand -{ - /** - * @var OrderMessageId[] - */ - private $orderMessageIds; - - /** - * @param int[] $orderMessageIds - */ - public function __construct(array $orderMessageIds) - { - foreach ($orderMessageIds as $orderMessageId) { - $this->orderMessageIds[] = new OrderMessageId($orderMessageId); - } - } - - /** - * @return OrderMessageId[] - */ - public function getOrderMessageIds(): array - { - return $this->orderMessageIds; - } -} diff --git a/src/Core/Domain/OrderMessage/Command/DeleteOrderMessageCommand.php b/src/Core/Domain/OrderMessage/Command/DeleteOrderMessageCommand.php deleted file mode 100644 index 05c6a51a..00000000 --- a/src/Core/Domain/OrderMessage/Command/DeleteOrderMessageCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Delete given order message - */ -class DeleteOrderMessageCommand -{ - /** - * @var OrderMessageId - */ - private $orderMessageId; - - /** - * @param int $orderMessageId - */ - public function __construct(int $orderMessageId) - { - $this->orderMessageId = new OrderMessageId($orderMessageId); - } - - /** - * @return OrderMessageId - */ - public function getOrderMessageId(): OrderMessageId - { - return $this->orderMessageId; - } -} diff --git a/src/Core/Domain/OrderMessage/Command/EditOrderMessageCommand.php b/src/Core/Domain/OrderMessage/Command/EditOrderMessageCommand.php deleted file mode 100644 index 6fec5a14..00000000 --- a/src/Core/Domain/OrderMessage/Command/EditOrderMessageCommand.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Edit given order message - */ -class EditOrderMessageCommand -{ - /** - * @var OrderMessageId - */ - private $orderMessageId; - - /** - * @var string[]|null - */ - private $localizedName; - - /** - * @var string[]|null - */ - private $localizedMessage; - - /** - * @param int $orderMessageId - * @param string[]|null $localizedName Array of localized name or null if name should not be edited - * @param string[]|null $localizedMessage Array of localized message or null if message should not be edited - */ - public function __construct(int $orderMessageId, array $localizedName = null, array $localizedMessage = null) - { - $this->orderMessageId = new OrderMessageId($orderMessageId); - $this->localizedName = $localizedName; - $this->localizedMessage = $localizedMessage; - } - - /** - * @return OrderMessageId - */ - public function getOrderMessageId(): OrderMessageId - { - return $this->orderMessageId; - } - - /** - * @return string[]|null - */ - public function getLocalizedName(): ?array - { - return $this->localizedName; - } - - /** - * @return string[]|null - */ - public function getLocalizedMessage(): ?array - { - return $this->localizedMessage; - } -} diff --git a/src/Core/Domain/OrderMessage/CommandHandler/AddOrderMessageHandlerInterface.php b/src/Core/Domain/OrderMessage/CommandHandler/AddOrderMessageHandlerInterface.php deleted file mode 100644 index f632dbb6..00000000 --- a/src/Core/Domain/OrderMessage/CommandHandler/AddOrderMessageHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\AddOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Interface for service that handles adding order message - */ -interface AddOrderMessageHandlerInterface -{ - /** - * @param AddOrderMessageCommand $command - * - * @return OrderMessageId - */ - public function handle(AddOrderMessageCommand $command): OrderMessageId; -} diff --git a/src/Core/Domain/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandlerInterface.php b/src/Core/Domain/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandlerInterface.php deleted file mode 100644 index 0443dae9..00000000 --- a/src/Core/Domain/OrderMessage/CommandHandler/BulkDeleteOrderMessageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\BulkDeleteOrderMessageCommand; - -/** - * Interface for service that handles deleting of order messages - */ -interface BulkDeleteOrderMessageHandlerInterface -{ - /*** - * @param BulkDeleteOrderMessageCommand $command - */ - public function handle(BulkDeleteOrderMessageCommand $command): void; -} diff --git a/src/Core/Domain/OrderMessage/CommandHandler/DeleteOrderMessageHandlerInterface.php b/src/Core/Domain/OrderMessage/CommandHandler/DeleteOrderMessageHandlerInterface.php deleted file mode 100644 index e00e07b0..00000000 --- a/src/Core/Domain/OrderMessage/CommandHandler/DeleteOrderMessageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\DeleteOrderMessageCommand; - -/** - * Interface for service that handles deleting order message - */ -interface DeleteOrderMessageHandlerInterface -{ - /** - * @param DeleteOrderMessageCommand $command - */ - public function handle(DeleteOrderMessageCommand $command): void; -} diff --git a/src/Core/Domain/OrderMessage/CommandHandler/EditOrderMessageHandlerInterface.php b/src/Core/Domain/OrderMessage/CommandHandler/EditOrderMessageHandlerInterface.php deleted file mode 100644 index 19710693..00000000 --- a/src/Core/Domain/OrderMessage/CommandHandler/EditOrderMessageHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\EditOrderMessageCommand; - -/** - * Interface for service that handles editing order message - */ -interface EditOrderMessageHandlerInterface -{ - /** - * @param EditOrderMessageCommand $command - */ - public function handle(EditOrderMessageCommand $command): void; -} diff --git a/src/Core/Domain/OrderMessage/Exception/OrderMessageConstraintException.php b/src/Core/Domain/OrderMessage/Exception/OrderMessageConstraintException.php deleted file mode 100644 index 328bd82d..00000000 --- a/src/Core/Domain/OrderMessage/Exception/OrderMessageConstraintException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception; - -class OrderMessageConstraintException extends OrderMessageException -{ -} diff --git a/src/Core/Domain/OrderMessage/Exception/OrderMessageException.php b/src/Core/Domain/OrderMessage/Exception/OrderMessageException.php deleted file mode 100644 index 1ea3e362..00000000 --- a/src/Core/Domain/OrderMessage/Exception/OrderMessageException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for order message subdomain - */ -class OrderMessageException extends DomainException -{ - public const FAILED_DELETE = 1; - public const FAILED_BULK_DELETE = 2; -} diff --git a/src/Core/Domain/OrderMessage/Exception/OrderMessageNotFoundException.php b/src/Core/Domain/OrderMessage/Exception/OrderMessageNotFoundException.php deleted file mode 100644 index 9ab77a7b..00000000 --- a/src/Core/Domain/OrderMessage/Exception/OrderMessageNotFoundException.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; -use Throwable; - -/** - * Thrown when order message is not found - */ -class OrderMessageNotFoundException extends OrderMessageException -{ - /** - * @var OrderMessageId - */ - private $orderMessageId; - - /** - * @param OrderMessageId $orderMessageId - * @param string $message - * @param int $code - * @param Throwable|null $previous - */ - public function __construct( - OrderMessageId $orderMessageId, - string $message = '', - int $code = 0, - Throwable $previous = null - ) { - parent::__construct($message, $code, $previous); - - $this->orderMessageId = $orderMessageId; - } - - /** - * @return OrderMessageId - */ - public function getOrderMessageId(): OrderMessageId - { - return $this->orderMessageId; - } -} diff --git a/src/Core/Domain/OrderMessage/OrderMessageConstraint.php b/src/Core/Domain/OrderMessage/OrderMessageConstraint.php deleted file mode 100644 index 095adfad..00000000 --- a/src/Core/Domain/OrderMessage/OrderMessageConstraint.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage; - -/** - * Defines constraints for Order message attributes - */ -class OrderMessageConstraint -{ - public const MAX_NAME_LENGTH = 128; - public const MAX_MESSAGE_LENGTH = 1200; -} diff --git a/src/Core/Domain/OrderMessage/Query/GetOrderMessageForEditing.php b/src/Core/Domain/OrderMessage/Query/GetOrderMessageForEditing.php deleted file mode 100644 index 976bc880..00000000 --- a/src/Core/Domain/OrderMessage/Query/GetOrderMessageForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Get order message data for editing - */ -class GetOrderMessageForEditing -{ - /** - * @var OrderMessageId - */ - private $orderMessageId; - - /** - * @param int $orderMessageId - */ - public function __construct(int $orderMessageId) - { - $this->orderMessageId = new OrderMessageId($orderMessageId); - } - - /** - * @return OrderMessageId - */ - public function getOrderMessageId(): OrderMessageId - { - return $this->orderMessageId; - } -} diff --git a/src/Core/Domain/OrderMessage/QueryHandler/GetOrderMessageForEditingHandlerInterface.php b/src/Core/Domain/OrderMessage/QueryHandler/GetOrderMessageForEditingHandlerInterface.php deleted file mode 100644 index 9e4d0307..00000000 --- a/src/Core/Domain/OrderMessage/QueryHandler/GetOrderMessageForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query\GetOrderMessageForEditing; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryResult\EditableOrderMessage; - -/** - * Interface for service that handles retrieving order message data - */ -interface GetOrderMessageForEditingHandlerInterface -{ - /** - * @param GetOrderMessageForEditing $query - * - * @return EditableOrderMessage - */ - public function handle(GetOrderMessageForEditing $query): EditableOrderMessage; -} diff --git a/src/Core/Domain/OrderMessage/QueryResult/EditableOrderMessage.php b/src/Core/Domain/OrderMessage/QueryResult/EditableOrderMessage.php deleted file mode 100644 index 372c6993..00000000 --- a/src/Core/Domain/OrderMessage/QueryResult/EditableOrderMessage.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Transfers current order message data that can be edited - */ -class EditableOrderMessage -{ - /** - * @var OrderMessageId - */ - private $orderMessageId; - - /** - * @var string[] - */ - private $localizedName; - - /** - * @var string[] - */ - private $localizedMessage; - - /** - * @param OrderMessageId $orderMessageId - * @param string[] $localizedName - * @param string[] $localizedMessage - */ - public function __construct(OrderMessageId $orderMessageId, array $localizedName, array $localizedMessage) - { - $this->orderMessageId = $orderMessageId; - $this->localizedName = $localizedName; - $this->localizedMessage = $localizedMessage; - } - - /** - * @return OrderMessageId - */ - public function getOrderMessageId(): OrderMessageId - { - return $this->orderMessageId; - } - - /** - * @return string[] - */ - public function getLocalizedName(): array - { - return $this->localizedName; - } - - /** - * @return string[] - */ - public function getLocalizedMessage(): array - { - return $this->localizedMessage; - } -} diff --git a/src/Core/Domain/OrderMessage/ValueObject/OrderMessageId.php b/src/Core/Domain/OrderMessage/ValueObject/OrderMessageId.php deleted file mode 100644 index 4c38f8c0..00000000 --- a/src/Core/Domain/OrderMessage/ValueObject/OrderMessageId.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject; - -/** - * Order message identity - */ -class OrderMessageId -{ - /** - * @var int - */ - private $orderMessageId; - - /** - * @param int $orderMessageId - */ - public function __construct(int $orderMessageId) - { - $this->orderMessageId = $orderMessageId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->orderMessageId; - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Command/BulkDeleteAttributeCommand.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Command/BulkDeleteAttributeCommand.php deleted file mode 100644 index 693dcdc2..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Command/BulkDeleteAttributeCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\ValueObject\AttributeId; - -/** - * Deletes attributes in bulk action - */ -final class BulkDeleteAttributeCommand -{ - /** - * @var AttributeId[] - */ - private $attributeIds; - - /** - * @param int[] $attributeIds - * - * @throws AttributeConstraintException - */ - public function __construct(array $attributeIds) - { - $this->setAttributeIds($attributeIds); - } - - /** - * @return AttributeId[] - */ - public function getAttributeIds() - { - return $this->attributeIds; - } - - /** - * @param array $attributeIds - * - * @throws AttributeConstraintException - */ - private function setAttributeIds(array $attributeIds) - { - foreach ($attributeIds as $attributeId) { - $this->attributeIds[] = new AttributeId($attributeId); - } - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Command/DeleteAttributeCommand.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Command/DeleteAttributeCommand.php deleted file mode 100644 index ad99c9a3..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Command/DeleteAttributeCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\ValueObject\AttributeId; - -/** - * Deletes Attribute by provided id - */ -final class DeleteAttributeCommand -{ - /** - * @var AttributeId - */ - private $attributeId; - - /** - * @param int $attributeId - * - * @throws AttributeConstraintException - */ - public function __construct($attributeId) - { - $this->attributeId = new AttributeId($attributeId); - } - - /** - * @return AttributeId - */ - public function getAttributeId() - { - return $this->attributeId; - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/BulkDeleteAttributeHandlerInterface.php b/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/BulkDeleteAttributeHandlerInterface.php deleted file mode 100644 index 25127656..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/BulkDeleteAttributeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\BulkDeleteAttributeCommand; - -/** - * Interface for handling command which deletes attributes in bulk action - */ -interface BulkDeleteAttributeHandlerInterface -{ - /** - * @param BulkDeleteAttributeCommand $command - */ - public function handle(BulkDeleteAttributeCommand $command); -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/DeleteAttributeHandlerInterface.php b/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/DeleteAttributeHandlerInterface.php deleted file mode 100644 index 9cd22fa0..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/CommandHandler/DeleteAttributeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\DeleteAttributeCommand; - -/** - * Interface for handling command which deletes Attribute - */ -interface DeleteAttributeHandlerInterface -{ - /** - * @param DeleteAttributeCommand $command - */ - public function handle(DeleteAttributeCommand $command); -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeConstraintException.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeConstraintException.php deleted file mode 100644 index fdfa8bb4..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception; - -/** - * Is thrown when attribute constraints are violated - */ -class AttributeConstraintException extends AttributeException -{ - /** - * When attribute id contains invalid values - */ - const INVALID_ID = 10; -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeException.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeException.php deleted file mode 100644 index 2a6191f9..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for attribute subdomain - */ -class AttributeException extends DomainException -{ -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeNotFoundException.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeNotFoundException.php deleted file mode 100644 index 80435c63..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/AttributeNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception; - -/** - * Thrown when required attribute cannot be found - */ -class AttributeNotFoundException extends AttributeException -{ -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/DeleteAttributeException.php b/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/DeleteAttributeException.php deleted file mode 100644 index 3bf2e7a4..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/Exception/DeleteAttributeException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception; - -/** - * Is thrown when attribute deletion fails - */ -class DeleteAttributeException extends AttributeException -{ - /** - * When fails to delete single attribute - */ - const FAILED_DELETE = 10; - - /** - * When deleting fails in bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/Product/AttributeGroup/Attribute/ValueObject/AttributeId.php b/src/Core/Domain/Product/AttributeGroup/Attribute/ValueObject/AttributeId.php deleted file mode 100644 index 1d8ad98f..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Attribute/ValueObject/AttributeId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeConstraintException; - -/** - * Provides identification data of Attribute - */ -final class AttributeId -{ - /** - * @var int - */ - private $attributeId; - - /** - * @param int $attributeId - * - * @throws AttributeConstraintException - */ - public function __construct($attributeId) - { - $this->assertIsIntegerGreaterThanZero($attributeId); - $this->attributeId = $attributeId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->attributeId; - } - - /** - * Validates that the value is integer and is greater than zero - * - * @param $value - * - * @throws AttributeConstraintException - */ - private function assertIsIntegerGreaterThanZero($value) - { - if (!is_int($value) || 0 >= $value) { - throw new AttributeConstraintException(sprintf('Invalid attribute id "%s".', var_export($value, true)), AttributeConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/Command/BulkDeleteAttributeGroupCommand.php b/src/Core/Domain/Product/AttributeGroup/Command/BulkDeleteAttributeGroupCommand.php deleted file mode 100644 index 1112d6bc..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Command/BulkDeleteAttributeGroupCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\ValueObject\AttributeGroupId; - -/** - * Deletes attribute groups in bulk action by provided ids - */ -final class BulkDeleteAttributeGroupCommand -{ - /** - * @var AttributeGroupId[] - */ - private $attributeGroupIds; - - /** - * @param int[] $attributeGroupIds - * - * @throws AttributeGroupConstraintException - */ - public function __construct(array $attributeGroupIds) - { - $this->setAttributeGroupIds($attributeGroupIds); - } - - /** - * @return AttributeGroupId[] - */ - public function getAttributeGroupIds() - { - return $this->attributeGroupIds; - } - - /** - * @param array $attributeGroupIds - * - * @throws AttributeGroupConstraintException - */ - private function setAttributeGroupIds(array $attributeGroupIds) - { - foreach ($attributeGroupIds as $attributeGroupId) { - $this->attributeGroupIds[] = new AttributeGroupId($attributeGroupId); - } - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/Command/DeleteAttributeGroupCommand.php b/src/Core/Domain/Product/AttributeGroup/Command/DeleteAttributeGroupCommand.php deleted file mode 100644 index b454926f..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Command/DeleteAttributeGroupCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\ValueObject\AttributeGroupId; - -/** - * Deletes attribute group by provided id - */ -final class DeleteAttributeGroupCommand -{ - /** - * @var AttributeGroupId - */ - private $attributeGroupId; - - /** - * @param int $attributeGroupId - * - * @throws AttributeGroupConstraintException - */ - public function __construct($attributeGroupId) - { - $this->attributeGroupId = new AttributeGroupId($attributeGroupId); - } - - /** - * @return AttributeGroupId - */ - public function getAttributeGroupId() - { - return $this->attributeGroupId; - } -} diff --git a/src/Core/Domain/Product/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandlerInterface.php b/src/Core/Domain/Product/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandlerInterface.php deleted file mode 100644 index 49b99346..00000000 --- a/src/Core/Domain/Product/AttributeGroup/CommandHandler/BulkDeleteAttributeGroupHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\BulkDeleteAttributeGroupCommand; - -/** - * Interface for handling command which deletes mutliple attribute groups - */ -interface BulkDeleteAttributeGroupHandlerInterface -{ - /** - * @param BulkDeleteAttributeGroupCommand $command - */ - public function handle(BulkDeleteAttributeGroupCommand $command); -} diff --git a/src/Core/Domain/Product/AttributeGroup/CommandHandler/DeleteAttributeGroupHandlerInterface.php b/src/Core/Domain/Product/AttributeGroup/CommandHandler/DeleteAttributeGroupHandlerInterface.php deleted file mode 100644 index f3430de1..00000000 --- a/src/Core/Domain/Product/AttributeGroup/CommandHandler/DeleteAttributeGroupHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\DeleteAttributeGroupCommand; - -/** - * Interface for handling command which deletes attribute group - */ -interface DeleteAttributeGroupHandlerInterface -{ - /** - * @param DeleteAttributeGroupCommand $command - */ - public function handle(DeleteAttributeGroupCommand $command); -} diff --git a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupConstraintException.php b/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupConstraintException.php deleted file mode 100644 index 519b75d8..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception; - -/** - * Is thrown when attribute group constraints are violated - */ -class AttributeGroupConstraintException extends AttributeGroupException -{ - /** - * When attribute group Id contains invalid values - */ - const INVALID_ID = 10; -} diff --git a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupException.php b/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupException.php deleted file mode 100644 index 2de43786..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for attribute group subdomain - */ -class AttributeGroupException extends DomainException -{ -} diff --git a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupNotFoundException.php b/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupNotFoundException.php deleted file mode 100644 index 28a37d0f..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Exception/AttributeGroupNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception; - -/** - * Is thrown when required attribute group cannot be found - */ -class AttributeGroupNotFoundException extends AttributeGroupException -{ -} diff --git a/src/Core/Domain/Product/AttributeGroup/Exception/DeleteAttributeGroupException.php b/src/Core/Domain/Product/AttributeGroup/Exception/DeleteAttributeGroupException.php deleted file mode 100644 index 09337e74..00000000 --- a/src/Core/Domain/Product/AttributeGroup/Exception/DeleteAttributeGroupException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception; - -/** - * Is thrown when deleting attribute group fails - */ -class DeleteAttributeGroupException extends AttributeGroupException -{ - /** - * When trying to delete single attribute group fails - */ - const FAILED_DELETE = 10; - - /** - * When deleting in bulk action fails - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/Product/AttributeGroup/ValueObject/AttributeGroupId.php b/src/Core/Domain/Product/AttributeGroup/ValueObject/AttributeGroupId.php deleted file mode 100644 index 1bff90a4..00000000 --- a/src/Core/Domain/Product/AttributeGroup/ValueObject/AttributeGroupId.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupConstraintException; - -/** - * Provides attribute group identification data - */ -final class AttributeGroupId -{ - /** - * @var int - */ - private $attributeGroupId; - - /** - * @param int $attributeGroupId - * - * @throws AttributeGroupConstraintException - */ - public function __construct($attributeGroupId) - { - $this->assertIsIntegerGreaterThanZero($attributeGroupId); - $this->attributeGroupId = $attributeGroupId; - } - - /** - * @return mixed - */ - public function getAttributeGroupId() - { - return $this->attributeGroupId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->attributeGroupId; - } - - /** - * Validates that the value is integer and is greater than zero - * - * @param $value - * - * @throws AttributeGroupConstraintException - */ - private function assertIsIntegerGreaterThanZero($value) - { - if (!is_int($value) || 0 >= $value) { - throw new AttributeGroupConstraintException(sprintf('Invalid attribute group id "%s".', var_export($value, true)), AttributeGroupConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Product/Combination/Exception/CombinationConstraintException.php b/src/Core/Domain/Product/Combination/Exception/CombinationConstraintException.php deleted file mode 100644 index 0aebfa04..00000000 --- a/src/Core/Domain/Product/Combination/Exception/CombinationConstraintException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Combination\Exception; - -/** - * Thrown when combination constraints are violated - */ -class CombinationConstraintException extends CombinationException -{ - const INVALID_ID = 1; -} diff --git a/src/Core/Domain/Product/Combination/Exception/CombinationException.php b/src/Core/Domain/Product/Combination/Exception/CombinationException.php deleted file mode 100644 index daf7f982..00000000 --- a/src/Core/Domain/Product/Combination/Exception/CombinationException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Combination\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for product combination subdomain - */ -class CombinationException extends DomainException -{ -} diff --git a/src/Core/Domain/Product/Combination/ValueObject/CombinationId.php b/src/Core/Domain/Product/Combination/ValueObject/CombinationId.php deleted file mode 100644 index 80498257..00000000 --- a/src/Core/Domain/Product/Combination/ValueObject/CombinationId.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Combination\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Product\Combination\Exception\CombinationConstraintException; - -/** - * Holds product combination identification data - */ -class CombinationId -{ - /** - * @var int - */ - private $combinationId; - - /** - * @param int $combinationId - * - * @throws CombinationConstraintException - */ - public function __construct(int $combinationId) - { - $this->assertValueIsPositive($combinationId); - $this->combinationId = $combinationId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->combinationId; - } - - /** - * @param int $value - * - * @throws CombinationConstraintException - */ - private function assertValueIsPositive(int $value) - { - if (0 >= $value) { - throw new CombinationConstraintException(sprintf('Combination id must be positive integer. "%s" given', $value), CombinationConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Product/Command/AssignProductToCategoryCommand.php b/src/Core/Domain/Product/Command/AssignProductToCategoryCommand.php deleted file mode 100644 index 0b481d9e..00000000 --- a/src/Core/Domain/Product/Command/AssignProductToCategoryCommand.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Command; - -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Class AssignProductToCategoryCommand adds a product to a category. - */ -class AssignProductToCategoryCommand -{ - /** - * @var CategoryId - */ - private $categoryId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @param int $categoryId - * @param int $productId - * - * @throws CategoryConstraintException - * @throws ProductConstraintException */ - public function __construct($categoryId, $productId) - { - $this->setCategoryId($categoryId); - $this->setProductId($productId); - } - - /** - * @param int $categoryId - * - * @return self - */ - public function setCategoryId(int $categoryId): AssignProductToCategoryCommand - { - $this->categoryId = new CategoryId($categoryId); - - return $this; - } - - /** - * @return CategoryId - */ - public function getCategoryId(): CategoryId - { - return $this->categoryId; - } - - /** - * @param int $productId - * - * @return self - */ - public function setProductId(int $productId): AssignProductToCategoryCommand - { - $this->productId = new ProductId($productId); - - return $this; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } -} diff --git a/src/Core/Domain/Product/Command/UpdateProductStatusCommand.php b/src/Core/Domain/Product/Command/UpdateProductStatusCommand.php deleted file mode 100644 index 2956e50e..00000000 --- a/src/Core/Domain/Product/Command/UpdateProductStatusCommand.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Command; - -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Class UpdateProductStatusCommand update a given product status - */ -class UpdateProductStatusCommand -{ - /** - * @var ProductId - */ - private $productId; - - /** - * @var bool - */ - private $enable; - - /** - * UpdateProductStatusCommand constructor. - * - * @param int $productId - * @param bool $enable - */ - public function __construct(int $productId, bool $enable) - { - $this->productId = new ProductId($productId); - $this->enable = $enable; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return bool - */ - public function getEnable(): bool - { - return $this->enable; - } -} diff --git a/src/Core/Domain/Product/CommandHandler/AssignProductToCategoryHandlerInterface.php b/src/Core/Domain/Product/CommandHandler/AssignProductToCategoryHandlerInterface.php deleted file mode 100644 index 5e28e9b8..00000000 --- a/src/Core/Domain/Product/CommandHandler/AssignProductToCategoryHandlerInterface.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\Command\AssignProductToCategoryCommand; - -interface AssignProductToCategoryHandlerInterface -{ - /** - * @param AssignProductToCategoryCommand $command - */ - public function handle(AssignProductToCategoryCommand $command); -} diff --git a/src/Core/Domain/Product/CommandHandler/UpdateProductStatusCommandHandlerInterface.php b/src/Core/Domain/Product/CommandHandler/UpdateProductStatusCommandHandlerInterface.php deleted file mode 100644 index 6752d5e8..00000000 --- a/src/Core/Domain/Product/CommandHandler/UpdateProductStatusCommandHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductStatusCommand; - -/** - * Interface for service that set product to be enabled or disabled - */ -interface UpdateProductStatusCommandHandlerInterface -{ - /** - * @param UpdateProductStatusCommand $command - */ - public function handle(UpdateProductStatusCommand $command); -} diff --git a/src/Core/Domain/Product/Customization/CustomizationSettings.php b/src/Core/Domain/Product/Customization/CustomizationSettings.php deleted file mode 100644 index 35aba928..00000000 --- a/src/Core/Domain/Product/Customization/CustomizationSettings.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Customization; - -/** - * Defines settings for customizations - */ -final class CustomizationSettings -{ - /** - * Maximum allowed length for customization text field value - */ - const MAX_TEXT_LENGTH = 255; -} diff --git a/src/Core/Domain/Product/Customization/Exception/CustomizationConstraintException.php b/src/Core/Domain/Product/Customization/Exception/CustomizationConstraintException.php deleted file mode 100644 index 0186f7f3..00000000 --- a/src/Core/Domain/Product/Customization/Exception/CustomizationConstraintException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Customization\Exception; - -/** - * Thrown when customization constraints are violated - */ -class CustomizationConstraintException extends CustomizationException -{ - /** - * When customization field is required to be filled - */ - const FIELD_IS_REQUIRED = 1; - - /** - * When customization field value length is exceeded - */ - const FIELD_IS_TOO_LONG = 2; - - /** - * When customization id is invalid - */ - const INVALID_ID = 3; -} diff --git a/src/Core/Domain/Product/Customization/Exception/CustomizationException.php b/src/Core/Domain/Product/Customization/Exception/CustomizationException.php deleted file mode 100644 index 6a3d3b6a..00000000 --- a/src/Core/Domain/Product/Customization/Exception/CustomizationException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Customization\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductException; - -/** - * Base exception for Product/Customization subdomain - */ -class CustomizationException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Customization/ValueObject/CustomizationId.php b/src/Core/Domain/Product/Customization/ValueObject/CustomizationId.php deleted file mode 100644 index 3f873283..00000000 --- a/src/Core/Domain/Product/Customization/ValueObject/CustomizationId.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Customization\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Product\Customization\Exception\CustomizationConstraintException; - -/** - * Holds product customization identification data - */ -class CustomizationId -{ - /** - * @var int - */ - private $customizationId; - - /** - * @param int $customizationId - */ - public function __construct(int $customizationId) - { - $this->customizationId = $customizationId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->customizationId; - } - - /** - * @param int $value - * - * @throws CustomizationConstraintException - */ - private function assertValueIsPositive(int $value) - { - if (0 >= $value) { - throw new CustomizationConstraintException(sprintf('Customization id must be positive integer. "%s" given', $value), CustomizationConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Product/Exception/CannotAssignProductToCategoryException.php b/src/Core/Domain/Product/Exception/CannotAssignProductToCategoryException.php deleted file mode 100644 index 9d5eaf7e..00000000 --- a/src/Core/Domain/Product/Exception/CannotAssignProductToCategoryException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -/** - * Is thrown when the assignation of a product to a category failed - */ -class CannotAssignProductToCategoryException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Exception/CannotUpdateProductException.php b/src/Core/Domain/Product/Exception/CannotUpdateProductException.php deleted file mode 100644 index 0de10d49..00000000 --- a/src/Core/Domain/Product/Exception/CannotUpdateProductException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -/** - * Is thrown when updating a product failed - */ -class CannotUpdateProductException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Exception/ProductConstraintException.php b/src/Core/Domain/Product/Exception/ProductConstraintException.php deleted file mode 100644 index 05e693da..00000000 --- a/src/Core/Domain/Product/Exception/ProductConstraintException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -class ProductConstraintException extends ProductException -{ - /** - * Code is used when invalid id is supplied. - */ - const INVALID_ID = 10; -} diff --git a/src/Core/Domain/Product/Exception/ProductCustomizationNotFoundException.php b/src/Core/Domain/Product/Exception/ProductCustomizationNotFoundException.php deleted file mode 100644 index 11b905aa..00000000 --- a/src/Core/Domain/Product/Exception/ProductCustomizationNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -/** - * Is thrown when the customization of a product is not found - */ -class ProductCustomizationNotFoundException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Exception/ProductException.php b/src/Core/Domain/Product/Exception/ProductException.php deleted file mode 100644 index d02e67a4..00000000 --- a/src/Core/Domain/Product/Exception/ProductException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Is base exception for Product subdomain - */ -class ProductException extends DomainException -{ -} diff --git a/src/Core/Domain/Product/Exception/ProductNotFoundException.php b/src/Core/Domain/Product/Exception/ProductNotFoundException.php deleted file mode 100644 index 6a35cb5b..00000000 --- a/src/Core/Domain/Product/Exception/ProductNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -/** - * Is thrown when product is not found - */ -class ProductNotFoundException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Exception/ProductOutOfStockException.php b/src/Core/Domain/Product/Exception/ProductOutOfStockException.php deleted file mode 100644 index 1c436719..00000000 --- a/src/Core/Domain/Product/Exception/ProductOutOfStockException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Exception; - -/** - * Is thrown when using product (e.g. adding to cart) which is out of stock - */ -class ProductOutOfStockException extends ProductException -{ -} diff --git a/src/Core/Domain/Product/Query/GetProductIsEnabled.php b/src/Core/Domain/Product/Query/GetProductIsEnabled.php deleted file mode 100644 index c04d9383..00000000 --- a/src/Core/Domain/Product/Query/GetProductIsEnabled.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Query; - -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Get current status (enabled/disabled) for a given product - */ -class GetProductIsEnabled -{ - /** - * @var ProductId - */ - private $productId; - - /** - * GetProductIsEnabled constructor. - * - * @param int $productId - */ - public function __construct(int $productId) - { - $this->productId = new ProductId($productId); - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } -} diff --git a/src/Core/Domain/Product/Query/SearchProducts.php b/src/Core/Domain/Product/Query/SearchProducts.php deleted file mode 100644 index 139762aa..00000000 --- a/src/Core/Domain/Product/Query/SearchProducts.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\Query; - -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\AlphaIsoCode; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\Order\ValueObject\OrderId; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductException; - -/** - * Queries for products by provided search phrase - */ -class SearchProducts -{ - /** - * @var string - */ - private $phrase; - - /** - * @var int - */ - private $resultsLimit; - - /** - * @var AlphaIsoCode - */ - private $alphaIsoCode; - - /** - * @var OrderId|null - */ - private $orderId; - - /** - * @param string $phrase - * @param int $resultsLimit - * @param string $isoCode - * @param int|null $orderId - * - * @throws ProductException - * @throws CurrencyConstraintException - */ - public function __construct( - string $phrase, - int $resultsLimit, - string $isoCode, - ?int $orderId = null - ) { - $this->assertIsNotEmptyString($phrase); - $this->phrase = $phrase; - $this->resultsLimit = $resultsLimit; - $this->alphaIsoCode = new AlphaIsoCode($isoCode); - if (null !== $orderId) { - $this->setOrderId($orderId); - } - } - - /** - * @return AlphaIsoCode - */ - public function getAlphaIsoCode(): AlphaIsoCode - { - return $this->alphaIsoCode; - } - - /** - * @return string - */ - public function getPhrase() - { - return $this->phrase; - } - - /** - * @return int - */ - public function getResultsLimit(): int - { - return $this->resultsLimit; - } - - /** - * @return OrderId|null - */ - public function getOrderId(): ?OrderId - { - return $this->orderId; - } - - /** - * @param int $orderId - * - * @throws OrderException - */ - private function setOrderId(int $orderId): void - { - $this->orderId = new OrderId($orderId); - } - - /** - * @param string $phrase - * - * @throws ProductException - */ - private function assertIsNotEmptyString(string $phrase): void - { - if (empty($phrase) || !is_string($phrase)) { - throw new ProductException('Product search phrase must be a not empty string'); - } - } -} diff --git a/src/Core/Domain/Product/QueryHandler/GetProductIsEnabledHandlerInterface.php b/src/Core/Domain/Product/QueryHandler/GetProductIsEnabledHandlerInterface.php deleted file mode 100644 index 62106426..00000000 --- a/src/Core/Domain/Product/QueryHandler/GetProductIsEnabledHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductIsEnabled; - -/** - * Interface for service that handles getting product status. - */ -interface GetProductIsEnabledHandlerInterface -{ - /** - * @param GetProductIsEnabled $query - * - * @return bool - */ - public function handle(GetProductIsEnabled $query); -} diff --git a/src/Core/Domain/Product/QueryHandler/SearchProductsHandlerInterface.php b/src/Core/Domain/Product/QueryHandler/SearchProductsHandlerInterface.php deleted file mode 100644 index 5e1a8b0b..00000000 --- a/src/Core/Domain/Product/QueryHandler/SearchProductsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Product\Query\SearchProducts; -use PrestaShop\PrestaShop\Core\Domain\Product\QueryResult\FoundProduct; - -/** - * Interface for handling SearchProducts query - */ -interface SearchProductsHandlerInterface -{ - /** - * @param SearchProducts $query - * - * @return FoundProduct[] - */ - public function handle(SearchProducts $query): array; -} diff --git a/src/Core/Domain/Product/QueryResult/FoundProduct.php b/src/Core/Domain/Product/QueryResult/FoundProduct.php deleted file mode 100644 index f4a9b8a0..00000000 --- a/src/Core/Domain/Product/QueryResult/FoundProduct.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\QueryResult; - -/** - * DTO for product that was found by search - */ -class FoundProduct -{ - /** - * @var bool - */ - private $availableOutOfStock; - - /** - * @var int - */ - private $productId; - - /** - * @var string - */ - private $name; - - /** - * @var float - */ - private $taxRate; - - /** - * @var string - */ - private $formattedPrice; - - /** - * @var float - */ - private $priceTaxIncl; - - /** - * @var float - */ - private $priceTaxExcl; - - /** - * @var int - */ - private $stock; - - /** - * @var string - */ - private $location; - - /** - * @var ProductCombination[] - */ - private $combinations; - - /** - * @var ProductCustomizationField[] - */ - private $customizationFields; - - /** - * @param int $productId - * @param string $name - * @param string $formattedPrice - * @param float $priceTaxIncl - * @param float $priceTaxExcl - * @param float $taxRate - * @param int $stock - * @param string $location - * @param bool $availableOutOfStock - * @param ProductCombination[] $combinations - * @param ProductCustomizationField[] $customizationFields - */ - public function __construct( - int $productId, - string $name, - string $formattedPrice, - float $priceTaxIncl, - float $priceTaxExcl, - float $taxRate, - int $stock, - string $location, - bool $availableOutOfStock, - array $combinations = [], - array $customizationFields = [] - ) { - $this->productId = $productId; - $this->name = $name; - $this->formattedPrice = $formattedPrice; - $this->priceTaxIncl = $priceTaxIncl; - $this->priceTaxExcl = $priceTaxExcl; - $this->taxRate = $taxRate; - $this->stock = $stock; - $this->location = $location; - $this->availableOutOfStock = $availableOutOfStock; - $this->combinations = $combinations; - $this->customizationFields = $customizationFields; - } - - /** - * @return int - */ - public function getProductId(): int - { - return $this->productId; - } - - /** - * @return string - */ - public function getLocation(): string - { - return $this->location; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getFormattedPrice(): string - { - return $this->formattedPrice; - } - - /** - * @return float - */ - public function getPriceTaxIncl(): float - { - return $this->priceTaxIncl; - } - - /** - * @return float - */ - public function getPriceTaxExcl(): float - { - return $this->priceTaxExcl; - } - - /** - * @return int - */ - public function getStock(): int - { - return $this->stock; - } - - /** - * @return float - */ - public function getTaxRate(): float - { - return $this->taxRate; - } - - /** - * @return ProductCombination[] - */ - public function getCombinations(): array - { - return $this->combinations; - } - - /** - * @return ProductCustomizationField[] - */ - public function getCustomizationFields(): array - { - return $this->customizationFields; - } - - /** - * @return bool - */ - public function isAvailableOutOfStock(): bool - { - return $this->availableOutOfStock; - } -} diff --git a/src/Core/Domain/Product/QueryResult/ProductCombination.php b/src/Core/Domain/Product/QueryResult/ProductCombination.php deleted file mode 100644 index dad96872..00000000 --- a/src/Core/Domain/Product/QueryResult/ProductCombination.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Product\QueryResult; - -/** - * Holds product combination data - */ -class ProductCombination -{ - /** - * @var int - */ - private $attributeCombinationId; - - /** - * @var string - */ - private $attribute; - - /** - * @var string - */ - private $location; - - /** - * @var string - */ - private $reference; - - /** - * @var int - */ - private $stock; - - /** - * @var float - */ - private $priceTaxExcluded; - - /** - * @var float - */ - private $priceTaxIncluded; - - /** - * @var string - */ - private $formattedPrice; - - /** - * @param int $attributeCombinationId - * @param string $attribute - * @param int $stock - * @param string $formattedPrice - * @param float $priceTaxExcluded - * @param float $priceTaxIncluded - * @param string $location - * @param string $reference - */ - public function __construct( - int $attributeCombinationId, - string $attribute, - int $stock, - string $formattedPrice, - float $priceTaxExcluded, - float $priceTaxIncluded, - string $location, - string $reference - ) { - $this->attributeCombinationId = $attributeCombinationId; - $this->attribute = $attribute; - $this->stock = $stock; - $this->formattedPrice = $formattedPrice; - $this->priceTaxExcluded = $priceTaxExcluded; - $this->priceTaxIncluded = $priceTaxIncluded; - $this->location = $location; - $this->reference = $reference; - } - - /** - * @return int - */ - public function getAttributeCombinationId(): int - { - return $this->attributeCombinationId; - } - - /** - * @return string - */ - public function getAttribute(): string - { - return $this->attribute; - } - - /** - * @return string - */ - public function getLocation(): string - { - return $this->location; - } - - /** - * @return float - */ - public function getPriceTaxExcluded(): float - { - return $this->priceTaxExcluded; - } - - /** - * @return float - */ - public function getPriceTaxIncluded(): float - { - return $this->priceTaxIncluded; - } - - /** - * @return int - */ - public function getStock(): int - { - return $this->stock; - } - - /** - * @return string - */ - public function getFormattedPrice(): string - { - return $this->formattedPrice; - } - - /** - * @return string - */ - public function getReference(): string - { - return $this->reference; - } - - /** - * @param string $name - */ - public function appendAttributeName(string $name) - { - $this->attribute .= ' - ' . $name; - } -} diff --git a/src/Core/Domain/Product/QueryResult/ProductCustomizationField.php b/src/Core/Domain/Product/QueryResult/ProductCustomizationField.php deleted file mode 100644 index 8d5ff6ef..00000000 --- a/src/Core/Domain/Product/QueryResult/ProductCustomizationField.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\QueryResult; - -/** - * Holds data of product customization field - */ -class ProductCustomizationField -{ - const TYPE_FILE = 0; - const TYPE_TEXT = 1; - - /** - * @var int - */ - private $customizationFieldId; - - /** - * @var int - */ - private $type; - - /** - * @var string - */ - private $name; - - /** - * @var bool - */ - private $isRequired; - - /** - * @param int $customizationFieldId - * @param int $type - * @param string $name - * @param bool $isRequired - */ - public function __construct( - int $customizationFieldId, - int $type, - string $name, - bool $isRequired - ) { - $this->customizationFieldId = $customizationFieldId; - $this->type = $type; - $this->name = $name; - $this->isRequired = $isRequired; - } - - /** - * @return int - */ - public function getCustomizationFieldId(): int - { - return $this->customizationFieldId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return int - */ - public function getType(): int - { - return $this->type; - } - - /** - * @return bool - */ - public function isRequired(): bool - { - return $this->isRequired; - } -} diff --git a/src/Core/Domain/Product/ValueObject/ProductId.php b/src/Core/Domain/Product/ValueObject/ProductId.php deleted file mode 100644 index 16fa8f10..00000000 --- a/src/Core/Domain/Product/ValueObject/ProductId.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Product\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductConstraintException; - -/** - * Product identity. - */ -class ProductId -{ - /** - * @var int - */ - private $productId; - - /** - * @param int $productId - */ - public function __construct($productId) - { - $this->assertIntegerIsGreaterThanZero($productId); - - $this->productId = $productId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->productId; - } - - /** - * @param int $productId - */ - private function assertIntegerIsGreaterThanZero($productId) - { - if (!is_int($productId) || 0 > $productId) { - throw new ProductConstraintException(sprintf('Product id %s is invalid. Product id must be number that is greater than zero.', var_export($productId, true))); - } - } -} diff --git a/src/Core/Domain/Profile/Command/AbstractProfileCommand.php b/src/Core/Domain/Profile/Command/AbstractProfileCommand.php deleted file mode 100644 index 5f5d08fa..00000000 --- a/src/Core/Domain/Profile/Command/AbstractProfileCommand.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Command; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\ProfileSettings; - -abstract class AbstractProfileCommand -{ - /** - * @var string[] - */ - protected $localizedNames; - - /** - * @param string[] $localizedNames - * - * @throws ProfileConstraintException - */ - public function __construct(array $localizedNames) - { - if (empty($localizedNames)) { - throw new ProfileException('Profile name cannot be empty'); - } - - foreach ($localizedNames as $localizedName) { - $this->assertNameIsStringAndRequiredLength($localizedName); - } - $this->localizedNames = $localizedNames; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param string $name - */ - protected function assertNameIsStringAndRequiredLength($name) - { - if (null !== $name && !is_string($name) || strlen($name) > ProfileSettings::NAME_MAX_LENGTH) { - throw new ProfileConstraintException(sprintf('Profile name should not exceed %d characters length but %s given', ProfileSettings::NAME_MAX_LENGTH, var_export($name, true)), ProfileConstraintException::INVALID_NAME); - } - } -} diff --git a/src/Core/Domain/Profile/Command/AddProfileCommand.php b/src/Core/Domain/Profile/Command/AddProfileCommand.php deleted file mode 100644 index 56014050..00000000 --- a/src/Core/Domain/Profile/Command/AddProfileCommand.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Command; - -/** - * Adds new profile - */ -class AddProfileCommand extends AbstractProfileCommand -{ -} diff --git a/src/Core/Domain/Profile/Command/BulkDeleteProfileCommand.php b/src/Core/Domain/Profile/Command/BulkDeleteProfileCommand.php deleted file mode 100644 index e5506b06..00000000 --- a/src/Core/Domain/Profile/Command/BulkDeleteProfileCommand.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Command; - -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Class BulkDeleteProfileCommand is a command to bulk delete profiles by given ids. - */ -class BulkDeleteProfileCommand -{ - /** - * @var ProfileId[] - */ - private $profileIds = []; - - /** - * @param array $profileIds - */ - public function __construct(array $profileIds) - { - $this->setProfileIds($profileIds); - } - - /** - * @return ProfileId[] - */ - public function getProfileIds() - { - return $this->profileIds; - } - - /** - * @param array $profileIds - */ - private function setProfileIds(array $profileIds) - { - foreach ($profileIds as $profileId) { - $this->profileIds[] = new ProfileId((int) $profileId); - } - } -} diff --git a/src/Core/Domain/Profile/Command/DeleteProfileCommand.php b/src/Core/Domain/Profile/Command/DeleteProfileCommand.php deleted file mode 100644 index ae6346f8..00000000 --- a/src/Core/Domain/Profile/Command/DeleteProfileCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Command; - -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Class DeleteProfileCommand is a command to delete profile by given id. - */ -class DeleteProfileCommand -{ - /** - * @var ProfileId - */ - private $profileId; - - /** - * @param int $profileId - */ - public function __construct($profileId) - { - $this->profileId = new ProfileId((int) $profileId); - } - - /** - * @return ProfileId - */ - public function getProfileId() - { - return $this->profileId; - } -} diff --git a/src/Core/Domain/Profile/Command/EditProfileCommand.php b/src/Core/Domain/Profile/Command/EditProfileCommand.php deleted file mode 100644 index eb9284ae..00000000 --- a/src/Core/Domain/Profile/Command/EditProfileCommand.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Command; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Edits existing Profile - */ -class EditProfileCommand extends AbstractProfileCommand -{ - /** - * @var ProfileId - */ - private $profileId; - - /** - * @param int $profileId - * @param string[] $localizedNames - * - * @throws ProfileException - */ - public function __construct($profileId, array $localizedNames) - { - parent::__construct($localizedNames); - $this->profileId = new ProfileId((int) $profileId); - } - - /** - * @return ProfileId - */ - public function getProfileId() - { - return $this->profileId; - } -} diff --git a/src/Core/Domain/Profile/CommandHandler/AddProfileHandlerInterface.php b/src/Core/Domain/Profile/CommandHandler/AddProfileHandlerInterface.php deleted file mode 100644 index 75a1411f..00000000 --- a/src/Core/Domain/Profile/CommandHandler/AddProfileHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\AddProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Interface for service that handles adding new profile - */ -interface AddProfileHandlerInterface -{ - /** - * @param AddProfileCommand $command - * - * @return ProfileId - */ - public function handle(AddProfileCommand $command); -} diff --git a/src/Core/Domain/Profile/CommandHandler/BulkDeleteProfileHandlerInterface.php b/src/Core/Domain/Profile/CommandHandler/BulkDeleteProfileHandlerInterface.php deleted file mode 100644 index 53a943de..00000000 --- a/src/Core/Domain/Profile/CommandHandler/BulkDeleteProfileHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\BulkDeleteProfileCommand; - -/** - * Interface BulkDeleteProfileHandlerInterface defines profile bulk deletion handler. - */ -interface BulkDeleteProfileHandlerInterface -{ - /** - * Delete multiple profiles. - * - * @param BulkDeleteProfileCommand $command - */ - public function handle(BulkDeleteProfileCommand $command); -} diff --git a/src/Core/Domain/Profile/CommandHandler/DeleteProfileHandlerInterface.php b/src/Core/Domain/Profile/CommandHandler/DeleteProfileHandlerInterface.php deleted file mode 100644 index b1d764ec..00000000 --- a/src/Core/Domain/Profile/CommandHandler/DeleteProfileHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\DeleteProfileCommand; - -/** - * Interface DeleteProfileHandlerInterface defines profile deletion handler. - */ -interface DeleteProfileHandlerInterface -{ - /** - * Delete profile. - * - * @param DeleteProfileCommand $command - */ - public function handle(DeleteProfileCommand $command); -} diff --git a/src/Core/Domain/Profile/CommandHandler/EditProfileHandlerInterface.php b/src/Core/Domain/Profile/CommandHandler/EditProfileHandlerInterface.php deleted file mode 100644 index 0972802b..00000000 --- a/src/Core/Domain/Profile/CommandHandler/EditProfileHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\EditProfileCommand; - -/** - * Interface for service that edits existing Profile - */ -interface EditProfileHandlerInterface -{ - /** - * @param EditProfileCommand $command - */ - public function handle(EditProfileCommand $command); -} diff --git a/src/Core/Domain/Profile/Exception/CannotDeleteSuperAdminProfileException.php b/src/Core/Domain/Profile/Exception/CannotDeleteSuperAdminProfileException.php deleted file mode 100644 index 69df4505..00000000 --- a/src/Core/Domain/Profile/Exception/CannotDeleteSuperAdminProfileException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Exception; - -/** - * Class CannotDeleteSuperAdminProfileException thrown on super admin profile deletion attempt. - */ -class CannotDeleteSuperAdminProfileException extends ProfileException -{ -} diff --git a/src/Core/Domain/Profile/Exception/FailedToDeleteProfileException.php b/src/Core/Domain/Profile/Exception/FailedToDeleteProfileException.php deleted file mode 100644 index 47d2698e..00000000 --- a/src/Core/Domain/Profile/Exception/FailedToDeleteProfileException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Exception; - -/** - * Class FailedToDeleteProfileException is thrown when Profile deletion fails. - */ -class FailedToDeleteProfileException extends ProfileException -{ - /** - * Code is used when cannot delete profile because it is assigned to employee. - */ - const PROFILE_IS_ASSIGNED_TO_EMPLOYEE = 1; - - /** - * Code is used when unexpected error (e.g. lost db connection) occures while deleting profile. - */ - const UNEXPECTED_ERROR = 2; - - /** - * Code is used when logged in employee attempts to delete its own profile. - */ - const PROFILE_IS_ASSIGNED_TO_CONTEXT_EMPLOYEE = 3; -} diff --git a/src/Core/Domain/Profile/Exception/ProfileConstraintException.php b/src/Core/Domain/Profile/Exception/ProfileConstraintException.php deleted file mode 100644 index 92d86085..00000000 --- a/src/Core/Domain/Profile/Exception/ProfileConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Exception; - -/** - * Is thrown when some constraint is violated in Profile subdomain - */ -class ProfileConstraintException extends ProfileException -{ - /** - * @var string Code is used when invalid profile name is encountered - */ - const INVALID_NAME = 1; -} diff --git a/src/Core/Domain/Profile/Exception/ProfileException.php b/src/Core/Domain/Profile/Exception/ProfileException.php deleted file mode 100644 index 25dbf1dd..00000000 --- a/src/Core/Domain/Profile/Exception/ProfileException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class ProfileException is a base exception for profiles context. - */ -class ProfileException extends DomainException -{ -} diff --git a/src/Core/Domain/Profile/Exception/ProfileNotFoundException.php b/src/Core/Domain/Profile/Exception/ProfileNotFoundException.php deleted file mode 100644 index af7214f7..00000000 --- a/src/Core/Domain/Profile/Exception/ProfileNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Exception; - -/** - * Class ProfileNotFoundException is thrown when Profile cannot be found. - */ -class ProfileNotFoundException extends ProfileException -{ -} diff --git a/src/Core/Domain/Profile/ProfileSettings.php b/src/Core/Domain/Profile/ProfileSettings.php deleted file mode 100644 index 3cb40af4..00000000 --- a/src/Core/Domain/Profile/ProfileSettings.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile; - -final class ProfileSettings -{ - /** - * Profile name max length as defined in the ObjectModel - */ - const NAME_MAX_LENGTH = 32; -} diff --git a/src/Core/Domain/Profile/Query/GetProfileForEditing.php b/src/Core/Domain/Profile/Query/GetProfileForEditing.php deleted file mode 100644 index 255fe7f2..00000000 --- a/src/Core/Domain/Profile/Query/GetProfileForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\Query; - -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Get Profile data for editing - */ -class GetProfileForEditing -{ - /** - * @var ProfileId - */ - private $profileId; - - /** - * @param int $profileId - */ - public function __construct($profileId) - { - $this->profileId = new ProfileId((int) $profileId); - } - - /** - * @return ProfileId - */ - public function getProfileId() - { - return $this->profileId; - } -} diff --git a/src/Core/Domain/Profile/QueryHandler/GetProfileForEditingHandlerInterface.php b/src/Core/Domain/Profile/QueryHandler/GetProfileForEditingHandlerInterface.php deleted file mode 100644 index ad4e2b52..00000000 --- a/src/Core/Domain/Profile/QueryHandler/GetProfileForEditingHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Query\GetProfileForEditing; - -/** - * Interface for service that gets Profile data for editing - */ -interface GetProfileForEditingHandlerInterface -{ - /** - * @param GetProfileForEditing $query - * - * @return mixed - */ - public function handle(GetProfileForEditing $query); -} diff --git a/src/Core/Domain/Profile/QueryResult/EditableProfile.php b/src/Core/Domain/Profile/QueryResult/EditableProfile.php deleted file mode 100644 index 8125c454..00000000 --- a/src/Core/Domain/Profile/QueryResult/EditableProfile.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Transfers editable Profile data - */ -class EditableProfile -{ - /** - * @var ProfileId - */ - private $profileId; - - /** - * @var string[] As langId => name - */ - private $localizedNames; - - /** - * @param ProfileId $profileId - * @param string[] $localizedNames - */ - public function __construct(ProfileId $profileId, array $localizedNames) - { - $this->profileId = $profileId; - $this->localizedNames = $localizedNames; - } - - /** - * @return ProfileId - */ - public function getProfileId() - { - return $this->profileId; - } - - /** - * @return array - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } -} diff --git a/src/Core/Domain/Profile/ValueObject/ProfileId.php b/src/Core/Domain/Profile/ValueObject/ProfileId.php deleted file mode 100644 index 7be08013..00000000 --- a/src/Core/Domain/Profile/ValueObject/ProfileId.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; - -/** - * Class ProfileId - */ -class ProfileId -{ - /** - * @var int - */ - private $profileId; - - /** - * @param int $profileId - * - * @throws ProfileException - */ - public function __construct($profileId) - { - // Strict type should be used in next major - if (!is_int($profileId)) { - @trigger_error('Invalid type, int is expected', E_STRICT); - } - - $this->setProfileId($profileId); - } - - /** - * @return int - */ - public function getValue() - { - return $this->profileId; - } - - /** - * @param int $profileId - * - * @throws ProfileException - */ - private function setProfileId($profileId) - { - if ((!is_int($profileId) && !ctype_digit($profileId)) || 0 >= $profileId) { - throw new ProfileException(sprintf('Invalid Profile id %s supplied', var_export($profileId, true))); - } - - $this->profileId = (int) $profileId; - } -} diff --git a/src/Core/Domain/Shop/Command/UploadLogosCommand.php b/src/Core/Domain/Shop/Command/UploadLogosCommand.php deleted file mode 100644 index 436436c7..00000000 --- a/src/Core/Domain/Shop/Command/UploadLogosCommand.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\Command; - -use PrestaShop\PrestaShop\Core\Domain\Exception\FileUploadException; -use PrestaShop\PrestaShop\Core\Domain\Shop\DTO\ShopLogoSettings; -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\NotSupportedFaviconExtensionException; -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\NotSupportedLogoImageExtensionException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Uploads logo image files - */ -class UploadLogosCommand -{ - /** - * @var UploadedFile|null - */ - private $uploadedHeaderLogo; - - /** - * @var UploadedFile|null - */ - private $uploadedInvoiceLogo; - - /** - * @var UploadedFile|null - */ - private $uploadedMailLogo; - - /** - * @var UploadedFile|null - */ - private $uploadedFavicon; - - /** - * @return UploadedFile|null - */ - public function getUploadedHeaderLogo() - { - return $this->uploadedHeaderLogo; - } - - /** - * @param UploadedFile $uploadedHeaderLogo - * - * @throws NotSupportedLogoImageExtensionException - * @throws FileUploadException - */ - public function setUploadedHeaderLogo(UploadedFile $uploadedHeaderLogo) - { - $this->assertIsValidLogoImageExtension($uploadedHeaderLogo); - $this->assertNativeFileValidationDoesNotFail($uploadedHeaderLogo); - - $this->uploadedHeaderLogo = $uploadedHeaderLogo; - } - - /** - * @return UploadedFile|null - */ - public function getUploadedInvoiceLogo() - { - return $this->uploadedInvoiceLogo; - } - - /** - * @param UploadedFile $uploadedInvoiceLogo - * - * @throws NotSupportedLogoImageExtensionException - * @throws FileUploadException - */ - public function setUploadedInvoiceLogo(UploadedFile $uploadedInvoiceLogo) - { - $this->assertIsValidLogoImageExtension($uploadedInvoiceLogo); - $this->assertNativeFileValidationDoesNotFail($uploadedInvoiceLogo); - - $this->uploadedInvoiceLogo = $uploadedInvoiceLogo; - } - - /** - * @return UploadedFile|null - */ - public function getUploadedMailLogo() - { - return $this->uploadedMailLogo; - } - - /** - * @param UploadedFile $uploadedMailLogo - * - * @throws NotSupportedLogoImageExtensionException - * @throws FileUploadException - */ - public function setUploadedMailLogo(UploadedFile $uploadedMailLogo) - { - $this->assertIsValidLogoImageExtension($uploadedMailLogo); - $this->assertNativeFileValidationDoesNotFail($uploadedMailLogo); - - $this->uploadedMailLogo = $uploadedMailLogo; - } - - /** - * @return UploadedFile|null - */ - public function getUploadedFavicon() - { - return $this->uploadedFavicon; - } - - /** - * @param UploadedFile $uploadedFavicon - * - * @throws NotSupportedFaviconExtensionException - * @throws FileUploadException - */ - public function setUploadedFavicon(UploadedFile $uploadedFavicon) - { - if (ShopLogoSettings::AVAILABLE_ICON_IMAGE_EXTENSION !== $uploadedFavicon->getClientOriginalExtension()) { - throw new NotSupportedFaviconExtensionException(sprintf('Not supported "%s" favicon extension. Supported extension is "ico".', $uploadedFavicon->getClientOriginalExtension())); - } - - $this->assertNativeFileValidationDoesNotFail($uploadedFavicon); - - $this->uploadedFavicon = $uploadedFavicon; - } - - /** - * @param UploadedFile $uploadedFile - * - * @throws NotSupportedLogoImageExtensionException - */ - private function assertIsValidLogoImageExtension(UploadedFile $uploadedFile) - { - $extension = $uploadedFile->getClientOriginalExtension(); - if (!in_array($extension, ShopLogoSettings::AVAILABLE_LOGO_IMAGE_EXTENSIONS, true)) { - throw new NotSupportedLogoImageExtensionException(sprintf('Not supported "%s" image logo extension. Supported extensions are ""', implode(',', ShopLogoSettings::AVAILABLE_LOGO_IMAGE_EXTENSIONS))); - } - } - - /** - * Checks if native file validation does not fail. - * - * @param UploadedFile $uploadedFile - * - * @throws FileUploadException - */ - private function assertNativeFileValidationDoesNotFail(UploadedFile $uploadedFile) - { - $errorCode = $uploadedFile->getError(); - - if ($errorCode !== UPLOAD_ERR_OK) { - throw new FileUploadException($uploadedFile->getErrorMessage(), $errorCode); - } - } -} diff --git a/src/Core/Domain/Shop/CommandHandler/UploadLogosHandlerInterface.php b/src/Core/Domain/Shop/CommandHandler/UploadLogosHandlerInterface.php deleted file mode 100644 index d39bb6fa..00000000 --- a/src/Core/Domain/Shop/CommandHandler/UploadLogosHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Shop\Command\UploadLogosCommand; - -/** - * Interface for service which handles UploadLogosCommand - */ -interface UploadLogosHandlerInterface -{ - /** - * @param UploadLogosCommand $command - */ - public function handle(UploadLogosCommand $command); -} diff --git a/src/Core/Domain/Shop/DTO/ShopLogoSettings.php b/src/Core/Domain/Shop/DTO/ShopLogoSettings.php deleted file mode 100644 index 5db4b3eb..00000000 --- a/src/Core/Domain/Shop/DTO/ShopLogoSettings.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\DTO; - -/** - * Holds default settings for shop logos. - */ -class ShopLogoSettings -{ - const HEADER_LOGO_FILE_NAME = 'PS_LOGO'; - - const MAIL_LOGO_FILE_NAME = 'PS_LOGO_MAIL'; - - const INVOICE_LOGO_FILE_NAME = 'PS_LOGO_INVOICE'; - - const FAVICON_FILE_NAME = 'PS_FAVICON'; - - /** - * @var array - a list of available image mime types - */ - const AVAILABLE_LOGO_IMAGE_EXTENSIONS = ['gif', 'jpg', 'jpeg', 'jpe', 'png']; - - /** - * @var string - a type used for icon images for shop logo - */ - const AVAILABLE_ICON_IMAGE_EXTENSION = 'ico'; - - /** - * Gets the list of available extensions with dot attached to the front of the extension - * - * @return array - */ - public function getLogoImageExtensionsWithDot() - { - $mimeTypes = []; - foreach (self::AVAILABLE_LOGO_IMAGE_EXTENSIONS as $imageExtension) { - $mimeTypes[] = '.' . $imageExtension; - } - - return $mimeTypes; - } - - /** - * Gets icon image extension with dot attached to the front. - * - * @return string - */ - public function getIconImageExtensionWithDot() - { - return '.' . self::AVAILABLE_ICON_IMAGE_EXTENSION; - } -} diff --git a/src/Core/Domain/Shop/Exception/NotSupportedFaviconExtensionException.php b/src/Core/Domain/Shop/Exception/NotSupportedFaviconExtensionException.php deleted file mode 100644 index 57a935a7..00000000 --- a/src/Core/Domain/Shop/Exception/NotSupportedFaviconExtensionException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\Exception; - -/** - * Class NotSupportedFaviconExtensionException - */ -class NotSupportedFaviconExtensionException extends ShopException -{ -} diff --git a/src/Core/Domain/Shop/Exception/NotSupportedLogoImageExtensionException.php b/src/Core/Domain/Shop/Exception/NotSupportedLogoImageExtensionException.php deleted file mode 100644 index 77f110ae..00000000 --- a/src/Core/Domain/Shop/Exception/NotSupportedLogoImageExtensionException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\Exception; - -class NotSupportedLogoImageExtensionException extends ShopException -{ -} diff --git a/src/Core/Domain/Shop/Exception/ShopException.php b/src/Core/Domain/Shop/Exception/ShopException.php deleted file mode 100644 index a2ae25f7..00000000 --- a/src/Core/Domain/Shop/Exception/ShopException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class ShopException is base exception for Shop domain. - */ -class ShopException extends DomainException -{ -} diff --git a/src/Core/Domain/Shop/Query/GetLogosPaths.php b/src/Core/Domain/Shop/Query/GetLogosPaths.php deleted file mode 100644 index 292a2904..00000000 --- a/src/Core/Domain/Shop/Query/GetLogosPaths.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\Query; - -/** - * Query responsible for getting header, email, invoice and favicon logos paths - */ -class GetLogosPaths -{ -} diff --git a/src/Core/Domain/Shop/QueryHandler/GetLogosPathsHandlerInterface.php b/src/Core/Domain/Shop/QueryHandler/GetLogosPathsHandlerInterface.php deleted file mode 100644 index 94132b59..00000000 --- a/src/Core/Domain/Shop/QueryHandler/GetLogosPathsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Shop\Query\GetLogosPaths; -use PrestaShop\PrestaShop\Core\Domain\Shop\QueryResult\LogosPaths; - -/** - * Interface for service which handles GetLogos query - */ -interface GetLogosPathsHandlerInterface -{ - /** - * @param GetLogosPaths $query - * - * @return LogosPaths - */ - public function handle(GetLogosPaths $query); -} diff --git a/src/Core/Domain/Shop/QueryResult/LogosPaths.php b/src/Core/Domain/Shop/QueryResult/LogosPaths.php deleted file mode 100644 index ae9a49ac..00000000 --- a/src/Core/Domain/Shop/QueryResult/LogosPaths.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\QueryResult; - -/** - * Holds data of header, email, invoice and favicon logos paths - */ -class LogosPaths -{ - /** - * @var string - */ - private $headerLogoPath; - - /** - * @var string - */ - private $mailLogoPath; - - /** - * @var string - */ - private $invoiceLogoPath; - - /** - * @var string - */ - private $faviconPath; - - /** - * @param string $headerLogoPath - * @param string $mailLogoPath - * @param string $invoiceLogoPath - * @param string $faviconPath - */ - public function __construct( - $headerLogoPath, - $mailLogoPath, - $invoiceLogoPath, - $faviconPath - ) { - $this->headerLogoPath = $headerLogoPath; - $this->mailLogoPath = $mailLogoPath; - $this->invoiceLogoPath = $invoiceLogoPath; - $this->faviconPath = $faviconPath; - } - - /** - * @return string - */ - public function getHeaderLogoPath() - { - return $this->headerLogoPath; - } - - /** - * @return string - */ - public function getMailLogoPath() - { - return $this->mailLogoPath; - } - - /** - * @return string - */ - public function getInvoiceLogoPath() - { - return $this->invoiceLogoPath; - } - - /** - * @return string - */ - public function getFaviconPath() - { - return $this->faviconPath; - } -} diff --git a/src/Core/Domain/Shop/ValueObject/ShopConstraint.php b/src/Core/Domain/Shop/ValueObject/ShopConstraint.php deleted file mode 100644 index 3d38d182..00000000 --- a/src/Core/Domain/Shop/ValueObject/ShopConstraint.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopException; - -class ShopConstraint -{ - /** - * @var ShopId|null - */ - private $shopId; - - /** - * @var ShopGroupId|null - */ - private $shopGroupId; - - /** - * Indicate if the value returned matches the constraints strictly, else it fallbacks to Shop > Group > Global value - * - * @var bool - */ - private $strict; - - /** - * Constraint to get configuration for a specific shop - * - * @param int $shopId - * - * @return static - * - * @throws ShopException - */ - public static function shop(int $shopId): self - { - return new static($shopId, null, false); - } - - /** - * Constraint to get configuration for a specific shop group - * - * @param int $shopGroupId - * - * @return static - * - * @throws ShopException - */ - public static function shopGroup(int $shopGroupId): self - { - return new static(null, $shopGroupId, false); - } - - /** - * Constraint to get configuration for all shops (the global value) - * - * @return static - */ - public static function allShops(): self - { - return new static(null, null, false); - } - - /** - * @param int|null $shopId - * @param int|null $shopGroupId - * @param bool $strict - * - * @throws ShopException - */ - public function __construct(?int $shopId, ?int $shopGroupId, bool $strict = false) - { - $this->shopId = null !== $shopId ? new ShopId($shopId) : null; - $this->shopGroupId = null !== $shopGroupId ? new ShopGroupId($shopGroupId) : null; - $this->strict = $strict; - } - - /** - * @return ShopId|null - */ - public function getShopId(): ?ShopId - { - return $this->shopId; - } - - /** - * @return ShopGroupId|null - */ - public function getShopGroupId(): ?ShopGroupId - { - return $this->shopGroupId; - } - - /** - * @return bool - */ - public function isStrict(): bool - { - return $this->strict; - } -} diff --git a/src/Core/Domain/Shop/ValueObject/ShopGroupId.php b/src/Core/Domain/Shop/ValueObject/ShopGroupId.php deleted file mode 100644 index 176bd4d0..00000000 --- a/src/Core/Domain/Shop/ValueObject/ShopGroupId.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopException; - -class ShopGroupId -{ - /** - * @var int - */ - private $shopGroupId; - - /** - * @param int $shopGroupId - * - * @throws ShopException - */ - public function __construct(int $shopGroupId) - { - $this->assertIsGreaterThanZero($shopGroupId); - - $this->shopGroupId = $shopGroupId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->shopGroupId; - } - - /** - * @param int $shopGroupId - * - * @throws ShopException - */ - private function assertIsGreaterThanZero(int $shopGroupId): void - { - if (0 >= $shopGroupId) { - throw new ShopException( - sprintf( - 'Shop id %s is invalid. Shop id must be number that is greater than zero.', - var_export($shopGroupId, true) - ) - ); - } - } -} diff --git a/src/Core/Domain/Shop/ValueObject/ShopId.php b/src/Core/Domain/Shop/ValueObject/ShopId.php deleted file mode 100644 index 46009175..00000000 --- a/src/Core/Domain/Shop/ValueObject/ShopId.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Shop\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\ShopException; - -/** - * Shop identity - */ -class ShopId -{ - /** - * @var int - */ - private $shopId; - - /** - * @param int $shopId - * - * @throws ShopException - */ - public function __construct(int $shopId) - { - $this->assertIsGreaterThanZero($shopId); - - $this->shopId = $shopId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->shopId; - } - - /** - * @param int $shopId - * - * @throws ShopException - */ - private function assertIsGreaterThanZero(int $shopId): void - { - if (0 >= $shopId) { - throw new ShopException( - sprintf( - 'Shop id %s is invalid. Shop id must be number that is greater than zero.', - var_export($shopId, true) - ) - ); - } - } -} diff --git a/src/Core/Domain/ShowcaseCard/Command/CloseShowcaseCardCommand.php b/src/Core/Domain/ShowcaseCard/Command/CloseShowcaseCardCommand.php deleted file mode 100644 index eb4ddb70..00000000 --- a/src/Core/Domain/ShowcaseCard/Command/CloseShowcaseCardCommand.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Command; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\InvalidShowcaseCardNameException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\ShowcaseCardException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; - -/** - * This command permanently closes a showcase card - */ -class CloseShowcaseCardCommand -{ - /** - * @var int - */ - private $employeeId; - - /** - * @var ShowcaseCard - */ - private $showcaseCard; - - /** - * CloseShowcaseCardCommand constructor. - * - * @param int $employeeId - * @param string $showcaseCardName Name of the showcase card - * - * @throws InvalidShowcaseCardNameException - * @throws ShowcaseCardException - */ - public function __construct($employeeId, $showcaseCardName) - { - if (!is_int($employeeId)) { - throw new ShowcaseCardException(sprintf('Expected employee id to be an int, but was %s', gettype($employeeId))); - } - - $this->employeeId = $employeeId; - $this->showcaseCard = new ShowcaseCard($showcaseCardName); - } - - /** - * @return int - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @return ShowcaseCard - */ - public function getShowcaseCard() - { - return $this->showcaseCard; - } -} diff --git a/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandler.php b/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandler.php deleted file mode 100644 index 7aaaaf16..00000000 --- a/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandler.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\CommandHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Command\CloseShowcaseCardCommand; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ConfigurationMap; - -/** - * Saves the showcase card status to keep it closed - */ -final class CloseShowcaseCardHandler implements CloseShowcaseCardHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var ConfigurationMap - */ - private $configurationMap; - - /** - * CloseShowcaseCardHandler constructor. - * - * @param ConfigurationInterface $configuration - * @param ConfigurationMap $configurationMap - */ - public function __construct(ConfigurationInterface $configuration, ConfigurationMap $configurationMap) - { - $this->configuration = $configuration; - $this->configurationMap = $configurationMap; - } - - /** - * @param CloseShowcaseCardCommand $command - */ - public function handle(CloseShowcaseCardCommand $command) - { - $configurationName = $this->configurationMap->getConfigurationNameForClosedStatus($command->getShowcaseCard()); - $this->configuration->set($configurationName, '1'); - } -} diff --git a/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandlerInterface.php b/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandlerInterface.php deleted file mode 100644 index 6c31cf08..00000000 --- a/src/Core/Domain/ShowcaseCard/CommandHandler/CloseShowcaseCardHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Command\CloseShowcaseCardCommand; - -/** - * Contract for handling CloseShowcaseCardCommand - */ -interface CloseShowcaseCardHandlerInterface -{ - /** - * Closes a showcase card permanently - * - * @param CloseShowcaseCardCommand $command - */ - public function handle(CloseShowcaseCardCommand $command); -} diff --git a/src/Core/Domain/ShowcaseCard/ConfigurationMap.php b/src/Core/Domain/ShowcaseCard/ConfigurationMap.php deleted file mode 100644 index 6805028b..00000000 --- a/src/Core/Domain/ShowcaseCard/ConfigurationMap.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\ShowcaseCardException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; - -/** - * Maps showcase card names to configuration names from ps_configuration - */ -class ConfigurationMap -{ - /** - * Template used to create configuration names for "closed status" - */ - const CLOSED_TEMPLATE = 'PS_SHOWCASECARD_%s_CLOSED'; - - /** - * @var array - */ - private $closedCardConfiguration; - - public function __construct() - { - $this->closedCardConfiguration = [ - ShowcaseCard::SEO_URLS_CARD => sprintf(self::CLOSED_TEMPLATE, 'SEO_URLS'), - ShowcaseCard::CATEGORIES_CARD => sprintf(self::CLOSED_TEMPLATE, 'CATEGORIES'), - ShowcaseCard::CUSTOMERS_CARD => sprintf(self::CLOSED_TEMPLATE, 'CUSTOMERS'), - ShowcaseCard::EMPLOYEES_CARD => sprintf(self::CLOSED_TEMPLATE, 'EMPLOYEES'), - ShowcaseCard::CMS_PAGES_CARD => sprintf(self::CLOSED_TEMPLATE, 'CMS_PAGES'), - ShowcaseCard::ATTRIBUTES_CARD => sprintf(self::CLOSED_TEMPLATE, 'ATTRIBUTES'), - ShowcaseCard::MONITORING_CARD => sprintf(self::CLOSED_TEMPLATE, 'MONITORING'), - ]; - } - - /** - * Returns the ps_configuration configuration name for "closed status" of the provided card - * - * @param ShowcaseCard $cardName - * - * @return string - * - * @throws ShowcaseCardException If there's no configuration for that showcase card - */ - public function getConfigurationNameForClosedStatus(ShowcaseCard $cardName) - { - $name = $cardName->getName(); - - if (!isset($this->closedCardConfiguration[$name])) { - throw new ShowcaseCardException(sprintf('No closed status configuration found for showcase card "%s"', $name)); - } - - return $this->closedCardConfiguration[$name]; - } -} diff --git a/src/Core/Domain/ShowcaseCard/Exception/InvalidShowcaseCardNameException.php b/src/Core/Domain/ShowcaseCard/Exception/InvalidShowcaseCardNameException.php deleted file mode 100644 index 060e6ca1..00000000 --- a/src/Core/Domain/ShowcaseCard/Exception/InvalidShowcaseCardNameException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception; - -/** - * Used when referencing an invalid showcase card name - */ -class InvalidShowcaseCardNameException extends ShowcaseCardException -{ -} diff --git a/src/Core/Domain/ShowcaseCard/Exception/ShowcaseCardException.php b/src/Core/Domain/ShowcaseCard/Exception/ShowcaseCardException.php deleted file mode 100644 index 5c7dbe60..00000000 --- a/src/Core/Domain/ShowcaseCard/Exception/ShowcaseCardException.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base class for Showcase card exceptions - */ -class ShowcaseCardException extends DomainException -{ -} diff --git a/src/Core/Domain/ShowcaseCard/Query/GetShowcaseCardIsClosed.php b/src/Core/Domain/ShowcaseCard/Query/GetShowcaseCardIsClosed.php deleted file mode 100644 index f5d773d0..00000000 --- a/src/Core/Domain/ShowcaseCard/Query/GetShowcaseCardIsClosed.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\InvalidShowcaseCardNameException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\ShowcaseCardException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; - -/** - * This query retrieves the "closed status" of a showcase card - */ -class GetShowcaseCardIsClosed -{ - /** - * @var int - */ - private $employeeId; - /** - * @var ShowcaseCard - */ - private $showcaseCard; - - /** - * GetShowcaseCardIsClosed constructor. - * - * @param int $employeeId - * @param string $showcaseCardName - * - * @throws InvalidShowcaseCardNameException - * @throws ShowcaseCardException - */ - public function __construct($employeeId, $showcaseCardName) - { - if (!is_int($employeeId)) { - throw new ShowcaseCardException(sprintf('Expected employee id to be an int, but was %s', gettype($employeeId))); - } - - $this->employeeId = $employeeId; - $this->showcaseCard = new ShowcaseCard($showcaseCardName); - } - - /** - * @return int - */ - public function getEmployeeId() - { - return $this->employeeId; - } - - /** - * @return ShowcaseCard - */ - public function getShowcaseCard() - { - return $this->showcaseCard; - } -} diff --git a/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandler.php b/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandler.php deleted file mode 100644 index d03140ae..00000000 --- a/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandler.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\QueryHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ConfigurationMap; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\ShowcaseCardException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; - -/** - * Finds out if a showcase card has been closed - */ -final class GetShowcaseCardIsClosedHandler implements GetShowcaseCardIsClosedHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - /** - * @var ConfigurationMap - */ - private $configurationMap; - - /** - * @param ConfigurationInterface $configuration - * @param ConfigurationMap $configurationMap - */ - public function __construct(ConfigurationInterface $configuration, ConfigurationMap $configurationMap) - { - $this->configuration = $configuration; - $this->configurationMap = $configurationMap; - } - - /** - * @param GetShowcaseCardIsClosed $query - * - * @return bool - * - * @throws ShowcaseCardException - */ - public function handle(GetShowcaseCardIsClosed $query) - { - $configurationName = $this->configurationMap->getConfigurationNameForClosedStatus($query->getShowcaseCard()); - - return (bool) $this->configuration->get($configurationName); - } -} diff --git a/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandlerInterface.php b/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandlerInterface.php deleted file mode 100644 index bce95d8d..00000000 --- a/src/Core/Domain/ShowcaseCard/QueryHandler/GetShowcaseCardIsClosedHandlerInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; - -/** - * Contract for handling GetShowcaseCardIsClosed - */ -interface GetShowcaseCardIsClosedHandlerInterface -{ - /** - * Returns the "closed state" of a showcase command - * - * @param GetShowcaseCardIsClosed $query - * - * @return bool True if the showcase card is closed, False otherwise - */ - public function handle(GetShowcaseCardIsClosed $query); -} diff --git a/src/Core/Domain/ShowcaseCard/ValueObject/ShowcaseCard.php b/src/Core/Domain/ShowcaseCard/ValueObject/ShowcaseCard.php deleted file mode 100644 index c8e85e0d..00000000 --- a/src/Core/Domain/ShowcaseCard/ValueObject/ShowcaseCard.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\InvalidShowcaseCardNameException; - -/** - * Showcase cards are help dialogs that appear at the top of pages to guide the merchant - */ -class ShowcaseCard -{ - /** - * Card shown in SEO & URLs - */ - const SEO_URLS_CARD = 'seo-urls_card'; - - /** - * Card shown in Categories - */ - const CATEGORIES_CARD = 'categories_card'; - - /** - * Card shown in Customers - */ - const CUSTOMERS_CARD = 'customers_card'; - - /** - * Card shown in Employees - */ - const EMPLOYEES_CARD = 'employees_card'; - - /** - * Card shown in Improve -> Design -> Pages - */ - const CMS_PAGES_CARD = 'cms-pages_card'; - - /** - * Card shown in Sell -> Catalog -> Attributes & features -> Attributes - */ - const ATTRIBUTES_CARD = 'attributes_card'; - - /** - * Card shown in Sell -> Catalog -> Monitoring - */ - const MONITORING_CARD = 'monitoring_card'; - - /** - * List of supported card names - */ - const SUPPORTED_NAMES = [ - self::SEO_URLS_CARD => true, - self::CATEGORIES_CARD => true, - self::CUSTOMERS_CARD => true, - self::EMPLOYEES_CARD => true, - self::CMS_PAGES_CARD => true, - self::ATTRIBUTES_CARD => true, - self::MONITORING_CARD => true, - ]; - - /** - * @var string - */ - private $name; - - /** - * ShowcaseCardName constructor. - * - * @param string $name Showcase card name - * - * @throws InvalidShowcaseCardNameException - */ - public function __construct($name) - { - if (!$this->isSupported($name)) { - throw new InvalidShowcaseCardNameException(sprintf('Unsupported showcase card name: %s', print_r($name, true))); - } - - $this->name = $name; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Indicates if the provided name matches an existing showcase card - * - * @param string $name - * - * @return bool - */ - private function isSupported($name) - { - return array_key_exists($name, self::SUPPORTED_NAMES); - } -} diff --git a/src/Core/Domain/SpecificPrice/Command/AddSpecificPriceCommand.php b/src/Core/Domain/SpecificPrice/Command/AddSpecificPriceCommand.php deleted file mode 100644 index 3369b20b..00000000 --- a/src/Core/Domain/SpecificPrice/Command/AddSpecificPriceCommand.php +++ /dev/null @@ -1,378 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command; - -use DateTime; -use Exception; -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceConstraintException; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; - -/** - * Adds specific price - */ -class AddSpecificPriceCommand -{ - /** - * @var ProductId - */ - private $productId; - - /** - * @var Reduction - */ - private $reduction; - - /** - * @var bool - */ - private $includeTax; - - /** - * @var Number - */ - private $price; - - /** - * @var int - */ - private $fromQuantity; - - /** - * @var int|null - */ - private $shopGroupId; - - /** - * @var int|null - */ - private $shopId; - - /** - * @var int|null - */ - private $cartId; - - /** - * @var int|null - */ - private $productAttributeId; - - /** - * @var int|null - */ - private $currencyId; - - /** - * @var int|null - */ - private $cartRuleId; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var int|null - */ - private $groupId; - - /** - * @var int|null - */ - private $customerId; - - /** - * @var DateTime|null - */ - private $dateTimeFrom; - - /** - * @var DateTime|null - */ - private $dateTimeTo; - - /** - * @param int $productId - * @param string $reductionType - * @param float $reductionValue - * @param bool $includeTax - * @param float $price - * @param int $fromQuantity - * - * @throws DomainConstraintException - */ - public function __construct( - int $productId, - string $reductionType, - float $reductionValue, - bool $includeTax, - float $price, - int $fromQuantity - ) { - $this->productId = new ProductId($productId); - $this->reduction = new Reduction($reductionType, $reductionValue); - $this->includeTax = $includeTax; - $this->price = new Number((string) $price); - $this->fromQuantity = $fromQuantity; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return Reduction - */ - public function getReduction(): Reduction - { - return $this->reduction; - } - - /** - * @return bool - */ - public function isIncludeTax(): bool - { - return $this->includeTax; - } - - /** - * @return Number - */ - public function getPrice(): Number - { - return $this->price; - } - - /** - * @return int - */ - public function getFromQuantity(): int - { - return $this->fromQuantity; - } - - /** - * @return DateTime|null - */ - public function getDateTimeFrom(): ?DateTime - { - return $this->dateTimeFrom; - } - - /** - * @param DateTime|null $dateTimeFrom - */ - public function setDateTimeFrom(?DateTime $dateTimeFrom): void - { - $this->dateTimeFrom = $this->createDateTime($dateTimeFrom); - } - - /** - * @return int|null - */ - public function getShopGroupId(): ?int - { - return $this->shopGroupId; - } - - /** - * @param int $shopGroupId - */ - public function setShopGroupId(int $shopGroupId): void - { - $this->shopGroupId = $shopGroupId; - } - - /** - * @return int|null - */ - public function getShopId(): ?int - { - return $this->shopId; - } - - /** - * @param int $shopId - */ - public function setShopId(int $shopId): void - { - $this->shopId = $shopId; - } - - /** - * @return int|null - */ - public function getCartId(): ?int - { - return $this->cartId; - } - - /** - * @param int $cartId - */ - public function setCartId(int $cartId): void - { - $this->cartId = $cartId; - } - - /** - * @return int|null - */ - public function getProductAttributeId(): ?int - { - return $this->productAttributeId; - } - - /** - * @param int $productAttributeId - */ - public function setProductAttributeId(int $productAttributeId): void - { - $this->productAttributeId = $productAttributeId; - } - - /** - * @return int|null - */ - public function getCurrencyId(): ?int - { - return $this->currencyId; - } - - /** - * @param int $currencyId - */ - public function setCurrencyId(int $currencyId): void - { - $this->currencyId = $currencyId; - } - - /** - * @return int|null - */ - public function getCartRuleId(): ?int - { - return $this->cartRuleId; - } - - /** - * @param int $cartRuleId - */ - public function setCartRuleId(int $cartRuleId): void - { - $this->cartRuleId = $cartRuleId; - } - - /** - * @return int|null - */ - public function getCountryId(): ?int - { - return $this->countryId; - } - - /** - * @param int $countryId - */ - public function setCountryId(int $countryId): void - { - $this->countryId = $countryId; - } - - /** - * @return int|null - */ - public function getGroupId(): ?int - { - return $this->groupId; - } - - /** - * @param int $groupId - */ - public function setGroupId(int $groupId): void - { - $this->groupId = $groupId; - } - - /** - * @return int|null - */ - public function getCustomerId(): ?int - { - return $this->customerId; - } - - /** - * @param int $customerId - */ - public function setCustomerId(int $customerId): void - { - $this->customerId = $customerId; - } - - /** - * @return DateTime|null - */ - public function getDateTimeTo(): ?DateTime - { - return $this->dateTimeTo; - } - - /** - * @param DateTime|null $dateTimeTo - */ - public function setDateTimeTo(?DateTime $dateTimeTo): void - { - $this->dateTimeTo = $this->createDateTime($dateTimeTo); - } - - /** - * @param string $dateTime - * - * @return DateTime - * - * @throws SpecificPriceConstraintException - */ - private function createDateTime(string $dateTime): DateTime - { - try { - return new DateTime($dateTime); - } catch (Exception $e) { - throw new SpecificPriceConstraintException('An error occured when creating DateTime object for specific price', SpecificPriceConstraintException::INVALID_DATETIME, $e); - } - } -} diff --git a/src/Core/Domain/SpecificPrice/Command/DeleteSpecificPriceByCartProductCommand.php b/src/Core/Domain/SpecificPrice/Command/DeleteSpecificPriceByCartProductCommand.php deleted file mode 100644 index a908aef5..00000000 --- a/src/Core/Domain/SpecificPrice/Command/DeleteSpecificPriceByCartProductCommand.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command; - -use PrestaShop\PrestaShop\Core\Domain\Cart\ValueObject\CartId; -use PrestaShop\PrestaShop\Core\Domain\Product\ValueObject\ProductId; - -/** - * Deletes specific price by cart id - */ -class DeleteSpecificPriceByCartProductCommand -{ - /** - * @var CartId - */ - private $cartId; - - /** - * @var ProductId - */ - private $productId; - - /** - * @var int|null - */ - private $productAttributeId; - - public function __construct( - int $cartId, - int $productId - ) { - $this->cartId = new CartId($cartId); - $this->productId = new ProductId($productId); - } - - /** - * @return CartId - */ - public function getCartId(): CartId - { - return $this->cartId; - } - - /** - * @return ProductId - */ - public function getProductId(): ProductId - { - return $this->productId; - } - - /** - * @return int|null - */ - public function getProductAttributeId(): ?int - { - return $this->productAttributeId; - } - - /** - * @param int $productAttributeId - */ - public function setProductAttributeId(int $productAttributeId): void - { - $this->productAttributeId = $productAttributeId; - } -} diff --git a/src/Core/Domain/SpecificPrice/CommandHandler/AddSpecificPriceHandlerInterface.php b/src/Core/Domain/SpecificPrice/CommandHandler/AddSpecificPriceHandlerInterface.php deleted file mode 100644 index ef54ef33..00000000 --- a/src/Core/Domain/SpecificPrice/CommandHandler/AddSpecificPriceHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\AddSpecificPriceCommand; -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\ValueObject\SpecificPriceId; - -/** - * Interface for handling AddSpecificPrice command - */ -interface AddSpecificPriceHandlerInterface -{ - /** - * @param AddSpecificPriceCommand $command - * - * @return SpecificPriceId - */ - public function handle(AddSpecificPriceCommand $command): SpecificPriceId; -} diff --git a/src/Core/Domain/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandlerInterface.php b/src/Core/Domain/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandlerInterface.php deleted file mode 100644 index 889b37e3..00000000 --- a/src/Core/Domain/SpecificPrice/CommandHandler/DeleteSpecificPriceByCartProductHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\DeleteSpecificPriceByCartProductCommand; - -/** - * Interface for handling DeleteSpecificPriceByCartProduct command - */ -interface DeleteSpecificPriceByCartProductHandlerInterface -{ - /** - * @param DeleteSpecificPriceByCartProductCommand $command - */ - public function handle(DeleteSpecificPriceByCartProductCommand $command): void; -} diff --git a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceConstraintException.php b/src/Core/Domain/SpecificPrice/Exception/SpecificPriceConstraintException.php deleted file mode 100644 index 02b8b7fe..00000000 --- a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceConstraintException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception; - -/** - * Thrown when specific price constraints are violated - */ -class SpecificPriceConstraintException extends SpecificPriceException -{ - /** - * When catalog price rule id is not valid - */ - const INVALID_ID = 1; - - /** - * When date-time format is invalid - */ - const INVALID_DATETIME = 2; - - /** - * When date range is not valid - */ - const INVALID_DATE_RANGE = 3; -} diff --git a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceException.php b/src/Core/Domain/SpecificPrice/Exception/SpecificPriceException.php deleted file mode 100644 index 2e59d64a..00000000 --- a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for SpecificPrice subdomain - */ -class SpecificPriceException extends DomainException -{ -} diff --git a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceNotFoundException.php b/src/Core/Domain/SpecificPrice/Exception/SpecificPriceNotFoundException.php deleted file mode 100644 index e8b58b12..00000000 --- a/src/Core/Domain/SpecificPrice/Exception/SpecificPriceNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception; - -/** - * Thrown when requested specific price could not be found - */ -class SpecificPriceNotFoundException extends SpecificPriceException -{ -} diff --git a/src/Core/Domain/SpecificPrice/ValueObject/SpecificPriceId.php b/src/Core/Domain/SpecificPrice/ValueObject/SpecificPriceId.php deleted file mode 100644 index 91fa7a10..00000000 --- a/src/Core/Domain/SpecificPrice/ValueObject/SpecificPriceId.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SpecificPrice\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Exception\SpecificPriceConstraintException; - -/** - * Holds identification data of specific price - */ -class SpecificPriceId -{ - /** - * @var int - */ - private $specificPriceId; - - /** - * @param int $specificPriceId - * - * @throws SpecificPriceConstraintException - */ - public function __construct(int $specificPriceId) - { - $this->assertIsGreaterThanZero($specificPriceId); - $this->specificPriceId = $specificPriceId; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->specificPriceId; - } - - /** - * Validates that the value is greater than zero - * - * @param int $value - * - * @throws SpecificPriceConstraintException - */ - private function assertIsGreaterThanZero(int $value): void - { - if (!is_int($value) || 0 >= $value) { - throw new SpecificPriceConstraintException(sprintf('Invalid specific price id "%s".', $value), SpecificPriceConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/SqlManagement/Command/AddSqlRequestCommand.php b/src/Core/Domain/SqlManagement/Command/AddSqlRequestCommand.php deleted file mode 100644 index 2948321b..00000000 --- a/src/Core/Domain/SqlManagement/Command/AddSqlRequestCommand.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestConstraintException; - -/** - * This command creates new SqlRequest entity with provided data. - */ -class AddSqlRequestCommand -{ - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $sql; - - /** - * @param string $name - * @param string $sql - * - * @throws SqlRequestConstraintException - */ - public function __construct($name, $sql) - { - $this - ->setName($name) - ->setSql($sql); - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getSql() - { - return $this->sql; - } - - /** - * Set Request SQL name. - * - * @param string $name - * - * @return self - * - * @throws SqlRequestConstraintException - */ - private function setName($name) - { - if (!is_string($name) || empty($name)) { - throw new SqlRequestConstraintException(sprintf('Invalid SqlRequest name %s', var_export($name, true)), SqlRequestConstraintException::INVALID_NAME); - } - - $this->name = $name; - - return $this; - } - - /** - * Set Request SQL query. - * - * @param string $sql - * - * @return $this - * - * @throws SqlRequestConstraintException - */ - private function setSql($sql) - { - if (!is_string($sql) || empty($sql)) { - throw new SqlRequestConstraintException(sprintf('Invalid SqlRequest SQL query %s', var_export($sql, true)), SqlRequestConstraintException::INVALID_SQL_QUERY); - } - - $this->sql = $sql; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Command/BulkDeleteSqlRequestCommand.php b/src/Core/Domain/SqlManagement/Command/BulkDeleteSqlRequestCommand.php deleted file mode 100644 index d982552d..00000000 --- a/src/Core/Domain/SqlManagement/Command/BulkDeleteSqlRequestCommand.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Class BulkDeleteSqlRequestCommand deletes provided SqlRequests. - */ -class BulkDeleteSqlRequestCommand -{ - /** - * @var SqlRequestId[] - */ - private $sqlRequestIds = []; - - /** - * @param int[] $sqlRequestIds - * - * @throws SqlRequestException - */ - public function __construct(array $sqlRequestIds) - { - $this->setSqlRequestIds($sqlRequestIds); - } - - /** - * @return SqlRequestId[] - */ - public function getSqlRequestIds() - { - return $this->sqlRequestIds; - } - - /** - * @param array $sqlRequestIds - * - * @throws SqlRequestException - * - * @return self - */ - private function setSqlRequestIds(array $sqlRequestIds) - { - if (empty($sqlRequestIds)) { - throw new SqlRequestConstraintException('Missing SqlRequest data for bulk deleting', SqlRequestConstraintException::MISSING_BULK_DATA); - } - - foreach ($sqlRequestIds as $sqlRequestId) { - $this->sqlRequestIds[] = new SqlRequestId($sqlRequestId); - } - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Command/DeleteSqlRequestCommand.php b/src/Core/Domain/SqlManagement/Command/DeleteSqlRequestCommand.php deleted file mode 100644 index 357c544e..00000000 --- a/src/Core/Domain/SqlManagement/Command/DeleteSqlRequestCommand.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Class DeleteSqlRequestCommand command delete SqlRequest by given id. - */ -class DeleteSqlRequestCommand -{ - /** - * @var SqlRequestId - */ - private $sqlRequestId; - - /** - * @param SqlRequestId $sqlRequestId - */ - public function __construct(SqlRequestId $sqlRequestId) - { - $this->setSqlRequestId($sqlRequestId); - } - - /** - * @return SqlRequestId - */ - public function getSqlRequestId() - { - return $this->sqlRequestId; - } - - /** - * @param SqlRequestId $sqlRequestId - * - * @return self - */ - private function setSqlRequestId($sqlRequestId) - { - $this->sqlRequestId = $sqlRequestId; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Command/EditSqlRequestCommand.php b/src/Core/Domain/SqlManagement/Command/EditSqlRequestCommand.php deleted file mode 100644 index 28328f66..00000000 --- a/src/Core/Domain/SqlManagement/Command/EditSqlRequestCommand.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * This command modifies an existing SqlRequest object, replacing its data by the provided one. - */ -class EditSqlRequestCommand -{ - /** - * @var SqlRequestId - */ - private $sqlRequestId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $sql; - - /** - * @param SqlRequestId $sqlRequestId - */ - public function __construct(SqlRequestId $sqlRequestId) - { - $this->setSqlRequestId($sqlRequestId); - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getSql() - { - return $this->sql; - } - - /** - * @return SqlRequestId - */ - public function getSqlRequestId() - { - return $this->sqlRequestId; - } - - /** - * @param SqlRequestId $sqlRequestId - * - * @return self - */ - private function setSqlRequestId(SqlRequestId $sqlRequestId) - { - $this->sqlRequestId = $sqlRequestId; - - return $this; - } - - /** - * Set Request SQL name. - * - * @param string $name - * - * @return self - * - * @throws SqlRequestConstraintException - */ - public function setName($name) - { - if (!is_string($name) || empty($name)) { - throw new SqlRequestConstraintException(sprintf('Invalid SqlRequest name "%s"', var_export($name, true)), SqlRequestConstraintException::INVALID_NAME); - } - - $this->name = $name; - - return $this; - } - - /** - * Set Request SQL query. - * - * @param string $sql - * - * @return self - * - * @throws SqlRequestConstraintException - */ - public function setSql($sql) - { - if (!is_string($sql) || empty($sql)) { - throw new SqlRequestConstraintException(sprintf('Invalid SqlRequest SQL query "%s"', var_export($sql, true)), SqlRequestConstraintException::INVALID_SQL_QUERY); - } - - $this->sql = $sql; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Command/SaveSqlRequestSettingsCommand.php b/src/Core/Domain/SqlManagement/Command/SaveSqlRequestSettingsCommand.php deleted file mode 100644 index a6dde544..00000000 --- a/src/Core/Domain/SqlManagement/Command/SaveSqlRequestSettingsCommand.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestSettingsConstraintException; -use PrestaShop\PrestaShop\Core\Encoding\CharsetEncoding; - -/** - * Class SaveSqlManagerSettingsCommand saves default file encoding settings - * for SqlRequest's query result export file. - */ -class SaveSqlRequestSettingsCommand -{ - /** - * @var string - */ - private $fileEncoding; - - /** - * @param string $fileEncoding - * - * @throws SqlRequestSettingsConstraintException - */ - public function __construct($fileEncoding) - { - $this->setFileEncoding($fileEncoding); - } - - /** - * @return string - */ - public function getFileEncoding() - { - return $this->fileEncoding; - } - - /** - * @param string $fileEncoding - * - * @return self - * - * @throws SqlRequestSettingsConstraintException - */ - private function setFileEncoding($fileEncoding) - { - if (!is_string($fileEncoding) || empty($fileEncoding)) { - throw new SqlRequestSettingsConstraintException(sprintf('Invalid File Encoding %s supplied', var_export($fileEncoding, true)), SqlRequestSettingsConstraintException::INVALID_FILE_ENCODING); - } - - $supportedFileEncodings = [ - CharsetEncoding::ISO_8859_1, - CharsetEncoding::UTF_8, - ]; - - if (!in_array($fileEncoding, $supportedFileEncodings)) { - throw new SqlRequestSettingsConstraintException(sprintf('Not supported File Encoding %s supplied. Supported encodings are %s', var_export($fileEncoding, true), var_export(implode(',', $supportedFileEncodings), true)), SqlRequestSettingsConstraintException::NOT_SUPPORTED_FILE_ENCODING); - } - - $this->fileEncoding = $fileEncoding; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/AddSqlRequestHandlerInterface.php b/src/Core/Domain/SqlManagement/CommandHandler/AddSqlRequestHandlerInterface.php deleted file mode 100644 index d2dd0b97..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/AddSqlRequestHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\AddSqlRequestCommand; - -/** - * Interface AddSqlRequestHandlerInterface defines contract for SqlRequest creation handler. - */ -interface AddSqlRequestHandlerInterface -{ - /** - * @param AddSqlRequestCommand $command - * - * @return int Created SqlRequest id - */ - public function handle(AddSqlRequestCommand $command); -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/BulkDeleteSqlRequestHandlerInterface.php b/src/Core/Domain/SqlManagement/CommandHandler/BulkDeleteSqlRequestHandlerInterface.php deleted file mode 100644 index 6f171c6c..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/BulkDeleteSqlRequestHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\BulkDeleteSqlRequestCommand; - -/** - * Interface BulkDeleteSqlRequestHandlerInterface defines contract for bulk deleting handler of SqlRequest. - */ -interface BulkDeleteSqlRequestHandlerInterface -{ - /** - * @param BulkDeleteSqlRequestCommand $command - */ - public function handle(BulkDeleteSqlRequestCommand $command); -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/DeleteSqlRequestHandlerInterface.php b/src/Core/Domain/SqlManagement/CommandHandler/DeleteSqlRequestHandlerInterface.php deleted file mode 100644 index ca4e9097..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/DeleteSqlRequestHandlerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\DeleteSqlRequestCommand; - -/** - * Interface DeleteSqlRequestHandlerInterface defines contract for SqlRequest delete handler. - */ -interface DeleteSqlRequestHandlerInterface -{ - /** - * Delete SqlRequest. - * - * @param DeleteSqlRequestCommand $command - */ - public function handle(DeleteSqlRequestCommand $command); -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/EditSqlRequestHandlerInterface.php b/src/Core/Domain/SqlManagement/CommandHandler/EditSqlRequestHandlerInterface.php deleted file mode 100644 index 5170a276..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/EditSqlRequestHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\EditSqlRequestCommand; - -/** - * Interface EditSqlRequestHandlerInterface defines contract SqlRequest editing handler. - */ -interface EditSqlRequestHandlerInterface -{ - /** - * @param EditSqlRequestCommand $command - */ - public function handle(EditSqlRequestCommand $command); -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandler.php b/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandler.php deleted file mode 100644 index 0e577256..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandler.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\SaveSqlRequestSettingsCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestSettings; -use PrestaShop\PrestaShop\Core\Encoding\CharsetEncoding; - -/** - * Class SaveSqlRequestSettingsHandler handles command to save SqlRequest settings. - */ -final class SaveSqlRequestSettingsHandler implements SaveSqlRequestSettingsHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(SaveSqlRequestSettingsCommand $command) - { - $this->configuration->set(SqlRequestSettings::FILE_ENCODING, $this->getEncodingFileValue($command)); - } - - /** - * File encodings are saved as integer values in databases. - * - * @param SaveSqlRequestSettingsCommand $command - * - * @return int - */ - private function getEncodingFileValue(SaveSqlRequestSettingsCommand $command) - { - $valuesMapping = [ - CharsetEncoding::UTF_8 => 1, - CharsetEncoding::ISO_8859_1 => 2, - ]; - - return $valuesMapping[$command->getFileEncoding()]; - } -} diff --git a/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandlerInterface.php b/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandlerInterface.php deleted file mode 100644 index 6e263508..00000000 --- a/src/Core/Domain/SqlManagement/CommandHandler/SaveSqlRequestSettingsHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\SaveSqlRequestSettingsCommand; - -/** - * Interface SaveSqlRequestSettingsHandlerInterface. - */ -interface SaveSqlRequestSettingsHandlerInterface -{ - /** - * @param SaveSqlRequestSettingsCommand $command - */ - public function handle(SaveSqlRequestSettingsCommand $command); -} diff --git a/src/Core/Domain/SqlManagement/DatabaseTableFields.php b/src/Core/Domain/SqlManagement/DatabaseTableFields.php deleted file mode 100644 index 0f00213d..00000000 --- a/src/Core/Domain/SqlManagement/DatabaseTableFields.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlManagementConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\DatabaseTableField; - -/** - * Class DatabaseTableFields stores fields of single database table. - */ -class DatabaseTableFields -{ - /** - * @var DatabaseTableField[] - */ - private $fields; - - /** - * @param DatabaseTableField[] $fields - * - * @throws SqlManagementConstraintException - */ - public function __construct(array $fields) - { - $this->setFields($fields); - } - - /** - * @return DatabaseTableField[] - */ - public function getFields() - { - return $this->fields; - } - - /** - * @param DatabaseTableField[] $fields - * - * @return self - * - * @throws SqlManagementConstraintException - */ - private function setFields(array $fields) - { - foreach ($fields as $field) { - if (!$field instanceof DatabaseTableField) { - throw new SqlManagementConstraintException(sprintf('Invalid database field %s supplied. Expected instance of %s', var_export($field, true), DatabaseTableField::class), SqlManagementConstraintException::INVALID_DATABASE_TABLE_FIELD); - } - } - - $this->fields = $fields; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/DatabaseTablesList.php b/src/Core/Domain/SqlManagement/DatabaseTablesList.php deleted file mode 100644 index 23a9e4d3..00000000 --- a/src/Core/Domain/SqlManagement/DatabaseTablesList.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; - -/** - * Class DatabaseTablesList stores list of database tables. - */ -class DatabaseTablesList -{ - /** - * @var string[] - */ - private $dbTables; - - /** - * @param string[] $dbTables - * - * @throws SqlRequestException - */ - public function __construct(array $dbTables) - { - $this->setTables($dbTables); - } - - /** - * @return string[] - */ - public function getTables() - { - return $this->dbTables; - } - - /** - * @param array $tables - * - * @return self - * - * @throws SqlRequestException - */ - private function setTables(array $tables) - { - $filteredTables = array_filter($tables, 'is_string'); - - if ($filteredTables !== $tables) { - throw new SqlRequestException('Invalid database table list provided. Database tables list must contain string values only.'); - } - - $this->dbTables = $tables; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/EditableSqlRequest.php b/src/Core/Domain/SqlManagement/EditableSqlRequest.php deleted file mode 100644 index b0373913..00000000 --- a/src/Core/Domain/SqlManagement/EditableSqlRequest.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Class EditableSqlRequest stores information about SqlRequest that can be edited. - */ -class EditableSqlRequest -{ - /** - * @var SqlRequestId - */ - private $sqlRequestId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $sql; - - /** - * @param SqlRequestId $requestSqlId - * @param string $name - * @param string $sql - * - * @throws SqlRequestException - */ - public function __construct( - SqlRequestId $requestSqlId, - $name, - $sql - ) { - $this - ->setSqlRequestId($requestSqlId) - ->setName($name) - ->setSql($sql); - } - - /** - * @return SqlRequestId - */ - public function getSqlRequestId() - { - return $this->sqlRequestId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getSql() - { - return $this->sql; - } - - /** - * @param SqlRequestId $sqlRequestId - * - * @return EditableSqlRequest - */ - private function setSqlRequestId(SqlRequestId $sqlRequestId) - { - $this->sqlRequestId = $sqlRequestId; - - return $this; - } - - /** - * @param string $name - * - * @return EditableSqlRequest - * - * @throws SqlRequestException - */ - private function setName($name) - { - if (empty($name)) { - throw new SqlRequestException('SqlRequest name cannot be empty'); - } - - $this->name = $name; - - return $this; - } - - /** - * @param string $sql - * - * @return EditableSqlRequest - * - * @throws SqlRequestException - */ - private function setSql($sql) - { - if (empty($sql)) { - throw new SqlRequestException('SqlRequest SQL cannot be empty'); - } - - $this->sql = $sql; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Exception/CannotAddSqlRequestException.php b/src/Core/Domain/SqlManagement/Exception/CannotAddSqlRequestException.php deleted file mode 100644 index 4aeaee30..00000000 --- a/src/Core/Domain/SqlManagement/Exception/CannotAddSqlRequestException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when new SqlRequest cannot be created - */ -class CannotAddSqlRequestException extends SqlRequestException -{ -} diff --git a/src/Core/Domain/SqlManagement/Exception/CannotDeleteSqlRequestException.php b/src/Core/Domain/SqlManagement/Exception/CannotDeleteSqlRequestException.php deleted file mode 100644 index 9da264bf..00000000 --- a/src/Core/Domain/SqlManagement/Exception/CannotDeleteSqlRequestException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when SqlRequest cannot be deleted - */ -class CannotDeleteSqlRequestException extends SqlRequestException -{ - /** - * When deleting single SqlRequest - */ - const CANNOT_SINGLE_DELETE = 10; - - /** - * When deleting SqlRequest in bulk action - */ - const CANNOT_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/SqlManagement/Exception/CannotEditSqlRequestException.php b/src/Core/Domain/SqlManagement/Exception/CannotEditSqlRequestException.php deleted file mode 100644 index 74a03d6a..00000000 --- a/src/Core/Domain/SqlManagement/Exception/CannotEditSqlRequestException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when SqlRequest cannot be edited - */ -class CannotEditSqlRequestException extends SqlRequestException -{ -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlManagementConstraintException.php b/src/Core/Domain/SqlManagement/Exception/SqlManagementConstraintException.php deleted file mode 100644 index fe6aff3d..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlManagementConstraintException.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when SqlManagement constraints are violated - */ -class SqlManagementConstraintException extends SqlManagementException -{ - /** - * When database table name is invalid - */ - const INVALID_DATABASE_TABLE_NAME = 10; - - /** - * When database table field is invalid - */ - const INVALID_DATABASE_TABLE_FIELD = 20; - - /** - * When database table field name is invalid - */ - const INVALID_DATABASE_TABLE_FIELD_NAME = 30; - - /** - * When database table field type is invalid - */ - const INVALID_DATABASE_TABLE_FIELD_TYPE = 40; -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlManagementException.php b/src/Core/Domain/SqlManagement/Exception/SqlManagementException.php deleted file mode 100644 index 4f4392c7..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlManagementException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class SqlManagementException base exception of SqlManagement bounded context. - */ -class SqlManagementException extends DomainException -{ -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlRequestConstraintException.php b/src/Core/Domain/SqlManagement/Exception/SqlRequestConstraintException.php deleted file mode 100644 index e8a30ecf..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlRequestConstraintException.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when SqlRequest constraints are violated - */ -class SqlRequestConstraintException extends SqlRequestException -{ - /** - * When provided name is not valid - */ - const INVALID_NAME = 10; - - /** - * When provided sql query is not valid - */ - const INVALID_SQL_QUERY = 20; - - /** - * When provided sql query format is invalid - */ - const MALFORMED_SQL_QUERY = 30; - - /** - * When empty data is provided for bulk action - */ - const MISSING_BULK_DATA = 40; -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlRequestException.php b/src/Core/Domain/SqlManagement/Exception/SqlRequestException.php deleted file mode 100644 index 8d95674f..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlRequestException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Base exception for SqlRequest sub-domain - */ -class SqlRequestException extends SqlManagementException -{ -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlRequestNotFoundException.php b/src/Core/Domain/SqlManagement/Exception/SqlRequestNotFoundException.php deleted file mode 100644 index 5b518932..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlRequestNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Is thrown when required SqlRequest cannot be found - */ -class SqlRequestNotFoundException extends SqlRequestException -{ -} diff --git a/src/Core/Domain/SqlManagement/Exception/SqlRequestSettingsConstraintException.php b/src/Core/Domain/SqlManagement/Exception/SqlRequestSettingsConstraintException.php deleted file mode 100644 index 063d59cb..00000000 --- a/src/Core/Domain/SqlManagement/Exception/SqlRequestSettingsConstraintException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception; - -/** - * Class SqlRequestSettingsConstraintException is thrown when invalid settings are supplied. - */ -class SqlRequestSettingsConstraintException extends SqlRequestException -{ - const INVALID_FILE_ENCODING = 10; - const NOT_SUPPORTED_FILE_ENCODING = 20; -} diff --git a/src/Core/Domain/SqlManagement/Query/GetDatabaseTableFieldsList.php b/src/Core/Domain/SqlManagement/Query/GetDatabaseTableFieldsList.php deleted file mode 100644 index 5bde72b0..00000000 --- a/src/Core/Domain/SqlManagement/Query/GetDatabaseTableFieldsList.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlManagementConstraintException; - -/** - * Class GetAttributesForDatabaseTableQuery gets list of attributes for given database table name. - */ -class GetDatabaseTableFieldsList -{ - /** - * @var string - */ - private $tableName; - - /** - * @param string $tableName - * - * @throws SqlManagementConstraintException - */ - public function __construct($tableName) - { - $this->setTableName($tableName); - } - - /** - * @return string - */ - public function getTableName() - { - return $this->tableName; - } - - /** - * @param string $tableName - * - * @return self - * - * @throws SqlManagementConstraintException - */ - public function setTableName($tableName) - { - if (!is_string($tableName) || empty($tableName)) { - throw new SqlManagementConstraintException(sprintf('Invalid database table name %s supplied', var_export($tableName, true)), SqlManagementConstraintException::INVALID_DATABASE_TABLE_NAME); - } - - $this->tableName = $tableName; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/Query/GetDatabaseTablesList.php b/src/Core/Domain/SqlManagement/Query/GetDatabaseTablesList.php deleted file mode 100644 index f1907281..00000000 --- a/src/Core/Domain/SqlManagement/Query/GetDatabaseTablesList.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query; - -/** - * Class GetDatabaseTablesListQuery gets list of database tables. - */ -class GetDatabaseTablesList -{ -} diff --git a/src/Core/Domain/SqlManagement/Query/GetSqlRequestExecutionResult.php b/src/Core/Domain/SqlManagement/Query/GetSqlRequestExecutionResult.php deleted file mode 100644 index c0f0b49f..00000000 --- a/src/Core/Domain/SqlManagement/Query/GetSqlRequestExecutionResult.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Class GetSqlRequestExecutionResultQuery returns the result of executing an SqlRequest query. - */ -class GetSqlRequestExecutionResult -{ - /** - * @var SqlRequestId - */ - private $requestSqlId; - - /** - * @param int $requestSqlId - * - * @throws SqlRequestException - */ - public function __construct($requestSqlId) - { - $this->requestSqlId = new SqlRequestId($requestSqlId); - } - - /** - * @return SqlRequestId - */ - public function getSqlRequestId() - { - return $this->requestSqlId; - } -} diff --git a/src/Core/Domain/SqlManagement/Query/GetSqlRequestForEditing.php b/src/Core/Domain/SqlManagement/Query/GetSqlRequestForEditing.php deleted file mode 100644 index 375000d9..00000000 --- a/src/Core/Domain/SqlManagement/Query/GetSqlRequestForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Class GetSqlRequestForEditingQuery gets SqlRequest data that can be edited. - */ -class GetSqlRequestForEditing -{ - /** - * @var SqlRequestId - */ - private $requestSqlId; - - /** - * @param $requestSqlId - * - * @throws SqlRequestException - */ - public function __construct($requestSqlId) - { - $this->requestSqlId = new SqlRequestId($requestSqlId); - } - - /** - * @return SqlRequestId - */ - public function getRequestSqlId() - { - return $this->requestSqlId; - } -} diff --git a/src/Core/Domain/SqlManagement/Query/GetSqlRequestSettings.php b/src/Core/Domain/SqlManagement/Query/GetSqlRequestSettings.php deleted file mode 100644 index 9c42e434..00000000 --- a/src/Core/Domain/SqlManagement/Query/GetSqlRequestSettings.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query; - -/** - * Class GetSqlRequestSettingsQuery gets SqlRequest settings. - */ -class GetSqlRequestSettings -{ -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTableFieldsListHandlerInterface.php b/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTableFieldsListHandlerInterface.php deleted file mode 100644 index 9ffd1c78..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTableFieldsListHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTableFields; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTableFieldsList; - -/** - * Interface GetAttributesForDatabaseTableHandlerInterface. - */ -interface GetDatabaseTableFieldsListHandlerInterface -{ - /** - * @param GetDatabaseTableFieldsList $query - * - * @return DatabaseTableFields - */ - public function handle(GetDatabaseTableFieldsList $query); -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTablesListHandlerInterface.php b/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTablesListHandlerInterface.php deleted file mode 100644 index ccd2d840..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetDatabaseTablesListHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTablesList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTablesList; - -/** - * Interface GetDatabaseTablesListHandlerInterface. - */ -interface GetDatabaseTablesListHandlerInterface -{ - /** - * @param GetDatabaseTablesList $query - * - * @return DatabaseTablesList - */ - public function handle(GetDatabaseTablesList $query); -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestExecutionResultHandlerInterface.php b/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestExecutionResultHandlerInterface.php deleted file mode 100644 index 5176ed21..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestExecutionResultHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestExecutionResult; - -/** - * Interface GetSqlRequestResultForViewingHandlerInterface defines contract for getting SqlRequest SQL query result. - */ -interface GetSqlRequestExecutionResultHandlerInterface -{ - /** - * @param GetSqlRequestExecutionResult $query - * - * @return SqlRequestExecutionResult - */ - public function handle(GetSqlRequestExecutionResult $query); -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestForEditingHandlerInterface.php b/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestForEditingHandlerInterface.php deleted file mode 100644 index dbeb7cf6..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestForEditingHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\EditableSqlRequest; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestForEditing; - -interface GetSqlRequestForEditingHandlerInterface -{ - /** - * @param GetSqlRequestForEditing $query - * - * @return EditableSqlRequest - */ - public function handle(GetSqlRequestForEditing $query); -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandler.php b/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandler.php deleted file mode 100644 index 608fb059..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestSettings; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestSettings; -use PrestaShop\PrestaShop\Core\Encoding\CharsetEncoding; - -/** - * Class GetSqlRequestSettingsHandler handles query to get SqlRequest settings. - */ -final class GetSqlRequestSettingsHandler implements GetSqlRequestSettingsHandlerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(GetSqlRequestSettings $query) - { - $fileEncodingIntValue = $this->configuration->get(SqlRequestSettings::FILE_ENCODING); - - return new SqlRequestSettings( - $this->getFileEncoding($fileEncodingIntValue) - ); - } - - /** - * File encodings are saved as integer values in databases. - * - * @param int|null $rawValue - * - * @return string - */ - private function getFileEncoding($rawValue) - { - $valuesMapping = [ - 1 => CharsetEncoding::UTF_8, - 2 => CharsetEncoding::ISO_8859_1, - ]; - - if (isset($valuesMapping[$rawValue])) { - return $valuesMapping[$rawValue]; - } - - return CharsetEncoding::UTF_8; - } -} diff --git a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandlerInterface.php b/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandlerInterface.php deleted file mode 100644 index 57537c1d..00000000 --- a/src/Core/Domain/SqlManagement/QueryHandler/GetSqlRequestSettingsHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestSettings; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestSettings; - -/** - * Interface GetSqlRequestSettingsHandlerInterface. - */ -interface GetSqlRequestSettingsHandlerInterface -{ - /** - * @param GetSqlRequestSettings $query - * - * @return SqlRequestSettings - */ - public function handle(GetSqlRequestSettings $query); -} diff --git a/src/Core/Domain/SqlManagement/SqlRequestExecutionResult.php b/src/Core/Domain/SqlManagement/SqlRequestExecutionResult.php deleted file mode 100644 index 89e0b02c..00000000 --- a/src/Core/Domain/SqlManagement/SqlRequestExecutionResult.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement; - -/** - * Class SqlRequestExecutionResult stores result of SqlRequest SQL query execution result. - */ -class SqlRequestExecutionResult -{ - /** - * @var array - */ - private $columns; - - /** - * @var array - */ - private $rows; - - /** - * @param array $columns - * @param array $rows - */ - public function __construct(array $columns, array $rows) - { - $this->columns = $columns; - $this->rows = $rows; - } - - /** - * @return array - */ - public function getColumns() - { - return $this->columns; - } - - /** - * @return array - */ - public function getRows() - { - return $this->rows; - } -} diff --git a/src/Core/Domain/SqlManagement/SqlRequestSettings.php b/src/Core/Domain/SqlManagement/SqlRequestSettings.php deleted file mode 100644 index c738f8c0..00000000 --- a/src/Core/Domain/SqlManagement/SqlRequestSettings.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement; - -/** - * Class SqlRequestSettings stores SqlRequest settings. - */ -class SqlRequestSettings -{ - /** - * Name of the setting for SqlRequest SQL query result file encoding in ps_configuration. - */ - const FILE_ENCODING = 'PS_ENCODING_FILE_MANAGER_SQL'; - - /** - * @var string Encoding in which downloaded SqlRequest SQL query result files will be encoded - */ - private $fileEncoding; - - /** - * @param $fileEncoding - */ - public function __construct($fileEncoding) - { - $this->setFileEncoding($fileEncoding); - } - - /** - * @return string - */ - public function getFileEncoding() - { - return $this->fileEncoding; - } - - /** - * @param string $fileEncoding - */ - private function setFileEncoding($fileEncoding) - { - $this->fileEncoding = $fileEncoding; - } -} diff --git a/src/Core/Domain/SqlManagement/ValueObject/DatabaseTableField.php b/src/Core/Domain/SqlManagement/ValueObject/DatabaseTableField.php deleted file mode 100644 index be0ff104..00000000 --- a/src/Core/Domain/SqlManagement/ValueObject/DatabaseTableField.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlManagementConstraintException; - -/** - * Class DatabaseTableField stores information about single database table field. - */ -class DatabaseTableField -{ - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $type; - - /** - * @param string $name - * @param string $type - * - * @throws SqlManagementConstraintException - */ - public function __construct($name, $type) - { - $this - ->setName($name) - ->setType($type); - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @param string $name - * - * @return self - * - * @throws SqlManagementConstraintException - */ - private function setName($name) - { - if (!is_string($name) || empty($name)) { - throw new SqlManagementConstraintException(sprintf('Invalid database table field name %s supplied', var_export($name, true)), SqlManagementConstraintException::INVALID_DATABASE_TABLE_FIELD_NAME); - } - - $this->name = $name; - - return $this; - } - - /** - * @return string - */ - public function getType() - { - return $this->type; - } - - /** - * @param string $type - * - * @return self - * - * @throws SqlManagementConstraintException - */ - private function setType($type) - { - if (!is_string($type) || empty($type)) { - throw new SqlManagementConstraintException(sprintf('Invalid database table field type %s supplied', var_export($type, true)), SqlManagementConstraintException::INVALID_DATABASE_TABLE_FIELD_TYPE); - } - - $this->type = $type; - - return $this; - } -} diff --git a/src/Core/Domain/SqlManagement/ValueObject/SqlRequestId.php b/src/Core/Domain/SqlManagement/ValueObject/SqlRequestId.php deleted file mode 100644 index e284af6d..00000000 --- a/src/Core/Domain/SqlManagement/ValueObject/SqlRequestId.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; - -/** - * Class SqlRequestId is SqlRequest identifier. - */ -class SqlRequestId -{ - /** - * @var int - */ - private $value; - - /** - * @param int $requestSqlId - * - * @throws SqlRequestException - */ - public function __construct($requestSqlId) - { - if (!is_numeric($requestSqlId) || $requestSqlId <= 0) { - throw new SqlRequestException(sprintf('Invalid SqlRequest id: %s', var_export($requestSqlId, true))); - } - - $this->value = (int) $requestSqlId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->value; - } -} diff --git a/src/Core/Domain/State/Exception/StateConstraintException.php b/src/Core/Domain/State/Exception/StateConstraintException.php deleted file mode 100644 index 36c09322..00000000 --- a/src/Core/Domain/State/Exception/StateConstraintException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\State\Exception; - -/** - * Is thrown when State constraint is violated - */ -class StateConstraintException extends StateException -{ - const INVALID_ID = 1; -} diff --git a/src/Core/Domain/State/Exception/StateException.php b/src/Core/Domain/State/Exception/StateException.php deleted file mode 100644 index e2ed6b1d..00000000 --- a/src/Core/Domain/State/Exception/StateException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\State\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for state subdomain - */ -class StateException extends DomainException -{ -} diff --git a/src/Core/Domain/State/ValueObject/StateId.php b/src/Core/Domain/State/ValueObject/StateId.php deleted file mode 100644 index e71bbea2..00000000 --- a/src/Core/Domain/State/ValueObject/StateId.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\State\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; - -/** - * Provides state id - */ -class StateId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - * - * @throws StateConstraintException - */ - public function __construct(int $id) - { - $this->assertPositiveInt($id); - $this->id = $id; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->id; - } - - /** - * @param int $value - * - * @throws StateConstraintException - */ - private function assertPositiveInt(int $value) - { - if (0 > $value) { - throw new StateConstraintException(sprintf('Invalid state id "%s".', var_export($value, true)), StateConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Supplier/Command/AbstractBulkSupplierCommand.php b/src/Core/Domain/Supplier/Command/AbstractBulkSupplierCommand.php deleted file mode 100644 index 8c0ccafe..00000000 --- a/src/Core/Domain/Supplier/Command/AbstractBulkSupplierCommand.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -/** - * Class AbstractBulkSupplierCommand is responsible for providing shared logic between all bulk actions - * in brands and suppliers listing. - */ -abstract class AbstractBulkSupplierCommand -{ - /** - * @param array $ids - * - * @return bool - */ - protected function assertIsEmptyOrContainsNonIntegerValues(array $ids) - { - return empty($ids) || $ids !== array_filter($ids, 'is_int'); - } -} diff --git a/src/Core/Domain/Supplier/Command/AddSupplierCommand.php b/src/Core/Domain/Supplier/Command/AddSupplierCommand.php deleted file mode 100644 index e61a4fe0..00000000 --- a/src/Core/Domain/Supplier/Command/AddSupplierCommand.php +++ /dev/null @@ -1,295 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -/** - * Creates new supplier with provided data - */ -class AddSupplierCommand -{ - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var bool - */ - private $enabled; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var array - */ - private $shopAssociation; - - /** - * @var string|null - */ - private $address2; - - /** - * @var string|null - */ - private $postCode; - /** - * @var int|null - */ - private $stateId; - - /** - * @var string|null - */ - private $phone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string|null - */ - private $dni; - - /** - * @param string $name - * @param string $address - * @param string $city - * @param int $countryId - * @param bool $enabled - * @param string[] $localizedDescriptions - * @param string[] $localizedMetaTitles - * @param string[] $localizedMetaDescriptions - * @param string[] $localizedMetaKeywords - * @param array $shopAssociation - * @param string|null $address2 - * @param string|null $postCode - * @param int|null $stateId - * @param string|null $phone - * @param string|null $mobilePhone - * @param string $dni - */ - public function __construct( - string $name, - string $address, - string $city, - int $countryId, - bool $enabled, - array $localizedDescriptions, - array $localizedMetaTitles, - array $localizedMetaDescriptions, - array $localizedMetaKeywords, - array $shopAssociation, - ?string $address2 = null, - ?string $postCode = null, - ?int $stateId = null, - ?string $phone = null, - ?string $mobilePhone = null, - ?string $dni = null - ) { - $this->name = $name; - $this->address = $address; - $this->city = $city; - $this->countryId = $countryId; - $this->enabled = $enabled; - $this->localizedDescriptions = $localizedDescriptions; - $this->localizedMetaTitles = $localizedMetaTitles; - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - $this->localizedMetaKeywords = $localizedMetaKeywords; - $this->shopAssociation = $shopAssociation; - $this->address2 = $address2; - $this->postCode = $postCode; - $this->stateId = $stateId; - $this->phone = $phone; - $this->mobilePhone = $mobilePhone; - $this->dni = $dni; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getAddress(): string - { - return $this->address; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string|null - */ - public function getAddress2(): ?string - { - return $this->address2; - } - - /** - * @return int - */ - public function getCountryId(): ?int - { - return $this->countryId; - } - - /** - * @return string|null - */ - public function getPostCode(): ?string - { - return $this->postCode; - } - - /** - * @return int|null - */ - public function getStateId(): ?int - { - return $this->stateId; - } - - /** - * @return string|null - */ - public function getPhone(): ?string - { - return $this->phone; - } - - /** - * @return string|null - */ - public function getMobilePhone(): ?string - { - return $this->mobilePhone; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions(): array - { - return $this->localizedDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles(): array - { - return $this->localizedMetaTitles; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions(): array - { - return $this->localizedMetaDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords(): array - { - return $this->localizedMetaKeywords; - } - - /** - * @return bool - */ - public function isEnabled(): bool - { - return $this->enabled; - } - - /** - * @return array - */ - public function getShopAssociation(): array - { - return $this->shopAssociation; - } - - /** - * @return string|null - */ - public function getDni(): ?string - { - return $this->dni; - } -} diff --git a/src/Core/Domain/Supplier/Command/BulkDeleteSupplierCommand.php b/src/Core/Domain/Supplier/Command/BulkDeleteSupplierCommand.php deleted file mode 100644 index d4428ab3..00000000 --- a/src/Core/Domain/Supplier/Command/BulkDeleteSupplierCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Class BulkDeleteSupplierCommand is responsible for deleting multiple suppliers. - */ -class BulkDeleteSupplierCommand extends AbstractBulkSupplierCommand -{ - /** - * @var SupplierId[] - */ - private $supplierIds; - - /** - * @param int[] $supplierIds - * - * @throws SupplierException - * @throws SupplierConstraintException - */ - public function __construct(array $supplierIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($supplierIds)) { - throw new SupplierConstraintException(sprintf('Missing supplier data or array %s contains non integer values for bulk deleting', var_export($supplierIds, true)), SupplierConstraintException::INVALID_BULK_DATA); - } - - $this->setSupplierIds($supplierIds); - } - - /** - * @return SupplierId[] - */ - public function getSupplierIds() - { - return $this->supplierIds; - } - - /** - * @param array $supplierIds - * - * @throws SupplierException - */ - private function setSupplierIds(array $supplierIds) - { - foreach ($supplierIds as $id) { - $this->supplierIds[] = new SupplierId($id); - } - } -} diff --git a/src/Core/Domain/Supplier/Command/BulkDisableSupplierCommand.php b/src/Core/Domain/Supplier/Command/BulkDisableSupplierCommand.php deleted file mode 100644 index 72d3dc60..00000000 --- a/src/Core/Domain/Supplier/Command/BulkDisableSupplierCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Class BulkDisableSupplierCommand is responsible for disabling multiple suppliers. - */ -class BulkDisableSupplierCommand extends AbstractBulkSupplierCommand -{ - /** - * @var SupplierId[] - */ - private $supplierIds; - - /** - * @param int[] $supplierIds - * - * @throws SupplierException - * @throws SupplierConstraintException - */ - public function __construct(array $supplierIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($supplierIds)) { - throw new SupplierConstraintException(sprintf('Missing supplier data or array %s contains non integer values for bulk disable', var_export($supplierIds, true)), SupplierConstraintException::INVALID_BULK_DATA); - } - - $this->setSupplierIds($supplierIds); - } - - /** - * @return SupplierId[] - */ - public function getSupplierIds() - { - return $this->supplierIds; - } - - /** - * @param array $supplierIds - * - * @throws SupplierException - */ - private function setSupplierIds(array $supplierIds) - { - foreach ($supplierIds as $id) { - $this->supplierIds[] = new SupplierId($id); - } - } -} diff --git a/src/Core/Domain/Supplier/Command/BulkEnableSupplierCommand.php b/src/Core/Domain/Supplier/Command/BulkEnableSupplierCommand.php deleted file mode 100644 index 2cfae390..00000000 --- a/src/Core/Domain/Supplier/Command/BulkEnableSupplierCommand.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Class BulkEnableSupplierCommand is responsible for enabling multiple suppliers. - */ -class BulkEnableSupplierCommand extends AbstractBulkSupplierCommand -{ - /** - * @var SupplierId[] - */ - private $supplierIds; - - /** - * @param int[] $supplierIds - * - * @throws SupplierException - * @throws SupplierConstraintException - */ - public function __construct(array $supplierIds) - { - if ($this->assertIsEmptyOrContainsNonIntegerValues($supplierIds)) { - throw new SupplierConstraintException(sprintf('Missing supplier data or array %s contains non integer values for bulk enable', var_export($supplierIds, true)), SupplierConstraintException::INVALID_BULK_DATA); - } - - $this->setSupplierIds($supplierIds); - } - - /** - * @return SupplierId[] - */ - public function getSupplierIds() - { - return $this->supplierIds; - } - - /** - * @param array $supplierIds - * - * @throws SupplierException - */ - private function setSupplierIds(array $supplierIds) - { - foreach ($supplierIds as $id) { - $this->supplierIds[] = new SupplierId($id); - } - } -} diff --git a/src/Core/Domain/Supplier/Command/DeleteSupplierCommand.php b/src/Core/Domain/Supplier/Command/DeleteSupplierCommand.php deleted file mode 100644 index a012b47e..00000000 --- a/src/Core/Domain/Supplier/Command/DeleteSupplierCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Class DeleteSupplierCommand is responsible for deleting the supplier. - */ -class DeleteSupplierCommand -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - public function __construct($supplierId) - { - $this->supplierId = new SupplierId($supplierId); - } - - /** - * @return SupplierId - */ - public function getSupplierId() - { - return $this->supplierId; - } -} diff --git a/src/Core/Domain/Supplier/Command/EditSupplierCommand.php b/src/Core/Domain/Supplier/Command/EditSupplierCommand.php deleted file mode 100644 index b39953c9..00000000 --- a/src/Core/Domain/Supplier/Command/EditSupplierCommand.php +++ /dev/null @@ -1,459 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Edits supplier with provided data - */ -class EditSupplierCommand -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @var string|null - */ - private $name; - - /** - * @var string[]|null - */ - private $localizedDescriptions; - - /** - * @var string|null - */ - private $address; - - /** - * @var string|null - */ - private $city; - - /** - * @var string|null - */ - private $address2; - - /** - * @var int|null - */ - private $countryId; - - /** - * @var string|null - */ - private $postCode; - - /** - * @var int|null - */ - private $stateId; - - /** - * @var string|null - */ - private $phone; - - /** - * @var string|null - */ - private $mobilePhone; - - /** - * @var string[]|null - */ - private $localizedMetaTitles; - - /** - * @var string[]|null - */ - private $localizedMetaDescriptions; - - /** - * @var string[]|null - */ - private $localizedMetaKeywords; - - /** - * @var bool|null - */ - private $enabled; - - /** - * @var array|null - */ - private $associatedShops; - - /** - * @var string|null - */ - private $dni; - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - public function __construct(int $supplierId) - { - $this->supplierId = new SupplierId($supplierId); - } - - /** - * @return SupplierId - */ - public function getSupplierId(): SupplierId - { - return $this->supplierId; - } - - /** - * @return string|null - */ - public function getName(): ?string - { - return $this->name; - } - - /** - * @param string $name - * - * @return EditSupplierCommand - */ - public function setName(string $name): self - { - $this->name = $name; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedDescriptions(): ?array - { - return $this->localizedDescriptions; - } - - /** - * @param string[] $localizedDescriptions - * - * @return EditSupplierCommand - */ - public function setLocalizedDescriptions(array $localizedDescriptions): self - { - $this->localizedDescriptions = $localizedDescriptions; - - return $this; - } - - /** - * @return string|null - */ - public function getAddress(): ?string - { - return $this->address; - } - - /** - * @param string $address - * - * @return EditSupplierCommand - */ - public function setAddress(string $address): self - { - $this->address = $address; - - return $this; - } - - /** - * @return string|null - */ - public function getCity(): ?string - { - return $this->city; - } - - /** - * @param string $city - * - * @return EditSupplierCommand - */ - public function setCity(string $city): self - { - $this->city = $city; - - return $this; - } - - /** - * @return string|null - */ - public function getAddress2(): ?string - { - return $this->address2; - } - - /** - * @param string $address2 - * - * @return EditSupplierCommand - */ - public function setAddress2(string $address2): self - { - $this->address2 = $address2; - - return $this; - } - - /** - * @return int|null - */ - public function getCountryId(): ?int - { - return $this->countryId; - } - - /** - * @param int $countryId - * - * @return EditSupplierCommand - */ - public function setCountryId(int $countryId): self - { - $this->countryId = $countryId; - - return $this; - } - - /** - * @return string|null - */ - public function getPostCode(): ?string - { - return $this->postCode; - } - - /** - * @param string $postCode - * - * @return EditSupplierCommand - */ - public function setPostCode(string $postCode): self - { - $this->postCode = $postCode; - - return $this; - } - - /** - * @return int|null - */ - public function getStateId(): ?int - { - return $this->stateId; - } - - /** - * @param int $stateId - * - * @return EditSupplierCommand - */ - public function setStateId(int $stateId): self - { - $this->stateId = $stateId; - - return $this; - } - - /** - * @return string|null - */ - public function getPhone(): ?string - { - return $this->phone; - } - - /** - * @param string $phone - * - * @return EditSupplierCommand - */ - public function setPhone(string $phone): self - { - $this->phone = $phone; - - return $this; - } - - /** - * @return string|null - */ - public function getMobilePhone(): ?string - { - return $this->mobilePhone; - } - - /** - * @param string $mobilePhone - * - * @return EditSupplierCommand - */ - public function setMobilePhone(string $mobilePhone): self - { - $this->mobilePhone = $mobilePhone; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaTitles(): ?array - { - return $this->localizedMetaTitles; - } - - /** - * @param string[] $localizedMetaTitles - * - * @return EditSupplierCommand - */ - public function setLocalizedMetaTitles(array $localizedMetaTitles): self - { - $this->localizedMetaTitles = $localizedMetaTitles; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaDescriptions(): ?array - { - return $this->localizedMetaDescriptions; - } - - /** - * @param string[] $localizedMetaDescriptions - * - * @return EditSupplierCommand - */ - public function setLocalizedMetaDescriptions(array $localizedMetaDescriptions): self - { - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - - return $this; - } - - /** - * @return string[]|null - */ - public function getLocalizedMetaKeywords(): ?array - { - return $this->localizedMetaKeywords; - } - - /** - * @param string[] $localizedMetaKeywords - * - * @return EditSupplierCommand - */ - public function setLocalizedMetaKeywords(array $localizedMetaKeywords): self - { - $this->localizedMetaKeywords = $localizedMetaKeywords; - - return $this; - } - - /** - * @return bool|null - */ - public function isEnabled(): ?bool - { - return $this->enabled; - } - - /** - * @param bool $enabled - * - * @return EditSupplierCommand - */ - public function setEnabled(bool $enabled): self - { - $this->enabled = $enabled; - - return $this; - } - - /** - * @return array|null - */ - public function getAssociatedShops(): ?array - { - return $this->associatedShops; - } - - /** - * @param array $associatedShops - * - * @return EditSupplierCommand - */ - public function setAssociatedShops(array $associatedShops): self - { - $this->associatedShops = $associatedShops; - - return $this; - } - - /** - * @return string|null - */ - public function getDni(): ?string - { - return $this->dni; - } - - /** - * @param string $dni - * - * @return EditSupplierCommand - */ - public function setDni(string $dni): self - { - $this->dni = $dni; - - return $this; - } -} diff --git a/src/Core/Domain/Supplier/Command/ToggleSupplierStatusCommand.php b/src/Core/Domain/Supplier/Command/ToggleSupplierStatusCommand.php deleted file mode 100644 index 539b6d8b..00000000 --- a/src/Core/Domain/Supplier/Command/ToggleSupplierStatusCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Command; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Class ToggleSupplierStatusCommand is responsible for toggling supplier status. - */ -class ToggleSupplierStatusCommand -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - public function __construct($supplierId) - { - $this->supplierId = new SupplierId($supplierId); - } - - /** - * @return SupplierId - */ - public function getSupplierId() - { - return $this->supplierId; - } -} diff --git a/src/Core/Domain/Supplier/CommandHandler/AddSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/AddSupplierHandlerInterface.php deleted file mode 100644 index 03bc1092..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/AddSupplierHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\AddSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Defines contract for AddSupplierHandler - */ -interface AddSupplierHandlerInterface -{ - /** - * @param AddSupplierCommand $command - * - * @return SupplierId - */ - public function handle(AddSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/BulkDeleteSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/BulkDeleteSupplierHandlerInterface.php deleted file mode 100644 index 0db7dcc6..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/BulkDeleteSupplierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDeleteSupplierCommand; - -/** - * Interface BulkDeleteSupplierHandlerInterface defines contract for BulkDeleteSupplierHandler. - */ -interface BulkDeleteSupplierHandlerInterface -{ - /** - * @param BulkDeleteSupplierCommand $command - */ - public function handle(BulkDeleteSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/BulkDisableSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/BulkDisableSupplierHandlerInterface.php deleted file mode 100644 index 378a76de..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/BulkDisableSupplierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDisableSupplierCommand; - -/** - * Interface BulkDisableSupplierHandlerInterface defines contract for BulkDisableSupplierHandler. - */ -interface BulkDisableSupplierHandlerInterface -{ - /** - * @param BulkDisableSupplierCommand $command - */ - public function handle(BulkDisableSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/BulkEnableSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/BulkEnableSupplierHandlerInterface.php deleted file mode 100644 index 20146558..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/BulkEnableSupplierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkEnableSupplierCommand; - -/** - * Interface BulkEnableSupplierHandlerInterface defines contract for BulkEnableSupplierHandler. - */ -interface BulkEnableSupplierHandlerInterface -{ - /** - * @param BulkEnableSupplierCommand $command - */ - public function handle(BulkEnableSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/DeleteSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/DeleteSupplierHandlerInterface.php deleted file mode 100644 index 798a058a..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/DeleteSupplierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\DeleteSupplierCommand; - -/** - * Interface DeleteSupplierHandlerInterface defines contract for DeleteSupplierHandler. - */ -interface DeleteSupplierHandlerInterface -{ - /** - * @param DeleteSupplierCommand $command - */ - public function handle(DeleteSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/EditSupplierHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/EditSupplierHandlerInterface.php deleted file mode 100644 index 36b8c119..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/EditSupplierHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\EditSupplierCommand; - -/** - * Defines contract for EditSupplierHandler - */ -interface EditSupplierHandlerInterface -{ - /** - * @param EditSupplierCommand $command - */ - public function handle(EditSupplierCommand $command); -} diff --git a/src/Core/Domain/Supplier/CommandHandler/ToggleSupplierStatusHandlerInterface.php b/src/Core/Domain/Supplier/CommandHandler/ToggleSupplierStatusHandlerInterface.php deleted file mode 100644 index be1ff53b..00000000 --- a/src/Core/Domain/Supplier/CommandHandler/ToggleSupplierStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\ToggleSupplierStatusCommand; - -/** - * Interface ToggleSupplierStatusHandlerInterface defines contract for ToggleSupplierStatusHandler. - */ -interface ToggleSupplierStatusHandlerInterface -{ - /** - * @param ToggleSupplierStatusCommand $command - */ - public function handle(ToggleSupplierStatusCommand $command); -} diff --git a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierAddressException.php b/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierAddressException.php deleted file mode 100644 index 99c9b037..00000000 --- a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierAddressException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when supplier address cannot be deleted - */ -class CannotDeleteSupplierAddressException extends SupplierException -{ -} diff --git a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierException.php b/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierException.php deleted file mode 100644 index 41dcc686..00000000 --- a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Thrown when fails to delete supplier - */ -class CannotDeleteSupplierException extends SupplierException -{ - /** - * When fails to delete supplier due to existing pending orders of that supplier - */ - const HAS_PENDING_ORDERS = 1; - - /** - * When fails to delete single supplier - */ - const FAILED_DELETE = 2; - - /** - * When fails to delete supplier in bulk action - */ - const FAILED_BULK_DELETE = 3; -} diff --git a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierProductRelationException.php b/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierProductRelationException.php deleted file mode 100644 index cda7c597..00000000 --- a/src/Core/Domain/Supplier/Exception/CannotDeleteSupplierProductRelationException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when supplier product relation cannot be deleted - */ -class CannotDeleteSupplierProductRelationException extends SupplierException -{ -} diff --git a/src/Core/Domain/Supplier/Exception/CannotToggleSupplierStatusException.php b/src/Core/Domain/Supplier/Exception/CannotToggleSupplierStatusException.php deleted file mode 100644 index f2524280..00000000 --- a/src/Core/Domain/Supplier/Exception/CannotToggleSupplierStatusException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when supplier status cannot be enabled or disabled in toggling action - */ -class CannotToggleSupplierStatusException extends SupplierException -{ -} diff --git a/src/Core/Domain/Supplier/Exception/CannotUpdateSupplierStatusException.php b/src/Core/Domain/Supplier/Exception/CannotUpdateSupplierStatusException.php deleted file mode 100644 index 7e00b4ab..00000000 --- a/src/Core/Domain/Supplier/Exception/CannotUpdateSupplierStatusException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when supplier status cannot be updated - */ -class CannotUpdateSupplierStatusException extends SupplierException -{ -} diff --git a/src/Core/Domain/Supplier/Exception/SupplierConstraintException.php b/src/Core/Domain/Supplier/Exception/SupplierConstraintException.php deleted file mode 100644 index c50cad0b..00000000 --- a/src/Core/Domain/Supplier/Exception/SupplierConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when supplier constraints are violated - */ -class SupplierConstraintException extends SupplierException -{ - /** - * When invalid data is provided for bulk action - */ - const INVALID_BULK_DATA = 1; -} diff --git a/src/Core/Domain/Supplier/Exception/SupplierException.php b/src/Core/Domain/Supplier/Exception/SupplierException.php deleted file mode 100644 index 4c3f37a6..00000000 --- a/src/Core/Domain/Supplier/Exception/SupplierException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for supplier sub-domain - */ -class SupplierException extends DomainException -{ -} diff --git a/src/Core/Domain/Supplier/Exception/SupplierNotFoundException.php b/src/Core/Domain/Supplier/Exception/SupplierNotFoundException.php deleted file mode 100644 index 81f4621b..00000000 --- a/src/Core/Domain/Supplier/Exception/SupplierNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Exception; - -/** - * Is thrown when required supplier cannot be found - */ -class SupplierNotFoundException extends SupplierException -{ -} diff --git a/src/Core/Domain/Supplier/Query/GetSupplierForEditing.php b/src/Core/Domain/Supplier/Query/GetSupplierForEditing.php deleted file mode 100644 index 620a9a31..00000000 --- a/src/Core/Domain/Supplier/Query/GetSupplierForEditing.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Query; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Gets supplier for editing in Back Office - */ -class GetSupplierForEditing -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - public function __construct(int $supplierId) - { - $this->supplierId = new SupplierId($supplierId); - } - - /** - * @return SupplierId $supplierId - */ - public function getSupplierId(): SupplierId - { - return $this->supplierId; - } -} diff --git a/src/Core/Domain/Supplier/Query/GetSupplierForViewing.php b/src/Core/Domain/Supplier/Query/GetSupplierForViewing.php deleted file mode 100644 index 88f67887..00000000 --- a/src/Core/Domain/Supplier/Query/GetSupplierForViewing.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\Query; - -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Get supplier information for viewing - */ -class GetSupplierForViewing -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @var LanguageId Language in which supplier is returned - */ - private $languageId; - - /** - * @param int $supplierId - * @param int $languageId - * - * @throws SupplierException - */ - public function __construct($supplierId, $languageId) - { - $this->supplierId = new SupplierId($supplierId); - $this->languageId = new LanguageId($languageId); - } - - /** - * @return SupplierId - */ - public function getSupplierId() - { - return $this->supplierId; - } - - /** - * @return LanguageId - */ - public function getLanguageId() - { - return $this->languageId; - } -} diff --git a/src/Core/Domain/Supplier/QueryHandler/GetSupplierForEditingHandlerInterface.php b/src/Core/Domain/Supplier/QueryHandler/GetSupplierForEditingHandlerInterface.php deleted file mode 100644 index 3e9c9dae..00000000 --- a/src/Core/Domain/Supplier/QueryHandler/GetSupplierForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForEditing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\EditableSupplier; - -/** - * Defines contract for GetSupplierForEditingHandler - */ -interface GetSupplierForEditingHandlerInterface -{ - /** - * @param GetSupplierForEditing $query - * - * @return EditableSupplier - */ - public function handle(GetSupplierForEditing $query); -} diff --git a/src/Core/Domain/Supplier/QueryHandler/GetSupplierForViewingHandlerInterface.php b/src/Core/Domain/Supplier/QueryHandler/GetSupplierForViewingHandlerInterface.php deleted file mode 100644 index f70e5adf..00000000 --- a/src/Core/Domain/Supplier/QueryHandler/GetSupplierForViewingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForViewing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\ViewableSupplier; - -/** - * Interface for service that handles query to get supplier for viewing - */ -interface GetSupplierForViewingHandlerInterface -{ - /** - * @param GetSupplierForViewing $query - * - * @return ViewableSupplier - */ - public function handle(GetSupplierForViewing $query); -} diff --git a/src/Core/Domain/Supplier/QueryResult/EditableSupplier.php b/src/Core/Domain/Supplier/QueryResult/EditableSupplier.php deleted file mode 100644 index 9af94cb3..00000000 --- a/src/Core/Domain/Supplier/QueryResult/EditableSupplier.php +++ /dev/null @@ -1,330 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; - -/** - * Transfers supplier data for editing - */ -class EditableSupplier -{ - /** - * @var SupplierId - */ - private $supplierId; - - /** - * @var string - */ - private $name; - - /** - * @var string[] - */ - private $localizedDescriptions; - - /** - * @var string - */ - private $address; - - /** - * @var string - */ - private $city; - - /** - * @var string - */ - private $address2; - - /** - * @var int - */ - private $countryId; - - /** - * @var string - */ - private $postCode; - - /** - * @var int - */ - private $stateId; - - /** - * @var string - */ - private $phone; - - /** - * @var string - */ - private $mobilePhone; - - /** - * @var array - */ - private $logoImage; - - /** - * @var string[] - */ - private $localizedMetaTitles; - - /** - * @var string[] - */ - private $localizedMetaDescriptions; - - /** - * @var string[] - */ - private $localizedMetaKeywords; - - /** - * @var bool - */ - private $enabled; - - /** - * @var array - */ - private $associatedShops; - - /** - * @var string - */ - private $dni; - - /** - * @param SupplierId $supplierId - * @param string $name - * @param string[] $localizedDescriptions - * @param string $address - * @param string $city - * @param string $address2 - * @param int $countryId - * @param string $postCode - * @param int $stateId - * @param string $phone - * @param string $mobilePhone - * @param string[] $localizedMetaTitles - * @param string[] $localizedMetaDescriptions - * @param string[] $localizedMetaKeywords - * @param bool $enabled - * @param array $associatedShops - * @param string $dni - * @param array|null $logoImage - */ - public function __construct( - SupplierId $supplierId, - string $name, - array $localizedDescriptions, - string $address, - string $city, - string $address2, - int $countryId, - string $postCode, - int $stateId, - string $phone, - string $mobilePhone, - array $localizedMetaTitles, - array $localizedMetaDescriptions, - array $localizedMetaKeywords, - bool $enabled, - array $associatedShops, - string $dni, - ?array $logoImage = null - ) { - $this->supplierId = $supplierId; - $this->name = $name; - $this->localizedDescriptions = $localizedDescriptions; - $this->address = $address; - $this->city = $city; - $this->address2 = $address2; - $this->countryId = $countryId; - $this->postCode = $postCode; - $this->stateId = $stateId; - $this->phone = $phone; - $this->mobilePhone = $mobilePhone; - $this->logoImage = $logoImage; - $this->localizedMetaTitles = $localizedMetaTitles; - $this->localizedMetaDescriptions = $localizedMetaDescriptions; - $this->localizedMetaKeywords = $localizedMetaKeywords; - $this->enabled = $enabled; - $this->dni = $dni; - $this->associatedShops = $associatedShops; - } - - /** - * @return SupplierId - */ - public function getSupplierId(): SupplierId - { - return $this->supplierId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string[] - */ - public function getLocalizedDescriptions(): array - { - return $this->localizedDescriptions; - } - - /** - * @return string - */ - public function getAddress(): string - { - return $this->address; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string - */ - public function getAddress2(): string - { - return $this->address2; - } - - /** - * @return int - */ - public function getCountryId(): int - { - return $this->countryId; - } - - /** - * @return string - */ - public function getPostCode(): string - { - return $this->postCode; - } - - /** - * @return int - */ - public function getStateId(): int - { - return $this->stateId; - } - - /** - * @return string - */ - public function getPhone(): string - { - return $this->phone; - } - - /** - * @return string - */ - public function getMobilePhone(): string - { - return $this->mobilePhone; - } - - /** - * @return array|null - */ - public function getLogoImage(): ?array - { - return $this->logoImage; - } - - /** - * @return string[] - */ - public function getLocalizedMetaTitles(): array - { - return $this->localizedMetaTitles; - } - - /** - * @return string[] - */ - public function getLocalizedMetaDescriptions(): array - { - return $this->localizedMetaDescriptions; - } - - /** - * @return string[] - */ - public function getLocalizedMetaKeywords(): array - { - return $this->localizedMetaKeywords; - } - - /** - * @return bool - */ - public function isEnabled(): bool - { - return $this->enabled; - } - - /** - * @return array - */ - public function getAssociatedShops(): array - { - return $this->associatedShops; - } - - /** - * @return string - */ - public function getDni(): string - { - return $this->dni; - } -} diff --git a/src/Core/Domain/Supplier/QueryResult/ViewableSupplier.php b/src/Core/Domain/Supplier/QueryResult/ViewableSupplier.php deleted file mode 100644 index c6e40ae0..00000000 --- a/src/Core/Domain/Supplier/QueryResult/ViewableSupplier.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult; - -/** - * Stores query result for getting supplier for viewing - */ -class ViewableSupplier -{ - /** - * @var string - */ - private $name; - - /** - * @var array - */ - private $supplierProducts; - - /** - * @param string $name - * @param array $supplierProducts - */ - public function __construct($name, array $supplierProducts) - { - $this->name = $name; - $this->supplierProducts = $supplierProducts; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return array - */ - public function getSupplierProducts() - { - return $this->supplierProducts; - } -} diff --git a/src/Core/Domain/Supplier/SupplierSettings.php b/src/Core/Domain/Supplier/SupplierSettings.php deleted file mode 100644 index 7aba3d00..00000000 --- a/src/Core/Domain/Supplier/SupplierSettings.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier; - -/** - * Defines settings for supplier - */ -final class SupplierSettings -{ - /** - * Maximum allowed symbols for name - */ - const MAX_NAME_LENGTH = 64; - - /** - * Maximum allowed symbols for meta title - */ - const MAX_META_TITLE_LENGTH = 255; - - /** - * Maximum allowed symbols for meta description - */ - const MAX_META_DESCRIPTION_LENGTH = 512; - - /** - * Maximum allowed symbols for meta keyword - */ - const MAX_META_KEYWORD_LENGTH = 255; -} diff --git a/src/Core/Domain/Supplier/ValueObject/SupplierId.php b/src/Core/Domain/Supplier/ValueObject/SupplierId.php deleted file mode 100644 index 652705d9..00000000 --- a/src/Core/Domain/Supplier/ValueObject/SupplierId.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; - -/** - * Class SupplierId - */ -class SupplierId -{ - /** - * @var int - */ - private $value; - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - public function __construct($supplierId) - { - $this->assertIsIntegerGreaterThanZero($supplierId); - $this->value = $supplierId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->value; - } - - /** - * @param int $supplierId - * - * @throws SupplierException - */ - private function assertIsIntegerGreaterThanZero($supplierId) - { - if (!is_int($supplierId) || 0 >= $supplierId) { - throw new SupplierException(sprintf('Invalid Supplier id: %s', var_export($supplierId, true))); - } - } -} diff --git a/src/Core/Domain/Tax/Command/AddTaxCommand.php b/src/Core/Domain/Tax/Command/AddTaxCommand.php deleted file mode 100644 index 44494c6f..00000000 --- a/src/Core/Domain/Tax/Command/AddTaxCommand.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -/** - * Adds new tax - */ -class AddTaxCommand -{ - /** - * @var array - */ - private $localizedNames; - - /** - * @var float - */ - private $rate; - - /** - * @var bool - */ - private $enabled; - - /** - * @param array $localizedNames - * @param float $rate - * @param bool $enabled - */ - public function __construct(array $localizedNames, $rate, $enabled) - { - $this->localizedNames = $localizedNames; - $this->rate = $rate; - $this->enabled = $enabled; - } - - /** - * @return array - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @return float - */ - public function getRate() - { - return $this->rate; - } - - /** - * @return bool - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * @param bool $enabled - */ - public function setEnabled($enabled) - { - $this->enabled = $enabled; - } -} diff --git a/src/Core/Domain/Tax/Command/BulkDeleteTaxCommand.php b/src/Core/Domain/Tax/Command/BulkDeleteTaxCommand.php deleted file mode 100644 index 8e7bc391..00000000 --- a/src/Core/Domain/Tax/Command/BulkDeleteTaxCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Deletes taxes on bulk action - */ -class BulkDeleteTaxCommand -{ - /** - * @var TaxId[] - */ - private $taxIds; - - /** - * @param TaxId[] $taxIds - * - * @throws TaxException - */ - public function __construct(array $taxIds) - { - $this->setTaxIds($taxIds); - } - - /** - * @return TaxId[] - */ - public function getTaxIds() - { - return $this->taxIds; - } - - /** - * @param int[] $taxIds - * - * @throws TaxException - */ - private function setTaxIds(array $taxIds) - { - foreach ($taxIds as $taxId) { - $this->taxIds[] = new TaxId((int) $taxId); - } - } -} diff --git a/src/Core/Domain/Tax/Command/BulkToggleTaxStatusCommand.php b/src/Core/Domain/Tax/Command/BulkToggleTaxStatusCommand.php deleted file mode 100644 index 10e0cdb1..00000000 --- a/src/Core/Domain/Tax/Command/BulkToggleTaxStatusCommand.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Toggles taxes status on bulk action - */ -class BulkToggleTaxStatusCommand -{ - /** - * @var bool - */ - private $expectedStatus; - - /** - * @var TaxId[] - */ - private $taxIds; - - /** - * @param int[] $taxIds - * @param bool $expectedStatus - * - * @throws TaxException - */ - public function __construct(array $taxIds, $expectedStatus) - { - $this->assertIsBool($expectedStatus); - $this->setTaxIds($taxIds); - $this->expectedStatus = $expectedStatus; - } - - /** - * @return bool - */ - public function getExpectedStatus() - { - return $this->expectedStatus; - } - - /** - * @return TaxId[] - */ - public function getTaxIds() - { - return $this->taxIds; - } - - /** - * @param array $taxIds - * - * @throws TaxException - */ - private function setTaxIds(array $taxIds) - { - foreach ($taxIds as $taxId) { - $this->taxIds[] = new TaxId((int) $taxId); - } - } - - /** - * Validates that value is of type boolean - * - * @param $value - * - * @throws TaxConstraintException - */ - private function assertIsBool($value) - { - if (!is_bool($value)) { - throw new TaxConstraintException(sprintf('Status must be of type bool, but given %s', var_export($value, true)), TaxConstraintException::INVALID_STATUS); - } - } -} diff --git a/src/Core/Domain/Tax/Command/DeleteTaxCommand.php b/src/Core/Domain/Tax/Command/DeleteTaxCommand.php deleted file mode 100644 index d2bdcf23..00000000 --- a/src/Core/Domain/Tax/Command/DeleteTaxCommand.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Deletes tax - */ -class DeleteTaxCommand -{ - /** - * @var TaxId - */ - private $taxId; - - /** - * @param int $taxId - * - * @throws \PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException - */ - public function __construct($taxId) - { - $this->taxId = new TaxId($taxId); - } - - /** - * @return TaxId - */ - public function getTaxId() - { - return $this->taxId; - } -} diff --git a/src/Core/Domain/Tax/Command/EditTaxCommand.php b/src/Core/Domain/Tax/Command/EditTaxCommand.php deleted file mode 100644 index 3915bfe9..00000000 --- a/src/Core/Domain/Tax/Command/EditTaxCommand.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Edits given tax with provided data - */ -class EditTaxCommand -{ - /** - * @var TaxId - */ - private $taxId; - - /** - * @var array|null - */ - private $localizedNames; - - /** - * @var float|null - */ - private $rate; - - /** - * @var bool|null - */ - private $enabled; - - /** - * @param int $taxId - * - * @throws TaxException - */ - public function __construct($taxId) - { - $this->taxId = new TaxId($taxId); - } - - /** - * @return TaxId - */ - public function getTaxId() - { - return $this->taxId; - } - - /** - * @return array|null - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @param array|null $localizedNames - * - * @return self - */ - public function setLocalizedNames($localizedNames) - { - $this->localizedNames = $localizedNames; - - return $this; - } - - /** - * @return float|null - */ - public function getRate() - { - return $this->rate; - } - - /** - * @param float|null $rate - * - * @return self - */ - public function setRate($rate) - { - $this->rate = $rate; - - return $this; - } - - /** - * @return bool|null - */ - public function isEnabled() - { - return $this->enabled; - } - - /** - * @param bool|null $enabled - * - * @return self - */ - public function setEnabled($enabled) - { - $this->enabled = $enabled; - - return $this; - } -} diff --git a/src/Core/Domain/Tax/Command/ToggleTaxStatusCommand.php b/src/Core/Domain/Tax/Command/ToggleTaxStatusCommand.php deleted file mode 100644 index b1e4bef6..00000000 --- a/src/Core/Domain/Tax/Command/ToggleTaxStatusCommand.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Command; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Toggles tax status - */ -class ToggleTaxStatusCommand -{ - /** - * @var bool - */ - private $expectedStatus; - - /** - * @var TaxId - */ - private $taxId; - - /** - * @param string $expectedStatus - * @param int $taxId - * - * @throws TaxException - */ - public function __construct($taxId, $expectedStatus) - { - $this->assertIsBool($expectedStatus); - $this->taxId = new TaxId($taxId); - $this->expectedStatus = $expectedStatus; - } - - /** - * @return bool - */ - public function getExpectedStatus() - { - return $this->expectedStatus; - } - - /** - * @return TaxId - */ - public function getTaxId() - { - return $this->taxId; - } - - /** - * Validates that value is of type boolean - * - * @param $value - * - * @throws TaxConstraintException - */ - private function assertIsBool($value) - { - if (!is_bool($value)) { - throw new TaxConstraintException(sprintf('Status must be of type bool, but given %s', var_export($value, true)), TaxConstraintException::INVALID_STATUS); - } - } -} diff --git a/src/Core/Domain/Tax/CommandHandler/AddTaxHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/AddTaxHandlerInterface.php deleted file mode 100644 index 4f21f988..00000000 --- a/src/Core/Domain/Tax/CommandHandler/AddTaxHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\AddTaxCommand; - -/** - * Defines contract for AddTaxHandler - */ -interface AddTaxHandlerInterface -{ - /** - * @param AddTaxCommand $command - */ - public function handle(AddTaxCommand $command); -} diff --git a/src/Core/Domain/Tax/CommandHandler/BulkDeleteTaxHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/BulkDeleteTaxHandlerInterface.php deleted file mode 100644 index 29a9c56b..00000000 --- a/src/Core/Domain/Tax/CommandHandler/BulkDeleteTaxHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkDeleteTaxCommand; - -/** - * Defines contract for BulkDeleteTaxHandler - */ -interface BulkDeleteTaxHandlerInterface -{ - /** - * @param BulkDeleteTaxCommand $command - */ - public function handle(BulkDeleteTaxCommand $command); -} diff --git a/src/Core/Domain/Tax/CommandHandler/BulkToggleTaxStatusHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/BulkToggleTaxStatusHandlerInterface.php deleted file mode 100644 index a9a291f0..00000000 --- a/src/Core/Domain/Tax/CommandHandler/BulkToggleTaxStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkToggleTaxStatusCommand; - -/** - * Defines contract for BulkToggleTaxStatus - */ -interface BulkToggleTaxStatusHandlerInterface -{ - /** - * @param BulkToggleTaxStatusCommand $command - */ - public function handle(BulkToggleTaxStatusCommand $command); -} diff --git a/src/Core/Domain/Tax/CommandHandler/DeleteTaxHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/DeleteTaxHandlerInterface.php deleted file mode 100644 index a3b38495..00000000 --- a/src/Core/Domain/Tax/CommandHandler/DeleteTaxHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\DeleteTaxCommand; - -/** - * Defines contract for DeleteTaxHandler - */ -interface DeleteTaxHandlerInterface -{ - /** - * @param DeleteTaxCommand $command - */ - public function handle(DeleteTaxCommand $command); -} diff --git a/src/Core/Domain/Tax/CommandHandler/EditTaxHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/EditTaxHandlerInterface.php deleted file mode 100644 index 3839be36..00000000 --- a/src/Core/Domain/Tax/CommandHandler/EditTaxHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\EditTaxCommand; - -/** - * Defines contract for EditTaxHandler - */ -interface EditTaxHandlerInterface -{ - /** - * @param EditTaxCommand $command - */ - public function handle(EditTaxCommand $command); -} diff --git a/src/Core/Domain/Tax/CommandHandler/ToggleTaxStatusHandlerInterface.php b/src/Core/Domain/Tax/CommandHandler/ToggleTaxStatusHandlerInterface.php deleted file mode 100644 index 42a156c9..00000000 --- a/src/Core/Domain/Tax/CommandHandler/ToggleTaxStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\ToggleTaxStatusCommand; - -/** - * Defines contract for ToggleTaxStatusHandler - */ -interface ToggleTaxStatusHandlerInterface -{ - /** - * @param ToggleTaxStatusCommand $command - */ - public function handle(ToggleTaxStatusCommand $command); -} diff --git a/src/Core/Domain/Tax/Exception/DeleteTaxException.php b/src/Core/Domain/Tax/Exception/DeleteTaxException.php deleted file mode 100644 index 66268cfe..00000000 --- a/src/Core/Domain/Tax/Exception/DeleteTaxException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Exception; - -/** - * Is thrown when tax or taxes cannot be deleted - */ -class DeleteTaxException extends TaxException -{ - /** - * When fails to delete single tax - */ - const FAILED_DELETE = 10; - - /** - * When fails to delete taxes on bulk action - */ - const FAILED_BULK_DELETE = 20; -} diff --git a/src/Core/Domain/Tax/Exception/TaxConstraintException.php b/src/Core/Domain/Tax/Exception/TaxConstraintException.php deleted file mode 100644 index 44cac3b7..00000000 --- a/src/Core/Domain/Tax/Exception/TaxConstraintException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Exception; - -/** - * Is thrown when tax is invalid - */ -class TaxConstraintException extends TaxException -{ - /** - * Thrown when provided tax id value is not valid - */ - const INVALID_ID = 10; - - /** - * Thrown when provided tax status value is not valid - */ - const INVALID_STATUS = 20; -} diff --git a/src/Core/Domain/Tax/Exception/TaxException.php b/src/Core/Domain/Tax/Exception/TaxException.php deleted file mode 100644 index ca658e98..00000000 --- a/src/Core/Domain/Tax/Exception/TaxException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Is base exception for Tax sub-domain - */ -class TaxException extends DomainException -{ -} diff --git a/src/Core/Domain/Tax/Exception/TaxNotFoundException.php b/src/Core/Domain/Tax/Exception/TaxNotFoundException.php deleted file mode 100644 index 8c28a044..00000000 --- a/src/Core/Domain/Tax/Exception/TaxNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Exception; - -/** - * Is thrown when tax is not found by provided id - */ -class TaxNotFoundException extends TaxException -{ -} diff --git a/src/Core/Domain/Tax/Exception/UpdateTaxException.php b/src/Core/Domain/Tax/Exception/UpdateTaxException.php deleted file mode 100644 index 32926c03..00000000 --- a/src/Core/Domain/Tax/Exception/UpdateTaxException.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Exception; - -/** - * Is thrown when tax or taxes cannot be updated - */ -class UpdateTaxException extends TaxException -{ - /** - * When fails to update single tax status - */ - const FAILED_UPDATE_STATUS = 10; - - /** - * When fails to update taxes status on bulk action - */ - const FAILED_BULK_UPDATE_STATUS = 20; -} diff --git a/src/Core/Domain/Tax/Query/GetTaxForEditing.php b/src/Core/Domain/Tax/Query/GetTaxForEditing.php deleted file mode 100644 index 3bbda32e..00000000 --- a/src/Core/Domain/Tax/Query/GetTaxForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\Query; - -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Gets tax for editing in Back Office - */ -class GetTaxForEditing -{ - /** - * @var TaxId - */ - private $taxId; - - /** - * @param int $taxId - */ - public function __construct($taxId) - { - $this->taxId = new TaxId($taxId); - } - - /** - * @return TaxId - */ - public function getTaxId() - { - return $this->taxId; - } -} diff --git a/src/Core/Domain/Tax/QueryHandler/GetTaxForEditingHandlerInterface.php b/src/Core/Domain/Tax/QueryHandler/GetTaxForEditingHandlerInterface.php deleted file mode 100644 index 42d7700c..00000000 --- a/src/Core/Domain/Tax/QueryHandler/GetTaxForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Query\GetTaxForEditing; -use PrestaShop\PrestaShop\Core\Domain\Tax\QueryResult\EditableTax; - -/** - * Defines contract for service that gets tax for editing - */ -interface GetTaxForEditingHandlerInterface -{ - /** - * @param GetTaxForEditing $query - * - * @return EditableTax - */ - public function handle(GetTaxForEditing $query); -} diff --git a/src/Core/Domain/Tax/QueryResult/EditableTax.php b/src/Core/Domain/Tax/QueryResult/EditableTax.php deleted file mode 100644 index b689f075..00000000 --- a/src/Core/Domain/Tax/QueryResult/EditableTax.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Transfers editable tax data - */ -class EditableTax -{ - /** - * @var TaxId - */ - private $taxId; - - /** - * @var string[] - */ - private $localizedNames; - - /** - * @var float - */ - private $rate; - - /** - * @var bool - */ - private $active; - - /** - * EditableTax constructor. - * - * @param TaxId $taxId - * @param string[] $localizedNames - * @param float $rate - * @param bool $active - */ - public function __construct(TaxId $taxId, array $localizedNames, $rate, $active) - { - $this->taxId = $taxId; - $this->localizedNames = $localizedNames; - $this->rate = $rate; - $this->active = $active; - } - - /** - * @return TaxId - */ - public function getTaxId() - { - return $this->taxId; - } - - /** - * @return string[] - */ - public function getLocalizedNames() - { - return $this->localizedNames; - } - - /** - * @return float - */ - public function getRate() - { - return $this->rate; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->active; - } -} diff --git a/src/Core/Domain/Tax/ValueObject/TaxId.php b/src/Core/Domain/Tax/ValueObject/TaxId.php deleted file mode 100644 index 8be1a67c..00000000 --- a/src/Core/Domain/Tax/ValueObject/TaxId.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxConstraintException; - -/** - * Provides tax id data - */ -class TaxId -{ - /** - * @var int - */ - private $taxId; - - /** - * @param int $taxId - * - * @throws TaxConstraintException - */ - public function __construct($taxId) - { - if (!is_int($taxId) || $taxId <= 0) { - throw new TaxConstraintException(sprintf('Invalid Tax id: %s', var_export($taxId, true)), TaxConstraintException::INVALID_ID); - } - - $this->taxId = $taxId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->taxId; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Command/BulkDeleteTaxRulesGroupCommand.php b/src/Core/Domain/TaxRulesGroup/Command/BulkDeleteTaxRulesGroupCommand.php deleted file mode 100644 index 2d172d03..00000000 --- a/src/Core/Domain/TaxRulesGroup/Command/BulkDeleteTaxRulesGroupCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Command responsible for multiple tax rules groups deletion - */ -class BulkDeleteTaxRulesGroupCommand -{ - /** - * @var TaxRulesGroupId[] - */ - private $taxRulesGroupIds; - - /** - * @param int[] $taxRulesGroupIds - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(array $taxRulesGroupIds) - { - $this->setTaxRulesGroupIds($taxRulesGroupIds); - } - - /** - * @return TaxRulesGroupId[] - */ - public function getTaxRulesGroupIds(): array - { - return $this->taxRulesGroupIds; - } - - /** - * @param int[] $taxRulesGroupIds - * - * @throws TaxRulesGroupConstraintException - */ - private function setTaxRulesGroupIds(array $taxRulesGroupIds) - { - foreach ($taxRulesGroupIds as $taxRulesGroupId) { - $this->taxRulesGroupIds[] = new TaxRulesGroupId($taxRulesGroupId); - } - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Command/BulkSetTaxRulesGroupStatusCommand.php b/src/Core/Domain/TaxRulesGroup/Command/BulkSetTaxRulesGroupStatusCommand.php deleted file mode 100644 index 646b2cb8..00000000 --- a/src/Core/Domain/TaxRulesGroup/Command/BulkSetTaxRulesGroupStatusCommand.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Command responsible for multiple tax rules groups status setting - */ -class BulkSetTaxRulesGroupStatusCommand -{ - /** - * @var TaxRulesGroupId[] - */ - private $taxRulesGroupIds = []; - - /** - * @var bool - */ - private $expectedStatus; - - /** - * @param array $taxRulesGroupIds - * @param bool $expectedStatus - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(array $taxRulesGroupIds, bool $expectedStatus) - { - $this->expectedStatus = $expectedStatus; - $this->setTaxRulesGroupIds($taxRulesGroupIds); - } - - /** - * @return bool - */ - public function getExpectedStatus(): bool - { - return $this->expectedStatus; - } - - /** - * @return TaxRulesGroupId[] - */ - public function getTaxRulesGroupIds(): array - { - return $this->taxRulesGroupIds; - } - - /** - * @param int[] $taxRulesGroupIds - * - * @throws TaxRulesGroupConstraintException - */ - private function setTaxRulesGroupIds(array $taxRulesGroupIds) - { - foreach ($taxRulesGroupIds as $taxRulesGroupId) { - $this->taxRulesGroupIds[] = new TaxRulesGroupId($taxRulesGroupId); - } - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Command/DeleteTaxRulesGroupCommand.php b/src/Core/Domain/TaxRulesGroup/Command/DeleteTaxRulesGroupCommand.php deleted file mode 100644 index d4a4a107..00000000 --- a/src/Core/Domain/TaxRulesGroup/Command/DeleteTaxRulesGroupCommand.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Command responsible for single tax rules group deletion - */ -class DeleteTaxRulesGroupCommand -{ - /** - * @var TaxRulesGroupId - */ - private $taxRulesGroupId; - - /** - * @param int $taxRulesGroupId - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(int $taxRulesGroupId) - { - $this->taxRulesGroupId = new TaxRulesGroupId($taxRulesGroupId); - } - - /** - * @return TaxRulesGroupId - */ - public function getTaxRulesGroupId(): TaxRulesGroupId - { - return $this->taxRulesGroupId; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Command/SetTaxRulesGroupStatusCommand.php b/src/Core/Domain/TaxRulesGroup/Command/SetTaxRulesGroupStatusCommand.php deleted file mode 100644 index cce73d32..00000000 --- a/src/Core/Domain/TaxRulesGroup/Command/SetTaxRulesGroupStatusCommand.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Command for setting single tax rules group status - */ -class SetTaxRulesGroupStatusCommand -{ - /** - * @var TaxRulesGroupId - */ - private $taxRulesGroupId; - - /** - * @var bool - */ - private $expectedStatus; - - /** - * @param int $taxRulesGroupId - * @param bool $expectedStatus - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(int $taxRulesGroupId, bool $expectedStatus) - { - $this->expectedStatus = $expectedStatus; - $this->taxRulesGroupId = new TaxRulesGroupId($taxRulesGroupId); - } - - /** - * @return TaxRulesGroupId - */ - public function getTaxRulesGroupId(): TaxRulesGroupId - { - return $this->taxRulesGroupId; - } - - /** - * @return bool - */ - public function getExpectedStatus(): bool - { - return $this->expectedStatus; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandlerInterface.php b/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandlerInterface.php deleted file mode 100644 index 25436166..00000000 --- a/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkDeleteTaxRulesGroupHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkDeleteTaxRulesGroupCommand; - -/** - * Defines contract for bulk delete tax rules group handler - */ -interface BulkDeleteTaxRulesGroupHandlerInterface -{ - /** - * @param BulkDeleteTaxRulesGroupCommand $command - */ - public function handle(BulkDeleteTaxRulesGroupCommand $command): void; -} diff --git a/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkToggleTaxRulesGroupStatusHandlerInterface.php b/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkToggleTaxRulesGroupStatusHandlerInterface.php deleted file mode 100644 index 65780477..00000000 --- a/src/Core/Domain/TaxRulesGroup/CommandHandler/BulkToggleTaxRulesGroupStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkSetTaxRulesGroupStatusCommand; - -/** - * Defines contract for bulk toggle tax rules group status handler - */ -interface BulkToggleTaxRulesGroupStatusHandlerInterface -{ - /** - * @param BulkSetTaxRulesGroupStatusCommand $command - */ - public function handle(BulkSetTaxRulesGroupStatusCommand $command): void; -} diff --git a/src/Core/Domain/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandlerInterface.php b/src/Core/Domain/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandlerInterface.php deleted file mode 100644 index b1c5d797..00000000 --- a/src/Core/Domain/TaxRulesGroup/CommandHandler/DeleteTaxRulesGroupHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\DeleteTaxRulesGroupCommand; - -/** - * Defines contract for delete tax rules group handler - */ -interface DeleteTaxRulesGroupHandlerInterface -{ - /** - * @param DeleteTaxRulesGroupCommand $command - */ - public function handle(DeleteTaxRulesGroupCommand $command): void; -} diff --git a/src/Core/Domain/TaxRulesGroup/CommandHandler/ToggleTaxRulesGroupStatusHandlerInterface.php b/src/Core/Domain/TaxRulesGroup/CommandHandler/ToggleTaxRulesGroupStatusHandlerInterface.php deleted file mode 100644 index 0a86224b..00000000 --- a/src/Core/Domain/TaxRulesGroup/CommandHandler/ToggleTaxRulesGroupStatusHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\SetTaxRulesGroupStatusCommand; - -/** - * Defines contract for toggle tax rules group status handler - */ -interface ToggleTaxRulesGroupStatusHandlerInterface -{ - /** - * @param SetTaxRulesGroupStatusCommand $command - */ - public function handle(SetTaxRulesGroupStatusCommand $command): void; -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkDeleteTaxRulesGroupException.php b/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkDeleteTaxRulesGroupException.php deleted file mode 100644 index b9eb61fa..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkDeleteTaxRulesGroupException.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -use Exception; - -/** - * Thrown on failure to delete all selected tax rules groups without errors - */ -class CannotBulkDeleteTaxRulesGroupException extends TaxRulesGroupException -{ - /** - * @var int[] - */ - private $taxRulesGroupsIds; - - public function __construct(array $taxRulesGroupsIds, $message = '', $code = 0, Exception $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->taxRulesGroupsIds = $taxRulesGroupsIds; - } - - /** - * @return int[] - */ - public function getTaxRulesGroupsIds() - { - return $this->taxRulesGroupsIds; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkUpdateTaxRulesGroupException.php b/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkUpdateTaxRulesGroupException.php deleted file mode 100644 index 2c3cab81..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/CannotBulkUpdateTaxRulesGroupException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -use Exception; - -/** - * Thrown on failure to bulk update tax rules groups without errors - */ -class CannotBulkUpdateTaxRulesGroupException extends TaxRulesGroupException -{ - /** - * @var int[] - */ - private $taxRulesGroupsIds; - - /** - * @param array $taxRulesGroupsIds - * @param string $message - * @param int $code - * @param Exception|null $previous - */ - public function __construct(array $taxRulesGroupsIds, $message = '', $code = 0, Exception $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->taxRulesGroupsIds = $taxRulesGroupsIds; - } - - /** - * @return int[] - */ - public function getTaxRulesGroupsIds() - { - return $this->taxRulesGroupsIds; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/CannotDeleteTaxRulesGroupException.php b/src/Core/Domain/TaxRulesGroup/Exception/CannotDeleteTaxRulesGroupException.php deleted file mode 100644 index 88757994..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/CannotDeleteTaxRulesGroupException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -/** - * Thrown on failure to delete single tax rules group - */ -class CannotDeleteTaxRulesGroupException extends TaxRulesGroupException -{ -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/CannotUpdateTaxRulesGroupException.php b/src/Core/Domain/TaxRulesGroup/Exception/CannotUpdateTaxRulesGroupException.php deleted file mode 100644 index a3fe8246..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/CannotUpdateTaxRulesGroupException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -/** - * Thrown on failure to update tax rules group - */ -class CannotUpdateTaxRulesGroupException extends TaxRulesGroupException -{ - /** - * Thrown when status toggling fails - */ - public const FAILED_TOGGLE_STATUS = 1; -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupConstraintException.php b/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupConstraintException.php deleted file mode 100644 index 7aaa8fa3..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -/** - * Thrown when tax rules group constraint is violated - */ -class TaxRulesGroupConstraintException extends TaxRulesGroupException -{ - /** - * Thrown when provided tax rules group id value is not valid - */ - public const INVALID_ID = 1; -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupException.php b/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupException.php deleted file mode 100644 index 05d51970..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for tax rules group subdomain - */ -class TaxRulesGroupException extends DomainException -{ -} diff --git a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupNotFoundException.php b/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupNotFoundException.php deleted file mode 100644 index f4a5bf21..00000000 --- a/src/Core/Domain/TaxRulesGroup/Exception/TaxRulesGroupNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception; - -/** - * Thrown on failure to find existing tax rules group - */ -class TaxRulesGroupNotFoundException extends TaxRulesGroupException -{ -} diff --git a/src/Core/Domain/TaxRulesGroup/Query/GetTaxRulesGroupForEditing.php b/src/Core/Domain/TaxRulesGroup/Query/GetTaxRulesGroupForEditing.php deleted file mode 100644 index 5b35b5c0..00000000 --- a/src/Core/Domain/TaxRulesGroup/Query/GetTaxRulesGroupForEditing.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Query; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Gets tax rules group for editing in Back Office - */ -class GetTaxRulesGroupForEditing -{ - /** - * @var TaxRulesGroupId - */ - private $taxRulesGroupId; - - /** - * @param int $taxRulesGroupId - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(int $taxRulesGroupId) - { - $this->taxRulesGroupId = new TaxRulesGroupId($taxRulesGroupId); - } - - /** - * @return TaxRulesGroupId $taxRulesGroupId - */ - public function getTaxRulesGroupId(): TaxRulesGroupId - { - return $this->taxRulesGroupId; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandlerInterface.php b/src/Core/Domain/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandlerInterface.php deleted file mode 100644 index 229a61fb..00000000 --- a/src/Core/Domain/TaxRulesGroup/QueryHandler/GetTaxRulesGroupForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Query\GetTaxRulesGroupForEditing; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryResult\EditableTaxRulesGroup; - -/** - * Defines contract for handler providing tax rules group for editing - */ -interface GetTaxRulesGroupForEditingHandlerInterface -{ - /** - * @param GetTaxRulesGroupForEditing $query - * - * @return EditableTaxRulesGroup - */ - public function handle(GetTaxRulesGroupForEditing $query): EditableTaxRulesGroup; -} diff --git a/src/Core/Domain/TaxRulesGroup/QueryResult/EditableTaxRulesGroup.php b/src/Core/Domain/TaxRulesGroup/QueryResult/EditableTaxRulesGroup.php deleted file mode 100644 index 0c62ec31..00000000 --- a/src/Core/Domain/TaxRulesGroup/QueryResult/EditableTaxRulesGroup.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject\TaxRulesGroupId; - -/** - * Transfers tax rules group data for editing - */ -class EditableTaxRulesGroup -{ - /** - * @var TaxRulesGroupId - */ - private $taxRulesGroupId; - - /** - * @var bool - */ - private $active; - - /** - * @param TaxRulesGroupId $taxRulesGroupId - * @param bool $active - */ - public function __construct(TaxRulesGroupId $taxRulesGroupId, bool $active) - { - $this->taxRulesGroupId = $taxRulesGroupId; - $this->active = $active; - } - - /** - * @return TaxRulesGroupId - */ - public function getTaxRulesGroupId(): TaxRulesGroupId - { - return $this->taxRulesGroupId; - } - - /** - * @return bool - */ - public function isActive(): bool - { - return $this->active; - } -} diff --git a/src/Core/Domain/TaxRulesGroup/ValueObject/TaxRulesGroupId.php b/src/Core/Domain/TaxRulesGroup/ValueObject/TaxRulesGroupId.php deleted file mode 100644 index 63c9b2eb..00000000 --- a/src/Core/Domain/TaxRulesGroup/ValueObject/TaxRulesGroupId.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; - -/** - * Provide tax rules group id - */ -class TaxRulesGroupId -{ - /** - * @var int - */ - private $id; - - /** - * @param int $id - * - * @throws TaxRulesGroupConstraintException - */ - public function __construct(int $id) - { - $this->assertPositiveInt($id); - $this->id = $id; - } - - /** - * @return int - */ - public function getValue(): int - { - return $this->id; - } - - /** - * @param int $value - * - * @throws TaxRulesGroupConstraintException - */ - private function assertPositiveInt(int $value): void - { - if (0 > $value) { - throw new TaxRulesGroupConstraintException(sprintf('Invalid tax rules group id "%s".', var_export($value, true)), TaxRulesGroupConstraintException::INVALID_ID); - } - } -} diff --git a/src/Core/Domain/Theme/Command/AdaptThemeToRTLLanguagesCommand.php b/src/Core/Domain/Theme/Command/AdaptThemeToRTLLanguagesCommand.php deleted file mode 100644 index a69eaf68..00000000 --- a/src/Core/Domain/Theme/Command/AdaptThemeToRTLLanguagesCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Command; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Class AdaptThemeToRTLLanguagesCommand adapts given theme to RTL languages. - */ -class AdaptThemeToRTLLanguagesCommand -{ - /** - * @var ThemeName - */ - private $themeName; - - /** - * @param ThemeName $themeName - */ - public function __construct(ThemeName $themeName) - { - $this->themeName = $themeName; - } - - /** - * @return ThemeName - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Domain/Theme/Command/DeleteThemeCommand.php b/src/Core/Domain/Theme/Command/DeleteThemeCommand.php deleted file mode 100644 index ac6459bd..00000000 --- a/src/Core/Domain/Theme/Command/DeleteThemeCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Command; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Class DeleteThemeCommand deletes given theme. - */ -class DeleteThemeCommand -{ - /** - * @var ThemeName - */ - private $themeName; - - /** - * @param ThemeName $themeName - */ - public function __construct(ThemeName $themeName) - { - $this->themeName = $themeName; - } - - /** - * @return ThemeName - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Domain/Theme/Command/EnableThemeCommand.php b/src/Core/Domain/Theme/Command/EnableThemeCommand.php deleted file mode 100644 index 0e2ef3de..00000000 --- a/src/Core/Domain/Theme/Command/EnableThemeCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Command; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Class EnableThemeCommand enables given Front Office theme for context's shop. - */ -class EnableThemeCommand -{ - /** - * @var ThemeName - */ - private $themeName; - - /** - * @param ThemeName $themeName - */ - public function __construct(ThemeName $themeName) - { - $this->themeName = $themeName; - } - - /** - * @return ThemeName - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Domain/Theme/Command/ImportThemeCommand.php b/src/Core/Domain/Theme/Command/ImportThemeCommand.php deleted file mode 100644 index d3c3425a..00000000 --- a/src/Core/Domain/Theme/Command/ImportThemeCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Command; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeImportSource; - -/** - * Class ImportThemeCommand imports theme from given source. - */ -class ImportThemeCommand -{ - /** - * @var ThemeImportSource - */ - private $importSource; - - /** - * @param ThemeImportSource $importSource - */ - public function __construct(ThemeImportSource $importSource) - { - $this->importSource = $importSource; - } - - /** - * @return ThemeImportSource - */ - public function getImportSource() - { - return $this->importSource; - } -} diff --git a/src/Core/Domain/Theme/Command/ResetThemeLayoutsCommand.php b/src/Core/Domain/Theme/Command/ResetThemeLayoutsCommand.php deleted file mode 100644 index ae32e9d4..00000000 --- a/src/Core/Domain/Theme/Command/ResetThemeLayoutsCommand.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Command; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Class ResetThemeLayoutsCommand resets theme's page layouts to defaults. - */ -class ResetThemeLayoutsCommand -{ - /** - * @var ThemeName - */ - private $themeName; - - /** - * @param ThemeName $themeName - */ - public function __construct(ThemeName $themeName) - { - $this->themeName = $themeName; - } - - /** - * @return ThemeName - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandler.php b/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandler.php deleted file mode 100644 index d0a87b0d..00000000 --- a/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\AdaptThemeToRTLLanguagesCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotAdaptThemeToRTLLanguagesException; -use PrestaShop\PrestaShop\Core\Localization\RTL\Exception\GenerationException; -use PrestaShop\PrestaShop\Core\Localization\RTL\StyleSheetProcessorFactoryInterface; - -/** - * Class AdaptThemeToRTLLanguagesHandler - */ -final class AdaptThemeToRTLLanguagesHandler implements AdaptThemeToRTLLanguagesHandlerInterface -{ - /** - * @var StyleSheetProcessorFactoryInterface - */ - private $stylesheetProcessorFactory; - - /** - * @param StyleSheetProcessorFactoryInterface $stylesheetProcessorFactory - */ - public function __construct(StyleSheetProcessorFactoryInterface $stylesheetProcessorFactory) - { - $this->stylesheetProcessorFactory = $stylesheetProcessorFactory; - } - - /** - * {@inheritdoc} - */ - public function handle(AdaptThemeToRTLLanguagesCommand $command) - { - $plainThemeName = $command->getThemeName()->getValue(); - - try { - $this->stylesheetProcessorFactory - ->create() - ->setProcessFOThemes([$plainThemeName]) - ->setRegenerate(true) - ->process() - ; - } catch (GenerationException $e) { - throw new CannotAdaptThemeToRTLLanguagesException(sprintf('Cannot adapt "%s" theme to RTL languages.', $plainThemeName), 0, $e); - } - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandlerInterface.php b/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandlerInterface.php deleted file mode 100644 index 5a30cc0a..00000000 --- a/src/Core/Domain/Theme/CommandHandler/AdaptThemeToRTLLanguagesHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\AdaptThemeToRTLLanguagesCommand; - -/** - * Interface AdaptThemeToRTLLanguagesHandlerInterface - */ -interface AdaptThemeToRTLLanguagesHandlerInterface -{ - /** - * @param AdaptThemeToRTLLanguagesCommand $command - */ - public function handle(AdaptThemeToRTLLanguagesCommand $command); -} diff --git a/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandler.php b/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandler.php deleted file mode 100644 index 7bf7a8b0..00000000 --- a/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandler.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\DeleteThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotDeleteThemeException; - -/** - * Class DeleteThemeHandler - */ -final class DeleteThemeHandler implements DeleteThemeHandlerInterface -{ - /** - * @var ThemeManager - */ - private $themeManager; - - /** - * @param ThemeManager $themeManager - */ - public function __construct(ThemeManager $themeManager) - { - $this->themeManager = $themeManager; - } - - /** - * @param DeleteThemeCommand $command - */ - public function handle(DeleteThemeCommand $command) - { - $plainThemeName = $command->getThemeName()->getValue(); - - if (!$this->themeManager->uninstall($plainThemeName)) { - throw new CannotDeleteThemeException(sprintf('Theme "%s" is used and thus cannot be deleted.', $plainThemeName)); - } - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandlerInterface.php b/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandlerInterface.php deleted file mode 100644 index ca268ae4..00000000 --- a/src/Core/Domain/Theme/CommandHandler/DeleteThemeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\DeleteThemeCommand; - -/** - * Interface DeleteThemeHandlerInterface - */ -interface DeleteThemeHandlerInterface -{ - /** - * @param DeleteThemeCommand $command - */ - public function handle(DeleteThemeCommand $command); -} diff --git a/src/Core/Domain/Theme/CommandHandler/EnableThemeHandler.php b/src/Core/Domain/Theme/CommandHandler/EnableThemeHandler.php deleted file mode 100644 index 22c550ca..00000000 --- a/src/Core/Domain/Theme/CommandHandler/EnableThemeHandler.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager; -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\EnableThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotEnableThemeException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ThemeConstraintException; - -/** - * Class EnableThemeHandler - */ -final class EnableThemeHandler implements EnableThemeHandlerInterface -{ - /** - * @var ThemeManager - */ - private $themeManager; - - /** - * @var CacheClearerInterface - */ - private $smartyCacheClearer; - - /** - * @var bool - */ - private $isSingleShopContext; - - /** - * @param ThemeManager $themeManager - * @param CacheClearerInterface $smartyCacheClearer - * @param $isSingleShopContext - */ - public function __construct( - ThemeManager $themeManager, - CacheClearerInterface $smartyCacheClearer, - $isSingleShopContext - ) { - $this->themeManager = $themeManager; - $this->smartyCacheClearer = $smartyCacheClearer; - $this->isSingleShopContext = $isSingleShopContext; - } - - /** - * {@inheritdoc} - * - * @throws CannotEnableThemeException - * @throws ThemeConstraintException - */ - public function handle(EnableThemeCommand $command) - { - if (!$this->isSingleShopContext) { - throw new ThemeConstraintException('Themes can be changed only in single shop context', ThemeConstraintException::RESTRICTED_ONLY_FOR_SINGLE_SHOP); - } - - $plainThemeName = $command->getThemeName()->getValue(); - - if (!$this->themeManager->enable($plainThemeName)) { - $errors = $this->themeManager->getErrors($plainThemeName); - - if (is_array($errors)) { - $error = reset($errors); - } elseif ($errors) { - $error = $errors; - } else { - // handle bad error usecases - $error = ''; - } - - throw new CannotEnableThemeException($error); - } - - $this->smartyCacheClearer->clear(); - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/EnableThemeHandlerInterface.php b/src/Core/Domain/Theme/CommandHandler/EnableThemeHandlerInterface.php deleted file mode 100644 index 80a0245e..00000000 --- a/src/Core/Domain/Theme/CommandHandler/EnableThemeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\EnableThemeCommand; - -/** - * Interface EnableThemeHandlerInterface - */ -interface EnableThemeHandlerInterface -{ - /** - * @param EnableThemeCommand $command - */ - public function handle(EnableThemeCommand $command); -} diff --git a/src/Core/Domain/Theme/CommandHandler/ImportThemeHandler.php b/src/Core/Domain/Theme/CommandHandler/ImportThemeHandler.php deleted file mode 100644 index 67fce6be..00000000 --- a/src/Core/Domain/Theme/CommandHandler/ImportThemeHandler.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Exception\ThemeAlreadyExistsException; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeUploaderInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ImportThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ImportedThemeAlreadyExistsException; -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeImportSource; -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Class ImportThemeHandler - */ -final class ImportThemeHandler implements ImportThemeHandlerInterface -{ - /** - * @var ThemeUploaderInterface - */ - private $themeUploader; - - /** - * @var ThemeManager - */ - private $themeManager; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ThemeUploaderInterface $themeUploader - * @param ThemeManager $themeManager - * @param ConfigurationInterface $configuration - */ - public function __construct( - ThemeUploaderInterface $themeUploader, - ThemeManager $themeManager, - ConfigurationInterface $configuration - ) { - $this->themeUploader = $themeUploader; - $this->themeManager = $themeManager; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function handle(ImportThemeCommand $command) - { - $type = $command->getImportSource()->getSourceType(); - $source = $command->getImportSource()->getSource(); - - if (ThemeImportSource::FROM_ARCHIVE === $type) { - $themePath = $this->themeUploader->upload($source); - } elseif (ThemeImportSource::FROM_WEB === $type) { - $themePath = $source; - } elseif (ThemeImportSource::FROM_FTP === $type) { - $themePath = $this->configuration->get('_PS_ALL_THEMES_DIR_') . $source; - } - - try { - $this->themeManager->install($themePath); - } catch (ThemeAlreadyExistsException $e) { - throw new ImportedThemeAlreadyExistsException(new ThemeName($e->getThemeName()), sprintf('Imported theme "%s" already exists.', $e->getThemeName()), 0, $e); - } finally { - if (ThemeImportSource::FROM_ARCHIVE === $type) { - @unlink($themePath); - } - } - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/ImportThemeHandlerInterface.php b/src/Core/Domain/Theme/CommandHandler/ImportThemeHandlerInterface.php deleted file mode 100644 index 756026d4..00000000 --- a/src/Core/Domain/Theme/CommandHandler/ImportThemeHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ImportThemeCommand; - -/** - * Interface ImportThemeHandlerInterface - */ -interface ImportThemeHandlerInterface -{ - /** - * @param ImportThemeCommand $command - */ - public function handle(ImportThemeCommand $command); -} diff --git a/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandler.php b/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandler.php deleted file mode 100644 index 0d7ba525..00000000 --- a/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandler.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ResetThemeLayoutsCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotResetThemeLayoutsException; - -/** - * Class ResetThemeLayoutsHandler - */ -final class ResetThemeLayoutsHandler implements ResetThemeLayoutsHandlerInterface -{ - /** - * @var ThemeManager - */ - private $themeManager; - - /** - * @param ThemeManager $themeManager - */ - public function __construct(ThemeManager $themeManager) - { - $this->themeManager = $themeManager; - } - - /** - * {@inheritdoc} - */ - public function handle(ResetThemeLayoutsCommand $command) - { - if (!$this->themeManager->reset($command->getThemeName()->getValue())) { - throw new CannotResetThemeLayoutsException(sprintf('Cannot reset "%s" theme page layouts.', $command->getThemeName()->getValue())); - } - } -} diff --git a/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandlerInterface.php b/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandlerInterface.php deleted file mode 100644 index bfa63d33..00000000 --- a/src/Core/Domain/Theme/CommandHandler/ResetThemeLayoutsHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ResetThemeLayoutsCommand; - -/** - * Interface ResetThemeLayoutsHandlerInterface - */ -interface ResetThemeLayoutsHandlerInterface -{ - /** - * @param ResetThemeLayoutsCommand $command - */ - public function handle(ResetThemeLayoutsCommand $command); -} diff --git a/src/Core/Domain/Theme/Exception/CannotAdaptThemeToRTLLanguagesException.php b/src/Core/Domain/Theme/Exception/CannotAdaptThemeToRTLLanguagesException.php deleted file mode 100644 index f04ab095..00000000 --- a/src/Core/Domain/Theme/Exception/CannotAdaptThemeToRTLLanguagesException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Thrown when fails to adapt to RTL languages - */ -class CannotAdaptThemeToRTLLanguagesException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/CannotDeleteThemeException.php b/src/Core/Domain/Theme/Exception/CannotDeleteThemeException.php deleted file mode 100644 index e4c591e3..00000000 --- a/src/Core/Domain/Theme/Exception/CannotDeleteThemeException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Thrown when fails to delete theme - */ -class CannotDeleteThemeException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/CannotEnableThemeException.php b/src/Core/Domain/Theme/Exception/CannotEnableThemeException.php deleted file mode 100644 index 128555f2..00000000 --- a/src/Core/Domain/Theme/Exception/CannotEnableThemeException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Thrown when fails to enable theme - */ -class CannotEnableThemeException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/CannotResetThemeLayoutsException.php b/src/Core/Domain/Theme/Exception/CannotResetThemeLayoutsException.php deleted file mode 100644 index cd99ccd6..00000000 --- a/src/Core/Domain/Theme/Exception/CannotResetThemeLayoutsException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Thrown when fails to reset theme layout - */ -class CannotResetThemeLayoutsException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/FailedToEnableThemeModuleException.php b/src/Core/Domain/Theme/Exception/FailedToEnableThemeModuleException.php deleted file mode 100644 index 83ea8847..00000000 --- a/src/Core/Domain/Theme/Exception/FailedToEnableThemeModuleException.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -class FailedToEnableThemeModuleException extends ThemeException -{ - /** - * @var string - */ - private $moduleName; - - public function __construct( - $moduleName, - $message = '', - $code = 0, - $previous = null - ) { - parent::__construct($message, $code, $previous); - - $this->moduleName = $moduleName; - } - - /** - * @return string - */ - public function getModuleName() - { - return $this->moduleName; - } -} diff --git a/src/Core/Domain/Theme/Exception/ImportedThemeAlreadyExistsException.php b/src/Core/Domain/Theme/Exception/ImportedThemeAlreadyExistsException.php deleted file mode 100644 index 16ca7a1b..00000000 --- a/src/Core/Domain/Theme/Exception/ImportedThemeAlreadyExistsException.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; - -/** - * Thrown when trying to import already existing theme - */ -class ImportedThemeAlreadyExistsException extends ThemeException -{ - /** - * @var ThemeName - */ - private $themeName; - - /** - * @param ThemeName $themeName - * @param string $message - * @param int $code - * @param null $previous - */ - public function __construct(ThemeName $themeName, $message = '', $code = 0, $previous = null) - { - parent::__construct($message, $code, $previous); - - $this->themeName = $themeName; - } - - /** - * @return ThemeName - */ - public function getThemeName() - { - return $this->themeName; - } -} diff --git a/src/Core/Domain/Theme/Exception/InvalidThemeNameException.php b/src/Core/Domain/Theme/Exception/InvalidThemeNameException.php deleted file mode 100644 index ab3d9fc8..00000000 --- a/src/Core/Domain/Theme/Exception/InvalidThemeNameException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Class InvalidThemeNameException is thrown when invalid theme name is provided. - */ -class InvalidThemeNameException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/NotSupportedThemeImportSourceException.php b/src/Core/Domain/Theme/Exception/NotSupportedThemeImportSourceException.php deleted file mode 100644 index 6c9d8637..00000000 --- a/src/Core/Domain/Theme/Exception/NotSupportedThemeImportSourceException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Class NotSupportedThemeImportSourceException is thrown when not supported theme import source is being used. - */ -class NotSupportedThemeImportSourceException extends ThemeException -{ -} diff --git a/src/Core/Domain/Theme/Exception/ThemeConstraintException.php b/src/Core/Domain/Theme/Exception/ThemeConstraintException.php deleted file mode 100644 index 105c1ed4..00000000 --- a/src/Core/Domain/Theme/Exception/ThemeConstraintException.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -/** - * Thrown when theme constraints are violated - */ -class ThemeConstraintException extends ThemeException -{ - /** - * When trying to change theme in multi-shop context - */ - const RESTRICTED_ONLY_FOR_SINGLE_SHOP = 1; - - /** - * When trying to upload zip file which does not contain theme.yml configuration file. - */ - const MISSING_CONFIGURATION_FILE = 2; - - /** - * Its either theme has missing required files or some required properties in theme.yml - */ - const INVALID_CONFIGURATION = 3; - - /** - * Some mandatory files are missing. - */ - const INVALID_DATA = 4; -} diff --git a/src/Core/Domain/Theme/Exception/ThemeException.php b/src/Core/Domain/Theme/Exception/ThemeException.php deleted file mode 100644 index 2b5f5613..00000000 --- a/src/Core/Domain/Theme/Exception/ThemeException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class ThemeException is base exception for theme sub-domain. - */ -class ThemeException extends DomainException -{ -} diff --git a/src/Core/Domain/Theme/ValueObject/ThemeImportSource.php b/src/Core/Domain/Theme/ValueObject/ThemeImportSource.php deleted file mode 100644 index 49ced47e..00000000 --- a/src/Core/Domain/Theme/ValueObject/ThemeImportSource.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\NotSupportedThemeImportSourceException; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class ThemeImportSource defines available sources from where theme can be imported. - */ -class ThemeImportSource -{ - const FROM_ARCHIVE = 'from_archive'; - const FROM_WEB = 'from_web'; - const FROM_FTP = 'from_ftp'; - - /** - * @var string - */ - private $sourceType; - - /** - * @var UploadedFile|string If import source type is "from archive" - * then $source is uploaded file or path to theme otherwise - */ - private $source; - - /** - * @param UploadedFile $uploadedTheme - * - * @return ThemeImportSource - */ - public static function fromArchive(UploadedFile $uploadedTheme) - { - return new self(self::FROM_ARCHIVE, $uploadedTheme); - } - - /** - * @param string $themeUrl - * - * @return ThemeImportSource - */ - public static function fromWeb($themeUrl) - { - return new self(self::FROM_WEB, $themeUrl); - } - - /** - * @param string $themeFtp - * - * @return ThemeImportSource - */ - public static function fromFtp($themeFtp) - { - return new self(self::FROM_FTP, $themeFtp); - } - - /** - * @param string $sourceType - * @param UploadedFile|string $source - * - * @throws NotSupportedThemeImportSourceException - */ - private function __construct($sourceType, $source) - { - $this->assertSupportedThemeImportSourceTypeSupplied($sourceType); - - $this->sourceType = $sourceType; - $this->source = $source; - } - - /** - * @return string - */ - public function getSourceType() - { - return $this->sourceType; - } - - /** - * @return string|UploadedFile - */ - public function getSource() - { - return $this->source; - } - - /** - * @param string $sourceType - * - * @throws NotSupportedThemeImportSourceException - */ - private function assertSupportedThemeImportSourceTypeSupplied($sourceType) - { - $supportedSources = [self::FROM_ARCHIVE, self::FROM_WEB, self::FROM_FTP]; - - if (!in_array($sourceType, $supportedSources)) { - throw new NotSupportedThemeImportSourceException(sprintf('Not supported %s theme import source type supplied. Supported sources are: "%s"', var_export($sourceType, true), implode(',', $supportedSources))); - } - } -} diff --git a/src/Core/Domain/Theme/ValueObject/ThemeName.php b/src/Core/Domain/Theme/ValueObject/ThemeName.php deleted file mode 100644 index da7e910b..00000000 --- a/src/Core/Domain/Theme/ValueObject/ThemeName.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\InvalidThemeNameException; - -/** - * Class ThemeName - */ -class ThemeName -{ - /** - * @var string - */ - private $themeName; - - /** - * @param string $themeName - */ - public function __construct($themeName) - { - $this->assertThemeNameIsNotEmptyString($themeName); - $this->assertThemeNameMatchesPattern($themeName); - - $this->themeName = $themeName; - } - - /** - * @return string - */ - public function getValue() - { - return $this->themeName; - } - - /** - * @param string $themeName - * - * @throws InvalidThemeNameException - */ - private function assertThemeNameIsNotEmptyString($themeName) - { - if (!is_string($themeName) || empty($themeName)) { - throw new InvalidThemeNameException('Theme name cannot be empty.'); - } - } - - /** - * @param string $themeName - * - * @throws InvalidThemeNameException - */ - private function assertThemeNameMatchesPattern($themeName) - { - if (!preg_match('/^[a-zA-Z0-9_.-]+$/', $themeName)) { - throw new InvalidThemeNameException(sprintf('Invalid theme name %s provided.', var_export($themeName, true))); - } - } -} diff --git a/src/Core/Domain/ValueObject/Email.php b/src/Core/Domain/ValueObject/Email.php deleted file mode 100644 index 55de7c04..00000000 --- a/src/Core/Domain/ValueObject/Email.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; - -/** - * Class Email is responsible for providing valid email value. - */ -class Email -{ - /** - * @var int Maximum allowed length for email - */ - const MAX_LENGTH = 255; - - /** - * @var string - */ - private $email; - - /** - * @param string $email - * - * @throws DomainConstraintException - */ - public function __construct($email) - { - $this->assertEmailIsString($email); - $this->assertEmailIsNotEmpty($email); - $this->assertEmailDoesNotExceedAllowedLength($email); - - $this->email = $email; - } - - /** - * @return string - */ - public function getValue() - { - return $this->email; - } - - /** - * Check if given email is the same as current - * - * @param Email $email - * - * @return bool - */ - public function isEqualTo(Email $email) - { - return strtolower($email->getValue()) === strtolower($this->getValue()); - } - - /** - * Check that email is not an empty string - * - * @param $email - * - * @throws DomainConstraintException - */ - public function assertEmailIsNotEmpty($email) - { - if (0 === strlen($email)) { - throw new DomainConstraintException('Email must not be empty', DomainConstraintException::INVALID_EMAIL); - } - } - - /** - * Assert that email length does not exceed allowed value - * - * @param string $email - * - * @throws DomainConstraintException - */ - private function assertEmailDoesNotExceedAllowedLength($email) - { - $email = html_entity_decode($email, ENT_COMPAT, 'UTF-8'); - - $length = function_exists('mb_strlen') ? mb_strlen($email, 'UTF-8') : strlen($email); - if (self::MAX_LENGTH < $length) { - throw new DomainConstraintException(sprintf('Email is too long. Max allowed length is %s', self::MAX_LENGTH), DomainConstraintException::INVALID_EMAIL); - } - } - - /** - * Assert email is of type string - * - * @param string $email - * - * @throws DomainConstraintException - */ - private function assertEmailIsString($email) - { - if (!is_string($email)) { - throw new DomainConstraintException('Email must be of type string', DomainConstraintException::INVALID_EMAIL); - } - } -} diff --git a/src/Core/Domain/ValueObject/Money.php b/src/Core/Domain/ValueObject/Money.php deleted file mode 100644 index fdff9931..00000000 --- a/src/Core/Domain/ValueObject/Money.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ValueObject; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; - -/** - * An amount of money with currency - */ -class Money -{ - /** - * @var Number - */ - private $amount; - - /** - * @var CurrencyId - */ - private $currencyId; - - /** - * @param Number $amount - * @param CurrencyId $currencyId - * - * @throws DomainConstraintException - */ - public function __construct(Number $amount, CurrencyId $currencyId) - { - if (!$amount->isGreaterOrEqualThanZero()) { - throw new DomainConstraintException(sprintf('Money amount cannot be lower than zero, %f given', $amount), DomainConstraintException::INVALID_MONEY_AMOUNT); - } - - $this->amount = $amount; - $this->currencyId = $currencyId; - } - - /** - * @return Number - */ - public function getAmount(): Number - { - return $this->amount; - } - - /** - * @return CurrencyId - */ - public function getCurrencyId(): CurrencyId - { - return $this->currencyId; - } -} diff --git a/src/Core/Domain/ValueObject/QuerySorting.php b/src/Core/Domain/ValueObject/QuerySorting.php deleted file mode 100644 index c82053db..00000000 --- a/src/Core/Domain/ValueObject/QuerySorting.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Domain\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Exception\InvalidSortingException; - -/** - * Class QuerySorting is responsible for providing valid sorting parameter. - */ -class QuerySorting -{ - public const ASC = 'ASC'; - public const DESC = 'DESC'; - - /** - * @var string - */ - private $sorting; - - /** - * @param string $sorting - * - * @throws InvalidSortingException - */ - public function __construct(string $sorting) - { - $sorting = strtoupper($sorting); - $this->assertSortingSupported($sorting); - - $this->sorting = $sorting; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->sorting; - } - - /** - * @param string $sorting - * - * @throws InvalidSortingException - */ - private function assertSortingSupported(string $sorting): void - { - if (!in_array($sorting, [self::ASC, self::DESC], true)) { - throw new InvalidSortingException(); - } - } -} diff --git a/src/Core/Domain/ValueObject/Reduction.php b/src/Core/Domain/ValueObject/Reduction.php deleted file mode 100644 index c12861f2..00000000 --- a/src/Core/Domain/ValueObject/Reduction.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\ValueObject; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; - -/** - * Provides valid reduction values - */ -class Reduction -{ - /** - * For reducing concrete amount of money from price - */ - const TYPE_AMOUNT = 'amount'; - - /** - * For reducing certain percentage calculated from price - */ - const TYPE_PERCENTAGE = 'percentage'; - - /** - * Allowed reduction types - */ - const ALLOWED_TYPES = [ - self::TYPE_AMOUNT, - self::TYPE_PERCENTAGE, - ]; - - /** - * Maximum allowed value for percentage type reduction - */ - const MAX_ALLOWED_PERCENTAGE = 100; - - /** - * @var string - */ - private $type; - - /** - * @var Number - */ - private $value; - - /** - * @param string $type - * @param float $value - * - * @throws DomainConstraintException - */ - public function __construct(string $type, float $value) - { - $this->assertIsAllowedType($type); - $this->assertIsValidValue($type, $value); - $this->type = $type; - $this->value = new Number((string) $value); - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return Number - */ - public function getValue(): Number - { - return $this->value; - } - - /** - * @param string $type - * - * @throws DomainConstraintException - */ - private function assertIsAllowedType(string $type) - { - if (!in_array($type, self::ALLOWED_TYPES, true)) { - throw new DomainConstraintException(sprintf('The reduction type "%s" is invalid. Valid types are: "%s", "%s".', $type, self::TYPE_AMOUNT, self::TYPE_PERCENTAGE), DomainConstraintException::INVALID_REDUCTION_TYPE); - } - } - - /** - * @param $type - * @param $value - * - * @throws DomainConstraintException - */ - private function assertIsValidValue(string $type, float $value) - { - if (self::TYPE_PERCENTAGE === $type) { - if (!$this->assertIsNotNegative($value) || self::MAX_ALLOWED_PERCENTAGE < $value) { - throw new DomainConstraintException(sprintf('Invalid reduction percentage "%s". It must be from 0 to %s%%', $value, self::MAX_ALLOWED_PERCENTAGE), DomainConstraintException::INVALID_REDUCTION_PERCENTAGE); - } - } - - if (!$this->assertIsNotNegative($value)) { - throw new DomainConstraintException(sprintf('Invalid reduction amount "%s". It cannot be less than 0', $value), DomainConstraintException::INVALID_REDUCTION_AMOUNT); - } - } - - /** - * @param float $value - * - * @return bool - */ - private function assertIsNotNegative(float $value) - { - return 0 <= $value; - } -} diff --git a/src/Core/Domain/Webservice/Command/AddWebserviceKeyCommand.php b/src/Core/Domain/Webservice/Command/AddWebserviceKeyCommand.php deleted file mode 100644 index 4b329e39..00000000 --- a/src/Core/Domain/Webservice/Command/AddWebserviceKeyCommand.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Command; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\Key; - -/** - * Adds new webservice key which is used to access PrestaShop's API - */ -class AddWebserviceKeyCommand -{ - /** - * @var Key - */ - private $key; - - /** - * @var string - */ - private $description; - - /** - * @var string - */ - private $status; - - /** - * @var array - */ - private $permissions; - - /** - * @var array - */ - private $associatedShops; - - /** - * @param string $key - * @param string $description - * @param bool $status - * @param array $permissions - * @param int[] $associatedShops - */ - public function __construct( - $key, - $description, - $status, - array $permissions, - array $associatedShops - ) { - $this->key = new Key($key); - $this->description = $description; - $this->status = $status; - $this->permissions = $permissions; - $this->associatedShops = $associatedShops; - } - - /** - * @return Key - */ - public function getKey() - { - return $this->key; - } - - /** - * @return mixed - */ - public function getDescription() - { - return $this->description; - } - - /** - * @return string - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return array - */ - public function getPermissions() - { - return $this->permissions; - } - - /** - * @return array - */ - public function getAssociatedShops() - { - return $this->associatedShops; - } -} diff --git a/src/Core/Domain/Webservice/Command/EditWebserviceKeyCommand.php b/src/Core/Domain/Webservice/Command/EditWebserviceKeyCommand.php deleted file mode 100644 index ab3da3b9..00000000 --- a/src/Core/Domain/Webservice/Command/EditWebserviceKeyCommand.php +++ /dev/null @@ -1,182 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Command; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\Key; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; - -/** - * Edits webservice key data - */ -class EditWebserviceKeyCommand -{ - /** - * @var WebserviceKeyId - */ - private $webserviceKeyId; - - /** - * @var Key|null - */ - private $key; - - /** - * @var string|null - */ - private $description; - - /** - * @var bool|null - */ - private $status; - - /** - * @var array|null - */ - private $permissions; - - /** - * @var int[]|null - */ - private $shopAssociation; - - /** - * @param int $webserviceKeyId - */ - public function __construct($webserviceKeyId) - { - $this->webserviceKeyId = new WebserviceKeyId($webserviceKeyId); - } - - /** - * @return WebserviceKeyId - */ - public function getWebserviceKeyId() - { - return $this->webserviceKeyId; - } - - /** - * @return Key|null - */ - public function getKey() - { - return $this->key; - } - - /** - * @param string $key - * - * @return self - */ - public function setKey($key) - { - $this->key = new Key($key); - - return $this; - } - - /** - * @return string|null - */ - public function getDescription() - { - return $this->description; - } - - /** - * @param string $description - * - * @return self - */ - public function setDescription($description) - { - $this->description = $description; - - return $this; - } - - /** - * @return bool|null - */ - public function getStatus() - { - return $this->status; - } - - /** - * @param bool $status - * - * @return self - */ - public function setStatus($status) - { - $this->status = $status; - - return $this; - } - - /** - * @return array|null - */ - public function getPermissions() - { - return $this->permissions; - } - - /** - * @param array $permissions - * - * @return self - */ - public function setPermissions(array $permissions) - { - $this->permissions = $permissions; - - return $this; - } - - /** - * @return int[]|null - */ - public function getShopAssociation() - { - return $this->shopAssociation; - } - - /** - * @param int[] $shopAssociation - * - * @return self - */ - public function setShopAssociation(array $shopAssociation) - { - $this->shopAssociation = $shopAssociation; - - return $this; - } -} diff --git a/src/Core/Domain/Webservice/CommandHandler/AddWebserviceKeyHandlerInterface.php b/src/Core/Domain/Webservice/CommandHandler/AddWebserviceKeyHandlerInterface.php deleted file mode 100644 index e4e0734d..00000000 --- a/src/Core/Domain/Webservice/CommandHandler/AddWebserviceKeyHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\AddWebserviceKeyCommand; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; - -/** - * Interface for service that handles adding new webservice key - */ -interface AddWebserviceKeyHandlerInterface -{ - /** - * @param AddWebserviceKeyCommand $command - * - * @return WebserviceKeyId - */ - public function handle(AddWebserviceKeyCommand $command); -} diff --git a/src/Core/Domain/Webservice/CommandHandler/EditWebserviceKeyHandlerInterface.php b/src/Core/Domain/Webservice/CommandHandler/EditWebserviceKeyHandlerInterface.php deleted file mode 100644 index 88003013..00000000 --- a/src/Core/Domain/Webservice/CommandHandler/EditWebserviceKeyHandlerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\CommandHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\EditWebserviceKeyCommand; - -/** - * Interface for service that handles - */ -interface EditWebserviceKeyHandlerInterface -{ - /** - * @param EditWebserviceKeyCommand $command - */ - public function handle(EditWebserviceKeyCommand $command); -} diff --git a/src/Core/Domain/Webservice/Exception/DuplicateWebserviceKeyException.php b/src/Core/Domain/Webservice/Exception/DuplicateWebserviceKeyException.php deleted file mode 100644 index a1bc72da..00000000 --- a/src/Core/Domain/Webservice/Exception/DuplicateWebserviceKeyException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Exception; - -/** - * Is thrown when duplicate service key is encountered (e.g. when creating new webservice key which already exists) - */ -class DuplicateWebserviceKeyException extends WebserviceException -{ -} diff --git a/src/Core/Domain/Webservice/Exception/WebserviceConstraintException.php b/src/Core/Domain/Webservice/Exception/WebserviceConstraintException.php deleted file mode 100644 index d62faee7..00000000 --- a/src/Core/Domain/Webservice/Exception/WebserviceConstraintException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Exception; - -/** - * Is thrown when some constraint is violated in Webservice subdomain - */ -class WebserviceConstraintException extends WebserviceException -{ - /** - * @var string Code is used when invalid webservice key is encountered - */ - const INVALID_KEY = 1; -} diff --git a/src/Core/Domain/Webservice/Exception/WebserviceException.php b/src/Core/Domain/Webservice/Exception/WebserviceException.php deleted file mode 100644 index b54f602d..00000000 --- a/src/Core/Domain/Webservice/Exception/WebserviceException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Exception; - -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Base exception for Webservice subdomain - */ -class WebserviceException extends DomainException -{ -} diff --git a/src/Core/Domain/Webservice/Exception/WebserviceKeyNotFoundException.php b/src/Core/Domain/Webservice/Exception/WebserviceKeyNotFoundException.php deleted file mode 100644 index 904ffe6c..00000000 --- a/src/Core/Domain/Webservice/Exception/WebserviceKeyNotFoundException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Exception; - -/** - * Is thrown when webservice key is not found - */ -class WebserviceKeyNotFoundException extends WebserviceException -{ -} diff --git a/src/Core/Domain/Webservice/Query/GetWebserviceKeyForEditing.php b/src/Core/Domain/Webservice/Query/GetWebserviceKeyForEditing.php deleted file mode 100644 index 45130bdd..00000000 --- a/src/Core/Domain/Webservice/Query/GetWebserviceKeyForEditing.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\Query; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; - -/** - * Get webservice key data for editing - */ -class GetWebserviceKeyForEditing -{ - /** - * @var WebserviceKeyId - */ - private $webserviceKeyId; - - /** - * @param int $webserviceKeyId - */ - public function __construct($webserviceKeyId) - { - $this->webserviceKeyId = new WebserviceKeyId($webserviceKeyId); - } - - /** - * @return WebserviceKeyId - */ - public function getWebserviceKeyId() - { - return $this->webserviceKeyId; - } -} diff --git a/src/Core/Domain/Webservice/QueryHandler/GetWebserviceKeyForEditingHandlerInterface.php b/src/Core/Domain/Webservice/QueryHandler/GetWebserviceKeyForEditingHandlerInterface.php deleted file mode 100644 index 8ef07f85..00000000 --- a/src/Core/Domain/Webservice/QueryHandler/GetWebserviceKeyForEditingHandlerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\QueryHandler; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Query\GetWebserviceKeyForEditing; -use PrestaShop\PrestaShop\Core\Domain\Webservice\QueryResult\EditableWebserviceKey; - -/** - * Interface for service that handles webservice key data retrieving for editing - */ -interface GetWebserviceKeyForEditingHandlerInterface -{ - /** - * @param GetWebserviceKeyForEditing $query - * - * @return EditableWebserviceKey - */ - public function handle(GetWebserviceKeyForEditing $query); -} diff --git a/src/Core/Domain/Webservice/QueryResult/EditableWebserviceKey.php b/src/Core/Domain/Webservice/QueryResult/EditableWebserviceKey.php deleted file mode 100644 index f1768f1a..00000000 --- a/src/Core/Domain/Webservice/QueryResult/EditableWebserviceKey.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\QueryResult; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; - -/** - * Editable data for webservice key - */ -class EditableWebserviceKey -{ - /** - * @var WebserviceKeyId - */ - private $webserviceKeyId; - - /** - * @var string - */ - private $key; - - /** - * @var string - */ - private $description; - - /** - * @var bool - */ - private $status; - - /** - * @var array - */ - private $resourcePermissions; - - /** - * @var int[] - */ - private $associatedShops; - - /** - * @param WebserviceKeyId $webserviceKeyId - * @param string $key - * @param string $description - * @param bool $status - * @param array $resourcePermissions - * @param array $associatedShops - */ - public function __construct( - WebserviceKeyId $webserviceKeyId, - $key, - $description, - $status, - array $resourcePermissions, - array $associatedShops - ) { - $this->webserviceKeyId = $webserviceKeyId; - $this->key = $key; - $this->description = $description; - $this->status = $status; - $this->resourcePermissions = $resourcePermissions; - $this->associatedShops = $associatedShops; - } - - /** - * @return WebserviceKeyId - */ - public function getWebserviceKeyId() - { - return $this->webserviceKeyId; - } - - /** - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * @return bool - */ - public function getStatus() - { - return $this->status; - } - - /** - * @return array - */ - public function getResourcePermissions() - { - return $this->resourcePermissions; - } - - /** - * @return int[] - */ - public function getAssociatedShops() - { - return $this->associatedShops; - } -} diff --git a/src/Core/Domain/Webservice/ValueObject/Key.php b/src/Core/Domain/Webservice/ValueObject/Key.php deleted file mode 100644 index 0da50bf0..00000000 --- a/src/Core/Domain/Webservice/ValueObject/Key.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; - -/** - * Encapsulates webservice key value - */ -class Key -{ - /** - * @var string Required length of webservice key - */ - const LENGTH = 32; - - /** - * @var string - */ - private $key; - - /** - * @param string $key - */ - public function __construct($key) - { - $this->assertKeyIsStringAndRequiredLength($key); - - $this->key = $key; - } - - /** - * @return string - */ - public function getValue() - { - return $this->key; - } - - /** - * @param string $key - */ - private function assertKeyIsStringAndRequiredLength($key) - { - if (!is_string($key) || strlen($key) !== self::LENGTH) { - throw new WebserviceConstraintException(sprintf('Webservice key must be string of %d characters length but %s given', self::LENGTH, var_export($key, true)), WebserviceConstraintException::INVALID_KEY); - } - } -} diff --git a/src/Core/Domain/Webservice/ValueObject/Permission.php b/src/Core/Domain/Webservice/ValueObject/Permission.php deleted file mode 100644 index ca510bc4..00000000 --- a/src/Core/Domain/Webservice/ValueObject/Permission.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject; - -/** - * Defines available permissions for Webservice keys - */ -class Permission -{ - /** - * @var string Permission to view resource - */ - const VIEW = 'GET'; - - /** - * @var string Permission to view resource - */ - const FAST_VIEW = 'HEAD'; - - /** - * @var string Permission to modify existing resource - */ - const MODIFY = 'PUT'; - - /** - * @var string Permission to add new resource - */ - const ADD = 'POST'; - - /** - * @var string Permission to delete existing resource - */ - const DELETE = 'DELETE'; -} diff --git a/src/Core/Domain/Webservice/ValueObject/WebserviceKeyId.php b/src/Core/Domain/Webservice/ValueObject/WebserviceKeyId.php deleted file mode 100644 index 3f2edef5..00000000 --- a/src/Core/Domain/Webservice/ValueObject/WebserviceKeyId.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; - -/** - * Encapsulates webservice key id value - */ -class WebserviceKeyId -{ - /** - * @var int - */ - private $webserviceKeyId; - - /** - * @param int $webserviceKeyId - */ - public function __construct($webserviceKeyId) - { - $this->assertWebserviceKeyIdIsIntegerGreaterThanZero($webserviceKeyId); - - $this->webserviceKeyId = $webserviceKeyId; - } - - /** - * @return int - */ - public function getValue() - { - return $this->webserviceKeyId; - } - - /** - * @param int $webserviceKeyId - */ - private function assertWebserviceKeyIdIsIntegerGreaterThanZero($webserviceKeyId) - { - if (!is_int($webserviceKeyId) || $webserviceKeyId <= 0) { - throw new WebserviceConstraintException(sprintf('Webservice key id must be integer greater than 0, but %s given', var_export($webserviceKeyId, true))); - } - } -} diff --git a/src/Core/Email/EmailConfigurationTesterInterface.php b/src/Core/Email/EmailConfigurationTesterInterface.php deleted file mode 100644 index b0cd136b..00000000 --- a/src/Core/Email/EmailConfigurationTesterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -/** - * Interface EmailConfigurationTesterInterface defines contract for email configuration tester. - */ -interface EmailConfigurationTesterInterface -{ - /** - * Test email configuration. - * - * @param array $config - * - * @return bool - */ - public function testConfiguration(array $config); -} diff --git a/src/Core/Email/EmailDataConfigurator.php b/src/Core/Email/EmailDataConfigurator.php deleted file mode 100644 index d580dd8a..00000000 --- a/src/Core/Email/EmailDataConfigurator.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class EmailDataConfigurator is responsible for configuring email data. - */ -final class EmailDataConfigurator implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'send_emails_to' => $this->configuration->get('PS_MAIL_EMAIL_MESSAGE'), - 'mail_method' => (int) $this->configuration->get('PS_MAIL_METHOD'), - 'mail_type' => (int) $this->configuration->get('PS_MAIL_TYPE'), - 'log_emails' => (bool) $this->configuration->get('PS_LOG_EMAILS'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_MAIL_EMAIL_MESSAGE', $config['send_emails_to']); - $this->configuration->set('PS_MAIL_METHOD', $config['mail_method']); - $this->configuration->set('PS_MAIL_TYPE', $config['mail_type']); - $this->configuration->set('PS_LOG_EMAILS', $config['log_emails']); - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['send_emails_to'], - $config['mail_method'], - $config['mail_type'], - $config['log_emails'] - ); - } -} diff --git a/src/Core/Email/EmailLister.php b/src/Core/Email/EmailLister.php deleted file mode 100644 index b6c97c5a..00000000 --- a/src/Core/Email/EmailLister.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem; - -class EmailLister -{ - private $filesystem; - - public function __construct(FileSystem $fs) - { - // Register dependencies - $this->filesystem = $fs; - } - - /** - * Return the list of available mails. - * - * @param null $lang - * @param null $dir - * - * @return array|null - */ - public function getAvailableMails($dir) - { - if (!is_dir($dir)) { - return null; - } - - $mail_directory = $this->filesystem->listEntriesRecursively($dir); - $mail_list = []; - - // Remove unwanted .html / .txt / .tpl / .php / . / .. - foreach ($mail_directory as $mail) { - if (strpos($mail->getFilename(), '.') !== false) { - $tmp = explode('.', $mail->getFilename()); - - // Check for filename existence (left part) and if extension is html (right part) - if (($tmp === false || !isset($tmp[0])) || (isset($tmp[1]) && $tmp[1] !== 'html')) { - continue; - } - - $mail_name_no_ext = $tmp[0]; - if (!in_array($mail_name_no_ext, $mail_list)) { - $mail_list[] = $mail_name_no_ext; - } - } - } - - return $mail_list; - } - - /** - * Give in input getAvailableMails(), will output a human readable and proper string name. - * - * @return string - */ - public function getCleanedMailName($mail_name) - { - if (strpos($mail_name, '.') !== false) { - $tmp = explode('.', $mail_name); - - if ($tmp === false || !isset($tmp[0])) { - return $mail_name; - } - - $mail_name = $tmp[0]; - } - - return ucfirst(str_replace(['_', '-'], ' ', $mail_name)); - } -} diff --git a/src/Core/Email/EmailLogEraserInterface.php b/src/Core/Email/EmailLogEraserInterface.php deleted file mode 100644 index 09f36f51..00000000 --- a/src/Core/Email/EmailLogEraserInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -/** - * Interface EmailLogEraserInterface defines contract for email logs eraser. - */ -interface EmailLogEraserInterface -{ - /** - * Erase given email logs. - * - * @param int[] $mailLogIds - * - * @return array - */ - public function erase(array $mailLogIds); - - /** - * Erase all email logs. - * - * @return bool TRUE if email logs where erased successfully or FALSE otherwise - */ - public function eraseAll(); -} diff --git a/src/Core/Email/MailOption.php b/src/Core/Email/MailOption.php deleted file mode 100644 index 778f6c40..00000000 --- a/src/Core/Email/MailOption.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -/** - * Class MailMethodOption defines available email sending method options. - */ -final class MailOption -{ - /** - * @var int Option defines that emails should be sent using native mail() function - */ - const METHOD_NATIVE = 1; - - /** - * @var int Option defines that emails should be sent using configured SMTP settings - */ - const METHOD_SMTP = 2; - - /** - * @var int Option defines that emails should not be sent - */ - const METHOD_NONE = 3; - - /** - * @var int Option defines that emails should be sent in HTML format only - */ - const TYPE_HTML = 1; - - /** - * @var int Option defines that emails should be sent in TXT format only - */ - const TYPE_TXT = 2; - - /** - * @var int Option defines that emails should be sent in both HTML and TXT formats - */ - const TYPE_BOTH = 3; - - /** - * Class should not be initialized as its responsibility is to hold mail method options. - */ - private function __construct() - { - } -} diff --git a/src/Core/Email/SmtpDataConfigurator.php b/src/Core/Email/SmtpDataConfigurator.php deleted file mode 100644 index 62b569ce..00000000 --- a/src/Core/Email/SmtpDataConfigurator.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Email; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class SmtpDataConfigurator is responsible for configuring SMTP data. - */ -final class SmtpDataConfigurator implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'domain' => $this->configuration->get('PS_MAIL_DOMAIN'), - 'server' => $this->configuration->get('PS_MAIL_SERVER'), - 'username' => $this->configuration->get('PS_MAIL_USER'), - 'password' => $this->configuration->get('PS_MAIL_PASSWD'), - 'encryption' => $this->configuration->get('PS_MAIL_SMTP_ENCRYPTION'), - 'port' => $this->configuration->get('PS_MAIL_SMTP_PORT'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - if ($this->validateConfiguration($config)) { - $this->configuration->set('PS_MAIL_DOMAIN', $config['domain']); - $this->configuration->set('PS_MAIL_SERVER', $config['server']); - $this->configuration->set('PS_MAIL_USER', $config['username']); - $this->configuration->set('PS_MAIL_SMTP_ENCRYPTION', $config['encryption']); - $this->configuration->set('PS_MAIL_SMTP_PORT', $config['port']); - - $smtpPassword = (string) $config['password']; - - if ('' !== $smtpPassword || !$this->configuration->get('PS_MAIL_PASSWD')) { - $this->configuration->set('PS_MAIL_PASSWD', $smtpPassword); - } - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['domain'], - $config['server'], - $config['username'], - $config['encryption'], - $config['port'], - $config['password'] - ); - } -} diff --git a/src/Core/Email/SwiftMailerValidation.php b/src/Core/Email/SwiftMailerValidation.php deleted file mode 100644 index 91fb049a..00000000 --- a/src/Core/Email/SwiftMailerValidation.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Email; - -use Egulias\EmailValidator\EmailLexer; -use Egulias\EmailValidator\Exception\InvalidEmail; -use Egulias\EmailValidator\Validation\EmailValidation; -use PrestaShop\PrestaShop\Core\Exception\NonASCIIInLocalPartException; - -class SwiftMailerValidation implements EmailValidation -{ - /** - * @var InvalidEmail|null - */ - private $error; - - /** - * {@inheritdoc} - */ - public function isValid($email, EmailLexer $emailLexer) - { - if (is_string($email)) { - $parts = explode('@', $email); - if (preg_match('/[^\x00-\x7F]/', $parts[0])) { - $this->error = new NonASCIIInLocalPartException(); - } - } - - return null === $this->error; - } - - /** - * {@inheritdoc} - */ - public function getError() - { - return $this->error; - } - - /** - * {@inheritdoc} - */ - public function getWarnings() - { - return []; - } -} diff --git a/src/Core/Employee/Access/EmployeeFormAccessCheckerInterface.php b/src/Core/Employee/Access/EmployeeFormAccessCheckerInterface.php deleted file mode 100644 index 476a71cc..00000000 --- a/src/Core/Employee/Access/EmployeeFormAccessCheckerInterface.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee\Access; - -/** - * Interface EmployeeFormAccessCheckerInterface defines employee form access checker. - */ -interface EmployeeFormAccessCheckerInterface -{ - /** - * Checks if employee has restricted access to the employee form. - * Restricted access usually is used when an employee edits their own account. - * Restricted access means that the employee is restricted from some of - * the fields in the edit form, which would modify his account's accessibility. - * E.g. active status, profile, shop association. - * - * @param int $employeeId - * - * @return bool - */ - public function isRestrictedAccess($employeeId); - - /** - * Check if context employee can access edit form for given employee. - * - * @param int $employeeId - * - * @return bool - */ - public function canAccessEditFormFor($employeeId); - - /** - * Check if context employee can access addons connect form control. - * - * @return bool - */ - public function canAccessAddonsConnect(); -} diff --git a/src/Core/Employee/Access/ProfileAccessChecker.php b/src/Core/Employee/Access/ProfileAccessChecker.php deleted file mode 100644 index 9bb0f2f7..00000000 --- a/src/Core/Employee/Access/ProfileAccessChecker.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee\Access; - -use PrestaShop\PrestaShop\Core\Employee\EmployeeDataProviderInterface; - -/** - * Class ProfileAccessChecker checks profile access for employee. - */ -final class ProfileAccessChecker implements ProfileAccessCheckerInterface -{ - /** - * @var EmployeeDataProviderInterface - */ - private $employeeDataProvider; - - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @param EmployeeDataProviderInterface $employeeDataProvider - * @param int $superAdminProfileId - */ - public function __construct( - EmployeeDataProviderInterface $employeeDataProvider, - $superAdminProfileId - ) { - $this->employeeDataProvider = $employeeDataProvider; - $this->superAdminProfileId = $superAdminProfileId; - } - - /** - * {@inheritdoc} - */ - public function canEmployeeAccessProfile($employeeId, $profileId) - { - if ($this->employeeDataProvider->isSuperAdmin($employeeId)) { - return true; - } - - return $profileId !== $this->superAdminProfileId; - } -} diff --git a/src/Core/Employee/Access/ProfileAccessCheckerInterface.php b/src/Core/Employee/Access/ProfileAccessCheckerInterface.php deleted file mode 100644 index 4f8c676f..00000000 --- a/src/Core/Employee/Access/ProfileAccessCheckerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee\Access; - -/** - * Interface ProfileAccessCheckerInterface describes a profile access checker. - */ -interface ProfileAccessCheckerInterface -{ - /** - * Checks if given employee can access given profile. - * - * @param int $employeeId - * @param int $profileId - * - * @return bool - */ - public function canEmployeeAccessProfile($employeeId, $profileId); -} diff --git a/src/Core/Employee/AvatarProviderInterface.php b/src/Core/Employee/AvatarProviderInterface.php deleted file mode 100644 index d7861868..00000000 --- a/src/Core/Employee/AvatarProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee; - -/** - * Interface AvatarProviderInterface describes employee avatar provider. - */ -interface AvatarProviderInterface -{ - /** - * Get default employee avatar URL. - * - * @return string - */ - public function getDefaultAvatarUrl(); -} diff --git a/src/Core/Employee/ContextEmployeeProviderInterface.php b/src/Core/Employee/ContextEmployeeProviderInterface.php deleted file mode 100644 index d82c1864..00000000 --- a/src/Core/Employee/ContextEmployeeProviderInterface.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee; - -/** - * Interface ContextEmployeeProviderInterface describes a context employee provider. - */ -interface ContextEmployeeProviderInterface -{ - /** - * Check if context employee is super admin. - * - * @return bool - */ - public function isSuperAdmin(); - - /** - * Get context employee's ID. - * - * @return int - */ - public function getId(); - - /** - * Get context employee's selected language ID. - * - * @return int - */ - public function getLanguageId(); - - /** - * Get context employee's profile ID. - * - * @return int - */ - public function getProfileId(); - - /** - * Get context employee's data as an array - * - * @return array - */ - public function getData(); -} diff --git a/src/Core/Employee/EmployeeDataProviderInterface.php b/src/Core/Employee/EmployeeDataProviderInterface.php deleted file mode 100644 index 6374e3e8..00000000 --- a/src/Core/Employee/EmployeeDataProviderInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee; - -/** - * Interface EmployeeDataProviderInterface describes an employee data provider. - */ -interface EmployeeDataProviderInterface -{ - /** - * Get employee's hashed password by employee's ID. - * - * @param int $employeeId - * - * @return string - */ - public function getEmployeeHashedPassword($employeeId); - - /** - * Checks if employee is a super admin. - * - * @param int $employeeId - * - * @return bool - */ - public function isSuperAdmin($employeeId); -} diff --git a/src/Core/Employee/FormLanguageChangerInterface.php b/src/Core/Employee/FormLanguageChangerInterface.php deleted file mode 100644 index 53d85f4b..00000000 --- a/src/Core/Employee/FormLanguageChangerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee; - -/** - * Interface FormLanguageSwitcherInterface describes an employee form language changer. - */ -interface FormLanguageChangerInterface -{ - /** - * Change employee form language to given one and save the selection in the cookies. - * - * @param string $languageIsoCode two letter iso code of the language - */ - public function changeLanguageInCookies($languageIsoCode); -} diff --git a/src/Core/Employee/NavigationMenuTogglerInterface.php b/src/Core/Employee/NavigationMenuTogglerInterface.php deleted file mode 100644 index 79eb8da9..00000000 --- a/src/Core/Employee/NavigationMenuTogglerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Employee; - -/** - * Interface NavigationMenuTogglerInterface describes an employee navigation menu toggler. - */ -interface NavigationMenuTogglerInterface -{ - /** - * Toggle the navigation for employee (collapse/expand) - * - * @param bool $shouldCollapse if true - collapse the navigation, expand it otherwise - */ - public function toggleNavigationMenuInCookies($shouldCollapse); -} diff --git a/src/Core/Encoding/CharsetEncoding.php b/src/Core/Encoding/CharsetEncoding.php deleted file mode 100644 index 79c12167..00000000 --- a/src/Core/Encoding/CharsetEncoding.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Encoding; - -/** - * Class CharsetEncoding defines file chartset encoding constants. - */ -final class CharsetEncoding -{ - const UTF_8 = 'utf-8'; - const ISO_8859_1 = 'iso-8859-1'; - - /** - * This class is not meant to be instantiated as it is used to access encoding constants only. - */ - private function __construct() - { - } -} diff --git a/src/Core/EnvironmentInterface.php b/src/Core/EnvironmentInterface.php deleted file mode 100644 index 294e50f0..00000000 --- a/src/Core/EnvironmentInterface.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core; - -/** - * EnvironmentInterface is used to store/access environment information like the current - * environment name or to know if debug mode is enabled. - */ -interface EnvironmentInterface -{ - /** - * Indicates the current environment (dev|prod|test) - * - * @return string - */ - public function getName(); - - /** - * Indicates if debug mode is enabled - * - * @return bool - */ - public function isDebug(); - - /** - * Indicates the path to the cache directory - * - * @return string - */ - public function getCacheDir(); -} diff --git a/src/Core/Exception/ContainerNotFoundException.php b/src/Core/Exception/ContainerNotFoundException.php deleted file mode 100644 index 4ea82e1b..00000000 --- a/src/Core/Exception/ContainerNotFoundException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -class ContainerNotFoundException extends \Exception -{ -} diff --git a/src/Core/Exception/CoreException.php b/src/Core/Exception/CoreException.php deleted file mode 100644 index aa2ea199..00000000 --- a/src/Core/Exception/CoreException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Base class for PrestaShop core exceptions - */ -class CoreException extends \Exception -{ -} diff --git a/src/Core/Exception/DatabaseException.php b/src/Core/Exception/DatabaseException.php deleted file mode 100644 index 0f4c2d66..00000000 --- a/src/Core/Exception/DatabaseException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Class DatabaseException any error linked to the database use this class as a base. - */ -class DatabaseException extends CoreException -{ -} diff --git a/src/Core/Exception/FileNotFoundException.php b/src/Core/Exception/FileNotFoundException.php deleted file mode 100644 index af7f5484..00000000 --- a/src/Core/Exception/FileNotFoundException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -class FileNotFoundException extends CoreException -{ -} diff --git a/src/Core/Exception/IOException.php b/src/Core/Exception/IOException.php deleted file mode 100644 index d21f39ae..00000000 --- a/src/Core/Exception/IOException.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -use Throwable; - -/** - * Exception class thrown when a filesystem operation failure happens. - */ -class IOException extends CoreException -{ - private $path; - - /** - * @param string $message - * @param int $code - * @param Throwable $previous - * @param string|null $path - */ - public function __construct($message = '', $code = 0, Throwable $previous = null, $path = null) - { - parent::__construct($message, $code, $previous); - $this->path = $path; - } - - /** - * Returns the associated path for the exception. - * - * @return string|null - */ - public function getPath() - { - return $this->path; - } -} diff --git a/src/Core/Exception/InvalidArgumentException.php b/src/Core/Exception/InvalidArgumentException.php deleted file mode 100644 index 140c58f4..00000000 --- a/src/Core/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -class InvalidArgumentException extends CoreException -{ -} diff --git a/src/Core/Exception/NonASCIIInLocalPartException.php b/src/Core/Exception/NonASCIIInLocalPartException.php deleted file mode 100644 index 2b73db4c..00000000 --- a/src/Core/Exception/NonASCIIInLocalPartException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -use Egulias\EmailValidator\Exception\InvalidEmail; - -/** - * Exception thrown when email local part contains non-ascii characters - */ -class NonASCIIInLocalPartException extends InvalidEmail -{ -} diff --git a/src/Core/Exception/ProductException.php b/src/Core/Exception/ProductException.php deleted file mode 100644 index 2022e4fb..00000000 --- a/src/Core/Exception/ProductException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Class ProductException used when an error linked to a product occurs. - */ -class ProductException extends TranslatableCoreException -{ -} diff --git a/src/Core/Exception/TranslatableCoreException.php b/src/Core/Exception/TranslatableCoreException.php deleted file mode 100644 index 38bee931..00000000 --- a/src/Core/Exception/TranslatableCoreException.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Class TranslatableCoreException. - */ -class TranslatableCoreException extends CoreException -{ - /** - * @var string - */ - private $key; - - /** - * @var string - */ - private $domain; - - /** - * @var array - */ - private $parameters = []; - - /** - * @param string $key - * @param string $domain - * @param array $parameters - * @param int $code - * @param Throwable|Exception|null $previous - */ - public function __construct( - $key, - $domain, - $parameters = [], - $code = 0, - $previous = null - ) { - parent::__construct($key, $code, $previous); - $this->key = $key; - $this->domain = $domain; - $this->parameters = $parameters; - } - - /** - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * @param string $key - * - * @return $this - */ - public function setKey($key) - { - $this->key = $key; - $this->message = $key; - - return $this; - } - - /** - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * @param string $domain - * - * @return $this - */ - public function setDomain($domain) - { - $this->domain = $domain; - - return $this; - } - - /** - * @return array - */ - public function getParameters() - { - return $this->parameters; - } - - /** - * @param array $parameters - * - * @return $this - */ - public function setParameters(array $parameters) - { - $this->parameters = $parameters; - - return $this; - } - - /** - * @return array - */ - public function toArray() - { - return [ - 'key' => $this->key, - 'domain' => $this->domain, - 'parameters' => $this->parameters, - ]; - } -} diff --git a/src/Core/Exception/TranslatedException.php b/src/Core/Exception/TranslatedException.php deleted file mode 100644 index 2d5be77a..00000000 --- a/src/Core/Exception/TranslatedException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Used for exceptions which messages are already translated and can be displayed straight to end-user - */ -class TranslatedException extends CoreException -{ -} diff --git a/src/Core/Exception/TypeException.php b/src/Core/Exception/TypeException.php deleted file mode 100644 index ef442cb2..00000000 --- a/src/Core/Exception/TypeException.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Exception; - -/** - * Class InvalidArgumentException is thrown when the provided argument of - * a class method is invalid. - */ -class TypeException extends CoreException -{ -} diff --git a/src/Core/Export/Data/ExportableData.php b/src/Core/Export/Data/ExportableData.php deleted file mode 100644 index baa3a598..00000000 --- a/src/Core/Export/Data/ExportableData.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\Data; - -/** - * Class ExportableData stores data that should be written to export file. - */ -final class ExportableData implements ExportableDataInterface -{ - /** - * @var string[] - */ - private $titles; - - /** - * @var array - */ - private $rows; - - /** - * @param string[] $titles - * @param array $rows - */ - public function __construct(array $titles, array $rows) - { - $this->titles = $titles; - $this->rows = $rows; - } - - /** - * {@inheritdoc} - */ - public function getTitles() - { - return $this->titles; - } - - /** - * {@inheritdoc} - */ - public function getRows() - { - return $this->rows; - } -} diff --git a/src/Core/Export/Data/ExportableDataInterface.php b/src/Core/Export/Data/ExportableDataInterface.php deleted file mode 100644 index 19e8b706..00000000 --- a/src/Core/Export/Data/ExportableDataInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\Data; - -/** - * Interface ExportableDataInterface. - */ -interface ExportableDataInterface -{ - /** - * Titles data. - * - * @return string[] - */ - public function getTitles(); - - /** - * Rows data. - * - * @return array[] - */ - public function getRows(); -} diff --git a/src/Core/Export/Exception/ExportException.php b/src/Core/Export/Exception/ExportException.php deleted file mode 100644 index 9741def3..00000000 --- a/src/Core/Export/Exception/ExportException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Base class for PrestaShop core file export exceptions - */ -class ExportException extends CoreException -{ -} diff --git a/src/Core/Export/Exception/FileWritingException.php b/src/Core/Export/Exception/FileWritingException.php deleted file mode 100644 index 72a345c2..00000000 --- a/src/Core/Export/Exception/FileWritingException.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\Exception; - -/** - * Is thrown when cannot export due to lacking write permissions - */ -class FileWritingException extends ExportException -{ - /** - * When file cannot be opened for writing - */ - const CANNOT_OPEN_FILE_FOR_WRITING = 10; -} diff --git a/src/Core/Export/ExportDirectory.php b/src/Core/Export/ExportDirectory.php deleted file mode 100644 index a1191d0f..00000000 --- a/src/Core/Export/ExportDirectory.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * ImportDirectory class is responsible for returning export directory & data related to it. - */ -final class ExportDirectory -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * Get path to import directory. - * - * @return string - */ - public function getDir() - { - return ($this->configuration->get('_PS_HOST_MODE_') ? - $this->configuration->get('_PS_ROOT_DIR_') : - $this->configuration->get('_PS_ADMIN_DIR_')) . DIRECTORY_SEPARATOR . 'export' . DIRECTORY_SEPARATOR; - } - - /** - * Use export directory object as a string. - * - * @return string - */ - public function __toString() - { - return $this->getDir(); - } -} diff --git a/src/Core/Export/FileWriter/ExportCsvFileWriter.php b/src/Core/Export/FileWriter/ExportCsvFileWriter.php deleted file mode 100644 index f223d7a2..00000000 --- a/src/Core/Export/FileWriter/ExportCsvFileWriter.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\FileWriter; - -use Exception; -use PrestaShop\PrestaShop\Core\Export\Data\ExportableDataInterface; -use PrestaShop\PrestaShop\Core\Export\Exception\FileWritingException; -use PrestaShop\PrestaShop\Core\Export\ExportDirectory; -use SplFileObject; - -/** - * Class ExportCsvFileWriter writes provided data into CSV file and saves it in export directory. - */ -final class ExportCsvFileWriter implements FileWriterInterface -{ - /** - * @var ExportDirectory - */ - private $exportDirectory; - - /** - * @param ExportDirectory $exportDirectory - */ - public function __construct(ExportDirectory $exportDirectory) - { - $this->exportDirectory = $exportDirectory; - } - - /** - * {@inheritdoc} - * - * @throws FileWritingException - */ - public function write($fileName, ExportableDataInterface $data) - { - $filePath = $this->exportDirectory . $fileName; - - try { - $exportFile = new SplFileObject($filePath, 'w'); - } catch (Exception $e) { - throw new FileWritingException(sprintf('Cannot open export file for writing'), FileWritingException::CANNOT_OPEN_FILE_FOR_WRITING); - } - - $exportFile->fputcsv($data->getTitles(), ';'); - - foreach ($data->getRows() as $row) { - $exportFile->fputcsv($row, ';'); - } - - return $exportFile; - } -} diff --git a/src/Core/Export/FileWriter/FileWriterInterface.php b/src/Core/Export/FileWriter/FileWriterInterface.php deleted file mode 100644 index 1d09c473..00000000 --- a/src/Core/Export/FileWriter/FileWriterInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Export\FileWriter; - -use PrestaShop\PrestaShop\Core\Export\Data\ExportableDataInterface; -use SplFileInfo; - -/** - * Interface FileWriterInterface. - */ -interface FileWriterInterface -{ - /** - * Write data to file. - * - * @param string $fileName - * @param ExportableDataInterface $data - * - * @return SplFileInfo - */ - public function write($fileName, ExportableDataInterface $data); -} diff --git a/src/Core/Feature/FeatureInterface.php b/src/Core/Feature/FeatureInterface.php deleted file mode 100644 index 4dbe8cd6..00000000 --- a/src/Core/Feature/FeatureInterface.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Feature; - -/** - * Defines how we should access to a feature. - */ -interface FeatureInterface -{ - /** - * @return bool - */ - public function isUsed(); - - /** - * @return bool - */ - public function isActive(); - - public function enable(); - - public function disable(); - - /** - * @param $status bool - */ - public function update($status); -} diff --git a/src/Core/Feature/TokenInUrls.php b/src/Core/Feature/TokenInUrls.php deleted file mode 100644 index 3ebf9321..00000000 --- a/src/Core/Feature/TokenInUrls.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -namespace PrestaShop\PrestaShop\Core\Feature; - -/** - * Defines if token in urls are disabled. - */ -final class TokenInUrls -{ - const DISABLED = 'disabled'; - const ENV_VAR = '_TOKEN_'; - - /** - * @return bool - */ - public static function isDisabled() - { - return true; - return getenv(self::ENV_VAR) === self::DISABLED; - } -} diff --git a/src/Core/File/Converter/FileConverterInterface.php b/src/Core/File/Converter/FileConverterInterface.php deleted file mode 100644 index 851c7789..00000000 --- a/src/Core/File/Converter/FileConverterInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\File\Converter; - -use SplFileInfo; - -/** - * Interface FileConverterInterface defines a file converter. - */ -interface FileConverterInterface -{ - /** - * Converts a file to a different format. - * - * @param SplFileInfo $sourceFile file to convert - * - * @return SplFileInfo converted file - */ - public function convert(SplFileInfo $sourceFile); -} diff --git a/src/Core/File/FileFinderInterface.php b/src/Core/File/FileFinderInterface.php deleted file mode 100644 index ad92a63b..00000000 --- a/src/Core/File/FileFinderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\File; - -/** - * Interface FileFinderInterface defines a file finder. - */ -interface FileFinderInterface -{ - /** - * Finds files. - * - * @return array of file paths - */ - public function find(); -} diff --git a/src/Core/File/InvoiceModelFinder.php b/src/Core/File/InvoiceModelFinder.php deleted file mode 100644 index 1cdeba4c..00000000 --- a/src/Core/File/InvoiceModelFinder.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\File; - -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; - -/** - * Class InvoiceModelFinder finds invoice model files. - */ -final class InvoiceModelFinder implements FileFinderInterface -{ - /** - * @var array - */ - private $invoiceModelDirectories; - - /** - * @param array $invoiceModelDirectories - */ - public function __construct(array $invoiceModelDirectories) - { - $this->invoiceModelDirectories = $invoiceModelDirectories; - } - - /** - * Finds all invoice model files. - * - * @return array - */ - public function find() - { - $directories = $this->invoiceModelDirectories; - $filesystem = new Filesystem(); - - foreach ($directories as $key => $directory) { - if (!$filesystem->exists($directory)) { - unset($directories[$key]); - } - } - - $finder = new Finder(); - $finder->files() - ->in($directories) - ->name('invoice-*.tpl'); - - $fileNames = []; - - foreach ($finder as $file) { - $fileNames[] = $file->getFilename(); - } - - return $fileNames; - } -} diff --git a/src/Core/Filter/CollectionFilter.php b/src/Core/Filter/CollectionFilter.php deleted file mode 100644 index f03eecf8..00000000 --- a/src/Core/Filter/CollectionFilter.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter; - -/** - * Iterates over a collection, filtering each element using a queue of filters. - */ -class CollectionFilter implements FilterInterface -{ - /** - * @var FilterInterface[] - */ - private $filters = []; - - /** - * Sets process queue. - * - * @param FilterInterface[] $filters - * - * @return $this - * - * @throws FilterException - */ - public function queue(array $filters) - { - foreach ($filters as $filter) { - if (!$filter instanceof FilterInterface) { - throw new FilterException(sprintf('The provided filter is not valid filter: "%s"', print_r($filter, true))); - } - } - - $this->filters = $filters; - - return $this; - } - - /** - * Returns the current queue. - * - * @return FilterInterface[] - */ - public function getQueue() - { - return $this->filters; - } - - /** - * Filters the provided subject. - * - * @param array $subject Collection to filter - * - * @return array - * - * @throws FilterException - */ - public function filter($subject) - { - if (!is_array($subject)) { - throw new FilterException(sprintf('Invalid subject: %s', print_r($subject, true))); - } - - foreach ($subject as $k => $value) { - foreach ($this->filters as $filter) { - $value = $filter->filter($value); - } - $subject[$k] = $value; - } - - return $subject; - } -} diff --git a/src/Core/Filter/FilterException.php b/src/Core/Filter/FilterException.php deleted file mode 100644 index 593bb90b..00000000 --- a/src/Core/Filter/FilterException.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter; - -class FilterException extends \Exception -{ -} diff --git a/src/Core/Filter/FilterInterface.php b/src/Core/Filter/FilterInterface.php deleted file mode 100644 index 3cd913d2..00000000 --- a/src/Core/Filter/FilterInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter; - -interface FilterInterface -{ - /** - * Performs a filter on the subject object. - * - * @param mixed $subject subject to filter - * - * @return mixed filtered subject - */ - public function filter($subject); -} diff --git a/src/Core/Filter/FrontEndObject/CartFilter.php b/src/Core/Filter/FrontEndObject/CartFilter.php deleted file mode 100644 index 9c347f3c..00000000 --- a/src/Core/Filter/FrontEndObject/CartFilter.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Cart objects that will be sent to the client. - */ -class CartFilter extends HashMapWhitelistFilter -{ - public function __construct($productsFilter) - { - $whitelist = [ - 'discounts', - 'minimalPurchase', - 'minimalPurchaseRequired', - 'products' => $productsFilter, - 'products_count', - 'subtotals', - 'summary_string', - 'totals', - 'vouchers', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/ConfigurationFilter.php b/src/Core/Filter/FrontEndObject/ConfigurationFilter.php deleted file mode 100644 index 0f8f904c..00000000 --- a/src/Core/Filter/FrontEndObject/ConfigurationFilter.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Configuration objects that will be sent to the client. - */ -class ConfigurationFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'display_taxes_label', - 'display_prices_tax_incl', - 'is_catalog', - 'opt_in', - 'quantity_discount', - 'return_enabled', - 'show_prices', - 'voucher_enabled', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/CustomerFilter.php b/src/Core/Filter/FrontEndObject/CustomerFilter.php deleted file mode 100644 index 1bcf4b1b..00000000 --- a/src/Core/Filter/FrontEndObject/CustomerFilter.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Customer objects that will be sent to the client. - */ -class CustomerFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'addresses', - 'ape', - 'birthday', - 'company', - 'email', - 'firstname', - 'gender' => (new HashMapWhitelistFilter()) - ->whitelist([ - 'type', - 'name', - ]), - 'is_logged', - 'lastname', - 'newsletter', - 'newsletter_date_add', - 'optin', - 'siret', - 'website', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/EmbeddedAttributesFilter.php b/src/Core/Filter/FrontEndObject/EmbeddedAttributesFilter.php deleted file mode 100644 index 55ced30c..00000000 --- a/src/Core/Filter/FrontEndObject/EmbeddedAttributesFilter.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Product EmbeddedAttributes objects that will be sent to the client. - */ -class EmbeddedAttributesFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'attributes', - 'available_later', - 'available_now', - 'category', - 'condition', - 'customizable', - 'description_short', - 'ecotax', - 'ecotax_rate', - 'features', - 'id_customization', - 'id_image', - 'id_manufacturer', - 'id_product', - 'id_product_attribute', - 'link_rewrite', - 'minimal_quantity', - 'name', - 'new', - 'on_sale', - 'online_only', - 'pack', - 'price', - 'price_amount', - 'price_without_reduction', - 'quantity', - 'quantity_wanted', - 'rate', - 'reduction', - 'reference', - 'specific_prices', - 'tax_name', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/MainFilter.php b/src/Core/Filter/FrontEndObject/MainFilter.php deleted file mode 100644 index a3b91c93..00000000 --- a/src/Core/Filter/FrontEndObject/MainFilter.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\CollectionFilter; -use PrestaShop\PrestaShop\Core\Filter\FilterInterface; - -/** - * Filters the main front end object ("prestashop" on your javascript console). - */ -class MainFilter implements FilterInterface -{ - /** - * @var FilterInterface[] filters, indexed by key to filter - */ - private $filters; - - /** - * @param array $filters FilterInterface[] filters, indexed by key to filter - */ - public function __construct(array $filters) - { - $this->filters = $filters; - } - - /** - * {@inheritdoc} - * - * @return array - */ - public function filter($subject) - { - foreach ($this->filters as $key => $filter) { - if (isset($subject[$key]) && $filter instanceof FilterInterface) { - if ($filter instanceof CollectionFilter && !is_array($subject[$key])) { - continue; - } - - $subject[$key] = $filter->filter($subject[$key]); - } - } - - return $subject; - } - - /** - * @return FilterInterface[] filters, indexed by key to filter - */ - public function getFilters() - { - return $this->filters; - } -} diff --git a/src/Core/Filter/FrontEndObject/ProductFilter.php b/src/Core/Filter/FrontEndObject/ProductFilter.php deleted file mode 100644 index 1b4ff64c..00000000 --- a/src/Core/Filter/FrontEndObject/ProductFilter.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Product objects that will be sent to the client. - */ -class ProductFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'add_to_cart_url', - 'allow_oosp', - 'attributes', - 'attributes_small', - 'availability', - 'availability_date', - 'availability_message', - 'available_later', - 'available_now', - 'canonical_url', - 'cart_quantity', - 'category', - 'condition', - 'cover', - 'customizable', - 'customizations', - 'description_short', - 'discount_amount', - 'discount_percentage', - 'discount_percentage_absolute', - 'discount_to_display', - 'discount_type', - 'down_quantity_url', - 'ean13', - 'ecotax', - 'ecotax_attr', - 'ecotax_rate', - 'embedded_attributes' => new EmbeddedAttributesFilter(), - 'flags', - 'has_discount', - 'id', - 'id_customization', - 'id_image', - 'id_manufacturer', - 'id_product', - 'id_product_attribute', - 'images', - 'isbn', - 'labels', - 'legend', - 'link_rewrite', - 'main_variants', - 'manufacturer_name', - 'minimal_quantity', - 'name', - 'new', - 'on_sale', - 'online_only', - 'pack', - 'price', - 'price_amount', - 'price_attribute', - 'price_with_reduction', - 'price_with_reduction_without_tax', - 'price_without_reduction', - 'price_wt', - 'quantity', - 'quantity_discounts', - 'quantity_wanted', - 'rate', - 'reduction', - 'reference', - 'reference_to_display', - 'regular_price', - 'regular_price_amount', - 'remove_from_cart_url', - 'show_availability', - 'show_price', - 'specific_prices', - 'stock_quantity', - 'tax_name', - 'total', - 'total_wt', - 'unit_price', - 'unit_price_full', - 'up_quantity_url', - 'upc', - 'update_quantity_url', - 'url', - 'weight_unit', - 'seo_availability', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/SearchResultProductFilter.php b/src/Core/Filter/FrontEndObject/SearchResultProductFilter.php deleted file mode 100644 index 50ce70cf..00000000 --- a/src/Core/Filter/FrontEndObject/SearchResultProductFilter.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -/** - * Filters Product objects for search results. - */ -class SearchResultProductFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'active', - 'add_to_cart_url', - 'canonical_url', - 'category_name', - 'cover', - 'description_short', - 'discount_amount', - 'discount_percentage', - 'discount_percentage_absolute', - 'discount_to_display', - 'discount_type', - 'has_discount', - 'id_product', - 'labels', - 'link', - 'link_rewrite', - 'main_variants', - 'manufacturer_name', - 'name', - 'position', - 'price', - 'price_amount', - 'rate', - 'reference', - 'regular_price', - 'regular_price_amount', - 'tax_name', - 'unit_price', - 'url', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/FrontEndObject/ShopFilter.php b/src/Core/Filter/FrontEndObject/ShopFilter.php deleted file mode 100644 index 4f7942a1..00000000 --- a/src/Core/Filter/FrontEndObject/ShopFilter.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter\FrontEndObject; - -use PrestaShop\PrestaShop\Core\Filter\HashMapWhitelistFilter; - -class ShopFilter extends HashMapWhitelistFilter -{ - public function __construct() - { - $whitelist = [ - 'favicon', - 'logo', - 'name', - 'stores_icon', - ]; - - $this->whitelist($whitelist); - } -} diff --git a/src/Core/Filter/HashMapWhitelistFilter.php b/src/Core/Filter/HashMapWhitelistFilter.php deleted file mode 100644 index 5976951a..00000000 --- a/src/Core/Filter/HashMapWhitelistFilter.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Filter; - -use PrestaShop\PrestaShop\Adapter\Presenter\AbstractLazyArray; - -/** - * This class filters associative arrays. - * - * Usage: - * - * ```php - * $map = [ - * 'foo' => 'something', - * 'bar' => null, - * 'baz' => array(), - * ]; - * - * $filter = (new HashMapFilter()) - * ->whitelist( - * ['foo', 'baz'] - * ); - * - * $filtered = $filter->filter(); - * // returns [ 'foo' => something, 'baz' => [] ]; - * ``` - * - * You can also nest filters: - * - * ```php - * $map = [ - * 'foo' => 'something', - * 'bar' => null, - * 'baz' => [true, false, 1, 0] - * ]; - * - * $filter = (new HashMapFilter()) - * ->whitelist([ - * 'foo', - * 'baz' => OnlyTruthyValuesInCollectionFilter() - * ]); - * - * $filtered = $filter->filter(); - * // returns [ 'foo' => something, 'baz' => [ true, 1 ] ]; - * ``` - */ -class HashMapWhitelistFilter implements FilterInterface -{ - /** - * Index of $keyToKeep => true. - * - * @var true[] - */ - protected $whitelistItems = []; - - /** - * Nested filters, indexed by $keyToKeep. - * - * @var FilterInterface[] - */ - protected $filters = []; - - /** - * Adds keys to the whitelist. - * - * This method accepts either: - * - string[] an array of keys to keep - * - FilterInterface[] an array of filters, indexed by keys to keep - * - A mixture of the two - * - * @param string[]|FilterInterface[] $definition - * - * @return $this - */ - public function whitelist($definition) - { - foreach ($definition as $k => $value) { - $this->addWhitelistItem($k, $value); - } - - return $this; - } - - /** - * Removes the provided key from the whitelist. - * - * @param string|int $key - * - * @return $this - * - * @throws FilterException if $key is not scalar - */ - public function removeFromWhitelist($key) - { - if (!is_scalar($key)) { - throw new FilterException(sprintf('Invalid parameter %s', print_r($key, true))); - } - - unset( - $this->whitelistItems[$key], - $this->filters[$key] - ); - - return $this; - } - - /** - * Returns the white list. - * - * @return true[] - */ - public function getWhitelistItems() - { - return $this->whitelistItems; - } - - /** - * Returns the nested filters, indexed by $keyToKeep. - * - * @return FilterInterface[] - */ - public function getFilters() - { - return $this->filters; - } - - /** - * Filters the subject. - * - * @param array $subject - * - * @return array The filtered subject - * - * @throws \RuntimeException - */ - public function filter($subject) - { - // keep whitelisted items - if ($subject instanceof AbstractLazyArray) { - // avoid modifying the original object - $subject = clone $subject; - $subject->intersectKey($this->whitelistItems); - // run nested filters - foreach ($this->filters as $key => $filter) { - if ($subject->offsetExists($key)) { - $filteredValue = $filter->filter($subject->offsetGet($key)); - $subject->offsetSet($key, $filteredValue, true); - } - } - } else { - $subject = array_intersect_key($subject, $this->whitelistItems); - // run nested filters - foreach ($this->filters as $key => $filter) { - if (array_key_exists($key, $subject)) { - $subject[$key] = $filter->filter($subject[$key]); - } - } - } - - return $subject; - } - - /** - * Adds an element to the whitelist. - * - * @param int|string $paramKey - * @param string|FilterInterface $paramValue - * - * @return $this - */ - private function addWhitelistItem($paramKey, $paramValue) - { - $keyToWhitelist = $paramValue; - if ($paramValue instanceof FilterInterface) { - $this->filters[$paramKey] = $paramValue; - - $keyToWhitelist = $paramKey; - } - - // add as key to allow faster search - $this->whitelistItems[$keyToWhitelist] = true; - - return $this; - } -} diff --git a/src/Core/Form/ChoiceProvider/AddressRequiredFieldsChoiceProvider.php b/src/Core/Form/ChoiceProvider/AddressRequiredFieldsChoiceProvider.php deleted file mode 100644 index 279cd270..00000000 --- a/src/Core/Form/ChoiceProvider/AddressRequiredFieldsChoiceProvider.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\RequiredFields; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Provides choices for configuring required fields for address - */ -final class AddressRequiredFieldsChoiceProvider implements FormChoiceProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getChoices() - { - return array_combine(RequiredFields::ALLOWED_REQUIRED_FIELDS, RequiredFields::ALLOWED_REQUIRED_FIELDS); - } -} diff --git a/src/Core/Form/ChoiceProvider/CanonicalRedirectTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/CanonicalRedirectTypeChoiceProvider.php deleted file mode 100644 index 46c3e717..00000000 --- a/src/Core/Form/ChoiceProvider/CanonicalRedirectTypeChoiceProvider.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CanonicalRedirectTypeChoiceProvider is responsible for providing choices for - * redirect to the canonical URL form field selection. - */ -final class CanonicalRedirectTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * CanonicalRedirectTypeChoiceProvider constructor. - * - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $noRedirectionMessage = $this->translator->trans( - 'No redirection (you may have duplicate content issues)', - [], - 'Admin.Shopparameters.Feature' - ); - - $movedTemporaryMessage = $this->translator->trans( - '302 Moved Temporarily (recommended while setting up your store)', - [], - 'Admin.Shopparameters.Feature' - ); - - $movedPermanentlyMessage = $this->translator->trans( - '301 Moved Permanently (recommended once you have gone live)', - [], - 'Admin.Shopparameters.Feature' - ); - - return [ - $noRedirectionMessage => 0, - $movedTemporaryMessage => 1, - $movedPermanentlyMessage => 2, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/CarrierByReferenceChoiceProvider.php b/src/Core/Form/ChoiceProvider/CarrierByReferenceChoiceProvider.php deleted file mode 100644 index e1d8268d..00000000 --- a/src/Core/Form/ChoiceProvider/CarrierByReferenceChoiceProvider.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Carrier\CarrierDataProvider; -use PrestaShop\PrestaShop\Adapter\Entity\Carrier; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class CarrierByReferenceChoiceProvider is responsible for providing carrier choices with value reference. - */ -final class CarrierByReferenceChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var CarrierDataProvider - */ - private $carrierDataProvider; - - /** - * @var int - */ - private $langId; - - /** - * @param CarrierDataProvider $carrierDataProvider - * @param int $langId - */ - public function __construct(CarrierDataProvider $carrierDataProvider, $langId) - { - $this->carrierDataProvider = $carrierDataProvider; - $this->langId = $langId; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - $carriers = $this->carrierDataProvider->getCarriers( - $this->langId, - false, - false, - false, - null, - Carrier::ALL_CARRIERS - ); - - foreach ($carriers as $carrier) { - $choiceId = $carrier['id_carrier'] . ' - ' . $carrier['name']; - if ($carrier['name']) { - $choiceId .= ' (' . $carrier['delay'] . ')'; - } - - $choices[$choiceId] = $carrier['id_reference']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/CategoryDeleteModeChoiceProvider.php b/src/Core/Form/ChoiceProvider/CategoryDeleteModeChoiceProvider.php deleted file mode 100644 index baea122a..00000000 --- a/src/Core/Form/ChoiceProvider/CategoryDeleteModeChoiceProvider.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryDeleteMode; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CategoryDeleteModeChoiceProvider. - */ -final class CategoryDeleteModeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $associateOnlyLabel = $this->translator->trans( - 'If they have no other category, I want to associate them with the parent category.', - [], - 'Admin.Catalog.Notification' - ); - - $associateAndDisableLabel = sprintf( - '%s %s', - $this->translator->trans( - 'If they have no other category, I want to associate them with the parent category and turn them offline.', - [], - 'Admin.Catalog.Notification' - ), - $this->translator->trans('(Recommended)', [], 'Admin.Catalog.Notification') - ); - - $deleteProductLabel = $this->translator->trans( - 'If they have no other category, I want to delete them as well.', - [], - 'Admin.Catalog.Notification' - ); - - return [ - $associateAndDisableLabel => CategoryDeleteMode::ASSOCIATE_PRODUCTS_WITH_PARENT_AND_DISABLE, - $associateOnlyLabel => CategoryDeleteMode::ASSOCIATE_PRODUCTS_WITH_PARENT_ONLY, - $deleteProductLabel => CategoryDeleteMode::REMOVE_ASSOCIATED_PRODUCTS, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/CmsCategoriesChoiceProvider.php b/src/Core/Form/ChoiceProvider/CmsCategoriesChoiceProvider.php deleted file mode 100644 index 62e04ed4..00000000 --- a/src/Core/Form/ChoiceProvider/CmsCategoriesChoiceProvider.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -final class CmsCategoriesChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $nestedCategories; - - /** - * @param array $nestedCategories - */ - public function __construct(array $nestedCategories) - { - $this->nestedCategories = $nestedCategories; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices[] = $this->buildChoiceTree($this->nestedCategories); - - return $choices; - } - - /** - * @param array $category - * - * @return array - */ - private function buildChoiceTree(array $category) - { - $tree = [ - 'id_cms_category' => $category['id_cms_category'], - 'name' => $category['name'], - ]; - - if (isset($category['children'])) { - foreach ($category['children'] as $childCategory) { - $tree['children'][] = $this->buildChoiceTree($childCategory); - } - } - - return $tree; - } -} diff --git a/src/Core/Form/ChoiceProvider/ContactByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/ContactByIdChoiceProvider.php deleted file mode 100644 index b27a4a01..00000000 --- a/src/Core/Form/ChoiceProvider/ContactByIdChoiceProvider.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Support\ContactRepositoryInterface; - -/** - * Class ContactByIdChoiceProvider is responsible for providing shop contact choices. - */ -final class ContactByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ContactRepositoryInterface - */ - private $contactRepository; - - /** - * @var int - */ - private $langId; - - /** - * @param ContactRepositoryInterface $contactRepository - * @param int $langId - */ - public function __construct( - ContactRepositoryInterface $contactRepository, - $langId - ) { - $this->contactRepository = $contactRepository; - $this->langId = $langId; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - $contacts = $this->contactRepository->findAllByLangId($this->langId); - - foreach ($contacts as $contact) { - $choices[$contact['name']] = $contact['id_contact']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/CountryByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/CountryByIdChoiceProvider.php deleted file mode 100644 index 9f2e4cda..00000000 --- a/src/Core/Form/ChoiceProvider/CountryByIdChoiceProvider.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Country\CountryDataProvider; -use PrestaShop\PrestaShop\Core\Form\FormChoiceAttributeProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class CountryByIdChoiceProvider provides country choices with ID values. - */ -final class CountryByIdChoiceProvider implements FormChoiceProviderInterface, FormChoiceAttributeProviderInterface -{ - /** - * @var CountryDataProvider - */ - private $countryDataProvider; - - /** - * @var int - */ - private $langId; - - /** - * @var array - */ - private $countries; - - /** - * @var int[] - */ - private $dniCountriesId; - - /** - * @var int[] - */ - private $postcodeCountriesId; - - /** - * @param int $langId - * @param CountryDataProvider $countryDataProvider - */ - public function __construct( - $langId, - CountryDataProvider $countryDataProvider - ) { - $this->langId = $langId; - $this->countryDataProvider = $countryDataProvider; - } - - /** - * Get currency choices. - * - * @return array - */ - public function getChoices() - { - $countries = $this->getCountries(); - $choices = []; - - foreach ($countries as $country) { - $choices[$country['name']] = $country['id_country']; - } - - return $choices; - } - - /** - * @return array - */ - public function getChoicesAttributes() - { - $countries = $this->getCountries(); - $dniCountriesId = $this->getDniCountriesId(); - $postcodeCountriesId = $this->getPostcodeCountriesId(); - $choicesAttributes = []; - - foreach ($countries as $country) { - if (in_array($country['id_country'], $dniCountriesId)) { - $choicesAttributes[$country['name']]['need_dni'] = 1; - } - if (in_array($country['id_country'], $postcodeCountriesId)) { - $choicesAttributes[$country['name']]['need_postcode'] = 1; - } - } - - return $choicesAttributes; - } - - /** - * @return array - */ - private function getCountries() - { - if (null === $this->countries) { - $this->countries = $this->countryDataProvider->getCountries($this->langId); - } - - return $this->countries; - } - - /** - * @return int[] - */ - private function getDniCountriesId() - { - if (null === $this->dniCountriesId) { - $this->dniCountriesId = $this->countryDataProvider->getCountriesIdWhichNeedDni(); - } - - return $this->dniCountriesId; - } - - private function getPostcodeCountriesId() - { - if (null === $this->postcodeCountriesId) { - $this->postcodeCountriesId = $this->countryDataProvider->getCountriesIdWhichNeedPostcode(); - } - - return $this->postcodeCountriesId; - } -} diff --git a/src/Core/Form/ChoiceProvider/CountryByIsoCodeChoiceProvider.php b/src/Core/Form/ChoiceProvider/CountryByIsoCodeChoiceProvider.php deleted file mode 100644 index 4e9b204e..00000000 --- a/src/Core/Form/ChoiceProvider/CountryByIsoCodeChoiceProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Country\CountryDataProvider; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class CountryChoiceProvider is responsible for providing both enabled/disabled country choices with ISO code values. - */ -final class CountryByIsoCodeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var CountryDataProvider - */ - private $countryDataProvider; - - /** - * @var int - */ - private $langId; - - /** - * @param int $langId - * @param CountryDataProvider $countryDataProvider - */ - public function __construct( - $langId, - CountryDataProvider $countryDataProvider - ) { - $this->countryDataProvider = $countryDataProvider; - $this->langId = $langId; - } - - /** - * Get country choices. - * - * @return array - */ - public function getChoices() - { - $choices = []; - $countries = $this->countryDataProvider->getCountries($this->langId); - - foreach ($countries as $country) { - $choices[$country['name']] = $country['iso_code']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/CurrencyByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/CurrencyByIdChoiceProvider.php deleted file mode 100644 index d54fafdd..00000000 --- a/src/Core/Form/ChoiceProvider/CurrencyByIdChoiceProvider.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Currency\CurrencyDataProvider; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class CurrencyByIdChoiceProvider provides currency choices with ID values. - */ -final class CurrencyByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var CurrencyDataProvider - */ - private $currencyDataProvider; - - /** - * @param CurrencyDataProvider $currencyDataProvider - */ - public function __construct(CurrencyDataProvider $currencyDataProvider) - { - $this->currencyDataProvider = $currencyDataProvider; - } - - /** - * Get currency choices. - * - * @return array - */ - public function getChoices() - { - $currencies = $this->currencyDataProvider->getCurrencies(false, true, true); - $choices = []; - - foreach ($currencies as $currency) { - $choices[sprintf('%s (%s)', $currency['name'], $currency['iso_code'])] = $currency['id_currency']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/CurrencyNameByIsoCodeChoiceProvider.php b/src/Core/Form/ChoiceProvider/CurrencyNameByIsoCodeChoiceProvider.php deleted file mode 100644 index a25651a6..00000000 --- a/src/Core/Form/ChoiceProvider/CurrencyNameByIsoCodeChoiceProvider.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\CurrencyData; - -/** - * Class CurrencyNameByIsoCodeChoiceProvider is responsible for retrieving currency names from cldr library. - */ -final class CurrencyNameByIsoCodeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var CurrencyData[] - */ - private $cldrAllCurrencies; - - /** - * @param CurrencyData[] $cldrAllCurrencies - */ - public function __construct(array $cldrAllCurrencies) - { - $this->cldrAllCurrencies = $cldrAllCurrencies; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $result = []; - foreach ($this->cldrAllCurrencies as $cldrCurrency) { - // filter only on active currency - // we dont need here currencies which were deactivated in all territories - if (!$cldrCurrency->isActive()) { - continue; - } - $currencyNames = $cldrCurrency->getDisplayNames(); - $isoCode = $cldrCurrency->getIsoCode(); - $displayName = sprintf('%s (%s)', $currencyNames['default'], $isoCode); - - $result[$displayName] = $isoCode; - } - ksort($result); - - return $result; - } -} diff --git a/src/Core/Form/ChoiceProvider/CustomerAddressesChoiceProvider.php b/src/Core/Form/ChoiceProvider/CustomerAddressesChoiceProvider.php deleted file mode 100644 index a0ff724f..00000000 --- a/src/Core/Form/ChoiceProvider/CustomerAddressesChoiceProvider.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; - -/** - * Provides choices for configuring required fields for customer - */ -final class CustomerAddressesChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * @var CustomerDataProvider - */ - private $customerDataProvider; - - /** - * @var int - */ - private $langId; - - /** - * @param CustomerDataProvider $customerDataProvider - * @param int $langId - */ - public function __construct(CustomerDataProvider $customerDataProvider, int $langId) - { - $this->customerDataProvider = $customerDataProvider; - $this->langId = $langId; - } - - /** - * {@inheritdoc} - */ - public function getChoices(array $options) - { - if (!isset($options['customer_id'])) { - throw new \InvalidArgumentException('Expected a customer_id option, none found'); - } - - $addresses = $this->customerDataProvider->getCustomerAddresses($options['customer_id'], $this->langId); - - $result = []; - foreach ($addresses as $address) { - $description = sprintf( - '%d- %s %s %s %s', - $address['id_address'], - $address['address1'], - $address['address2'] ?: '', - $address['postcode'], - $address['city'] - ); - - $result[$description] = $address['id_address']; - } - - return $result; - } -} diff --git a/src/Core/Form/ChoiceProvider/CustomerDeleteMethodChoiceProvider.php b/src/Core/Form/ChoiceProvider/CustomerDeleteMethodChoiceProvider.php deleted file mode 100644 index 81b046c2..00000000 --- a/src/Core/Form/ChoiceProvider/CustomerDeleteMethodChoiceProvider.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerDeleteMethod; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides choices in which customer can be deleted. - */ -final class CustomerDeleteMethodChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $allowRegistrationLabel = $this->translator->trans( - 'I want my customers to be able to register again with the same email address. All data will be removed from the database.', - [], - 'Admin.Orderscustomers.Notification' - ); - - $denyRegistraionLabel = $this->translator->trans( - 'I do not want my customer(s) to register again with the same email address. All selected customer(s) will be removed from this list but their corresponding data will be kept in the database.', - [], - 'Admin.Orderscustomers.Notification' - ); - - return [ - $allowRegistrationLabel => CustomerDeleteMethod::ALLOW_CUSTOMER_REGISTRATION, - $denyRegistraionLabel => CustomerDeleteMethod::DENY_CUSTOMER_REGISTRATION, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/CustomerRequiredFieldsChoiceProvider.php b/src/Core/Form/ChoiceProvider/CustomerRequiredFieldsChoiceProvider.php deleted file mode 100644 index 3e1e7cca..00000000 --- a/src/Core/Form/ChoiceProvider/CustomerRequiredFieldsChoiceProvider.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\RequiredField; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides choices for configuring required fields for customer - */ -final class CustomerRequiredFieldsChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Partner offers', [], 'Admin.Orderscustomers.Feature') => RequiredField::PARTNER_OFFERS, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesChoiceProvider.php b/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesChoiceProvider.php deleted file mode 100644 index 77bf2038..00000000 --- a/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesChoiceProvider.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Selects order messages itself. - */ -final class CustomerServiceOrderMessagesChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $orderMessages; - - public function __construct(array $orderMessages) - { - $this->orderMessages = $orderMessages; - } - - /** - * {@inheritdoc} - */ - public function getChoices(): array - { - $result = []; - - foreach ($this->orderMessages as $orderMessage) { - $result[$orderMessage['id_order_message']] = $orderMessage['message']; - } - - return $result; - } -} diff --git a/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesNameChoiceProvider.php deleted file mode 100644 index c1609089..00000000 --- a/src/Core/Form/ChoiceProvider/CustomerServiceOrderMessagesNameChoiceProvider.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Gets choices for predefined order message types. - */ -final class CustomerServiceOrderMessagesNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $orderMessages; - - public function __construct(array $orderMessages) - { - $this->orderMessages = $orderMessages; - } - - /** - * {@inheritdoc} - */ - public function getChoices(): array - { - $result = []; - - foreach ($this->orderMessages as $orderMessage) { - $result[$orderMessage['name']] = $orderMessage['id_order_message']; - } - - return $result; - } -} diff --git a/src/Core/Form/ChoiceProvider/DefaultMetaPageNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/DefaultMetaPageNameChoiceProvider.php deleted file mode 100644 index 90942570..00000000 --- a/src/Core/Form/ChoiceProvider/DefaultMetaPageNameChoiceProvider.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Meta\MetaDataProviderInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Class DefaultMetaPageNameChoiceProvider is responsible for providing default page choices in - * Shop parameters -> Traffic & Seo -> Seo & Urls -> form. - */ -final class DefaultMetaPageNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var MetaDataProviderInterface - */ - private $dataProvider; - - /** - * DefaultPageChoiceProvider constructor. - * - * @param RequestStack $requestStack - * @param MetaDataProviderInterface $dataProvider - * - * @todo: get rid of request stack by creating new interface. - */ - public function __construct( - RequestStack $requestStack, - MetaDataProviderInterface $dataProvider - ) { - $this->requestStack = $requestStack; - $this->dataProvider = $dataProvider; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $defaultPages = $this->dataProvider->getDefaultMetaPageNamesExcludingFilled(); - $currentPage = $this->getCurrentPage(); - - if (null !== $currentPage) { - $defaultPages[$currentPage] = $currentPage; - asort($defaultPages); - } - - return $defaultPages; - } - - /** - * Gets current page. - * - * @return string|null - */ - private function getCurrentPage() - { - $currentRequest = $this->requestStack->getCurrentRequest(); - - $metaId = null; - if (null !== $currentRequest) { - $metaId = $currentRequest->attributes->get('metaId'); - } - - if ($metaId) { - return $this->dataProvider->getDefaultMetaPageNameById($metaId); - } - - return null; - } -} diff --git a/src/Core/Form/ChoiceProvider/EmailContentTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/EmailContentTypeChoiceProvider.php deleted file mode 100644 index 22b2d766..00000000 --- a/src/Core/Form/ChoiceProvider/EmailContentTypeChoiceProvider.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class EmailContentTypeChoiceProvider provides email content type choices. - */ -final class EmailContentTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * Get email content type choices. - * - * @return array - */ - public function getChoices() - { - return [ - $this->translator->trans('Subject', [], 'Admin.Global') => 'subject', - $this->translator->trans('Body', [], 'Admin.International.Feature') => 'body', - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/GroupByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/GroupByIdChoiceProvider.php deleted file mode 100644 index 701ba395..00000000 --- a/src/Core/Form/ChoiceProvider/GroupByIdChoiceProvider.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Group\GroupDataProvider; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class GroupByIdChoiceProvider is responsible for providing customer group choices with Id values. - */ -final class GroupByIdChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var GroupDataProvider - */ - private $groupDataProvider; - - /** - * @var int - */ - private $langId; - - /** - * @param GroupDataProvider $groupDataProvider - * @param int $langId - */ - public function __construct( - GroupDataProvider $groupDataProvider, - $langId - ) { - $this->groupDataProvider = $groupDataProvider; - $this->langId = $langId; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - $groups = $this->groupDataProvider->getGroups($this->langId); - - foreach ($groups as $group) { - $choices[$group['name']] = $group['id_group']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ImportEntityFieldChoiceProvider.php b/src/Core/Form/ChoiceProvider/ImportEntityFieldChoiceProvider.php deleted file mode 100644 index 026022cd..00000000 --- a/src/Core/Form/ChoiceProvider/ImportEntityFieldChoiceProvider.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Import\EntityField\Provider\EntityFieldsProviderFinderInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportEntityException; - -/** - * Class ImportEntityFieldChoiceProvider is responsible for providing entity import field choices. - */ -final class ImportEntityFieldChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var EntityFieldsProviderFinderInterface - */ - private $entityFieldsProviderFinder; - - /** - * @var int selected import entity - */ - private $selectedEntity; - - /** - * @param EntityFieldsProviderFinderInterface $entityFieldsProviderFinder - * @param int $selectedEntity - */ - public function __construct( - EntityFieldsProviderFinderInterface $entityFieldsProviderFinder, - $selectedEntity - ) { - $this->entityFieldsProviderFinder = $entityFieldsProviderFinder; - $this->selectedEntity = $selectedEntity; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - try { - $entityFieldCollection = $this->entityFieldsProviderFinder->find($this->selectedEntity)->getCollection(); - } catch (NotSupportedImportEntityException $e) { - return []; - } - - $choices = []; - - foreach ($entityFieldCollection as $entityField) { - $label = $entityField->getLabel(); - - if ($entityField->isRequired()) { - $label .= '*'; - } - - $choices[$label] = $entityField->getName(); - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ImportMatchConfigurationChoiceProvider.php b/src/Core/Form/ChoiceProvider/ImportMatchConfigurationChoiceProvider.php deleted file mode 100644 index 5ecfa2ab..00000000 --- a/src/Core/Form/ChoiceProvider/ImportMatchConfigurationChoiceProvider.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ImportMatchConfigurationChoiceProvider is responsible for providing choices - * in Advanced parameters -> Import -> Step 2 -> Load a data matching configuration. - */ -final class ImportMatchConfigurationChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $matchConfigurations; - - /** - * @param array $matchConfigurations - */ - public function __construct(array $matchConfigurations) - { - $this->matchConfigurations = $matchConfigurations; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - foreach ($this->matchConfigurations as $configuration) { - $choices[$configuration['name']] = $configuration['id_import_match']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/InvoiceModelByNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/InvoiceModelByNameChoiceProvider.php deleted file mode 100644 index f90a52c5..00000000 --- a/src/Core/Form/ChoiceProvider/InvoiceModelByNameChoiceProvider.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\File\FileFinderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class InvoiceModelByNameChoiceProvider provides invoice model choices with name values. - */ -final class InvoiceModelByNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var FileFinderInterface - */ - private $invoiceModelFinder; - - /** - * @param FileFinderInterface $invoiceModelFinder - */ - public function __construct(FileFinderInterface $invoiceModelFinder) - { - $this->invoiceModelFinder = $invoiceModelFinder; - } - - /** - * Get invoice model choices. - * - * @return array - */ - public function getChoices() - { - $choices = [ - 'invoice' => 'invoice', - ]; - - $invoiceModels = $this->invoiceModelFinder->find(); - - foreach ($invoiceModels as $invoiceModel) { - $modelName = basename($invoiceModel, '.tpl'); - $choices[$modelName] = $modelName; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/LanguageByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/LanguageByIdChoiceProvider.php deleted file mode 100644 index 89c7a5da..00000000 --- a/src/Core/Form/ChoiceProvider/LanguageByIdChoiceProvider.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Language\LanguageDataProvider; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; - -/** - * Class LanguageByIdChoiceProvider provides active language choices with ID values. - */ -final class LanguageByIdChoiceProvider implements ConfigurableFormChoiceProviderInterface -{ - /** - * @var LanguageDataProvider - */ - private $languageDataProvider; - - /** - * LanguageByIdChoiceProvider constructor. - * - * @param LanguageDataProvider $languageDataProvider - */ - public function __construct(LanguageDataProvider $languageDataProvider) - { - $this->languageDataProvider = $languageDataProvider; - } - - /** - * Get active language choices for form. - * - * @return array - */ - public function getChoices(array $options = []) - { - $choices = []; - $shopId = isset($options['shop_id']) && (int) $options['shop_id'] > 0 ? $options['shop_id'] : false; - foreach ($this->languageDataProvider->getLanguages(true, $shopId) as $language) { - $choices[$language['name']] = $language['id_lang']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/LanguageChoiceProvider.php b/src/Core/Form/ChoiceProvider/LanguageChoiceProvider.php deleted file mode 100644 index 9fb3a705..00000000 --- a/src/Core/Form/ChoiceProvider/LanguageChoiceProvider.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class LanguageChoiceProvider provides languages choices with ID values. - * - * @todo this class could be merged with \PrestaShop\PrestaShop\Core\Form\ChoiceProvider\LanguageByIdChoiceProvider - * as this class can fully achieve the same behavior as the LanguageByIdChoiceProvider. - * It would break BC though, so couldn't be done at the moment. - */ -final class LanguageChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $languages; - - /** - * @param array $languages - */ - public function __construct(array $languages) - { - $this->languages = $languages; - } - - /** - * Get active language choices for form. - * - * @return array - */ - public function getChoices() - { - $choices = []; - - foreach ($this->languages as $language) { - $choices[$language['name']] = $language['id_lang']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/LocalizationPackByIsoCodeChoiceProvider.php b/src/Core/Form/ChoiceProvider/LocalizationPackByIsoCodeChoiceProvider.php deleted file mode 100644 index e2bb4453..00000000 --- a/src/Core/Form/ChoiceProvider/LocalizationPackByIsoCodeChoiceProvider.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Localization\Pack\Loader\LocalizationPackLoaderInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class LocalizationPackByIsoCodeChoiceProvider provides localization pack choices with iso code values. - */ -final class LocalizationPackByIsoCodeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var LocalizationPackLoaderInterface - */ - private $remoteLocalizationPackLoader; - - /** - * @var LocalizationPackLoaderInterface - */ - private $localLocalizationPackLoader; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param LocalizationPackLoaderInterface $remoteLocalizationPackLoader - * @param LocalizationPackLoaderInterface $localLocalizationPackLoader - * @param ConfigurationInterface $configuration - * @param TranslatorInterface $translator - */ - public function __construct( - LocalizationPackLoaderInterface $remoteLocalizationPackLoader, - LocalizationPackLoaderInterface $localLocalizationPackLoader, - ConfigurationInterface $configuration, - TranslatorInterface $translator - ) { - $this->remoteLocalizationPackLoader = $remoteLocalizationPackLoader; - $this->localLocalizationPackLoader = $localLocalizationPackLoader; - $this->configuration = $configuration; - $this->translator = $translator; - } - - /** - * Get localization pack choices. - * - * @return array - */ - public function getChoices() - { - $localizationPacks = $this->remoteLocalizationPackLoader->getLocalizationPackList(); - if (null === $localizationPacks) { - $localizationPacks = $this->localLocalizationPackLoader->getLocalizationPackList(); - } - - $choices = []; - - if ($localizationPacks) { - foreach ($localizationPacks as $pack) { - $choices[(string) $pack->name] = (string) $pack->iso; - } - } - - $rootDir = $this->configuration->get('_PS_ROOT_DIR_'); - - $finder = (new Finder()) - ->files() - ->depth('0') - ->in($rootDir . '/localization') - ->name('/^([a-z]{2})\.xml$/'); - - foreach ($finder as $file) { - list($iso) = explode('.', $file->getFilename()); - - // if localization pack was not loaded yet and it exists locally - // then add it to choices list - if (!in_array($iso, $choices)) { - $pack = $this->localLocalizationPackLoader->getLocalizationPack($iso); - $packName = $this->translator->trans( - '%s (local)', - [ - (string) $pack['name'], - ], - 'Admin.International.Feature' - ); - - $choices[$packName] = $iso; - } - } - - // sort choices alphabetically - ksort($choices); - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/MailMethodChoiceProvider.php b/src/Core/Form/ChoiceProvider/MailMethodChoiceProvider.php deleted file mode 100644 index 16667663..00000000 --- a/src/Core/Form/ChoiceProvider/MailMethodChoiceProvider.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Email\MailOption; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class MailMethodChoiceProvider provides choices for mail methods. - */ -final class MailMethodChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param ConfigurationInterface $configuration - * @param TranslatorInterface $translator - */ - public function __construct( - ConfigurationInterface $configuration, - TranslatorInterface $translator - ) { - $this->configuration = $configuration; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - if (null === $this->configuration->get('_PS_HOST_MODE_')) { - $choices[ - $this->trans('Use /usr/sbin/sendmail (recommended; works in most cases)', [], 'Admin.Advparameters.Feature') - ] = MailOption::METHOD_NATIVE; - } - - $choices[ - $this->trans('Set my own SMTP parameters (for advanced users ONLY)', [], 'Admin.Advparameters.Feature') - ] = MailOption::METHOD_SMTP; - - $choices[ - $this->trans('Never send emails (may be useful for testing purposes)', [], 'Admin.Advparameters.Feature') - ] = MailOption::METHOD_NONE; - - return $choices; - } - - /** - * @param string $key - * @param array $params - * @param string $domain - * - * @return string - */ - private function trans($key, array $params, $domain) - { - return $this->translator->trans($key, $params, $domain); - } -} diff --git a/src/Core/Form/ChoiceProvider/MailThemeChoiceProvider.php b/src/Core/Form/ChoiceProvider/MailThemeChoiceProvider.php deleted file mode 100644 index 1f28d21d..00000000 --- a/src/Core/Form/ChoiceProvider/MailThemeChoiceProvider.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCollectionInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; - -/** - * Class MailThemeChoiceProvider is responsible to provide a list of available mail themes. - */ -class MailThemeChoiceProvider implements FormChoiceProviderInterface -{ - /** @var array */ - private $choices; - - /** @var ThemeCatalogInterface */ - private $themeCatalog; - - /** - * @param ThemeCatalogInterface $themeCatalog - */ - public function __construct(ThemeCatalogInterface $themeCatalog) - { - $this->themeCatalog = $themeCatalog; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - if (null === $this->choices) { - $this->choices = []; - - /** @var ThemeCollectionInterface $collection */ - $collection = $this->themeCatalog->listThemes(); - - /** @var ThemeInterface $theme */ - foreach ($collection as $theme) { - $this->choices[$theme->getName()] = $theme->getName(); - } - } - - return $this->choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ModuleByNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/ModuleByNameChoiceProvider.php deleted file mode 100644 index 69130ea7..00000000 --- a/src/Core/Form/ChoiceProvider/ModuleByNameChoiceProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ModuleByNameChoiceProvider provides module choices with name values. - */ -final class ModuleByNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var AddonsCollection collection of installed modules - */ - private $installedModules; - - /** - * @param AddonsCollection $installedModules - */ - public function __construct(AddonsCollection $installedModules) - { - $this->installedModules = $installedModules; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $moduleChoices = []; - - /** @var Module $module */ - foreach ($this->installedModules as $module) { - $moduleChoices[$module->get('displayName')] = $module->get('name'); - } - - return $moduleChoices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ModuleMetaPageNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/ModuleMetaPageNameChoiceProvider.php deleted file mode 100644 index 10fb006c..00000000 --- a/src/Core/Form/ChoiceProvider/ModuleMetaPageNameChoiceProvider.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Meta\MetaDataProviderInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Class ModuleMetaPageNameChoiceProvider is responsible for providing module page choices in - * Shop parameters -> Traffic & Seo -> Seo & Urls -> form. - */ -final class ModuleMetaPageNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var MetaDataProviderInterface - */ - private $dataProvider; - - /** - * DefaultPageChoiceProvider constructor. - * - * @param RequestStack $requestStack - * @param MetaDataProviderInterface $dataProvider - */ - public function __construct( - RequestStack $requestStack, - MetaDataProviderInterface $dataProvider - ) { - $this->requestStack = $requestStack; - $this->dataProvider = $dataProvider; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $defaultPages = $this->dataProvider->getNotConfiguredModuleMetaPageNames(); - $currentPage = $this->getCurrentPage(); - - if (null !== $currentPage) { - $defaultPages[str_replace('module-', '', $currentPage)] = $currentPage; - asort($defaultPages); - } - - return $defaultPages; - } - - /** - * Gets current page. - * - * @return string|null - */ - private function getCurrentPage() - { - $currentRequest = $this->requestStack->getCurrentRequest(); - - $metaId = null; - if (null !== $currentRequest) { - $metaId = $currentRequest->attributes->get('metaId'); - } - - if ($metaId) { - return $this->dataProvider->getModuleMetaPageNameById($metaId); - } - - return null; - } -} diff --git a/src/Core/Form/ChoiceProvider/NonInstalledLocalizationChoiceProvider.php b/src/Core/Form/ChoiceProvider/NonInstalledLocalizationChoiceProvider.php deleted file mode 100644 index 88edd741..00000000 --- a/src/Core/Form/ChoiceProvider/NonInstalledLocalizationChoiceProvider.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Adapter\Language\LanguageDataProvider; -use PrestaShop\PrestaShop\Adapter\Language\LanguageValidator; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageValidatorInterface; - -/** - * Class NonInstalledLocalizationChoiceProvider provides non installed localization choices - * with name keys and iso code values. - */ -final class NonInstalledLocalizationChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var LanguageValidator - */ - private $languageValidator; - - /** - * @var LanguageDataProvider - */ - private $languageProvider; - /** - * @var array - */ - private $languagePackList; - - /** - * @param array $languagePackList - * @param LanguageValidatorInterface $languageValidator - * @param LanguageDataProvider $languageProvider - */ - public function __construct( - array $languagePackList, - LanguageValidatorInterface $languageValidator, - LanguageDataProvider $languageProvider - ) { - $this->languageValidator = $languageValidator; - $this->languageProvider = $languageProvider; - $this->languagePackList = $languagePackList; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - foreach (array_keys($this->languagePackList) as $locale) { - if ($this->languageValidator->isInstalledByLocale($locale)) { - continue; - } - - $languageDetails = $this->languageProvider->getLanguageDetails($locale); - - if (isset($languageDetails['iso_code'], $languageDetails['name'])) { - $choices[$languageDetails['name']] = $languageDetails['iso_code']; - } - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/OrderDiscountTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/OrderDiscountTypeChoiceProvider.php deleted file mode 100644 index 7f65bad0..00000000 --- a/src/Core/Form/ChoiceProvider/OrderDiscountTypeChoiceProvider.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Order\OrderDiscountType; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -final class OrderDiscountTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Percent', [], 'Admin.Global') => OrderDiscountType::DISCOUNT_PERCENT, - $this->translator->trans('Amount', [], 'Admin.Global') => OrderDiscountType::DISCOUNT_AMOUNT, - $this->translator->trans('Free shipping', [], 'Admin.Shipping.Feature') => OrderDiscountType::FREE_SHIPPING, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/OrderStateByIdChoiceProvider.php b/src/Core/Form/ChoiceProvider/OrderStateByIdChoiceProvider.php deleted file mode 100644 index a484aa70..00000000 --- a/src/Core/Form/ChoiceProvider/OrderStateByIdChoiceProvider.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceAttributeProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Order\OrderStateDataProviderInterface; -use PrestaShop\PrestaShop\Core\Util\ColorBrightnessCalculator; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class OrderStateByIdChoiceProvider provides order state choices with ID values. - */ -final class OrderStateByIdChoiceProvider implements FormChoiceProviderInterface, FormChoiceAttributeProviderInterface, ConfigurableFormChoiceProviderInterface -{ - /** - * @var int language ID - */ - private $languageId; - - /** - * @var OrderStateDataProviderInterface - */ - private $orderStateDataProvider; - - /** - * @var ColorBrightnessCalculator - */ - private $colorBrightnessCalculator; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param int $languageId language ID - * @param OrderStateDataProviderInterface $orderStateDataProvider - * @param ColorBrightnessCalculator $colorBrightnessCalculator - * @param TranslatorInterface $translator - */ - public function __construct( - $languageId, - OrderStateDataProviderInterface $orderStateDataProvider, - ColorBrightnessCalculator $colorBrightnessCalculator, - TranslatorInterface $translator - ) { - $this->languageId = $languageId; - $this->orderStateDataProvider = $orderStateDataProvider; - $this->colorBrightnessCalculator = $colorBrightnessCalculator; - $this->translator = $translator; - } - - /** - * Get order state choices. - * - * @param array $options - * - * @return array - */ - public function getChoices(array $options = []) - { - $orderStates = $this->orderStateDataProvider->getOrderStates($this->languageId); - $choices = []; - - foreach ($orderStates as $orderState) { - if ($orderState['deleted'] == 1 && (empty($options['current_state']) || $options['current_state'] != $orderState['id_order_state'])) { - continue; - } - $orderState['name'] .= $orderState['deleted'] == 1 ? ' ' . $this->translator->trans('(deleted)', [], 'Admin.Global') : ''; - $choices[$orderState['name']] = $orderState['id_order_state']; - } - - return $choices; - } - - /** - * Get order state choices attributes. - * - * @return array - */ - public function getChoicesAttributes() - { - $orderStates = $this->orderStateDataProvider->getOrderStates($this->languageId); - $attrs = []; - - foreach ($orderStates as $orderState) { - $orderState['name'] .= $orderState['deleted'] == 1 ? ' ' . $this->translator->trans('(deleted)', [], 'Admin.Global') : ''; - $attrs[$orderState['name']]['data-background-color'] = $orderState['color']; - $attrs[$orderState['name']]['data-is-bright'] = $this->colorBrightnessCalculator->isBright($orderState['color']); - } - - return $attrs; - } -} diff --git a/src/Core/Form/ChoiceProvider/PermissionsChoiceProvider.php b/src/Core/Form/ChoiceProvider/PermissionsChoiceProvider.php deleted file mode 100644 index be6fe8f0..00000000 --- a/src/Core/Form/ChoiceProvider/PermissionsChoiceProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\Permission; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides webservice key permissions choices - */ -final class PermissionsChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('All', [], 'Admin.Global') => 'all', - $this->translator->trans('View (GET)', [], 'Admin.Advparameters.Feature') => Permission::VIEW, - $this->translator->trans('Modify (PUT)', [], 'Admin.Advparameters.Feature') => Permission::MODIFY, - $this->translator->trans('Add (POST)', [], 'Admin.Advparameters.Feature') => Permission::ADD, - $this->translator->trans('Delete (DELETE)', [], 'Admin.Advparameters.Feature') => Permission::DELETE, - $this->translator->trans('Fast view (HEAD)', [], 'Admin.Advparameters.Feature') => Permission::FAST_VIEW, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/PriceReductionTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/PriceReductionTypeChoiceProvider.php deleted file mode 100644 index b1e19988..00000000 --- a/src/Core/Form/ChoiceProvider/PriceReductionTypeChoiceProvider.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides choices for price reduction types - */ -final class PriceReductionTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Amount', [], 'Admin.Global') => Reduction::TYPE_AMOUNT, - $this->translator->trans('Percentage', [], 'Admin.Global') => Reduction::TYPE_PERCENTAGE, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/ProfileChoiceProvider.php b/src/Core/Form/ChoiceProvider/ProfileChoiceProvider.php deleted file mode 100644 index 5dd558f9..00000000 --- a/src/Core/Form/ChoiceProvider/ProfileChoiceProvider.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ProfileChoiceProvider provides employee profile choices. - */ -final class ProfileChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $profiles; - - /** - * @param array $profiles - */ - public function __construct(array $profiles) - { - $this->profiles = $profiles; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - foreach ($this->profiles as $profile) { - $choices[$profile['name']] = $profile['id_profile']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/StatusChoiceProvider.php b/src/Core/Form/ChoiceProvider/StatusChoiceProvider.php deleted file mode 100644 index 8b6fe524..00000000 --- a/src/Core/Form/ChoiceProvider/StatusChoiceProvider.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class StatusChoiceProvider is responsible for providing choices for list statuses filter criteria. - */ -final class StatusChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * StatusChoiceProvider constructor. - * - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Yes', [], 'Admin.Global') => 1, - $this->translator->trans('No', [], 'Admin.Global') => 0, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/TabChoiceProvider.php b/src/Core/Form/ChoiceProvider/TabChoiceProvider.php deleted file mode 100644 index 94c08d6f..00000000 --- a/src/Core/Form/ChoiceProvider/TabChoiceProvider.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class TabChoiceProvider provides Tab choices with name values. - * - * This class is used for choosing Default page when creating employee - */ -final class TabChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var array - */ - private $tabs; - - /** - * @param array $tabs - */ - public function __construct(array $tabs) - { - $this->tabs = $tabs; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - foreach ($this->tabs as $tab) { - if (!empty($tab['children'])) { - $choices[$tab['name']] = []; - - foreach ($tab['children'] as $childTab) { - if ($childTab['name']) { - $choices[$tab['name']][$childTab['name']] = $childTab['id_tab']; - } - } - } else { - $choices[$tab['name']] = $tab['id_tab']; - } - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/TaxAddressTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/TaxAddressTypeChoiceProvider.php deleted file mode 100644 index 11d5b601..00000000 --- a/src/Core/Form/ChoiceProvider/TaxAddressTypeChoiceProvider.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides address type choices - */ -final class TaxAddressTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * Get choices. - * - * @return array - */ - public function getChoices() - { - return [ - $this->translator->trans('Invoice address', [], 'Admin.International.Feature') => 'id_address_invoice', - $this->translator->trans('Delivery address', [], 'Admin.International.Feature') => 'id_address_delivery', - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/TaxInclusionChoiceProvider.php b/src/Core/Form/ChoiceProvider/TaxInclusionChoiceProvider.php deleted file mode 100644 index 483e81a0..00000000 --- a/src/Core/Form/ChoiceProvider/TaxInclusionChoiceProvider.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides choices for tax inclusion - */ -final class TaxInclusionChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Tax included', [], 'Admin.Global') => 1, - $this->translator->trans('Tax excluded', [], 'Admin.Global') => 0, - ]; - } -} diff --git a/src/Core/Form/ChoiceProvider/ThemeByNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/ThemeByNameChoiceProvider.php deleted file mode 100644 index e0bb0522..00000000 --- a/src/Core/Form/ChoiceProvider/ThemeByNameChoiceProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeCollection; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ThemeByNameChoiceProvider provides theme choices with name values. - */ -final class ThemeByNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ThemeCollection collection of themes - */ - private $themeCollection; - - /** - * @param ThemeCollection $themeCollection - */ - public function __construct(ThemeCollection $themeCollection) - { - $this->themeCollection = $themeCollection; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $themeChoices = []; - - /** @var Theme $theme */ - foreach ($this->themeCollection as $theme) { - $themeChoices[$theme->getName()] = $theme->getName(); - } - - return $themeChoices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ThemeByNameWithEmailsChoiceProvider.php b/src/Core/Form/ChoiceProvider/ThemeByNameWithEmailsChoiceProvider.php deleted file mode 100644 index a5a812f7..00000000 --- a/src/Core/Form/ChoiceProvider/ThemeByNameWithEmailsChoiceProvider.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeCollection; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ThemeByNameChoiceProvider provides theme choices with name values, but it - * filters themes which haven't overridden any email templates. - */ -final class ThemeByNameWithEmailsChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ThemeCollection collection of themes - */ - private $themeCollection; - - /** - * @param ThemeCollection $themeCollection - */ - public function __construct(ThemeCollection $themeCollection) - { - $this->themeCollection = $themeCollection; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $themeChoices = []; - - /** @var Theme $theme */ - foreach ($this->themeCollection as $theme) { - $coreMailsFolder = $theme->getDirectory() . '/mails'; - $modulesMailFolder = $theme->getDirectory() . '/modules'; - if (is_dir($coreMailsFolder) || is_dir($modulesMailFolder)) { - $themeChoices[$theme->getName()] = $theme->getName(); - } - } - - return $themeChoices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ThemeChoiceProvider.php b/src/Core/Form/ChoiceProvider/ThemeChoiceProvider.php deleted file mode 100644 index 943b972a..00000000 --- a/src/Core/Form/ChoiceProvider/ThemeChoiceProvider.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ThemeChoiceProvider provides available themes as choices. - */ -final class ThemeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ThemeProviderInterface - */ - private $themeProvider; - - /** - * @param ThemeProviderInterface $themeProvider - */ - public function __construct(ThemeProviderInterface $themeProvider) - { - $this->themeProvider = $themeProvider; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $usedTheme = $this->themeProvider->getCurrentlyUsedTheme(); - $notUsedThemes = $this->themeProvider->getNotUsedThemes(); - - $choices = []; - $choices[$usedTheme->getName()] = $usedTheme->getName(); - - foreach ($notUsedThemes as $theme) { - $choices[$theme->getName()] = $theme->getName(); - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ThemePageLayoutsChoiceProvider.php b/src/Core/Form/ChoiceProvider/ThemePageLayoutsChoiceProvider.php deleted file mode 100644 index c295196d..00000000 --- a/src/Core/Form/ChoiceProvider/ThemePageLayoutsChoiceProvider.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; - -/** - * Class ThemePageLayoutsChoiceProvider proves page layout choices for given theme. - */ -final class ThemePageLayoutsChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var Theme - */ - private $theme; - - /** - * @param Theme $theme - */ - public function __construct(Theme $theme) - { - $this->theme = $theme; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $choices = []; - - foreach ($this->theme->getAvailableLayouts() as $layoutId => $availableLayout) { - $choices[sprintf('%s - %s', $availableLayout['name'], $availableLayout['description'])] = $layoutId; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/ThemeZipChoiceProvider.php b/src/Core/Form/ChoiceProvider/ThemeZipChoiceProvider.php deleted file mode 100644 index c23e4560..00000000 --- a/src/Core/Form/ChoiceProvider/ThemeZipChoiceProvider.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Class ThemeZipChoiceProvider provides choices for uploaded Front Office theme zips. - */ -final class ThemeZipChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - $themeZipsFinder = (new Finder()) - ->in($this->configuration->get('_PS_ALL_THEMES_DIR_')) - ->files() - ->name('*.zip') - ; - - $themeZips = []; - - /** @var SplFileInfo $themeZip */ - foreach ($themeZipsFinder as $themeZip) { - $themeZips[$themeZip->getFilename()] = $themeZip->getFilename(); - } - - return $themeZips; - } -} diff --git a/src/Core/Form/ChoiceProvider/TimezoneByNameChoiceProvider.php b/src/Core/Form/ChoiceProvider/TimezoneByNameChoiceProvider.php deleted file mode 100644 index 46d0c1dc..00000000 --- a/src/Core/Form/ChoiceProvider/TimezoneByNameChoiceProvider.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Entity\Repository\TimezoneRepository; - -/** - * Class TimezoneByNameChoiceProvider provides timezone choices with name values. - */ -final class TimezoneByNameChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TimezoneRepository - */ - private $timezoneRepository; - - /** - * @param TimezoneRepository $timezoneRepository - */ - public function __construct(TimezoneRepository $timezoneRepository) - { - $this->timezoneRepository = $timezoneRepository; - } - - /** - * Get timezone choices. - * - * @return array - */ - public function getChoices() - { - $timezones = $this->timezoneRepository->findAll(); - $choices = []; - - foreach ($timezones as $timezone) { - $choices[$timezone['name']] = $timezone['name']; - } - - return $choices; - } -} diff --git a/src/Core/Form/ChoiceProvider/TranslationTypeChoiceProvider.php b/src/Core/Form/ChoiceProvider/TranslationTypeChoiceProvider.php deleted file mode 100644 index 5d434f18..00000000 --- a/src/Core/Form/ChoiceProvider/TranslationTypeChoiceProvider.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\ChoiceProvider; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class TranslationTypeByNameChoiceProvider provides translation type choices. - */ -final class TranslationTypeChoiceProvider implements FormChoiceProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getChoices() - { - return [ - $this->translator->trans('Back office translations', [], 'Admin.International.Feature') => 'back', - $this->translator->trans('Themes translations', [], 'Admin.International.Feature') => 'themes', - $this->translator->trans('Installed modules translations', [], 'Admin.International.Feature') => 'modules', - $this->translator->trans('Email translations', [], 'Admin.International.Feature') => 'mails', - $this->translator->trans('Other translations', [], 'Admin.International.Feature') => 'others', - ]; - } -} diff --git a/src/Core/Form/ConfigurableFormChoiceProviderInterface.php b/src/Core/Form/ConfigurableFormChoiceProviderInterface.php deleted file mode 100644 index c6e9d0a2..00000000 --- a/src/Core/Form/ConfigurableFormChoiceProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -/** - * Interface for services that provide configurable form choices (e.g. States choices depending on country). - */ -interface ConfigurableFormChoiceProviderInterface -{ - /** - * @param array $options - * - * @return array - */ - public function getChoices(array $options); -} diff --git a/src/Core/Form/DTO/ShopRestriction.php b/src/Core/Form/DTO/ShopRestriction.php deleted file mode 100644 index a5f40e64..00000000 --- a/src/Core/Form/DTO/ShopRestriction.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\DTO; - -/** - * Shop restriction object holds the shop ids for which restriction is being applied and the fields which are impacted - * by the certain shop restriction. - */ -class ShopRestriction -{ - /** - * @var int[] - */ - private $shopIds; - - /** - * @var ShopRestrictionField[] - */ - private $shopRestrictionFields; - - /** - * @param int[] $shopIds - * @param ShopRestrictionField[] $shopRestrictionFields - */ - public function __construct(array $shopIds, array $shopRestrictionFields) - { - $this->shopIds = $shopIds; - $this->shopRestrictionFields = $shopRestrictionFields; - } - - /** - * @return int[] - */ - public function getShopIds() - { - return $this->shopIds; - } - - /** - * @return ShopRestrictionField[] - */ - public function getShopRestrictionFields() - { - return $this->shopRestrictionFields; - } -} diff --git a/src/Core/Form/DTO/ShopRestrictionField.php b/src/Core/Form/DTO/ShopRestrictionField.php deleted file mode 100644 index 091b3b54..00000000 --- a/src/Core/Form/DTO/ShopRestrictionField.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\DTO; - -/** - * Holds the field name for which the multi-store restriction checkbox has been checked or unchecked and the status if it - * was restricted or not. - */ -class ShopRestrictionField -{ - /** - * @var string - */ - private $fieldName; - - /** - * @var bool - */ - private $isRestrictedToContextShop; - - /** - * @param string $fieldName - * @param bool $isRestrictedToContextShop - */ - public function __construct($fieldName, $isRestrictedToContextShop) - { - $this->fieldName = $fieldName; - $this->isRestrictedToContextShop = $isRestrictedToContextShop; - } - - /** - * @return string - */ - public function getFieldName() - { - return $this->fieldName; - } - - /** - * @return bool - */ - public function isRestrictedToContextShop() - { - return $this->isRestrictedToContextShop; - } -} diff --git a/src/Core/Form/FormChoiceAttributeProviderInterface.php b/src/Core/Form/FormChoiceAttributeProviderInterface.php deleted file mode 100644 index 6bc2eafe..00000000 --- a/src/Core/Form/FormChoiceAttributeProviderInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -/** - * Interface FormChoiceProviderInterface defines contract for choice attribute providers. - */ -interface FormChoiceAttributeProviderInterface -{ - /** - * Get choices attributes. - * return [{choice_value} => [...$attributes]] - * - * @return array - */ - public function getChoicesAttributes(); -} diff --git a/src/Core/Form/FormChoiceProviderInterface.php b/src/Core/Form/FormChoiceProviderInterface.php deleted file mode 100644 index 237ed8ac..00000000 --- a/src/Core/Form/FormChoiceProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -/** - * Interface FormChoiceProviderInterface defines contract for choice providers. - */ -interface FormChoiceProviderInterface -{ - /** - * Get choices. - * - * @return array - */ - public function getChoices(); -} diff --git a/src/Core/Form/FormDataProviderInterface.php b/src/Core/Form/FormDataProviderInterface.php deleted file mode 100644 index ee6c9e6f..00000000 --- a/src/Core/Form/FormDataProviderInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -/** - * Symfony forms data provider. - */ -interface FormDataProviderInterface -{ - /** - * @return array the form data as an associative array - */ - public function getData(); - - /** - * Persists form Data in Database and Filesystem. - * - * @param array $data - * - * @return array $errors if data can't persisted an array of errors messages - * - * @throws UndefinedOptionsException - */ - public function setData(array $data); -} diff --git a/src/Core/Form/FormHandler.php b/src/Core/Form/FormHandler.php deleted file mode 100644 index c708c354..00000000 --- a/src/Core/Form/FormHandler.php +++ /dev/null @@ -1,137 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -use Exception; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; - -/** - * Complete implementation of FormHandlerInterface. - */ -class FormHandler implements FormHandlerInterface -{ - /** - * @var FormBuilderInterface the form builder - */ - protected $formBuilder; - - /** - * @var FormDataProviderInterface the form data provider - */ - protected $formDataProvider; - - /** - * @var HookDispatcherInterface the event dispatcher - */ - protected $hookDispatcher; - - /** - * @var string the hook name - */ - protected $hookName; - - /** - * @var array the list of Form Types - */ - protected $formTypes; - - /** - * @var string the form name - */ - protected $formName; - - /** - * FormHandler constructor. - * - * @param FormBuilderInterface $formBuilder - * @param HookDispatcherInterface $hookDispatcher - * @param FormDataProviderInterface $formDataProvider - * @param array $formTypes - * @param string $hookName - * @param string $formName - */ - public function __construct( - FormBuilderInterface $formBuilder, - HookDispatcherInterface $hookDispatcher, - FormDataProviderInterface $formDataProvider, - array $formTypes, - $hookName, - $formName = 'form' - ) { - $this->formName = $formName; - $this->formBuilder = $formBuilder->getFormFactory()->createNamedBuilder($formName); - $this->hookDispatcher = $hookDispatcher; - $this->formDataProvider = $formDataProvider; - $this->formTypes = $formTypes; - $this->hookName = $hookName; - } - - /** - * {@inheritdoc} - * - * @throws Exception - */ - public function getForm() - { - foreach ($this->formTypes as $formName => $formType) { - $this->formBuilder->add($formName, $formType); - } - - $this->formBuilder->setData($this->formDataProvider->getData()); - $this->hookDispatcher->dispatchWithParameters( - "action{$this->hookName}Form", - [ - 'form_builder' => &$this->formBuilder, - ] - ); - - return $this->formBuilder->getForm(); - } - - /** - * {@inheritdoc} - * - * @throws Exception - * @throws UndefinedOptionsException - */ - public function save(array $data) - { - $errors = $this->formDataProvider->setData($data); - - $this->hookDispatcher->dispatchWithParameters( - "action{$this->hookName}Save", - [ - 'errors' => &$errors, - 'form_data' => &$data, - ] - ); - - return $errors; - } -} diff --git a/src/Core/Form/FormHandlerInterface.php b/src/Core/Form/FormHandlerInterface.php deleted file mode 100644 index 77e284e3..00000000 --- a/src/Core/Form/FormHandlerInterface.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -use Symfony\Component\Form\FormInterface; - -/** - * Manage Symfony forms outside the controllers. - */ -interface FormHandlerInterface -{ - /** - * @return FormInterface - */ - public function getForm(); - - /** - * Describe what need to be done on saving the form: mostly persists the data - * using a form data provider, but it's also the right place to dispatch events/log something. - * - * @param array $data data retrieved from form that need to be persisted in database - * - * @throws \Exception if the data can't be handled - * - * @return array $errors if data can't persisted an array of errors messages - */ - public function save(array $data); -} diff --git a/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php b/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php deleted file mode 100644 index d1db735d..00000000 --- a/src/Core/Form/IdentifiableObject/Builder/FormBuilder.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\Form\FormInterface; - -/** - * Creates new forms for identifiable objects. - */ -final class FormBuilder implements FormBuilderInterface -{ - /** - * @var FormFactoryInterface - */ - private $formFactory; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var FormDataProviderInterface - */ - private $dataProvider; - - /** - * @var string - */ - private $formType; - - /** - * @param FormFactoryInterface $formFactory - * @param HookDispatcherInterface $hookDispatcher - * @param FormDataProviderInterface $dataProvider - * @param string $formType - */ - public function __construct( - FormFactoryInterface $formFactory, - HookDispatcherInterface $hookDispatcher, - FormDataProviderInterface $dataProvider, - $formType - ) { - $this->formFactory = $formFactory; - $this->hookDispatcher = $hookDispatcher; - $this->dataProvider = $dataProvider; - $this->formType = $formType; - } - - /** - * {@inheritdoc} - */ - public function getForm(array $data = [], array $options = []) - { - if (is_array($defaultData = $this->dataProvider->getDefaultData())) { - $data = array_merge($defaultData, $data); - } - - return $this->buildForm( - $this->formType, - $data, - null, - $options - ); - } - - /** - * {@inheritdoc} - */ - public function getFormFor($id, array $data = [], array $options = []) - { - $data = array_merge($this->dataProvider->getData($id), $data); - - return $this->buildForm( - $this->formType, - $data, - $id, - $options - ); - } - - /** - * @param string $formType - * @param array $data - * @param int|null $id - * @param array $options - * - * @return FormInterface - */ - private function buildForm($formType, $data, $id = null, array $options = []) - { - $formBuilder = $this->formFactory->createBuilder($formType, $data, $options); - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($formBuilder->getName()) . 'FormBuilderModifier', [ - 'form_builder' => $formBuilder, - 'data' => &$data, - 'id' => $id, - ]); - - return $formBuilder->getForm(); - } -} diff --git a/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactory.php b/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactory.php deleted file mode 100644 index 26bcb8fe..00000000 --- a/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactory.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\Form\FormFactoryInterface; - -/** - * Creates new form builders which are used to get forms for identifiable objects. - */ -final class FormBuilderFactory implements FormBuilderFactoryInterface -{ - /** - * @var FormFactoryInterface - */ - private $formFactory; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @param FormFactoryInterface $formFactory - * @param HookDispatcherInterface $hookDispatcher - */ - public function __construct( - FormFactoryInterface $formFactory, - HookDispatcherInterface $hookDispatcher - ) { - $this->formFactory = $formFactory; - $this->hookDispatcher = $hookDispatcher; - } - - /** - * {@inheritdoc} - */ - public function create($formType, FormDataProviderInterface $dataProvider) - { - return new FormBuilder( - $this->formFactory, - $this->hookDispatcher, - $dataProvider, - $formType - ); - } -} diff --git a/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactoryInterface.php b/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactoryInterface.php deleted file mode 100644 index 07a2d8ed..00000000 --- a/src/Core/Form/IdentifiableObject/Builder/FormBuilderFactoryInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FormDataProviderInterface; - -/** - * Defines interface for creating form builders. - */ -interface FormBuilderFactoryInterface -{ - /** - * @param string $formType - * @param FormDataProviderInterface $dataProvider - * - * @return FormBuilderInterface - */ - public function create($formType, FormDataProviderInterface $dataProvider); -} diff --git a/src/Core/Form/IdentifiableObject/Builder/FormBuilderInterface.php b/src/Core/Form/IdentifiableObject/Builder/FormBuilderInterface.php deleted file mode 100644 index c0a51865..00000000 --- a/src/Core/Form/IdentifiableObject/Builder/FormBuilderInterface.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder; - -use Symfony\Component\Form\FormInterface; - -/** - * Defines contract for identifiable object form factories. - */ -interface FormBuilderInterface -{ - /** - * Create new form. - * - * @param array $data - * @param array $options - * - * @return FormInterface - */ - public function getForm(array $data = [], array $options = []); - - /** - * Create new form for given object. - * - * @param int $id - * @param array $data - * @param array $options - * - * @return FormInterface - */ - public function getFormFor($id, array $data = [], array $options = []); -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/AddressFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/AddressFormDataHandler.php deleted file mode 100644 index d3ca7263..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/AddressFormDataHandler.php +++ /dev/null @@ -1,175 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider; -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; - -/** - * Handles submitted address form data - */ -final class AddressFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var CustomerDataProvider - */ - private $customerDataProvider; - - /** - * @param CommandBusInterface $commandBus - * @param CustomerDataProvider $customerDataProvider - */ - public function __construct(CommandBusInterface $commandBus, CustomerDataProvider $customerDataProvider) - { - $this->commandBus = $commandBus; - $this->customerDataProvider = $customerDataProvider; - } - - /** - * {@inheritdoc] - * - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function create(array $data) - { - if (!empty($data['id_customer'])) { - $customerId = $data['id_customer']; - } else { - $customerId = $this->customerDataProvider->getIdByEmail($data['customer_email']); - } - - $addAddressCommand = new AddCustomerAddressCommand( - $customerId, - $data['alias'], - $data['first_name'], - $data['last_name'], - $data['address1'], - $data['city'], - (int) $data['id_country'], - $data['postcode'], - $data['dni'], - $data['company'], - $data['vat_number'], - $data['address2'], - (int) $data['id_state'], - $data['phone'], - $data['phone_mobile'] ?? null, - $data['other'] - ); - - /** @var AddressId $addressId */ - $addressId = $this->commandBus->handle($addAddressCommand); - - return $addressId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws AddressConstraintException - * @throws CountryConstraintException - * @throws StateConstraintException - */ - public function update($addressId, array $data) - { - $editAddressCommand = new EditCustomerAddressCommand($addressId); - - if (isset($data['alias'])) { - $editAddressCommand->setAddressAlias($data['alias']); - } - - if (isset($data['first_name'])) { - $editAddressCommand->setFirstName($data['first_name']); - } - - if (isset($data['last_name'])) { - $editAddressCommand->setLastName($data['last_name']); - } - - if (isset($data['address1'])) { - $editAddressCommand->setAddress($data['address1']); - } - - if (isset($data['city'])) { - $editAddressCommand->setCity($data['city']); - } - - if (isset($data['id_country'])) { - $editAddressCommand->setCountryId((int) $data['id_country']); - } - - if (isset($data['postcode'])) { - $editAddressCommand->setPostCode($data['postcode']); - } - - if (isset($data['dni'])) { - $editAddressCommand->setDni($data['dni']); - } - - if (isset($data['company'])) { - $editAddressCommand->setCompany($data['company']); - } - - if (isset($data['vat_number'])) { - $editAddressCommand->setVatNumber($data['vat_number']); - } - - if (isset($data['address2'])) { - $editAddressCommand->setAddress2($data['address2']); - } - - if (isset($data['id_state'])) { - $editAddressCommand->setStateId((int) $data['id_state']); - } - - if (isset($data['phone'])) { - $editAddressCommand->setHomePhone($data['phone']); - } - - if (isset($data['phone_mobile'])) { - $editAddressCommand->setMobilePhone($data['phone_mobile']); - } - - if (isset($data['other'])) { - $editAddressCommand->setOther($data['other']); - } - - $this->commandBus->handle($editAddressCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/AttachmentFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/AttachmentFormDataHandler.php deleted file mode 100644 index 91efffab..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/AttachmentFormDataHandler.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\AddAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\EditAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\ValueObject\AttachmentId; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Creates/updates attachment from data submitted in category form - */ -final class AttachmentFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - $command = $this->createAddAttachmentCommand($data); - - /** @var AttachmentId $attachmentId */ - $attachmentId = $this->commandBus->handle($command); - - return $attachmentId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws AttachmentConstraintException - */ - public function update($attachmentId, array $data) - { - $attachmentIdObject = new AttachmentId((int) $attachmentId); - - $command = $this->createEditAttachmentCommand($attachmentIdObject, $data); - - $this->commandBus->handle($command); - } - - /** - * Creates edit attachment command from - * - * @param $attachmentId - * @param array $data - * - * @return EditAttachmentCommand - */ - private function createEditAttachmentCommand( - AttachmentId $attachmentId, - array $data - ): EditAttachmentCommand { - /** @var UploadedFile|null $fileObject */ - $fileObject = $data['file']; - - $command = new EditAttachmentCommand($attachmentId); - $command->setLocalizedNames($data['name']); - $command->setLocalizedDescriptions($data['file_description']); - - if ($fileObject instanceof UploadedFile) { - $command->setFileInfo( - $fileObject->getPathname(), - $fileObject->getMimeType(), - $fileObject->getClientOriginalName(), - $fileObject->getSize() - ); - } - - return $command; - } - - /** - * @param array $data - * - * @return AddAttachmentCommand - */ - private function createAddAttachmentCommand(array $data) - { - $addAttachmentCommand = new AddAttachmentCommand( - $data['name'], - $data['file_description'] - ); - - if (isset($data['file']) && $data['file'] !== null) { - /** @var UploadedFile $file */ - $file = $data['file']; - - $addAttachmentCommand->setFileInformation( - $file->getPathname(), - $file->getSize(), - $file->getMimeType(), - $file->getClientOriginalName() - ); - } - - return $addAttachmentCommand; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CancellationFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CancellationFormDataHandler.php deleted file mode 100644 index cbff315b..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CancellationFormDataHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\CancelOrderProductCommand; - -/** - * Class CancellationFormDataHandler - */ -final class CancellationFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $commandBus - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $commandBus, CommandBusInterface $queryBus) - { - $this->commandBus = $commandBus; - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - return; - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $cancelledProducts = []; - foreach ($data['products'] as $product) { - if (isset($data['selected_' . $product->getOrderDetailId()]) && $data['selected_' . $product->getOrderDetailId()]) { - $cancelledProducts[$product->getOrderDetailId()] = $data['quantity_' . $product->getOrderDetailId()] ?? 0; - } - } - - $command = new CancelOrderProductCommand( - $cancelledProducts, - $id - ); - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CartAddressFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CartAddressFormDataHandler.php deleted file mode 100644 index a156a75d..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CartAddressFormDataHandler.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCartAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAddressTypeException; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; - -class CartAddressFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - // Not used for creation, only edition - } - - /** - * {@inheritdoc} - * - * @throws CartConstraintException - * @throws CountryConstraintException - * @throws StateConstraintException - * @throws InvalidAddressTypeException - */ - public function update($cartId, array $data) - { - $editAddressCommand = new EditCartAddressCommand($cartId, $data['address_type']); - - if (isset($data['alias'])) { - $editAddressCommand->setAddressAlias($data['alias']); - } - - if (isset($data['first_name'])) { - $editAddressCommand->setFirstName($data['first_name']); - } - - if (isset($data['last_name'])) { - $editAddressCommand->setLastName($data['last_name']); - } - - if (isset($data['address1'])) { - $editAddressCommand->setAddress($data['address1']); - } - - if (isset($data['city'])) { - $editAddressCommand->setCity($data['city']); - } - - if (isset($data['id_country'])) { - $editAddressCommand->setCountryId((int) $data['id_country']); - } - - if (isset($data['postcode'])) { - $editAddressCommand->setPostCode($data['postcode']); - } - - if (isset($data['dni'])) { - $editAddressCommand->setDni($data['dni']); - } - - if (isset($data['company'])) { - $editAddressCommand->setCompany($data['company']); - } - - if (isset($data['vat_number'])) { - $editAddressCommand->setVatNumber($data['vat_number']); - } - - if (isset($data['address2'])) { - $editAddressCommand->setAddress2($data['address2']); - } - - if (isset($data['id_state'])) { - $editAddressCommand->setStateId((int) $data['id_state']); - } - - if (isset($data['phone'])) { - $editAddressCommand->setHomePhone($data['phone']); - } - - if (isset($data['phone_mobile'])) { - $editAddressCommand->setMobilePhone($data['phone_mobile']); - } - - if (isset($data['other'])) { - $editAddressCommand->setOther($data['other']); - } - - $this->commandBus->handle($editAddressCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CatalogPriceRuleFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CatalogPriceRuleFormDataHandler.php deleted file mode 100644 index 47e2f98b..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CatalogPriceRuleFormDataHandler.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\AddCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\EditCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\ValueObject\CatalogPriceRuleId; - -/** - * Handles submitted catalog price rule form data - */ -final class CatalogPriceRuleFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var bool - */ - private $isMultishopEnabled; - - /** - * @var int - */ - private $contextShopId; - - /** - * @param CommandBusInterface $commandBus - * @param bool $isMultishopEnabled - * @param int $contextShopId - */ - public function __construct( - CommandBusInterface $commandBus, - bool $isMultishopEnabled, - int $contextShopId - ) { - $this->commandBus = $commandBus; - $this->contextShopId = $contextShopId; - $this->isMultishopEnabled = $isMultishopEnabled; - } - - /** - * {@inheritdoc} - */ - public function create(array $data): int - { - if (!$this->isMultishopEnabled) { - $data['id_shop'] = $this->contextShopId; - } - - if ($data['leave_initial_price']) { - $data['price'] = -1; - } - - $command = new AddCatalogPriceRuleCommand( - $data['name'], - (int) $data['id_currency'], - (int) $data['id_country'], - (int) $data['id_group'], - (int) $data['from_quantity'], - $data['reduction']['type'], - (float) $data['reduction']['value'], - (int) $data['id_shop'], - (bool) $data['include_tax'], - (float) $data['price'] - ); - - if ($data['date_range']['from']) { - $command->setDateTimeFrom($data['date_range']['from']); - } - - if ($data['date_range']['to']) { - $command->setDateTimeTo($data['date_range']['to']); - } - - /** @var CatalogPriceRuleId $catalogPriceRuleId */ - $catalogPriceRuleId = $this->commandBus->handle($command); - - return $catalogPriceRuleId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws CatalogPriceRuleException - */ - public function update($catalogPriceRuleId, array $data) - { - $editCatalogPriceRuleCommand = new EditCatalogPriceRuleCommand((int) $catalogPriceRuleId); - $this->fillCommandWithData($editCatalogPriceRuleCommand, $data); - - $this->commandBus->handle($editCatalogPriceRuleCommand); - } - - /** - * @param EditCatalogPriceRuleCommand $command - * @param array $data - * - * @throws CatalogPriceRuleException - */ - private function fillCommandWithData(EditCatalogPriceRuleCommand $command, array $data) - { - if ($data['leave_initial_price']) { - $data['price'] = -1; - } - - $command->setName($data['name']); - $command->setShopId((int) $data['id_shop']); - $command->setCurrencyId((int) $data['id_currency']); - $command->setCountryId((int) $data['id_country']); - $command->setGroupId((int) $data['id_group']); - $command->setFromQuantity((int) $data['from_quantity']); - $command->setPrice((float) $data['price']); - $command->setIncludeTax((bool) $data['include_tax']); - $command->setReduction($data['reduction']['type'], (float) $data['reduction']['value']); - - if ($data['date_range']['from']) { - $command->setDateTimeFrom($data['date_range']['from']); - } - - if ($data['date_range']['to']) { - $command->setDateTimeTo($data['date_range']['to']); - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CategoryFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CategoryFormDataHandler.php deleted file mode 100644 index 38b4d182..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CategoryFormDataHandler.php +++ /dev/null @@ -1,201 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Creates/updates category from data submitted in category form - */ -final class CategoryFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var ImageUploaderInterface - */ - private $categoryCoverUploader; - - /** - * @var ImageUploaderInterface - */ - private $categoryThumbnailUploader; - - /** - * @var ImageUploaderInterface - */ - private $categoryMenuThumbnailUploader; - - /** - * @param CommandBusInterface $commandBus - * @param ImageUploaderInterface $categoryCoverUploader - * @param ImageUploaderInterface $categoryThumbnailUploader - * @param ImageUploaderInterface $categoryMenuThumbnailUploader - */ - public function __construct( - CommandBusInterface $commandBus, - ImageUploaderInterface $categoryCoverUploader, - ImageUploaderInterface $categoryThumbnailUploader, - ImageUploaderInterface $categoryMenuThumbnailUploader - ) { - $this->commandBus = $commandBus; - $this->categoryCoverUploader = $categoryCoverUploader; - $this->categoryThumbnailUploader = $categoryThumbnailUploader; - $this->categoryMenuThumbnailUploader = $categoryMenuThumbnailUploader; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - $command = $this->createAddCategoryCommand($data); - - /** @var CategoryId $categoryId */ - $categoryId = $this->commandBus->handle($command); - - $this->uploadImages( - $categoryId, - $data['cover_image'], - $data['thumbnail_image'], - $data['menu_thumbnail_images'] - ); - - return $categoryId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($categoryId, array $data) - { - $command = $this->createEditCategoryCommand($categoryId, $data); - - $this->commandBus->handle($command); - - $categoryId = new CategoryId((int) $categoryId); - - $this->uploadImages( - $categoryId, - $data['cover_image'], - $data['thumbnail_image'], - $data['menu_thumbnail_images'] - ); - } - - /** - * Creates add category command from form data - * - * @param array $data - * - * @return AddCategoryCommand - */ - private function createAddCategoryCommand(array $data) - { - $command = new AddCategoryCommand( - $data['name'], - $data['link_rewrite'], - (bool) $data['active'], - (int) $data['id_parent'] - ); - - $command->setLocalizedDescriptions($data['description']); - $command->setLocalizedMetaTitles($data['meta_title']); - $command->setLocalizedMetaDescriptions($data['meta_description']); - $command->setLocalizedMetaKeywords($data['meta_keyword']); - $command->setAssociatedGroupIds($data['group_association']); - - if (isset($data['shop_association'])) { - $command->setAssociatedShopIds($data['shop_association']); - } - - return $command; - } - - /** - * Creates edit category command from - * - * @param int $categoryId - * @param array $data - * - * @return EditCategoryCommand - */ - private function createEditCategoryCommand($categoryId, array $data) - { - $command = new EditCategoryCommand($categoryId); - $command->setIsActive($data['active']); - $command->setLocalizedLinkRewrites($data['link_rewrite']); - $command->setLocalizedNames($data['name']); - $command->setParentCategoryId($data['id_parent']); - $command->setLocalizedDescriptions($data['description']); - $command->setLocalizedMetaTitles($data['meta_title']); - $command->setLocalizedMetaDescriptions($data['meta_description']); - $command->setLocalizedMetaKeywords($data['meta_keyword']); - $command->setAssociatedGroupIds($data['group_association']); - - if (isset($data['shop_association'])) { - $command->setAssociatedShopIds($data['shop_association']); - } - - return $command; - } - - /** - * @param CategoryId $categoryId - * @param UploadedFile $coverImage - * @param UploadedFile $thumbnailImage - * @param UploadedFile[] $menuThumbnailImages - */ - private function uploadImages( - CategoryId $categoryId, - UploadedFile $coverImage = null, - UploadedFile $thumbnailImage = null, - array $menuThumbnailImages = [] - ) { - if (null !== $coverImage) { - $this->categoryCoverUploader->upload($categoryId->getValue(), $coverImage); - } - - if (null !== $thumbnailImage) { - $this->categoryThumbnailUploader->upload($categoryId->getValue(), $thumbnailImage); - } - - if (!empty($menuThumbnailImages)) { - foreach ($menuThumbnailImages as $menuThumbnail) { - $this->categoryMenuThumbnailUploader->upload($categoryId->getValue(), $menuThumbnail); - } - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CmsPageCategoryFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CmsPageCategoryFormDataHandler.php deleted file mode 100644 index 4cfa04b2..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CmsPageCategoryFormDataHandler.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\AddCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\EditCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * Class CmsPageCategoryFormDataHandler is responsible for creating and updating cms page category form data. - */ -final class CmsPageCategoryFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function create(array $data) - { - $addCmsPageCategoryCommand = new AddCmsPageCategoryCommand( - $data['name'], - $data['friendly_url'], - (int) $data['parent_category'], - $data['is_displayed'] - ); - - $addCmsPageCategoryCommand - ->setLocalisedDescription($data['description']) - ->setLocalisedMetaDescription($data['meta_description']) - ->setLocalisedMetaKeywords($data['meta_keywords']) - ->setLocalisedMetaTitle($data['meta_title']) - ->setShopAssociation(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - /** @var CmsPageCategoryId $result */ - $result = $this->commandBus->handle($addCmsPageCategoryCommand); - - return $result->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function update($id, array $data) - { - $editCmsPageCategoryCommand = new EditCmsPageCategoryCommand((int) $id); - - $editCmsPageCategoryCommand - ->setLocalisedName($data['name']) - ->setLocalisedFriendlyUrl($data['friendly_url']) - ->setParentId((int) $data['parent_category']) - ->setIsDisplayed($data['is_displayed']) - ->setLocalisedDescription($data['description']) - ->setLocalisedMetaDescription($data['meta_description']) - ->setLocalisedMetaKeywords($data['meta_keywords']) - ->setLocalisedMetaTitle($data['meta_title']) - ->setShopAssociation(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - $this->commandBus->handle($editCmsPageCategoryCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CmsPageFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CmsPageFormDataHandler.php deleted file mode 100644 index d7bd7380..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CmsPageFormDataHandler.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\AddCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\EditCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\ValueObject\CmsPageId; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; - -/** - * {@inheritdoc} - */ -final class CmsPageFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * Create object from form data. - * - * @param array $data - * - * @return int - * - * @throws CmsPageCategoryException - */ - public function create(array $data) - { - /** - * @var CmsPageId - */ - $cmsPageId = $this->commandBus->handle(new AddCmsPageCommand( - (int) $data['page_category_id'], - $data['title'], - $data['meta_title'], - $data['meta_description'], - $data['meta_keyword'], - $data['friendly_url'], - $data['content'], - $data['is_indexed_for_search'], - $data['is_displayed'], - is_array($data['shop_association']) ? $data['shop_association'] : [] - )); - - return $cmsPageId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws CmsPageException - * @throws CmsPageCategoryException - */ - public function update($cmsPageId, array $data) - { - $editCmsPageCommand = new EditCmsPageCommand((int) $cmsPageId); - $this->fillCommandWithData($editCmsPageCommand, $data); - - $this->commandBus->handle($editCmsPageCommand); - } - - /** - * @param EditCmsPageCommand $command - * @param array $data - * - * @throws CmsPageCategoryException - */ - private function fillCommandWithData(EditCmsPageCommand $command, array $data) - { - $command->setCmsPageCategoryId((int) $data['page_category_id']); - $command->setLocalizedTitle($data['title']); - $command->setLocalizedMetaTitle($data['meta_title']); - $command->setLocalizedMetaDescription($data['meta_description']); - $command->setLocalizedMetaKeyword($data['meta_keyword']); - $command->setLocalizedFriendlyUrl($data['friendly_url']); - $command->setLocalizedContent($data['content']); - $command->setIsIndexedForSearch($data['is_indexed_for_search']); - $command->setIsDisplayed($data['is_displayed']); - $command->setShopAssociation($data['shop_association']); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/ContactFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/ContactFormDataHandler.php deleted file mode 100644 index ce84f18d..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/ContactFormDataHandler.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\AddContactCommand; -use PrestaShop\PrestaShop\Core\Domain\Contact\Command\EditContactCommand; -use PrestaShop\PrestaShop\Core\Domain\Contact\ValueObject\ContactId; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; - -/** - * Class ContactFormDataHandler is responsible for handling create and update of contact form. - */ -final class ContactFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - * - * @throws DomainException - */ - public function create(array $data) - { - $addContactCommand = (new AddContactCommand($data['title'], $data['is_messages_saving_enabled'])) - ->setLocalisedDescription($data['description']) - ->setShopAssociation(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - if ($data['email']) { - $addContactCommand->setEmail($data['email']); - } - - /** @var ContactId $result */ - $result = $this->commandBus->handle($addContactCommand); - - return $result->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws DomainException - */ - public function update($contactId, array $data) - { - $editContactCommand = (new EditContactCommand((int) $contactId)) - ->setLocalisedTitles($data['title']) - ->setIsMessagesSavingEnabled($data['is_messages_saving_enabled']) - ->setLocalisedDescription($data['description']) - ->setShopAssociation(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - if ($data['email']) { - $editContactCommand->setEmail($data['email']); - } - - $this->commandBus->handle($editContactCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CurrencyFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CurrencyFormDataHandler.php deleted file mode 100644 index 249df58e..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CurrencyFormDataHandler.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerInterface; -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddUnofficialCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditUnofficialCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\CurrencyId; - -/** - * Class CurrencyFormDataHandler - */ -final class CurrencyFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var CacheClearerInterface[] - */ - private $cacheClearerCollection; - - /** - * @param CommandBusInterface $commandBus - * @param CacheClearerInterface[] $cacheClearerCollection - */ - public function __construct( - CommandBusInterface $commandBus, - array $cacheClearerCollection - ) { - $this->commandBus = $commandBus; - $this->cacheClearerCollection = $cacheClearerCollection; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - if ($data['unofficial']) { - $command = new AddUnofficialCurrencyCommand( - $data['iso_code'], - (float) $data['exchange_rate'], - $data['active'] - ); - } else { - $command = new AddCurrencyCommand( - $data['iso_code'], - (float) $data['exchange_rate'], - $data['active'] - ); - } - - $command - ->setPrecision((int) $data['precision']) - ->setLocalizedNames($data['names']) - ->setLocalizedSymbols($data['symbols']) - ->setLocalizedTransformations($data['transformations']) - ->setShopIds(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - /** @var CurrencyId $currencyId */ - $currencyId = $this->commandBus->handle($command); - $this->clearCache(); - - return $currencyId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - if ($data['unofficial']) { - $command = new EditUnofficialCurrencyCommand((int) $id); - $command - ->setIsoCode($data['iso_code']) - ; - } else { - $command = new EditCurrencyCommand((int) $id); - } - - $command - ->setLocalizedNames($data['names']) - ->setLocalizedSymbols($data['symbols']) - ->setLocalizedTransformations($data['transformations']) - ->setExchangeRate((float) $data['exchange_rate']) - ->setPrecision((int) $data['precision']) - ->setIsEnabled($data['active']) - ->setShopIds(is_array($data['shop_association']) ? $data['shop_association'] : []) - ; - - $this->commandBus->handle($command); - $this->clearCache(); - } - - /** - * Clear the cache provided - */ - private function clearCache() - { - foreach ($this->cacheClearerCollection as $cacheClearer) { - $cacheClearer->clear(); - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/CustomerFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/CustomerFormDataHandler.php deleted file mode 100644 index 268c989c..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/CustomerFormDataHandler.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\AddCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\EditCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Birthday; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerId; - -/** - * Saves or updates customer data submitted in form - */ -final class CustomerFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var bool - */ - private $isB2bFeatureEnabled; - - /** - * @param CommandBusInterface $bus - * @param int $contextShopId - * @param bool $isB2bFeatureEnabled - */ - public function __construct( - CommandBusInterface $bus, - $contextShopId, - $isB2bFeatureEnabled - ) { - $this->bus = $bus; - $this->contextShopId = $contextShopId; - $this->isB2bFeatureEnabled = $isB2bFeatureEnabled; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - $command = $this->buildCustomerAddCommandFromFormData($data); - - /** @var CustomerId $customerId */ - $customerId = $this->bus->handle($command); - - return $customerId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($customerId, array $data) - { - $command = $this->buildCustomerEditCommand($customerId, $data); - - $this->bus->handle($command); - } - - /** - * @param array $data - * - * @return AddCustomerCommand - */ - private function buildCustomerAddCommandFromFormData(array $data) - { - $groupIds = array_map(function ($groupId) { - return (int) $groupId; - }, $data['group_ids']); - - $command = new AddCustomerCommand( - $data['first_name'], - $data['last_name'], - $data['email'], - $data['password'], - (int) $data['default_group_id'], - $groupIds, - $this->contextShopId, - (int) $data['gender_id'], - (bool) $data['is_enabled'], - (bool) $data['is_partner_offers_subscribed'], - $data['birthday'] ?: Birthday::EMPTY_BIRTHDAY - ); - - if (!$this->isB2bFeatureEnabled) { - return $command; - } - - $command - ->setCompanyName((string) $data['company_name']) - ->setSiretCode((string) $data['siret_code']) - ->setApeCode((string) $data['ape_code']) - ->setWebsite((string) $data['website']) - ->setAllowedOutstandingAmount((float) $data['allowed_outstanding_amount']) - ->setMaxPaymentDays((int) $data['max_payment_days']) - ->setRiskId((int) $data['risk_id']) - ; - - return $command; - } - - /** - * @param int $customerId - * @param array $data - * - * @return EditCustomerCommand - */ - private function buildCustomerEditCommand($customerId, array $data) - { - $groupIds = array_map(function ($groupId) { - return (int) $groupId; - }, $data['group_ids']); - - $command = (new EditCustomerCommand($customerId)) - ->setGenderId($data['gender_id']) - ->setEmail($data['email']) - ->setFirstName($data['first_name']) - ->setLastName($data['last_name']) - ->setIsEnabled($data['is_enabled']) - ->setIsPartnerOffersSubscribed($data['is_partner_offers_subscribed']) - ->setDefaultGroupId((int) $data['default_group_id']) - ->setGroupIds($groupIds) - ->setBirthday($data['birthday'] ?: Birthday::EMPTY_BIRTHDAY) - ; - - if (null !== $data['password']) { - $command->setPassword($data['password']); - } - - if ($this->isB2bFeatureEnabled) { - $command - ->setCompanyName((string) $data['company_name']) - ->setSiretCode((string) $data['siret_code']) - ->setApeCode((string) $data['ape_code']) - ->setWebsite((string) $data['website']) - ->setAllowedOutstandingAmount((float) $data['allowed_outstanding_amount']) - ->setMaxPaymentDays((int) $data['max_payment_days']) - ->setRiskId((int) $data['risk_id']) - ; - } - - return $command; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/EmployeeFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/EmployeeFormDataHandler.php deleted file mode 100644 index 42143d5c..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/EmployeeFormDataHandler.php +++ /dev/null @@ -1,197 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Crypto\Hashing; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\AddEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\EditEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\EmployeeId; -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Employee\Access\EmployeeFormAccessCheckerInterface; -use PrestaShop\PrestaShop\Core\Employee\EmployeeDataProviderInterface; - -/** - * Handles submitted employee form's data. - */ -final class EmployeeFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @var array - */ - private $defaultShopAssociation; - - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @var EmployeeFormAccessCheckerInterface - */ - private $employeeFormAccessChecker; - - /** - * @var EmployeeDataProviderInterface - */ - private $employeeDataProvider; - - /** - * @var Hashing - */ - private $hashing; - - /** - * @param CommandBusInterface $bus - * @param array $defaultShopAssociation - * @param int $superAdminProfileId - * @param EmployeeFormAccessCheckerInterface $employeeFormAccessChecker - * @param EmployeeDataProviderInterface $employeeDataProvider - * @param Hashing $hashing - */ - public function __construct( - CommandBusInterface $bus, - array $defaultShopAssociation, - $superAdminProfileId, - EmployeeFormAccessCheckerInterface $employeeFormAccessChecker, - EmployeeDataProviderInterface $employeeDataProvider, - Hashing $hashing - ) { - $this->bus = $bus; - $this->defaultShopAssociation = $defaultShopAssociation; - $this->superAdminProfileId = $superAdminProfileId; - $this->employeeFormAccessChecker = $employeeFormAccessChecker; - $this->employeeDataProvider = $employeeDataProvider; - $this->hashing = $hashing; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - // Super admins have access to all shops and that cannot be changed by the user. - if ($data['profile'] == $this->superAdminProfileId) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - /** @var EmployeeId $employeeId */ - $employeeId = $this->bus->handle(new AddEmployeeCommand( - $data['firstname'], - $data['lastname'], - $data['email'], - $data['password'], - $data['default_page'], - $data['language'], - $data['active'], - $data['profile'], - isset($data['shop_association']) ? $data['shop_association'] : $this->defaultShopAssociation - )); - - return $employeeId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $command = (new EditEmployeeCommand($id)) - ->setFirstName($data['firstname']) - ->setLastName($data['lastname']) - ->setEmail($data['email']) - ->setDefaultPageId((int) $data['default_page']) - ->setLanguageId((int) $data['language']) - ->setActive((bool) $data['active']) - ->setProfileId((int) $data['profile']) - ; - - if ($this->employeeFormAccessChecker->isRestrictedAccess((int) $id)) { - if ($this->shouldChangePassword($data)) { - $this->assertPasswordIsSameAsOldPassword( - $data['change_password']['old_password'], - $id - ); - - $command->setPlainPassword($data['change_password']['new_password']); - } - } elseif (isset($data['password'])) { - $command->setPlainPassword($data['password']); - } - - if (isset($data['shop_association'])) { - $shopAssociation = $data['shop_association'] ?: []; - $command->setShopAssociation( - array_map(function ($shopId) { return (int) $shopId; }, $shopAssociation) - ); - } - - $this->bus->handle($command); - } - - /** - * Asserts if given password is the same as employee's password. - * - * @param string $plainPassword - * @param int $employeeId - * - * @throws EmployeeConstraintException - */ - private function assertPasswordIsSameAsOldPassword($plainPassword, $employeeId) - { - $oldPassword = $this->employeeDataProvider->getEmployeeHashedPassword($employeeId); - - if (!$this->hashing->checkHash($plainPassword, $oldPassword)) { - throw new EmployeeConstraintException('Old and new passwords do not match.', EmployeeConstraintException::INCORRECT_PASSWORD); - } - } - - /** - * Checks if all required fields are present in form data for changing the password. - * - * @param array $formData - * - * @return bool - */ - private function shouldChangePassword(array $formData) - { - if (!isset($formData['change_password'])) { - return false; - } - - return - null !== $formData['change_password']['old_password'] && - null !== $formData['change_password']['new_password'] - ; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/FeatureFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/FeatureFormDataHandler.php deleted file mode 100644 index 66195112..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/FeatureFormDataHandler.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\AddFeatureCommand; -use PrestaShop\PrestaShop\Core\Domain\Feature\Command\EditFeatureCommand; -use PrestaShop\PrestaShop\Core\Domain\Feature\ValueObject\FeatureId; - -/** - * Handles data of submitted Feature form. - */ -final class FeatureFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - /** @var FeatureId $featureId */ - $featureId = $this->commandBus->handle(new AddFeatureCommand( - $data['name'], - $data['shop_association'] ?? [] - )); - - return $featureId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $command = new EditFeatureCommand($id); - $command->setLocalizedNames($data['name']); - - if (isset($data['shop_association'])) { - $command->setAssociatedShopIds($data['shop_association']); - } - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/FormDataHandlerInterface.php b/src/Core/Form/IdentifiableObject/DataHandler/FormDataHandlerInterface.php deleted file mode 100644 index 84c8e2ef..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/FormDataHandlerInterface.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -/** - * Interface IdentifiableObjectFormDataHandlerInterface. - */ -interface FormDataHandlerInterface -{ - /** - * Create object from form data. - * - * @param array $data - * - * @return mixed ID of identifiable object - */ - public function create(array $data); - - /** - * Update object with form data. - * - * @param int $id - * @param array $data - */ - public function update($id, array $data); -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/LanguageFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/LanguageFormDataHandler.php deleted file mode 100644 index 26e72128..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/LanguageFormDataHandler.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\AddLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\EditLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\ValueObject\LanguageId; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Handles submitted language form data - */ -final class LanguageFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @param CommandBusInterface $bus - */ - public function __construct(CommandBusInterface $bus) - { - $this->bus = $bus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - if (!isset($data['shop_association']) || !$data['shop_association']) { - $data['shop_association'] = []; - } - - /** @var UploadedFile $uploadedFlagImage */ - $uploadedFlagImage = $data['flag_image']; - /** @var UploadedFile $uploadedFlagImage */ - $uploadedNoPictureImage = $data['no_picture_image']; - - /** @var LanguageId $languageId */ - $languageId = $this->bus->handle(new AddLanguageCommand( - $data['name'], - $data['iso_code'], - $data['tag_ietf'], - $data['short_date_format'], - $data['full_date_format'], - $uploadedFlagImage->getPathname(), - $uploadedNoPictureImage->getPathname(), - $data['is_rtl'], - $data['is_active'], - $data['shop_association'] - )); - - return $languageId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($languageId, array $data) - { - $command = (new EditLanguageCommand($languageId)) - ->setName((string) $data['name']) - ->setIsoCode((string) $data['iso_code']) - ->setTagIETF((string) $data['tag_ietf']) - ->setShortDateFormat((string) $data['short_date_format']) - ->setFullDateFormat((string) $data['full_date_format']) - ->setIsRtl($data['is_rtl']) - ->setIsActive($data['is_active']) - ; - - if ($data['flag_image'] instanceof UploadedFile) { - $command->setFlagImagePath($data['flag_image']->getPathname()); - } - - if ($data['no_picture_image'] instanceof UploadedFile) { - $command->setNoPictureImagePath($data['no_picture_image']->getPathname()); - } - - if (isset($data['shop_association'])) { - $shopAssociation = $data['shop_association'] ?: []; - $shopAssociation = array_map(function ($shopId) { return (int) $shopId; }, $shopAssociation); - - $command->setShopAssociation($shopAssociation); - } - - $this->bus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerAddressFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerAddressFormDataHandler.php deleted file mode 100644 index c97cbac0..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerAddressFormDataHandler.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\AddManufacturerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditManufacturerAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\ValueObject\AddressId; - -/** - * Handles submitted manufacturer address form data - */ -final class ManufacturerAddressFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc] - */ - public function create(array $data) - { - /** @var AddressId $addressId */ - $addressId = $this->commandBus->handle(new AddManufacturerAddressCommand( - $data['last_name'], - $data['first_name'], - $data['address'], - $data['id_country'], - $data['city'], - $data['id_manufacturer'], - $data['address2'], - $data['post_code'], - $data['id_state'], - $data['home_phone'], - $data['mobile_phone'], - $data['other'], - $data['dni'] - )); - - return $addressId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($addressId, array $data) - { - $command = new EditManufacturerAddressCommand((int) $addressId); - $this->fillCommandWithData($command, $data); - - $this->commandBus->handle($command); - } - - /** - * Fills EditManufacturerAddressCommand with form data - * - * @param EditManufacturerAddressCommand $command - * @param array $data - * - * @throws AddressConstraintException - */ - private function fillCommandWithData(EditManufacturerAddressCommand $command, array $data) - { - if (null !== $data['id_manufacturer']) { - $command->setManufacturerId($data['id_manufacturer']); - } - if (null !== $data['last_name']) { - $command->setLastName($data['last_name']); - } - if (null !== $data['first_name']) { - $command->setFirstName($data['first_name']); - } - if (null !== $data['address']) { - $command->setAddress($data['address']); - } - if (null !== $data['id_country']) { - $command->setCountryId($data['id_country']); - } - if (null !== $data['city']) { - $command->setCity($data['city']); - } - if (null !== $data['address2']) { - $command->setAddress2($data['address2']); - } - if (null !== $data['post_code']) { - $command->setPostCode($data['post_code']); - } - if (null !== $data['id_state']) { - $command->setStateId($data['id_state']); - } - if (null !== $data['home_phone']) { - $command->setHomePhone($data['home_phone']); - } - if (null !== $data['mobile_phone']) { - $command->setMobilePhone($data['mobile_phone']); - } - if (null !== $data['other']) { - $command->setOther($data['other']); - } - if (null !== $data['dni']) { - $command->setDni($data['dni']); - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerFormDataHandler.php deleted file mode 100644 index 4cacd737..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/ManufacturerFormDataHandler.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\AddManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\EditManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\ValueObject\ManufacturerId; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Handles submitted manufacturer form data - */ -final class ManufacturerFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - /** - * @var ImageUploaderInterface - */ - private $imageUploader; - - /** - * @param CommandBusInterface $bus - * @param ImageUploaderInterface $imageUploader - */ - public function __construct( - CommandBusInterface $bus, - ImageUploaderInterface $imageUploader - ) { - $this->bus = $bus; - $this->imageUploader = $imageUploader; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - if (!isset($data['shop_association']) || !$data['shop_association']) { - $data['shop_association'] = []; - } - - /** @var ManufacturerId $manufacturerId */ - $manufacturerId = $this->bus->handle(new AddManufacturerCommand( - $data['name'], - $data['is_enabled'], - $data['short_description'], - $data['description'], - $data['meta_title'], - $data['meta_description'], - $data['meta_keyword'], - $data['shop_association'] - )); - - /** @var UploadedFile $uploadedFlagImage */ - $uploadedLogo = $data['logo']; - - if ($uploadedLogo instanceof UploadedFile) { - $this->imageUploader->upload($manufacturerId->getValue(), $uploadedLogo); - } - - return $manufacturerId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($manufacturerId, array $data) - { - /** @var UploadedFile $uploadedFlagImage */ - $uploadedLogo = $data['logo']; - $logo = null; - - if ($uploadedLogo instanceof UploadedFile) { - $this->imageUploader->upload($manufacturerId, $uploadedLogo); - } - - $command = (new EditManufacturerCommand($manufacturerId)) - ->setName((string) $data['name']) - ->setLocalizedShortDescriptions($data['short_description']) - ->setLocalizedDescriptions($data['description']) - ->setLocalizedMetaDescriptions($data['meta_description']) - ->setLocalizedMetaTitles($data['meta_title']) - ->setLocalizedMetaKeywords($data['meta_keyword']) - ->setEnabled((bool) $data['is_enabled']) - ; - - if (isset($data['shop_association'])) { - $shopAssociation = $data['shop_association'] ?: []; - $shopAssociation = array_map(function ($shopId) { return (int) $shopId; }, $shopAssociation); - - $command->setAssociatedShops($shopAssociation); - } - - $this->bus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/MetaFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/MetaFormDataHandler.php deleted file mode 100644 index 54767bd3..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/MetaFormDataHandler.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\AddMetaCommand; -use PrestaShop\PrestaShop\Core\Domain\Meta\Command\EditMetaCommand; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\ValueObject\MetaId; - -/** - * Class MetaFormDataHandler is responsible to handle creation and update logic for meta form. - */ -final class MetaFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - * - * @throws MetaException - */ - public function create(array $data) - { - $addMetaCommand = (new AddMetaCommand($data['page_name'])) - ->setLocalisedPageTitle($data['page_title']) - ->setLocalisedMetaDescription($data['meta_description']) - ->setLocalisedMetaKeywords($data['meta_keywords']) - ->setLocalisedRewriteUrls($data['url_rewrite']) - ; - - /** @var MetaId $metaId */ - $metaId = $this->commandBus->handle($addMetaCommand); - - return $metaId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws MetaException - */ - public function update($metaId, array $data) - { - $editMetaCommand = (new EditMetaCommand((int) $metaId)) - ->setPageName($data['page_name']) - ->setLocalisedPageTitles($data['page_title']) - ->setLocalisedMetaDescriptions($data['meta_description']) - ->setLocalisedMetaKeywords($data['meta_keywords']) - ->setLocalisedRewriteUrls($data['url_rewrite']) - ; - - $this->commandBus->handle($editMetaCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/OrderAddressFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/OrderAddressFormDataHandler.php deleted file mode 100644 index 7669df7d..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/OrderAddressFormDataHandler.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditOrderAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\InvalidAddressTypeException; -use PrestaShop\PrestaShop\Core\Domain\Order\Exception\OrderException; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; - -class OrderAddressFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - // Not used for creation, only edition - } - - /** - * {@inheritdoc} - * - * @throws CountryConstraintException - * @throws StateConstraintException - * @throws InvalidAddressTypeException - * @throws OrderException - */ - public function update($orderId, array $data) - { - $editAddressCommand = new EditOrderAddressCommand($orderId, $data['address_type']); - - if (isset($data['alias'])) { - $editAddressCommand->setAddressAlias($data['alias']); - } - - if (isset($data['first_name'])) { - $editAddressCommand->setFirstName($data['first_name']); - } - - if (isset($data['last_name'])) { - $editAddressCommand->setLastName($data['last_name']); - } - - if (isset($data['address1'])) { - $editAddressCommand->setAddress($data['address1']); - } - - if (isset($data['city'])) { - $editAddressCommand->setCity($data['city']); - } - - if (isset($data['id_country'])) { - $editAddressCommand->setCountryId((int) $data['id_country']); - } - - if (isset($data['postcode'])) { - $editAddressCommand->setPostCode($data['postcode']); - } - - if (isset($data['dni'])) { - $editAddressCommand->setDni($data['dni']); - } - - if (isset($data['company'])) { - $editAddressCommand->setCompany($data['company']); - } - - if (isset($data['vat_number'])) { - $editAddressCommand->setVatNumber($data['vat_number']); - } - - if (isset($data['address2'])) { - $editAddressCommand->setAddress2($data['address2']); - } - - if (isset($data['id_state'])) { - $editAddressCommand->setStateId((int) $data['id_state']); - } - - if (isset($data['phone'])) { - $editAddressCommand->setHomePhone($data['phone']); - } - - if (isset($data['phone_mobile'])) { - $editAddressCommand->setMobilePhone($data['phone_mobile']); - } - - if (isset($data['other'])) { - $editAddressCommand->setOther($data['other']); - } - - $this->commandBus->handle($editAddressCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/OrderMessageFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/OrderMessageFormDataHandler.php deleted file mode 100644 index fd06b1e8..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/OrderMessageFormDataHandler.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\AddOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\EditOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\ValueObject\OrderMessageId; - -/** - * Handles data that was submitted with order message form - */ -final class OrderMessageFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - /** @var OrderMessageId $orderMessageId */ - $orderMessageId = $this->commandBus->handle(new AddOrderMessageCommand($data['name'], $data['message'])); - - return $orderMessageId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($orderMessageId, array $data) - { - $this->commandBus->handle(new EditOrderMessageCommand($orderMessageId, $data['name'], $data['message'])); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/PartialRefundFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/PartialRefundFormDataHandler.php deleted file mode 100644 index 79af6a8e..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/PartialRefundFormDataHandler.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssuePartialRefundCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; - -/** - * Class PartialRefundFormDataHandler - */ -final class PartialRefundFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - return; - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $refunds = []; - foreach ($data['products'] as $product) { - $orderDetailId = $product->getOrderDetailId(); - if (!empty($data['quantity_' . $orderDetailId]) || !empty((float) $data['amount_' . $orderDetailId])) { - $refunds[$orderDetailId]['quantity'] = $data['quantity_' . $orderDetailId] ?? 0; - $refunds[$orderDetailId]['amount'] = $data['amount_' . $orderDetailId] ?? 0; - } - } - - $command = new IssuePartialRefundCommand( - $id, - $refunds, - $data['shipping_amount'], - $data['restock'], - $data['credit_slip'], - $data['voucher'], - $data['voucher_refund_type'] ?? VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND - ); - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/ProfileFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/ProfileFormDataHandler.php deleted file mode 100644 index 8f878664..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/ProfileFormDataHandler.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\AddProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\EditProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\ValueObject\ProfileId; - -/** - * Saves or updates Profile using form data - */ -final class ProfileFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @param CommandBusInterface $bus - */ - public function __construct(CommandBusInterface $bus) - { - $this->bus = $bus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - /** @var ProfileId $profileId */ - $profileId = $this->bus->handle(new AddProfileCommand($data['name'])); - - return $profileId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($profileId, array $data) - { - /* @var ProfileId $profileId */ - $this->bus->handle(new EditProfileCommand($profileId, $data['name'])); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/ReturnProductFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/ReturnProductFormDataHandler.php deleted file mode 100644 index 35b18043..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/ReturnProductFormDataHandler.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueReturnProductCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; - -class ReturnProductFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - return; - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $refunds = []; - foreach ($data['products'] as $product) { - $orderDetailId = $product->getOrderDetailId(); - if (!isset($data['selected_' . $orderDetailId]) || !(bool) $data['selected_' . $orderDetailId]) { - continue; - } - $refunds[$orderDetailId]['quantity'] = $data['quantity_' . $orderDetailId] ?? 0; - } - - $command = new IssueReturnProductCommand( - $id, - $refunds, - $data['restock'], - $data['shipping'], - $data['credit_slip'], - $data['voucher'], - $data['voucher_refund_type'] ?? VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND - ); - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/RootCategoryFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/RootCategoryFormDataHandler.php deleted file mode 100644 index 99274db2..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/RootCategoryFormDataHandler.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddRootCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\EditRootCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Creates/updates root category from data submited in category form - */ -final class RootCategoryFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var ImageUploaderInterface - */ - private $categoryCoverUploader; - - /** - * @var ImageUploaderInterface - */ - private $categoryThumbnailUploader; - - /** - * @var ImageUploaderInterface - */ - private $categoryMenuThumbnailUploader; - - /** - * @param CommandBusInterface $commandBus - * @param ImageUploaderInterface $categoryCoverUploader - * @param ImageUploaderInterface $categoryThumbnailUploader - * @param ImageUploaderInterface $categoryMenuThumbnailUploader - */ - public function __construct( - CommandBusInterface $commandBus, - ImageUploaderInterface $categoryCoverUploader, - ImageUploaderInterface $categoryThumbnailUploader, - ImageUploaderInterface $categoryMenuThumbnailUploader - ) { - $this->commandBus = $commandBus; - $this->categoryCoverUploader = $categoryCoverUploader; - $this->categoryThumbnailUploader = $categoryThumbnailUploader; - $this->categoryMenuThumbnailUploader = $categoryMenuThumbnailUploader; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - $command = $this->createAddRootCategoryCommand($data); - - /** @var CategoryId $categoryId */ - $categoryId = $this->commandBus->handle($command); - - $this->uploadImages( - $categoryId->getValue(), - $data['cover_image'], - $data['thumbnail_image'], - $data['menu_thumbnail_images'] - ); - - return $categoryId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($rootCategoryId, array $data) - { - $command = $this->createEditRootCategoryCommand($rootCategoryId, $data); - - $this->commandBus->handle($command); - - $this->uploadImages( - $rootCategoryId, - $data['cover_image'], - $data['thumbnail_image'], - $data['menu_thumbnail_images'] - ); - } - - /** - * Creates command with form data for adding new root category - * - * @param array $data - * - * @return AddRootCategoryCommand - */ - public function createAddRootCategoryCommand(array $data) - { - $command = new AddRootCategoryCommand( - $data['name'], - $data['link_rewrite'], - $data['active'] - ); - - $command->setLocalizedDescriptions($data['description']); - $command->setLocalizedMetaTitles($data['meta_title']); - $command->setLocalizedMetaDescriptions($data['meta_description']); - $command->setLocalizedMetaKeywords($data['meta_keyword']); - $command->setAssociatedGroupIds($data['group_association']); - $command->setAssociatedShopIds($data['shop_association']); - - return $command; - } - - /** - * @param int $rootCategoryId - * @param array $data - * - * @return EditRootCategoryCommand - */ - private function createEditRootCategoryCommand($rootCategoryId, array $data) - { - $command = new EditRootCategoryCommand($rootCategoryId); - $command->setIsActive($data['active']); - $command->setLocalizedLinkRewrites($data['link_rewrite']); - $command->setLocalizedNames($data['name']); - $command->setLocalizedDescriptions($data['description']); - $command->setLocalizedMetaTitles($data['meta_title']); - $command->setLocalizedMetaDescriptions($data['meta_description']); - $command->setLocalizedMetaKeywords($data['meta_keyword']); - $command->setAssociatedGroupIds($data['group_association']); - $command->setAssociatedShopIds($data['shop_association']); - - return $command; - } - - /** - * @param int $categoryId - * @param UploadedFile $coverImage - * @param UploadedFile $thumbnailImage - * @param UploadedFile[] $menuThumbnailImages - */ - private function uploadImages( - $categoryId, - UploadedFile $coverImage = null, - UploadedFile $thumbnailImage = null, - array $menuThumbnailImages = [] - ) { - if (null !== $coverImage) { - $this->categoryCoverUploader->upload($categoryId, $coverImage); - } - - if (null !== $thumbnailImage) { - $this->categoryThumbnailUploader->upload($categoryId, $thumbnailImage); - } - - if (!empty($menuThumbnailImages)) { - foreach ($menuThumbnailImages as $menuThumbnail) { - $this->categoryMenuThumbnailUploader->upload($categoryId, $menuThumbnail); - } - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/SqlRequestFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/SqlRequestFormDataHandler.php deleted file mode 100644 index 88f26acd..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/SqlRequestFormDataHandler.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\AddSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\EditSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; - -/** - * Creates or updates SqlRequest objects using form data. - */ -final class SqlRequestFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $bus - */ - public function __construct(CommandBusInterface $bus) - { - $this->commandBus = $bus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - /** @var SqlRequestId $sqlRequestId */ - $sqlRequestId = $this->commandBus->handle(new AddSqlRequestCommand($data['name'], $data['sql'])); - - return $sqlRequestId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $sqlRequestId = new SqlRequestId($id); - - $command = (new EditSqlRequestCommand($sqlRequestId)) - ->setName($data['name']) - ->setSql($data['sql']); - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/StandardRefundFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/StandardRefundFormDataHandler.php deleted file mode 100644 index 195ca99f..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/StandardRefundFormDataHandler.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueStandardRefundCommand; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; - -/** - * Class StandardRefundFormDataHandler - */ -final class StandardRefundFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @param CommandBusInterface $commandBus - */ - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - return; - } - - /** - * {@inheritdoc} - */ - public function update($id, array $data) - { - $refunds = []; - foreach ($data['products'] as $product) { - $orderDetailId = $product->getOrderDetailId(); - if (!isset($data['selected_' . $orderDetailId]) || !(bool) $data['selected_' . $orderDetailId]) { - continue; - } - $refunds[$orderDetailId]['quantity'] = $data['quantity_' . $orderDetailId] ?? 0; - } - - $command = new IssueStandardRefundCommand( - $id, - $refunds, - $data['shipping'], - $data['credit_slip'], - $data['voucher'], - $data['voucher_refund_type'] ?? VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND - ); - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/SupplierFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/SupplierFormDataHandler.php deleted file mode 100644 index 1dd5e322..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/SupplierFormDataHandler.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\AddSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\EditSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\ValueObject\SupplierId; -use PrestaShop\PrestaShop\Core\Image\Uploader\ImageUploaderInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Handles submitted supplier form data - */ -final class SupplierFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - /** - * @var ImageUploaderInterface - */ - private $imageUploader; - - /** - * @param CommandBusInterface $commandBus - * @param ImageUploaderInterface $imageUploader - */ - public function __construct( - CommandBusInterface $commandBus, - ImageUploaderInterface $imageUploader - ) { - $this->commandBus = $commandBus; - $this->imageUploader = $imageUploader; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - if (!isset($data['shop_association']) || !$data['shop_association']) { - $data['shop_association'] = []; - } - - /** @var SupplierId $supplierId */ - $supplierId = $this->commandBus->handle(new AddSupplierCommand( - $data['name'], - $data['address'], - $data['city'], - (int) $data['id_country'], - (bool) $data['is_enabled'], - $data['description'], - $data['meta_title'], - $data['meta_description'], - $data['meta_keyword'], - $data['shop_association'], - $data['address2'], - $data['post_code'], - isset($data['id_state']) ? (int) $data['id_state'] : null, - $data['phone'], - $data['mobile_phone'], - $data['dni'] - )); - - /** @var UploadedFile $uploadedFlagImage */ - $uploadedLogo = $data['logo']; - - if ($uploadedLogo instanceof UploadedFile) { - $this->imageUploader->upload($supplierId->getValue(), $uploadedLogo); - } - - return $supplierId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($supplierId, array $data) - { - /** @var UploadedFile $uploadedFlagImage */ - $uploadedLogo = $data['logo']; - $logo = null; - - if ($uploadedLogo instanceof UploadedFile) { - $this->imageUploader->upload($supplierId, $uploadedLogo); - } - - $command = new EditSupplierCommand($supplierId); - $this->fillCommandWithData($command, $data); - - $this->commandBus->handle($command); - } - - /** - * Fills command with provided data - * - * @param EditSupplierCommand $command - * @param array $data - */ - private function fillCommandWithData(EditSupplierCommand $command, array $data) - { - if (null !== $data['name']) { - $command->setName($data['name']); - } - if (null !== $data['description']) { - $command->setLocalizedDescriptions($data['description']); - } - if (null !== $data['phone']) { - $command->setPhone($data['phone']); - } - if (null !== $data['mobile_phone']) { - $command->setMobilePhone($data['mobile_phone']); - } - if (null !== $data['address']) { - $command->setAddress($data['address']); - } - if (null !== $data['address2']) { - $command->setAddress2($data['address2']); - } - if (null !== $data['post_code']) { - $command->setPostCode($data['post_code']); - } - if (null !== $data['city']) { - $command->setCity($data['city']); - } - if (null !== $data['id_country']) { - $command->setCountryId((int) $data['id_country']); - } - if (null !== $data['meta_title']) { - $command->setLocalizedMetaTitles($data['meta_title']); - } - if (null !== $data['meta_description']) { - $command->setLocalizedMetaDescriptions($data['meta_description']); - } - if (null !== $data['is_enabled']) { - $command->setEnabled((bool) $data['is_enabled']); - } - if (null !== $data['dni']) { - $command->setDni($data['dni']); - } - - if (isset($data['id_state'])) { - $command->setStateId((int) $data['id_state']); - } - - if (isset($data['shop_association'])) { - $shopAssociation = $data['shop_association'] ?: []; - $shopAssociation = array_map(function ($shopId) { return (int) $shopId; }, $shopAssociation); - - $command->setAssociatedShops($shopAssociation); - } - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/TaxFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/TaxFormDataHandler.php deleted file mode 100644 index 8f81eb8d..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/TaxFormDataHandler.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\AddTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\EditTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\ValueObject\TaxId; - -/** - * Handles submitted tax form data - */ -final class TaxFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - public function __construct(CommandBusInterface $commandBus) - { - $this->commandBus = $commandBus; - } - - /** - * Create object from form data. - * - * @param array $data - * - * @return mixed - */ - public function create(array $data) - { - $command = new AddTaxCommand( - $data['name'], - (float) $data['rate'], - (bool) $data['is_enabled'] - ); - - /** @var TaxId $taxId */ - $taxId = $this->commandBus->handle($command); - - return $taxId->getValue(); - } - - /** - * {@inheritdoc} - * - * @throws TaxException - */ - public function update($id, array $data) - { - $command = (new EditTaxCommand($id)) - ->setLocalizedNames($data['name']) - ->setRate((float) $data['rate']) - ->setEnabled((bool) $data['is_enabled']) - ; - - $this->commandBus->handle($command); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataHandler/WebserviceKeyFormDataHandler.php b/src/Core/Form/IdentifiableObject/DataHandler/WebserviceKeyFormDataHandler.php deleted file mode 100644 index 7335031e..00000000 --- a/src/Core/Form/IdentifiableObject/DataHandler/WebserviceKeyFormDataHandler.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\AddWebserviceKeyCommand; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Command\EditWebserviceKeyCommand; -use PrestaShop\PrestaShop\Core\Domain\Webservice\ValueObject\WebserviceKeyId; - -/** - * Creates/updates webservice key with submited form data - */ -final class WebserviceKeyFormDataHandler implements FormDataHandlerInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var int - */ - private $contextShopId; - - /** - * @param CommandBusInterface $commandBus - * @param int $contextShopId - */ - public function __construct(CommandBusInterface $commandBus, $contextShopId) - { - $this->commandBus = $commandBus; - $this->contextShopId = $contextShopId; - } - - /** - * {@inheritdoc} - */ - public function create(array $data) - { - if (!isset($data['shop_association'])) { - $data['shop_association'] = [(int) $this->contextShopId]; - } - - /** @var WebserviceKeyId $webserviceKeyId */ - $webserviceKeyId = $this->commandBus->handle(new AddWebserviceKeyCommand( - $data['key'], - $data['description'], - $data['status'], - $data['permissions'], - $data['shop_association'] - )); - - return $webserviceKeyId->getValue(); - } - - /** - * {@inheritdoc} - */ - public function update($weserviceKeyId, array $data) - { - $editCommand = new EditWebserviceKeyCommand($weserviceKeyId); - $editCommand - ->setKey($data['key']) - ->setDescription($data['description']) - ->setStatus($data['status']) - ->setPermissions($data['permissions']) - ; - - if (isset($data['shop_association'])) { - $editCommand->setShopAssociation($data['shop_association']); - } - - $this->commandBus->handle($editCommand); - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/AddressFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/AddressFormDataProvider.php deleted file mode 100644 index d0d345ec..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/AddressFormDataProvider.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableCustomerAddress; - -/** - * Provides data for address add/edit form - */ -final class AddressFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var int - */ - private $defaultCountryId; - - /** - * @param CommandBusInterface $queryBus - * @param int $defaultCountryId - */ - public function __construct(CommandBusInterface $queryBus, int $defaultCountryId) - { - $this->queryBus = $queryBus; - $this->defaultCountryId = $defaultCountryId; - } - - /** - * {@inheritdoc} - * - * @throws AddressConstraintException - */ - public function getData($addressId) - { - /** @var EditableCustomerAddress $editableAddress */ - $editableAddress = $this->queryBus->handle(new GetCustomerAddressForEditing((int) $addressId)); - - $data = [ - 'id_customer' => $editableAddress->getCustomerId()->getValue(), - 'customer_email' => $editableAddress->getCustomerEmail(), - 'dni' => $editableAddress->getDni(), - 'alias' => $editableAddress->getAddressAlias(), - 'first_name' => $editableAddress->getFirstName(), - 'last_name' => $editableAddress->getLastName(), - 'company' => $editableAddress->getCompany(), - 'vat_number' => $editableAddress->getVatNumber(), - 'address1' => $editableAddress->getAddress(), - 'address2' => $editableAddress->getAddress2(), - 'city' => $editableAddress->getCity(), - 'postcode' => $editableAddress->getPostCode(), - 'id_country' => $editableAddress->getCountryId()->getValue(), - 'id_state' => $editableAddress->getStateId()->getValue(), - 'phone' => $editableAddress->getHomePhone(), - 'phone_mobile' => $editableAddress->getMobilePhone(), - 'other' => $editableAddress->getOther(), - ]; - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'id_country' => $this->defaultCountryId, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/AttachmentFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/AttachmentFormDataProvider.php deleted file mode 100644 index 0542489f..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/AttachmentFormDataProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachmentForEditing; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\EditableAttachment; - -/** - * Provides data for attachment add/edit forms - */ -final class AttachmentFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($attachmentId) - { - /** @var EditableAttachment $editableAttachment */ - $editableAttachment = $this->queryBus->handle(new GetAttachmentForEditing((int) $attachmentId)); - - $data = [ - 'name' => $editableAttachment->getName(), - 'file_name' => $editableAttachment->getFileName(), - 'file_description' => $editableAttachment->getDescription(), - ]; - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return []; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CancelProductFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CancelProductFormDataProvider.php deleted file mode 100644 index aef7fe04..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CancelProductFormDataProvider.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; -use PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderForViewing; -use PrestaShop\PrestaShop\Core\Domain\Order\QueryResult\OrderForViewing; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; - -/** - * Provides data for product cancellation form in order page - */ -final class CancelProductFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var CurrencyDataProviderInterface - */ - private $currencyDataProvider; - - /** - * @param CommandBusInterface $queryBus - * @param CurrencyDataProviderInterface $currencyDataProvider - */ - public function __construct( - CommandBusInterface $queryBus, - CurrencyDataProviderInterface $currencyDataProvider - ) { - $this->queryBus = $queryBus; - $this->currencyDataProvider = $currencyDataProvider; - } - - /** - * {@inheritdoc} - */ - public function getData($orderId) - { - /** @var OrderForViewing $orderForViewing */ - $orderForViewing = $this->queryBus->handle(new GetOrderForViewing((int) $orderId)); - $computingPrecision = new ComputingPrecision(); - $currency = $this->currencyDataProvider->getCurrencyById($orderForViewing->getCurrencyId()); - - return [ - 'products' => $orderForViewing->getProducts()->getProducts(), - 'taxMethod' => $orderForViewing->getTaxMethod(), - 'precision' => $computingPrecision->getPrecision($currency->precision), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return []; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CatalogPriceRuleFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CatalogPriceRuleFormDataProvider.php deleted file mode 100644 index e67ca64d..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CatalogPriceRuleFormDataProvider.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query\GetCatalogPriceRuleForEditing; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryResult\editableCatalogPriceRule; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; - -/** - * Provides data for catalog price rule add/edit forms - */ -final class CatalogPriceRuleFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($catalogPriceRuleId) - { - /** @var editableCatalogPriceRule $editableCatalogPriceRule */ - $editableCatalogPriceRule = $this->queryBus->handle(new GetCatalogPriceRuleForEditing((int) $catalogPriceRuleId)); - - $dateTimeFormat = 'Y-m-d H:i:s'; - $price = $editableCatalogPriceRule->getPrice(); - $leaveInitialPrice = false; - $from = $editableCatalogPriceRule->getFrom(); - $to = $editableCatalogPriceRule->getTo(); - - if ($price->isLowerOrEqualThanZero()) { - $price = null; - $leaveInitialPrice = true; - } - - $data = [ - 'name' => $editableCatalogPriceRule->getName(), - 'id_shop' => $editableCatalogPriceRule->getShopId(), - 'id_currency' => $editableCatalogPriceRule->getCurrencyId(), - 'id_country' => $editableCatalogPriceRule->getCountryId(), - 'id_group' => $editableCatalogPriceRule->getGroupId(), - 'from_quantity' => $editableCatalogPriceRule->getFromQuantity(), - 'price' => null === $price ? $price : (string) $price, - 'leave_initial_price' => $leaveInitialPrice, - 'date_range' => [ - 'from' => $from ? $from->format($dateTimeFormat) : '', - 'to' => $to ? $to->format($dateTimeFormat) : '', - ], - 'include_tax' => $editableCatalogPriceRule->isTaxIncluded(), - 'reduction' => [ - 'type' => $editableCatalogPriceRule->getReduction()->getType(), - 'value' => (string) $editableCatalogPriceRule->getReduction()->getValue(), - ], - ]; - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'from_quantity' => 1, - 'leave_initial_price' => true, - 'reduction' => [ - 'type' => Reduction::TYPE_AMOUNT, - 'value' => 0, - ], - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CategoryFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CategoryFormDataProvider.php deleted file mode 100644 index 32cb8d0d..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CategoryFormDataProvider.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryResult\EditableCategory; -use PrestaShop\PrestaShop\Core\Group\Provider\DefaultGroupsProviderInterface; - -/** - * Provides data for category add/edit category forms - */ -final class CategoryFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var int - */ - private $contextShopRootCategoryId; - - /** - * @var DefaultGroupsProviderInterface - */ - private $defaultGroupsProvider; - - /** - * @param CommandBusInterface $queryBus - * @param int $contextShopId - * @param int $contextShopRootCategoryId - * @param DefaultGroupsProviderInterface $defaultGroupsProvider - */ - public function __construct( - CommandBusInterface $queryBus, - $contextShopId, - $contextShopRootCategoryId, - DefaultGroupsProviderInterface $defaultGroupsProvider - ) { - $this->queryBus = $queryBus; - $this->contextShopId = $contextShopId; - $this->contextShopRootCategoryId = $contextShopRootCategoryId; - $this->defaultGroupsProvider = $defaultGroupsProvider; - } - - /** - * {@inheritdoc} - */ - public function getData($categoryId) - { - /** @var EditableCategory $editableCategory */ - $editableCategory = $this->queryBus->handle(new GetCategoryForEditing($categoryId)); - - return [ - 'name' => $editableCategory->getName(), - 'active' => $editableCategory->isActive(), - 'id_parent' => $editableCategory->getParentId(), - 'description' => $editableCategory->getDescription(), - 'meta_title' => $editableCategory->getMetaTitle(), - 'meta_description' => $editableCategory->getMetaDescription(), - 'meta_keyword' => $editableCategory->getMetaKeywords(), - 'link_rewrite' => $editableCategory->getLinkRewrite(), - 'group_association' => $editableCategory->getGroupAssociationIds(), - 'shop_association' => $editableCategory->getShopAssociationIds(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $defaultGroups = $this->defaultGroupsProvider->getGroups(); - - return [ - 'id_parent' => $this->contextShopRootCategoryId, - 'group_association' => [ - $defaultGroups->getVisitorsGroup()->getId(), - $defaultGroups->getGuestsGroup()->getId(), - $defaultGroups->getCustomersGroup()->getId(), - ], - 'shop_association' => $this->contextShopId, - 'active' => true, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CmsPageCategoryFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CmsPageCategoryFormDataProvider.php deleted file mode 100644 index 13ee3dcf..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CmsPageCategoryFormDataProvider.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\QueryResult\EditableCmsPageCategory; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -final class CmsPageCategoryFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @param CommandBusInterface $queryBus - * @param array $contextShopIds - */ - public function __construct(CommandBusInterface $queryBus, array $contextShopIds) - { - $this->queryBus = $queryBus; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - * - * @throws CmsPageCategoryException - */ - public function getData($id) - { - /** @var EditableCmsPageCategory $editableCmsPageCategory */ - $editableCmsPageCategory = $this->queryBus->handle(new GetCmsPageCategoryForEditing($id)); - - return [ - 'name' => $editableCmsPageCategory->getLocalisedName(), - 'is_displayed' => $editableCmsPageCategory->isDisplayed(), - 'parent_category' => $editableCmsPageCategory->getParentId()->getValue(), - 'description' => $editableCmsPageCategory->getLocalisedDescription(), - 'meta_title' => $editableCmsPageCategory->getMetaTitle(), - 'meta_description' => $editableCmsPageCategory->getLocalisedMetaDescription(), - 'meta_keywords' => $editableCmsPageCategory->getLocalisedMetaKeywords(), - 'friendly_url' => $editableCmsPageCategory->getLocalisedFriendlyUrl(), - 'shop_association' => $editableCmsPageCategory->getShopIds(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'parent_category' => CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID, - 'shop_association' => $this->contextShopIds, - 'is_displayed' => true, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CmsPageFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CmsPageFormDataProvider.php deleted file mode 100644 index fde3a4e2..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CmsPageFormDataProvider.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsPageForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryResult\EditableCmsPage; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; - -/** - * {@inheritdoc} - */ -class CmsPageFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @param CommandBusInterface $queryBus - * @param array $contextShopIds - */ - public function __construct(CommandBusInterface $queryBus, array $contextShopIds) - { - $this->queryBus = $queryBus; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - * - * @throws CmsPageException - */ - public function getData($cmsPageId) - { - /** @var EditableCmsPage $editableCmsPage */ - $editableCmsPage = $this->queryBus->handle(new GetCmsPageForEditing($cmsPageId)); - - return [ - 'page_category_id' => $editableCmsPage->getCmsPageCategoryId()->getValue(), - 'title' => $editableCmsPage->getLocalizedTitle(), - 'meta_title' => $editableCmsPage->getLocalizedMetaTitle(), - 'meta_description' => $editableCmsPage->getLocalizedMetaDescription(), - 'meta_keyword' => $editableCmsPage->getLocalizedMetaKeyword(), - 'friendly_url' => $editableCmsPage->getLocalizedFriendlyUrl(), - 'content' => $editableCmsPage->getLocalizedContent(), - 'is_indexed_for_search' => $editableCmsPage->isIndexedForSearch(), - 'is_displayed' => $editableCmsPage->isDisplayed(), - 'shop_association' => $editableCmsPage->getShopAssociation(), - ]; - } - - /** - * Get default form data. - * - * @return mixed - */ - public function getDefaultData() - { - return [ - 'page_category_id' => CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID, - 'shop_association' => $this->contextShopIds, - 'is_indexed_for_search' => false, - 'is_displayed' => false, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/ContactFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/ContactFormDataProvider.php deleted file mode 100644 index 0ddca683..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/ContactFormDataProvider.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Query\GetContactForEditing; -use PrestaShop\PrestaShop\Core\Domain\Contact\QueryResult\EditableContact; -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class ContactFormDataProvider is responsible for providing form data for contacts by contact id or by giving default - * values. - */ -final class ContactFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var DataTransformerInterface - */ - private $stringArrayToIntegerArrayDataTransformer; - - /** - * @param CommandBusInterface $queryBus - * @param DataTransformerInterface $stringArrayToIntegerArrayDataTransformer - * @param int[] $contextShopIds - */ - public function __construct( - CommandBusInterface $queryBus, - DataTransformerInterface $stringArrayToIntegerArrayDataTransformer, - array $contextShopIds - ) { - $this->queryBus = $queryBus; - $this->contextShopIds = $contextShopIds; - $this->stringArrayToIntegerArrayDataTransformer = $stringArrayToIntegerArrayDataTransformer; - } - - /** - * {@inheritdoc} - * - * @throws ContactException - */ - public function getData($contactId) - { - /** @var EditableContact $editableContact */ - $editableContact = $this->queryBus->handle(new GetContactForEditing($contactId)); - - return [ - 'title' => $editableContact->getLocalisedTitles(), - 'email' => null !== $editableContact->getEmail() ? $editableContact->getEmail()->getValue() : '', - 'is_messages_saving_enabled' => $editableContact->isMessagesSavingEnabled(), - 'description' => $editableContact->getLocalisedDescription(), - 'shop_association' => $editableContact->getShopAssociation(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $shopIds = $this->stringArrayToIntegerArrayDataTransformer->reverseTransform($this->contextShopIds); - - return [ - 'shop_association' => $shopIds, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CurrencyFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CurrencyFormDataProvider.php deleted file mode 100644 index c1962899..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CurrencyFormDataProvider.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyForEditing; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\ExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\Precision; - -/** - * Class CurrencyFormDataProvider - */ -final class CurrencyFormDataProvider implements FormDataProviderInterface -{ - /** - * @var array - */ - private $contextShopIds; - - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - * @param array $contextShopIds - */ - public function __construct(CommandBusInterface $queryBus, array $contextShopIds) - { - $this->contextShopIds = $contextShopIds; - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($id) - { - /** @var \PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\EditableCurrency $result */ - $result = $this->queryBus->handle(new GetCurrencyForEditing((int) $id)); - - return [ - 'id' => $id, - 'iso_code' => $result->getIsoCode(), - 'names' => $result->getNames(), - 'symbols' => $result->getSymbols(), - 'transformations' => $result->getTransformations(), - 'exchange_rate' => $result->getExchangeRate(), - 'precision' => $result->getPrecision(), - 'shop_association' => $result->getAssociatedShopIds(), - 'active' => $result->isEnabled(), - 'unofficial' => $result->isUnofficial(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'precision' => Precision::DEFAULT_PRECISION, - 'exchange_rate' => ExchangeRate::DEFAULT_RATE, - 'shop_association' => $this->contextShopIds, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/CustomerFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/CustomerFormDataProvider.php deleted file mode 100644 index 477e791b..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/CustomerFormDataProvider.php +++ /dev/null @@ -1,141 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\EditableCustomer; -use PrestaShop\PrestaShop\Core\Group\Provider\DefaultGroupsProviderInterface; - -/** - * Provides data for customer forms - */ -final class CustomerFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var DefaultGroupsProviderInterface - */ - private $defaultGroupsProvider; - - /** - * @var bool - */ - private $isB2bFeatureEnabled; - - /** - * @param CommandBusInterface $queryBus - * @param ConfigurationInterface $configuration - * @param DefaultGroupsProviderInterface $defaultGroupsProvider - * @param bool $isB2bFeatureEnabled - */ - public function __construct( - CommandBusInterface $queryBus, - ConfigurationInterface $configuration, - DefaultGroupsProviderInterface $defaultGroupsProvider, - $isB2bFeatureEnabled - ) { - $this->queryBus = $queryBus; - $this->configuration = $configuration; - $this->defaultGroupsProvider = $defaultGroupsProvider; - $this->isB2bFeatureEnabled = $isB2bFeatureEnabled; - } - - /** - * {@inheritdoc} - */ - public function getData($customerId) - { - /** @var EditableCustomer $editableCustomer */ - $editableCustomer = $this->queryBus->handle(new GetCustomerForEditing((int) $customerId)); - $birthday = $editableCustomer->getBirthday(); - - $data = [ - 'gender_id' => $editableCustomer->getGenderId(), - 'first_name' => $editableCustomer->getFirstName()->getValue(), - 'last_name' => $editableCustomer->getLastName()->getValue(), - 'email' => $editableCustomer->getEmail()->getValue(), - 'birthday' => $birthday->isEmpty() ? null : $birthday->getValue(), - 'is_enabled' => $editableCustomer->isEnabled(), - 'is_partner_offers_subscribed' => $editableCustomer->isPartnerOffersSubscribed(), - 'group_ids' => $editableCustomer->getGroupIds(), - 'default_group_id' => $editableCustomer->getDefaultGroupId(), - ]; - - if ($this->isB2bFeatureEnabled) { - $data = array_merge($data, [ - 'company_name' => $editableCustomer->getCompanyName(), - 'siret_code' => $editableCustomer->getSiretCode(), - 'ape_code' => $editableCustomer->getApeCode(), - 'website' => $editableCustomer->getWebsite(), - 'allowed_outstanding_amount' => $editableCustomer->getAllowedOutstandingAmount(), - 'max_payment_days' => $editableCustomer->getMaxPaymentDays(), - 'risk_id' => $editableCustomer->getRiskId(), - ]); - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $defaultGroups = $this->defaultGroupsProvider->getGroups(); - - $data = [ - 'is_enabled' => true, - 'is_partner_offers_subscribed' => false, - 'group_ids' => [ - $defaultGroups->getVisitorsGroup()->getId(), - $defaultGroups->getGuestsGroup()->getId(), - $defaultGroups->getCustomersGroup()->getId(), - ], - 'default_group_id' => (int) $this->configuration->get('PS_CUSTOMER_GROUP'), - ]; - - if ($this->isB2bFeatureEnabled) { - $data = array_merge($data, [ - 'allowed_outstanding_amount' => 0, - 'max_payment_days' => 0, - ]); - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/EmployeeFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/EmployeeFormDataProvider.php deleted file mode 100644 index 62c33eb9..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/EmployeeFormDataProvider.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeForEditing; -use PrestaShop\PrestaShop\Core\Domain\Employee\QueryResult\EditableEmployee; - -/** - * Provides data for employee forms. - */ -final class EmployeeFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var bool - */ - private $isMultistoreFeatureActive; - - /** - * @var array - */ - private $defaultShopAssociation; - - /** - * @param CommandBusInterface $queryBus - * @param bool $isMultistoreFeatureActive - * @param array $defaultShopAssociation - */ - public function __construct( - CommandBusInterface $queryBus, - $isMultistoreFeatureActive, - array $defaultShopAssociation - ) { - $this->queryBus = $queryBus; - $this->isMultistoreFeatureActive = $isMultistoreFeatureActive; - $this->defaultShopAssociation = $defaultShopAssociation; - } - - /** - * {@inheritdoc} - */ - public function getData($employeeId) - { - /** @var EditableEmployee $editableEmployee */ - $editableEmployee = $this->queryBus->handle(new GetEmployeeForEditing((int) $employeeId)); - - return [ - 'firstname' => $editableEmployee->getFirstName()->getValue(), - 'lastname' => $editableEmployee->getLastName()->getValue(), - 'email' => $editableEmployee->getEmail()->getValue(), - 'default_page' => $editableEmployee->getDefaultPageId(), - 'language' => $editableEmployee->getLanguageId(), - 'active' => $editableEmployee->isActive(), - 'profile' => $editableEmployee->getProfileId(), - 'shop_association' => $editableEmployee->getShopAssociation(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $data = [ - 'active' => true, - ]; - - if ($this->isMultistoreFeatureActive) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/FeatureFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/FeatureFormDataProvider.php deleted file mode 100644 index 3c860e8b..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/FeatureFormDataProvider.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Feature\Query\GetFeatureForEditing; -use PrestaShop\PrestaShop\Core\Domain\Feature\QueryResult\EditableFeature; - -/** - * Provides data for feature forms. - */ -final class FeatureFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var bool - */ - private $isMultistoreFeatureActive; - - /** - * @var array - */ - private $defaultShopAssociation; - - /** - * @param CommandBusInterface $queryBus - * @param bool $isMultistoreFeatureActive - * @param array $defaultShopAssociation - */ - public function __construct( - CommandBusInterface $queryBus, - $isMultistoreFeatureActive, - array $defaultShopAssociation - ) { - $this->queryBus = $queryBus; - $this->isMultistoreFeatureActive = $isMultistoreFeatureActive; - $this->defaultShopAssociation = $defaultShopAssociation; - } - - /** - * {@inheritdoc} - */ - public function getData($id) - { - /** @var EditableFeature $editableFeature */ - $editableFeature = $this->queryBus->handle(new GetFeatureForEditing((int) $id)); - - return [ - 'name' => $editableFeature->getName(), - 'shop_association' => $editableFeature->getShopAssociationIds(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $data = []; - - if ($this->isMultistoreFeatureActive) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/FormDataProviderInterface.php b/src/Core/Form/IdentifiableObject/DataProvider/FormDataProviderInterface.php deleted file mode 100644 index 56feafe4..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/FormDataProviderInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -/** - * Interface for services that provide data form identifiable object forms. - */ -interface FormDataProviderInterface -{ - /** - * Get form data for given object with given id. - * - * @param int $id - * - * @return mixed - */ - public function getData($id); - - /** - * Get default form data. - * - * @return mixed - */ - public function getDefaultData(); -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php deleted file mode 100644 index ebdcb204..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/LanguageFormDataProvider.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; -use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; - -/** - * Provides data for language's add/edit forms - */ -final class LanguageFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @var bool - */ - private $isMultistoreFeatureActive; - - /** - * @var int[] - */ - private $defaultShopAssociation; - - /** - * @param CommandBusInterface $bus - * @param bool $isMultistoreFeatureActive - * @param int[] $defaultShopAssociation - */ - public function __construct( - CommandBusInterface $bus, - $isMultistoreFeatureActive, - array $defaultShopAssociation - ) { - $this->bus = $bus; - $this->isMultistoreFeatureActive = $isMultistoreFeatureActive; - $this->defaultShopAssociation = $defaultShopAssociation; - } - - /** - * {@inheritdoc} - */ - public function getData($languageId) - { - /** @var EditableLanguage $editableLanguage */ - $editableLanguage = $this->bus->handle(new GetLanguageForEditing($languageId)); - - $data = [ - 'name' => $editableLanguage->getName(), - 'iso_code' => $editableLanguage->getIsoCode()->getValue(), - 'tag_ietf' => $editableLanguage->getTagIETF()->getValue(), - 'short_date_format' => $editableLanguage->getShortDateFormat(), - 'full_date_format' => $editableLanguage->getFullDateFormat(), - 'is_rtl' => $editableLanguage->isRtl(), - 'is_active' => $editableLanguage->isActive(), - ]; - - if ($this->isMultistoreFeatureActive) { - $data['shop_association'] = $editableLanguage->getShopAssociation(); - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $data = [ - 'short_date_format' => 'Y-m-d', - 'full_date_format' => 'Y-m-d H:i:s', - 'is_rtl' => false, - 'is_active' => true, - ]; - - if ($this->isMultistoreFeatureActive) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerAddressFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerAddressFormDataProvider.php deleted file mode 100644 index 6b7c0fde..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerAddressFormDataProvider.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetManufacturerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableManufacturerAddress; - -/** - * Provides data for address add/edit form - */ -final class ManufacturerAddressFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var int - */ - private $defaultCountryId; - - /** - * @param CommandBusInterface $queryBus - * @param $defaultCountryId - */ - public function __construct( - CommandBusInterface $queryBus, - $defaultCountryId - ) { - $this->queryBus = $queryBus; - $this->defaultCountryId = $defaultCountryId; - } - - /** - * {@inheritdoc} - * - * @throws AddressConstraintException - */ - public function getData($addressId) - { - /** @var EditableManufacturerAddress $editableAddress */ - $editableAddress = $this->queryBus->handle(new GetManufacturerAddressForEditing((int) $addressId)); - $manufacturerId = $editableAddress->getManufacturerId(); - - return [ - 'id_manufacturer' => $manufacturerId, - 'last_name' => $editableAddress->getLastName(), - 'first_name' => $editableAddress->getFirstName(), - 'address' => $editableAddress->getAddress(), - 'city' => $editableAddress->getCity(), - 'address2' => $editableAddress->getAddress2(), - 'id_country' => $editableAddress->getCountryId(), - 'post_code' => $editableAddress->getPostCode(), - 'id_state' => $editableAddress->getStateId(), - 'home_phone' => $editableAddress->getHomePhone(), - 'mobile_phone' => $editableAddress->getMobilePhone(), - 'other' => $editableAddress->getOther(), - 'dni' => $editableAddress->getDni(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'id_country' => $this->defaultCountryId, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerFormDataProvider.php deleted file mode 100644 index 900c6faf..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/ManufacturerFormDataProvider.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\EditableManufacturer; - -/** - * Provides data for manufacturers add/edit forms - */ -final class ManufacturerFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $bus; - - /** - * @var bool - */ - private $multistoreEnabled; - - /** - * @var int[] - */ - private $defaultShopAssociation; - - /** - * @param CommandBusInterface $bus - * @param $multistoreEnabled - * @param int[] $defaultShopAssociation - */ - public function __construct( - CommandBusInterface $bus, - $multistoreEnabled, - array $defaultShopAssociation - ) { - $this->bus = $bus; - $this->multistoreEnabled = $multistoreEnabled; - $this->defaultShopAssociation = $defaultShopAssociation; - } - - /** - * {@inheritdoc} - */ - public function getData($manufacturerId) - { - /** @var EditableManufacturer $editableManufacturer */ - $editableManufacturer = $this->bus->handle(new GetManufacturerForEditing((int) $manufacturerId)); - - $data = [ - 'name' => $editableManufacturer->getName(), - 'short_description' => $editableManufacturer->getLocalizedShortDescriptions(), - 'description' => $editableManufacturer->getLocalizedDescriptions(), - 'meta_title' => $editableManufacturer->getLocalizedMetaTitles(), - 'meta_description' => $editableManufacturer->getLocalizedMetaDescriptions(), - 'meta_keyword' => $editableManufacturer->getLocalizedMetaKeywords(), - 'is_enabled' => $editableManufacturer->isEnabled(), - ]; - - if ($this->multistoreEnabled) { - $data['shop_association'] = $editableManufacturer->getAssociatedShops(); - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $data['is_enabled'] = true; - - if ($this->multistoreEnabled) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/MetaFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/MetaFormDataProvider.php deleted file mode 100644 index d333277d..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/MetaFormDataProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetMetaForEditing; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult\EditableMeta; - -/** - * Class MetaFormDataProvider is responsible for providing required data for meta form. - */ -final class MetaFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - * - * @throws MetaException - */ - public function getData($metaId) - { - /** @var EditableMeta $result */ - $result = $this->queryBus->handle(new GetMetaForEditing((int) $metaId)); - - return [ - 'page_name' => $result->getPageName()->getValue(), - 'page_title' => $result->getLocalisedPageTitles(), - 'meta_description' => $result->getLocalisedMetaDescriptions(), - 'meta_keywords' => $result->getLocalisedMetaKeywords(), - 'url_rewrite' => $result->getLocalisedUrlRewrites(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return null; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/OrderMessageFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/OrderMessageFormDataProvider.php deleted file mode 100644 index 30a1f733..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/OrderMessageFormDataProvider.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query\GetOrderMessageForEditing; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryResult\EditableOrderMessage; - -/** - * Provides add/edit data for order message form - */ -final class OrderMessageFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($orderMessageId) - { - /** @var EditableOrderMessage $editableOrderMessage */ - $editableOrderMessage = $this->queryBus->handle(new GetOrderMessageForEditing((int) $orderMessageId)); - - return [ - 'name' => $editableOrderMessage->getLocalizedName(), - 'message' => $editableOrderMessage->getLocalizedMessage(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return []; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/ProfileFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/ProfileFormDataProvider.php deleted file mode 100644 index 28366874..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/ProfileFormDataProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Profile\Query\GetProfileForEditing; -use PrestaShop\PrestaShop\Core\Domain\Profile\QueryResult\EditableProfile; - -/** - * Provides data for Profile form - */ -final class ProfileFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($profileId) - { - /** @var EditableProfile $editableProfile */ - $editableProfile = $this->queryBus->handle(new GetProfileForEditing($profileId)); - - return [ - 'name' => $editableProfile->getLocalizedNames(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return []; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/SqlRequestFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/SqlRequestFormDataProvider.php deleted file mode 100644 index bd4da1d0..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/SqlRequestFormDataProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\EditableSqlRequest; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestForEditing; - -/** - * Provides data for SqlRequest forms. - */ -final class SqlRequestFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($id) - { - $getRequestSqlForEditingQuery = new GetSqlRequestForEditing($id); - - /** @var EditableSqlRequest $editableSqlRequest */ - $editableSqlRequest = $this->queryBus->handle($getRequestSqlForEditingQuery); - - return [ - 'id' => $editableSqlRequest->getSqlRequestId()->getValue(), - 'name' => $editableSqlRequest->getName(), - 'sql' => $editableSqlRequest->getSql(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return null; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/SupplierFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/SupplierFormDataProvider.php deleted file mode 100644 index 271b0a90..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/SupplierFormDataProvider.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForEditing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\EditableSupplier; - -/** - * Provides data for suppliers add/edit forms - */ -final class SupplierFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var bool - */ - private $multistoreEnabled; - - /** - * @var int[] - */ - private $defaultShopAssociation; - - /** - * @var int - */ - private $contextCountryId; - - /** - * @param CommandBusInterface $queryBus - * @param $multistoreEnabled - * @param int[] $defaultShopAssociation - * @param int $contextCountryId - */ - public function __construct( - CommandBusInterface $queryBus, - $multistoreEnabled, - array $defaultShopAssociation, - $contextCountryId - ) { - $this->queryBus = $queryBus; - $this->multistoreEnabled = $multistoreEnabled; - $this->defaultShopAssociation = $defaultShopAssociation; - $this->contextCountryId = $contextCountryId; - } - - /** - * {@inheritdoc} - * - * @throws SupplierException - */ - public function getData($supplierId) - { - /** @var EditableSupplier $editableSupplier */ - $editableSupplier = $this->queryBus->handle(new GetSupplierForEditing((int) $supplierId)); - - $data = [ - 'name' => $editableSupplier->getName(), - 'description' => $editableSupplier->getLocalizedDescriptions(), - 'phone' => $editableSupplier->getPhone(), - 'mobile_phone' => $editableSupplier->getMobilePhone(), - 'address' => $editableSupplier->getAddress(), - 'address2' => $editableSupplier->getAddress2(), - 'post_code' => $editableSupplier->getPostCode(), - 'city' => $editableSupplier->getCity(), - 'id_country' => $editableSupplier->getCountryId(), - 'id_state' => $editableSupplier->getStateId(), - 'meta_title' => $editableSupplier->getLocalizedMetaTitles(), - 'meta_description' => $editableSupplier->getLocalizedMetaDescriptions(), - 'meta_keyword' => $editableSupplier->getLocalizedMetaKeywords(), - 'is_enabled' => $editableSupplier->isEnabled(), - 'dni' => $editableSupplier->getDni(), - ]; - - if ($this->multistoreEnabled) { - $data['shop_association'] = $editableSupplier->getAssociatedShops(); - } - - return $data; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - $data['is_enabled'] = false; - $data['id_country'] = $this->contextCountryId; - - if ($this->multistoreEnabled) { - $data['shop_association'] = $this->defaultShopAssociation; - } - - return $data; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/TaxFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/TaxFormDataProvider.php deleted file mode 100644 index 9276802f..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/TaxFormDataProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Tax\Query\GetTaxForEditing; -use PrestaShop\PrestaShop\Core\Domain\Tax\QueryResult\EditableTax; - -/** - * Provides Data for tax add/edit form - */ -final class TaxFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $queryBus - */ - public function __construct(CommandBusInterface $queryBus) - { - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getData($taxId) - { - /** @var EditableTax $editableTax */ - $editableTax = $this->queryBus->handle(new GetTaxForEditing($taxId)); - - return [ - 'name' => $editableTax->getLocalizedNames(), - 'rate' => $editableTax->getRate(), - 'is_enabled' => $editableTax->isActive(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'is_enabled' => false, - ]; - } -} diff --git a/src/Core/Form/IdentifiableObject/DataProvider/WebserviceKeyFormDataProvider.php b/src/Core/Form/IdentifiableObject/DataProvider/WebserviceKeyFormDataProvider.php deleted file mode 100644 index 0782fab8..00000000 --- a/src/Core/Form/IdentifiableObject/DataProvider/WebserviceKeyFormDataProvider.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Query\GetWebserviceKeyForEditing; -use PrestaShop\PrestaShop\Core\Domain\Webservice\QueryResult\EditableWebserviceKey; - -/** - * Provides data for webservice key form - */ -final class WebserviceKeyFormDataProvider implements FormDataProviderInterface -{ - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var int[] - */ - private $shopIds; - - /** - * @param CommandBusInterface $queryBus - * @param int[] $shopIds - */ - public function __construct(CommandBusInterface $queryBus, array $shopIds) - { - $this->queryBus = $queryBus; - $this->shopIds = $shopIds; - } - - /** - * {@inheritdoc} - */ - public function getData($webserviceKeyId) - { - /** @var EditableWebserviceKey $editableWebserviceKey */ - $editableWebserviceKey = $this->queryBus->handle(new GetWebserviceKeyForEditing($webserviceKeyId)); - - return [ - 'key' => $editableWebserviceKey->getKey(), - 'description' => $editableWebserviceKey->getDescription(), - 'status' => $editableWebserviceKey->getStatus(), - 'permissions' => $this->normalizeResourcePermissions( - $editableWebserviceKey->getResourcePermissions() - ), - 'shop_association' => $editableWebserviceKey->getAssociatedShops(), - ]; - } - - /** - * {@inheritdoc} - */ - public function getDefaultData() - { - return [ - 'status' => true, - 'shop_association' => $this->shopIds, - ]; - } - - /** - * Normalizes resource permissions to be in format that is accepted by form - * - * @param array $resourcePermissions - * - * @return array - */ - private function normalizeResourcePermissions(array $resourcePermissions) - { - $normalizedResourcePermissions = []; - - foreach ($resourcePermissions as $resource => $permissions) { - foreach ($permissions as $permission) { - $normalizedResourcePermissions[$permission][] = $resource; - } - } - - return $normalizedResourcePermissions; - } -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandler.php b/src/Core/Form/IdentifiableObject/Handler/FormHandler.php deleted file mode 100644 index 36d96ed2..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandler.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\Form\FormError; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Handles identifiable object form and delegates form data saving to data handler. - */ -final class FormHandler implements FormHandlerInterface -{ - /** - * @var FormDataHandlerInterface - */ - private $dataHandler; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var bool - */ - private $isDemoModeEnabled; - - /** - * @param FormDataHandlerInterface $dataHandler - * @param HookDispatcherInterface $hookDispatcher - * @param TranslatorInterface $translator - * @param bool $isDemoModeEnabled - */ - public function __construct( - FormDataHandlerInterface $dataHandler, - HookDispatcherInterface $hookDispatcher, - TranslatorInterface $translator, - $isDemoModeEnabled - ) { - $this->dataHandler = $dataHandler; - $this->hookDispatcher = $hookDispatcher; - $this->translator = $translator; - $this->isDemoModeEnabled = $isDemoModeEnabled; - } - - /** - * {@inheritdoc} - */ - public function handle(FormInterface $form) - { - return $this->handleForm($form); - } - - /** - * {@inheritdoc} - */ - public function handleFor($id, FormInterface $form) - { - return $this->handleForm($form, $id); - } - - /** - * @param FormInterface $form - * @param int|null $id - * - * @return FormHandlerResultInterface - */ - private function handleForm(FormInterface $form, $id = null) - { - if (!$form->isSubmitted()) { - return FormHandlerResult::createNotSubmitted(); - } - - if ($this->isDemoModeEnabled) { - $form->addError( - new FormError( - $this->translator->trans('This functionality has been disabled.', [], 'Admin.Notifications.Error') - ) - ); - - return FormHandlerResult::createSubmittedButNotValid(); - } - - if (!$form->isValid()) { - return FormHandlerResult::createSubmittedButNotValid(); - } - - if (null !== $id) { - return $this->handleFormUpdate($form, $id); - } - - return $this->handleFormCreate($form); - } - - /** - * @param FormInterface $form - * @param int $id - * - * @return FormHandlerResultInterface - */ - private function handleFormUpdate(FormInterface $form, $id) - { - $data = $form->getData(); - - $this->hookDispatcher->dispatchWithParameters('actionBeforeUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ - 'form_data' => &$data, - 'id' => $id, - ]); - - $this->dataHandler->update($id, $data); - - $this->hookDispatcher->dispatchWithParameters('actionAfterUpdate' . Container::camelize($form->getName()) . 'FormHandler', [ - 'id' => $id, - 'form_data' => &$data, - ]); - - return FormHandlerResult::createWithId($id); - } - - /** - * @param FormInterface $form - * - * @return FormHandlerResult - */ - private function handleFormCreate(FormInterface $form) - { - $data = $form->getData(); - - $this->hookDispatcher->dispatchWithParameters( - 'actionBeforeCreate' . Container::camelize($form->getName()) . 'FormHandler', [ - 'form_data' => &$data, - ] - ); - - $id = $this->dataHandler->create($data); - - $this->hookDispatcher->dispatchWithParameters('actionAfterCreate' . Container::camelize($form->getName()) . 'FormHandler', [ - 'id' => $id, - 'form_data' => &$data, - ]); - - return FormHandlerResult::createWithId($id); - } -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactory.php b/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactory.php deleted file mode 100644 index 5d08c96c..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactory.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Creates new form handlers. - */ -final class FormHandlerFactory implements FormHandlerFactoryInterface -{ - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var string - */ - private $isDemoModeEnabled; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param TranslatorInterface $translator - * @param bool $isDemoModeEnabled - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - TranslatorInterface $translator, - $isDemoModeEnabled - ) { - $this->hookDispatcher = $hookDispatcher; - $this->translator = $translator; - $this->isDemoModeEnabled = $isDemoModeEnabled; - } - - /** - * {@inheritdoc} - */ - public function create(FormDataHandlerInterface $dataHandler) - { - return new FormHandler( - $dataHandler, - $this->hookDispatcher, - $this->translator, - $this->isDemoModeEnabled - ); - } -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactoryInterface.php b/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactoryInterface.php deleted file mode 100644 index 27d08405..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandlerFactoryInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FormDataHandlerInterface; - -/** - * Defines interface for form handler factories. - */ -interface FormHandlerFactoryInterface -{ - /** - * Creates new form handler with given data handler. - * - * @param FormDataHandlerInterface $dataHandler - * - * @return FormHandlerInterface - */ - public function create(FormDataHandlerInterface $dataHandler); -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandlerInterface.php b/src/Core/Form/IdentifiableObject/Handler/FormHandlerInterface.php deleted file mode 100644 index 95a7c0a8..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandlerInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -use Symfony\Component\Form\FormInterface; - -/** - * Defines interface for handling identifiable object's form. - */ -interface FormHandlerInterface -{ - /** - * Handles form by creating new object. - * - * @param FormInterface $form - * - * @return FormHandlerResultInterface - */ - public function handle(FormInterface $form); - - /** - * Handles form for given object. - * - * @param int $id - * @param FormInterface $form - * - * @return FormHandlerResultInterface - */ - public function handleFor($id, FormInterface $form); -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandlerResult.php b/src/Core/Form/IdentifiableObject/Handler/FormHandlerResult.php deleted file mode 100644 index d9af8e41..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandlerResult.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -/** - * Stores results for handling forms. - */ -class FormHandlerResult implements FormHandlerResultInterface -{ - /** - * @var bool - */ - private $isValid; - - /** - * @var bool - */ - private $isSubmitted; - - /** - * @var int|null - */ - private $identifiableObjectId; - - /** - * @param int|null $identifiableObjectId ID of identifiable object or null if it does not exist - * @param bool $isSubmitted - * @param bool $isValid - */ - private function __construct($identifiableObjectId, $isSubmitted, $isValid) - { - $this->identifiableObjectId = $identifiableObjectId; - $this->isSubmitted = $isSubmitted; - $this->isValid = $isValid; - } - - /** - * Creates successful form handler result with identifiable object id. - * - * @param int $identifiableObjectId - * - * @return FormHandlerResult - */ - public static function createWithId($identifiableObjectId) - { - return new self( - $identifiableObjectId, - true, - true - ); - } - - /** - * Creates form handler result when form which was provided form handling was not submitted - * - * @return FormHandlerResult - */ - public static function createNotSubmitted() - { - return new self( - null, - false, - false - ); - } - - /** - * Creates result for submitted but not valid form - * - * @return FormHandlerResult - */ - public static function createSubmittedButNotValid() - { - return new self( - null, - true, - false - ); - } - - /** - * @return bool - */ - public function isValid() - { - return $this->isValid; - } - - /** - * @return bool - */ - public function isSubmitted() - { - return $this->isSubmitted; - } - - /** - * @return int|null - */ - public function getIdentifiableObjectId() - { - return $this->identifiableObjectId; - } -} diff --git a/src/Core/Form/IdentifiableObject/Handler/FormHandlerResultInterface.php b/src/Core/Form/IdentifiableObject/Handler/FormHandlerResultInterface.php deleted file mode 100644 index 08f1c3e3..00000000 --- a/src/Core/Form/IdentifiableObject/Handler/FormHandlerResultInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler; - -/** - * Defines interface for form handler result DTO - */ -interface FormHandlerResultInterface -{ - /** - * Check if form is valid and does not contains any errors - * - * @return bool - */ - public function isValid(); - - /** - * Check if form was actually submitted - * - * @return bool - */ - public function isSubmitted(); - - /** - * Get identifiable object id - * - * @return int|null ID of identifiable object or null if it does not exist - */ - public function getIdentifiableObjectId(); -} diff --git a/src/Core/Form/MultiStoreSettingsFormDataProviderInterface.php b/src/Core/Form/MultiStoreSettingsFormDataProviderInterface.php deleted file mode 100644 index 3f004de0..00000000 --- a/src/Core/Form/MultiStoreSettingsFormDataProviderInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Form; - -/** - * Providers additional settings required for multi store form functionality. - */ -interface MultiStoreSettingsFormDataProviderInterface -{ - /** - * Gets data which are used in form data providers. - * - * @return array - they key is the form type field name and the value is true or false. If true, then the multi shop - * checkbox value is selected and otherwise. - */ - public function getData(); -} diff --git a/src/Core/Foundation/Database/DatabaseInterface.php b/src/Core/Foundation/Database/DatabaseInterface.php deleted file mode 100644 index a53c3e34..00000000 --- a/src/Core/Foundation/Database/DatabaseInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -interface DatabaseInterface -{ - public function select($sqlString); - - public function escape($unsafeData); -} diff --git a/src/Core/Foundation/Database/EntityDataInconsistencyException.php b/src/Core/Foundation/Database/EntityDataInconsistencyException.php deleted file mode 100644 index 7ec92bd4..00000000 --- a/src/Core/Foundation/Database/EntityDataInconsistencyException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -class EntityDataInconsistencyException extends Exception -{ -} diff --git a/src/Core/Foundation/Database/EntityInterface.php b/src/Core/Foundation/Database/EntityInterface.php deleted file mode 100644 index dd1baa89..00000000 --- a/src/Core/Foundation/Database/EntityInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -interface EntityInterface -{ - /** - * Returns the name of the repository class for this entity. - * If unspecified, a generic repository will be used for the entity. - * - * @return string or false value - */ - public static function getRepositoryClassName(); - - public function save(); - - public function delete(); - - public function hydrate(array $keyValueData); -} diff --git a/src/Core/Foundation/Database/EntityManager.php b/src/Core/Foundation/Database/EntityManager.php deleted file mode 100644 index 8d9e7dd0..00000000 --- a/src/Core/Foundation/Database/EntityManager.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -use PrestaShop\PrestaShop\Adapter\EntityMetaDataRetriever; - -class EntityManager -{ - private $db; - private $configuration; - - private $entityMetaData = []; - - public function __construct( - DatabaseInterface $db, - \PrestaShop\PrestaShop\Core\ConfigurationInterface $configuration - ) { - $this->db = $db; - $this->configuration = $configuration; - } - - /** - * Return current database object used. - * - * @return DatabaseInterface - */ - public function getDatabase() - { - return $this->db; - } - - /** - * Return current repository used. - * - * @param $className - * - * @return mixed - */ - public function getRepository($className) - { - if (is_callable([$className, 'getRepositoryClassName'])) { - $repositoryClass = call_user_func([$className, 'getRepositoryClassName']); - } else { - $repositoryClass = null; - } - - if (!$repositoryClass) { - $repositoryClass = '\\PrestaShop\\PrestaShop\\Core\\Foundation\\Database\\EntityRepository'; - } - - $repository = new $repositoryClass( - $this, - $this->configuration->get('_DB_PREFIX_'), - $this->getEntityMetaData($className) - ); - - return $repository; - } - - /** - * Return entity's meta data. - * - * @param $className - * - * @return mixed - * - * @throws \PrestaShop\PrestaShop\Adapter\CoreException - */ - public function getEntityMetaData($className) - { - if (!array_key_exists($className, $this->entityMetaData)) { - $metaDataRetriever = new EntityMetaDataRetriever(); - $this->entityMetaData[$className] = $metaDataRetriever->getEntityMetaData($className); - } - - return $this->entityMetaData[$className]; - } - - /** - * Flush entity to DB. - * - * @param EntityInterface $entity - * - * @return $this - */ - public function save(EntityInterface $entity) - { - $entity->save(); - - return $this; - } - - /** - * DElete entity from DB. - * - * @param EntityInterface $entity - * - * @return $this - */ - public function delete(EntityInterface $entity) - { - $entity->delete(); - - return $this; - } -} diff --git a/src/Core/Foundation/Database/EntityManager/QueryBuilder.php b/src/Core/Foundation/Database/EntityManager/QueryBuilder.php deleted file mode 100644 index fae82ef3..00000000 --- a/src/Core/Foundation/Database/EntityManager/QueryBuilder.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database\EntityManager; - -use PrestaShop\PrestaShop\Core\Foundation\Database\Exception; - -class QueryBuilder -{ - private $db; - - public function __construct(\PrestaShop\PrestaShop\Core\Foundation\Database\DatabaseInterface $db) - { - $this->db = $db; - } - - public function quote($value) - { - $escaped = $this->db->escape($value); - - if (is_string($value)) { - return "'" . $escaped . "'"; - } else { - return $escaped; - } - } - - public function buildWhereConditions($andOrOr, array $conditions) - { - $operator = strtoupper($andOrOr); - - if ($operator !== 'AND' && $operator !== 'OR') { - throw new Exception(sprintf('Invalid operator %s - must be "and" or "or".', $andOrOr)); - } - - $parts = []; - - foreach ($conditions as $key => $value) { - if (is_scalar($value)) { - $parts[] = $key . ' = ' . $this->quote($value); - } else { - $list = []; - foreach ($value as $item) { - $list[] = $this->quote($item); - } - $parts[] = $key . ' IN (' . implode(', ', $list) . ')'; - } - } - - return implode(" $operator ", $parts); - } -} diff --git a/src/Core/Foundation/Database/EntityMetaData.php b/src/Core/Foundation/Database/EntityMetaData.php deleted file mode 100644 index c66646e3..00000000 --- a/src/Core/Foundation/Database/EntityMetaData.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -class EntityMetaData -{ - private $tableName; - private $primaryKeyFieldnames; - - public function setTableName($name) - { - $this->tableName = $name; - - return $this; - } - - public function getTableName() - { - return $this->tableName; - } - - public function setPrimaryKeyFieldNames(array $primaryKeyFieldnames) - { - $this->primaryKeyFieldnames = $primaryKeyFieldnames; - - return $this; - } - - public function getPrimaryKeyFieldnames() - { - return $this->primaryKeyFieldnames; - } - - public function setEntityClassName($entityClassName) - { - $this->entityClassName = $entityClassName; - - return $this; - } - - public function getEntityClassName() - { - return $this->entityClassName; - } -} diff --git a/src/Core/Foundation/Database/EntityNotFoundException.php b/src/Core/Foundation/Database/EntityNotFoundException.php deleted file mode 100644 index 1334ae8e..00000000 --- a/src/Core/Foundation/Database/EntityNotFoundException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -class EntityNotFoundException extends Exception -{ -} diff --git a/src/Core/Foundation/Database/EntityRepository.php b/src/Core/Foundation/Database/EntityRepository.php deleted file mode 100644 index 216d740c..00000000 --- a/src/Core/Foundation/Database/EntityRepository.php +++ /dev/null @@ -1,232 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -use PrestaShop\PrestaShop\Core\Foundation\Database\EntityManager\QueryBuilder; - -class EntityRepository -{ - protected $entityManager; - protected $db; - protected $tablesPrefix; - protected $entityMetaData; - protected $queryBuilder; - - public function __construct( - EntityManager $entityManager, - $tablesPrefix, - EntityMetaData $entityMetaData - ) { - $this->entityManager = $entityManager; - $this->db = $this->entityManager->getDatabase(); - $this->tablesPrefix = $tablesPrefix; - $this->entityMetaData = $entityMetaData; - $this->queryBuilder = new QueryBuilder($this->db); - } - - public function __call($method, $arguments) - { - if (0 === strpos($method, 'findOneBy')) { - $one = true; - $by = substr($method, 9); - } elseif (0 === strpos($method, 'findBy')) { - $one = false; - $by = substr($method, 6); - } else { - throw new Exception(sprintf('Undefind method %s.', $method)); - } - - if (count($arguments) !== 1) { - throw new Exception(sprintf('Method %s takes exactly one argument.', $method)); - } - - if (!$by) { - $where = $arguments[0]; - } else { - $where = []; - $by = $this->convertToDbFieldName($by); - $where[$by] = $arguments[0]; - } - - return $this->doFind($one, $where); - } - - /** - * Convert a camelCase field name to a snakeCase one - * e.g.: findAllByIdCMS => id_cms. - * - * @param $camel_case_field_name - * - * @return string - */ - private function convertToDbFieldName($camel_case_field_name) - { - return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $camel_case_field_name)); - } - - /** - * Return ID field name. - * - * @return mixed - * - * @throws Exception - */ - protected function getIdFieldName() - { - $primary = $this->entityMetaData->getPrimaryKeyFieldnames(); - - if (count($primary) === 0) { - throw new Exception(sprintf('No primary key defined in entity `%s`.', $this->entityMetaData->getEntityClassName())); - } elseif (count($primary) > 1) { - throw new Exception(sprintf('Entity `%s` has a composite primary key, which is not supported by entity repositories.', $this->entityMetaData->getEntityClassName())); - } - - return $primary[0]; - } - - /** - * Returns escaped+prefixed current table name. - * - * @return mixed - */ - protected function getTableNameWithPrefix() - { - return $this->db->escape($this->tablesPrefix . $this->entityMetaData->getTableName()); - } - - /** - * Returns escaped DB table prefix. - * - * @return mixed - */ - protected function getPrefix() - { - return $this->db->escape($this->tablesPrefix); - } - - /** - * Return a new empty Entity depending on current Repository selected. - * - * @return mixed - */ - public function getNewEntity() - { - $entityClassName = $this->entityMetaData->getEntityClassName(); - - return new $entityClassName(); - } - - /** - * This function takes an array of database rows as input - * and returns an hydrated entity if there is one row only. - * - * Null is returned when there are no rows, and an exception is thrown - * if there are too many rows. - * - * @param array $rows Database rows - */ - protected function hydrateOne(array $rows) - { - if (count($rows) === 0) { - return null; - } elseif (count($rows) > 1) { - throw new Exception('Too many rows returned.'); - } else { - $data = $rows[0]; - $entity = $this->getNewEntity(); - $entity->hydrate($data); - - return $entity; - } - } - - protected function hydrateMany(array $rows) - { - $entities = []; - foreach ($rows as $row) { - $entity = $this->getNewEntity(); - $entity->hydrate($row); - $entities[] = $entity; - } - - return $entities; - } - - /** - * Constructs and performs 'SELECT' in DB. - * - * @param $one - * @param array $cumulativeConditions - * - * @return array|mixed|null - * - * @throws Exception - */ - private function doFind($one, array $cumulativeConditions) - { - $whereClause = $this->queryBuilder->buildWhereConditions('AND', $cumulativeConditions); - - $sql = 'SELECT * FROM ' . $this->getTableNameWithPrefix() . ' WHERE ' . $whereClause; - - $rows = $this->db->select($sql); - - if ($one) { - return $this->hydrateOne($rows); - } else { - return $this->hydrateMany($rows); - } - } - - /** - * Find one entity in DB. - * - * @param $id - * - * @return array|mixed|null - * - * @throws Exception - */ - public function findOne($id) - { - $conditions = []; - $conditions[$this->getIdFieldName()] = $id; - - return $this->doFind(true, $conditions); - } - - /** - * Find all entities in DB. - * - * @return array - */ - public function findAll() - { - $sql = 'SELECT * FROM ' . $this->getTableNameWithPrefix(); - - return $this->hydrateMany($this->db->select($sql)); - } -} diff --git a/src/Core/Foundation/Database/Exception.php b/src/Core/Foundation/Database/Exception.php deleted file mode 100644 index 5c1f8651..00000000 --- a/src/Core/Foundation/Database/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Database; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class Exception extends CoreException -{ -} diff --git a/src/Core/Foundation/Exception/InvalidVersionException.php b/src/Core/Foundation/Exception/InvalidVersionException.php deleted file mode 100644 index 4ecc25aa..00000000 --- a/src/Core/Foundation/Exception/InvalidVersionException.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * This exception will be thrown if an invalid Shop version name is used - * in the application. - */ -class InvalidVersionException extends CoreException -{ - /** - * Construct. - * - * @param string $version the provided PrestaShop version - */ - public function __construct($version) - { - $message = sprintf( - 'You provided an invalid version string ("%s"). A valid version string ' . - 'must contain numeric characters separated by "." characters, for example "1.7.4.0".', - $version - ); - parent::__construct($message, 0, null); - } -} diff --git a/src/Core/Foundation/Filesystem/Exception.php b/src/Core/Foundation/Filesystem/Exception.php deleted file mode 100644 index cfd9ceab..00000000 --- a/src/Core/Foundation/Filesystem/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Filesystem; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class Exception extends CoreException -{ -} diff --git a/src/Core/Foundation/Filesystem/FileSystem.php b/src/Core/Foundation/Filesystem/FileSystem.php deleted file mode 100644 index 6a998f06..00000000 --- a/src/Core/Foundation/Filesystem/FileSystem.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Filesystem; - -use SplFileInfo; - -class FileSystem -{ - /** - * Default mode for directories - */ - const DEFAULT_MODE_FOLDER = 0755; - - /** - * Default mode for files - */ - const DEFAULT_MODE_FILE = 0644; - - /** - * Replaces directory separators with the system's native one - * and trims the trailing separator. - */ - public function normalizePath($path) - { - return rtrim( - str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path), - DIRECTORY_SEPARATOR - ); - } - - private function joinTwoPaths($a, $b) - { - return $this->normalizePath($a) . DIRECTORY_SEPARATOR . $this->normalizePath($b); - } - - /** - * Joins an arbitrary number of paths, normalizing them along the way. - */ - public function joinPaths() - { - if (func_num_args() < 2) { - throw new Exception('joinPaths requires at least 2 arguments.'); - } elseif (func_num_args() === 2) { - $arg_O = func_get_arg(0); - $arg_1 = func_get_arg(1); - - return $this->joinTwoPaths($arg_O, $arg_1); - } elseif (func_num_args() > 2) { - $func_args = func_get_args(); - $arg_0 = func_get_arg(0); - - return $this->joinPaths( - $arg_0, - call_user_func_array( - [$this, - 'joinPaths', ], - array_slice($func_args, 1) - ) - ); - } - } - - /** - * Performs a depth first listing of directory entries. - * Throws exception if $path is not a file. - * If $path is a file and not a directory, just gets the file info for it - * and return it in an array. - * - * @return an array of SplFileInfo object indexed by file path - */ - public function listEntriesRecursively($path) - { - if (!file_exists($path)) { - throw new Exception(sprintf('No such file or directory: %s', $path)); - } - - if (!is_dir($path)) { - throw new Exception(sprintf('%s is not a directory', $path)); - } - - $entries = []; - - foreach (scandir($path) as $entry) { - if ($entry === '.' || $entry === '..') { - continue; - } - - $newPath = $this->joinPaths($path, $entry); - $info = new SplFileInfo($newPath); - - $entries[$newPath] = $info; - - if ($info->isDir()) { - $entries = array_merge( - $entries, - $this->listEntriesRecursively($newPath) - ); - } - } - - return $entries; - } - - /** - * Filter used by listFilesRecursively. - */ - private function matchOnlyFiles(SplFileInfo $info) - { - return $info->isFile(); - } - - /** - * Same as listEntriesRecursively but returns only files. - */ - public function listFilesRecursively($path) - { - return array_filter( - $this->listEntriesRecursively($path), - [$this, 'matchOnlyFiles'] - ); - } -} diff --git a/src/Core/Foundation/IoC/Container.php b/src/Core/Foundation/IoC/Container.php deleted file mode 100644 index 8186f285..00000000 --- a/src/Core/Foundation/IoC/Container.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\IoC; - -use ReflectionClass; - -class Container -{ - private $bindings = []; - private $instances = []; - private $namespaceAliases = []; - - public function knows($serviceName) - { - return array_key_exists($serviceName, $this->bindings); - } - - private function knowsNamespaceAlias($alias) - { - return array_key_exists($alias, $this->namespaceAliases); - } - - public function bind($serviceName, $constructor, $shared = false) - { - if ($this->knows($serviceName)) { - throw new Exception(sprintf('Cannot bind `%s` again. A service name can only be bound once.', $serviceName)); - } - - $this->bindings[$serviceName] = [ - 'constructor' => $constructor, - 'shared' => $shared, - ]; - - return $this; - } - - public function aliasNamespace($alias, $namespacePrefix) - { - if ($this->knowsNamespaceAlias($alias)) { - throw new Exception(sprintf('Namespace alias `%1$s` already exists and points to `%2$s`', $alias, $this->namespaceAliases[$alias])); - } - - $this->namespaceAliases[$alias] = $namespacePrefix; - - return $this; - } - - public function resolveClassName($className) - { - $colonPos = strpos($className, ':'); - if (0 !== $colonPos && false !== $colonPos) { - $alias = substr($className, 0, $colonPos); - if ($this->knowsNamespaceAlias($alias)) { - $class = ltrim(substr($className, $colonPos + 1), '\\'); - - return $this->namespaceAliases[$alias] . '\\' . $class; - } - } - - return $className; - } - - private function makeInstanceFromClassName($className, array $alreadySeen) - { - $className = $this->resolveClassName($className); - - try { - $refl = new ReflectionClass($className); - } catch (\ReflectionException $re) { - throw new Exception(sprintf('This doesn\'t seem to be a class name: `%s`.', $className)); - } - - $args = []; - - if ($refl->isAbstract()) { - throw new Exception(sprintf('Cannot build abstract class: `%s`.', $className)); - } - - $classConstructor = $refl->getConstructor(); - - if ($classConstructor) { - foreach ($classConstructor->getParameters() as $param) { - $paramClass = $param->getClass(); - if ($paramClass) { - $args[] = $this->doMake($param->getClass()->getName(), $alreadySeen); - } elseif ($param->isDefaultValueAvailable()) { - $args[] = $param->getDefaultValue(); - } else { - throw new Exception(sprintf('Cannot build a `%s`.', $className)); - } - } - } - - if (count($args) > 0) { - return $refl->newInstanceArgs($args); - } else { - // newInstanceArgs with empty array fails in PHP 5.3 when the class - // doesn't have an explicitly defined constructor - return $refl->newInstance(); - } - } - - private function doMake($serviceName, array $alreadySeen = []) - { - if (array_key_exists($serviceName, $alreadySeen)) { - throw new Exception(sprintf('Cyclic dependency detected while building `%s`.', $serviceName)); - } - - $alreadySeen[$serviceName] = true; - - if (!$this->knows($serviceName)) { - $this->bind($serviceName, $serviceName); - } - - $binding = $this->bindings[$serviceName]; - - if ($binding['shared'] && array_key_exists($serviceName, $this->instances)) { - return $this->instances[$serviceName]; - } else { - $constructor = $binding['constructor']; - - if (is_callable($constructor)) { - $service = call_user_func($constructor); - } elseif (!is_string($constructor)) { - // user already provided the value, no need to construct it. - $service = $constructor; - } else { - // assume the $constructor is a class name - $service = $this->makeInstanceFromClassName($constructor, $alreadySeen); - } - - if ($binding['shared']) { - $this->instances[$serviceName] = $service; - } - - return $service; - } - } - - public function make($serviceName) - { - return $this->doMake($serviceName, []); - } -} diff --git a/src/Core/Foundation/IoC/Exception.php b/src/Core/Foundation/IoC/Exception.php deleted file mode 100644 index e8e8f343..00000000 --- a/src/Core/Foundation/IoC/Exception.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\IoC; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class Exception extends CoreException -{ -} diff --git a/src/Core/Foundation/Templating/PresenterInterface.php b/src/Core/Foundation/Templating/PresenterInterface.php deleted file mode 100644 index 380a23a6..00000000 --- a/src/Core/Foundation/Templating/PresenterInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Templating; - -interface PresenterInterface -{ - public function present($object); // must return an array -} diff --git a/src/Core/Foundation/Templating/RenderableInterface.php b/src/Core/Foundation/Templating/RenderableInterface.php deleted file mode 100644 index ce5b3379..00000000 --- a/src/Core/Foundation/Templating/RenderableInterface.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Templating; - -interface RenderableInterface -{ - public function setTemplate($templatePath); - - public function getTemplate(); - - public function render(array $extraParams = []); -} diff --git a/src/Core/Foundation/Templating/RenderableProxy.php b/src/Core/Foundation/Templating/RenderableProxy.php deleted file mode 100644 index 04cb5614..00000000 --- a/src/Core/Foundation/Templating/RenderableProxy.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation\Templating; - -class RenderableProxy -{ - private $renderable; - - public function __construct(RenderableInterface $renderable) - { - $this->renderable = $renderable; - } - - public function setTemplate($templatePath) - { - $this->renderable->setTemplate($templatePath); - - return $this; - } - - public function getTemplate() - { - return $this->renderable->getTemplate(); - } - - public function render(array $extraParams = []) - { - return $this->renderable->render($extraParams); - } -} diff --git a/src/Core/Foundation/Version.php b/src/Core/Foundation/Version.php deleted file mode 100644 index eff74840..00000000 --- a/src/Core/Foundation/Version.php +++ /dev/null @@ -1,394 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Foundation; - -use PrestaShop\PrestaShop\Core\Foundation\Exception\InvalidVersionException; - -/** - * Class responsible of managing the right version of Shop - * for every internal/external services. - */ -class Version -{ - /** - * Full version name. - * - * @var string - */ - private $version; - - /** - * Major version name. - * - * @var string - */ - private $majorVersionString; - - /** - * Major version. - * - * @var int - */ - private $majorVersion; - - /** - * Minor version. - * - * @var int - */ - private $minorVersion; - - /** - * Patch version. - * - * @var int - */ - private $patchVersion; - - /** - * Pre release version, (eg. "dev", "beta"...) - * - * @var string - */ - private $preReleaseVersion; - - /** - * Build metadata (eg. build number) - * - * @var string - */ - private $buildMetadata; - - /** - * Initialize version data. - * - * @param string $version Version - * @param string $majorVersionString Legacy major version in string format (eg. "1.7") - * @param int $majorVersion Major version - * @param int $minorVersion [default=0] Minor version - * @param int $patchVersion [default=0] Patch version - * @param string $preReleaseVersion [default=''] Pre release version (eg. "dev", "beta"...) - * @param string $buildMetadata [default=''] Build metadata (eg. build number) - */ - public function __construct( - $version, - $majorVersionString, - $majorVersion, - $minorVersion = 0, - $patchVersion = 0, - $preReleaseVersion = '', - $buildMetadata = '' - ) { - $this->version = $this->removeLegacyPrefix($version, $majorVersionString); - $this->majorVersionString = $majorVersionString; - $this->majorVersion = $majorVersion; - $this->minorVersion = $minorVersion; - $this->patchVersion = $patchVersion; - $this->preReleaseVersion = $preReleaseVersion; - $this->buildMetadata = $buildMetadata; - } - - /** - * Builds an instance form a version string - * - * @param string $version - * - * @return self - * - * @throws InvalidVersionException If the version is invalid - */ - public static function buildFromString($version) - { - $matches = []; - $regex = '/^([\d]+)(?:\.([\d]+))?(?:\.([\d]+))?(?:\.(?[\d]+))?(?:-(?[0-9A-Za-z-.]+))?(?:\+(?[0-9A-Za-z-.]+))?$/'; - - if (!preg_match($regex, $version, $matches)) { - throw new InvalidVersionException($version); - } - - if (isset($matches['legacy']) && '' !== $matches['legacy']) { - // legacy version like "1.7.5.0" - $major = (int) $matches[2]; - $minor = (int) $matches[3]; - $patch = (int) $matches['legacy']; - $version = substr($version, strpos($version, '.') + 1); - } else { - $major = (int) $matches[1]; - $minor = isset($matches[2]) ? (int) $matches[2] : 0; - $patch = isset($matches[3]) ? (int) $matches[3] : 0; - } - - return new self( - $version, - "1.$major", - $major, - $minor, - $patch, - isset($matches['prerelease']) ? $matches['prerelease'] : '', - isset($matches['build']) ? $matches['build'] : '' - ); - } - - /** - * Returns the current version in legacy format (eg. "1.7.6.0") - * - * @param bool $full [default=false] If true, include pre-release and build metadata (eg. "1.7.6.0-dev+build.1") - * - * @return string - */ - public function getVersion($full = false) - { - $version = '1.' . $this->version; - - if (!$full) { - // remove extra parts - return preg_replace('/[-\+].*/', '', $version); - } - - return $version; - } - - /** - * Returns SemVer compliant version (eg. "7.6.0") - * - * @return string - */ - public function getSemVersion() - { - return $this->version; - } - - /** - * Returns the current major version as a string. - * - * @return string For example "1.7" - */ - public function getMajorVersionString() - { - return $this->majorVersionString; - } - - /** - * Returns the current major version as an integer. - * - * @return int For example 17 - */ - public function getMajorVersion() - { - return $this->majorVersion; - } - - /** - * Returns the current minor version. - * - * @return int - */ - public function getMinorVersion() - { - return $this->minorVersion; - } - - /** - * Returns the current patch version. - * - * @return int - */ - public function getPatchVersion() - { - return $this->patchVersion; - } - - /** - * Returns the current release version. - * - * @deprecated Since 1.7.6.0, use getPatchVersion(); - * - * @return int - */ - public function getReleaseVersion() - { - @trigger_error( - 'getReleaseVersion() is deprecated since version 1.7.6.0 Use getPatchVersion() instead.', - E_USER_DEPRECATED - ); - - return $this->getPatchVersion(); - } - - /** - * Returns the current pre release version (if any) - * - * @return string - */ - public function getPreReleaseVersion() - { - return $this->preReleaseVersion; - } - - /** - * Returns the current build metadata (if any) - * - * @return string - */ - public function getBuildMetadata() - { - return $this->buildMetadata; - } - - /** - * Returns if the current version is greater than the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isGreaterThan($version) - { - return $this->versionCompare($version, '>'); - } - - /** - * Returns if the current version is greater than or equal to the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isGreaterThanOrEqualTo($version) - { - return $this->versionCompare($version, '>='); - } - - /** - * Returns if the current version is less than the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isLessThan($version) - { - return $this->versionCompare($version, '<'); - } - - /** - * Returns if the current version is less than or equal to the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isLessThanOrEqualTo($version) - { - return $this->versionCompare($version, '<='); - } - - /** - * Returns if the current version is equal to the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isEqualTo($version) - { - return $this->versionCompare($version, '='); - } - - /** - * Returns if the current version is not equal to the provided version. - * - * @param $version Must be a valid version string, for example "1.7.4.0" - * - * @return bool - * - * @throws InvalidVersionException If the provided version is invalid - */ - public function isNotEqualTo($version) - { - return $this->versionCompare($version, '!='); - } - - /** - * Returns the semantic version string - */ - public function __toString() - { - return $this->getSemVersion(); - } - - /** - * Compares the current version with the provided version depending on the provided operator. - * It sanitized both version to have a. - * - * @param $version string Must be a valid version string, for example "1.7.4.0" - * @param $operator string Operator for version_compare(), - * allowed values are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne - * - * @return bool result of the comparison - * - * @throws InvalidVersionException if the provided version is invalid - */ - private function versionCompare($version, $operator) - { - $otherVersion = self::buildFromString($version); - - $first = $this->getSemVersion(); - $other = $otherVersion->getSemVersion(); - - $result = version_compare($first, $other, $operator); - - return $result; - } - - /** - * Remove legacy 1.x prefix if needed - * - * @param string $version - * @param string $majorVersionString - * - * @return bool|string - */ - private function removeLegacyPrefix($version, $majorVersionString) - { - if ('1.' === substr($version, 0, 2) && substr($version, 0, strlen($majorVersionString)) === $majorVersionString) { - $version = substr($version, 2); - } - - return $version; - } -} diff --git a/src/Core/Geolocation/GeoLite/GeoLiteCityChecker.php b/src/Core/Geolocation/GeoLite/GeoLiteCityChecker.php deleted file mode 100644 index 4674745a..00000000 --- a/src/Core/Geolocation/GeoLite/GeoLiteCityChecker.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Geolocation\GeoLite; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class GeoLiteCityChecker is responsible for checking if GeoLiteCity data is available. - */ -final class GeoLiteCityChecker implements GeoLiteCityCheckerInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function isAvailable() - { - $geoIpDir = $this->configuration->get('_PS_GEOIP_DIR_'); - $geoLiteCityFile = $this->configuration->get('_PS_GEOIP_CITY_FILE_'); - - return file_exists($geoIpDir . $geoLiteCityFile); - } -} diff --git a/src/Core/Geolocation/GeoLite/GeoLiteCityCheckerInterface.php b/src/Core/Geolocation/GeoLite/GeoLiteCityCheckerInterface.php deleted file mode 100644 index b85195cc..00000000 --- a/src/Core/Geolocation/GeoLite/GeoLiteCityCheckerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Geolocation\GeoLite; - -/** - * Interface GeoLiteCityInterface defines contract for GeoLiteCity. - */ -interface GeoLiteCityCheckerInterface -{ - /** - * Check if GeoLiteCity data is available in PrestaShop installation. - * - * @return bool - */ - public function isAvailable(); -} diff --git a/src/Core/Grid/Action/AbstractGridAction.php b/src/Core/Grid/Action/AbstractGridAction.php deleted file mode 100644 index a05c1521..00000000 --- a/src/Core/Grid/Action/AbstractGridAction.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action; - -use Symfony\Component\OptionsResolver\OptionsResolver; - -abstract class AbstractGridAction implements GridActionInterface -{ - /** - * @var string - */ - private $id; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $type; - - /** - * @var string - */ - private $icon; - - /** - * @var array - */ - private $options; - - /** - * @param string $id - */ - public function __construct($id) - { - $this->id = $id; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getIcon() - { - return $this->icon; - } - - /** - * {@inheritdoc} - */ - public function setIcon($icon) - { - $this->icon = $icon; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $this->resolveOptions($options); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - if (null === $this->options) { - $this->resolveOptions(); - } - - return $this->options; - } - - /** - * Default bulk action options configuration. You can override it if options are needed. - * - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - } - - /** - * Resolve action options. - * - * @param array $options - */ - private function resolveOptions(array $options = []) - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - - $this->options = $resolver->resolve($options); - } -} diff --git a/src/Core/Grid/Action/Bulk/AbstractBulkAction.php b/src/Core/Grid/Action/Bulk/AbstractBulkAction.php deleted file mode 100644 index 7ef10587..00000000 --- a/src/Core/Grid/Action/Bulk/AbstractBulkAction.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk; - -use Symfony\Component\OptionsResolver\OptionsResolver; - -abstract class AbstractBulkAction implements BulkActionInterface -{ - /** - * @var string - */ - private $id; - - /** - * @var string - */ - protected $name; - - /** - * @var array - */ - private $options; - - /** - * @param string $id - */ - public function __construct($id) - { - $this->id = $id; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $this->resolveOptions($options); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - if (null === $this->options) { - $this->resolveOptions(); - } - - return $this->options; - } - - /** - * Default bulk action options configuration. You can override it if options are needed. - * - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - } - - /** - * Resolve bulk action options. - * - * @param array $options - */ - private function resolveOptions(array $options = []) - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - - $this->options = $resolver->resolve($options); - } -} diff --git a/src/Core/Grid/Action/Bulk/BulkActionCollection.php b/src/Core/Grid/Action/Bulk/BulkActionCollection.php deleted file mode 100644 index 7281e729..00000000 --- a/src/Core/Grid/Action/Bulk/BulkActionCollection.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; - -/** - * Class BulkActionCollection holds bulk action collection available for grid. - * - * @property BulkActionInterface[] $items - */ -final class BulkActionCollection extends AbstractCollection implements BulkActionCollectionInterface -{ - /** - * {@inheritdoc} - */ - public function add(BulkActionInterface $bulkAction) - { - $this->items[$bulkAction->getId()] = $bulkAction; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - $bulkActionsArray = []; - - foreach ($this->items as $bulkAction) { - $bulkActionsArray[] = [ - 'id' => $bulkAction->getId(), - 'name' => $bulkAction->getName(), - 'type' => $bulkAction->getType(), - 'options' => $bulkAction->getOptions(), - ]; - } - - return $bulkActionsArray; - } -} diff --git a/src/Core/Grid/Action/Bulk/BulkActionCollectionInterface.php b/src/Core/Grid/Action/Bulk/BulkActionCollectionInterface.php deleted file mode 100644 index 1fe5fece..00000000 --- a/src/Core/Grid/Action/Bulk/BulkActionCollectionInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk; - -use Iterator; - -/** - * Interface BulkActionCollectionInterface defines bulk actions contract. - */ -interface BulkActionCollectionInterface extends Iterator -{ - /** - * Add bulk action to collection. - * - * @param BulkActionInterface $bulkAction - * - * @return self - */ - public function add(BulkActionInterface $bulkAction); - - /** - * Get bulk actions as array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Grid/Action/Bulk/BulkActionInterface.php b/src/Core/Grid/Action/Bulk/BulkActionInterface.php deleted file mode 100644 index e35fd0c0..00000000 --- a/src/Core/Grid/Action/Bulk/BulkActionInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk; - -/** - * Interface BulkActionInterface defines contract for single grid bulk action. - */ -interface BulkActionInterface -{ - /** - * Get unique bulk action identifier for grid. - * - * @return string - */ - public function getId(); - - /** - * Get translated bulk action name. - * - * @return string - */ - public function getName(); - - /** - * Get action type. - * - * @return string - */ - public function getType(); - - /** - * Get action options. - * - * @return array - */ - public function getOptions(); - - /** - * Set options for bulk action. - * - * @param array $options - * - * @return self - */ - public function setOptions(array $options); - - /** - * Set bulk action name. - * - * @param string $name - * - * @return self - */ - public function setName($name); -} diff --git a/src/Core/Grid/Action/Bulk/Type/ButtonBulkAction.php b/src/Core/Grid/Action/Bulk/Type/ButtonBulkAction.php deleted file mode 100644 index ccc78caf..00000000 --- a/src/Core/Grid/Action/Bulk/Type/ButtonBulkAction.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\AbstractBulkAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ButtonBulkAction holds data to display a simple button, it allows you to - * set a (required) class and additional (optional) attributes that can then be used - * in javascript. - */ -final class ButtonBulkAction extends AbstractBulkAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'button'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'class', - ]) - ->setDefaults([ - 'attributes' => [], - ]) - ->setAllowedTypes('class', 'string') - ->setAllowedTypes('attributes', 'array'); - } -} diff --git a/src/Core/Grid/Action/Bulk/Type/Catalog/Category/DeleteCategoriesBulkAction.php b/src/Core/Grid/Action/Bulk/Type/Catalog/Category/DeleteCategoriesBulkAction.php deleted file mode 100644 index 2272d9ba..00000000 --- a/src/Core/Grid/Action/Bulk/Type/Catalog/Category/DeleteCategoriesBulkAction.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\Catalog\Category; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\AbstractBulkAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class DeleteCategoriesBulkAction implements bulk deleting for categories grid. - */ -final class DeleteCategoriesBulkAction extends AbstractBulkAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'delete_categories'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'categories_bulk_delete_route', - ]) - ->setAllowedTypes('categories_bulk_delete_route', 'string'); - } -} diff --git a/src/Core/Grid/Action/Bulk/Type/Customer/DeleteCustomersBulkAction.php b/src/Core/Grid/Action/Bulk/Type/Customer/DeleteCustomersBulkAction.php deleted file mode 100644 index 6b39c48c..00000000 --- a/src/Core/Grid/Action/Bulk/Type/Customer/DeleteCustomersBulkAction.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\Customer; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\AbstractBulkAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Allows to configure "Delete" customers bulk action. - */ -final class DeleteCustomersBulkAction extends AbstractBulkAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'delete_customers'; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'customers_bulk_delete_route', - ]) - ->setAllowedTypes('customers_bulk_delete_route', 'string') - ; - } -} diff --git a/src/Core/Grid/Action/Bulk/Type/ModalFormSubmitBulkAction.php b/src/Core/Grid/Action/Bulk/Type/ModalFormSubmitBulkAction.php deleted file mode 100644 index a07fc34c..00000000 --- a/src/Core/Grid/Action/Bulk/Type/ModalFormSubmitBulkAction.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\AbstractBulkAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Bulk actions that submit form in modal - */ -final class ModalFormSubmitBulkAction extends AbstractBulkAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'modal_form_submit'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'submit_route', - 'modal_id', - ]) - ->setAllowedTypes('submit_route', 'string') - ->setAllowedTypes('modal_id', 'string') - ; - } -} diff --git a/src/Core/Grid/Action/Bulk/Type/SubmitBulkAction.php b/src/Core/Grid/Action/Bulk/Type/SubmitBulkAction.php deleted file mode 100644 index e4219487..00000000 --- a/src/Core/Grid/Action/Bulk/Type/SubmitBulkAction.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\AbstractBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\ModalOptions; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class BulkAction holds data about single bulk action available in grid. - */ -final class SubmitBulkAction extends AbstractBulkAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'submit'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'submit_route', - ]) - ->setDefaults([ - 'confirm_message' => null, - 'modal_options' => null, - 'submit_method' => 'POST', - 'route_params' => [], - ]) - ->setAllowedTypes('submit_route', 'string') - ->setAllowedTypes('confirm_message', ['string', 'null']) - ->setAllowedTypes('modal_options', [ModalOptions::class, 'null']) - ->setAllowedValues('submit_method', ['POST', 'GET']) - ->setAllowedTypes('route_params', 'array'); - } -} diff --git a/src/Core/Grid/Action/GridActionCollection.php b/src/Core/Grid/Action/GridActionCollection.php deleted file mode 100644 index bd34b465..00000000 --- a/src/Core/Grid/Action/GridActionCollection.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; - -/** - * Class PanelActionCollection is responsible for holding single grid actions. - * - * @property GridActionInterface[] $items - */ -final class GridActionCollection extends AbstractCollection implements GridActionCollectionInterface -{ - /** - * {@inheritdoc} - */ - public function add(GridActionInterface $action) - { - $this->items[$action->getId()] = $action; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - $actionsArray = []; - - foreach ($this->items as $action) { - $actionsArray[] = [ - 'id' => $action->getId(), - 'name' => $action->getName(), - 'icon' => $action->getIcon(), - 'type' => $action->getType(), - 'options' => $action->getOptions(), - ]; - } - - return $actionsArray; - } -} diff --git a/src/Core/Grid/Action/GridActionCollectionInterface.php b/src/Core/Grid/Action/GridActionCollectionInterface.php deleted file mode 100644 index 1bb818d3..00000000 --- a/src/Core/Grid/Action/GridActionCollectionInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action; - -use Iterator; - -/** - * Interface PanelActionCollectionInterface defines contract for grid action collection. - */ -interface GridActionCollectionInterface extends Iterator -{ - /** - * Add grid action to collection. - * - * @param GridActionInterface $action - * - * @return self - */ - public function add(GridActionInterface $action); - - /** - * Get grid panel actions as array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Grid/Action/GridActionInterface.php b/src/Core/Grid/Action/GridActionInterface.php deleted file mode 100644 index f3c7967b..00000000 --- a/src/Core/Grid/Action/GridActionInterface.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action; - -/** - * Interface GridActionInterface. - */ -interface GridActionInterface -{ - /** - * Return unique action identifier. - * - * @return string - */ - public function getId(); - - /** - * Returns translated action name. - * - * @return string - */ - public function getName(); - - /** - * Set action name. - * - * @param string $name - * - * @return self - */ - public function setName($name); - - /** - * Returns action icon name. - * - * @return string - */ - public function getIcon(); - - /** - * Set action icon name. - * - * @param string $icon - * - * @return string - */ - public function setIcon($icon); - - /** - * Returns grid action type. - * - * @return string - */ - public function getType(); - - /** - * Get action options. - * - * @return array - */ - public function getOptions(); - - /** - * Set action options. - * - * @param array $options - * - * @return self - */ - public function setOptions(array $options); -} diff --git a/src/Core/Grid/Action/ModalOptions.php b/src/Core/Grid/Action/ModalOptions.php deleted file mode 100644 index 3f90c793..00000000 --- a/src/Core/Grid/Action/ModalOptions.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action; - -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ModalOptions used to configure modal used in actions like SubmitBulkAction - */ -class ModalOptions -{ - /** - * @var array - */ - private $options; - - /** - * @param array $options - */ - public function __construct(array $options = []) - { - $this->setOptions($options); - } - - /** - * @return array - */ - public function getOptions(): array - { - return $this->options; - } - - /** - * @param array $options - * - * @return ModalOptions - */ - public function setOptions(array $options): ModalOptions - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - - $this->options = $resolver->resolve($options); - - return $this; - } - - /** - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'title' => null, - 'confirm_button_label' => null, - 'confirm_button_class' => 'btn-primary', - 'close_button_label' => null, - ]) - ->setAllowedTypes('title', ['string', 'null']) - ->setAllowedTypes('confirm_button_label', ['string', 'null']) - ->setAllowedTypes('confirm_button_class', 'string') - ; - } -} diff --git a/src/Core/Grid/Action/Row/AbstractRowAction.php b/src/Core/Grid/Action/Row/AbstractRowAction.php deleted file mode 100644 index cddddba1..00000000 --- a/src/Core/Grid/Action/Row/AbstractRowAction.php +++ /dev/null @@ -1,166 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row; - -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class AbstractRowAction. - */ -abstract class AbstractRowAction implements RowActionInterface -{ - /** - * @var string - */ - private $id; - - /** - * @var string - */ - private $name; - - /** - * @var array|null - */ - private $options; - - /** - * @var string - */ - private $icon; - - /** - * @param string $id - */ - public function __construct($id) - { - $this->id = $id; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getIcon() - { - return $this->icon; - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setIcon($icon) - { - $this->icon = $icon; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $this->resolveOptions($options); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - if (null === $this->options) { - $this->resolveOptions(); - } - - return $this->options; - } - - /** - * {@inheritdoc} - */ - public function isApplicable(array $record) - { - return true; - } - - /** - * Default action options configuration. You can override it if options are needed. - * - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'use_inline_display' => false, - ]) - // if set to true then it displays only icons - ->setAllowedTypes('use_inline_display', 'bool') - ; - } - - /** - * Resolve action options. - * - * @param array $options - */ - private function resolveOptions(array $options = []) - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - - $this->options = $resolver->resolve($options); - } -} diff --git a/src/Core/Grid/Action/Row/AccessibilityChecker/AccessibilityCheckerInterface.php b/src/Core/Grid/Action/Row/AccessibilityChecker/AccessibilityCheckerInterface.php deleted file mode 100644 index ca8b0dab..00000000 --- a/src/Core/Grid/Action/Row/AccessibilityChecker/AccessibilityCheckerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker; - -/** - * Interface ApplicabilityCheckerInterface. - */ -interface AccessibilityCheckerInterface -{ - /** - * Check if record is applicable for row action. - * - * @param array $record - * - * @return bool - */ - public function isGranted(array $record); -} diff --git a/src/Core/Grid/Action/Row/AccessibilityChecker/DeleteProfileAccessibilityChecker.php b/src/Core/Grid/Action/Row/AccessibilityChecker/DeleteProfileAccessibilityChecker.php deleted file mode 100644 index 93d10059..00000000 --- a/src/Core/Grid/Action/Row/AccessibilityChecker/DeleteProfileAccessibilityChecker.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker; - -/** - * Class DeleteProfileAccessibilityChecker. - * - * @internal - */ -final class DeleteProfileAccessibilityChecker implements AccessibilityCheckerInterface -{ - /** - * @var int - */ - private $superAdminProfileId; - - /** - * @param int $superAdminProfileId - */ - public function __construct($superAdminProfileId) - { - $this->superAdminProfileId = $superAdminProfileId; - } - - /** - * {@inheritdoc} - */ - public function isGranted(array $profile) - { - return $profile['id_profile'] != $this->superAdminProfileId; - } -} diff --git a/src/Core/Grid/Action/Row/AccessibilityChecker/PrintDeliverySlipAccessibilityChecker.php b/src/Core/Grid/Action/Row/AccessibilityChecker/PrintDeliverySlipAccessibilityChecker.php deleted file mode 100644 index edf4ca5a..00000000 --- a/src/Core/Grid/Action/Row/AccessibilityChecker/PrintDeliverySlipAccessibilityChecker.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker; - -/** - * Checks if print delivery slip option can be visible in order list. - */ -final class PrintDeliverySlipAccessibilityChecker implements AccessibilityCheckerInterface -{ - /** - * {@inheritdoc} - */ - public function isGranted(array $record) - { - return $record['delivery_number'] ?? null; - } -} diff --git a/src/Core/Grid/Action/Row/AccessibilityChecker/PrintInvoiceAccessibilityChecker.php b/src/Core/Grid/Action/Row/AccessibilityChecker/PrintInvoiceAccessibilityChecker.php deleted file mode 100644 index e2400e90..00000000 --- a/src/Core/Grid/Action/Row/AccessibilityChecker/PrintInvoiceAccessibilityChecker.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker; - -/** - * Checks if print invoice option can be visible in order list. - */ -final class PrintInvoiceAccessibilityChecker implements AccessibilityCheckerInterface -{ - /** - * {@inheritdoc} - */ - public function isGranted(array $record) - { - return $record['is_invoice_available'] ?? null; - } -} diff --git a/src/Core/Grid/Action/Row/RowActionCollection.php b/src/Core/Grid/Action/Row/RowActionCollection.php deleted file mode 100644 index 230dcf1d..00000000 --- a/src/Core/Grid/Action/Row/RowActionCollection.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; - -/** - * Class RowActionCollection defines contract for grid row action collection. - */ -final class RowActionCollection extends AbstractCollection implements RowActionCollectionInterface -{ - /** - * {@inheritdoc} - */ - public function add(RowActionInterface $action) - { - $this->items[$action->getId()] = $action; - - return $this; - } -} diff --git a/src/Core/Grid/Action/Row/RowActionCollectionInterface.php b/src/Core/Grid/Action/Row/RowActionCollectionInterface.php deleted file mode 100644 index 1befaebd..00000000 --- a/src/Core/Grid/Action/Row/RowActionCollectionInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row; - -use Iterator; - -/** - * Interface RowActionCollectionInterface defines contract for row actions collection. - */ -interface RowActionCollectionInterface extends Iterator -{ - /** - * Add row action to collection. - * - * @param RowActionInterface $action - * - * @return self - */ - public function add(RowActionInterface $action); -} diff --git a/src/Core/Grid/Action/Row/RowActionInterface.php b/src/Core/Grid/Action/Row/RowActionInterface.php deleted file mode 100644 index f788e3e5..00000000 --- a/src/Core/Grid/Action/Row/RowActionInterface.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row; - -/** - * Interface RowActionInterface defines contract for grid's row action. - */ -interface RowActionInterface -{ - /** - * Get unique row id for grid row's action. - * - * @return string - */ - public function getId(); - - /** - * Get action type. - * - * @return string - */ - public function getType(); - - /** - * Get translated row action name. - * - * @return string - */ - public function getName(); - - /** - * Set action name. - * - * @param string $name - * - * @return self - */ - public function setName($name); - - /** - * Get row action icon. - * - * @return string - */ - public function getIcon(); - - /** - * Set action icon. - * - * @param string $icon - * - * @return self - */ - public function setIcon($icon); - - /** - * Get action options. - * - * @return array - */ - public function getOptions(); - - /** - * Set action options. - * - * @param array $options - * - * @return self - */ - public function setOptions(array $options); - - /** - * Check if action is applicable for given record. - * - * @param array $record - * - * @return bool - */ - public function isApplicable(array $record); -} diff --git a/src/Core/Grid/Action/Row/Type/Category/DeleteCategoryRowAction.php b/src/Core/Grid/Action/Row/Type/Category/DeleteCategoryRowAction.php deleted file mode 100644 index 4776a199..00000000 --- a/src/Core/Grid/Action/Row/Type/Category/DeleteCategoryRowAction.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\Category; - -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AbstractRowAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class DeleteCategoryRowAction adds "Delete" action to row. - */ -final class DeleteCategoryRowAction extends AbstractRowAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'delete_category'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'category_id_field', - 'category_delete_route', - ]) - ->setAllowedTypes('category_id_field', 'string') - ->setAllowedTypes('category_delete_route', 'string'); - } -} diff --git a/src/Core/Grid/Action/Row/Type/Customer/DeleteCustomerRowAction.php b/src/Core/Grid/Action/Row/Type/Customer/DeleteCustomerRowAction.php deleted file mode 100644 index f098881d..00000000 --- a/src/Core/Grid/Action/Row/Type/Customer/DeleteCustomerRowAction.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\Customer; - -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AbstractRowAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class DeleteCustomerRowAction extends AbstractRowAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'delete_customer'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'customer_id_field', - 'customer_delete_route', - ]) - ->setAllowedTypes('customer_id_field', 'string') - ->setAllowedTypes('customer_delete_route', 'string') - ; - } -} diff --git a/src/Core/Grid/Action/Row/Type/LinkRowAction.php b/src/Core/Grid/Action/Row/Type/LinkRowAction.php deleted file mode 100644 index 7b15983c..00000000 --- a/src/Core/Grid/Action/Row/Type/LinkRowAction.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AbstractRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class LinkRowAction extends AbstractRowAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'link'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'route', - 'route_param_name', - 'route_param_field', - ]) - ->setDefaults([ - 'confirm_message' => '', - 'accessibility_checker' => null, - //pass extra_route_params in case one param is not enough. - //route_param_name and route_param_field becomes redundant, but it cannot be removed due to BC break - 'extra_route_params' => [], - 'clickable_row' => false, - ]) - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('route_param_name', 'string') - ->setAllowedTypes('route_param_field', 'string') - ->setAllowedTypes('extra_route_params', 'array') - ->setAllowedTypes('confirm_message', 'string') - ->setAllowedTypes('accessibility_checker', [AccessibilityCheckerInterface::class, 'callable', 'null']) - ->setAllowedTypes('clickable_row', 'boolean') - ; - } - - /** - * {@inheritdoc} - */ - public function isApplicable(array $record) - { - $accessibilityChecker = $this->getOptions()['accessibility_checker']; - - if ($accessibilityChecker instanceof AccessibilityCheckerInterface) { - return $accessibilityChecker->isGranted($record); - } - - if (is_callable($accessibilityChecker)) { - return call_user_func($accessibilityChecker, $record); - } - - return parent::isApplicable($record); - } -} diff --git a/src/Core/Grid/Action/Row/Type/SubmitRowAction.php b/src/Core/Grid/Action/Row/Type/SubmitRowAction.php deleted file mode 100644 index 1888bd26..00000000 --- a/src/Core/Grid/Action/Row/Type/SubmitRowAction.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Row\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AbstractRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Defines row action as form submit. - */ -final class SubmitRowAction extends AbstractRowAction -{ - const MESSAGE_TYPE_STATIC = 'static'; // Static confirmation message type is standard confirmation message type - const MESSAGE_TYPE_DYNAMIC = 'dynamic'; // Dynamic confirmation message type enables dynamic confirmation message - - /** - * {@inheritdoc} - */ - public function getType() - { - return 'submit'; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'route', - 'route_param_name', - 'route_param_field', - ]) - ->setDefaults([ - 'method' => 'POST', - 'confirm_message' => '', - 'accessibility_checker' => null, - 'confirm_message_type' => self::MESSAGE_TYPE_STATIC, - 'dynamic_message_field' => '', - 'extra_route_params' => [], - ]) - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('route_param_name', 'string') - ->setAllowedTypes('route_param_field', 'string') - ->setAllowedTypes('extra_route_params', 'array') - ->setAllowedTypes('method', 'string') - ->setAllowedTypes('confirm_message', 'string') - ->setAllowedTypes('accessibility_checker', [AccessibilityCheckerInterface::class, 'callable', 'null']) - ->setAllowedTypes('dynamic_message_field', 'string') - ->setAllowedTypes('confirm_message_type', 'string') - ; - } - - /** - * {@inheritdoc} - */ - public function isApplicable(array $record) - { - $accessibilityChecker = $this->getOptions()['accessibility_checker']; - - if ($accessibilityChecker instanceof AccessibilityCheckerInterface) { - return $accessibilityChecker->isGranted($record); - } - - if (is_callable($accessibilityChecker)) { - return call_user_func($accessibilityChecker, $record); - } - - return parent::isApplicable($record); - } -} diff --git a/src/Core/Grid/Action/Type/LinkGridAction.php b/src/Core/Grid/Action/Type/LinkGridAction.php deleted file mode 100644 index d75c118f..00000000 --- a/src/Core/Grid/Action/Type/LinkGridAction.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\AbstractGridAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class LinkGridAction defines grid action which is link. - */ -final class LinkGridAction extends AbstractGridAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'link'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'route', - ]) - ->setDefaults([ - 'route_params' => [], - ]) - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('route_params', 'array'); - } -} diff --git a/src/Core/Grid/Action/Type/SimpleGridAction.php b/src/Core/Grid/Action/Type/SimpleGridAction.php deleted file mode 100644 index ddba106e..00000000 --- a/src/Core/Grid/Action/Type/SimpleGridAction.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\AbstractGridAction; - -final class SimpleGridAction extends AbstractGridAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'simple'; - } -} diff --git a/src/Core/Grid/Action/Type/SubmitGridAction.php b/src/Core/Grid/Action/Type/SubmitGridAction.php deleted file mode 100644 index 379e73f9..00000000 --- a/src/Core/Grid/Action/Type/SubmitGridAction.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Action\Type; - -use PrestaShop\PrestaShop\Core\Grid\Action\AbstractGridAction; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class SubmitGridAction represents grid action that can be submitted. - */ -final class SubmitGridAction extends AbstractGridAction -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'submit'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'submit_route', - ]) - ->setDefaults([ - 'submit_method' => 'POST', - 'confirm_message' => null, - ]) - ->setAllowedTypes('submit_route', 'string') - ->setAllowedTypes('confirm_message', ['null', 'string']) - ->setAllowedValues('submit_method', ['POST', 'GET']); - } -} diff --git a/src/Core/Grid/Collection/AbstractCollection.php b/src/Core/Grid/Collection/AbstractCollection.php deleted file mode 100644 index 4b695918..00000000 --- a/src/Core/Grid/Collection/AbstractCollection.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Collection; - -use Countable; -use Iterator; - -/** - * Class AbstractCollection is responsible for providing base collection implementation. - */ -abstract class AbstractCollection implements Iterator, Countable -{ - /** - * @var array - */ - protected $items = []; - - /** - * {@inheritdoc} - */ - public function current() - { - return current($this->items); - } - - /** - * {@inheritdoc} - */ - public function next() - { - return next($this->items); - } - - /** - * {@inheritdoc} - */ - public function key() - { - return key($this->items); - } - - /** - * {@inheritdoc} - */ - public function valid() - { - return false !== $this->current(); - } - - /** - * {@inheritdoc} - */ - public function rewind() - { - reset($this->items); - } - - /** - * {@inheritdoc} - */ - public function count() - { - return count($this->items); - } -} diff --git a/src/Core/Grid/Column/AbstractColumn.php b/src/Core/Grid/Column/AbstractColumn.php deleted file mode 100644 index 7cacc686..00000000 --- a/src/Core/Grid/Column/AbstractColumn.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column; - -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class AbtractColumn implements reusable column methods. - */ -abstract class AbstractColumn implements ColumnInterface -{ - /** - * @var string - */ - private $id; - - /** - * @var string - */ - private $name; - - /** - * @var array - */ - private $options; - - /** - * @param string $id - */ - public function __construct($id) - { - $this->id = $id; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $this->resolveOptions($options); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - if (null === $this->options) { - $this->resolveOptions(); - } - - return $this->options; - } - - /** - * Default column options configuration. You can override or extend it needed options. - * - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'sortable' => true, - 'clickable' => false, - ]) - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('clickable', 'bool'); - } - - /** - * Resolve column options. - * - * @param array $options - */ - private function resolveOptions(array $options = []) - { - $resolver = new OptionsResolver(); - $this->configureOptions($resolver); - - $this->options = $resolver->resolve($options); - } -} diff --git a/src/Core/Grid/Column/ColumnCollection.php b/src/Core/Grid/Column/ColumnCollection.php deleted file mode 100644 index 0c15b5d1..00000000 --- a/src/Core/Grid/Column/ColumnCollection.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; -use PrestaShop\PrestaShop\Core\Grid\Exception\ColumnNotFoundException; - -/** - * Class ColumnCollection holds collection of columns for grid. - * - * @property ColumnInterface[] $items - */ -final class ColumnCollection extends AbstractCollection implements ColumnCollectionInterface -{ - /** - * @internal - */ - const POSITION_AFTER = 'after'; - - /** - * @internal - */ - const POSITION_BEFORE = 'before'; - - /** - * {@inheritdoc} - */ - public function add(ColumnInterface $column) - { - $this->items[$column->getId()] = $column; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function addAfter($id, ColumnInterface $newColumn) - { - $this->insertByPosition($id, $newColumn, self::POSITION_AFTER); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function addBefore($id, ColumnInterface $newColumn) - { - $this->insertByPosition($id, $newColumn, self::POSITION_BEFORE); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function remove($id) - { - if (isset($this->items[$id])) { - unset($this->items[$id]); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - $columns = []; - - foreach ($this->items as $item) { - $columns[] = [ - 'id' => $item->getId(), - 'name' => $item->getName(), - 'type' => $item->getType(), - 'options' => $item->getOptions(), - ]; - } - - return $columns; - } - - /** - * Move an existing Column to a specific position. - * - * @param string $id the Column ID original position in the Collection - * @param int $position the Column ID destination position in the Collection - * - * @return self - */ - public function move($id, $position) - { - if (!isset($this->items[$id])) { - throw new ColumnNotFoundException(sprintf('Cannot insert new column into collection. Column with id "%s" was not found.', $id)); - } - - $column = $this->items[$id]; - unset($this->items[$id]); - - $columns = array_slice($this->items, 0, $position, true) + - [$column->getId() => $column] + - array_slice($this->items, $position, null, true); - - $this->items = $columns; - - return $this; - } - - /** - * Insert new column into collection at given position. - * - * @param string $id Existing column id - * @param ColumnInterface $newColumn Column to insert - * @param string $position Position: "before" or "after" - * - * @throws ColumnNotFoundException When column with given $id does not exist - */ - private function insertByPosition($id, ColumnInterface $newColumn, $position) - { - if (!isset($this->items[$id])) { - throw new ColumnNotFoundException(sprintf('Cannot insert new column into collection. Column with id "%s" was not found.', $id)); - } - - $existingColumnKeyPosition = array_search($id, array_keys($this->items)); - - if (self::POSITION_AFTER === $position) { - ++$existingColumnKeyPosition; - } - - $columns = array_slice($this->items, 0, $existingColumnKeyPosition, true) + - [$newColumn->getId() => $newColumn] + - array_slice($this->items, $existingColumnKeyPosition, null, true); - - $this->items = $columns; - } -} diff --git a/src/Core/Grid/Column/ColumnCollectionInterface.php b/src/Core/Grid/Column/ColumnCollectionInterface.php deleted file mode 100644 index d5cfb0f7..00000000 --- a/src/Core/Grid/Column/ColumnCollectionInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column; - -use Countable; -use Iterator; - -/** - * Interface ColumnCollectionInterface defines contract for grid column collection. - */ -interface ColumnCollectionInterface extends Iterator, Countable -{ - /** - * Add column to collection. - * - * @param ColumnInterface $column - * - * @return self - */ - public function add(ColumnInterface $column); - - /** - * Add column after given column. - * - * @param string $id Column id - * @param ColumnInterface $column - * - * @return self - */ - public function addAfter($id, ColumnInterface $column); - - /** - * @param string $id Column id - * @param ColumnInterface $column - * - * @return self - */ - public function addBefore($id, ColumnInterface $column); - - /** - * Remove column from collection. - * - * @param string $id - * - * @return self - */ - public function remove($id); - - /** - * Get columns as array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Grid/Column/ColumnInterface.php b/src/Core/Grid/Column/ColumnInterface.php deleted file mode 100644 index ee07aea9..00000000 --- a/src/Core/Grid/Column/ColumnInterface.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column; - -/** - * Interface ColumnInterface exposes contract for single column. - */ -interface ColumnInterface -{ - /** - * Get unique column id. - * - * @return string - * @return self - */ - public function getId(); - - /** - * Get column type. - * - * @return string - */ - public function getType(); - - /** - * Get translated column name. - * - * @return string - */ - public function getName(); - - /** - * Translated column name. - * - * @param string $name - * - * @return self - */ - public function setName($name); - - /** - * Get column related options. - * - * @return array - */ - public function getOptions(); - - /** - * Set column options. - * - * @param array $options - * - * @return self - */ - public function setOptions(array $options); -} diff --git a/src/Core/Grid/Column/Type/Attribute/AttributeColorColumn.php b/src/Core/Grid/Column/Type/Attribute/AttributeColorColumn.php deleted file mode 100644 index 4191b705..00000000 --- a/src/Core/Grid/Column/Type/Attribute/AttributeColorColumn.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Attribute; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Defines column which renders a block filled with color - */ -final class AttributeColorColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'attribute_color'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setAllowedTypes('field', 'string') - ; - } -} diff --git a/src/Core/Grid/Column/Type/BooleanColumn.php b/src/Core/Grid/Column/Type/BooleanColumn.php deleted file mode 100644 index 7e139b95..00000000 --- a/src/Core/Grid/Column/Type/BooleanColumn.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Boolean column allows adding boolean columns (Yes/No, On/Off and etc) to grid - */ -final class BooleanColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'boolean'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'field', - 'true_name', - 'false_name', - ]) - ->setDefaults([ - 'clickable' => false, - ]) - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('true_name', 'string') - ->setAllowedTypes('true_name', 'string') - ->setAllowedTypes('clickable', 'bool') - ; - } -} diff --git a/src/Core/Grid/Column/Type/Category/CategoryPositionColumn.php b/src/Core/Grid/Column/Type/Category/CategoryPositionColumn.php deleted file mode 100644 index c26a22ae..00000000 --- a/src/Core/Grid/Column/Type/Category/CategoryPositionColumn.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Category; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class CategoryPositionColumn. - */ -final class CategoryPositionColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'category_position'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'field', - 'id_field', - 'id_parent_field', - 'update_route', - ]) - ->setDefaults([ - 'sortable' => true, - ]) - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('id_field', 'string') - ->setAllowedTypes('id_parent_field', 'string') - ->setAllowedTypes('update_route', 'string'); - } -} diff --git a/src/Core/Grid/Column/Type/ColorColumn.php b/src/Core/Grid/Column/Type/ColorColumn.php deleted file mode 100644 index f54c7a49..00000000 --- a/src/Core/Grid/Column/Type/ColorColumn.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Column which background color can be configured. - */ -final class ColorColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'color'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - 'color_field', - ]) - ; - } -} diff --git a/src/Core/Grid/Column/Type/Common/ActionColumn.php b/src/Core/Grid/Column/Type/Common/ActionColumn.php deleted file mode 100644 index 145b15d7..00000000 --- a/src/Core/Grid/Column/Type/Common/ActionColumn.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class ActionColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'action'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'actions' => null, - ]) - ->setAllowedTypes('actions', ['null', RowActionCollection::class]); - } -} diff --git a/src/Core/Grid/Column/Type/Common/BadgeColumn.php b/src/Core/Grid/Column/Type/Common/BadgeColumn.php deleted file mode 100644 index 2fffe64c..00000000 --- a/src/Core/Grid/Column/Type/Common/BadgeColumn.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class BadgeColumn displays column with badge. - */ -final class BadgeColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'badge'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setDefaults([ - 'badge_type' => 'success', - 'empty_value' => '', - 'clickable' => true, - ]) - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('empty_value', 'string') - ->setAllowedTypes('clickable', 'bool') - ->setAllowedValues('badge_type', ['success', 'info', 'danger', 'warning']); - } -} diff --git a/src/Core/Grid/Column/Type/Common/BulkActionColumn.php b/src/Core/Grid/Column/Type/Common/BulkActionColumn.php deleted file mode 100644 index df089689..00000000 --- a/src/Core/Grid/Column/Type/Common/BulkActionColumn.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class BulkActionColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'bulk_action'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'bulk_field', - ]) - ->setAllowedTypes('bulk_field', 'string'); - } -} diff --git a/src/Core/Grid/Column/Type/Common/ChoiceColumn.php b/src/Core/Grid/Column/Type/Common/ChoiceColumn.php deleted file mode 100644 index 3820ab93..00000000 --- a/src/Core/Grid/Column/Type/Common/ChoiceColumn.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Displays choices in the grid. - */ -final class ChoiceColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType(): string - { - return 'choice'; - } - - protected function configureOptions(OptionsResolver $resolver): void - { - parent::configureOptions($resolver); - - $resolver - ->setRequired( - [ - 'choice_provider', - 'field', - 'route', - ] - ) - ->setDefaults([ - 'color_field' => '', - 'record_route_params' => [], - ]) - ->setAllowedTypes('choice_provider', ConfigurableFormChoiceProviderInterface::class) - ->setAllowedTypes('field', ['string', 'int', 'bool']) - ->setAllowedTypes('color_field', 'string') - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('record_route_params', 'array') - ; - } -} diff --git a/src/Core/Grid/Column/Type/Common/DateTimeColumn.php b/src/Core/Grid/Column/Type/Common/DateTimeColumn.php deleted file mode 100644 index b86476c4..00000000 --- a/src/Core/Grid/Column/Type/Common/DateTimeColumn.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class DateTimeColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'date_time'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setDefaults([ - 'format' => 'Y-m-d H:i:s', - 'empty_data' => '', - 'clickable' => false, - ]) - ->setAllowedTypes('format', 'string') - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('empty_data', 'string') - ->setAllowedTypes('clickable', 'bool'); - } -} diff --git a/src/Core/Grid/Column/Type/Common/DraggableColumn.php b/src/Core/Grid/Column/Type/Common/DraggableColumn.php deleted file mode 100644 index 5bc1ddf7..00000000 --- a/src/Core/Grid/Column/Type/Common/DraggableColumn.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Is used to add draggable column to grid. - * This column is commonly used with PositionColumn. - */ -final class DraggableColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'draggable'; - } - - /** - * @param OptionsResolver $resolver - */ - protected function configureOptions(OptionsResolver $resolver) - { - } -} diff --git a/src/Core/Grid/Column/Type/Common/IdentifierColumn.php b/src/Core/Grid/Column/Type/Common/IdentifierColumn.php deleted file mode 100644 index 4c2e8bab..00000000 --- a/src/Core/Grid/Column/Type/Common/IdentifierColumn.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\PreviewColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Columns is used as identifier in grid (e.g. Product ID, Category ID & etc) - */ -final class IdentifierColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'identifier'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'identifier_field', - ]) - ->setDefaults([ - 'sortable' => true, - 'with_bulk_field' => false, - 'bulk_field' => null, - 'preview' => null, - 'clickable' => true, - ]) - ->setAllowedTypes('identifier_field', 'string') - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('with_bulk_field', 'bool') - ->setAllowedTypes('bulk_field', ['string', 'null']) - ->setAllowedTypes('clickable', 'bool') - ->setAllowedValues('preview', function ($previewColumn) { - return $previewColumn instanceof PreviewColumn || $previewColumn === null; - }) - ; - } -} diff --git a/src/Core/Grid/Column/Type/Common/ImageColumn.php b/src/Core/Grid/Column/Type/Common/ImageColumn.php deleted file mode 100644 index 4122f2b8..00000000 --- a/src/Core/Grid/Column/Type/Common/ImageColumn.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ImageColumn renders column as image. - */ -final class ImageColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'image'; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'src_field', - ]) - ->setDefaults([ - 'clickable' => true, - ]) - ->setAllowedTypes('src_field', 'string') - ->setAllowedTypes('clickable', 'bool'); - } -} diff --git a/src/Core/Grid/Column/Type/Common/LinkColumn.php b/src/Core/Grid/Column/Type/Common/LinkColumn.php deleted file mode 100644 index 6e834d83..00000000 --- a/src/Core/Grid/Column/Type/Common/LinkColumn.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class LinkColumn is used to define column which is link to record action (view, edit, add). - */ -final class LinkColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'link'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'sortable' => true, - 'icon' => null, - 'button_template' => false, - 'color_template' => 'primary', - 'clickable' => false, - ]) - ->setRequired([ - 'field', - 'route', - 'route_param_name', - 'route_param_field', - ]) - ->setDefined([ - 'icon', - 'target', - ]) - ->setAllowedTypes('field', ['string', 'null']) - ->setAllowedTypes('icon', ['string', 'null']) - ->setAllowedTypes('target', ['string', 'null']) - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('route_param_name', 'string') - ->setAllowedTypes('route_param_field', 'string') - ->setAllowedTypes('clickable', 'bool') - ->setAllowedValues('color_template', [ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - ]) - ->setAllowedValues('button_template', [ - false, - 'outline', - 'normal', - ]) - - ; - } -} diff --git a/src/Core/Grid/Column/Type/Common/PositionColumn.php b/src/Core/Grid/Column/Type/Common/PositionColumn.php deleted file mode 100644 index b83ae5c5..00000000 --- a/src/Core/Grid/Column/Type/Common/PositionColumn.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use PrestaShop\PrestaShop\Core\Grid\Position\GridPositionUpdater; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class PositionColumn defines a position column used to sort elements in a grid, - * it is associated to a special template, and works well with the PositionExtension - * javascript extension and the GridPositionUpdater service. - * - * @see admin-dev/themes/new-theme/js/components/grid/extension/position-extension.js - * @see GridPositionUpdater - */ -final class PositionColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'position'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'id_field', - 'position_field', - 'update_route', - ]) - ->setDefaults([ - 'sortable' => true, - 'update_method' => 'GET', - 'record_route_params' => [], - 'clickable' => true, - ]) - ->setAllowedTypes('id_field', 'string') - ->setAllowedTypes('position_field', 'string') - ->setAllowedTypes('update_route', 'string') - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('update_method', 'string') - ->setAllowedTypes('record_route_params', ['array']) - ->setAllowedTypes('clickable', 'bool') - ->setAllowedValues('update_method', ['GET', 'POST']); - } -} diff --git a/src/Core/Grid/Column/Type/Common/ToggleColumn.php b/src/Core/Grid/Column/Type/Common/ToggleColumn.php deleted file mode 100644 index 6cd82faa..00000000 --- a/src/Core/Grid/Column/Type/Common/ToggleColumn.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Common; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\Exception\MissingOptionsException; -use Symfony\Component\OptionsResolver\Options; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This Column is used to display booleans. - * - it will display an icon instead of the value - * - if user clicks on it, this triggers a toggle of the boolean value. - */ -final class ToggleColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'toggle'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'sortable' => true, - // @deprecated, use route_param_name option instead - 'route_param_id' => '', - 'route_param_name' => '', - ]) - ->setRequired([ - 'field', - 'primary_field', - 'route', - ]) - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('primary_field', 'string') - ->setAllowedTypes('route', 'string') - ->setAllowedTypes('route_param_name', 'string') - ->setAllowedTypes('sortable', 'bool') - ->setAllowedTypes('route_param_id', 'string') - ; - - $resolver->setNormalizer('route_param_name', static function (Options $options, $value) { - if (!empty($value)) { - return $value; - } - - // Fallback on route_param_id if it's specified - if (!empty($options['route_param_id'])) { - return $options['route_param_id']; - } - - throw new MissingOptionsException(sprintf('Option "%s" is missing for "%s" column options.', 'route_param_name', self::class)); - }); - } -} diff --git a/src/Core/Grid/Column/Type/DataColumn.php b/src/Core/Grid/Column/Type/DataColumn.php deleted file mode 100644 index 9797884e..00000000 --- a/src/Core/Grid/Column/Type/DataColumn.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class Column defines most simple column in the grid that renders raw data. - */ -final class DataColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'data'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setDefaults([ - 'clickable' => true, - ]) - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('clickable', 'bool') - ; - } -} diff --git a/src/Core/Grid/Column/Type/DisableableLinkColumn.php b/src/Core/Grid/Column/Type/DisableableLinkColumn.php deleted file mode 100644 index 88ab38e9..00000000 --- a/src/Core/Grid/Column/Type/DisableableLinkColumn.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class DisableableLinkColumn extends AbstractColumn -{ - /** - * @var LinkColumn - */ - private $linkColumn; - - public function __construct($id) - { - parent::__construct($id); - $this->linkColumn = new LinkColumn($id); - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return 'disableable_link'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired(['disabled_field']) - ->setAllowedTypes('disabled_field', ['string', 'null']) - ; - } - - /** - * {@inheritdoc} - */ - public function setOptions(array $options) - { - $disabledOptions = []; - - if (isset($options['disabled_field'])) { - $disabledOptions['disabled_field'] = $options['disabled_field']; - unset($options['disabled_field']); - } - - $this->linkColumn->setOptions($options); - parent::setOptions($disabledOptions); - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getOptions() - { - return array_merge($this->linkColumn->getOptions(), parent::getOptions()); - } -} diff --git a/src/Core/Grid/Column/Type/Employee/EmployeeNameWithAvatarColumn.php b/src/Core/Grid/Column/Type/Employee/EmployeeNameWithAvatarColumn.php deleted file mode 100644 index 9384a98c..00000000 --- a/src/Core/Grid/Column/Type/Employee/EmployeeNameWithAvatarColumn.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Employee; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class EmployeeNameWithAvatarColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'employee_name_with_avatar'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setAllowedTypes('field', 'string'); - } -} diff --git a/src/Core/Grid/Column/Type/LinkGroupColumn.php b/src/Core/Grid/Column/Type/LinkGroupColumn.php deleted file mode 100644 index c5e1ecf6..00000000 --- a/src/Core/Grid/Column/Type/LinkGroupColumn.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Allows adding group of links in single column - */ -final class LinkGroupColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'link_group'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'links', - ]) - ->setAllowedTypes('links', 'array') - ; - } -} diff --git a/src/Core/Grid/Column/Type/OrderPriceColumn.php b/src/Core/Grid/Column/Type/OrderPriceColumn.php deleted file mode 100644 index 44c2bf38..00000000 --- a/src/Core/Grid/Column/Type/OrderPriceColumn.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Displays order price - */ -final class OrderPriceColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'order_price'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - 'is_paid_field', - ]) - ->setAllowedTypes('field', 'string') - ->setAllowedTypes('is_paid_field', 'string') - ; - } -} diff --git a/src/Core/Grid/Column/Type/PreviewColumn.php b/src/Core/Grid/Column/Type/PreviewColumn.php deleted file mode 100644 index fdd8c970..00000000 --- a/src/Core/Grid/Column/Type/PreviewColumn.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Allows adding Preview functionality to grid rows - */ -final class PreviewColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'preview'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'icon_expand', - 'icon_collapse', - 'preview_data_route', - ]) - ->setDefined([ - 'preview_route_params', - ]) - ->setAllowedTypes('preview_data_route', 'string') - ->setAllowedTypes('preview_route_params', 'array') - ->setAllowedTypes('icon_expand', 'string') - ->setAllowedTypes('icon_collapse', 'string') - ; - } -} diff --git a/src/Core/Grid/Column/Type/Status/SeverityLevelColumn.php b/src/Core/Grid/Column/Type/Status/SeverityLevelColumn.php deleted file mode 100644 index 2732834a..00000000 --- a/src/Core/Grid/Column/Type/Status/SeverityLevelColumn.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Column\Type\Status; - -use PrestaShop\PrestaShop\Core\Grid\Column\AbstractColumn; -use Symfony\Component\OptionsResolver\OptionsResolver; - -final class SeverityLevelColumn extends AbstractColumn -{ - /** - * {@inheritdoc} - */ - public function getType() - { - return 'severity_level'; - } - - /** - * {@inheritdoc} - */ - protected function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver - ->setRequired([ - 'field', - ]) - ->setDefaults([ - 'with_message' => false, - ]) - ->setAllowedTypes('with_message', 'bool') - ->setAllowedTypes('field', 'string'); - } -} diff --git a/src/Core/Grid/Data/Factory/AttachmentGridDataFactoryDecorator.php b/src/Core/Grid/Data/Factory/AttachmentGridDataFactoryDecorator.php deleted file mode 100644 index c8664057..00000000 --- a/src/Core/Grid/Data/Factory/AttachmentGridDataFactoryDecorator.php +++ /dev/null @@ -1,160 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use Doctrine\DBAL\Connection; -use PDO; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Util\File\FileSizeConverter; -use PrestaShopBundle\Translation\TranslatorAwareTrait; - -/** - * Decorates attachment grid data factory - */ -final class AttachmentGridDataFactoryDecorator implements GridDataFactoryInterface -{ - use TranslatorAwareTrait; - - /** - * @var GridDataFactoryInterface - */ - private $attachmentDoctrineGridDataFactory; - - /** - * @var int - */ - private $employeeIdLang; - - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @var FileSizeConverter - */ - private $fileSizeConverter; - - /** - * @param GridDataFactoryInterface $attachmentDoctrineGridDataFactory - * @param int $employeeIdLang - * @param Connection $connection - * @param string $dbPrefix - * @param FileSizeConverter $fileSizeConverter - */ - public function __construct( - GridDataFactoryInterface $attachmentDoctrineGridDataFactory, - int $employeeIdLang, - Connection $connection, - string $dbPrefix, - FileSizeConverter $fileSizeConverter - ) { - $this->attachmentDoctrineGridDataFactory = $attachmentDoctrineGridDataFactory; - $this->employeeIdLang = $employeeIdLang; - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - $this->fileSizeConverter = $fileSizeConverter; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $attachmentData = $this->attachmentDoctrineGridDataFactory->getData($searchCriteria); - - $attachmentRecords = $this->applyModifications($attachmentData->getRecords()); - - return new GridData( - $attachmentRecords, - $attachmentData->getRecordsTotal(), - $attachmentData->getQuery() - ); - } - - /** - * @param RecordCollectionInterface $attachments - * - * @return RecordCollection - */ - private function applyModifications(RecordCollectionInterface $attachments): RecordCollection - { - $modifiedAttachments = []; - - foreach ($attachments as $attachment) { - if ((int) $attachment['products'] > 0) { - $productNamesArray = $this->getProductNames($attachment['id_attachment']); - $productNames = implode(', ', $productNamesArray); - $attachment['dynamic_message'] = $this->trans( - 'This file is associated with the following products. Are you sure you want to delete it?', - [], - 'Admin.Catalog.Notification' - ); - $attachment['dynamic_message'] .= PHP_EOL . PHP_EOL . $productNames; - } - - $attachment['file_size'] = $this->fileSizeConverter->convert((int) $attachment['file_size']); - $attachment['products'] .= ' ' . $this->trans('product(s)', [], 'Admin.Catalog.Feature'); - - $modifiedAttachments[] = $attachment; - } - - return new RecordCollection($modifiedAttachments); - } - - /** - * @param string $attachmentId - * - * @return array - */ - private function getProductNames(string $attachmentId): array - { - $qb = $this->connection->createQueryBuilder(); - - $qb->select('DISTINCT pl.`name`') - ->from($this->dbPrefix . 'product_attachment', 'pa') - ->leftJoin( - 'pa', - $this->dbPrefix . 'product_lang', - 'pl', - 'pa.`id_product` = pl.`id_product` AND pl.`id_lang` = :langId' - ) - ->where('pa.`id_attachment` = :attachmentId') - ->setParameter('attachmentId', $attachmentId) - ->setParameter('langId', $this->employeeIdLang); - - return $qb->execute()->fetchAll(PDO::FETCH_COLUMN); - } -} diff --git a/src/Core/Grid/Data/Factory/AttributeGroupGridDataFactory.php b/src/Core/Grid/Data/Factory/AttributeGroupGridDataFactory.php deleted file mode 100644 index 246eb888..00000000 --- a/src/Core/Grid/Data/Factory/AttributeGroupGridDataFactory.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Decorates database records for grid presentation - */ -final class AttributeGroupGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $attributeDataFactory; - - /** - * @param GridDataFactoryInterface $attributeDataFactory - */ - public function __construct(GridDataFactoryInterface $attributeDataFactory) - { - $this->attributeDataFactory = $attributeDataFactory; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $records = $this->attributeDataFactory->getData($searchCriteria); - $modifiedRecords = $this->modifyRecords($records->getRecords()->all()); - - return new GridData( - new RecordCollection($modifiedRecords), - $records->getRecordsTotal(), - $records->getQuery() - ); - } - - /** - * @param array $records - * - * @return array - */ - private function modifyRecords(array $records): array - { - foreach ($records as &$record) { - if (null === $record['values']) { - $record['values'] = '0'; - } - } - - return $records; - } -} diff --git a/src/Core/Grid/Data/Factory/CatalogPriceRuleGridDataFactory.php b/src/Core/Grid/Data/Factory/CatalogPriceRuleGridDataFactory.php deleted file mode 100644 index feabc309..00000000 --- a/src/Core/Grid/Data/Factory/CatalogPriceRuleGridDataFactory.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Gets data for catalog price rule grid - */ -final class CatalogPriceRuleGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $priceRuleDataFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param GridDataFactoryInterface $priceRuleDataFactory - * @param TranslatorInterface $translator - */ - public function __construct(GridDataFactoryInterface $priceRuleDataFactory, TranslatorInterface $translator) - { - $this->priceRuleDataFactory = $priceRuleDataFactory; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $priceRuleData = $this->priceRuleDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $priceRuleData->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $priceRuleData->getRecordsTotal(), - $priceRuleData->getQuery() - ); - } - - /** - * @param array $priceRules - * - * @return array - */ - private function applyModification(array $priceRules) - { - foreach ($priceRules as &$priceRule) { - foreach ($priceRule as &$value) { - if ($value === null) { - $value = '--'; - } - } - - Reduction::TYPE_AMOUNT === $priceRule['reduction_type'] ? - $priceRule['reduction_type'] = $this->translator->trans('Amount', [], 'Admin.Global') : - $priceRule['reduction_type'] = $this->translator->trans('Percentage', [], 'Admin.Global'); - } - - return $priceRules; - } -} diff --git a/src/Core/Grid/Data/Factory/CategoryDataFactory.php b/src/Core/Grid/Data/Factory/CategoryDataFactory.php deleted file mode 100644 index 57ac69a7..00000000 --- a/src/Core/Grid/Data/Factory/CategoryDataFactory.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class CategoryDataFactory decorates DoctrineGridDataFactory configured for categories to modify category records. - */ -final class CategoryDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $doctrineCategoryDataFactory; - - /** - * @param GridDataFactoryInterface $doctrineCategoryDataFactory - */ - public function __construct(GridDataFactoryInterface $doctrineCategoryDataFactory) - { - $this->doctrineCategoryDataFactory = $doctrineCategoryDataFactory; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $data = $this->doctrineCategoryDataFactory->getData($searchCriteria); - - $records = $this->modifyRecords($data->getRecords()->all()); - - return new GridData( - new RecordCollection($records), - $data->getRecordsTotal(), - $data->getQuery() - ); - } - - /** - * Modify category records. - * - * @param array $records - * - * @return array - */ - private function modifyRecords(array $records) - { - foreach ($records as $key => $record) { - $records[$key]['description'] = strip_tags(stripslashes($record['description'])); - } - - return $records; - } -} diff --git a/src/Core/Grid/Data/Factory/CreditSlipGridDataFactory.php b/src/Core/Grid/Data/Factory/CreditSlipGridDataFactory.php deleted file mode 100644 index 2f139ef2..00000000 --- a/src/Core/Grid/Data/Factory/CreditSlipGridDataFactory.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Provides data for credit slip grid - */ -final class CreditSlipGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $creditSlipDataFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param GridDataFactoryInterface $creditSlipDataFactory - * @param TranslatorInterface $translator - */ - public function __construct( - GridDataFactoryInterface $creditSlipDataFactory, - TranslatorInterface $translator - ) { - $this->creditSlipDataFactory = $creditSlipDataFactory; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $creditSlipData = $this->creditSlipDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $creditSlipData->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $creditSlipData->getRecordsTotal(), - $creditSlipData->getQuery() - ); - } - - /** - * @param array $creditSlips - * - * @return array - */ - private function applyModification(array $creditSlips) - { - foreach ($creditSlips as $i => $creditSlip) { - $creditSlips[$i]['link_value'] = $this->translator->trans( - 'Download credit slip', [], 'Admin.Orderscustomers.Feature' - ); - } - - return $creditSlips; - } -} diff --git a/src/Core/Grid/Data/Factory/CustomerGridDataFactoryDecorator.php b/src/Core/Grid/Data/Factory/CustomerGridDataFactoryDecorator.php deleted file mode 100644 index e2711003..00000000 --- a/src/Core/Grid/Data/Factory/CustomerGridDataFactoryDecorator.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Localization\LocaleInterface; - -/** - * Class CustomerGridDataFactoryDecorator decorates data from customer doctrine data factory. - */ -final class CustomerGridDataFactoryDecorator implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $customerDoctrineGridDataFactory; - - /** - * @var LocaleInterface - */ - private $locale; - - /** - * @var string - */ - private $contextCurrencyIsoCode; - - /** - * @param GridDataFactoryInterface $customerDoctrineGridDataFactory - * @param LocaleInterface $locale - * @param string $contextCurrencyIsoCode - */ - public function __construct( - GridDataFactoryInterface $customerDoctrineGridDataFactory, - LocaleInterface $locale, - $contextCurrencyIsoCode - ) { - $this->customerDoctrineGridDataFactory = $customerDoctrineGridDataFactory; - $this->locale = $locale; - $this->contextCurrencyIsoCode = $contextCurrencyIsoCode; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $customerData = $this->customerDoctrineGridDataFactory->getData($searchCriteria); - - $customerRecords = $this->applyModifications($customerData->getRecords()); - - return new GridData( - $customerRecords, - $customerData->getRecordsTotal(), - $customerData->getQuery() - ); - } - - /** - * @param RecordCollectionInterface $customers - * - * @return RecordCollection - */ - private function applyModifications(RecordCollectionInterface $customers) - { - $modifiedCustomers = []; - - foreach ($customers as $customer) { - if (empty($customer['social_title'])) { - $customer['social_title'] = '--'; - } - - if (null === $customer['company']) { - $customer['company'] = '--'; - } - - if (!empty($customer['total_spent'])) { - $customer['total_spent'] = $this->locale->formatPrice( - $customer['total_spent'], - $this->contextCurrencyIsoCode - ); - } - - if (null === $customer['connect']) { - $customer['connect'] = '--'; - } - - $modifiedCustomers[] = $customer; - } - - return new RecordCollection($modifiedCustomers); - } -} diff --git a/src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php b/src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php deleted file mode 100644 index a1204725..00000000 --- a/src/Core/Grid/Data/Factory/DoctrineGridDataFactory.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use Doctrine\DBAL\Query\QueryBuilder; -use PDO; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Query\DoctrineQueryBuilderInterface; -use PrestaShop\PrestaShop\Core\Grid\Query\QueryParserInterface; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\DependencyInjection\Container; - -/** - * Class DoctrineGridDataFactory is responsible for returning grid data using Doctrine query builders. - */ -final class DoctrineGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var DoctrineQueryBuilderInterface - */ - private $gridQueryBuilder; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var QueryParserInterface - */ - private $queryParser; - - /** - * @var string - */ - private $gridId; - - /** - * @param DoctrineQueryBuilderInterface $gridQueryBuilder - * @param HookDispatcherInterface $hookDispatcher - * @param QueryParserInterface $queryParser - * @param string $gridId - */ - public function __construct( - DoctrineQueryBuilderInterface $gridQueryBuilder, - HookDispatcherInterface $hookDispatcher, - QueryParserInterface $queryParser, - $gridId - ) { - $this->gridQueryBuilder = $gridQueryBuilder; - $this->hookDispatcher = $hookDispatcher; - $this->queryParser = $queryParser; - $this->gridId = $gridId; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $searchQueryBuilder = $this->gridQueryBuilder->getSearchQueryBuilder($searchCriteria); - $countQueryBuilder = $this->gridQueryBuilder->getCountQueryBuilder($searchCriteria); - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($this->gridId) . 'GridQueryBuilderModifier', [ - 'search_query_builder' => $searchQueryBuilder, - 'count_query_builder' => $countQueryBuilder, - 'search_criteria' => $searchCriteria, - ]); - - $records = $searchQueryBuilder->execute()->fetchAll(); - $recordsTotal = (int) $countQueryBuilder->execute()->fetch(PDO::FETCH_COLUMN); - - $records = new RecordCollection($records); - - return new GridData( - $records, - $recordsTotal, - $this->getRawQuery($searchQueryBuilder) - ); - } - - /** - * @param QueryBuilder $queryBuilder - * - * @return string - */ - private function getRawQuery(QueryBuilder $queryBuilder) - { - $query = $queryBuilder->getSQL(); - $parameters = $queryBuilder->getParameters(); - - return $this->queryParser->parse($query, $parameters); - } -} diff --git a/src/Core/Grid/Data/Factory/EmptyCategoryGridDataFactory.php b/src/Core/Grid/Data/Factory/EmptyCategoryGridDataFactory.php deleted file mode 100644 index cb3712a5..00000000 --- a/src/Core/Grid/Data/Factory/EmptyCategoryGridDataFactory.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Modifies records from database for empty_category grid - */ -final class EmptyCategoryGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $doctrineEmptyCategoryDataFactory; - - /** - * @param GridDataFactoryInterface $doctrineEmptyCategoryDataFactory - */ - public function __construct(GridDataFactoryInterface $doctrineEmptyCategoryDataFactory) - { - $this->doctrineEmptyCategoryDataFactory = $doctrineEmptyCategoryDataFactory; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $data = $this->doctrineEmptyCategoryDataFactory->getData($searchCriteria); - - $records = $this->modifyRecords($data->getRecords()->all()); - - return new GridData( - new RecordCollection($records), - $data->getRecordsTotal(), - $data->getQuery() - ); - } - - /** - * Modify empty category records. - * - * @param array $records - * - * @return array - */ - private function modifyRecords(array $records) - { - foreach ($records as $key => $record) { - $records[$key]['description'] = strip_tags(stripslashes($record['description'])); - } - - return $records; - } -} diff --git a/src/Core/Grid/Data/Factory/GridDataFactoryInterface.php b/src/Core/Grid/Data/Factory/GridDataFactoryInterface.php deleted file mode 100644 index 3350ae57..00000000 --- a/src/Core/Grid/Data/Factory/GridDataFactoryInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Interface GridDataFactoryInterface defines contract for grid data factories. - */ -interface GridDataFactoryInterface -{ - /** - * @param SearchCriteriaInterface $searchCriteria - * - * @return GridData - */ - public function getData(SearchCriteriaInterface $searchCriteria); -} diff --git a/src/Core/Grid/Data/Factory/LanguageGridDataFactory.php b/src/Core/Grid/Data/Factory/LanguageGridDataFactory.php deleted file mode 100644 index 7f073978..00000000 --- a/src/Core/Grid/Data/Factory/LanguageGridDataFactory.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; - -/** - * Class LanguageGridDataFactory gets data for languages grid. - */ -final class LanguageGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $doctrineLanguageDataFactory; - - /** - * @var ImageProviderInterface - */ - private $languageFlagThumbnailProvider; - - /** - * @param GridDataFactoryInterface $doctrineLanguageDataFactory - * @param ImageProviderInterface $languageFlagThumbnailProvider - */ - public function __construct( - GridDataFactoryInterface $doctrineLanguageDataFactory, - ImageProviderInterface $languageFlagThumbnailProvider - ) { - $this->doctrineLanguageDataFactory = $doctrineLanguageDataFactory; - $this->languageFlagThumbnailProvider = $languageFlagThumbnailProvider; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $languageData = $this->doctrineLanguageDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $languageData->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $languageData->getRecordsTotal(), - $languageData->getQuery() - ); - } - - /** - * @param array $languages - * - * @return array - */ - private function applyModification(array $languages) - { - foreach ($languages as $i => $language) { - $languages[$i]['flag'] = $this->languageFlagThumbnailProvider->getPath($language['id_lang']); - } - - return $languages; - } -} diff --git a/src/Core/Grid/Data/Factory/ManufacturerAddressGridDataFactory.php b/src/Core/Grid/Data/Factory/ManufacturerAddressGridDataFactory.php deleted file mode 100644 index 5525c2b2..00000000 --- a/src/Core/Grid/Data/Factory/ManufacturerAddressGridDataFactory.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Gets data for manufacturer addresses grid - */ -class ManufacturerAddressGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $manufacturerAddressDataFactory; - - /** - * @param GridDataFactoryInterface $manufacturerAddressDataFactory - */ - public function __construct(GridDataFactoryInterface $manufacturerAddressDataFactory) - { - $this->manufacturerAddressDataFactory = $manufacturerAddressDataFactory; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $addresses = $this->manufacturerAddressDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $addresses->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $addresses->getRecordsTotal(), - $addresses->getQuery() - ); - } - - /** - * @param array $addresses - * - * @return array - */ - private function applyModification(array $addresses) - { - $modifiedAddresses = []; - foreach ($addresses as $address) { - if (null === $address['name']) { - $address['name'] = '--'; - } - $modifiedAddresses[] = $address; - } - - return $modifiedAddresses; - } -} diff --git a/src/Core/Grid/Data/Factory/ManufacturerGridDataFactory.php b/src/Core/Grid/Data/Factory/ManufacturerGridDataFactory.php deleted file mode 100644 index 5b39bae3..00000000 --- a/src/Core/Grid/Data/Factory/ManufacturerGridDataFactory.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; - -/** - * Gets data for manufacturer grid - */ -final class ManufacturerGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $manufacturerDataFactory; - - /** - * @var ImageProviderInterface - */ - private $manufacturerLogoThumbnailProvider; - - /** - * @param GridDataFactoryInterface $manufacturerDataFactory - * @param ImageProviderInterface $manufacturerLogoThumbnailProvider - */ - public function __construct( - GridDataFactoryInterface $manufacturerDataFactory, - ImageProviderInterface $manufacturerLogoThumbnailProvider - ) { - $this->manufacturerDataFactory = $manufacturerDataFactory; - $this->manufacturerLogoThumbnailProvider = $manufacturerLogoThumbnailProvider; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $manufacturerData = $this->manufacturerDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $manufacturerData->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $manufacturerData->getRecordsTotal(), - $manufacturerData->getQuery() - ); - } - - /** - * @param array $manufacturers - * - * @return array - */ - private function applyModification(array $manufacturers) - { - foreach ($manufacturers as $i => $manufacturer) { - $manufacturers[$i]['logo'] = $this->manufacturerLogoThumbnailProvider->getPath( - $manufacturer['id_manufacturer'] - ); - - if (null === $manufacturers[$i]['addresses_count']) { - $manufacturers[$i]['addresses_count'] = '--'; - } - } - - return $manufacturers; - } -} diff --git a/src/Core/Grid/Data/Factory/OrderGridDataFactory.php b/src/Core/Grid/Data/Factory/OrderGridDataFactory.php deleted file mode 100644 index 8e2106ea..00000000 --- a/src/Core/Grid/Data/Factory/OrderGridDataFactory.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Localization\Locale\RepositoryInterface; - -/** - * Decorates DoctrineGridDataFactory configured for orders to modify order records. - */ -final class OrderGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $dataFactory; - - /** - * @var RepositoryInterface - */ - private $localeRepository; - - /** - * @var string - */ - private $contextLocale; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param GridDataFactoryInterface $dataFactory - * @param RepositoryInterface $localeRepository - * @param ConfigurationInterface $configuration - * @param string $contextLocale - */ - public function __construct( - GridDataFactoryInterface $dataFactory, - RepositoryInterface $localeRepository, - ConfigurationInterface $configuration, - $contextLocale - ) { - $this->dataFactory = $dataFactory; - $this->localeRepository = $localeRepository; - $this->contextLocale = $contextLocale; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $data = $this->dataFactory->getData($searchCriteria); - $records = $data->getRecords()->all(); - - $locale = $this->localeRepository->getLocale($this->contextLocale); - $isInvoicesEnabled = $this->configuration->get('PS_INVOICE'); - - foreach ($records as &$record) { - if (!$record['company']) { - $record['company'] = '--'; - } - - $record['total_paid_tax_incl'] = $locale->formatPrice( - $record['total_paid_tax_incl'], - $record['iso_code'] - ); - - $record['is_invoice_available'] = $isInvoicesEnabled && $record['invoice_number']; - } - - return new GridData( - new RecordCollection($records), - $data->getRecordsTotal(), - $data->getQuery() - ); - } -} diff --git a/src/Core/Grid/Data/Factory/SupplierGridDataFactory.php b/src/Core/Grid/Data/Factory/SupplierGridDataFactory.php deleted file mode 100644 index 21f6b832..00000000 --- a/src/Core/Grid/Data/Factory/SupplierGridDataFactory.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridData; -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Image\ImageProviderInterface; - -/** - * Class SupplierGridDataFactory gets data for supplier grid. - */ -final class SupplierGridDataFactory implements GridDataFactoryInterface -{ - /** - * @var GridDataFactoryInterface - */ - private $supplierDataFactory; - - /** - * @var ImageProviderInterface - */ - private $supplierLogoImageProvider; - - /** - * @param GridDataFactoryInterface $supplierDataFactory - * @param ImageProviderInterface $supplierLogoImageProvider - */ - public function __construct( - GridDataFactoryInterface $supplierDataFactory, - ImageProviderInterface $supplierLogoImageProvider - ) { - $this->supplierDataFactory = $supplierDataFactory; - $this->supplierLogoImageProvider = $supplierLogoImageProvider; - } - - /** - * {@inheritdoc} - */ - public function getData(SearchCriteriaInterface $searchCriteria) - { - $supplierData = $this->supplierDataFactory->getData($searchCriteria); - - $modifiedRecords = $this->applyModification( - $supplierData->getRecords()->all() - ); - - return new GridData( - new RecordCollection($modifiedRecords), - $supplierData->getRecordsTotal(), - $supplierData->getQuery() - ); - } - - /** - * @param array $suppliers - * - * @return array - */ - private function applyModification(array $suppliers) - { - foreach ($suppliers as $i => $supplier) { - $suppliers[$i]['logo'] = $this->supplierLogoImageProvider->getPath($supplier['id_supplier']); - } - - return $suppliers; - } -} diff --git a/src/Core/Grid/Data/GridData.php b/src/Core/Grid/Data/GridData.php deleted file mode 100644 index a8705c7a..00000000 --- a/src/Core/Grid/Data/GridData.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data; - -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollectionInterface; - -/** - * Class GridData is responsible for storing grid data. - */ -final class GridData implements GridDataInterface -{ - /** - * @var array - */ - private $records; - - /** - * @var int - */ - private $recordsTotal; - - /** - * @var string - */ - private $query; - - /** - * @param RecordCollectionInterface $records Filtered & paginated rows data - * @param int $recordsTotal Total number of rows (without pagination) - * @param string $query Query used to get rows - */ - public function __construct(RecordCollectionInterface $records, $recordsTotal, $query = '') - { - $this->records = $records; - $this->recordsTotal = $recordsTotal; - $this->query = $query; - } - - /** - * {@inheritdoc} - */ - public function getRecords() - { - return $this->records; - } - - /** - * {@inheritdoc} - */ - public function getRecordsTotal() - { - return $this->recordsTotal; - } - - /** - * {@inheritdoc} - */ - public function getQuery() - { - return $this->query; - } -} diff --git a/src/Core/Grid/Data/GridDataInterface.php b/src/Core/Grid/Data/GridDataInterface.php deleted file mode 100644 index 86cffcff..00000000 --- a/src/Core/Grid/Data/GridDataInterface.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Data; - -use PrestaShop\PrestaShop\Core\Grid\Record\RecordCollection; - -/** - * Interface GridDataInterface exposes contract for final grid data. - */ -interface GridDataInterface -{ - /** - * Returns final grid rows ready for rendering. - * - * @return RecordCollection - */ - public function getRecords(); - - /** - * Returns total rows in data source. - * - * @return int - */ - public function getRecordsTotal(); - - /** - * Return query which was used to get rows. - * - * @return string - */ - public function getQuery(); -} diff --git a/src/Core/Grid/Definition/Factory/AbstractFilterableGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AbstractFilterableGridDefinitionFactory.php deleted file mode 100644 index b952e3df..00000000 --- a/src/Core/Grid/Definition/Factory/AbstractFilterableGridDefinitionFactory.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -/** - * Class AbstractFilterableGridDefinitionFactory implements filterable grid definition creation. - */ -abstract class AbstractFilterableGridDefinitionFactory extends AbstractGridDefinitionFactory implements FilterableGridDefinitionFactoryInterface -{ - /** - * {@inheritdoc} - * - * Grid definition already has an internal id used or hooks, that can also be used as an identifier for filters - */ - public function getFilterId(): string - { - return $this->getId(); - } -} diff --git a/src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php deleted file mode 100644 index 878b9f17..00000000 --- a/src/Core/Grid/Definition/Factory/AbstractGridDefinitionFactory.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinition; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollectionInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Event\Dispatcher\NullDispatcher; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\DependencyInjection\Container; - -/** - * Class AbstractGridDefinitionFactory implements grid definition creation. - */ -abstract class AbstractGridDefinitionFactory implements GridDefinitionFactoryInterface -{ - use TranslatorAwareTrait; - - /** - * @var HookDispatcherInterface - */ - protected $hookDispatcher; - - /** - * @param HookDispatcherInterface|null $hookDispatcher - */ - public function __construct(HookDispatcherInterface $hookDispatcher = null) - { - if (null === $hookDispatcher) { - @trigger_error('The $hookDispatcher parameter should not be null, inject your main HookDispatcherInterface service, or NullDispatcher if you don\'t need hooks.', E_USER_DEPRECATED); - } - $this->hookDispatcher = $hookDispatcher ? $hookDispatcher : new NullDispatcher(); - } - - /** - * Set hook dispatcher. - * - * @param HookDispatcherInterface $hookDispatcher - * - * @deprecated - */ - final public function setHookDispatcher(HookDispatcherInterface $hookDispatcher) - { - @trigger_error('The AbstractGridDefinitionFactory::setHookDispatcher method is deprecated as of 1.7.5.1 Please use the constructor instead', E_USER_DEPRECATED); - - $this->hookDispatcher = $hookDispatcher; - } - - /** - * {@inheritdoc} - */ - final public function getDefinition() - { - $definition = new GridDefinition( - $this->getId(), - $this->getName(), - $this->getColumns(), - $this->getFilters(), - $this->getGridActions(), - $this->getBulkActions() - ); - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDefinitionModifier', [ - 'definition' => $definition, - ]); - - return $definition; - } - - /** - * Get unique grid identifier. - * - * @return string - */ - abstract protected function getId(); - - /** - * Get translated grid name. - * - * @return string - */ - abstract protected function getName(); - - /** - * Get defined columns for grid. - * - * @return ColumnCollectionInterface - */ - abstract protected function getColumns(); - - /** - * Get defined grid actions. - * Override this method to define custom grid actions collection. - * - * @return GridActionCollectionInterface - */ - protected function getGridActions() - { - return new GridActionCollection(); - } - - /** - * Get defined bulk actions. - * Override this method to define custom bulk actions collection. - * - * @return BulkActionCollectionInterface - */ - protected function getBulkActions() - { - return new BulkActionCollection(); - } - - /** - * Get defined filters. - * Override this method to define custom filters collection. - * - * @return FilterCollectionInterface - */ - protected function getFilters() - { - return new FilterCollection(); - } -} diff --git a/src/Core/Grid/Definition/Factory/AddressGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AddressGridDefinitionFactory.php deleted file mode 100644 index 2454581b..00000000 --- a/src/Core/Grid/Definition/Factory/AddressGridDefinitionFactory.php +++ /dev/null @@ -1,292 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollectionInterface; -use PrestaShopBundle\Form\Admin\Type\CountryChoiceType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class is responsible for defining 'Sell > Customer > Addresses' grid. - */ -final class AddressGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - public const GRID_ID = 'address'; - - /** - * {@inheritdoc} - */ - protected function getId(): string - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName(): string - { - return $this->trans('Addresses', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns(): ColumnCollectionInterface - { - $columns = (new ColumnCollection()) - ->add( - (new BulkActionColumn('addresses_bulk')) - ->setOptions([ - 'bulk_field' => 'id_address', - ]) - ) - ->add( - (new DataColumn('id_address')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_address', - ]) - ) - ->add( - (new DataColumn('firstname')) - ->setName($this->trans('First name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'firstname', - ]) - ) - ->add( - (new DataColumn('lastname')) - ->setName($this->trans('Last name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'lastname', - ]) - ) - ->add( - (new DataColumn('address1')) - ->setName($this->trans('Address', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'address1', - ]) - ) - ->add( - (new DataColumn('postcode')) - ->setName($this->trans('Zip/postal code', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'postcode', - ]) - ) - ->add( - (new DataColumn('city')) - ->setName($this->trans('City', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'city', - ]) - )->add( - (new DataColumn('country_name')) - ->setName($this->trans('Country', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'country_name', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_addresses_edit', - 'route_param_name' => 'addressId', - 'route_param_field' => 'id_address', - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_addresses_delete', - 'route_param_name' => 'addressId', - 'route_param_field' => 'id_address', - ]) - ), - ]) - ) - ; - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters(): FilterCollectionInterface - { - $filters = (new FilterCollection()) - ->add( - (new Filter('id_address', NumberType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('id_address') - ) - ->add( - (new Filter('firstname', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search first name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('firstname') - ) - ->add( - (new Filter('lastname', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search last name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('lastname') - ) - ->add( - (new Filter('address1', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search address', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('address1') - ) - ->add( - (new Filter('postcode', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search post code', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('postcode') - ) - ->add( - (new Filter('city', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search city', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('city') - ) - ->add( - (new Filter('id_country', CountryChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('country_name') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_addresses_index', - ]) - ); - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions(): GridActionCollectionInterface - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions(): BulkActionCollectionInterface - { - return (new BulkActionCollection()) - ->add( - $this->buildBulkDeleteAction('admin_addresses_delete_bulk') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/AttachmentGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AttachmentGridDefinitionFactory.php deleted file mode 100644 index f8f1c515..00000000 --- a/src/Core/Grid/Definition/Factory/AttachmentGridDefinitionFactory.php +++ /dev/null @@ -1,267 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines attachments list grid - */ -final class AttachmentGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - public const GRID_ID = 'attachment'; - - /** - * @param HookDispatcherInterface $hookDispatcher - */ - public function __construct(HookDispatcherInterface $hookDispatcher) - { - parent::__construct($hookDispatcher); - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Files', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columns = (new ColumnCollection()) - ->add( - (new BulkActionColumn('files_bulk')) - ->setOptions([ - 'bulk_field' => 'id_attachment', - ]) - ) - ->add( - (new DataColumn('id_attachment')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_attachment', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new DataColumn('file')) - ->setName($this->trans('File', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'file', - ]) - ) - ->add( - (new DataColumn('file_size')) - ->setName($this->trans('Size', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'file_size', - ]) - ) - ->add( - (new DataColumn('products')) - ->setName($this->trans('Products', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'products', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_attachments_edit', - 'route_param_name' => 'attachmentId', - 'route_param_field' => 'id_attachment', - ]) - ) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_attachments_view', - 'route_param_name' => 'attachmentId', - 'route_param_field' => 'id_attachment', - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_attachments_delete', - 'route_param_name' => 'attachmentId', - 'route_param_field' => 'id_attachment', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'confirm_message_type' => SubmitRowAction::MESSAGE_TYPE_DYNAMIC, - 'dynamic_message_field' => 'dynamic_message', - ]) - ), - ]) - ); - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = (new FilterCollection()) - ->add( - (new Filter('id_attachment', NumberType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('id_attachment') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search file name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('name') - ) - ->add( - (new Filter('file_size', NumberType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search file size', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('file_size') - ) - ->add( - (new Filter('products', NumberType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Products', [], 'Admin.Catalog.Feature'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('products') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_attachments_index', - ]) - ); - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - $this->buildBulkDeleteAction('admin_attachments_delete_bulk') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/AttributeGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AttributeGridDefinitionFactory.php deleted file mode 100644 index 97add02c..00000000 --- a/src/Core/Grid/Definition/Factory/AttributeGridDefinitionFactory.php +++ /dev/null @@ -1,295 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\AttributeGroup\AttributeGroupViewDataProviderInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Attribute\AttributeColorColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines grid for attributes group > attributes list - */ -final class AttributeGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - const GRID_ID = 'attribute'; - - /** - * @var int - */ - private $attributeGroupId; - - /** - * @var AttributeGroupViewDataProviderInterface - */ - private $attributeGroupViewDataProvider; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param int $attributeGroupId - * @param AttributeGroupViewDataProviderInterface $attributeGroupViewDataProvider - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $attributeGroupId, - AttributeGroupViewDataProviderInterface $attributeGroupViewDataProvider - ) { - parent::__construct($hookDispatcher); - $this->attributeGroupId = $attributeGroupId; - $this->attributeGroupViewDataProvider = $attributeGroupViewDataProvider; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->attributeGroupViewDataProvider->getAttributeGroupNameById((int) $this->attributeGroupId); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columns = (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_attribute', - ]) - ) - ->add((new DataColumn('id_attribute')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_attribute', - ]) - ) - ->add((new DataColumn('value')) - ->setName($this->trans('Value', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'value', - ]) - ); - - if ($this->attributeGroupViewDataProvider->isColorGroup($this->attributeGroupId)) { - $columns->add((new AttributeColorColumn('color')) - ->setName($this->trans('Color', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'color', - ]) - ); - } - - $columns - ->add((new PositionColumn('position')) - ->setName($this->trans('Position', [], 'Admin.Global')) - ->setOptions([ - 'id_field' => 'id_attribute', - 'position_field' => 'position', - 'update_method' => 'POST', - 'update_route' => 'admin_attributes_update_position', - 'record_route_params' => [ - 'id_attribute_group' => 'attributeGroupId', - ], - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_attributes_edit', - 'route_param_name' => 'attributeGroupId', - 'route_param_field' => 'id_attribute_group', - 'extra_route_params' => [ - 'attributeId' => 'id_attribute', - ], - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_attributes_delete', - 'route_param_name' => 'attributeGroupId', - 'route_param_field' => 'id_attribute_group', - 'extra_route_params' => [ - 'attributeId' => 'id_attribute', - ], - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'attributes', - ], - ]) - ) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = (new FilterCollection()) - ->add((new Filter('id_attribute', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_attribute') - ) - ->add((new Filter('value', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search value', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('value') - ) - ->add((new Filter('position', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search position', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('position') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_attributes_index', - 'redirect_route_params' => [ - 'attributeGroupId' => $this->attributeGroupId, - ], - ]) - ->setAssociatedColumn('actions') - ); - - if ($this->attributeGroupViewDataProvider->isColorGroup($this->attributeGroupId)) { - $filters->add((new Filter('color', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search color', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('color') - ); - } - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_attributes_bulk_delete', - 'route_params' => [ - 'attributeGroupId' => $this->attributeGroupId, - ], - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/AttributeGroupGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/AttributeGroupGridDefinitionFactory.php deleted file mode 100644 index b698951a..00000000 --- a/src/Core/Grid/Definition/Factory/AttributeGroupGridDefinitionFactory.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines attribute groups grid - */ -final class AttributeGroupGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - const GRID_ID = 'attribute_group'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Attributes', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_attribute_group', - ]) - ) - ->add((new DataColumn('id_attribute_group')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_attribute_group', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new DataColumn('values')) - ->setName($this->trans('Values', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'values', - 'sortable' => false, - ]) - ) - ->add((new PositionColumn('position')) - ->setName($this->trans('Position', [], 'Admin.Global')) - ->setOptions([ - 'id_field' => 'id_attribute_group', - 'position_field' => 'position', - 'update_method' => 'POST', - 'update_route' => 'admin_attribute_groups_update_position', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_attributes_index', - 'route_param_name' => 'attributeGroupId', - 'route_param_field' => 'id_attribute_group', - ]) - ) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_attribute_groups_edit', - 'route_param_name' => 'attributeGroupId', - 'route_param_field' => 'id_attribute_group', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_attribute_groups_delete', - 'route_param_name' => 'attributeGroupId', - 'route_param_field' => 'id_attribute_group', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'attribute_groups', - ], - ]) - ) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_attribute_group', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_attribute_group') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('position', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search position', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('position') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_attribute_groups_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_attribute_groups_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/BackupDefinitionFactory.php b/src/Core/Grid/Definition/Factory/BackupDefinitionFactory.php deleted file mode 100644 index 428b250a..00000000 --- a/src/Core/Grid/Definition/Factory/BackupDefinitionFactory.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; - -/** - * Class BackupDefinitionFactory is responsible for defining 'Configure > Advanced Parameters > Database > Backup' grid. - */ -final class BackupDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'backup'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('DB Backup', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('backup_bulk_file_names')) - ->setOptions([ - 'bulk_field' => 'file_name', - ]) - ) - ->add( - (new DataColumn('date')) - ->setName($this->trans('Date', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'date_formatted', - 'sortable' => false, - ]) - ) - ->add( - (new DataColumn('age')) - ->setName($this->trans('Age', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'age_formatted', - 'sortable' => false, - ]) - ) - ->add( - (new DataColumn('file_name')) - ->setName($this->trans('Filename', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'file_name', - 'sortable' => false, - ]) - ) - ->add( - (new DataColumn('file_size')) - ->setName($this->trans('File size', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'file_size_formatted', - 'sortable' => false, - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('view')) - ->setIcon('remove_red_eye') - ->setOptions([ - 'route' => 'admin_backups_download_view', - 'route_param_name' => 'downloadFileName', - 'route_param_field' => 'file_name', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_backups_delete', - 'route_param_name' => 'deleteFileName', - 'route_param_field' => 'file_name', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_backups')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_backups_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/BulkDeleteActionTrait.php b/src/Core/Grid/Definition/Factory/BulkDeleteActionTrait.php deleted file mode 100644 index b68db452..00000000 --- a/src/Core/Grid/Definition/Factory/BulkDeleteActionTrait.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\ModalOptions; - -/** - * Trait to help build the bulk delete action - */ -trait BulkDeleteActionTrait -{ - /** - * @param string $bulkDeleteRouteName - * - * @return BulkActionInterface - */ - protected function buildBulkDeleteAction(string $bulkDeleteRouteName) - { - return (new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => $bulkDeleteRouteName, - 'confirm_message' => $this->trans('Are you sure you want to delete the selected item(s)?', [], 'Admin.Global'), - 'modal_options' => new ModalOptions([ - 'title' => $this->trans('Delete selection', [], 'Admin.Actions'), - 'confirm_button_label' => $this->trans('Delete', [], 'Admin.Actions'), - 'confirm_button_class' => 'btn-danger', - ]), - ]) - ; - } - - /** - * Shortcut method to translate text. - * - * @param string $id - * @param array $options - * @param string $domain - * - * @return string - */ - abstract protected function trans($id, array $options, $domain); -} diff --git a/src/Core/Grid/Definition/Factory/CatalogPriceRuleGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CatalogPriceRuleGridDefinitionFactory.php deleted file mode 100644 index a2191f6b..00000000 --- a/src/Core/Grid/Definition/Factory/CatalogPriceRuleGridDefinitionFactory.php +++ /dev/null @@ -1,347 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class responsible for providing columns, filters, actions for catalog price rule list. - */ -final class CatalogPriceRuleGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - const GRID_ID = 'catalog_price_rule'; - - public function __construct( - HookDispatcherInterface $hookDispatcher - ) { - parent::__construct($hookDispatcher); - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Catalog price rules', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_specific_price_rule', - ]) - ) - ->add((new DataColumn('id_specific_price_rule')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_specific_price_rule', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new DataColumn('shop')) - ->setName($this->trans('Shop', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'shop', - ]) - ) - ->add((new DataColumn('currency')) - ->setName($this->trans('Currency', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'currency', - ]) - ) - ->add((new DataColumn('country')) - ->setName($this->trans('Country', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'country', - ]) - ) - ->add((new DataColumn('group_name')) - ->setName($this->trans('Group', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'group_name', - ]) - ) - ->add((new DataColumn('from_quantity')) - ->setName($this->trans('From quantity', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'from_quantity', - ]) - ) - ->add((new DataColumn('reduction_type')) - ->setName($this->trans('Reduction type', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'reduction_type', - ]) - ) - ->add((new DataColumn('reduction')) - ->setName($this->trans('Reduction', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'reduction', - ]) - ) - ->add((new DateTimeColumn('date_from')) - ->setName($this->trans('Beginning', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'format' => 'Y-m-d H:i', - 'field' => 'date_from', - ]) - ) - ->add((new DateTimeColumn('date_to')) - ->setName($this->trans('End', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'format' => 'Y-m-d H:i', - 'field' => 'date_to', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_catalog_price_rules_edit', - 'route_param_name' => 'catalogPriceRuleId', - 'route_param_field' => 'id_specific_price_rule', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'POST', - 'route' => 'admin_catalog_price_rules_delete', - 'route_param_name' => 'catalogPriceRuleId', - 'route_param_field' => 'id_specific_price_rule', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_specific_price_rule', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('ID', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('id_specific_price_rule') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Name', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('shop', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Shop', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('shop') - ) - ->add((new Filter('currency', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Currency', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('currency') - ) - ->add((new Filter('country', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Country', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('country') - ) - ->add((new Filter('group_name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Group', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('group_name') - ) - ->add((new Filter('from_quantity', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('From quantity', [], 'Admin.Catalog.Feature'), - ], - ]) - ->setAssociatedColumn('from_quantity') - ) - ->add((new Filter('reduction_type', ChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choices' => [ - $this->trans('Percentage', [], 'Admin.Global') => 'percentage', - $this->trans('Amount', [], 'Admin.Global') => 'amount', - ], - ]) - ->setAssociatedColumn('reduction_type') - ) - ->add((new Filter('reduction', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Reduction', [], 'Admin.Catalog.Feature'), - ], - ]) - ->setAssociatedColumn('reduction') - ) - ->add((new Filter('date_from', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Beginning', [], 'Admin.Catalog.Feature'), - ], - 'date_format' => 'YYYY-MM-DD HH:mm:ss', - ]) - ->setAssociatedColumn('date_from') - ) - ->add((new Filter('date_to', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('End', [], 'Admin.Catalog.Feature'), - ], - 'date_format' => 'YYYY-MM-DD HH:mm:ss', - ]) - ->setAssociatedColumn('date_to') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_catalog_price_rules_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_catalog_price_rules_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/CategoryGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CategoryGridDefinitionFactory.php deleted file mode 100644 index 40150a71..00000000 --- a/src/Core/Grid/Definition/Factory/CategoryGridDefinitionFactory.php +++ /dev/null @@ -1,369 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\Catalog\Category\DeleteCategoriesBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\Category\DeleteCategoryRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Category\CategoryPositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DraggableColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\IdentifierColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class CategoryGridDefinitionFactory builds Grid definition for Categories listing. - */ -final class CategoryGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - const GRID_ID = 'category'; - - /** - * @var string - */ - private $resetActionUrl; - - /** - * @var string - */ - private $redirectActionUrl; - - /** - * @var AccessibilityCheckerInterface - */ - private $categoryForViewAccessibilityChecker; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetActionUrl - * @param string $redirectActionUrl - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param AccessibilityCheckerInterface $categoryForViewAccessibilityChecker - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetActionUrl, - $redirectActionUrl, - MultistoreContextCheckerInterface $multistoreContextChecker, - AccessibilityCheckerInterface $categoryForViewAccessibilityChecker - ) { - parent::__construct($hookDispatcher); - $this->resetActionUrl = $resetActionUrl; - $this->redirectActionUrl = $redirectActionUrl; - $this->categoryForViewAccessibilityChecker = $categoryForViewAccessibilityChecker; - $this->multistoreContextChecker = $multistoreContextChecker; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Categories', [], 'Admin.Global'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columns = (new ColumnCollection()) - ->add( - (new IdentifierColumn('id_category')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'identifier_field' => 'id_category', - 'bulk_field' => 'id_category', - 'with_bulk_field' => true, - 'clickable' => false, - ]) - ) - ->add( - (new LinkColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - 'route' => 'admin_categories_index', - 'route_param_name' => 'categoryId', - 'route_param_field' => 'id_category', - ]) - ) - ->add( - (new DataColumn('description')) - ->setName($this->trans('Description', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'description', - 'sortable' => false, - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Displayed', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_category', - 'route' => 'admin_categories_toggle_status', - 'route_param_name' => 'categoryId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => $this->getRowActions(), - ]) - ); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $columns - ->addAfter( - 'description', - (new CategoryPositionColumn('position')) - ->setName($this->trans('Position', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'position', - 'id_field' => 'id_category', - 'id_parent_field' => 'id_parent', - 'update_route' => 'admin_categories_update_position', - ]) - ) - ->addBefore('id_category', new DraggableColumn('position_drag')) - ; - } - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = (new FilterCollection()) - ->add( - (new Filter('id_category', TextType::class)) - ->setAssociatedColumn('id_category') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('name', TextType::class)) - ->setAssociatedColumn('name') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('description', TextType::class)) - ->setAssociatedColumn('description') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search description', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_categories_index', - ]) - ); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $filters->add( - (new Filter('position', TextType::class)) - ->setAssociatedColumn('position') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search position', [], 'Admin.Actions'), - ], - ]) - ); - } - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'categories', - ], - ]) - ) - ->add( - (new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_categories_export', - ]) - ) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_categories_bulk_enable_status', - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_categories_bulk_disable_status', - ]) - ) - ->add( - (new DeleteCategoriesBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'categories_bulk_delete_route' => 'admin_categories_bulk_delete', - ]) - ); - } - - /** - * @return RowActionCollection - */ - private function getRowActions() - { - return (new RowActionCollection()) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_categories_index', - 'route_param_name' => 'categoryId', - 'route_param_field' => 'id_category', - 'accessibility_checker' => $this->categoryForViewAccessibilityChecker, - 'clickable_row' => true, - ]) - ) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_categories_edit', - 'route_param_name' => 'categoryId', - 'route_param_field' => 'id_category', - 'clickable_row' => true, // Will only apply if first link action is filtered - ]) - ) - ->add( - (new DeleteCategoryRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'category_id_field' => 'id_category', - 'category_delete_route' => 'admin_categories_delete', - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/CmsPageCategoryDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CmsPageCategoryDefinitionFactory.php deleted file mode 100644 index 1456a7b6..00000000 --- a/src/Core/Grid/Definition/Factory/CmsPageCategoryDefinitionFactory.php +++ /dev/null @@ -1,360 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Class CmsPageCategoryDefinitionFactory builds Grid definition for Cms page category listing. - */ -final class CmsPageCategoryDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - const GRID_ID = 'cms_page_category'; - - /** - * @var int - */ - private $cmsCategoryParentId; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var bool - */ - private $isMultiStoreFeatureUsed; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param RequestStack $requestStack - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param bool $isMultiStoreFeatureUsed - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - RequestStack $requestStack, - MultistoreContextCheckerInterface $multistoreContextChecker, - $isMultiStoreFeatureUsed - ) { - parent::__construct($hookDispatcher); - $this->setCmsPageCategoryParentId($requestStack); - - $this->multistoreContextChecker = $multistoreContextChecker; - $this->isMultiStoreFeatureUsed = $isMultiStoreFeatureUsed; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Categories', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columnCollection = (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_cms_category', - ]) - ) - ->add((new DataColumn('id_cms_category')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_cms_category', - ]) - ) - ->add((new LinkColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - 'route' => 'admin_cms_pages_index', - 'route_param_name' => 'id_cms_category', - 'route_param_field' => 'id_cms_category', - ]) - ) - ->add((new DataColumn('description')) - ->setName($this->trans('Description', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'description', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Displayed', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'route' => 'admin_cms_pages_category_toggle', - 'primary_field' => 'id_cms_category', - 'route_param_name' => 'cmsCategoryId', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_cms_pages_index', - 'route_param_name' => 'id_cms_category', - 'route_param_field' => 'id_cms_category', - 'clickable_row' => true, - ]) - ) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_cms_pages_category_edit', - 'route_param_name' => 'cmsCategoryId', - 'route_param_field' => 'id_cms_category', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_cms_pages_category_delete', - 'route_param_name' => 'cmsCategoryId', - 'route_param_field' => 'id_cms_category', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - - if ($this->isAllShopContextOrShopFeatureIsNotUsed()) { - $columnCollection - ->addAfter( - 'description', - (new PositionColumn('position')) - ->setName($this->trans('Position', [], 'Admin.Global')) - ->setOptions([ - 'id_field' => 'id_cms_category', - 'position_field' => 'position', - 'update_method' => 'POST', - 'update_route' => 'admin_cms_pages_category_update_position', - 'record_route_params' => [ - 'id_parent' => 'id_cms_category', - ], - ]) - ); - } - - return $columnCollection; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $actionsTypeOptions = [ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_cms_pages_index', - ]; - - if ($this->cmsCategoryParentId) { - $actionsTypeOptions['redirect_route_params'] = [ - 'id_cms_category' => $this->cmsCategoryParentId, - ]; - - $actionsTypeOptions['reset_route_params']['id_cms_category'] = $this->cmsCategoryParentId; - } - - $filterCollection = (new FilterCollection()) - ->add((new Filter('id_cms_category', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('ID', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('id_cms_category') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Name', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('description', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Description', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('description') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions($actionsTypeOptions) - ->setAssociatedColumn('actions') - ) - ; - - if ($this->isAllShopContextOrShopFeatureIsNotUsed()) { - $filterCollection - ->add((new Filter('position', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Position', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('position') - ) - ; - } - - return $filterCollection; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_cms_pages_category_bulk_status_enable', - ]) - ) - ->add((new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_cms_pages_category_bulk_status_disable', - ]) - ) - ->add( - $this->buildBulkDeleteAction('admin_cms_pages_category_delete_bulk') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * Sets cms page category parent id directly from request attribute. On not found case, it assigns the default one. - * - * @param RequestStack $requestStack - */ - private function setCmsPageCategoryParentId(RequestStack $requestStack) - { - $request = $requestStack->getCurrentRequest(); - - if (null !== $request && $request->query->getInt('id_cms_category')) { - $this->cmsCategoryParentId = $request->query->getInt('id_cms_category'); - } - } - - /** - * This function is required due to in cms_category contains position column - on ideal case cms_category_shop - * should have this column configured instead. - * In such case the condition would be $this->multistoreContextChecker->isSingleShopContext() - * - * @return bool - */ - private function isAllShopContextOrShopFeatureIsNotUsed() - { - return $this->multistoreContextChecker->isAllShopContext() || !$this->isMultiStoreFeatureUsed; - } -} diff --git a/src/Core/Grid/Definition/Factory/CmsPageDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CmsPageDefinitionFactory.php deleted file mode 100644 index b14ca1f3..00000000 --- a/src/Core/Grid/Definition/Factory/CmsPageDefinitionFactory.php +++ /dev/null @@ -1,378 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryNameForListing; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Class responsible for providing columns, filters, actions for cms page list. - */ -class CmsPageDefinitionFactory extends AbstractGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - const GRID_ID = 'cms_page'; - - /** - * @var int - */ - private $cmsCategoryParentId; - - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var bool - */ - private $isMultiStoreFeatureUsed; - - public function __construct( - HookDispatcherInterface $hookDispatcher, - CommandBusInterface $queryBus, - RequestStack $requestStack, - MultistoreContextCheckerInterface $multistoreContextChecker, - $isMultiStoreFeatureUsed - ) { - parent::__construct($hookDispatcher); - - $this->queryBus = $queryBus; - $this->requestStack = $requestStack; - - $this->setCmsPageCategoryParentId($requestStack); - $this->multistoreContextChecker = $multistoreContextChecker; - $this->isMultiStoreFeatureUsed = $isMultiStoreFeatureUsed; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - $cmsCategoryName = $this->queryBus->handle(new GetCmsPageCategoryNameForListing()); - - return $this->trans( - 'Pages in category "%name%"', - ['%name%' => $cmsCategoryName], - 'Admin.Design.Feature' - ); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columnCollection = (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_cms', - ]) - ) - ->add((new DataColumn('id_cms')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_cms', - ]) - ) - ->add((new DataColumn('link_rewrite')) - ->setName($this->trans('URL', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'link_rewrite', - ]) - ) - ->add((new DataColumn('meta_title')) - ->setName($this->trans('Title', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'meta_title', - ]) - ) - ->add((new DataColumn('head_seo_title')) - ->setName($this->trans('Meta title', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'head_seo_title', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Displayed', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'route' => 'admin_cms_pages_toggle', - 'primary_field' => 'id_cms', - 'route_param_name' => 'cmsId', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_cms_pages_edit', - 'route_param_name' => 'cmsPageId', - 'route_param_field' => 'id_cms', - 'clickable_row' => true, - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_cms_pages_delete', - 'route_param_name' => 'cmsId', - 'route_param_field' => 'id_cms', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - - if ($this->isAllShopContextOrShopFeatureIsNotUsed()) { - $columnCollection - ->addAfter( - 'head_seo_title', - (new PositionColumn('position')) - ->setName($this->trans('Position', [], 'Admin.Global')) - ->setOptions([ - 'id_field' => 'id_cms', - 'position_field' => 'position', - 'update_method' => 'POST', - 'update_route' => 'admin_cms_pages_update_position', - 'record_route_params' => [ - 'id_cms_category' => 'id_cms_category', - ], - ]) - ); - } - - return $columnCollection; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $actionsTypeOptions = [ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_cms_pages_index', - ]; - - if ($this->cmsCategoryParentId) { - $actionsTypeOptions['redirect_route_params'] = [ - 'id_cms_category' => $this->cmsCategoryParentId, - ]; - - $actionsTypeOptions['reset_route_params']['id_cms_category'] = $this->cmsCategoryParentId; - } - - $filterCollection = (new FilterCollection()) - ->add((new Filter('id_cms', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('ID', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('id_cms') - ) - ->add((new Filter('link_rewrite', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('URL', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('link_rewrite') - ) - ->add((new Filter('meta_title', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Title', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('meta_title') - ) - ->add((new Filter('head_seo_title', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Meta title', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('head_seo_title') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions($actionsTypeOptions) - ->setAssociatedColumn('actions') - ) - ; - - if ($this->isAllShopContextOrShopFeatureIsNotUsed()) { - $filterCollection - ->add((new Filter('position', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Position', [], 'Admin.Global'), - ], - ]) - ->setAssociatedColumn('position') - ) - ; - } - - return $filterCollection; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_cms_pages_bulk_enable_status', - ]) - ) - ->add((new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_cms_pages_bulk_disable_status', - ]) - ) - ->add( - $this->buildBulkDeleteAction('admin_cms_pages_bulk_delete') - ) - ; - } - - /** - * Sets cms page category parent id directly from request attribute. On not found case, it assigns the default one. - * - * @param RequestStack $requestStack - */ - private function setCmsPageCategoryParentId(RequestStack $requestStack) - { - $request = $requestStack->getCurrentRequest(); - - if (null !== $request && $request->query->getInt('id_cms_category')) { - $this->cmsCategoryParentId = $request->query->getInt('id_cms_category'); - } - } - - /** - * This function is required due to in cms_category contains position column - on ideal case cms_category_shop - * should have this column configured instead. - * In such case the condition would be $this->multistoreContextChecker->isSingleShopContext() - * - * @return bool - */ - private function isAllShopContextOrShopFeatureIsNotUsed() - { - return $this->multistoreContextChecker->isAllShopContext() || !$this->isMultiStoreFeatureUsed; - } -} diff --git a/src/Core/Grid/Definition/Factory/ContactGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/ContactGridDefinitionFactory.php deleted file mode 100644 index ccfbe3f8..00000000 --- a/src/Core/Grid/Definition/Factory/ContactGridDefinitionFactory.php +++ /dev/null @@ -1,252 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class ContactGridDefinitionFactory is responsible for creating Contact grid definition. - */ -final class ContactGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string - */ - private $resetSearchUrl; - - /** - * @var string - */ - private $redirectionUrl; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetSearchUrl - * @param string $redirectionUrl - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetSearchUrl, - $redirectionUrl - ) { - parent::__construct($hookDispatcher); - $this->resetSearchUrl = $resetSearchUrl; - $this->redirectionUrl = $redirectionUrl; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'contact'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Contacts', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_contact', - ]) - ) - ->add( - (new DataColumn('id_contact')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_contact', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Title', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new DataColumn('email')) - ->setName($this->trans('Email address', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'email', - ]) - ) - ->add( - (new DataColumn('description')) - ->setName($this->trans('Description', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'description', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_contacts_edit', - 'route_param_name' => 'contactId', - 'route_param_field' => 'id_contact', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'POST', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_contacts_delete', - 'route_param_name' => 'contactId', - 'route_param_field' => 'id_contact', - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_contact', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('id_contact') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('name') - ) - ->add( - (new Filter('email', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('email') - ) - ->add( - (new Filter('description', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('description') - ) - - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetSearchUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_all')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_contacts_delete_bulk', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/CreditSlipGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CreditSlipGridDefinitionFactory.php deleted file mode 100644 index 511f560d..00000000 --- a/src/Core/Grid/Definition/Factory/CreditSlipGridDefinitionFactory.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines grid for credit slip listing - */ -final class CreditSlipGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - const GRID_ID = 'credit_slip'; - - /** - * @var string - */ - private $dateFormat; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $dateFormat The format in which date column values should be shown - */ - public function __construct(HookDispatcherInterface $hookDispatcher, $dateFormat) - { - parent::__construct($hookDispatcher); - $this->dateFormat = $dateFormat; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Credit Slips', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new DataColumn('id_order_slip')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_order_slip', - ]) - ) - ->add((new DataColumn('id_order')) - ->setName($this->trans('Order ID', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'id_order', - ]) - ) - ->add((new DateTimeColumn('date_add')) - ->setName($this->trans('Date issued', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'date_add', - 'format' => $this->dateFormat, - ]) - ) - ->add( - (new LinkColumn('pdf')) - ->setName($this->trans('PDF', [], 'Admin.Global')) - ->setOptions([ - 'sortable' => false, - 'field' => 'link_value', - 'route' => 'admin_credit_slips_generate_pdf', - 'route_param_name' => 'creditSlipId', - 'route_param_field' => 'id_order_slip', - 'icon' => 'insert_drive_file', - 'button_template' => 'outline', - 'color_template' => 'secondary', - ]) - ) - ->add((new ActionColumn('actions'))); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_credit_slip', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_order_slip') - ) - ->add((new Filter('id_order', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search order ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_order') - ) - ->add((new Filter('date_issued', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('date_add') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_credit_slips_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/CurrencyGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CurrencyGridDefinitionFactory.php deleted file mode 100644 index b499a1a8..00000000 --- a/src/Core/Grid/Definition/Factory/CurrencyGridDefinitionFactory.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class CurrencyGridDefinitionFactory is responsible for defining definition for currency list located in - * "International -> Localization -> currencies". - */ -final class CurrencyGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - const GRID_ID = 'currency'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Currencies', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new DataColumn('currency')) - ->setName($this->trans('Currency', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'currency', - 'sortable' => false, - ]) - ) - ->add((new DataColumn('symbol')) - ->setName($this->trans('Symbol', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'symbol', - 'sortable' => false, - ]) - ) - ->add((new DataColumn('iso_code')) - ->setName($this->trans('ISO code', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'iso_code', - ]) - ) - ->add((new DataColumn('conversion_rate')) - ->setName($this->trans('Exchange rate', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'conversion_rate', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_currency', - 'route' => 'admin_currencies_toggle_status', - 'route_param_name' => 'currencyId', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_currencies_edit', - 'route_param_name' => 'currencyId', - 'route_param_field' => 'id_currency', - 'clickable_row' => true, - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_currencies_delete', - 'route_param_name' => 'currencyId', - 'route_param_field' => 'id_currency', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('iso_code', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('ISO code', [], 'Admin.International.Feature'), - ], - ]) - ->setAssociatedColumn('iso_code') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('active') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_currencies_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/CustomerGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/CustomerGridDefinitionFactory.php deleted file mode 100644 index dc1167b3..00000000 --- a/src/Core/Grid/Definition/Factory/CustomerGridDefinitionFactory.php +++ /dev/null @@ -1,444 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\Customer\DeleteCustomersBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\Customer\DeleteCustomerRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BadgeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class CustomerGridDefinitionFactory defines customers grid structure. - */ -final class CustomerGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - const GRID_ID = 'customer'; - - /** - * @var bool - */ - private $isB2bFeatureEnabled; - - /** - * @var bool - */ - private $isMultistoreFeatureEnabled; - - /** - * @var array - */ - private $genderChoices; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param bool $isB2bFeatureEnabled - * @param bool $isMultistoreFeatureEnabled - * @param array $genderChoices - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $isB2bFeatureEnabled, - $isMultistoreFeatureEnabled, - array $genderChoices - ) { - parent::__construct($hookDispatcher); - $this->isB2bFeatureEnabled = $isB2bFeatureEnabled; - $this->isMultistoreFeatureEnabled = $isMultistoreFeatureEnabled; - $this->genderChoices = $genderChoices; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Manage your Customers', [], 'Admin.Orderscustomers.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columns = (new ColumnCollection()) - ->add( - (new BulkActionColumn('customers_bulk')) - ->setOptions([ - 'bulk_field' => 'id_customer', - ]) - ) - ->add( - (new DataColumn('id_customer')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_customer', - ]) - ) - ->add( - (new DataColumn('social_title')) - ->setName($this->trans('Social title', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'social_title', - ]) - ) - ->add( - (new DataColumn('firstname')) - ->setName($this->trans('First name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'firstname', - ]) - ) - ->add( - (new DataColumn('lastname')) - ->setName($this->trans('Last name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'lastname', - ]) - ) - ->add( - (new DataColumn('email')) - ->setName($this->trans('Email address', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'email', - ]) - ) - ->add( - (new BadgeColumn('total_spent')) - ->setName($this->trans('Sales', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'total_spent', - 'empty_value' => '--', - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_customer', - 'route' => 'admin_customers_toggle_status', - 'route_param_name' => 'customerId', - ]) - ) - ->add( - (new ToggleColumn('newsletter')) - ->setName($this->trans('Newsletter', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'newsletter', - 'primary_field' => 'id_customer', - 'route' => 'admin_customers_toggle_newsletter_subscription', - 'route_param_name' => 'customerId', - ]) - ) - ->add( - (new ToggleColumn('optin')) - ->setName($this->trans('Partner offers', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'optin', - 'primary_field' => 'id_customer', - 'route' => 'admin_customers_toggle_partner_offer_subscription', - 'route_param_name' => 'customerId', - ]) - ) - ->add( - (new DataColumn('date_add')) - ->setName($this->trans('Registration', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'date_add', - ]) - ) - ->add( - (new DataColumn('connect')) - ->setName($this->trans('Last visit', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'connect', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_customers_edit', - 'route_param_name' => 'customerId', - 'route_param_field' => 'id_customer', - ]) - ) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_customers_view', - 'route_param_name' => 'customerId', - 'route_param_field' => 'id_customer', - 'clickable_row' => true, - ]) - ) - ->add((new DeleteCustomerRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'customer_id_field' => 'id_customer', - 'customer_delete_route' => 'admin_customers_delete', - ]) - ), - ]) - ); - - if ($this->isB2bFeatureEnabled) { - $columns->addAfter( - 'email', - (new DataColumn('company')) - ->setName($this->trans('Company', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'company', - ]) - ); - } - - if ($this->isMultistoreFeatureEnabled) { - $columns->addBefore( - 'actions', - (new DataColumn('shop_name')) - ->setName($this->trans('Shop', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'shop_name', - 'sortable' => false, - ]) - ); - } - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = (new FilterCollection()) - ->add( - (new Filter('id_customer', NumberType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('id_customer') - ) - ->add( - (new Filter('social_title', ChoiceType::class)) - ->setTypeOptions([ - 'choices' => $this->genderChoices, - 'expanded' => false, - 'multiple' => false, - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('social_title') - ) - ->add( - (new Filter('firstname', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search first name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('firstname') - ) - ->add( - (new Filter('lastname', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search last name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('lastname') - ) - ->add( - (new Filter('email', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search email', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('email') - ) - ->add( - (new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('newsletter', YesAndNoChoiceType::class)) - ->setAssociatedColumn('newsletter') - ) - ->add( - (new Filter('optin', YesAndNoChoiceType::class)) - ->setAssociatedColumn('optin') - ) - ->add( - (new Filter('date_add', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('date_add') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_customers_index', - ]) - ->setAssociatedColumn('actions') - ); - - if ($this->isB2bFeatureEnabled) { - $filters->add( - (new Filter('company', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search company', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('company') - ); - } - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'customers', - ], - ]) - ) - ->add( - (new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_customers_export', - ]) - ) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_customers_enable_bulk', - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_customers_disable_bulk', - ]) - ) - ->add((new DeleteCustomersBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'customers_bulk_delete_route' => 'admin_customers_delete_bulk', - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/EmailLogsDefinitionFactory.php b/src/Core/Grid/Definition/Factory/EmailLogsDefinitionFactory.php deleted file mode 100644 index 31180efc..00000000 --- a/src/Core/Grid/Definition/Factory/EmailLogsDefinitionFactory.php +++ /dev/null @@ -1,289 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SubmitGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class EmailLogsDefinitionFactory is responsible for creating email logs definition. - */ -final class EmailLogsDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string the URL to reset Grid filters - */ - private $resetActionUrl; - - /** - * @var string the URL for redirection - */ - private $redirectionUrl; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $languageChoiceProvider; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetActionUrl - * @param string $redirectionUrl - * @param ConfigurableFormChoiceProviderInterface $languageChoiceProvider - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetActionUrl, - $redirectionUrl, - ConfigurableFormChoiceProviderInterface $languageChoiceProvider - ) { - parent::__construct($hookDispatcher); - $this->resetActionUrl = $resetActionUrl; - $this->redirectionUrl = $redirectionUrl; - $this->languageChoiceProvider = $languageChoiceProvider; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'email_logs'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('E-mail', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('delete_email_logs')) - ->setOptions([ - 'bulk_field' => 'id_mail', - ]) - ) - ->add( - (new DataColumn('id_mail')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_mail', - ]) - ) - ->add( - (new DataColumn('recipient')) - ->setName($this->trans('Recipient', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'recipient', - ]) - ) - ->add( - (new DataColumn('template')) - ->setName($this->trans('Template', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'template', - ]) - ) - ->add( - (new DataColumn('language')) - ->setName($this->trans('Language', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'language', - ]) - ) - ->add( - (new DataColumn('subject')) - ->setName($this->trans('Subject', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'subject', - ]) - ) - ->add( - (new DataColumn('date_add')) - ->setName($this->trans('Sent', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'date_add', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('delete')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_emails_delete', - 'route_param_name' => 'mailId', - 'route_param_field' => 'id_mail', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_mail', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('id_mail') - ) - ->add( - (new Filter('recipient', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('recipient') - ) - ->add( - (new Filter('template', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('template') - ) - ->add( - (new Filter('id_lang', ChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choices' => $this->languageChoiceProvider->getChoices(), - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('language') - ) - ->add( - (new Filter('subject', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('subject') - ) - ->add( - (new Filter('date_add', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('date_add') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetActionUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SubmitGridAction('delete_all_email_logs')) - ->setName($this->trans('Erase all', [], 'Admin.Advparameters.Feature')) - ->setIcon('delete') - ->setOptions([ - 'submit_route' => 'admin_emails_delete_all', - 'confirm_message' => $this->trans('Are you sure?', [], 'Admin.Notifications.Warning'), - ]) - ) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_email_logs')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_emails_delete_bulk', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/EmployeeGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/EmployeeGridDefinitionFactory.php deleted file mode 100644 index e98d65b4..00000000 --- a/src/Core/Grid/Definition/Factory/EmployeeGridDefinitionFactory.php +++ /dev/null @@ -1,323 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\Common\Team\ProfileChoiceType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class EmployeeGridDefinitionFactory creates grid definition for Employee data. - */ -final class EmployeeGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string - */ - private $resetUrl; - - /** - * @var string - */ - private $redirectUrl; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetUrl - * @param string $redirectUrl - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetUrl, - $redirectUrl - ) { - parent::__construct($hookDispatcher); - $this->resetUrl = $resetUrl; - $this->redirectUrl = $redirectUrl; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'employee'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Employees', [], 'Admin.Advparameters.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('employee_bulk')) - ->setOptions([ - 'bulk_field' => 'id_employee', - ]) - ) - ->add( - (new DataColumn('id_employee')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_employee', - ]) - ) - ->add( - (new DataColumn('firstname')) - ->setName($this->trans('First name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'firstname', - ]) - ) - ->add( - (new DataColumn('lastname')) - ->setName($this->trans('Last name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'lastname', - ]) - ) - ->add( - (new DataColumn('email')) - ->setName($this->trans('Email address', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'email', - ]) - ) - ->add( - (new DataColumn('profile')) - ->setName($this->trans('Profile', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'profile_name', - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Active', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_employee', - 'route' => 'admin_employees_toggle_status', - 'route_param_name' => 'employeeId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_employees_edit', - 'route_param_name' => 'employeeId', - 'route_param_field' => 'id_employee', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_employees_delete', - 'route_param_name' => 'employeeId', - 'route_param_field' => 'id_employee', - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_employee', NumberType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_employee') - ) - ->add( - (new Filter('firstname', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search first name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('firstname') - ) - ->add( - (new Filter('lastname', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search last name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('lastname') - ) - ->add( - (new Filter('email', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search email', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('email') - ) - ->add( - (new Filter('profile', ProfileChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('profile') - ) - ->add( - (new Filter('active', ChoiceType::class)) - ->setTypeOptions([ - 'choices' => [ - $this->trans('Yes', [], 'Admin.Global') => 1, - $this->trans('No', [], 'Admin.Global') => 0, - ], - 'required' => false, - 'choice_translation_domain' => false, - ]) - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetUrl, - 'data-redirect' => $this->redirectUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_employees_bulk_enable_status', - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_employees_bulk_disable_status', - ]) - ) - ->add( - (new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_employees_bulk_delete', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/FilterableGridDefinitionFactoryInterface.php b/src/Core/Grid/Definition/Factory/FilterableGridDefinitionFactoryInterface.php deleted file mode 100644 index 6c15ed8f..00000000 --- a/src/Core/Grid/Definition/Factory/FilterableGridDefinitionFactoryInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -/** - * This interface allows to identify the filters associated to a Grid, which is then used - * to scope its parameters in request (thus allowing multi grid on same page) and as a key - * to persist them in database (and of course etch them afterwards). - */ -interface FilterableGridDefinitionFactoryInterface extends GridDefinitionFactoryInterface -{ - /** - * Returns a (unique) id to identify the grid filters, this is used as a key to persist - * (and clear) the Filters associated to the grid. - * - * @return string - */ - public function getFilterId(): string; -} diff --git a/src/Core/Grid/Definition/Factory/GridDefinitionFactoryInterface.php b/src/Core/Grid/Definition/Factory/GridDefinitionFactoryInterface.php deleted file mode 100644 index eacd347e..00000000 --- a/src/Core/Grid/Definition/Factory/GridDefinitionFactoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; - -/** - * Interface GridDefinitionFactoryInterface defines contract for creating grid. - */ -interface GridDefinitionFactoryInterface -{ - /** - * Create new grid definition. - * - * @return GridDefinitionInterface - */ - public function getDefinition(); -} diff --git a/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php deleted file mode 100644 index 60580f13..00000000 --- a/src/Core/Grid/Definition/Factory/LanguageGridDefinitionFactory.php +++ /dev/null @@ -1,329 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ImageColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class LanguageGridDefinitionFactory creates definition for languages grid. - */ -final class LanguageGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - const GRID_ID = 'language'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Languages', [], 'Admin.Global'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('language_bulk')) - ->setOptions([ - 'bulk_field' => 'id_lang', - ]) - ) - ->add( - (new DataColumn('id_lang')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_lang', - ]) - ) - ->add( - (new ImageColumn('flag')) - ->setName($this->trans('Flag', [], 'Admin.International.Feature')) - ->setOptions([ - 'src_field' => 'flag', - ]) - ) - ->add( - (new LinkColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - 'route' => 'admin_languages_edit', - 'route_param_name' => 'languageId', - 'route_param_field' => 'id_lang', - ]) - ) - ->add( - (new DataColumn('iso_code')) - ->setName($this->trans('ISO code', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'iso_code', - ]) - ) - ->add( - (new DataColumn('language_code')) - ->setName($this->trans('Language code', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'language_code', - ]) - ) - ->add( - (new DataColumn('date_format_lite')) - ->setName($this->trans('Date format', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'date_format_lite', - ]) - ) - ->add( - (new DataColumn('date_format_full')) - ->setName($this->trans('Date format (full)', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'date_format_full', - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_lang', - 'route' => 'admin_languages_toggle_status', - 'route_param_name' => 'languageId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_languages_edit', - 'route_param_name' => 'languageId', - 'route_param_field' => 'id_lang', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_languages_delete', - 'route_param_name' => 'languageId', - 'route_param_field' => 'id_lang', - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_lang', NumberType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_lang') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add( - (new Filter('iso_code', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search ISO code', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('iso_code') - ) - ->add( - (new Filter('language_code', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search code', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('language_code') - ) - ->add( - (new Filter('date_format_lite', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('date_format_lite') - ) - ->add( - (new Filter('date_format_full', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->translator->trans('Search date format', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('date_format_full') - ) - ->add( - (new Filter('active', ChoiceType::class)) - ->setTypeOptions([ - 'choices' => [ - $this->trans('Yes', [], 'Admin.Global') => 1, - $this->trans('No', [], 'Admin.Global') => 0, - ], - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_languages_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_languages_bulk_toggle_status', - 'route_params' => [ - 'status' => 'enable', - ], - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_languages_bulk_toggle_status', - 'route_params' => [ - 'status' => 'disable', - ], - ]) - ) - ->add( - $this->buildBulkDeleteAction('admin_languages_bulk_delete') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/LogGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/LogGridDefinitionFactory.php deleted file mode 100644 index 9a3b25e5..00000000 --- a/src/Core/Grid/Definition/Factory/LogGridDefinitionFactory.php +++ /dev/null @@ -1,268 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SubmitGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Employee\EmployeeNameWithAvatarColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Status\SeverityLevelColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class LogGridDefinitionFactory is responsible for creating new instance of Log grid definition. - */ -final class LogGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string the URL to reset Grid filters - */ - private $resetActionUrl; - - /** - * @var string the URL for redirection - */ - private $redirectionUrl; - - /** - * LogGridDefinitionFactory constructor. - * - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetActionUrl - * @param string $redirectionUrl - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetActionUrl, - $redirectionUrl - ) { - parent::__construct($hookDispatcher); - $this->resetActionUrl = $resetActionUrl; - $this->redirectionUrl = $redirectionUrl; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'logs'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Logs', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new DataColumn('id_log')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_log', - ]) - ) - ->add( - (new EmployeeNameWithAvatarColumn('employee')) - ->setName($this->trans('Employee', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'employee', - ]) - ) - ->add( - (new SeverityLevelColumn('severity')) - ->setName($this->trans('Severity (1-4)', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'with_message' => true, - 'field' => 'severity', - ]) - ) - ->add( - (new DataColumn('message')) - ->setName($this->trans('Message', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'message', - ]) - ) - ->add( - (new DataColumn('object_type')) - ->setName($this->trans('Object type', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'object_type', - ]) - ) - ->add( - (new DataColumn('object_id')) - ->setName($this->trans('Object ID', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'object_id', - ]) - ) - ->add( - (new DataColumn('error_code')) - ->setName($this->trans('Error code', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'error_code', - ]) - ) - ->add( - (new DateTimeColumn('date_add')) - ->setName($this->trans('Date', [], 'Admin.Global')) - ->setOptions([ - 'format' => 'Y-m-d H:i', - 'field' => 'date_add', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ); - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_log', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('id_log') - ) - ->add( - (new Filter('employee', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('employee') - ) - ->add( - (new Filter('severity', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('severity') - ) - ->add( - (new Filter('message', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('message') - ) - ->add( - (new Filter('object_type', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('object_type') - ) - ->add( - (new Filter('object_id', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('object_id') - ) - ->add( - (new Filter('error_code', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('error_code') - ) - ->add( - (new Filter('date_add', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('date_add') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetActionUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SubmitGridAction('delete_all_email_logs')) - ->setName($this->trans('Erase all', [], 'Admin.Advparameters.Feature')) - ->setIcon('delete') - ->setOptions([ - 'submit_route' => 'admin_logs_delete_all', - 'confirm_message' => $this->trans('Are you sure?', [], 'Admin.Notifications.Warning'), - ]) - ) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/ManufacturerAddressGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/ManufacturerAddressGridDefinitionFactory.php deleted file mode 100644 index e0a2bbf8..00000000 --- a/src/Core/Grid/Definition/Factory/ManufacturerAddressGridDefinitionFactory.php +++ /dev/null @@ -1,286 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\CountryChoiceType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class ManufacturerAddressGridDefinitionFactory is responsible for creating Manufacturers address grid definition. - */ -final class ManufacturerAddressGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - const GRID_ID = 'manufacturer_address'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Addresses', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_address', - ]) - ) - ->add((new DataColumn('id_address')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_address', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Brand', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new DataColumn('firstname')) - ->setName($this->trans('First name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'firstname', - ]) - ) - ->add((new DataColumn('lastname')) - ->setName($this->trans('Last name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'lastname', - ]) - ) - ->add((new DataColumn('postcode')) - ->setName($this->trans('Zip/Postal code', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'postcode', - ]) - ) - ->add((new DataColumn('city')) - ->setName($this->trans('City', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'city', - ]) - ) - ->add((new DataColumn('country')) - ->setName($this->trans('Country', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'country', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_manufacturer_addresses_edit', - 'route_param_name' => 'addressId', - 'route_param_field' => 'id_address', - 'clickable_row' => true, - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_manufacturer_addresses_delete', - 'route_param_name' => 'addressId', - 'route_param_field' => 'id_address', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_address', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_address') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('firstname', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search first name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('firstname') - ) - ->add((new Filter('lastname', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search last name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('lastname') - ) - ->add((new Filter('postcode', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search post code', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('postcode') - ) - ->add((new Filter('city', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search city', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('city') - ) - ->add((new Filter('country', CountryChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('country') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_manufacturers_index', - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - $this->buildBulkDeleteAction('admin_manufacturer_addresses_bulk_delete') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'manufacturers', - ], - ]) - ) - ->add((new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_manufacturer_addresses_export', - ]) - ) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/ManufacturerGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/ManufacturerGridDefinitionFactory.php deleted file mode 100644 index e1aaf656..00000000 --- a/src/Core/Grid/Definition/Factory/ManufacturerGridDefinitionFactory.php +++ /dev/null @@ -1,263 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ImageColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class ManufacturerGridDefinitionFactory is responsible for creating Manufacturers grid definition. - */ -final class ManufacturerGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - const GRID_ID = 'manufacturer'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Brands', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_manufacturer', - ]) - ) - ->add((new DataColumn('id_manufacturer')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_manufacturer', - ]) - ) - ->add((new ImageColumn('logo')) - ->setName($this->trans('Logo', [], 'Admin.Global')) - ->setOptions([ - 'src_field' => 'logo', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new DataColumn('addresses_count')) - ->setName($this->trans('Addresses', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'addresses_count', - ]) - ) - ->add((new DataColumn('products_count')) - ->setName($this->trans('Products', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'products_count', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_manufacturer', - 'route' => 'admin_manufacturers_toggle_status', - 'route_param_name' => 'manufacturerId', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_manufacturers_view', - 'route_param_name' => 'manufacturerId', - 'route_param_field' => 'id_manufacturer', - 'clickable_row' => true, - ]) - ) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_manufacturers_edit', - 'route_param_name' => 'manufacturerId', - 'route_param_field' => 'id_manufacturer', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_manufacturers_delete', - 'route_param_name' => 'manufacturerId', - 'route_param_field' => 'id_manufacturer', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'manufacturers', - ], - ]) - ) - ->add((new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_manufacturers_export', - ]) - ) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_manufacturer', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_manufacturer') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_manufacturers_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_manufacturers_bulk_enable_status', - ]) - ) - ->add((new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_manufacturers_bulk_disable_status', - ]) - )->add( - $this->buildBulkDeleteAction('admin_manufacturers_bulk_delete') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/MerchandiseReturnGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/MerchandiseReturnGridDefinitionFactory.php deleted file mode 100644 index b9083b9d..00000000 --- a/src/Core/Grid/Definition/Factory/MerchandiseReturnGridDefinitionFactory.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\ColorColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class MerchandiseReturnGridDefinitionFactory builds grid definition for merchandise returns grid. - */ -final class MerchandiseReturnGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - const GRID_ID = 'merchandise_return'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Merchandise Returns', [], 'Admin.Orderscustomers.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $columns = (new ColumnCollection()) - ->add( - (new DataColumn('id_order_return')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_order_return', - ]) - ) - ->add( - (new DataColumn('id_order')) - ->setName($this->trans('Order ID', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'id_order', - ]) - ) - ->add( - (new ColorColumn('status')) - ->setName($this->trans('Status', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'status', - 'color_field' => 'color', - ]) - ) - ->add( - (new DateTimeColumn('date_add')) - ->setName($this->trans('Date issued', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'date_add', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ) - ; - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_order_return', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_order_return') - ) - ->add((new Filter('id_order', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search order ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_order') - ) - ->add((new Filter('status', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('status') - ) - ->add((new Filter('date_add', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - 'date_format' => 'YYYY-MM-DD', - ]) - ->setAssociatedColumn('date_add') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_merchandise_returns_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/MetaGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/MetaGridDefinitionFactory.php deleted file mode 100644 index 7bd26e14..00000000 --- a/src/Core/Grid/Definition/Factory/MetaGridDefinitionFactory.php +++ /dev/null @@ -1,227 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class MetaGridDefinitionFactory is responsible for adding definition for Seo & urls list. - */ -final class MetaGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'meta'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('SEO & URLs', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_meta', - ]) - ) - ->add( - (new DataColumn('id_meta')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_meta', - ]) - ) - ->add( - (new DataColumn('page')) - ->setName($this->trans('Page', [], 'Admin.Shopparameters.Feature')) - ->setOptions([ - 'field' => 'page', - ]) - ) - ->add( - (new DataColumn('title')) - ->setName($this->trans('Page title', [], 'Admin.Shopparameters.Feature')) - ->setOptions([ - 'field' => 'title', - ]) - ) - ->add( - (new DataColumn('url_rewrite')) - ->setName($this->trans('Friendly URL', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'url_rewrite', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_metas_edit', - 'route_param_name' => 'metaId', - 'route_param_field' => 'id_meta', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_metas_delete', - 'route_param_name' => 'metaId', - 'route_param_field' => 'id_meta', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_meta', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('id_meta') - ) - ->add( - (new Filter('page', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('page') - ) - ->add( - (new Filter('title', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('title') - ) - ->add( - (new Filter('url_rewrite', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('url_rewrite') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search', - 'reset_route_params' => [ - 'controller' => 'meta', - 'action' => 'index', - ], - 'redirect_route' => 'admin_metas_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_seo_urls')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_metas_delete_bulk', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/AbstractProductGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/AbstractProductGridDefinitionFactory.php deleted file mode 100644 index 073618da..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/AbstractProductGridDefinitionFactory.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\IdentifierColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines reusable grids for product listing in monitoring page - */ -abstract class AbstractProductGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * {@inheritdoc} - */ - protected function getId() - { - return $this::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new IdentifierColumn('id_product')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'identifier_field' => 'id_product', - ]) - ) - ->add( - (new DataColumn('reference')) - ->setName($this->trans('Reference', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'reference', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Status', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_product', - 'route' => 'admin_product_toggle_status', - 'route_param_name' => 'productId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => $this->getRowActions(), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = (new FilterCollection()) - ->add( - (new Filter('id_product', TextType::class)) - ->setAssociatedColumn('id_product') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('reference', TextType::class)) - ->setAssociatedColumn('reference') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search reference', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('name', TextType::class)) - ->setAssociatedColumn('name') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => $this::GRID_ID, - ], - 'redirect_route' => 'admin_monitorings_index', - ]) - ->setAssociatedColumn('actions') - ); - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ); - } - - /** - * @return RowActionCollection - */ - protected function getRowActions() - { - return (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_product_form', - 'route_param_name' => 'id', - 'route_param_field' => 'id_product', - ]) - ) - ->add( - (new LinkRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_product_unit_action', - 'route_param_name' => 'id', - 'route_param_field' => 'id_product', - 'extra_route_params' => ['action' => 'delete'], - 'confirm_message' => $this->trans('Delete selected item?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/DisabledProductGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/DisabledProductGridDefinitionFactory.php deleted file mode 100644 index 9ae75b9f..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/DisabledProductGridDefinitionFactory.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\IdentifierColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Builds Grid definition for disabled product grid - */ -final class DisabledProductGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'disabled_product'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('List of disabled products', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new IdentifierColumn('id_product')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'identifier_field' => 'id_product', - ]) - ) - ->add( - (new DataColumn('reference')) - ->setName($this->trans('Reference', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'reference', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => $this->getRowActions(), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_product', TextType::class)) - ->setAssociatedColumn('id_product') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('reference', TextType::class)) - ->setAssociatedColumn('reference') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search reference', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('name', TextType::class)) - ->setAssociatedColumn('name') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => $this::GRID_ID, - ], - 'redirect_route' => 'admin_monitorings_index', - ]) - ->setAssociatedColumn('actions') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/EmptyCategoryGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/EmptyCategoryGridDefinitionFactory.php deleted file mode 100644 index 94a52233..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/EmptyCategoryGridDefinitionFactory.php +++ /dev/null @@ -1,218 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\Category\DeleteCategoryRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\IdentifierColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Builds Grid definition for empty categories listing - */ -final class EmptyCategoryGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - const GRID_ID = 'empty_category'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('List of empty categories', [], 'Admin.Catalog.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new IdentifierColumn('id_category')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'identifier_field' => 'id_category', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new DataColumn('description')) - ->setName($this->trans('Description', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'description', - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Displayed', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_category', - 'route' => 'admin_categories_toggle_status', - 'route_param_name' => 'categoryId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => $this->getRowActions(), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_category', TextType::class)) - ->setAssociatedColumn('id_category') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('name', TextType::class)) - ->setAssociatedColumn('name') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('description', TextType::class)) - ->setAssociatedColumn('description') - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search description', [], 'Admin.Actions'), - ], - ]) - ) - ->add( - (new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_monitorings_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ); - } - - /** - * @return RowActionCollection - */ - private function getRowActions() - { - return (new RowActionCollection()) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_categories_index', //@todo: implement view products of this category - 'route_param_name' => 'id_category', - 'route_param_field' => 'id_category', - ]) - ) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_categories_edit', - 'route_param_name' => 'categoryId', - 'route_param_field' => 'id_category', - ]) - ) - ->add( - (new DeleteCategoryRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'category_id_field' => 'id_category', - 'category_delete_route' => 'admin_categories_delete', - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithCombinationGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithCombinationGridDefinitionFactory.php deleted file mode 100644 index 90879a9e..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithCombinationGridDefinitionFactory.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -/** - * Builds Grid definition for product with combination and without quantities grid - */ -final class NoQtyProductWithCombinationGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'no_qty_product_with_combination'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans( - 'List of products with combinations but without available quantities for sale', - [], - 'Admin.Catalog.Feature' - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithoutCombinationGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithoutCombinationGridDefinitionFactory.php deleted file mode 100644 index a452f5fd..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/NoQtyProductWithoutCombinationGridDefinitionFactory.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -/** - * Builds Grid definition for product without combination and without quantities grid - */ -final class NoQtyProductWithoutCombinationGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'no_qty_product_without_combination'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans( - 'List of products without combinations and without available quantities for sale', - [], - 'Admin.Catalog.Feature' - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutDescriptionGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutDescriptionGridDefinitionFactory.php deleted file mode 100644 index 3a04624a..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutDescriptionGridDefinitionFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -/** - * Builds Grid definition for product without description grid - */ -final class ProductWithoutDescriptionGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'product_without_description'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('List of products without description', [], 'Admin.Catalog.Feature'); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutImageGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutImageGridDefinitionFactory.php deleted file mode 100644 index 1c4cb00a..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutImageGridDefinitionFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -/** - * Builds Grid definition for product without image grid - */ -final class ProductWithoutImageGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'product_without_image'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('List of products without images', [], 'Admin.Catalog.Feature'); - } -} diff --git a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutPriceGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutPriceGridDefinitionFactory.php deleted file mode 100644 index 290c3029..00000000 --- a/src/Core/Grid/Definition/Factory/Monitoring/ProductWithoutPriceGridDefinitionFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring; - -/** - * Builds Grid definition for product without price grid - */ -final class ProductWithoutPriceGridDefinitionFactory extends AbstractProductGridDefinitionFactory -{ - const GRID_ID = 'product_without_price'; - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('List of products without price', [], 'Admin.Catalog.Feature'); - } -} diff --git a/src/Core/Grid/Definition/Factory/OrderGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/OrderGridDefinitionFactory.php deleted file mode 100644 index f8082134..00000000 --- a/src/Core/Grid/Definition/Factory/OrderGridDefinitionFactory.php +++ /dev/null @@ -1,505 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\ButtonBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\ModalFormSubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\BooleanColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ChoiceColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\DateTimeColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\IdentifierColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DisableableLinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\OrderPriceColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\PreviewColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Creates definition for Orders grid - */ -final class OrderGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - const GRID_ID = 'order'; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var FormChoiceProviderInterface - */ - private $orderCountriesChoiceProvider; - - /** - * @var FormChoiceProviderInterface - */ - private $orderStatusesChoiceProvider; - - /** - * @var string - */ - private $contextDateFormat; - - /** - * @var FeatureInterface - */ - private $multistoreFeature; - /** - * @var FormChoiceProviderInterface - */ - private $orderStatesChoiceProvider; - - /** - * @var AccessibilityCheckerInterface - */ - private $printInvoiceAccessibilityChecker; - - /** - * @var AccessibilityCheckerInterface - */ - private $printDeliverySlipAccessibilityChecker; - - /** - * @param HookDispatcherInterface $dispatcher - * @param ConfigurationInterface $configuration - * @param FormChoiceProviderInterface $orderCountriesChoiceProvider - * @param FormChoiceProviderInterface $orderStatusesChoiceProvider - * @param string $contextDateFormat - * @param FeatureInterface $multistoreFeature - * @param AccessibilityCheckerInterface $printInvoiceAccessibilityChecker - * @param AccessibilityCheckerInterface $printDeliverySlipAccessibilityChecker - * @param FormChoiceProviderInterface $orderStatesChoiceProvider - */ - public function __construct( - HookDispatcherInterface $dispatcher, - ConfigurationInterface $configuration, - FormChoiceProviderInterface $orderCountriesChoiceProvider, - FormChoiceProviderInterface $orderStatusesChoiceProvider, - $contextDateFormat, - FeatureInterface $multistoreFeature, - AccessibilityCheckerInterface $printInvoiceAccessibilityChecker, - AccessibilityCheckerInterface $printDeliverySlipAccessibilityChecker, - FormChoiceProviderInterface $orderStatesChoiceProvider - ) { - parent::__construct($dispatcher); - - $this->configuration = $configuration; - $this->orderCountriesChoiceProvider = $orderCountriesChoiceProvider; - $this->orderStatusesChoiceProvider = $orderStatusesChoiceProvider; - $this->contextDateFormat = $contextDateFormat; - $this->multistoreFeature = $multistoreFeature; - $this->printInvoiceAccessibilityChecker = $printInvoiceAccessibilityChecker; - $this->printDeliverySlipAccessibilityChecker = $printDeliverySlipAccessibilityChecker; - $this->orderStatesChoiceProvider = $orderStatesChoiceProvider; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Orders', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - $previewColumn = (new PreviewColumn('preview')) - ->setOptions([ - 'icon_expand' => 'keyboard_arrow_down', - 'icon_collapse' => 'keyboard_arrow_up', - 'preview_data_route' => 'admin_orders_preview', - 'preview_route_params' => [ - 'orderId' => 'id_order', - ], - ]) - ; - - $columns = (new ColumnCollection()) - ->add( - (new BulkActionColumn('orders_bulk')) - ->setOptions([ - 'bulk_field' => 'id_order', - ]) - ) - ->add((new IdentifierColumn('id_order')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'identifier_field' => 'id_order', - 'preview' => $previewColumn, - 'clickable' => false, - ]) - ) - ->add((new DataColumn('reference')) - ->setName($this->trans('Reference', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'reference', - ]) - ) - ->add((new BooleanColumn('new')) - ->setName($this->trans('New client', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'field' => 'new', - 'true_name' => $this->trans('Yes', [], 'Admin.Global'), - 'false_name' => $this->trans('No', [], 'Admin.Global'), - 'clickable' => true, - ]) - ) - ->add((new DisableableLinkColumn('customer')) - ->setName($this->trans('Customer', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'customer', - 'disabled_field' => 'deleted_customer', - 'route' => 'admin_customers_view', - 'route_param_name' => 'customerId', - 'route_param_field' => 'id_customer', - 'target' => '_blank', - ]) - ) - ->add((new OrderPriceColumn('total_paid_tax_incl')) - ->setName($this->trans('Total', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'total_paid_tax_incl', - 'is_paid_field' => 'paid', - 'clickable' => true, - ]) - ) - ->add((new DataColumn('payment')) - ->setName($this->trans('Payment', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'payment', - ]) - ) - ->add((new ChoiceColumn('osname')) - ->setName($this->trans('Status', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'current_state', - 'route' => 'admin_orders_list_update_status', - 'color_field' => 'color', - 'choice_provider' => $this->orderStatesChoiceProvider, - 'record_route_params' => [ - 'id_order' => 'orderId', - ], - ]) - ) - ->add((new DateTimeColumn('date_add')) - ->setName($this->trans('Date', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'date_add', - 'format' => $this->contextDateFormat, - 'clickable' => true, - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => $this->getRowActions(), - ]) - ) - ; - - if ($this->orderCountriesChoiceProvider->getChoices()) { - $columns->addAfter('new', (new DataColumn('country_name')) - ->setName($this->trans('Delivery', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'country_name', - ]) - ); - } - - if ($this->configuration->get('PS_B2B_ENABLE')) { - $columns->addAfter('customer', (new DataColumn('company')) - ->setName($this->trans('Company', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'company', - ]) - ); - } - - if ($this->multistoreFeature->isUsed()) { - $columns->addBefore('actions', (new DataColumn('shop_name')) - ->setName($this->trans('Shop', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'shop_name', - 'sortable' => false, - ]) - ); - } - - return $columns; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - $filters = new FilterCollection(); - - $filters - ->add((new Filter('id_order', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_order') - ) - ->add((new Filter('reference', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search reference', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('reference') - ) - ->add((new Filter('new', YesAndNoChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('new') - ) - ->add((new Filter('customer', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search customer', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('customer') - ) - ->add((new Filter('total_paid_tax_incl', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search total', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('total_paid_tax_incl') - ) - ->add((new Filter('payment', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search payment', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('payment') - ) - ->add((new Filter('osname', ChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choices' => $this->orderStatusesChoiceProvider->getChoices(), - 'translation_domain' => false, - ]) - ->setAssociatedColumn('osname') - ) - ->add((new Filter('date_add', DateRangeType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('date_add') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_orders_index', - ]) - ->setAssociatedColumn('actions') - ) - ; - - $orderCountriesChoices = $this->orderCountriesChoiceProvider->getChoices(); - - if (!empty($orderCountriesChoices)) { - $filters->add((new Filter('country_name', ChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choices' => $orderCountriesChoices, - ]) - ->setAssociatedColumn('country_name') - ); - } - - if ($this->configuration->get('PS_B2B_ENABLE')) { - $filters->add((new Filter('company', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search company', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('company') - ); - } - - return $filters; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_orders_export', - ]) - ) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new ModalFormSubmitBulkAction('change_order_status')) - ->setName($this->trans('Change Order Status', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'submit_route' => 'admin_orders_change_orders_status', - 'modal_id' => 'changeOrdersStatusModal', - ]) - ) - ->add((new ButtonBulkAction('open_tabs')) - ->setName($this->trans('Open in new tabs', [], 'Admin.Orderscustomers.Feature')) - ->setOptions([ - 'class' => 'open_tabs', - 'attributes' => [ - 'data-route' => 'admin_orders_view', - 'data-route-param-name' => 'orderId', - 'data-tabs-blocked-message' => $this->trans( - 'It looks like you have exceeded the number of tabs allowed. Check your browser settings to open multiple tabs.', - [], - 'Admin.Orderscustomers.Feature' - ), - ], - ]) - ) - ; - } - - /** - * @return RowActionCollection - */ - private function getRowActions(): RowActionCollection - { - return (new RowActionCollection()) - ->add( - (new LinkRowAction('print_invoice')) - ->setName($this->trans('View invoice', [], 'Admin.Orderscustomers.Feature')) - ->setIcon('receipt') - ->setOptions([ - 'accessibility_checker' => $this->printInvoiceAccessibilityChecker, - 'route' => 'admin_orders_generate_invoice_pdf', - 'route_param_name' => 'orderId', - 'route_param_field' => 'id_order', - 'use_inline_display' => true, - ]) - ) - ->add( - (new LinkRowAction('print_delivery_slip')) - ->setName($this->trans('View delivery slip', [], 'Admin.Orderscustomers.Feature')) - ->setIcon('local_shipping') - ->setOptions([ - 'accessibility_checker' => $this->printDeliverySlipAccessibilityChecker, - 'route' => 'admin_orders_generate_delivery_slip_pdf', - 'route_param_name' => 'orderId', - 'route_param_field' => 'id_order', - 'use_inline_display' => true, - ]) - ) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_orders_view', - 'route_param_name' => 'orderId', - 'route_param_field' => 'id_order', - 'use_inline_display' => true, - 'clickable_row' => true, - ]) - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/OrderMessageGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/OrderMessageGridDefinitionFactory.php deleted file mode 100644 index f414d240..00000000 --- a/src/Core/Grid/Definition/Factory/OrderMessageGridDefinitionFactory.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Creates definition for order message grid - */ -final class OrderMessageGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - public const GRID_ID = 'order_message'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Order messages', [], 'Admin.Orderscustomers.Feature'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('order_messages_bulk')) - ->setOptions([ - 'bulk_field' => 'id_order_message', - ]) - ) - ->add((new DataColumn('id_order_message')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_order_message', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new DataColumn('message')) - ->setName($this->trans('Message', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'message', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_order_messages_edit', - 'route_param_name' => 'orderMessageId', - 'route_param_field' => 'id_order_message', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_order_messages_delete', - 'route_param_name' => 'orderMessageId', - 'route_param_field' => 'id_order_message', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_order_message', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('id_order_message') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('message', TextType::class)) - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Search message', [], 'Admin.Actions'), - ], - 'required' => false, - ]) - ->setAssociatedColumn('message') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_order_messages_index', - ]) - ->setAssociatedColumn('actions')) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - $this->buildBulkDeleteAction('admin_order_messages_bulk_delete') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/ProfileGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/ProfileGridDefinitionFactory.php deleted file mode 100644 index 961b8e46..00000000 --- a/src/Core/Grid/Definition/Factory/ProfileGridDefinitionFactory.php +++ /dev/null @@ -1,230 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\AccessibilityCheckerInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class ProfilesGridDefinitionFactory responsible for creating Profiles grid definition. - */ -final class ProfileGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string - */ - private $resetActionUrl; - - /** - * @var string - */ - private $redirectionUrl; - - /** - * @var AccessibilityCheckerInterface - */ - private $deleteProfileAccessibilityChecker; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetActionUrl - * @param string $redirectionUrl - * @param AccessibilityCheckerInterface $deleteProfileAccessibilityChecker - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetActionUrl, - $redirectionUrl, - AccessibilityCheckerInterface $deleteProfileAccessibilityChecker - ) { - parent::__construct($hookDispatcher); - $this->resetActionUrl = $resetActionUrl; - $this->redirectionUrl = $redirectionUrl; - $this->deleteProfileAccessibilityChecker = $deleteProfileAccessibilityChecker; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'profile'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Profiles', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_profile', - ]) - ) - ->add((new DataColumn('id_profile')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_profile', - ]) - ) - ->add((new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('edit')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_profiles_edit', - 'route_param_name' => 'profileId', - 'route_param_field' => 'id_profile', - 'clickable_row' => true, - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'route' => 'admin_profiles_delete', - 'route_param_name' => 'profileId', - 'route_param_field' => 'id_profile', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'accessibility_checker' => $this->deleteProfileAccessibilityChecker, - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_profile', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'size' => 'small', - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_profile') - ) - ->add((new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetActionUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('bulk_delete_profiles')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_profiles_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/RequestSqlGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/RequestSqlGridDefinitionFactory.php deleted file mode 100644 index 0ed6da50..00000000 --- a/src/Core/Grid/Definition/Factory/RequestSqlGridDefinitionFactory.php +++ /dev/null @@ -1,252 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class RequestSqlGridDefinitionFactory is responsible for creating RequestSql grid definition. - */ -final class RequestSqlGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var string - */ - private $resetSearchUrl; - - /** - * @var string - */ - private $redirectionUrl; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param string $resetSearchUrl - * @param string $redirectionUrl - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - $resetSearchUrl, - $redirectionUrl - ) { - parent::__construct($hookDispatcher); - $this->resetSearchUrl = $resetSearchUrl; - $this->redirectionUrl = $redirectionUrl; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'sql_request'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('SQL Manager', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_request_sql', - ]) - ) - ->add( - (new DataColumn('id_request_sql')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_request_sql', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('SQL query Name', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new DataColumn('sql')) - ->setName($this->trans('SQL query', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'sql', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('export')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_sql_requests_export', - 'route_param_name' => 'sqlRequestId', - 'route_param_field' => 'id_request_sql', - ]) - ) - ->add( - (new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Global')) - ->setIcon('remove_red_eye') - ->setOptions([ - 'route' => 'admin_sql_requests_view', - 'route_param_name' => 'sqlRequestId', - 'route_param_field' => 'id_request_sql', - 'clickable_row' => true, - ]) - ) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Global')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_sql_requests_edit', - 'route_param_name' => 'sqlRequestId', - 'route_param_field' => 'id_request_sql', - ]) - ) - ->add( - (new LinkRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans('Delete selected item?', [], 'Admin.Notifications.Warning'), - 'route' => 'admin_sql_requests_delete', - 'route_param_name' => 'sqlRequestId', - 'route_param_field' => 'id_request_sql', - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_request_sql', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('id_request_sql') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('name') - ) - ->add( - (new Filter('sql', TextType::class)) - ->setTypeOptions([ - 'required' => false, - ]) - ->setAssociatedColumn('sql') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetSearchUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('delete_all')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_sql_requests_delete_bulk', - 'submit_method' => 'POST', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/SupplierGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/SupplierGridDefinitionFactory.php deleted file mode 100644 index 2f4f51e5..00000000 --- a/src/Core/Grid/Definition/Factory/SupplierGridDefinitionFactory.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\LinkGridAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ImageColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\LinkColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class SupplierGridDefinitionFactory creates definition for supplier grid. - */ -final class SupplierGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - /** - * @var string - */ - public const GRID_ID = 'supplier'; - - use BulkDeleteActionTrait; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Suppliers', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add((new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_supplier', - ]) - ) - ->add((new DataColumn('id_supplier')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_supplier', - ]) - ) - ->add((new ImageColumn('logo')) - ->setName($this->trans('Logo', [], 'Admin.Global')) - ->setOptions([ - 'src_field' => 'logo', - ]) - ) - ->add((new LinkColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - 'route' => 'admin_suppliers_edit', - 'route_param_name' => 'supplierId', - 'route_param_field' => 'id_supplier', - ]) - ) - ->add((new DataColumn('products_count')) - ->setName($this->trans('Number of products', [], 'Admin.Catalog.Feature')) - ->setOptions([ - 'field' => 'products_count', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_supplier', - 'route' => 'admin_suppliers_toggle_status', - 'route_param_name' => 'supplierId', - ]) - ) - ->add((new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add((new LinkRowAction('view')) - ->setName($this->trans('View', [], 'Admin.Actions')) - ->setIcon('zoom_in') - ->setOptions([ - 'route' => 'admin_suppliers_view', - 'route_param_name' => 'supplierId', - 'route_param_field' => 'id_supplier', - 'clickable_row' => true, - ]) - ) - ->add((new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_suppliers_edit', - 'route_param_name' => 'supplierId', - 'route_param_field' => 'id_supplier', - ]) - ) - ->add((new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_suppliers_delete', - 'route_param_name' => 'supplierId', - 'route_param_field' => 'id_supplier', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add((new Filter('id_supplier', TextType::class)) - ->setAssociatedColumn('id_supplier') - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('ID', [], 'Admin.Global'), - ], - 'required' => false, - ]) - ) - ->add((new Filter('name', TextType::class)) - ->setAssociatedColumn('name') - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Name', [], 'Admin.Global'), - ], - 'required' => false, - ]) - ) - ->add((new Filter('products_count', TextType::class)) - ->setAssociatedColumn('products_count') - ->setTypeOptions([ - 'attr' => [ - 'placeholder' => $this->trans('Number of products', [], 'Admin.Catalog.Feature'), - ], - 'required' => false, - ]) - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setAssociatedColumn('active') - ->setTypeOptions([ - 'required' => false, - ]) - ) - ->add((new Filter('actions', SearchAndResetType::class)) - ->setAssociatedColumn('actions') - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search_by_filter_id', - 'reset_route_params' => [ - 'filterId' => self::GRID_ID, - ], - 'redirect_route' => 'admin_suppliers_index', - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add((new SubmitBulkAction('suppliers_enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_suppliers_bulk_enable', - ]) - ) - ->add((new SubmitBulkAction('suppliers_disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_suppliers_bulk_disable', - ]) - ) - ->add( - $this->buildBulkDeleteAction('admin_suppliers_bulk_delete') - ) - ; - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add((new LinkGridAction('import')) - ->setName($this->trans('Import', [], 'Admin.Actions')) - ->setIcon('cloud_upload') - ->setOptions([ - 'route' => 'admin_import', - 'route_params' => [ - 'import_type' => 'suppliers', - ], - ]) - ) - ->add((new LinkGridAction('export')) - ->setName($this->trans('Export', [], 'Admin.Actions')) - ->setIcon('cloud_download') - ->setOptions([ - 'route' => 'admin_suppliers_export', - ]) - ) - ->add((new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add((new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add((new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ) - ; - } -} diff --git a/src/Core/Grid/Definition/Factory/TaxGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/TaxGridDefinitionFactory.php deleted file mode 100644 index cbc8d955..00000000 --- a/src/Core/Grid/Definition/Factory/TaxGridDefinitionFactory.php +++ /dev/null @@ -1,252 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class TaxGridDefinitionFactory is responsible for creating Tax grid definition. - */ -final class TaxGridDefinitionFactory extends AbstractGridDefinitionFactory -{ - use BulkDeleteActionTrait; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'tax'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Taxes', [], 'Admin.Global'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_tax', - ]) - ) - ->add( - (new DataColumn('id_tax')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_tax', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add( - (new DataColumn('rate')) - ->setName($this->trans('Rate', [], 'Admin.International.Feature')) - ->setOptions([ - 'field' => 'rate', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_tax', - 'route' => 'admin_taxes_toggle_status', - 'route_param_name' => 'taxId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_taxes_edit', - 'route_param_name' => 'taxId', - 'route_param_field' => 'id_tax', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_taxes_delete', - 'route_param_name' => 'taxId', - 'route_param_field' => 'id_tax', - ]) - ), - ]) - ) - ; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_tax', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_tax') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add( - (new Filter('rate', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search rate', [], 'Admin.International.Feature'), - ], - ]) - ->setAssociatedColumn('rate') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search', - 'reset_route_params' => [ - 'controller' => 'tax', - 'action' => 'index', - ], - 'redirect_route' => 'admin_taxes_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_taxes_bulk_enable_status', - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_taxes_bulk_disable_status', - ]) - ) - ->add( - $this->buildBulkDeleteAction('admin_taxes_bulk_delete') - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/TaxRulesGroupGridDefinitionFactory.php b/src/Core/Grid/Definition/Factory/TaxRulesGroupGridDefinitionFactory.php deleted file mode 100644 index 6ecbbf6b..00000000 --- a/src/Core/Grid/Definition/Factory/TaxRulesGroupGridDefinitionFactory.php +++ /dev/null @@ -1,238 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Defines tax rules groups grid - */ -final class TaxRulesGroupGridDefinitionFactory extends AbstractFilterableGridDefinitionFactory -{ - public const GRID_ID = 'tax_rules_group'; - - /** - * {@inheritdoc} - */ - protected function getId() - { - return self::GRID_ID; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Tax Rules', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk')) - ->setOptions([ - 'bulk_field' => 'id_tax_rules_group', - ]) - ) - ->add( - (new DataColumn('id_tax_rules_group')) - ->setName($this->trans('ID', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'id_tax_rules_group', - ]) - ) - ->add( - (new DataColumn('name')) - ->setName($this->trans('Name', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'name', - ]) - ) - ->add((new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_tax_rules_group', - 'route' => 'admin_tax_rules_groups_toggle_status', - 'route_param_name' => 'taxRulesGroupId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setName($this->trans('Edit', [], 'Admin.Actions')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_tax_rules_groups_edit', - 'route_param_name' => 'taxRulesGroupId', - 'route_param_field' => 'id_tax_rules_group', - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - 'route' => 'admin_tax_rules_groups_delete', - 'route_param_name' => 'taxRulesGroupId', - 'route_param_field' => 'id_tax_rules_group', - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('id_tax_rules_group', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search ID', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('id_tax_rules_group') - ) - ->add( - (new Filter('name', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search name', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('name') - ) - ->add((new Filter('active', YesAndNoChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'reset_route' => 'admin_common_reset_search', - 'reset_route_params' => [ - 'controller' => 'taxRulesGroup', - 'action' => 'index', - ], - 'redirect_route' => 'admin_tax_rules_groups_index', - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_tax_rules_groups_bulk_enable_status', - ]) - ) - ->add( - (new SubmitBulkAction('disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_tax_rules_groups_bulk_disable_status', - ]) - ) - ->add( - (new SubmitBulkAction('delete_selection')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_tax_rules_groups_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/Factory/WebserviceKeyDefinitionFactory.php b/src/Core/Grid/Definition/Factory/WebserviceKeyDefinitionFactory.php deleted file mode 100644 index 011a0665..00000000 --- a/src/Core/Grid/Definition/Factory/WebserviceKeyDefinitionFactory.php +++ /dev/null @@ -1,275 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\Type\SubmitBulkAction; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\RowActionCollection; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\LinkRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Row\Type\SubmitRowAction; -use PrestaShop\PrestaShop\Core\Grid\Action\Type\SimpleGridAction; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollection; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\BulkActionColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\ToggleColumn; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn; -use PrestaShop\PrestaShop\Core\Grid\Filter\Filter; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollection; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Form\Admin\Type\SearchAndResetType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Class WebserviceKeyDefinitionFactory is responsible for creating grid definition for Webservice grid. - */ -final class WebserviceKeyDefinitionFactory extends AbstractGridDefinitionFactory -{ - /** - * @var array - */ - private $statusChoices; - - /** - * @var string - */ - private $resetActionUrl; - - /** - * @var string - */ - private $redirectionUrl; - - /** - * WebserviceKeyDefinitionFactory constructor. - * - * @param HookDispatcherInterface $hookDispatcher - * @param array $statusChoices - * @param $resetActionUrl - * @param $redirectionUrl - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - array $statusChoices, - $resetActionUrl, - $redirectionUrl - ) { - parent::__construct($hookDispatcher); - $this->statusChoices = $statusChoices; - $this->resetActionUrl = $resetActionUrl; - $this->redirectionUrl = $redirectionUrl; - } - - /** - * {@inheritdoc} - */ - protected function getId() - { - return 'webservice_key'; - } - - /** - * {@inheritdoc} - */ - protected function getName() - { - return $this->trans('Webservice', [], 'Admin.Navigation.Menu'); - } - - /** - * {@inheritdoc} - */ - protected function getColumns() - { - return (new ColumnCollection()) - ->add( - (new BulkActionColumn('bulk_action')) - ->setOptions([ - 'bulk_field' => 'id_webservice_account', - ]) - ) - ->add( - (new DataColumn('key')) - ->setName($this->trans('Key', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'key', - ]) - ) - ->add( - (new DataColumn('description')) - ->setName($this->trans('Key description', [], 'Admin.Advparameters.Feature')) - ->setOptions([ - 'field' => 'description', - 'sortable' => false, - ]) - ) - ->add( - (new ToggleColumn('active')) - ->setName($this->trans('Enabled', [], 'Admin.Global')) - ->setOptions([ - 'field' => 'active', - 'primary_field' => 'id_webservice_account', - 'route' => 'admin_webservice_keys_toggle_status', - 'route_param_name' => 'webserviceKeyId', - ]) - ) - ->add( - (new ActionColumn('actions')) - ->setName($this->trans('Actions', [], 'Admin.Global')) - ->setOptions([ - 'actions' => (new RowActionCollection()) - ->add( - (new LinkRowAction('edit')) - ->setIcon('edit') - ->setOptions([ - 'route' => 'admin_webservice_keys_edit', - 'route_param_name' => 'webserviceKeyId', - 'route_param_field' => 'id_webservice_account', - 'clickable_row' => true, - ]) - ) - ->add( - (new SubmitRowAction('delete')) - ->setName($this->trans('Delete', [], 'Admin.Actions')) - ->setIcon('delete') - ->setOptions([ - 'method' => 'DELETE', - 'route' => 'admin_webservice_keys_delete', - 'route_param_name' => 'webserviceKeyId', - 'route_param_field' => 'id_webservice_account', - 'confirm_message' => $this->trans( - 'Delete selected item?', - [], - 'Admin.Notifications.Warning' - ), - ]) - ), - ]) - ); - } - - /** - * {@inheritdoc} - */ - protected function getFilters() - { - return (new FilterCollection()) - ->add( - (new Filter('key', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search key', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('key') - ) - ->add( - (new Filter('description', TextType::class)) - ->setTypeOptions([ - 'required' => false, - 'attr' => [ - 'placeholder' => $this->trans('Search description', [], 'Admin.Actions'), - ], - ]) - ->setAssociatedColumn('description') - ) - ->add( - (new Filter('active', ChoiceType::class)) - ->setTypeOptions([ - 'required' => false, - 'choices' => $this->statusChoices, - 'choice_translation_domain' => false, - ]) - ->setAssociatedColumn('active') - ) - ->add( - (new Filter('actions', SearchAndResetType::class)) - ->setTypeOptions([ - 'attr' => [ - 'data-url' => $this->resetActionUrl, - 'data-redirect' => $this->redirectionUrl, - ], - ]) - ->setAssociatedColumn('actions') - ); - } - - /** - * {@inheritdoc} - */ - protected function getGridActions() - { - return (new GridActionCollection()) - ->add( - (new SimpleGridAction('common_refresh_list')) - ->setName($this->trans('Refresh list', [], 'Admin.Advparameters.Feature')) - ->setIcon('refresh') - ) - ->add( - (new SimpleGridAction('common_show_query')) - ->setName($this->trans('Show SQL query', [], 'Admin.Actions')) - ->setIcon('code') - ) - ->add( - (new SimpleGridAction('common_export_sql_manager')) - ->setName($this->trans('Export to SQL Manager', [], 'Admin.Actions')) - ->setIcon('storage') - ); - } - - /** - * {@inheritdoc} - */ - protected function getBulkActions() - { - return (new BulkActionCollection()) - ->add( - (new SubmitBulkAction('webservice_enable_selection')) - ->setName($this->trans('Enable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_webservice_keys_bulk_enable', - ]) - ) - ->add( - (new SubmitBulkAction('webservice_disable_selection')) - ->setName($this->trans('Disable selection', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_webservice_keys_bulk_disable', - ]) - ) - ->add( - (new SubmitBulkAction('delete_webservice')) - ->setName($this->trans('Delete selected', [], 'Admin.Actions')) - ->setOptions([ - 'submit_route' => 'admin_webservice_keys_bulk_delete', - 'confirm_message' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Warning'), - ]) - ); - } -} diff --git a/src/Core/Grid/Definition/GridDefinition.php b/src/Core/Grid/Definition/GridDefinition.php deleted file mode 100644 index a5fe7fb7..00000000 --- a/src/Core/Grid/Definition/GridDefinition.php +++ /dev/null @@ -1,186 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnInterface; -use PrestaShop\PrestaShop\Core\Grid\Exception\InvalidDataException; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollectionInterface; - -/** - * Class Definition is responsible for storing grid definition (columns, row actions & etc.). - */ -final class GridDefinition implements GridDefinitionInterface -{ - /** - * @var string Unique grid identifier - */ - private $id; - - /** - * @var string Grid name - */ - private $name; - - /** - * @var ColumnInterface[] - */ - private $columns; - - /** - * @var GridActionCollectionInterface - */ - private $gridActions; - - /** - * @var BulkActionCollectionInterface - */ - private $bulkActions; - - /** - * @var FilterCollectionInterface - */ - private $filters; - - /** - * @param string $id Unique grid identifier - * @param string $name - * @param ColumnCollectionInterface $columns - * @param FilterCollectionInterface $filters - * @param GridActionCollectionInterface $gridActions - * @param BulkActionCollectionInterface $bulkActions - */ - public function __construct( - $id, - $name, - ColumnCollectionInterface $columns, - FilterCollectionInterface $filters, - GridActionCollectionInterface $gridActions, - BulkActionCollectionInterface $bulkActions - ) { - $this->id = $id; - $this->name = $name; - $this->columns = $columns; - $this->filters = $filters; - $this->gridActions = $gridActions; - $this->bulkActions = $bulkActions; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getColumns() - { - return $this->columns; - } - - /** - * {@inheritdoc} - */ - public function getBulkActions() - { - return $this->bulkActions; - } - - /** - * {@inheritdoc} - */ - public function getGridActions() - { - return $this->gridActions; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return $this->filters; - } - - /** - * @param string $name - */ - public function setName($name) - { - if (!is_string($name)) { - throw new InvalidDataException('Definition name should be a string.'); - } - - $this->name = $name; - } - - /** - * @param ColumnCollectionInterface $columns - */ - public function setColumns($columns) - { - $this->columns = $columns; - } - - /** - * @param GridActionCollectionInterface $gridActions - */ - public function setGridActions(GridActionCollectionInterface $gridActions) - { - $this->gridActions = $gridActions; - } - - /** - * @param BulkActionCollectionInterface $bulkActions - */ - public function setBulkActions(BulkActionCollectionInterface $bulkActions) - { - $this->bulkActions = $bulkActions; - } - - /** - * @param FilterCollectionInterface $filters - */ - public function setFilters(FilterCollectionInterface $filters) - { - $this->filters = $filters; - } -} diff --git a/src/Core/Grid/Definition/GridDefinitionInterface.php b/src/Core/Grid/Definition/GridDefinitionInterface.php deleted file mode 100644 index 0493f106..00000000 --- a/src/Core/Grid/Definition/GridDefinitionInterface.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Definition; - -use PrestaShop\PrestaShop\Core\Grid\Action\Bulk\BulkActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Action\GridActionCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnCollectionInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterCollectionInterface; - -/** - * Interface GridDefinitionInterface defines contract for grid definition. - */ -interface GridDefinitionInterface -{ - /** - * Get unique grid identifier. - * - * @return string - */ - public function getId(); - - /** - * Get grid name. - * - * @return string - */ - public function getName(); - - /** - * Get grid columns. - * - * @return ColumnCollectionInterface - */ - public function getColumns(); - - /** - * @return BulkActionCollectionInterface - */ - public function getBulkActions(); - - /** - * Get grid actions. - * - * @return GridActionCollectionInterface - */ - public function getGridActions(); - - /** - * Get filters. - * - * @return FilterCollectionInterface - */ - public function getFilters(); -} diff --git a/src/Core/Grid/Exception/ColumnNotFoundException.php b/src/Core/Grid/Exception/ColumnNotFoundException.php deleted file mode 100644 index ba607885..00000000 --- a/src/Core/Grid/Exception/ColumnNotFoundException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use Exception; - -class ColumnNotFoundException extends Exception implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/ExceptionInterface.php b/src/Core/Grid/Exception/ExceptionInterface.php deleted file mode 100644 index 965cda08..00000000 --- a/src/Core/Grid/Exception/ExceptionInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -/** - * Interface ExceptionInterface is implemented by all grid exceptions. - */ -interface ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/InvalidActionDataException.php b/src/Core/Grid/Exception/InvalidActionDataException.php deleted file mode 100644 index 3ef05777..00000000 --- a/src/Core/Grid/Exception/InvalidActionDataException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use Exception; - -class InvalidActionDataException extends Exception implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/InvalidColumnDataException.php b/src/Core/Grid/Exception/InvalidColumnDataException.php deleted file mode 100644 index f4b21648..00000000 --- a/src/Core/Grid/Exception/InvalidColumnDataException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use Exception; - -class InvalidColumnDataException extends Exception implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/InvalidDataException.php b/src/Core/Grid/Exception/InvalidDataException.php deleted file mode 100644 index 0c533893..00000000 --- a/src/Core/Grid/Exception/InvalidDataException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use Exception; - -class InvalidDataException extends Exception implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/MissingColumnInRowException.php b/src/Core/Grid/Exception/MissingColumnInRowException.php deleted file mode 100644 index 4b435b92..00000000 --- a/src/Core/Grid/Exception/MissingColumnInRowException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use LogicException; - -/** - * Class MissingColumnInRowException. - */ -class MissingColumnInRowException extends LogicException implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Exception/UnsupportedParameterException.php b/src/Core/Grid/Exception/UnsupportedParameterException.php deleted file mode 100644 index 1c84c85e..00000000 --- a/src/Core/Grid/Exception/UnsupportedParameterException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Exception; - -use Exception; - -class UnsupportedParameterException extends Exception implements ExceptionInterface -{ -} diff --git a/src/Core/Grid/Factory/CategoryGridFactoryDecorator.php b/src/Core/Grid/Factory/CategoryGridFactoryDecorator.php deleted file mode 100644 index fdf6c3f8..00000000 --- a/src/Core/Grid/Factory/CategoryGridFactoryDecorator.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\GridFilterFormFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Grid; -use PrestaShop\PrestaShop\Core\Grid\GridFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\GridInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Form\FormInterface; - -/** - * Decorates Category grid factory - */ -final class CategoryGridFactoryDecorator implements GridFactoryInterface -{ - /** - * @var GridFactoryInterface - */ - private $categoryGridFactory; - - /** - * @var GridFilterFormFactoryInterface - */ - private $filterFormFactory; - - /** - * @param GridFactoryInterface $categoryGridFactory - * @param GridFilterFormFactoryInterface $filterFormFactory optional - * - * $filterFormFactory is optional in order to comply with SemVer - */ - public function __construct( - GridFactoryInterface $categoryGridFactory, - GridFilterFormFactoryInterface $filterFormFactory = null - ) { - $this->categoryGridFactory = $categoryGridFactory; - $this->filterFormFactory = $filterFormFactory; - } - - /** - * {@inheritdoc} - */ - public function getGrid(SearchCriteriaInterface $searchCriteria) - { - $categoryGrid = $this->categoryGridFactory->getGrid($searchCriteria); - - $this->removePositionDragColumnIfEligible($searchCriteria, $categoryGrid); - - $filters = $searchCriteria->getFilters(); - if ($this->isHomeCategory($filters) && ($this->filterFormFactory !== null)) { - return $categoryGrid; - } - - $this->injectCategoryIdIntoSearchTypeOptions($categoryGrid, $filters); - - $filterForm = $this->rebuildFilterForm($searchCriteria, $categoryGrid); - - return new Grid( - $categoryGrid->getDefinition(), - $categoryGrid->getData(), - $searchCriteria, - $filterForm - ); - } - - /** - * @param array $filters - * - * @return bool - */ - private function isHomeCategory(array $filters) - { - return isset($filters['is_home_category']) - && $filters['is_home_category'] === true; - } - - /** - * Position can only be changed when grid is - * ordered by "position" in "asc" way. - * - * @param SearchCriteriaInterface $searchCriteria - * @param GridInterface $categoryGrid - */ - private function removePositionDragColumnIfEligible( - SearchCriteriaInterface $searchCriteria, - $categoryGrid - ) { - if ('position' !== $searchCriteria->getOrderBy() || - 'asc' !== $searchCriteria->getOrderWay()) { - $categoryGrid->getDefinition() - ->getColumns() - ->remove('position_drag'); - } - } - - /** - * @param GridInterface $categoryGrid - * @param array $filters - */ - private function injectCategoryIdIntoSearchTypeOptions($categoryGrid, array $filters) - { - /** @var FilterInterface $actionsFilter */ - $actionsFilter = $categoryGrid->getDefinition() - ->getFilters()->get('actions'); - - $typeOptions = $actionsFilter->getTypeOptions(); - $typeOptions['redirect_route_params'] = ['categoryId' => $filters['id_category_parent']]; - $actionsFilter->setTypeOptions($typeOptions); - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * @param GridInterface $categoryGrid - * - * @return FormInterface - */ - private function rebuildFilterForm( - SearchCriteriaInterface $searchCriteria, - GridInterface $categoryGrid) - { - $filterForm = $this->filterFormFactory->create($categoryGrid->getDefinition()); - $filterForm->setData($searchCriteria->getFilters()); - - return $filterForm; - } -} diff --git a/src/Core/Grid/Filter/CategoryFilterFormFactory.php b/src/Core/Grid/Filter/CategoryFilterFormFactory.php deleted file mode 100644 index 5d540cbe..00000000 --- a/src/Core/Grid/Filter/CategoryFilterFormFactory.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * Class CategoryFilterFormFactory decorates original filter factory to add custom submit action. - */ -final class CategoryFilterFormFactory implements GridFilterFormFactoryInterface -{ - /** - * @var GridFilterFormFactoryInterface - */ - private $formFactory; - - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @param GridFilterFormFactoryInterface $formFactory - * @param UrlGeneratorInterface $urlGenerator - * @param RequestStack $requestStack - */ - public function __construct( - GridFilterFormFactoryInterface $formFactory, - UrlGeneratorInterface $urlGenerator, - RequestStack $requestStack - ) { - $this->formFactory = $formFactory; - $this->urlGenerator = $urlGenerator; - $this->requestStack = $requestStack; - } - - /** - * {@inheritdoc} - */ - public function create(GridDefinitionInterface $definition) - { - $categoryFilterForm = $this->formFactory->create($definition); - - $newCategoryFormBuilder = $categoryFilterForm->getConfig()->getFormFactory()->createNamedBuilder( - $definition->getId(), - FormType::class - ); - - /** @var FormInterface $categoryFormItem */ - foreach ($categoryFilterForm as $categoryFormItem) { - $newCategoryFormBuilder->add( - $categoryFormItem->getName(), - get_class($categoryFormItem->getConfig()->getType()->getInnerType()), - $categoryFormItem->getConfig()->getOptions() - ); - } - - $queryParams = []; - $request = $this->requestStack->getCurrentRequest(); - - if ((null !== $request) && ($request->attributes->has('categoryId'))) { - $queryParams['categoryId'] = $request->attributes->get('categoryId'); - } - - $newCategoryFormBuilder->setAction( - $this->urlGenerator->generate('admin_categories_search', $queryParams) - ); - - return $newCategoryFormBuilder->getForm(); - } -} diff --git a/src/Core/Grid/Filter/CmsPageFilterFormFactory.php b/src/Core/Grid/Filter/CmsPageFilterFormFactory.php deleted file mode 100644 index 4a5f98bd..00000000 --- a/src/Core/Grid/Filter/CmsPageFilterFormFactory.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * Class CmsPageCategoryFilterFormFactory is responsible for changing form action to the custom one. - */ -final class CmsPageFilterFormFactory implements GridFilterFormFactoryInterface -{ - /** - * @var GridFilterFormFactoryInterface - */ - private $formFactory; - - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @param GridFilterFormFactoryInterface $formFactory - * @param UrlGeneratorInterface $urlGenerator - * @param RequestStack $requestStack - */ - public function __construct( - GridFilterFormFactoryInterface $formFactory, - UrlGeneratorInterface $urlGenerator, - RequestStack $requestStack - ) { - $this->formFactory = $formFactory; - $this->urlGenerator = $urlGenerator; - $this->requestStack = $requestStack; - } - - /** - * {@inheritdoc} - */ - public function create(GridDefinitionInterface $definition) - { - $cmsPageCategoryFilterForm = $this->formFactory->create($definition); - - $newCmsPageCategoryFormBuilder = $cmsPageCategoryFilterForm->getConfig()->getFormFactory()->createNamedBuilder( - $definition->getId(), - FormType::class - ); - - /** @var FormInterface $categoryFormItem */ - foreach ($cmsPageCategoryFilterForm as $categoryFormItem) { - $newCmsPageCategoryFormBuilder->add( - $categoryFormItem->getName(), - get_class($categoryFormItem->getConfig()->getType()->getInnerType()), - $categoryFormItem->getConfig()->getOptions() - ); - } - - $request = $this->requestStack->getCurrentRequest(); - - if (null !== $request) { - $newActionUrl = $this->urlGenerator->generate('admin_cms_pages_search', [ - 'id_cms_category' => $request->query->getInt('id_cms_category'), - ]); - - $newCmsPageCategoryFormBuilder->setAction($newActionUrl); - } - - return $newCmsPageCategoryFormBuilder->getForm(); - } -} diff --git a/src/Core/Grid/Filter/Filter.php b/src/Core/Grid/Filter/Filter.php deleted file mode 100644 index ef408273..00000000 --- a/src/Core/Grid/Filter/Filter.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -/** - * Class Filter defines single filter for grid. - */ -final class Filter implements FilterInterface -{ - /** - * @var string Fully qualified filter type class name - */ - private $type; - - /** - * @var array Filter type options - */ - private $typeOptions = []; - - /** - * @var string Filter name - */ - private $name; - - /** - * @var string|null Column ID if filter is associated with columns - */ - private $column; - - /** - * @param string $name - * @param string $filterFormType - */ - public function __construct($name, $filterFormType) - { - $this->type = $filterFormType; - $this->name = $name; - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return $this->type; - } - - /** - * {@inheritdoc} - */ - public function setTypeOptions(array $filterTypeOptions) - { - $this->typeOptions = $filterTypeOptions; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getTypeOptions() - { - return $this->typeOptions; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function setAssociatedColumn($columnId) - { - $this->column = $columnId; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getAssociatedColumn() - { - return $this->column; - } -} diff --git a/src/Core/Grid/Filter/FilterCollection.php b/src/Core/Grid/Filter/FilterCollection.php deleted file mode 100644 index 4dab9657..00000000 --- a/src/Core/Grid/Filter/FilterCollection.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -/** - * Class FilterCollection manages filters collection for grid. - */ -final class FilterCollection implements FilterCollectionInterface -{ - /** - * @var FilterInterface[] - */ - private $filters = []; - - /** - * {@inheritdoc} - */ - public function add(FilterInterface $filter) - { - $this->filters[$filter->getName()] = $filter; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function remove($filterName) - { - if (isset($this->filters[$filterName])) { - unset($this->filters[$filterName]); - } - - return $this; - } - - /** - * @param string $filterName - * - * @return FilterInterface|null return null if no filter with given filter name - */ - public function get($filterName) - { - if (isset($this->filters[$filterName])) { - return $this->filters[$filterName]; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function all() - { - return $this->filters; - } -} diff --git a/src/Core/Grid/Filter/FilterCollectionInterface.php b/src/Core/Grid/Filter/FilterCollectionInterface.php deleted file mode 100644 index eef92f9e..00000000 --- a/src/Core/Grid/Filter/FilterCollectionInterface.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -/** - * Interface FilterCollectionInterface defines contract for grid filters. - */ -interface FilterCollectionInterface -{ - /** - * Add filter to collection. - * - * @param FilterInterface $filter - * - * @return self - */ - public function add(FilterInterface $filter); - - /** - * Remove filter from collection. - * - * @param string $filterName - * - * @return self - */ - public function remove($filterName); - - /** - * Get all filters. - * - * @return FilterInterface[] - */ - public function all(); -} diff --git a/src/Core/Grid/Filter/FilterFormFactoryFormActionDecorator.php b/src/Core/Grid/Filter/FilterFormFactoryFormActionDecorator.php deleted file mode 100644 index 1f3dd3ff..00000000 --- a/src/Core/Grid/Filter/FilterFormFactoryFormActionDecorator.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * Decorates grid filter form action. - */ -final class FilterFormFactoryFormActionDecorator implements GridFilterFormFactoryInterface -{ - /** - * @var GridFilterFormFactoryInterface - */ - private $delegate; - - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @var string - */ - private $formActionRoute; - - /** - * @param GridFilterFormFactoryInterface $delegate - * @param UrlGeneratorInterface $urlGenerator - * @param string $formActionRoute will change the form action of filters form to this - */ - public function __construct( - GridFilterFormFactoryInterface $delegate, - UrlGeneratorInterface $urlGenerator, - string $formActionRoute - ) { - $this->delegate = $delegate; - $this->urlGenerator = $urlGenerator; - $this->formActionRoute = $formActionRoute; - } - - /** - * {@inheritdoc} - */ - public function create(GridDefinitionInterface $definition) - { - $filterForm = $this->delegate->create($definition); - - $formBuilder = $filterForm->getConfig()->getFormFactory()->createNamedBuilder( - $definition->getId(), - FormType::class - ); - - /** @var FormInterface $formItem */ - foreach ($filterForm as $formItem) { - $formBuilder->add( - $formItem->getName(), - get_class($formItem->getConfig()->getType()->getInnerType()), - $formItem->getConfig()->getOptions() - ); - } - - $formBuilder->setAction( - $this->urlGenerator->generate($this->formActionRoute) - ); - - return $formBuilder->getForm(); - } -} diff --git a/src/Core/Grid/Filter/FilterInterface.php b/src/Core/Grid/Filter/FilterInterface.php deleted file mode 100644 index cd89fa61..00000000 --- a/src/Core/Grid/Filter/FilterInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -/** - * Interface FilterInterface defines contract for grid filter. - */ -interface FilterInterface -{ - /** - * Get filter type to use. - * - * @return string Fully qualified filter type class name - */ - public function getType(); - - /** - * Get filter name. - * - * @return string - */ - public function getName(); - - /** - * Set filter type options. - * - * @param array $filterTypeOptions - * - * @return self - */ - public function setTypeOptions(array $filterTypeOptions); - - /** - * Get filter type options. - * - * @return array - */ - public function getTypeOptions(); - - /** - * Set column ID if filter is associated with column. - * - * @param string $columnId - * - * @return self - */ - public function setAssociatedColumn($columnId); - - /** - * Get associated column. - * - * @return string|null - */ - public function getAssociatedColumn(); -} diff --git a/src/Core/Grid/Filter/GridFilterFormFactory.php b/src/Core/Grid/Filter/GridFilterFormFactory.php deleted file mode 100644 index 1d95216a..00000000 --- a/src/Core/Grid/Filter/GridFilterFormFactory.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Event\Dispatcher\NullDispatcher; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\FormFactoryInterface; - -/** - * Class FilterFormFactory is responsible for creating grid filter form. - */ -final class GridFilterFormFactory implements GridFilterFormFactoryInterface -{ - /** - * @var FormFactoryInterface - */ - private $formFactory; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @param FormFactoryInterface $formFactory - * @param HookDispatcherInterface|null $hookDispatcher - */ - public function __construct( - FormFactoryInterface $formFactory, - HookDispatcherInterface $hookDispatcher = null - ) { - $this->formFactory = $formFactory; - - if (null === $hookDispatcher) { - @trigger_error('The $hookDispatcher parameter should not be null, inject your main HookDispatcherInterface service, or NullDispatcher if you don\'t need hooks.', E_USER_DEPRECATED); - } - $this->hookDispatcher = $hookDispatcher ? $hookDispatcher : new NullDispatcher(); - } - - /** - * {@inheritdoc} - */ - public function create(GridDefinitionInterface $definition) - { - $formBuilder = $this->formFactory->createNamedBuilder( - $definition->getId(), - FormType::class - ); - - /** @var FilterInterface $filter */ - foreach ($definition->getFilters()->all() as $filter) { - $formBuilder->add( - $filter->getName(), - $filter->getType(), - $filter->getTypeOptions() - ); - } - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridFilterFormModifier', [ - 'filter_form_builder' => $formBuilder, - ]); - - return $formBuilder->getForm(); - } -} diff --git a/src/Core/Grid/Filter/GridFilterFormFactoryInterface.php b/src/Core/Grid/Filter/GridFilterFormFactoryInterface.php deleted file mode 100644 index ce48947a..00000000 --- a/src/Core/Grid/Filter/GridFilterFormFactoryInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Filter; - -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use Symfony\Component\Form\FormInterface; - -/** - * Interface FilterFormFactoryInterface. - */ -interface GridFilterFormFactoryInterface -{ - /** - * Create filters form for grid definition. - * - * @param GridDefinitionInterface $definition - * - * @return FormInterface - */ - public function create(GridDefinitionInterface $definition); -} diff --git a/src/Core/Grid/Grid.php b/src/Core/Grid/Grid.php deleted file mode 100644 index d89efbc8..00000000 --- a/src/Core/Grid/Grid.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridDataInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Form\FormInterface; - -/** - * Class Grid is responsible for holding final Grid data. - */ -final class Grid implements GridInterface -{ - /** - * @var GridDefinitionInterface - */ - private $definition; - - /** - * @var GridDataInterface - */ - private $data; - - /** - * @var SearchCriteriaInterface - */ - private $searchCriteria; - - /** - * @var FormInterface - */ - private $filtersForm; - - /** - * @param GridDefinitionInterface $definition - * @param GridDataInterface $data - * @param SearchCriteriaInterface $searchCriteria - * @param FormInterface $filtersForm - */ - public function __construct( - GridDefinitionInterface $definition, - GridDataInterface $data, - SearchCriteriaInterface $searchCriteria, - FormInterface $filtersForm - ) { - $this->definition = $definition; - $this->data = $data; - $this->searchCriteria = $searchCriteria; - $this->filtersForm = $filtersForm; - } - - /** - * {@inheritdoc} - */ - public function getDefinition() - { - return $this->definition; - } - - /** - * {@inheritdoc} - */ - public function getSearchCriteria() - { - return $this->searchCriteria; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return $this->data; - } - - /** - * {@inheritdoc} - */ - public function getFilterForm() - { - return $this->filtersForm; - } -} diff --git a/src/Core/Grid/GridFactory.php b/src/Core/Grid/GridFactory.php deleted file mode 100644 index a5a13486..00000000 --- a/src/Core/Grid/GridFactory.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\GridFilterFormFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShopBundle\Event\Dispatcher\NullDispatcher; -use Symfony\Component\DependencyInjection\Container; - -/** - * Class GridFactory is responsible for creating final Grid instance. - */ -final class GridFactory implements GridFactoryInterface -{ - /** - * @var GridDefinitionFactoryInterface - */ - private $definitionFactory; - - /** - * @var GridDataFactoryInterface - */ - private $dataFactory; - - /** - * @var GridFilterFormFactoryInterface - */ - private $filterFormFactory; - - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @param GridDefinitionFactoryInterface $definitionFactory - * @param GridDataFactoryInterface $dataFactory - * @param GridFilterFormFactoryInterface $filterFormFactory - * @param HookDispatcherInterface|null $hookDispatcher - */ - public function __construct( - GridDefinitionFactoryInterface $definitionFactory, - GridDataFactoryInterface $dataFactory, - GridFilterFormFactoryInterface $filterFormFactory, - HookDispatcherInterface $hookDispatcher = null - ) { - $this->definitionFactory = $definitionFactory; - $this->dataFactory = $dataFactory; - $this->filterFormFactory = $filterFormFactory; - - if (null === $hookDispatcher) { - @trigger_error('The $hookDispatcher parameter should not be null, inject your main HookDispatcherInterface service, or NullDispatcher if you don\'t need hooks.', E_USER_DEPRECATED); - } - $this->hookDispatcher = $hookDispatcher ? $hookDispatcher : new NullDispatcher(); - } - - /** - * {@inheritdoc} - */ - public function getGrid(SearchCriteriaInterface $searchCriteria) - { - $definition = $this->definitionFactory->getDefinition(); - $data = $this->dataFactory->getData($searchCriteria); - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridDataModifier', [ - 'data' => &$data, - ]); - - $filterForm = $this->filterFormFactory->create($definition); - $filterForm->setData($searchCriteria->getFilters()); - - return new Grid( - $definition, - $data, - $searchCriteria, - $filterForm - ); - } -} diff --git a/src/Core/Grid/GridFactoryInterface.php b/src/Core/Grid/GridFactoryInterface.php deleted file mode 100644 index 8f45dfb3..00000000 --- a/src/Core/Grid/GridFactoryInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Interface GridFactoryInterface exposes contract for grid factory which is responsible for creating Grid instances. - */ -interface GridFactoryInterface -{ - /** - * Create grid with filtered data. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return GridInterface - */ - public function getGrid(SearchCriteriaInterface $searchCriteria); -} diff --git a/src/Core/Grid/GridInterface.php b/src/Core/Grid/GridInterface.php deleted file mode 100644 index 68d366ce..00000000 --- a/src/Core/Grid/GridInterface.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Data\GridDataInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\Form\FormInterface; - -/** - * Interface GridInterface defines contract for grid. - */ -interface GridInterface -{ - /** - * Get grid definition. - * - * @return GridDefinitionInterface - */ - public function getDefinition(); - - /** - * Get grid data. - * - * @return GridDataInterface - */ - public function getData(); - - /** - * Get grid data search criteria. - * - * @return SearchCriteriaInterface - */ - public function getSearchCriteria(); - - /** - * Get grid filter form. - * - * @return FormInterface - */ - public function getFilterForm(); -} diff --git a/src/Core/Grid/Position/Exception/PositionDataException.php b/src/Core/Grid/Position/Exception/PositionDataException.php deleted file mode 100644 index 304ac1fc..00000000 --- a/src/Core/Grid/Position/Exception/PositionDataException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position\Exception; - -/** - * Class PositionDataException, used by the PositionDataHandler. - */ -class PositionDataException extends PositionException -{ -} diff --git a/src/Core/Grid/Position/Exception/PositionException.php b/src/Core/Grid/Position/Exception/PositionException.php deleted file mode 100644 index bcab057c..00000000 --- a/src/Core/Grid/Position/Exception/PositionException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position\Exception; - -use PrestaShop\PrestaShop\Core\Exception\TranslatableCoreException; - -/** - * Class PositionException used by the GridPositionUpdater component. - */ -class PositionException extends TranslatableCoreException -{ -} diff --git a/src/Core/Grid/Position/Exception/PositionUpdateException.php b/src/Core/Grid/Position/Exception/PositionUpdateException.php deleted file mode 100644 index dd23a009..00000000 --- a/src/Core/Grid/Position/Exception/PositionUpdateException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position\Exception; - -/** - * Class PositionUpdateException throw by GridPositionUpdater. - */ -class PositionUpdateException extends PositionException -{ -} diff --git a/src/Core/Grid/Position/GridPositionUpdater.php b/src/Core/Grid/Position/GridPositionUpdater.php deleted file mode 100644 index 3f15456f..00000000 --- a/src/Core/Grid/Position/GridPositionUpdater.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use PrestaShop\PrestaShop\Core\Grid\Position\UpdateHandler\PositionUpdateHandlerInterface; - -/** - * Class GridPositionUpdater, this class is responsible for updating the position of items - * of a grid using the information from a PositionUpdateInterface object. - */ -final class GridPositionUpdater implements GridPositionUpdaterInterface -{ - /** - * @var PositionUpdateHandlerInterface - */ - private $updateHandler; - - /** - * @param PositionUpdateHandlerInterface $updateHandler - */ - public function __construct(PositionUpdateHandlerInterface $updateHandler) - { - $this->updateHandler = $updateHandler; - } - - /** - * {@inheritdoc} - */ - public function update(PositionUpdateInterface $positionUpdate) - { - $newPositions = $this->getNewPositions($positionUpdate); - $this->sortByPositionValue($newPositions); - $this->updateHandler->updatePositions($positionUpdate->getPositionDefinition(), $newPositions); - } - - /** - * @param PositionUpdateInterface $positionUpdate - * - * @return array - */ - private function getNewPositions(PositionUpdateInterface $positionUpdate) - { - $positions = $this->updateHandler->getCurrentPositions($positionUpdate->getPositionDefinition(), $positionUpdate->getParentId()); - - /** @var PositionModificationInterface $rowModification */ - foreach ($positionUpdate->getPositionModificationCollection() as $rowModification) { - $positions[$rowModification->getId()] = $rowModification->getNewPosition(); - } - - return $positions; - } - - /** - * @param $positions - */ - private function sortByPositionValue(&$positions) - { - asort($positions); - } -} diff --git a/src/Core/Grid/Position/GridPositionUpdaterInterface.php b/src/Core/Grid/Position/GridPositionUpdaterInterface.php deleted file mode 100644 index 9f00dc3e..00000000 --- a/src/Core/Grid/Position/GridPositionUpdaterInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException; - -/** - * Interface GridPositionUpdaterInterface, this interface is responsible for updating the position of items - * of a grid using the information from a PositionUpdateInterface object. - */ -interface GridPositionUpdaterInterface -{ - /** - * Updates a grid based on the data in PositionUpdateInterface composed - * of the PositionDefinitionInterface allowing to build the query, the - * new positions and optionally a parentId - * Throws a PositionUpdateException if something went wrong. - * - * @param PositionUpdateInterface $positionUpdate - * - * @throws PositionUpdateException - */ - public function update(PositionUpdateInterface $positionUpdate); -} diff --git a/src/Core/Grid/Position/PositionDefinition.php b/src/Core/Grid/Position/PositionDefinition.php deleted file mode 100644 index 0b55dee7..00000000 --- a/src/Core/Grid/Position/PositionDefinition.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Class PositionDefinition used to define a position relationship, see - * PositionDefinitionInterface for more details. - */ -final class PositionDefinition implements PositionDefinitionInterface -{ - /** - * @var string - */ - private $table; - - /** - * @var string - */ - private $idField; - - /** - * @var string - */ - private $positionField; - - /** - * @var string|null - */ - private $parentIdField; - - /** - * @param string $table - * @param string $idField - * @param string $positionField - * @param string|null $parentIdField - */ - public function __construct( - $table, - $idField, - $positionField, - $parentIdField = null - ) { - $this->table = $table; - $this->idField = $idField; - $this->positionField = $positionField; - $this->parentIdField = $parentIdField; - } - - /** - * {@inheritdoc} - */ - public function getTable() - { - return $this->table; - } - - /** - * {@inheritdoc} - */ - public function getIdField() - { - return $this->idField; - } - - /** - * {@inheritdoc} - */ - public function getPositionField() - { - return $this->positionField; - } - - /** - * {@inheritdoc} - */ - public function getParentIdField() - { - return $this->parentIdField; - } -} diff --git a/src/Core/Grid/Position/PositionDefinitionInterface.php b/src/Core/Grid/Position/PositionDefinitionInterface.php deleted file mode 100644 index d32729f4..00000000 --- a/src/Core/Grid/Position/PositionDefinitionInterface.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Interface PositionDefinitionInterface used to define a position relationship, - * contains information about the database storing the position. - */ -interface PositionDefinitionInterface -{ - /** - * The name of the table containing the position. - * - * @return string - */ - public function getTable(); - - /** - * The name of the ID field in the row containing position. - * - * @return string - */ - public function getIdField(); - - /** - * The name of the position field in the row containing position. - * - * @return string - */ - public function getPositionField(); - - /** - * The name of the parent ID field in the row containing position, it - * is used to compute the positions in the parent scope. - * It is optional as the position may be bound to the table scope only. - * - * @return string|null - */ - public function getParentIdField(); -} diff --git a/src/Core/Grid/Position/PositionModification.php b/src/Core/Grid/Position/PositionModification.php deleted file mode 100644 index db3b4483..00000000 --- a/src/Core/Grid/Position/PositionModification.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Class PositionModification contains the modification for a - * designated row. - */ -final class PositionModification implements PositionModificationInterface -{ - /** - * @var string|int - */ - private $id; - - /** - * @var int - */ - private $oldPosition; - - /** - * @var int - */ - private $newPosition; - - /** - * @param string|int $id - * @param int $oldPosition - * @param int $newPosition - */ - public function __construct( - $id, - $oldPosition, - $newPosition - ) { - $this->id = $id; - $this->oldPosition = $oldPosition; - $this->newPosition = $newPosition; - } - - /** - * {@inheritdoc} - */ - public function getId() - { - return $this->id; - } - - /** - * {@inheritdoc} - */ - public function getOldPosition() - { - return $this->oldPosition; - } - - /** - * {@inheritdoc} - */ - public function getNewPosition() - { - return $this->newPosition; - } -} diff --git a/src/Core/Grid/Position/PositionModificationCollection.php b/src/Core/Grid/Position/PositionModificationCollection.php deleted file mode 100644 index 1c3565ca..00000000 --- a/src/Core/Grid/Position/PositionModificationCollection.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; - -/** - * Class PositionModificationCollection holds collection of row modifications for grid. - * - * @property PositionModificationInterface[] $items - */ -final class PositionModificationCollection extends AbstractCollection implements PositionModificationCollectionInterface -{ - /** - * {@inheritdoc} - */ - public function add(PositionModificationInterface $positionModification) - { - $this->items[$positionModification->getId()] = $positionModification; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function remove(PositionModificationInterface $positionModification) - { - if (isset($this->items[$positionModification->getId()])) { - unset($this->items[$positionModification->getId()]); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - $positionModifications = []; - - /** @var PositionModificationInterface $item */ - foreach ($this->items as $item) { - $positionModifications[] = [ - 'id' => $item->getId(), - 'oldPosition' => $item->getOldPosition(), - 'newPosition' => $item->getNewPosition(), - ]; - } - - return $positionModifications; - } -} diff --git a/src/Core/Grid/Position/PositionModificationCollectionInterface.php b/src/Core/Grid/Position/PositionModificationCollectionInterface.php deleted file mode 100644 index 2ffa03bc..00000000 --- a/src/Core/Grid/Position/PositionModificationCollectionInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use Countable; -use Iterator; - -/** - * Interface PositionModificationCollectionInterface defines contract for grid RowModificationInterface collection. - */ -interface PositionModificationCollectionInterface extends Iterator, Countable -{ - /** - * Add rowModification to collection. - * - * @param PositionModificationInterface $positionModification - * - * @return self - */ - public function add(PositionModificationInterface $positionModification); - - /** - * Remove positionModification from collection. - * - * @param PositionModificationInterface $positionModification - * - * @return self - */ - public function remove(PositionModificationInterface $positionModification); - - /** - * Get positionModifications as array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Grid/Position/PositionModificationInterface.php b/src/Core/Grid/Position/PositionModificationInterface.php deleted file mode 100644 index b1a01280..00000000 --- a/src/Core/Grid/Position/PositionModificationInterface.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Interface PositionModificationInterface contains the modification for a - * designated row. - */ -interface PositionModificationInterface -{ - /** - * The row id allowing to match it. - * - * @return string|int - */ - public function getId(); - - /** - * The former row position. - * - * @return int - */ - public function getOldPosition(); - - /** - * The new row position. - * - * @return int - */ - public function getNewPosition(); -} diff --git a/src/Core/Grid/Position/PositionUpdate.php b/src/Core/Grid/Position/PositionUpdate.php deleted file mode 100644 index c03d20bd..00000000 --- a/src/Core/Grid/Position/PositionUpdate.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Class PositionUpdate contains the modifications needed - * to update the grid positions. - */ -final class PositionUpdate implements PositionUpdateInterface -{ - /** - * @var PositionDefinitionInterface - */ - private $positionDefinition; - - /** - * @var PositionModificationCollectionInterface - */ - private $positionModificationCollection; - - /** - * @var string|null - */ - private $parentId; - - /** - * @param PositionModificationCollectionInterface $positionModificationCollection - * @param PositionDefinitionInterface $positionDefinition - * @param string|null $parentId - */ - public function __construct( - PositionModificationCollectionInterface $positionModificationCollection, - PositionDefinitionInterface $positionDefinition, - $parentId = null - ) { - $this->positionDefinition = $positionDefinition; - $this->positionModificationCollection = $positionModificationCollection; - $this->parentId = $parentId; - } - - /** - * {@inheritdoc} - */ - public function getPositionDefinition() - { - return $this->positionDefinition; - } - - /** - * {@inheritdoc} - */ - public function getPositionModificationCollection() - { - return $this->positionModificationCollection; - } - - /** - * {@inheritdoc} - */ - public function getParentId() - { - return $this->parentId; - } -} diff --git a/src/Core/Grid/Position/PositionUpdateFactory.php b/src/Core/Grid/Position/PositionUpdateFactory.php deleted file mode 100644 index f1abddd2..00000000 --- a/src/Core/Grid/Position/PositionUpdateFactory.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionDataException; - -/** - * Class PositionUpdateFactory is a basic implementation of the PositionUpdateFactoryInterface, - * it transforms the provided array data into a PositionUpdate object. - */ -final class PositionUpdateFactory implements PositionUpdateFactoryInterface -{ - const POSITION_KEY = 'Invalid position %i data, missing %s field.'; - - /** - * @var string - */ - private $positionsField; - - /** - * @var string - */ - private $rowIdField; - - /** - * @var string - */ - private $oldPositionField; - - /** - * @var string - */ - private $newPositionField; - - /** - * @var string - */ - private $parentIdField; - - /** - * @param string $positionsField - * @param string $rowIdField - * @param string $oldPositionField - * @param string $newPositionField - * @param string $parentIdField - */ - public function __construct( - $positionsField, - $rowIdField, - $oldPositionField, - $newPositionField, - $parentIdField - ) { - $this->positionsField = $positionsField; - $this->rowIdField = $rowIdField; - $this->oldPositionField = $oldPositionField; - $this->newPositionField = $newPositionField; - $this->parentIdField = $parentIdField; - } - - /** - * {@inheritdoc} - */ - public function buildPositionUpdate(array $data, PositionDefinition $positionDefinition) - { - $this->validateData($data, $positionDefinition); - - $updates = new PositionModificationCollection(); - foreach ($data[$this->positionsField] as $index => $position) { - $this->validatePositionData($position, $index); - - $updates->add(new PositionModification( - $position[$this->rowIdField], - $position[$this->oldPositionField], - $position[$this->newPositionField] - )); - } - - $positionUpdate = new PositionUpdate( - $updates, - $positionDefinition, - isset($data[$this->parentIdField]) ? $data[$this->parentIdField] : null - ); - - return $positionUpdate; - } - - /** - * @param array $data - * @param PositionDefinition $positionDefinition - * - * @throws PositionDataException - */ - private function validateData(array $data, PositionDefinition $positionDefinition) - { - if (empty($data[$this->positionsField])) { - throw new PositionDataException('Missing ' . $this->positionsField . ' in your data.', 'Admin.Notifications.Failure'); - } - - if (null !== $positionDefinition->getParentIdField() && empty($data[$this->parentIdField])) { - throw new PositionDataException('Missing ' . $this->parentIdField . ' in your data.', 'Admin.Notifications.Failure'); - } - } - - /** - * Validate the position format, throw a PositionDataException if is not correct. - * - * @param array $position - * @param int $index - * - * @throws PositionDataException - */ - private function validatePositionData(array $position, $index) - { - if (!isset($position[$this->rowIdField])) { - throw new PositionDataException(self::POSITION_KEY, 'Admin.Notifications.Failure', [$index, $this->rowIdField]); - } - if (!isset($position[$this->oldPositionField])) { - throw new PositionDataException(self::POSITION_KEY, 'Admin.Notifications.Failure', [$index, $this->oldPositionField]); - } - if (!isset($position[$this->newPositionField])) { - throw new PositionDataException(self::POSITION_KEY, 'Admin.Notifications.Failure', [$index, $this->newPositionField]); - } - } -} diff --git a/src/Core/Grid/Position/PositionUpdateFactoryInterface.php b/src/Core/Grid/Position/PositionUpdateFactoryInterface.php deleted file mode 100644 index 37a75888..00000000 --- a/src/Core/Grid/Position/PositionUpdateFactoryInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionDataException; - -/** - * Interface PositionUpdateFactoryInterface is used to interpret the provided - * data array and transform it in a fully filled PositionUpdate object. - */ -interface PositionUpdateFactoryInterface -{ - /** - * Transform the provided data into a PositionUpdate. - * - * @param array $data - * @param PositionDefinition $positionDefinition - * - * @return PositionUpdate - * - * @throws PositionDataException - */ - public function buildPositionUpdate(array $data, PositionDefinition $positionDefinition); -} diff --git a/src/Core/Grid/Position/PositionUpdateInterface.php b/src/Core/Grid/Position/PositionUpdateInterface.php deleted file mode 100644 index d9d792a3..00000000 --- a/src/Core/Grid/Position/PositionUpdateInterface.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position; - -/** - * Interface PositionUpdateInterface contains the modifications needed - * to update the grid positions. - */ -interface PositionUpdateInterface -{ - /** - * The PositionDefinition defines the position relationship and - * allows to be build the database request. - * - * @return PositionDefinitionInterface - */ - public function getPositionDefinition(); - - /** - * A collection of modifications for each modified rows. - * - * @return PositionModificationCollectionInterface - */ - public function getPositionModificationCollection(); - - /** - * If the PositionDefinition needs a parent and has defined a - * parentIdField then this field contains its value. - * - * @return string|null - */ - public function getParentId(); -} diff --git a/src/Core/Grid/Position/UpdateHandler/DoctrinePositionUpdateHandler.php b/src/Core/Grid/Position/UpdateHandler/DoctrinePositionUpdateHandler.php deleted file mode 100644 index dc346abb..00000000 --- a/src/Core/Grid/Position/UpdateHandler/DoctrinePositionUpdateHandler.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position\UpdateHandler; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\ConnectionException; -use Doctrine\DBAL\Statement; -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException; -use PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinitionInterface; - -/** - * Class DoctrinePositionUpdateHandler updates the grid positions using a Doctrine - * Connection. - */ -final class DoctrinePositionUpdateHandler implements PositionUpdateHandlerInterface -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @param Connection $connection - * @param string $dbPrefix - */ - public function __construct( - Connection $connection, - $dbPrefix - ) { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - } - - /** - * {@inheritdoc} - */ - public function getCurrentPositions(PositionDefinitionInterface $positionDefinition, $parentId = null) - { - $qb = $this->connection->createQueryBuilder(); - $qb - ->from($this->dbPrefix . $positionDefinition->getTable(), 't') - ->select('t.' . $positionDefinition->getIdField() . ', t.' . $positionDefinition->getPositionField()) - ->addOrderBy('t.' . $positionDefinition->getPositionField(), 'ASC'); - - if (null !== $parentId && null !== $positionDefinition->getParentIdField()) { - $qb - ->andWhere('t.' . $positionDefinition->getParentIdField() . ' = :parentId') - ->setParameter('parentId', $parentId); - } - - $positions = $qb->execute()->fetchAll(); - $currentPositions = []; - foreach ($positions as $position) { - $positionId = $position[$positionDefinition->getIdField()]; - $currentPositions[$positionId] = $position[$positionDefinition->getPositionField()]; - } - - return $currentPositions; - } - - /** - * {@inheritdoc} - */ - public function updatePositions(PositionDefinitionInterface $positionDefinition, array $newPositions) - { - try { - $this->connection->beginTransaction(); - $positionIndex = 0; - foreach ($newPositions as $rowId => $newPosition) { - $qb = $this->connection->createQueryBuilder(); - $qb - ->update($this->dbPrefix . $positionDefinition->getTable()) - ->set($positionDefinition->getPositionField(), ':position') - ->andWhere($positionDefinition->getIdField() . ' = :rowId') - ->setParameter('rowId', $rowId) - ->setParameter('position', $positionIndex); - - $statement = $qb->execute(); - if ($statement instanceof Statement && $statement->errorCode()) { - throw new PositionUpdateException('Could not update #%i', 'Admin.Catalog.Notification', [$rowId]); - } - ++$positionIndex; - } - $this->connection->commit(); - } catch (ConnectionException $e) { - $this->connection->rollBack(); - - throw new PositionUpdateException('Could not update.', 'Admin.Catalog.Notification'); - } - } -} diff --git a/src/Core/Grid/Position/UpdateHandler/PositionUpdateHandlerInterface.php b/src/Core/Grid/Position/UpdateHandler/PositionUpdateHandlerInterface.php deleted file mode 100644 index be42f008..00000000 --- a/src/Core/Grid/Position/UpdateHandler/PositionUpdateHandlerInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Position\UpdateHandler; - -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException; -use PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinitionInterface; - -/** - * Interface PositionUpdateHandlerInterface is used by GridPositionUpdater to - * manipulate the data, handling the manipulation in this interface allows the - * GridPositionUpdater to adapt more easily to different databases or any other - * persistence solutions. - */ -interface PositionUpdateHandlerInterface -{ - /** - * Returns the complete list of positions based on the PositionDefinitionInterface - * The expected return is an associative array with row IDs used as keys and positions - * as values. - * - * ex: $currentPositions = [ - * 1 => 0, - * 4 => 1, - * 42 => 2, - * 3 => 3 - * ]; - * - * @param string|int $parentId - * @param PositionDefinitionInterface $positionDefinition - * - * @return array - */ - public function getCurrentPositions(PositionDefinitionInterface $positionDefinition, $parentId = null); - - /** - * This method is used to update the new positions previously fetched through getCurrentPositions which - * have been updated by the GridPositionUpdater, hence the $newPositions has the same format as the one - * returned by getCurrentPositions, except of course the positions are likely to have changed. - * - * ex: $newPositions = [ - * 1 => 3, - * 4 => 1, - * 42 => 2, - * 3 => 3 - * ]; - * - * Throws a PositionUpdateException if something went wrong. - * - * @param PositionDefinitionInterface $positionDefinition - * @param array $newPositions - * - * @throws PositionUpdateException - */ - public function updatePositions(PositionDefinitionInterface $positionDefinition, array $newPositions); -} diff --git a/src/Core/Grid/Presenter/GridPresenter.php b/src/Core/Grid/Presenter/GridPresenter.php deleted file mode 100644 index b1dc4f36..00000000 --- a/src/Core/Grid/Presenter/GridPresenter.php +++ /dev/null @@ -1,170 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Presenter; - -use PrestaShop\PrestaShop\Core\Grid\Column\ColumnInterface; -use PrestaShop\PrestaShop\Core\Grid\Column\Type\Common\PositionColumn; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\FilterInterface; -use PrestaShop\PrestaShop\Core\Grid\GridInterface; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Search\Filters; -use Symfony\Component\DependencyInjection\Container; - -/** - * Class GridPresenter is responsible for presenting grid. - */ -final class GridPresenter implements GridPresenterInterface -{ - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - public function __construct(HookDispatcherInterface $hookDispatcher) - { - $this->hookDispatcher = $hookDispatcher; - } - - /** - * {@inheritdoc} - */ - public function present(GridInterface $grid) - { - $filterForm = $grid->getFilterForm(); - - $definition = $grid->getDefinition(); - $searchCriteria = $grid->getSearchCriteria(); - $data = $grid->getData(); - $presentedGrid = [ - 'id' => $definition->getId(), - 'name' => $definition->getName(), - 'filter_form' => $filterForm->createView(), - 'form_prefix' => '', - 'columns' => $this->getColumns($grid), - 'column_filters' => $this->getColumnFilters($definition), - 'actions' => [ - 'grid' => $definition->getGridActions()->toArray(), - 'bulk' => $definition->getBulkActions()->toArray(), - ], - 'data' => [ - 'records' => $data->getRecords(), - 'records_total' => $data->getRecordsTotal(), - 'query' => $data->getQuery(), - ], - 'pagination' => [ - 'offset' => $searchCriteria->getOffset(), - 'limit' => $searchCriteria->getLimit(), - ], - 'sorting' => [ - 'order_by' => $searchCriteria->getOrderBy(), - 'order_way' => $searchCriteria->getOrderWay(), - ], - 'filters' => $searchCriteria->getFilters(), - 'attributes' => [ - 'is_empty_state' => empty($filterForm->getData()) && $data->getRecords()->count() === 0, - ], - ]; - - if ($searchCriteria instanceof Filters) { - $presentedGrid['form_prefix'] = $searchCriteria->getFilterId(); - } - - $this->hookDispatcher->dispatchWithParameters('action' . Container::camelize($definition->getId()) . 'GridPresenterModifier', [ - 'presented_grid' => &$presentedGrid, - ]); - - return $presentedGrid; - } - - /** - * Returns the columns formatted as array, adds an additional position handle - * column when needed. - * - * @param GridInterface $grid - * - * @return array - */ - private function getColumns(GridInterface $grid) - { - $columns = $grid->getDefinition()->getColumns()->toArray(); - - $positionColumn = $this->getOrderingPosition($grid); - if (null !== $positionColumn) { - array_unshift($columns, [ - 'id' => $positionColumn->getId() . '_handle', - 'name' => $positionColumn->getName(), - 'type' => 'position_handle', - 'options' => $positionColumn->getOptions(), - ]); - } - - return $columns; - } - - /** - * @param GridInterface $grid - * - * @return ColumnInterface|null - */ - public function getOrderingPosition(GridInterface $grid) - { - $searchCriteria = $grid->getSearchCriteria(); - /** @var ColumnInterface $column */ - foreach ($grid->getDefinition()->getColumns() as $column) { - if ($column instanceof PositionColumn && - strtolower($column->getId()) == strtolower($searchCriteria->getOrderBy()) && - 'asc' == strtolower($searchCriteria->getOrderWay()) - ) { - return $column; - } - } - - return null; - } - - /** - * Get filters that have associated columns. - * - * @param GridDefinitionInterface $definition - * - * @return array - */ - private function getColumnFilters(GridDefinitionInterface $definition) - { - $columnFiltersMapping = []; - - /** @var FilterInterface $filter */ - foreach ($definition->getFilters()->all() as $filter) { - if (null !== $associatedColumn = $filter->getAssociatedColumn()) { - $columnFiltersMapping[$associatedColumn][] = $filter->getName(); - } - } - - return $columnFiltersMapping; - } -} diff --git a/src/Core/Grid/Presenter/GridPresenterInterface.php b/src/Core/Grid/Presenter/GridPresenterInterface.php deleted file mode 100644 index 118471c1..00000000 --- a/src/Core/Grid/Presenter/GridPresenterInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Presenter; - -use PrestaShop\PrestaShop\Core\Grid\GridInterface; - -/** - * Interface GridPresenterInterface defines contract for grid presenter. - */ -interface GridPresenterInterface -{ - /** - * Present grid as plain array. - * - * @param GridInterface $grid - * - * @return array - */ - public function present(GridInterface $grid); -} diff --git a/src/Core/Grid/Query/AbstractDoctrineQueryBuilder.php b/src/Core/Grid/Query/AbstractDoctrineQueryBuilder.php deleted file mode 100644 index 019cb8e4..00000000 --- a/src/Core/Grid/Query/AbstractDoctrineQueryBuilder.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; - -/** - * Class AbstractDoctrineQueryBuilder provides most common dependencies of doctrine query builders. - */ -abstract class AbstractDoctrineQueryBuilder implements DoctrineQueryBuilderInterface -{ - /** - * @var Connection - */ - protected $connection; - - /** - * @var string - */ - protected $dbPrefix; - - /** - * @param Connection $connection - * @param $dbPrefix - */ - public function __construct(Connection $connection, $dbPrefix) - { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - } -} diff --git a/src/Core/Grid/Query/AddressQueryBuilder.php b/src/Core/Grid/Query/AddressQueryBuilder.php deleted file mode 100644 index 3cce6195..00000000 --- a/src/Core/Grid/Query/AddressQueryBuilder.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds search & count queries for address grid. - */ -final class AddressQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLangId - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - string $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - int $contextLangId, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextLangId = $contextLangId; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('a.`id_address`, a.`firstname`, a.`lastname`, a.`address1`, a.`postcode`, a.`city`') - ->addSelect('cl.`name` as country_name') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT a.`id_address`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying addresses list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters): QueryBuilder - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'address', 'a') - ->where('a.`id_customer` != 0') - ->andWhere('a.`deleted` = 0'); - - $qb->leftJoin( - 'a', - $this->dbPrefix . 'country', - 'c', - 'a.`id_country` = c.`id_country`' - ); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'country_lang', - 'cl', - 'c.`id_country` = cl.`id_country` AND cl.`id_lang` = :idLang' - ); - - $qb->leftJoin( - 'a', - $this->dbPrefix . 'customer', - 'customer', - 'a.`id_customer` = customer.`id_customer`' - ); - - $qb->andWhere('customer.id_shop IN (:context_shop_ids)') - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ->setParameter('idLang', $this->contextLangId); - - $this->applyFilters($qb, $filters); - - return $qb; - } - - /** - * Apply filters to address query builder. - * - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFiltersMap = [ - 'id_address' => 'a.id_address', - 'firstname' => 'a.firstname', - 'lastname' => 'a.lastname', - 'address1' => 'a.address1', - 'postcode' => 'a.postcode', - 'city' => 'a.city', - 'id_country' => 'cl.id_country', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap) || empty($value)) { - continue; - } - - if ('id_country' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' = :' . $filterName) - ->setParameter($filterName, $value); - - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - } - } -} diff --git a/src/Core/Grid/Query/AttachmentQueryBuilder.php b/src/Core/Grid/Query/AttachmentQueryBuilder.php deleted file mode 100644 index 93937eae..00000000 --- a/src/Core/Grid/Query/AttachmentQueryBuilder.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Attachment query builder builds search & count data for attachment grid. - */ -final class AttachmentQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $employeeIdLang; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param string $employeeIdLang - */ - public function __construct( - Connection $connection, - string $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - string $employeeIdLang - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->employeeIdLang = $employeeIdLang; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('a.`id_attachment`, al.`name`, a.`file`, a.`file_size`') - ->addSelect('COALESCE(virtual_product_attachment.`product_count`, 0) AS products') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria): QueryBuilder - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT a.`id_attachment`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying webservice list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters): QueryBuilder - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'attachment', 'a') - ->leftJoin( - 'a', - $this->dbPrefix . 'attachment_lang', - 'al', - 'a.`id_attachment` = al.`id_attachment`' - ); - - $productCountQb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'product_attachment', 'pa') - ->select('pa.`id_attachment`, COUNT(*) as product_count') - ->groupBy('id_attachment'); - - $qb->leftJoin('a', - '(' . $productCountQb->getSQL() . ')', - 'virtual_product_attachment', - 'a.`id_attachment` = virtual_product_attachment.`id_attachment`'); - - $qb->andWhere('al.`id_lang` = :employee_id_lang'); - $qb->setParameter('employee_id_lang', $this->employeeIdLang); - $this->applyFilters($qb, $filters); - - return $qb; - } - - /** - * Apply filters to attachments query builder. - * - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFiltersMap = [ - 'id_attachment' => 'a.id_attachment', - 'name' => 'al.name', - 'file_size' => 'a.file_size', - 'products' => 'virtual_product_attachment.product_count', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if ('id_attachment' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - if ('products' === $filterName && $value === '0') { - $qb->andWhere($allowedFiltersMap[$filterName] . ' IS NULL'); - - $qb->setParameter($filterName, $value); - - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - } - } -} diff --git a/src/Core/Grid/Query/AttributeGroupQueryBuilder.php b/src/Core/Grid/Query/AttributeGroupQueryBuilder.php deleted file mode 100644 index e445d384..00000000 --- a/src/Core/Grid/Query/AttributeGroupQueryBuilder.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Provides sql for attributes group list - */ -final class AttributeGroupQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLangId - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param int[] $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextLangId, - MultistoreContextCheckerInterface $multistoreContextChecker, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - $this->contextLangId = $contextLangId; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->multistoreContextChecker = $multistoreContextChecker; - $this->contextShopIds = $contextShopIds; - } - - /** - * Get query that searches grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('DISTINCT ag.id_attribute_group, agl.name, ag.position, acount.values'); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * Get query that counts grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(DISTINCT ag.id_attribute_group)'); - - return $qb; - } - - /** - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $subQuery = $this->connection->createQueryBuilder() - ->select('COUNT(DISTINCT a.id_attribute) AS `values`, a.id_attribute_group') - ->from($this->dbPrefix . 'attribute', 'a') - ->groupBy('a.id_attribute_group'); - - if (!$this->multistoreContextChecker->isAllShopContext()) { - $subQuery->andWhere('attrShop.id_shop IN (:contextShopIds)'); - } - - $subQuery->leftJoin( - 'a', - $this->dbPrefix . 'attribute_shop', - 'attrShop', - 'a.id_attribute = attrShop.id_attribute' - ); - - $qb = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'attribute_group', 'ag') - ->leftJoin( - 'ag', - '(' . $subQuery->getSQL() . ')', - 'acount', - 'acount.id_attribute_group = ag.id_attribute_group' - ) - ->setParameter('contextLangId', $this->contextLangId) - ->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - $qb->leftJoin( - 'ag', - $this->dbPrefix . 'attribute_group_lang', - 'agl', - 'agl.id_attribute_group = ag.id_attribute_group AND agl.id_lang = :contextLangId' - ); - - $qb->leftJoin( - 'ag', - $this->dbPrefix . 'attribute_group_shop', - 'ags', - 'ag.id_attribute_group = ags.id_attribute_group' - ); - $qb->andWhere('ags.id_shop IN (:contextShopIds)'); - - $this->applyFilters($filters, $qb); - - return $qb; - } - - /** - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(array $filters, QueryBuilder $qb) - { - $allowedFiltersMap = [ - 'id_attribute_group' => 'ag.id_attribute_group', - 'name' => 'agl.name', - 'position' => 'ag.position', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if ('name' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - continue; - } - - if ('position' === $filterName) { - // When filtering by position, - // value must be decreased by 1, - // since position value in database starts at 0, - // but for user display positions are increased by 1. - if (is_numeric($value)) { - --$value; - } else { - $value = null; - } - } - - $qb->andWhere($allowedFiltersMap[$filterName] . ' = :' . $filterName) - ->setParameter($filterName, $value); - } - } -} diff --git a/src/Core/Grid/Query/AttributeQueryBuilder.php b/src/Core/Grid/Query/AttributeQueryBuilder.php deleted file mode 100644 index 1ff8f3b4..00000000 --- a/src/Core/Grid/Query/AttributeQueryBuilder.php +++ /dev/null @@ -1,208 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Provides sql for attributes group > attribute list - */ -final class AttributeQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var int - */ - private $attributeGroupId; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLangId - * @param int $attributeGroupId - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param int[] $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextLangId, - $attributeGroupId, - MultistoreContextCheckerInterface $multistoreContextChecker, - $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - $this->contextLangId = $contextLangId; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->attributeGroupId = $attributeGroupId; - $this->multistoreContextChecker = $multistoreContextChecker; - $this->contextShopIds = $contextShopIds; - } - - /** - * Get query that searches grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('DISTINCT a.id_attribute, a.color, a.id_attribute_group, al.name AS value, a.position'); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * Get query that counts grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(DISTINCT a.`id_attribute`)'); - - return $qb; - } - - /** - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'attribute', 'a') - ->setParameter('contextLangId', $this->contextLangId) - ->setParameter('attributeGroupId', $this->attributeGroupId) - ->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ->andWhere('al.id_lang = :contextLangId') - ->andWhere('ag.id_attribute_group = :attributeGroupId'); - - if (!$this->multistoreContextChecker->isAllShopContext()) { - $qb->andWhere('ashop.id_shop IN (:contextShopIds)'); - } - - $qb->leftJoin( - 'a', - $this->dbPrefix . 'attribute_shop', - 'ashop', - 'a.id_attribute = ashop.id_attribute' - ); - - $qb->leftJoin( - 'a', - $this->dbPrefix . 'attribute_group', - 'ag', - 'a.id_attribute_group = ag.id_attribute_group'); - - $qb->leftJoin( - 'a', - $this->dbPrefix . 'attribute_lang', - 'al', - 'a.id_attribute = al.id_attribute' - ); - - $this->applyFilters($filters, $qb); - - return $qb; - } - - /** - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(array $filters, QueryBuilder $qb) - { - $allowedFiltersMap = [ - 'id_attribute' => 'a.id_attribute', - 'value' => 'al.name', - 'position' => 'a.position', - 'color' => 'a.color', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if ('value' === $filterName || 'color' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - continue; - } - - if ('position' === $filterName) { - // When filtering by position, - // value must be decreased by 1, - // since position value in database starts at 0, - // but for user display positions are increased by 1. - if (is_numeric($value)) { - --$value; - } else { - $value = null; - } - } - - $qb->andWhere('a.`' . $filterName . '` = :' . $filterName) - ->setParameter($filterName, $value); - } - } -} diff --git a/src/Core/Grid/Query/CatalogPriceRuleQueryBuilder.php b/src/Core/Grid/Query/CatalogPriceRuleQueryBuilder.php deleted file mode 100644 index fde4e538..00000000 --- a/src/Core/Grid/Query/CatalogPriceRuleQueryBuilder.php +++ /dev/null @@ -1,210 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for catalog price rule list - */ -final class CatalogPriceRuleQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var int - */ - private $contextIdLang; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - * @param int $contextIdLang - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds, - $contextIdLang - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - $this->contextIdLang = $contextIdLang; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb->select( - 'pr.id_specific_price_rule, - pr.name, - pr.from_quantity, - pr.reduction, - pr.reduction_type, - pr.from date_from, - pr.to date_to, - pr_shop.name shop, - pr_currency.name currency, - pr_country.name country, - pr_group.name group_name' - ); - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT pr.`id_specific_price_rule`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql for catalog price rule listing. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'specific_price_rule', 'pr') - ->leftJoin( - 'pr', - $this->dbPrefix . 'shop', - 'pr_shop', - 'pr_shop.`id_shop` = pr.`id_shop` AND pr.`id_shop` IN (:contextShopIds)' - ) - ->leftJoin( - 'pr', - $this->dbPrefix . 'currency_lang', - 'pr_currency', - 'pr_currency.`id_currency` = pr.`id_currency` AND pr_currency.`id_lang` = :contextLangId' - ) - ->leftJoin( - 'pr', - $this->dbPrefix . 'country_lang', - 'pr_country', - 'pr_country.`id_country` = pr.`id_country` AND pr_country.`id_lang` = :contextLangId' - ) - ->leftJoin( - 'pr', - $this->dbPrefix . 'group_lang', - 'pr_group', - 'pr_group.`id_group` = pr.`id_group` AND pr_group.`id_lang` = :contextLangId' - ) - ; - - $this->applyFilters($qb, $filters); - $qb->setParameter('contextLangId', $this->contextIdLang); - $qb->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - return $qb; - } - - /** - * @param QueryBuilder $qb - * @param array $filters - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFiltersAliasMap = [ - 'id_specific_price_rule' => 'pr.id_specific_price_rule', - 'name' => 'pr.name', - 'from_quantity' => 'pr.from_quantity', - 'reduction' => 'pr.reduction', - 'reduction_type' => 'pr.reduction_type', - 'date_from' => 'pr.from', - 'date_to' => 'pr.to', - 'shop' => 'pr_shop.name', - 'currency' => 'pr_currency.name', - 'country' => 'pr_country.name', - 'group_name' => 'pr_group.name', - ]; - - $exactMatchFilters = ['id_specific_price_rule', 'from_quantity', 'reduction', 'reduction_type']; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersAliasMap)) { - return; - } - - if (in_array($filterName, $exactMatchFilters, true)) { - $qb->andWhere($allowedFiltersAliasMap[$filterName] . ' = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - if ('date_from' === $filterName || 'date_to' === $filterName) { - if (isset($value['from'])) { - $qb->andWhere($allowedFiltersAliasMap[$filterName] . ' >= :' . $filterName . '_from'); - $qb->setParameter($filterName . '_from', $value['from']); - } - if (isset($value['to'])) { - $qb->andWhere($allowedFiltersAliasMap[$filterName] . ' <= :' . $filterName . '_to'); - $qb->setParameter($filterName . '_to', $value['to']); - } - - continue; - } - - $qb->andWhere($allowedFiltersAliasMap[$filterName] . ' LIKE :' . $filterName); - $qb->setParameter($filterName, "%$value%"); - } - } -} diff --git a/src/Core/Grid/Query/CategoryQueryBuilder.php b/src/Core/Grid/Query/CategoryQueryBuilder.php deleted file mode 100644 index 5768b1e0..00000000 --- a/src/Core/Grid/Query/CategoryQueryBuilder.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Class CategoryQueryBuilder builds search & count queries for categories grid. - */ -final class CategoryQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var int|null - * - * Can be null for backward-compatibility - */ - private $rootCategoryId; - - /** - * @var DoctrineSearchCriteriaApplicator - */ - private $searchCriteriaApplicator; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var FeatureInterface - */ - private $multistoreFeature; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicator $searchCriteriaApplicator - * @param int $contextLangId - * @param int $contextShopId - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param FeatureInterface $multistoreFeature - * @param int|null $rootCategoryId - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicator $searchCriteriaApplicator, - $contextLangId, - $contextShopId, - MultistoreContextCheckerInterface $multistoreContextChecker, - FeatureInterface $multistoreFeature, - $rootCategoryId = null - ) { - parent::__construct($connection, $dbPrefix); - - $this->contextLangId = $contextLangId; - $this->contextShopId = $contextShopId; - $this->rootCategoryId = $rootCategoryId; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->multistoreContextChecker = $multistoreContextChecker; - $this->multistoreFeature = $multistoreFeature; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('c.id_category, c.id_parent, c.active, cl.name, cl.description, cs.position'); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(c.id_category)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'category', 'c') - ->setParameter('context_lang_id', $this->contextLangId) - ->setParameter('context_shop_id', $this->contextShopId); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'category_lang', - 'cl', - $this->multistoreFeature->isUsed() && $this->multistoreContextChecker->isSingleShopContext() ? - 'c.id_category = cl.id_category AND cl.id_lang = :context_lang_id AND cl.id_shop = :context_shop_id' : - 'c.id_category = cl.id_category AND cl.id_lang = :context_lang_id AND cl.id_shop = c.id_shop_default' - ); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'category_shop', - 'cs', - $this->multistoreContextChecker->isSingleShopContext() ? - 'c.id_category = cs.id_category AND cs.id_shop = :context_shop_id' : - 'c.id_category = cs.id_category AND cs.id_shop = c.id_shop_default' - ); - - foreach ($filters as $filterName => $filterValue) { - if ('id_category' === $filterName) { - $qb->andWhere("c.id_category = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - // exclude root category from search results - if ($this->rootCategoryId !== null) { - $qb->andWhere('c.id_category != :root_category_id'); - $qb->setParameter('root_category_id', $this->rootCategoryId); - } - - if ('name' === $filterName) { - $qb->andWhere("cl.name LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('description' === $filterName) { - $qb->andWhere("cl.description LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('position' === $filterName) { - // When filtering by position, - // value must be decreased by 1, - // since position value in database starts at 0, - // but for user display positions are increased by 1. - if (is_numeric($filterValue)) { - --$filterValue; - } else { - $filterValue = null; - } - - $qb->andWhere("cs.position = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if ('active' === $filterName) { - $qb->andWhere("c.active = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if ('id_category_parent' === $filterName) { - if ($this->isSearchRequestOnHomeCategory($filters)) { - continue; - } - - $qb->andWhere("c.id_parent = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - } - - if ($this->multistoreFeature->isUsed() && $this->multistoreContextChecker->isSingleShopContext()) { - $qb->andWhere('cs.id_shop = :context_shop_id'); - } - - return $qb; - } - - /** - * @param array $filters - * - * @return bool - */ - private function isSearchRequestOnHomeCategory(array $filters) - { - return isset($filters['is_home_category'], $filters['is_search_request']) - && $filters['is_home_category'] === true && $filters['is_search_request'] === true; - } -} diff --git a/src/Core/Grid/Query/CmsPageCategoryQueryBuilder.php b/src/Core/Grid/Query/CmsPageCategoryQueryBuilder.php deleted file mode 100644 index 092ecaca..00000000 --- a/src/Core/Grid/Query/CmsPageCategoryQueryBuilder.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class CmsPageCategoryQueryBuilder builds search & count queries for cms page categories grid. - */ -final class CmsPageCategoryQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var int - */ - private $contextIdLang; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - * @param int $contextIdLang - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds, - $contextIdLang - ) { - parent::__construct($connection, $dbPrefix); - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - $this->contextIdLang = $contextIdLang; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('cc.`id_cms_category`, cc.`id_parent`, cc.`active`, cc.`position`, ccl.`name`, ccl.`description`') - ->groupBy('cc.`id_cms_category`') - ->orderBy( - $this->getModifiedOrderBy($searchCriteria->getOrderBy()), - $searchCriteria->getOrderWay() - ) - ; - - $this->searchCriteriaApplicator->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT cc.`id_cms_category`)') - ; - - return $qb; - } - - /** - * Gets query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $availableFilters = [ - 'id_cms_category_parent', - 'id_cms_category', - 'active', - 'position', - 'name', - 'description', - ]; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'cms_category', 'cc') - ->leftJoin( - 'cc', - $this->dbPrefix . 'cms_category_lang', - 'ccl', - 'ccl.`id_cms_category` = cc.`id_cms_category`' - ) - ->innerJoin( - 'cc', - $this->dbPrefix . 'cms_category_shop', - 'ccs', - 'ccs.`id_cms_category` = cc.`id_cms_category`' - ) - ; - - $qb->andWhere('ccl.`id_lang` = :contextLangId'); - $qb->andWhere('ccl.`id_shop` IN (:contextShopIds)'); - $qb->andWhere('ccs.`id_shop` IN (:contextShopIds)'); - - $qb->setParameter('contextLangId', $this->contextIdLang); - $qb->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - foreach ($filters as $filterName => $value) { - if (!in_array($filterName, $availableFilters, true)) { - continue; - } - - if ('id_cms_category_parent' === $filterName) { - $qb->andWhere('cc.`id_parent` = :id_cms_category_parent'); - $qb->setParameter('id_cms_category_parent', $value); - - continue; - } - - if (in_array($filterName, ['id_cms_category', 'active'], true)) { - $qb->andWhere('cc.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - if ('position' === $filterName) { - $modifiedPositionFilter = $this->getModifiedPositionFilter($value); - $qb->andWhere('cc.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $modifiedPositionFilter); - - continue; - } - - $qb->andWhere('ccl.`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $value . '%'); - } - - return $qb; - } - - /** - * Gets modified order by by having prefix appended. - * - * @param string $orderBy - * - * @return string - */ - private function getModifiedOrderBy($orderBy) - { - if ('id_cms_category' === $orderBy) { - $orderBy = 'cc.`id_cms_category`'; - } - - return $orderBy; - } - - /** - * Gets modified position filter value. This is required due to in database position filter index starts from 0 and - * for the customer which wants to filter results the value starts from 1 instead. - * - * @param $positionFilterValue - * - * @return int|null - if null is returned then no results are found since position field does not hold null values - */ - private function getModifiedPositionFilter($positionFilterValue) - { - if (!is_numeric($positionFilterValue)) { - return null; - } - - $reducedByOneFilterValue = $positionFilterValue - 1; - - if (0 > $reducedByOneFilterValue) { - return null; - } - - return $reducedByOneFilterValue; - } -} diff --git a/src/Core/Grid/Query/CmsPageQueryBuilder.php b/src/Core/Grid/Query/CmsPageQueryBuilder.php deleted file mode 100644 index 79b8ce24..00000000 --- a/src/Core/Grid/Query/CmsPageQueryBuilder.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class responsible for providing sql which is needed to render cms page list. - */ -final class CmsPageQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var int - */ - private $contextIdLang; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - * @param int $contextIdLang - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds, - $contextIdLang - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - $this->contextIdLang = $contextIdLang; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('c.`id_cms`, cl.`link_rewrite`, c.`active`, c.`position`, cl.`meta_title`, cl.`head_seo_title`') - ->addSelect('c.`id_cms_category`') - ->groupBy('c.`id_cms`') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT c.`id_cms`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql for cms page listing. - * - * @param array $filters - * - * @return \Doctrine\DBAL\Query\QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $availableFilters = [ - 'id_cms_category_parent', - 'id_cms', - 'link_rewrite', - 'meta_title', - 'head_seo_title', - 'position', - 'active', - ]; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'cms', 'c') - ->leftJoin( - 'c', - $this->dbPrefix . 'cms_lang', - 'cl', - 'cl.`id_cms` = c.`id_cms`' - ) - ->innerJoin( - 'c', - $this->dbPrefix . 'cms_shop', - 'cs', - 'cs.`id_cms` = c.`id_cms`' - ) - ; - - $qb->andWhere('cl.`id_lang` = :contextLangId'); - $qb->andWhere('cl.`id_shop` IN (:contextShopIds)'); - $qb->andWhere('cs.`id_shop` IN (:contextShopIds)'); - - $qb->setParameter('contextLangId', $this->contextIdLang); - $qb->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - foreach ($filters as $filterName => $value) { - if (!in_array($filterName, $availableFilters, true)) { - continue; - } - - if ('id_cms_category_parent' === $filterName) { - $qb->andWhere('c.`id_cms_category` = :id_cms_category_parent'); - $qb->setParameter('id_cms_category_parent', $value); - - continue; - } - - if (in_array($filterName, ['id_cms', 'active'], true)) { - $qb->andWhere('c.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - if ('position' === $filterName) { - $modifiedPositionFilter = $this->getModifiedPositionFilter($value); - $qb->andWhere('c.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $modifiedPositionFilter); - continue; - } - - $qb->andWhere('cl.`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $value . '%'); - } - - return $qb; - } - - /** - * Gets modified position filter value. This is required due to in database position filter index starts from 0 and - * for the customer which wants to filter results the value starts from 1 instead. - * - * @param $positionFilterValue - * - * @return int|null - if null is returned then no results are found since position field does not hold null values - */ - private function getModifiedPositionFilter($positionFilterValue) - { - if (!is_numeric($positionFilterValue)) { - return null; - } - $reducedByOneFilterValue = $positionFilterValue - 1; - if (0 > $reducedByOneFilterValue) { - return null; - } - - return $reducedByOneFilterValue; - } -} diff --git a/src/Core/Grid/Query/ContactQueryBuilder.php b/src/Core/Grid/Query/ContactQueryBuilder.php deleted file mode 100644 index 7776eaca..00000000 --- a/src/Core/Grid/Query/ContactQueryBuilder.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class ContactsQueryBuilder is responsible for building queries for Contacts grid data. - */ -final class ContactQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $languageId; - - /** - * @var array - */ - private $contextShopsIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $languageId - * @param array $contextShopsIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $languageId, - array $contextShopsIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->languageId = $languageId; - $this->contextShopsIds = $contextShopsIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb - ->select('c.id_contact, c.email, cl.name, cl.description') - ->groupBy('c.id_contact'); - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT c.id_contact)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $allowedFilters = [ - 'id_contact', - 'name', - 'email', - 'description', - ]; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'contact', 'c') - ->innerJoin('c', $this->dbPrefix . 'contact_lang', 'cl', 'c.id_contact = cl.id_contact') - ->innerJoin('c', $this->dbPrefix . 'contact_shop', 'cs', 'c.id_contact = cs.id_contact') - ->andWhere('cl.`id_lang`= :language') - ->andWhere('cs.`id_shop` IN (:shops)') - ->setParameter('language', $this->languageId) - ->setParameter('shops', $this->contextShopsIds, Connection::PARAM_INT_ARRAY); - - foreach ($filters as $name => $value) { - if (!in_array($name, $allowedFilters, true)) { - continue; - } - - if ('id_contact' === $name) { - $qb->andWhere('c.`id_contact` = :' . $name); - $qb->setParameter($name, $value); - - continue; - } - - $qb->andWhere("$name LIKE :$name"); - $qb->setParameter($name, '%' . $value . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/CreditSlipQueryBuilder.php b/src/Core/Grid/Query/CreditSlipQueryBuilder.php deleted file mode 100644 index 00e6ecdd..00000000 --- a/src/Core/Grid/Query/CreditSlipQueryBuilder.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class responsible for providing sql for credit slip list - */ -final class CreditSlipQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('slip.id_order_slip, slip.id_order, slip.date_add') - ->groupBy('slip.id_order_slip') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT slip.`id_order_slip`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql for credit slip listing. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'order_slip', 'slip') - ->leftJoin( - 'slip', - $this->dbPrefix . 'orders', - 'orders', - 'slip.id_order = orders.id_order' - ) - ; - $qb->andWhere('orders.id_shop IN (:contextShopIds)'); - $qb->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - $this->applyFilters($qb, $filters); - - return $qb; - } - - /** - * @param QueryBuilder $qb - * @param array $filters - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $availableFiltersMap = [ - 'id_credit_slip' => 'slip.id_order_slip', - 'id_order' => 'slip.id_order', - 'date_issued' => 'slip.date_add', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $availableFiltersMap)) { - continue; - } - - if ('id_credit_slip' === $filterName || 'id_order' === $filterName) { - $qb->andWhere($availableFiltersMap[$filterName] . "= :$filterName"); - $qb->setParameter($filterName, $value); - - continue; - } - - if ('date_issued' === $filterName) { - if (isset($value['from'])) { - $qb->andWhere($availableFiltersMap[$filterName] . ' >= :date_from'); - $qb->setParameter('date_from', sprintf('%s 0:0:0', $value['from'])); - } - if (isset($value['to'])) { - $qb->andWhere($availableFiltersMap[$filterName] . ' <= :date_to'); - $qb->setParameter('date_to', sprintf('%s 23:59:59', $value['to'])); - } - continue; - } - } - } -} diff --git a/src/Core/Grid/Query/CurrencyQueryBuilder.php b/src/Core/Grid/Query/CurrencyQueryBuilder.php deleted file mode 100644 index d867866c..00000000 --- a/src/Core/Grid/Query/CurrencyQueryBuilder.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PDO; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class CurrencyQueryBuilder builds search & count queries for currencies grid. - */ -final class CurrencyQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var int - */ - private $contextLangId; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds, - $contextLangId - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('c.`id_currency`, c.`iso_code`, cs.`conversion_rate`, c.`active`, c.`modified`, c.`unofficial`, cl.`name`, cl.`symbol`') - ->groupBy('c.`id_currency`') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT c.`id_currency`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying webservice list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $allowedFilters = [ - 'iso_code', - 'active', - ]; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'currency', 'c') - ->innerJoin( - 'c', - $this->dbPrefix . 'currency_shop', - 'cs', - 'c.`id_currency` = cs.`id_currency`' - ) - ->innerJoin( - 'c', - $this->dbPrefix . 'currency_lang', - 'cl', - 'c.`id_currency` = cl.`id_currency`' - ) - ; - $qb->andWhere('cs.`id_shop` IN (:shops)'); - $qb->andWhere('cl.`id_lang` = :lang'); - $qb->andWhere('c.`deleted` = 0'); - - $qb->setParameter('shops', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - $qb->setParameter('lang', $this->contextLangId, PDO::PARAM_INT); - - foreach ($filters as $filterName => $value) { - if (!in_array($filterName, $allowedFilters, true)) { - continue; - } - - if ('active' === $filterName) { - $qb->andWhere('c.`active` = :active'); - $qb->setParameter('active', $value); - - continue; - } - - $qb->andWhere('c.`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $value . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/CustomerQueryBuilder.php b/src/Core/Grid/Query/CustomerQueryBuilder.php deleted file mode 100644 index 1a25dad8..00000000 --- a/src/Core/Grid/Query/CustomerQueryBuilder.php +++ /dev/null @@ -1,270 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class CustomerQueryBuilder builds queries to fetch data for customers grid. - */ -final class CustomerQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $criteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator - * @param int $contextLangId - * @param int[] $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator, - $contextLangId, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->contextLangId = $contextLangId; - $this->contextShopIds = $contextShopIds; - $this->criteriaApplicator = $criteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $searchQueryBuilder = $this->getCustomerQueryBuilder($searchCriteria) - ->select('c.id_customer, c.firstname, c.lastname, c.email, c.active, c.newsletter, c.optin') - ->addSelect('c.date_add, gl.name as social_title, s.name as shop_name, c.company'); - - $this->appendTotalSpentQuery($searchQueryBuilder); - $this->appendLastVisitQuery($searchQueryBuilder); - $this->applySorting($searchQueryBuilder, $searchCriteria); - - $this->criteriaApplicator->applyPagination( - $searchCriteria, - $searchQueryBuilder - ); - - return $searchQueryBuilder; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $countQueryBuilder = $this->getCustomerQueryBuilder($searchCriteria) - ->select('COUNT(*)'); - - return $countQueryBuilder; - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getCustomerQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $queryBuilder = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'customer', 'c') - ->leftJoin( - 'c', - $this->dbPrefix . 'gender_lang', - 'gl', - 'c.id_gender = gl.id_gender AND gl.id_lang = :context_lang_id' - ) - ->leftJoin( - 'c', - $this->dbPrefix . 'shop', - 's', - 'c.id_shop = s.id_shop' - ) - ->where('c.deleted = 0') - ->andWhere('c.id_shop IN (:context_shop_ids)') - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ->setParameter('context_lang_id', $this->contextLangId); - - $this->applyFilters($searchCriteria->getFilters(), $queryBuilder); - - return $queryBuilder; - } - - /** - * @param QueryBuilder $queryBuilder - */ - private function appendTotalSpentQuery(QueryBuilder $queryBuilder) - { - $totalSpentQueryBuilder = $this->connection->createQueryBuilder() - ->select('SUM(total_paid_real / conversion_rate)') - ->from($this->dbPrefix . 'orders', 'o') - ->where('o.id_customer = c.id_customer') - ->andWhere('o.id_shop IN (:context_shop_ids)') - ->andWhere('o.valid = 1') - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - $queryBuilder->addSelect('(' . $totalSpentQueryBuilder->getSQL() . ') as total_spent'); - } - - /** - * Append "last visit" column to customers query builder. - * - * @param QueryBuilder $queryBuilder - */ - private function appendLastVisitQuery(QueryBuilder $queryBuilder) - { - $lastVisitQueryBuilder = $this->connection->createQueryBuilder() - ->select('con.date_add') - ->from($this->dbPrefix . 'guest', 'g') - ->leftJoin('g', $this->dbPrefix . 'connections', 'con', 'con.id_guest = g.id_guest') - ->where('g.id_customer = c.id_customer') - ->orderBy('con.date_add', 'DESC') - ->setMaxResults(1); - - $queryBuilder->addSelect('(' . $lastVisitQueryBuilder->getSQL() . ') as connect'); - } - - /** - * Apply filters to customers query builder. - * - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(array $filters, QueryBuilder $qb) - { - $allowedFilters = [ - 'id_customer', - 'social_title', - 'firstname', - 'lastname', - 'email', - 'active', - 'newsletter', - 'optin', - 'date_add', - 'company', - ]; - - foreach ($filters as $filterName => $filterValue) { - if (!in_array($filterName, $allowedFilters)) { - continue; - } - - if (in_array($filterName, ['active', 'newsletter', 'optin', 'id_customer'])) { - $qb->andWhere('c.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if ('social_title' === $filterName) { - $qb->andWhere('gl.id_gender = :' . $filterName); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if ('date_add' === $filterName) { - $qb->andWhere('c.date_add >= :date_from AND c.date_add <= :date_to'); - $qb->setParameter('date_from', sprintf('%s 0:0:0', $filterValue['from'])); - $qb->setParameter('date_to', sprintf('%s 23:59:59', $filterValue['to'])); - - if (isset($filterValue['from'])) { - $qb->andWhere('c.date_add >= :date_from'); - $qb->setParameter('date_from', sprintf('%s 0:0:0', $filterValue['from'])); - } - - if (isset($filterValue['to'])) { - $qb->andWhere('c.date_add <= :date_to'); - $qb->setParameter('date_to', sprintf('%s 23:59:59', $filterValue['to'])); - } - - continue; - } - - $qb->andWhere('`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - } - } - - /** - * Apply sorting so search query builder for customers. - * - * @param QueryBuilder $searchQueryBuilder - * @param SearchCriteriaInterface $searchCriteria - */ - private function applySorting(QueryBuilder $searchQueryBuilder, SearchCriteriaInterface $searchCriteria) - { - switch ($searchCriteria->getOrderBy()) { - case 'id_customer': - case 'firstname': - case 'lastname': - case 'email': - case 'date_add': - case 'company': - case 'active': - case 'newsletter': - case 'optin': - $orderBy = 'c.' . $searchCriteria->getOrderBy(); - - break; - case 'social_title': - $orderBy = 'gl.name'; - - break; - case 'connect': - case 'total_spent': - $orderBy = $searchCriteria->getOrderBy(); - - break; - default: - return; - } - - $searchQueryBuilder->orderBy($orderBy, $searchCriteria->getOrderWay()); - } -} diff --git a/src/Core/Grid/Query/DoctrineQueryBuilderInterface.php b/src/Core/Grid/Query/DoctrineQueryBuilderInterface.php deleted file mode 100644 index 7c359118..00000000 --- a/src/Core/Grid/Query/DoctrineQueryBuilderInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class DoctrineQueryBuilderInterface defines contract to retrieve Doctrine query builders needed to get grid data. - */ -interface DoctrineQueryBuilderInterface -{ - /** - * Get query that searches grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria); - - /** - * Get query that counts grid rows. - * - * @param SearchCriteriaInterface|null $searchCriteria - * - * @return QueryBuilder - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria); -} diff --git a/src/Core/Grid/Query/DoctrineQueryParser.php b/src/Core/Grid/Query/DoctrineQueryParser.php deleted file mode 100644 index 0e0fd4eb..00000000 --- a/src/Core/Grid/Query/DoctrineQueryParser.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use PrestaShop\PrestaShop\Core\Grid\Exception\UnsupportedParameterException; - -/** - * This class offers a DBAL implementation of Query parser. - */ -final class DoctrineQueryParser implements QueryParserInterface -{ - /** - * {@inheritdoc} - */ - public function parse($query, array $queryParameters) - { - $values = []; - foreach ($queryParameters as $key => $value) { - if (!is_string($key)) { - throw new UnsupportedParameterException('Only named parameters are supported in prepared queries.'); - } - $values[':' . $key] = $this->parseValue($value); - } - - return strtr($query, $values); - } - - /** - * @param mixed $value the parameter value - * - * @return string the partial raw parameter - * - * @throws UnsupportedParameterException - */ - private function parseValue($value) - { - if (is_string($value)) { - return $this->parseStringParameter($value); - } - - if (is_numeric($value)) { - return $this->parseNumericParameter($value); - } - - if (is_array($value)) { - return $this->parseArrayParameter($value); - } - - if (is_bool($value)) { - return $this->parseBooleanParameter($value); - } - - if ($value === null) { - return 'NULL'; - } - - throw new UnsupportedParameterException('Unsupported value type: ' . gettype($value)); - } - - /** - * @param string $value - * - * @return string - */ - private function parseStringParameter($value) - { - return "'" . addslashes($value) . "'"; - } - - /** - * @param int|float $value - * - * @return int|float - */ - private function parseNumericParameter($value) - { - return $value; - } - - /** - * @param array $value - * - * @return string - */ - private function parseArrayParameter(array $value) - { - return "'" . implode("', '", array_map('addslashes', $value)) . "'"; - } - - /** - * @param bool $value - * - * @return string - */ - private function parseBooleanParameter($value) - { - return $value ? 'TRUE' : 'FALSE'; - } -} diff --git a/src/Core/Grid/Query/DoctrineSearchCriteriaApplicator.php b/src/Core/Grid/Query/DoctrineSearchCriteriaApplicator.php deleted file mode 100644 index 21cfad70..00000000 --- a/src/Core/Grid/Query/DoctrineSearchCriteriaApplicator.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class DoctrineSearchCriteriaApplicator applies search criteria to doctrine query builder. - */ -final class DoctrineSearchCriteriaApplicator implements DoctrineSearchCriteriaApplicatorInterface -{ - /** - * {@inheritdoc} - */ - public function applyPagination(SearchCriteriaInterface $searchCriteria, QueryBuilder $queryBuilder) - { - if (null !== $searchCriteria->getLimit()) { - $queryBuilder->setMaxResults($searchCriteria->getLimit()); - } - - if (null !== $searchCriteria->getOffset()) { - $queryBuilder->setFirstResult($searchCriteria->getOffset()); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function applySorting(SearchCriteriaInterface $searchCriteria, QueryBuilder $queryBuilder) - { - if (null !== $searchCriteria->getOrderBy() && null !== $searchCriteria->getOrderWay()) { - $queryBuilder->orderBy( - $searchCriteria->getOrderBy(), - $searchCriteria->getOrderWay() - ); - } - - return $this; - } -} diff --git a/src/Core/Grid/Query/DoctrineSearchCriteriaApplicatorInterface.php b/src/Core/Grid/Query/DoctrineSearchCriteriaApplicatorInterface.php deleted file mode 100644 index f987d39a..00000000 --- a/src/Core/Grid/Query/DoctrineSearchCriteriaApplicatorInterface.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Interface DoctrineSearchCriteriaApplicatorInterface contract for doctrine query builder applicator. - */ -interface DoctrineSearchCriteriaApplicatorInterface -{ - /** - * Apply pagination on query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * @param QueryBuilder $queryBuilder - * - * @return self - */ - public function applyPagination(SearchCriteriaInterface $searchCriteria, QueryBuilder $queryBuilder); - - /** - * Apply sorting on query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * @param QueryBuilder $queryBuilder - * - * @return self - */ - public function applySorting(SearchCriteriaInterface $searchCriteria, QueryBuilder $queryBuilder); -} diff --git a/src/Core/Grid/Query/EmailLogsQueryBuilder.php b/src/Core/Grid/Query/EmailLogsQueryBuilder.php deleted file mode 100644 index a170c909..00000000 --- a/src/Core/Grid/Query/EmailLogsQueryBuilder.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class EmailLogsQueryBuilder is responsible for building queries for email logs grid data. - */ -final class EmailLogsQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('m.*, l.name AS language'); - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(m.id_mail)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'mail', 'm') - ->leftJoin('m', $this->dbPrefix . 'lang', 'l', 'm.id_lang = l.id_lang'); - - foreach ($filters as $name => $value) { - if ('id_lang' === $name) { - $qb->andWhere("l.id_lang = :$name"); - $qb->setParameter($name, $value); - - continue; - } - - if ('date_add' === $name) { - if (isset($value['from'])) { - $qb->andWhere('m.date_add >= :date_from'); - $qb->setParameter('date_from', sprintf('%s %s', $value['from'], '0:0:0')); - } - - if (isset($value['to'])) { - $qb->andWhere('m.date_add <= :date_to'); - $qb->setParameter('date_to', sprintf('%s %s', $value['to'], '23:59:59')); - } - - continue; - } - - $qb->andWhere("$name LIKE :$name"); - $qb->setParameter($name, '%' . $value . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/EmployeeQueryBuilder.php b/src/Core/Grid/Query/EmployeeQueryBuilder.php deleted file mode 100644 index 99afd1fe..00000000 --- a/src/Core/Grid/Query/EmployeeQueryBuilder.php +++ /dev/null @@ -1,192 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class EmployeeQueryBuilder builds queries for Employees grid. - */ -final class EmployeeQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var string - */ - private $contextIdLang; - - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param string $contextIdLang - * @param int[] $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextIdLang, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextIdLang = $contextIdLang; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $searchQueryBuilder = $this->getEmployeeQueryBuilder($searchCriteria) - ->select('e.*, pl.name as profile_name'); - - $this->searchCriteriaApplicator->applyPagination($searchCriteria, $searchQueryBuilder); - $this->applySorting($searchCriteria, $searchQueryBuilder); - - return $searchQueryBuilder; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $countQueryBuilder = $this->getEmployeeQueryBuilder($searchCriteria) - ->select('COUNT(e.id_profile)'); - - return $countQueryBuilder; - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getEmployeeQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $sub = $this->connection->createQueryBuilder() - ->select(1) - ->from($this->dbPrefix . 'employee_shop', 'es') - ->where('e.id_employee = es.id_employee') - ->andWhere('es.id_shop IN (:context_shop_ids)'); - - $qb = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'employee', 'e') - ->leftJoin( - 'e', - $this->dbPrefix . 'profile_lang', - 'pl', - 'e.id_profile = pl.id_profile AND pl.id_lang = ' . (int) $this->contextIdLang - ) - ->andWhere('EXISTS (' . $sub->getSQL() . ')') - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - $this->applyFilters($qb, $searchCriteria->getFilters()); - - return $qb; - } - - /** - * Apply filters for Query builder. - * - * @param QueryBuilder $queryBuilder - * @param array $filters - */ - private function applyFilters(QueryBuilder $queryBuilder, array $filters) - { - $allowedFilters = [ - 'id_employee', - 'firstname', - 'lastname', - 'email', - 'profile', - 'active', - ]; - - foreach ($filters as $filterName => $filterValue) { - if (!in_array($filterName, $allowedFilters)) { - continue; - } - - if ('id_employee' === $filterName) { - $queryBuilder->andWhere('e.id_employee = :' . $filterName); - $queryBuilder->setParameter($filterName, $filterValue); - - continue; - } - - if ('profile' === $filterName) { - $queryBuilder->andWhere('pl.id_profile = :id_profile'); - $queryBuilder->setParameter('id_profile', $filterValue); - - continue; - } - - if ('active' === $filterName) { - $queryBuilder->andWhere('e.active = :active'); - $queryBuilder->setParameter('active', $filterValue); - - continue; - } - - $queryBuilder->andWhere("`$filterName` LIKE :$filterName"); - $queryBuilder->setParameter($filterName, '%' . $filterValue . '%'); - } - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * @param QueryBuilder $queryBuilder - */ - private function applySorting(SearchCriteriaInterface $searchCriteria, QueryBuilder $queryBuilder) - { - if ($searchCriteria->getOrderBy() && $searchCriteria->getOrderWay()) { - $orderBy = $searchCriteria->getOrderBy(); - - if ('profile' === $orderBy) { - $orderBy = 'pl.name'; - } - - $queryBuilder->orderBy($orderBy, $searchCriteria->getOrderWay()); - } - } -} diff --git a/src/Core/Grid/Query/Filter/DoctrineFilterApplicator.php b/src/Core/Grid/Query/Filter/DoctrineFilterApplicator.php deleted file mode 100644 index 8cbd5daa..00000000 --- a/src/Core/Grid/Query/Filter/DoctrineFilterApplicator.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Filter; - -use Doctrine\DBAL\Query\QueryBuilder; - -final class DoctrineFilterApplicator implements DoctrineFilterApplicatorInterface -{ - /** - * {@inheritdoc} - */ - public function apply(QueryBuilder $qb, SqlFilters $filters, array $filterValues) - { - if (empty($filterValues)) { - return; - } - - foreach ($filters->getFilters() as $filter) { - $sqlField = $filter['sql_field']; - $filterName = $filter['filter_name']; - - if (!isset($filterValues[$filterName])) { - continue; - } - - $value = $filterValues[$filterName]; - - switch ($filter['comparison']) { - case SqlFilters::WHERE_STRICT: - $qb->andWhere("$sqlField = :$filterName"); - $qb->setParameter($filterName, $value); - - break; - case SqlFilters::WHERE_LIKE: - $qb->andWhere("$sqlField LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $value . '%'); - - break; - case SqlFilters::HAVING_LIKE: - $qb->andHaving("$sqlField LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $value . '%'); - - break; - case SqlFilters::WHERE_DATE: - if (isset($value['from'])) { - $name = sprintf('%s_from', $filterName); - - $qb->andWhere("$sqlField >= :$name"); - $qb->setParameter($name, sprintf('%s %s', $value['from'], '0:0:0')); - } - - if (isset($value['to'])) { - $name = sprintf('%s_to', $filterName); - - $qb->andWhere("$sqlField <= :$name"); - $qb->setParameter($name, sprintf('%s %s', $value['to'], '23:59:59')); - } - - break; - } - } - } -} diff --git a/src/Core/Grid/Query/Filter/DoctrineFilterApplicatorInterface.php b/src/Core/Grid/Query/Filter/DoctrineFilterApplicatorInterface.php deleted file mode 100644 index 65866a46..00000000 --- a/src/Core/Grid/Query/Filter/DoctrineFilterApplicatorInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Filter; - -use Doctrine\DBAL\Query\QueryBuilder; - -/** - * Interface for service that applies filters for Doctrine query builder - */ -interface DoctrineFilterApplicatorInterface -{ - /** - * @param QueryBuilder $qb - * @param SqlFilters $filters - * @param array $filterValues - */ - public function apply(QueryBuilder $qb, SqlFilters $filters, array $filterValues); -} diff --git a/src/Core/Grid/Query/Filter/SqlFilters.php b/src/Core/Grid/Query/Filter/SqlFilters.php deleted file mode 100644 index 01c5c6d6..00000000 --- a/src/Core/Grid/Query/Filter/SqlFilters.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Filter; - -/** - * Stores filters to be applied on SQL query - */ -final class SqlFilters -{ - const WHERE_STRICT = 1; - const WHERE_LIKE = 2; - const HAVING_LIKE = 3; - const WHERE_DATE = 4; - - /** @var array */ - private $filters = []; - - /** - * @param string $filterName - * @param string $sqlField - * @param int $comparison - * - * @return self - */ - public function addFilter($filterName, $sqlField, $comparison = self::WHERE_STRICT) - { - $this->filters[] = [ - 'filter_name' => $filterName, - 'sql_field' => $sqlField, - 'comparison' => $comparison, - ]; - - return $this; - } - - /** - * @return array - */ - public function getFilters() - { - return $this->filters; - } -} diff --git a/src/Core/Grid/Query/LanguageQueryBuilder.php b/src/Core/Grid/Query/LanguageQueryBuilder.php deleted file mode 100644 index bc45b2d1..00000000 --- a/src/Core/Grid/Query/LanguageQueryBuilder.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class LanguageQueryBuilder provides query builders for languages grid. - */ -final class LanguageQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $builder = $this->getLanguageQueryBuilder($searchCriteria) - ->select('l.*'); - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $builder) - ->applyPagination($searchCriteria, $builder); - - return $builder; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - return $this->getLanguageQueryBuilder($searchCriteria)->select('COUNT(id_lang)'); - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getLanguageQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $builder = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'lang', 'l'); - - $this->applyFilters($builder, $searchCriteria); - - return $builder; - } - - /** - * @param QueryBuilder $builder - * @param SearchCriteriaInterface $searchCriteria - */ - private function applyFilters(QueryBuilder $builder, SearchCriteriaInterface $searchCriteria) - { - $allowedFilters = [ - 'id_lang', - 'name', - 'iso_code', - 'language_code', - 'date_format_lite', - 'date_format_full', - 'active', - ]; - - foreach ($searchCriteria->getFilters() as $filterName => $filterValue) { - if (!in_array($filterName, $allowedFilters)) { - continue; - } - - if (in_array($filterName, ['id_lang', 'active'])) { - $builder->andWhere($filterName . ' = :' . $filterName); - $builder->setParameter($filterName, $filterValue); - - continue; - } - - $builder->andWhere($filterName . ' LIKE :' . $filterName); - $builder->setParameter($filterName, '%' . $filterValue . '%'); - } - } -} diff --git a/src/Core/Grid/Query/ManufacturerAddressQueryBuilder.php b/src/Core/Grid/Query/ManufacturerAddressQueryBuilder.php deleted file mode 100644 index 3ad95568..00000000 --- a/src/Core/Grid/Query/ManufacturerAddressQueryBuilder.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class ManufacturerAddressQueryBuilder is responsible for building queries for manufacturers addresses grid data. - */ -final class ManufacturerAddressQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $contextLangId; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLangId - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextLangId - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilderByFilters($searchCriteria->getFilters()); - $qb->select('a.id_address, m.name, a.firstname, a.lastname, a.postcode, a.city, cl.name as country'); - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilderByFilters($searchCriteria->getFilters()); - $qb->select('COUNT(DISTINCT a.`id_address`)'); - - return $qb; - } - - /** - * Gets query builder with common sql needed for manufacturer addresses grid. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilderByFilters(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'address', 'a') - ->leftJoin( - 'a', - $this->dbPrefix . 'country_lang', - 'cl', - 'cl.id_country = a.id_country AND cl.id_lang = :lang' - ) - ->setParameter('lang', $this->contextLangId) - ->leftJoin( - 'a', - $this->dbPrefix . 'manufacturer', - 'm', 'm.id_manufacturer = a.id_manufacturer' - ) - ->andWhere('a.id_customer = 0') - ->andWhere('a.id_supplier = 0') - ->andWhere('a.id_warehouse = 0') - ->andWhere('a.deleted = 0') - ; - $this->applyFilters($qb, $filters); - - return $qb; - } - - /** - * @param QueryBuilder $qb - * @param array $filters - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFiltersMap = [ - 'id_address' => 'a.id_address', - 'name' => 'm.name', - 'firstname' => 'a.firstname', - 'lastname' => 'a.lastname', - 'postcode' => 'a.postcode', - 'city' => 'a.city', - 'country' => 'a.id_country', - ]; - $exactMatchingFilters = ['id_address', 'country']; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if (in_array($filterName, $exactMatchingFilters, true)) { - if (empty($value)) { - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . " = :$filterName") - ->setParameter($filterName, $value); - - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . " LIKE :$filterName") - ->setParameter($filterName, '%' . $value . '%'); - } - } -} diff --git a/src/Core/Grid/Query/ManufacturerQueryBuilder.php b/src/Core/Grid/Query/ManufacturerQueryBuilder.php deleted file mode 100644 index a08bf9b8..00000000 --- a/src/Core/Grid/Query/ManufacturerQueryBuilder.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class ManufacturerQueryBuilder is responsible for building queries for manufacturers grid data. - */ -final class ManufacturerQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - /** - * @var int[] - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->contextShopIds = $contextShopIds; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $addressesQb = $this->connection->createQueryBuilder(); - $addressesQb->select('COUNT(a.`id_manufacturer`) AS `addresses_count`') - ->from($this->dbPrefix . 'address', 'a') - ->where('m.`id_manufacturer` = a.`id_manufacturer`') - ->andWhere('a.`deleted` = 0') - ->groupBy('a.`id_manufacturer`') - ; - - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb - ->select('m.`id_manufacturer`, m.`name`, m.`active`') - ->addSelect('COUNT(p.`id_product`) AS `products_count`') - ->addSelect('(' . $addressesQb->getSQL() . ') AS addresses_count') - ->groupBy('m.`id_manufacturer`') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(DISTINCT m.`id_manufacturer`)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $allowedFilters = ['id_manufacturer', 'name', 'active']; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'manufacturer', 'm') - ->innerJoin( - 'm', - $this->dbPrefix . 'manufacturer_shop', - 'ms', - 'ms.`id_manufacturer` = m.`id_manufacturer`' - ) - ->leftJoin( - 'm', - $this->dbPrefix . 'product', - 'p', - 'm.`id_manufacturer` = p.`id_manufacturer`' - ) - ; - - foreach ($filters as $filterName => $value) { - if (!in_array($filterName, $allowedFilters, true)) { - continue; - } - - if ('name' === $filterName) { - $qb->andWhere('m.`name` LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - continue; - } - $qb->andWhere('m.`' . $filterName . '` = :' . $filterName) - ->setParameter($filterName, $value); - } - - $qb->andWhere('ms.`id_shop` IN (:contextShopIds)'); - - $qb->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/MerchandiseReturnQueryBuilder.php b/src/Core/Grid/Query/MerchandiseReturnQueryBuilder.php deleted file mode 100644 index b4b13d96..00000000 --- a/src/Core/Grid/Query/MerchandiseReturnQueryBuilder.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class MerchandiseReturnQueryBuilder builds queries for merchandise returns grid data. - */ -final class MerchandiseReturnQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLanguageId - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - int $contextLanguageId, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextLanguageId = $contextLanguageId; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getMerchandiseReturnQueryBuilder($searchCriteria); - $qb - ->select('r.id_order_return, r.id_order, r.date_add, orsl.name status, ors.color') - ->groupBy('r.id_order_return'); - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - return $this->getMerchandiseReturnQueryBuilder($searchCriteria) - ->select('COUNT(r.id_order_return)'); - } - - /** - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getMerchandiseReturnQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $queryBuilder = $this->connection->createQueryBuilder() - ->from($this->dbPrefix . 'order_return', 'r') - ->leftJoin( - 'r', - $this->dbPrefix . 'order_return_state', - 'ors', - 'r.state = ors.id_order_return_state' - ) - ->leftJoin( - 'r', - $this->dbPrefix . 'order_return_state_lang', - 'orsl', - 'orsl.id_order_return_state = r.state AND orsl.id_lang = :context_language_id' - ) - ->setParameter('context_language_id', $this->contextLanguageId) - ->leftJoin( - 'r', - $this->dbPrefix . 'orders', - 'o', - 'o.id_order = r.id_order' - ) - ->andWhere('o.id_shop IN (:context_shop_ids)') - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - $this->applyFilters($searchCriteria->getFilters(), $queryBuilder); - - return $queryBuilder; - } - - /** - * Apply filters to merchandise returns query builder. - * - * @param array $filters - * @param QueryBuilder $qb - */ - private function applyFilters(array $filters, QueryBuilder $qb) - { - $allowedFilters = [ - 'id_order_return', - 'id_order', - 'status', - 'date_add', - ]; - - foreach ($filters as $filterName => $filterValue) { - if (!in_array($filterName, $allowedFilters)) { - continue; - } - - if ('id_order' === $filterName) { - $qb->andWhere('o.`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('status' === $filterName) { - $qb->andWhere('orsl.`name` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('date_add' === $filterName) { - if (isset($filterValue['from'])) { - $qb->andWhere('r.date_add >= :date_from'); - $qb->setParameter('date_from', sprintf('%s 0:0:0', $filterValue['from'])); - } - - if (isset($filterValue['to'])) { - $qb->andWhere('r.date_add <= :date_to'); - $qb->setParameter('date_to', sprintf('%s 23:59:59', $filterValue['to'])); - } - - continue; - } - - $qb->andWhere('`' . $filterName . '` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - } - } -} diff --git a/src/Core/Grid/Query/MetaQueryBuilder.php b/src/Core/Grid/Query/MetaQueryBuilder.php deleted file mode 100644 index 4d1424a2..00000000 --- a/src/Core/Grid/Query/MetaQueryBuilder.php +++ /dev/null @@ -1,160 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class MetaQueryBuilder is responsible for providing data for seo & urls list. - */ -final class MetaQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextIdLang; - - /** - * @var int - */ - private $contextIdShop; - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * MetaQueryBuilder constructor. - * - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextIdLang - * @param int $contextIdShop - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextIdLang, - $contextIdShop - ) { - parent::__construct($connection, $dbPrefix); - $this->contextIdLang = $contextIdLang; - $this->contextIdShop = $contextIdShop; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('m.`id_meta`, m.`page`, l.`title`, l.`url_rewrite`'); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(m.`id_meta`)'); - - return $qb; - } - - /** - * Gets query builder with common sql for meta table. - * - * @param array $filters - * - * @return \Doctrine\DBAL\Query\QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $availableFilters = [ - 'id_meta', - 'page', - 'title', - 'url_rewrite', - ]; - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'meta', 'm') - ->innerJoin( - 'm', - $this->dbPrefix . 'meta_lang', - 'l', - 'm.`id_meta` = l.`id_meta`' - ); - - $qb->andWhere('l.`id_lang` = :id_lang'); - $qb->andWhere('l.`id_shop` = :id_shop'); - - $qb->setParameters([ - 'id_lang' => $this->contextIdLang, - 'id_shop' => $this->contextIdShop, - ]); - - $qb->andWhere('m.`configurable`=1'); - - foreach ($filters as $name => $value) { - if (!in_array($name, $availableFilters, true)) { - continue; - } - - if ('id_meta' === $name) { - $qb->andWhere('m.`id_meta` = :' . $name); - $qb->setParameter($name, $value); - - continue; - } - - if ('page' === $name) { - $qb->andWhere('m.`page` LIKE :' . $name); - $qb->setParameter($name, '%' . $value . '%'); - - continue; - } - - $qb->andWhere('l.`' . $name . '` LIKE :' . $name); - $qb->setParameter($name, '%' . $value . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/AbstractProductQueryBuilder.php b/src/Core/Grid/Query/Monitoring/AbstractProductQueryBuilder.php deleted file mode 100644 index a536c664..00000000 --- a/src/Core/Grid/Query/Monitoring/AbstractProductQueryBuilder.php +++ /dev/null @@ -1,179 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\AbstractDoctrineQueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\DoctrineSearchCriteriaApplicator; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Provides reusable queries for lists of monitoring products - */ -abstract class AbstractProductQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var Connection - */ - protected $connection; - - /** - * @var string - */ - protected $dbPrefix; - - /** - * @var int - */ - protected $contextLangId; - - /** - * @var int - */ - protected $contextShopId; - - /** - * @var DoctrineSearchCriteriaApplicator - */ - protected $searchCriteriaApplicator; - - /** - * @var MultistoreContextCheckerInterface - */ - protected $multistoreContextChecker; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicator $searchCriteriaApplicator - * @param int $contextLangId - * @param int $contextShopId - * @param MultistoreContextCheckerInterface $multistoreContextChecker - */ - public function __construct( - Connection $connection, - $dbPrefix, - $contextLangId, - $contextShopId, - DoctrineSearchCriteriaApplicator $searchCriteriaApplicator, - MultistoreContextCheckerInterface $multistoreContextChecker - ) { - parent::__construct($connection, $dbPrefix); - $this->contextLangId = $contextLangId; - $this->contextShopId = $contextShopId; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->multistoreContextChecker = $multistoreContextChecker; - } - - /** - * Provides commonly reusable query for monitoring products lists - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - protected function getProductsCommonQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $isSingleShopContext = $this->multistoreContextChecker->isSingleShopContext(); - - $qb = $this->connection - ->createQueryBuilder() - ->select(['p.id_product', 'p.reference', 'p.active', 'pl.name']) - ->from($this->dbPrefix . 'product', 'p') - ->setParameter('context_lang_id', $this->contextLangId) - ->setParameter('context_shop_id', $this->contextShopId); - - $qb->leftJoin( - 'p', - $this->dbPrefix . 'product_lang', - 'pl', - $isSingleShopContext ? - 'p.id_product = pl.id_product AND pl.id_lang = :context_lang_id AND pl.id_shop = :context_shop_id' : - 'p.id_product = pl.id_product AND pl.id_lang = :context_lang_id AND pl.id_shop = p.id_shop_default' - ); - - $qb->leftJoin( - 'p', - $this->dbPrefix . 'product_shop', - 'ps', - $isSingleShopContext ? - 'p.id_product = ps.id_product AND ps.id_shop = :context_shop_id' : - 'p.id_product = ps.id_product AND ps.id_shop = p.id_shop_default' - ); - - if ($isSingleShopContext) { - $qb->andWhere('ps.id_shop = :context_shop_id'); - } - - $this->applyFilters($qb, $searchCriteria->getFilters()); - - return $qb; - } - - /** - * @param QueryBuilder $qb - * @param array $filters - */ - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFilters = ['id_product', 'reference', 'name', 'active']; - - foreach ($filters as $filterName => $filterValue) { - if (!in_array($filterName, $allowedFilters, true)) { - continue; - } - - if ('id_product' === $filterName) { - $qb->andWhere("p.id_product = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if ('reference' === $filterName) { - $qb->andWhere("p.reference LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('name' === $filterName) { - $qb->andWhere("pl.name LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if ('active' === $filterName) { - $qb->andWhere("p.active = :$filterName"); - $qb->setParameter($filterName, $filterValue); - } - } - } -} diff --git a/src/Core/Grid/Query/Monitoring/DisabledProductQueryBuilder.php b/src/Core/Grid/Query/Monitoring/DisabledProductQueryBuilder.php deleted file mode 100644 index c9167f41..00000000 --- a/src/Core/Grid/Query/Monitoring/DisabledProductQueryBuilder.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for disabled product list data - */ -final class DisabledProductQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - $qb->andWhere('ps.active = 0'); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $qb->andWhere('ps.id_shop = :context_shop_id') - ->setParameter('context_shop_id', $this->contextShopId); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/EmptyCategoryQueryBuilder.php b/src/Core/Grid/Query/Monitoring/EmptyCategoryQueryBuilder.php deleted file mode 100644 index 2140e066..00000000 --- a/src/Core/Grid/Query/Monitoring/EmptyCategoryQueryBuilder.php +++ /dev/null @@ -1,199 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\AbstractDoctrineQueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\DoctrineSearchCriteriaApplicator; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Builds queries for empty category list data - */ -final class EmptyCategoryQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var DoctrineSearchCriteriaApplicator - */ - private $searchCriteriaApplicator; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @var int - */ - private $rootCategoryId; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicator $searchCriteriaApplicator - * @param int $contextLangId - * @param int $contextShopId - * @param MultistoreContextCheckerInterface $multistoreContextChecker - * @param $rootCategoryId - */ - public function __construct( - Connection $connection, - $dbPrefix, - $contextLangId, - $contextShopId, - DoctrineSearchCriteriaApplicator $searchCriteriaApplicator, - MultistoreContextCheckerInterface $multistoreContextChecker, - $rootCategoryId - ) { - parent::__construct($connection, $dbPrefix); - $this->contextLangId = $contextLangId; - $this->contextShopId = $contextShopId; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->multistoreContextChecker = $multistoreContextChecker; - $this->rootCategoryId = $rootCategoryId; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('c.id_category, c.active, cl.name, cl.description'); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('COUNT(c.id_category)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $isSingleShopContext = $this->multistoreContextChecker->isSingleShopContext(); - - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'category', 'c') - ->setParameter('context_lang_id', $this->contextLangId) - ->setParameter('context_shop_id', $this->contextShopId) - ->setParameter('root_category_id', $this->rootCategoryId); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'category_lang', - 'cl', - $isSingleShopContext ? - 'c.id_category = cl.id_category AND cl.id_lang = :context_lang_id AND cl.id_shop = :context_shop_id' : - 'c.id_category = cl.id_category AND cl.id_lang = :context_lang_id AND cl.id_shop = c.id_shop_default' - ); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'category_shop', - 'cs', - $isSingleShopContext ? - 'c.id_category = cs.id_category AND cs.id_shop = :context_shop_id' : - 'c.id_category = cs.id_category AND cs.id_shop = c.id_shop_default' - ); - - $qb->leftJoin( - 'c', - $this->dbPrefix . 'category_product', - 'cp', - 'c.`id_category` = cp.id_category' - ); - - $subSelect = $this->connection->createQueryBuilder() - ->select('1') - ->from($this->dbPrefix . 'category_product', 'cp') - ->andWhere('c.id_category = cp.id_category') - ; - - $qb->andWhere('NOT EXISTS(' . $subSelect->getSQL() . ')'); - $qb->andWhere('c.id_category != :root_category_id'); - - if ($isSingleShopContext) { - $qb->andWhere('cs.id_shop = :context_shop_id'); - } - - $allowedFiltersAliasMap = [ - 'id_category' => 'c.id_category', - 'active' => 'c.active', - 'name' => 'cl.name', - 'description' => 'cl.description', - ]; - - foreach ($filters as $filterName => $filterValue) { - if (!array_key_exists($filterName, $allowedFiltersAliasMap)) { - continue; - } - - if ('active' === $filterName || 'id_category' === $filterName) { - $qb->andWhere($allowedFiltersAliasMap[$filterName] . " = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - $qb->andWhere($allowedFiltersAliasMap[$filterName] . " LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/NoQtyProductWithCombinationQueryBuilder.php b/src/Core/Grid/Query/Monitoring/NoQtyProductWithCombinationQueryBuilder.php deleted file mode 100644 index 67332ad2..00000000 --- a/src/Core/Grid/Query/Monitoring/NoQtyProductWithCombinationQueryBuilder.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for product with combination but without quantities list data - */ -final class NoQtyProductWithCombinationQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Gets generic query builder - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - - $attrSubQuery = $this->connection->createQueryBuilder() - ->select(1) - ->from($this->dbPrefix . 'product_attribute', 'pa') - ->andWhere('pa.id_product = p.id_product'); - - $subQuery = $this->connection->createQueryBuilder()->select(1); - $subQuery - ->from($this->dbPrefix . 'stock_available', 'stock') - ->andWhere('p.id_product = stock.id_product') - ->andWhere('EXISTS(' . $attrSubQuery->getSQL() . ')') - ->andWhere('IFNULL(stock.quantity, 0) <= 0'); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $attrSubQuery->andWhere('stock.id_shop = :context_shop_id') - ->setParameter('context_shop_id', $this->contextShopId); - } - - $qb->andWhere('EXISTS(' . $subQuery->getSQL() . ')'); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/NoQtyProductWithoutCombinationQueryBuilder.php b/src/Core/Grid/Query/Monitoring/NoQtyProductWithoutCombinationQueryBuilder.php deleted file mode 100644 index 97862cd2..00000000 --- a/src/Core/Grid/Query/Monitoring/NoQtyProductWithoutCombinationQueryBuilder.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for product without combination and without quantities list data - */ -final class NoQtyProductWithoutCombinationQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - - $attrSubQuery = $this->connection->createQueryBuilder() - ->select(1) - ->from($this->dbPrefix . 'product_attribute', 'pa') - ->andWhere('pa.id_product = p.id_product'); - - $subQuery = $this->connection->createQueryBuilder(); - $subQuery->select(1) - ->from($this->dbPrefix . 'stock_available', 'stock') - ->andWhere('p.id_product = stock.id_product') - ->andWhere('NOT EXISTS(' . $attrSubQuery->getSQL() . ')') - ->andWhere('IFNULL(stock.quantity, 0) <= 0'); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $subQuery->andWhere('stock.id_shop = :context_shop_id') - ->setParameter('context_shop_id', $this->contextShopId); - } - - $qb->andWhere('EXISTS(' . $subQuery->getSQL() . ')'); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/ProductWithoutDescriptionQueryBuilder.php b/src/Core/Grid/Query/Monitoring/ProductWithoutDescriptionQueryBuilder.php deleted file mode 100644 index 38866b55..00000000 --- a/src/Core/Grid/Query/Monitoring/ProductWithoutDescriptionQueryBuilder.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for product without description list data - */ -final class ProductWithoutDescriptionQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - $qb->andWhere('pl.description IS NULL OR pl.description = ""') - ->andWhere('pl.description_short IS NULL OR pl.description_short = ""'); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/ProductWithoutImageQueryBuilder.php b/src/Core/Grid/Query/Monitoring/ProductWithoutImageQueryBuilder.php deleted file mode 100644 index 4741053a..00000000 --- a/src/Core/Grid/Query/Monitoring/ProductWithoutImageQueryBuilder.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for product without image list data - */ -final class ProductWithoutImageQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - - $imageSubQuery = $this->connection->createQueryBuilder() - ->select(1) - ->from($this->dbPrefix . 'image_shop', 'img') - ->andWhere('p.id_product = img.id_product'); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $imageSubQuery->andWhere('img.id_shop = :context_shop_id'); - } else { - $imageSubQuery->andWhere('img.id_shop = p.id_shop_default'); - } - - $qb->andWhere('NOT EXISTS(' . $imageSubQuery->getSQL() . ')'); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/Monitoring/ProductWithoutPriceQueryBuilder.php b/src/Core/Grid/Query/Monitoring/ProductWithoutPriceQueryBuilder.php deleted file mode 100644 index bdffb500..00000000 --- a/src/Core/Grid/Query/Monitoring/ProductWithoutPriceQueryBuilder.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query\Monitoring; - -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds query for product without price list data - */ -final class ProductWithoutPriceQueryBuilder extends AbstractProductQueryBuilder -{ - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria); - $qb->select('COUNT(DISTINCT p.id_product)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return QueryBuilder - */ - private function getQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getProductsCommonQueryBuilder($searchCriteria); - - $specPriceSubQuery = $this->connection->createQueryBuilder() - ->select(1) - ->from($this->dbPrefix . 'specific_price', 'sp') - ->andWhere('p.id_product = sp.id_product'); - - if ($this->multistoreContextChecker->isSingleShopContext()) { - $specPriceSubQuery->andWhere('sp.id_shop = :context_shop_id') - ->setParameter('context_shop_id', $this->contextShopId); - } - - $qb->andWhere('p.price = 0') - ->andWhere('p.wholesale_price = 0') - ->andWhere('NOT EXISTS(' . $specPriceSubQuery->getSQL() . ')'); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/OrderMessageQueryBuilder.php b/src/Core/Grid/Query/OrderMessageQueryBuilder.php deleted file mode 100644 index bc3a342d..00000000 --- a/src/Core/Grid/Query/OrderMessageQueryBuilder.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\Filter\DoctrineFilterApplicatorInterface; -use PrestaShop\PrestaShop\Core\Grid\Query\Filter\SqlFilters; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds search & count queries for Order message grid - */ -final class OrderMessageQueryBuilder implements DoctrineQueryBuilderInterface -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $dbPrefix; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var DoctrineFilterApplicatorInterface - */ - private $doctrineFilterApplicator; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $doctrineSearchCriteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param int $contextLanguageId - * @param DoctrineFilterApplicatorInterface $doctrineFilterApplicator - * @param DoctrineSearchCriteriaApplicatorInterface $doctrineSearchCriteriaApplicator - */ - public function __construct( - Connection $connection, - string $dbPrefix, - int $contextLanguageId, - DoctrineFilterApplicatorInterface $doctrineFilterApplicator, - DoctrineSearchCriteriaApplicatorInterface $doctrineSearchCriteriaApplicator - ) { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - $this->contextLanguageId = $contextLanguageId; - $this->doctrineFilterApplicator = $doctrineFilterApplicator; - $this->doctrineSearchCriteriaApplicator = $doctrineSearchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->buildBaseQuery($searchCriteria); - $qb->select('om.id_order_message, oml.name, oml.message'); - - $this->doctrineSearchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->buildBaseQuery($searchCriteria); - $qb->select('COUNT(om.id_order_message)'); - - return $qb; - } - - /** - * @param SearchCriteriaInterface $criteria - * - * @return QueryBuilder - */ - private function buildBaseQuery(SearchCriteriaInterface $criteria): QueryBuilder - { - $qb = $this->connection->createQueryBuilder(); - - $qb - ->from($this->dbPrefix . 'order_message', 'om') - ->leftJoin( - 'om', - $this->dbPrefix . 'order_message_lang', - 'oml', - 'oml.id_order_message = om.id_order_message AND oml.id_lang = :context_lang_id' - ) - ->setParameter('context_lang_id', $this->contextLanguageId) - ; - - $sqlFilters = (new SqlFilters()) - ->addFilter('id_order_message', 'om.id_order_message', SqlFilters::WHERE_LIKE) - ->addFilter('name', 'oml.name', SqlFilters::WHERE_LIKE) - ->addFilter('message', 'oml.message', SqlFilters::WHERE_LIKE) - ; - - $this->doctrineFilterApplicator->apply($qb, $sqlFilters, $criteria->getFilters()); - - return $qb; - } -} diff --git a/src/Core/Grid/Query/OrderQueryBuilder.php b/src/Core/Grid/Query/OrderQueryBuilder.php deleted file mode 100644 index c273fd75..00000000 --- a/src/Core/Grid/Query/OrderQueryBuilder.php +++ /dev/null @@ -1,316 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PDO; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Builds SQL queries using Doctrine for retrieving data for orders grid - */ -final class OrderQueryBuilder implements DoctrineQueryBuilderInterface -{ - /** - * @var Connection - */ - protected $connection; - - /** - * @var string - */ - protected $dbPrefix; - - /** - * @var int - */ - private $contextLangId; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $criteriaApplicator; - /** - * @var array - */ - private $contextShopIds; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator - * @param int $contextLangId - * @param int[] $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $criteriaApplicator, - $contextLangId, - array $contextShopIds - ) { - $this->connection = $connection; - $this->dbPrefix = $dbPrefix; - $this->contextLangId = $contextLangId; - $this->criteriaApplicator = $criteriaApplicator; - $this->contextShopIds = $contextShopIds; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this - ->getBaseQueryBuilder($searchCriteria->getFilters()) - ->addSelect($this->getCustomerField() . ' AS `customer`') - ->addSelect('o.id_order, o.reference, o.total_paid_tax_incl, os.paid, osl.name AS osname') - ->addSelect('o.id_currency, cur.iso_code') - ->addSelect('o.current_state, o.id_customer') - ->addSelect('cu.`id_customer` IS NULL as `deleted_customer`') - ->addSelect('os.color, o.payment, s.name AS shop_name') - ->addSelect('o.date_add, cu.company, cl.name AS country_name, o.invoice_number, o.delivery_number') - ; - - $this->addNewCustomerField($qb); - - $this->applySorting($qb, $searchCriteria); - - $qb = $this->applyNewCustomerFilter($qb, $searchCriteria->getFilters()); - - $this->criteriaApplicator - ->applyPagination($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getBaseQueryBuilder($searchCriteria->getFilters()); - if (isset($searchCriteria->getFilters()['new'])) { - $this->addNewCustomerField($qb->addSelect('o.id_order as o_id_order')); - $qb = $this->applyNewCustomerFilter($qb, $searchCriteria->getFilters()); - $qb->select('count(o_id_order)'); - } else { - $qb->select('count(o.id_order)'); - } - - return $qb; - } - - /** - * @param array $filters - * - * @return QueryBuilder - */ - private function getBaseQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'orders', 'o') - ->leftJoin('o', $this->dbPrefix . 'customer', 'cu', 'o.id_customer = cu.id_customer') - ->leftJoin('o', $this->dbPrefix . 'currency', 'cur', 'o.id_currency = cur.id_currency') - ->innerJoin('o', $this->dbPrefix . 'address', 'a', 'o.id_address_delivery = a.id_address') - ->innerJoin('a', $this->dbPrefix . 'country', 'c', 'a.id_country = c.id_country') - ->innerJoin( - 'c', - $this->dbPrefix . 'country_lang', - 'cl', - 'c.id_country = cl.id_country AND cl.id_lang = :context_lang_id' - ) - ->leftJoin('o', $this->dbPrefix . 'order_state', 'os', 'o.current_state = os.id_order_state') - ->leftJoin( - 'os', - $this->dbPrefix . 'order_state_lang', - 'osl', - 'os.id_order_state = osl.id_order_state AND osl.id_lang = :context_lang_id' - ) - ->leftJoin('o', $this->dbPrefix . 'shop', 's', 'o.id_shop = s.id_shop') - ->andWhere('o.`id_shop` IN (:context_shop_ids)') - ->setParameter('context_lang_id', $this->contextLangId, PDO::PARAM_INT) - ->setParameter('context_shop_ids', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ; - - $strictComparisonFilters = [ - 'id_order' => 'o.id_order', - 'country_name' => 'c.id_country', - 'total_paid_tax_incl' => 'o.total_paid_tax_incl', - 'osname' => 'os.id_order_state', - ]; - - $likeComparisonFilters = [ - 'reference' => 'o.`reference`', - 'company' => 'cu.`company`', - 'payment' => 'o.`payment`', - 'customer' => $this->getCustomerField(), - ]; - - $havingLikeComparisonFilters = []; - - $dateComparisonFilters = [ - 'date_add' => 'o.`date_add`', - ]; - - foreach ($filters as $filterName => $filterValue) { - if (isset($strictComparisonFilters[$filterName])) { - $alias = $strictComparisonFilters[$filterName]; - - $qb->andWhere("$alias = :$filterName"); - $qb->setParameter($filterName, $filterValue); - - continue; - } - - if (isset($likeComparisonFilters[$filterName])) { - $alias = $likeComparisonFilters[$filterName]; - - $qb->andWhere("$alias LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if (isset($havingLikeComparisonFilters[$filterName])) { - $alias = $havingLikeComparisonFilters[$filterName]; - - $qb->andHaving("$alias LIKE :$filterName"); - $qb->setParameter($filterName, '%' . $filterValue . '%'); - - continue; - } - - if (isset($dateComparisonFilters[$filterName])) { - $alias = $dateComparisonFilters[$filterName]; - - if (isset($filterValue['from'])) { - $name = sprintf('%s_from', $filterName); - - $qb->andWhere("$alias >= :$name"); - $qb->setParameter($name, sprintf('%s %s', $filterValue['from'], '0:0:0')); - } - - if (isset($filterValue['to'])) { - $name = sprintf('%s_to', $filterName); - - $qb->andWhere("$alias <= :$name"); - $qb->setParameter($name, sprintf('%s %s', $filterValue['to'], '23:59:59')); - } - - continue; - } - } - - return $qb; - } - - /** - * @param QueryBuilder $qb - */ - private function addNewCustomerField(QueryBuilder $qb) - { - $newCustomerSubSelect = $this->connection - ->createQueryBuilder() - ->select('so.id_order') - ->from($this->dbPrefix . 'orders', 'so') - ->where('so.id_customer = o.id_customer') - ->andWhere('so.id_order < o.id_order') - ->setMaxResults(1) - ; - - $qb->addSelect('IF ((' . $newCustomerSubSelect->getSQL() . ') > 0, 0, 1) AS new'); - } - - /** - * @return string - */ - private function getCustomerField() - { - return 'CONCAT(LEFT(cu.`firstname`, 1), \'. \', cu.`lastname`)'; - } - - /** - * @param QueryBuilder $qb - * @param array $filters - * - * @return QueryBuilder - */ - private function applyNewCustomerFilter(QueryBuilder $qb, array $filters) - { - if (!isset($filters['new'])) { - return $qb; - } - - $builder = $this->connection - ->createQueryBuilder() - ->select('*') - ->from('(' . $qb->getSQL() . ') tmp_table') - ->andWhere('new = :new') - ->setParameter('new', $filters['new']) - ; - - foreach ($qb->getParameters() as $name => $previousParam) { - $builder->setParameter( - $name, - $previousParam, - is_array($previousParam) ? Connection::PARAM_INT_ARRAY : null - ); - } - - return $builder; - } - - /** - * @param QueryBuilder $qb - * @param SearchCriteriaInterface $criteria - */ - private function applySorting(QueryBuilder $qb, SearchCriteriaInterface $criteria) - { - $sortableFields = [ - 'id_order' => 'o.id_order', - 'country_name' => 'c.id_country', - 'total_paid_tax_incl' => 'o.total_paid_tax_incl', - 'reference' => 'o.`reference`', - 'company' => 'cu.`company`', - 'payment' => 'o.`payment`', - 'customer' => 'customer', - 'osname' => 'osl.name', - 'date_add' => 'o.`date_add`', - ]; - - if (isset($sortableFields[$criteria->getOrderBy()])) { - $qb->orderBy( - $sortableFields[$criteria->getOrderBy()], - $criteria->getOrderWay() - ); - } - } -} diff --git a/src/Core/Grid/Query/ProfileQueryBuilder.php b/src/Core/Grid/Query/ProfileQueryBuilder.php deleted file mode 100644 index fe853bca..00000000 --- a/src/Core/Grid/Query/ProfileQueryBuilder.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class ProfilesQueryBuilder is responsible for building queries for profiles grid data. - */ -final class ProfileQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $languageId; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param $contextLanguageId - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextLanguageId - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->languageId = $contextLanguageId; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('p.id_profile, pl.name') - ; - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(p.id_profile)') - ; - - return $qb; - } - - /** - * Get generic query builder. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'profile', 'p') - ->innerJoin('p', $this->dbPrefix . 'profile_lang', 'pl', 'p.id_profile = pl.id_profile') - ->andWhere('pl.id_lang = :language') - ->setParameter('language', $this->languageId) - ; - - $allowedFilters = [ - 'id_profile', - 'name', - ]; - - foreach ($filters as $name => $value) { - if (!in_array($name, $allowedFilters, true)) { - continue; - } - - if ('id_profile' === $name) { - $qb->andWhere("p.id_profile = :$name"); - $qb->setParameter($name, $value); - - continue; - } - - $qb->andWhere("$name LIKE :$name"); - $qb->setParameter($name, '%' . $value . '%'); - } - - return $qb; - } -} diff --git a/src/Core/Grid/Query/QueryParserInterface.php b/src/Core/Grid/Query/QueryParserInterface.php deleted file mode 100644 index a2de7333..00000000 --- a/src/Core/Grid/Query/QueryParserInterface.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -/** - * Returns the executable query from a prepared one. - */ -interface QueryParserInterface -{ - /** - * @param string $query the prepared query - * @param array $queryParameters the query parameters - * - * @return string - */ - public function parse($query, array $queryParameters); -} diff --git a/src/Core/Grid/Query/SupplierQueryBuilder.php b/src/Core/Grid/Query/SupplierQueryBuilder.php deleted file mode 100644 index a910d88d..00000000 --- a/src/Core/Grid/Query/SupplierQueryBuilder.php +++ /dev/null @@ -1,246 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class SupplierQueryBuilder builds search & count queries for suppliers grid. - */ -final class SupplierQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var int - */ - private $contextLangId; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param int $contextLangId - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $contextLangId, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->contextLangId = $contextLangId; - $this->contextShopIds = $contextShopIds; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $filters = $searchCriteria->getFilters(); - $isCountFilter = array_key_exists('products_count', $filters); - - if ($isCountFilter) { - $qb = $this->getQueryBuilderByProductsCount($filters); - $qb->select('*'); - $this->applyFilters($qb, $filters, 'subQuery'); - $this->applyListQueryParameters($qb); - } else { - $qb = $this->getQueryBuilder(); - $this->applyListQuerySelection($qb); - $this->applyListQueryParameters($qb); - $this->applyFilters($qb, $filters, 's'); - } - - $this->searchCriteriaApplicator - ->applySorting($searchCriteria, $qb) - ->applyPagination($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $filters = $searchCriteria->getFilters(); - $isCountFilter = array_key_exists('products_count', $filters); - - if ($isCountFilter) { - $alias = 'subQuery'; - $qb = $this->getQueryBuilderByProductsCount($filters); - $this->applyFilters($qb, $filters, $alias); - $this->applyListQueryParameters($qb); - } else { - $qb = $this->getQueryBuilder(); - $this->applyListQueryParameters($qb); - $this->applyFilters($qb, $filters, 's'); - $alias = 's'; - } - - $qb->select('COUNT(DISTINCT ' . $alias . '.`id_supplier`)'); - - return $qb; - } - - /** - * Get generic query builder. - * - * @return QueryBuilder - */ - private function getQueryBuilder() - { - return $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'supplier', 's') - ->innerJoin( - 's', - $this->dbPrefix . 'supplier_lang', - 'sl', - 'sl.`id_supplier` = s.`id_supplier`' - ) - ->innerJoin( - 's', - $this->dbPrefix . 'supplier_shop', - 'ss', - 'ss.`id_supplier` = s.`id_supplier`' - ) - ->leftJoin( - 's', - $this->dbPrefix . 'product_supplier', - 'ps', - 'ps.`id_supplier` = s.`id_supplier`' - ) - ->andWhere('sl.`id_lang` = :contextLangId') - ->andWhere('ss.`id_shop` IN (:contextShopIds)') - ; - } - - /** - * Gets query builder by product count which uses the main query as the sub-query in FROM condition. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilderByProductsCount(array $filters) - { - $subQuery = $this->getQueryBuilder(); - $this->applyListQuerySelection($subQuery); - - $alias = 'subQuery'; - - $qb = $this->connection - ->createQueryBuilder() - ->from( - '(' . $subQuery->getSQL() . ')', - $alias - ) - ->where('subQuery.`products_count` = :productsCountFilter') - ; - - $qb->setParameter('productsCountFilter', $filters['products_count']); - - return $qb; - } - - /** - * Adds select and group by statements. - * - * @param QueryBuilder $qb - */ - private function applyListQuerySelection(QueryBuilder $qb) - { - $qb - ->select('s.`id_supplier`, s.`name`, s.`active`') - ->addSelect('COUNT(DISTINCT ps.`id_product`) AS `products_count`') - ->groupBy('s.`id_supplier`') - ; - } - - /** - * Sets the parameters which are used in the queries. - * - * @param QueryBuilder $qb - */ - private function applyListQueryParameters(QueryBuilder $qb) - { - $qb - ->setParameter('contextLangId', $this->contextLangId) - ->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ; - } - - /** - * Adds filter restrictions. - * - * @param QueryBuilder $qb - * @param array $filters - * @param string $alias - */ - private function applyFilters(QueryBuilder $qb, array $filters, $alias) - { - $availableFilters = [ - 'id_supplier', - 'name', - 'active', - ]; - - foreach ($filters as $filterName => $value) { - if (!in_array($filterName, $availableFilters, true)) { - continue; - } - - if (in_array($filterName, ['id_supplier', 'active'], true)) { - $qb->andWhere($alias . '.`' . $filterName . '` = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - $qb->andWhere($alias . '.`name` LIKE :' . $filterName); - $qb->setParameter($filterName, '%' . $value . '%'); - } - } -} diff --git a/src/Core/Grid/Query/TaxQueryBuilder.php b/src/Core/Grid/Query/TaxQueryBuilder.php deleted file mode 100644 index 3c784f81..00000000 --- a/src/Core/Grid/Query/TaxQueryBuilder.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class TaxQueryBuilder builds search & count queries for taxes grid. - */ -final class TaxQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var int - */ - private $employeeIdLang; - - /** - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param $employeeIdLang - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $employeeIdLang - ) { - parent::__construct($connection, $dbPrefix); - - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->employeeIdLang = $employeeIdLang; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('t.`id_tax`, tl.`name`, t.`rate`, t.`active`') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT t.`id_tax`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying webservice list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'tax', 't') - ->leftJoin( - 't', - $this->dbPrefix . 'tax_lang', - 'tl', - 't.`id_tax` = tl.`id_tax`' - ); - $qb->andWhere('tl.`id_lang` = :employee_id_lang'); - $qb->andWhere('t.`deleted` = 0'); - - $qb->setParameter('employee_id_lang', $this->employeeIdLang); - $this->applyFilters($qb, $filters); - - return $qb; - } - - private function applyFilters(QueryBuilder $qb, array $filters) - { - $allowedFiltersMap = [ - 'id_tax' => 't.id_tax', - 'name' => 'tl.name', - 'rate' => 't.rate', - 'active' => 't.active', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if ('active' === $filterName || 'id_tax' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' = :' . $filterName); - $qb->setParameter($filterName, $value); - - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - } - } -} diff --git a/src/Core/Grid/Query/TaxRulesGroupQueryBuilder.php b/src/Core/Grid/Query/TaxRulesGroupQueryBuilder.php deleted file mode 100644 index f483a70e..00000000 --- a/src/Core/Grid/Query/TaxRulesGroupQueryBuilder.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Query builder builds search & count queries for tax rules group grid. - */ -class TaxRulesGroupQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var array - */ - private $contextShopIds; - - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @param Connection $connection - * @param string $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds - ) { - parent::__construct($connection, $dbPrefix); - - $this->contextShopIds = $contextShopIds; - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - - $qb - ->select('trg.`id_tax_rules_group`, trg.`name`, trg.`active`') - ; - - $this->searchCriteriaApplicator - ->applyPagination($searchCriteria, $qb) - ->applySorting($searchCriteria, $qb) - ; - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT trg.`id_tax_rules_group`)') - ; - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying tax rule groups list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters): QueryBuilder - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'tax_rules_group', 'trg') - ->leftJoin( - 'trg', - $this->dbPrefix . 'tax_rules_group_shop', - 'trgs', - 'trg.`id_tax_rules_group` = trgs.`id_tax_rules_group`' - ); - - $qb->andWhere('trgs.`id_shop` IN (:contextShopIds)') - ->andWhere('trg.`deleted` = 0') - ->setParameter('contextShopIds', $this->contextShopIds, Connection::PARAM_INT_ARRAY); - - $this->applyFilters($qb, $filters); - - return $qb; - } - - /** - * Tax rule groups list filtering - * - * @param QueryBuilder $qb - * @param array $filters - */ - private function applyFilters(QueryBuilder $qb, array $filters): void - { - $allowedFiltersMap = [ - 'id_tax_rules_group' => 'trg.id_tax_rules_group', - 'name' => 'trg.name', - 'active' => 'trg.active', - ]; - - foreach ($filters as $filterName => $value) { - if (!array_key_exists($filterName, $allowedFiltersMap)) { - continue; - } - - if ('name' === $filterName) { - $qb->andWhere($allowedFiltersMap[$filterName] . ' LIKE :' . $filterName) - ->setParameter($filterName, '%' . $value . '%'); - - continue; - } - - $qb->andWhere($allowedFiltersMap[$filterName] . ' = :' . $filterName) - ->setParameter($filterName, $value); - } - } -} diff --git a/src/Core/Grid/Query/WebserviceKeyQueryBuilder.php b/src/Core/Grid/Query/WebserviceKeyQueryBuilder.php deleted file mode 100644 index 0100dfa1..00000000 --- a/src/Core/Grid/Query/WebserviceKeyQueryBuilder.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Query; - -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Query\QueryBuilder; -use PrestaShop\PrestaShop\Core\Grid\Query\Filter\DoctrineFilterApplicatorInterface; -use PrestaShop\PrestaShop\Core\Grid\Query\Filter\SqlFilters; -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Class WebserviceKeyQueryBuilder is responsible for providing data for webservice accounts list. - */ -final class WebserviceKeyQueryBuilder extends AbstractDoctrineQueryBuilder -{ - /** - * @var DoctrineSearchCriteriaApplicatorInterface - */ - private $searchCriteriaApplicator; - - /** - * @var array - */ - private $contextShopIds; - - /** - * @var DoctrineFilterApplicatorInterface - */ - private $doctrineFilterApplicator; - - /** - * WebserviceKeyQueryBuilder constructor. - * - * @param Connection $connection - * @param $dbPrefix - * @param DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param array $contextShopIds - * @param DoctrineFilterApplicatorInterface $doctrineFilterApplicator - */ - public function __construct( - Connection $connection, - $dbPrefix, - DoctrineSearchCriteriaApplicatorInterface $searchCriteriaApplicator, - array $contextShopIds, - DoctrineFilterApplicatorInterface $doctrineFilterApplicator - ) { - parent::__construct($connection, $dbPrefix); - $this->searchCriteriaApplicator = $searchCriteriaApplicator; - $this->contextShopIds = $contextShopIds; - $this->connection = $connection; - $this->doctrineFilterApplicator = $doctrineFilterApplicator; - } - - /** - * {@inheritdoc} - */ - public function getSearchQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()); - $qb->select('wa.`id_webservice_account`, wa.`key`, wa.`description`, wa.`active`') - ->orderBy( - $this->getModifiedOrderBy($searchCriteria->getOrderBy()), - $searchCriteria->getOrderWay() - ) - ->groupBy('wa.`id_webservice_account`'); - - $this->searchCriteriaApplicator->applyPagination($searchCriteria, $qb); - - return $qb; - } - - /** - * {@inheritdoc} - */ - public function getCountQueryBuilder(SearchCriteriaInterface $searchCriteria) - { - $qb = $this->getQueryBuilder($searchCriteria->getFilters()) - ->select('COUNT(DISTINCT wa.`id_webservice_account`)'); - - return $qb; - } - - /** - * Gets query builder with the common sql used for displaying webservice list and applying filter actions. - * - * @param array $filters - * - * @return QueryBuilder - */ - private function getQueryBuilder(array $filters) - { - $qb = $this->connection - ->createQueryBuilder() - ->from($this->dbPrefix . 'webservice_account', 'wa') - ->innerJoin( - 'wa', - $this->dbPrefix . 'webservice_account_shop', - 'was', - 'was.`id_webservice_account` = wa.`id_webservice_account`' - ) - ->andWhere('was.`id_shop` IN (:shops)') - ->setParameter('shops', $this->contextShopIds, Connection::PARAM_INT_ARRAY) - ; - - $sqlFilters = (new SqlFilters()) - ->addFilter('key', 'wa.key', SqlFilters::WHERE_LIKE) - ->addFilter('active', 'wa.active', SqlFilters::WHERE_STRICT) - ->addFilter('description', 'wa.description', SqlFilters::WHERE_LIKE) - ; - - $this->doctrineFilterApplicator->apply($qb, $sqlFilters, $filters); - - return $qb; - } - - /** - * Gets modified order by which includes an alias for reserved keyword. - * - * @param string $orderBy - original order by value - * - * @return string - */ - private function getModifiedOrderBy($orderBy) - { - return 'wa.`' . $orderBy . '`'; - } -} diff --git a/src/Core/Grid/Record/RecordCollection.php b/src/Core/Grid/Record/RecordCollection.php deleted file mode 100644 index ec651032..00000000 --- a/src/Core/Grid/Record/RecordCollection.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Record; - -use PrestaShop\PrestaShop\Core\Grid\Collection\AbstractCollection; - -/** - * Class RecordCollection is a wrapper around rows from database. - */ -final class RecordCollection extends AbstractCollection implements RecordCollectionInterface -{ - /** - * @param array $records Raw records data - */ - public function __construct(array $records = []) - { - $this->items = $records; - } - - /** - * {@inheritdoc} - */ - public function all() - { - return $this->items; - } -} diff --git a/src/Core/Grid/Record/RecordCollectionInterface.php b/src/Core/Grid/Record/RecordCollectionInterface.php deleted file mode 100644 index 7b105c89..00000000 --- a/src/Core/Grid/Record/RecordCollectionInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Record; - -use Countable; -use Iterator; - -/** - * Interface RecordCollectionInterface defines interface for raw rows wrapper. - */ -interface RecordCollectionInterface extends Countable, Iterator -{ - /** - * Get raw rows. - * - * @return array - */ - public function all(); -} diff --git a/src/Core/Grid/Search/Factory/DecoratedSearchCriteriaFactory.php b/src/Core/Grid/Search/Factory/DecoratedSearchCriteriaFactory.php deleted file mode 100644 index 1580611e..00000000 --- a/src/Core/Grid/Search/Factory/DecoratedSearchCriteriaFactory.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Search\Factory; - -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; - -/** - * Interface DecoratedSearchCriteriaFactory defines contract for decorated search criteria factory. - */ -interface DecoratedSearchCriteriaFactory -{ - /** - * Create new search criteria. - * - * @param SearchCriteriaInterface $searchCriteria - * - * @return SearchCriteriaInterface - */ - public function createFrom(SearchCriteriaInterface $searchCriteria); -} diff --git a/src/Core/Grid/Search/SearchCriteria.php b/src/Core/Grid/Search/SearchCriteria.php deleted file mode 100644 index 7911c353..00000000 --- a/src/Core/Grid/Search/SearchCriteria.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Search; - -/** - * Class SearchCriteria stores search criteria for grid data. - */ -final class SearchCriteria implements SearchCriteriaInterface -{ - /** - * @var array - */ - private $filters; - - /** - * @var string|null - */ - private $orderBy; - - /** - * @var string|null - */ - private $orderWay; - - /** - * @var string|null - */ - private $offset; - - /** - * @var string|null - */ - private $limit; - - /** - * @param array $filters - * @param string|null $orderBy - * @param string|null $orderWay - * @param string|null $offset - * @param string|null $limit - */ - public function __construct(array $filters = [], $orderBy = null, $orderWay = null, $offset = null, $limit = null) - { - $this->filters = $filters; - $this->orderBy = $orderBy; - $this->orderWay = $orderWay; - $this->offset = $offset; - $this->limit = $limit; - } - - /** - * {@inheritdoc} - */ - public function getOrderBy() - { - return $this->orderBy; - } - - /** - * {@inheritdoc} - */ - public function getOrderWay() - { - return $this->orderWay; - } - - /** - * {@inheritdoc} - */ - public function getOffset() - { - return $this->offset; - } - - /** - * {@inheritdoc} - */ - public function getLimit() - { - return $this->limit; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return $this->filters; - } -} diff --git a/src/Core/Grid/Search/SearchCriteriaInterface.php b/src/Core/Grid/Search/SearchCriteriaInterface.php deleted file mode 100644 index 8633044e..00000000 --- a/src/Core/Grid/Search/SearchCriteriaInterface.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Grid\Search; - -/** - * Interface SearchCriteriaInterface. - */ -interface SearchCriteriaInterface -{ - /** - * @return string|null Return order by or null to disable ordering - */ - public function getOrderBy(); - - /** - * @return string|null Return order by or null to disable ordering - */ - public function getOrderWay(); - - /** - * @return int|null Return offset or null to disable offset - */ - public function getOffset(); - - /** - * @return int|null Return limit or null to disable limiting - */ - public function getLimit(); - - /** - * @return array Return filters - */ - public function getFilters(); -} diff --git a/src/Core/Group/Provider/DefaultGroup.php b/src/Core/Group/Provider/DefaultGroup.php deleted file mode 100644 index 3d11e2f8..00000000 --- a/src/Core/Group/Provider/DefaultGroup.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Group\Provider; - -/** - * Stores information for default group - */ -class DefaultGroup -{ - /** - * @var int - */ - private $groupId; - - /** - * @var string - */ - private $name; - - /** - * @param int $groupId - * @param string $name - */ - public function __construct($groupId, $name) - { - $this->groupId = $groupId; - $this->name = $name; - } - - /** - * @return int - */ - public function getId() - { - return $this->groupId; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } -} diff --git a/src/Core/Group/Provider/DefaultGroups.php b/src/Core/Group/Provider/DefaultGroups.php deleted file mode 100644 index 8c48c531..00000000 --- a/src/Core/Group/Provider/DefaultGroups.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Group\Provider; - -/** - * Stores default group options - */ -class DefaultGroups -{ - /** - * @var DefaultGroup - */ - private $visitorsGroup; - - /** - * @var DefaultGroup - */ - private $guestsGroup; - - /** - * @var DefaultGroup - */ - private $customersGroup; - - /** - * @param DefaultGroup $visitorsGroup - * @param DefaultGroup $guestsGroup - * @param DefaultGroup $customersGroup - */ - public function __construct(DefaultGroup $visitorsGroup, DefaultGroup $guestsGroup, DefaultGroup $customersGroup) - { - $this->visitorsGroup = $visitorsGroup; - $this->guestsGroup = $guestsGroup; - $this->customersGroup = $customersGroup; - } - - /** - * Get default visitors group - * - * @return DefaultGroup - */ - public function getVisitorsGroup() - { - return $this->visitorsGroup; - } - - /** - * Get default guests group - * - * @return DefaultGroup - */ - public function getGuestsGroup() - { - return $this->guestsGroup; - } - - /** - * Get customers group - * - * @return DefaultGroup - */ - public function getCustomersGroup() - { - return $this->customersGroup; - } - - /** - * Get default groups - * - * @return DefaultGroup[] - */ - public function getGroups() - { - return [ - $this->getVisitorsGroup(), - $this->getGuestsGroup(), - $this->getCustomersGroup(), - ]; - } -} diff --git a/src/Core/Group/Provider/DefaultGroupsProviderInterface.php b/src/Core/Group/Provider/DefaultGroupsProviderInterface.php deleted file mode 100644 index f5932786..00000000 --- a/src/Core/Group/Provider/DefaultGroupsProviderInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Group\Provider; - -/** - * Interface for service that retrieves default customer group options - */ -interface DefaultGroupsProviderInterface -{ - /** - * @return DefaultGroups - */ - public function getGroups(); -} diff --git a/src/Core/Hook/Generator/HookDescriptionGenerator.php b/src/Core/Hook/Generator/HookDescriptionGenerator.php deleted file mode 100644 index 0b994e9d..00000000 --- a/src/Core/Hook/Generator/HookDescriptionGenerator.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Generator; - -use PrestaShop\PrestaShop\Core\Hook\HookDescription; -use PrestaShop\PrestaShop\Core\Util\String\StringModifierInterface; -use PrestaShop\PrestaShop\Core\Util\String\StringValidatorInterface; - -/** - * Generates description for hook names. - */ -final class HookDescriptionGenerator implements HookDescriptionGeneratorInterface -{ - /** - * @var array - */ - private $hookDescriptions; - - /** - * @var StringValidatorInterface - */ - private $stringValidator; - - /** - * @var StringModifierInterface - */ - private $stringModifier; - - /** - * @param array $hookDescriptions - * @param StringValidatorInterface $stringValidator - * @param StringModifierInterface $stringModifier - */ - public function __construct( - array $hookDescriptions, - StringValidatorInterface $stringValidator, - StringModifierInterface $stringModifier - ) { - $this->hookDescriptions = $hookDescriptions; - $this->stringValidator = $stringValidator; - $this->stringModifier = $stringModifier; - } - - /** - * {@inheritdoc} - */ - public function generate($hookName) - { - foreach ($this->hookDescriptions as $hookPlaceholder => $hookDescription) { - $prefix = isset($hookDescription['prefix']) ? $hookDescription['prefix'] : ''; - $suffix = isset($hookDescription['suffix']) ? $hookDescription['suffix'] : ''; - - if ($this->stringValidator->startsWithAndEndsWith($hookName, $prefix, $suffix) && - !$this->stringValidator->doesContainsWhiteSpaces($hookName) - ) { - $hookId = $this->extractHookId($hookName, $prefix, $suffix); - - return new HookDescription( - $hookName, - $this->getTextWithHookId($hookDescription['title'], $hookId), - $this->getTextWithHookId($hookDescription['description'], $hookId) - ); - } - } - - return new HookDescription( - $hookName, - '', - '' - ); - } - - /** - * Removes from hook name id prefix and suffix. - * - * @param string $hookName - * @param string $prefix - * @param string $suffix - * - * @return string - */ - private function extractHookId($hookName, $prefix, $suffix) - { - return str_replace([$prefix, $suffix], '', $hookName); - } - - /** - * Gets text with replaced hook id. - * - * @param string $description - * @param string $hookId - * - * @return string - */ - private function getTextWithHookId($description, $hookId) - { - if (!$this->doesHookDescriptionContainsPlaceholder($description)) { - return $description; - } - - $hookIdSplitByCamelCase = $this->stringModifier->splitByCamelCase($hookId); - - $isPlaceholderAsFirstValueInString = $this->doesPlaceholderIsTheFirstElementOfTheDescription($description); - - if ($isPlaceholderAsFirstValueInString) { - $hookIdSplitByCamelCase = ucfirst($hookIdSplitByCamelCase); - } else { - $hookIdSplitByCamelCase = strtolower($hookIdSplitByCamelCase); - } - - return sprintf($description, $hookIdSplitByCamelCase); - } - - /** - * Checks if hook description contains placeholder value. - * - * @param string $description - * - * @return bool - */ - private function doesHookDescriptionContainsPlaceholder($description) - { - return false !== strpos($description, '%s'); - } - - /** - * Checks if placeholder is the first element of the string. - * - * @param string $description - * - * @return bool - */ - private function doesPlaceholderIsTheFirstElementOfTheDescription($description) - { - return 0 === strncmp($description, '%s', 2); - } -} diff --git a/src/Core/Hook/Generator/HookDescriptionGeneratorInterface.php b/src/Core/Hook/Generator/HookDescriptionGeneratorInterface.php deleted file mode 100644 index b98702d3..00000000 --- a/src/Core/Hook/Generator/HookDescriptionGeneratorInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Generator; - -use PrestaShop\PrestaShop\Core\Hook\HookDescription; - -/** - * Defines contract for generating description for hook names. - */ -interface HookDescriptionGeneratorInterface -{ - /** - * @param string $hookName - * - * @return HookDescription - */ - public function generate($hookName); -} diff --git a/src/Core/Hook/Hook.php b/src/Core/Hook/Hook.php deleted file mode 100644 index 566b2c33..00000000 --- a/src/Core/Hook/Hook.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Class Hook defines hook. - */ -final class Hook implements HookInterface -{ - /** - * @var string - */ - private $name; - - /** - * @var array - */ - private $parameters; - - /** - * @param string $name - * @param array $parameters - */ - public function __construct($name, array $parameters = []) - { - $this->name = $name; - $this->parameters = $parameters; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function getParameters() - { - return $this->parameters; - } -} diff --git a/src/Core/Hook/HookDescription.php b/src/Core/Hook/HookDescription.php deleted file mode 100644 index 673f4afc..00000000 --- a/src/Core/Hook/HookDescription.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Class holds descriptive information about the hook. - */ -final class HookDescription -{ - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $title; - - /** - * @var string - */ - private $description; - - /** - * @param string $name - * @param string $title - * @param string $description - */ - public function __construct($name, $title, $description) - { - $this->name = $name; - $this->title = $title; - $this->description = $description; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->description; - } -} diff --git a/src/Core/Hook/HookDispatcher.php b/src/Core/Hook/HookDispatcher.php deleted file mode 100644 index 697f2a2a..00000000 --- a/src/Core/Hook/HookDispatcher.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -use PrestaShop\PrestaShop\Adapter\Hook\HookDispatcher as HookDispatcherAdapter; -use Symfony\Component\EventDispatcher\Event; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; - -/** - * Class HookDispatcher is responsible for dispatching hooks. - */ -final class HookDispatcher implements HookDispatcherInterface -{ - /** - * @var HookDispatcherAdapter - */ - private $hookDispatcherAdapter; - - /** - * @param HookDispatcherAdapter $hookDispatcherAdapter - */ - public function __construct(HookDispatcherAdapter $hookDispatcherAdapter) - { - $this->hookDispatcherAdapter = $hookDispatcherAdapter; - } - - /** - * {@inheritdoc} - */ - public function dispatchHook(HookInterface $hook) - { - $this->hookDispatcherAdapter->dispatchForParameters( - $hook->getName(), - $hook->getParameters() - ); - } - - /** - * {@inheritdoc} - */ - public function dispatchWithParameters($hookName, array $hookParameters = []) - { - $this->dispatchHook(new Hook($hookName, $hookParameters)); - } - - /** - * {@inheritdoc} - */ - public function dispatchRendering(HookInterface $hook) - { - $event = $this->hookDispatcherAdapter->renderForParameters( - $hook->getName(), - $hook->getParameters() - ); - - $content = $event->getContent(); - array_walk($content, function (&$partialContent) { - $partialContent = empty($partialContent) ? '' : current($partialContent); - }); - - return new RenderedHook($hook, $content); - } - - /** - * {@inheritdoc} - */ - public function dispatchRenderingWithParameters($hookName, array $hookParameters = []) - { - return $this->dispatchRendering(new Hook($hookName, $hookParameters)); - } - - /** - * {@inheritdoc} - */ - public function dispatch($eventName, Event $event = null) - { - return $this->hookDispatcherAdapter->dispatch($eventName, $event); - } - - /** - * {@inheritdoc} - */ - public function addListener($eventName, $listener, $priority = 0) - { - $this->hookDispatcherAdapter->addListener($eventName, $listener, $priority); - } - - /** - * {@inheritdoc} - */ - public function addSubscriber(EventSubscriberInterface $subscriber) - { - $this->hookDispatcherAdapter->addSubscriber($subscriber); - } - - /** - * {@inheritdoc} - */ - public function removeListener($eventName, $listener) - { - $this->hookDispatcherAdapter->removeListener($eventName, $listener); - } - - /** - * {@inheritdoc} - */ - public function removeSubscriber(EventSubscriberInterface $subscriber) - { - $this->hookDispatcherAdapter->removeSubscriber($subscriber); - } - - /** - * {@inheritdoc} - */ - public function getListeners($eventName = null) - { - return $this->hookDispatcherAdapter->getListeners($eventName); - } - - /** - * {@inheritdoc} - */ - public function getListenerPriority($eventName, $listener) - { - return $this->hookDispatcherAdapter->getListenerPriority($eventName, $listener); - } - - /** - * {@inheritdoc} - */ - public function hasListeners($eventName = null) - { - return $this->hookDispatcherAdapter->hasListeners($eventName); - } -} diff --git a/src/Core/Hook/HookDispatcherAwareTrait.php b/src/Core/Hook/HookDispatcherAwareTrait.php deleted file mode 100644 index 27f84917..00000000 --- a/src/Core/Hook/HookDispatcherAwareTrait.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Trait EventDispatcherAwareTrait. - * - * @deprecated - */ -trait HookDispatcherAwareTrait -{ - /** - * @var HookDispatcherInterface - */ - protected $hookDispatcher; - - /** - * Set hook dispatcher. - * - * @param HookDispatcherInterface $hookDispatcher - */ - public function setHookDispatcher(HookDispatcherInterface $hookDispatcher) - { - @trigger_error('HookDispatcherAwareTrait is deprecated as of 1.7.5.1 and will be removed in the next major version. If you need to inject HookDispatcherInterface use the constructor not setter injection.', E_USER_DEPRECATED); - - $this->hookDispatcher = $hookDispatcher; - } -} diff --git a/src/Core/Hook/HookDispatcherInterface.php b/src/Core/Hook/HookDispatcherInterface.php deleted file mode 100644 index bb9f445d..00000000 --- a/src/Core/Hook/HookDispatcherInterface.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -/** - * Interface HookDispatcherInterface defines contract for hook dispatcher - * Extends EventDispatcherInterface for compatibility with the Event Dispatcher component. - */ -interface HookDispatcherInterface extends EventDispatcherInterface -{ - /** - * Dispatch given hook. - * - * @param HookInterface $hook - */ - public function dispatchHook(HookInterface $hook); - - /** - * Dispatch hook with raw parameters. - * - * @param string $hookName - * @param array $hookParameters - */ - public function dispatchWithParameters($hookName, array $hookParameters = []); - - /** - * Dispatch rendering hook. - * - * @param HookInterface $hook - * - * @return RenderedHookInterface - */ - public function dispatchRendering(HookInterface $hook); - - /** - * Dispatch rendering hook with parameters. - * - * @param string $hookName - * @param array $hookParameters - * - * @return RenderedHookInterface - */ - public function dispatchRenderingWithParameters($hookName, array $hookParameters = []); -} diff --git a/src/Core/Hook/HookInterface.php b/src/Core/Hook/HookInterface.php deleted file mode 100644 index e4220971..00000000 --- a/src/Core/Hook/HookInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Interface HookInterface defines contract for hook. - */ -interface HookInterface -{ - /** - * Get hook name. - * - * @return string - */ - public function getName(); - - /** - * Get hook parameters. - * - * @return array - */ - public function getParameters(); -} diff --git a/src/Core/Hook/Provider/GridDefinitionHookByServiceIdsProvider.php b/src/Core/Hook/Provider/GridDefinitionHookByServiceIdsProvider.php deleted file mode 100644 index fa860e04..00000000 --- a/src/Core/Hook/Provider/GridDefinitionHookByServiceIdsProvider.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Provider; - -use Exception; -use Generator; -use Logger; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Provides hooks list by calling service ids from the container. - */ -final class GridDefinitionHookByServiceIdsProvider implements HookByServiceIdsProviderInterface -{ - const HOOK_PREFIX = 'action'; - const GRID_DEFINITION_HOOK_SUFFIX = 'GridDefinitionModifier'; - const GRID_QUERY_BUILDER_HOOK_SUFFIX = 'GridQueryBuilderModifier'; - const GRID_DATA_HOOK_SUFFIX = 'GridDataModifier'; - const GRID_FILTER_FORM_SUFFIX = 'GridFilterFormModifier'; - const GRID_PRESENTER_SUFFIX = 'GridPresenterModifier'; - - /** - * @var ContainerInterface - */ - private $container; - - /** - * @param ContainerInterface $container - */ - public function __construct(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * {@inheritdoc} - */ - public function getHookNames(array $gridDefinitionServiceIds) - { - /** @var Generator $gridDefinitionIds */ - $gridDefinitionIds = $this->getGridDefinitionIds($gridDefinitionServiceIds); - - $gridDefinitionHookNames = []; - $gridQueryBuilderHookNames = []; - $gridDataHookNames = []; - $gridFilterFormHookNames = []; - $gridPresenterHookNames = []; - - foreach ($gridDefinitionIds as $gridDefinitionId) { - $gridDefinitionHookNames[] = $this->formatHookName( - self::HOOK_PREFIX, - $gridDefinitionId, - self::GRID_DEFINITION_HOOK_SUFFIX - ); - - $gridQueryBuilderHookNames[] = $this->formatHookName( - self::HOOK_PREFIX, - $gridDefinitionId, - self::GRID_QUERY_BUILDER_HOOK_SUFFIX - ); - - $gridDataHookNames[] = $this->formatHookName( - self::HOOK_PREFIX, - $gridDefinitionId, - self::GRID_DATA_HOOK_SUFFIX - ); - - $gridFilterFormHookNames[] = $this->formatHookName( - self::HOOK_PREFIX, - $gridDefinitionId, - self::GRID_FILTER_FORM_SUFFIX - ); - - $gridPresenterHookNames[] = $this->formatHookName( - self::HOOK_PREFIX, - $gridDefinitionId, - self::GRID_PRESENTER_SUFFIX - ); - } - - return array_merge( - $gridDefinitionHookNames, - $gridQueryBuilderHookNames, - $gridDataHookNames, - $gridFilterFormHookNames, - $gridPresenterHookNames - ); - } - - /** - * Gets grid definition ids which are used in a grid hook formation. - * - * @param array $gridDefinitionServiceIds - * - * @return Generator - */ - private function getGridDefinitionIds(array $gridDefinitionServiceIds) - { - foreach ($gridDefinitionServiceIds as $serviceId) { - try { - $service = $this->container->get($serviceId); - if (!$service instanceof GridDefinitionFactoryInterface) { - continue; - } - $definition = $service->getDefinition(); - $definitionId = $definition->getId(); - $camelizedDefinitionId = Container::camelize($definitionId); - yield $camelizedDefinitionId; - } catch (Exception $e) { - Logger::addLog(sprintf('Error while loading service: %s . Error: %s', $serviceId, $e)); - } - } - } - - /** - * Formats hook names. - * - * @param string $hookStartsWith - * @param string $hookId - * @param string $hookEndsWidth - * - * @return string - */ - private function formatHookName($hookStartsWith, $hookId, $hookEndsWidth) - { - return $hookStartsWith . $hookId . $hookEndsWidth; - } -} diff --git a/src/Core/Hook/Provider/HookByFormTypeProviderInterface.php b/src/Core/Hook/Provider/HookByFormTypeProviderInterface.php deleted file mode 100644 index 1b748f09..00000000 --- a/src/Core/Hook/Provider/HookByFormTypeProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Provider; - -/** - * Defines contract for providing hooks from form types. - */ -interface HookByFormTypeProviderInterface -{ - /** - * @param string[] $formTypes - * - * @return string[] - */ - public function getHookNames(array $formTypes); -} diff --git a/src/Core/Hook/Provider/HookByServiceIdsProviderInterface.php b/src/Core/Hook/Provider/HookByServiceIdsProviderInterface.php deleted file mode 100644 index 18e5d33c..00000000 --- a/src/Core/Hook/Provider/HookByServiceIdsProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Provider; - -/** - * Defines contract for providing hooks by using service ids. - */ -interface HookByServiceIdsProviderInterface -{ - /** - * @param string[] $gridDefinitionServiceIds - * - * @return string[] - */ - public function getHookNames(array $gridDefinitionServiceIds); -} diff --git a/src/Core/Hook/Provider/IdentifiableObjectHookByFormTypeProvider.php b/src/Core/Hook/Provider/IdentifiableObjectHookByFormTypeProvider.php deleted file mode 100644 index 27373783..00000000 --- a/src/Core/Hook/Provider/IdentifiableObjectHookByFormTypeProvider.php +++ /dev/null @@ -1,154 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook\Provider; - -use Exception; -use Generator; -use Logger; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\Form\FormRegistryInterface; -use Throwable; - -/** - * Gets hook names by identifiable object form types. - */ -final class IdentifiableObjectHookByFormTypeProvider implements HookByFormTypeProviderInterface -{ - const FORM_TYPE_POSITION_IN_CONSTRUCTOR_OF_FORM_BUILDER = 0; - - const FORM_BUILDER_HOOK_PREFIX = 'action'; - const FORM_BUILDER_HOOK_SUFFIX = 'FormBuilderModifier'; - - const FORM_HANDLER_UPDATE_BEFORE_PREFIX = 'actionBeforeUpdate'; - const FORM_HANDLER_UPDATE_AFTER_PREFIX = 'actionAfterUpdate'; - const FORM_HANDLER_CREATE_BEFORE_PREFIX = 'actionBeforeCreate'; - const FORM_HANDLER_CREATE_AFTER_PREFIX = 'actionAfterCreate'; - const FORM_HANDLER_SUFFIX = 'FormHandler'; - - /** - * @var FormRegistryInterface - */ - private $formFactory; - - /** - * @param FormFactoryInterface $formFactory - */ - public function __construct(FormFactoryInterface $formFactory) - { - $this->formFactory = $formFactory; - } - - /** - * {@inheritdoc} - */ - public function getHookNames(array $formTypes) - { - $formNames = $this->getFormNames($formTypes); - - $formBuilderHookNames = []; - $formHandlerBeforeUpdateHookNames = []; - $formHandlerAfterUpdateHookNames = []; - $formHandlerBeforeCreateHookNames = []; - $formHandlerAfterCreateHookNames = []; - - foreach ($formNames as $formName) { - $formBuilderHookNames[] = $this->formatHookName( - self::FORM_BUILDER_HOOK_PREFIX, - $formName, - self::FORM_BUILDER_HOOK_SUFFIX - ); - - $formHandlerBeforeUpdateHookNames[] = $this->formatHookName( - self::FORM_HANDLER_UPDATE_BEFORE_PREFIX, - $formName, - self::FORM_HANDLER_SUFFIX - ); - - $formHandlerAfterUpdateHookNames[] = $this->formatHookName( - self::FORM_HANDLER_UPDATE_AFTER_PREFIX, - $formName, - self::FORM_HANDLER_SUFFIX - ); - - $formHandlerBeforeCreateHookNames[] = $this->formatHookName( - self::FORM_HANDLER_CREATE_BEFORE_PREFIX, - $formName, - self::FORM_HANDLER_SUFFIX - ); - - $formHandlerAfterCreateHookNames[] = $this->formatHookName( - self::FORM_HANDLER_CREATE_AFTER_PREFIX, - $formName, - self::FORM_HANDLER_SUFFIX - ); - } - - return array_merge( - $formBuilderHookNames, - $formHandlerBeforeUpdateHookNames, - $formHandlerAfterUpdateHookNames, - $formHandlerBeforeCreateHookNames, - $formHandlerAfterCreateHookNames - ); - } - - /** - * Gets form names which are used when generating hooks. - * - * @param Definition[] $formTypes - * - * @return Generator - */ - private function getFormNames(array $formTypes) - { - foreach ($formTypes as $formType) { - try { - yield $this->formFactory->createBuilder($formType)->getName(); - } catch (Exception $e) { - Logger::addLog(sprintf('Error while loading formType: %s . Error: %s', $formType, $e)); - } catch (Throwable $e) { - Logger::addLog(sprintf('Invalid argument exception: %s . Error: %s', $formType, $e)); - } - } - } - - /** - * Formats hook names. - * - * @param string $hookStartsWith - * @param string $hookId - * @param string $hookEndsWidth - * - * @return string - */ - private function formatHookName($hookStartsWith, $hookId, $hookEndsWidth) - { - return $hookStartsWith . Container::camelize($hookId) . $hookEndsWidth; - } -} diff --git a/src/Core/Hook/RenderedHook.php b/src/Core/Hook/RenderedHook.php deleted file mode 100644 index 86f4bb71..00000000 --- a/src/Core/Hook/RenderedHook.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Class RenderingHook defines rendered hook. - */ -final class RenderedHook implements RenderedHookInterface -{ - /** - * @var HookInterface - */ - private $hook; - - /** - * @var array ['module_name' => 'rendered_content', ...] - */ - private $content; - - /** - * @param HookInterface $hook - * @param array $content - */ - public function __construct(HookInterface $hook, array $content = []) - { - $this->hook = $hook; - $this->content = $content; - } - - /** - * {@inheritdoc} - */ - public function getHook() - { - return $this->hook; - } - - /** - * {@inheritdoc} - */ - public function getContent() - { - return $this->content; - } - - /** - * {@inheritdoc} - */ - public function outputContent() - { - return implode('', $this->content); - } -} diff --git a/src/Core/Hook/RenderedHookInterface.php b/src/Core/Hook/RenderedHookInterface.php deleted file mode 100644 index 3332a412..00000000 --- a/src/Core/Hook/RenderedHookInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Hook; - -/** - * Interface RenderedHookInterface defines contract for rendered hook. - */ -interface RenderedHookInterface -{ - /** - * Get rendered hook. - * - * @return HookInterface - */ - public function getHook(); - - /** - * Get rendered content. - * - * @return array - */ - public function getContent(); - - /** - * Returns displayable content. - * - * @return string - */ - public function outputContent(); -} diff --git a/src/Core/Image/Deleter/ImageFileDeleter.php b/src/Core/Image/Deleter/ImageFileDeleter.php deleted file mode 100644 index 133281c4..00000000 --- a/src/Core/Image/Deleter/ImageFileDeleter.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Deleter; - -/** - * Class ImageFileDeleter is responsible for deleting image files. - */ -final class ImageFileDeleter implements ImageFileDeleterInterface -{ - /** - * {@inheritdoc} - */ - public function deleteFromPath($path, $recursively = false, $deleteSubdirectories = false, $format = 'jpg') - { - if (!$path || !$format || !is_dir($path)) { - return false; - } - - foreach (scandir($path, SCANDIR_SORT_NONE) as $file) { - $pattern = '/^[0-9]+(\-(.*))?\.' . $format . '$/'; - - if ($recursively && is_dir($path . $file) && (preg_match('/^[0-9]$/', $file))) { - // Recursion - $this->deleteFromPath($path . $file . '/', $recursively, $deleteSubdirectories, $format); - } - - // Delete the file by regex pattern - $this->deleteByPattern($pattern, $path, $file); - - // Delete fileType file if it exists in the same directory. - if (file_exists($path . 'fileType')) { - unlink($path . 'fileType'); - } - } - - // Can we remove the image folder? - if ($deleteSubdirectories && is_numeric(basename($path))) { - $removeFolder = true; - foreach (scandir($path, SCANDIR_SORT_NONE) as $file) { - if (($file != '.' && $file != '..' && $file != 'index.php')) { - $removeFolder = false; - break; - } - } - - if ($removeFolder) { - // we're only removing index.php if it's a folder we want to delete - if (file_exists($path . 'index.php')) { - unlink($path . 'index.php'); - } - rmdir($path); - } - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function deleteAllImages($path, $format = 'jpg') - { - foreach (scandir($path, SCANDIR_SORT_NONE) as $file) { - $this->deleteByPattern( - '/(.*)\.' . $format . '$/', - $path, - $file - ); - } - } - - /** - * Delete images by given regex pattern from given path. - * - * @param string $pattern regex pattern - * @param string $path file directory path - * @param string $filename - */ - private function deleteByPattern($pattern, $path, $filename) - { - if (preg_match($pattern, $filename)) { - unlink($path . $filename); - } - } -} diff --git a/src/Core/Image/Deleter/ImageFileDeleterInterface.php b/src/Core/Image/Deleter/ImageFileDeleterInterface.php deleted file mode 100644 index 8078b9be..00000000 --- a/src/Core/Image/Deleter/ImageFileDeleterInterface.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Deleter; - -/** - * Interface ImageFileDeleterInterface describes an image file deleter. - */ -interface ImageFileDeleterInterface -{ - /** - * Recursively deletes all images in the given path and removes empty folders. - * - * @param string $path images directory - * @param bool $recursively if true deletes images from subdirectories - * @param bool $deleteSubdirectories if true deletes the subdirectories as well - * @param string $format image format - * - * @return bool - */ - public function deleteFromPath($path, $recursively = false, $deleteSubdirectories = false, $format = 'jpg'); - - /** - * Delete all images from given path. - * - * @param string $path - * @param string $format - */ - public function deleteAllImages($path, $format = 'jpg'); -} diff --git a/src/Core/Image/ImageProviderInterface.php b/src/Core/Image/ImageProviderInterface.php deleted file mode 100644 index 58ad4cb4..00000000 --- a/src/Core/Image/ImageProviderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image; - -/** - * Interface ThumbnailProviderInterface. - */ -interface ImageProviderInterface -{ - /** - * Get thumbnail image path. - * - * @param int $imageId - * - * @return string Path to thumbnail - */ - public function getPath($imageId); -} diff --git a/src/Core/Image/ImageTypeRepository.php b/src/Core/Image/ImageTypeRepository.php deleted file mode 100644 index f9c31c6d..00000000 --- a/src/Core/Image/ImageTypeRepository.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image; - -use Db; -use Shop; - -class ImageTypeRepository -{ - private $shop; - private $db; - private $db_prefix; - - public function __construct( - Shop $shop, - Db $db - ) { - $this->shop = $shop; - $this->db = $db; - $this->db_prefix = $db->getPrefix(); - } - - public function setTypes(array $types) - { - $this->removeAllTypes(); - foreach ($types as $name => $data) { - $this->createType( - $name, - $data['width'], - $data['height'], - $data['scope'] - ); - } - - return $this; - } - - public function createType($name, $width, $height, array $scope) - { - $data = [ - 'name' => $this->db->escape($name), - 'width' => $this->db->escape($width), - 'height' => $this->db->escape($height), - ]; - - foreach ($this->getScopeList() as $scope_item) { - if (in_array($scope_item, $scope)) { - $data[$scope_item] = 1; - } else { - $data[$scope_item] = 0; - } - } - - $this->db->insert('image_type', $data); - - return $this->getIdByName($name); - } - - public function getScopeList() - { - return ['products', 'categories', 'manufacturers', 'suppliers', 'stores']; - } - - public function getIdByName($name) - { - $escaped_name = $this->db->escape($name); - - $id_image_type = $this->db->getValue( - "SELECT id_image_type FROM {$this->db_prefix}image_type WHERE name = '$escaped_name'" - ); - - return (int) $id_image_type; - } - - protected function removeAllTypes() - { - Db::getInstance()->execute( - "TRUNCATE TABLE {$this->db_prefix}image_type" - ); - } -} diff --git a/src/Core/Image/Parser/ImageTagSourceParser.php b/src/Core/Image/Parser/ImageTagSourceParser.php deleted file mode 100644 index 943d276a..00000000 --- a/src/Core/Image/Parser/ImageTagSourceParser.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Parser; - -/** - * Class ImageTagPathParser parses "src" attribute of given image tag and prefixed it with shop's uri. - * - * This service helps retrieving image path from image tag generated by legacy ImageManager::thumbnail() method - * so image can be displayed in new pages. - */ -final class ImageTagSourceParser implements ImageTagSourceParserInterface -{ - /** - * @var string - */ - private $shopRootUri; - - /** - * @param string $shopRootUri - */ - public function __construct($shopRootUri) - { - $this->shopRootUri = $shopRootUri; - } - - /** - * {@inheritdoc} - */ - public function parse($imageTag) - { - $replacement = 'src="/'; - $imageTag = preg_replace('/src="(\.\.\/|\.\/)+/', $replacement, $imageTag); - - if (null === $imageTag) { - return null; - } - - preg_match('/src="\/([^"]+)"/', $imageTag, $path); - - if (empty($path[1])) { - return null; - } - - return sprintf('/%s', $path[1]); - } -} diff --git a/src/Core/Image/Parser/ImageTagSourceParserInterface.php b/src/Core/Image/Parser/ImageTagSourceParserInterface.php deleted file mode 100644 index ef3ea708..00000000 --- a/src/Core/Image/Parser/ImageTagSourceParserInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Parser; - -/** - * Interface ImageTagSourceParserInterface is contract for image "src" attribute parser. - */ -interface ImageTagSourceParserInterface -{ - /** - * @param string $imageTag Example '' - * - * @return string Parsed "src" attribute - */ - public function parse($imageTag); -} diff --git a/src/Core/Image/Uploader/Exception/ImageOptimizationException.php b/src/Core/Image/Uploader/Exception/ImageOptimizationException.php deleted file mode 100644 index 8c42ab19..00000000 --- a/src/Core/Image/Uploader/Exception/ImageOptimizationException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Uploader\Exception; - -/** - * Class ImageOptimizationException is thrown when resizing, cutting or optimizing image fails. - */ -class ImageOptimizationException extends \Exception -{ -} diff --git a/src/Core/Image/Uploader/Exception/ImageUploadException.php b/src/Core/Image/Uploader/Exception/ImageUploadException.php deleted file mode 100644 index d26e7ad1..00000000 --- a/src/Core/Image/Uploader/Exception/ImageUploadException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Uploader\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class ImageUploadException extends CoreException -{ -} diff --git a/src/Core/Image/Uploader/Exception/MemoryLimitException.php b/src/Core/Image/Uploader/Exception/MemoryLimitException.php deleted file mode 100644 index 95f1cf92..00000000 --- a/src/Core/Image/Uploader/Exception/MemoryLimitException.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Uploader\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class MemoryLimitException extends CoreException -{ -} diff --git a/src/Core/Image/Uploader/Exception/UploadedImageConstraintException.php b/src/Core/Image/Uploader/Exception/UploadedImageConstraintException.php deleted file mode 100644 index c8adb331..00000000 --- a/src/Core/Image/Uploader/Exception/UploadedImageConstraintException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Uploader\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -class UploadedImageConstraintException extends CoreException -{ - const EXCEEDED_SIZE = 1; - const UNRECOGNIZED_FORMAT = 2; - const UNKNOWN_ERROR = 4; -} diff --git a/src/Core/Image/Uploader/ImageUploaderInterface.php b/src/Core/Image/Uploader/ImageUploaderInterface.php deleted file mode 100644 index 08dec114..00000000 --- a/src/Core/Image/Uploader/ImageUploaderInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Image\Uploader; - -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Interface ImageUploaderInterface is contract for entity (e.g. Category, Product & etc.) image uploader. - */ -interface ImageUploaderInterface -{ - /** - * Upload entity image. - * - * @param int $entityId - * @param UploadedFile $uploadedImage - */ - public function upload($entityId, UploadedFile $uploadedImage); -} diff --git a/src/Core/Import/Access/ImportAccessChecker.php b/src/Core/Import/Access/ImportAccessChecker.php deleted file mode 100644 index 3e08479b..00000000 --- a/src/Core/Import/Access/ImportAccessChecker.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Access; - -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; - -/** - * Class ImportAccessChecker is responsible for checking import access. - */ -final class ImportAccessChecker implements ImportAccessCheckerInterface -{ - /** - * @var ContextEmployeeProviderInterface - */ - private $contextEmployeeProvider; - - /** - * @param ContextEmployeeProviderInterface $contextEmployeeProvider - */ - public function __construct(ContextEmployeeProviderInterface $contextEmployeeProvider) - { - $this->contextEmployeeProvider = $contextEmployeeProvider; - } - - /** - * {@inheritdoc} - */ - public function canTruncateData() - { - return $this->contextEmployeeProvider->isSuperAdmin(); - } -} diff --git a/src/Core/Import/Access/ImportAccessCheckerInterface.php b/src/Core/Import/Access/ImportAccessCheckerInterface.php deleted file mode 100644 index e00f69de..00000000 --- a/src/Core/Import/Access/ImportAccessCheckerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Access; - -/** - * Interface ImportAccessCheckerInterface checks import access. - */ -interface ImportAccessCheckerInterface -{ - /** - * Checks if data truncation is allowed. - * - * @return bool - */ - public function canTruncateData(); -} diff --git a/src/Core/Import/Configuration/ImportConfig.php b/src/Core/Import/Configuration/ImportConfig.php deleted file mode 100644 index 44457978..00000000 --- a/src/Core/Import/Configuration/ImportConfig.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -/** - * Class ImportConfig defines import configuration. - */ -final class ImportConfig implements ImportConfigInterface -{ - /** - * @var string - */ - private $fileName; - - /** - * @var int - */ - private $entityType; - - /** - * @var string - */ - private $languageIso; - - /** - * @var string - */ - private $separator; - - /** - * @var string - */ - private $multipleValueSeparator; - - /** - * @var bool - */ - private $truncate; - - /** - * @var bool - */ - private $skipThumbnailRegeneration; - - /** - * @var bool - */ - private $matchReferences; - - /** - * @var bool - */ - private $forceIds; - - /** - * @var bool - */ - private $sendEmail; - - /** - * @var int - */ - private $skipRows; - - /** - * @param string $fileName - * @param int $entityType - * @param string $languageIso - * @param string $separator - * @param string $multipleValueSeparator - * @param bool $truncate - * @param bool $skipThumbnailRegeneration - * @param bool $matchReferences - * @param bool $forceIds - * @param bool $sendEmail - * @param int $skipRows - */ - public function __construct( - $fileName, - $entityType, - $languageIso, - $separator, - $multipleValueSeparator, - $truncate, - $skipThumbnailRegeneration, - $matchReferences, - $forceIds, - $sendEmail, - $skipRows = 0 - ) { - $this->fileName = $fileName; - $this->entityType = $entityType; - $this->languageIso = $languageIso; - $this->separator = $separator; - $this->multipleValueSeparator = $multipleValueSeparator; - $this->truncate = $truncate; - $this->skipThumbnailRegeneration = $skipThumbnailRegeneration; - $this->matchReferences = $matchReferences; - $this->forceIds = $forceIds; - $this->sendEmail = $sendEmail; - $this->skipRows = $skipRows; - } - - /** - * {@inheritdoc} - */ - public function getFileName() - { - return $this->fileName; - } - - /** - * {@inheritdoc} - */ - public function getEntityType() - { - return $this->entityType; - } - - /** - * {@inheritdoc} - */ - public function getLanguageIso() - { - return $this->languageIso; - } - - /** - * {@inheritdoc} - */ - public function getSeparator() - { - return $this->separator; - } - - /** - * {@inheritdoc} - */ - public function getMultipleValueSeparator() - { - return $this->multipleValueSeparator; - } - - /** - * {@inheritdoc} - */ - public function truncate() - { - return $this->truncate; - } - - /** - * {@inheritdoc} - */ - public function skipThumbnailRegeneration() - { - return $this->skipThumbnailRegeneration; - } - - /** - * {@inheritdoc} - */ - public function matchReferences() - { - return $this->matchReferences; - } - - /** - * {@inheritdoc} - */ - public function forceIds() - { - return $this->forceIds; - } - - /** - * {@inheritdoc} - */ - public function sendEmail() - { - return $this->sendEmail; - } - - /** - * {@inheritdoc} - */ - public function getNumberOfRowsToSkip() - { - return $this->skipRows; - } -} diff --git a/src/Core/Import/Configuration/ImportConfigFactory.php b/src/Core/Import/Configuration/ImportConfigFactory.php deleted file mode 100644 index 2588e6e5..00000000 --- a/src/Core/Import/Configuration/ImportConfigFactory.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -use PrestaShop\PrestaShop\Core\Import\ImportSettings; -use Symfony\Component\HttpFoundation\Request; - -/** - * Class ImportConfigFactory describes an import configuration factory. - */ -final class ImportConfigFactory implements ImportConfigFactoryInterface -{ - /** - * {@inheritdoc} - */ - public function buildFromRequest(Request $request) - { - $separator = $request->request->get( - 'separator', - $request->getSession()->get('separator', ImportSettings::DEFAULT_SEPARATOR) - ); - - $multivalueSeparator = $request->request->get( - 'multiple_value_separator', - $request->getSession()->get('multiple_value_separator', ImportSettings::DEFAULT_MULTIVALUE_SEPARATOR) - ); - - return new ImportConfig( - $request->request->get('csv', $request->getSession()->get('csv')), - $request->request->getInt('entity', $request->getSession()->get('entity', 0)), - $request->request->get('iso_lang', $request->getSession()->get('iso_lang')), - $separator, - $multivalueSeparator, - $request->request->getBoolean('truncate', $request->getSession()->get('truncate', false)), - $request->request->getBoolean('regenerate', $request->getSession()->get('regenerate', false)), - $request->request->getBoolean('match_ref', $request->getSession()->get('match_ref', false)), - $request->request->getBoolean('forceIDs', $request->getSession()->get('forceIDs', false)), - $request->request->getBoolean('sendemail', $request->getSession()->get('sendemail', true)), - $request->request->getInt('skip', 0) - ); - } -} diff --git a/src/Core/Import/Configuration/ImportConfigFactoryInterface.php b/src/Core/Import/Configuration/ImportConfigFactoryInterface.php deleted file mode 100644 index e8e4a388..00000000 --- a/src/Core/Import/Configuration/ImportConfigFactoryInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -use Symfony\Component\HttpFoundation\Request; - -/** - * Interface ImportConfigFactoryInterface defines an import configuration factory. - */ -interface ImportConfigFactoryInterface -{ - /** - * Build import configuration VO out of form data. - * - * @param Request $request - * - * @return ImportConfigInterface - */ - public function buildFromRequest(Request $request); -} diff --git a/src/Core/Import/Configuration/ImportConfigInterface.php b/src/Core/Import/Configuration/ImportConfigInterface.php deleted file mode 100644 index 89dc5081..00000000 --- a/src/Core/Import/Configuration/ImportConfigInterface.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -/** - * Interface ImportConfigInterface describes an import configuration VO. - */ -interface ImportConfigInterface -{ - /** - * Get the import file name. - * - * @return string - */ - public function getFileName(); - - /** - * Get the import entity type. - * - * @see constants defined in \PrestaShop\PrestaShop\Core\Import\Entity for available types. - * - * @return int - */ - public function getEntityType(); - - /** - * Get import language ISO code. - * - * @return string - */ - public function getLanguageIso(); - - /** - * Get import file's separator. - * - * @return string - */ - public function getSeparator(); - - /** - * Get import file's multiple value separator. - * - * @return string - */ - public function getMultipleValueSeparator(); - - /** - * Should the entity data be truncated before import. - * - * @return bool - */ - public function truncate(); - - /** - * Should skip the thumbnail regeneration after import. - * - * @return bool - */ - public function skipThumbnailRegeneration(); - - /** - * Should the product reference be used as import primary key. - * - * @return bool - */ - public function matchReferences(); - - /** - * Should the IDs from import file be used as-is. - * - * @return bool - */ - public function forceIds(); - - /** - * Should the system send a confirmation email when the import operation completes. - * - * @return bool - */ - public function sendEmail(); - - /** - * Get number of rows to skip from the beginning of import file. - * - * @return int - */ - public function getNumberOfRowsToSkip(); -} diff --git a/src/Core/Import/Configuration/ImportRuntimeConfig.php b/src/Core/Import/Configuration/ImportRuntimeConfig.php deleted file mode 100644 index ba1f1ae1..00000000 --- a/src/Core/Import/Configuration/ImportRuntimeConfig.php +++ /dev/null @@ -1,257 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -/** - * Class ImportRuntimeConfig defines import runtime configuration. - */ -final class ImportRuntimeConfig implements ImportRuntimeConfigInterface -{ - /** - * @var bool - */ - private $shouldValidateData; - - /** - * @var int - */ - private $offset; - - /** - * @var int - */ - private $limit; - - /** - * @var array import entity fields mapping - */ - private $entityFields; - - /** - * @var array - */ - private $sharedData = []; - - /** - * @var int - */ - private $stepIndex; - - /** - * @var int - */ - private $processedRows = 0; - - /** - * @var int request size in bytes - */ - private $requestSize; - - /** - * @var int post size limit in bytes - */ - private $postSizeLimit; - - /** - * @var int total number of rows to be imported - */ - private $totalNumberOfRows; - - /** - * @var array - */ - private $notices; - - /** - * @var array - */ - private $warnings; - - /** - * @var array - */ - private $errors; - - /** - * @param bool $shouldValidateData - * @param int $offset - * @param int $limit - * @param array $sharedData - * @param array $entityFields - */ - public function __construct( - $shouldValidateData, - $offset, - $limit, - array $sharedData, - array $entityFields - ) { - $this->shouldValidateData = $shouldValidateData; - $this->offset = $offset; - $this->limit = $limit; - $this->entityFields = $entityFields; - $this->sharedData = $sharedData; - } - - /** - * {@inheritdoc} - */ - public function shouldValidateData() - { - return $this->shouldValidateData; - } - - /** - * {@inheritdoc} - */ - public function getOffset() - { - return $this->offset; - } - - /** - * {@inheritdoc} - */ - public function getLimit() - { - return $this->limit; - } - - /** - * {@inheritdoc} - */ - public function getEntityFields() - { - return $this->entityFields; - } - - /** - * {@inheritdoc} - */ - public function getSharedData() - { - return $this->sharedData; - } - - /** - * {@inheritdoc} - */ - public function addSharedDataItem($key, $value) - { - $this->sharedData[$key] = $value; - } - - /** - * {@inheritdoc} - */ - public function isFinished() - { - return $this->processedRows < $this->limit; - } - - /** - * {@inheritdoc} - */ - public function setNumberOfProcessedRows($number) - { - $this->processedRows = $number; - } - - /** - * {@inheritdoc} - */ - public function getNumberOfProcessedRows() - { - return $this->processedRows; - } - - /** - * {@inheritdoc} - */ - public function setRequestSizeInBytes($size) - { - $this->requestSize = $size; - } - - /** - * {@inheritdoc} - */ - public function setPostSizeLimitInBytes($size) - { - $this->postSizeLimit = $size; - } - - /** - * {@inheritdoc} - */ - public function setTotalNumberOfRows($number) - { - $this->totalNumberOfRows = $number; - } - - /** - * {@inheritdoc} - */ - public function setNotices(array $notices) - { - $this->notices = $notices; - } - - /** - * {@inheritdoc} - */ - public function setWarnings(array $warnings) - { - $this->warnings = $warnings; - } - - /** - * {@inheritdoc} - */ - public function setErrors(array $errors) - { - $this->errors = $errors; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - return [ - 'crossStepsVariables' => $this->sharedData, - 'doneCount' => $this->processedRows + $this->offset, - 'isFinished' => $this->isFinished(), - 'nextPostSize' => $this->requestSize, - 'postSizeLimit' => $this->postSizeLimit, - 'totalCount' => $this->totalNumberOfRows, - 'notices' => $this->notices, - 'warnings' => $this->warnings, - 'errors' => $this->errors, - ]; - } -} diff --git a/src/Core/Import/Configuration/ImportRuntimeConfigFactory.php b/src/Core/Import/Configuration/ImportRuntimeConfigFactory.php deleted file mode 100644 index cc3c5ce5..00000000 --- a/src/Core/Import/Configuration/ImportRuntimeConfigFactory.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -use Symfony\Component\HttpFoundation\Request; - -/** - * Class ImportRuntimeConfigFactory is responsible for building import runtime config. - */ -final class ImportRuntimeConfigFactory implements ImportRuntimeConfigFactoryInterface -{ - /** - * {@inheritdoc} - */ - public function buildFromRequest(Request $request) - { - $sharedData = $request->request->get('crossStepsVars', []); - - return new ImportRuntimeConfig( - $request->request->getBoolean('validateOnly'), - $request->request->getInt('offset'), - $request->request->getInt('limit'), - json_decode($sharedData, true), - $request->request->get('type_value', []) - ); - } -} diff --git a/src/Core/Import/Configuration/ImportRuntimeConfigFactoryInterface.php b/src/Core/Import/Configuration/ImportRuntimeConfigFactoryInterface.php deleted file mode 100644 index 668ba108..00000000 --- a/src/Core/Import/Configuration/ImportRuntimeConfigFactoryInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -use Symfony\Component\HttpFoundation\Request; - -/** - * Interface ImportRuntimeConfigFactoryInterface describes an import runtime config factory. - */ -interface ImportRuntimeConfigFactoryInterface -{ - /** - * Build runtime config object out of request. - * - * @param Request $request - * - * @return ImportRuntimeConfigInterface - */ - public function buildFromRequest(Request $request); -} diff --git a/src/Core/Import/Configuration/ImportRuntimeConfigInterface.php b/src/Core/Import/Configuration/ImportRuntimeConfigInterface.php deleted file mode 100644 index 778e147f..00000000 --- a/src/Core/Import/Configuration/ImportRuntimeConfigInterface.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Configuration; - -/** - * Interface ImportRuntimeConfigInterface describes import runtime configuration. - * Since import is a multi-process operation, this configuration can change - * during each import process. - */ -interface ImportRuntimeConfigInterface -{ - /** - * Checks if import should validate the data instead of importing it. - * - * @return bool - */ - public function shouldValidateData(); - - /** - * Get current import offset. - * Works similarly to SQL offset. - * - * @return int - */ - public function getOffset(); - - /** - * Get current import limit. - * Similar to SQL limit. - * - * @return int - */ - public function getLimit(); - - /** - * Get the data, that is shared between import processes. - * - * @return array - */ - public function getSharedData(); - - /** - * Add a shared data item. - * - * @param string $key - * @param mixed $value - */ - public function addSharedDataItem($key, $value); - - /** - * Get import entity fields. - * - * @return array - */ - public function getEntityFields(); - - /** - * Get number of rows processed in current import iteration. - * - * @return int - */ - public function getNumberOfProcessedRows(); - - /** - * Check if the import is completely finished. - * - * @return bool - */ - public function isFinished(); - - /** - * Set number of rows processed during import process runtime. - * - * @param int $number - */ - public function setNumberOfProcessedRows($number); - - /** - * Set request size in bytes. - * - * @param int $size - */ - public function setRequestSizeInBytes($size); - - /** - * Set post size limit in bytes. - * - * @param int $size - */ - public function setPostSizeLimitInBytes($size); - - /** - * Set the total number of rows to be imported. - * - * @param $number - */ - public function setTotalNumberOfRows($number); - - /** - * Set notices that occurred during the import process. - * - * @param array $notices - * - * @return array - */ - public function setNotices(array $notices); - - /** - * Set warnings that occurred during the import process. - * - * @param array $warnings - * - * @return array - */ - public function setWarnings(array $warnings); - - /** - * Set errors that occurred during the import process. - * - * @param array $errors - * - * @return array - */ - public function setErrors(array $errors); - - /** - * Convert object to an array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Import/CsvValueSeparatorNormalizer.php b/src/Core/Import/CsvValueSeparatorNormalizer.php deleted file mode 100644 index 126d2869..00000000 --- a/src/Core/Import/CsvValueSeparatorNormalizer.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -/** - * Class CsvValueSeparatorNormalizer normalizes import separator before usage. - */ -final class CsvValueSeparatorNormalizer implements StringNormalizerInterface -{ - /** - * {@inheritdoc} - */ - public function normalize($value) - { - $value = trim($value); - $value = substr($value, 0, 1); - - return $value ?: ImportSettings::DEFAULT_SEPARATOR; - } -} diff --git a/src/Core/Import/Entity.php b/src/Core/Import/Entity.php deleted file mode 100644 index 3d0df9ea..00000000 --- a/src/Core/Import/Entity.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportTypeException; - -/** - * Class Entity defines available import entities. - */ -final class Entity -{ - const TYPE_CATEGORIES = 0; - const TYPE_PRODUCTS = 1; - const TYPE_COMBINATIONS = 2; - const TYPE_CUSTOMERS = 3; - const TYPE_ADDRESSES = 4; - const TYPE_MANUFACTURERS = 5; - const TYPE_SUPPLIERS = 6; - const TYPE_ALIAS = 7; - const TYPE_STORE_CONTACTS = 8; - - const AVAILABLE_TYPES = [ - 'categories' => self::TYPE_CATEGORIES, - 'products' => self::TYPE_PRODUCTS, - 'combinations' => self::TYPE_COMBINATIONS, - 'customers' => self::TYPE_CUSTOMERS, - 'addresses' => self::TYPE_ADDRESSES, - 'manufacturers' => self::TYPE_MANUFACTURERS, - 'suppliers' => self::TYPE_SUPPLIERS, - 'alias' => self::TYPE_ALIAS, - 'contacts' => self::TYPE_STORE_CONTACTS, - ]; - - /** - * Get import entity type from name. - * - * @param string $importType - * - * @return string - */ - public static function getFromName($importType) - { - if (array_key_exists($importType, self::AVAILABLE_TYPES)) { - return self::AVAILABLE_TYPES[$importType]; - } - - throw new NotSupportedImportTypeException(sprintf('Import type with name "%s" is not supported.', $importType)); - } - - /** - * Class is not supposed to be initialized. - */ - private function __construct() - { - } -} diff --git a/src/Core/Import/Entity/ImportEntityDeleterInterface.php b/src/Core/Import/Entity/ImportEntityDeleterInterface.php deleted file mode 100644 index ebc54f9c..00000000 --- a/src/Core/Import/Entity/ImportEntityDeleterInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Entity; - -/** - * Interface ImportEntityDeleterInterface describes an import entity deleter. - */ -interface ImportEntityDeleterInterface -{ - /** - * Delete all import entity data for given import entity type. - * - * @param int $importEntity - */ - public function deleteAll($importEntity); -} diff --git a/src/Core/Import/EntityField/EntityField.php b/src/Core/Import/EntityField/EntityField.php deleted file mode 100644 index 9eb73aa1..00000000 --- a/src/Core/Import/EntityField/EntityField.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField; - -/** - * Class EntityField defines an entity field. - */ -final class EntityField implements EntityFieldInterface -{ - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $label; - - /** - * @var string - */ - private $description; - - /** - * @var bool - */ - private $required; - - /** - * @param string $name - * @param string $label - * @param string $description - * @param bool $required - */ - public function __construct($name, $label, $description = '', $required = false) - { - $this->name = $name; - $this->label = $label; - $this->description = $description; - $this->required = $required; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * Get field's label. - * - * @return string - */ - public function getLabel() - { - return $this->label; - } - - /** - * Get field's description. - * - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * {@inheritdoc} - */ - public function isRequired() - { - return $this->required; - } -} diff --git a/src/Core/Import/EntityField/EntityFieldCollection.php b/src/Core/Import/EntityField/EntityFieldCollection.php deleted file mode 100644 index c1ecb315..00000000 --- a/src/Core/Import/EntityField/EntityFieldCollection.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField; - -use ArrayIterator; - -/** - * Class EntityFieldCollection defines an entity field collection. - */ -final class EntityFieldCollection implements EntityFieldCollectionInterface -{ - /** - * @var array - */ - private $entityFields = []; - - /** - * {@inheritdoc} - */ - public function addEntityField(EntityFieldInterface $entityField) - { - $this->entityFields[] = $entityField; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getRequiredFields() - { - $requiredFields = []; - - /** @var EntityFieldInterface $entityField */ - foreach ($this->entityFields as $entityField) { - if ($entityField->isRequired()) { - $requiredFields[] = $entityField->getName(); - } - } - - return $requiredFields; - } - - /** - * {@inheritdoc} - */ - public function toArray() - { - $array = []; - - /** @var EntityFieldInterface $entityField */ - foreach ($this->entityFields as $entityField) { - $array[] = [ - 'label' => $entityField->getLabel(), - 'description' => $entityField->getDescription(), - 'required' => $entityField->isRequired(), - ]; - } - - return $array; - } - - /** - * {@inheritdoc} - */ - public static function createFromArray(array $entityFields) - { - $collection = new self(); - - foreach ($entityFields as $entityField) { - $collection->addEntityField($entityField); - } - - return $collection; - } - - /** - * {@inheritdoc} - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->entityFields); - } - - /** - * {@inheritdoc} - */ - public function offsetGet($offset) - { - return $this->entityFields[$offset]; - } - - /** - * {@inheritdoc} - */ - public function offsetSet($offset, $value) - { - $this->entityFields[$offset] = $value; - } - - /** - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - unset($this->entityFields[$offset]); - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - return new ArrayIterator($this->entityFields); - } - - /** - * {@inheritdoc} - */ - public function count() - { - return count($this->entityFields); - } -} diff --git a/src/Core/Import/EntityField/EntityFieldCollectionInterface.php b/src/Core/Import/EntityField/EntityFieldCollectionInterface.php deleted file mode 100644 index 36d29911..00000000 --- a/src/Core/Import/EntityField/EntityFieldCollectionInterface.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField; - -use ArrayAccess; -use Countable; -use IteratorAggregate; - -/** - * Interface EntityFieldCollectionInterface describes a collection of entity fields. - */ -interface EntityFieldCollectionInterface extends ArrayAccess, Countable, IteratorAggregate -{ - /** - * Add an entity field to the collection. - * - * @param EntityFieldInterface $entityField - * - * @return self - */ - public function addEntityField(EntityFieldInterface $entityField); - - /** - * Get required fields from the collection. - * - * @return array - */ - public function getRequiredFields(); - - /** - * Creates a collection from array of entity fields. - * - * @param array $entityFields array of objects implementing EntityFieldInterface - * - * @return self - */ - public static function createFromArray(array $entityFields); - - /** - * Converts the collection to array. - * - * @return array - */ - public function toArray(); -} diff --git a/src/Core/Import/EntityField/EntityFieldInterface.php b/src/Core/Import/EntityField/EntityFieldInterface.php deleted file mode 100644 index f1854c9e..00000000 --- a/src/Core/Import/EntityField/EntityFieldInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField; - -/** - * Interface EntityFieldInterface describes an entity field. - */ -interface EntityFieldInterface -{ - /** - * Get field's name. - * - * @return string - */ - public function getName(); - - /** - * Get field's label. - * - * @return string - */ - public function getLabel(); - - /** - * Get field's description. - * - * @return string - */ - public function getDescription(); - - /** - * Checks if the field is required. - * - * @return bool - */ - public function isRequired(); -} diff --git a/src/Core/Import/EntityField/Provider/AddressFieldsProvider.php b/src/Core/Import/EntityField/Provider/AddressFieldsProvider.php deleted file mode 100644 index 120ab228..00000000 --- a/src/Core/Import/EntityField/Provider/AddressFieldsProvider.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class AddressFieldsProvider defines an address fields provider. - */ -final class AddressFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('alias', $this->trans('Alias', 'Admin.Shopparameters.Feature'), '', true), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('customer_email', $this->trans('Customer email', 'Admin.Advparameters.Feature'), '', true), - new EntityField('id_customer', $this->trans('Customer ID', 'Admin.Advparameters.Feature')), - new EntityField('manufacturer', $this->trans('Brand', 'Admin.Global')), - new EntityField('supplier', $this->trans('Supplier', 'Admin.Global')), - new EntityField('company', $this->trans('Company', 'Admin.Global')), - new EntityField('lastname', $this->trans('Last name', 'Admin.Global'), '', true), - new EntityField('firstname', $this->trans('First name', 'Admin.Global'), '', true), - new EntityField('address1', $this->trans('Address', 'Admin.Global'), '', true), - new EntityField('address2', $this->trans('Address (2)', 'Admin.Global')), - new EntityField('postcode', $this->trans('Zip/postal code', 'Admin.Global'), '', true), - new EntityField('city', $this->trans('City', 'Admin.Global'), '', true), - new EntityField('country', $this->trans('Country', 'Admin.Global'), '', true), - new EntityField('state', $this->trans('State', 'Admin.Global')), - new EntityField('other', $this->trans('Other', 'Admin.Global')), - new EntityField('phone', $this->trans('Phone', 'Admin.Global')), - new EntityField('phone_mobile', $this->trans('Mobile Phone', 'Admin.Global')), - new EntityField('vat_number', $this->trans('VAT number', 'Admin.Orderscustomers.Feature')), - new EntityField('dni', $this->trans('Identification number', 'Admin.Orderscustomers.Feature')), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/AliasFieldsProvider.php b/src/Core/Import/EntityField/Provider/AliasFieldsProvider.php deleted file mode 100644 index 4008104b..00000000 --- a/src/Core/Import/EntityField/Provider/AliasFieldsProvider.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class AliasFieldsProvider defines an alias fields provider. - */ -final class AliasFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('alias', $this->trans('Alias', 'Admin.Shopparameters.Feature'), '', true), - new EntityField('search', $this->trans('Search', 'Admin.Shopparameters.Feature'), '', true), - new EntityField('active', $this->trans('Active', 'Admin.Global')), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/CategoryFieldsProvider.php b/src/Core/Import/EntityField/Provider/CategoryFieldsProvider.php deleted file mode 100644 index 6205d1ce..00000000 --- a/src/Core/Import/EntityField/Provider/CategoryFieldsProvider.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CategoryFieldsProvider defines a category fields provider. - */ -final class CategoryFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('name', $this->trans('Name', 'Admin.Global')), - new EntityField('parent', $this->trans('Parent category', 'Admin.Catalog.Feature')), - new EntityField( - 'is_root_category', - $this->trans('Root category (0/1)', 'Admin.Advparameters.Feature'), - $this->trans('A category root is where a category tree can begin. This is used with multistore.', 'Admin.Advparameters.Help') - ), - new EntityField('description', $this->trans('Description', 'Admin.Global')), - new EntityField('meta_title', $this->trans('Meta title', 'Admin.Global')), - new EntityField('meta_keywords', $this->trans('Meta keywords', 'Admin.Global')), - new EntityField('meta_description', $this->trans('Meta description', 'Admin.Global')), - new EntityField('link_rewrite', $this->trans('Rewritten URL', 'Admin.Shopparameters.Feature')), - new EntityField('image', $this->trans('Image URL', 'Admin.Advparameters.Feature')), - new EntityField( - 'shop', - $this->trans('ID / Name of shop', 'Admin.Advparameters.Feature'), - $this->trans('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', 'Admin.Advparameters.Help') - ), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/CombinationFieldsProvider.php b/src/Core/Import/EntityField/Provider/CombinationFieldsProvider.php deleted file mode 100644 index 12b1af56..00000000 --- a/src/Core/Import/EntityField/Provider/CombinationFieldsProvider.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CombinationFieldsProvider defines a combination fields provider. - */ -final class CombinationFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id_product', $this->trans('Product ID', 'Admin.Advparameters.Feature')), - new EntityField('product_reference', $this->trans('Product reference', 'Admin.Advparameters.Feature')), - new EntityField('group', $this->trans('Attribute (Name:Type:Position)', 'Admin.Advparameters.Feature'), '', true), - new EntityField('attribute', $this->trans('Value (Value:Position)', 'Admin.Advparameters.Feature'), '', true), - new EntityField('supplier_reference', $this->trans('Supplier reference', 'Admin.Advparameters.Feature')), - new EntityField('reference', $this->trans('Reference', 'Admin.Global')), - new EntityField('ean13', $this->trans('EAN13', 'Admin.Advparameters.Feature')), - new EntityField('upc', $this->trans('UPC', 'Admin.Advparameters.Feature')), - new EntityField('mpn', $this->trans('MPN', 'Admin.Catalog.Feature')), - new EntityField('wholesale_price', $this->trans('Cost price', 'Admin.Catalog.Feature')), - new EntityField('price', $this->trans('Impact on price', 'Admin.Catalog.Feature')), - new EntityField('ecotax', $this->trans('Ecotax', 'Admin.Catalog.Feature')), - new EntityField('quantity', $this->trans('Quantity', 'Admin.Global')), - new EntityField('minimal_quantity', $this->trans('Minimal quantity', 'Admin.Advparameters.Feature')), - new EntityField('low_stock_threshold', $this->trans('Low stock level', 'Admin.Catalog.Feature')), - new EntityField( - 'low_stock_alert', - $this->trans('Send me an email when the quantity is under this level', 'Admin.Catalog.Feature') - ), - new EntityField('weight', $this->trans('Impact on weight', 'Admin.Catalog.Feature')), - new EntityField('default_on', $this->trans('Default (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('available_date', $this->trans('Combination availability date', 'Admin.Advparameters.Feature')), - new EntityField('image_position', $this->trans('Choose among product images by position (1,2,3...)', 'Admin.Advparameters.Feature')), - new EntityField('image_url', $this->trans('Image URLs (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('image_alt', $this->trans('Image alt texts (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField( - 'shop', - $this->trans('ID / Name of shop', 'Admin.Advparameters.Feature'), - $this->trans('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', 'Admin.Advparameters.Help') - ), - new EntityField( - 'advanced_stock_management', - $this->trans('Advanced Stock Management', 'Admin.Advparameters.Feature'), - $this->trans('Enable Advanced Stock Management on product (0 = No, 1 = Yes)', 'Admin.Advparameters.Help') - ), - new EntityField( - 'depends_on_stock', - $this->trans('Depends on stock', 'Admin.Advparameters.Feature'), - $this->trans('0 = Use quantity set in product, 1 = Use quantity from warehouse.', 'Admin.Advparameters.Help') - ), - new EntityField( - 'warehouse', - $this->trans('Warehouse', 'Admin.Advparameters.Feature'), - $this->trans('ID of the warehouse to set as storage.', 'Admin.Advparameters.Help') - ), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/CustomerFieldsProvider.php b/src/Core/Import/EntityField/Provider/CustomerFieldsProvider.php deleted file mode 100644 index c265604c..00000000 --- a/src/Core/Import/EntityField/Provider/CustomerFieldsProvider.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class CustomerFieldsProvider defines a customer fields provider. - */ -final class CustomerFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('id_gender', $this->trans('Titles ID (Mr = 1, Ms = 2, else 0)', 'Admin.Advparameters.Feature')), - new EntityField('email', $this->trans('Email', 'Admin.Global'), '', true), - new EntityField('passwd', $this->trans('Password', 'Admin.Global'), '', true), - new EntityField('birthday', $this->trans('Birth date (yyyy-mm-dd)', 'Admin.Advparameters.Feature')), - new EntityField('lastname', $this->trans('Last name', 'Admin.Global'), '', true), - new EntityField('firstname', $this->trans('First name', 'Admin.Global'), '', true), - new EntityField('newsletter', $this->trans('Newsletter (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('optin', $this->trans('Partner offers (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('date_add', $this->trans('Registration date (yyyy-mm-dd)', 'Admin.Advparameters.Feature')), - new EntityField('group', $this->trans('Groups (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('id_default_group', $this->trans('Default group ID', 'Admin.Advparameters.Feature')), - new EntityField( - 'id_shop', - $this->trans('ID / Name of shop', 'Admin.Advparameters.Feature'), - $this->trans('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', 'Admin.Advparameters.Help') - ), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinder.php b/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinder.php deleted file mode 100644 index 25796905..00000000 --- a/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinder.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportEntityException; - -/** - * Class EntityFieldsProviderFinder defines an entity fields provider finder. - */ -final class EntityFieldsProviderFinder implements EntityFieldsProviderFinderInterface -{ - /** - * @var array of entity fields providers - */ - private $entityFieldsProviders; - - /** - * @param array $entityFieldsProviders - */ - public function __construct(array $entityFieldsProviders) - { - $this->entityFieldsProviders = $entityFieldsProviders; - } - - /** - * {@inheritdoc} - */ - public function find($importEntity) - { - if (!isset($this->entityFieldsProviders[$importEntity])) { - throw new NotSupportedImportEntityException("Entity fields provider does not exist for entity $importEntity."); - } - - return $this->entityFieldsProviders[$importEntity]; - } -} diff --git a/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinderInterface.php b/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinderInterface.php deleted file mode 100644 index 5aefc1ae..00000000 --- a/src/Core/Import/EntityField/Provider/EntityFieldsProviderFinderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -/** - * Interface EntityFieldsProviderFinderInterface describes an entity fields finder. - */ -interface EntityFieldsProviderFinderInterface -{ - /** - * Find the appropriate entity fields provider. - * - * @param int $importEntity import entity ID (@see PrestaShop\PrestaShop\Core\Import\Entity) - * - * @return EntityFieldsProviderInterface - */ - public function find($importEntity); -} diff --git a/src/Core/Import/EntityField/Provider/EntityFieldsProviderInterface.php b/src/Core/Import/EntityField/Provider/EntityFieldsProviderInterface.php deleted file mode 100644 index c86ab17d..00000000 --- a/src/Core/Import/EntityField/Provider/EntityFieldsProviderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollectionInterface; - -/** - * Interface EntityFieldsProviderInterface defines a provider of entity fields. - */ -interface EntityFieldsProviderInterface -{ - /** - * Get entity field as a collection. - * - * @return EntityFieldCollectionInterface - */ - public function getCollection(); -} diff --git a/src/Core/Import/EntityField/Provider/ProductFieldsProvider.php b/src/Core/Import/EntityField/Provider/ProductFieldsProvider.php deleted file mode 100644 index 979ecf97..00000000 --- a/src/Core/Import/EntityField/Provider/ProductFieldsProvider.php +++ /dev/null @@ -1,193 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class ProductFieldsProvider defines a product fields provider. - */ -final class ProductFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('name', $this->trans('Name', 'Admin.Global')), - new EntityField('category', $this->trans('Categories (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('price_tex', $this->trans('Price tax excluded', 'Admin.Advparameters.Feature')), - new EntityField('price_tin', $this->trans('Price tax included', 'Admin.Advparameters.Feature')), - new EntityField('id_tax_rules_group', $this->trans('Tax rule ID', 'Admin.Advparameters.Feature')), - new EntityField('wholesale_price', $this->trans('Cost price', 'Admin.Catalog.Feature')), - new EntityField('on_sale', $this->trans('On sale (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('reduction_price', $this->trans('Discount amount', 'Admin.Advparameters.Feature')), - new EntityField('reduction_percent', $this->trans('Discount percent', 'Admin.Advparameters.Feature')), - new EntityField('reduction_from', $this->trans('Discount from (yyyy-mm-dd)', 'Admin.Advparameters.Feature')), - new EntityField('reduction_to', $this->trans('Discount to (yyyy-mm-dd)', 'Admin.Advparameters.Feature')), - new EntityField('reference', $this->trans('Reference #', 'Admin.Advparameters.Feature')), - new EntityField('supplier_reference', $this->trans('Supplier reference #', 'Admin.Advparameters.Feature')), - new EntityField('supplier', $this->trans('Supplier', 'Admin.Global')), - new EntityField('manufacturer', $this->trans('Brand', 'Admin.Global')), - new EntityField('ean13', $this->trans('EAN13', 'Admin.Advparameters.Feature')), - new EntityField('upc', $this->trans('UPC', 'Admin.Advparameters.Feature')), - new EntityField('mpn', $this->trans('MPN', 'Admin.Catalog.Feature')), - new EntityField('ecotax', $this->trans('Ecotax', 'Admin.Catalog.Feature')), - new EntityField('width', $this->trans('Width', 'Admin.Global')), - new EntityField('height', $this->trans('Height', 'Admin.Global')), - new EntityField('depth', $this->trans('Depth', 'Admin.Global')), - new EntityField('weight', $this->trans('Weight', 'Admin.Global')), - new EntityField( - 'delivery_in_stock', - $this->trans('Delivery time of in-stock products:', 'Admin.Catalog.Feature') - ), - new EntityField( - 'delivery_out_stock', - $this->trans('Delivery time of out-of-stock products with allowed orders:', 'Admin.Advparameters.Feature') - ), - new EntityField('quantity', $this->trans('Quantity', 'Admin.Global')), - new EntityField('minimal_quantity', $this->trans('Minimal quantity', 'Admin.Advparameters.Feature')), - new EntityField('low_stock_threshold', $this->trans('Low stock level', 'Admin.Catalog.Feature')), - new EntityField( - 'low_stock_alert', - $this->trans('Send me an email when the quantity is under this level', 'Admin.Catalog.Feature') - ), - new EntityField('visibility', $this->trans('Visibility', 'Admin.Catalog.Feature')), - new EntityField('additional_shipping_cost', $this->trans('Additional shipping cost', 'Admin.Advparameters.Feature')), - new EntityField('unity', $this->trans('Unit for the price per unit', 'Admin.Advparameters.Feature')), - new EntityField('unit_price', $this->trans('Price per unit', 'Admin.Advparameters.Feature')), - new EntityField('description_short', $this->trans('Summary', 'Admin.Catalog.Feature')), - new EntityField('description', $this->trans('Description', 'Admin.Global')), - new EntityField('tags', $this->trans('Tags (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('meta_title', $this->trans('Meta title', 'Admin.Global')), - new EntityField('meta_keywords', $this->trans('Meta keywords', 'Admin.Global')), - new EntityField('meta_description', $this->trans('Meta description', 'Admin.Global')), - new EntityField('link_rewrite', $this->trans('Rewritten URL', 'Admin.Advparameters.Feature')), - new EntityField('available_now', $this->trans('Label when in stock', 'Admin.Catalog.Feature')), - new EntityField('available_later', $this->trans('Label when backorder allowed', 'Admin.Advparameters.Feature')), - new EntityField('available_for_order', $this->trans('Available for order (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('available_date', $this->trans('Product availability date', 'Admin.Advparameters.Feature')), - new EntityField('date_add', $this->trans('Product creation date', 'Admin.Advparameters.Feature')), - new EntityField('show_price', $this->trans('Show price (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('image', $this->trans('Image URLs (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('image_alt', $this->trans('Image alt texts (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('delete_existing_images', $this->trans('Delete existing images (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('features', $this->trans('Feature (Name:Value:Position:Customized)', 'Admin.Advparameters.Feature')), - new EntityField('online_only', $this->trans('Available online only (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('condition', $this->trans('Condition', 'Admin.Catalog.Feature')), - new EntityField('customizable', $this->trans('Customizable (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('uploadable_files', $this->trans('Uploadable files (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('text_fields', $this->trans('Text fields (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('out_of_stock', $this->trans('Action when out of stock', 'Admin.Advparameters.Feature')), - new EntityField('is_virtual', $this->trans('Virtual product (0 = No, 1 = Yes)', 'Admin.Advparameters.Feature')), - new EntityField('file_url', $this->trans('File URL', 'Admin.Advparameters.Feature')), - new EntityField( - 'nb_downloadable', - $this->trans('Number of allowed downloads', 'Admin.Catalog.Feature'), - $this->trans( - 'Number of days this file can be accessed by customers. Set to zero for unlimited access.', - 'Admin.Catalog.Help' - ) - ), - new EntityField('date_expiration', $this->trans('Expiration date (yyyy-mm-dd)', 'Admin.Advparameters.Feature')), - new EntityField( - 'nb_days_accessible', - $this->trans('Number of days', 'Admin.Advparameters.Feature'), - $this->trans( - 'Number of days this file can be accessed by customers. Set to zero for unlimited access.', - 'Admin.Catalog.Help' - ) - ), - new EntityField( - 'shop', - $this->trans('ID / Name of shop', 'Admin.Advparameters.Feature'), - $this->trans( - 'Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', - 'Admin.Advparameters.Help' - ) - ), - new EntityField( - 'advanced_stock_management', - $this->trans('Advanced Stock Management', 'Admin.Advparameters.Feature'), - $this->trans( - 'Enable Advanced Stock Management on product (0 = No, 1 = Yes).', - 'Admin.Advparameters.Help' - ) - ), - new EntityField( - 'depends_on_stock', - $this->trans('Depends on stock', 'Admin.Advparameters.Feature'), - $this->trans( - '0 = Use quantity set in product, 1 = Use quantity from warehouse.', - 'Admin.Advparameters.Help' - ) - ), - new EntityField( - 'warehouse', - $this->trans('Warehouse', 'Admin.Advparameters.Feature'), - $this->trans( - 'ID of the warehouse to set as storage.', - 'Admin.Advparameters.Help' - ) - ), - new EntityField('accessories', $this->trans('Accessories (x,y,z...)', 'Admin.Advparameters.Feature')), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/StoreContactFieldsProvider.php b/src/Core/Import/EntityField/Provider/StoreContactFieldsProvider.php deleted file mode 100644 index ed0474ba..00000000 --- a/src/Core/Import/EntityField/Provider/StoreContactFieldsProvider.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class StoreContactFieldCollectionFactory defines a store contact fields provider. - */ -final class StoreContactFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('name', $this->trans('Name', 'Admin.Global')), - new EntityField('address1', $this->trans('Address', 'Admin.Global'), '', true), - new EntityField('address2', $this->trans('Address (2)', 'Admin.Advparameters.Feature')), - new EntityField('postcode', $this->trans('Zip/postal code', 'Admin.Global')), - new EntityField('state', $this->trans('State', 'Admin.Global')), - new EntityField('city', $this->trans('City', 'Admin.Global'), '', true), - new EntityField('country', $this->trans('Country', 'Admin.Global'), '', true), - new EntityField('latitude', $this->trans('Latitude', 'Admin.Advparameters.Feature'), '', true), - new EntityField('longitude', $this->trans('Longitude', 'Admin.Advparameters.Feature'), '', true), - new EntityField('phone', $this->trans('Phone', 'Admin.Global')), - new EntityField('fax', $this->trans('Fax', 'Admin.Global')), - new EntityField('email', $this->trans('Email address', 'Admin.Global')), - new EntityField('note', $this->trans('Note', 'Admin.Global')), - new EntityField('hours', $this->trans('Hours (x,y,z...)', 'Admin.Advparameters.Feature')), - new EntityField('image', $this->trans('Image URL', 'Admin.Advparameters.Feature')), - new EntityField( - 'shop', - $this->trans('ID / Name of shop', 'Admin.Advparameters.Feature'), - $this->trans('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', 'Admin.Advparameters.Help') - ), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/EntityField/Provider/SupplierFieldsProvider.php b/src/Core/Import/EntityField/Provider/SupplierFieldsProvider.php deleted file mode 100644 index b6a82088..00000000 --- a/src/Core/Import/EntityField/Provider/SupplierFieldsProvider.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\EntityField\Provider; - -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityField; -use PrestaShop\PrestaShop\Core\Import\EntityField\EntityFieldCollection; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class SupplierFieldsProvider defines a supplier fields provider. - */ -final class SupplierFieldsProvider implements EntityFieldsProviderInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function getCollection() - { - $fields = [ - new EntityField('id', $this->trans('ID', 'Admin.Global')), - new EntityField('active', $this->trans('Active (0/1)', 'Admin.Advparameters.Feature')), - new EntityField('name', $this->trans('Name', 'Admin.Global')), - new EntityField('description', $this->trans('Description', 'Admin.Global')), - new EntityField('short_description', $this->trans('Short description', 'Admin.Catalog.Feature')), - new EntityField('meta_title', $this->trans('Meta title', 'Admin.Global')), - new EntityField('meta_keywords', $this->trans('Meta keywords', 'Admin.Global')), - new EntityField('meta_description', $this->trans('Meta description', 'Admin.Global')), - new EntityField('image', $this->trans('Image URL', 'Admin.Advparameters.Feature')), - new EntityField( - 'shop', - $this->trans('ID / Name of group shop', 'Admin.Advparameters.Feature'), - $this->trans('Ignore this field if you don\'t use the Multistore tool. If you leave this field empty, the default shop will be used.', 'Admin.Advparameters.Help') - ), - ]; - - return EntityFieldCollection::createFromArray($fields); - } - - /** - * A shorter name method for translations. - * - * @param string $id translation ID - * @param string $domain translation domain - * - * @return string - */ - private function trans($id, $domain = 'Admin.Advparameters.Feature') - { - return $this->translator->trans($id, [], $domain); - } -} diff --git a/src/Core/Import/Exception/EmptyDataRowException.php b/src/Core/Import/Exception/EmptyDataRowException.php deleted file mode 100644 index 4308b4d8..00000000 --- a/src/Core/Import/Exception/EmptyDataRowException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class EmptyDataRowException thrown when the import handler finds an empty data row. - */ -class EmptyDataRowException extends InvalidDataRowException -{ -} diff --git a/src/Core/Import/Exception/ImportException.php b/src/Core/Import/Exception/ImportException.php deleted file mode 100644 index a753ee86..00000000 --- a/src/Core/Import/Exception/ImportException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class ImportException is extended by all import exceptions. - */ -class ImportException extends CoreException -{ -} diff --git a/src/Core/Import/Exception/InvalidDataRowException.php b/src/Core/Import/Exception/InvalidDataRowException.php deleted file mode 100644 index bdb7098d..00000000 --- a/src/Core/Import/Exception/InvalidDataRowException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class InvalidDataRowException thrown when import handler encounters an invalid data row. - */ -class InvalidDataRowException extends ImportException -{ -} diff --git a/src/Core/Import/Exception/NotSupportedImportEntityException.php b/src/Core/Import/Exception/NotSupportedImportEntityException.php deleted file mode 100644 index 2ed4480c..00000000 --- a/src/Core/Import/Exception/NotSupportedImportEntityException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class NotSupportedImportEntityException is thrown when not supported import entity is provided. - */ -class NotSupportedImportEntityException extends ImportException -{ -} diff --git a/src/Core/Import/Exception/NotSupportedImportTypeException.php b/src/Core/Import/Exception/NotSupportedImportTypeException.php deleted file mode 100644 index 6e1867f2..00000000 --- a/src/Core/Import/Exception/NotSupportedImportTypeException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class NotSupportedImportTypeException is thrown when no supported import type is provided. - */ -class NotSupportedImportTypeException extends ImportException -{ -} diff --git a/src/Core/Import/Exception/SkippedIterationException.php b/src/Core/Import/Exception/SkippedIterationException.php deleted file mode 100644 index 45d2946b..00000000 --- a/src/Core/Import/Exception/SkippedIterationException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class SkippedIterationException thrown when an import iteration is skipped. - */ -class SkippedIterationException extends ImportException -{ -} diff --git a/src/Core/Import/Exception/UnavailableImportFileException.php b/src/Core/Import/Exception/UnavailableImportFileException.php deleted file mode 100644 index ac4de276..00000000 --- a/src/Core/Import/Exception/UnavailableImportFileException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class UnavailableImportFileException thrown when import file is not available. - */ -class UnavailableImportFileException extends ImportException -{ -} diff --git a/src/Core/Import/Exception/UnreadableFileException.php b/src/Core/Import/Exception/UnreadableFileException.php deleted file mode 100644 index 8659a13e..00000000 --- a/src/Core/Import/Exception/UnreadableFileException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Exception; - -/** - * Class UnreadableFileException is thrown when the import file cannot be read. - */ -class UnreadableFileException extends ImportException -{ -} diff --git a/src/Core/Import/File/CsvFileReader.php b/src/Core/Import/File/CsvFileReader.php deleted file mode 100644 index fa279b24..00000000 --- a/src/Core/Import/File/CsvFileReader.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use PrestaShop\PrestaShop\Core\Import\Exception\UnreadableFileException; -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRow; -use SplFileInfo; - -/** - * Class CsvFileReader defines a CSV file reader. - */ -final class CsvFileReader implements FileReaderInterface -{ - /** - * @var string the data delimiter in the CSV row - */ - private $delimiter; - - /** - * @var int - */ - private $length; - - /** - * @var string - */ - private $enclosure; - - /** - * @var string - */ - private $escape; - - /** - * @var FileOpenerInterface - */ - private $fileOpener; - - /** - * @param FileOpenerInterface $fileOpener - * @param string $delimiter - * @param int $length - * @param string $enclosure - * @param string $escape - */ - public function __construct( - FileOpenerInterface $fileOpener, - $delimiter = ';', - $length = 0, - $enclosure = '"', - $escape = '\\' - ) { - $this->delimiter = $delimiter; - $this->length = $length; - $this->enclosure = $enclosure; - $this->escape = $escape; - $this->fileOpener = $fileOpener; - } - - /** - * {@inheritdoc} - */ - public function read(SplFileInfo $file) - { - if (!$file->isReadable()) { - throw new UnreadableFileException(); - } - - $convertToUtf8 = !mb_check_encoding(file_get_contents($file), 'UTF-8'); - $handle = $this->fileOpener->open($file); - - while ($row = fgetcsv($handle, $this->length, $this->delimiter, $this->enclosure, $this->escape)) { - if ($convertToUtf8) { - $row = array_map('utf8_encode', $row); - } - - yield DataRow::createFromArray($row); - } - - fclose($handle); - } -} diff --git a/src/Core/Import/File/DataCell/DataCell.php b/src/Core/Import/File/DataCell/DataCell.php deleted file mode 100644 index 62b0d719..00000000 --- a/src/Core/Import/File/DataCell/DataCell.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataCell; - -/** - * Class DataCell defines a data cell of imported file. - */ -final class DataCell implements DataCellInterface -{ - /** - * @var string key of the data - */ - private $key; - - /** - * @var string data value - */ - private $value; - - /** - * @param string $key - * @param string $value - */ - public function __construct($key, $value) - { - $this->key = $key; - $this->value = $value; - } - - /** - * {@inheritdoc} - */ - public function getValue() - { - return $this->value; - } - - /** - * {@inheritdoc} - */ - public function getKey() - { - return $this->key; - } -} diff --git a/src/Core/Import/File/DataCell/DataCellInterface.php b/src/Core/Import/File/DataCell/DataCellInterface.php deleted file mode 100644 index 845b4963..00000000 --- a/src/Core/Import/File/DataCell/DataCellInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataCell; - -/** - * Interface DataCellInterface describes a data cell from imported file. - */ -interface DataCellInterface -{ - /** - * Get the value of the cell. - * - * @return string - */ - public function getValue(); - - /** - * Get the key of the cell. - * - * @return string - */ - public function getKey(); -} diff --git a/src/Core/Import/File/DataCell/EmptyDataCell.php b/src/Core/Import/File/DataCell/EmptyDataCell.php deleted file mode 100644 index df877861..00000000 --- a/src/Core/Import/File/DataCell/EmptyDataCell.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataCell; - -/** - * Class EmptyDataCell defines an empty data cell. - */ -final class EmptyDataCell implements DataCellInterface -{ - /** - * {@inheritdoc} - */ - public function getValue() - { - return ''; - } - - /** - * {@inheritdoc} - */ - public function getKey() - { - return ''; - } -} diff --git a/src/Core/Import/File/DataRow/DataRow.php b/src/Core/Import/File/DataRow/DataRow.php deleted file mode 100644 index 9c9c6924..00000000 --- a/src/Core/Import/File/DataRow/DataRow.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use ArrayIterator; -use PrestaShop\PrestaShop\Core\Import\File\DataCell\DataCell; -use PrestaShop\PrestaShop\Core\Import\File\DataCell\DataCellInterface; - -/** - * Class DataRow defines a basic data row of imported file. - */ -final class DataRow implements DataRowInterface -{ - /** - * @var DataCellInterface[] - */ - private $cells = []; - - /** - * {@inheritdoc} - */ - public function addCell(DataCellInterface $cell) - { - $this->cells[] = $cell; - - return $this; - } - - /** - * {@inheritdoc} - */ - public static function createFromArray(array $data) - { - $row = new self(); - - foreach ($data as $key => $value) { - $row->addCell(new DataCell($key, $value)); - } - - return $row; - } - - /** - * {@inheritdoc} - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->cells); - } - - /** - * {@inheritdoc} - */ - public function offsetGet($offset) - { - return $this->cells[$offset]; - } - - /** - * {@inheritdoc} - */ - public function offsetSet($offset, $value) - { - $this->cells[$offset] = $value; - } - - /** - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - unset($this->cells[$offset]); - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - return new ArrayIterator($this->cells); - } - - /** - * {@inheritdoc} - */ - public function count() - { - return count($this->cells); - } - - /** - * {@inheritdoc} - */ - public function isEmpty() - { - if (0 === count($this->cells)) { - return true; - } - - foreach ($this->cells as $cell) { - // If at least one cell is not empty - the row is not empty. - if ('' !== $cell->getValue()) { - return false; - } - } - - return true; - } -} diff --git a/src/Core/Import/File/DataRow/DataRowCollection.php b/src/Core/Import/File/DataRow/DataRowCollection.php deleted file mode 100644 index fa78b69e..00000000 --- a/src/Core/Import/File/DataRow/DataRowCollection.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use ArrayIterator; - -/** - * Class DataRowCollection defines a collection of data rows. - */ -final class DataRowCollection implements DataRowCollectionInterface -{ - /** - * @var array of DataRowInterface objects - */ - private $dataRows = []; - - /** - * {@inheritdoc} - */ - public function addDataRow(DataRowInterface $dataRow) - { - $this->dataRows[] = $dataRow; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function offsetExists($offset) - { - return array_key_exists($offset, $this->dataRows); - } - - /** - * {@inheritdoc} - */ - public function offsetGet($offset) - { - if (!$this->offsetExists($offset)) { - return null; - } - - return $this->dataRows[$offset]; - } - - /** - * {@inheritdoc} - */ - public function offsetSet($offset, $value) - { - $this->dataRows[$offset] = $value; - } - - /** - * {@inheritdoc} - */ - public function offsetUnset($offset) - { - unset($this->dataRows[$offset]); - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - return new ArrayIterator($this->dataRows); - } - - /** - * {@inheritdoc} - */ - public function getLargestRowSize() - { - $maxSize = 0; - - foreach ($this->dataRows as $dataRow) { - $maxSize = max($maxSize, count($dataRow)); - } - - return $maxSize; - } -} diff --git a/src/Core/Import/File/DataRow/DataRowCollectionInterface.php b/src/Core/Import/File/DataRow/DataRowCollectionInterface.php deleted file mode 100644 index 23af846d..00000000 --- a/src/Core/Import/File/DataRow/DataRowCollectionInterface.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use ArrayAccess; -use IteratorAggregate; - -/** - * Interface DataRowCollectionInterface describes a collection of data rows. - */ -interface DataRowCollectionInterface extends ArrayAccess, IteratorAggregate -{ - /** - * Add a data row to this collection. - * - * @param DataRowInterface $dataRow - * - * @return self - */ - public function addDataRow(DataRowInterface $dataRow); - - /** - * Get the number of cells in the largest row of collection. - * - * @return int - */ - public function getLargestRowSize(); -} diff --git a/src/Core/Import/File/DataRow/DataRowCollectionPresenter.php b/src/Core/Import/File/DataRow/DataRowCollectionPresenter.php deleted file mode 100644 index f4fba730..00000000 --- a/src/Core/Import/File/DataRow/DataRowCollectionPresenter.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use PrestaShop\PrestaShop\Core\Import\File\DataCell\EmptyDataCell; - -/** - * Class DataRowCollectionPresenter presents a data row collection. - */ -final class DataRowCollectionPresenter implements DataRowCollectionPresenterInterface -{ - /** - * @var DataRowPresenterInterface - */ - private $dataRowPresenter; - - /** - * @param DataRowPresenterInterface $dataRowPresenter - */ - public function __construct(DataRowPresenterInterface $dataRowPresenter) - { - $this->dataRowPresenter = $dataRowPresenter; - } - - /** - * {@inheritdoc} - */ - public function present(DataRowCollectionInterface $dataRowCollection) - { - $presentedCollection = [ - 'rows' => [], - 'row_size' => $dataRowCollection->getLargestRowSize(), - ]; - - /** @var DataRowInterface $dataRow */ - foreach ($dataRowCollection as $dataRow) { - $this->normalizeDataRow($dataRow, $dataRowCollection->getLargestRowSize()); - $presentedCollection['rows'][] = $this->dataRowPresenter->present($dataRow); - } - - return $presentedCollection; - } - - /** - * Normalize the data row by adding empty data cells until the expected row size is reached. - * This allows all rows to be equal in size. - * - * @param DataRowInterface $dataRow - * @param int $expectedRowSize number of columns this row will reach - */ - private function normalizeDataRow(DataRowInterface $dataRow, $expectedRowSize) - { - while (count($dataRow) < $expectedRowSize) { - $dataRow->addCell(new EmptyDataCell()); - } - } -} diff --git a/src/Core/Import/File/DataRow/DataRowCollectionPresenterInterface.php b/src/Core/Import/File/DataRow/DataRowCollectionPresenterInterface.php deleted file mode 100644 index 683985ea..00000000 --- a/src/Core/Import/File/DataRow/DataRowCollectionPresenterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -/** - * Interface DataRowCollectionPresenterInterface describes a data row collection presenter. - */ -interface DataRowCollectionPresenterInterface -{ - /** - * Present a data row collection into array. - * - * @param DataRowCollectionInterface $dataRowCollection - * - * @return array - */ - public function present(DataRowCollectionInterface $dataRowCollection); -} diff --git a/src/Core/Import/File/DataRow/DataRowInterface.php b/src/Core/Import/File/DataRow/DataRowInterface.php deleted file mode 100644 index 4de74ed1..00000000 --- a/src/Core/Import/File/DataRow/DataRowInterface.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use ArrayAccess; -use Countable; -use IteratorAggregate; -use PrestaShop\PrestaShop\Core\Import\File\DataCell\DataCellInterface; - -/** - * Interface DataRowInterface describes a data row from imported file. - */ -interface DataRowInterface extends ArrayAccess, IteratorAggregate, Countable -{ - /** - * Add a cell to this row. - * - * @param DataCellInterface $cell - * - * @return self - */ - public function addCell(DataCellInterface $cell); - - /** - * Create a data row from given array. - * - * @param array $data - * - * @return self - */ - public static function createFromArray(array $data); - - /** - * @param mixed $offset - * - * @return DataCellInterface - */ - public function offsetGet($offset); - - /** - * Check if the row is empty. - * - * @return bool - */ - public function isEmpty(); -} diff --git a/src/Core/Import/File/DataRow/DataRowPresenter.php b/src/Core/Import/File/DataRow/DataRowPresenter.php deleted file mode 100644 index 10d26282..00000000 --- a/src/Core/Import/File/DataRow/DataRowPresenter.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -use PrestaShop\PrestaShop\Core\Import\File\DataCell\DataCellInterface; - -/** - * Class DataRowPresenter defines a data row presenter. - */ -final class DataRowPresenter implements DataRowPresenterInterface -{ - /** - * {@inheritdoc} - */ - public function present(DataRowInterface $dataRow) - { - $presentedRow = []; - - /** @var DataCellInterface $dataCell */ - foreach ($dataRow as $dataCell) { - $presentedRow[] = [ - 'value' => $dataCell->getValue(), - ]; - } - - return $presentedRow; - } -} diff --git a/src/Core/Import/File/DataRow/DataRowPresenterInterface.php b/src/Core/Import/File/DataRow/DataRowPresenterInterface.php deleted file mode 100644 index 81f18a4e..00000000 --- a/src/Core/Import/File/DataRow/DataRowPresenterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow; - -/** - * Interface DataRowPresenterInterface describes a data row presenter. - */ -interface DataRowPresenterInterface -{ - /** - * Present a data row. - * - * @param DataRowInterface $dataRow - * - * @return array - */ - public function present(DataRowInterface $dataRow); -} diff --git a/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactory.php b/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactory.php deleted file mode 100644 index 9fd2a117..00000000 --- a/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactory.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow\Factory; - -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowCollection; -use PrestaShop\PrestaShop\Core\Import\File\FileReaderInterface; -use SplFileInfo; - -/** - * Class DataRowCollectionFactory defines a data row collection factory. - */ -final class DataRowCollectionFactory implements DataRowCollectionFactoryInterface -{ - /** - * @var FileReaderInterface - */ - private $fileReader; - - /** - * @param FileReaderInterface $fileReader - */ - public function __construct(FileReaderInterface $fileReader) - { - $this->fileReader = $fileReader; - } - - /** - * {@inheritdoc} - */ - public function buildFromFile(SplFileInfo $file, $maxRowsInCollection = null) - { - $dataRowCollection = new DataRowCollection(); - $rowIndex = 0; - - foreach ($this->fileReader->read($file) as $dataRow) { - if (null !== $maxRowsInCollection && $rowIndex >= $maxRowsInCollection) { - break; - } - - $dataRowCollection->addDataRow($dataRow); - ++$rowIndex; - } - - return $dataRowCollection; - } -} diff --git a/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactoryInterface.php b/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactoryInterface.php deleted file mode 100644 index 634f64c0..00000000 --- a/src/Core/Import/File/DataRow/Factory/DataRowCollectionFactoryInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File\DataRow\Factory; - -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowCollectionInterface; -use SplFileInfo; - -/** - * Interface DataRowCollectionFactoryInterface describes a data row collection factory. - */ -interface DataRowCollectionFactoryInterface -{ - /** - * Builds a data row collection. - * - * @param SplFileInfo $file - * @param int $maxRowsInCollection maximum number of rows this collection can have. Unlimited if not provided. - * - * @return DataRowCollectionInterface - */ - public function buildFromFile(SplFileInfo $file, $maxRowsInCollection = null); -} diff --git a/src/Core/Import/File/FileFinder.php b/src/Core/Import/File/FileFinder.php deleted file mode 100644 index 4ef48285..00000000 --- a/src/Core/Import/File/FileFinder.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use PrestaShop\PrestaShop\Core\Import\ImportDirectory; -use Symfony\Component\Finder\Finder; - -/** - * Class responsible for finding import files. - */ -final class FileFinder -{ - /** - * @var ImportDirectory - */ - private $importDirectory; - - public function __construct(ImportDirectory $importDirectory) - { - $this->importDirectory = $importDirectory; - } - - /** - * Get import file names in import directory. - * - * @return array|string[] - */ - public function getImportFileNames() - { - if (!$this->importDirectory->isReadable()) { - return []; - } - - $finder = new Finder(); - $finder - ->files() - ->in($this->importDirectory->getDir()) - ->notName('/^index\.php/i'); - - $fileNames = []; - - foreach ($finder as $file) { - $fileNames[] = $file->getFilename(); - } - - return $fileNames; - } -} diff --git a/src/Core/Import/File/FileOpenerInterface.php b/src/Core/Import/File/FileOpenerInterface.php deleted file mode 100644 index f3fc6f75..00000000 --- a/src/Core/Import/File/FileOpenerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use SplFileInfo; - -/** - * Interface FileOpenerInterface describes an import file opener. - */ -interface FileOpenerInterface -{ - /** - * @param SplFileInfo $file - * - * @return mixed file handle - */ - public function open(SplFileInfo $file); -} diff --git a/src/Core/Import/File/FileReaderInterface.php b/src/Core/Import/File/FileReaderInterface.php deleted file mode 100644 index e157b5ee..00000000 --- a/src/Core/Import/File/FileReaderInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use Generator; -use PrestaShop\PrestaShop\Core\Import\Exception\UnreadableFileException; -use SplFileInfo; - -/** - * Interface FileReaderInterface describes a file reader. - */ -interface FileReaderInterface -{ - /** - * Read the file. - * - * @param SplFileInfo $file - * - * @return Generator - * - * @throws UnreadableFileException - */ - public function read(SplFileInfo $file); -} diff --git a/src/Core/Import/File/FileRemoval.php b/src/Core/Import/File/FileRemoval.php deleted file mode 100644 index 12cb5d11..00000000 --- a/src/Core/Import/File/FileRemoval.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use PrestaShop\PrestaShop\Core\Import\ImportDirectory; -use Symfony\Component\Filesystem\Filesystem; - -/** - * FileRemoval is responsible for deleting import files. - */ -final class FileRemoval -{ - /** - * @var ImportDirectory - */ - private $importDirectory; - - public function __construct(ImportDirectory $importDirectory) - { - $this->importDirectory = $importDirectory; - } - - /** - * Remove file from import directory. - * - * @param $filename - */ - public function remove($filename) - { - $fs = new Filesystem(); - $fs->remove($this->importDirectory . $filename); - } -} diff --git a/src/Core/Import/File/FileUploader.php b/src/Core/Import/File/FileUploader.php deleted file mode 100644 index 73341f60..00000000 --- a/src/Core/Import/File/FileUploader.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\File; - -use PrestaShop\PrestaShop\Core\Import\ImportDirectory; -use PrestaShopBundle\Exception\FileUploadException; -use Symfony\Component\HttpFoundation\File\Exception\FileException; -use Symfony\Component\HttpFoundation\File\File; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * FileUploader is responsible for uploading import files to import directory. - */ -final class FileUploader -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ImportDirectory - */ - private $importDirectory; - - /** - * @param TranslatorInterface $translator - * @param ImportDirectory $importDirectory - */ - public function __construct( - TranslatorInterface $translator, - ImportDirectory $importDirectory - ) { - $this->translator = $translator; - $this->importDirectory = $importDirectory; - } - - /** - * Handle import file uploading to admin import/ directory. - * - * @param UploadedFile $uploadedFile - * - * @return File - * - * @throws FileUploadException - */ - public function upload(UploadedFile $uploadedFile) - { - if ($error = $this->validateUploadedFile($uploadedFile)) { - throw new FileUploadException($error); - } - - $uploadedFileName = sprintf( - '%s-%s', - date('YmdHis'), - $uploadedFile->getClientOriginalName() - ); - - try { - $file = $uploadedFile->move( - $this->importDirectory, - $uploadedFileName - ); - } catch (FileException $e) { - $error = $this->translator->trans('An error occurred while uploading / copying the file.', [], 'Admin.Advparameters.Notification'); - - throw new FileUploadException($error); - } - - return $file; - } - - /** - * Check if uploaded file is valid. - * - * @param UploadedFile $uploadedFile - * - * @return string|false Returns error string on error or FALSE otherwise - */ - protected function validateUploadedFile(UploadedFile $uploadedFile) - { - $error = false; - - switch ($uploadedFile->getError()) { - case UPLOAD_ERR_INI_SIZE: - $error = $this->translator->trans('The uploaded file exceeds the upload_max_filesize directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess.', [], 'Admin.Advparameters.Notification'); - - break; - case UPLOAD_ERR_FORM_SIZE: - $message = $this->translator->trans('The uploaded file exceeds the post_max_size directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess, for example:', [], 'Admin.Advparameters.Notification'); - $error = sprintf('%s %s', $message, 'php_value post_max_size 20M'); - - break; - case UPLOAD_ERR_PARTIAL: - $error = $this->translator->trans('The uploaded file was only partially uploaded.', [], 'Admin.Advparameters.Notification'); - - break; - case UPLOAD_ERR_NO_FILE: - $error = $this->translator->trans('No file was uploaded.', [], 'Admin.Advparameters.Notification'); - - break; - } - - if ($error) { - return $error; - } - - if (!preg_match('#([^\.]*?)\.(csv|xls[xt]?|o[dt]s)$#is', $uploadedFile->getClientOriginalName())) { - $error = $this->translator->trans('The extension of your file should be .csv.', [], 'Admin.Advparameters.Notification'); - } - - return $error; - } -} diff --git a/src/Core/Import/Handler/ImportHandlerFinderInterface.php b/src/Core/Import/Handler/ImportHandlerFinderInterface.php deleted file mode 100644 index 40d20c59..00000000 --- a/src/Core/Import/Handler/ImportHandlerFinderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Handler; - -/** - * Interface ImportHandlerFinderInterface describes an import handler finder. - */ -interface ImportHandlerFinderInterface -{ - /** - * Find the proper import handler for given entity type. - * - * @param $importEntityType - * - * @return ImportHandlerInterface - */ - public function find($importEntityType); -} diff --git a/src/Core/Import/Handler/ImportHandlerInterface.php b/src/Core/Import/Handler/ImportHandlerInterface.php deleted file mode 100644 index d509ca12..00000000 --- a/src/Core/Import/Handler/ImportHandlerInterface.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Handler; - -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\EmptyDataRowException; -use PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowInterface; - -/** - * Interface ImportHandlerInterface describes an import handler. - */ -interface ImportHandlerInterface -{ - /** - * Executed before import process is started. - * - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - public function setUp(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig); - - /** - * Imports one data row. - * - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - * @param DataRowInterface $dataRow - * - * @throws EmptyDataRowException - */ - public function importRow( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - DataRowInterface $dataRow - ); - - /** - * Executed when the import process is completed. - * - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - public function tearDown(ImportConfigInterface $importConfig, ImportRuntimeConfigInterface $runtimeConfig); - - /** - * Get warning messages that occurred during import. - * - * @return array - */ - public function getWarnings(); - - /** - * Get error messages that occurred during import. - * - * @return array - */ - public function getErrors(); - - /** - * Get notice messages that occurred during import. - * - * @return array - */ - public function getNotices(); - - /** - * Check whether this import handler supports given entity type. - * - * @param int $importEntityType - * - * @return bool - */ - public function supports($importEntityType); -} diff --git a/src/Core/Import/ImportDirectory.php b/src/Core/Import/ImportDirectory.php deleted file mode 100644 index 89a70fd0..00000000 --- a/src/Core/Import/ImportDirectory.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\Filesystem\Filesystem; - -/** - * ImportDirectory class is responsible for returning import directory & data related to it. - */ -final class ImportDirectory -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * Get path to import directory. - * - * @return string - */ - public function getDir() - { - return ($this->configuration->get('_PS_HOST_MODE_') ? - $this->configuration->get('_PS_ROOT_DIR_') : - $this->configuration->get('_PS_ADMIN_DIR_')) . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR; - } - - /** - * Check if import directory exists. - * - * @return bool - */ - public function exists() - { - return (new Filesystem())->exists($this->getDir()); - } - - /** - * Check if import directory is writable. - * - * @return bool - */ - public function isWritable() - { - return is_writable($this->getDir()); - } - - /** - * Check if import directory is readable. - * - * @return bool - */ - public function isReadable() - { - return is_readable($this->getDir()); - } - - /** - * Use import directory object as a string. - * - * @return string - */ - public function __toString() - { - return $this->getDir(); - } -} diff --git a/src/Core/Import/ImportSettings.php b/src/Core/Import/ImportSettings.php deleted file mode 100644 index c19834a6..00000000 --- a/src/Core/Import/ImportSettings.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -/** - * Class ImportSettings provides import constants to be used in import pages. - */ -final class ImportSettings -{ - /** - * Default value separator. - */ - const DEFAULT_SEPARATOR = ';'; - - /** - * Default multiple value separator. - */ - const DEFAULT_MULTIVALUE_SEPARATOR = ','; - - /** - * Maximum number of columns that are visible in the import matches configuration page. - */ - const MAX_VISIBLE_COLUMNS = 6; - - /** - * Maximum number of rows that are visible in the import matces configuration page. - */ - const MAX_VISIBLE_ROWS = 10; - - /** - * This class cannot be instantiated. - */ - private function __construct() - { - } -} diff --git a/src/Core/Import/Importer.php b/src/Core/Import/Importer.php deleted file mode 100644 index 7316e621..00000000 --- a/src/Core/Import/Importer.php +++ /dev/null @@ -1,238 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -use PrestaShop\PrestaShop\Core\Configuration\IniConfiguration; -use PrestaShop\PrestaShop\Core\Import\Access\ImportAccessCheckerInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Entity\ImportEntityDeleterInterface; -use PrestaShop\PrestaShop\Core\Import\Exception\InvalidDataRowException; -use PrestaShop\PrestaShop\Core\Import\Exception\SkippedIterationException; -use PrestaShop\PrestaShop\Core\Import\File\FileReaderInterface; -use PrestaShop\PrestaShop\Core\Import\Handler\ImportHandlerInterface; -use SplFileInfo; - -/** - * Class Importer is responsible for data import. - */ -final class Importer implements ImporterInterface -{ - /** - * @var ImportEntityDeleterInterface - */ - private $entityDeleter; - - /** - * @var ImportAccessCheckerInterface - */ - private $accessChecker; - - /** - * @var FileReaderInterface - */ - private $fileReader; - - /** - * @var ImportDirectory - */ - private $importDir; - - /** - * @var IniConfiguration - */ - private $iniConfiguration; - - /** - * @param ImportAccessCheckerInterface $accessChecker - * @param ImportEntityDeleterInterface $entityDeleter - * @param FileReaderInterface $fileReader - * @param ImportDirectory $importDir - * @param IniConfiguration $iniConfiguration - */ - public function __construct( - ImportAccessCheckerInterface $accessChecker, - ImportEntityDeleterInterface $entityDeleter, - FileReaderInterface $fileReader, - ImportDirectory $importDir, - IniConfiguration $iniConfiguration - ) { - $this->entityDeleter = $entityDeleter; - $this->accessChecker = $accessChecker; - $this->fileReader = $fileReader; - $this->importDir = $importDir; - $this->iniConfiguration = $iniConfiguration; - } - - /** - * {@inheritdoc} - */ - public function import( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - ImportHandlerInterface $importHandler - ) { - $this->setUp($importHandler, $importConfig, $runtimeConfig); - - $importFile = new SplFileInfo($this->importDir . $importConfig->getFileName()); - - // Current row index - $rowIndex = 0; - - // Number of rows processed during import process. - $processedRows = 0; - - // Total number of importable rows in the whole file. - $totalNumberOfRows = 0; - - $skipRows = $importConfig->getNumberOfRowsToSkip() + $runtimeConfig->getOffset(); - $limit = $runtimeConfig->getLimit() + $skipRows; - $isFirstIteration = $this->isFirstIteration($runtimeConfig); - - foreach ($this->fileReader->read($importFile) as $dataRow) { - if ($isFirstIteration) { - ++$totalNumberOfRows; - } - - // Skip rows until the correct row is reached. - if ($rowIndex < $skipRows) { - ++$rowIndex; - continue; - } - - // If import process limit is reached - stop importing the rows. - if ($rowIndex >= $limit) { - // On the first iteration we need to continue counting the number of rows - if ($isFirstIteration) { - continue; - } - break; - } - - try { - // Import one row - $importHandler->importRow( - $importConfig, - $runtimeConfig, - $dataRow - ); - } catch (InvalidDataRowException $e) { - continue; - } catch (SkippedIterationException $e) { - continue; - } finally { - ++$processedRows; - ++$rowIndex; - } - } - - // Calculate total number of rows only in the first import iteration. - if ($isFirstIteration && $runtimeConfig->shouldValidateData()) { - $runtimeConfig->setTotalNumberOfRows($totalNumberOfRows - $skipRows); - } - - $runtimeConfig->setNumberOfProcessedRows($processedRows); - - $this->tearDown($importHandler, $importConfig, $runtimeConfig); - } - - /** - * Checks if data should be truncated. - * Data should be truncated only when it's not validation step - * and it's the first batch of the first process of the import. - * - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - * - * @return bool - */ - public function shouldTruncateData( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig - ) { - return - $importConfig->truncate() && - !$runtimeConfig->shouldValidateData() && - $this->isFirstIteration($runtimeConfig) - ; - } - - /** - * Checks if current import iteration is the first. - * - * @param ImportRuntimeConfigInterface $runtimeConfig - * - * @return bool - */ - private function isFirstIteration(ImportRuntimeConfigInterface $runtimeConfig) - { - return 0 === $runtimeConfig->getOffset(); - } - - /** - * Set the import process up. - * - * @param ImportHandlerInterface $importHandler - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - private function setUp( - ImportHandlerInterface $importHandler, - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig - ) { - if ($this->shouldTruncateData($importConfig, $runtimeConfig) && $this->accessChecker->canTruncateData()) { - $this->entityDeleter->deleteAll($importConfig->getEntityType()); - } - - $importHandler->setUp($importConfig, $runtimeConfig); - } - - /** - * Tear the import process down. - * - * @param ImportHandlerInterface $importHandler - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - */ - private function tearDown( - ImportHandlerInterface $importHandler, - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig - ) { - $importHandler->tearDown($importConfig, $runtimeConfig); - - // Calculating shared data size and adding some extra bytes for other values. - $runtimeConfig->setRequestSizeInBytes( - mb_strlen(json_encode($runtimeConfig->getSharedData())) + 1024 * 64 - ); - $runtimeConfig->setPostSizeLimitInBytes($this->iniConfiguration->getUploadMaxSizeInBytes()); - $runtimeConfig->setNotices($importHandler->getNotices()); - $runtimeConfig->setWarnings($importHandler->getWarnings()); - $runtimeConfig->setErrors($importHandler->getErrors()); - } -} diff --git a/src/Core/Import/ImporterInterface.php b/src/Core/Import/ImporterInterface.php deleted file mode 100644 index 293af782..00000000 --- a/src/Core/Import/ImporterInterface.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigInterface; -use PrestaShop\PrestaShop\Core\Import\Handler\ImportHandlerInterface; - -/** - * Interface ImporterInterface describes an import processing unit. - */ -interface ImporterInterface -{ - /** - * Process the import. - * - * @param ImportConfigInterface $importConfig - * @param ImportRuntimeConfigInterface $runtimeConfig - * @param ImportHandlerInterface $importHandler - * - * @return - */ - public function import( - ImportConfigInterface $importConfig, - ImportRuntimeConfigInterface $runtimeConfig, - ImportHandlerInterface $importHandler - ); -} diff --git a/src/Core/Import/Sample/SampleFileProvider.php b/src/Core/Import/Sample/SampleFileProvider.php deleted file mode 100644 index 1f40689d..00000000 --- a/src/Core/Import/Sample/SampleFileProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Sample; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException; -use Symfony\Component\HttpFoundation\File\File; - -/** - * Class SampleFileProvider is responsible for providing sample import files. - */ -final class SampleFileProvider implements SampleFileProviderInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getFile($sampleFileName) - { - $path = $this->configuration->get('_PS_ROOT_DIR_') . - DIRECTORY_SEPARATOR . - 'docs' . - DIRECTORY_SEPARATOR . - 'csv_import' . - DIRECTORY_SEPARATOR; - - try { - $sampleFile = new File($path . $sampleFileName . '.csv'); - } catch (FileNotFoundException $e) { - return null; - } - - return $sampleFile; - } -} diff --git a/src/Core/Import/Sample/SampleFileProviderInterface.php b/src/Core/Import/Sample/SampleFileProviderInterface.php deleted file mode 100644 index 0243531b..00000000 --- a/src/Core/Import/Sample/SampleFileProviderInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Sample; - -use Symfony\Component\HttpFoundation\File\File; - -/** - * Interface SampleFileProviderInterface defines contract for sample import file provider. - */ -interface SampleFileProviderInterface -{ - /** - * Get sample import file. - * - * @param string $sampleFileName - * - * @return File|null File if files was found or null otherwise - */ - public function getFile($sampleFileName); -} diff --git a/src/Core/Import/StringNormalizerInterface.php b/src/Core/Import/StringNormalizerInterface.php deleted file mode 100644 index 116f9d9f..00000000 --- a/src/Core/Import/StringNormalizerInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import; - -/** - * Interface StringNormalizerInterface describes a string normalizer. - */ -interface StringNormalizerInterface -{ - /** - * Normalizes a string value. - * - * @param string $value - * - * @return string normalized string - */ - public function normalize($value); -} diff --git a/src/Core/Import/Validator/ImportRequestValidator.php b/src/Core/Import/Validator/ImportRequestValidator.php deleted file mode 100644 index 7a92d8dc..00000000 --- a/src/Core/Import/Validator/ImportRequestValidator.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Validator; - -use PrestaShop\PrestaShop\Core\Import\Exception\UnavailableImportFileException; -use Symfony\Component\HttpFoundation\Request; - -/** - * Class ImportRequestValidator is responsible for validating import request. - */ -final class ImportRequestValidator implements ImportRequestValidatorInterface -{ - /** - * {@inheritdoc} - */ - public function validate(Request $request) - { - if (!$request->request->has('csv')) { - throw new UnavailableImportFileException(); - } - } -} diff --git a/src/Core/Import/Validator/ImportRequestValidatorInterface.php b/src/Core/Import/Validator/ImportRequestValidatorInterface.php deleted file mode 100644 index a451a661..00000000 --- a/src/Core/Import/Validator/ImportRequestValidatorInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Import\Validator; - -use Symfony\Component\HttpFoundation\Request; - -/** - * Interface ImportRequestValidatorInterface describes a request validator for import process. - */ -interface ImportRequestValidatorInterface -{ - /** - * Validate a request for import. - * - * @param Request $request - */ - public function validate(Request $request); -} diff --git a/src/Core/Kpi/Exception/InvalidArgumentException.php b/src/Core/Kpi/Exception/InvalidArgumentException.php deleted file mode 100644 index 45491546..00000000 --- a/src/Core/Kpi/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Will be thrown if Kpi factory arguments are invalid. - */ -final class InvalidArgumentException extends CoreException -{ - /** - * @param mixed $kpi - * - * @return InvalidArgumentException - */ - public static function invalidKpi($kpi) - { - $exceptionMessage = sprintf( - 'Kpi must be an instance of KpiInterface, got `%s`.', - gettype($kpi) - ); - - return new self($exceptionMessage); - } - - /** - * @param mixed $identifier - * - * @return InvalidArgumentException - */ - public static function invalidIdentifier($identifier) - { - $exceptionMessage = sprintf( - 'Identifier must be a string, got `%s`.', - gettype($identifier) - ); - - return new self($exceptionMessage); - } -} diff --git a/src/Core/Kpi/KpiInterface.php b/src/Core/Kpi/KpiInterface.php deleted file mode 100644 index 56d40350..00000000 --- a/src/Core/Kpi/KpiInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi; - -/** - * Interface KpiInterface describes a KPI. - */ -interface KpiInterface extends RenderableKpi -{ -} diff --git a/src/Core/Kpi/RenderableKpi.php b/src/Core/Kpi/RenderableKpi.php deleted file mode 100644 index 718cb66d..00000000 --- a/src/Core/Kpi/RenderableKpi.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi; - -/** - * Interface RenderableKpi describes a renderable KPI. - */ -interface RenderableKpi -{ - /** - * Renders the KPI's view. - * - * @return string - */ - public function render(); -} diff --git a/src/Core/Kpi/Row/HookableKpiRowFactory.php b/src/Core/Kpi/Row/HookableKpiRowFactory.php deleted file mode 100644 index 21af7c4b..00000000 --- a/src/Core/Kpi/Row/HookableKpiRowFactory.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Kpi\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * Class KpiRowFactory builds a KPI row, able to dispatch a hook. - */ -final class HookableKpiRowFactory implements KpiRowFactoryInterface -{ - /** - * @var KpiInterface[] the list of KPIs to display - */ - private $kpis; - - /** - * @var HookDispatcherInterface the Hook Dispatcher - */ - private $hookDispatcher; - - /** - * @var string used to make the hook selectable - */ - private $identifier; - - /** - * @var array - */ - private $options = []; - - /** - * @param KpiInterface[] $kpis - * @param HookDispatcherInterface $hookDispatcher - * @param string $identifier - */ - public function __construct( - array $kpis, - HookDispatcherInterface $hookDispatcher, - $identifier - ) { - if ($this->validateKpis($kpis) && $this->validateIdentifier($identifier)) { - $this->kpis = $kpis; - $this->hookDispatcher = $hookDispatcher; - $this->identifier = $identifier; - } - } - - /** - * {@inheritdoc} - */ - public function build() - { - $kpiRow = new KpiRow($this->options); - - $this->hookDispatcher->dispatchWithParameters($this->getHookName($this->identifier), [ - 'kpis' => &$this->kpis, - ]); - - if ($this->validateKpis($this->kpis)) { - foreach ($this->kpis as $kpi) { - $kpiRow->addKpi($kpi); - } - - return $kpiRow; - } - } - - /** - * Set options for kpi row - * - * @param array $options - */ - public function setOptions(array $options) - { - $this->options = $options; - } - - /** - * @param array $kpis - * - * @return bool true if valid, else throw an exception - * - * @throws InvalidArgumentException - */ - private function validateKpis(array $kpis) - { - foreach ($kpis as $kpi) { - if (!$kpi instanceof KpiInterface) { - throw InvalidArgumentException::invalidKpi($kpi); - } - } - - return true; - } - - /** - * @param mixed $identifier - * - * @return bool true if valid, else throw an exception - * - * @throws InvalidArgumentException - */ - private function validateIdentifier($identifier) - { - if (!is_string($identifier)) { - throw InvalidArgumentException::invalidIdentifier($identifier); - } - - return true; - } - - /** - * @param string $identifier - * - * @return string - */ - private function getHookName($identifier) - { - return 'action' . ucfirst($identifier) . 'KpiRowModifier'; - } -} diff --git a/src/Core/Kpi/Row/KpiRow.php b/src/Core/Kpi/Row/KpiRow.php deleted file mode 100644 index 2d5bb73b..00000000 --- a/src/Core/Kpi/Row/KpiRow.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * Class KpiRow defines a row of KPIs. - */ -final class KpiRow implements KpiRowInterface -{ - /** - * @var bool - */ - private $allowRefresh = true; - - /** - * @var array[KpiInterface] - */ - private $kpis = []; - - /** - * @var array - */ - private $options; - - /** - * @param array $options - */ - public function __construct(array $options = []) - { - $this->options = $options; - } - - /** - * {@inheritdoc} - */ - public function addKpi(KpiInterface $kpi) - { - // setOptions() is optional & not part of interface to avoid BC break - if (method_exists($kpi, 'setOptions')) { - $kpi->setOptions($this->options); - } - - $this->kpis[] = $kpi; - } - - /** - * @return array[KpiInterface] - */ - public function getKpis() - { - return $this->kpis; - } - - /** - * @param bool $allowRefresh - */ - public function setAllowRefresh($allowRefresh) - { - $this->allowRefresh = $allowRefresh; - } - - /** - * @return bool - */ - public function isRefreshAllowed() - { - return $this->allowRefresh; - } - - /** - * @return array - */ - public function getOptions() - { - return $this->options; - } -} diff --git a/src/Core/Kpi/Row/KpiRowFactory.php b/src/Core/Kpi/Row/KpiRowFactory.php deleted file mode 100644 index ab5bc022..00000000 --- a/src/Core/Kpi/Row/KpiRowFactory.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * Class KpiRowFactory builds a KPI row. - * - * @deprecated since 1.7.6, will be removed in the next major version, use HookableKpiRowFactory instead. - */ -final class KpiRowFactory implements KpiRowFactoryInterface -{ - /** - * @var KpiInterface[] - */ - private $kpis; - - /** - * @param KpiInterface ...$kpis - */ - public function __construct(KpiInterface ...$kpis) - { - @trigger_error( - 'Using `KpiRowFactory` class is deprecated and will be removed in the next major,' . - 'use HookableKpiRowFactory instead', - E_USER_DEPRECATED - ); - - $this->kpis = $kpis; - } - - /** - * {@inheritdoc} - */ - public function build() - { - $kpiRow = new KpiRow(); - - foreach ($this->kpis as $kpi) { - $kpiRow->addKpi($kpi); - } - - return $kpiRow; - } -} diff --git a/src/Core/Kpi/Row/KpiRowFactoryInterface.php b/src/Core/Kpi/Row/KpiRowFactoryInterface.php deleted file mode 100644 index 1040acad..00000000 --- a/src/Core/Kpi/Row/KpiRowFactoryInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -/** - * Interface KpiRowFactoryInterface describes a KPI row factory. - */ -interface KpiRowFactoryInterface -{ - /** - * Builds a KPI row. - * - * @return KpiRowInterface - */ - public function build(); -} diff --git a/src/Core/Kpi/Row/KpiRowInterface.php b/src/Core/Kpi/Row/KpiRowInterface.php deleted file mode 100644 index 7558fd7b..00000000 --- a/src/Core/Kpi/Row/KpiRowInterface.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * Interface KpiRowInterface describes a KPI row. - */ -interface KpiRowInterface -{ - /** - * Add a KPI to this row. - * - * @param KpiInterface $kpi - */ - public function addKpi(KpiInterface $kpi); - - /** - * @return array[KpiInterface] - */ - public function getKpis(); - - /** - * @param bool $allowRefresh - */ - public function setAllowRefresh($allowRefresh); - - /** - * @return bool - */ - public function isRefreshAllowed(); - - /** - * @return array - */ - public function getOptions(); -} diff --git a/src/Core/Kpi/Row/KpiRowPresenter.php b/src/Core/Kpi/Row/KpiRowPresenter.php deleted file mode 100644 index 076b9a71..00000000 --- a/src/Core/Kpi/Row/KpiRowPresenter.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -use PrestaShop\PrestaShop\Core\Kpi\KpiInterface; - -/** - * Class KpiRowPresenter presents a KPI row. - */ -final class KpiRowPresenter implements KpiRowPresenterInterface -{ - /** - * {@inheritdoc} - */ - public function present(KpiRowInterface $kpiRow) - { - $renderedKpis = []; - - /** @var KpiInterface $kpi */ - foreach ($kpiRow->getKpis() as $kpi) { - $renderedKpis[] = $kpi->render($kpiRow->getOptions()); - } - - return [ - 'kpis' => $renderedKpis, - 'allowRefresh' => $kpiRow->isRefreshAllowed(), - ]; - } -} diff --git a/src/Core/Kpi/Row/KpiRowPresenterInterface.php b/src/Core/Kpi/Row/KpiRowPresenterInterface.php deleted file mode 100644 index 8ee01553..00000000 --- a/src/Core/Kpi/Row/KpiRowPresenterInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Kpi\Row; - -/** - * Interface KpiRowPresenterInterface describes a KPI row presenter. - */ -interface KpiRowPresenterInterface -{ - /** - * @param KpiRowInterface $kpiRow - * - * @return array - */ - public function present(KpiRowInterface $kpiRow); -} diff --git a/src/Core/Language/Copier/LanguageCopierConfig.php b/src/Core/Language/Copier/LanguageCopierConfig.php deleted file mode 100644 index 1dc75283..00000000 --- a/src/Core/Language/Copier/LanguageCopierConfig.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Copier; - -/** - * Class LanguageCopierConfig provides configuration for language copier. - */ -final class LanguageCopierConfig implements LanguageCopierConfigInterface -{ - /** - * @var string the theme name from which the language will be copied - */ - private $themeFrom; - - /** - * @var string the language iso code, which will be copied from - */ - private $languageFrom; - - /** - * @var string the theme name to which the language will be copied - */ - private $themeTo; - - /** - * @var string the language iso code, which will be copied to - */ - private $languageTo; - - /** - * @param string $themeFrom - * @param string $languageFrom - * @param string $themeTo - * @param string $languageTo - */ - public function __construct($themeFrom, $languageFrom, $themeTo, $languageTo) - { - $this->themeFrom = $themeFrom; - $this->languageFrom = $languageFrom; - $this->themeTo = $themeTo; - $this->languageTo = $languageTo; - } - - /** - * {@inheritdoc} - */ - public function getThemeFrom() - { - return $this->themeFrom; - } - - /** - * {@inheritdoc} - */ - public function getLanguageFrom() - { - return $this->languageFrom; - } - - /** - * {@inheritdoc} - */ - public function getThemeTo() - { - return $this->themeTo; - } - - /** - * {@inheritdoc} - */ - public function getLanguageTo() - { - return $this->languageTo; - } -} diff --git a/src/Core/Language/Copier/LanguageCopierConfigInterface.php b/src/Core/Language/Copier/LanguageCopierConfigInterface.php deleted file mode 100644 index 454b66ed..00000000 --- a/src/Core/Language/Copier/LanguageCopierConfigInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Copier; - -/** - * Interface LanguageCopierConfigInterface defines configuration, required for copying a language. - */ -interface LanguageCopierConfigInterface -{ - /** - * Get the theme name that language will be copied from. - * - * @return string - */ - public function getThemeFrom(); - - /** - * Get the language name to copy from. - * - * @return string - */ - public function getLanguageFrom(); - - /** - * Get the theme name that language will be copied to. - * - * @return string - */ - public function getThemeTo(); - - /** - * Get the language name to copy to. - * - * @return string - */ - public function getLanguageTo(); -} diff --git a/src/Core/Language/Copier/LanguageCopierInterface.php b/src/Core/Language/Copier/LanguageCopierInterface.php deleted file mode 100644 index 3fe9cc34..00000000 --- a/src/Core/Language/Copier/LanguageCopierInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Copier; - -/** - * Interface LanguageCopierInterface defines a language copier. - */ -interface LanguageCopierInterface -{ - /** - * Copies a language with given config. - * - * @param LanguageCopierConfigInterface $config - * - * @return array of errors if any occurred, empty array otherwise - */ - public function copy(LanguageCopierConfigInterface $config); -} diff --git a/src/Core/Language/LanguageActivatorInterface.php b/src/Core/Language/LanguageActivatorInterface.php deleted file mode 100644 index a924e91a..00000000 --- a/src/Core/Language/LanguageActivatorInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language; - -/** - * Interface LanguageActivatorInterface defines contract for language activator. - */ -interface LanguageActivatorInterface -{ - /** - * Activate language. - * - * @param int $langId - */ - public function enable($langId); - - /** - * Deactivate language. - * - * @param int $langId - */ - public function disable($langId); -} diff --git a/src/Core/Language/LanguageDefaultFontsCatalog.php b/src/Core/Language/LanguageDefaultFontsCatalog.php deleted file mode 100644 index 36ca1746..00000000 --- a/src/Core/Language/LanguageDefaultFontsCatalog.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language; - -/** - * Class LanguageDefaultFontsCatalog is used for languages that need a specific font to display their - * characters. This class is a catalog referencing which languages need special fonts and associate - * the appropriate font to each language. - */ -class LanguageDefaultFontsCatalog -{ - /** - * This is a non exhaustive list of language which need a specific font - * so that their characters are correctly displayed. - * - * @var array - */ - private $languageDefaultFonts = [ - 'fa' => 'Tahoma', - 'ar' => 'Tahoma', - ]; - - /** - * @param array|null $languageDefaultFonts - */ - public function __construct(array $languageDefaultFonts = null) - { - if (null !== $languageDefaultFonts) { - $this->languageDefaultFonts = $languageDefaultFonts; - } - } - - /** - * @param LanguageInterface $language - * - * @return string - */ - public function getDefaultFontByLanguage(LanguageInterface $language) - { - $isoCode = $language->getIsoCode(); - if (isset($this->languageDefaultFonts[$isoCode])) { - return $this->languageDefaultFonts[$isoCode]; - } - - return ''; - } -} diff --git a/src/Core/Language/LanguageInterface.php b/src/Core/Language/LanguageInterface.php deleted file mode 100644 index ebdbe1ad..00000000 --- a/src/Core/Language/LanguageInterface.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language; - -/** - * Interface LanguageInterface defines a language object (iso code, locale, - * if it is an RTL language, ...) - */ -interface LanguageInterface -{ - /** - * Database id - * - * @return string - */ - public function getId(); - - /** - * Explicit name of the language - * - * @return string - */ - public function getName(); - - /** - * 2-letter iso code - * - * @return string - */ - public function getIsoCode(); - - /** - * 5-letter iso code - * - * @return string - */ - public function getLocale(); - - /** - * 5-letter iso code - * - * @return string - */ - public function getLanguageCode(); - - /** - * Is the language RTL (read from right to left) - * - * @return bool - */ - public function isRTL(); -} diff --git a/src/Core/Language/LanguageRepositoryInterface.php b/src/Core/Language/LanguageRepositoryInterface.php deleted file mode 100644 index a85adcb6..00000000 --- a/src/Core/Language/LanguageRepositoryInterface.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language; - -/** - * Interface LanguageRepositoryInterface allows to fetch a LanguageInterface - * via different methods. - */ -interface LanguageRepositoryInterface -{ - /** - * Returns a LanguageInterface whose locale matches the provided one. - * - * @param string $locale - * - * @return LanguageInterface - */ - public function getOneByLocale($locale); - - /** - * Returns a LanguageInterface which isoCode matches the provided one. - * - * @param string $isoCode - * - * @return LanguageInterface - */ - public function getOneByIsoCode($isoCode); - - /** - * Returns a LanguageInterface whose locale matches the provided one, - * if no one is found try matching by isoCode (splitting the locale if - * necessary). - * - * @param string $locale - * - * @return LanguageInterface - */ - public function getOneByLocaleOrIsoCode($locale); -} diff --git a/src/Core/Language/LanguageValidatorInterface.php b/src/Core/Language/LanguageValidatorInterface.php deleted file mode 100644 index 5a50c48b..00000000 --- a/src/Core/Language/LanguageValidatorInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language; - -/** - * Interface LanguageValidatorInterface defines contract for LanguageValidator. - */ -interface LanguageValidatorInterface -{ - /** - * Checks if language is installed by comparing locale. - * - * @param string $locale - * - * @return bool - */ - public function isInstalledByLocale($locale); -} diff --git a/src/Core/Language/Pack/Import/LanguagePackImporterInterface.php b/src/Core/Language/Pack/Import/LanguagePackImporterInterface.php deleted file mode 100644 index c001a1d7..00000000 --- a/src/Core/Language/Pack/Import/LanguagePackImporterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Pack\Import; - -/** - * Interface LanguagePackImporterInterface contract for language importer. - */ -interface LanguagePackImporterInterface -{ - /** - * Imports language pack. - * - * @param string $isoCode - * - * @return array - returns array with error messages or an empty array on success case - */ - public function import($isoCode); -} diff --git a/src/Core/Language/Pack/LanguagePackInstallerInterface.php b/src/Core/Language/Pack/LanguagePackInstallerInterface.php deleted file mode 100644 index 8315dd38..00000000 --- a/src/Core/Language/Pack/LanguagePackInstallerInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Pack; - -/** - * Interface LanguagePackInstallerInterface defines contract for language pack installer. - */ -interface LanguagePackInstallerInterface -{ - /** - * Downloads and installs language pack data. - * - * @param string $iso -3166-2 alpha-2 format code - * - * @return array - if not empty then it contains errors. In another case the function - * has been executed successfully - */ - public function downloadAndInstallLanguagePack($iso); -} diff --git a/src/Core/Language/Pack/Loader/LanguagePackLoaderInterface.php b/src/Core/Language/Pack/Loader/LanguagePackLoaderInterface.php deleted file mode 100644 index b5180e91..00000000 --- a/src/Core/Language/Pack/Loader/LanguagePackLoaderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Pack\Loader; - -/** - * Interface LanguagePackLoaderInterface defines contract for language pack loader. - */ -interface LanguagePackLoaderInterface -{ - /** - * Gets language pack data. - * - * @return array - array key is the language locale and the value is language name - */ - public function getLanguagePackList(); -} diff --git a/src/Core/Language/Pack/Loader/RemoteLanguagePackLoader.php b/src/Core/Language/Pack/Loader/RemoteLanguagePackLoader.php deleted file mode 100644 index 8aec17f2..00000000 --- a/src/Core/Language/Pack/Loader/RemoteLanguagePackLoader.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\Pack\Loader; - -use PrestaShop\PrestaShop\Core\Foundation\Version; - -/** - * Class RemoteLanguagePackLoader is responsible for retrieving language pack data from remote host. - */ -final class RemoteLanguagePackLoader implements LanguagePackLoaderInterface -{ - /** - * The link from which available languages are retrieved. - */ - const PACK_LINK = 'http://i18n.prestashop.com/translations/%ps_version%/available_languages.json'; - - /** - * @var Version - */ - private $version; - - /** - * @param Version $version - */ - public function __construct(Version $version) - { - $this->version = $version; - } - - /** - * {@inheritdoc} - */ - public function getLanguagePackList() - { - $normalizedLink = str_replace('%ps_version%', $this->version->getVersion(), self::PACK_LINK); - $jsonResponse = file_get_contents($normalizedLink); - - $result = []; - if ($jsonResponse) { - $result = json_decode($jsonResponse, true); - } - - return $result; - } -} diff --git a/src/Core/Language/RTL/InstalledLanguageCheckerInterface.php b/src/Core/Language/RTL/InstalledLanguageCheckerInterface.php deleted file mode 100644 index 6ac2c826..00000000 --- a/src/Core/Language/RTL/InstalledLanguageCheckerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Language\RTL; - -/** - * Interface InstalledRtlLanguageCheckerInterface - */ -interface InstalledLanguageCheckerInterface -{ - /** - * Check if there are at least one RTL language installed in shop. - * - * @return bool - */ - public function isInstalledRtlLanguage(); -} diff --git a/src/Core/Localization/CLDR/ComputingPrecision.php b/src/Core/Localization/CLDR/ComputingPrecision.php deleted file mode 100644 index fb173163..00000000 --- a/src/Core/Localization/CLDR/ComputingPrecision.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * {@inheritdoc} - */ -final class ComputingPrecision implements ComputingPrecisionInterface -{ - const MULTIPLIER = 1; - const MINIMAL_VALUE = 0; - - /** - * {@inheritdoc} - */ - public function getPrecision(int $displayPrecision) - { - // the MULTIPLIER attribute is set to 1 for now, so that it matches display precision - $computingPrecision = $displayPrecision * self::MULTIPLIER; - - return ($computingPrecision < self::MINIMAL_VALUE) ? self::MINIMAL_VALUE : $computingPrecision; - } -} diff --git a/src/Core/Localization/CLDR/ComputingPrecisionInterface.php b/src/Core/Localization/CLDR/ComputingPrecisionInterface.php deleted file mode 100644 index bfd052c1..00000000 --- a/src/Core/Localization/CLDR/ComputingPrecisionInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * Will calculate the computing precision (fraction digits number used for computations) that should - * be used for a given display precision. - */ -interface ComputingPrecisionInterface -{ - /** - * Number of decimal digits to take into account when computing values - * for a given display precision - * - * @var int - * - * @return int - */ - public function getPrecision(int $displayPrecision); -} diff --git a/src/Core/Localization/CLDR/Currency.php b/src/Core/Localization/CLDR/Currency.php deleted file mode 100644 index 23d97928..00000000 --- a/src/Core/Localization/CLDR/Currency.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * CLDR Currency entity. This is an immutable data object. - * - * This class represents the immutable object of CLDR data for a specific currency, translated in a given language. - * It is the only data object visible and handleable by "outside" code (meaning non-CLDR code). - * CLDR Locale objects aggregate multiple CLDR Currency instances (available currencies), and return this class when - * asked for a given currency. - */ -final class Currency implements CurrencyInterface -{ - /** - * Alphabetic ISO 4217 currency code. - * - * @var string - */ - private $isoCode; - - /** - * Numeric ISO 4217 currency code. - * - * @var string - */ - private $numericIsoCode; - - /** - * Number of decimal digits to display for a price in this currency. - * - * @var int - */ - private $decimalDigits; - - /** - * Possible names depending on count context. - * - * e.g.: "Used currency is dollar" (default), "I need one dollar" (one), "I need five dollars" (other) - * [ - * 'default' => 'dollar', - * 'one' => 'dollar', - * 'other' => 'dollars', - * ] - * - * @var string[] - */ - private $displayNames; - - /** - * Possible symbols (PrestaShop is using narrow). - * - * e.g.: - * [ - * 'default' => 'US$', - * 'narrow' => '$', - * ] - * - * @var string[] - */ - private $symbols; - - public function __construct(CurrencyData $currencyData) - { - $this->isoCode = $currencyData->getIsoCode(); - $this->numericIsoCode = $currencyData->getNumericIsoCode(); - $this->decimalDigits = $currencyData->getDecimalDigits(); - $this->displayNames = $currencyData->getDisplayNames(); - $this->symbols = $currencyData->getSymbols(); - } - - /** - * Get the ISO code of this currency. - * - * @return string - * The currency's ISO 4217 code - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * Get the numeric ISO code of this currency. - * - * @return string The currency's ISO 4217 numeric code - */ - public function getNumericIsoCode() - { - return $this->numericIsoCode; - } - - /** - * Get the number of decimal digits to display when formatting a price with this currency. - * - * @return int The number of decimal digits to display - */ - public function getDecimalDigits() - { - return $this->decimalDigits; - } - - /** - * Get the display name for the passed count context. - * - * @param string $countContext - * The count context - * "default" = talking about the currency (e.g.: "used currency is Euro") - * "one" = talking about one unit of this currency (e.g.: "one euro") - * "other" = talking about several units of this currency (e.g.: "ten euros") - * - * @return string The wanted display name - */ - public function getDisplayName($countContext = CurrencyInterface::DISPLAY_NAME_COUNT_DEFAULT) - { - if (!in_array($countContext, [CurrencyInterface::DISPLAY_NAME_COUNT_DEFAULT, CurrencyInterface::DISPLAY_NAME_COUNT_ONE, CurrencyInterface::DISPLAY_NAME_COUNT_OTHER])) { - throw new LocalizationException(sprintf('Unknown display name: "%s"', print_r($countContext, true))); - } - - return $this->displayNames[$countContext]; - } - - /** - * Get the symbol of this currency. Narrow symbol is returned by default. - * - * @param string $type Possible value: "default" ("$") and "narrow" ("US$") - * - * @return string The currency's symbol - * - * @throws LocalizationException When an invalid symbol type is passed - */ - public function getSymbol($type = CurrencyInterface::SYMBOL_TYPE_NARROW) - { - if (!in_array($type, [CurrencyInterface::SYMBOL_TYPE_NARROW, CurrencyInterface::SYMBOL_TYPE_DEFAULT])) { - throw new LocalizationException(sprintf('Unknown symbol type: "%s"', print_r($type, true))); - } - - if (isset($this->symbols[$type])) { - return $this->symbols[$type]; - } - - return $this->symbols[CurrencyInterface::SYMBOL_TYPE_DEFAULT]; - } -} diff --git a/src/Core/Localization/CLDR/CurrencyData.php b/src/Core/Localization/CLDR/CurrencyData.php deleted file mode 100644 index bb47a700..00000000 --- a/src/Core/Localization/CLDR/CurrencyData.php +++ /dev/null @@ -1,248 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * The CurrencyData class is the exact representation of Currency's data structure inside CLDR xml data files. - * - * This class is only used internally, it is mutable and overridable until fully built. It can then be used as - * an intermediary data bag to build a real CLDR Currency (immutable) object. - */ -class CurrencyData -{ - /** - * Alphabetic ISO 4217 currency code. - * - * @var string - */ - protected $isoCode; - - /** - * Numeric ISO 4217 currency code. - * - * @var string - */ - protected $numericIsoCode; - - /** - * Number of decimal digits to display for a price in this currency. - * - * @var int - */ - protected $decimalDigits; - - /** - * Possible names depending on count context. - * - * e.g.: "Used currency is dollar" (default), "I need one dollar" (one), "I need five dollars" (other) - * [ - * 'default' => 'dollar', - * 'one' => 'dollar', - * 'other' => 'dollars', - * ] - * - * @var string[] - */ - protected $displayNames; - - /** - * Possible symbols (PrestaShop is using narrow). - * - * e.g.: - * [ - * 'default' => 'US$', - * 'narrow' => '$', - * ] - * - * @var string[] - */ - protected $symbols; - - /** - * Is the currency used somewhere, or was it deactivated in all territories - * - * @var bool|null - */ - protected $active; - - /** - * Override this object's data with another CurrencyData object. - * - * @param CurrencyData $currencyData - * Currency data to use for the override - * - * @return $this - * Fluent interface - */ - public function overrideWith(CurrencyData $currencyData) - { - if (null !== $currencyData->getIsoCode()) { - $this->setIsoCode($currencyData->getIsoCode()); - } - - if (null !== $currencyData->getNumericIsoCode()) { - $this->setNumericIsoCode($currencyData->getNumericIsoCode()); - } - - if (null !== $currencyData->isActive()) { - $this->setActive($currencyData->isActive()); - } - - if (null !== $currencyData->getDecimalDigits()) { - $this->setDecimalDigits($currencyData->getDecimalDigits()); - } - - if (null !== $currencyData->getDisplayNames()) { - $this->displayNames = array_merge($this->displayNames ?? [], $currencyData->getDisplayNames()); - } - - if (null !== $currencyData->getSymbols()) { - $this->symbols = array_merge($this->symbols ?? [], $currencyData->getSymbols()); - } - - return $this; - } - - /** - * @return string - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - * - * @return CurrencyData - */ - public function setIsoCode($isoCode) - { - $this->isoCode = $isoCode; - - return $this; - } - - /** - * @return string - */ - public function getNumericIsoCode() - { - return $this->numericIsoCode; - } - - /** - * @param string $numericIsoCode - * - * @return CurrencyData - */ - public function setNumericIsoCode($numericIsoCode) - { - $this->numericIsoCode = $numericIsoCode; - - return $this; - } - - /** - * @return int - */ - public function getDecimalDigits() - { - return $this->decimalDigits; - } - - /** - * @param int $decimalDigits - * - * @return CurrencyData - */ - public function setDecimalDigits($decimalDigits) - { - $this->decimalDigits = $decimalDigits; - - return $this; - } - - /** - * @return string[] - */ - public function getDisplayNames() - { - return $this->displayNames; - } - - /** - * @param string[] $displayNames - * - * @return CurrencyData - */ - public function setDisplayNames($displayNames) - { - $this->displayNames = $displayNames; - - return $this; - } - - /** - * @return string[] - */ - public function getSymbols() - { - return $this->symbols; - } - - /** - * @param string[] $symbols - * - * @return CurrencyData - */ - public function setSymbols($symbols) - { - $this->symbols = $symbols; - - return $this; - } - - /** - * is currency still active in some territory - * - * @return bool|null - */ - public function isActive() - { - return $this->active; - } - - /** - * @param bool $active - */ - public function setActive($active) - { - $this->active = (bool) $active; - } -} diff --git a/src/Core/Localization/CLDR/CurrencyDataLayerInterface.php b/src/Core/Localization/CLDR/CurrencyDataLayerInterface.php deleted file mode 100644 index 5aeb82fe..00000000 --- a/src/Core/Localization/CLDR/CurrencyDataLayerInterface.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * CLDR Currency data layer classes interface. - * - * Describes the behavior of CldrCurrencyDataLayer classes - */ -interface CurrencyDataLayerInterface -{ - /** - * Read Currency by currency code. - * - * @param string $currencyCode - * The currency code (ISO 4217) - * - * @return CurrencyData - * The searched CLDR currency data - */ - public function read($currencyCode); - - /** - * Write a currency data object into the data source. - * - * @param string $currencyCode - * The currency code (ISO 4217) - * @param CurrencyData $currencyData - * The currency data to write - * - * @return CurrencyData - * The currency data to be written by the upper data layer - */ - public function write($currencyCode, $currencyData); - - /** - * Set the lower layer. - * When reading data, if nothing is found then it will try to read in the lower data layer - * When writing data, the data will also be written in the lower data layer. - * - * @param currencyDataLayerInterface $lowerLayer - * The lower data layer - * - * @return self - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer); -} diff --git a/src/Core/Localization/CLDR/CurrencyInterface.php b/src/Core/Localization/CLDR/CurrencyInterface.php deleted file mode 100644 index f7e53d20..00000000 --- a/src/Core/Localization/CLDR/CurrencyInterface.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR\DataLayer; - -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Data\Layer\DataLayerException; -use PrestaShop\PrestaShop\Core\Localization\CLDR\CurrencyData; -use PrestaShop\PrestaShop\Core\Localization\CLDR\CurrencyDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\Currency\LocalizedCurrencyId; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use Symfony\Component\Cache\Adapter\AdapterInterface; - -/** - * CurrencyCache CLDR data layer. - * - * This currency data layer reads and writes CLDR CurrencyData from a cache adapter - */ -final class CurrencyCache extends AbstractDataLayer implements CurrencyDataLayerInterface -{ - /** - * Symfony Cache component adapter. - * - * Provides cached CurrencyData objects - * Implements PSR-6: Cache Interface (@see http://www.php-fig.org/psr/psr-6/) - * - * @var AdapterInterface - */ - protected $cache; - - public function __construct(AdapterInterface $cache) - { - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a CLDR CurrencyData object into the current layer. - * - * Might be a file access, cache read, DB select... - * - * @param mixed $currencyCode - * The CLDR CurrencyData object identifier - * - * @return CurrencyData|null - * The wanted CLDR CurrencyData object (null if not found) - */ - protected function doRead($currencyCode) - { - $cacheItem = $this->cache->getItem($currencyCode); - - return $cacheItem->isHit() - ? $cacheItem->get() - : null; - } - - /** - * {@inheritdoc} - */ - public function write($id, $data) - { - if (!($data instanceof CurrencyData)) { - throw new LocalizationException('$data must be an instance of ' . CurrencyData::class); - } - - return parent::write($id, $data); - } - - /** - * Actually write a CLDR CurrencyData object into the current layer. - * - * Might be a file edit, cache update, DB insert/update... - * - * @param LocalizedCurrencyId $currencyDataId - * The data object identifier - * @param CurrencyData $data - * The data object to be written - * - * @throws DataLayerException - * When write fails - */ - protected function doWrite($currencyDataId, $data) - { - $cacheItem = $this->cache->getItem((string) $currencyDataId); - $cacheItem->set($data); - - $saved = $this->cache->save($cacheItem); - - if (!$saved) { - throw new DataLayerException('Unable to persist data in cache data layer'); - } - } -} diff --git a/src/Core/Localization/CLDR/DataLayer/LocaleCache.php b/src/Core/Localization/CLDR/DataLayer/LocaleCache.php deleted file mode 100644 index 6f945be0..00000000 --- a/src/Core/Localization/CLDR/DataLayer/LocaleCache.php +++ /dev/null @@ -1,125 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR\DataLayer; - -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Data\Layer\DataLayerException; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleData; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleDataLayerInterface as CldrLocaleDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use Symfony\Component\Cache\Adapter\AdapterInterface; - -/** - * LocaleCache CLDR data layer. - * - * This locale data layer reads and writes CLDR LocaleData from a cache adapter - */ -class LocaleCache extends AbstractDataLayer implements CldrLocaleDataLayerInterface -{ - /** - * Symfony Cache component adapter. - * - * Provides cached LocaleData objects - * Implements PSR-6: Cache Interface (@see http://www.php-fig.org/psr/psr-6/) - * - * @var AdapterInterface - */ - protected $cache; - - public function __construct(AdapterInterface $cache) - { - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function setLowerLayer(CldrLocaleDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a CLDR LocaleData object into the current layer. - * - * Data is read from passed cache adapter - * - * @param string $localeCode - * The CLDR LocaleData object identifier - * - * @return LocaleData|null - * The wanted CLDR LocaleData object (null if not found) - */ - protected function doRead($localeCode) - { - $cacheItem = $this->cache->getItem($localeCode); - - return $cacheItem->isHit() - ? $cacheItem->get() - : null; - } - - /** - * {@inheritdoc} - */ - public function write($id, $data) - { - if (!($data instanceof LocaleData)) { - throw new LocalizationException('$data must be an instance of ' . LocaleData::class); - } - - return parent::write($id, $data); - } - - /** - * Actually write a LocaleData object into the current layer. - * - * Might be a file edit, cache update, DB insert/update... - * - * @param mixed $localeCode - * The LocaleData object identifier - * @param LocaleData $data - * The CLDR LocaleData object to be written - * - * @throws DataLayerException - * When write fails - */ - protected function doWrite($localeCode, $data) - { - $cacheItem = $this->cache->getItem($localeCode); - $cacheItem->set($data); - - $saved = $this->cache->save($cacheItem); - - if (!$saved) { - throw new DataLayerException('Unable to persist data in cache data layer'); - } - } -} diff --git a/src/Core/Localization/CLDR/DataLayer/LocaleReference.php b/src/Core/Localization/CLDR/DataLayer/LocaleReference.php deleted file mode 100644 index c08eebb6..00000000 --- a/src/Core/Localization/CLDR/DataLayer/LocaleReference.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR\DataLayer; - -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleData; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleDataLayerInterface as CldrLocaleDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ReaderInterface; - -/** - * Locale reference data layer. - * - * Provides reference (CLDR) data for locale, number specification, currencies... - * Data comes from CLDR official data files, and is read only. - */ -class LocaleReference extends AbstractDataLayer implements CldrLocaleDataLayerInterface -{ - /** - * CLDR files reader. - * - * Provides LocaleData objects - * - * @var ReaderInterface - */ - protected $reader; - - public function __construct(ReaderInterface $reader) - { - $this->reader = $reader; - } - - /** - * {@inheritdoc} - */ - public function setLowerLayer(CldrLocaleDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a CLDR LocaleData object into the current layer. - * - * Data is read from official CLDR file (via the CLDR files reader) - * - * @param string $localeCode - * The CLDR LocaleData object identifier - * - * @return LocaleData|null - * The wanted CLDR LocaleData object (null if not found) - */ - protected function doRead($localeCode) - { - return $this->reader->readLocaleData($localeCode); - } - - /** - * CLDR files are read only. Nothing can be written there. - * - * @param string $localeCode - * The CLDR LocaleData object identifier - * @param LocaleData $data - * The CLDR LocaleData object to be written - */ - protected function doWrite($localeCode, $data) - { - // Nothing. - } -} diff --git a/src/Core/Localization/CLDR/Locale.php b/src/Core/Localization/CLDR/Locale.php deleted file mode 100644 index db0d7bce..00000000 --- a/src/Core/Localization/CLDR/Locale.php +++ /dev/null @@ -1,320 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * CLDR Locale entity. This is an immutable data object. - * - * This class represents the immutable object of CLDR data for a specific locale, translated in a given language. - * It is the only data object visible and handleable by "outside" code (meaning non-CLDR code). - */ -final class Locale implements LocaleInterface -{ - /** - * The locale code for this data (either language code or IETF tag). - * - * @var string - */ - protected $localeCode; - - /** - * List of available numbering systems - * Array of strings (codes). - * - * @var string[] - */ - protected $numberingSystems; - - /** - * Default numbering system. - * - * @var string - */ - protected $defaultNumberingSystem; - - /** - * Used to suppress groupings below a certain value. - * - * 1 -> grouping starts at 4 figures integers (1,000 and more) - * 2 -> grouping starts at 5 figures integers (10,000 and more) - * - * @var int - */ - protected $minimumGroupingDigits; - - /** - * Collection of all available symbols list (by numbering system). - * - * @var NumberSymbolsData[] - */ - protected $numberSymbols; - - /** - * Collection of all available decimal patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $decimalPatterns; - - /** - * Collection of all available percent patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $percentPatterns; - - /** - * Collection of all available currency patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $currencyPatterns; - - /** - * All currencies, by ISO code. - * - * @var CurrencyData[] - */ - protected $currencies; - - public function __construct(LocaleData $localeData) - { - $this->localeCode = $localeData->getLocaleCode(); - $this->numberingSystems = $localeData->getNumberingSystems(); - $this->defaultNumberingSystem = $localeData->getDefaultNumberingSystem(); - $this->minimumGroupingDigits = $localeData->getMinimumGroupingDigits(); - $this->numberSymbols = $localeData->getNumberSymbols(); - $this->decimalPatterns = $localeData->getDecimalPatterns(); - $this->percentPatterns = $localeData->getPercentPatterns(); - $this->currencyPatterns = $localeData->getCurrencyPatterns(); - $this->currencies = $localeData->getCurrencies(); - } - - /** - * Get the code of this Locale (simplified IETF notation). - * - * @return string - * The locale code - */ - public function getLocaleCode() - { - return $this->localeCode; - } - - /** - * Get all available numbering systems for this locale. - * - * @return string[] - */ - public function getNumberingSystems() - { - return $this->numberingSystems; - } - - /** - * Get the default numbering system for this locale. - * - * @return string - */ - public function getDefaultNumberingSystem() - { - return $this->defaultNumberingSystem; - } - - /** - * Get the minimum grouping digits number when formatting numbers for this locale. - * - * @return int - */ - public function getMinimumGroupingDigits() - { - return $this->minimumGroupingDigits; - } - - /** - * Get all available number symbols lists, by numbering system. - * - * @return NumberSymbolsData[] - * All number symbols lists (by numbering system) - */ - public function getAllNumberSymbols() - { - return $this->numberSymbols; - } - - /** - * Get the number symbols to use for a given numbering system. - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return NumberSymbolsData - * The wanted number symbols - * - * @throws LocalizationException - * When passed $numberingSystem is invalid - */ - public function getNumberSymbolsByNumberingSystem($numberingSystem = null) - { - if (null === $numberingSystem) { - $numberingSystem = $this->getDefaultNumberingSystem(); - } - if (!isset($this->getAllNumberSymbols()[$numberingSystem])) { - throw new LocalizationException('Invalid numbering system: ' . $numberingSystem); - } - - return $this->getAllNumberSymbols()[$numberingSystem]; - } - - /** - * Get the pattern to use when formatting a decimal number (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The decimal pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getDecimalPattern($numberingSystem = null) - { - if (null === $numberingSystem) { - $numberingSystem = $this->getDefaultNumberingSystem(); - } - if (!isset($this->decimalPatterns[$numberingSystem])) { - throw new LocalizationException('No decimal pattern found for numbering system: ' . $numberingSystem); - } - - return $this->decimalPatterns[$numberingSystem]; - } - - /** - * Get the pattern to use when formatting a percentage (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The percent pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getPercentPattern($numberingSystem = null) - { - if (null === $numberingSystem) { - $numberingSystem = $this->getDefaultNumberingSystem(); - } - if (!isset($this->percentPatterns[$numberingSystem])) { - throw new LocalizationException('No percent pattern found for numbering system: ' . $numberingSystem); - } - - return $this->percentPatterns[$numberingSystem]; - } - - /** - * Get the pattern to use when formatting a price (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The currency pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getCurrencyPattern($numberingSystem = null) - { - if (null === $numberingSystem) { - $numberingSystem = $this->getDefaultNumberingSystem(); - } - if (!isset($this->currencyPatterns[$numberingSystem])) { - throw new LocalizationException('No currency pattern found for numbering system: ' . $numberingSystem); - } - - return $this->currencyPatterns[$numberingSystem]; - } - - /** - * Get a given CLDR Currency. - * - * @param string $currencyCode An ISO 4217 currency code - * - * @return CurrencyInterface|null The wanted CLDR Currency. Null if this currency is not available for this locale. - */ - public function getCurrency($currencyCode) - { - $currencyData = $this->getCurrencyData($currencyCode); - if (!empty($currencyData)) { - return new Currency($currencyData); - } - - return null; - } - - /** - * Get CLDR data of a given currency. - * - * @param string $currencyCode - * An ISO 4217 currency code - * - * @return CurrencyData|null - * The wanted currency data. Null if this currency is not available for this locale. - */ - public function getCurrencyData($currencyCode) - { - if (!empty($this->currencies[$currencyCode])) { - return $this->currencies[$currencyCode]; - } - - return null; - } - - /** - * Get CLDR data of all currencies. - * - * @return currencyData[] - * Data of all currencies - */ - public function getAllCurrencies() - { - return $this->currencies; - } -} diff --git a/src/Core/Localization/CLDR/LocaleData.php b/src/Core/Localization/CLDR/LocaleData.php deleted file mode 100644 index 9fa133dc..00000000 --- a/src/Core/Localization/CLDR/LocaleData.php +++ /dev/null @@ -1,371 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * The LocaleData class is the exact representation of Locale's data structure inside CLDR xml data files. - * - * This class is only used internally, it is mutable and overridable until fully built. It can then be used as - * an intermediary data bag to build a real CLDR Locale (immutable) object. - */ -class LocaleData -{ - /** - * The locale code for this data (either language code or IETF tag). - * e.G.: 'fr', 'fr-FR'... - * - * @var string - */ - protected $localeCode; - - /** - * List of available numbering systems - * Array of strings (codes). - * - * @var string[] - */ - protected $numberingSystems; - - /** - * Default numbering system. - * - * @var string - */ - protected $defaultNumberingSystem; - - /** - * Used to suppress groupings below a certain value. - * - * 1 -> grouping starts at 4 figures integers (1,000 and more) - * 2 -> grouping starts at 5 figures integers (10,000 and more) - * - * @var int - */ - protected $minimumGroupingDigits; - - /** - * Collection of all available symbols list (by numbering system). - * - * @var NumberSymbolsData[] - */ - protected $numberSymbols; - - /** - * Collection of all available decimal patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $decimalPatterns; - - /** - * Collection of all available percent patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $percentPatterns; - - /** - * Collection of all available currency patterns (by numbering system) - * Array of strings (patterns). - * - * @var string[] - */ - protected $currencyPatterns; - - /** - * All currencies, by ISO code. - * - * @var CurrencyData[] - */ - protected $currencies; - - /** - * Override this object's data with another LocaleData object. - * - * @param LocaleData $localeData Locale data to use for the override - * - * @return $this Fluent interface - */ - public function overrideWith(LocaleData $localeData) - { - if (null !== $localeData->getLocaleCode()) { - $this->setLocaleCode($localeData->getLocaleCode()); - } - - if (null !== $localeData->getNumberingSystems()) { - if (null === $this->numberingSystems) { - $this->numberingSystems = []; - } - $this->numberingSystems = array_merge($this->numberingSystems, $localeData->getNumberingSystems()); - } - - if (null !== $localeData->getDefaultNumberingSystem()) { - $this->setDefaultNumberingSystem($localeData->getDefaultNumberingSystem()); - } - - if (null !== $localeData->getMinimumGroupingDigits()) { - $this->setMinimumGroupingDigits($localeData->getMinimumGroupingDigits()); - } - - if (null !== $localeData->getNumberSymbols()) { - foreach ($localeData->getNumberSymbols() as $numberingSystem => $symbolsData) { - if (!isset($this->numberSymbols[$numberingSystem])) { - $this->numberSymbols[$numberingSystem] = $symbolsData; - - continue; - } - $this->numberSymbols[$numberingSystem]->overrideWith($symbolsData); - } - } - - if (null !== $localeData->getDecimalPatterns()) { - $this->setDecimalPatterns($localeData->getDecimalPatterns()); - } - - if (null !== $localeData->getPercentPatterns()) { - $this->setPercentPatterns($localeData->getPercentPatterns()); - } - - if (null !== $localeData->getCurrencyPatterns()) { - if (null === $this->currencyPatterns) { - $this->currencyPatterns = []; - } - $this->currencyPatterns = array_merge($this->currencyPatterns, $localeData->getCurrencyPatterns()); - } - - if (null !== $localeData->getCurrencies()) { - foreach ($localeData->getCurrencies() as $code => $currencyData) { - if (!isset($this->currencies[$code])) { - $this->currencies[$code] = $currencyData; - continue; - } - $this->currencies[$code]->overrideWith($currencyData); - } - } - - return $this; - } - - /** - * @return string - */ - public function getLocaleCode() - { - return $this->localeCode; - } - - /** - * @param string $localeCode - * - * @return LocaleData - */ - public function setLocaleCode($localeCode) - { - $this->localeCode = $localeCode; - - return $this; - } - - /** - * @return string[] - */ - public function getNumberingSystems() - { - return $this->numberingSystems; - } - - /** - * @param string[] $numberingSystems - * - * @return LocaleData - */ - public function setNumberingSystems($numberingSystems) - { - $this->numberingSystems = $numberingSystems; - - return $this; - } - - /** - * @return string - */ - public function getDefaultNumberingSystem() - { - return $this->defaultNumberingSystem; - } - - /** - * @param string $defaultNumberingSystem - * - * @return LocaleData - */ - public function setDefaultNumberingSystem($defaultNumberingSystem) - { - $this->defaultNumberingSystem = $defaultNumberingSystem; - - return $this; - } - - /** - * @return int - */ - public function getMinimumGroupingDigits() - { - return $this->minimumGroupingDigits; - } - - /** - * @param int $minimumGroupingDigits - * - * @return LocaleData - */ - public function setMinimumGroupingDigits($minimumGroupingDigits) - { - $this->minimumGroupingDigits = $minimumGroupingDigits; - - return $this; - } - - /** - * @return \PrestaShop\PrestaShop\Core\Localization\CLDR\NumberSymbolsData[] - */ - public function getNumberSymbols() - { - return $this->numberSymbols; - } - - /** - * @param \PrestaShop\PrestaShop\Core\Localization\CLDR\NumberSymbolsData[] $numberSymbols - * - * @return LocaleData - */ - public function setNumberSymbols($numberSymbols) - { - $this->numberSymbols = $numberSymbols; - - return $this; - } - - /** - * @return string[] - */ - public function getDecimalPatterns() - { - return $this->decimalPatterns; - } - - /** - * @param string[] $decimalPatterns - * - * @return LocaleData - */ - public function setDecimalPatterns($decimalPatterns) - { - $this->decimalPatterns = $decimalPatterns; - - return $this; - } - - /** - * @return string[] - */ - public function getPercentPatterns() - { - return $this->percentPatterns; - } - - /** - * @param string[] $percentPatterns - * - * @return LocaleData - */ - public function setPercentPatterns($percentPatterns) - { - $this->percentPatterns = $percentPatterns; - - return $this; - } - - /** - * @return string[] - */ - public function getCurrencyPatterns() - { - return $this->currencyPatterns; - } - - /** - * @param string[] $currencyPatterns - * - * @return LocaleData - */ - public function setCurrencyPatterns($currencyPatterns) - { - $this->currencyPatterns = $currencyPatterns; - - return $this; - } - - /** - * @return CurrencyData[] - */ - public function getCurrencies() - { - return $this->currencies; - } - - /** - * @param string $currencyIsoCode - * - * @return CurrencyData|null - */ - public function getCurrencyByIsoCode($currencyIsoCode) - { - foreach ($this->getCurrencies() as $currencyData) { - if ($currencyData->getIsoCode() == $currencyIsoCode) { - return $currencyData; - } - } - - return null; - } - - /** - * @param CurrencyData[] $currencies - * - * @return LocaleData - */ - public function setCurrencies($currencies) - { - $this->currencies = $currencies; - - return $this; - } -} diff --git a/src/Core/Localization/CLDR/LocaleDataLayerInterface.php b/src/Core/Localization/CLDR/LocaleDataLayerInterface.php deleted file mode 100644 index 0a734db1..00000000 --- a/src/Core/Localization/CLDR/LocaleDataLayerInterface.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * CLDR Locale data layer classes interface. - * - * Describes the behavior of CldrLocaleDataLayer classes - */ -interface LocaleDataLayerInterface -{ - /** - * Read CLDR locale data by locale code. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @return LocaleData - * The searched locale's CLDR data - */ - public function read($localeCode); - - /** - * Write a locale's CLDR data object into the data source. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * @param LocaleData $localeData - * The locale's CLDR data to write - * - * @return LocaleData - * The locale's CLDR data to be written by the upper data layer - */ - public function write($localeCode, $localeData); - - /** - * Set the lower layer. - * When reading data, if nothing is found then it will try to read in the lower data layer - * When writing data, the data will also be written in the lower data layer. - * - * @param localeDataLayerInterface $lowerLayer - * The lower data layer - * - * @return self - */ - public function setLowerLayer(LocaleDataLayerInterface $lowerLayer); -} diff --git a/src/Core/Localization/CLDR/LocaleDataSource.php b/src/Core/Localization/CLDR/LocaleDataSource.php deleted file mode 100644 index 9f302d61..00000000 --- a/src/Core/Localization/CLDR/LocaleDataSource.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleDataLayerInterface as CldrLocaleDataLayerInterface; - -/** - * LocaleDataSource provides CLDR LocaleData objects. - * - * This class uses Locale data layers as middlewares stack to read CLDR data. - */ -class LocaleDataSource -{ - /** - * @var CldrLocaleDataLayerInterface - */ - private $topLayer; - - /** - * LocaleDataSource constructor needs a CldrLocaleDataLayerInterface layer object. - * This top layer might be chained with lower layers and will be the entry point of this middleware stack. - * - * @param CldrLocaleDataLayerInterface $topLayer - */ - public function __construct(CldrLocaleDataLayerInterface $topLayer) - { - $this->topLayer = $topLayer; - } - - /** - * @param string $localeCode - * - * @return LocaleData - */ - public function getLocaleData($localeCode) - { - return $this->topLayer->read($localeCode); - } -} diff --git a/src/Core/Localization/CLDR/LocaleInterface.php b/src/Core/Localization/CLDR/LocaleInterface.php deleted file mode 100644 index 84b95697..00000000 --- a/src/Core/Localization/CLDR/LocaleInterface.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * CLDR Locale entity. This is an immutable data object. - * - * This class represents the immutable object of CLDR data for a specific locale, translated in a given language. - * It is the only data object visible and handleable by "outside" code (meaning non-CLDR code). - */ -interface LocaleInterface -{ - /** - * Get the code of this Locale (simplified IETF notation). - * - * @return string - * The locale code - */ - public function getLocaleCode(); - - /** - * Get all available numbering systems for this locale. - * - * @return string[] - */ - public function getNumberingSystems(); - - /** - * Get the default numbering system for this locale. - * - * @return string - */ - public function getDefaultNumberingSystem(); - - /** - * Get the minimum grouping digits number when formatting numbers for this locale. - * - * @return int - */ - public function getMinimumGroupingDigits(); - - /** - * Get all available number symbols lists, by numbering system. - * - * @return NumberSymbolsData[] - * All number symbols lists (by numbering system) - */ - public function getAllNumberSymbols(); - - /** - * Get the number symbols to use for a given numbering system. - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return NumberSymbolsData - * The wanted number symbols - * - * @throws LocalizationException - * When passed $numberingSystem is invalid - */ - public function getNumberSymbolsByNumberingSystem($numberingSystem = null); - - /** - * Get the pattern to use when formatting a decimal number (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The decimal pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getDecimalPattern($numberingSystem = null); - - /** - * Get the pattern to use when formatting a percentage (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The percent pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getPercentPattern($numberingSystem = null); - - /** - * Get the pattern to use when formatting a price (for a given numbering system). - * - * @param string|null $numberingSystem - * The numbering system of the wanted symbols set. - * If null, the default numbering system of this locale will be used. - * - * @return string - * The currency pattern - * - * @throws LocalizationException - * When passed numbering system is invalid - */ - public function getCurrencyPattern($numberingSystem = null); - - /** - * Get a given CLDR Currency. - * - * @param string $currencyCode An ISO 4217 currency code - * - * @return CurrencyInterface|null The wanted CLDR Currency. Null if this currency is not available for this locale. - */ - public function getCurrency($currencyCode); - - /** - * Get CLDR data of a given currency. - * - * @param string $currencyCode - * An ISO 4217 currency code - * - * @return CurrencyData|null - * The wanted currency data. Null if this currency is not available for this locale. - */ - public function getCurrencyData($currencyCode); - - /** - * Get CLDR data of all currencies. - * - * @return currencyData[] - * Data of all currencies - */ - public function getAllCurrencies(); -} diff --git a/src/Core/Localization/CLDR/LocaleRepository.php b/src/Core/Localization/CLDR/LocaleRepository.php deleted file mode 100644 index 1bafdf02..00000000 --- a/src/Core/Localization/CLDR/LocaleRepository.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\CLDR\Locale as CldrLocale; - -/** - * CLDR Locale Repository. - * - * Provides CLDR Locale objects - */ -class LocaleRepository -{ - /** - * @var LocaleDataSource - */ - protected $dataSource; - - public function __construct(LocaleDataSource $dataSource) - { - $this->dataSource = $dataSource; - } - - /** - * Get a CLDR Locale by simplified IETF tag. - * - * @param string $localeCode - * e.g.: fr-FR, en-US... - * - * @return CldrLocale|null - * A CldrLocale object. Null if not found - */ - public function getLocale($localeCode) - { - $localeData = $this->dataSource->getLocaleData($localeCode); - - if (null === $localeData) { - return null; - } - - return new CldrLocale($localeData); - } -} diff --git a/src/Core/Localization/CLDR/NumberSymbolsData.php b/src/Core/Localization/CLDR/NumberSymbolsData.php deleted file mode 100644 index 5bff453f..00000000 --- a/src/Core/Localization/CLDR/NumberSymbolsData.php +++ /dev/null @@ -1,504 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -/** - * Number's symbols data object. Regroups all symbols used when formatting a number - * (decimal separator, thousands separator, etc.). - */ -class NumberSymbolsData -{ - /** - * Decimal separator character. - * - * Separates the integer and fractional part of the number. - * - * @var string - */ - protected $decimal; - - /** - * Digits group separator character. - * - * separates clusters of integer digits to make large numbers more legible; commonly used for thousands(grouping - * size 3, e.g. "100,000,000") or in some locales, ten-thousands (grouping size 4, e.g. "1,0000,0000"). - * - * @var string - */ - protected $group; - - /** - * List elements separator character. - * - * Symbol used to separate numbers in a list intended to represent structured data such as an array. - * - * @var string - */ - protected $list; - - /** - * Percent sign character. - * - * Used to indicate a percentage (1/100th) amount. - * - * @var string - */ - protected $percentSign; - - /** - * Minus sign character. - * - * Symbol used to denote negative value. - * - * @var string - */ - protected $minusSign; - - /** - * Plus sign character. - * - * Symbol used to denote positive value. - * It can be used to produce modified patterns, so that 3.12 is formatted as "+3.12", for example. - * - * @var string - */ - protected $plusSign; - - /** - * Exponential character. - * - * Symbol separating the mantissa and exponent values. - * - * @var string - */ - protected $exponential; - - /** - * Superscripting exponent character. - * - * Used in numbers to show a format like "1.23 × 10^4" - * (exponential character is a shortcut for "× 10^n" notation) - * - * @var string - */ - protected $superscriptingExponent; - - /** - * Permille sign character. - * - * Used to define them as a per-mille (1/1000th) amount. - * - * @var string - */ - protected $perMille; - - /** - * The infinity sign. Corresponds to the IEEE infinity bit pattern. - * - * @var string - */ - protected $infinity; - - /** - * The NaN (Not A Number) sign. Corresponds to the IEEE NaN bit pattern. - * - * @var string - */ - protected $nan; - - /** - * Separator used in date-time formatting. - * - * eg.: ":" => 20:00:00 (latn) - * eg.: "," => 20,00,00 (arab) - * - * @var string - */ - protected $timeSeparator; - - /** - * Will be set when decimal separator is different when formatting a price. - * - * @var string - */ - protected $currencyDecimal; - - /** - * Will be set when digits grouping is different when formatting a price. - * - * @var string - */ - protected $currencyGroup; - - /** - * Override this object's symbols with another NumberSymbolsData object. - * - * @param NumberSymbolsData $symbolsData Symbols to use for the override - * - * @return $this Fluent interface - */ - public function overrideWith(NumberSymbolsData $symbolsData) - { - if (null !== $symbolsData->getDecimal()) { - $this->setDecimal($symbolsData->getDecimal()); - } - - if (null !== $symbolsData->getGroup()) { - $this->setGroup($symbolsData->getGroup()); - } - - if (null !== $symbolsData->getList()) { - $this->setList($symbolsData->getList()); - } - - if (null !== $symbolsData->getPercentSign()) { - $this->setPercentSign($symbolsData->getPercentSign()); - } - - if (null !== $symbolsData->getMinusSign()) { - $this->setMinusSign($symbolsData->getMinusSign()); - } - - if (null !== $symbolsData->getPlusSign()) { - $this->setPlusSign($symbolsData->getPlusSign()); - } - - if (null !== $symbolsData->getExponential()) { - $this->setExponential($symbolsData->getExponential()); - } - - if (null !== $symbolsData->getSuperscriptingExponent()) { - $this->setSuperscriptingExponent($symbolsData->getSuperscriptingExponent()); - } - - if (null !== $symbolsData->getPerMille()) { - $this->setPerMille($symbolsData->getPerMille()); - } - - if (null !== $symbolsData->getInfinity()) { - $this->setInfinity($symbolsData->getInfinity()); - } - - if (null !== $symbolsData->getNan()) { - $this->setNan($symbolsData->getNan()); - } - - if (null !== $symbolsData->getTimeSeparator()) { - $this->setTimeSeparator($symbolsData->getTimeSeparator()); - } - - if (null !== $symbolsData->getCurrencyDecimal()) { - $this->setCurrencyDecimal($symbolsData->getCurrencyDecimal()); - } - - if (null !== $symbolsData->getCurrencyGroup()) { - $this->setCurrencyGroup($symbolsData->getCurrencyGroup()); - } - - return $this; - } - - /** - * @return string - */ - public function getDecimal() - { - return $this->decimal; - } - - /** - * @param string $decimal - * - * @return NumberSymbolsData - */ - public function setDecimal($decimal) - { - $this->decimal = $decimal; - - return $this; - } - - /** - * @return string - */ - public function getGroup() - { - return $this->group; - } - - /** - * @param string $group - * - * @return NumberSymbolsData - */ - public function setGroup($group) - { - $this->group = $group; - - return $this; - } - - /** - * @return string - */ - public function getList() - { - return $this->list; - } - - /** - * @param string $list - * - * @return NumberSymbolsData - */ - public function setList($list) - { - $this->list = $list; - - return $this; - } - - /** - * @return string - */ - public function getPercentSign() - { - return $this->percentSign; - } - - /** - * @param string $percentSign - * - * @return NumberSymbolsData - */ - public function setPercentSign($percentSign) - { - $this->percentSign = $percentSign; - - return $this; - } - - /** - * @return string - */ - public function getMinusSign() - { - return $this->minusSign; - } - - /** - * @param string $minusSign - * - * @return NumberSymbolsData - */ - public function setMinusSign($minusSign) - { - $this->minusSign = $minusSign; - - return $this; - } - - /** - * @return string - */ - public function getPlusSign() - { - return $this->plusSign; - } - - /** - * @param string $plusSign - * - * @return NumberSymbolsData - */ - public function setPlusSign($plusSign) - { - $this->plusSign = $plusSign; - - return $this; - } - - /** - * @return string - */ - public function getExponential() - { - return $this->exponential; - } - - /** - * @param string $exponential - * - * @return NumberSymbolsData - */ - public function setExponential($exponential) - { - $this->exponential = $exponential; - - return $this; - } - - /** - * @return string - */ - public function getSuperscriptingExponent() - { - return $this->superscriptingExponent; - } - - /** - * @param string $superscriptingExponent - * - * @return NumberSymbolsData - */ - public function setSuperscriptingExponent($superscriptingExponent) - { - $this->superscriptingExponent = $superscriptingExponent; - - return $this; - } - - /** - * @return string - */ - public function getPerMille() - { - return $this->perMille; - } - - /** - * @param string $perMille - * - * @return NumberSymbolsData - */ - public function setPerMille($perMille) - { - $this->perMille = $perMille; - - return $this; - } - - /** - * @return string - */ - public function getInfinity() - { - return $this->infinity; - } - - /** - * @param string $infinity - * - * @return NumberSymbolsData - */ - public function setInfinity($infinity) - { - $this->infinity = $infinity; - - return $this; - } - - /** - * @return string - */ - public function getNan() - { - return $this->nan; - } - - /** - * @param string $nan - * - * @return NumberSymbolsData - */ - public function setNan($nan) - { - $this->nan = $nan; - - return $this; - } - - /** - * @return string - */ - public function getTimeSeparator() - { - return $this->timeSeparator; - } - - /** - * @param string $timeSeparator - * - * @return NumberSymbolsData - */ - public function setTimeSeparator($timeSeparator) - { - $this->timeSeparator = $timeSeparator; - - return $this; - } - - /** - * @return string - */ - public function getCurrencyDecimal() - { - return $this->currencyDecimal; - } - - /** - * @param string $currencyDecimal - * - * @return NumberSymbolsData - */ - public function setCurrencyDecimal($currencyDecimal) - { - $this->currencyDecimal = $currencyDecimal; - - return $this; - } - - /** - * @return string - */ - public function getCurrencyGroup() - { - return $this->currencyGroup; - } - - /** - * @param string $currencyGroup - * - * @return NumberSymbolsData - */ - public function setCurrencyGroup($currencyGroup) - { - $this->currencyGroup = $currencyGroup; - - return $this; - } -} diff --git a/src/Core/Localization/CLDR/Reader.php b/src/Core/Localization/CLDR/Reader.php deleted file mode 100644 index 9040f05f..00000000 --- a/src/Core/Localization/CLDR/Reader.php +++ /dev/null @@ -1,670 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationFileNotFoundException; -use SimpleXMLElement; - -/** - * CLDR files reader class. - * - * This class provides CLDR LocaleData objects built with data coming from official CLDR xml data files. - */ -class Reader implements ReaderInterface -{ - const CLDR_ROOT = 'localization/CLDR/'; - const CLDR_MAIN = 'localization/CLDR/core/common/main/'; - const CLDR_SUPPLEMENTAL = 'localization/CLDR/core/common/supplemental/'; - - const CLDR_ROOT_LOCALE = 'root'; - - const SUPPL_DATA_CURRENCY = 'currencyData'; - const SUPPL_DATA_LANGUAGE = 'languageData'; - const SUPPL_DATA_NUMBERING = 'numberingSystems'; - const SUPPL_DATA_PARENT_LOCALES = 'parentLocales'; // For specific locales hierarchy - - const DEFAULT_CURRENCY_DIGITS = 2; - - const CURRENCY_CODE_TEST = 'XTS'; - - /** - * delay after currency deactivation to prevent currency add by list - */ - const CURRENCY_ACTIVE_DELAY = 365; - - protected $mainXml = []; - - /** - * Supplemental data for all locales. - * Contains data about parent locales, currencies, languages... - * - * @var SimplexmlElement - */ - protected $supplementalXml; - - /** - * Additional data about numbering systems - * Mainly used for digits (they depend on numbering system). - * - * @var SimpleXMLElement - */ - protected $numberingSystemsXml; - - /** - * Read locale data by locale code. - * - * @param $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * The underscore notation is also accepted (fr_FR, en_US...) - * - * @return LocaleData - * A LocaleData object - * - * @throws LocalizationException - * When the locale code is unknown or invalid - */ - public function readLocaleData($localeCode) - { - // CLDR filenames use a different notation from IETF. - $localeCode = str_replace('-', '_', $localeCode); - - $this->validateLocaleCodeForFilenames($localeCode); - $this->initSupplementalData(); - - $finalData = new LocaleData(); - $lookup = $this->getLookup($localeCode); - foreach ($lookup as $thisLocaleCode) { - try { - $partialData = $this->getLocaleData($thisLocaleCode); - $finalData = $finalData->overrideWith($partialData); - } catch (LocalizationFileNotFoundException $e) { - // Sometimes a file can be missing. - // Example for Chinese : zh_CN.xml doesn't exist. There is only a zh.xml file. - // That's why we can't let this exception bubble up. - continue; - } - } - - return $finalData; - } - - /** - * Validate a locale code. - * - * If the passed code doesn't respect the CLDR files naming style, an exception will be raised - * e.g.: "fr_FR" and "en_001" are valid - * - * @param $localeCode - * Locale code to be validated - * - * @throws LocalizationException - * When locale code is invalid - */ - protected function validateLocaleCodeForFilenames($localeCode) - { - if (!preg_match('#^[a-zA-Z0-9]+(_[a-zA-Z0-9]+)*$#', $localeCode)) { - throw new LocalizationException(sprintf('Invalid locale code: "%s"', $localeCode)); - } - } - - /** - * Initialize supplemental CLDR data. - */ - protected function initSupplementalData() - { - // Supplemental data about currencies, languages and parent locales - if (!isset($this->supplementalXml)) { - $supplementalPath = realpath( - _PS_ROOT_DIR_ . '/' - . self::CLDR_SUPPLEMENTAL - . 'supplementalData.xml' - ); - $this->supplementalXml = simplexml_load_file($supplementalPath); - } - - // This file contains special digits for non-occidental numbering systems - if (!isset($this->numberingSystemsXml)) { - $numberingSystemsPath = realpath( - _PS_ROOT_DIR_ . '/' - . self::CLDR_SUPPLEMENTAL - . 'numberingSystems.xml' - ); - $this->numberingSystemsXml = simplexml_load_file($numberingSystemsPath); - } - } - - /** - * Build lookup files stack for a given locale code. - * - * @param $localeCode - * The given locale code (simplified IETF notation) - * - * @return array - * The lookup - * ['root', , $localeCode] - * - * @throws LocalizationException - * When locale code is invalid or unknown - * - * @see http://www.unicode.org/reports/tr35/tr35.html#Lookup - */ - protected function getLookup($localeCode) - { - $lookup = [$localeCode]; - - while ($localeCode = $this->getParentLocale($localeCode)) { - array_unshift($lookup, $localeCode); - } - - return $lookup; - } - - /** - * Get the parent locale for a given locale code. - * - * @param $localeCode - * CLDR filenames' style locale code (with underscores) - * eg.: en, fr, en_GB, fr_FR... - * - * @return string|null - * The parent locale code (CLDR filenames' style). Null if no parent. - * - * @throws LocalizationException - */ - protected function getParentLocale($localeCode) - { - // root is the... root of all CLDR locales' data. Then no parent. - if (self::CLDR_ROOT_LOCALE == $localeCode) { - return null; - } - - // The special case from supplemental data - foreach ($this->supplementalXml->parentLocales->parentLocale as $data) { - $locales = explode(' ', $data['locales']); - if (in_array($localeCode, $locales)) { - return $data['parent']; - } - } - - // The common case with truncation - $pos = strrpos($localeCode, '_'); - if (false !== $pos) { - $parent = substr($localeCode, 0, $pos); - if (false === $parent) { - throw new LocalizationException(sprintf('Invalid locale code: "%s"', $localeCode)); - } - - return $parent; - } - - // The "top level" case. When only language code is left in $localeCode: 'en', 'fr'... then parent is "root". - return self::CLDR_ROOT_LOCALE; - } - - /** - * Get CLDR official xml data for a given locale tag. - * - * The locale tag can be either an IETF tag (en-GB) or a simple language code (en) - * - * @param string $localeCode - * The locale code - * - * @return SimplexmlElement - * The locale data - * - * @throws LocalizationFileNotFoundException - * If this locale code has no corresponding xml file - */ - protected function getMainXmlData($localeCode) - { - return simplexml_load_file($this->mainPath($localeCode . '.xml')); - } - - /** - * Get the real path for CLDR main data folder - * If a filename is provided, it will be added at the end of the path. - * - * @param string $filename (Optional) The filename to be added to the path - * - * @return string The realpath of CLDR main data folder - * - * @throws LocalizationFileNotFoundException - */ - protected function mainPath($filename = '') - { - $path = realpath(_PS_ROOT_DIR_ . '/' . self::CLDR_MAIN . ($filename ? $filename : '')); - if (false === $path) { - throw new LocalizationFileNotFoundException("The file $filename does not exist"); - } - - return $path; - } - - /** - * Extracts locale data from CLDR xml data. - * XML data will be mapped in a LocaleData object. - * - * @param string $localeTag The wanted locale. Can be either a language code (e.g.: fr) of an IETF tag (e.g.: en-US) - * - * @return LocaleData - */ - protected function getLocaleData($localeTag) - { - $xmlData = $this->getMainXmlData($localeTag); - - $supplementalData = ['digits' => $this->getDigitsData()]; - - return $this->mapLocaleData($xmlData, $supplementalData); - } - - /** - * Maps locale data from SimplexmlElement to a LocaleData object. - * - * @param SimplexmlElement $xmlLocaleData - * XML locale data - * @param array $supplementalData - * Supplemental locale data - * - * @return LocaleData - * The mapped locale data - * - * @todo use $supplementalData for non-occidental digits - * - * @see http://cldr.unicode.org/development/development-process/design-proposals/resolution-of-cldr-files - */ - protected function mapLocaleData(SimpleXMLElement $xmlLocaleData, $supplementalData) - { - $localeData = new LocaleData(); - - // Geo - if (isset($xmlLocaleData->identity->language)) { - $localeData->setLocaleCode((string) $xmlLocaleData->identity->language['type']); - } - if (isset($xmlLocaleData->identity->territory)) { - $localeData->setLocaleCode( - $localeData->getLocaleCode() . '-' . $xmlLocaleData->identity->territory['type'] - ); - } - - // Numbers - $numbersData = $xmlLocaleData->numbers; - // Default numbering system. - if (isset($numbersData->defaultNumberingSystem)) { - $localeData->setDefaultNumberingSystem((string) $numbersData->defaultNumberingSystem); - } - // Minimum grouping digits value defines when we should start grouping digits. - // 1 => we start grouping at 4 figures numbers (1,000+) (most frequent) - // 2 => we start grouping at 5 figures numbers (10,000+) - if (isset($numbersData->minimumGroupingDigits)) { - $localeData->setMinimumGroupingDigits((int) $numbersData->minimumGroupingDigits); - } - // Complete numbering systems list with the "others" available for this locale. - // Possible other systems are "native", "traditional" and "finance". - // @see http://www.unicode.org/reports/tr35/tr35-numbers.html#otherNumberingSystems - if (isset($numbersData->otherNumberingSystems)) { - $numberingSystems = []; - foreach ($numbersData->otherNumberingSystems->children() as $system) { - /* @var $system SimplexmlElement */ - $numberingSystems[$system->getName()] = (string) $system; - } - $localeData->setNumberingSystems($numberingSystems); - } - // Symbols (by numbering system) - if (isset($numbersData->symbols)) { - $numberSymbols = $localeData->getNumberSymbols(); - /** @var SimpleXMLElement $symbolsNode */ - foreach ($numbersData->symbols as $symbolsNode) { - if (!isset($symbolsNode['numberSystem'])) { - continue; - } - $thisNumberingSystem = (string) $symbolsNode['numberSystem']; - - // Copying data from another node when relevant (alias) - if (isset($symbolsNode->alias)) { - // @see /localization/CLDR/core/common/main/root.xml - $results = $symbolsNode->xpath($symbolsNode->alias['path']); - if (empty($results)) { - continue; - } - $symbolsNode = $results[0]; - } - - $symbolsList = new NumberSymbolsData(); - if (isset($symbolsNode->decimal)) { - $symbolsList->setDecimal((string) $symbolsNode->decimal); - } - if (isset($symbolsNode->group)) { - $symbolsList->setGroup((string) $symbolsNode->group); - } - if (isset($symbolsNode->list)) { - $symbolsList->setList((string) $symbolsNode->list); - } - if (isset($symbolsNode->percentSign)) { - $symbolsList->setPercentSign((string) $symbolsNode->percentSign); - } - if (isset($symbolsNode->minusSign)) { - $symbolsList->setMinusSign((string) $symbolsNode->minusSign); - } - if (isset($symbolsNode->plusSign)) { - $symbolsList->setPlusSign((string) $symbolsNode->plusSign); - } - if (isset($symbolsNode->exponential)) { - $symbolsList->setExponential((string) $symbolsNode->exponential); - } - if (isset($symbolsNode->superscriptingExponent)) { - $symbolsList->setSuperscriptingExponent((string) $symbolsNode->superscriptingExponent); - } - if (isset($symbolsNode->perMille)) { - $symbolsList->setPerMille((string) $symbolsNode->perMille); - } - if (isset($symbolsNode->infinity)) { - $symbolsList->setInfinity((string) $symbolsNode->infinity); - } - if (isset($symbolsNode->nan)) { - $symbolsList->setNan((string) $symbolsNode->nan); - } - if (isset($symbolsNode->timeSeparator)) { - $symbolsList->setTimeSeparator((string) $symbolsNode->timeSeparator); - } - if (isset($symbolsNode->currencyDecimal)) { - $symbolsList->setCurrencyDecimal((string) $symbolsNode->currencyDecimal); - } - if (isset($symbolsNode->currencyGroup)) { - $symbolsList->setCurrencyGroup((string) $symbolsNode->currencyGroup); - } - - $numberSymbols[$thisNumberingSystem] = $symbolsList; - } - $localeData->setNumberSymbols($numberSymbols); - } - // Decimal patterns (by numbering system) - if (isset($numbersData->decimalFormats)) { - $decimalPatterns = $localeData->getDecimalPatterns(); - /** @var SimplexmlElement $format */ - foreach ($numbersData->decimalFormats as $format) { - /** @var SimplexmlElement $format */ - $numberSystem = (string) $format['numberSystem']; - $patternResult = $format->xpath('decimalFormatLength[not(@type)]/decimalFormat/pattern'); - if (isset($patternResult[0])) { - $decimalPatterns[$numberSystem] = (string) $patternResult[0]; - } - } - // Aliases nodes are in root.xml only. They avoid duplicated data. - // We browse aliases after all regular patterns have been defined, and duplicate data for target number - // systems. - foreach ($numbersData->decimalFormats as $format) { - /** @var SimplexmlElement $format */ - $numberSystem = (string) $format['numberSystem']; - // If alias is set, we just copy data from another numbering system: - $alias = $format->alias; - if ($alias - && preg_match( - "#^\.\.\/decimalFormats\[@numberSystem='([^)]+)'\]$#", - (string) $alias['path'], - $matches - ) - ) { - $aliasNumSys = $matches[1]; - $decimalPatterns[$numberSystem] = $decimalPatterns[$aliasNumSys]; - - continue; - } - } - $localeData->setDecimalPatterns($decimalPatterns); - } - // Percent patterns (by numbering system) - if (isset($numbersData->percentFormats)) { - $percentPatterns = $localeData->getPercentPatterns(); - foreach ($numbersData->percentFormats as $format) { - $numberSystem = (string) $format['numberSystem']; - $patternResult = $format->xpath('percentFormatLength/percentFormat/pattern'); - if (isset($patternResult[0])) { - $percentPatterns[$numberSystem] = (string) $patternResult[0]; - } - } - // Aliases nodes are in root.xml only. They avoid duplicated data. - // We browse aliases after all regular patterns have been defined, and duplicate data for target number - // systems. - foreach ($numbersData->percentFormats as $format) { - /** @var SimplexmlElement $format */ - $numberSystem = (string) $format['numberSystem']; - // If alias is set, we just copy data from another numbering system: - $alias = $format->alias; - if ($alias - && preg_match( - "#^\.\.\/percentFormats\[@numberSystem='([^)]+)'\]$#", - (string) $alias['path'], - $matches - ) - ) { - $aliasNumSys = $matches[1]; - $percentPatterns[$numberSystem] = $percentPatterns[$aliasNumSys]; - - continue; - } - } - $localeData->setPercentPatterns($percentPatterns); - } - // Currency patterns (by numbering system) - if (isset($numbersData->currencyFormats)) { - $currencyPatterns = $localeData->getCurrencyPatterns(); - foreach ($numbersData->currencyFormats as $format) { - /** @var SimplexmlElement $format */ - $numberSystem = (string) $format['numberSystem']; - $patternResult = $format->xpath( - 'currencyFormatLength[not(@*)]/currencyFormat[@type="standard"]/pattern' - ); - if (isset($patternResult[0])) { - $currencyPatterns[$numberSystem] = (string) $patternResult[0]; - } - } - // Aliases nodes are in root.xml only. They avoid duplicated data. - // We browse aliases after all regular patterns have been defined, and duplicate data for target number - // systems. - foreach ($numbersData->currencyFormats as $format) { - /** @var SimplexmlElement $format */ - $numberSystem = (string) $format['numberSystem']; - // If alias is set, we just copy data from another numbering system: - $alias = $format->alias; - if ($alias - && preg_match( - "#^\.\.\/currencyFormats\[@numberSystem='([^)]+)'\]$#", - (string) $alias['path'], - $matches - ) - ) { - $aliasNumSys = $matches[1]; - $currencyPatterns[$numberSystem] = $currencyPatterns[$aliasNumSys]; - - continue; - } - } - $localeData->setCurrencyPatterns($currencyPatterns); - } - - // Currencies - $currenciesData = $numbersData->currencies; - $currencyActiveDateThreshold = time() - self::CURRENCY_ACTIVE_DELAY * 86400; - if (isset($currenciesData->currency)) { - $currencies = $localeData->getCurrencies(); - foreach ($currenciesData->currency as $currencyNode) { - $currencyCode = (string) $currencyNode['type']; - if ($currencyCode == self::CURRENCY_CODE_TEST) { - // dont store test currency - continue; - } - - $currencyData = new CurrencyData(); - $currencyData->setIsoCode($currencyCode); - - // check if currency is still active in one territory - $currencyDates = $this->supplementalXml->supplementalData->xpath('//region/currency[@iso4217="' . $currencyCode . '"]'); - if (!empty($currencyDates) && $this->isCurrencyActiveSomewhere($currencyDates, $currencyActiveDateThreshold)) { - $currencyData->setActive(true); - } else { - // no territory with dates means currency was never used - $currencyData->setActive(false); - } - - // Symbols - $symbols = $currencyData->getSymbols(); - foreach ($currencyNode->symbol as $symbolNode) { - $type = (string) $symbolNode['alt']; - if (empty($type)) { - $type = 'default'; - } - $symbols[$type] = (string) $symbolNode; - } - $currencyData->setSymbols($symbols); - - // Names - $displayNames = $currencyData->getDisplayNames(); - foreach ($currencyNode->displayName as $nameNode) { - $countContext = 'default'; - if (!empty($nameNode['count'])) { - $countContext = (string) $nameNode['count']; - } - $displayNames[$countContext] = (string) $nameNode; - } - $currencyData->setDisplayNames($displayNames); - - // Supplemental (fraction digits and numeric iso code) - $codesMapping = $this->supplementalXml->supplementalData->xpath( - '//codeMappings/currencyCodes[@type="' . $currencyCode . '"]' - ); - - if (!empty($codesMapping)) { - /** @var SimplexmlElement $codesMapping */ - $codesMapping = $codesMapping[0]; - $numericIsoCode = (string) $codesMapping->attributes()->numeric; - if (strlen($numericIsoCode) < 3) { - $numericIsoCode = str_pad($numericIsoCode, 3, '0', STR_PAD_LEFT); - } - $currencyData->setNumericIsoCode($numericIsoCode); - } - - $fractionsData = $this->supplementalXml->supplementalData->xpath( - '//currencyData/fractions/info[@iso4217="' . $currencyCode . '"]' - ); - - if (empty($fractionsData)) { - $fractionsData = $this->supplementalXml->supplementalData->xpath( - '//currencyData/fractions/info[@iso4217="DEFAULT"]' - ); - } - - if (!empty($fractionsData)) { - /** @var SimplexmlElement $fractionsData */ - $fractionsData = $fractionsData[0]; - $currencyData->setDecimalDigits((int) (string) $fractionsData->attributes()->digits); - } - - $currencies[$currencyCode] = $currencyData; - } - $localeData->setCurrencies($currencies); - } - - return $localeData; - } - - /** - * Extract all existing digits sets from supplemental xml data. - * - * @return array - * eg.: - * [ - * 'latn' => '0123456789', - * 'arab' => '٠١٢٣٤٥٦٧٨٩', - * 'fullwide' => '0123456789', - * ] - */ - protected function getDigitsData() - { - $digitsSets = []; - $results = $this->numberingSystemsXml->numberingSystems->xpath('//numberingSystem[@type="numeric"]'); - foreach ($results as $numberingSystem) { - $systemId = (string) $numberingSystem['id']; - $digits = (string) $numberingSystem['digits']; - $digitsSets[$systemId] = $digits; - } - - return $digitsSets; - } - - /** - * @param string $currencyCode currency iso code - * @param SimpleXMLElement $supplementalData xml bloc from CLDR - * @param int $currencyActiveDateThreshold timestamp after which currency should be used - * - * @return bool - */ - protected function shouldCurrencyBeReturned($currencyCode, SimplexmlElement $supplementalData, $currencyActiveDateThreshold) - { - // dont store test currency - if ($currencyCode == self::CURRENCY_CODE_TEST) { - return false; - } - // check if currency is still active in one territory - $currencyDates = $supplementalData->xpath('//region/currency[@iso4217="' . $currencyCode . '"]'); - if (empty($currencyDates)) { - // no territory with dates means currency was never used - return false; - } - - return $this->isCurrencyActiveSomewhere($currencyDates, $currencyActiveDateThreshold); - } - - /** - * check if currency is still in use in some territory - * - * @param array $currencyDates - * @param int $currencyActiveDateThreshold timestamp after which currency should be used - * - * @return bool - */ - protected function isCurrencyActiveSomewhere(array $currencyDates, $currencyActiveDateThreshold) - { - foreach ($currencyDates as $currencyDate) { - if (empty($currencyDate->attributes()->to)) { - // no date "to": currency is active in some territory - return true; - } - - // date "to" given: check if currency was active in near past to propose it - $dateTo = \DateTime::createFromFormat('Y-m-d', $currencyDate->attributes()->to); - if (false !== $dateTo && $dateTo->getTimestamp() > $currencyActiveDateThreshold) { - return true; - } - } - - return false; - } -} diff --git a/src/Core/Localization/CLDR/ReaderInterface.php b/src/Core/Localization/CLDR/ReaderInterface.php deleted file mode 100644 index 69216a81..00000000 --- a/src/Core/Localization/CLDR/ReaderInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\CLDR; - -interface ReaderInterface -{ - /** - * Read locale data by locale code. - * - * @param $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @return LocaleData - * A LocaleData object - */ - public function readLocaleData($localeCode); -} diff --git a/src/Core/Localization/Currency.php b/src/Core/Localization/Currency.php deleted file mode 100644 index e1f2bc8f..00000000 --- a/src/Core/Localization/Currency.php +++ /dev/null @@ -1,222 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * The Currency class is used to feed callers with currency-related data. - * - * For instance, the LocaleRepository uses currency data to build Price specifications - */ -class Currency implements CurrencyInterface -{ - /** - * Is this currency active ? - * - * @var bool - */ - protected $isActive; - - /** - * Conversion rate of this currency against the default shop's currency. - * - * Price in currency A * currency A's conversion rate = price in default currency - * - * Example: - * Given the Euro as default shop's currency, - * If 1 dollar = 1.31 euros, - * Then conversion rate for Dollar will be 1.31 - * - * @var float - */ - protected $conversionRate; - - /** - * Currency's alphabetic ISO code (ISO 4217). - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @var string - */ - protected $isoCode; - - /** - * Currency's numeric ISO code (ISO 4217). - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @var string - */ - protected $numericIsoCode; - - /** - * Currency's symbols, by locale code. - * - * eg.: $symbolsUSD = [ - * 'en-US' => '$', - * 'es-CO' => 'US$', // In Colombia, colombian peso's symbol is "$". They have to differentiate foreign dollars. - * ] - * - * @var string[] - */ - protected $symbols; - - /** - * Number of decimal digits to use with this currency. - * - * @var int - */ - protected $precision; - - /** - * the currency's name, by locale code. - * - * @var string[] - */ - protected $names; - - /** - * Currency's patterns, by locale code. - * - * eg.: $patternsUSD = [ - * 'fr-FR' => '#,##0.00 ¤', - * 'en-EN' => '¤#,##0.00', - * ] - * - * @var string[] - */ - protected $patterns; - - /** - * @param bool $isActive Is this currency active ? - * @param float $conversionRate Conversion rate of this currency against the default shop's currency - * @param string $isoCode Currency's alphabetic ISO code (ISO 4217) - * @param int $numericIsoCode Currency's numeric ISO code (ISO 4217) - * @param string[] $symbols Currency's symbols, by locale code - * @param int $precision Number of decimal digits to use with this currency - * @param string[] $names the currency's name, by locale code - * @param string[] $patterns the currency's pattern, by locale code - */ - public function __construct( - $isActive, - $conversionRate, - $isoCode, - $numericIsoCode, - $symbols, - $precision, - $names, - $patterns = [] - ) { - $this->isActive = $isActive; - $this->conversionRate = $conversionRate; - $this->isoCode = $isoCode; - $this->numericIsoCode = $numericIsoCode; - $this->symbols = $symbols; - $this->precision = $precision; - $this->names = $names; - $this->patterns = $patterns; - } - - /** - * {@inheritdoc} - */ - public function isActive() - { - return $this->isActive; - } - - /** - * {@inheritdoc} - */ - public function getConversionRate() - { - return $this->conversionRate; - } - - /** - * {@inheritdoc} - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * {@inheritdoc} - */ - public function getNumericIsoCode() - { - return $this->numericIsoCode; - } - - /** - * {@inheritdoc} - * - * @throws LocalizationException - */ - public function getSymbol($localeCode) - { - if (!isset($this->symbols[$localeCode])) { - throw new LocalizationException('Unknown locale code: ' . $localeCode); - } - - return $this->symbols[$localeCode]; - } - - /** - * {@inheritdoc} - */ - public function getDecimalPrecision() - { - return $this->precision; - } - - /** - * {@inheritdoc} - * - * @throws LocalizationException - */ - public function getName($localeCode) - { - if (!isset($this->names[$localeCode])) { - throw new LocalizationException('Unknown locale code: ' . $localeCode); - } - - return $this->names[$localeCode]; - } - - /** - * @param string $localeCode - * - * @return string - */ - public function getPattern($localeCode) - { - return $this->patterns[$localeCode] ?? ''; - } -} diff --git a/src/Core/Localization/Currency/CurrencyCollection.php b/src/Core/Localization/Currency/CurrencyCollection.php deleted file mode 100644 index 6083565f..00000000 --- a/src/Core/Localization/Currency/CurrencyCollection.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -use ArrayIterator; -use Countable; -use IteratorAggregate; -use PrestaShop\PrestaShop\Core\Localization\Currency; - -class CurrencyCollection implements IteratorAggregate, Countable -{ - protected $currencies = []; - - /** - * Gets the current CurrencyCollection as an Iterator that includes all currencies. - * - * It implements \IteratorAggregate. - * - * @return Currency[] (needed for auto-completion) - * An ArrayIterator object for iterating over currencies - */ - public function getIterator() - { - /** @var Currency[] $iterator (needed for auto-completion) */ - $iterator = new ArrayIterator($this->currencies); - - return $iterator; - } - - /** - * Gets the number of Currencies in this collection. - * - * @return int - * The number of currencies - */ - public function count() - { - return count($this->currencies); - } - - /** - * Adds a currency at the end of the collection. - * - * @param currency $currency - * The currency to add - * - * @return CurrencyCollection - * Fluent interface - */ - public function add(Currency $currency) - { - $this->currencies[$currency->getIsoCode()] = $currency; - - return $this; - } - - /** - * Returns all currencies in this collection. - * - * @return Currency[] - * An array of currencies - */ - public function all() - { - return $this->currencies; - } - - /** - * Gets a currency by ISO code. - * - * @param string $isoCode - * The currency code (alphabetic ISO 4217 code) - * - * @return Currency|null - * A Currency instance or null when not found - */ - public function get($isoCode) - { - return isset($this->currencies[$isoCode]) - ? $this->currencies[$isoCode] - : null; - } - - /** - * Removes a currency or an array of currencies by iso code from the collection. - * - * @param string|string[] $isoCode - * The currency ISO code or an array of currency ISO codes - * - * @return CurrencyCollection - * Fluent interface - */ - public function remove($isoCode) - { - foreach ((array) $isoCode as $c) { - unset($this->currencies[$c]); - } - - return $this; - } - - /** - * Adds a currency collection at the end of the current set by appending all - * currencies of the added collection. - * - * @param CurrencyCollection $collection The CurrencyCollection to append at the end of the current one - * - * @return CurrencyCollection Fluent interface - */ - public function addCollection(CurrencyCollection $collection) - { - // we need to remove all currencies with the same codes first because just replacing them - // would not place the new currency at the end of the merged array - foreach ($collection->all() as $isoCode => $currency) { - unset($this->currencies[$isoCode]); - $this->currencies[$isoCode] = $currency; - } - - return $this; - } - - /** - * Clear the collection, removing all contained currencies. - * - * @return CurrencyCollection - * Fluent interface - */ - public function clear() - { - $this->currencies = []; - - return $this; - } -} diff --git a/src/Core/Localization/Currency/CurrencyData.php b/src/Core/Localization/Currency/CurrencyData.php deleted file mode 100644 index eb7b38c9..00000000 --- a/src/Core/Localization/Currency/CurrencyData.php +++ /dev/null @@ -1,283 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -/** - * Localization Currency data object. - * - * This class is only used internally, it is mutable and overridable until fully built. It can then be used as - * an intermediary data bag to build a real Localization/Currency (immutable) object. - */ -class CurrencyData -{ - /** - * Is this currency active ? - * - * @var bool - */ - protected $isActive; - - /** - * Conversion rate of this currency against the default shop's currency. - * - * Price in currency A * currency A's conversion rate = price in default currency - * - * Example: - * Given the Euro as default shop's currency, - * If 1 dollar = 1.31 euros, - * Then conversion rate for Dollar will be 1.31 - * - * @var float - */ - protected $conversionRate; - - /** - * Currency's alphabetic ISO code (ISO 4217). - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @var string - */ - protected $isoCode; - - /** - * Currency's numeric ISO code (ISO 4217). - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @var string - */ - protected $numericIsoCode; - - /** - * Currency's symbols, by locale code. - * - * eg.: $symbolsUSD = [ - * 'en-US' => '$', - * 'es-CO' => 'US$', // In Colombia, colombian peso's symbol is "$". They have to differentiate foreign dollars. - * ] - * - * @var string[] - */ - protected $symbols; - - /** - * Number of decimal digits to use with this currency. - * - * @var int - */ - protected $precision; - - /** - * the currency's name, by locale code. - * - * @var string[] - */ - protected $names; - - /** - * Currency's patterns, by locale code. - * - * eg.: $patternsUSD = [ - * 'fr-FR' => '#,##0.00 ¤', - * 'en-EN' => '¤#,##0.00', - * ] - * - * @var string[] - */ - protected $patterns; - - public function overrideWith(CurrencyData $currencyData) - { - if ($currencyData->isActive() !== null) { - $this->isActive = $currencyData->isActive(); - } - - if ($currencyData->getConversionRate() !== null) { - $this->conversionRate = $currencyData->getConversionRate(); - } - - if ($currencyData->getIsoCode() !== null) { - $this->isoCode = $currencyData->getIsoCode(); - } - - if ($currencyData->getNumericIsoCode() !== null) { - $this->numericIsoCode = $currencyData->getNumericIsoCode(); - } - - if ($currencyData->getSymbols() !== null) { - $this->symbols = array_merge($this->symbols ?? [], $currencyData->getSymbols()); - } - - if ($currencyData->getPrecision() !== null) { - $this->precision = $currencyData->getPrecision(); - } - - if ($currencyData->getNames() !== null) { - $this->names = array_merge($this->names ?? [], $currencyData->getNames()); - } - - if ($currencyData->getPatterns() !== null) { - $this->patterns = array_merge($this->patterns ?? [], $currencyData->getPatterns()); - } - - return $this; - } - - /** - * @return bool - */ - public function isActive() - { - return $this->isActive; - } - - /** - * @param bool $isActive - */ - public function setIsActive($isActive) - { - $this->isActive = $isActive; - } - - /** - * @return float - */ - public function getConversionRate() - { - return $this->conversionRate; - } - - /** - * @param float $conversionRate - */ - public function setConversionRate($conversionRate) - { - $this->conversionRate = $conversionRate; - } - - /** - * @return string - */ - public function getIsoCode() - { - return $this->isoCode; - } - - /** - * @param string $isoCode - */ - public function setIsoCode($isoCode) - { - $this->isoCode = $isoCode; - } - - /** - * @return string - */ - public function getNumericIsoCode() - { - return $this->numericIsoCode; - } - - /** - * @param string $numericIsoCode - */ - public function setNumericIsoCode($numericIsoCode) - { - $this->numericIsoCode = $numericIsoCode; - } - - /** - * @return string[] - */ - public function getSymbols() - { - return $this->symbols; - } - - /** - * @param string[] $symbols - */ - public function setSymbols($symbols) - { - $this->symbols = $symbols; - } - - /** - * @return int - */ - public function getPrecision() - { - return $this->precision; - } - - /** - * @param int $precision - */ - public function setPrecision($precision) - { - $this->precision = $precision; - } - - /** - * @return string[] - */ - public function getNames() - { - return $this->names; - } - - /** - * @param string[] $names - */ - public function setNames($names) - { - $this->names = $names; - } - - /** - * Currency patterns, indexed by locale code - * - * @return string[]|null - */ - public function getPatterns(): ?array - { - return $this->patterns; - } - - /** - * Currency patterns, indexed by locale code - * - * @param string[] $patterns - */ - public function setPatterns(array $patterns) - { - $this->patterns = $patterns; - } -} diff --git a/src/Core/Localization/Currency/CurrencyDataLayerInterface.php b/src/Core/Localization/Currency/CurrencyDataLayerInterface.php deleted file mode 100644 index 0061a9d2..00000000 --- a/src/Core/Localization/Currency/CurrencyDataLayerInterface.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -/** - * Currency data layer classes interface. - * - * Describes the behavior of CurrencyDataLayer classes - */ -interface CurrencyDataLayerInterface -{ - /** - * Read Currency data by currency code. - * - * @param string $currencyCode - * The currency code (ISO 4217) - * - * @return CurrencyData - * The searched currency data - */ - public function read($currencyCode); - - /** - * Write a Currency object into the data source. - * - * @param string $currencyCode - * The currency code (ISO 4217) - * @param CurrencyData $currencyData - * The currency data to write - * - * @return CurrencyData - * The currency data to be written by the upper data layer - */ - public function write($currencyCode, $currencyData); - - /** - * Set the lower layer. - * When reading data, if nothing is found then it will try to read in the lower data layer - * When writing data, the data will also be written in the lower data layer. - * - * @param currencyDataLayerInterface $lowerLayer - * The lower data layer - * - * @return self - * Fluent interface - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer); -} diff --git a/src/Core/Localization/Currency/CurrencyDataSource.php b/src/Core/Localization/Currency/CurrencyDataSource.php deleted file mode 100644 index ecb2734d..00000000 --- a/src/Core/Localization/Currency/CurrencyDataSource.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -use PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer\CurrencyInstalled as CurrencyInstalledDataLayer; - -/** - * Localization CurrencyData source - * Uses a stack of middleware data layers to read / write CurrencyData objects. - */ -class CurrencyDataSource implements DataSourceInterface -{ - /** - * The top layer of the middleware stack. - * - * @var CurrencyDataLayerInterface - */ - protected $topLayer; - - /** - * @var CurrencyInstalledDataLayer - */ - protected $installedDataLayer; - - /** - * CurrencyDataSource constructor needs CurrencyDataLayer objects. - * This top layer might be chained with lower layers and will be the entry point of this middleware stack. - * - * @param CurrencyDataLayerInterface $topLayer - * @param CurrencyInstalledDataLayer $installedDataLayer - */ - public function __construct(CurrencyDataLayerInterface $topLayer, CurrencyInstalledDataLayer $installedDataLayer) - { - $this->topLayer = $topLayer; - $this->installedDataLayer = $installedDataLayer; - } - - /** - * {@inheritdoc} - */ - public function getLocalizedCurrencyData(LocalizedCurrencyId $localizedCurrencyId) - { - return $this->topLayer->read($localizedCurrencyId); - } - - /** - * Is this currency available ? - * (an available currency is not deleted AND is active). - * - * @param $currencyCode - * - * @return bool - * True if currency is available - */ - public function isCurrencyAvailable($currencyCode) - { - return $this->installedDataLayer->isAvailable($currencyCode); - } - - /** - * {@inheritdoc} - */ - public function getAvailableCurrenciesData($localeCode) - { - return $this->formatCurrenciesData($this->installedDataLayer->getAvailableCurrencyCodes(), $localeCode); - } - - /** - * {@inheritdoc} - */ - public function getAllInstalledCurrenciesData($localeCode) - { - return $this->formatCurrenciesData($this->installedDataLayer->getAllInstalledCurrencyIsoCodes(), $localeCode); - } - - /** - * @param array $currencyCodes - * @param string $localeCode - * - * @return array - */ - private function formatCurrenciesData(array $currencyCodes, $localeCode) - { - $currenciesData = []; - foreach ($currencyCodes as $currencyCode) { - $currenciesData[] = $this->getLocalizedCurrencyData(new LocalizedCurrencyId($currencyCode, $localeCode)); - } - - return $currenciesData; - } -} diff --git a/src/Core/Localization/Currency/DataLayer/CurrencyCache.php b/src/Core/Localization/Currency/DataLayer/CurrencyCache.php deleted file mode 100644 index ceeb6fc7..00000000 --- a/src/Core/Localization/Currency/DataLayer/CurrencyCache.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer; - -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Data\Layer\DataLayerException; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyData as CurrencyData; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyDataLayerInterface as CurrencyDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\Currency\LocalizedCurrencyId; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use Symfony\Component\Cache\Adapter\AdapterInterface; - -/** - * Localization/CurrencyCache data layer. - * - * This currency data layer reads and writes Localization/CurrencyData from a cache adapter - */ -class CurrencyCache extends AbstractDataLayer implements CurrencyDataLayerInterface -{ - /** - * Symfony Cache component adapter. - * - * Provides cached CurrencyData objects - * Implements PSR-6: Cache Interface (@see http://www.php-fig.org/psr/psr-6/) - * - * @var AdapterInterface - */ - private $cache; - - public function __construct(AdapterInterface $cache) - { - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a CurrencyData object into the current layer. - * - * Might be a file access, cache read, DB select... - * - * @param LocalizedCurrencyId $currencyDataId - * The CurrencyData object identifier (currency code + locale code) - * - * @return CurrencyData|null - * The wanted CurrencyData object (null if not found) - * - * @throws LocalizationException - * When $currencyDataId is invalid - * @throws \Psr\Cache\InvalidArgumentException - */ - protected function doRead($currencyDataId) - { - if (!$currencyDataId instanceof LocalizedCurrencyId) { - throw new LocalizationException('$currencyDataId must be a CurrencyDataIdentifier object'); - } - - $cacheItem = $this->cache->getItem((string) $currencyDataId); - - return $cacheItem->isHit() - ? $cacheItem->get() - : null; - } - - /** - * Actually write a CurrencyData object into the current layer. - * - * Might be a file edit, cache update, DB insert/update... - * - * @param LocalizedCurrencyId $currencyDataId - * The data object identifier - * @param CurrencyData $currencyData - * The data object to be written - * - * @throws DataLayerException - * When write fails - * @throws LocalizationException - * When $currencyDataId is invalid - * @throws \Psr\Cache\InvalidArgumentException - */ - protected function doWrite($currencyDataId, $currencyData) - { - if (!$currencyDataId instanceof LocalizedCurrencyId) { - throw new LocalizationException('$currencyDataId must be a CurrencyDataIdentifier object'); - } - - $cacheItem = $this->cache->getItem((string) $currencyDataId); - $cacheItem->set($currencyData); - - $saved = $this->cache->save($cacheItem); - - if (!$saved) { - throw new DataLayerException('Unable to persist data in cache data layer'); - } - } -} diff --git a/src/Core/Localization/Currency/DataLayer/CurrencyDatabase.php b/src/Core/Localization/Currency/DataLayer/CurrencyDatabase.php deleted file mode 100644 index 0ae86beb..00000000 --- a/src/Core/Localization/Currency/DataLayer/CurrencyDatabase.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer; - -use Language; -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Data\Layer\DataLayerException; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyData; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\Currency\LocalizedCurrencyId; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * Currency Database data layer. - * - * Provides and persists currency data from/into database - */ -class CurrencyDatabase extends AbstractDataLayer implements CurrencyDataLayerInterface -{ - /** - * @var CurrencyDataProviderInterface - */ - protected $dataProvider; - - /** - * This layer must be ready only, displaying a price should not change the database data - * - * @var bool - */ - protected $isWritable = false; - - /** - * @param CurrencyDataProviderInterface $dataProvider - */ - public function __construct( - CurrencyDataProviderInterface $dataProvider - ) { - $this->dataProvider = $dataProvider; - } - - /** - * Set the lower layer. - * When reading data, if nothing is found then it will try to read in the lower data layer - * When writing data, the data will also be written in the lower data layer. - * - * @param currencyDataLayerInterface $lowerLayer - * The lower data layer - * - * @return self - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a data object into the current layer. - * - * Data is read into database - * - * @param LocalizedCurrencyId $currencyDataId - * The CurrencyData object identifier (currency code + locale code) - * - * @return CurrencyData|null - * The wanted CurrencyData object (null if not found) - * - * @throws LocalizationException - * When $currencyDataId is invalid - */ - protected function doRead($currencyDataId) - { - if (!$currencyDataId instanceof LocalizedCurrencyId) { - throw new LocalizationException('First parameter must be an instance of ' . LocalizedCurrencyId::class); - } - - $localeCode = $currencyDataId->getLocaleCode(); - $currencyCode = $currencyDataId->getCurrencyCode(); - $currencyEntity = $this->dataProvider->getCurrencyByIsoCodeAndLocale($currencyCode, $localeCode); - - if (null === $currencyEntity) { - return null; - } - - $currencyData = new CurrencyData(); - $currencyData->setIsoCode($currencyEntity->iso_code); - $currencyData->setNumericIsoCode($currencyEntity->numeric_iso_code); - $currencyData->setPrecision($currencyEntity->precision); - $currencyData->setNames([$localeCode => $currencyEntity->name]); - $currencyData->setSymbols([$localeCode => $currencyEntity->symbol]); - - $idLang = Language::getIdByLocale($localeCode, true); - $currencyPattern = $currencyEntity->getPattern($idLang); - if (!empty($currencyPattern)) { - $currencyData->setPatterns([$localeCode => $currencyEntity->getPattern($idLang)]); - } - - return $currencyData; - } - - /** - * Actually write a data object into the current layer - * Here, this is a DB insert/update... - * - * @param LocalizedCurrencyId $currencyDataId - * The CurrencyData object identifier (currency code + locale code) - * @param CurrencyData $currencyData - * The data object to be written - * - * @throws DataLayerException - * If something goes wrong when trying to write into DB - * @throws LocalizationException - * When $currencyDataId is invalid - */ - protected function doWrite($currencyDataId, $currencyData) - { - // We should not save anything in this layer. The CLDR or its Repository nor any of its layers - // should modify the database. This could override customization added by the user with default - // CLDR values. Any changes on the database must be managed through the backoffice and the appropriate - // commands/handlers - } -} diff --git a/src/Core/Localization/Currency/DataLayer/CurrencyInstalled.php b/src/Core/Localization/Currency/DataLayer/CurrencyInstalled.php deleted file mode 100644 index 3def6b5b..00000000 --- a/src/Core/Localization/Currency/DataLayer/CurrencyInstalled.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer; - -use Currency; -use PrestaShop\PrestaShop\Core\Currency\CurrencyDataProviderInterface; - -/** - * Installed Currencies data layer. - * - * Provides currencies' installation info - */ -class CurrencyInstalled -{ - /** - * This adapter will provide data from DB / ORM about Currency (via legacy entity). - * - * @var CurrencyDataProviderInterface - */ - protected $dataProvider; - - public function __construct(CurrencyDataProviderInterface $dataProvider) - { - $this->dataProvider = $dataProvider; - } - - /** - * Check if a currency is currently available (not deleted + active). - * - * @param $currencyCode - * The said currency ISO code - * - * @return bool - * True if this currency is available - */ - public function isAvailable($currencyCode) - { - $currency = $this->dataProvider->getCurrencyByIsoCode($currencyCode); - - if ($currency instanceof Currency) { - return (bool) $currency->active; - } - - return false; - } - - /** - * Get all available (not deleted + active) currencies' ISO codes. - * - * @return string[] - */ - public function getAvailableCurrencyCodes() - { - $currencies = $this->dataProvider->findAll(); - $currencyIsoCodes = array_column($currencies, 'iso_code'); - - return $currencyIsoCodes; - } - - /** - * Get all the available currencies' ISO codes (present in database no matter if it's deleted or active). - * - * @return string[] - */ - public function getAllInstalledCurrencyIsoCodes() - { - $currencies = $this->dataProvider->findAllInstalled(); - $currencyIsoCodes = array_column($currencies, 'iso_code'); - - return $currencyIsoCodes; - } -} diff --git a/src/Core/Localization/Currency/DataLayer/CurrencyReference.php b/src/Core/Localization/Currency/DataLayer/CurrencyReference.php deleted file mode 100644 index 8640c03b..00000000 --- a/src/Core/Localization/Currency/DataLayer/CurrencyReference.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer; - -use PrestaShop\PrestaShop\Core\Data\Layer\AbstractDataLayer; -use PrestaShop\PrestaShop\Core\Localization\CLDR\CurrencyInterface as CldrCurrency; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository as CldrLocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyData as CurrencyData; -use PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyDataLayerInterface; -use PrestaShop\PrestaShop\Core\Localization\Currency\LocalizedCurrencyId; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * Localization/CurrencyReference data layer. - * - * Provides reference data for currencies... - * Data comes from CLDR official data files, and is read only. - */ -class CurrencyReference extends AbstractDataLayer implements CurrencyDataLayerInterface -{ - /** - * CLDR locale repository. - * - * Provides LocaleData objects - * - * @var CldrLocaleRepository - */ - protected $cldrLocaleRepository; - - public function __construct(CldrLocaleRepository $cldrLocaleRepository) - { - $this->cldrLocaleRepository = $cldrLocaleRepository; - $this->isWritable = false; - } - - /** - * {@inheritdoc} - */ - public function setLowerLayer(CurrencyDataLayerInterface $lowerLayer) - { - $this->lowerDataLayer = $lowerLayer; - - return $this; - } - - /** - * Actually read a CurrencyData object into the current layer. - * - * Data is read from official CLDR files (via the CLDR LocaleRepository) - * - * @param LocalizedCurrencyId $currencyDataId - * The CurrencyData object identifier - * - * @return CurrencyData|null - * The wanted CurrencyData object (null if not found) - * - * @throws LocalizationException - * In case of invalid $currencyDataId - * Also in case of invalid type asked for symbol (but use a constant, so it is very unlikely...) - */ - protected function doRead($currencyDataId) - { - if (!$currencyDataId instanceof LocalizedCurrencyId) { - throw new LocalizationException('$currencyDataId must be a CurrencyDataIdentifier object'); - } - - $localeCode = $currencyDataId->getLocaleCode(); - $cldrLocale = $this->cldrLocaleRepository->getLocale($localeCode); - - if (empty($cldrLocale)) { - return null; - } - - $cldrCurrency = $cldrLocale->getCurrency($currencyDataId->getCurrencyCode()); - - if (empty($cldrCurrency)) { - return null; - } - - $currencyData = new CurrencyData(); - $currencyData->setIsoCode($cldrCurrency->getIsoCode()); - $currencyData->setNumericIsoCode($cldrCurrency->getNumericIsoCode()); - $currencyData->setSymbols([$localeCode => $cldrCurrency->getSymbol(CldrCurrency::SYMBOL_TYPE_NARROW)]); - $currencyData->setPrecision($cldrCurrency->getDecimalDigits()); - $currencyData->setNames([$localeCode => $cldrCurrency->getDisplayName()]); - - return $currencyData; - } - - /** - * CLDR files are read only. Nothing can be written there. - * - * @param LocalizedCurrencyId $currencyDataId - * The LocaleData object identifier - * @param CurrencyData $currencyData - * The CurrencyData object to be written - */ - protected function doWrite($currencyDataId, $currencyData) - { - // Nothing. - } -} diff --git a/src/Core/Localization/Currency/DataSourceInterface.php b/src/Core/Localization/Currency/DataSourceInterface.php deleted file mode 100644 index 2ec24db9..00000000 --- a/src/Core/Localization/Currency/DataSourceInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -/** - * Currency data repository interface. - * - * Describes the behavior of currency DataRepository classes - */ -interface DataSourceInterface -{ - /** - * Get complete currency data by currency code, in a given language. - * - * @param LocalizedCurrencyId $localizedCurrencyId - * The currency data identifier (currency code + locale code) - * - * @return CurrencyData - * The currency data - */ - public function getLocalizedCurrencyData(LocalizedCurrencyId $localizedCurrencyId); - - /** - * Is this currency available ? - * (an available currency is not deleted AND is active). - * - * @param $currencyCode - * - * @return bool - * True if currency is available - */ - public function isCurrencyAvailable($currencyCode); - - /** - * Get all the available (installed + active) currencies' data. - * - * @param string $localeCode - * Data will be translated in this language - * - * @return CurrencyData[] - * The available currencies' data - */ - public function getAvailableCurrenciesData($localeCode); - - /** - * Get all installed currencies' data in database (regardless of their active or soft deleted status). - * - * @param string $localeCode - * Data will be translated in this language - * - * @return CurrencyData[] - * The installed currencies' database data - */ - public function getAllInstalledCurrenciesData($localeCode); -} diff --git a/src/Core/Localization/Currency/LocalizedCurrencyId.php b/src/Core/Localization/Currency/LocalizedCurrencyId.php deleted file mode 100644 index c3c60698..00000000 --- a/src/Core/Localization/Currency/LocalizedCurrencyId.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -/** - * Value-object representing an identifier for a currency, "translated" in a given locale (language + region). - */ -class LocalizedCurrencyId -{ - /** - * ISO 4217 code of the currency. - * - * @var string - */ - private $currencyCode; - - /** - * CurrencyData's data is translated in this locale. - * IETF tag (e.g.: fr-FR, en-US...). - * - * @var string - */ - private $localeCode; - - /** - * @param string $currencyCode - * ISO 4217 currency code - * @param $localeCode - * IETF tag (e.g.: fr-FR, en-US...) - */ - public function __construct($currencyCode, $localeCode) - { - $this->currencyCode = $currencyCode; - $this->localeCode = $localeCode; - } - - public function __toString() - { - return $this->currencyCode . '-' . $this->localeCode; - } - - /** - * @return string - */ - public function getCurrencyCode() - { - return $this->currencyCode; - } - - /** - * @return string - */ - public function getLocaleCode() - { - return $this->localeCode; - } -} diff --git a/src/Core/Localization/Currency/PatternTransformer.php b/src/Core/Localization/Currency/PatternTransformer.php deleted file mode 100644 index d666c771..00000000 --- a/src/Core/Localization/Currency/PatternTransformer.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; - -/** - * Transform a currency pattern by moving the symbol position, with or without - * a separation space (no-break space). - */ -class PatternTransformer -{ - const NO_BREAK_SPACE = "\u{00A0}"; - const RTL_CHARACTER = "\u{200F}"; - const REGULAR_SPACE = ' '; - const CURRENCY_SYMBOL = '¤'; - - const TYPE_LEFT_SYMBOL_WITH_SPACE = 'leftWithSpace'; - const TYPE_LEFT_SYMBOL_WITHOUT_SPACE = 'leftWithoutSpace'; - const TYPE_RIGHT_SYMBOL_WITH_SPACE = 'rightWithSpace'; - const TYPE_RIGHT_SYMBOL_WITHOUT_SPACE = 'rightWithoutSpace'; - - const ALLOWED_TRANSFORMATIONS = [ - self::TYPE_LEFT_SYMBOL_WITH_SPACE, - self::TYPE_LEFT_SYMBOL_WITHOUT_SPACE, - self::TYPE_RIGHT_SYMBOL_WITH_SPACE, - self::TYPE_RIGHT_SYMBOL_WITHOUT_SPACE, - ]; - - const CHARACTERS_TO_TRIM = - self::CURRENCY_SYMBOL . - self::NO_BREAK_SPACE . - self::REGULAR_SPACE . - self::RTL_CHARACTER - ; - - const TRANSFORM_DICTIONARY = [ - self::TYPE_LEFT_SYMBOL_WITH_SPACE => '$rtl$currencySymbol$nbsp$pattern', - self::TYPE_LEFT_SYMBOL_WITHOUT_SPACE => '$rtl$currencySymbol$pattern', - self::TYPE_RIGHT_SYMBOL_WITH_SPACE => '$rtl$pattern$nbsp$currencySymbol', - self::TYPE_RIGHT_SYMBOL_WITHOUT_SPACE => '$rtl$pattern$currencySymbol', - ]; - - /** - * @param string $currencyPattern - * @param string $transformationType - * - * @return string - * - * @throws InvalidArgumentException - */ - public function transform(string $currencyPattern, string $transformationType): string - { - if (!in_array($transformationType, self::ALLOWED_TRANSFORMATIONS)) { - throw new InvalidArgumentException(sprintf('Invalid transformation type "%s", allowed transformations are: %s', $transformationType, implode(',', self::ALLOWED_TRANSFORMATIONS))); - } - - $transformedPatterns = []; - $currencyPatterns = explode(';', $currencyPattern); - foreach ($currencyPatterns as $pattern) { - $transformedPatterns[] = $this->transformPattern($pattern, $transformationType); - } - - return implode(';', $transformedPatterns); - } - - /** - * @param string $currencyPattern - * - * @return string - */ - public function getTransformationType(string $currencyPattern) - { - $patterns = explode(';', $currencyPattern); - $pattern = str_replace(self::RTL_CHARACTER, '', $patterns[0]); - - $regexpList = [ - self::TYPE_LEFT_SYMBOL_WITH_SPACE => '/^¤[ ' . self::NO_BREAK_SPACE . ']+.+/', - self::TYPE_LEFT_SYMBOL_WITHOUT_SPACE => '/^¤[^ ' . self::NO_BREAK_SPACE . ']+/', - self::TYPE_RIGHT_SYMBOL_WITH_SPACE => '/.+[ ' . self::NO_BREAK_SPACE . ']+¤$/', - self::TYPE_RIGHT_SYMBOL_WITHOUT_SPACE => '/[^ ' . self::NO_BREAK_SPACE . ']+¤$/', - ]; - foreach ($regexpList as $type => $regexp) { - if (preg_match($regexp, $pattern)) { - return $type; - } - } - - return ''; - } - - /** - * @param string $basePattern - * @param string $transformationType - * - * @return string - */ - private function transformPattern(string $basePattern, string $transformationType) - { - $rtlCharacter = $this->getRtlCharacter($basePattern); - $trimmedPattern = trim($basePattern, self::CHARACTERS_TO_TRIM); - - return strtr( - self::TRANSFORM_DICTIONARY[$transformationType], - [ - '$rtl' => $rtlCharacter, - '$currencySymbol' => self::CURRENCY_SYMBOL, - '$nbsp' => self::NO_BREAK_SPACE, - '$pattern' => $trimmedPattern, - ] - ); - } - - /** - * @param string $currencyPattern - * - * @return string - */ - private function getRtlCharacter(string $currencyPattern): string - { - return (false !== strpos($currencyPattern, self::RTL_CHARACTER)) ? self::RTL_CHARACTER : ''; - } -} diff --git a/src/Core/Localization/Currency/Repository.php b/src/Core/Localization/Currency/Repository.php deleted file mode 100644 index 274e3d8b..00000000 --- a/src/Core/Localization/Currency/Repository.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -use PrestaShop\PrestaShop\Core\Localization\Currency; -use PrestaShop\PrestaShop\Core\Localization\Currency\DataSourceInterface as CurrencyDataSourceInterface; -use PrestaShop\PrestaShop\Core\Localization\Currency\RepositoryInterface as CurrencyRepositoryInterface; - -/** - * Currency repository class. - * - * Used to get Localization/Currency instances (by currency code for example) - */ -class Repository implements CurrencyRepositoryInterface -{ - /** - * Available currencies, indexed by ISO code. - * Lazy loaded. - * - * @var Currency[] - */ - protected $currencies; - - /** - * @var CurrencyDataSourceInterface - */ - protected $dataSource; - - public function __construct(CurrencyDataSourceInterface $dataSource) - { - $this->dataSource = $dataSource; - } - - /** - * {@inheritdoc} - */ - public function getCurrency($currencyCode, $localeCode) - { - if (!isset($this->currencies[$currencyCode])) { - $data = $this->dataSource->getLocalizedCurrencyData( - new LocalizedCurrencyId($currencyCode, $localeCode) - ); - - $this->currencies[$currencyCode] = $this->createCurrencyFromData($data); - } - - return $this->currencies[$currencyCode]; - } - - /** - * {@inheritdoc} - */ - public function getAvailableCurrencies($localeCode) - { - return $this->createCurrenciesFromData($this->dataSource->getAvailableCurrenciesData($localeCode)); - } - - /** - * {@inheritdoc} - */ - public function getAllInstalledCurrencies($localeCode) - { - return $this->createCurrenciesFromData($this->dataSource->getAllInstalledCurrenciesData($localeCode)); - } - - /** - * @param array $currenciesData - * - * @return CurrencyCollection - */ - private function createCurrenciesFromData(array $currenciesData) - { - $currencies = new CurrencyCollection(); - /** @var CurrencyData $currencyDatum */ - foreach ($currenciesData as $currencyDatum) { - $currencies->add($this->createCurrencyFromData($currencyDatum)); - } - - return $currencies; - } - - /** - * @param CurrencyData $currencyData - * - * @return Currency - */ - private function createCurrencyFromData(CurrencyData $currencyData) - { - return new Currency( - $currencyData->isActive(), - $currencyData->getConversionRate(), - $currencyData->getIsoCode(), - $currencyData->getNumericIsoCode(), - $currencyData->getSymbols(), - $currencyData->getPrecision(), - $currencyData->getNames(), - $currencyData->getPatterns() - ); - } -} diff --git a/src/Core/Localization/Currency/RepositoryInterface.php b/src/Core/Localization/Currency/RepositoryInterface.php deleted file mode 100644 index 69b1ae00..00000000 --- a/src/Core/Localization/Currency/RepositoryInterface.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Currency; - -use PrestaShop\PrestaShop\Core\Localization\Currency; - -/** - * Currency repository interface. - * - * Describes the behavior of Currency Repository classes - */ -interface RepositoryInterface -{ - /** - * Get a Currency instance by ISO code. - * - * @param string $currencyCode - * Wanted currency's ISO code - * Must be an alphabetic ISO 4217 currency code - * @param string $localeCode - * Currency data will be translated in this language - * - * @return Currency - * The wanted Currency instance - */ - public function getCurrency($currencyCode, $localeCode); - - /** - * Get all the available currencies (installed + active). - * - * @param string $localeCode - * IETF tag. Data will be translated in this language - * - * @return CurrencyCollection - * The available currencies - */ - public function getAvailableCurrencies($localeCode); - - /** - * Get all the installed currencies in database (regardless of their active or soft deleted status). - * - * @param string $localeCode - * IETF tag. Data will be translated in this language - * - * @return CurrencyCollection - * The installed currencies in database - */ - public function getAllInstalledCurrencies($localeCode); -} diff --git a/src/Core/Localization/CurrencyInterface.php b/src/Core/Localization/CurrencyInterface.php deleted file mode 100644 index 73967c52..00000000 --- a/src/Core/Localization/CurrencyInterface.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization; - -/** - * Currency entities interface. - * - * Describes the behavior of currency classes - */ -interface CurrencyInterface -{ - /** - * Check if this currency is active. - * - * @return bool - * true if currency is active - */ - public function isActive(); - - /** - * Get the conversion rate (exchange rate) of this currency against the shop's default currency. - * - * Price in currency A * currency A's conversion rate = price in default currency - * - * Example: - * Given the Euro as default shop's currency, - * If 1 dollar = 1.31 euros, - * Then conversion rate for Dollar will be 1.31 - * - * @return float - * The conversion rate of this currency - */ - public function getConversionRate(); - - /** - * Get the alphabetic ISO code of this currency. - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @return string - */ - public function getIsoCode(); - - /** - * Get the numeric ISO code of this currency. - * - * @see https://www.iso.org/iso-4217-currency-codes.html - * - * @return int - */ - public function getNumericIsoCode(); - - /** - * Get the currency symbol for a given locale code. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @see https://en.wikipedia.org/wiki/IETF_language_tag - * @see https://www.w3.org/International/articles/language-tags - * - * @return string - * The currency symbol for this locale - */ - public function getSymbol($localeCode); - - /** - * Get the number of decimal digits to use with this currency. - * - * Example: Euro's decimal precision is 2 (1 234,56 EUR) - * Example: Colombian peso's decimal precision is 0 (1 235 COP) - * - * @return int - */ - public function getDecimalPrecision(); - - /** - * Get the currency's name for a given locale code. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @see https://en.wikipedia.org/wiki/IETF_language_tag - * @see https://www.w3.org/International/articles/language-tags - * - * @return string - * The currency's name for this locale - */ - public function getName($localeCode); -} diff --git a/src/Core/Localization/Exception/LocalizationException.php b/src/Core/Localization/Exception/LocalizationException.php deleted file mode 100644 index f946537d..00000000 --- a/src/Core/Localization/Exception/LocalizationException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Base class for core localization exceptions - */ -class LocalizationException extends CoreException -{ -} diff --git a/src/Core/Localization/Exception/LocalizationFileNotFoundException.php b/src/Core/Localization/Exception/LocalizationFileNotFoundException.php deleted file mode 100644 index 3163d30e..00000000 --- a/src/Core/Localization/Exception/LocalizationFileNotFoundException.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Exception; - -class LocalizationFileNotFoundException extends LocalizationException -{ -} diff --git a/src/Core/Localization/Locale.php b/src/Core/Localization/Locale.php deleted file mode 100644 index 1cfc94eb..00000000 --- a/src/Core/Localization/Locale.php +++ /dev/null @@ -1,185 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Number\Formatter as NumberFormatter; -use PrestaShop\PrestaShop\Core\Localization\Specification\Number as NumberSpecification; -use PrestaShop\PrestaShop\Core\Localization\Specification\NumberCollection as PriceSpecificationMap; -use PrestaShop\PrestaShop\Core\Localization\Specification\Price as PriceSpecification; - -/** - * Locale entity. - * - * This is the main CLDR entry point. For example, Locale is used to format numbers, prices, percentages. - * To build a Locale instance, use the Locale repository. - */ -class Locale implements LocaleInterface -{ - /** - * Latin numbering system is the "occidental" numbering system. Number digits are 0123456789. - * This is the default numbering system in PrestaShop, even for arabian or asian languages, until we - * provide a way to configure this in admin. - */ - const NUMBERING_SYSTEM_LATIN = 'latn'; - - /** - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US. - * - * @var string - */ - protected $code; - - /** - * Number formatter. - * Used to format raw numbers in this locale context. - * - * @var NumberFormatter - */ - protected $numberFormatter; - - /** - * Number formatting specification. - * - * @var NumberSpecification - */ - protected $numberSpecification; - - /** - * Price formatting specifications collection (one spec per currency). - * - * @var PriceSpecificationMap - */ - protected $priceSpecifications; - - /** - * Locale constructor. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * @param NumberSpecification $numberSpecification - * Number specification used when formatting a number - * @param PriceSpecificationMap $priceSpecifications - * Collection of Price specifications (one per installed currency) - * @param NumberFormatter $formatter - * This number formatter will use stored number / price specs - */ - public function __construct( - $localeCode, - NumberSpecification $numberSpecification, - PriceSpecificationMap $priceSpecifications, - NumberFormatter $formatter - ) { - $this->code = (string) $localeCode; - $this->numberSpecification = $numberSpecification; - $this->priceSpecifications = $priceSpecifications; - $this->numberFormatter = $formatter; - } - - /** - * Get this locale's code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US. - * - * @return string - */ - public function getCode() - { - return $this->code; - } - - /** - * Format a number according to locale rules. - * - * @param int|float|string $number - * The number to be formatted - * - * @return string - * The formatted number - * - * @throws Exception\LocalizationException - */ - public function formatNumber($number) - { - return $this->numberFormatter->format( - $number, - $this->numberSpecification - ); - } - - /** - * Format a number as a price. - * - * @param int|float|string $number - * Number to be formatted as a price - * @param string $currencyCode - * Currency of the price - * - * @return string The formatted price - * - * @throws Exception\LocalizationException - */ - public function formatPrice($number, $currencyCode) - { - return $this->numberFormatter->format( - $number, - $this->getPriceSpecification($currencyCode) - ); - } - - /** - * Get price specification - * - * @param string $currencyCode Currency of the price - * - * @return PriceSpecification - */ - public function getPriceSpecification($currencyCode) - { - $currencyCode = (string) $currencyCode; - $priceSpec = $this->priceSpecifications->get($currencyCode); - if (null === $priceSpec) { - throw new LocalizationException('Price specification not found for currency: "' . $currencyCode . '"'); - } - - return $priceSpec; - } - - /** - * Get number specification - * - * @return NumberSpecification - */ - public function getNumberSpecification() - { - return $this->numberSpecification; - } -} diff --git a/src/Core/Localization/Locale/Repository.php b/src/Core/Localization/Locale/Repository.php deleted file mode 100644 index 74191fa7..00000000 --- a/src/Core/Localization/Locale/Repository.php +++ /dev/null @@ -1,246 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Locale; - -use PrestaShop\Decimal\Operation\Rounding; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository as CldrLocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Currency\RepositoryInterface as CurrencyRepositoryInterface; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShop\PrestaShop\Core\Localization\Number\Formatter as NumberFormatter; -use PrestaShop\PrestaShop\Core\Localization\Specification\Factory as SpecificationFactory; -use PrestaShop\PrestaShop\Core\Localization\Specification\Number as NumberSpecification; -use PrestaShop\PrestaShop\Core\Localization\Specification\NumberCollection as PriceSpecificationMap; -use PrestaShop\PrestaShop\Core\Localization\Specification\Price as PriceSpecification; - -/** - * Locale repository. - * - * Used to get locale instances. - * This repository manages all dependencies needed to create a complete Localization/Locale instance - */ -class Repository implements RepositoryInterface -{ - /** - * Max number of digits to use in the fraction part of a decimal number - * This is a default value. - */ - const MAX_FRACTION_DIGITS = 3; - - /** - * Repository used to retrieve low level CLDR locale objects. - * - * @var CldrLocaleRepository - */ - protected $cldrLocaleRepository; - - /** - * Repository used to retrieve Currency objects. - * - * @var CurrencyRepositoryInterface - */ - protected $currencyRepository; - - /** - * Rounding mode to use when formatting numbers - * Possible values are listed in PrestaShop\Decimal\Operation\Rounding::ROUND_* constants. - * - * @var string - */ - protected $roundingMode; - - /** - * Numbering system to use when formatting numbers. - * Default value: "latn". - * - * @see http://cldr.unicode.org/translation/numbering-systems - * - * @var string - */ - protected $numberingSystem; - - /** - * Currency display type - * Default is "symbol". But sometimes you may want to display the currency code instead. - * Possible values: PrestaShop\PrestaShop\Core\Localization\Specification\Price::CURRENCY_DISPLAY_*. - * - * @var string - */ - protected $currencyDisplayType; - - /** - * Already instantiated Locale objects. - * - * @var Locale[] - */ - protected $locales; - - /** - * Should we group digits in a number's integer part ? - * - * @var bool - */ - protected $numberGroupingUsed; - - /** - * Max number of digits to display in a number's decimal part. - * - * @var int - */ - protected $maxFractionDigits; - - /** - * @var SpecificationFactory - */ - protected $specificationFactory; - - public function __construct( - CldrLocaleRepository $cldrLocaleRepository, - CurrencyRepositoryInterface $currencyRepository, - $roundingMode = Rounding::ROUND_HALF_UP, - $numberingSystem = Locale::NUMBERING_SYSTEM_LATIN, - $currencyDisplayType = PriceSpecification::CURRENCY_DISPLAY_SYMBOL, - $groupingUsed = true, - $maxFractionDigits = self::MAX_FRACTION_DIGITS - ) { - $this->cldrLocaleRepository = $cldrLocaleRepository; - $this->currencyRepository = $currencyRepository; - $this->roundingMode = $roundingMode; - $this->numberingSystem = $numberingSystem; - $this->currencyDisplayType = $currencyDisplayType; - $this->numberGroupingUsed = $groupingUsed; - $this->maxFractionDigits = $maxFractionDigits; - $this->specificationFactory = new SpecificationFactory(); - } - - /** - * {@inheritdoc} - */ - public function getLocale($localeCode) - { - if (!isset($this->locales[$localeCode])) { - $this->locales[$localeCode] = new Locale( - $localeCode, - $this->getNumberSpecification($localeCode), - $this->getPriceSpecifications($localeCode), - new NumberFormatter($this->roundingMode, $this->numberingSystem) - ); - } - - return $this->locales[$localeCode]; - } - - /** - * Get the Number specification for a given locale. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @return NumberSpecification - * A Number specification - * - * @throws LocalizationException - */ - protected function getNumberSpecification($localeCode) - { - $cldrLocale = $this->cldrLocaleRepository->getLocale($localeCode); - - if (null === $cldrLocale) { - throw new LocalizationException('CLDR locale not found for locale code "' . $localeCode . '"'); - } - - return $this->specificationFactory->buildNumberSpecification( - $cldrLocale, - $this->maxFractionDigits, - $this->numberGroupingUsed - ); - } - - /** - * Get all the Price specifications for a given locale. - * Each installed currency has its own Price specification. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @return PriceSpecificationMap - * All installed currencies' Price specifications - * - * @throws LocalizationException - */ - protected function getPriceSpecifications($localeCode) - { - $cldrLocale = $this->cldrLocaleRepository->getLocale($localeCode); - if (null === $cldrLocale) { - throw new LocalizationException('CLDR locale not found for locale code "' . $localeCode . '"'); - } - - $currencies = $this->currencyRepository->getAllInstalledCurrencies($localeCode); - - $priceSpecifications = new PriceSpecificationMap(); - foreach ($currencies as $currency) { - // Build the spec - $thisPriceSpecification = (new SpecificationFactory())->buildPriceSpecification( - $localeCode, - $cldrLocale, - $currency, - $this->numberGroupingUsed, - $this->currencyDisplayType, - (int) $currency->getDecimalPrecision() - ); - - // Add the spec to the collection - $priceSpecifications->add( - $thisPriceSpecification->getCurrencyCode(), - $thisPriceSpecification - ); - } - - return $priceSpecifications; - } - - /** - * @return bool - */ - public function isNumberGroupingUsed() - { - return $this->numberGroupingUsed; - } - - /** - * @return string - */ - public function getCurrencyDisplayType() - { - return $this->currencyDisplayType; - } -} diff --git a/src/Core/Localization/Locale/RepositoryInterface.php b/src/Core/Localization/Locale/RepositoryInterface.php deleted file mode 100644 index 1c1f08ac..00000000 --- a/src/Core/Localization/Locale/RepositoryInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Locale; - -use PrestaShop\PrestaShop\Core\Localization\Locale; - -interface RepositoryInterface -{ - /** - * Get a Locale instance by locale code. - * - * @param string $localeCode - * The locale code (simplified IETF tag syntax) - * Combination of ISO 639-1 (2-letters language code) and ISO 3166-2 (2-letters region code) - * eg: fr-FR, en-US - * - * @return Locale - * A Locale instance - */ - public function getLocale($localeCode); -} diff --git a/src/Core/Localization/LocaleInterface.php b/src/Core/Localization/LocaleInterface.php deleted file mode 100644 index 2530ad28..00000000 --- a/src/Core/Localization/LocaleInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization; - -/** - * Locale entity interface. - * - * Describes the behavior of locale classes - */ -interface LocaleInterface -{ - /** - * Format a number according to locale rules. - * - * @param int|float|string $number The number to be formatted - * - * @return string The formatted number - */ - public function formatNumber($number); - - /** - * Format a number as a price. - * - * @param int|float|string $number Number to be formatted as a price - * @param string $currencyCode Currency of the price - * - * @return string The formatted price - */ - public function formatPrice($number, $currencyCode); -} diff --git a/src/Core/Localization/Number/Formatter.php b/src/Core/Localization/Number/Formatter.php deleted file mode 100644 index 9ef12aeb..00000000 --- a/src/Core/Localization/Number/Formatter.php +++ /dev/null @@ -1,403 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Number; - -use InvalidArgumentException as SPLInvalidArgumentException; -use PrestaShop\Decimal\Number as DecimalNumber; -use PrestaShop\Decimal\Operation\Rounding; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Specification\NumberInterface as NumberSpecification; -use PrestaShop\PrestaShop\Core\Localization\Specification\Price as PriceSpecification; - -/** - * Formats a number (raw, price, percentage) according to passed specifications. - */ -class Formatter -{ - /** - * These placeholders are used in CLDR number formatting templates. - * They are meant to be replaced by the correct localized symbols in the number formatting process. - */ - const CURRENCY_SYMBOL_PLACEHOLDER = '¤'; - const DECIMAL_SEPARATOR_PLACEHOLDER = '.'; - const GROUP_SEPARATOR_PLACEHOLDER = ','; - const MINUS_SIGN_PLACEHOLDER = '-'; - const PERCENT_SYMBOL_PLACEHOLDER = '%'; - const PLUS_SIGN_PLACEHOLDER = '+'; - - /** - * @var string The wanted rounding mode when formatting numbers. - * Cf. PrestaShop\Decimal\Operation\Rounding::ROUND_* values - */ - protected $roundingMode; - - /** - * @var string Numbering system to use when formatting numbers - * - * @see http://cldr.unicode.org/translation/numbering-systems - */ - protected $numberingSystem; - - /** - * Number specification to be used when formatting a number. - * - * @var NumberSpecification - */ - protected $numberSpecification; - - /** - * Create a number formatter instance. - * - * @param int $roundingMode - * The wanted rounding mode when formatting numbers - * Cf. PrestaShop\Decimal\Operation\Rounding::ROUND_* values - * @param string $numberingSystem - * Numbering system to use when formatting numbers. @see http://cldr.unicode.org/translation/numbering-systems - */ - public function __construct($roundingMode, $numberingSystem) - { - $this->roundingMode = $roundingMode; - $this->numberingSystem = $numberingSystem; - } - - /** - * Formats the passed number according to specifications. - * - * @param int|float|string $number - * The number to format - * @param NumberSpecification $specification - * Number specification to be used (can be a number spec, a price spec, a percentage spec) - * - * @return string - * The formatted number - * You should use this this value for display, without modifying it - * - * @throws LocalizationException - */ - public function format($number, NumberSpecification $specification) - { - $this->numberSpecification = $specification; - - try { - $decimalNumber = $this->prepareNumber($number); - } catch (SPLInvalidArgumentException $e) { - throw new LocalizationException('Invalid $number parameter: ' . $e->getMessage(), 0, $e); - } - - /* - * We need to work on the absolute value first. - * Then the CLDR pattern will add the sign if relevant (at the end). - */ - $isNegative = $decimalNumber->isNegative(); - $decimalNumber = $decimalNumber->toPositive(); - - list($majorDigits, $minorDigits) = $this->extractMajorMinorDigits($decimalNumber); - $majorDigits = $this->splitMajorGroups($majorDigits); - $minorDigits = $this->adjustMinorDigitsZeroes($minorDigits); - - // Assemble the final number - $formattedNumber = $majorDigits; - if ($minorDigits) { - $formattedNumber .= self::DECIMAL_SEPARATOR_PLACEHOLDER . $minorDigits; - } - - // Get the good CLDR formatting pattern. Sign is important here ! - $pattern = $this->getCldrPattern($isNegative); - $formattedNumber = $this->addPlaceholders($formattedNumber, $pattern); - $formattedNumber = $this->localizeNumber($formattedNumber); - - $formattedNumber = $this->performSpecificReplacements($formattedNumber); - - return $formattedNumber; - } - - /** - * Prepares a basic number (either a string, an integer or a float) to be formatted. - * - * @param $number - * The number to be prepared - * - * @return DecimalNumber - * The prepared number - */ - protected function prepareNumber($number) - { - $decimalNumber = new DecimalNumber((string) $number); - $precision = $this->numberSpecification->getMaxFractionDigits(); - $roundedNumber = (new Rounding())->compute( - $decimalNumber, - $precision, - $this->roundingMode - ); - - return $roundedNumber; - } - - /** - * Get $number's major and minor digits. - * - * Major digits are the "integer" part (before decimal separator), minor digits are the fractional part - * Result will be an array of exactly 2 items: [$majorDigits, $minorDigits] - * - * Usage example: - * list($majorDigits, $minorDigits) = $this->getMajorMinorDigits($decimalNumber); - * - * @param DecimalNumber $number - * - * @return string[] - */ - protected function extractMajorMinorDigits(DecimalNumber $number) - { - // Get the number's major and minor digits. - $majorDigits = $number->getIntegerPart(); - $minorDigits = $number->getFractionalPart(); - $minorDigits = ('0' === $minorDigits) ? '' : $minorDigits; - - return [$majorDigits, $minorDigits]; - } - - /** - * Splits major digits into groups. - * - * e.g.: Given the major digits "1234567", and major group size - * configured to 3 digits, the result would be "1 234 567" - * - * @param $majorDigits - * The major digits to be grouped - * - * @return string - * The grouped major digits - */ - protected function splitMajorGroups($majorDigits) - { - if ($this->numberSpecification->isGroupingUsed()) { - // Reverse the major digits, since they are grouped from the right. - $majorDigits = array_reverse(str_split($majorDigits)); - // Group the major digits. - $groups = []; - $groups[] = array_splice($majorDigits, 0, $this->numberSpecification->getPrimaryGroupSize()); - while (!empty($majorDigits)) { - $groups[] = array_splice($majorDigits, 0, $this->numberSpecification->getSecondaryGroupSize()); - } - // Reverse back the digits and the groups - $groups = array_reverse($groups); - foreach ($groups as &$group) { - $group = implode('', array_reverse($group)); - } - // Reconstruct the major digits. - $majorDigits = implode(self::GROUP_SEPARATOR_PLACEHOLDER, $groups); - } - - return $majorDigits; - } - - /** - * Adds or remove trailing zeroes, depending on specified min and max fraction digits numbers. - * - * @param string $minorDigits - * Digits to be adjusted with (trimmed or padded) zeroes - * - * @return string - * The adjusted minor digits - */ - protected function adjustMinorDigitsZeroes($minorDigits) - { - if (strlen($minorDigits) < $this->numberSpecification->getMinFractionDigits()) { - // Re-add needed zeroes - $minorDigits = str_pad( - $minorDigits, - $this->numberSpecification->getMinFractionDigits(), - '0' - ); - } - - if (strlen($minorDigits) > $this->numberSpecification->getMaxFractionDigits()) { - // Strip any trailing zeroes. - $minorDigits = rtrim($minorDigits, '0'); - } - - return $minorDigits; - } - - /** - * Get the CLDR formatting pattern. - * - * @see http://cldr.unicode.org/translation/number-patterns - * - * @param bool $isNegative - * If true, the negative pattern will be returned instead of the positive one - * - * @return string - * The CLDR formatting pattern - */ - protected function getCldrPattern($isNegative) - { - if ((bool) $isNegative) { - return $this->numberSpecification->getNegativePattern(); - } - - return $this->numberSpecification->getPositivePattern(); - } - - /** - * Localize the passed number. - * - * If needed, occidental ("latn") digits are replaced with the relevant - * ones (for instance with arab digits). - * Symbol placeholders will also be replaced by the real symbols (configured - * in number specification) - * - * @param string $number - * The number to be processed - * - * @return string - * The number after digits and symbols replacement - */ - protected function localizeNumber($number) - { - // If locale uses non-latin digits - $number = $this->replaceDigits($number); - - // Placeholders become real localized symbols - $number = $this->replaceSymbols($number); - - return $number; - } - - /** - * Replace latin digits with relevant numbering system's digits. - * - * @param string $number - * The number to process - * - * @return string - * The number with replaced digits - */ - protected function replaceDigits($number) - { - // TODO use digits set from the locale (cf. /localization/CLDR/core/common/supplemental/numberingSystems.xml) - return $number; - } - - /** - * Replace placeholder number symbols with relevant numbering system's symbols. - * - * @param string $number - * The number to process - * - * @return string - * The number with replaced symbols - */ - protected function replaceSymbols($number) - { - $symbols = $this->numberSpecification->getSymbolsByNumberingSystem($this->numberingSystem); - $replacements = [ - self::DECIMAL_SEPARATOR_PLACEHOLDER => $symbols->getDecimal(), - self::GROUP_SEPARATOR_PLACEHOLDER => $symbols->getGroup(), - self::MINUS_SIGN_PLACEHOLDER => $symbols->getMinusSign(), - self::PERCENT_SYMBOL_PLACEHOLDER => $symbols->getPercentSign(), - self::PLUS_SIGN_PLACEHOLDER => $symbols->getPlusSign(), - ]; - - return strtr($number, $replacements); - } - - /** - * Add missing placeholders to the number using the passed CLDR pattern. - * - * Missing placeholders can be the percent sign, currency symbol, etc. - * - * e.g. with a currency CLDR pattern: - * - Passed number (partially formatted): 1,234.567 - * - Returned number: 1,234.567 ¤ - * ("¤" symbol is the currency symbol placeholder) - * - * @see http://cldr.unicode.org/translation/number-patterns - * - * @param $formattedNumber - * Number to process - * @param $pattern - * CLDR formatting pattern to use - * - * @return string - */ - protected function addPlaceholders($formattedNumber, $pattern) - { - /* - * Regex groups explanation: - * # : literal "#" character. Once. - * (,#+)* : any other "#" characters group, separated by ",". Zero to infinity times. - * 0 : literal "0" character. Once. - * (\.[0#]+)* : any combination of "0" and "#" characters groups, separated by '.'. Zero to infinity times. - */ - $formattedNumber = preg_replace('/#?(,#+)*0(\.[0#]+)*/', $formattedNumber, $pattern); - - return $formattedNumber; - } - - /** - * Perform some more specific replacements. - * - * Specific replacements are needed when number specification is extended. - * For instance, prices have an extended number specification in order to - * add currency symbol to the formatted number. - * - * @param string $formattedNumber - * - * @return mixed - */ - public function performSpecificReplacements($formattedNumber) - { - $formattedNumber = $this->tryCurrencyReplacement($formattedNumber); - - return $formattedNumber; - } - - /** - * Try to replace currency placeholder by actual currency. - * - * Placeholder will be replaced either by the symbol or the ISO code, depending on price specification - * - * @param $formattedNumber - * The number to format - * - * @return string - * The number after currency replacement - */ - protected function tryCurrencyReplacement($formattedNumber) - { - if ($this->numberSpecification instanceof PriceSpecification) { - $currency = PriceSpecification::CURRENCY_DISPLAY_CODE == $this->numberSpecification->getCurrencyDisplay() - ? $this->numberSpecification->getCurrencyCode() - : $this->numberSpecification->getCurrencySymbol(); - - $formattedNumber = str_replace(self::CURRENCY_SYMBOL_PLACEHOLDER, $currency, $formattedNumber); - } - - return $formattedNumber; - } -} diff --git a/src/Core/Localization/Pack/Factory/LocalizationPackFactory.php b/src/Core/Localization/Pack/Factory/LocalizationPackFactory.php deleted file mode 100644 index 024e16cc..00000000 --- a/src/Core/Localization/Pack/Factory/LocalizationPackFactory.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Factory; - -use PrestaShop\PrestaShop\Adapter\Entity\LocalizationPack; - -/** - * Class LocalizationPackFactory is responsible for creating localization pack instances. - */ -final class LocalizationPackFactory implements LocalizationPackFactoryInterface -{ - /** - * {@inheritdoc} - */ - public function createNew() - { - return new LocalizationPack(); - } -} diff --git a/src/Core/Localization/Pack/Factory/LocalizationPackFactoryInterface.php b/src/Core/Localization/Pack/Factory/LocalizationPackFactoryInterface.php deleted file mode 100644 index 016c8416..00000000 --- a/src/Core/Localization/Pack/Factory/LocalizationPackFactoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Factory; - -use PrestaShop\PrestaShop\Adapter\Entity\LocalizationPack; - -/** - * Interface LocalizationPackFactoryInterface defines contract for localization pack factory. - */ -interface LocalizationPackFactoryInterface -{ - /** - * Creates new localization pack. - * - * @return LocalizationPack - */ - public function createNew(); -} diff --git a/src/Core/Localization/Pack/Import/LocalizationPackImportConfig.php b/src/Core/Localization/Pack/Import/LocalizationPackImportConfig.php deleted file mode 100644 index 674e5c00..00000000 --- a/src/Core/Localization/Pack/Import/LocalizationPackImportConfig.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Import; - -/** - * Class LocalizationPackImportConfig is value object which is responsible - * for storing localization pack configuration for import. - */ -final class LocalizationPackImportConfig implements LocalizationPackImportConfigInterface -{ - /** - * @var string - */ - private $countryIso; - - /** - * @var array - */ - private $contentToImport; - - /** - * @var bool - */ - private $downloadPackData; - - /** - * @param string $countryIso Country ISO code - * @param array $contentToImport Content that should be impoerted (e.g states, taxes & etc) - * @param bool $downloadPackData Whether pack data should be downloaded from prestashop.com server - */ - public function __construct($countryIso, array $contentToImport, $downloadPackData) - { - $this->countryIso = (string) $countryIso; - $this->contentToImport = $contentToImport; - $this->downloadPackData = (bool) $downloadPackData; - } - - /** - * Get country ISO code. - * - * @return string - */ - public function getCountryIsoCode() - { - return $this->countryIso; - } - - /** - * Get content to import. - * - * @return array - */ - public function getContentToImport() - { - return $this->contentToImport; - } - - /** - * Whether pack data should be downloaded. - * - * @return bool - */ - public function shouldDownloadPackData() - { - return $this->downloadPackData; - } -} diff --git a/src/Core/Localization/Pack/Import/LocalizationPackImportConfigInterface.php b/src/Core/Localization/Pack/Import/LocalizationPackImportConfigInterface.php deleted file mode 100644 index c183e6e1..00000000 --- a/src/Core/Localization/Pack/Import/LocalizationPackImportConfigInterface.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Import; - -/** - * Interface LocalizationPackImportConfigInterface defines. - */ -interface LocalizationPackImportConfigInterface -{ - /** - * Available content to import. - */ - const CONTENT_STATES = 'states'; - const CONTENT_TAXES = 'taxes'; - const CONTENT_CURRENCIES = 'currencies'; - const CONTENT_LANGUAGES = 'languages'; - const CONTENT_UNITS = 'units'; - const CONTENT_GROUPS = 'groups'; - - /** - * Get country ISO code. - * - * @return string - */ - public function getCountryIsoCode(); - - /** - * Get content to import. - * - * @return array - */ - public function getContentToImport(); - - /** - * Whether pack data should be downloaded. - * - * @return bool - */ - public function shouldDownloadPackData(); -} diff --git a/src/Core/Localization/Pack/Import/LocalizationPackImporter.php b/src/Core/Localization/Pack/Import/LocalizationPackImporter.php deleted file mode 100644 index cb1c13d0..00000000 --- a/src/Core/Localization/Pack/Import/LocalizationPackImporter.php +++ /dev/null @@ -1,181 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Import; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Localization\Pack\Factory\LocalizationPackFactoryInterface; -use PrestaShop\PrestaShop\Core\Localization\Pack\Loader\LocalizationPackLoaderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class LocalizationPackImporter is responsible for importing localization pack. - */ -final class LocalizationPackImporter implements LocalizationPackImporterInterface -{ - /** - * @var LocalizationPackLoaderInterface - */ - private $remoteLocalizationPackLoader; - - /** - * @var LocalizationPackLoaderInterface - */ - private $localLocalizationPackLoader; - - /** - * @var LocalizationPackFactoryInterface - */ - private $localizationPackFactory; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param LocalizationPackLoaderInterface $remoteLocalizationPackLoader - * @param LocalizationPackLoaderInterface $localLocalizationPackLoader - * @param LocalizationPackFactoryInterface $localizationPackFactory - * @param TranslatorInterface $translator - * @param ConfigurationInterface $configuration - */ - public function __construct( - LocalizationPackLoaderInterface $remoteLocalizationPackLoader, - LocalizationPackLoaderInterface $localLocalizationPackLoader, - LocalizationPackFactoryInterface $localizationPackFactory, - TranslatorInterface $translator, - ConfigurationInterface $configuration - ) { - $this->remoteLocalizationPackLoader = $remoteLocalizationPackLoader; - $this->localLocalizationPackLoader = $localLocalizationPackLoader; - $this->localizationPackFactory = $localizationPackFactory; - $this->translator = $translator; - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function import(LocalizationPackImportConfig $config) - { - $errors = $this->checkConfig($config); - if (!empty($errors)) { - return $errors; - } - - $pack = null; - - if ($config->shouldDownloadPackData() || $this->configuration->get('_PS_HOST_MODE_')) { - $pack = $this->remoteLocalizationPackLoader->getLocalizationPack( - $config->getCountryIsoCode() - ); - } - - if (null === $pack) { - $pack = $this->localLocalizationPackLoader->getLocalizationPack( - $config->getCountryIsoCode() - ); - - if (null === $pack) { - $error = $this->trans('Cannot load the localization pack.', 'Admin.International.Notification'); - - return [$error]; - } - } - - $localizationPack = $this->localizationPackFactory->createNew(); - - $localizationPack->loadLocalisationPack( - $pack, - $config->getContentToImport(), - false, - $config->getCountryIsoCode() - ); - - return $localizationPack->getErrors(); - } - - /** - * Check if configuration is valid. - * - * @param LocalizationPackImportConfig $config - * - * @return array Errors if any - */ - private function checkConfig(LocalizationPackImportConfig $config) - { - if (empty($config->getCountryIsoCode())) { - $error = $this->trans('Invalid selection', 'Admin.Notifications.Error'); - - return [$error]; - } - - if (empty($config->getContentToImport())) { - $error = $this->trans('Please select at least one item to import.', 'Admin.International.Notification'); - - return [$error]; - } - - $contentItems = [ - LocalizationPackImportConfigInterface::CONTENT_STATES, - LocalizationPackImportConfigInterface::CONTENT_TAXES, - LocalizationPackImportConfigInterface::CONTENT_CURRENCIES, - LocalizationPackImportConfigInterface::CONTENT_LANGUAGES, - LocalizationPackImportConfigInterface::CONTENT_UNITS, - LocalizationPackImportConfigInterface::CONTENT_GROUPS, - ]; - - foreach ($config->getContentToImport() as $contentItem) { - if (!in_array($contentItem, $contentItems)) { - $error = $this->trans('Invalid selection', 'Admin.Notifications.Error'); - - return [$error]; - } - } - - return []; - } - - /** - * Translate message. - * - * @param string $message - * @param string $domain - * @param array $params - * - * @return string - */ - private function trans($message, $domain, array $params = []) - { - return $this->translator->trans($message, $params, $domain); - } -} diff --git a/src/Core/Localization/Pack/Import/LocalizationPackImporterInterface.php b/src/Core/Localization/Pack/Import/LocalizationPackImporterInterface.php deleted file mode 100644 index 34a4e029..00000000 --- a/src/Core/Localization/Pack/Import/LocalizationPackImporterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Import; - -/** - * Interface LocalizationPackImporterInterface defines contract for localization importer. - */ -interface LocalizationPackImporterInterface -{ - /** - * Import localization pack. - * - * @param LocalizationPackImportConfig $config - * - * @return array Returns errors if any or empty array otherwise - */ - public function import(LocalizationPackImportConfig $config); -} diff --git a/src/Core/Localization/Pack/Loader/AbstractLocalizationPackLoader.php b/src/Core/Localization/Pack/Loader/AbstractLocalizationPackLoader.php deleted file mode 100644 index a152744d..00000000 --- a/src/Core/Localization/Pack/Loader/AbstractLocalizationPackLoader.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Loader; - -use ErrorException; -use SimpleXMLElement; - -/** - * Class AbstractLocalizationPackLoader is abstract localization pack loader that implements XML loading from file. - */ -abstract class AbstractLocalizationPackLoader implements LocalizationPackLoaderInterface -{ - /** - * Loads XML from local or remote file. - * - * @param string $file - * - * @return SimpleXMLElement|null - */ - protected function loadXml($file) - { - try { - $xml = simplexml_load_file($file); - } catch (ErrorException $e) { - return null; - } - - return false === $xml ? null : $xml; - } -} diff --git a/src/Core/Localization/Pack/Loader/LocalLocalizationPackLoader.php b/src/Core/Localization/Pack/Loader/LocalLocalizationPackLoader.php deleted file mode 100644 index e7d985f5..00000000 --- a/src/Core/Localization/Pack/Loader/LocalLocalizationPackLoader.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Loader; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class LocalLocalizationPackLoader is responsible for loading localization pack data from local host. - */ -final class LocalLocalizationPackLoader extends AbstractLocalizationPackLoader -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getLocalizationPackList() - { - $rootDir = $this->configuration->get('_PS_ROOT_DIR_'); - - $localizationFile = sprintf('%s/localization/localization.xml', $rootDir); - if (!file_exists($localizationFile)) { - return null; - } - - return $this->loadXml($localizationFile); - } - - /** - * {@inheritdoc} - */ - public function getLocalizationPack($countryIso) - { - $rootDir = $this->configuration->get('_PS_HOST_MODE_') ? - $this->configuration->get('_PS_CORE_DIR_') : - $this->configuration->get('_PS_ROOT_DIR_'); - - $localizationPackFile = sprintf('%s/localization/%s.xml', $rootDir, $countryIso); - if (!file_exists($localizationPackFile)) { - return null; - } - - return $this->loadXml($localizationPackFile); - } -} diff --git a/src/Core/Localization/Pack/Loader/LocalizationPackLoaderInterface.php b/src/Core/Localization/Pack/Loader/LocalizationPackLoaderInterface.php deleted file mode 100644 index 0c0723ca..00000000 --- a/src/Core/Localization/Pack/Loader/LocalizationPackLoaderInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Loader; - -use SimpleXMLElement; - -/** - * Interface LocalizationPackLoaderInterface defines contract for localization pack loaders. - */ -interface LocalizationPackLoaderInterface -{ - /** - * Get localization packs list. - * - * @return SimpleXMLElement|null SimpleXMLElement with localization packs data or null if packs are not available - */ - public function getLocalizationPackList(); - - /** - * Get single localization pack data. - * - * @param string $countryIso Country ISO Alpha-2 code - * - * @return SimpleXMLElement|null - */ - public function getLocalizationPack($countryIso); -} diff --git a/src/Core/Localization/Pack/Loader/RemoteLocalizationPackLoader.php b/src/Core/Localization/Pack/Loader/RemoteLocalizationPackLoader.php deleted file mode 100644 index 6d451db3..00000000 --- a/src/Core/Localization/Pack/Loader/RemoteLocalizationPackLoader.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Pack\Loader; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Foundation\Version; - -/** - * Class RemoteLocalizationPackLoader is responsible for loading localization pack data from prestashop.com. - */ -final class RemoteLocalizationPackLoader extends AbstractLocalizationPackLoader -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var Version - */ - private $version; - - /** - * @param ConfigurationInterface $configuration - * @param Version $version - */ - public function __construct(ConfigurationInterface $configuration, Version $version) - { - $this->configuration = $configuration; - $this->version = $version; - } - - /** - * {@inheritdoc} - */ - public function getLocalizationPackList() - { - $apiUrl = $this->configuration->get('_PS_API_URL_'); - - $xmlLocalizationPacks = $this->loadXml($apiUrl . '/rss/localization.xml'); - if (!$xmlLocalizationPacks) { - return null; - } - - return $xmlLocalizationPacks; - } - - /** - * {@inheritdoc} - */ - public function getLocalizationPack($countryIso) - { - $apiUrl = $this->configuration->get('_PS_API_URL_'); - $localizationPackUrl = sprintf('%s/localization/%s/%s.xml', $apiUrl, $this->version->getMajorVersion(), $countryIso); - - $pack = $this->loadXml($localizationPackUrl); - if (false === $pack) { - return null; - } - - return $pack; - } -} diff --git a/src/Core/Localization/RTL/Exception/GenerationException.php b/src/Core/Localization/RTL/Exception/GenerationException.php deleted file mode 100644 index 10bd107e..00000000 --- a/src/Core/Localization/RTL/Exception/GenerationException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\RTL\Exception; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * Is thrown when unable to generate RTL files - */ -class GenerationException extends LocalizationException -{ -} diff --git a/src/Core/Localization/RTL/Processor.php b/src/Core/Localization/RTL/Processor.php deleted file mode 100644 index 674b7b5e..00000000 --- a/src/Core/Localization/RTL/Processor.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\RTL; - -use PrestaShop\PrestaShop\Adapter\Entity\Language; -use PrestaShop\PrestaShop\Core\Localization\RTL\Exception\GenerationException; - -/** - * Processes stylesheets by transforming them to RTL. - */ -class Processor -{ - /** - * @var string Installed language 2-letter ISO code - */ - private $languageCode = ''; - - /** - * @var bool Indicates if the BO theme should be processed - */ - private $processBOTheme = false; - - /** - * @var string[] Names of the FO themes to process - */ - private $processFOThemes = []; - - /** - * @var array Indicates additional paths to process - */ - private $processPaths = []; - - /** - * @var bool Indicates if this is performed during install - */ - private $isInstall = false; - - /** - * @var bool Indicates if the RTL files should be generated even if they already exist - */ - private $regenerate = false; - - /** - * @var string[] Path to the default modules to process - */ - private $defaultModulesToProcess = []; - - /** - * @var bool Indicates if the default modules should be processed - */ - private $processDefaultModules = false; - - /** - * @var string Path to PrestaShop's admin directory - */ - private $adminDir = ''; - - /** - * @var string Path to the themes directory - */ - private $themesDir = ''; - - /** - * Processor constructor. - * - * @param string $adminDir Path to PrestaShop's admin directory - * @param string $themesDir Path to the FO themes directory - * @param string[] $defaultModulesToProcess Path to the default modules to process - */ - public function __construct($adminDir, $themesDir, array $defaultModulesToProcess) - { - $this->adminDir = $adminDir; - $this->themesDir = $themesDir; - $this->defaultModulesToProcess = $defaultModulesToProcess; - } - - /** - * Specifies the installed language 2-letter ISO code. - * - * @param string $languageCode - * - * @return Processor - */ - public function setLanguageCode($languageCode) - { - $this->languageCode = $languageCode; - - return $this; - } - - /** - * Specifies if the BO theme should be processed. - * - * @param bool $processBOTheme - * - * @return Processor - */ - public function setProcessBOTheme($processBOTheme) - { - $this->processBOTheme = $processBOTheme; - - return $this; - } - - /** - * Specifies the names of the FO themes to process. - * - * @param string[] $processFOThemes - * - * @return Processor - */ - public function setProcessFOThemes(array $processFOThemes) - { - $this->processFOThemes = $processFOThemes; - - return $this; - } - - /** - * Specifies additional paths to process. - * - * @param string[] $processPaths - * - * @return Processor - */ - public function setProcessPaths(array $processPaths) - { - $this->processPaths = $processPaths; - - return $this; - } - - /** - * Specifies if this is performed during install. - * - * @param bool $isInstall - * - * @return Processor - */ - public function setIsInstall($isInstall) - { - $this->isInstall = $isInstall; - - return $this; - } - - /** - * Specifies if the RTL files should be generated even if they already exist. - * - * @param bool $regenerate - * - * @return Processor - */ - public function setRegenerate($regenerate) - { - $this->regenerate = $regenerate; - - return $this; - } - - /** - * Specifies if the default modules should be processed. - * - * @param bool $processDefaultModules - * - * @return Processor - */ - public function setProcessDefaultModules($processDefaultModules) - { - $this->processDefaultModules = $processDefaultModules; - - return $this; - } - - /** - * @throws Exception\GenerationException - * @throws \Exception - */ - public function process() - { - if ($this->languageCode) { - $lang_pack = Language::getLangDetails($this->languageCode); - if (!$lang_pack['is_rtl']) { - return; - } - } - - $generator = new StylesheetGenerator(); - // generate stylesheets for BO themes - if ($this->processBOTheme) { - if (!is_dir($this->adminDir)) { - throw new GenerationException("Cannot generate BO themes: \"{$this->adminDir}\" is not a directory"); - } - - $generator->generateInDirectory($this->adminDir . DIRECTORY_SEPARATOR . 'themes'); - } - - // generate stylesheets for BO themes - if ($this->processFOThemes) { - foreach ($this->processFOThemes as $themeName) { - $generator->generateInDirectory($this->themesDir . DIRECTORY_SEPARATOR . $themeName); - } - } - - // generate stylesheets for default modules - if ($this->processDefaultModules) { - $this->processPaths = array_merge($this->processPaths, $this->defaultModulesToProcess); - } - - if (!empty($this->processPaths)) { - foreach ($this->processPaths as $path) { - if (!empty($path) && is_dir($path)) { - $generator->generateInDirectory($path); - } - } - } - } -} diff --git a/src/Core/Localization/RTL/StyleSheetProcessorFactory.php b/src/Core/Localization/RTL/StyleSheetProcessorFactory.php deleted file mode 100644 index d6e51c70..00000000 --- a/src/Core/Localization/RTL/StyleSheetProcessorFactory.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\RTL; - -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class StyleSheetProcessorFactory - */ -final class StyleSheetProcessorFactory implements StyleSheetProcessorFactoryInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function create() - { - $rootDir = $this->configuration->get('_PS_ROOT_DIR_'); - $moduleDir = $this->configuration->get('_PS_MODULE_DIR_'); - - if (null === $adminDir = $this->configuration->get('_PS_ADMIN_DIR_')) { - $adminDir = $rootDir . DIRECTORY_SEPARATOR . 'admin'; - $adminDir = is_dir($adminDir) ? $adminDir : ($adminDir . '-dev'); - } - - $themesDir = $this->configuration->get('_PS_ROOT_DIR_') . DIRECTORY_SEPARATOR . 'themes'; - - // @todo: improve modules configuration - // see: https://github.com/PrestaShop/PrestaShop/pull/11169#discussion_r231824489 - $modulesToProcess = [ - $moduleDir . 'gamification', - $moduleDir . 'welcome', - $moduleDir . 'cronjobs', - ]; - - return new Processor( - $adminDir, - $themesDir, - $modulesToProcess - ); - } -} diff --git a/src/Core/Localization/RTL/StyleSheetProcessorFactoryInterface.php b/src/Core/Localization/RTL/StyleSheetProcessorFactoryInterface.php deleted file mode 100644 index f171795a..00000000 --- a/src/Core/Localization/RTL/StyleSheetProcessorFactoryInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\RTL; - -/** - * Interface StyleSheetProcessorFactoryInterface creates RTL stylesheet processor. - */ -interface StyleSheetProcessorFactoryInterface -{ - /** - * @return Processor - */ - public function create(); -} diff --git a/src/Core/Localization/RTL/StylesheetGenerator.php b/src/Core/Localization/RTL/StylesheetGenerator.php deleted file mode 100644 index 87e521c3..00000000 --- a/src/Core/Localization/RTL/StylesheetGenerator.php +++ /dev/null @@ -1,232 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\RTL; - -use CSSJanus; -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem; -use PrestaShop\PrestaShop\Core\Localization\RTL\Exception\GenerationException; -use Tools; - -/** - * Creates RTL versions of LTR CSS files. - * - * This class creates new files based on the original ones by using CSSJanus first, - * then applying an optional .rtlfix file, if one with the same name as the processed file is found. - * - * Inspired by "Localize Fixture" from Mahdi Shad @ iPresta - * - * @see https://github.com/iPresta/localize-fixture - */ -class StylesheetGenerator -{ - /** - * Default file type to look up. - */ - const DEFAULT_FILE_TYPE = 'css'; - - /** - * Default suffix to use for RTL transformed files. - */ - const DEFAULT_RTL_SUFFIX = '_rtl'; - - /** - * Extension of RTL fix files. - */ - const RTLFIX_EXTENSION = 'rtlfix'; - - /** - * @var string - */ - private $fileType; - - /** - * @var string - */ - private $rtlSuffix; - - /** - * @param string $fileType [default='css'] File type (CSS or SCSS) - * @param string $rtlSuffix [default='_rtl'] Suffix to add to transformed RTL files - */ - public function __construct($fileType = self::DEFAULT_FILE_TYPE, $rtlSuffix = self::DEFAULT_RTL_SUFFIX) - { - $this->fileType = $fileType; - $this->rtlSuffix = $rtlSuffix; - } - - /** - * Creates an RTL version of all the files in the selected path recursively. - * - * @param string $directory Path to process. All CSS files in this directory will be processed. - * @param bool $regenerate [default=false] Indicates if RTL files should be re-generated even if they exist - * - * @throws GenerationException - */ - public function generateInDirectory($directory, $regenerate = false) - { - $allFiles = $this->getFilesInDirectory($directory); - - foreach ($allFiles as $file) { - if ($this->shouldProcessFile($directory . '/' . $file, $regenerate)) { - $this->processFile($directory . '/' . $file); - } - } - } - - /** - * Indicates if a file should be processed or not. - * - * @param string $file File path - * @param bool $regenerate Indicates if RTL files should be re-generated even if they exist - * - * @return bool - */ - private function shouldProcessFile($file, $regenerate) - { - return - strpos($file, '/node_modules/') === false - // does not end with .rtlfix - && substr(rtrim($file, '.' . $this->fileType), -4) !== $this->rtlSuffix - // RTL file does not exist or we are regenerating them - && ($regenerate || !file_exists($this->getRtlFileName($file))); - } - - /** - * Creates an RTL version of a file. - * - * @param string $filePath Path to the file to process - * - * @throws GenerationException - */ - private function processFile($filePath) - { - $content = file_get_contents($filePath); - - if ($content === false) { - throw new GenerationException(sprintf('Unable to read from CSS file: %s', $filePath)); - } - - $rendered = CSSJanus::transform($content); - - if (strlen($rendered) === 0 && strlen($content) !== 0) { - throw new GenerationException(sprintf('Failed to generate RTL CSS from file: %s', $filePath)); - } - - $content = $this->appendRtlFixIfNecessary( - $rendered, - $filePath - ); - - $this->saveFile($content, $filePath); - } - - /** - * Creates a list of all files of the required type in the provided directory recursively. - * - * @param string $directory Directory to scan - * - * @return string[] Array of file paths, relative to the provided directory - */ - private function getFilesInDirectory($directory) - { - return Tools::scandir($directory, $this->fileType, '', true); - } - - /** - * Removes the file extension from path. - * - * @param string $filePath Path to a file - * - * @return string - */ - private function getFilePathWithoutExtension($filePath) - { - $path = pathinfo($filePath); - - return $path['dirname'] . '/' . $path['filename']; - } - - /** - * Returns the full path for the RTL filename corresponding to the provided base filename. - * - * @param string $baseFileName Base file name - * - * @return string RTL filename - */ - private function getRtlFileName($baseFileName) - { - return $this->getFilePathWithoutExtension($baseFileName) . $this->rtlSuffix . '.' . $this->fileType; - } - - /** - * Appends the content of an .rtlfix file to $content. - * - * @param string $content Base content - * @param string $baseFile Path to the processed file - * - * @return string Content with RTL fix applied - * - * @throws GenerationException If unable to read from .rtlfix file - */ - private function appendRtlFixIfNecessary($content, $baseFile) - { - $filePath = $this->getFilePathWithoutExtension($baseFile); - - $rtlFixFilePath = $filePath . '.' . self::RTLFIX_EXTENSION; - - if (file_exists($rtlFixFilePath)) { - $rtlFixContent = file_get_contents($rtlFixFilePath); - - if ($rtlFixContent === false) { - throw new GenerationException(sprintf('Failed to read from file: %s', $rtlFixFilePath)); - } - - return $content . PHP_EOL . $rtlFixContent; - } - - return $content; - } - - /** - * Saves $content the appropriate file based on the name of the original file. - * - * @param string $content Content to save - * @param string $baseFile Name of the original file - * - * @throws GenerationException If unable to write to file - */ - private function saveFile($content, $baseFile) - { - $rtlFilePath = $this->getRtlFileName($baseFile); - - if (false === file_put_contents($rtlFilePath, $content)) { - throw new GenerationException(sprintf('Unable to write file to: %s', $rtlFilePath)); - } - - @chmod($rtlFilePath, FileSystem::DEFAULT_MODE_FILE); - } -} diff --git a/src/Core/Localization/Specification/Factory.php b/src/Core/Localization/Specification/Factory.php deleted file mode 100644 index b923ba22..00000000 --- a/src/Core/Localization/Specification/Factory.php +++ /dev/null @@ -1,284 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleInterface as CldrLocaleInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\NumberSymbolsData; -use PrestaShop\PrestaShop\Core\Localization\Currency; -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Specification\Number as NumberSpecification; -use PrestaShop\PrestaShop\Core\Localization\Specification\Price as PriceSpecification; - -/** - * Number specification factory. - * Builds Number, Price or Percentage specifications objects. - * - * Uses a CLDR Locale instance to extract relevant data needed to build a specification object - */ -class Factory -{ - /** - * Build a Number specification from a CLDR Locale object. - * - * @param CldrLocaleInterface $cldrLocale - * This CldrLocale object is a low level data object extracted from CLDR data source - * @param int $maxFractionDigits - * Max number of digits to display in a number's decimal part - * @param bool $numberGroupingUsed - * Should we group digits in a number's integer part ? - * - * @return NumberSpecification - * - * @throws LocalizationException - */ - public function buildNumberSpecification(CldrLocaleInterface $cldrLocale, $maxFractionDigits, $numberGroupingUsed) - { - $decimalPattern = $cldrLocale->getDecimalPattern(); - $numbersSymbols = $cldrLocale->getAllNumberSymbols(); - // Use positive pattern to retrieve information - $positivePattern = $this->getPositivePattern($decimalPattern); - - return new NumberSpecification( - $positivePattern, - $this->getNegativePattern($decimalPattern), - $this->computeNumberSymbolLists($numbersSymbols), - $maxFractionDigits, - $this->getMinFractionDigits($positivePattern), - $numberGroupingUsed, - $this->getPrimaryGroupSize($positivePattern), - $this->getSecondaryGroupSize($positivePattern) - ); - } - - /** - * Build a Price specification from a CLDR Locale object and a Currency object. - * - * @param string $localeCode - * The concerned locale - * @param CldrLocaleInterface $cldrLocale - * This CldrLocale object is a low level data object extracted from CLDR data source - * It contains data about the concerned locale - * @param Currency $currency - * This Currency object brings missing specification to format a number as a price - * @param bool $numberGroupingUsed - * Should we group digits when formatting prices ? - * @param $currencyDisplayType - * Type of display for currency symbol (symbol or ISO code) - * @param int $maxFractionDigits|null - * The decimal precision of the price - * - * @return PriceSpecification - * - * @throws LocalizationException - */ - public function buildPriceSpecification( - $localeCode, - CldrLocaleInterface $cldrLocale, - Currency $currency, - $numberGroupingUsed, - $currencyDisplayType, - ?int $maxFractionDigits = null - ) { - $currencyPattern = $currency->getPattern($localeCode) ?: $cldrLocale->getCurrencyPattern(); - $numbersSymbols = $cldrLocale->getAllNumberSymbols(); - // Use positive pattern to retrieve information - $positivePattern = $this->getPositivePattern($currencyPattern); - - return new PriceSpecification( - $positivePattern, - $this->getNegativePattern($currencyPattern), - $this->computeNumberSymbolLists($numbersSymbols), - $maxFractionDigits ?? $this->getMaxFractionDigits($positivePattern), - $this->getMinFractionDigits($positivePattern), - $numberGroupingUsed && $this->getPrimaryGroupSize($positivePattern) > 1, - $this->getPrimaryGroupSize($positivePattern), - $this->getSecondaryGroupSize($positivePattern), - $currencyDisplayType, - $currency->getSymbol($localeCode), - $currency->getIsoCode() - ); - } - - /** - * Extract the positive pattern from a CLDR formatting pattern - * Works with any formatting pattern (number, price, percentage). - * - * @param string $pattern - * The CLDR pattern - * - * @return string - * The extracted positive pattern - */ - protected function getPositivePattern($pattern) - { - $patterns = explode(';', $pattern); - - return isset($patterns[0]) ? $patterns[0] : ''; - } - - /** - * Extract the negative pattern from a CLDR formatting pattern - * Works with any formatting pattern (number, price, percentage). - * - * @param string $pattern - * The CLDR pattern - * - * @return string - * The extracted negative pattern - */ - protected function getNegativePattern($pattern) - { - $patterns = explode(';', $pattern); - - return isset($patterns[1]) - ? $patterns[1] - : '-' . $patterns[0]; - } - - /** - * Convert a list of CLDR number symbols data into a list of NumberSymbolList objects. - * - * @param NumberSymbolsData[] $allNumberSymbolsData - * All the CLDR number symbols data indexed by numbering system - * - * @return NumberSymbolList[] - * - * @throws LocalizationException - * If passed data is invalid - */ - protected function computeNumberSymbolLists($allNumberSymbolsData) - { - $symbolsLists = []; - foreach ($allNumberSymbolsData as $numberingSystem => $numberSymbolsData) { - $symbolsLists[$numberingSystem] = $this->getNumberSymbolList($numberSymbolsData); - } - - return $symbolsLists; - } - - /** - * Get a NumberSymbolList object from a CLDR NumberSymbolsData object. - * - * @param NumberSymbolsData $symbolsData Data that will be used to build the NumberSymbolList object - * - * @return NumberSymbolList An immutable NumberSymbolList object - * - * @throws LocalizationException If passed data is invalid - */ - protected function getNumberSymbolList(NumberSymbolsData $symbolsData) - { - return new NumberSymbolList( - $symbolsData->getDecimal(), - $symbolsData->getGroup(), - $symbolsData->getList(), - $symbolsData->getPercentSign(), - $symbolsData->getMinusSign(), - $symbolsData->getPlusSign(), - $symbolsData->getExponential(), - $symbolsData->getSuperscriptingExponent(), - $symbolsData->getPerMille(), - $symbolsData->getInfinity(), - $symbolsData->getNan() - ); - } - - /** - * Extract the min number of fraction digits from a number pattern (decimal, currency, percentage). - * - * @param string $pattern - * The formatting pattern to use for extraction - * - * @return int - * The min number of fraction digits to display in the final number - */ - protected function getMinFractionDigits($pattern) - { - $dotPos = (int) strpos($pattern, '.'); - - return substr_count($pattern, '0', $dotPos); - } - - /** - * Extract the max number of fraction digits from a number pattern (decimal, currency, percentage). - * - * @param string $pattern The formatting pattern to use for extraction (eg 0.00##) - * - * @return int The max number of fraction digits to display in the final number - */ - protected function getMaxFractionDigits($pattern) - { - $dotPos = (int) strpos($pattern, '.'); - - return strlen(substr($pattern, $dotPos + 1)); - } - - /** - * Get the primary digits group size from a number formatting pattern. - * - * @param string $pattern - * The CLDR number formatting pattern (e.g.: #,##0.###) - * - * @return int - * The primary group size of the passed pattern - */ - protected function getPrimaryGroupSize($pattern) - { - $groups = $this->getPatternGroups($pattern); - $nbGroups = count($groups); - - return strlen($groups[$nbGroups - 1]); - } - - /** - * Get the secondary digits group size from a number formatting pattern - * e.g.: with #,##0.### => No secondary group. Will return primary group size. - * e.g.: with #,##,##0.### => Secondary group size is 2, primary group size is 3. - * - * @param string $pattern The CLDR number formatting pattern - * - * @return int The secondary group size of the passed pattern - */ - protected function getSecondaryGroupSize($pattern) - { - $groups = $this->getPatternGroups($pattern); - $nbGroups = count($groups); - - if ($nbGroups > 2) { - return strlen($groups[$nbGroups - 2]); - } - - return strlen($groups[$nbGroups - 1]); - } - - protected function getPatternGroups($pattern) - { - $parts = explode('.', $pattern); - $integerPart = $parts[0]; - - return explode(',', $integerPart); - } -} diff --git a/src/Core/Localization/Specification/Number.php b/src/Core/Localization/Specification/Number.php deleted file mode 100644 index 5b9f04d1..00000000 --- a/src/Core/Localization/Specification/Number.php +++ /dev/null @@ -1,345 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * Number specification class. - * - * Regroups rules and data used when formatting a decimal number in a given locale and a given numbering system - * (latin, arab, ...). - */ -class Number implements NumberInterface -{ - /** - * Number specification constructor. - * - * @param string $positivePattern - * CLDR formatting pattern for positive amounts - * @param string $negativePattern - * CLDR formatting pattern for negative amounts - * @param NumberSymbolList[] $symbols - * List of available number symbols lists (NumberSymbolList objects) - * Each list is indexed by numbering system - * @param int $maxFractionDigits - * Maximum number of digits after decimal separator - * @param int $minFractionDigits - * Minimum number of digits after decimal separator - * @param bool $groupingUsed - * Is digits grouping used ? - * @param int $primaryGroupSize - * Size of primary digits group in the number - * @param int $secondaryGroupSize - * Size of secondary digits group in the number - * - * @throws LocalizationException - */ - public function __construct( - $positivePattern, - $negativePattern, - $symbols, - $maxFractionDigits, - $minFractionDigits, - $groupingUsed, - $primaryGroupSize, - $secondaryGroupSize - ) { - $this->positivePattern = $positivePattern; - $this->negativePattern = $negativePattern; - $this->symbols = $symbols; - - if ($maxFractionDigits < $minFractionDigits) { - $minFractionDigits = $maxFractionDigits; - } - $this->maxFractionDigits = $maxFractionDigits; - $this->minFractionDigits = $minFractionDigits; - - $this->groupingUsed = $groupingUsed; - $this->primaryGroupSize = $primaryGroupSize; - $this->secondaryGroupSize = $secondaryGroupSize; - - $this->validateData(); - } - - /** - * Positive number pattern. - * - * Unicode's CLDR specific syntax. Describes how to format a positive number. - * eg: #,##0.### (decimal) - * eg: #,##0.##0 % (percentage) - * eg: #,##0.00 ¤ (price) - * - * @var string - */ - protected $positivePattern; - - /** - * Negative number pattern. - * - * Unicode's CLDR specific syntax. Describes how to format a negative number. - * eg: -#,##0.### (decimal) - * eg: -#,##0.##0 % (percentage) - * eg: -#,##0.00 ¤ (price) - * - * @var string - */ - protected $negativePattern; - - /** - * List of available number symbols lists (NumberSymbolList objects) - * Each list is indexed by numbering system. - * - * @var NumberSymbolList[] - */ - protected $symbols; - - /** - * Maximum number of digits after decimal separator (rounding if needed). - * - * @var int - */ - protected $maxFractionDigits; - - /** - * Minimum number of digits after decimal separator (fill with "0" if needed). - * - * @var int - */ - protected $minFractionDigits; - - /** - * Is digits grouping used ? - * eg: if yes -> "9 999 999". If no => "9999999". - * - * @var bool - */ - protected $groupingUsed; - - /** - * Size of primary digits group in the number - * e.g.: 999 is the primary group in this number: 1 234 999.567. - * - * @var int - */ - protected $primaryGroupSize; - - /** - * Size of secondary digits groups in the number - * eg: 999 is a secondary group in this number: 123 999 456.789 - * eg: another secondary group (still 999): 999 123 456.789. - * - * @var int - */ - protected $secondaryGroupSize; - - /** - * Get all specified symbols lists, indexed by available numbering system. - * - * Each item of the result is a NumberSymbolList - * - * @return NumberSymbolList[] - */ - public function getAllSymbols() - { - return $this->symbols; - } - - /** - * Get the specified symbols list for a given numbering system. - * - * @param string $numberingSystem - * Numbering system to use when formatting numbers. @see http://cldr.unicode.org/translation/numbering-systems - * - * @return NumberSymbolList - * - * @throws LocalizationException - */ - public function getSymbolsByNumberingSystem($numberingSystem = NumberInterface::NUMBERING_SYSTEM_LATIN) - { - if (!isset($this->symbols[$numberingSystem])) { - throw new LocalizationException('Unknown or invalid numbering system'); - } - - return $this->symbols[$numberingSystem]; - } - - /** - * Get the formatting rules for this number (when positive). - * - * This pattern uses the Unicode CLDR number pattern syntax - * - * @return string - */ - public function getPositivePattern() - { - return $this->positivePattern; - } - - /** - * Get the formatting rules for this number (when negative). - * - * This pattern uses the Unicode CLDR number pattern syntax - * - * @return string - */ - public function getNegativePattern() - { - return $this->negativePattern; - } - - /** - * Get the maximum number of digits after decimal separator (rounding if needed). - * - * @return int - */ - public function getMaxFractionDigits() - { - return $this->maxFractionDigits; - } - - /** - * Get the minimum number of digits after decimal separator (fill with "0" if needed). - * - * @return int - */ - public function getMinFractionDigits() - { - return $this->minFractionDigits; - } - - /** - * Get the "grouping" flag. This flag defines if digits grouping should be used when formatting this number. - * - * @return bool - */ - public function isGroupingUsed() - { - return $this->groupingUsed; - } - - /** - * Get the size of primary digits group in the number. - * - * @return int - */ - public function getPrimaryGroupSize() - { - return $this->primaryGroupSize; - } - - /** - * Get the size of secondary digits groups in the number. - * - * @return int - */ - public function getSecondaryGroupSize() - { - return $this->secondaryGroupSize; - } - - /** - * Data (attributes) validation. - * - * @throws LocalizationException - */ - protected function validateData() - { - if (!isset($this->positivePattern) - || !is_string($this->positivePattern) - ) { - throw new LocalizationException('Invalid positivePattern'); - } - - if (!isset($this->negativePattern) - || !is_string($this->negativePattern) - ) { - throw new LocalizationException('Invalid negativePattern'); - } - - if (!isset($this->symbols) - || !(is_array($this->symbols)) - ) { - throw new LocalizationException('Invalid symbols'); - } - - foreach ($this->symbols as $symbolList) { - if (!$symbolList instanceof NumberSymbolList) { - throw new LocalizationException('Symbol lists must be instances of NumberSymbolList'); - } - } - - if (!isset($this->maxFractionDigits) - || !is_int($this->maxFractionDigits) - ) { - throw new LocalizationException('Invalid maxFractionDigits'); - } - - if (!isset($this->minFractionDigits) - || !is_int($this->minFractionDigits) - ) { - throw new LocalizationException('Invalid minFractionDigits'); - } - - if (!isset($this->groupingUsed) - || !is_bool($this->groupingUsed) - ) { - throw new LocalizationException('Invalid groupingUsed'); - } - - if (!isset($this->primaryGroupSize) - || !is_int($this->primaryGroupSize) - ) { - throw new LocalizationException('Invalid primaryGroupSize'); - } - - if (!isset($this->secondaryGroupSize) - || !is_int($this->secondaryGroupSize) - ) { - throw new LocalizationException('Invalid secondaryGroupSize'); - } - } - - /** - * To array function - * - * @return array - */ - public function toArray() - { - return [ - 'numberSymbols' => $this->getSymbolsByNumberingSystem()->toArray(), - 'positivePattern' => $this->getPositivePattern(), - 'negativePattern' => $this->getNegativePattern(), - 'maxFractionDigits' => $this->getMaxFractionDigits(), - 'minFractionDigits' => $this->getMinFractionDigits(), - 'groupingUsed' => $this->isGroupingUsed(), - 'primaryGroupSize' => $this->getPrimaryGroupSize(), - 'secondaryGroupSize' => $this->getSecondaryGroupSize(), - ]; - } -} diff --git a/src/Core/Localization/Specification/NumberCollection.php b/src/Core/Localization/Specification/NumberCollection.php deleted file mode 100644 index b32a2323..00000000 --- a/src/Core/Localization/Specification/NumberCollection.php +++ /dev/null @@ -1,148 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use ArrayIterator; -use Countable; -use IteratorAggregate; -use PrestaShop\PrestaShop\Core\Localization\Specification\NumberInterface as NumberSpecificationInterface; - -/** - * Number specifications collection - * Contains a list of Number specification items (all implementing NumberInterface). - */ -class NumberCollection implements IteratorAggregate, Countable -{ - /** - * The Number specification items. - * - * @var NumberSpecificationInterface[] - */ - protected $numberSpecifications = []; - - /** - * Gets the current NumberCollection as an Iterator that includes all Number specification items. - * - * It implements \IteratorAggregate. - * - * @return ArrayIterator|NumberSpecificationInterface[] - * An ArrayIterator object for iterating over Number specification items - */ - public function getIterator() - { - return new ArrayIterator($this->numberSpecifications); - } - - /** - * Gets the number of Number specification items in this collection. - * - * @return int - * The number of Number specification items - */ - public function count() - { - return count($this->numberSpecifications); - } - - /** - * Adds a Number specification item at the end of the collection. - * - * @param int|string $index - * The item index - * @param numberSpecificationInterface $numberSpecification - * The Number specification item to add - * - * @return NumberCollection - * Fluent interface - */ - public function add($index, NumberSpecificationInterface $numberSpecification) - { - $this->numberSpecifications[$index] = $numberSpecification; - - return $this; - } - - /** - * Returns all Number specification items in this collection. - * - * @return NumberSpecificationInterface[] - * An array of Number specification items - */ - public function all() - { - return $this->numberSpecifications; - } - - /** - * Gets a Number specification item by index. - * - * @param int|string $index - * The Number specification item index into this collection - * (@see NumberCollection::add()) - * - * @return NumberSpecificationInterface|null - * A Number specification instance or null when not found - */ - public function get($index) - { - return isset($this->numberSpecifications[$index]) - ? $this->numberSpecifications[$index] - : null; - } - - /** - * Removes a Number specification item or an array of Number specification items by index from the collection. - * - * @param int|string|int[]|string[]|array $index - * The Number specification item index or an array of Number specification item indexes - * - * @return NumberCollection - * Fluent interface - */ - public function remove($index) - { - foreach ((array) $index as $i) { - unset($this->numberSpecifications[$i]); - } - - return $this; - } - - /** - * Clear the collection, removing all contained Number specification items. - * - * @return NumberCollection - * Fluent interface - */ - public function clear() - { - $this->numberSpecifications = []; - - return $this; - } -} diff --git a/src/Core/Localization/Specification/NumberInterface.php b/src/Core/Localization/Specification/NumberInterface.php deleted file mode 100644 index fd695b15..00000000 --- a/src/Core/Localization/Specification/NumberInterface.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -/** - * Number specification interface. - * - * Regroups rules and data used when formatting a decimal number in a given locale and a given numbering system - * (latin, arab, ...). - */ -interface NumberInterface -{ - /** - * Latin numbering system is the "occidental" numbering system. Number digits are 0123456789. - * This is the default numbering system in PrestaShop, even for arabian or asian languages, until we - * provide a way to configure this in admin. - */ - const NUMBERING_SYSTEM_LATIN = 'latn'; - - /** - * Get all specified symbols lists, indexed by available numbering system. - * - * Each item of the result is a NumberSymbolList - * - * @return NumberSymbolList[] - */ - public function getAllSymbols(); - - /** - * Get the specified symbols list for a given numbering system. - * - * @param string $numberingSystem - * Numbering system to use when formatting numbers. @see http://cldr.unicode.org/translation/numbering-systems - * - * @return NumberSymbolList - */ - public function getSymbolsByNumberingSystem($numberingSystem = NumberInterface::NUMBERING_SYSTEM_LATIN); - - /** - * Get the formatting rules for this number (when positive). - * - * This pattern uses the Unicode CLDR number pattern syntax - * - * @return string - */ - public function getPositivePattern(); - - /** - * Get the formatting rules for this number (when negative). - * - * This pattern uses the Unicode CLDR number pattern syntax - * - * @return string - */ - public function getNegativePattern(); - - /** - * Get the maximum number of digits after decimal separator (rounding if needed). - * - * @return int - */ - public function getMaxFractionDigits(); - - /** - * Get the minimum number of digits after decimal separator (fill with "0" if needed). - * - * @return int - */ - public function getMinFractionDigits(); - - /** - * Get the "grouping" flag. This flag defines if digits grouping should be used when formatting this number. - * - * @return bool - */ - public function isGroupingUsed(); - - /** - * Get the size of primary digits group in the number. - * - * @return int - */ - public function getPrimaryGroupSize(); - - /** - * Get the size of secondary digits groups in the number. - * - * @return int - */ - public function getSecondaryGroupSize(); -} diff --git a/src/Core/Localization/Specification/NumberSymbolList.php b/src/Core/Localization/Specification/NumberSymbolList.php deleted file mode 100644 index 12e0324e..00000000 --- a/src/Core/Localization/Specification/NumberSymbolList.php +++ /dev/null @@ -1,400 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; - -/** - * Number's symbols data object. Regroups all symbols used when formatting a number - * (decimal separator, thousands separator, etc.). - */ -class NumberSymbolList -{ - /** - * Decimal separator character. - * - * Separates the integer and fractional part of the number. - * - * @var string - */ - protected $decimal; - - /** - * Digits group separator character. - * - * separates clusters of integer digits to make large numbers more legible; commonly used for thousands(grouping - * size 3, e.g. "100,000,000") or in some locales, ten-thousands (grouping size 4, e.g. "1,0000,0000"). - * - * @var string - */ - protected $group; - - /** - * List elements separator character. - * - * Symbol used to separate numbers in a list intended to represent structured data such as an array. - * - * @var string - */ - protected $list; - - /** - * Percent sign character. - * - * Used to indicate a percentage (1/100th) amount. - * - * @var string - */ - protected $percentSign; - - /** - * Minus sign character. - * - * Symbol used to denote negative value. - * - * @var string - */ - protected $minusSign; - - /** - * Plus sign character. - * - * Symbol used to denote positive value. - * It can be used to produce modified patterns, so that 3.12 is formatted as "+3.12", for example. - * - * @var string - */ - protected $plusSign; - - /** - * Exponential character. - * - * Symbol separating the mantissa and exponent values. - * - * @var string - */ - protected $exponential; - - /** - * Superscripting exponent character. - * - * Used in numbers to show a format like "1.23 × 10^4" - * (exponential character is a shortcut for "× 10^n" notation) - * - * @var string - */ - protected $superscriptingExponent; - - /** - * Permille sign character. - * - * Used to define them as a per-mille (1/1000th) amount. - * - * @var string - */ - protected $perMille; - - /** - * The infinity sign. Corresponds to the IEEE infinity bit pattern. - * - * @var string - */ - protected $infinity; - - /** - * The NaN (Not A Number) sign. Corresponds to the IEEE NaN bit pattern. - * - * @var string - */ - protected $nan; - - /** - * NumberSymbolList constructor. - * - * @param string $decimal - * Decimal separator character - * @param string $group - * Digits group separator character - * @param string $list - * List elements separator character - * @param string $percentSign - * Percent sign character - * @param string $minusSign - * Minus sign character - * @param string $plusSign - * Plus sign character - * @param string $exponential - * Exponential character - * @param string $superscriptingExponent - * Superscripting exponent character - * @param string $perMille - * Permille sign character - * @param string $infinity - * The infinity sign. Corresponds to the IEEE infinity bit pattern. - * @param string $nan - * The NaN (Not A Number) sign. Corresponds to the IEEE NaN bit pattern. - * - * @throws LocalizationException - */ - public function __construct( - $decimal, - $group, - $list, - $percentSign, - $minusSign, - $plusSign, - $exponential, - $superscriptingExponent, - $perMille, - $infinity, - $nan - ) { - $this->decimal = $decimal; - $this->group = $group; - $this->list = $list; - $this->percentSign = $percentSign; - $this->minusSign = $minusSign; - $this->plusSign = $plusSign; - $this->exponential = $exponential; - $this->superscriptingExponent = $superscriptingExponent; - $this->perMille = $perMille; - $this->infinity = $infinity; - $this->nan = $nan; - - $this->validateData(); - } - - /** - * Get the decimal separator. - * - * @return string - */ - public function getDecimal() - { - return $this->decimal; - } - - /** - * Get the digit groups separator. - * - * @return string - */ - public function getGroup() - { - return $this->group; - } - - /** - * Get the list elements separator. - * - * @return string - */ - public function getList() - { - return $this->list; - } - - /** - * Get the percent sign. - * - * @return string - */ - public function getPercentSign() - { - return $this->percentSign; - } - - /** - * Get the minus sign. - * - * @return string - */ - public function getMinusSign() - { - return $this->minusSign; - } - - /** - * Get the plus sign. - * - * @return string - */ - public function getPlusSign() - { - return $this->plusSign; - } - - /** - * Get the exponential character. - * - * @return string - */ - public function getExponential() - { - return $this->exponential; - } - - /** - * Get the exponent character. - * - * @return string - */ - public function getSuperscriptingExponent() - { - return $this->superscriptingExponent; - } - - /** - * Gert the per mille symbol (often "‰"). - * - * @see https://en.wikipedia.org/wiki/Per_mille - * - * @return string - */ - public function getPerMille() - { - return $this->perMille; - } - - /** - * Get the infinity symbol (often "∞"). - * - * @see https://en.wikipedia.org/wiki/Infinity_symbol - * - * @return string - */ - public function getInfinity() - { - return $this->infinity; - } - - /** - * Get the NaN (not a number) sign. - * - * @return string - */ - public function getNan() - { - return $this->nan; - } - - /** - * Symbols list validation. - * - * @throws LocalizationException - */ - protected function validateData() - { - if (!isset($this->decimal) - || !is_string($this->decimal) - ) { - throw new LocalizationException('Invalid decimal : ' . print_r($this->decimal, true)); - } - - if (!isset($this->group) - || !is_string($this->group) - ) { - throw new LocalizationException('Invalid group : ' . print_r($this->group, true)); - } - - if (!isset($this->list) - || !is_string($this->list) - ) { - throw new LocalizationException('Invalid symbols list : ' . print_r($this->list, true)); - } - - if (!isset($this->percentSign) - || !is_string($this->percentSign) - ) { - throw new LocalizationException('Invalid percentSign : ' . print_r($this->percentSign, true)); - } - - if (!isset($this->minusSign) - || !is_string($this->minusSign) - ) { - throw new LocalizationException('Invalid minusSign : ' . print_r($this->minusSign, true)); - } - - if (!isset($this->plusSign) - || !is_string($this->plusSign) - ) { - throw new LocalizationException('Invalid plusSign : ' . print_r($this->plusSign, true)); - } - - if (!isset($this->exponential) - || !is_string($this->exponential) - ) { - throw new LocalizationException('Invalid exponential : ' . print_r($this->exponential, true)); - } - - if (!isset($this->superscriptingExponent) - || !is_string($this->superscriptingExponent) - ) { - throw new LocalizationException('Invalid superscriptingExponent : ' . print_r($this->superscriptingExponent, true)); - } - - if (!isset($this->perMille) - || !is_string($this->perMille) - ) { - throw new LocalizationException('Invalid perMille : ' . print_r($this->perMille, true)); - } - - if (!isset($this->infinity) - || !is_string($this->infinity) - ) { - throw new LocalizationException('Invalid infinity : ' . print_r($this->infinity, true)); - } - - if (!isset($this->nan) - || !is_string($this->nan) - ) { - throw new LocalizationException('Invalid nan : ' . print_r($this->nan, true)); - } - } - - /** - * To array function - * - * @return array - */ - public function toArray() - { - return [ - $this->getDecimal(), - $this->getGroup(), - $this->getList(), - $this->getPercentSign(), - $this->getMinusSign(), - $this->getPlusSign(), - $this->getExponential(), - $this->getSuperscriptingExponent(), - $this->getPerMille(), - $this->getInfinity(), - $this->getNaN(), - ]; - } -} diff --git a/src/Core/Localization/Specification/Percentage.php b/src/Core/Localization/Specification/Percentage.php deleted file mode 100644 index 7d54f4f3..00000000 --- a/src/Core/Localization/Specification/Percentage.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use PrestaShop\PrestaShop\Core\Localization\Specification\Number as NumberSpecification; - -/** - * Percentage specification class. - * - * Regroups specific rules and data used when formatting a percentage number in a given locale and a given numbering - * system (latin, arab, ...). - */ -class Percentage extends NumberSpecification -{ -} diff --git a/src/Core/Localization/Specification/Price.php b/src/Core/Localization/Specification/Price.php deleted file mode 100644 index 099b4634..00000000 --- a/src/Core/Localization/Specification/Price.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Localization\Specification; - -use PrestaShop\PrestaShop\Core\Localization\Exception\LocalizationException; -use PrestaShop\PrestaShop\Core\Localization\Specification\Number as NumberSpecification; - -/** - * Price number specification class - * Regroups specific rules and data used when formatting a price in a given locale and a given numbering system - * (latin, arab, ...). - */ -class Price extends NumberSpecification -{ - /** - * Currency display option: symbol notation. - */ - const CURRENCY_DISPLAY_SYMBOL = 'symbol'; - - /** - * Currency display option: ISO code notation. - */ - const CURRENCY_DISPLAY_CODE = 'code'; - - /** - * Type of display for currency symbol - * cf. self::CURRENCY_DISPLAY_SYMBOL and self::CURRENCY_DISPLAY_CODE constants. - * - * @var string - */ - protected $currencyDisplay; - - /** - * @var string The currency symbol - * eg : € - */ - protected $currencySymbol; - - /** - * @var string The currency code - * eg : EUR - */ - protected $currencyCode; - - /** - * Price specification constructor. - * - * @param string $positivePattern - * CLDR formatting pattern for positive amounts - * @param string $negativePattern - * CLDR formatting pattern for negative amounts - * @param NumberSymbolList[] $symbols - * List of available number symbols lists (NumberSymbolList objects) - * Each list is indexed by numbering system - * @param int $maxFractionDigits - * Maximum number of digits after decimal separator - * @param int $minFractionDigits - * Minimum number of digits after decimal separator - * @param bool $groupingUsed - * Is digits grouping used ? - * @param int $primaryGroupSize - * Size of primary digits group in the number - * @param int $secondaryGroupSize - * Size of secondary digits group in the number - * @param string $currencyDisplay - * Type of display for currency symbol - * @param string $currencySymbol - * Currency symbol of this price (eg. : €) - * @param $currencyCode - * Currency code of this price (e.g.: EUR) - * - * @throws LocalizationException - */ - public function __construct( - $positivePattern, - $negativePattern, - $symbols, - $maxFractionDigits, - $minFractionDigits, - $groupingUsed, - $primaryGroupSize, - $secondaryGroupSize, - $currencyDisplay, - $currencySymbol, - $currencyCode - ) { - $this->currencyDisplay = $currencyDisplay; - $this->currencySymbol = $currencySymbol; - $this->currencyCode = $currencyCode; - - parent::__construct( - $positivePattern, - $negativePattern, - $symbols, - $maxFractionDigits, - $minFractionDigits, - $groupingUsed, - $primaryGroupSize, - $secondaryGroupSize - ); - } - - /** - * Get type of display for currency symbol. - * - * @return string - */ - public function getCurrencyDisplay() - { - return $this->currencyDisplay; - } - - /** - * Get the currency symbol - * e.g.: €. - * - * @return string - */ - public function getCurrencySymbol() - { - return $this->currencySymbol; - } - - /** - * Get the currency ISO code - * e.g.: EUR. - * - * @return string - */ - public function getCurrencyCode() - { - return $this->currencyCode; - } - - /** - * Data (attributes) validation. - * - * @throws LocalizationException - */ - protected function validateData() - { - parent::validateData(); - - if (!isset($this->currencyDisplay) - || !in_array($this->currencyDisplay, [self::CURRENCY_DISPLAY_CODE, self::CURRENCY_DISPLAY_SYMBOL]) - ) { - throw new LocalizationException('Invalid currencyDisplay'); - } - } - - /** - * To array function - * - * @return array - */ - public function toArray() - { - return array_merge( - [ - 'currencyCode' => $this->getCurrencyCode(), - 'currencySymbol' => $this->getCurrencySymbol(), - ], - parent::toArray() - ); - } -} diff --git a/src/Core/MailTemplate/FolderThemeCatalog.php b/src/Core/MailTemplate/FolderThemeCatalog.php deleted file mode 100644 index e164e5f3..00000000 --- a/src/Core/MailTemplate/FolderThemeCatalog.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Exception\TypeException; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * This is a basic mail layouts catalog, not a lot of intelligence it is based - * simply on existing files on the $mailThemesFolder (no database, or config files). - */ -final class FolderThemeCatalog implements ThemeCatalogInterface -{ - /** @var string */ - private $mailThemesFolder; - - /** @var HookDispatcherInterface */ - private $hookDispatcher; - - /** @var FolderThemeScanner */ - private $scanner; - - /** - * @param string $mailThemesFolder - * @param FolderThemeScanner $scanner - * @param HookDispatcherInterface $hookDispatcher - */ - public function __construct( - $mailThemesFolder, - FolderThemeScanner $scanner, - HookDispatcherInterface $hookDispatcher - ) { - $this->mailThemesFolder = $mailThemesFolder; - $this->scanner = $scanner; - $this->hookDispatcher = $hookDispatcher; - } - - /** - * Returns the list of found themes (non empty folders, in the mail themes - * folder). - * - * @throws FileNotFoundException - * @throws TypeException - * - * @return ThemeCollectionInterface - */ - public function listThemes() - { - $this->checkThemesFolder(); - - $finder = new Finder(); - $finder->sortByName(); - $finder->directories()->in($this->mailThemesFolder)->depth(0); - $mailThemes = new ThemeCollection(); - /** @var SplFileInfo $mailThemeFolder */ - foreach ($finder as $mailThemeFolder) { - $mailTheme = $this->scanner->scan($mailThemeFolder->getRealPath()); - if ($mailTheme->getLayouts()->count() > 0) { - $mailThemes[] = $mailTheme; - } - } - - //This hook allows you to add/remove a mail theme - $this->hookDispatcher->dispatchWithParameters( - ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK, - ['mailThemes' => $mailThemes] - ); - - return $mailThemes; - } - - /** - * @param string $theme - * - * @throws FileNotFoundException - * @throws InvalidArgumentException - * @throws TypeException - * - * @return ThemeInterface - */ - public function getByName($theme) - { - /** @var ThemeCollectionInterface $availableThemes */ - $availableThemes = $this->listThemes(); - $themeNames = []; - /** @var ThemeInterface $availableTheme */ - foreach ($availableThemes as $availableTheme) { - if ($theme === $availableTheme->getName()) { - return $availableTheme; - } - $themeNames[] = $availableTheme->getName(); - } - - throw new InvalidArgumentException(sprintf('Invalid requested theme "%s", only available themes are: %s', $theme, implode(', ', $themeNames))); - } - - /** - * @throws FileNotFoundException - */ - private function checkThemesFolder() - { - if (!is_dir($this->mailThemesFolder)) { - throw new FileNotFoundException(sprintf('Invalid mail themes folder "%s": no such directory', $this->mailThemesFolder)); - } - } -} diff --git a/src/Core/MailTemplate/FolderThemeScanner.php b/src/Core/MailTemplate/FolderThemeScanner.php deleted file mode 100644 index c8e92bd5..00000000 --- a/src/Core/MailTemplate/FolderThemeScanner.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\TypeException; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\Layout; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollection; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollectionInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Class FolderThemeScanner is used to scan a mail theme folder, it returns a ThemeInterface with all - * its layouts. - */ -final class FolderThemeScanner -{ - /** - * @param string $mailThemeFolder - * - * @return ThemeInterface|null - * - * @throws FileNotFoundException - * @throws TypeException - */ - public function scan($mailThemeFolder) - { - $this->checkThemeFolder($mailThemeFolder); - - $mailTheme = new Theme(basename($mailThemeFolder)); - - $finder = new Finder(); - $finder->files()->in($mailThemeFolder); - if ($finder->count() > 0) { - $mailTheme->setLayouts($this->findThemeLayouts($mailThemeFolder)); - } - - return $mailTheme; - } - - /** - * @param string $mailThemeFolder - * - * @throws TypeException - * - * @return LayoutCollectionInterface - */ - private function findThemeLayouts($mailThemeFolder) - { - $mailThemeLayouts = new LayoutCollection(); - $this->addCoreLayouts($mailThemeLayouts, $mailThemeFolder); - $this->addModulesLayouts($mailThemeLayouts, $mailThemeFolder); - - return $mailThemeLayouts; - } - - /** - * @param LayoutCollectionInterface $collection - * @param string $mailThemeFolder - */ - private function addCoreLayouts(LayoutCollectionInterface $collection, $mailThemeFolder) - { - $coreLayoutsFolder = implode(DIRECTORY_SEPARATOR, [ - $mailThemeFolder, - MailTemplateInterface::CORE_CATEGORY, - ]); - if (!is_dir($coreLayoutsFolder)) { - return; - } - - $this->addLayoutsFromFolder($collection, $coreLayoutsFolder); - } - - /** - * @param LayoutCollectionInterface $collection - * @param string $mailThemeFolder - */ - private function addModulesLayouts(LayoutCollectionInterface $collection, $mailThemeFolder) - { - $moduleLayoutsFolder = implode(DIRECTORY_SEPARATOR, [ - $mailThemeFolder, - MailTemplateInterface::MODULES_CATEGORY, - ]); - if (!is_dir($moduleLayoutsFolder)) { - return; - } - - $moduleFinder = new Finder(); - $moduleFinder->directories()->in($moduleLayoutsFolder)->depth(0); - - /* @var SplFileInfo $moduleFolder */ - foreach ($moduleFinder as $moduleFolder) { - $this->addLayoutsFromFolder($collection, $moduleFolder->getRealPath(), $moduleFolder->getFilename()); - } - } - - /** - * @param LayoutCollectionInterface $collection - * @param string $folder - * @param string $moduleName - */ - private function addLayoutsFromFolder( - LayoutCollectionInterface $collection, - $folder, - $moduleName = '' - ) { - $layoutFiles = []; - $finder = new Finder(); - $finder->files()->in($folder)->sortByName(); - /** @var SplFileInfo $fileInfo */ - foreach ($finder as $fileInfo) { - //Get filename without any extension (ex: account.html.twig -> account) - $layoutName = preg_replace('/\..+/', '', $fileInfo->getBasename()); - if (!isset($layoutFiles[$layoutName])) { - $layoutFiles[$layoutName] = [ - MailTemplateInterface::HTML_TYPE => '', - MailTemplateInterface::TXT_TYPE => '', - ]; - } - $templateType = $this->getTemplateType($fileInfo); - $layoutFiles[$layoutName][$templateType] = $fileInfo->getRealPath(); - } - - foreach ($layoutFiles as $layoutName => $layouts) { - $collection->add(new Layout( - $layoutName, - $layouts[MailTemplateInterface::HTML_TYPE], - $layouts[MailTemplateInterface::TXT_TYPE], - $moduleName - )); - } - } - - /** - * @param SplFileInfo $fileInfo - * - * @return string - */ - private function getTemplateType(SplFileInfo $fileInfo) - { - $ext = !empty($fileInfo->getExtension()) ? '.' . $fileInfo->getExtension() : ''; - $htmlTypeRegexp = sprintf('/.+\.%s%s/', MailTemplateInterface::HTML_TYPE, $ext); - if (preg_match($htmlTypeRegexp, $fileInfo->getFilename())) { - return MailTemplateInterface::HTML_TYPE; - } - - return MailTemplateInterface::TXT_TYPE; - } - - /** - * @throws FileNotFoundException - */ - private function checkThemeFolder($mailThemeFolder) - { - if (!is_dir($mailThemeFolder)) { - throw new FileNotFoundException(sprintf('Invalid mail theme folder "%s": no such directory', $mailThemeFolder)); - } - } -} diff --git a/src/Core/MailTemplate/Layout/Layout.php b/src/Core/MailTemplate/Layout/Layout.php deleted file mode 100644 index 6c807733..00000000 --- a/src/Core/MailTemplate/Layout/Layout.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -/** - * Class MailLayout is the default implementation of MailLayoutInterface, - * it is a simple immutable data container with no logic. It contains the - * basic info about a mail layout which is used to generate a MailTemplate. - */ -class Layout implements LayoutInterface -{ - /** @var string */ - private $name; - - /** @var string */ - private $htmlPath; - - /** @var string */ - private $txtPath; - - /** @var string */ - private $moduleName; - - /** - * @param string $name Name of the layout to describe its purpose - * @param string $htmlPath Absolute path of the html layout file - * @param string $txtPath Absolute path of the txt layout file - * @param string $moduleName Which module this layout is associated to (if any) - */ - public function __construct( - $name, - $htmlPath, - $txtPath, - $moduleName = '' - ) { - $this->name = $name; - $this->htmlPath = $htmlPath; - $this->txtPath = $txtPath; - $this->moduleName = $moduleName; - } - - /** - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * @return string - */ - public function getHtmlPath() - { - return $this->htmlPath; - } - - /** - * @return string - */ - public function getTxtPath() - { - return $this->txtPath; - } - - /** - * @return string - */ - public function getModuleName() - { - return $this->moduleName; - } -} diff --git a/src/Core/MailTemplate/Layout/LayoutCollection.php b/src/Core/MailTemplate/Layout/LayoutCollection.php deleted file mode 100644 index ab35c088..00000000 --- a/src/Core/MailTemplate/Layout/LayoutCollection.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -use PrestaShop\PrestaShop\Core\Data\AbstractTypedCollection; - -class LayoutCollection extends AbstractTypedCollection implements LayoutCollectionInterface -{ - /** - * {@inheritdoc} - */ - protected function getType() - { - return LayoutInterface::class; - } - - /** - * {@inheritdoc} - */ - public function merge(LayoutCollectionInterface $collection) - { - /** @var LayoutInterface $newLayout */ - foreach ($collection as $newLayout) { - if (null !== ($oldLayout = $this->getLayout($newLayout->getName(), $newLayout->getModuleName()))) { - $this->replace($oldLayout, $newLayout); - } else { - $this->add($newLayout); - } - } - } - - /** - * {@inheritdoc} - */ - public function replace(LayoutInterface $oldLayout, LayoutInterface $newLayout) - { - if (!$this->contains($oldLayout)) { - return false; - } - - $oldLayoutIndex = $this->indexOf($oldLayout); - $this->offsetSet($oldLayoutIndex, $newLayout); - - return $this->contains($newLayout); - } - - /** - * {@inheritdoc} - */ - public function getLayout($layoutName, $moduleName) - { - /** @var LayoutInterface $layout */ - foreach ($this as $layout) { - if ($layoutName === $layout->getName() && $moduleName === $layout->getModuleName()) { - return $layout; - } - } - - return null; - } -} diff --git a/src/Core/MailTemplate/Layout/LayoutCollectionInterface.php b/src/Core/MailTemplate/Layout/LayoutCollectionInterface.php deleted file mode 100644 index 6f71e26b..00000000 --- a/src/Core/MailTemplate/Layout/LayoutCollectionInterface.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -/** - * Interface MailLayoutCollectionInterface contains a list of layouts used to generate - * mail templates. Modules can add/remove their own layouts to this collection through - * the hook: - * ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK = actionListMailThemes - */ -interface LayoutCollectionInterface extends \IteratorAggregate, \Countable -{ - /** - * @param LayoutInterface $layout - * - * @return bool - */ - public function contains($layout); - - /** - * @param LayoutInterface $layout - */ - public function add($layout); - - /** - * @param LayoutInterface $layout - */ - public function remove($layout); - - /** - * @param LayoutInterface $oldLayout - * @param LayoutInterface $newLayout - * - * @return bool - */ - public function replace(LayoutInterface $oldLayout, LayoutInterface $newLayout); - - /** - * @param string $layoutName - * @param string $moduleName - * - * @return LayoutInterface|null - */ - public function getLayout($layoutName, $moduleName); - - /** - * @param LayoutCollectionInterface $collection - */ - public function merge(LayoutCollectionInterface $collection); -} diff --git a/src/Core/MailTemplate/Layout/LayoutInterface.php b/src/Core/MailTemplate/Layout/LayoutInterface.php deleted file mode 100644 index 65337825..00000000 --- a/src/Core/MailTemplate/Layout/LayoutInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -/** - * Interface LayoutInterface is used to contain the basic info about a mail layout. - */ -interface LayoutInterface -{ - /** - * Name of the layout to describe its purpose - * - * @return string - */ - public function getName(); - - /** - * Absolute path of the html layout file - * - * @return string - */ - public function getHtmlPath(); - - /** - * Absolute path of the html layout file - * - * @return string - */ - public function getTxtPath(); - - /** - * Which module this layout is associated to (if any) - * - * @return string|null - */ - public function getModuleName(); -} diff --git a/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php b/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php deleted file mode 100644 index e61aee69..00000000 --- a/src/Core/MailTemplate/Layout/LayoutVariablesBuilder.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageDefaultFontsCatalog; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; - -/** - * MailLayoutVariablesBuilder is a basic implementation of MailLayoutVariablesBuilderInterface - * - it formats the variables for template - * - it is able to inject default fonts for specified languages - * - it includes default variables (set in the constructor) - * - it dispatches a hook to allow overriding its output - */ -class LayoutVariablesBuilder implements LayoutVariablesBuilderInterface -{ - /** @var array */ - private $defaultVariables; - - /** @var HookDispatcherInterface */ - private $hookDispatcher; - - /** - * @var LanguageDefaultFontsCatalog - */ - private $languageDefaultFonts; - - /** - * @param HookDispatcherInterface $hookDispatcher - * @param LanguageDefaultFontsCatalog $languageDefaultFonts - * @param array $defaultVariables - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - LanguageDefaultFontsCatalog $languageDefaultFonts, - array $defaultVariables = [] - ) { - $this->hookDispatcher = $hookDispatcher; - $this->languageDefaultFonts = $languageDefaultFonts; - $this->defaultVariables = $defaultVariables; - } - - /** - * {@inheritdoc} - */ - public function buildVariables(LayoutInterface $mailLayout, LanguageInterface $language) - { - $languageDefaultFont = $this->languageDefaultFonts->getDefaultFontByLanguage($language); - if (!empty($languageDefaultFont)) { - $languageDefaultFont .= ','; - } - - $mailLayoutVariables = array_merge($this->defaultVariables, [ - 'languageIsRTL' => $language->isRTL(), - 'languageDefaultFont' => $languageDefaultFont, - 'templateName' => $mailLayout->getName(), - 'templateModuleName' => $mailLayout->getModuleName(), - 'locale' => $language->getLocale(), - ]); - - //This hook allows to change the variables of a layout - $this->hookDispatcher->dispatchWithParameters( - LayoutVariablesBuilderInterface::BUILD_MAIL_LAYOUT_VARIABLES_HOOK, - [ - 'mailLayout' => $mailLayout, - 'mailLayoutVariables' => &$mailLayoutVariables, - ] - ); - - return $mailLayoutVariables; - } -} diff --git a/src/Core/MailTemplate/Layout/LayoutVariablesBuilderInterface.php b/src/Core/MailTemplate/Layout/LayoutVariablesBuilderInterface.php deleted file mode 100644 index 6180abb4..00000000 --- a/src/Core/MailTemplate/Layout/LayoutVariablesBuilderInterface.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Layout; - -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; - -/** - * LayoutVariablesBuilderInterface is used by the MailTemplateRendererInterface - * to render the mails, it returns an array of generic layout variables like: - * - templateModuleName: name of the associated module - * - languageIsRTL: is the language read from Right To Left - * - locale: the locale in which the template is generated - * - emailPublicWebRoot: public mail root for assets - */ -interface LayoutVariablesBuilderInterface -{ - const BUILD_MAIL_LAYOUT_VARIABLES_HOOK = 'actionBuildMailLayoutVariables'; - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * - * @return array - */ - public function buildVariables(LayoutInterface $layout, LanguageInterface $language); -} diff --git a/src/Core/MailTemplate/MailTemplateGenerator.php b/src/Core/MailTemplate/MailTemplateGenerator.php deleted file mode 100644 index 61491e96..00000000 --- a/src/Core/MailTemplate/MailTemplateGenerator.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollectionInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -use Psr\Log\LoggerAwareTrait; -use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; -use Symfony\Component\Filesystem\Filesystem; - -/** - * Class MailTemplateGenerator iterates through the layouts in the provided theme, - * it uses the Renderer to display them (with the requested LanguageInterface) and - * then export them as template files in the specified output folder. - */ -class MailTemplateGenerator -{ - use LoggerAwareTrait; - - /** @var MailTemplateRendererInterface */ - private $renderer; - - /** @var Filesystem */ - private $fileSystem; - - /** - * @param MailTemplateRendererInterface $renderer - * @param LoggerInterface|null $logger - */ - public function __construct( - MailTemplateRendererInterface $renderer, - LoggerInterface $logger = null - ) { - $this->renderer = $renderer; - $this->logger = null !== $logger ? $logger : new NullLogger(); - $this->fileSystem = new Filesystem(); - } - - /** - * @param ThemeInterface $theme - * @param LanguageInterface $language - * @param string $coreOutputFolder - * @param string $modulesOutputFolder - * @param bool $overwriteTemplates [default=false] - * - * @throws FileNotFoundException - */ - public function generateTemplates( - ThemeInterface $theme, - LanguageInterface $language, - $coreOutputFolder, - $modulesOutputFolder, - $overwriteTemplates = false - ) { - if (!is_dir($coreOutputFolder)) { - throw new FileNotFoundException(sprintf('Invalid core output folder "%s"', $coreOutputFolder)); - } - - if (!is_dir($modulesOutputFolder)) { - throw new FileNotFoundException(sprintf('Invalid modules output folder "%s"', $modulesOutputFolder)); - } - - $this->logger->info(sprintf('Exporting mail with theme %s for language %s', $theme->getName(), $language->getName())); - $this->logger->info(sprintf('Core output folder: %s', $coreOutputFolder)); - $this->logger->info(sprintf('Modules output folder: %s', $modulesOutputFolder)); - - /** @var LayoutCollectionInterface $layouts */ - $layouts = $theme->getLayouts(); - /** @var LayoutInterface $layout */ - foreach ($layouts as $layout) { - if (!empty($layout->getModuleName())) { - $outputFolder = implode(DIRECTORY_SEPARATOR, [$modulesOutputFolder, $layout->getModuleName(), 'mails', $language->getIsoCode()]); - } else { - $outputFolder = implode(DIRECTORY_SEPARATOR, [$coreOutputFolder, $language->getIsoCode()]); - } - - //Generate HTML template - $htmlTemplatePath = $this->generateTemplatePath($layout, MailTemplateInterface::HTML_TYPE, $outputFolder); - if (!$this->fileSystem->exists($htmlTemplatePath) || $overwriteTemplates) { - $generatedTemplate = $this->renderer->renderHtml($layout, $language); - $this->fileSystem->dumpFile($htmlTemplatePath, $generatedTemplate); - $this->logger->info(sprintf('Generate html template %s at %s', $layout->getName(), $htmlTemplatePath)); - } - - //Generate TXT template - $txtTemplatePath = $this->generateTemplatePath($layout, MailTemplateInterface::TXT_TYPE, $outputFolder); - if (!$this->fileSystem->exists($txtTemplatePath) || $overwriteTemplates) { - $generatedTemplate = $this->renderer->renderTxt($layout, $language); - $this->fileSystem->dumpFile($txtTemplatePath, $generatedTemplate); - $this->logger->info(sprintf('Generate txt template %s at %s', $layout->getName(), $txtTemplatePath)); - } - } - } - - /** - * @param LayoutInterface $layout - * @param string $templateType - * @param string $outputFolder - * - * @return string - */ - private function generateTemplatePath(LayoutInterface $layout, $templateType, $outputFolder) - { - return implode(DIRECTORY_SEPARATOR, [$outputFolder, $layout->getName()]) . '.' . $templateType; - } -} diff --git a/src/Core/MailTemplate/MailTemplateInterface.php b/src/Core/MailTemplate/MailTemplateInterface.php deleted file mode 100644 index dbcb2830..00000000 --- a/src/Core/MailTemplate/MailTemplateInterface.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -/** - * Interface MailTemplateInterface describe a mail template. A mail template - * is a static file (in html or txt format) used by the Mail class to send - * transactional emails. - */ -interface MailTemplateInterface -{ - const CORE_CATEGORY = 'core'; - const MODULES_CATEGORY = 'modules'; - - const HTML_TYPE = 'html'; - const TXT_TYPE = 'txt'; - - /** - * Whether the template is used by the core or modules - * - * @return string - */ - public function getCategory(); - - /** - * Whether the template is an html or txt type - * - * @return string - */ - public function getType(); - - /** - * Returns the absolute path to the template file. - * - * @return string - */ - public function getPath(); -} diff --git a/src/Core/MailTemplate/MailTemplateRendererInterface.php b/src/Core/MailTemplate/MailTemplateRendererInterface.php deleted file mode 100644 index 8e9ddbfb..00000000 --- a/src/Core/MailTemplate/MailTemplateRendererInterface.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Transformation\TransformationInterface; - -/** - * MailTemplateRendererInterface is used to render a specific MailLayoutInterface - * with the specified LanguageInterface. - */ -interface MailTemplateRendererInterface -{ - const GET_MAIL_LAYOUT_TRANSFORMATIONS = 'actionGetMailLayoutTransformations'; - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * - * @return string - */ - public function renderTxt(LayoutInterface $layout, LanguageInterface $language); - - /** - * @param LayoutInterface $layout - * @param LanguageInterface $language - * - * @return string - */ - public function renderHtml(LayoutInterface $layout, LanguageInterface $language); - - /** - * Adds a transformer to the renderer, when template is rendered all transformers - * matching its type (html or txt) are applied to the output content. - * - * @param TransformationInterface $transformer - * - * @return $this - */ - public function addTransformation(TransformationInterface $transformer); -} diff --git a/src/Core/MailTemplate/MailThemeConfiguration.php b/src/Core/MailTemplate/MailThemeConfiguration.php deleted file mode 100644 index dfe5d70d..00000000 --- a/src/Core/MailTemplate/MailThemeConfiguration.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Exception\CoreException; -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; - -/** - * Class MailThemeConfiguration is used to save Mail Theme settings - * in "Design > Mail Theme" page. - */ -final class MailThemeConfiguration implements DataConfigurationInterface -{ - /** @var ConfigurationInterface */ - private $configuration; - - /** @var ThemeCatalogInterface */ - private $themeCatalog; - - /** - * @param ConfigurationInterface $configuration - * @param ThemeCatalogInterface $themeCatalog - */ - public function __construct( - ConfigurationInterface $configuration, - ThemeCatalogInterface $themeCatalog - ) { - $this->configuration = $configuration; - $this->themeCatalog = $themeCatalog; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'defaultTheme' => $this->configuration->get('PS_MAIL_THEME'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - try { - $this->validateConfiguration($configuration); - $this->configuration->set('PS_MAIL_THEME', $configuration['defaultTheme']); - } catch (CoreException $e) { - $errors[] = $e->getMessage(); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - if (empty($configuration['defaultTheme'])) { - throw new InvalidArgumentException('Default theme can not be empty'); - } - - return null !== $this->themeCatalog->getByName($configuration['defaultTheme']); - } -} diff --git a/src/Core/MailTemplate/Theme.php b/src/Core/MailTemplate/Theme.php deleted file mode 100644 index 1bc9c387..00000000 --- a/src/Core/MailTemplate/Theme.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollection; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollectionInterface; - -/** - * Class MailTheme basic immutable implementation of MailThemeInterface. - */ -class Theme implements ThemeInterface -{ - /** @var string */ - private $name; - - /** - * @var LayoutCollectionInterface - */ - private $layouts; - - /** - * @param string $name - */ - public function __construct($name) - { - $this->name = $name; - $this->layouts = new LayoutCollection(); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * @return LayoutCollectionInterface - */ - public function getLayouts() - { - return $this->layouts; - } - - /** - * @param LayoutCollectionInterface $layouts - * - * @return $this - */ - public function setLayouts($layouts) - { - $this->layouts = $layouts; - - return $this; - } -} diff --git a/src/Core/MailTemplate/ThemeCatalogInterface.php b/src/Core/MailTemplate/ThemeCatalogInterface.php deleted file mode 100644 index a5187702..00000000 --- a/src/Core/MailTemplate/ThemeCatalogInterface.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; - -/** - * Interface ThemeCatalogInterface is used to list the available themes to generate - * mail templates, each one containing its own layouts. Layouts are divided in two - * categories "core" and "modules" layouts. You can change the themes collection or - * modify a theme's layout collection via the hook: - * ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK = actionListMailThemes - */ -interface ThemeCatalogInterface -{ - const LIST_MAIL_THEMES_HOOK = 'actionListMailThemes'; - - /** - * Returns the list of existing themes. - * - * @return ThemeCollectionInterface - */ - public function listThemes(); - - /** - * @param string $theme - * - * @throws InvalidArgumentException - * - * @return ThemeInterface - */ - public function getByName($theme); -} diff --git a/src/Core/MailTemplate/ThemeCollection.php b/src/Core/MailTemplate/ThemeCollection.php deleted file mode 100644 index fb78f11a..00000000 --- a/src/Core/MailTemplate/ThemeCollection.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\Data\AbstractTypedCollection; - -/** - * Class MailThemeCollection is a collection of MailThemeInterface elements. - */ -class ThemeCollection extends AbstractTypedCollection implements ThemeCollectionInterface -{ - /** - * {@inheritdoc} - */ - protected function getType() - { - return ThemeInterface::class; - } - - /** - * @param string $themeName - * - * @return ThemeInterface|null - */ - public function getByName($themeName) - { - return $this->filter(function (ThemeInterface $theme) use ($themeName) { - return $themeName === $theme->getName(); - })->first(); - } -} diff --git a/src/Core/MailTemplate/ThemeCollectionInterface.php b/src/Core/MailTemplate/ThemeCollectionInterface.php deleted file mode 100644 index f8d26f00..00000000 --- a/src/Core/MailTemplate/ThemeCollectionInterface.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -/** - * Interface ThemeCollectionInterface contains a list of themes to - * generate mail templates. Modules can add/remove their own through the hook: - * ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK = actionListMailThemes - */ -interface ThemeCollectionInterface extends \IteratorAggregate, \Countable -{ - /** - * @param ThemeInterface $theme - * - * @return bool - */ - public function contains($theme); - - /** - * @param ThemeInterface $theme - */ - public function add($theme); - - /** - * @param ThemeInterface $theme - */ - public function remove($theme); - - /** - * @param string $themeName - * - * @return ThemeInterface|null - */ - public function getByName($themeName); -} diff --git a/src/Core/MailTemplate/ThemeInterface.php b/src/Core/MailTemplate/ThemeInterface.php deleted file mode 100644 index 5e8603f3..00000000 --- a/src/Core/MailTemplate/ThemeInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate; - -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutCollectionInterface; - -/** - * Interface MailThemeInterface is used to define mail templates - * themes. It is very simple for now (only a name) but it could evolve in - * the future (include a config, a parent theme, ...) - */ -interface ThemeInterface -{ - /** - * @return string - */ - public function getName(); - - /** - * @return LayoutCollectionInterface - */ - public function getLayouts(); -} diff --git a/src/Core/MailTemplate/Transformation/AbstractTransformation.php b/src/Core/MailTemplate/Transformation/AbstractTransformation.php deleted file mode 100644 index 05c4d453..00000000 --- a/src/Core/MailTemplate/Transformation/AbstractTransformation.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateInterface; - -/** - * Class AbstractTransformation is a basic abstract class for TransformationInterface - */ -abstract class AbstractTransformation implements TransformationInterface -{ - /** @var LanguageInterface */ - protected $language; - - /** @var string */ - protected $type; - - /** - * @param string $type - * - * @throws InvalidArgumentException - */ - public function __construct($type) - { - $availableTypes = [ - MailTemplateInterface::HTML_TYPE, - MailTemplateInterface::TXT_TYPE, - ]; - if (!in_array($type, $availableTypes)) { - throw new InvalidArgumentException(sprintf('Invalid type %s, available types are: %s', $type, implode(', ', $availableTypes))); - } - - $this->type = $type; - } - - /** - * {@inheritdoc} - */ - public function getType() - { - return $this->type; - } - - /** - * {@inheritdoc} - */ - public function setLanguage(LanguageInterface $language) - { - $this->language = $language; - - return $this; - } -} diff --git a/src/Core/MailTemplate/Transformation/CSSInlineTransformation.php b/src/Core/MailTemplate/Transformation/CSSInlineTransformation.php deleted file mode 100644 index 878fe0e5..00000000 --- a/src/Core/MailTemplate/Transformation/CSSInlineTransformation.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use DOMAttr; -use DOMElement; -use Pelago\Emogrifier; -use Pelago\Emogrifier\HtmlProcessor\CssToAttributeConverter; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateInterface; -use Symfony\Component\DomCrawler\Crawler; -use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles; - -/** - * Class CSSInlineTransformation applies a transformation on html templates, it downloads - * each css files integrated in the template, and then applies them on the html inline-style. - * This is used for some mail readers which don't load css styles but can interpret them when - * set inline. - */ -class CSSInlineTransformation extends AbstractTransformation -{ - public function __construct() - { - parent::__construct(MailTemplateInterface::HTML_TYPE); - } - - /** - * {@inheritdoc} - */ - public function apply($templateContent, array $templateVariables) - { - if (MailTemplateInterface::HTML_TYPE != $this->type) { - return $templateContent; - } - - /** - * For unknown reason Emogrifier modifies href attribute with variables written - * like this {shop_url} so we temporarily change them to @shop_url@ - */ - $templateContent = preg_replace('/\{(\w+)\}/', '@\1@', $templateContent); - - $cssContent = $this->getCssContent($templateContent); - - $cssToInlineStyles = new CssToInlineStyles(); - $templateContent = $cssToInlineStyles->convert($templateContent, $cssContent); - - $converter = CssToAttributeConverter::fromHtml($templateContent); - $templateContent = $converter->convertCssToVisualAttributes()->render(); - - return preg_replace('/@(\w+)@/', '{\1}', $templateContent); - } - - /** - * @param string $templateContent - * - * @return string - */ - private function getCssContent($templateContent) - { - $crawler = new Crawler($templateContent); - $cssTags = $crawler->filter('link[type="text/css"]'); - $cssUrls = []; - /** @var DOMElement $cssTag */ - foreach ($cssTags as $cssTag) { - /** @var DOMAttr $hrefAttr */ - if ($hrefAttr = $cssTag->attributes->getNamedItem('href')) { - $cssUrls[] = $hrefAttr->nodeValue; - } - } - $cssContents = ''; - foreach ($cssUrls as $cssUrl) { - $cssContent = @file_get_contents($cssUrl); - if (!empty($cssContent)) { - $cssContents .= $cssContent; - } - } - - return $cssContents; - } -} diff --git a/src/Core/MailTemplate/Transformation/HTMLToTextTransformation.php b/src/Core/MailTemplate/Transformation/HTMLToTextTransformation.php deleted file mode 100644 index 688128ed..00000000 --- a/src/Core/MailTemplate/Transformation/HTMLToTextTransformation.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use Html2Text\Html2Text; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateInterface; - -/** - * HTMLTextifyTransformation is used to remove any HTML tags from the template. It - * is especially useful when no txt layout is defined and the renderer uses the html - * layout as a base. This transformation then removes any html tags but keep the raw - * information. - */ -class HTMLToTextTransformation extends AbstractTransformation -{ - public function __construct() - { - parent::__construct(MailTemplateInterface::TXT_TYPE); - } - - /** - * {@inheritdoc} - */ - public function apply($templateContent, array $templateVariables) - { - $templateContent = Html2Text::convert($templateContent, true); - if (PHP_EOL != $templateContent[strlen($templateContent) - 1]) { - $templateContent .= PHP_EOL; - } - - return $templateContent; - } -} diff --git a/src/Core/MailTemplate/Transformation/MailVariablesTransformation.php b/src/Core/MailTemplate/Transformation/MailVariablesTransformation.php deleted file mode 100644 index 70d9752e..00000000 --- a/src/Core/MailTemplate/Transformation/MailVariablesTransformation.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; - -/** - * Class MailVariablesTransformation is used only for preview, it replaces the - * variables present in the mail templates (this replacement is usually performed - * by the Mail class in real behavior). - * You can set the variables using the actionBuildMailLayoutVariables and setting - * them in the `templateVars` key, or simply via the constructor. - */ -class MailVariablesTransformation extends AbstractTransformation -{ - /** - * @var array - */ - private $replaceVariables; - - /** - * @param string $type - * @param array $replaceVariables - * - * @throws InvalidArgumentException - */ - public function __construct($type, array $replaceVariables = []) - { - parent::__construct($type); - $this->replaceVariables = $replaceVariables; - } - - /** - * {@inheritdoc} - */ - public function apply($templateContent, array $templateVariables) - { - $replaceVariables = $this->replaceVariables; - if (!empty($templateVariables['templateVars'])) { - $replaceVariables = array_merge_recursive( - $replaceVariables, - $templateVariables['templateVars'] - ); - } - if (!empty($replaceVariables)) { - $templateContent = strtr($templateContent, $replaceVariables); - } - - return $templateContent; - } -} diff --git a/src/Core/MailTemplate/Transformation/TransformationCollection.php b/src/Core/MailTemplate/Transformation/TransformationCollection.php deleted file mode 100644 index 453de93c..00000000 --- a/src/Core/MailTemplate/Transformation/TransformationCollection.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use PrestaShop\PrestaShop\Core\Data\AbstractTypedCollection; - -class TransformationCollection extends AbstractTypedCollection implements TransformationCollectionInterface -{ - /** - * {@inheritdoc} - */ - protected function getType() - { - return TransformationInterface::class; - } -} diff --git a/src/Core/MailTemplate/Transformation/TransformationCollectionInterface.php b/src/Core/MailTemplate/Transformation/TransformationCollectionInterface.php deleted file mode 100644 index 72861691..00000000 --- a/src/Core/MailTemplate/Transformation/TransformationCollectionInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -/** - * TransformationCollectionInterface contains a list of transformations applied - * on mail templates when they are generated. - */ -interface TransformationCollectionInterface extends \IteratorAggregate, \Countable -{ - /** - * @param TransformationInterface $transformation - * - * @return bool - */ - public function contains($transformation); - - /** - * @param TransformationInterface $transformation - */ - public function add($transformation); - - /** - * @param TransformationInterface $transformation - */ - public function remove($transformation); -} diff --git a/src/Core/MailTemplate/Transformation/TransformationInterface.php b/src/Core/MailTemplate/Transformation/TransformationInterface.php deleted file mode 100644 index 5bf5bacc..00000000 --- a/src/Core/MailTemplate/Transformation/TransformationInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MailTemplate\Transformation; - -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; - -/** - * TransformationInterface is used by the MailTemplateRendererInterface to apply a - * transformation on the generated template (textify html, inline css, add a css or - * an image per language). - */ -interface TransformationInterface -{ - /** - * @param string $templateContent - * @param array $templateVariables - * - * @return string - */ - public function apply($templateContent, array $templateVariables); - - /** - * Returns the type of templates this transformation is associated with, - * either html or txt, so that the renderer knows if it has to be applied - * or not - * - * @return string - */ - public function getType(); - - /** - * @param LanguageInterface $language - * - * @return $this - */ - public function setLanguage(LanguageInterface $language); -} diff --git a/src/Core/MerchandiseReturn/Configuration/MerchandiseReturnOptionsConfiguration.php b/src/Core/MerchandiseReturn/Configuration/MerchandiseReturnOptionsConfiguration.php deleted file mode 100644 index ebd6e6f8..00000000 --- a/src/Core/MerchandiseReturn/Configuration/MerchandiseReturnOptionsConfiguration.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\MerchandiseReturn\Configuration; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Provides data configuration for merchandise returns options form - */ -final class MerchandiseReturnOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_order_return' => (bool) $this->configuration->get('PS_ORDER_RETURN'), - 'order_return_period_in_days' => (int) $this->configuration->get('PS_ORDER_RETURN_NB_DAYS'), - 'order_return_prefix' => $this->configuration->get('PS_RETURN_PREFIX'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if (!$this->validateConfiguration($configuration)) { - $errors[] = [ - 'key' => 'Invalid configuration', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Warning', - ]; - } else { - $this->configuration->set('PS_ORDER_RETURN', $configuration['enable_order_return']); - $this->configuration->set('PS_ORDER_RETURN_NB_DAYS', $configuration['order_return_period_in_days']); - $this->configuration->set('PS_RETURN_PREFIX', $configuration['order_return_prefix']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset($configuration['enable_order_return']); - } -} diff --git a/src/Core/Meta/MetaDataProviderInterface.php b/src/Core/Meta/MetaDataProviderInterface.php deleted file mode 100644 index 182c6c59..00000000 --- a/src/Core/Meta/MetaDataProviderInterface.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Meta; - -/** - * Interface MetaDataProviderInterface defines contract fot MetaDataProvider. - */ -interface MetaDataProviderInterface -{ - /** - * Gets id by page. - * - * @param string $pageName - * - * @return int - */ - public function getIdByPage($pageName); - - /** - * Gets default page by meta id. - * - * @param int $metaId - * - * @return string|null - */ - public function getDefaultMetaPageNameById($metaId); - - /** - * Gets module page by meta id. - * - * @param int $metaId - * - * @return string|null - */ - public function getModuleMetaPageNameById($metaId); - - /** - * Gets default pages which are not configured in Seo & urls page. - * - * @return array - */ - public function getDefaultMetaPageNamesExcludingFilled(); - - /** - * Gets module pages which are not configured in Seo & urls page. - * - * @return array - */ - public function getNotConfiguredModuleMetaPageNames(); -} diff --git a/src/Core/Module/Configuration/PaymentRestrictionsConfigurator.php b/src/Core/Module/Configuration/PaymentRestrictionsConfigurator.php deleted file mode 100644 index 9694ecb3..00000000 --- a/src/Core/Module/Configuration/PaymentRestrictionsConfigurator.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\Configuration; - -use Doctrine\DBAL\Connection; -use PrestaShop\PrestaShop\Core\Module\DataProvider\PaymentModuleListProviderInterface; - -/** - * Class PaymentRestrictionsConfigurator is responsible for configuring restrictions for payment modules. - */ -final class PaymentRestrictionsConfigurator implements PaymentRestrictionsConfiguratorInterface -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string - */ - private $databasePrefix; - - /** - * @var int - */ - private $shopId; - - /** - * @var PaymentModuleListProviderInterface - */ - private $paymentModuleProvider; - - /** - * @param Connection $connection - * @param string $databasePrefix - * @param int $shopId - * @param PaymentModuleListProviderInterface $paymentModuleProvider - */ - public function __construct( - Connection $connection, - $databasePrefix, - $shopId, - PaymentModuleListProviderInterface $paymentModuleProvider - ) { - $this->connection = $connection; - $this->databasePrefix = $databasePrefix; - $this->shopId = $shopId; - $this->paymentModuleProvider = $paymentModuleProvider; - } - - /** - * {@inheritdoc} - */ - public function configureCurrencyRestrictions(array $currencyRestrictions) - { - $this->configureRestrictions('currency', $currencyRestrictions); - } - - /** - * {@inheritdoc} - */ - public function configureCountryRestrictions(array $countryRestrictions) - { - $this->configureRestrictions('country', $countryRestrictions); - } - - /** - * {@inheritdoc} - */ - public function configureGroupRestrictions(array $groupRestrictions) - { - $this->configureRestrictions('group', $groupRestrictions); - } - - /** - * {@inheritdoc} - */ - public function configureCarrierRestrictions(array $carrierRestrictions) - { - $this->configureRestrictions('carrier', $carrierRestrictions); - } - - /** - * @param string $restrictionType - * @param array $restrictions - */ - private function configureRestrictions($restrictionType, array $restrictions) - { - list($moduleIds, $newConfiguration) = $this->parseRestrictionData($restrictions); - - $this->clearCurrentConfiguration($restrictionType, $moduleIds); - $this->insertNewConfiguration($restrictionType, $newConfiguration); - } - - /** - * Clear current configuration for given restriction type. - * - * @param string $restrictionType - * @param int[] $moduleIds - * - * @return int - */ - private function clearCurrentConfiguration($restrictionType, array $moduleIds) - { - $clearSql = ' - DELETE FROM ' . $this->getTableNameForRestriction($restrictionType) . ' - WHERE id_shop = ' . (int) $this->shopId . ' AND id_module IN (' . implode(',', array_map('intval', $moduleIds)) . ') - '; - - return $this->connection->executeUpdate($clearSql); - } - - /** - * Insert new configuration for given restriction type. - * - * @param string $restrictionType - * @param array $newConfiguration - */ - private function insertNewConfiguration($restrictionType, $newConfiguration) - { - if (!empty($newConfiguration)) { - $fieldName = 'carrier' === $restrictionType ? 'reference' : $restrictionType; - - $this->connection->executeUpdate(' - INSERT INTO `' . $this->getTableNameForRestriction($restrictionType) . '` - (`id_module`, `id_shop`, `id_' . $fieldName . '`) - VALUES ' . implode(',', $newConfiguration)); - } - } - - /** - * Get table name for module restrictions. - * - * @param string $restrictionType - * - * @return string - */ - private function getTableNameForRestriction($restrictionType) - { - return $this->databasePrefix . 'module_' . $restrictionType; - } - - /** - * Parse data from restrictions. - * - * @param array $restrictions - * - * @return array - */ - private function parseRestrictionData(array $restrictions) - { - $moduleIds = []; - $insertValues = []; - - $paymentModules = $this->paymentModuleProvider->getPaymentModuleList(); - - foreach ($restrictions as $moduleName => $restriction) { - if (isset($paymentModules[$moduleName])) { - $moduleId = $paymentModules[$moduleName]->database->get('id'); - - $moduleIds[] = $moduleId; - - if (!is_array($restriction)) { - $restriction = [$restriction]; - } - - foreach ($restriction as $restrictionValues) { - $insertValues[] = '(' . (int) $moduleId . ', ' . (int) $this->shopId . ', ' . (int) $restrictionValues . ')'; - } - } - } - - return [ - $moduleIds, - $insertValues, - ]; - } -} diff --git a/src/Core/Module/Configuration/PaymentRestrictionsConfiguratorInterface.php b/src/Core/Module/Configuration/PaymentRestrictionsConfiguratorInterface.php deleted file mode 100644 index ffe24d5f..00000000 --- a/src/Core/Module/Configuration/PaymentRestrictionsConfiguratorInterface.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\Configuration; - -/** - * Interface PaymentRestrictionsConfigurator defines contract for payment module restrications configurator. - */ -interface PaymentRestrictionsConfiguratorInterface -{ - /** - * Configure payment module restrictions for currencies. - * - * @param array $currencyRestrictions - * - * @return bool - */ - public function configureCurrencyRestrictions(array $currencyRestrictions); - - /** - * Configure payment module restrictions for countries. - * - * @param array $countryRestrictions - * - * @return bool - */ - public function configureCountryRestrictions(array $countryRestrictions); - - /** - * Configure payment module restrictions for customer groups. - * - * @param array $groupRestrictions - * - * @return bool - */ - public function configureGroupRestrictions(array $groupRestrictions); - - /** - * Configure payment module restrictions for carriers. - * - * @param array $groupRestrictions - * - * @return bool - */ - public function configureCarrierRestrictions(array $groupRestrictions); -} diff --git a/src/Core/Module/DataProvider/PaymentModuleListProviderInterface.php b/src/Core/Module/DataProvider/PaymentModuleListProviderInterface.php deleted file mode 100644 index 6287383f..00000000 --- a/src/Core/Module/DataProvider/PaymentModuleListProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\DataProvider; - -/** - * Interface PaymentModuleProviderInterface defines contract for payment module list provider. - */ -interface PaymentModuleListProviderInterface -{ - /** - * Get payment module data. - * - * @return array - */ - public function getPaymentModuleList(); -} diff --git a/src/Core/Module/DataProvider/TabModuleListProviderInterface.php b/src/Core/Module/DataProvider/TabModuleListProviderInterface.php deleted file mode 100644 index d2b74585..00000000 --- a/src/Core/Module/DataProvider/TabModuleListProviderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\DataProvider; - -/** - * Interface TabModuleListProviderInterface defines contract for tab module provider. - */ -interface TabModuleListProviderInterface -{ - /** - * Get tab modules. - * - * @param string $tabClassName - * - * @return array - */ - public function getTabModules($tabClassName); -} diff --git a/src/Core/Module/Exception/ModuleErrorException.php b/src/Core/Module/Exception/ModuleErrorException.php deleted file mode 100644 index 37b7c1b7..00000000 --- a/src/Core/Module/Exception/ModuleErrorException.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Default module error implementation - * The message of this exception will be displayed to the end-user - * - * You can use it in a module hooked on a Symfony page - */ -class ModuleErrorException extends CoreException implements ModuleErrorInterface -{ -} diff --git a/src/Core/Module/Exception/ModuleErrorInterface.php b/src/Core/Module/Exception/ModuleErrorInterface.php deleted file mode 100644 index 0549d2b6..00000000 --- a/src/Core/Module/Exception/ModuleErrorInterface.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module\Exception; - -/** - * If an exception that implements this ModuleErrorInterface - * is thrown, its message will be displayed to the end-user - */ -interface ModuleErrorInterface -{ -} diff --git a/src/Core/Module/HookConfigurator.php b/src/Core/Module/HookConfigurator.php deleted file mode 100644 index 2bc5a84e..00000000 --- a/src/Core/Module/HookConfigurator.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module; - -class HookConfigurator -{ - private $hookRepository; - - public function __construct(HookRepository $hookRepository) - { - $this->hookRepository = $hookRepository; - } - - /** - * $hooks is a hook configuration description - * as found in theme.yml, - * it has a format like: - * [ - * "someHookName" => [ - * null, - * "blockstuff", - * "othermodule" - * ], - * "someOtherHookName" => [ - * null, - * "blockmenu" => [ - * "except_pages" => ["category", "product"] - * ] - * ] - * ]. - */ - public function getThemeHooksConfiguration(array $hooks) - { - $hooks = array_filter($hooks, 'is_array'); - $uniqueModuleList = $this->getUniqueModuleToHookList($hooks); - $currentHooks = $this->hookRepository->getDisplayHooksWithModules(); - - foreach ($currentHooks as $hookName => $moduleList) { - foreach ($moduleList as $key => $value) { - if (in_array($value, $uniqueModuleList)) { - unset($currentHooks[$hookName][$key]); - } - } - } - - foreach ($hooks as $hookName => $modules) { - $firstNullValueFound = true; - $existing = isset($currentHooks[$hookName]) ? - $currentHooks[$hookName] : - []; - $currentHooks[$hookName] = []; - foreach ($modules as $key => $module) { - if ($module === null && $firstNullValueFound) { - $firstNullValueFound = false; - foreach ($existing as $m) { - $currentHooks[$hookName][] = $m; - } - } elseif (is_array($module)) { - $currentHooks[$hookName][$key] = $module; - } elseif ($module !== null) { - $currentHooks[$hookName][] = $module; - } - } - } - - return $currentHooks; - } - - public function setHooksConfiguration(array $hooks) - { - $this->hookRepository->persistHooksConfiguration( - $this->getThemeHooksConfiguration($hooks) - ); - - return $this; - } - - public function addHook($name, $title, $description) - { - $this->hookRepository->createHook($name, $title, $description); - - return $this; - } - - private function getUniqueModuleToHookList(array $hooks) - { - $list = []; - foreach ($hooks as $modules) { - $list = array_merge($list, $modules); - } - - return $list; - } -} diff --git a/src/Core/Module/HookRepository.php b/src/Core/Module/HookRepository.php deleted file mode 100644 index 3c23ac6d..00000000 --- a/src/Core/Module/HookRepository.php +++ /dev/null @@ -1,262 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module; - -use Db; -use Exception; -use PrestaShop\PrestaShop\Adapter\Hook\HookInformationProvider; -use Shop; - -class HookRepository -{ - private $hookInfo; - private $shop; - private $db; - private $db_prefix; - - public function __construct( - HookInformationProvider $hookInfo, - Shop $shop, - Db $db - ) { - $this->hookInfo = $hookInfo; - $this->shop = $shop; - $this->db = $db; - $this->db_prefix = $db->getPrefix(); - } - - public function getIdByName($hook_name) - { - $escaped_hook_name = $this->db->escape($hook_name); - - $id_hook = $this->db->getValue( - "SELECT id_hook FROM {$this->db_prefix}hook WHERE name = '$escaped_hook_name'" - ); - - return (int) $id_hook; - } - - public function createHook($hook_name, $title = '', $description = '', $position = 1) - { - $this->db->insert('hook', [ - 'name' => $this->db->escape($hook_name), - 'title' => $this->db->escape($title), - 'description' => $this->db->escape($description), - 'position' => $this->db->escape($position), - ], false, true, Db::REPLACE); - - return $this->getIdByName($hook_name); - } - - private function getIdModule($module_name) - { - $escaped_module_name = $this->db->escape($module_name); - - $id_module = $this->db->getValue( - "SELECT id_module FROM {$this->db_prefix}module WHERE name = '$escaped_module_name'" - ); - - return (int) $id_module; - } - - public function unHookModulesFromHook($hook_name) - { - $id_hook = $this->getIdByName($hook_name); - $id_shop = (int) $this->shop->id; - - $this->db->execute("DELETE FROM {$this->db_prefix}hook_module - WHERE id_hook = $id_hook AND id_shop = $id_shop - "); - - $this->db->execute("DELETE FROM {$this->db_prefix}hook_module_exceptions - WHERE id_hook = $id_hook AND id_shop = $id_shop - "); - - return $this; - } - - /** - * Saves hook settings for a list of hooks. - * The $hooks array should have this format: - * [ - * "hookName" => [ - * "module1", - * "module2", - * "module3" => [ - * "except_pages" => [ - * "page1", - * "page2", - * "page3" - * ] - * ] - * ] - * ] - * Only hooks present as keys in the $hooks array are affected and all changes - * are only done for the shop this Repository belongs to. - */ - public function persistHooksConfiguration(array $hooks) - { - foreach ($hooks as $hook_name => $module_names) { - $id_hook = $this->getIdByName($hook_name); - if (!$id_hook) { - $id_hook = $this->createHook($hook_name); - } - if (!$id_hook) { - throw new Exception(sprintf('Could not create hook `%1$s`.', $hook_name)); - } - - $this->unHookModulesFromHook($hook_name); - - $position = 0; - foreach ($module_names as $key => $module) { - if (is_array($module)) { - $module_name = key($module); - $extra_data = current($module); - } else { - $module_name = $module; - $extra_data = []; - } - - ++$position; - $id_module = $this->getIdModule($module_name); - if (!$id_module) { - continue; - } - - $row = [ - 'id_module' => $id_module, - 'id_shop' => (int) $this->shop->id, - 'id_hook' => $id_hook, - 'position' => $position, - ]; - - $this->db->insert('hook_module', $row); - - if (!empty($extra_data['except_pages'])) { - $this->setModuleHookExceptions( - $id_module, - $id_hook, - $extra_data['except_pages'] - ); - } - } - } - - return $this; - } - - private function setModuleHookExceptions($id_module, $id_hook, array $pages) - { - $id_shop = (int) $this->shop->id; - $id_module = (int) $id_module; - $id_hook = (int) $id_hook; - - $this->db->execute("DELETE FROM {$this->db_prefix}hook_module_exceptions - WHERE id_shop = $id_shop - AND id_module = $id_module - AND id_hook = $id_hook - "); - - foreach ($pages as $page) { - $this->db->insert('hook_module_exceptions', [ - 'id_shop' => $id_shop, - 'id_module' => $id_module, - 'id_hook' => $id_hook, - 'file_name' => $page, - ]); - } - - return $this; - } - - private function getModuleHookExceptions($id_module, $id_hook) - { - $id_shop = (int) $this->shop->id; - $id_module = (int) $id_module; - $id_hook = (int) $id_hook; - - $rows = $this->db->executeS("SELECT file_name - FROM {$this->db_prefix}hook_module_exceptions - WHERE id_shop = $id_shop - AND id_module = $id_module - AND id_hook = $id_hook - ORDER BY file_name ASC - "); - - return array_map(function ($row) { - return $row['file_name']; - }, $rows); - } - - public function getHooksWithModules() - { - $id_shop = (int) $this->shop->id; - - $sql = "SELECT h.name as hook_name, h.id_hook, m.name as module_name, m.id_module - FROM {$this->db_prefix}hook_module hm - INNER JOIN {$this->db_prefix}hook h - ON h.id_hook = hm.id_hook - INNER JOIN {$this->db_prefix}module m - ON m.id_module = hm.id_module - WHERE hm.id_shop = $id_shop - ORDER BY h.name ASC, hm.position ASC - "; - - $rows = $this->db->executeS($sql); - - $hooks = []; - - foreach ($rows as $row) { - $exceptions = $this->getModuleHookExceptions( - $row['id_module'], - $row['id_hook'] - ); - - if (empty($exceptions)) { - $hooks[$row['hook_name']][] = $row['module_name']; - } else { - $hooks[$row['hook_name']][$row['module_name']] = [ - 'except_pages' => $exceptions, - ]; - } - } - - return $hooks; - } - - public function getDisplayHooksWithModules() - { - $hooks = []; - foreach ($this->getHooksWithModules() as $hook_name => $modules) { - if ($this->hookInfo->isDisplayHookName($hook_name)) { - $hooks[$hook_name] = $modules; - } - } - - return $hooks; - } -} diff --git a/src/Core/Module/ModuleInterface.php b/src/Core/Module/ModuleInterface.php deleted file mode 100644 index eb654dba..00000000 --- a/src/Core/Module/ModuleInterface.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module; - -/** - * Define what should be a module. - * Note:We don't typeHint on old Module class to not create hard dependency with Legacy. - */ -interface ModuleInterface -{ -} diff --git a/src/Core/Module/WidgetInterface.php b/src/Core/Module/WidgetInterface.php deleted file mode 100644 index 7e65768b..00000000 --- a/src/Core/Module/WidgetInterface.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Module; - -interface WidgetInterface -{ - public function renderWidget($hookName, array $configuration); - - public function getWidgetVariables($hookName, array $configuration); -} diff --git a/src/Core/Multistore/MultistoreConfig.php b/src/Core/Multistore/MultistoreConfig.php deleted file mode 100644 index 22c99b84..00000000 --- a/src/Core/Multistore/MultistoreConfig.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Multistore; - -/** - * Class MultistoreConfig. - */ -class MultistoreConfig -{ - /** - * Name of configuration for Multistore feature status in ps_configuration table. - */ - const FEATURE_STATUS = 'PS_MULTISHOP_FEATURE_ACTIVE'; -} diff --git a/src/Core/Multistore/MultistoreContextCheckerInterface.php b/src/Core/Multistore/MultistoreContextCheckerInterface.php deleted file mode 100644 index f1e70a85..00000000 --- a/src/Core/Multistore/MultistoreContextCheckerInterface.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Multistore; - -/** - * Interface MultistoreContextCheckerInterface. - */ -interface MultistoreContextCheckerInterface -{ - /** - * Check if current shop is in single store context. - * - * @return bool - */ - public function isAllShopContext(); - - /** - * Check if current shop is in "Group" shop context. - * - * @return bool - */ - public function isGroupShopContext(); - - /** - * Check if current shop is in "Single" shop context. - * - * @return bool - */ - public function isSingleShopContext(); -} diff --git a/src/Core/Order/InvoiceInterface.php b/src/Core/Order/InvoiceInterface.php deleted file mode 100644 index 364fd780..00000000 --- a/src/Core/Order/InvoiceInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Order; - -interface InvoiceInterface -{ - /** - * Return collection of Invoice. - * - * @param string $dateFrom Date From - * @param string $dateTo Date To - * - * @return array[InvoiceLegacy] - */ - public static function getByDeliveryDateInterval($dateFrom, $dateTo); -} diff --git a/src/Core/Order/OrderInvoiceDataProviderInterface.php b/src/Core/Order/OrderInvoiceDataProviderInterface.php deleted file mode 100644 index bcef91e3..00000000 --- a/src/Core/Order/OrderInvoiceDataProviderInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Order; - -use DateTimeInterface; - -/** - * Interface OrderInvoiceDataProviderInterface defines OrderInvoice data provider. - */ -interface OrderInvoiceDataProviderInterface -{ - /** - * Returns all the order invoices that match the date interval. - * - * @param DateTimeInterface $dateFrom - * @param DateTimeInterface $dateTo - * - * @return array collection of OrderInvoice objects - */ - public function getByDateInterval(DateTimeInterface $dateFrom, DateTimeInterface $dateTo); - - /** - * Returns all the order invoices by given status. - * - * @param int $orderStateId - * - * @return array collection of OrderInvoice objects - */ - public function getByStatus($orderStateId); - - /** - * Returns the next available invoice number. - * - * @return int - */ - public function getNextInvoiceNumber(); -} diff --git a/src/Core/Order/OrderSiblingProviderInterface.php b/src/Core/Order/OrderSiblingProviderInterface.php deleted file mode 100644 index cd95b817..00000000 --- a/src/Core/Order/OrderSiblingProviderInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Order; - -interface OrderSiblingProviderInterface -{ - /** - * @param int $orderId - * - * @return int returns previous order id or 0 if it does not exist - */ - public function getNextOrderId(int $orderId): int; - - /** - * @param int $orderId - * - * @return int returns next order id or 0 if it does not exist - */ - public function getPreviousOrderId(int $orderId): int; -} diff --git a/src/Core/Order/OrderStateDataProviderInterface.php b/src/Core/Order/OrderStateDataProviderInterface.php deleted file mode 100644 index bd77f29f..00000000 --- a/src/Core/Order/OrderStateDataProviderInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Order; - -/** - * Interface OrderStateDataProviderInterface defines OrderState data provider. - */ -interface OrderStateDataProviderInterface -{ - /** - * Get order states in given language. - * - * @param int $languageId - * - * @return array - */ - public function getOrderStates($languageId); -} diff --git a/src/Core/PDF/Exception/MissingDataException.php b/src/Core/PDF/Exception/MissingDataException.php deleted file mode 100644 index a2eaba4a..00000000 --- a/src/Core/PDF/Exception/MissingDataException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\PDF\Exception; - -/** - * Thrown when required data for pdf generating is missing - */ -class MissingDataException extends PdfException -{ -} diff --git a/src/Core/PDF/Exception/PdfException.php b/src/Core/PDF/Exception/PdfException.php deleted file mode 100644 index 480e36fa..00000000 --- a/src/Core/PDF/Exception/PdfException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\PDF\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Base exception for PDF generation related exceptions - */ -class PdfException extends CoreException -{ -} diff --git a/src/Core/PDF/PDFGeneratorInterface.php b/src/Core/PDF/PDFGeneratorInterface.php deleted file mode 100644 index 6af1fad0..00000000 --- a/src/Core/PDF/PDFGeneratorInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\PDF; - -/** - * Interface PDFGeneratorInterface defines a PDF generator. - */ -interface PDFGeneratorInterface -{ - /** - * Generates PDF out of given object and template using legacy generator. - * - * @param array $objectCollection collection of objects - */ - public function generatePDF(array $objectCollection); -} diff --git a/src/Core/PDF/PDFTemplateTypeProviderInterface.php b/src/Core/PDF/PDFTemplateTypeProviderInterface.php deleted file mode 100644 index e3adb796..00000000 --- a/src/Core/PDF/PDFTemplateTypeProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\PDF; - -/** - * Interface PDFDataProviderInterface describes a PDF template type provider. - */ -interface PDFTemplateTypeProviderInterface -{ - /** - * Gets PDF template type. - * - * @return string - */ - public function getPDFTemplateType(); -} diff --git a/src/Core/Payment/PaymentModulePreferencesConfiguration.php b/src/Core/Payment/PaymentModulePreferencesConfiguration.php deleted file mode 100644 index 44616f36..00000000 --- a/src/Core/Payment/PaymentModulePreferencesConfiguration.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Payment; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Module\Configuration\PaymentRestrictionsConfiguratorInterface; -use PrestaShop\PrestaShop\Core\Module\DataProvider\PaymentModuleListProviderInterface; - -/** - * Class PaymentModulePreferencesConfiguration is responsible for configuring payment module restrictions. - */ -final class PaymentModulePreferencesConfiguration implements DataConfigurationInterface -{ - /** - * @var PaymentModuleListProviderInterface - */ - private $paymentModuleProvider; - - /** - * @var PaymentRestrictionsConfiguratorInterface - */ - private $paymentRestrictionsConfigurator; - - /** - * @param PaymentModuleListProviderInterface $paymentModuleProvider - * @param PaymentRestrictionsConfiguratorInterface $paymentRestrictionsConfigurator - */ - public function __construct( - PaymentModuleListProviderInterface $paymentModuleProvider, - PaymentRestrictionsConfiguratorInterface $paymentRestrictionsConfigurator - ) { - $this->paymentModuleProvider = $paymentModuleProvider; - $this->paymentRestrictionsConfigurator = $paymentRestrictionsConfigurator; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - $config = []; - $paymentModules = $this->paymentModuleProvider->getPaymentModuleList(); - - foreach ($paymentModules as $paymentModule) { - $config['currency_restrictions'][$paymentModule->get('name')] = $paymentModule->get('currencies'); - $config['country_restrictions'][$paymentModule->get('name')] = $paymentModule->get('countries'); - $config['group_restrictions'][$paymentModule->get('name')] = $paymentModule->get('groups'); - $config['carrier_restrictions'][$paymentModule->get('name')] = $paymentModule->get('carriers'); - } - - return $config; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $config) - { - $errors = []; - - if ($this->validateConfiguration($config)) { - $this->paymentRestrictionsConfigurator->configureCurrencyRestrictions($config['currency_restrictions']); - $this->paymentRestrictionsConfigurator->configureCountryRestrictions($config['country_restrictions']); - $this->paymentRestrictionsConfigurator->configureGroupRestrictions($config['group_restrictions']); - $this->paymentRestrictionsConfigurator->configureCarrierRestrictions($config['carrier_restrictions']); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $config) - { - return isset( - $config['currency_restrictions'], - $config['country_restrictions'], - $config['group_restrictions'], - $config['carrier_restrictions'] - ); - } -} diff --git a/src/Core/Payment/PaymentOption.php b/src/Core/Payment/PaymentOption.php deleted file mode 100644 index 298065ff..00000000 --- a/src/Core/Payment/PaymentOption.php +++ /dev/null @@ -1,374 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Payment; - -use PrestaShopBundle\Service\Hook\HookContentClassInterface; - -/** - * We define 4 types of payment options:. - * - * - the "offline" kind: simple URL to call + information to display (e.g. bankwire, cheque) - * - the "external" kind: simple URL to call, but payment processed on PSP's website (e.g. simple paypal) - * - the "embedded" kind: you write your credit card info in a form that is on your site and not inside an iframe (e.g. stripe) - * - the "iframe" kind: payment form is displayed on your website but inside an iframe (e.g. atos) - */ -class PaymentOption implements HookContentClassInterface -{ - /** - * This text will be displayed - * in the payment option selection widget. - * - * @var string - */ - private $callToActionText; - - /** - * Additional information to display to the customer. - * This is free HTML, and may be used by modules such as - * bankwire to display to which account the bank transfer should be made. - * - * @var string - */ - private $additionalInformation; - - /** - * The URL to a picture to display in the - * payment option selection widget. - * - * @var string - */ - private $logo; - - /** - * The URL to which the request to process the - * payment must be made. - * - * @var string - */ - private $action; - - /** - * An associative array of additional parameters to use when sending - * the request to $action, - * e.g. if $action is "http://payment-provider.example.com/process", - * $method is "GET" - * and $inputs is ['customerName' => 'bob'] - * then the request will be made to: - * "http://payment-provider.example.com/process?customerName=bob". - * - * @var array - */ - private $inputs; - - /** - * Custom HTML to display e.g. a form where - * you write your credit card number. - * The HTML MUST NOT contain a submit button, as - * the Core will submit the form. - * - * @var string - */ - private $form; - - /** - * Custom HTML containing an iframe with the - * payment confirmation widget for modules like ATOS. - * - * @var string - */ - private $iframe; - - /** - * For internal reasons, the name of the module - * that provided this option. - * Is this still necessary? - * - * @var string - */ - private $moduleName; - - /** - * Was the module form generated by binaries ? - * - * @var bool - */ - private $binary; - - /** - * Return Call to Action Text. - * - * @return string - */ - public function getCallToActionText() - { - return $this->callToActionText; - } - - /** - * Set Call To Action Text. - * - * @param $callToActionText - * - * @return $this - */ - public function setCallToActionText($callToActionText) - { - $this->callToActionText = $callToActionText; - - return $this; - } - - /** - * Return Additional Information. - * - * @return string - */ - public function getAdditionalInformation() - { - return $this->additionalInformation; - } - - /** - * Set Additional Information. - * - * @param $additionalInformation - * - * @return $this - */ - public function setAdditionalInformation($additionalInformation) - { - $this->additionalInformation = $additionalInformation; - - return $this; - } - - /** - * Return logo path. - * - * @return string - */ - public function getLogo() - { - return $this->logo; - } - - /** - * Set logo path. - * - * @param $logo - * - * @return $this - */ - public function setLogo($logo) - { - $this->logo = $logo; - - return $this; - } - - /** - * Return action to perform (POST/GET). - * - * @return string - */ - public function getAction() - { - return $this->action; - } - - /** - * Set action to be performed by this option. - * - * @param $action - * - * @return $this - */ - public function setAction($action) - { - $this->action = $action; - - return $this; - } - - /** - * Return inputs contained in this payment option. - * - * @return mixed - */ - public function getInputs() - { - return $this->inputs; - } - - /** - * Set inputs for this payment option. - * - * @param $inputs - * - * @return $this - */ - public function setInputs($inputs) - { - $this->inputs = $inputs; - - return $this; - } - - /** - * Get payment option form. - * - * @return mixed - */ - public function getForm() - { - return $this->form; - } - - /** - * Set payment option form. - * - * @param $form - * - * @return $this - */ - public function setForm($form) - { - $this->form = $form; - - return $this; - } - - /** - * Get related module name to this payment option. - * - * @return string - */ - public function getModuleName() - { - return $this->moduleName; - } - - /** - * Set related module name to this payment option. - * - * @param $moduleName - * - * @return $this - */ - public function setModuleName($moduleName) - { - $this->moduleName = $moduleName; - - return $this; - } - - /** - * Was the module form generated by - * binaries ? - * - * @return bool - */ - public function isBinary() - { - return $this->binary; - } - - /** - * Set if the form was generated by binaries. - * - * @param $binary - * - * @return $this - */ - public function setBinary($binary) - { - $this->binary = $binary; - - return $this; - } - - public function toArray() - { - return [ - 'module_name' => $this->moduleName, - 'binary' => $this->binary, - 'action' => $this->action, - 'form' => $this->form, - 'inputs' => $this->inputs, - 'logo' => $this->logo, - 'additionalInformation' => $this->additionalInformation, - 'call_to_action_text' => $this->callToActionText, - ]; - } - - /** - * Legacy options were specified this way: - * - either an array with a top level property 'cta_text' and then the other properties - * - or a numerically indexed array or arrays as described above. - * - * Since this was a mess, this method is provided to convert them. - * It takes as input a legacy option (in either form) and always - * returns an array of instances of PrestaShop\PrestaShop\Core\Payment\PaymentOption - */ - public static function convertLegacyOption(array $legacyOption) - { - if (!$legacyOption) { - return; - } - - if (array_key_exists('cta_text', $legacyOption)) { - $legacyOption = [$legacyOption]; - } - - $newOptions = []; - - $defaults = [ - 'additionalInformation' => null, - 'action' => null, - 'form' => null, - 'method' => null, - 'inputs' => [], - 'logo' => null, - ]; - - foreach ($legacyOption as $option) { - $option = array_merge($defaults, $option); - - $newOption = new self(); - $newOption->setCallToActionText($option['cta_text']) - ->setAdditionalInformation($option['additionalInformation']) - ->setAction($option['action']) - ->setForm($option['form']) - ->setInputs($option['inputs']) - ->setLogo($option['logo']); - - $newOptions[] = $newOption; - } - - return $newOptions; - } -} diff --git a/src/Core/Payment/PaymentOptionFormDecorator.php b/src/Core/Payment/PaymentOptionFormDecorator.php deleted file mode 100644 index f429f06d..00000000 --- a/src/Core/Payment/PaymentOptionFormDecorator.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Payment; - -use DOMDocument; - -class PaymentOptionFormDecorator -{ - public function addHiddenSubmitButton($formHTML, $optionId) - { - $doc = new DOMDocument(); - $doc->encoding = 'UTF-8'; - - $doc->loadHTML('' . $formHTML); - - $forms = $doc->getElementsByTagName('form'); - if ($forms->length !== 1) { - return false; - } - - $hiddenSubmitButton = $doc->createElement('button'); - - $styleAttr = $doc->createAttribute('style'); - $styleAttr->value = 'display:none'; - - $idAttr = $doc->createAttribute('id'); - $idAttr->value = 'pay-with-' . $optionId; - - $typeAttr = $doc->createAttribute('type'); - $typeAttr->value = 'submit'; - - $hiddenSubmitButton->appendChild($styleAttr); - $hiddenSubmitButton->appendChild($idAttr); - $hiddenSubmitButton->appendChild($typeAttr); - - $forms->item(0)->appendChild($hiddenSubmitButton); - - $body = $doc->getElementsByTagName('body')->item(0); - $html = ''; - - foreach ($body->childNodes as $node) { - $html .= $doc->saveHTML($node); - } - - return $html; - } -} diff --git a/src/Core/Product/ProductAdminDrawer.php b/src/Core/Product/ProductAdminDrawer.php deleted file mode 100644 index afb029ec..00000000 --- a/src/Core/Product/ProductAdminDrawer.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -use PrestaShopBundle\Service\Hook\HookContentClassInterface; - -class ProductAdminDrawer implements HookContentClassInterface -{ - /** - * Material icon reference to display above the title. - * - * @var string - */ - protected $icon; - - /** - * ID suffix to add in the generated DOM element. - * - * @var string - */ - protected $id; - - /** - * Destination of the link. - * - * @var string - */ - protected $link; - - /** - * Title of the button. Should be short. - * - * @var string - */ - protected $title; - - public function __construct(array $data = []) - { - if (!empty($data['icon'])) { - $this->setIcon($data['icon']); - } - if (!empty($data['id'])) { - $this->setId($data['id']); - } - if (!empty($data['link'])) { - $this->setLink($data['link']); - } - if (!empty($data['title'])) { - $this->setTitle($data['title']); - } - } - - public function getIcon() - { - return $this->icon; - } - - public function getId() - { - return $this->id; - } - - public function getLink() - { - return $this->link; - } - - public function getTitle() - { - return $this->title; - } - - public function setIcon($icon) - { - $this->icon = $icon; - - return $this; - } - - public function setId($id) - { - $this->id = $id; - - return $this; - } - - public function setLink($link) - { - $this->link = $link; - - return $this; - } - - public function setTitle($title) - { - $this->title = $title; - - return $this; - } - - public function toArray() - { - return [ - 'icon' => $this->icon, - 'id' => $this->id, - 'link' => $this->link, - 'title' => $this->title, - ]; - } -} diff --git a/src/Core/Product/ProductCsvExporter.php b/src/Core/Product/ProductCsvExporter.php deleted file mode 100644 index 9720a6cf..00000000 --- a/src/Core/Product/ProductCsvExporter.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Service\DataProvider\Admin\ProductInterface as ProductDataProviderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Used to export list of Products in CSV in the Product list page. - * For internal use only. - */ -final class ProductCsvExporter implements ProductExporterInterface -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ProductDataProviderInterface - */ - private $productProvider; - - public function __construct(TranslatorInterface $translator, ProductDataProviderInterface $productProvider) - { - $this->translator = $translator; - $this->productProvider = $productProvider; - } - - /** - * In this specific case, we don't need to pass a products list. - * - * @param array $products - * - * @return CsvResponse - * - * @throws \InvalidArgumentException - * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException - */ - public function export(array $products = []) - { - $productProvider = $this->productProvider; - $persistedFilterParameters = $productProvider->getPersistedFilterParameters(); - $orderBy = $persistedFilterParameters['last_orderBy']; - $sortOrder = $persistedFilterParameters['last_sortOrder']; - - // prepare callback to fetch data from DB - $dataCallback = function ($offset, $limit) use ($productProvider, $orderBy, $sortOrder) { - return $productProvider->getCatalogProductList($offset, $limit, $orderBy, $sortOrder, [], true, false); - }; - - $headersData = [ - 'id_product' => 'Product ID', - 'image_link' => $this->trans('Image', 'Admin.Global'), - 'name' => $this->trans('Name', 'Admin.Global'), - 'reference' => $this->trans('Reference', 'Admin.Global'), - 'name_category' => $this->trans('Category', 'Admin.Global'), - 'price' => $this->trans('Price (tax excl.)', 'Admin.Catalog.Feature'), - 'price_final' => $this->trans('Price (tax incl.)', 'Admin.Catalog.Feature'), - 'sav_quantity' => $this->trans('Quantity', 'Admin.Global'), - 'badge_danger' => $this->trans('Status', 'Admin.Global'), - 'position' => $this->trans('Position', 'Admin.Global'), - ]; - - return (new CsvResponse()) - ->setData($dataCallback) - ->setHeadersData($headersData) - ->setModeType(CsvResponse::MODE_OFFSET) - ->setLimit(5000) - ->setFileName('product_' . date('Y-m-d_His') . '.csv'); - } - - /** - * Translator helper. - * - * @param $key - * @param $domain - * - * @return string - * - * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException - */ - private function trans($key, $domain) - { - return $this->translator->trans($key, [], $domain); - } -} diff --git a/src/Core/Product/ProductExporterInterface.php b/src/Core/Product/ProductExporterInterface.php deleted file mode 100644 index 5dc39228..00000000 --- a/src/Core/Product/ProductExporterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -use Symfony\Component\HttpFoundation\Response; - -/** - * Allow the export of a list of products. - */ -interface ProductExporterInterface -{ - /** - * @param array $products - * - * @return Response - */ - public function export(array $products); -} diff --git a/src/Core/Product/ProductExtraContent.php b/src/Core/Product/ProductExtraContent.php deleted file mode 100644 index b9935376..00000000 --- a/src/Core/Product/ProductExtraContent.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -use PrestaShopBundle\Service\Hook\HookContentClassInterface; - -class ProductExtraContent implements HookContentClassInterface -{ - /** - * Title of the content. This can be used in the template - * e.g as a tab name or an anchor. - * - * @var string - */ - private $title; - - /** - * Content in HTML to display. - * This is the main attribute of this class. - * - * @var string - */ - private $content; - - /** - * For some reason, you may need to have a class on the div generated, - * or to be able to set an anchor. - * - * @var array - */ - private $attr = [ - 'id' => '', - 'class' => '', - ]; - - public function getTitle() - { - return $this->title; - } - - public function getContent() - { - return $this->content; - } - - public function getAttr() - { - return $this->attr; - } - - public function setTitle($title) - { - $this->title = $title; - - return $this; - } - - public function setContent($content) - { - $this->content = $content; - - return $this; - } - - public function addAttr($attr) - { - $this->attr = array_merge($this->attr, $attr); - - return $this; - } - - public function setAttr($attr) - { - // We declare default values for if and class which - // could be mandatory in the template - $this->attr = array_merge([ - 'id' => '', - 'class' => '', - ], $attr); - - return $this; - } - - public function toArray() - { - return [ - 'title' => $this->title, - 'content' => $this->content, - 'attr' => $this->attr, - ]; - } -} diff --git a/src/Core/Product/ProductExtraContentFinder.php b/src/Core/Product/ProductExtraContentFinder.php deleted file mode 100644 index f42d592d..00000000 --- a/src/Core/Product/ProductExtraContentFinder.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -use PrestaShopBundle\Service\Hook\HookFinder; - -/** - * This class gets the extra content to display on the product page - * from the modules hooked on displayProductExtraContent. - */ -class ProductExtraContentFinder extends HookFinder -{ - protected $hookName = 'displayProductExtraContent'; - protected $expectedInstanceClasses = ['PrestaShop\PrestaShop\Core\Product\ProductExtraContent']; - - /** - * Execute hook to get all addionnal product content, and check if valid - * (not empty and only instances of class ProductExtraContent). - * - * @return array - * - * @throws \Exception - */ - public function find() - { - // Check first that we have a product to send as params - if (!array_key_exists('product', $this->params) || !$this->params['product'] instanceof \Product) { - throw new \Exception('Required product param not found.'); - } - - return parent::find(); - } -} diff --git a/src/Core/Product/ProductInterface.php b/src/Core/Product/ProductInterface.php deleted file mode 100644 index d83a0b8c..00000000 --- a/src/Core/Product/ProductInterface.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -interface ProductInterface -{ - const REDIRECT_TYPE_CATEGORY_MOVED_PERMANENTLY = '301-category'; - const REDIRECT_TYPE_CATEGORY_FOUND = '302-category'; - const REDIRECT_TYPE_PRODUCT_MOVED_PERMANENTLY = '301-product'; - const REDIRECT_TYPE_PRODUCT_FOUND = '302-product'; - const REDIRECT_TYPE_NOT_FOUND = '404'; -} diff --git a/src/Core/Product/ProductListingPresenter.php b/src/Core/Product/ProductListingPresenter.php deleted file mode 100644 index a9b6a158..00000000 --- a/src/Core/Product/ProductListingPresenter.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingPresenter - * - * Class ProductListingPresenter - */ -class ProductListingPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductListingPresenter -{ -} diff --git a/src/Core/Product/ProductPresentationSettings.php b/src/Core/Product/ProductPresentationSettings.php deleted file mode 100644 index 99d3eb3b..00000000 --- a/src/Core/Product/ProductPresentationSettings.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -class ProductPresentationSettings -{ - public $catalog_mode; - public $catalog_mode_with_prices; - public $restricted_country_mode; - public $include_taxes; - public $allow_add_variant_to_cart_from_listing; - public $stock_management_enabled; - public $showPrices; - public $lastRemainingItems; - - public function shouldShowPrice() - { - return $this->showPrices && (!$this->catalog_mode || $this->catalog_mode_with_prices); - } -} diff --git a/src/Core/Product/ProductPresenter.php b/src/Core/Product/ProductPresenter.php deleted file mode 100644 index c39643ed..00000000 --- a/src/Core/Product/ProductPresenter.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product; - -/** - * @deprecated since 1.7.4.0 - * @see \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductPresenter - * - * Class ProductPresenter - */ -class ProductPresenter extends \PrestaShop\PrestaShop\Adapter\Presenter\Product\ProductPresenter -{ -} diff --git a/src/Core/Product/Search/Exception/InvalidSortOrderDirectionException.php b/src/Core/Product/Search/Exception/InvalidSortOrderDirectionException.php deleted file mode 100644 index 24173dfa..00000000 --- a/src/Core/Product/Search/Exception/InvalidSortOrderDirectionException.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Thrown when sort order direction is not valid - */ -class InvalidSortOrderDirectionException extends CoreException -{ - /** - * @param string $direction the invalid direction - */ - public function __construct($direction) - { - $message = sprintf( - 'Invalid SortOrder direction `%s`. Expecting one of: `ASC`, `DESC`, or `RANDOM`.', - $direction - ); - - parent::__construct($message, 0, null); - } -} diff --git a/src/Core/Product/Search/Facet.php b/src/Core/Product/Search/Facet.php deleted file mode 100644 index 94d7c533..00000000 --- a/src/Core/Product/Search/Facet.php +++ /dev/null @@ -1,233 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * We call a facet a set of filters combined with logical operators. - */ -class Facet -{ - /** - * @var string the facet label - */ - private $label = ''; - - /** - * @var string the facet type - */ - private $type = ''; - - /** - * @var bool if true, the facet is displayed - */ - private $displayed = true; - - /** - * @var array the facet properties - */ - private $properties = []; - - /** - * @var array the facet filters - */ - private $filters = []; - - /** - * @var bool if true, allows the multiple selection - */ - private $multipleSelectionAllowed = true; - - /** - * @var string the widget type - */ - private $widgetType = 'radio'; - - /** - * @return array an array representation of the facet - */ - public function toArray() - { - return [ - 'label' => $this->label, - 'displayed' => $this->displayed, - 'type' => $this->type, - 'properties' => $this->properties, - 'filters' => array_map(function (Filter $filter) { - return $filter->toArray(); - }, $this->filters), - 'multipleSelectionAllowed' => $this->multipleSelectionAllowed, - 'widgetType' => $this->widgetType, - ]; - } - - /** - * @param string $label the facet label - * - * @return $this - */ - public function setLabel($label) - { - $this->label = $label; - - return $this; - } - - /** - * @return string the facet label - */ - public function getLabel() - { - return $this->label; - } - - /** - * @param string $type the facet type - * - * @return $this - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * @return string the facet type - */ - public function getType() - { - return $this->type; - } - - /** - * @param string $name the facet property name - * @param mixed $value the facet property value - * - * @return $this - */ - public function setProperty($name, $value) - { - $this->properties[$name] = $value; - - return $this; - } - - /** - * @param string $name the facet property name - * - * @return mixed|null - */ - public function getProperty($name) - { - if (!array_key_exists($name, $this->properties)) { - return null; - } - - return $this->properties[$name]; - } - - /** - * @param Filter $filter the facet filter - * - * @return $this - */ - public function addFilter(Filter $filter) - { - $this->filters[] = $filter; - - return $this; - } - - /** - * @return array the list of facet filters - */ - public function getFilters() - { - return $this->filters; - } - - /** - * @param bool $isAllowed allows/disallows the multiple selection - * - * @return $this - */ - public function setMultipleSelectionAllowed($isAllowed = true) - { - $this->multipleSelectionAllowed = $isAllowed; - - return $this; - } - - /** - * @return bool returns true if multiple selection is allowed - */ - public function isMultipleSelectionAllowed() - { - return $this->multipleSelectionAllowed; - } - - /** - * @param bool $displayed sets the display of the facet - * - * @return $this - */ - public function setDisplayed($displayed = true) - { - $this->displayed = $displayed; - - return $this; - } - - /** - * @return bool returns true if the facet is displayed - */ - public function isDisplayed() - { - return $this->displayed; - } - - /** - * @param string $widgetType sets the widget type of the facet - * - * @return $this - */ - public function setWidgetType($widgetType) - { - $this->widgetType = $widgetType; - - return $this; - } - - /** - * @return string returns the facet widget type - */ - public function getWidgetType() - { - return $this->widgetType; - } -} diff --git a/src/Core/Product/Search/FacetCollection.php b/src/Core/Product/Search/FacetCollection.php deleted file mode 100644 index 56fe02f7..00000000 --- a/src/Core/Product/Search/FacetCollection.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * Stores a list of facets. - */ -class FacetCollection -{ - /** - * @var array the list of facets - */ - private $facets = []; - - /** - * @param Facet $facet the facet to add - * - * @return $this - */ - public function addFacet(Facet $facet) - { - $this->facets[] = $facet; - - return $this; - } - - /** - * @param array $facets the facets to add - * - * @return $this - */ - public function setFacets(array $facets) - { - $this->facets = []; - foreach ($facets as $facet) { - $this->addFacet($facet); - } - - return $this; - } - - /** - * @return array returns the list of facets - */ - public function getFacets() - { - return $this->facets; - } -} diff --git a/src/Core/Product/Search/FacetsRendererInterface.php b/src/Core/Product/Search/FacetsRendererInterface.php deleted file mode 100644 index 2d619955..00000000 --- a/src/Core/Product/Search/FacetsRendererInterface.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * Define how we render facets and active filters. - */ -interface FacetsRendererInterface -{ - /** - * @param ProductSearchContext $context - * @param ProductSearchResult $result - * - * @return string HTML content is expected here - */ - public function renderFacets( - ProductSearchContext $context, - ProductSearchResult $result - ); - - /** - * @param ProductSearchContext $context - * @param ProductSearchResult $result - * - * @return string HTML content is expected here - */ - public function renderActiveFilters( - ProductSearchContext $context, - ProductSearchResult $result - ); -} diff --git a/src/Core/Product/Search/Filter.php b/src/Core/Product/Search/Filter.php deleted file mode 100644 index f5368668..00000000 --- a/src/Core/Product/Search/Filter.php +++ /dev/null @@ -1,254 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -class Filter -{ - /** - * @var string the filter label - */ - private $label = ''; - - /** - * @var string internal type, used by query logic - */ - private $type = ''; - - /** - * @var bool whether or not the filter is used in the query - */ - private $active = false; - - /** - * @var bool whether or not the filter is displayed - */ - private $displayed = true; - - /** - * @var array the filter properties - */ - private $properties = []; - - /** - * @var int the filter magnitude - */ - private $magnitude = 0; - - /** - * @var mixed the filter value - */ - private $value; - - /** - * @var array the filter next encoded facets - */ - private $nextEncodedFacets = []; - - /** - * @return array an array representation of the filter - */ - public function toArray() - { - return [ - 'label' => $this->label, - 'type' => $this->type, - 'active' => $this->active, - 'displayed' => $this->displayed, - 'properties' => $this->properties, - 'magnitude' => $this->magnitude, - 'value' => $this->value, - 'nextEncodedFacets' => $this->nextEncodedFacets, - ]; - } - - /** - * @param string $label the filter label - * - * @return $this - */ - public function setLabel($label) - { - $this->label = $label; - - return $this; - } - - /** - * @return string the filter label - */ - public function getLabel() - { - return $this->label; - } - - /** - * @param string $type the filter type - * - * @return $this - */ - public function setType($type) - { - $this->type = $type; - - return $this; - } - - /** - * @return string the filter type - */ - public function getType() - { - return $this->type; - } - - /** - * @param string $name the filter property name - * @param mixed $value the filter property value - * - * @return $this - */ - public function setProperty($name, $value) - { - $this->properties[$name] = $value; - - return $this; - } - - /** - * @param string $name the filter property name - * - * @return mixed|null - */ - public function getProperty($name) - { - if (!array_key_exists($name, $this->properties)) { - return null; - } - - return $this->properties[$name]; - } - - /** - * @param $value - * - * @return $this - */ - public function setValue($value) - { - $this->value = $value; - - return $this; - } - - /** - * @return mixed - */ - public function getValue() - { - return $this->value; - } - - /** - * @param int $magnitude the filter magnitude - * - * @return $this - */ - public function setMagnitude($magnitude) - { - $this->magnitude = (int) $magnitude; - - return $this; - } - - /** - * @return int the filter magnitude - */ - public function getMagnitude() - { - return $this->magnitude; - } - - /** - * @param bool $active sets the activation of the filter - * - * @return $this - */ - public function setActive($active = true) - { - $this->active = $active; - - return $this; - } - - /** - * @return bool returns true if the filter is active - */ - public function isActive() - { - return $this->active; - } - - /** - * @param bool $displayed sets the display of the filter - * - * @return $this - */ - public function setDisplayed($displayed = true) - { - $this->displayed = $displayed; - - return $this; - } - - /** - * @return bool returns true if the filter is displayed - */ - public function isDisplayed() - { - return $this->displayed; - } - - /** - * @param $nextEncodedFacets - * - * @return $this - */ - public function setNextEncodedFacets($nextEncodedFacets) - { - $this->nextEncodedFacets = $nextEncodedFacets; - - return $this; - } - - /** - * @return array - */ - public function getNextEncodedFacets() - { - return $this->nextEncodedFacets; - } -} diff --git a/src/Core/Product/Search/Pagination.php b/src/Core/Product/Search/Pagination.php deleted file mode 100644 index cbf6258b..00000000 --- a/src/Core/Product/Search/Pagination.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -class Pagination -{ - /** - * @var int the total number of pages for this query - */ - private $pagesCount; - - /** - * @var int the index of the returned page - */ - private $page; - - /** - * @param int $pagesCount - * - * @return $this - */ - public function setPagesCount($pagesCount) - { - if (!is_int($pagesCount)) { - trigger_error(sprintf('Integer value is expected, got `%s`', gettype($pagesCount)), E_USER_NOTICE); - $pagesCount = (int) $pagesCount; - } - - $this->pagesCount = $pagesCount; - - return $this; - } - - /** - * @return int - */ - public function getPagesCount() - { - return $this->pagesCount; - } - - /** - * @param int $page - * - * @return $this - */ - public function setPage($page) - { - if (!is_int($page)) { - trigger_error(sprintf('Integer value is expected, got `%s`', gettype($page)), E_USER_NOTICE); - $page = (int) $page; - } - - $this->page = $page; - - return $this; - } - - /** - * @return int - */ - public function getPage() - { - return $this->page; - } - - /** - * @param $page - * @param string $type - * - * @return array - */ - private function buildPageLink($page, $type = 'page') - { - $current = $page === $this->getPage(); - - return [ - 'type' => $type, - 'page' => $page, - 'clickable' => !$current, - 'current' => $type === 'page' ? $current : false, - ]; - } - - /** - * @return array - */ - private function buildSpacer() - { - return [ - 'type' => 'spacer', - 'page' => null, - 'clickable' => false, - 'current' => false, - ]; - } - - /** - * @return array - */ - public function buildLinks() - { - $links = []; - - $addPageLink = function ($page) use (&$links) { - static $lastPage = null; - - if ($page < 1 || $page > $this->getPagesCount()) { - return; - } - - if (null !== $lastPage && $page > $lastPage + 1) { - $links[] = $this->buildSpacer(); - } - - if ($page !== $lastPage) { - $links[] = $this->buildPageLink($page); - } - - $lastPage = $page; - }; - - $boundaryContextLength = 1; - $pageContextLength = 3; - - $links[] = $this->buildPageLink(max(1, $this->getPage() - 1), 'previous'); - - for ($i = 0; $i < $boundaryContextLength; ++$i) { - $addPageLink(1 + $i); - } - - $start = max(1, $this->getPage() - (int) floor(($pageContextLength - 1) / 2)); - if ($start + $pageContextLength > $this->getPagesCount()) { - $start = $this->getPagesCount() - $pageContextLength + 1; - } - - for ($i = 0; $i < $pageContextLength; ++$i) { - $addPageLink($start + $i); - } - - for ($i = 0; $i < $boundaryContextLength; ++$i) { - $addPageLink($this->getPagesCount() - $boundaryContextLength + 1 + $i); - } - - $links[] = $this->buildPageLink(min($this->getPagesCount(), $this->getPage() + 1), 'next'); - - return $links; - } -} diff --git a/src/Core/Product/Search/ProductSearchContext.php b/src/Core/Product/Search/ProductSearchContext.php deleted file mode 100644 index f9904f8d..00000000 --- a/src/Core/Product/Search/ProductSearchContext.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -use Context; - -class ProductSearchContext -{ - /** - * @var int the Shop id - */ - private $idShop; - - /** - * @var int the Language id - */ - private $idLang; - - /** - * @var int the Currency id - */ - private $idCurrency; - - /** - * @var int the Customer id - */ - private $idCustomer; - - public function __construct(Context $context = null) - { - if ($context) { - $this->idShop = $context->shop->id; - $this->idLang = $context->language->id; - $this->idCurrency = $context->currency->id; - $this->idCustomer = $context->customer->id; - } - } - - /** - * @param int $idShop - * - * @return $this - */ - public function setIdShop($idShop) - { - $this->idShop = $idShop; - - return $this; - } - - /** - * @return int the Product Search Shop id - */ - public function getIdShop() - { - return $this->idShop; - } - - /** - * @param int $idLang - * - * @return $this - */ - public function setIdLang($idLang) - { - $this->idLang = $idLang; - - return $this; - } - - /** - * @return int the Product Search Language id - */ - public function getIdLang() - { - return $this->idLang; - } - - /** - * @param int $idCurrency - * - * @return $this - */ - public function setIdCurrency($idCurrency) - { - $this->idCurrency = $idCurrency; - - return $this; - } - - /** - * @return int the Product Search Currency id - */ - public function getIdCurrency() - { - return $this->idCurrency; - } - - /** - * @param int $idCustomer - * - * @return $this - */ - public function setIdCustomer($idCustomer) - { - $this->idCustomer = $idCustomer; - - return $this; - } - - /** - * @return int the Product Search Customer id - */ - public function getIdCustomer() - { - return $this->idCustomer; - } -} diff --git a/src/Core/Product/Search/ProductSearchProviderInterface.php b/src/Core/Product/Search/ProductSearchProviderInterface.php deleted file mode 100644 index fefc5853..00000000 --- a/src/Core/Product/Search/ProductSearchProviderInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * Will define the query to execute in order to retrieve the list of products. - */ -interface ProductSearchProviderInterface -{ - /** - * @param ProductSearchContext $context - * @param ProductSearchQuery $query - * - * @return ProductSearchResult - */ - public function runQuery( - ProductSearchContext $context, - ProductSearchQuery $query - ); -} diff --git a/src/Core/Product/Search/ProductSearchQuery.php b/src/Core/Product/Search/ProductSearchQuery.php deleted file mode 100644 index f0b19925..00000000 --- a/src/Core/Product/Search/ProductSearchQuery.php +++ /dev/null @@ -1,294 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * Define the Product Query to execute according the the encoded facets. - */ -class ProductSearchQuery -{ - /** - * @var string - */ - private $queryType; - - /** - * @var int - */ - private $idCategory; - - /** - * @var int - */ - private $idManufacturer; - - /** - * @var int - */ - private $idSupplier; - - /** - * @var string - */ - private $searchString; - - /** - * @var string - */ - private $searchTag; - - /** - * @var array - */ - private $encodedFacets; - - /** - * A default that is multiple of 2, 3 and 4 should be OK for - * many layouts. - * - * @var int 12 is the best number ever - */ - private $resultsPerPage = 12; - - /** - * @var int - */ - private $page = 1; - - /** - * @var SortOrder - */ - private $sortOrder; - - /** - * ProductSearchQuery constructor. - */ - public function __construct() - { - $this->setSortOrder(new SortOrder('product', 'name', 'ASC')); - } - - /** - * @param string $queryType - * - * @return $this - */ - public function setQueryType($queryType) - { - $this->queryType = $queryType; - - return $this; - } - - /** - * @return string - */ - public function getQueryType() - { - return $this->queryType; - } - - /** - * @param $idCategory - * - * @return $this - */ - public function setIdCategory($idCategory) - { - $this->idCategory = $idCategory; - - return $this; - } - - /** - * @return int - */ - public function getIdCategory() - { - return $this->idCategory; - } - - /** - * @param $idManufacturer - * - * @return $this - */ - public function setIdManufacturer($idManufacturer) - { - $this->idManufacturer = $idManufacturer; - - return $this; - } - - /** - * @return int - */ - public function getIdManufacturer() - { - return $this->idManufacturer; - } - - /** - * @param $idSupplier - * - * @return $this - */ - public function setIdSupplier($idSupplier) - { - $this->idSupplier = $idSupplier; - - return $this; - } - - /** - * @return int - */ - public function getIdSupplier() - { - return $this->idSupplier; - } - - /** - * @param $resultsPerPage - * - * @return $this - */ - public function setResultsPerPage($resultsPerPage) - { - $this->resultsPerPage = (int) $resultsPerPage; - - return $this; - } - - /** - * @return int - */ - public function getResultsPerPage() - { - return $this->resultsPerPage; - } - - /** - * @param $page - * - * @return $this - */ - public function setPage($page) - { - $this->page = (int) $page; - - return $this; - } - - /** - * @return int - */ - public function getPage() - { - return $this->page; - } - - /** - * @param SortOrder $sortOrder - * - * @return $this - */ - public function setSortOrder(SortOrder $sortOrder) - { - $this->sortOrder = $sortOrder; - - return $this; - } - - /** - * @return SortOrder - */ - public function getSortOrder() - { - return $this->sortOrder; - } - - /** - * @param $searchString - * - * @return $this - */ - public function setSearchString($searchString) - { - $this->searchString = $searchString; - - return $this; - } - - /** - * @return string - */ - public function getSearchString() - { - return $this->searchString; - } - - /** - * @param $searchTag - * - * @return $this - */ - public function setSearchTag($searchTag) - { - $this->searchTag = $searchTag; - - return $this; - } - - /** - * @return string - */ - public function getSearchTag() - { - return $this->searchTag; - } - - /** - * @param array $encodedFacets - * - * @return $this - */ - public function setEncodedFacets($encodedFacets) - { - $this->encodedFacets = $encodedFacets; - - return $this; - } - - /** - * @return array - */ - public function getEncodedFacets() - { - return $this->encodedFacets; - } -} diff --git a/src/Core/Product/Search/ProductSearchResult.php b/src/Core/Product/Search/ProductSearchResult.php deleted file mode 100644 index 0ce02353..00000000 --- a/src/Core/Product/Search/ProductSearchResult.php +++ /dev/null @@ -1,191 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -class ProductSearchResult -{ - /** - * @var array - */ - private $products = []; - /** - * @var - */ - private $totalProductsCount; - /** - * @var - */ - private $facetCollection; - /** - * @var - */ - private $encodedFacets; - /** - * @var array - */ - private $availableSortOrders = []; - /** - * @var - */ - private $currentSortOrder; - - /** - * @param array $products - * - * @return $this - */ - public function setProducts(array $products) - { - $this->products = $products; - - return $this; - } - - /** - * @return array - */ - public function getProducts() - { - return $this->products; - } - - /** - * @param $totalProductsCount - * - * @return $this - */ - public function setTotalProductsCount($totalProductsCount) - { - $this->totalProductsCount = $totalProductsCount; - - return $this; - } - - /** - * @return mixed - */ - public function getTotalProductsCount() - { - return $this->totalProductsCount; - } - - /** - * @param FacetCollection $facetCollection - * - * @return $this - */ - public function setFacetCollection(FacetCollection $facetCollection) - { - $this->facetCollection = $facetCollection; - - return $this; - } - - /** - * @return FacetCollection - */ - public function getFacetCollection() - { - return $this->facetCollection; - } - - /** - * @param $encodedFacets - * - * @return $this - */ - public function setEncodedFacets($encodedFacets) - { - $this->encodedFacets = $encodedFacets; - - return $this; - } - - /** - * @return mixed - */ - public function getEncodedFacets() - { - return $this->encodedFacets; - } - - /** - * @param SortOrder $sortOrder - * - * @return $this - */ - public function addAvailableSortOrder(SortOrder $sortOrder) - { - $this->availableSortOrders[] = $sortOrder; - - return $this; - } - - /** - * @return array - */ - public function getAvailableSortOrders() - { - return $this->availableSortOrders; - } - - /** - * @param array $sortOrders - * - * @return $this - */ - public function setAvailableSortOrders(array $sortOrders) - { - $this->availableSortOrders = []; - - foreach ($sortOrders as $sortOrder) { - $this->addAvailableSortOrder($sortOrder); - } - - return $this; - } - - /** - * @param SortOrder $currentSortOrder - * - * @return $this - */ - public function setCurrentSortOrder(SortOrder $currentSortOrder) - { - $this->currentSortOrder = $currentSortOrder; - - return $this; - } - - /** - * @return mixed - */ - public function getCurrentSortOrder() - { - return $this->currentSortOrder; - } -} diff --git a/src/Core/Product/Search/SortOrder.php b/src/Core/Product/Search/SortOrder.php deleted file mode 100644 index 3f126d21..00000000 --- a/src/Core/Product/Search/SortOrder.php +++ /dev/null @@ -1,260 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -use PrestaShop\PrestaShop\Core\Product\Search\Exception\InvalidSortOrderDirectionException; - -/** - * This class define in which order the list of products will be sorted. - */ -class SortOrder -{ - /** - * @var string the SortOrder entity - */ - private $entity; - /** - * @var string the SortOrder field - */ - private $field; - /** - * @var string the SortOrder direction - */ - private $direction; - /** - * @var string string The SortOrder label - */ - private $label; - - /** - * SortOrder constructor. - * - * @param string $entity the SortOrder entity - * @param string $field the SortOrder field - * @param string $direction the SortOrder direction - * - * @throws Exception - */ - public function __construct($entity, $field, $direction = 'asc') - { - $this - ->setEntity($entity) - ->setField($field) - ->setDirection($direction); - } - - /** - * Will returns a new Sort Order with random direction. - * - * @return SortOrder - * - * @throws Exception - */ - public static function random() - { - return new static('', '', 'random'); - } - - /** - * @return bool if true, the Sort Order direction is random - */ - public function isRandom() - { - return $this->getDirection() === 'random'; - } - - /** - * @return array the array representation of a Sort Order - */ - public function toArray() - { - return [ - 'entity' => $this->entity, - 'field' => $this->field, - 'direction' => $this->direction, - 'label' => $this->label, - 'urlParameter' => $this->toString(), - ]; - } - - /** - * @return string the string representation of a Sort Order - */ - public function toString() - { - return "{$this->entity}.{$this->field}.{$this->direction}"; - } - - /** - * Creates a new Sort Order from string of this kind: {entity}.{field}.{direction}. - * - * @param string $sortOrderConfiguration the Sort Order configuration string - * - * @return SortOrder - * - * @throws Exception - */ - public static function newFromString($sortOrderConfiguration) - { - list($entity, $field, $direction) = explode('.', $sortOrderConfiguration); - - return new static($entity, $field, $direction); - } - - /** - * @param string $label the Sort Order label - * - * @return $this - */ - public function setLabel($label) - { - $this->label = $label; - - return $this; - } - - /** - * @return string the Sort Order label - */ - public function getLabel() - { - return $this->label; - } - - /** - * @param string $entity the Sort Order entity - * - * @return $this - */ - public function setEntity($entity) - { - $this->entity = $entity; - - return $this; - } - - /** - * @return string the Sort Order entity - */ - public function getEntity() - { - return $this->entity; - } - - /** - * @param string $field the Sort Order field - * - * @return $this - */ - public function setField($field) - { - $this->field = $field; - - return $this; - } - - /** - * @return string the Sort Order field - */ - public function getField() - { - return $this->field; - } - - /** - * @param string $direction - * - * @return string - * - * @throws Exception - */ - public function setDirection($direction) - { - $formattedDirection = strtolower($direction); - if (!in_array($formattedDirection, ['asc', 'desc', 'random'])) { - throw new InvalidSortOrderDirectionException($direction); - } - - $this->direction = $formattedDirection; - - return $this->direction; - } - - /** - * @return string the Sort Order direction - */ - public function getDirection() - { - return $this->direction; - } - - /** - * @return string returns the order way using legacy prefix - */ - private function getLegacyPrefix() - { - if ($this->entity === 'product') { - if ($this->field === 'name') { - return 'pl.'; - } elseif ($this->field === 'position') { - return 'cp.'; - } elseif ($this->field === 'manufacturer_name') { - $this->setField('name'); - - return 'm.'; - } else { - return 'p.'; - } - } elseif ($this->entity === 'manufacturer') { - return 'm.'; - } - } - - /** - * @param bool $prefix if true, relies on legacy prefix - * - * @return string - */ - public function toLegacyOrderBy($prefix = false) - { - if ($prefix) { - return $this->getLegacyPrefix() . $this->field; - } elseif ($this->entity === 'manufacturer' && $this->field === 'name') { - return 'manufacturer_name'; - } else { - return $this->field; - } - } - - /** - * @return string the legacy order way - */ - public function toLegacyOrderWay() - { - return $this->getDirection(); - } -} diff --git a/src/Core/Product/Search/SortOrderFactory.php b/src/Core/Product/Search/SortOrderFactory.php deleted file mode 100644 index 26e412a3..00000000 --- a/src/Core/Product/Search/SortOrderFactory.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -use Symfony\Component\Translation\TranslatorInterface; - -/** - * This class is not a factory but a provider of default Sort Orders. - * - * @deprecated since 1.7.6 and to be removed in the next major: use SortOrdersCollection:getDefaults instead. - */ -class SortOrderFactory -{ - /** - * @var TranslatorInterface the translator - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - @trigger_error( - 'This class is deprecated since 1.7.6, use SortOrdersCollection::getDefaults instead.', - E_USER_DEPRECATED - ); - $this->translator = $translator; - } - - /** - * @return array - * - * @throws \Exception - */ - public function getDefaultSortOrders() - { - return (new SortOrdersCollection($this->translator))->getDefaults(); - } -} diff --git a/src/Core/Product/Search/SortOrdersCollection.php b/src/Core/Product/Search/SortOrdersCollection.php deleted file mode 100644 index f1beebd6..00000000 --- a/src/Core/Product/Search/SortOrdersCollection.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -use Symfony\Component\Translation\TranslatorInterface; - -/** - * This class provide the list of default Sort Orders. - */ -final class SortOrdersCollection -{ - /** - * @var TranslatorInterface the translator - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * @return array - * - * @throws \Exception - */ - public function getDefaults() - { - return [ - (new SortOrder('product', 'position', 'desc'))->setLabel( - $this->translator->trans('Relevance', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'asc'))->setLabel( - $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'name', 'desc'))->setLabel( - $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'asc'))->setLabel( - $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog') - ), - (new SortOrder('product', 'price', 'desc'))->setLabel( - $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog') - ), - ]; - } -} diff --git a/src/Core/Product/Search/URLFragmentSerializer.php b/src/Core/Product/Search/URLFragmentSerializer.php deleted file mode 100644 index 8ebe5f8c..00000000 --- a/src/Core/Product/Search/URLFragmentSerializer.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Product\Search; - -/** - * This class is a serializer for URL fragments. - */ -class URLFragmentSerializer -{ - /** - * @param array $fragment - * - * @return string - */ - public function serialize(array $fragment) - { - $parts = []; - foreach ($fragment as $key => $values) { - array_unshift($values, $key); - $parts[] = $this->serializeListOfStrings('-', '-', $values); - } - - return $this->serializeListOfStrings('/', '/', $parts); - } - - /** - * @param string $string - * - * @return array - */ - public function unserialize($string) - { - $fragment = []; - $parts = $this->unserializeListOfStrings('/', '/', $string); - foreach ($parts as $part) { - $values = $this->unserializeListOfStrings('-', '-', $part); - $key = array_shift($values); - $fragment[$key] = $values; - } - - return $fragment; - } - - /** - * @param string $separator the string separator - * @param string $escape the string escape - * @param array $list - * - * @return string - */ - private function serializeListOfStrings($separator, $escape, array $list) - { - return implode($separator, array_map(function ($item) use ($separator, $escape) { - return str_replace($separator, $escape . $separator, $item); - }, $list)); - } - - /** - * @param string $separator the string separator - * @param string $escape the string escape - * @param string $string the UTF8 string - * - * @return array - */ - private function unserializeListOfStrings($separator, $escape, $string) - { - $list = []; - $currentString = ''; - $escaping = false; - - // get UTF-8 chars, inspired from http://stackoverflow.com/questions/9438158/split-utf8-string-into-array-of-chars - $arrayOfCharacters = []; - preg_match_all('/./u', $string, $arrayOfCharacters); - $characters = $arrayOfCharacters[0]; - - foreach ($characters as $character) { - if ($escaping) { - if ($character === $separator || $character === $escape) { - $currentString .= $character; - } else { - $list[] = $currentString; - $currentString = $character; - } - $escaping = false; - } else { - if ($character === $escape) { - $escaping = true; - } elseif ($character === $separator) { - $list[] = $currentString; - $currentString = ''; - } else { - $currentString .= $character; - } - } - } - - if ($escaping) { - $currentString .= $escape; - } - - if ('' !== $currentString) { - $list[] = $currentString; - } - - return $list; - } -} diff --git a/src/Core/Proxy/CachedFileFinderProxy.php b/src/Core/Proxy/CachedFileFinderProxy.php deleted file mode 100644 index 7e910a2c..00000000 --- a/src/Core/Proxy/CachedFileFinderProxy.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Proxy; - -use PrestaShop\PrestaShop\Core\File\FileFinderInterface; - -/** - * Class CachedFileFinderProxy is a local cache proxy of file finder. - */ -final class CachedFileFinderProxy implements FileFinderInterface -{ - /** - * @var FileFinderInterface - */ - private $delegate; - - /** - * @var array - */ - private $filesCache; - - /** - * @param FileFinderInterface $delegate instance of file finder - */ - public function __construct(FileFinderInterface $delegate) - { - $this->delegate = $delegate; - } - - /** - * {@inheritdoc} - */ - public function find() - { - if (null === $this->filesCache) { - $this->filesCache = $this->delegate->find(); - } - - return $this->filesCache; - } -} diff --git a/src/Core/Repository/RepositoryInterface.php b/src/Core/Repository/RepositoryInterface.php deleted file mode 100644 index 7b1fdb24..00000000 --- a/src/Core/Repository/RepositoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Repository; - -/** - * Define the contract to access entities. - * - * A repository should only contains methods for querying the data. - */ -interface RepositoryInterface -{ - /** - * Returns the complete list of items. - * - * @return array - */ - public function findAll(); -} diff --git a/src/Core/Routing/EntityLinkBuilderFactory.php b/src/Core/Routing/EntityLinkBuilderFactory.php deleted file mode 100644 index 4dcd044c..00000000 --- a/src/Core/Routing/EntityLinkBuilderFactory.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Routing; - -use PrestaShop\PrestaShop\Core\Routing\Exception\BuilderNotFoundException; - -/** - * Class EntityLinkBuilderFactory is able to return the builder for an entity. - */ -class EntityLinkBuilderFactory -{ - /** - * @var EntityLinkBuilderInterface[] - */ - private $builders; - - /** - * @param array $builders - */ - public function __construct(array $builders) - { - $this->builders = $builders; - } - - /** - * @param string $entity - * - * @return EntityLinkBuilderInterface - * - * @throws BuilderNotFoundException - */ - public function getBuilderFor($entity) - { - foreach ($this->builders as $builder) { - if ($builder->canBuild($entity)) { - return $builder; - } - } - - throw new BuilderNotFoundException(sprintf('Can not find a builder for entity %s', $entity)); - } -} diff --git a/src/Core/Routing/EntityLinkBuilderInterface.php b/src/Core/Routing/EntityLinkBuilderInterface.php deleted file mode 100644 index 35166e3c..00000000 --- a/src/Core/Routing/EntityLinkBuilderInterface.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Routing; - -/** - * Interface EntityLinkBuilderInterface is able to build links for entities, like - * edit or view link. Each interface is able to say if it can manage a certain type - * of entity. - */ -interface EntityLinkBuilderInterface -{ - /** - * @param string $entity - * @param array $parameters - * - * @return string - */ - public function getViewLink($entity, array $parameters); - - /** - * @param string $entity - * @param array $parameters - * - * @return string - */ - public function getEditLink($entity, array $parameters); - - /** - * @param string $entity - * - * @return bool - */ - public function canBuild($entity); -} diff --git a/src/Core/Routing/Exception/BuilderNotFoundException.php b/src/Core/Routing/Exception/BuilderNotFoundException.php deleted file mode 100644 index 9204a8a5..00000000 --- a/src/Core/Routing/Exception/BuilderNotFoundException.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Routing\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class BuilderNotFoundException thrown when the factory can't find a builder - * matching with an entity. - */ -class BuilderNotFoundException extends CoreException -{ -} diff --git a/src/Core/Search/Builder/AbstractFiltersBuilder.php b/src/Core/Search/Builder/AbstractFiltersBuilder.php deleted file mode 100644 index 3a23e40a..00000000 --- a/src/Core/Search/Builder/AbstractFiltersBuilder.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Basic abstract class for FiltersBuilder classes, able to store the filters_id - * from the config. - */ -abstract class AbstractFiltersBuilder implements FiltersBuilderInterface -{ - /** @var string */ - protected $filterId; - - /** - * {@inheritdoc} - */ - public function setConfig(array $config) - { - $this->filterId = isset($config['filter_id']) ? $config['filter_id'] : ''; - - return $this; - } - - /** - * {@inheritdoc} - */ - abstract public function buildFilters(Filters $filters = null); - - /** - * @param Filters|null $filters - * - * @return string - */ - protected function getFilterId(Filters $filters = null) - { - if (null === $filters) { - return $this->filterId; - } - - return $filters->getFilterId(); - } -} diff --git a/src/Core/Search/Builder/AbstractRepositoryFiltersBuilder.php b/src/Core/Search/Builder/AbstractRepositoryFiltersBuilder.php deleted file mode 100644 index 9bd3f7ec..00000000 --- a/src/Core/Search/Builder/AbstractRepositoryFiltersBuilder.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShop\PrestaShop\Core\Search\ControllerAction; -use PrestaShopBundle\Entity\Repository\AdminFilterRepository; -use Symfony\Component\HttpFoundation\Request; - -/** - * Basic abstract class for filters related to the database, whether they need to persist - * or search for filters. It is created with all the necessary services and configuration - * including the context (employee + shop), and it can extract the filters matching from - * the config or the request (either via filter_id or via controller/action matching). - */ -abstract class AbstractRepositoryFiltersBuilder extends AbstractFiltersBuilder -{ - /** @var AdminFilterRepository */ - protected $adminFilterRepository; - - /** @var ContextEmployeeProviderInterface */ - protected $employeeProvider; - - /** @var int */ - protected $shopId; - - /** @var string */ - protected $controller; - - /** @var string */ - protected $action; - - /** - * @param AdminFilterRepository $adminFilterRepository - * @param ContextEmployeeProviderInterface $employeeProvider - * @param int $shopId - */ - public function __construct( - AdminFilterRepository $adminFilterRepository, - ContextEmployeeProviderInterface $employeeProvider, - $shopId - ) { - $this->adminFilterRepository = $adminFilterRepository; - $this->employeeProvider = $employeeProvider; - $this->shopId = $shopId; - } - - /** - * {@inheritdoc} - */ - public function setConfig(array $config) - { - $defaultController = $defaultAction = ''; - if (isset($config['request']) && $config['request'] instanceof Request) { - $request = $config['request']; - list($defaultController, $defaultAction) = ControllerAction::fromString($request->get('_controller')); - } - - $this->controller = isset($config['controller']) ? $config['controller'] : $defaultController; - $this->action = isset($config['action']) ? $config['action'] : $defaultAction; - - return parent::setConfig($config); - } -} diff --git a/src/Core/Search/Builder/ChainedFiltersBuilder.php b/src/Core/Search/Builder/ChainedFiltersBuilder.php deleted file mode 100644 index 9ec4535f..00000000 --- a/src/Core/Search/Builder/ChainedFiltersBuilder.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * This builder is used to compose other builders, it iterates through its builders - * set the config for all of them (each one can pick its own parameters), and when - * building iterates through them overriding the same Filters instance step by step. - * - * This allows to split every Filters building into separate classes and then compose - * them based on your needs. - */ -final class ChainedFiltersBuilder extends AbstractFiltersBuilder -{ - /** @var FiltersBuilderCollection */ - private $builders; - - /** - * @param array $builders Array of FiltersBuilderInterface - * - * @throws \PrestaShop\PrestaShop\Core\Exception\TypeException - */ - public function __construct(array $builders = []) - { - $this->builders = new FiltersBuilderCollection($builders); - } - - /** - * {@inheritdoc} - */ - public function setConfig(array $config) - { - parent::setConfig($config); - - /** @var FiltersBuilderInterface $builder */ - foreach ($this->builders as $builder) { - $builder->setConfig($config); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function buildFilters(Filters $filters = null) - { - if (empty($this->builders)) { - return $filters; - } - - /** @var FiltersBuilderInterface $builder */ - foreach ($this->builders as $builder) { - $filters = $builder->buildFilters($filters); - } - - return $filters; - } -} diff --git a/src/Core/Search/Builder/ClassFiltersBuilder.php b/src/Core/Search/Builder/ClassFiltersBuilder.php deleted file mode 100644 index 0fd6eb1e..00000000 --- a/src/Core/Search/Builder/ClassFiltersBuilder.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * This builder instantiate a filters object of the specified type using - * its default values for creation. - */ -final class ClassFiltersBuilder extends AbstractFiltersBuilder -{ - /** @var string */ - private $filtersClass; - - /** - * {@inheritdoc} - */ - public function setConfig(array $config) - { - if (isset($config['filters_class'])) { - $this->filtersClass = $config['filters_class']; - } - - return parent::setConfig($config); - } - - /** - * Build the filters with the class defined by filtersClass - * - * @param Filters|null $filters - * - * @return Filters - */ - public function buildFilters(Filters $filters = null) - { - if (null === $this->filtersClass) { - return $filters; - } - - /** @var array $defaultParameters */ - $defaultParameters = call_user_func([$this->filtersClass, 'getDefaults']); - if (null !== $filters) { - /** @var Filters $typedFilters */ - $typedFilters = new $this->filtersClass($filters->all(), $filters->getFilterId()); - $typedFilters->add($defaultParameters); - } else { - $typedFilters = new $this->filtersClass($defaultParameters, $this->filterId); - } - - return $typedFilters; - } -} diff --git a/src/Core/Search/Builder/EventFiltersBuilder.php b/src/Core/Search/Builder/EventFiltersBuilder.php deleted file mode 100644 index e2b0afab..00000000 --- a/src/Core/Search/Builder/EventFiltersBuilder.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; -use PrestaShopBundle\Event\FilterSearchCriteriaEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -/** - * This builder is used to allow modification of the built filters via - * a symfony event prestashop.search_criteria.filter (used to change the - * generic building process in some edge cases) - * - * @see FilterCategorySearchCriteriaListener - */ -final class EventFiltersBuilder extends AbstractFiltersBuilder -{ - /** @var EventDispatcherInterface */ - private $dispatcher; - - /** - * @param EventDispatcherInterface $dispatcher - */ - public function __construct(EventDispatcherInterface $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - /** - * {@inheritdoc} - */ - public function buildFilters(Filters $filters = null) - { - $filterSearchParametersEvent = new FilterSearchCriteriaEvent($filters); - $this->dispatcher->dispatch(FilterSearchCriteriaEvent::NAME, $filterSearchParametersEvent); - - return $filterSearchParametersEvent->getSearchCriteria(); - } -} diff --git a/src/Core/Search/Builder/FiltersBuilderCollection.php b/src/Core/Search/Builder/FiltersBuilderCollection.php deleted file mode 100644 index 695a3d3e..00000000 --- a/src/Core/Search/Builder/FiltersBuilderCollection.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Data\AbstractTypedCollection; - -/** - * Collection of FiltersBuilderInterface. - */ -final class FiltersBuilderCollection extends AbstractTypedCollection -{ - /** - * {@inheritdoc} - */ - protected function getType() - { - return FiltersBuilderInterface::class; - } -} diff --git a/src/Core/Search/Builder/FiltersBuilderInterface.php b/src/Core/Search/Builder/FiltersBuilderInterface.php deleted file mode 100644 index 0d6d52a1..00000000 --- a/src/Core/Search/Builder/FiltersBuilderInterface.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Interface for filters builders, each builder needs a config which is provided - * through the setConfig method which MUST be called before calling buildFilters. - * - * As the builders are called one after the other they may be provided with an - * existing filters instance that they need to override, if not they simply create - * a new Filters instance. - */ -interface FiltersBuilderInterface -{ - const FILTER_TYPES = [ - 'limit', - 'offset', - 'orderBy', - 'sortOrder', - 'filters', - ]; - - /** - * Allows to set a config through an associative array, this method should - * be called before buildFilters, it returns the builder for convenience so - * you can chain both calls (e.g: $builder->setConfig($config)->buildFilters()) - * - * @param array $config - * - * @return $this - */ - public function setConfig(array $config); - - /** - * This method is called to build the filters, the filters parameter is used if - * you want to override a pre existing filter. All builders should keep that in - * mind as they can be used consecutively with other builders and must not drop - * existing values carelessly. - * - * @param Filters|null $filters - * - * @return Filters - */ - public function buildFilters(Filters $filters = null); -} diff --git a/src/Core/Search/Builder/PersistFiltersBuilder.php b/src/Core/Search/Builder/PersistFiltersBuilder.php deleted file mode 100644 index a76a022e..00000000 --- a/src/Core/Search/Builder/PersistFiltersBuilder.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * This builder does not modify the filters but instead saves them in database for - * each Employee, thus it can then be found by the RepositoryFiltersBuilder. - */ -final class PersistFiltersBuilder extends AbstractRepositoryFiltersBuilder -{ - /** - * @param Filters|null $filters - * - * @return Filters - * - * @throws \Doctrine\ORM\OptimisticLockException - */ - public function buildFilters(Filters $filters = null) - { - if (null === $filters || !$this->employeeProvider->getId() || !$this->shopId) { - return $filters; - } - - $filterId = $this->getFilterId($filters); - if (empty($filterId) && (empty($this->controller) || empty($this->action))) { - return $filters; - } - - $filtersToSave = $filters->all(); - unset($filtersToSave['offset']); - - if (!empty($filterId)) { - $this->adminFilterRepository->createOrUpdateByEmployeeAndFilterId( - $this->employeeProvider->getId(), - $this->shopId, - $filtersToSave, - $filterId - ); - } else { - $this->adminFilterRepository->createOrUpdateByEmployeeAndRouteParams( - $this->employeeProvider->getId(), - $this->shopId, - $filtersToSave, - $this->controller, - $this->action - ); - } - - return $filters; - } -} diff --git a/src/Core/Search/Builder/RepositoryFiltersBuilder.php b/src/Core/Search/Builder/RepositoryFiltersBuilder.php deleted file mode 100644 index e895f384..00000000 --- a/src/Core/Search/Builder/RepositoryFiltersBuilder.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; -use PrestaShopBundle\Entity\AdminFilter; - -/** - * This builder is able to get the employee saved filter: - * - thanks to filterId if one has been specified (either in the config or by the Filters sub class) - * - thanks to controller/action matching from the request - */ -final class RepositoryFiltersBuilder extends AbstractRepositoryFiltersBuilder -{ - /** - * {@inheritdoc} - */ - public function buildFilters(Filters $filters = null) - { - if (!$this->employeeProvider->getId() || !$this->shopId) { - return $filters; - } - - $filterId = $this->getFilterId($filters); - $parameters = $this->getParametersFromRepository($filterId); - - if (null !== $filters) { - $filters->add($parameters); - } else { - $filters = new Filters($parameters, $filterId); - } - - return $filters; - } - - /** - * @param string $filterId - * - * @return array - */ - private function getParametersFromRepository($filterId) - { - if (empty($filterId) && (empty($this->controller) || empty($this->action))) { - return []; - } - - if (!empty($filterId)) { - /** @var AdminFilter $adminFilter */ - $adminFilter = $this->adminFilterRepository->findByEmployeeAndFilterId( - $this->employeeProvider->getId(), - $this->shopId, - $filterId - ); - } else { - /** @var AdminFilter $adminFilter */ - $adminFilter = $this->adminFilterRepository->findByEmployeeAndRouteParams( - $this->employeeProvider->getId(), - $this->shopId, - $this->controller, - $this->action - ); - } - - if (!$adminFilter) { - return []; - } - - return json_decode($adminFilter->getFilter(), true); - } -} diff --git a/src/Core/Search/Builder/RequestFiltersBuilder.php b/src/Core/Search/Builder/RequestFiltersBuilder.php deleted file mode 100644 index 5001b050..00000000 --- a/src/Core/Search/Builder/RequestFiltersBuilder.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Builder; - -use PrestaShop\PrestaShop\Core\Search\Filters; -use Symfony\Component\HttpFoundation\Request; - -/** - * This builder builds a Filters instance from the request, it is able to fetch the - * parameters from both GET and POST requests. If the built filter has a filterId - * it filters the request parameters in a scope (e.g: ?language[limit]=10 instead of - * ?limit=10) - * The filterId can be set - * - from the builder config - * - from the provided filter which class has a default filterId - * - from the provided filter which has been manually instantiated with a filterId - */ -final class RequestFiltersBuilder extends AbstractFiltersBuilder -{ - /** @var Request */ - private $request; - - /** - * {@inheritdoc} - */ - public function setConfig(array $config) - { - $this->request = isset($config['request']) ? $config['request'] : null; - - return parent::setConfig($config); - } - - /** - * {@inheritdoc} - */ - public function buildFilters(Filters $filters = null) - { - if (null === $this->request) { - return $filters; - } - - $filterId = $this->getFilterId($filters); - $queryParams = $this->request->query->all(); - $requestParams = $this->request->request->all(); - - //If filters have a filterId then parameters are sent in a namespace (eg: grid_id[limit]=10 instead of limit=10) - if (!empty($filterId)) { - $queryParams = isset($queryParams[$filterId]) ? $queryParams[$filterId] : []; - $requestParams = isset($requestParams[$filterId]) ? $requestParams[$filterId] : []; - } - - $parameters = []; - foreach (self::FILTER_TYPES as $type) { - if (isset($queryParams[$type])) { - $parameters[$type] = $queryParams[$type]; - } elseif (isset($requestParams[$type])) { - $parameters[$type] = $requestParams[$type]; - } - } - - if (null !== $filters) { - $filters->add($parameters); - } else { - $filters = new Filters($parameters, $filterId); - } - - return $filters; - } -} diff --git a/src/Core/Search/ControllerAction.php b/src/Core/Search/ControllerAction.php deleted file mode 100644 index d5346862..00000000 --- a/src/Core/Search/ControllerAction.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search; - -/** - * Utility class to extract information from modern controller FQCN. - */ -final class ControllerAction -{ - /** - * Retrieve the Controller's action and name from a FQCN notation of Symfony controller. - * This function expects a string like MyNamespace\Foo\FooController::bazAction. - * - * @param string $controller - * - * @return array - */ - public static function fromString($controller) - { - return [ - self::getControllerName($controller), - self::getActionName($controller), - ]; - } - - /** - * Get current controller name. - * - * @param string $controller the full controller name - * - * @return string - */ - private static function getControllerName($controller) - { - preg_match('~(\w+)Controller(?:::(?:\w+)Action)?$~', $controller, $matches); - - return !empty($matches) ? strtolower($matches[1]) : 'N/A'; - } - - /** - * Get current action name. - * - * @param string $controller the full controller name - * - * @return string - */ - private static function getActionName($controller) - { - preg_match('~::(\w+)Action$~', $controller, $matches); - - return !empty($matches) ? strtolower($matches[1]) : 'N/A'; - } -} diff --git a/src/Core/Search/Filters.php b/src/Core/Search/Filters.php deleted file mode 100644 index b8221461..00000000 --- a/src/Core/Search/Filters.php +++ /dev/null @@ -1,140 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search; - -use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; -use Symfony\Component\HttpFoundation\ParameterBag; - -/** - * This class is responsible of managing filters of Listing pages. - */ -class Filters extends ParameterBag implements SearchCriteriaInterface -{ - /** @var string */ - protected $filterId = ''; - - /** - * @param array $filters - * @param string $filterId - */ - public function __construct(array $filters = [], $filterId = '') - { - parent::__construct($filters); - $this->filterId = !empty($filterId) ? $filterId : $this->filterId; - } - - /** - * @return Filters - */ - public static function buildDefaults() - { - return new static(static::getDefaults()); - } - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => null, - 'sortOrder' => null, - 'filters' => [], - ]; - } - - /** - * {@inheritdoc} - */ - public function getOrderBy() - { - return $this->get('orderBy'); - } - - /** - * {@inheritdoc} - */ - public function getOrderWay() - { - return $this->get('sortOrder'); - } - - /** - * {@inheritdoc} - */ - public function getOffset() - { - return $this->get('offset'); - } - - /** - * {@inheritdoc} - */ - public function getLimit() - { - return $this->get('limit'); - } - - /** - * @param array $parameters - */ - public function addFilter(array $parameters = []) - { - $filters = array_replace($this->getFilters(), $parameters); - $this->set('filters', $filters); - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return $this->get('filters'); - } - - /** - * @return string - */ - public function getFilterId() - { - return $this->filterId; - } - - /** - * @param string $filterId - * - * @return $this - */ - public function setFilterId($filterId) - { - $this->filterId = $filterId; - - return $this; - } -} diff --git a/src/Core/Search/Filters/AddressFilters.php b/src/Core/Search/Filters/AddressFilters.php deleted file mode 100644 index 79c7493e..00000000 --- a/src/Core/Search/Filters/AddressFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AddressGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Default addresses list filters - */ -final class AddressFilters extends Filters -{ - /** @var string */ - protected $filterId = AddressGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults(): array - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_address', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/AttachmentFilters.php b/src/Core/Search/Filters/AttachmentFilters.php deleted file mode 100644 index a3159d19..00000000 --- a/src/Core/Search/Filters/AttachmentFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttachmentGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for Attachments grid. - */ -final class AttachmentFilters extends Filters -{ - /** @var string */ - protected $filterId = AttachmentGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_attachment', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/AttributeFilters.php b/src/Core/Search/Filters/AttributeFilters.php deleted file mode 100644 index 1af7c93f..00000000 --- a/src/Core/Search/Filters/AttributeFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttributeGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Responsible for providing filter values for attribute groups > attributes grid. - */ -final class AttributeFilters extends Filters -{ - /** @var string */ - protected $filterId = AttributeGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_attribute', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/AttributeGroupFilters.php b/src/Core/Search/Filters/AttributeGroupFilters.php deleted file mode 100644 index 7139323c..00000000 --- a/src/Core/Search/Filters/AttributeGroupFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttributeGroupGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Responsible for providing filter values for attribute groups list - */ -final class AttributeGroupFilters extends Filters -{ - /** @var string */ - protected $filterId = AttributeGroupGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'position', - 'sortOrder' => 'desc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/BackupFilters.php b/src/Core/Search/Filters/BackupFilters.php deleted file mode 100644 index 67e7a13c..00000000 --- a/src/Core/Search/Filters/BackupFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class BackupFilters defines filters for 'Configure > Advanced Parameters > Database > Backup' listing. - */ -final class BackupFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => null, - 'sortOrder' => null, - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CatalogPriceRuleFilters.php b/src/Core/Search/Filters/CatalogPriceRuleFilters.php deleted file mode 100644 index 39f516eb..00000000 --- a/src/Core/Search/Filters/CatalogPriceRuleFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CatalogPriceRuleGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Responsible for providing default filters for catalog price rule grid. - */ -final class CatalogPriceRuleFilters extends Filters -{ - /** @var string */ - protected $filterId = CatalogPriceRuleGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_specific_price_rule', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CategoryFilters.php b/src/Core/Search/Filters/CategoryFilters.php deleted file mode 100644 index f68267e0..00000000 --- a/src/Core/Search/Filters/CategoryFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CategoryGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class CategoryFilters defines default filters for Category grid. - */ -final class CategoryFilters extends Filters -{ - /** @var string */ - protected $filterId = CategoryGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'position', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CmsPageCategoryFilters.php b/src/Core/Search/Filters/CmsPageCategoryFilters.php deleted file mode 100644 index 72f55db4..00000000 --- a/src/Core/Search/Filters/CmsPageCategoryFilters.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageCategoryDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class CmsPageCategoryFilters defines default filters for cms page category grid. - */ -final class CmsPageCategoryFilters extends Filters -{ - protected $filterId = CmsPageCategoryDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'position', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CmsPageFilters.php b/src/Core/Search/Filters/CmsPageFilters.php deleted file mode 100644 index 260c524e..00000000 --- a/src/Core/Search/Filters/CmsPageFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -final class CmsPageFilters extends Filters -{ - protected $filterId = CmsPageDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'position', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/ContactFilters.php b/src/Core/Search/Filters/ContactFilters.php deleted file mode 100644 index 1c2bbb3c..00000000 --- a/src/Core/Search/Filters/ContactFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class ContactFilters is responsible for providing default filter values for Contacts list. - */ -final class ContactFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'id_contact', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CreditSlipFilters.php b/src/Core/Search/Filters/CreditSlipFilters.php deleted file mode 100644 index e2606553..00000000 --- a/src/Core/Search/Filters/CreditSlipFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CreditSlipGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Provides default filters for credit slip list - */ -final class CreditSlipFilters extends Filters -{ - /** @var string */ - protected $filterId = CreditSlipGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_order_slip', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CurrencyFilters.php b/src/Core/Search/Filters/CurrencyFilters.php deleted file mode 100644 index ac46954b..00000000 --- a/src/Core/Search/Filters/CurrencyFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CurrencyGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class CurrencyFilters is responsible for providing default filters for currency grid. - */ -final class CurrencyFilters extends Filters -{ - /** @var string */ - protected $filterId = CurrencyGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_currency', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/CustomerFilters.php b/src/Core/Search/Filters/CustomerFilters.php deleted file mode 100644 index fd277aae..00000000 --- a/src/Core/Search/Filters/CustomerFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CustomerGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class CustomerFilters provides default filters for customers grid. - */ -final class CustomerFilters extends Filters -{ - /** @var string */ - protected $filterId = CustomerGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'date_add', - 'sortOrder' => 'DESC', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/EmailLogsFilter.php b/src/Core/Search/Filters/EmailLogsFilter.php deleted file mode 100644 index 4104f74c..00000000 --- a/src/Core/Search/Filters/EmailLogsFilter.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class EmailLogsFilter defines default filters for Email logs grid. - */ -final class EmailLogsFilter extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_mail', - 'sortOrder' => 'desc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/EmployeeFilters.php b/src/Core/Search/Filters/EmployeeFilters.php deleted file mode 100644 index 75d707a3..00000000 --- a/src/Core/Search/Filters/EmployeeFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class EmployeeFilters holds search criteria for Employee grid. - */ -final class EmployeeFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_employee', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/LanguageFilters.php b/src/Core/Search/Filters/LanguageFilters.php deleted file mode 100644 index 049e0789..00000000 --- a/src/Core/Search/Filters/LanguageFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\LanguageGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class LanguageFilters define default filters used for languages filtering. - */ -final class LanguageFilters extends Filters -{ - /** @var string */ - protected $filterId = LanguageGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_lang', - 'sortOrder' => 'ASC', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/LogsFilters.php b/src/Core/Search/Filters/LogsFilters.php deleted file mode 100644 index 14d85653..00000000 --- a/src/Core/Search/Filters/LogsFilters.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * This class manage the defaults values for user request filters - * of page Configure > Advanced Parameters > Logs. - */ -final class LogsFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'id_log', - 'sortOrder' => 'desc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/ManufacturerAddressFilters.php b/src/Core/Search/Filters/ManufacturerAddressFilters.php deleted file mode 100644 index e82c6930..00000000 --- a/src/Core/Search/Filters/ManufacturerAddressFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerAddressGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class ManufacturerAddressFilters is responsible for providing filter values for manufacturer address grid. - */ -final class ManufacturerAddressFilters extends Filters -{ - /** @var string */ - protected $filterId = ManufacturerAddressGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'id_address', - 'sortOrder' => 'desc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/ManufacturerFilters.php b/src/Core/Search/Filters/ManufacturerFilters.php deleted file mode 100644 index a1a948fb..00000000 --- a/src/Core/Search/Filters/ManufacturerFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class ManufacturerFilters is responsible for providing filter values for manufacturer grid. - */ -final class ManufacturerFilters extends Filters -{ - /** @var string */ - protected $filterId = ManufacturerGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/MerchandiseReturnFilters.php b/src/Core/Search/Filters/MerchandiseReturnFilters.php deleted file mode 100644 index f4cc97ac..00000000 --- a/src/Core/Search/Filters/MerchandiseReturnFilters.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\MerchandiseReturnGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Provides default filters for merchandise returns grid. - */ -final class MerchandiseReturnFilters extends Filters -{ - protected $filterId = MerchandiseReturnGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_order_return', - 'sortOrder' => 'ASC', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/MetaFilters.php b/src/Core/Search/Filters/MetaFilters.php deleted file mode 100644 index 67a95040..00000000 --- a/src/Core/Search/Filters/MetaFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class MetaFilters is responsible for providing default filter values for Seo & urls list. - */ -final class MetaFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_meta', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/DisabledProductFilters.php b/src/Core/Search/Filters/Monitoring/DisabledProductFilters.php deleted file mode 100644 index 6c893634..00000000 --- a/src/Core/Search/Filters/Monitoring/DisabledProductFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\DisabledProductGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product with combination grid. - */ -final class DisabledProductFilters extends Filters -{ - /** @var string */ - protected $filterId = DisabledProductGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/EmptyCategoryFilters.php b/src/Core/Search/Filters/Monitoring/EmptyCategoryFilters.php deleted file mode 100644 index 73607839..00000000 --- a/src/Core/Search/Filters/Monitoring/EmptyCategoryFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\EmptyCategoryGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for empty category grid. - */ -final class EmptyCategoryFilters extends Filters -{ - /** @var string */ - protected $filterId = EmptyCategoryGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/NoQtyProductWithCombinationFilters.php b/src/Core/Search/Filters/Monitoring/NoQtyProductWithCombinationFilters.php deleted file mode 100644 index b02c2568..00000000 --- a/src/Core/Search/Filters/Monitoring/NoQtyProductWithCombinationFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithCombinationGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product with combination grid. - */ -final class NoQtyProductWithCombinationFilters extends Filters -{ - /** @var string */ - protected $filterId = NoQtyProductWithCombinationGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/NoQtyProductWithoutCombinationFilters.php b/src/Core/Search/Filters/Monitoring/NoQtyProductWithoutCombinationFilters.php deleted file mode 100644 index 954d0f7c..00000000 --- a/src/Core/Search/Filters/Monitoring/NoQtyProductWithoutCombinationFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithoutCombinationGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product with combination grid. - */ -final class NoQtyProductWithoutCombinationFilters extends Filters -{ - /** @var string */ - protected $filterId = NoQtyProductWithoutCombinationGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/ProductWithoutDescriptionFilters.php b/src/Core/Search/Filters/Monitoring/ProductWithoutDescriptionFilters.php deleted file mode 100644 index 031c8d59..00000000 --- a/src/Core/Search/Filters/Monitoring/ProductWithoutDescriptionFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutDescriptionGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product without description grid. - */ -final class ProductWithoutDescriptionFilters extends Filters -{ - /** @var string */ - protected $filterId = ProductWithoutDescriptionGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/ProductWithoutImageFilters.php b/src/Core/Search/Filters/Monitoring/ProductWithoutImageFilters.php deleted file mode 100644 index d9ef11ff..00000000 --- a/src/Core/Search/Filters/Monitoring/ProductWithoutImageFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutImageGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product without image grid. - */ -final class ProductWithoutImageFilters extends Filters -{ - /** @var string */ - protected $filterId = ProductWithoutImageGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/Monitoring/ProductWithoutPriceFilters.php b/src/Core/Search/Filters/Monitoring/ProductWithoutPriceFilters.php deleted file mode 100644 index 9d74cfd9..00000000 --- a/src/Core/Search/Filters/Monitoring/ProductWithoutPriceFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters\Monitoring; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutPriceGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines default filters for product without price grid. - */ -final class ProductWithoutPriceFilters extends Filters -{ - /** @var string */ - protected $filterId = ProductWithoutPriceGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 20, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/OrderFilters.php b/src/Core/Search/Filters/OrderFilters.php deleted file mode 100644 index 0d1de207..00000000 --- a/src/Core/Search/Filters/OrderFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\OrderGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Stores filters for Order grid - */ -final class OrderFilters extends Filters -{ - /** @var string */ - protected $filterId = OrderGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_order', - 'sortOrder' => 'DESC', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/OrderMessageFilters.php b/src/Core/Search/Filters/OrderMessageFilters.php deleted file mode 100644 index 4eabd307..00000000 --- a/src/Core/Search/Filters/OrderMessageFilters.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\OrderMessageGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Defines filters for order message grid - */ -final class OrderMessageFilters extends Filters -{ - /** @var string */ - protected $filterId = OrderMessageGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_order_message', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/ProfileFilters.php b/src/Core/Search/Filters/ProfileFilters.php deleted file mode 100644 index 07e17720..00000000 --- a/src/Core/Search/Filters/ProfileFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class ProfilesFilters is responsible for providing default filter values for Profiles grid. - */ -final class ProfileFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'id_profile', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/RequestSqlFilters.php b/src/Core/Search/Filters/RequestSqlFilters.php deleted file mode 100644 index b04265bd..00000000 --- a/src/Core/Search/Filters/RequestSqlFilters.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -class RequestSqlFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 10, - 'offset' => 0, - 'orderBy' => 'id_request_sql', - 'sortOrder' => 'desc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/SupplierFilters.php b/src/Core/Search/Filters/SupplierFilters.php deleted file mode 100644 index 599e200b..00000000 --- a/src/Core/Search/Filters/SupplierFilters.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\SupplierGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class SupplierFilters defines default filters for Suppliers grid. - */ -final class SupplierFilters extends Filters -{ - /** - * @var string - */ - protected $filterId = SupplierGridDefinitionFactory::GRID_ID; - - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'name', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/TaxFilters.php b/src/Core/Search/Filters/TaxFilters.php deleted file mode 100644 index 40f4ecd9..00000000 --- a/src/Core/Search/Filters/TaxFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Provides default filters for taxes grid. - */ -final class TaxFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_tax', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/TaxRulesGroupFilters.php b/src/Core/Search/Filters/TaxRulesGroupFilters.php deleted file mode 100644 index fc05a7bd..00000000 --- a/src/Core/Search/Filters/TaxRulesGroupFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Provides default filters for tax rule groups grid. - */ -final class TaxRulesGroupFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_tax_rules_group', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/Filters/WebserviceKeyFilters.php b/src/Core/Search/Filters/WebserviceKeyFilters.php deleted file mode 100644 index dab930a0..00000000 --- a/src/Core/Search/Filters/WebserviceKeyFilters.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search\Filters; - -use PrestaShop\PrestaShop\Core\Search\Filters; - -/** - * Class WebserviceKeyFilters is responsible for providing default values for webservice account list. - */ -final class WebserviceKeyFilters extends Filters -{ - /** - * {@inheritdoc} - */ - public static function getDefaults() - { - return [ - 'limit' => 50, - 'offset' => 0, - 'orderBy' => 'id_webservice_account', - 'sortOrder' => 'asc', - 'filters' => [], - ]; - } -} diff --git a/src/Core/Search/SearchParameters.php b/src/Core/Search/SearchParameters.php deleted file mode 100644 index 54617724..00000000 --- a/src/Core/Search/SearchParameters.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Search; - -use PrestaShopBundle\Entity\AdminFilter; -use PrestaShopBundle\Entity\Repository\AdminFilterRepository; -use Symfony\Component\HttpFoundation\Request; - -/** - * Retrieve filters parameters if any from the User request. - * - * @deprecated Use FiltersBuilderInterface instead - */ -final class SearchParameters implements SearchParametersInterface -{ - /** - * @var AdminFilterRepository - */ - private $adminFilterRepository; - - public function __construct(AdminFilterRepository $adminFilterRepository) - { - $this->adminFilterRepository = $adminFilterRepository; - } - - /** - * {@inheritdoc} - */ - public function getFiltersFromRequest(Request $request, $filterClass) - { - $queryParams = $request->query->all(); - $requestParams = $request->request->all(); - - $parameters = []; - foreach (self::FILTER_TYPES as $type) { - if (isset($queryParams[$type])) { - $parameters[$type] = $queryParams[$type]; - } elseif (isset($requestParams[$type])) { - $parameters[$type] = $requestParams[$type]; - } - } - - return new $filterClass($parameters); - } - - /** - * {@inheritdoc} - */ - public function getFiltersFromRepository($employeeId, $shopId, $controller, $action, $filterClass) - { - /** @var AdminFilter $adminFilter */ - $adminFilter = $this->adminFilterRepository->findByEmployeeAndRouteParams( - $employeeId, - $shopId, - $controller, - $action - ); - - $parameters = null !== $adminFilter ? json_decode($adminFilter->getFilter(), true) : []; - - return new $filterClass($parameters); - } -} diff --git a/src/Core/Search/SearchParametersInterface.php b/src/Core/Search/SearchParametersInterface.php deleted file mode 100644 index 2e7dc588..00000000 --- a/src/Core/Search/SearchParametersInterface.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Security; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\IOException; - -/** - * Interface used to protect a folder (via htaccess file, index.php redirection file, ...) - */ -interface FolderGuardInterface -{ - /** - * @param string $folderPath - * - * @throws IOException - * @throws FileNotFoundException - */ - public function protectFolder($folderPath); -} diff --git a/src/Core/Security/HtaccessFolderGuard.php b/src/Core/Security/HtaccessFolderGuard.php deleted file mode 100644 index 3df7fe93..00000000 --- a/src/Core/Security/HtaccessFolderGuard.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Security; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\IOException; - -/** - * Class HtaccessFolderGuard protects a designated folder by inserting an htaccess file in it - * which prevents access from an external call. - */ -class HtaccessFolderGuard implements FolderGuardInterface -{ - /** - * @var string - */ - private $htaccessContent; - - /** - * @param string $htaccessTemplatePath - * - * @throws FileNotFoundException - */ - public function __construct($htaccessTemplatePath) - { - if (!file_exists($htaccessTemplatePath)) { - throw new FileNotFoundException(sprintf('Could not find file %s', $htaccessTemplatePath)); - } - $this->htaccessContent = file_get_contents($htaccessTemplatePath); - } - - /** - * {@inheritdoc} - */ - public function protectFolder($folderPath) - { - if (!is_dir($folderPath)) { - throw new FileNotFoundException(sprintf('Cannot protect nonexistent folder %s', $folderPath)); - } - - $htaccessPath = $folderPath . DIRECTORY_SEPARATOR . '.htaccess'; - if (!file_exists($htaccessPath)) { - if (!is_writable($folderPath)) { - throw new IOException('Could not write into module folder', 0, null, $folderPath); - } - - file_put_contents($htaccessPath, $this->htaccessContent); - } - } -} diff --git a/src/Core/Session/SessionInterface.php b/src/Core/Session/SessionInterface.php deleted file mode 100644 index de9d4d64..00000000 --- a/src/Core/Session/SessionInterface.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Session; - -/** - * SessionInterface is used to store/access to the session token used by customers and employees - */ -interface SessionInterface -{ - /** - * Returns session id - * - * @return int - */ - public function getId(); - - /** - * Set session user id - * - * @param int $id - * - * @return void - */ - public function setUserId($id); - - /** - * Returns session user id - * - * @return int - */ - public function getUserId(); - - /** - * Set session token - * - * @param string $string - * - * @return void - */ - public function setToken($string); - - /** - * Returns session token - * - * @return string - */ - public function getToken(); - - /** - * Adds current object to the database. - */ - public function add(); - - /** - * Deletes current object from database. - */ - public function delete(); -} diff --git a/src/Core/Shop/LogoUploader.php b/src/Core/Shop/LogoUploader.php deleted file mode 100644 index 20b82999..00000000 --- a/src/Core/Shop/LogoUploader.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Shop; - -use Configuration; -use Context; -use ImageManager; -use PrestaShopException; -use Shop; -use Tools; - -/** - * Class LogoUploader used to manage upload of Shop logos and favicon. - */ -class LogoUploader -{ - /** @var the shop */ - private $shop; - - /** - * @var array - */ - private $errors = []; - - public function __construct(Shop $shop) - { - $this->shop = $shop; - } - - public function updateHeader() - { - $this->update('PS_LOGO', 'logo'); - } - - public function updateMail() - { - $this->update('PS_LOGO_MAIL', 'logo_mail'); - } - - public function updateInvoice() - { - $this->update('PS_LOGO_INVOICE', 'logo_invoice'); - } - - public function updateFavicon() - { - $shopId = (int) $this->shop->id; - if ($shopId == Configuration::get('PS_SHOP_DEFAULT')) { - $this->uploadIco('PS_FAVICON', _PS_IMG_DIR_ . 'favicon.ico'); - } - if ($this->uploadIco('PS_FAVICON', _PS_IMG_DIR_ . 'favicon-' . $shopId . '.ico')) { - Configuration::updateValue('PS_FAVICON', 'favicon-' . $shopId . '.ico'); - } - - Configuration::updateGlobalValue('PS_FAVICON', 'favicon.ico'); - } - - /** - * Generic function which allows logo upload. - * - * @param $fieldName - * @param $logoPrefix - * @param $files[] the array of files to avoid use $_POST - * - * @return bool - * - * @throws PrestaShopException in case of upload failure - */ - public function update($fieldName, $logoPrefix, array $files = []) - { - $files = empty($files) ? $_FILES : $files; - - if (isset($files[$fieldName]['tmp_name'], $files[$fieldName]['tmp_name'], $files[$fieldName]['size'])) { - if ($error = ImageManager::validateUpload($files[$fieldName], Tools::getMaxUploadSize())) { - throw new PrestaShopException($error); - } - $tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS'); - - if (!$tmpName || !move_uploaded_file($files[$fieldName]['tmp_name'], $tmpName)) { - throw new PrestaShopException(sprintf('%Upload of temporary file to %s has failed.', $tmpName)); - } - - $fileExtension = ($fieldName == 'PS_STORES_ICON') ? '.gif' : '.jpg'; - $logoName = $this->getLogoName($logoPrefix, $fileExtension); - - if ($fieldName == 'PS_STORES_ICON') { - if (!@ImageManager::resize($tmpName, _PS_IMG_DIR_ . $logoName, null, null, 'gif', true)) { - throw new PrestaShopException(sprintf('An error occurred while attempting to copy shop icon %s.', $logoName)); - } - } else { - if (!@ImageManager::resize($tmpName, _PS_IMG_DIR_ . $logoName)) { - throw new PrestaShopException(sprintf('An error occurred while attempting to copy shop logo %s.', $logoName)); - } - } - - $idShop = $this->shop->id; - $idShopGroup = null; - - if (!count($this->errors) && @filemtime(_PS_IMG_DIR_ . Configuration::get($fieldName))) { - if (Shop::isFeatureActive()) { - $this->updateInMultiShopContext($idShop, $idShopGroup, $fieldName); - } else { - @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); - } - } - - Configuration::updateValue($fieldName, $logoName, false, $idShopGroup, $idShop); - unlink($tmpName); - - return true; - } - - return false; - } - - private function updateInMultiShopContext(&$idShop, &$idShopGroup, $fieldName) - { - if (Shop::getContext() == Shop::CONTEXT_SHOP) { - $idShop = Shop::getContextShopID(); - $idShopGroup = Shop::getContextShopGroupID(); - Shop::setContext(Shop::CONTEXT_ALL); - $logoAll = Configuration::get($fieldName); - Shop::setContext(Shop::CONTEXT_GROUP); - $logoGroup = Configuration::get($fieldName); - Shop::setContext(Shop::CONTEXT_SHOP); - $logoShop = Configuration::get($fieldName); - if ($logoAll != $logoShop && $logoGroup != $logoShop && $logoShop != false) { - @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); - } - } elseif (Shop::getContext() == Shop::CONTEXT_GROUP) { - $idShopGroup = Shop::getContextShopGroupID(); - Shop::setContext(Shop::CONTEXT_ALL); - $logoAll = Configuration::get($fieldName); - Shop::setContext(Shop::CONTEXT_GROUP); - if ($logoAll != Configuration::get($fieldName)) { - @unlink(_PS_IMG_DIR_ . Configuration::get($fieldName)); - } - } - } - - public function uploadIco($name, $destination, $files = []) - { - $files = empty($files) ? $_FILES : $files; - - if (isset($files[$name]['tmp_name']) && !empty($files[$name]['tmp_name'])) { - if ($error = ImageManager::validateIconUpload($files[$name])) { - throw new PrestaShopException($error); - } elseif (!copy($_FILES[$name]['tmp_name'], $destination)) { - throw new PrestaShopException(Context::getContext()->getTranslator()->trans('An error occurred while uploading the favicon: cannot copy file "%s" to folder "%s".', [$files[$name]['tmp_name'], $destination], 'Admin.Design.Notification')); - } - } - - return !count($this->errors); - } - - private function getLogoName($logoPrefix, $fileExtension) - { - $shopId = $this->shop->id; - $shopName = $this->shop->name; - - $logoName = Tools::link_rewrite($shopName) - . '-' - . $logoPrefix - . '-' - . (int) Configuration::get('PS_IMG_UPDATE_TIME') - . (int) $shopId . $fileExtension; - - if ($this->shop->getContext() == Shop::CONTEXT_ALL - || $shopId == 0 - || Shop::isFeatureActive() == false - ) { - $logoName = Tools::link_rewrite($shopName) - . '-' - . $logoPrefix . '-' . (int) Configuration::get('PS_IMG_UPDATE_TIME') . $fileExtension; - } - - return $logoName; - } -} diff --git a/src/Core/Shop/ShopContextInterface.php b/src/Core/Shop/ShopContextInterface.php deleted file mode 100644 index adbac93d..00000000 --- a/src/Core/Shop/ShopContextInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Shop; - -/** - * Interface ShopContextInterface - */ -interface ShopContextInterface -{ - /** - * Get name for context shop. - * - * @return string - */ - public function getShopName(); -} diff --git a/src/Core/Shop/Url/UrlProviderInterface.php b/src/Core/Shop/Url/UrlProviderInterface.php deleted file mode 100644 index 10293681..00000000 --- a/src/Core/Shop/Url/UrlProviderInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Shop\Url; - -/** - * Interface UrlProviderInterface - */ -interface UrlProviderInterface -{ - /** - * @return string - */ - public function getUrl(); -} diff --git a/src/Core/SqlManager/Configuration/SqlRequestConfiguration.php b/src/Core/SqlManager/Configuration/SqlRequestConfiguration.php deleted file mode 100644 index 7f65ea36..00000000 --- a/src/Core/SqlManager/Configuration/SqlRequestConfiguration.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\SqlManager\Configuration; - -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\SaveSqlRequestSettingsCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestSettingsConstraintException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestSettings; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestSettings; - -/** - * Class RequestSqlConfiguration is responsible for RequestSql configuration. - */ -final class SqlRequestConfiguration implements DataConfigurationInterface -{ - /** - * @var CommandBusInterface - */ - private $commandBus; - - /** - * @var CommandBusInterface - */ - private $queryBus; - - /** - * @param CommandBusInterface $commandBus - * @param CommandBusInterface $queryBus - */ - public function __construct( - CommandBusInterface $commandBus, - CommandBusInterface $queryBus - ) { - $this->commandBus = $commandBus; - $this->queryBus = $queryBus; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - /** @var SqlRequestSettings $sqlRequestSettings */ - $sqlRequestSettings = $this->queryBus->handle(new GetSqlRequestSettings()); - - return [ - 'default_file_encoding' => $sqlRequestSettings->getFileEncoding(), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if ($this->validateConfiguration($configuration)) { - try { - $command = new SaveSqlRequestSettingsCommand( - $configuration['default_file_encoding'] - ); - - $this->commandBus->handle($command); - } catch (SqlRequestSettingsConstraintException $e) { - $errors = $this->handleUpdateException($e); - } - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset($configuration['default_file_encoding']); - } - - /** - * Handle exception when configuration update fails. - * - * @param SqlRequestSettingsConstraintException $e - * - * @return array Array of errors - */ - private function handleUpdateException(SqlRequestSettingsConstraintException $e) - { - $code = $e->getCode(); - - $errorMessages = [ - SqlRequestSettingsConstraintException::INVALID_FILE_ENCODING => [ - 'key' => 'The %s field is invalid.', - 'parameters' => ['default_file_encoding'], - 'domain' => 'Admin.Notifications.Error', - ], - SqlRequestSettingsConstraintException::NOT_SUPPORTED_FILE_ENCODING => [ - 'key' => 'The %s field is invalid.', - 'parameters' => ['default_file_encoding'], - 'domain' => 'Admin.Notifications.Error', - ], - ]; - - return $errorMessages[$code]; - } -} diff --git a/src/Core/SqlManager/Exporter/SqlRequestExporter.php b/src/Core/SqlManager/Exporter/SqlRequestExporter.php deleted file mode 100644 index c5fef12e..00000000 --- a/src/Core/SqlManager/Exporter/SqlRequestExporter.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\SqlManager\Exporter; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; -use PrestaShop\PrestaShop\Core\Export\Data\ExportableData; -use PrestaShop\PrestaShop\Core\Export\FileWriter\FileWriterInterface; - -/** - * Class SqlRequestExporter exports SqlRequest query execution result into CSV file under export directory. - */ -final class SqlRequestExporter implements SqlRequestExporterInterface -{ - /** - * @var FileWriterInterface - */ - private $csvFileWriter; - - /** - * @param FileWriterInterface $csvFileWriter - */ - public function __construct(FileWriterInterface $csvFileWriter) - { - $this->csvFileWriter = $csvFileWriter; - } - - /** - * {@inheritdoc} - */ - public function exportToFile(SqlRequestId $sqlRequestId, SqlRequestExecutionResult $result) - { - $exportData = new ExportableData( - $result->getColumns(), - $result->getRows() - ); - - $exportFileName = sprintf('request_sql_%s.csv', $sqlRequestId->getValue()); - - return $this->csvFileWriter->write($exportFileName, $exportData); - } -} diff --git a/src/Core/SqlManager/Exporter/SqlRequestExporterInterface.php b/src/Core/SqlManager/Exporter/SqlRequestExporterInterface.php deleted file mode 100644 index 37a453a6..00000000 --- a/src/Core/SqlManager/Exporter/SqlRequestExporterInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\SqlManager\Exporter; - -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; -use SplFileInfo; - -/** - * Interface SqlRequestExporterInterface defines contract for SqlRequest exporter. - */ -interface SqlRequestExporterInterface -{ - /** - * Export SqlRequest query execution result to file. - * - * @param SqlRequestId $sqlRequestId - * @param SqlRequestExecutionResult $sqlRequestExecutionResult - * - * @return SplFileInfo - */ - public function exportToFile(SqlRequestId $sqlRequestId, SqlRequestExecutionResult $sqlRequestExecutionResult); -} diff --git a/src/Core/Stock/StockManager.php b/src/Core/Stock/StockManager.php deleted file mode 100644 index c9d5dea7..00000000 --- a/src/Core/Stock/StockManager.php +++ /dev/null @@ -1,419 +0,0 @@ - - * @copyright 2007-2019 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - * International Registered Trademark & Property of PrestaShop SA - */ - -namespace PrestaShop\PrestaShop\Core\Stock; - -use Access; -use Combination; -use Configuration; -use Context; -use DateTime; -use Employee; -use Mail; -use Pack; -use PrestaShop\PrestaShop\Adapter\LegacyContext as ContextAdapter; -use PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider; -use PrestaShop\PrestaShop\Adapter\ServiceLocator; -use PrestaShop\PrestaShop\Adapter\SymfonyContainer; -use PrestaShopBundle\Entity\StockMvt; -use Product; -use StockAvailable; - -/** - * Class StockManager Refactored features about product stocks. - */ -class StockManager -{ - /** - * This will update a Pack quantity and will decrease the quantity of containing Products if needed. - * - * @param Product $product A product pack object to update its quantity - * @param StockAvailable $stock_available the stock of the product to fix with correct quantity - * @param int $delta_quantity The movement of the stock (negative for a decrease) - * @param int|null $id_shop Optional shop ID - */ - public function updatePackQuantity($product, $stock_available, $delta_quantity, $id_shop = null) - { - /** @TODO We should call the needed classes with the Symfony dependency injection instead of the Homemade Service Locator */ - $serviceLocator = new ServiceLocator(); - $configuration = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Core\\ConfigurationInterface'); - - if ($product->pack_stock_type == Pack::STOCK_TYPE_PRODUCTS_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ($product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && $configuration->get('PS_PACK_STOCK_TYPE') > 0) - ) { - $packItemsManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\Product\\PackItemsManager'); - $stockManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\StockManager'); - $cacheManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\CacheManager'); - - $products_pack = $packItemsManager->getPackItems($product); - foreach ($products_pack as $product_pack) { - $productStockAvailable = $stockManager->getStockAvailableByProduct($product_pack, $product_pack->id_pack_product_attribute, $id_shop); - $productStockAvailable->quantity = $productStockAvailable->quantity + ($delta_quantity * $product_pack->pack_quantity); - $productStockAvailable->update(); - - $cacheManager->clean('StockAvailable::getQuantityAvailableByProduct_' . (int) $product_pack->id . '*'); - } - } - - $stock_available->quantity = $stock_available->quantity + $delta_quantity; - - if ($product->pack_stock_type == Pack::STOCK_TYPE_PACK_ONLY - || $product->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH - || ( - $product->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && ($configuration->get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_ONLY - || $configuration->get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_BOTH) - ) - ) { - $stock_available->update(); - } - } - - /** - * This will decrease (if needed) Packs containing this product - * (with the right declination) if there is not enough product in stocks. - * - * @param Product $product A product object to update its quantity - * @param int $id_product_attribute The product attribute to update - * @param StockAvailable $stock_available the stock of the product to fix with correct quantity - * @param int|null $id_shop Optional shop ID - */ - public function updatePacksQuantityContainingProduct($product, $id_product_attribute, $stock_available, $id_shop = null) - { - /** @TODO We should call the needed classes with the Symfony dependency injection instead of the Homemade Service Locator */ - $serviceLocator = new ServiceLocator(); - - $configuration = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Core\\ConfigurationInterface'); - $packItemsManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\Product\\PackItemsManager'); - $stockManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\StockManager'); - $cacheManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\CacheManager'); - - $packs = $packItemsManager->getPacksContainingItem($product, $id_product_attribute); - foreach ($packs as $pack) { - // Decrease stocks of the pack only if pack is in linked stock mode (option called 'Decrement both') - if (!((int) $pack->pack_stock_type == Pack::STOCK_TYPE_PACK_BOTH) - && !((int) $pack->pack_stock_type == Pack::STOCK_TYPE_DEFAULT - && $configuration->get('PS_PACK_STOCK_TYPE') == Pack::STOCK_TYPE_PACK_BOTH) - ) { - continue; - } - - // Decrease stocks of the pack only if there is not enough items to make the actual pack stocks. - - // How many packs can be made with the remaining product stocks - $quantity_by_pack = $pack->pack_item_quantity; - $max_pack_quantity = max(array(0, floor($stock_available->quantity / $quantity_by_pack))); - - $stock_available_pack = $stockManager->getStockAvailableByProduct($pack, null, $id_shop); - if ($stock_available_pack->quantity > $max_pack_quantity) { - $stock_available_pack->quantity = $max_pack_quantity; - $stock_available_pack->update(); - - $cacheManager->clean('StockAvailable::getQuantityAvailableByProduct_' . (int) $pack->id . '*'); - } - } - } - - /** - * Will update Product available stock int he given declinaison. If product is a Pack, could decrease the sub products. - * If Product is contained in a Pack, Pack could be decreased or not (only if sub product stocks become not sufficient). - * - * @param Product $product The product to update its stockAvailable - * @param int $id_product_attribute The declinaison to update (null if not) - * @param int $delta_quantity The quantity change (positive or negative) - * @param int|null $id_shop Optional - * @param bool $add_movement Optional - * @param array $params Optional - */ - public function updateQuantity($product, $id_product_attribute, $delta_quantity, $id_shop = null, $add_movement = false, $params = array()) - { - /** @TODO We should call the needed classes with the Symfony dependency injection instead of the Homemade Service Locator */ - $serviceLocator = new ServiceLocator(); - $stockManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\StockManager'); - $packItemsManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\Product\\PackItemsManager'); - $cacheManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\CacheManager'); - $hookManager = $serviceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\HookManager'); - - $stockAvailable = $stockManager->getStockAvailableByProduct($product, $id_product_attribute, $id_shop); - - // Update quantity of the pack products - if ($packItemsManager->isPack($product)) { - // The product is a pack - $this->updatePackQuantity($product, $stockAvailable, $delta_quantity, $id_shop); - } else { - // The product is not a pack - $stockAvailable->quantity = $stockAvailable->quantity + $delta_quantity; - $stockAvailable->update(); - - // Decrease case only: the stock of linked packs should be decreased too. - if ($delta_quantity < 0) { - // The product is not a pack, but the product combination is part of a pack (use of isPacked, not isPack) - if ($packItemsManager->isPacked($product, $id_product_attribute)) { - $this->updatePacksQuantityContainingProduct($product, $id_product_attribute, $stockAvailable, $id_shop); - } - } - } - - // Prepare movement and save it - if (true === $add_movement && 0 != $delta_quantity) { - $this->saveMovement($product->id, $id_product_attribute, $delta_quantity, $params); - } - - $hookManager->exec( - 'actionUpdateQuantity', - array( - 'id_product' => $product->id, - 'id_product_attribute' => $id_product_attribute, - 'quantity' => $stockAvailable->quantity, - ) - ); - - if ($this->checkIfMustSendLowStockAlert($product, $id_product_attribute, $stockAvailable->quantity)) { - $this->sendLowStockAlert($product, $id_product_attribute, $stockAvailable->quantity); - } - - $cacheManager->clean('StockAvailable::getQuantityAvailableByProduct_' . (int) $product->id . '*'); - } - - /** - * @param Product $product - * @param int $id_product_attribute - * @param int $newQuantity - * - * @return bool - */ - protected function checkIfMustSendLowStockAlert($product, $id_product_attribute, $newQuantity) - { - if (!Configuration::get('PS_STOCK_MANAGEMENT')) { - return false; - } - - // Do not send mail if multiples product are created / imported. - if (defined('PS_MASS_PRODUCT_CREATION')) { - return false; - } - - $productHasAttributes = $product->hasAttributes(); - if ($productHasAttributes && $id_product_attribute) { - $combination = new Combination($id_product_attribute); - - return $this->isCombinationQuantityUnderAlertThreshold($combination, $newQuantity); - } elseif (!$productHasAttributes && !$id_product_attribute) { - return $this->isProductQuantityUnderAlertThreshold($product, $newQuantity); - } - - return false; - } - - /** - * @param Product $product - * @param int $newQuantity - * - * @return bool - */ - protected function isProductQuantityUnderAlertThreshold($product, $newQuantity) - { - // low_stock_threshold empty to disable (can be negative, null or zero) - if ($product->low_stock_alert - && $product->low_stock_threshold !== '' - && $product->low_stock_threshold !== null - && $newQuantity <= (int) $product->low_stock_threshold - ) { - return true; - } - - return false; - } - - /** - * @param Combination $combination - * @param int $newQuantity - * - * @return bool - */ - protected function isCombinationQuantityUnderAlertThreshold(Combination $combination, $newQuantity) - { - // low_stock_threshold empty to disable (can be negative, null or zero) - if ($combination->low_stock_alert - && $combination->low_stock_threshold !== '' - && $combination->low_stock_threshold !== null - && $newQuantity <= (int) $combination->low_stock_threshold - ) { - return true; - } - - return false; - } - - /** - * @param Product $product - * @param int $id_product_attribute - * @param int $newQuantity - * - * @throws \Exception - * @throws \PrestaShopException - */ - protected function sendLowStockAlert($product, $id_product_attribute, $newQuantity) - { - $context = Context::getContext(); - $idShop = (int) $context->shop->id; - $idLang = (int) $context->language->id; - $configuration = Configuration::getMultiple( - array( - 'MA_LAST_QTIES', - 'PS_STOCK_MANAGEMENT', - 'PS_SHOP_EMAIL', - 'PS_SHOP_NAME', - ), - null, - null, - $idShop - ); - $productName = Product::getProductName($product->id, $id_product_attribute, $idLang); - if ($id_product_attribute) { - $combination = new Combination($id_product_attribute); - $lowStockThreshold = $combination->low_stock_threshold; - } else { - $lowStockThreshold = $product->low_stock_threshold; - } - $templateVars = array( - '{qty}' => $newQuantity, - '{last_qty}' => $lowStockThreshold, - '{product}' => $productName, - ); - // get emails on employees who have right to run stock page - $emails = array(); - $employees = Employee::getEmployees(); - foreach ($employees as $employeeData) { - $employee = new Employee($employeeData['id_employee']); - if (Access::isGranted('ROLE_MOD_TAB_ADMINSTOCKMANAGEMENT_READ', $employee->id_profile)) { - $emails[] = $employee->email; - } - } - // Send 1 email by merchant mail, because Mail::Send doesn't work with an array of recipients - foreach ($emails as $email) { - Mail::Send( - $idLang, - 'productoutofstock', - Mail::l('Niski stan magazynowy produktu', $idLang), - $templateVars, - $email, - null, - (string) $configuration['PS_SHOP_EMAIL'], - (string) $configuration['PS_SHOP_NAME'], - null, - null, - dirname(__FILE__) . '/mails/', - false, - $idShop - ); - } - } - - /** - * Public method to save a Movement. - * - * @param $productId - * @param $productAttributeId - * @param $deltaQuantity - * @param array $params - * - * @return bool - */ - public function saveMovement($productId, $productAttributeId, $deltaQuantity, $params = array()) - { - if ($deltaQuantity != 0) { - $stockMvt = $this->prepareMovement($productId, $productAttributeId, $deltaQuantity, $params); - - if ($stockMvt) { - $sfContainer = SymfonyContainer::getInstance(); - if (null !== $sfContainer) { - $stockMvtRepository = $sfContainer->get('prestashop.core.api.stock_movement.repository'); - - return $stockMvtRepository->saveStockMvt($stockMvt); - } - } - } - - return false; - } - - /** - * Prepare a Movement for registration. - * - * @param $productId - * @param $productAttributeId - * @param $deltaQuantity - * @param array $params - * - * @return bool|StockMvt - */ - private function prepareMovement($productId, $productAttributeId, $deltaQuantity, $params = array()) - { - $product = (new ProductDataProvider())->getProductInstance($productId); - - if ($product->id) { - $stockManager = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Adapter\\StockManager'); - $stockAvailable = $stockManager->getStockAvailableByProduct($product, $productAttributeId); - - if ($stockAvailable->id) { - $stockMvt = new StockMvt(); - - $stockMvt->setIdStock((int) $stockAvailable->id); - - if (!empty($params['id_order'])) { - $stockMvt->setIdOrder((int) $params['id_order']); - } - - if (!empty($params['id_stock_mvt_reason'])) { - $stockMvt->setIdStockMvtReason((int) $params['id_stock_mvt_reason']); - } - - if (!empty($params['id_supply_order'])) { - $stockMvt->setIdSupplyOrder((int) $params['id_supply_order']); - } - - $stockMvt->setSign($deltaQuantity >= 1 ? 1 : -1); - $stockMvt->setPhysicalQuantity(abs($deltaQuantity)); - - $stockMvt->setDateAdd(new DateTime()); - - $employee = (new ContextAdapter())->getContext()->employee; - if (!empty($employee)) { - $stockMvt->setIdEmployee($employee->id); - $stockMvt->setEmployeeFirstname($employee->firstname); - $stockMvt->setEmployeeLastname($employee->lastname); - } - - return $stockMvt; - } - } - - return false; - } -} diff --git a/src/Core/String/CharacterCleaner.php b/src/Core/String/CharacterCleaner.php deleted file mode 100644 index c74a0e88..00000000 --- a/src/Core/String/CharacterCleaner.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\String; - -class CharacterCleaner -{ - /** - * Delete unicode class from regular expression patterns. - * - * @param string $pattern - * - * @return string pattern - */ - public function cleanNonUnicodeSupport($pattern) - { - if (!defined('PREG_BAD_UTF8_OFFSET')) { - return $pattern; - } - - return preg_replace('/\\\[px]\{[a-z]{1,2}\}|(\/[a-z]*)u([a-z]*)$/i', '$1$2', $pattern); - } -} diff --git a/src/Core/Support/ContactRepositoryInterface.php b/src/Core/Support/ContactRepositoryInterface.php deleted file mode 100644 index e9f857cb..00000000 --- a/src/Core/Support/ContactRepositoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Support; - -/** - * Interface ContactRepositoryInterface defines contract for shop contact repository. - */ -interface ContactRepositoryInterface -{ - /** - * Get shop contacts. - * - * @param int $langId Language ID in which contacts should be returned - * - * @return array - */ - public function findAllByLangId($langId); -} diff --git a/src/Core/Tax/Ecotax/ProductEcotaxResetterInterface.php b/src/Core/Tax/Ecotax/ProductEcotaxResetterInterface.php deleted file mode 100644 index 2d47c674..00000000 --- a/src/Core/Tax/Ecotax/ProductEcotaxResetterInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Tax\Ecotax; - -/** - * Resets Ecotax for products - */ -interface ProductEcotaxResetterInterface -{ - /** - * Resets ecotax for all products - */ - public function reset(); -} diff --git a/src/Core/Tax/TaxOptionsConfiguration.php b/src/Core/Tax/TaxOptionsConfiguration.php deleted file mode 100644 index f693918d..00000000 --- a/src/Core/Tax/TaxOptionsConfiguration.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Tax; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Tax\Ecotax\ProductEcotaxResetterInterface; - -/** - * Handles configuration data for tax options. - */ -final class TaxOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - /** - * @var ProductEcotaxResetterInterface - */ - private $productEcotaxResetter; - - /** - * @param ConfigurationInterface $configuration - * @param ProductEcotaxResetterInterface $productEcotaxResetter - */ - public function __construct( - ConfigurationInterface $configuration, - ProductEcotaxResetterInterface $productEcotaxResetter - ) { - $this->configuration = $configuration; - $this->productEcotaxResetter = $productEcotaxResetter; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'enable_tax' => (bool) $this->configuration->get('PS_TAX'), - 'display_tax_in_cart' => (bool) $this->configuration->get('PS_TAX_DISPLAY'), - 'tax_address_type' => $this->configuration->get('PS_TAX_ADDRESS_TYPE'), - 'use_eco_tax' => (bool) $this->configuration->get('PS_USE_ECOTAX'), - 'eco_tax_rule_group' => $this->configuration->get('PS_ECOTAX_TAX_RULES_GROUP_ID'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_TAX', (bool) $configuration['enable_tax']); - $this->configuration->set('PS_TAX_DISPLAY', (bool) $configuration['display_tax_in_cart']); - $this->configuration->set('PS_TAX_ADDRESS_TYPE', $configuration['tax_address_type']); - $this->updateEcotax($configuration['use_eco_tax']); - - if ($configuration['use_eco_tax'] && isset($configuration['eco_tax_rule_group'])) { - $this->configuration->set('PS_ECOTAX_TAX_RULES_GROUP_ID', $configuration['eco_tax_rule_group']); - } - - if (false === $configuration['enable_tax']) { - $this->configuration->set('PS_TAX_DISPLAY', false); - } - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['enable_tax'], - $configuration['tax_address_type'], - $configuration['use_eco_tax'] - ); - } - - /** - * Responsible for ecotax update - * - * @param bool $isEnabled - */ - private function updateEcotax($isEnabled) - { - $wasEnabled = (bool) $this->configuration->get('PS_USE_ECOTAX'); - - if (!$isEnabled && $wasEnabled !== $isEnabled) { - $this->productEcotaxResetter->reset(); - } - $this->configuration->set('PS_USE_ECOTAX', $isEnabled); - } -} diff --git a/src/Core/Team/Employee/Configuration/EmployeeOptionsConfiguration.php b/src/Core/Team/Employee/Configuration/EmployeeOptionsConfiguration.php deleted file mode 100644 index 8e172164..00000000 --- a/src/Core/Team/Employee/Configuration/EmployeeOptionsConfiguration.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Team\Employee\Configuration; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; - -/** - * Class EmployeeOptionsConfiguration handles configuration data for employee options. - */ -final class EmployeeOptionsConfiguration implements DataConfigurationInterface -{ - /** - * @var ConfigurationInterface - */ - private $configuration; - - /** - * @var OptionsCheckerInterface - */ - private $optionsChecker; - - /** - * @param ConfigurationInterface $configuration - */ - public function __construct(ConfigurationInterface $configuration, OptionsCheckerInterface $optionsChecker) - { - $this->configuration = $configuration; - $this->optionsChecker = $optionsChecker; - } - - /** - * {@inheritdoc} - */ - public function getConfiguration() - { - return [ - 'password_change_time' => (int) $this->configuration->get('PS_PASSWD_TIME_BACK'), - 'allow_employee_specific_language' => (int) $this->configuration->get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG'), - ]; - } - - /** - * {@inheritdoc} - */ - public function updateConfiguration(array $configuration) - { - $errors = []; - - if (!$this->optionsChecker->canBeChanged()) { - $errors[] = [ - 'key' => 'You cannot change the value of this configuration field in the context of this shop.', - 'parameters' => [], - 'domain' => 'Admin.Notifications.Warning', - ]; - - return $errors; - } - - if ($this->validateConfiguration($configuration)) { - $this->configuration->set('PS_PASSWD_TIME_BACK', (int) $configuration['password_change_time']); - $this->configuration->set( - 'PS_BO_ALLOW_EMPLOYEE_FORM_LANG', - (bool) $configuration['allow_employee_specific_language'] - ); - } - - return $errors; - } - - /** - * {@inheritdoc} - */ - public function validateConfiguration(array $configuration) - { - return isset( - $configuration['password_change_time'], - $configuration['allow_employee_specific_language'] - ); - } -} diff --git a/src/Core/Team/Employee/Configuration/OptionsChecker.php b/src/Core/Team/Employee/Configuration/OptionsChecker.php deleted file mode 100644 index 60dcdfe8..00000000 --- a/src/Core/Team/Employee/Configuration/OptionsChecker.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Team\Employee\Configuration; - -use PrestaShop\PrestaShop\Core\Feature\FeatureInterface; -use PrestaShop\PrestaShop\Core\Multistore\MultistoreContextCheckerInterface; - -/** - * Class OptionsChecker checks if employee options can be changed depending on current shop context. - */ -final class OptionsChecker implements OptionsCheckerInterface -{ - /** - * @var FeatureInterface - */ - private $multistoreFeature; - - /** - * @var MultistoreContextCheckerInterface - */ - private $multistoreContextChecker; - - /** - * @param FeatureInterface $multistoreFeature - * @param MultistoreContextCheckerInterface $multistoreContextChecker - */ - public function __construct( - FeatureInterface $multistoreFeature, - MultistoreContextCheckerInterface $multistoreContextChecker - ) { - $this->multistoreFeature = $multistoreFeature; - $this->multistoreContextChecker = $multistoreContextChecker; - } - - /** - * {@inheritdoc} - */ - public function canBeChanged() - { - if (!$this->multistoreFeature->isUsed() - && $this->multistoreContextChecker->isSingleShopContext() - ) { - return true; - } - - return $this->multistoreContextChecker->isAllShopContext(); - } -} diff --git a/src/Core/Team/Employee/Configuration/OptionsCheckerInterface.php b/src/Core/Team/Employee/Configuration/OptionsCheckerInterface.php deleted file mode 100644 index fbb451bb..00000000 --- a/src/Core/Team/Employee/Configuration/OptionsCheckerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Team\Employee\Configuration; - -/** - * Interface OptionsCheckerInterface. - */ -interface OptionsCheckerInterface -{ - /** - * Check if employee options can be changed. - * - * @return bool - */ - public function canBeChanged(); -} diff --git a/src/Core/Translation/Locale/Converter.php b/src/Core/Translation/Locale/Converter.php deleted file mode 100644 index eeefd043..00000000 --- a/src/Core/Translation/Locale/Converter.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Translation\Locale; - -/** - * Helper to manipulate the locales (IETF language tag) specific to PrestaShop - * - * @doc https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags - */ -final class Converter -{ - /** - * @var string the path to the JSON file responsible of mapping between lang and locale - */ - private $translationsMappingFile; - - /** - * @param string $translationsMappingFile - */ - public function __construct($translationsMappingFile) - { - $this->translationsMappingFile = $translationsMappingFile; - } - - /** - * @var string the locale (like "fr-FR") - * - * @return string|bool the legacy PrestaShop locale (like "fr") - */ - public function toLegacyLocale($locale) - { - return array_search($locale, $this->getLangToLocalesMapping()); - } - - /** - * @param string $legacyLocale the legacy PrestaShop locale - * - * @return string|bool the locale - */ - public function toLanguageTag($legacyLocale) - { - $mappingLocales = $this->getLangToLocalesMapping(); - - return isset($mappingLocales[$legacyLocale]) ? $mappingLocales[$legacyLocale] : false; - } - - /** - * Get the PrestaShop locale from real locale (like "fr-FR") - * - * @return string The PrestaShop locale (like "fr_FR") - */ - public static function toPrestaShopLocale($locale) - { - return str_replace('-', '_', $locale); - } - - /** - * Extracted from TranslationService class - * - * @return mixed - * - * @throws Exception - */ - private function getLangToLocalesMapping() - { - $legacyToStandardLocalesJson = file_get_contents($this->translationsMappingFile); - $legacyToStandardLocales = json_decode($legacyToStandardLocalesJson, true); - - $jsonLastErrorCode = json_last_error(); - if (JSON_ERROR_NONE !== $jsonLastErrorCode) { - throw new Exception('The legacy to standard locales JSON could not be decoded', $jsonLastErrorCode); - } - - return $legacyToStandardLocales; - } -} diff --git a/src/Core/Util/ArabicToLatinDigitConverter.php b/src/Core/Util/ArabicToLatinDigitConverter.php deleted file mode 100644 index 6e6d9b85..00000000 --- a/src/Core/Util/ArabicToLatinDigitConverter.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Util; - -/** - * Utility class to convert arabic/persian digits to latin digits - */ -class ArabicToLatinDigitConverter -{ - public const ARABIC = 1; - - public const PERSIAN = 2; - - private const TRANSLATION_TABLE = [ - // arabic numbers - '٠' => '0', - '١' => '1', - '٢' => '2', - '٣' => '3', - '٤' => '4', - '٥' => '5', - '٦' => '6', - '٧' => '7', - '٨' => '8', - '٩' => '9', - // persian numbers (NOT the same UTF codes!) - '۰' => '0', - '۱' => '1', - '۲' => '2', - '۳' => '3', - '۴' => '4', - '۵' => '5', - '۶' => '6', - '۷' => '7', - '۸' => '8', - '۹' => '9', - ]; - - /** - * Convert from arabic/persian digits to latin digits - * - * @param string $str - * - * @return string - */ - public function convert(string $str): string - { - return strtr($str, self::TRANSLATION_TABLE); - } - - /** - * Convert from latin digits to arabic or persian digits - * - * @param string $str - * @param int $lang - * - * @return string - */ - public function reverseConvert(string $str, int $lang = self::ARABIC): string - { - $table = array_slice(self::TRANSLATION_TABLE, $lang === self::ARABIC ? 0 : 10, 10, true); - - return strtr($str, array_flip($table)); - } -} diff --git a/src/Core/Util/BoolParser.php b/src/Core/Util/BoolParser.php deleted file mode 100644 index ea090f61..00000000 --- a/src/Core/Util/BoolParser.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util; - -class BoolParser -{ - /** - * @param string|int $value - * - * @return bool - */ - public static function castToBool($value) - { - if (is_bool($value)) { - return $value; - } - if (is_numeric($value)) { - return (bool) $value; // 0 => false; all other true - } - - return strtolower($value) !== 'false'; - } -} diff --git a/src/Core/Util/ColorBrightnessCalculator.php b/src/Core/Util/ColorBrightnessCalculator.php deleted file mode 100644 index 41bd2e29..00000000 --- a/src/Core/Util/ColorBrightnessCalculator.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util; - -/** - * Calculates color brightness - */ -final class ColorBrightnessCalculator -{ - /** - * Minimum color value after which it's considered bright - */ - public const BRIGHT_COLOR_MIN = 130; - - /** - * @param string $hexColor - * - * @return bool - */ - public function isBright($hexColor) - { - return $this->calculate($hexColor) >= self::BRIGHT_COLOR_MIN; - } - - /** - * @param $hexColor - * - * @return float|int - */ - private function calculate($hexColor) - { - if (strtolower($hexColor) === 'transparent') { - return self::BRIGHT_COLOR_MIN; - } - - $hexColor = str_replace('#', '', $hexColor); - - if (strlen($hexColor) === 3) { - $hexColor .= $hexColor; - } - - $r = hexdec(substr($hexColor, 0, 2)); - $g = hexdec(substr($hexColor, 2, 2)); - $b = hexdec(substr($hexColor, 4, 2)); - - return (($r * 299) + ($g * 587) + ($b * 114)) / 1000; - } -} diff --git a/src/Core/Util/DateTime/DateTime.php b/src/Core/Util/DateTime/DateTime.php deleted file mode 100644 index d71eb88b..00000000 --- a/src/Core/Util/DateTime/DateTime.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\DateTime; - -use RuntimeException; - -/** - * Defines reusable values for DateTime - */ -final class DateTime -{ - /** - * DateTime value which should be considered same as null - */ - const NULL_VALUE = '0000-00-00 00:00:00'; - - /** - * This class only defines constants and has no reason to be initialized - */ - public function __construct() - { - throw new RuntimeException(sprintf('This class purpose is to define constants only. You might have mistaken it with "%s"', \DateTime::class)); - } -} diff --git a/src/Core/Util/DateTime/TimeDefinition.php b/src/Core/Util/DateTime/TimeDefinition.php deleted file mode 100644 index 47a71245..00000000 --- a/src/Core/Util/DateTime/TimeDefinition.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\DateTime; - -/** - * Class TimeDefinition defines common time intervals in different formats. - */ -final class TimeDefinition -{ - const HOUR_IN_SECONDS = 3600; - const DAY_IN_SECONDS = 86400; - - /** - * Object is not suppose to be initialized as it's responsibility is to define time constants. - */ - private function __construct() - { - } -} diff --git a/src/Core/Util/File/FileSizeConverter.php b/src/Core/Util/File/FileSizeConverter.php deleted file mode 100644 index 6ea27694..00000000 --- a/src/Core/Util/File/FileSizeConverter.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\File; - -/** - * Converts int value to formatted file size value - */ -class FileSizeConverter -{ - /** - * @param int $bytes - * @param int $precision - * - * @return string - */ - public function convert(int $bytes, int $precision = 2): string - { - $units = ['B', 'kB', 'MB', 'GB', 'TB']; - $bytes = max($bytes, 0); - $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); - $pow = min($pow, count($units) - 1); - - if ($bytes >= 1024) { - $bytes /= pow(1024, $pow); - $bytes = number_format(round($bytes, $precision), 2, '.', ''); - } - - return $bytes . $units[$pow]; - } -} diff --git a/src/Core/Util/File/YamlParser.php b/src/Core/Util/File/YamlParser.php deleted file mode 100644 index 2ed0337a..00000000 --- a/src/Core/Util/File/YamlParser.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\File; - -use InvalidArgumentException; -use RuntimeException; -use Symfony\Component\Config\ConfigCache; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Yaml; - -/** - * This class adds a cache layer on top of the standard Yaml parser for improved performance - */ -final class YamlParser -{ - /** - * @var string - */ - private $cacheDir; - - /** - * @var bool - */ - private $useCache; - - /** - * YamlParser constructor. - * - * @param string $cacheDir - * @param bool $useCache - */ - public function __construct($cacheDir, $useCache = true) - { - $this->cacheDir = $cacheDir; - $this->useCache = $useCache; - } - - /** - * Parse a YAML File and return the result - * - * @param string $sourceFile - * @param bool $forceRefresh - * - * @return mixed The YAML converted to a PHP value - * - * @throws InvalidArgumentException - * @throws RuntimeException - * @throws ParseException - */ - public function parse($sourceFile, $forceRefresh = false) - { - if (!$this->useCache) { - return Yaml::parseFile($sourceFile); - } - - $phpConfigFile = $this->getCacheFile($sourceFile); - // we set the debug flag to true to force the cache freshness check - $configCache = new ConfigCache($phpConfigFile, true); - if (!$forceRefresh && $configCache->isFresh()) { - return require $phpConfigFile; - } - - $config = Yaml::parseFile($sourceFile); - $resources = [ - new FileResource($sourceFile), - ]; - $configCache->write('cacheDir, - md5($sourceFile) - ); - } -} diff --git a/src/Core/Util/HelperCard/DocumentationLinkProvider.php b/src/Core/Util/HelperCard/DocumentationLinkProvider.php deleted file mode 100644 index 622c64a3..00000000 --- a/src/Core/Util/HelperCard/DocumentationLinkProvider.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\HelperCard; - -/** - * Class HelperCardDocumentationLinkProvider provides documentation links for helper cards. - */ -final class DocumentationLinkProvider implements DocumentationLinkProviderInterface -{ - /** - * @var string - */ - private $contextLangIsoCode; - - /** - * @var array - */ - private $documentationLinks; - - /** - * @param string $contextLangIsoCode - * @param array $documentationLinks - */ - public function __construct( - $contextLangIsoCode, - array $documentationLinks - ) { - $this->contextLangIsoCode = $contextLangIsoCode; - $this->documentationLinks = $documentationLinks; - } - - /** - * {@inheritdoc} - */ - public function getLink($cardType) - { - if (isset($this->documentationLinks[$cardType])) { - $cardLinks = $this->documentationLinks[$cardType]; - - if (isset($cardLinks[$this->contextLangIsoCode])) { - return $cardLinks[$this->contextLangIsoCode]; - } - - if (isset($cardLinks['_fallback'])) { - return $cardLinks['_fallback']; - } - } - - throw new HelperCardDocumentationDoesNotExistException(sprintf('Documentation for helper card "%s" does not exist', $cardType)); - } -} diff --git a/src/Core/Util/HelperCard/DocumentationLinkProviderInterface.php b/src/Core/Util/HelperCard/DocumentationLinkProviderInterface.php deleted file mode 100644 index 3ff4beeb..00000000 --- a/src/Core/Util/HelperCard/DocumentationLinkProviderInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\HelperCard; - -/** - * Interface DocumentationLinkProviderInterface - */ -interface DocumentationLinkProviderInterface -{ - /** - * @param string $cardType - * - * @return string Link for documentation - */ - public function getLink($cardType); -} diff --git a/src/Core/Util/HelperCard/HelperCardDocumentationDoesNotExistException.php b/src/Core/Util/HelperCard/HelperCardDocumentationDoesNotExistException.php deleted file mode 100644 index 3c4b8164..00000000 --- a/src/Core/Util/HelperCard/HelperCardDocumentationDoesNotExistException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\HelperCard; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class HelperCardDocumentationDoesNotExistException - */ -class HelperCardDocumentationDoesNotExistException extends CoreException -{ -} diff --git a/src/Core/Util/InternationalizedDomainNameConverter.php b/src/Core/Util/InternationalizedDomainNameConverter.php deleted file mode 100644 index d913964b..00000000 --- a/src/Core/Util/InternationalizedDomainNameConverter.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShop\PrestaShop\Core\Util; - -class InternationalizedDomainNameConverter -{ - /** - * Convert the host part of the email from punycode to utf8 (e.g,. email@xn--e1aybc.xn--p1ai -> email@тест.рф) - * - * @param string $email - * - * @return string - */ - public function emailToUtf8(string $email): string - { - $parts = explode('@', $email); - if (count($parts) !== 2) { - return $email; - } - - return $parts[0] . '@' . idn_to_utf8($parts[1], 0, INTL_IDNA_VARIANT_UTS46); - } -} diff --git a/src/Core/Util/String/StringModifier.php b/src/Core/Util/String/StringModifier.php deleted file mode 100644 index 3fa494c0..00000000 --- a/src/Core/Util/String/StringModifier.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\String; - -/** - * This class defines reusable methods for strings modifications. - */ -final class StringModifier implements StringModifierInterface -{ - /** - * {@inheritdoc} - */ - public function splitByCamelCase($string) - { - $regex = '/(?)(?<=[a-z])(?=[A-Z]) | (?<=[A-Z])(?=[A-Z][a-z])/x'; - - $splitString = preg_split($regex, $string); - - return implode(' ', $splitString); - } -} diff --git a/src/Core/Util/String/StringModifierInterface.php b/src/Core/Util/String/StringModifierInterface.php deleted file mode 100644 index 0bb50154..00000000 --- a/src/Core/Util/String/StringModifierInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\String; - -/** - * Defines reusable methods for strings modifications. - */ -interface StringModifierInterface -{ - /** - * @param $string - * - * @return string - */ - public function splitByCamelCase($string); -} diff --git a/src/Core/Util/String/StringValidator.php b/src/Core/Util/String/StringValidator.php deleted file mode 100644 index b252069e..00000000 --- a/src/Core/Util/String/StringValidator.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\String; - -/** - * This class defines reusable methods for checking strings under certain conditions. - */ -final class StringValidator implements StringValidatorInterface -{ - /** - * {@inheritdoc} - */ - public function startsWith($string, $prefix) - { - return strpos($string, $prefix) === 0; - } - - /** - * {@inheritdoc} - */ - public function endsWith($string, $suffix) - { - $length = strlen($suffix); - - if (0 === $length) { - return false; - } - - return substr($string, -$length) === $suffix; - } - - /** - * {@inheritdoc} - */ - public function startsWithAndEndsWith($string, $prefix, $suffix) - { - return $this->startsWith($string, $prefix) && $this->endsWith($string, $suffix); - } - - /** - * {@inheritdoc} - */ - public function doesContainsWhiteSpaces($string) - { - return preg_match('/\s/', $string); - } -} diff --git a/src/Core/Util/String/StringValidatorInterface.php b/src/Core/Util/String/StringValidatorInterface.php deleted file mode 100644 index 9bdb3cda..00000000 --- a/src/Core/Util/String/StringValidatorInterface.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\String; - -/** - * Defines reusable methods for checking strings under certain conditions. - */ -interface StringValidatorInterface -{ - /** - * @param string $string - * @param string $prefix - * - * @return bool - */ - public function startsWith($string, $prefix); - - /** - * @param string $string - * @param string $suffix - * - * @return bool - */ - public function endsWith($string, $suffix); - - /** - * @param string $string - * @param string $prefix - * @param string $suffix - * - * @return bool - */ - public function startsWithAndEndsWith($string, $prefix, $suffix); - - /** - * @param string $string - * - * @return bool - */ - public function doesContainsWhiteSpaces($string); -} diff --git a/src/Core/Util/Url/BackUrlProvider.php b/src/Core/Util/Url/BackUrlProvider.php deleted file mode 100644 index 87cff697..00000000 --- a/src/Core/Util/Url/BackUrlProvider.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\Url; - -use Symfony\Component\HttpFoundation\Request; - -/** - * gets back url. - */ -class BackUrlProvider -{ - /** - * @param Request $request - * - * @return string - */ - public function getBackUrl(Request $request) - { - $backUrl = $request->query->get('back'); - - return urldecode($backUrl); - } -} diff --git a/src/Core/Util/Url/UrlFileChecker.php b/src/Core/Util/Url/UrlFileChecker.php deleted file mode 100644 index 5a10affa..00000000 --- a/src/Core/Util/Url/UrlFileChecker.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\Url; - -/** - * Class UrlFileChecker - */ -final class UrlFileChecker implements UrlFileCheckerInterface -{ - /** - * @var string - */ - private $fileDir; - - /** - * @param string $fileDir - */ - public function __construct($fileDir) - { - $this->fileDir = $fileDir; - } - - /** - * @return bool - */ - public function isHtaccessFileWritable() - { - return $this->isFileWritable('.htaccess'); - } - - /** - * @return bool - */ - public function isRobotsFileWritable() - { - return $this->isFileWritable('robots.txt'); - } - - /** - * @param string $fileName - * - * @return bool - */ - private function isFileWritable($fileName) - { - $filePath = $this->fileDir . DIRECTORY_SEPARATOR . $fileName; - - if (file_exists($filePath)) { - return is_writable($filePath); - } - - return is_writable($this->fileDir); - } -} diff --git a/src/Core/Util/Url/UrlFileCheckerInterface.php b/src/Core/Util/Url/UrlFileCheckerInterface.php deleted file mode 100644 index 3622e5d0..00000000 --- a/src/Core/Util/Url/UrlFileCheckerInterface.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Util\Url; - -/** - * Interface UrlFileCheckerInterface defines contract for UrlFileChecker. - */ -interface UrlFileCheckerInterface -{ - /** - * Check if .htaccess file for Front Office is writable. - * - * @return bool - */ - public function isHtaccessFileWritable(); - - /** - * Check if robots.txt file for Front Office is writable. - * - * @return bool - */ - public function isRobotsFileWritable(); -} diff --git a/src/Core/Validation/Validator.php b/src/Core/Validation/Validator.php deleted file mode 100644 index b57a7ca5..00000000 --- a/src/Core/Validation/Validator.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Validation; - -use PrestaShop\PrestaShop\Adapter\Validate; - -/** - * Class Validator is responsible for validating data. - */ -final class Validator implements ValidatorInterface -{ - /** - * @var Validate - */ - private $validate; - - /** - * @param Validate $validate - */ - public function __construct(Validate $validate) - { - $this->validate = $validate; - } - - /** - * {@inheritdoc} - */ - public function isCleanHtml($html, array $options = []) - { - $defaultOptions = [ - 'allow_iframe' => false, - ]; - $options = array_merge($defaultOptions, $options); - - return $this->validate->isCleanHtml($html, $options['allow_iframe']); - } - - /** - * {@inheritdoc} - */ - public function isModuleName($name) - { - return $this->validate->isModuleName($name); - } -} diff --git a/src/Core/Validation/ValidatorInterface.php b/src/Core/Validation/ValidatorInterface.php deleted file mode 100644 index 5d40f807..00000000 --- a/src/Core/Validation/ValidatorInterface.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Validation; - -interface ValidatorInterface -{ - /** - * Check if HTML is clean. - * - * @param string $html - * @param array $options - * - * @return bool - */ - public function isCleanHtml($html, array $options = []); - - /** - * Check if Module name is valid. - * - * @param string $name - * - * @return bool - */ - public function isModuleName($name); -} diff --git a/src/Core/Webservice/ServerRequirementsChecker.php b/src/Core/Webservice/ServerRequirementsChecker.php deleted file mode 100644 index 75892702..00000000 --- a/src/Core/Webservice/ServerRequirementsChecker.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Webservice; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Hosting\HostingInformation; -use PrestaShop\PrestaShop\Core\Configuration\PhpExtensionCheckerInterface; -use RuntimeException; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Looks at server configuration in order to check if PrestaShop's Webservice feature can be enabled. - */ -final class ServerRequirementsChecker implements ServerRequirementsCheckerInterface -{ - const ISSUE_APACHE_MOD_AUTH_BASIC_NOT_AVAILABLE = 'issue_apache_mod_auth_basic_not_available'; - const ISSUE_APACHE_MOD_AUTH_REWRITE_NOT_AVAILABLE = 'issue_apache_mod_auth_rewrite_not_available'; - const ISSUE_EXT_SIMPLEXML_NOT_AVAILABLE = 'issue_ext_simplexml_not_available'; - const ISSUE_HTTPS_NOT_AVAILABLE = 'issue_https_not_available'; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var Configuration - */ - private $configuration; - - /** - * @var HostingInformation - */ - private $hostingInformation; - - /** - * @var PhpExtensionCheckerInterface - */ - private $phpExtensionChecker; - - /** - * @param TranslatorInterface $translator - * @param Configuration $configuration - * @param HostingInformation $hostingInformation - * @param PhpExtensionCheckerInterface $phpExtensionChecker - */ - public function __construct( - TranslatorInterface $translator, - Configuration $configuration, - HostingInformation $hostingInformation, - PhpExtensionCheckerInterface $phpExtensionChecker - ) { - $this->translator = $translator; - $this->configuration = $configuration; - $this->hostingInformation = $hostingInformation; - $this->phpExtensionChecker = $phpExtensionChecker; - } - - /** - * Analyses the server configuration (apache configuration and php settings) - * to check whether PrestaShop Webservice can be used or not. - * - * @return array empty if no errors - */ - public function checkForErrors() - { - $issues = $this->lookForIssues(); - - if (empty($issues)) { - return []; - } - - $allWarningMessages = $this->getWarningMessages(); - $selectedWarningMessages = []; - - foreach ($issues as $issue) { - if (false === array_key_exists($issue, $allWarningMessages)) { - throw new RuntimeException(sprintf('Unexpected configuration issue "%s"', $issue)); - } - - $selectedWarningMessages[] = $allWarningMessages[$issue]; - } - - return $selectedWarningMessages; - } - - /** - * @return string[] - */ - private function lookForIssues() - { - $issues = []; - - if (!$this->phpExtensionChecker->loaded('SimpleXML')) { - $issues[] = self::ISSUE_EXT_SIMPLEXML_NOT_AVAILABLE; - } - - if (false === $this->configuration->getBoolean('PS_SSL_ENABLED')) { - $issues[] = self::ISSUE_HTTPS_NOT_AVAILABLE; - } - - if (false === strpos($this->hostingInformation->getServerInformation()['version'], 'Apache')) { - return $issues; - } - - if (function_exists('apache_get_modules')) { - $apache_modules = apache_get_modules(); - - if (false === in_array('mod_auth_basic', $apache_modules)) { - $issues[] = self::ISSUE_APACHE_MOD_AUTH_BASIC_NOT_AVAILABLE; - } - - if (false === in_array('mod_rewrite', $apache_modules)) { - $issues[] = self::ISSUE_APACHE_MOD_AUTH_REWRITE_NOT_AVAILABLE; - } - } - - return $issues; - } - - /** - * @return string[] - */ - private function getWarningMessages() - { - return [ - self::ISSUE_APACHE_MOD_AUTH_BASIC_NOT_AVAILABLE => $this->translator->trans( - 'Please activate the \'mod_rewrite\' Apache module to allow the PrestaShop webservice.', - [], - 'Admin.Advparameters.Notification' - ), - self::ISSUE_APACHE_MOD_AUTH_REWRITE_NOT_AVAILABLE => $this->translator->trans( - 'We could not check to see if basic authentication and rewrite extensions have been activated. Please manually check if they\'ve been activated in order to use the PrestaShop webservice.', - [], - 'Admin.Advparameters.Notification' - ), - self::ISSUE_EXT_SIMPLEXML_NOT_AVAILABLE => $this->translator->trans( - 'Please activate the \'SimpleXML\' PHP extension to allow testing of PrestaShop\'s webservice.', - [], - 'Admin.Advparameters.Notification' - ), - self::ISSUE_HTTPS_NOT_AVAILABLE => $this->translator->trans( - 'It is preferable to use SSL (https:) for webservice calls, as it avoids the "man in the middle" type security issues.', - [], - 'Admin.Advparameters.Notification' - ), - ]; - } -} diff --git a/src/Core/Webservice/ServerRequirementsCheckerInterface.php b/src/Core/Webservice/ServerRequirementsCheckerInterface.php deleted file mode 100644 index cb46eea9..00000000 --- a/src/Core/Webservice/ServerRequirementsCheckerInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShop\PrestaShop\Core\Webservice; - -/** - * Interface ServerRequirementsCheckerInterface. - */ -interface ServerRequirementsCheckerInterface -{ - /** - * Check if server meets requirements to support Webservice feature. - * - * @return array Errors if any - */ - public function checkForErrors(); -} diff --git a/src/PrestaShopBundle/Api/QueryParamsCollection.php b/src/PrestaShopBundle/Api/QueryParamsCollection.php deleted file mode 100644 index 98729134..00000000 --- a/src/PrestaShopBundle/Api/QueryParamsCollection.php +++ /dev/null @@ -1,740 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api; - -use Doctrine\Common\Util\Inflector; -use PrestaShopBundle\Exception\InvalidPaginationParamsException; -use Symfony\Component\HttpFoundation\Request; - -abstract class QueryParamsCollection -{ - const SQL_PARAM_FIRST_RESULT = 'first_result'; - - const SQL_PARAM_MAX_RESULTS = 'max_results'; - - const SQL_CLAUSE_WHERE = 'where'; - - const SQL_CLAUSE_HAVING = 'having'; - - /** - * @var array - */ - protected $queryParams = []; - - protected $defaultPageIndex = 1; - - protected $defaultPageSize = 100; - - /** - * @return array - */ - public function getQueryParams() - { - return $this->queryParams; - } - - /** - * @return int - */ - public function getDefaultPageIndex() - { - return $this->defaultPageIndex; - } - - /** - * @return int - */ - public function getDefaultPageSize() - { - return $this->defaultPageSize; - } - - /** - * @param $pageSize int - * - * @return $this - */ - public function setPageSize($pageSize) - { - $this->queryParams['page_size'] = (int) $pageSize; - - return $this; - } - - /** - * @param $pageIndex int - * - * @return $this - */ - public function setPageIndex($pageIndex) - { - $this->queryParams['page_index'] = (int) $pageIndex; - - return $this; - } - - /** - * @param Request $request - * - * @return $this - */ - public function fromRequest(Request $request) - { - $queryParams = $request->query->all(); - - $queryParams = $this->excludeUnknownParams($queryParams); - $queryParams = $this->parsePaginationParams($queryParams); - $queryParams = $this->parseOrderParams($queryParams); - $this->queryParams = $this->parseFilterParams($queryParams, $request); - - return $this; - } - - /** - * @param $queryParams - * - * @return mixed - */ - protected function excludeUnknownParams(array $queryParams) - { - $queryParamsNames = array_keys($queryParams); - array_walk($queryParamsNames, function ($name) use (&$queryParams) { - $validParams = array_merge( - $this->getValidPaginationParams(), - $this->getValidOrderParams(), - $this->getValidFilterParams() - ); - - if (!in_array($name, $validParams)) { - unset($queryParams[$name]); - } - }); - - return $queryParams; - } - - /** - * @param array $queryParams - * @param Request $request - * - * @return array - */ - protected function parseFilterParams(array $queryParams, Request $request) - { - $allParameters = array_merge( - $request->attributes->all(), - $request->query->all() - ); - - $filters = array_filter(array_keys($allParameters), function ($filter) { - return in_array($filter, $this->getValidFilterParams()); - }); - - $filterParams = []; - array_walk($filters, function ($filter) use ($allParameters, &$filterParams) { - if (is_array($allParameters[$filter])) { - $allParameters[$filter] = array_filter($allParameters[$filter], function ($value) { - return is_int($value) || (is_string($value) && strlen(trim($value)) > 0); - }); - } - - $filterParams[$filter] = $allParameters[$filter]; - if (is_array($filterParams[$filter]) && count($filterParams[$filter]) === 0) { - unset($filterParams[$filter]); - } - }); - - $queryParams['filter'] = $filterParams; - - return $queryParams; - } - - /** - * @return array - */ - abstract protected function getValidFilterParams(); - - /** - * @param array $queryParams - * - * @return array - */ - protected function parsePaginationParams(array $queryParams) - { - if (!array_key_exists('page_index', $queryParams)) { - $queryParams['page_index'] = $this->getDefaultPageIndex(); - } - - if (!array_key_exists('page_size', $queryParams)) { - $queryParams['page_size'] = $this->getDefaultPageSize(); - } - - $queryParams['page_size'] = (int) $queryParams['page_size']; - $queryParams['page_index'] = (int) $queryParams['page_index']; - - if ( - $queryParams['page_size'] > $this->getDefaultPageSize() || - $queryParams['page_size'] < 1 - ) { - throw new InvalidPaginationParamsException(sprintf('A page size should be an integer greater than 1 and fewer than %s', $this->getDefaultPageSize())); - } - - if ($queryParams['page_index'] < 1) { - throw new InvalidPaginationParamsException(); - } - - return $queryParams; - } - - /** - * @return array - */ - protected function getValidPaginationParams() - { - return [ - 'page_size', - 'page_index', - 'order', - ]; - } - - /** - * @param array $queryParams - * - * @return array|mixed - */ - protected function parseOrderParams(array $queryParams) - { - if (!array_key_exists('order', $queryParams)) { - $queryParams = $this->setDefaultOrderParam($queryParams); - } - - if (!is_array($queryParams['order'])) { - $queryParams['order'] = (array) $queryParams['order']; - } - - foreach ($queryParams['order'] as $key => &$order) { - $order = strtolower($order); - $filterColumn = $this->removeDirection($order); - - if (!in_array($filterColumn, $this->getValidOrderParams())) { - unset($queryParams['order'][$key]); - } - } - - if (empty($queryParams['order'])) { - $queryParams = $this->setDefaultOrderParam($queryParams); - } - - return $queryParams; - } - - /** - * @return array - */ - abstract protected function getValidOrderParams(); - - /** - * @param $queryParams - * - * @return mixed - */ - abstract protected function setDefaultOrderParam($queryParams); - - /** - * @param $subject - * - * @return mixed - */ - protected function removeDirection($subject) - { - $subject = str_replace(' asc', '', $subject); - - return str_replace(' desc', '', $subject); - } - - /** - * @return string - */ - public function getSqlOrder() - { - $implodableOrder = []; - - foreach ($this->queryParams['order'] as $order) { - $descendingOrder = false !== strpos($order, 'desc'); - $filterColumn = $this->removeDirection($order); - - $orderFiltered = '{' . $filterColumn . '}'; - - if ($descendingOrder) { - $orderFiltered = $orderFiltered . ' DESC'; - } - - $implodableOrder[] = $orderFiltered; - } - - return 'ORDER BY ' . implode(', ', $implodableOrder) . ' '; - } - - /** - * @return array - */ - public function getSqlFilters() - { - $whereFilters = []; - - foreach ($this->queryParams['filter'] as $column => $value) { - $whereFilters = $this->appendSqlFilter($value, $column, $whereFilters); - } - - $filters = [ - self::SQL_CLAUSE_WHERE => implode("\n", $whereFilters), - ]; - - $filters = $this->appendSqlSearchFilter($filters); - - return $filters; - } - - /** - * @return bool - */ - protected function hasSearchFilter() - { - return array_key_exists('keywords', $this->queryParams['filter']); - } - - /** - * @param $value - * @param $column - * @param array $filters - * - * @return array - */ - protected function appendSqlFilter($value, $column, array $filters) - { - $column = Inflector::tableize($column); - - if ('attributes' === $column) { - return $this->appendSqlAttributesFilter($filters, $value); - } - - if ('features' === $column) { - return $this->appendSqlFeaturesFilter($filters, $value); - } - - if ('keywords' === $column) { - return $filters; - } - - if ('category_id' === $column) { - return $this->appendSqlCategoryFilter($filters); - } - - if ('date_add' === $column) { - return $this->appendSqlDateAddFilter($filters, $value); - } - - if ('active' === $column) { - return $this->appendSqlActiveFilter($filters, $value); - } - - if (!is_array($value)) { - $filters[] = sprintf('AND {%s} = :%s', $column, $column); - - return $filters; - } - - $placeholders = array_map(function ($index) use ($column) { - return ':' . $column . '_' . $index; - }, array_keys($value)); - - $filters[] = sprintf('AND {%s} IN (%s)', $column, implode(',', $placeholders)); - - return $filters; - } - - /** - * @return array - */ - public function getSqlParams() - { - return array_merge( - $this->getSqlPaginationParams(), - $this->getSqlFiltersParams() - ); - } - - /** - * @return array - */ - public function getSqlPaginationParams() - { - $maxResult = $this->queryParams['page_size']; - $pageIndex = $this->queryParams['page_index']; - $firstResult = ($pageIndex - 1) * $maxResult; - - return [ - self::SQL_PARAM_MAX_RESULTS => (int) $maxResult, - self::SQL_PARAM_FIRST_RESULT => (int) $firstResult, - ]; - } - - /** - * @return array - */ - private function getSqlFiltersParams() - { - $sqlParams = []; - - if (count($this->queryParams['filter']) === 0) { - return $sqlParams; - } - - foreach ($this->queryParams['filter'] as $column => $value) { - $sqlParams = $this->appendSqlFilterParams($column, $value, $sqlParams); - } - - return $sqlParams; - } - - /** - * @param $column - * @param $value - * @param $sqlParams - * - * @return mixed - */ - protected function appendSqlFilterParams($column, $value, $sqlParams) - { - $column = Inflector::tableize($column); - - if ('attributes' === $column) { - return $this->appendSqlAttributesFilterParam($value, $sqlParams); - } - - if ('features' === $column) { - return $this->appendSqlFeaturesFilterParam($value, $sqlParams); - } - - if ('keywords' === $column) { - return $this->appendSqlSearchFilterParam($value, $sqlParams); - } - - if ('category_id' === $column) { - return $this->appendSqlCategoryFilterParam($value, $sqlParams); - } - - if ('date_add' === $column) { - return $this->appendSqlDateAddFilterParam($value, $sqlParams); - } - - if ('active' === $column) { - return $this->appendSqlActiveFilterParam($value, $sqlParams); - } - - if (!is_array($value)) { - $sqlParams[$column] = (int) $value; - - return $sqlParams; - } - - array_map(function ($index, $value) use (&$sqlParams, $column) { - $sqlParams[$column . '_' . $index] = (int) $value; - }, array_keys($value), $value); - - return $sqlParams; - } - - /** - * @param array $filters - * - * @return array - */ - protected function appendSqlCategoryFilter(array $filters) - { - $filters[] = 'AND EXISTS(SELECT 1 FROM {table_prefix}category_product cp - WHERE cp.id_product=p.id_product AND FIND_IN_SET(cp.id_category, :categories_ids))'; - - return $filters; - } - - /** - * @param $value - * @param $sqlParams - * - * @return mixed - */ - protected function appendSqlCategoryFilterParam($value, $sqlParams) - { - if (!is_array($value)) { - $value = [$value]; - } - - $value = array_map('intval', $value); - $sqlParams[':categories_ids'] = implode(',', $value); - - return $sqlParams; - } - - /** - * @param array $filters - * @param dateAdd - * - * @return array - */ - protected function appendSqlDateAddFilter(array $filters, $dateAdd) - { - if (!is_array($dateAdd)) { - $dateAdd = [$dateAdd]; - } - - if (array_key_exists('sup', $dateAdd)) { - $search = ($this->isTimestamp($dateAdd['sup']) ? 'UNIX_TIMESTAMP(%s)' : '%s'); - $filters[] = sprintf('AND ' . $search . ' >= %s', '{date_add}', ':date_add_sup'); - } - if (array_key_exists('inf', $dateAdd)) { - $search = ($this->isTimestamp($dateAdd['inf']) ? 'UNIX_TIMESTAMP(%s)' : '%s'); - $filters[] = sprintf('AND ' . $search . ' <= %s', '{date_add}', ':date_add_inf'); - } - - return $filters; - } - - /** - * @param $value - * @param $sqlParams - * - * @return mixed - */ - protected function appendSqlDateAddFilterParam($value, $sqlParams) - { - if (!is_array($value)) { - $value = [$value]; - } - - if (array_key_exists('sup', $value)) { - $sqlParams[':date_add_sup'] = $value['sup']; - } - if (array_key_exists('inf', $value)) { - $sqlParams[':date_add_inf'] = $value['inf']; - } - - return $sqlParams; - } - - /** - * @param array $filters - * @param active - * - * @return array - */ - protected function appendSqlActiveFilter(array $filters, $active) - { - if (in_array($active, ['0', '1'])) { - $filters[] = sprintf('AND %s = %s', '{active}', ':active'); - } - - return $filters; - } - - /** - * @param $value - * @param $sqlParams - * - * @return mixed - */ - protected function appendSqlActiveFilterParam($value, $sqlParams) - { - if (in_array($value, ['0', '1'])) { - $sqlParams[':active'] = $value; - } - - return $sqlParams; - } - - /** - * @param array $filters - * @param $attributes - * - * @return array - */ - protected function appendSqlAttributesFilter(array $filters, $attributes) - { - if (!is_array($attributes)) { - $attributes = [$attributes]; - } - - $attributesKeys = array_keys($attributes); - array_walk($attributesKeys, function ($key) use (&$filters) { - $filters[] = sprintf('AND EXISTS(SELECT 1 - FROM {table_prefix}product_attribute_combination pac - LEFT JOIN {table_prefix}attribute a ON ( - pac.id_attribute = a.id_attribute - ) - WHERE pac.id_product_attribute=pa.id_product_attribute - AND a.id_attribute=:attribute_id_%d - AND a.id_attribute_group=:attribute_group_id_%d)', $key, $key); - }); - - return $filters; - } - - /** - * @param array $value - * @param $sqlParams - * - * @return array - */ - protected function appendSqlAttributesFilterParam($value, $sqlParams) - { - if (!is_array($value)) { - $value = [$value]; - } - - array_map(function ($index, $value) use (&$sqlParams) { - list($idAttributeGroup, $idAttribute) = explode(':', $value); - $sqlParams['attribute_id_' . $index] = (string) $idAttribute; - $sqlParams['attribute_group_id_' . $index] = (string) $idAttributeGroup; - }, range(0, count($value) - 1), $value); - - return $sqlParams; - } - - /** - * @param array $filters - * @param $attributes - * - * @return array - */ - protected function appendSqlFeaturesFilter(array $filters, $attributes) - { - if (!is_array($attributes)) { - $attributes = [$attributes]; - } - - $attributesKeys = array_keys($attributes); - array_walk($attributesKeys, function ($key) use (&$filters) { - $filters[] = sprintf('AND EXISTS(SELECT 1 - FROM {table_prefix}feature_product fp - LEFT JOIN {table_prefix}feature f ON ( - fp.id_feature = f.id_feature - ) - LEFT JOIN {table_prefix}feature_shop fs ON ( - fs.id_shop = :shop_id AND - fs.id_feature = f.id_feature - ) - LEFT JOIN {table_prefix}feature_value fv ON ( - f.id_feature = fv.id_feature AND - fp.id_feature_value = fv.id_feature_value - ) - WHERE fv.custom = 0 AND fp.id_product=p.id_product - AND fp.id_feature=:feature_id_%d - AND fp.id_feature_value=:feature_value_id_%d)', $key, $key); - }); - - return $filters; - } - - /** - * @param array $value - * @param $sqlParams - * - * @return array - */ - protected function appendSqlFeaturesFilterParam($value, $sqlParams) - { - if (!is_array($value)) { - $value = [$value]; - } - - array_map(function ($index, $value) use (&$sqlParams) { - list($idFeature, $idFeatureValue) = explode(':', $value); - $sqlParams['feature_id_' . $index] = (string) $idFeature; - $sqlParams['feature_value_id_' . $index] = (string) $idFeatureValue; - }, range(0, count($value) - 1), $value); - - return $sqlParams; - } - - /** - * @param $filters - * - * @return mixed - */ - protected function appendSqlSearchFilter($filters) - { - if (!$this->hasSearchFilter()) { - return $filters; - } - - if (!is_array($this->queryParams['filter']['keywords'])) { - $this->queryParams['filter']['keywords'] = (array) $this->queryParams['filter']['keywords']; - } - - $parts = array_map(function ($index) { - return sprintf( - 'AND (' . - '{supplier_name} LIKE :keyword_%d OR ' . - '{product_reference} LIKE :keyword_%d OR ' . - '{product_name} LIKE :keyword_%d OR ' . - '{combination_name} LIKE :keyword_%d' . - ')', - $index, - $index, - $index, - $index - ); - }, range(0, count($this->queryParams['filter']['keywords']) - 1)); - - $filters[self::SQL_CLAUSE_HAVING] = implode("\n", $parts); - - return $filters; - } - - protected function appendSqlSearchFilterParam($value, $sqlParams) - { - if (!is_array($value)) { - $value = [$value]; - } - - array_map(function ($index, $value) use (&$sqlParams) { - $sqlParams['keyword_' . $index] = (string) ('%' . $value . '%'); - }, range(0, count($value) - 1), $value); - - return $sqlParams; - } - - protected function isTimestamp($timestamp) - { - $check = (is_int($timestamp) || is_float($timestamp)) ? $timestamp : (string) (int) $timestamp; - - return ($check === $timestamp) - && ((int) $timestamp <= PHP_INT_MAX) - && ((int) $timestamp >= ~PHP_INT_MAX); - } -} diff --git a/src/PrestaShopBundle/Api/QueryStockMovementParamsCollection.php b/src/PrestaShopBundle/Api/QueryStockMovementParamsCollection.php deleted file mode 100644 index c40304e8..00000000 --- a/src/PrestaShopBundle/Api/QueryStockMovementParamsCollection.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api; - -class QueryStockMovementParamsCollection extends QueryStockParamsCollection -{ - /** - * @return array - */ - protected function getValidFilterParams() - { - return [ - 'productId', - 'supplier_id', - 'category_id', - 'keywords', - 'attributes', - 'features', - 'date_add', - 'id_employee', - 'id_stock_mvt_reason', - ]; - } - - /** - * @return array - */ - protected function getValidOrderParams() - { - return [ - 'product', - 'reference', - 'date_add', - 'id_stock_mvt', - ]; - } - - /** - * @param $queryParams - * - * @return mixed - */ - protected function setDefaultOrderParam($queryParams) - { - $queryParams['order'] = ['id_stock_mvt DESC']; - - return $queryParams; - } -} diff --git a/src/PrestaShopBundle/Api/QueryStockParamsCollection.php b/src/PrestaShopBundle/Api/QueryStockParamsCollection.php deleted file mode 100644 index 8c75300a..00000000 --- a/src/PrestaShopBundle/Api/QueryStockParamsCollection.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api; - -class QueryStockParamsCollection extends QueryParamsCollection -{ - /** - * @param array $queryParams - * - * @return array|mixed - */ - protected function parseOrderParams(array $queryParams) - { - $queryParams = parent::parseOrderParams($queryParams); - - if (array_key_exists('low_stock', $queryParams) && 1 == $queryParams['low_stock']) { - array_unshift($queryParams['order'], 'product_low_stock_alert desc'); - } - - return $queryParams; - } - - /** - * @return array - */ - protected function getValidFilterParams() - { - return [ - 'productId', - 'supplier_id', - 'category_id', - 'keywords', - 'attributes', - 'features', - 'active', - ]; - } - - /** - * @return array - */ - protected function getValidOrderParams() - { - return [ - 'product', - 'reference', - 'supplier', - 'available_quantity', - 'physical_quantity', - 'active', - 'low_stock', - ]; - } - - /** - * @param $queryParams - * - * @return mixed - */ - protected function setDefaultOrderParam($queryParams) - { - $queryParams['order'] = ['product DESC']; - - return $queryParams; - } -} diff --git a/src/PrestaShopBundle/Api/QueryTranslationParamsCollection.php b/src/PrestaShopBundle/Api/QueryTranslationParamsCollection.php deleted file mode 100644 index 21d4495d..00000000 --- a/src/PrestaShopBundle/Api/QueryTranslationParamsCollection.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api; - -class QueryTranslationParamsCollection extends QueryParamsCollection -{ - protected $defaultPageIndex = 1; - - protected $defaultPageSize = 20; - - /** - * @return array - */ - protected function getValidFilterParams() - { - return []; - } - - /** - * @return array - */ - protected function getValidOrderParams() - { - return []; - } - - /** - * @param $queryParams - * - * @return mixed - */ - protected function setDefaultOrderParam($queryParams) - { - $queryParams['order'] = ['unknown']; - - return $queryParams; - } -} diff --git a/src/PrestaShopBundle/Api/Stock/Movement.php b/src/PrestaShopBundle/Api/Stock/Movement.php deleted file mode 100644 index 5032db49..00000000 --- a/src/PrestaShopBundle/Api/Stock/Movement.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api\Stock; - -use PrestaShopBundle\Entity\ProductIdentity; - -class Movement -{ - /** - * @var ProductIdentity - */ - private $productIdentity; - - /** - * @var int - */ - private $delta; - - public function __construct(ProductIdentity $productIdentity, $delta) - { - $this->productIdentity = $productIdentity; - $this->delta = (int) $delta; - } - - /** - * @return ProductIdentity - */ - public function getProductIdentity() - { - return $this->productIdentity; - } - - /** - * @return int - */ - public function getDelta() - { - return $this->delta; - } -} diff --git a/src/PrestaShopBundle/Api/Stock/MovementsCollection.php b/src/PrestaShopBundle/Api/Stock/MovementsCollection.php deleted file mode 100644 index d638f3cd..00000000 --- a/src/PrestaShopBundle/Api/Stock/MovementsCollection.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Api\Stock; - -use PrestaShopBundle\Entity\ProductIdentity; - -class MovementsCollection -{ - private $movements = []; - - /** - * @param array $stockMovementsParams - * - * @return $this - */ - public function fromArray(array $stockMovementsParams) - { - $movements = []; - - array_walk($stockMovementsParams, function ($item) use (&$movements) { - $combinationId = 0; - - if ($item['delta'] != 0) { - if (array_key_exists('combination_id', $item)) { - $combinationId = $item['combination_id']; - } - - $productIdentity = ProductIdentity::fromArray([ - 'product_id' => $item['product_id'], - 'combination_id' => $combinationId, - ]); - - $movements[] = new Movement($productIdentity, $item['delta']); - } - }); - - $this->movements = $movements; - - return $this; - } - - /** - * @param callable $callback - * - * @return array - */ - public function map(callable $callback) - { - return array_map($callback, $this->movements); - } -} diff --git a/src/PrestaShopBundle/Cache/CacheWarmer.php b/src/PrestaShopBundle/Cache/CacheWarmer.php deleted file mode 100644 index b18b3058..00000000 --- a/src/PrestaShopBundle/Cache/CacheWarmer.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Cache; - -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; - -class CacheWarmer implements CacheWarmerInterface -{ - private $fileSystem; - - public function __construct(FileSystem $fileSystem) - { - $this->fileSystem = $fileSystem; - } - - public function warmUp($cacheDir) - { - $legacyDirs = [ - $cacheDir . DIRECTORY_SEPARATOR . 'cachefs', - $cacheDir . DIRECTORY_SEPARATOR . 'purifier', - $cacheDir . DIRECTORY_SEPARATOR . 'push', - $cacheDir . DIRECTORY_SEPARATOR . 'sandbox', - $cacheDir . DIRECTORY_SEPARATOR . 'tcpdf', - ]; - - $this->fileSystem->mkdir($legacyDirs); - } - - public function isOptional() - { - return false; - } -} diff --git a/src/PrestaShopBundle/Cache/Factory/CacheSubscriberFactory.php b/src/PrestaShopBundle/Cache/Factory/CacheSubscriberFactory.php deleted file mode 100644 index d4ae95ce..00000000 --- a/src/PrestaShopBundle/Cache/Factory/CacheSubscriberFactory.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Cache\Factory; - -use GuzzleHttp\Message\Request; -use GuzzleHttp\Subscriber\Cache\CacheStorageInterface; -use GuzzleHttp\Subscriber\Cache\CacheSubscriber; - -/** - * Instanciate a CacheSubscriber for Guzzle - */ -final class CacheSubscriberFactory -{ - /** - * @param CacheStorageInterface $storage - * - * @return CacheSubscriber - */ - public function create(CacheStorageInterface $storage) - { - return new CacheSubscriber($storage, function (Request $request) { return true; }); - } -} diff --git a/src/PrestaShopBundle/Cache/LocalizationWarmer.php b/src/PrestaShopBundle/Cache/LocalizationWarmer.php deleted file mode 100644 index 68cd6174..00000000 --- a/src/PrestaShopBundle/Cache/LocalizationWarmer.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Cache; - -use Symfony\Component\Filesystem\Exception\IOExceptionInterface; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; - -class LocalizationWarmer implements CacheWarmerInterface -{ - private $version; - private $country; - - public function __construct($version, $country) - { - $this->version = $version; - $this->country = $country; - } - - public function warmUp($cacheDir) - { - $fs = new Filesystem(); - - if (is_dir($cacheDir)) { - try { - $fs->mkdir($cacheDir); - } catch (IOExceptionInterface $e) { - //@todo: log - } - } - - $path_cache_file = $cacheDir . $this->version . $this->country . '.xml'; - - if (is_file($path_cache_file)) { - $localization_file_content = file_get_contents($path_cache_file); - } else { - $localization_file = _PS_ROOT_DIR_ . '/localization/default.xml'; - - if (file_exists(_PS_ROOT_DIR_ . '/localization/' . $this->country . '.xml')) { - $localization_file = _PS_ROOT_DIR_ . '/localization/' . $this->country . '.xml'; - } - - $localization_file_content = file_get_contents($localization_file); - - try { - $fs->dumpFile($path_cache_file, $localization_file_content); - } catch (IOExceptionInterface $e) { - //@todo: log - } - } - - return $localization_file_content; - } - - public function isOptional() - { - return false; - } -} diff --git a/src/PrestaShopBundle/Cache/ModuleTemplateCacheWarmer.php b/src/PrestaShopBundle/Cache/ModuleTemplateCacheWarmer.php deleted file mode 100644 index 5516ea84..00000000 --- a/src/PrestaShopBundle/Cache/ModuleTemplateCacheWarmer.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Cache; - -use Psr\Container\ContainerInterface; -use Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinderInterface; -use Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheCacheWarmer; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Templating\TemplateReference; -use Twig\Error\Error; - -/** - * Generates the Twig cache for all paths, with a specific filter for given namespace - */ -class ModuleTemplateCacheWarmer extends TemplateCacheCacheWarmer -{ - private $paths; - - /** - * {@inheritdoc} - */ - public function __construct(ContainerInterface $container, TemplateFinderInterface $finder = null, $paths = []) - { - $this->paths = []; - $keyToRemove = array_search('Modules', $paths); - // If the key was found, move it in a new array - if (false !== $keyToRemove) { - $exceptionPath = $paths[$keyToRemove]; - unset($paths[$keyToRemove]); - $this->paths = [$keyToRemove => $exceptionPath]; - } - parent::__construct($container, $finder, $paths); - } - - /** - * {@inheritdoc} - */ - public function warmUp($cacheDir) - { - // Default behavior for all folder except Modules - parent::warmUp($cacheDir); - - $twig = $this->container->get('twig'); - $templates = []; - - foreach ($this->paths as $path => $namespace) { - $templates = array_merge($templates, $this->findTemplatesInFolder($namespace, $path)); - } - - foreach ($templates as $template) { - if ('twig' !== $template->get('engine')) { - continue; - } - - try { - $twig->loadTemplate($template); - } catch (Error $e) { - // problem during compilation, give up - } - } - } - - /** - * Find templates from *.twig files in the given directory. - * - * @param string $namespace The namespace for these templates - * @param string $dir The folder where to look for templates - * - * @return array An array of templates of type TemplateReferenceInterface - */ - private function findTemplatesInFolder($namespace, $dir) - { - if (!is_dir($dir)) { - return []; - } - - $templates = []; - $finder = new Finder(); - - foreach ($finder->files()->followLinks()->name('*.twig')->in($dir) as $file) { - $name = $file->getRelativePathname(); - $templates[] = new TemplateReference( - $namespace ? sprintf('@%s/%s', $namespace, $name) : $name, - 'twig' - ); - } - - return $templates; - } -} diff --git a/src/PrestaShopBundle/Command/AppendConfigurationFileHooksListCommand.php b/src/PrestaShopBundle/Command/AppendConfigurationFileHooksListCommand.php deleted file mode 100644 index aab62d6a..00000000 --- a/src/PrestaShopBundle/Command/AppendConfigurationFileHooksListCommand.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Employee; -use Exception; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Hook\HookDescription; -use SimpleXMLElement; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Finder\Finder; - -/** - * This command is used for appending the hook names in the configuration file. - */ -class AppendConfigurationFileHooksListCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('prestashop:update:configuration-file-hooks-listing') - ->setDescription('Appends configuration file hooks list') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $container = $this->getContainer(); - - $this->initContext(); - - $io = new SymfonyStyle($input, $output); - - if (!in_array($container->getParameter('kernel.environment'), ['dev', 'test'])) { - $io->warning('Dev or test environment is required to fully list all the hooks'); - - return; - } - - $hookNames = $this->getHookNames(); - $hookDescriptions = $this->getHookDescriptions($hookNames); - - try { - $addedHooks = $this->appendHooksInConfigurationFile($hookDescriptions); - } catch (Exception $e) { - $io->error($e->getMessage()); - } - - if (!empty($addedHooks)) { - $io->title('Hooks added to configuration file'); - $io->note(sprintf('Total hooks added: %s', count($addedHooks))); - - return; - } - - $io->note('No new hooks have been added to configuration file'); - } - - /** - * Initialize PrestaShop Context - */ - private function initContext() - { - /** @var LegacyContext $legacyContext */ - $legacyContext = $this->getContainer()->get('prestashop.adapter.legacy.context'); - //We need to have an employee or the listing hooks don't work - //see LegacyHookSubscriber - if (!$legacyContext->getContext()->employee) { - //Even a non existing employee is fine - $legacyContext->getContext()->employee = new Employee(); - } - } - - /** - * Gets all hooks names which need to be appended. - * - * @return string[] - */ - private function getHookNames() - { - $container = $this->getContainer(); - - $gridServiceIds = $container->getParameter('prestashop.core.grid.definition.service_ids'); - $optionsFormHookNames = $container->getParameter('prestashop.hook.option_form_hook_names'); - $identifiableObjectFormTypes = $container->getParameter('prestashop.core.form.identifiable_object.form_types'); - - $gridDefinitionHooksProvider = $container->get( - 'prestashop.core.hook.provider.grid_definition_hook_by_service_ids_provider' - ); - - $identifiableObjectFormTypeProvider = $container->get( - 'prestashop.core.hook.provider.identifiable_object_hook_by_form_type_provider' - ); - - $gridDefinitionHookNames = $gridDefinitionHooksProvider->getHookNames($gridServiceIds); - - $identifiableObjectHookNames = $identifiableObjectFormTypeProvider->getHookNames($identifiableObjectFormTypes); - - return array_merge( - $identifiableObjectHookNames, - $optionsFormHookNames, - $gridDefinitionHookNames - ); - } - - /** - * Appends given hooks in the configuration file. - * - * @param HookDescription[] $hookDescriptions - * - * @return array - * - * @throws Exception - */ - private function appendHooksInConfigurationFile(array $hookDescriptions) - { - $hookConfigurationFileLocation = $this->getContainer()->get('kernel')->getRootDir() . '/../install-dev/data/xml/'; - $hookFileName = 'hook.xml'; - $fullFilePath = $hookConfigurationFileLocation . $hookFileName; - - $filesFinder = new Finder(); - $filesFinder - ->files() - ->in($hookConfigurationFileLocation) - ->name($hookFileName) - ; - - $hookFileContent = null; - - foreach ($filesFinder as $fileInfo) { - $hookFileContent = $fileInfo->getContents(); - - break; - } - - if (!$hookFileContent) { - throw new Exception(sprintf('File %s has not been found', $fullFilePath)); - } - - $xmlFileContent = new SimpleXMLElement($hookFileContent); - - if (!isset($xmlFileContent->entities, $xmlFileContent->entities->hook)) { - return []; - } - - $existingHookNames = $this->filterExistingHookNames($xmlFileContent->entities->hook); - - $addedHooks = []; - foreach ($hookDescriptions as $hookDescription) { - if (in_array($hookDescription->getName(), $existingHookNames)) { - continue; - } - - $hook = $xmlFileContent->entities->addChild('hook'); - - $hook->addAttribute('id', $hookDescription->getName()); - $hook->addChild('name', $hookDescription->getName()); - $hook->addChild('title', $hookDescription->getTitle()); - $hook->addChild('description', $hookDescription->getDescription()); - - $addedHooks[] = $hookDescription; - } - - if (!$xmlFileContent->saveXML($fullFilePath)) { - throw new Exception(sprintf('Failed to save new xml content to file %s', $fullFilePath)); - } - - return $addedHooks; - } - - /** - * Gets existing hook names which are already defined in the file. - * - * @param SimpleXMLElement $hooksFromXmlFile - * - * @return array - */ - private function filterExistingHookNames(SimpleXMLElement $hooksFromXmlFile) - { - $hookNames = []; - foreach ($hooksFromXmlFile as $hook) { - if (!isset($hook->name)) { - continue; - } - - $hookNames[] = $hook->name->__toString(); - } - - return $hookNames; - } - - /** - * Gets hook descriptions - * - * @param array $hookNames - * - * @return HookDescription[] - */ - private function getHookDescriptions(array $hookNames) - { - $descriptionGenerator = $this->getContainer()->get('prestashop.core.hook.generator.hook_description_generator'); - - $descriptions = []; - foreach ($hookNames as $hookName) { - $hookDescription = $descriptionGenerator->generate($hookName); - - $descriptions[] = $hookDescription; - } - - return $descriptions; - } -} diff --git a/src/PrestaShopBundle/Command/AppendHooksListForSqlUpgradeFileCommand.php b/src/PrestaShopBundle/Command/AppendHooksListForSqlUpgradeFileCommand.php deleted file mode 100644 index 8f916677..00000000 --- a/src/PrestaShopBundle/Command/AppendHooksListForSqlUpgradeFileCommand.php +++ /dev/null @@ -1,268 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Employee; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\Hook\HookDescription; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Filesystem\Exception\FileNotFoundException; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Appends sql upgrade file with the sql which can be used to create new hooks. - */ -class AppendHooksListForSqlUpgradeFileCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('prestashop:update:sql-upgrade-file-hooks-listing') - ->setDescription( - 'Adds sql to sql upgrade file which contains hook insert opeartion' - ) - ->addArgument( - 'ps-version', - InputArgument::REQUIRED, - 'The prestashop version for which sql upgrade file will be searched' - ) - ; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $container = $this->getContainer(); - - $this->initContext(); - - $io = new SymfonyStyle($input, $output); - - if (!in_array($container->getParameter('kernel.environment'), ['dev', 'test'])) { - $io->warning('Dev or test environment is required to fully list all the hooks'); - - return; - } - - $hookNames = $this->getHookNames(); - $hookNames = $this->getWithoutRegisteredHooks($hookNames); - - if (empty($hookNames)) { - $io->note('No hooks found.'); - - return; - } - - $hookDescriptions = $this->getHookDescriptions($hookNames); - - try { - $sqlUpgradeFile = $this->getSqlUpgradeFileByPrestaShopVersion($input->getArgument('ps-version')); - } catch (FileNotFoundException $exception) { - $io->error($exception->getMessage()); - - return; - } - - $sqlInsertStatement = $this->getSqlInsertStatement($hookDescriptions); - - $this->appendSqlToFile($sqlUpgradeFile->getFileInfo()->getPathName(), $sqlInsertStatement); - - $io->success( - sprintf( - 'All %s hooks have been listed to file %s', - count($hookNames), - $sqlUpgradeFile->getFileInfo()->getPathName() - ) - ); - } - - /** - * Initialize PrestaShop Context - */ - private function initContext() - { - /** @var LegacyContext $legacyContext */ - $legacyContext = $this->getContainer()->get('prestashop.adapter.legacy.context'); - //We need to have an employee or the listing hooks don't work - //see LegacyHookSubscriber - if (!$legacyContext->getContext()->employee) { - //Even a non existing employee is fine - $legacyContext->getContext()->employee = new Employee(); - } - } - - /** - * Gets all hooks names which need to be appended. - * - * @return string[] - */ - private function getHookNames() - { - $container = $this->getContainer(); - - $gridServiceIds = $container->getParameter('prestashop.core.grid.definition.service_ids'); - $optionsFormHookNames = $container->getParameter('prestashop.hook.option_form_hook_names'); - $identifiableObjectFormTypes = $container->getParameter('prestashop.core.form.identifiable_object.form_types'); - - $gridDefinitionHooksProvider = $container->get( - 'prestashop.core.hook.provider.grid_definition_hook_by_service_ids_provider' - ); - - $identifiableObjectFormTypeProvider = $container->get( - 'prestashop.core.hook.provider.identifiable_object_hook_by_form_type_provider' - ); - - $gridDefinitionHookNames = $gridDefinitionHooksProvider->getHookNames($gridServiceIds); - - $identifiableObjectHookNames = $identifiableObjectFormTypeProvider->getHookNames($identifiableObjectFormTypes); - - return array_merge( - $identifiableObjectHookNames, - $optionsFormHookNames, - $gridDefinitionHookNames - ); - } - - /** - * Gets sql upgrade file by PrestaShop version. - * - * @param string $version - * - * @return SplFileInfo - */ - private function getSqlUpgradeFileByPrestaShopVersion($version) - { - $sqlUpgradeFilesLocation = $this->getContainer()->get('kernel')->getRootDir() . '/../install-dev/upgrade/sql/'; - $sqlUpgradeFile = $version . '.sql'; - - $filesFinder = new Finder(); - $filesFinder - ->files() - ->in($sqlUpgradeFilesLocation) - ->name($sqlUpgradeFile) - ; - - $filesCount = $filesFinder->count(); - - if (1 !== $filesCount) { - throw new FileNotFoundException(sprintf('Expected to find 1 file but %s files found with name %s', $filesFinder->count(), $sqlUpgradeFile)); - } - - foreach ($filesFinder as $sqlInfo) { - return $sqlInfo; - } - - return null; - } - - /** - * Gets sql insert statement. - * - * @param HookDescription[] $hookDescriptions - * - * @return string - */ - private function getSqlInsertStatement(array $hookDescriptions) - { - $valuesToInsert = []; - foreach ($hookDescriptions as $hookDescription) { - $valuesToInsert[] = sprintf( - '(NULL,"%s","%s","%s","1")', - pSQL($hookDescription->getName()), - pSQL($hookDescription->getTitle()), - pSQL($hookDescription->getDescription()) - ); - } - - if (empty($valuesToInsert)) { - return ''; - } - - return sprintf( - 'INSERT IGNORE INTO `PREFIX_hook` (`id_hook`, `name`, `title`, `description`, `position`) VALUES %s;', - implode(',', $valuesToInsert) - ); - } - - /** - * Appends new content to the given file. - * - * @param string $pathToFile - * @param string $content - */ - private function appendSqlToFile($pathToFile, $content) - { - $fileSystem = new FileSystem(); - - $fileSystem->appendToFile($pathToFile, $content); - } - - /** - * Filters out already registered hooks. - * - * @param array $hookNames - * - * @return array - */ - private function getWithoutRegisteredHooks(array $hookNames) - { - $hooksProvider = $this->getContainer()->get('prestashop.adapter.legacy.hook'); - $registeredHooks = $hooksProvider->getHooks(); - $registeredHookNames = array_column($registeredHooks, 'name'); - - return array_diff($hookNames, $registeredHookNames); - } - - /** - * Gets hook descriptions - * - * @param array $hookNames - * - * @return HookDescription[] - */ - private function getHookDescriptions(array $hookNames) - { - $descriptionGenerator = $this->getContainer()->get('prestashop.core.hook.generator.hook_description_generator'); - - $descriptions = []; - foreach ($hookNames as $hookName) { - $hookDescription = $descriptionGenerator->generate($hookName); - - $descriptions[] = $hookDescription; - } - - return $descriptions; - } -} diff --git a/src/PrestaShopBundle/Command/CheckTranslationDuplicatesCommand.php b/src/PrestaShopBundle/Command/CheckTranslationDuplicatesCommand.php deleted file mode 100644 index 11e7df13..00000000 --- a/src/PrestaShopBundle/Command/CheckTranslationDuplicatesCommand.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use PrestaShopBundle\Translation\PrestaShopTranslatorTrait; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class CheckTranslationDuplicatesCommand extends ContainerAwareCommand -{ - protected function configure() - { - $this - ->setName('prestashop:translation:find-duplicates') - ->setDescription('Find duplicates of your translations'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - // Get dependancies - $translator = $this->getContainer()->get('translator'); - $catalogue = $translator->getCatalogue()->all(); - - // Init progress bar - $progress = new ProgressBar($output, count($catalogue, true)); - $progress->start(); - $progress->setRedrawFrequency(20); - - $duplicates = []; - - foreach ($catalogue as $domain => $messages) { - $nbOfMessages = count($messages); - // In order to use a for() loop, we need integers as keys - $messages = array_keys($messages); - - // We compare strings from the same array, so we have two for() loops - for ($i = 0; $i < $nbOfMessages; ++$i) { - for ($j = ($i + 1); $j < $nbOfMessages; ++$j) { - if ($this->check($messages[$i], $messages[$j])) { - $duplicates[$domain][] = [$i => $messages[$i], $j => $messages[$j]]; - } - } - $progress->advance(); - } - } - - $progress->finish(); - $output->writeln(''); - - // If we have duplicates to fix, let's display them and return their count. - // This will allow us to add the command in the tests. - if (count($duplicates)) { - $output->writeln('Duplicates found:'); - dump($duplicates); - - return count($duplicates, true); - } - - $output->writeln('Awww yisss! There is no duplicate in your translator catalog.'); - - return 0; - } - - /** - * We consider strings as equals if they have the same value after params cleanup. - * - * @param string $message1 - * @param string $message2 - * - * @return bool - */ - protected function check($message1, $message2) - { - return $this->removeParams($message1) == $this->removeParams($message2); - } - - /** - * This function replaces all parameters with a ~ in a string to translate. - * This allow the algorithm to check if the strings are the same once the parameters made generic - * i.e: Error when disabling module %module% ==> Error when disabling module ~. - * - * @param string $message - * - * @return string with replaced parameters - */ - protected function removeParams($message) - { - // Remove PrestaShop arguments %% - $message = preg_replace(PrestaShopTranslatorTrait::$regexClassicParams, '~', $message); - // Remove all related sprintf arguments - $message = preg_replace(PrestaShopTranslatorTrait::$regexSprintfParams, '~', $message); - - return $message; - } -} diff --git a/src/PrestaShopBundle/Command/ExportThemeCommand.php b/src/PrestaShopBundle/Command/ExportThemeCommand.php deleted file mode 100644 index 4e133a02..00000000 --- a/src/PrestaShopBundle/Command/ExportThemeCommand.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -\Smarty_Autoloader::register(); - -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class ExportThemeCommand extends ContainerAwareCommand -{ - protected function configure() - { - $this - ->setName('prestashop:theme:export') - ->setDescription('Create zip to distribute theme with its dependencies') - ->addArgument('theme', InputArgument::REQUIRED, 'Theme to export directory name.'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $repository = $this->getContainer()->get('prestashop.core.addon.theme.repository'); - $theme = $repository->getInstanceByName($input->getArgument('theme')); - - $themeExporter = $this->getContainer()->get('prestashop.core.addon.theme.exporter'); - $path = $themeExporter->export($theme); - - $formatter = $this->getHelper('formatter'); - $translator = $this->getContainer()->get('translator'); - $successMsg = $translator->trans( - 'Your theme has been correctly exported: %path%', - ['%path%' => $path], - 'Admin.Design.Notification' - ); - $formattedBlock = $formatter->formatBlock($successMsg, 'info', true); - $output->writeln($formattedBlock); - } -} diff --git a/src/PrestaShopBundle/Command/GenerateMailTemplatesCommand.php b/src/PrestaShopBundle/Command/GenerateMailTemplatesCommand.php deleted file mode 100644 index c7c02352..00000000 --- a/src/PrestaShopBundle/Command/GenerateMailTemplatesCommand.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Employee; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; - -class GenerateMailTemplatesCommand extends ContainerAwareCommand -{ - protected function configure() - { - $this - ->setName('prestashop:mail:generate') - ->setDescription('Generate mail templates for a specified theme') - ->addArgument('theme', InputArgument::REQUIRED, 'Theme to use for mail templates.') - ->addArgument('locale', InputArgument::REQUIRED, 'Which locale to use for the templates.') - ->addArgument('coreOutputFolder', InputArgument::OPTIONAL, 'Output folder to export core templates.') - ->addArgument('modulesOutputFolder', InputArgument::OPTIONAL, 'Output folder to export modules templates (by default same as core).') - ->addOption('overwrite', 'o', InputOption::VALUE_OPTIONAL, 'Overwrite existing templates', false) - ; - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int|void|null - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $themeName = $input->getArgument('theme'); - $coreOutputFolder = $input->getArgument('coreOutputFolder'); - if (!empty($coreOutputFolder) && file_exists($coreOutputFolder)) { - $coreOutputFolder = realpath($coreOutputFolder); - } - $modulesOutputFolder = $input->getArgument('modulesOutputFolder'); - if (!empty($modulesOutputFolder) && file_exists($modulesOutputFolder)) { - $modulesOutputFolder = realpath($modulesOutputFolder); - } else { - $modulesOutputFolder = $coreOutputFolder; - } - $overwrite = false !== $input->getOption('overwrite'); - - $this->initContext(); - - $locale = $input->getArgument('locale'); - - $output->writeln(sprintf('Exporting mail with theme %s for language %s', $themeName, $locale)); - - /** @var GenerateThemeMailTemplatesCommand $generateCommand */ - $generateCommand = new GenerateThemeMailTemplatesCommand( - $themeName, - $locale, - $overwrite, - $coreOutputFolder ?: '', - $modulesOutputFolder ?: '' - ); - /** @var CommandBusInterface $commandBus */ - $commandBus = $this->getContainer()->get('prestashop.core.command_bus'); - $commandBus->handle($generateCommand); - } - - /** - * Initialize PrestaShop Context - */ - private function initContext() - { - /** @var LegacyContext $legacyContext */ - $legacyContext = $this->getContainer()->get('prestashop.adapter.legacy.context'); - //We need to have an employee or the module hooks don't work - //see LegacyHookSubscriber - if (!$legacyContext->getContext()->employee) { - //Even a non existing employee is fine - $legacyContext->getContext()->employee = new Employee(42); - } - } -} diff --git a/src/PrestaShopBundle/Command/LegacyLinkLinterCommand.php b/src/PrestaShopBundle/Command/LegacyLinkLinterCommand.php deleted file mode 100644 index 96dc4665..00000000 --- a/src/PrestaShopBundle/Command/LegacyLinkLinterCommand.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; - -/** - * Checks if all admin routes are configured with _legacy_link - */ -class LegacyLinkLinterCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('prestashop:linter:legacy-link') - ->setDescription('Checks if _legacy_link is configured in BackOffice routes'); - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $unconfiguredRoutes = $this->getUnconfiguredRoutes(); - $io = new SymfonyStyle($input, $output); - - if (!empty($unconfiguredRoutes)) { - $io->warning(sprintf( - '%s routes are not configured with _legacy_link:', - count($unconfiguredRoutes) - )); - $io->listing($unconfiguredRoutes); - - return; - } - - $io->success('There is no routes without _legacy_link settings'); - } - - /** - * Returns routes that are missing _legacy_link configuration - * - * @return array - */ - private function getUnconfiguredRoutes() - { - $legacyLinkLinter = $this->getContainer()->get('prestashop.bundle.routing.linter.legacy_link_linter'); - $adminRouteProvider = $this->getContainer()->get('prestashop.bundle.routing.linter.admin_route_provider'); - $routes = $adminRouteProvider->getRoutes(); - $unconfiguredRoutes = []; - - foreach ($routes as $routeName => $route) { - if (true === $legacyLinkLinter->lint('_legacy_link', $route)) { - continue; - } - $unconfiguredRoutes[] = $routeName; - } - - return $unconfiguredRoutes; - } -} diff --git a/src/PrestaShopBundle/Command/ListCommandsAndQueriesCommand.php b/src/PrestaShopBundle/Command/ListCommandsAndQueriesCommand.php deleted file mode 100644 index 0f96e6a6..00000000 --- a/src/PrestaShopBundle/Command/ListCommandsAndQueriesCommand.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Formatter\OutputFormatterStyle; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Lists all commands and queries definitions - */ -class ListCommandsAndQueriesCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - public function configure() - { - $this - ->setName('prestashop:list:commands-and-queries') - ->setDescription('Lists available CQRS commands and queries') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $commands = $this->getContainer()->getParameter('prestashop.commands_and_queries'); - $commandDefinitionParser = $this->getContainer()->get('prestashop.core.provider.command_definition_provider'); - - $outputStyle = new OutputFormatterStyle('blue', null); - $output->getFormatter()->setStyle('blue', $outputStyle); - - foreach ($commands as $key => $commandName) { - $commandDefinition = $commandDefinitionParser->parseDefinition($commandName); - - $output->writeln(++$key . '.'); - $output->writeln('Class: ' . $commandDefinition->getClassName() . ''); - $output->writeln('Type: ' . $commandDefinition->getCommandType() . ''); - $output->writeln('' . $commandDefinition->getDescription() . ''); - $output->writeln(''); - } - } -} diff --git a/src/PrestaShopBundle/Command/ModuleCommand.php b/src/PrestaShopBundle/Command/ModuleCommand.php deleted file mode 100644 index 544ca133..00000000 --- a/src/PrestaShopBundle/Command/ModuleCommand.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Employee; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class ModuleCommand extends ContainerAwareCommand -{ - private $allowedActions = [ - 'install', - 'uninstall', - 'enable', - 'disable', - 'enable_mobile', - 'disable_mobile', - 'reset', - 'upgrade', - 'configure', - ]; - - /** - * @var \Symfony\Component\Console\Helper\FormatterHelper - */ - protected $formatter; - - /** - * @var \PrestaShopBundle\Translation\Translator - */ - protected $translator; - - /** - * @var \Symfony\Component\Console\Input\Input - */ - protected $input; - - /** - * @var \Symfony\Component\Console\Output\Output - */ - protected $output; - - protected function configure() - { - $this - ->setName('prestashop:module') - ->setDescription('Manage your modules via command line') - ->addArgument('action', InputArgument::REQUIRED, sprintf('Action to execute (Allowed actions: %s).', implode(' / ', $this->allowedActions))) - ->addArgument('module name', InputArgument::REQUIRED, 'Module on which the action will be executed') - ->addArgument('file path', InputArgument::OPTIONAL, 'YML file path for configuration'); - } - - protected function init(InputInterface $input, OutputInterface $output) - { - $this->formatter = $this->getHelper('formatter'); - $this->translator = $this->getContainer()->get('translator'); - $this->input = $input; - $this->output = $output; - /** @var LegacyContext $legacyContext */ - $legacyContext = $this->getContainer()->get('prestashop.adapter.legacy.context'); - //We need to have an employee or the module hooks don't work - //see LegacyHookSubscriber - if (!$legacyContext->getContext()->employee) { - //Even a non existing employee is fine - $legacyContext->getContext()->employee = new Employee(42); - } - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->init($input, $output); - - $moduleName = $input->getArgument('module name'); - $action = $input->getArgument('action'); - $file = $input->getArgument('file path'); - - if (!in_array($action, $this->allowedActions)) { - $this->displayMessage( - $this->translator->trans( - 'Unknown module action. It must be one of these values: %actions%', - ['%actions%' => implode(' / ', $this->allowedActions)], - 'Admin.Modules.Notification' - ), - 'error' - ); - - return; - } - - if ($action === 'configure') { - $this->executeConfigureModuleAction($moduleName, $file); - } else { - $this->executeGenericModuleAction($action, $moduleName); - } - } - - protected function executeConfigureModuleAction($moduleName, $file = null) - { - $moduleSelfConfigurator = $this->getContainer()->get('prestashop.adapter.module.self_configurator'); - $moduleSelfConfigurator->module($moduleName); - if ($file) { - $moduleSelfConfigurator->file($file); - } - - // Check if validation passed and exit in case of errors - $errors = $moduleSelfConfigurator->validate(); - if (!empty($errors)) { - // Display errors as a list - $errors = array_map(function ($val) { return '- ' . $val; }, $errors); - // And add a default message at the top - array_unshift($errors, $this->translator->trans( - 'Validation of configuration details failed:', - [], - 'Admin.Modules.Notification' - )); - $this->displayMessage($errors, 'error'); - - return; - } - - // Actual configuration - $moduleSelfConfigurator->configure(); - $this->displayMessage( - $this->translator->trans('Configuration successfully applied.', [], 'Admin.Modules.Notification'), - 'info' - ); - } - - protected function executeGenericModuleAction($action, $moduleName) - { - /** - * @var \PrestaShop\PrestaShop\Core\Addon\Module\ModuleManager - */ - $moduleManager = $this->getContainer()->get('prestashop.module.manager'); - if ($moduleManager->{$action}($moduleName)) { - $this->displayMessage( - $this->translator->trans( - '%action% action on module %module% succeeded.', - [ - '%action%' => ucfirst(str_replace('_', ' ', $action)), - '%module%' => $moduleName, ], - 'Admin.Modules.Notification' - ) - ); - - return; - } - - $error = $moduleManager->getError($moduleName); - $this->displayMessage( - $this->translator->trans( - 'Cannot %action% module %module%. %error_details%', - [ - '%action%' => str_replace('_', ' ', $action), - '%module%' => $moduleName, - '%error_details%' => $error, ], - 'Admin.Modules.Notification' - ), - 'error' - ); - } - - protected function displayMessage($message, $type = 'info') - { - $this->output->writeln( - $this->formatter->formatBlock($message, $type, true) - ); - } -} diff --git a/src/PrestaShopBundle/Command/NamingConventionLinterCommand.php b/src/PrestaShopBundle/Command/NamingConventionLinterCommand.php deleted file mode 100644 index 9b5df97b..00000000 --- a/src/PrestaShopBundle/Command/NamingConventionLinterCommand.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use PrestaShopBundle\Routing\Linter\Exception\LinterException; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Routing\Route; - -/** - * Runs naming conventions linter in the CLI - */ -final class NamingConventionLinterCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - public function configure() - { - $this - ->setName('prestashop:linter:naming-convention') - ->setDescription('Checks if Back Office routes and controllers follow naming convention.') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $adminRouteProvider = $this->getContainer()->get('prestashop.bundle.routing.linter.admin_route_provider'); - $namingConventionLinter = $this->getContainer() - ->get('prestashop.bundle.routing.linter.naming_convention_linter'); - - $ioTableheaders = ['Invalid routes', 'Valid routes suggestions']; - $ioTableRows = []; - /** @var Route $route */ - foreach ($adminRouteProvider->getRoutes() as $routeName => $route) { - try { - $namingConventionLinter->lint($routeName, $route); - } catch (LinterException $e) { - $ioTableRows[] = [$routeName, $e->getExpectedRouteName()]; - } - } - - $io = new SymfonyStyle($input, $output); - - if (!empty($ioTableRows)) { - $io->title('PrestaShop routes follow admin_{resources}_{action} naming convention structure'); - $io->warning(sprintf( - '%s routes are not following naming conventions:', - count($ioTableRows) - )); - $io->table($ioTableheaders, $ioTableRows); - - return 1; - } - - $io->success('Admin routes and controllers follow naming conventions.'); - - return 0; - } -} diff --git a/src/PrestaShopBundle/Command/SecurityAnnotationLinterCommand.php b/src/PrestaShopBundle/Command/SecurityAnnotationLinterCommand.php deleted file mode 100644 index 79393d4e..00000000 --- a/src/PrestaShopBundle/Command/SecurityAnnotationLinterCommand.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use PrestaShopBundle\Routing\Linter\Exception\LinterException; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Routing\Route; - -/** - * Checks if all admin routes have @AdminSecurity configured - */ -final class SecurityAnnotationLinterCommand extends ContainerAwareCommand -{ - /** - * {@inheritdoc} - */ - public function configure() - { - $this - ->setName('prestashop:linter:security-annotation') - ->setDescription('Checks if Back Office route controllers has configured Security annotations.') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $adminRouteProvider = $this->getContainer()->get('prestashop.bundle.routing.linter.admin_route_provider'); - $securityAnnotationLinter = $this->getContainer() - ->get('prestashop.bundle.routing.linter.security_annotation_linter'); - - $notConfiguredRoutes = []; - - /** @var Route $route */ - foreach ($adminRouteProvider->getRoutes() as $routeName => $route) { - try { - $securityAnnotationLinter->lint($routeName, $route); - } catch (LinterException $e) { - $notConfiguredRoutes[] = $routeName; - } - } - - $io = new SymfonyStyle($input, $output); - - if (!empty($notConfiguredRoutes)) { - $io->warning(sprintf( - '%s routes are not configured with @AdminSecurity annotation:', - count($notConfiguredRoutes) - )); - $io->listing($notConfiguredRoutes); - - return; - } - - $io->success('Admin routes has @AdminSecurity configured.'); - } -} diff --git a/src/PrestaShopBundle/Command/ThemeEnablerCommand.php b/src/PrestaShopBundle/Command/ThemeEnablerCommand.php deleted file mode 100644 index 746d631a..00000000 --- a/src/PrestaShopBundle/Command/ThemeEnablerCommand.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Context; -use Employee; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Style\SymfonyStyle; - -final class ThemeEnablerCommand extends ContainerAwareCommand -{ - /** - * @var bool using CLI, the user must be allowed to enable themes - */ - const USER_ALLOWED_TO_ENABLE = true; - - /** - * @var int if the activation of the theme fails, return the right code - */ - const RETURN_CODE_FAILED = 1; - - /** - * {@inheritdoc} - */ - protected function init(InputInterface $input, OutputInterface $output) - { - Context::getContext()->employee = new Employee(); - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('prestashop:theme:enable') - ->setDescription('Manage your themes via command line') - ->addArgument('theme', InputArgument::REQUIRED, 'Module on which the action will be executed') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $io = new SymfonyStyle($input, $output); - $theme = $input->getArgument('theme'); - $this->init($input, $output); - - $activationSuccess = $this->getContainer() - ->get('prestashop.core.addon.theme.theme_manager') - ->enable( - $theme, - self::USER_ALLOWED_TO_ENABLE - ) - ; - - if (false === $activationSuccess) { - $io->error(sprintf('The selected theme "%s" is invalid', $theme)); - - return self::RETURN_CODE_FAILED; - } - - $io->success(sprintf('Theme "%s" enabled with success.', $theme)); - } -} diff --git a/src/PrestaShopBundle/Command/UpdateEUTaxruleGroupsCommand.php b/src/PrestaShopBundle/Command/UpdateEUTaxruleGroupsCommand.php deleted file mode 100644 index d110f792..00000000 --- a/src/PrestaShopBundle/Command/UpdateEUTaxruleGroupsCommand.php +++ /dev/null @@ -1,242 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use DOMDocument; -use SimpleXMLElement; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * This script will update the tax rule groups for virtual products from all EU localization packs. - * All it needs is that the correct tax in each localization pack is marked with `eu-tax-group="virtual"`. - **. - * - * 1) - * Parse all files under /localization, - * looking for elements that have the attribute eu-tax-group="virtual". - * - * Store the list of files (`$euLocalizationFiles`) where such taxes have been found, - * in a next step we'll store the new tax group in each of them. - * - * 2) - * Remove all taxRulesGroup's that have the attribute eu-tax-group="virtual". - * - * 3) - * Build a new taxRulesGroup containing all the taxes found in the first step. - * - * 4) - * Inject the new taxRulesGroup into all packs of `$euLocalizationFiles`, not forgetting - * to also inject the required taxes. - * - * Warning: do not duplicate the tax with attribute eu-tax-group="virtual" of the pack being updated. - * - * Mark the injected group with the attributes eu-tax-group="virtual" and auto-generated="1" - * Mark the injected taxes witth the attributes from-eu-tax-group="virtual" and auto-generated="1" - * - * Clean things up by removing all the previous taxes that had the attributes eu-tax-group="virtual" and auto-generated="1" - */ -class UpdateEUTaxruleGroupsCommand extends ContainerAwareCommand -{ - /** - * @var OutputInterface - */ - private $output; - - protected function configure() - { - $this - ->setName('prestashop:taxes:update-eu-tax-rule-groups') - ->setDescription('Update EU Tax rule groups'); - } - - public function execute(InputInterface $input, OutputInterface $output) - { - /* Tweak */ - $this->output = $output; - - $localizationPacksRoot = $this->getContainer()->getParameter('kernel.root_dir') . '/../localization'; - - if (!$localizationPacksRoot) { - return $output->writeln("Could not find the folder containing the localization files (should be 'localization' at the root of the PrestaShop folder)"); - } - - $euLocalizationFiles = []; - - foreach (scandir($localizationPacksRoot, SCANDIR_SORT_ASCENDING) as $entry) { - if (!preg_match('/\.xml$/', $entry)) { - continue; - } - - $localizationPackFile = $localizationPacksRoot . DIRECTORY_SEPARATOR . $entry; - - $localizationPack = @simplexml_load_file($localizationPackFile); - - // Some packs do not have taxes - if (!$localizationPack || !$localizationPack->taxes->tax) { - continue; - } - - foreach ($localizationPack->taxes->tax as $tax) { - if ((string) $tax['eu-tax-group'] === 'virtual') { - if (!isset($euLocalizationFiles[$localizationPackFile])) { - $euLocalizationFiles[$localizationPackFile] = [ - 'virtualTax' => $tax, - 'pack' => $localizationPack, - 'iso_code_country' => basename($entry, '.xml'), - ]; - } else { - return $output->writeln("Too many taxes with eu-tax-group=\"virtual\" found in `$localizationPackFile`."); - } - } - } - } - - foreach ($euLocalizationFiles as $path => $file) { - $nodesToKill = []; - - // Get max tax id, and list of nodes to kill - $taxId = 0; - foreach ($file['pack']->taxes->tax as $tax) { - if ((string) $tax['auto-generated'] === '1' && (string) $tax['from-eu-tax-group'] === 'virtual') { - $nodesToKill[] = $tax; - } else { - // We only count the ids of the taxes we're not going to remove! - $taxId = max($taxId, (int) $tax['id']); - } - } - - foreach ($file['pack']->taxes->taxRulesGroup as $trg) { - if ((string) $trg['auto-generated'] === '1' && (string) $trg['eu-tax-group'] === 'virtual') { - $nodesToKill[] = $trg; - } - } - - // This is the first tax id we're allowed to use. - ++$taxId; - - // Prepare new taxRulesGroup - - $taxRulesGroup = $file['pack']->taxes->addChild('taxRulesGroup'); - $taxRulesGroup->addAttribute('name', 'EU VAT For Virtual Products'); - $taxRulesGroup->addAttribute('auto-generated', '1'); - $taxRulesGroup->addAttribute('eu-tax-group', 'virtual'); - - $this->addTaxRule($taxRulesGroup, $file['virtualTax'], $file['iso_code_country']); - - foreach ($euLocalizationFiles as $foreignPath => $foreignFile) { - if ($foreignPath === $path) { - // We already added the tax that belongs to this pack - continue; - } - - $tax = $this->addTax($file['pack']->taxes, $foreignFile['virtualTax'], [ - 'id' => (string) $taxId, - 'auto-generated' => '1', - 'from-eu-tax-group' => 'virtual', - ], ['eu-tax-group']); - - $this->addTaxRule($taxRulesGroup, $tax, $foreignFile['iso_code_country']); - - ++$taxId; - } - - foreach ($nodesToKill as $node) { - unset($node[0]); - } - - $dom = new DOMDocument('1.0'); - $dom->preserveWhiteSpace = false; - $dom->formatOutput = true; - $dom->loadXML($file['pack']->asXML()); - file_put_contents($path, $dom->saveXML()); - } - - $nUpdated = count($euLocalizationFiles); - - $output->writeln("Updated the virtual tax groups for $nUpdated localization files"); - } - - protected function addTax(SimpleXMLElement $taxes, SimpleXMLElement $tax, array $attributesToUpdate = [], array $attributesToRemove = []) - { - $newTax = new SimpleXMLElement(''); - - $taxRulesGroups = $taxes->xpath('//taxRulesGroup[1]'); - $insertBefore = $taxRulesGroups[0]; - - if (!$insertBefore) { - return $this->output->writeln("Could not find any `taxRulesGroup`, don't know where to append the tax."); - } - - /** - * Add the `tax` node before the first `taxRulesGroup`. - * Yes, the dom API is beautiful. - */ - $dom = dom_import_simplexml($taxes); - - $new = $dom->insertBefore( - $dom->ownerDocument->importNode(dom_import_simplexml($newTax)), - dom_import_simplexml($insertBefore) - ); - - $newTax = simplexml_import_dom($new); - - $newAttributes = []; - - foreach ($tax->attributes() as $attribute) { - $name = $attribute->getName(); - - // This attribute seems to cause trouble, skip it. - if ($name === 'account_number' || in_array($name, $attributesToRemove)) { - continue; - } - - $value = (string) $attribute; - - $newAttributes[$name] = $value; - } - - $newAttributes = array_merge($newAttributes, $attributesToUpdate); - - foreach ($newAttributes as $name => $value) { - $newTax->addAttribute($name, $value); - } - - return $newTax; - } - - protected function addTaxRule(SimpleXMLElement $taxRulesGroup, SimpleXMLElement $tax, $iso_code_country) - { - $taxRule = $taxRulesGroup->addChild('taxRule'); - - $taxRule->addAttribute('iso_code_country', $iso_code_country); - $taxRule->addAttribute('id_tax', (string) $tax['id']); - - return $taxRule; - } -} diff --git a/src/PrestaShopBundle/Command/UpdateLicensesCommand.php b/src/PrestaShopBundle/Command/UpdateLicensesCommand.php deleted file mode 100644 index 6a1d5d96..00000000 --- a/src/PrestaShopBundle/Command/UpdateLicensesCommand.php +++ /dev/null @@ -1,376 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use PhpParser\ParserFactory; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -class UpdateLicensesCommand extends Command -{ - private $text = '/** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the {licenseName} - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * {licenseLink} - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license {licenseLink} {licenseName} - */'; - - /** - * @var string - */ - private $license; - - private $aflLicense = [ - 'themes/classic/', - 'themes/StarterTheme/', - 'modules/', - ]; - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('prestashop:licenses:update') - ->setDescription('Rewrite your licenses to be up-to-date'); - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->text = str_replace('{currentYear}', date('Y'), $this->text); - - $extensions = [ - 'php', - 'js', - 'css', - 'tpl', - 'html.twig', - 'json', - 'vue', - ]; - - foreach ($extensions as $extension) { - $this->findAndCheckExtension($output, $extension); - } - } - - /** - * @param OutputInterface $output - * @param string $ext - */ - private function findAndCheckExtension(OutputInterface $output, $ext) - { - $finder = new Finder(); - $finder - ->files() - ->name('*.' . $ext) - ->in(_PS_ROOT_DIR_) - ->exclude([ - // versioning folders - '.git', - '.github', - '.composer', - // admin folders - 'admin-dev/filemanager', - 'admin-dev/themes/default/public/', - 'admin-dev/themes/new-theme/public/', - // js dependencies - 'js/tiny_mce', - 'js/jquery', - 'js/cropper', - // mails folder - 'mails/themes/classic/', - 'mails/themes/modern/', - // tools dependencies - 'tools/htmlpurifier', - // dependencies - 'vendor', - 'node_modules', - // themes assets - 'themes/classic/assets/', - 'themes/starterTheme/assets/', - // tests folders - 'tests/Resources/modules/', - 'tests/Resources/themes/', - 'tests/Resources/translations/', - 'tests/resources/ModulesOverrideInstallUninstallTest/', - 'tests-legacy/PrestaShopBundle/Twig/Fixtures/', - 'tests-legacy/resources/', - 'tests/E2E/', - 'tests/Unit/Resources/assets/', - 'tests/UI/', - ]) - ->ignoreDotFiles(false); - $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); - - $output->writeln('Updating license in ' . strtoupper($ext) . ' files ...'); - $progress = new ProgressBar($output, count($finder)); - $progress->start(); - $progress->setRedrawFrequency(20); - - $filesToIgnore = [ - 'composer.json', - 'package.json', - 'admin-dev/themes/default/css/font.css', - 'admin-dev/themes/new-theme/package.json', - 'tools/build/Library/InstallUnpacker/content/js-runner.js', - 'themes/classic/_dev/package.json', - 'tools/build/composer.json', - ]; - - foreach ($finder as $file) { - $this->license = $this->text; - $this->makeGoodLicense($file); - - if (in_array($file->getRelativePathName(), $filesToIgnore)) { - continue; - } - - switch ($file->getExtension()) { - case 'php': - try { - $nodes = $parser->parse($file->getContents()); - if (count($nodes)) { - $this->addLicenseToNode($nodes[0], $file); - } - } catch (\PhpParser\Error $exception) { - $output->writeln('Syntax error on file ' . $file->getRelativePathname() . '. Continue ...'); - } - - break; - case 'js': - case 'css': - $this->addLicenseToFile($file); - - break; - case 'tpl': - $this->addLicenseToSmartyTemplate($file); - - break; - case 'twig': - $this->addLicenseToTwigTemplate($file); - - break; - case 'json': - $this->addLicenseToJsonFile($file); - - break; - case 'vue': - $this->addLicenseToHtmlFile($file); - - break; - } - $progress->advance(); - } - - $progress->finish(); - $output->writeln(''); - } - - /** - * @param SplFileInfo $file - */ - private function makeGoodLicense(SplFileInfo $file) - { - if ($this->isAFLLicense($file->getRelativePathname())) { - $this->makeAFLLicense(); - } else { - $this->makeOSLLicense(); - } - } - - /** - * @param $fileName - * - * @return bool - */ - private function isAFLLicense($fileName) - { - foreach ($this->aflLicense as $afl) { - if (0 === strpos($fileName, $afl)) { - return true; - } - } - - return false; - } - - /** - * Replace for OSL licenses. - */ - private function makeOSLLicense() - { - $this->license = str_replace('{licenseName}', 'Open Software License (OSL 3.0)', $this->license); - $this->license = str_replace('{licenseLink}', 'https://opensource.org/licenses/OSL-3.0', $this->license); - } - - /** - * Replace for AFL licenses. - */ - private function makeAFLLicense() - { - $this->license = str_replace('{licenseName}', 'Academic Free License 3.0 (AFL-3.0)', $this->license); - $this->license = str_replace('{licenseLink}', 'https://opensource.org/licenses/AFL-3.0', $this->license); - } - - /** - * @param SplFileInfo $file - * @param string $startDelimiter - * @param string $endDelimiter - */ - private function addLicenseToFile($file, $startDelimiter = '\/', $endDelimiter = '\/') - { - $content = $file->getContents(); - // Regular expression found thanks to Stephen Ostermiller's Blog. http://blog.ostermiller.org/find-comment - $regex = '%' . $startDelimiter . '\*([^*]|[\r\n]|(\*+([^*' . $endDelimiter . ']|[\r\n])))*\*+' . $endDelimiter . '%'; - $matches = []; - $text = $this->license; - if ($startDelimiter != '\/') { - $text = $startDelimiter . ltrim($text, '/'); - } - if ($endDelimiter != '\/') { - $text = rtrim($text, '/') . $endDelimiter; - } - - // Try to find an existing license - preg_match($regex, $content, $matches); - - if (count($matches)) { - // Found - Replace it if prestashop one - foreach ($matches as $match) { - if (stripos($match, 'prestashop') !== false) { - $content = str_replace($match, $text, $content); - } - } - } else { - // Not found - Add it at the beginning of the file - $content = $text . "\n" . $content; - } - - file_put_contents($file->getRelativePathname(), $content); - } - - /** - * @param $node - * @param SplFileInfo $file - */ - private function addLicenseToNode($node, SplFileInfo $file) - { - if (!$node->hasAttribute('comments')) { - $needle = 'license . "\n"; - $haystack = $file->getContents(); - - $pos = strpos($haystack, $needle); - // Important, if the getRelativePathname(), $newstring); - } - - return; - } - - $comments = $node->getAttribute('comments'); - foreach ($comments as $comment) { - if ($comment instanceof \PhpParser\Comment - && strpos($comment->getText(), 'prestashop') !== false) { - file_put_contents($file->getRelativePathname(), str_replace($comment->getText(), $this->license, $file->getContents())); - } - } - } - - /** - * @param SplFileInfo $file - */ - private function addLicenseToSmartyTemplate(SplFileInfo $file) - { - $this->addLicenseToFile($file, '{', '}'); - } - - /** - * @param SplFileInfo $file - */ - private function addLicenseToTwigTemplate(SplFileInfo $file) - { - if (strrpos($file->getRelativePathName(), 'html.twig') !== false) { - $this->addLicenseToFile($file, '{#', '#}'); - } - } - - /** - * @param SplFileInfo $file - */ - private function addLicenseToHtmlFile(SplFileInfo $file) - { - $this->addLicenseToFile($file, ''); - } - - /** - * @param SplFileInfo $file - * - * @return bool - */ - private function addLicenseToJsonFile(SplFileInfo $file) - { - if (!in_array($file->getFilename(), ['composer.json', 'package.json'])) { - return false; - } - - $content = (array) json_decode($file->getContents()); - $content['author'] = 'PrestaShop'; - $content['license'] = $this->isAFLLicense($file->getRelativePathname()) ? 'AFL-3.0' : 'OSL-3.0'; - - return file_put_contents($file->getRelativePathname(), json_encode($content, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); - } -} diff --git a/src/PrestaShopBundle/Command/UpdateSchemaCommand.php b/src/PrestaShopBundle/Command/UpdateSchemaCommand.php deleted file mode 100644 index 3bf6bc82..00000000 --- a/src/PrestaShopBundle/Command/UpdateSchemaCommand.php +++ /dev/null @@ -1,224 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Command; - -use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Tools\SchemaTool; -use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class UpdateSchemaCommand extends ContainerAwareCommand -{ - /** - * @var EntityManagerInterface - */ - private $em; - - private $metadata; - - private $dbName; - - private $dbPrefix; - - protected function configure() - { - $this - ->setName('prestashop:schema:update-without-foreign') - ->setDescription('Update the database'); - } - - /** - * @param InputInterface $input - * @param OutputInterface $output - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $container = $this->getContainer(); - - $this->dbName = $container->getParameter('database_name'); - $this->dbPrefix = $container->getParameter('database_prefix'); - - $this->em = $container->get('doctrine')->getManager(); - $this->metadata = $this->em->getMetadataFactory()->getAllMetadata(); - - $conn = $this->em->getConnection(); - $conn->beginTransaction(); - - $output->writeln('Updating database schema...'); - $sqls = 0; - - // First drop any existing FK - $query = $conn->query( - 'SELECT CONSTRAINT_NAME, TABLE_NAME - FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS - WHERE CONSTRAINT_TYPE = "FOREIGN KEY" - AND TABLE_SCHEMA = "' . $this->dbName . '" - AND TABLE_NAME LIKE "' . $this->dbPrefix . '%" ' - ); - - $results = $query->fetchAll(); - foreach ($results as $result) { - $drop = 'ALTER TABLE ' . $result['TABLE_NAME'] . ' DROP FOREIGN KEY ' . $result['CONSTRAINT_NAME']; - $output->writeln('Executing: ' . $drop); - $conn->executeQuery($drop); - ++$sqls; - } - - $schemaTool = new SchemaTool($this->em); - $updateSchemaSql = $schemaTool->getUpdateSchemaSql($this->metadata, false); - - $removedTables = []; - $dropForeignKeyQueries = []; - - // Remove the DROP TABLE - foreach ($updateSchemaSql as $key => $sql) { - $matches = []; - if (preg_match('/DROP TABLE (.+?)$/', $sql, $matches)) { - unset($updateSchemaSql[$key]); - $removedTables[] = $matches[1]; - } - } - - // Then remove the ALTER TABLE on removed tables - foreach ($updateSchemaSql as $key => $sql) { - $matches = []; - if (preg_match('/ALTER TABLE (.+?) /', $sql, $matches)) { - $alteredTables = $matches[1]; - if (in_array($alteredTables, $removedTables)) { - unset($updateSchemaSql[$key]); - } - } - } - - // Remove duplicated DROP FOREIGN KEY - foreach ($updateSchemaSql as $key => $sql) { - if (preg_match('/ DROP FOREIGN KEY /', $sql)) { - $hashedSql = md5($sql); - if (in_array($hashedSql, $dropForeignKeyQueries)) { - unset($updateSchemaSql[$key]); - } else { - $dropForeignKeyQueries[] = $hashedSql; - } - } - } - - // Remove ADD CONSTRAINT - foreach ($updateSchemaSql as $key => $sql) { - if (preg_match('/ ADD CONSTRAINT /', $sql)) { - unset($updateSchemaSql[$key]); - } - } - - $constraints = []; - - // Move DROP FOREIGN KEY at the beginning of the sql list - foreach ($updateSchemaSql as $key => $sql) { - if (preg_match('/ DROP FOREIGN KEY /', $sql)) { - $constraints[] = $sql; - unset($updateSchemaSql[$key]); - } - } - - foreach ($constraints as $constraint) { - array_unshift($updateSchemaSql, $constraint); - } - - // Put back DEFAULT fields, since it cannot be described in the ORM model - foreach ($updateSchemaSql as $key => $sql) { - $matches = []; - if (preg_match('/ALTER TABLE (.+?) /', $sql, $matches)) { - $tableName = $matches[1]; - $matches = []; - if (preg_match_all('/([^\s,]*?) CHANGE (.+?) (.+?)(,|$)/', $sql, $matches)) { - foreach ($matches[2] as $matchKey => $fieldName) { - // remove table name - $matches[0][$matchKey] = preg_replace( - '/(.+?) CHANGE/', - ' CHANGE', - $matches[0][$matchKey] - ); - // remove quote - $originalFieldName = $fieldName; - $fieldName = str_replace('`', '', $fieldName); - // get old default value - $query = $conn->query('SHOW FULL COLUMNS FROM ' . $tableName . ' WHERE Field="' . $fieldName . '"'); - $results = $query->fetchAll(); - $oldDefaultValue = $results[0]['Default']; - $extra = $results[0]['Extra']; - if ($oldDefaultValue !== null - && strpos($oldDefaultValue, 'CURRENT_TIMESTAMP') === false) { - $oldDefaultValue = "'" . $oldDefaultValue . "'"; - } - if ($oldDefaultValue === null) { - $oldDefaultValue = 'NULL'; - } - // set the old default value - if (!($results[0]['Null'] == 'NO' && $results[0]['Default'] === null) - && !($oldDefaultValue === 'NULL' - && strpos($matches[0][$matchKey], 'NOT NULL') !== false) - && (strpos($matches[0][$matchKey], 'BLOB') === false) - && (strpos($matches[0][$matchKey], 'TEXT') === false) - ) { - if (preg_match('/DEFAULT/', $matches[0][$matchKey])) { - $matches[0][$matchKey] = - preg_replace('/DEFAULT (.+?)(,|$)/', 'DEFAULT ' . - $oldDefaultValue . '$2' . ' ' . $extra, $matches[0][$matchKey]); - } else { - $matches[0][$matchKey] = - preg_replace('/(.+?)(,|$)/uis', '$1 DEFAULT ' . - $oldDefaultValue . ' ' . $extra . '$2', $matches[0][$matchKey]); - } - } - $updateSchemaSql[$key] = preg_replace( - '/ CHANGE ' . $originalFieldName . ' (.+?)(,|$)/uis', - $matches[0][$matchKey], - $updateSchemaSql[$key] - ); - } - } - } - } - - $sqls += count($updateSchemaSql); - // Now execute the queries! - foreach ($updateSchemaSql as $sql) { - try { - $output->writeln('Executing: ' . $sql); - $conn->executeQuery($sql); - } catch (\Exception $e) { - $conn->rollBack(); - - throw($e); - } - } - $conn->commit(); - - $pluralization = (1 > $sqls) ? 'query was' : 'queries were'; - $output->writeln(sprintf('Database schema updated successfully! "%s" %s executed', $sqls, $pluralization)); - } -} diff --git a/src/PrestaShopBundle/Component/CsvResponse.php b/src/PrestaShopBundle/Component/CsvResponse.php deleted file mode 100644 index e1ab6cfa..00000000 --- a/src/PrestaShopBundle/Component/CsvResponse.php +++ /dev/null @@ -1,297 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Component; - -use Symfony\Component\HttpFoundation\ResponseHeaderBag; -use Symfony\Component\HttpFoundation\StreamedResponse; - -class CsvResponse extends StreamedResponse -{ - // Mode used to paginate page per page, 1/100, 2/100, 3/000, etc - const MODE_PAGINATION = 1; - - // Mode used to paginate by offset, 1/100, 100/100, 200/100, etc (like MySql limit) - const MODE_OFFSET = 2; - - /** - * @var array() CSV content - */ - private $data; - - /** - * @var string Export filename - */ - private $fileName; - - /** - * @var array - */ - private $headersData = []; - - /** - * @var int, self::MODE_PAGINATION by default - */ - private $modeType = self::MODE_PAGINATION; - - /** - * @var int|null - */ - private $start = null; - - /** - * @var int Default limit - */ - private $limit = 1000; - - /** - * Constructor. - * - * @param callable|null $callback A valid PHP callback or null to set it later - * @param int $status The response status code - * @param array $headers An array of response headers - */ - public function __construct($callback = null, $status = 200, $headers = []) - { - parent::__construct($callback, $status, $headers); - - if (null === $callback) { - $this->setCallback([$this, 'processData']); - } - - $this->setFileName('export_' . date('Y-m-d_His') . '.csv'); - $this->headers->set('Content-Type', 'text/csv; charset=utf-8'); - } - - /** - * @param array|callable $data - * - * @return $this - */ - public function setData($data) - { - $this->data = $data; - - return $this; - } - - /** - * @param array $headersData - * - * @return $this - */ - public function setHeadersData(array $headersData) - { - $this->headersData = $headersData; - - return $this; - } - - /** - * @param $modeType int - * - * @return $this - */ - public function setModeType($modeType) - { - $this->modeType = (int) $modeType; - - return $this; - } - - /** - * @param $start int - * - * @return $this - */ - public function setStart($start) - { - $this->start = (int) $start; - - return $this; - } - - /** - * @param $limit int - * - * @return $this - */ - public function setLimit($limit) - { - $this->limit = (int) $limit; - - return $this; - } - - /** - * @param string $fileName - * - * @return $this - * - * @throws \InvalidArgumentException - */ - public function setFileName($fileName) - { - $this->fileName = $fileName; - - $disposition = $this->headers->makeDisposition( - ResponseHeaderBag::DISPOSITION_ATTACHMENT, - $this->fileName - ); - $this->headers->set('Content-Disposition', $disposition); - - return $this; - } - - /** - * Callback function for StreamedResponse. - * - * @throws \LogicException - */ - public function processData() - { - $this->initStart(); - - if (is_array($this->data)) { - $this->processDataArray(); - - return; - } - - if (is_callable($this->data)) { - $this->processDataCallback(); - - return; - } - - throw new \LogicException('The data must be an array or a valid PHP callable function.'); - } - - /** - * Process to data export if $this->data is an array. - */ - private function processDataArray() - { - $handle = tmpfile(); - fputcsv($handle, $this->headersData, ';'); - - foreach ($this->data as $line) { - fputcsv($handle, $line, ';'); - } - - $this->dumpFile($handle); - } - - /** - * Process to data export if $this->data is a callable function. - */ - private function processDataCallback() - { - $handle = tmpfile(); - fputcsv($handle, $this->headersData, ';'); - - do { - $data = call_user_func_array($this->data, [$this->start, $this->limit]); - - $count = count($data); - if ($count === 0) { - break; - } - - foreach ($data as $line) { - $lineData = []; - - foreach (array_keys($this->headersData) as $column) { - if (array_key_exists($column, $line)) { - $lineData[] = $line[$column]; - } - } - - fputcsv($handle, $lineData, ';'); - } - - $this->incrementData(); - } while ($count === $this->limit); - - $this->dumpFile($handle); - } - - /** - * Just init $this->start if it is null. - */ - private function initStart() - { - if (null !== $this->start) { - return; - } - - if (self::MODE_PAGINATION === $this->modeType) { - $this->setStart(1); - } - - if (self::MODE_OFFSET === $this->modeType) { - $this->setStart(0); - } - } - - /** - * Increment the start data for the process. - * - * @throws \LogicException - */ - private function incrementData() - { - if (self::MODE_PAGINATION === $this->modeType) { - $this->setStart($this->start + 1); - - return; - } - - if (self::MODE_OFFSET === $this->modeType) { - $this->setStart($this->start + $this->limit); - - return; - } - - throw new \LogicException('The modeType is not a valid value.'); - } - - /** - * @param $handle, file pointer - */ - private function dumpFile($handle) - { - fseek($handle, 0); - - while (!feof($handle)) { - $buffer = fread($handle, 1024); - echo $buffer; - flush(); - } - - fclose($handle); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/AddonsController.php b/src/PrestaShopBundle/Controller/Admin/AddonsController.php deleted file mode 100644 index 9101a8ae..00000000 --- a/src/PrestaShopBundle/Controller/Admin/AddonsController.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Configuration; -use Exception; -use PhpEncryption; -use Symfony\Component\HttpFoundation\Cookie; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; - -class AddonsController extends FrameworkBundleAdminController -{ - /** - * Controller responsible of the authentication on PrestaShop Addons. - * - * @param Request $request - * - * @return JsonResponse - */ - public function loginAction(Request $request) - { - $addonsProvider = $this->get('prestashop.core.admin.data_provider.addons_interface'); - $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $response = new JsonResponse(); - - // Parameters needed in order to authenticate the merchant : login and password - $params = [ - 'format' => 'json', - 'username_addons' => $request->request->get('username_addons', null), - 'password_addons' => $request->request->get('password_addons', null), - ]; - - try { - $json = $addonsProvider->request('check_customer', $params); - - Configuration::updateValue('PS_LOGGED_ON_ADDONS', 1); - - $phpEncryption = new PhpEncryption(_NEW_COOKIE_KEY_); - - $response->headers->setCookie( - new Cookie('username_addons', $phpEncryption->encrypt($params['username_addons'])) - ); - $response->headers->setCookie( - new Cookie('password_addons', $phpEncryption->encrypt($params['password_addons'])) - ); - $response->headers->setCookie(new Cookie('is_contributor', (int) $json->is_contributor)); - - $response->setData(['success' => 1, 'message' => '']); - $modulesProvider->clearCatalogCache(); - } catch (Exception $e) { - $response->setData([ - 'success' => 0, - 'message' => $this->trans( - 'PrestaShop was unable to log in to Addons. Please check your credentials and your Internet connection.', - 'Admin.Notifications.Error' - ), - ]); - } - - return $response; - } - - /** - * Controller responsible of the authentication on PrestaShop Addons. - * - * @param Request $request - * - * @return JsonResponse - */ - public function logoutAction(Request $request) - { - $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $modulesProvider->clearCatalogCache(); - - if ($request->isXmlHttpRequest()) { - $response = new JsonResponse(); - $response->setData([ - 'success' => 1, - 'message' => '', - ]); - } else { - if ($request->server->get('HTTP_REFERER')) { - $url = $request->server->get('HTTP_REFERER'); - } else { - $url = $this->redirect($this->generateUrl('admin_module_catalog')); - } - $response = new RedirectResponse($url); - } - $response->headers->clearCookie('username_addons'); - $response->headers->clearCookie('password_addons'); - $response->headers->clearCookie('is_contributor'); - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/AttachementProductController.php b/src/PrestaShopBundle/Controller/Admin/AttachementProductController.php deleted file mode 100644 index 6d0e750d..00000000 --- a/src/PrestaShopBundle/Controller/Admin/AttachementProductController.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Admin controller for product attachments (in /product/form page). - */ -class AttachementProductController extends FrameworkBundleAdminController -{ - /** - * Manage form add product attachment. - * - * @AdminSecurity("is_granted(['create', 'update'], 'ADMINPRODUCTS_')") - * - * @param int $idProduct - * @param Request $request - * - * @return JsonResponse - */ - public function addAction($idProduct, Request $request) - { - $response = new JsonResponse(); - $legacyContext = $this->get('prestashop.adapter.legacy.context'); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - - //get product - $product = $productAdapter->getProduct((int) $idProduct); - - if (!$product || !$request->isXmlHttpRequest()) { - return $response; - } - - $form = $this->createForm( - 'PrestaShopBundle\Form\Admin\Product\ProductAttachement', - null, - ['csrf_protection' => false] - ); - - $form->handleRequest($request); - - if ($form->isValid()) { - $data = $form->getData(); - $res = $adminProductWrapper->processAddAttachment($product, $data, $legacyContext->getLanguages()); - if ($res) { - $res->real_name = $data['name']; - $response->setData($res); - } - } else { - $response->setStatusCode(400); - $response->setData($this->getFormErrorsForJS($form)); - } - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/AttributeController.php b/src/PrestaShopBundle/Controller/Admin/AttributeController.php deleted file mode 100644 index 0096d637..00000000 --- a/src/PrestaShopBundle/Controller/Admin/AttributeController.php +++ /dev/null @@ -1,329 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Product; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Admin controller for the attribute / attribute group. - */ -class AttributeController extends FrameworkBundleAdminController -{ - /** - * get All Attributes as json. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @return JsonResponse - */ - public function getAllAttributesAction() - { - $response = new JsonResponse(); - $locales = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - $attributes = $this->get('prestashop.adapter.data_provider.attribute')->getAttributes($locales[0]['id_lang'], true); - - $dataGroupAttributes = []; - $data = []; - foreach ($attributes as $attribute) { - /* Construct attribute group selector. Ex : Color : All */ - $dataGroupAttributes[$attribute['id_attribute_group']] = [ - 'value' => 'group-' . $attribute['id_attribute_group'], - 'label' => $attribute['public_name'] . ' : ' . $this->trans('All', 'Admin.Global'), - 'data' => [ - 'id_group' => $attribute['id_attribute_group'], - 'name' => $attribute['public_name'], - ], - ]; - - $data[] = [ - 'value' => $attribute['id_attribute'], - 'label' => $attribute['public_name'] . ' : ' . $attribute['name'], - 'data' => [ - 'id_group' => $attribute['id_attribute_group'], - 'name' => $attribute['name'], - ], - ]; - } - - $data = array_merge($dataGroupAttributes, $data); - - $response->setData($data); - - return $response; - } - - /** - * Attributes generator. - * - * @AdminSecurity("is_granted(['create', 'update'], request.get('_legacy_controller'))") - * - * @param Request $request The request - * - * @return JsonResponse - */ - public function attributesGeneratorAction(Request $request) - { - $response = new JsonResponse(); - $locales = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - $options = $request->get('options'); - $idProduct = isset($request->get('form')['id_product']) ? $request->get('form')['id_product'] : null; - - //get product - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $product = $productAdapter->getProduct((int) $idProduct); - - if (!is_object($product) || empty($product->id) || empty($options) || !is_array($options)) { - $response->setStatusCode(400); - - return $response; - } - - //store exisiting product combinations - $existingCombinationsIds = array_map(function ($o) { - return $o['id_product_attribute']; - }, $product->getAttributeCombinations(1, false)); - - //get clean attributes ids - $newOptions = []; - foreach ($options as $idGroup => $attributes) { - foreach ($attributes as $attribute) { - //If attribute is a group attribute, replace group data by all attributes group - if (false !== strpos($attribute, 'group')) { - $allGroupAttributes = $this->get('prestashop.adapter.data_provider.attribute')->getAttributeIdsByGroup((int) $idGroup, true); - foreach ($allGroupAttributes as $groupAttribute) { - $newOptions[$idGroup][$groupAttribute] = $groupAttribute; - } - } else { - $newOptions[$idGroup][$attribute] = $attribute; - } - } - } - - //create attributes - $this->get('prestashop.adapter.admin.controller.attribute_generator')->processGenerate($product, $newOptions); - - //get all product combinations - $allCombinations = $product->getAttributeCombinations(1, false); - - $allCombinationsIds = array_map(function ($o) { - return $o['id_product_attribute']; - }, $allCombinations); - - //get new created combinations Ids - $newCombinationIds = array_diff($allCombinationsIds, $existingCombinationsIds); - - $attributes = $product->sortCombinationByAttributePosition($newCombinationIds, $locales[0]['id_lang']); - $this->ensureProductHasDefaultCombination($product, $attributes); - - $response = new JsonResponse(); - $combinationDataProvider = $this->get('prestashop.adapter.data_provider.combination'); - $result = [ - 'ids_product_attribute' => [], - 'form' => '', - ]; - - foreach ($attributes as $attribute) { - foreach ($attribute as $combination) { - $form = $this->get('form.factory') - ->createNamed( - 'combination_' . $combination['id_product_attribute'], - 'PrestaShopBundle\Form\Admin\Product\ProductCombination', - $combinationDataProvider->getFormCombination($combination['id_product_attribute']) - ); - $result['form'] .= $this->renderView( - '@Product/ProductPage/Forms/form_combination.html.twig', - [ - 'form' => $form->createView(), - ] - ); - $result['ids_product_attribute'][] = $combination['id_product_attribute']; - } - } - - return $response->create($result); - } - - /** - * @param Product $product - * @param array $combinations - */ - public function ensureProductHasDefaultCombination(Product $product, array $combinations) - { - if (count($combinations)) { - $defaultProductAttributeId = $product->getDefaultIdProductAttribute(); - if (!$defaultProductAttributeId) { - /* - * Combinations indexed by position, then attribute id - * ex: $combinations = [ - * 3 => [ //4th position attribute - * 45 => [ //product_attribute id - * ] - * ] - * ] - */ - $firstPosition = array_keys($combinations)[0]; - if (!empty($combinations[$firstPosition])) { - $firstAttributeId = array_keys($combinations[$firstPosition])[0]; - $product->setDefaultAttribute($firstAttributeId); - } - } - } - } - - /** - * Delete a product attribute. - * - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))") - * - * @param int $idProduct The product ID - * @param Request $request The request - * - * @return JsonResponse - */ - public function deleteAttributeAction($idProduct, Request $request) - { - $response = new JsonResponse(); - - if (!$request->isXmlHttpRequest()) { - return $response; - } - - $legacyResponse = false; - - if ($request->request->has('attribute-ids')) { - $attributeIds = $request->request->get('attribute-ids'); - foreach ($attributeIds as $attributeId) { - $legacyResponse = $this->get('prestashop.adapter.admin.controller.attribute_generator') - ->ajaxProcessDeleteProductAttribute($attributeId, $idProduct); - } - - if ($legacyResponse['status'] == 'error') { - $response->setStatusCode(400); - } - - $response->setData(['message' => $legacyResponse['message']]); - } - - return $response; - } - - /** - * Delete all product attributes. - * - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))") - * - * @param int $idProduct The product ID - * @param Request $request The request - * - * @return JsonResponse - */ - public function deleteAllAttributeAction($idProduct, Request $request) - { - $attributeAdapter = $this->get('prestashop.adapter.data_provider.attribute'); - $response = new JsonResponse(); - - //get all attribute for a product - $combinations = $attributeAdapter->getProductCombinations($idProduct); - - if (!$combinations || !$request->isXmlHttpRequest()) { - return $response; - } - - $res = false; - - foreach ($combinations as $combination) { - $res = $this->get('prestashop.adapter.admin.controller.attribute_generator') - ->ajaxProcessDeleteProductAttribute($combination['id_product_attribute'], $idProduct); - - if ($res['status'] == 'error') { - $response->setStatusCode(400); - - break; - } - } - - $response->setData(['message' => $res['message']]); - - return $response; - } - - /** - * get the images form for a product combinations. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param int $idProduct The product id - * @param Request $request The request - * - * @return JsonResponse - */ - public function getFormImagesAction($idProduct, Request $request) - { - $response = new JsonResponse(); - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $attributeAdapter = $this->get('prestashop.adapter.data_provider.attribute'); - $locales = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - - //get product - $product = $productAdapter->getProduct((int) $idProduct); - - //get product images - $productImages = $productAdapter->getImages($idProduct, $locales[0]['id_lang']); - - if (!$request->isXmlHttpRequest() || !is_object($product) || empty($product->id)) { - $response->setStatusCode(400); - - return $response; - } - - $data = []; - $combinations = $attributeAdapter->getProductCombinations($idProduct); - foreach ($combinations as $combination) { - //get combination images - $combinationImages = array_map(function ($o) { - return $o['id']; - }, $attributeAdapter->getImages($combination['id_product_attribute'])); - - $newProductImages = $productImages; - foreach ($newProductImages as $k => $image) { - $newProductImages[$k]['id_image_attr'] = false; - if (in_array($image['id'], $combinationImages)) { - $newProductImages[$k]['id_image_attr'] = true; - } - } - - $data[$combination['id_product_attribute']] = $newProductImages; - } - - $response->setData($data); - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/CategoryController.php b/src/PrestaShopBundle/Controller/Admin/CategoryController.php deleted file mode 100644 index fb374ba3..00000000 --- a/src/PrestaShopBundle/Controller/Admin/CategoryController.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryId; -use PrestaShop\PrestaShop\Core\Domain\Product\Command\AssignProductToCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\CannotAssignProductToCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductException; -use PrestaShopBundle\Form\Admin\Category\SimpleCategory; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - -/** - * Admin controller for the Category pages. - */ -class CategoryController extends FrameworkBundleAdminController -{ - /** - * Process Ajax Form to add a simple category (name and parent category). - * - * @param Request $request - * - * @return string - */ - public function addSimpleCategoryFormAction(Request $request) - { - $response = new JsonResponse(); - $commandBus = $this->get('prestashop.core.command_bus'); - $tools = $this->get('prestashop.adapter.tools'); - $shopContext = $this->get('prestashop.adapter.shop.context'); - $shopList = $shopContext->getShops(false, true); - $currentIdShop = $shopContext->getContextShopID(); - $defaultLanguageId = $this->get('prestashop.adapter.legacy.configuration')->getInt('PS_LANG_DEFAULT'); - - $form = $this->createFormBuilder() - ->add('category', SimpleCategory::class) - ->getForm(); - - $form->handleRequest($request); - - if ($form->isValid()) { - $data = $form->getData(); - - $localizedName = [ - $defaultLanguageId => $data['category']['name'], - ]; - - $command = new AddCategoryCommand( - $localizedName, - [$defaultLanguageId => $tools->linkRewrite($data['category']['name'])], - true, - (int) $data['category']['id_parent'] - ); - - $command->setAssociatedShopIds($currentIdShop ? [$currentIdShop => $currentIdShop] : $shopList); - - try { - /** @var CategoryId $categoryId */ - $categoryId = $commandBus->handle($command); - - if ($categoryId->getValue()) { - $response->setData( - [ - 'category' => [ - 'id' => $categoryId->getValue(), - 'id_parent' => $data['category']['id_parent'], - 'name' => $localizedName, - ], - ] - ); - if ($request->query->has('id_product')) { - $assignProductToCategoryCommand = new AssignProductToCategoryCommand( - $categoryId->getValue(), - $request->query->get('id_product') - ); - $commandBus->handle($assignProductToCategoryCommand); - } - } - } catch (CategoryException $e) { - // TODO: do some frontend work to display this error message from ajax query - $response->setStatusCode(Response::HTTP_BAD_REQUEST); - $response->setData(['error' => $this->getErrorMessageForException($e, $this->getErrorMessages($data['category']['name']))]); - } catch (ProductException $e) { - // TODO: do some frontend work to display this error message from ajax query - $response->setStatusCode(Response::HTTP_BAD_REQUEST); - $response->setData(['error' => $this->getErrorMessageForException($e, $this->getErrorMessages($data['category']['name']))]); - } - } else { - $response->setStatusCode(Response::HTTP_BAD_REQUEST); - $response->setData($this->getFormErrorsForJS($form)); - } - - return $response; - } - - /** - * Get Categories formatted like ajax_product_file.php. - * - * @param $limit - * @param Request $request - * - * @return JsonResponse - */ - public function getAjaxCategoriesAction($limit, Request $request) - { - if (!$request->isXmlHttpRequest()) { - throw new NotFoundHttpException('Should be ajax request.'); - } - - return new JsonResponse( - $this->get('prestashop.adapter.data_provider.category')->getAjaxCategories($request->get('query'), $limit, true) - ); - } - - /** - * @param string $categoryName - * - * @return array - */ - private function getErrorMessages(string $categoryName): array - { - return [ - CategoryException::class => $this->trans( - 'Category "%s" could not be created.', - 'Admin.Notifications.Error', - [$categoryName] - ), - CannotAssignProductToCategoryException::class => $this->trans( - 'This product could not be assigned to category "%s".', - 'Admin.Notifications.Error', - [$categoryName] - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/CombinationController.php b/src/PrestaShopBundle/Controller/Admin/CombinationController.php deleted file mode 100644 index 87e6cfb0..00000000 --- a/src/PrestaShopBundle/Controller/Admin/CombinationController.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShopBundle\Form\Admin\Product\ProductCombination; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; - -class CombinationController extends FrameworkBundleAdminController -{ - /** - * Generate combination - * - * @AdminSecurity("is_granted(['create', 'update'], 'ADMINPRODUCTS_')") - * - * @return Response - */ - public function generateCombinationFormAction($combinationIds) - { - $response = new Response(); - - $combinationIds = explode('-', $combinationIds); - if ($combinationIds === false || count($combinationIds) == 0) { - return $response; - } - - $combinationDataProvider = $this->get('prestashop.adapter.data_provider.combination'); - $combinations = $combinationDataProvider->getFormCombinations($combinationIds, (int) $this->getContext()->language->id); - - $formFactory = $this->get('form.factory'); - foreach ($combinations as $combinationId => $combination) { - $forms[] = $formFactory->createNamed( - "combination_$combinationId", - ProductCombination::class, - $combination - )->createView(); - } - - return $response->setContent($this->renderView( - '@Product/ProductPage/Forms/form_combination_collection.html.twig', - [ - 'combinationForms' => $forms, - ] - )); - } - - /** - * Get all Combinations for a product. - * - * @AdminSecurity("is_granted(['read'], 'ADMINPRODUCTS_')") - * - * @param int $idProduct The product id - * - * @return JsonResponse - */ - public function getProductCombinationsAction($idProduct) - { - $response = new JsonResponse(); - - //get product - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $product = $productAdapter->getProduct((int) $idProduct); - - //get combinations - - $modelMapper = $this->get('prestashop.adapter.admin.model.product'); - - $combinations = $modelMapper->getAttributesResume($product); - - $combinationList = []; - - if (is_array($combinations)) { - foreach ($combinations as $combination) { - $combinationList[] = ['id' => $combination['id_product_attribute'], 'name' => $combination['attribute_designation']]; - } - } - - $response->setData($combinationList); - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/CommonController.php b/src/PrestaShopBundle/Controller/Admin/CommonController.php deleted file mode 100644 index d810c71a..00000000 --- a/src/PrestaShopBundle/Controller/Admin/CommonController.php +++ /dev/null @@ -1,404 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Context; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder; -use PrestaShop\PrestaShop\Core\Domain\Notification\Command\UpdateEmployeeNotificationLastElementCommand; -use PrestaShop\PrestaShop\Core\Domain\Notification\Query\GetNotificationLastElements; -use PrestaShop\PrestaShop\Core\Domain\Notification\QueryResult\NotificationsResults; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\FilterableGridDefinitionFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface; -use PrestaShop\PrestaShop\Core\Kpi\Row\KpiRowInterface; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Service\DataProvider\Admin\RecommendedModules; -use PrestaShopBundle\Service\Grid\ControllerResponseBuilder; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use ReflectionClass; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Admin controller for the common actions across the whole admin interface. - */ -class CommonController extends FrameworkBundleAdminController -{ - /** - * Get a summary of recent events on the shop. - * This includes: - * - Created orders - * - Registered customers - * - New messages. - * - * @return JsonResponse - */ - public function notificationsAction() - { - $employeeId = Context::getContext()->employee->id; - /** @var NotificationsResults $elements */ - $elements = $this->getQueryBus()->handle(new GetNotificationLastElements($employeeId)); - - return new JsonResponse($elements->getNotificationsResultsForJS()); - } - - /** - * Update the last time a notification type has been seen. - * - * @param Request $request - * - * @throws TypeException - */ - public function notificationsAckAction(Request $request) - { - $type = $request->request->get('type'); - $this->getCommandBus()->handle(new UpdateEmployeeNotificationLastElementCommand($type)); - - return new JsonResponse(true); - } - - /** - * This will allow you to retrieve an HTML code with a ready and linked paginator. - * - * To be able to use this paginator, the current route must have these standard parameters: - * - offset - * - limit - * Both will be automatically manipulated by the paginator. - * The navigator links (previous/next page...) will never tranfer POST and/or GET parameters - * (only route parameters that are in the URL). - * - * You must add a JS file to the list of JS for view rendering: pagination.js - * - * The final way to render a paginator is the following: - * {% render controller('PrestaShopBundle\\Controller\\Admin\\CommonController::paginationAction', - * {'limit': limit, 'offset': offset, 'total': product_count, 'caller_parameters': pagination_parameters}) %} - * - * @Template("@PrestaShop/Admin/Common/pagination.html.twig") - * - * @param Request $request - * @param int $limit - * @param int $offset - * @param int $total - * @param string $view full|quicknav To change default template used to render the content - * @param string $prefix Indicates the params prefix (eg: ?limit=10&offset=20 -> ?scope[limit]=10&scope[offset]=20) - * - * @return array|Response - */ - public function paginationAction(Request $request, $limit = 10, $offset = 0, $total = 0, $view = 'full', $prefix = '') - { - $offsetParam = empty($prefix) ? 'offset' : sprintf('%s[offset]', $prefix); - $limitParam = empty($prefix) ? 'limit' : sprintf('%s[limit]', $prefix); - - $limit = max($limit, 10); - - $currentPage = floor($offset / $limit) + 1; - $pageCount = ceil($total / $limit); - $from = $offset; - $to = $offset + $limit - 1; - - // urls from route - $callerParameters = $request->attributes->get('caller_parameters', []); - foreach ($callerParameters as $k => $v) { - if (strpos($k, '_') === 0) { - unset($callerParameters[$k]); - } - } - $callerParameters += ['_route' => false]; - $routeName = $request->attributes->get('caller_route', $callerParameters['_route']); - $nextPageUrl = (!$routeName || ($offset + $limit >= $total)) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => min($total - 1, $offset + $limit), - $limitParam => $limit, - ] - )); - - $previousPageUrl = (!$routeName || ($offset == 0)) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => max(0, $offset - $limit), - $limitParam => $limit, - ] - )); - $firstPageUrl = (!$routeName || ($offset == 0)) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => 0, - $limitParam => $limit, - ] - )); - $lastPageUrl = (!$routeName || ($offset + $limit >= $total)) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => ($pageCount - 1) * $limit, - $limitParam => $limit, - ] - )); - $changeLimitUrl = (!$routeName) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => 0, - $limitParam => '_limit', - ] - )); - $jumpPageUrl = (!$routeName) ? false : $this->generateUrl($routeName, array_merge( - $callerParameters, - [ - $offsetParam => 999999, - $limitParam => $limit, - ] - )); - $limitChoices = $request->attributes->get('limit_choices', [10, 20, 50, 100]); - - // Template vars injection - $vars = [ - 'limit' => $limit, - 'changeLimitUrl' => $changeLimitUrl, - 'first_url' => $firstPageUrl, - 'previous_url' => $previousPageUrl, - 'from' => $from, - 'to' => $to, - 'total' => $total, - 'current_page' => $currentPage, - 'page_count' => $pageCount, - 'next_url' => $nextPageUrl, - 'last_url' => $lastPageUrl, - 'jump_page_url' => $jumpPageUrl, - 'limit_choices' => $limitChoices, - ]; - if ($view != 'full') { - return $this->render('@PrestaShop/Admin/Common/pagination_' . $view . '.html.twig', $vars); - } - - return $vars; - } - - /** - * This will allow you to retrieve an HTML code with a list of recommended modules depending on the domain. - * - * @Template("@PrestaShop/Admin/Common/recommendedModules.html.twig") - * - * @param string $domain - * @param int $limit - * @param int $randomize - * - * @return array Template vars - */ - public function recommendedModulesAction($domain, $limit = 0, $randomize = 0) - { - $recommendedModules = $this->get('prestashop.data_provider.modules.recommended'); - /** @var $recommendedModules RecommendedModules */ - $moduleIdList = $recommendedModules->getRecommendedModuleIdList($domain, ($randomize == 1)); - - $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - /** @var $modulesProvider AdminModuleDataProvider */ - $modulesRepository = ModuleManagerBuilder::getInstance()->buildRepository(); - - $modules = []; - foreach ($moduleIdList as $id) { - try { - $module = $modulesRepository->getModule($id); - } catch (\Exception $e) { - continue; - } - $modules[] = $module; - } - - if ($randomize == 1) { - shuffle($modules); - } - - $modules = $recommendedModules->filterInstalledAndBadModules($modules); - $collection = AddonsCollection::createFrom($modules); - $modules = $modulesProvider->generateAddonsUrls($collection); - - return [ - 'domain' => $domain, - 'modules' => array_slice($modules, 0, $limit, true), - ]; - } - - /** - * Render a right sidebar with content from an URL. - * - * @param $url - * @param string $title - * @param string $footer - * - * @return Response - */ - public function renderSidebarAction($url, $title = '', $footer = '') - { - $tools = $this->get('prestashop.adapter.tools'); - - return $this->render('@PrestaShop/Admin/Common/_partials/_sidebar.html.twig', [ - 'footer' => $tools->purifyHTML($footer), - 'title' => $title, - 'url' => urldecode($url), - ]); - } - - /** - * Renders a KPI row. - * - * @param KpiRowInterface $kpiRow - * - * @return Response - */ - public function renderKpiRowAction(KpiRowInterface $kpiRow) - { - $presenter = $this->get('prestashop.core.kpi_row.presenter'); - - return $this->render('@PrestaShop/Admin/Common/Kpi/kpi_row.html.twig', [ - 'kpiRow' => $presenter->present($kpiRow), - ]); - } - - /** - * @param string $controller - * @param string $action - * @param string $filterId - * - * @return JsonResponse - * - * @throws \Doctrine\ORM\OptimisticLockException - */ - public function resetSearchAction($controller = '', $action = '', $filterId = '') - { - $adminFiltersRepository = $this->get('prestashop.core.admin.admin_filter.repository'); - $employeeId = $this->getUser()->getId(); - $shopId = $this->getContext()->shop->id; - - // for compatibility when $controller and $action are used - if (!empty($controller) && !empty($action)) { - $adminFilter = $adminFiltersRepository->findByEmployeeAndRouteParams( - $employeeId, $shopId, $controller, $action - ); - } - - if (!empty($filterId)) { - $adminFilter = $adminFiltersRepository->findByEmployeeAndFilterId($employeeId, $shopId, $filterId); - } - - if (isset($adminFilter)) { - $adminFiltersRepository->unsetFilters($adminFilter); - } - - return new JsonResponse(); - } - - /** - * Specific action to render a specific field twice. - * - * @param $formName the form name - * @param $formType the form type FQCN - * @param $fieldName the field name - * @param $fieldData the field data - * - * @return Response - */ - public function renderFieldAction($formName, $formType, $fieldName, $fieldData) - { - $formData = [ - $formName => [ - $fieldName => $fieldData, - ], - ]; - - $form = $this->createFormBuilder($formData); - $form->add($formName, $formType); - - return $this->render('@PrestaShop/Admin/Common/_partials/_form_field.html.twig', [ - 'form' => $form->getForm()->get($formName)->get($fieldName)->createView(), - 'formId' => $formName . '_' . $fieldName . '_rendered', - ]); - } - - /** - * Process Grid search. - * - * @param Request $request - * @param string $gridDefinitionFactoryServiceId - * @param string $redirectRoute - * @param array $redirectQueryParamsToKeep - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @return RedirectResponse - */ - public function searchGridAction( - Request $request, - $gridDefinitionFactoryServiceId, - $redirectRoute, - array $redirectQueryParamsToKeep = [] - ) { - /** @var GridDefinitionFactoryInterface $definitionFactory */ - $definitionFactory = $this->get($gridDefinitionFactoryServiceId); - - $filterId = null; - - if ($definitionFactory instanceof FilterableGridDefinitionFactoryInterface) { - $filterId = $definitionFactory->getFilterId(); - } elseif ($definitionFactory instanceof AbstractGridDefinitionFactory) { - // for backward compatibility for AbstractGridDefinitionFactory - // using ::GRID_ID (that has been replaced by AbstractFilterableGridDefinitionFactory) - $reflect = new ReflectionClass($definitionFactory); - if (array_key_exists('GRID_ID', $reflect->getConstants())) { - $filterId = $definitionFactory::GRID_ID; - } - } - - if (null !== $filterId) { - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $definitionFactory, - $request, - $filterId, - $redirectRoute, - $redirectQueryParamsToKeep - ); - } - - // Legacy grid definition which use controller/action as filter keys (and no scope for parameters) - /** @var ControllerResponseBuilder $responseBuilder */ - $controllerResponseBuilder = $this->get('prestashop.bundle.grid.controller_response_builder'); - - return $controllerResponseBuilder->buildSearchResponse( - $definitionFactory, - $request, - $redirectRoute, - $redirectQueryParamsToKeep - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php deleted file mode 100644 index 90fa8d8f..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/AdministrationController.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Administration" page display. - */ -class AdministrationController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'AdminAdminPreferences'; - - /** - * Show Administration page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param FormInterface $form - * - * @return Response - */ - public function indexAction(FormInterface $form = null) - { - $form = null === $form ? $this->get('prestashop.adapter.administration.form_handler')->getForm() : $form; - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/administration.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Administration', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminAdminPreferences'), - 'requireFilterStatus' => false, - 'form' => $form->createView(), - ]); - } - - /** - * Process the Administration configuration form. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_administration") - * @DemoRestricted(redirectRoute="admin_administration") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $this->dispatchHook('actionAdminAdminPreferencesControllerPostProcessBefore', ['controller' => $this]); - - $form = $this->get('prestashop.adapter.administration.form_handler')->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - $saveErrors = $this->get('prestashop.adapter.administration.form_handler')->save($data); - - if (0 === count($saveErrors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_administration'); - } - - $this->flashErrors($saveErrors); - } - - return $this->redirectToRoute('admin_administration'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/BackupController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/BackupController.php deleted file mode 100644 index 0138f9f7..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/BackupController.php +++ /dev/null @@ -1,300 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Adapter\Backup\Backup; -use PrestaShop\PrestaShop\Core\Backup\Exception\BackupException; -use PrestaShop\PrestaShop\Core\Backup\Exception\DirectoryIsNotWritableException; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\BackupFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class BackupController is responsible of "Configure > Advanced Parameters > Database > Backup" page. - */ -class BackupController extends FrameworkBundleAdminController -{ - /** - * Show backup page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param BackupFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, BackupFilters $filters) - { - $backupForm = $this->getBackupFormHandler()->getForm(); - $configuration = $this->get('prestashop.adapter.legacy.configuration'); - - $hasDownloadFile = false; - $downloadFile = null; - - if ($request->query->has('download_filename')) { - $hasDownloadFile = true; - $backup = new Backup($request->query->get('download_filename')); - $downloadFile = [ - 'url' => $backup->getUrl(), - 'size' => number_format($backup->getSize() * 0.000001, 2, '.', ''), - ]; - } - - $backupsGridFactory = $this->get('prestashop.core.grid.factory.backup'); - $backupGrid = $backupsGridFactory->getGrid($filters); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Backup/index.html.twig', [ - 'backupGrid' => $this->presentGrid($backupGrid), - 'backupForm' => $backupForm->createView(), - 'isHostMode' => $configuration->get('_PS_HOST_MODE_'), - 'dbPrefix' => $configuration->get('_DB_PREFIX_'), - 'hasDownloadFile' => $hasDownloadFile, - 'downloadFile' => $downloadFile, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Show file download view. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_backups_index") - * - * @param Request $request - * @param string $downloadFileName - * - * @return Response - */ - public function downloadViewAction(Request $request, $downloadFileName) - { - $backup = new Backup($downloadFileName); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Backup/download_view.html.twig', [ - 'downloadFile' => [ - 'url' => $backup->getUrl(), - 'size' => $backup->getSize(), - ], - 'layoutTitle' => $this->trans('View', 'Admin.Actions'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Return a backup content as a download. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller')~'_')") - * @DemoRestricted(redirectRoute="admin_backup") - * - * @param string $downloadFileName - * - * @return BinaryFileResponse - */ - public function downloadContentAction($downloadFileName) - { - $backup = new Backup($downloadFileName); - - return new BinaryFileResponse($backup->getFilePath()); - } - - /** - * Process backup options saving. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_backups_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $backupFormHandler = $this->getBackupFormHandler(); - - $backupForm = $backupFormHandler->getForm(); - $backupForm->handleRequest($request); - - if ($backupForm->isSubmitted()) { - $errors = $backupFormHandler->save($backupForm->getData()); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } - } - - return $this->redirectToRoute('admin_backups_index'); - } - - /** - * Create new backup. - * - * @AdminSecurity("is_granted(['create'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_backups_index") - * - * @return RedirectResponse - */ - public function createAction() - { - try { - $backupCreator = $this->get('prestashop.adapter.backup.database_creator'); - $backup = $backupCreator->createBackup(); - - $this->addFlash( - 'success', - $this->trans( - 'It appears the backup was successful, however you must download and carefully verify the backup file before proceeding.', - 'Admin.Advparameters.Notification' - ) - ); - - return $this->redirectToRoute('admin_backups_index', ['download_filename' => $backup->getFileName()]); - } catch (DirectoryIsNotWritableException $e) { - $this->addFlash( - 'error', - $this->trans( - 'The "Backups" directory located in the admin directory must be writable (CHMOD 755 / 777).', - 'Admin.Advparameters.Notification' - ) - ); - } catch (BackupException $e) { - $this->addFlash('error', $this->trans('The backup file does not exist', 'Admin.Advparameters.Notification')); - } - - return $this->redirectToRoute('admin_backups_index'); - } - - /** - * Process backup file deletion. - * - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_backups_index") - * - * @param string $deleteFileName - * - * @return RedirectResponse - */ - public function deleteAction($deleteFileName) - { - $backup = new Backup($deleteFileName); - $backupRemover = $this->get('prestashop.adapter.backup.backup_remover'); - - if (!$backupRemover->remove($backup)) { - $this->addFlash( - 'error', - sprintf( - '%s "%s"', - $this->trans('Error deleting', 'Admin.Advparameters.Notification'), - $backup->getFileName() - ) - ); - - return $this->redirectToRoute('admin_backups_index'); - } - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_backups_index'); - } - - /** - * Process bulk backup deletion. - * - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_backups_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $backupsToDelete = $request->request->get('backup_backup_bulk_file_names', []); - - if (empty($backupsToDelete)) { - $this->addFlash( - 'error', - $this->trans('You must select at least one element to delete.', 'Admin.Notifications.Error') - ); - - return $this->redirectToRoute('admin_backups_index'); - } - - $backupRemover = $this->get('prestashop.adapter.backup.backup_remover'); - $failedBackups = []; - - foreach ($backupsToDelete as $backupFileName) { - $backup = new Backup($backupFileName); - - if (!$backupRemover->remove($backup)) { - $failedBackups[] = $backup->getFileName(); - } - } - - if (!empty($failedBackups)) { - $this->addFlash( - 'error', - $this->trans('An error occurred while deleting this selection.', 'Admin.Notifications.Error') - ); - - foreach ($failedBackups as $backupFileName) { - $this->addFlash( - 'error', - $this->trans('Can\'t delete #%id%', 'Admin.Notifications.Error', ['%id%' => $backupFileName]) - ); - } - - return $this->redirectToRoute('admin_backups_index'); - } - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - - return $this->redirectToRoute('admin_backups_index'); - } - - /** - * Get backup form handler. - * - * @return FormHandlerInterface - */ - protected function getBackupFormHandler() - { - return $this->get('prestashop.admin.backup.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmailController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmailController.php deleted file mode 100644 index 9d0b7cd1..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmailController.php +++ /dev/null @@ -1,276 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Core\Email\MailOption; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\EmailLogsFilter; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Email\TestEmailSendingType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class EmailController is responsible for handling "Configure > Advanced Parameters > E-mail" page. - */ -class EmailController extends FrameworkBundleAdminController -{ - /** - * Show email configuration page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * @param EmailLogsFilter $filters - * - * @return Response - */ - public function indexAction(Request $request, EmailLogsFilter $filters) - { - $configuration = $this->get('prestashop.adapter.legacy.configuration'); - - $emailConfigurationForm = $this->getEmailConfigurationFormHandler()->getForm(); - $extensionChecker = $this->get('prestashop.core.configuration.php_extension_checker'); - - $testEmailSendingForm = $this->createForm(TestEmailSendingType::class, [ - 'send_email_to' => $configuration->get('PS_SHOP_EMAIL'), - ]); - - $isEmailLogsEnabled = $configuration->get('PS_LOG_EMAILS'); - - $presentedEmailLogsGrid = null; - - if ($isEmailLogsEnabled) { - $emailLogsGridFactory = $this->get('prestashop.core.grid.factory.email_logs'); - $emailLogsGrid = $emailLogsGridFactory->getGrid($filters); - $presentedEmailLogsGrid = $this->presentGrid($emailLogsGrid); - } - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Email/index.html.twig', [ - 'emailConfigurationForm' => $emailConfigurationForm->createView(), - 'isOpenSslExtensionLoaded' => $extensionChecker->loaded('openssl'), - 'smtpMailMethod' => MailOption::METHOD_SMTP, - 'testEmailSendingForm' => $testEmailSendingForm->createView(), - 'emailLogsGrid' => $presentedEmailLogsGrid, - 'isEmailLogsEnabled' => $isEmailLogsEnabled, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.email_logs'); - $emailLogsDefinition = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $filtersForm = $gridFilterFormFactory->create($emailLogsDefinition); - $filtersForm->handleRequest($request); - - $filters = []; - - if ($filtersForm->isSubmitted()) { - $filters = $filtersForm->getData(); - } - - return $this->redirectToRoute('admin_emails_index', ['filters' => $filters]); - } - - /** - * Process email configuration saving. - * - * @DemoRestricted(redirectRoute="admin_emails_index") - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $formHandler = $this->getEmailConfigurationFormHandler(); - $emailConfigurationForm = $formHandler->getForm(); - $emailConfigurationForm->handleRequest($request); - - if ($emailConfigurationForm->isSubmitted()) { - $errors = $formHandler->save($emailConfigurationForm->getData()); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The settings have been successfully updated.', 'Admin.Notifications.Success') - ); - } - } - - return $this->redirectToRoute('admin_emails_index'); - } - - /** - * Delete selected email logs. - * - * @DemoRestricted(redirectRoute="admin_emails_index") - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request) - { - $mailLogsToDelete = $request->request->get('email_logs_delete_email_logs'); - - $mailLogsEraser = $this->get('prestashop.adapter.email.email_log_eraser'); - $errors = $mailLogsEraser->erase($mailLogsToDelete); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_emails_index'); - } - - /** - * Delete all email logs. - * - * @DemoRestricted(redirectRoute="admin_emails_index") - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))", message="Access denied.") - * - * @return RedirectResponse - */ - public function deleteAllAction() - { - $mailLogsEraser = $this->get('prestashop.adapter.email.email_log_eraser'); - - if ($mailLogsEraser->eraseAll()) { - $this->addFlash('success', $this->trans('Successful deletion', 'Admin.Notifications.Success')); - } - - return $this->redirectToRoute('admin_emails_index'); - } - - /** - * Delete single email log. - * - * @DemoRestricted(redirectRoute="admin_emails_index") - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))", message="Access denied.") - * - * @param int $mailId - * - * @return RedirectResponse - */ - public function deleteAction($mailId) - { - $mailLogsEraser = $this->get('prestashop.adapter.email.email_log_eraser'); - $errors = $mailLogsEraser->erase([$mailId]); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_emails_index'); - } - - /** - * Processes test email sending. - * - * @param Request $request - * - * @return Response - */ - public function sendTestAction(Request $request) - { - if ($this->isDemoModeEnabled()) { - return $this->json([ - 'errors' => [ - $this->getDemoModeErrorMessage(), - ], - ]); - } - - if (!in_array( - $this->authorizationLevel($request->attributes->get('_legacy_controller')), - [ - PageVoter::LEVEL_READ, - PageVoter::LEVEL_UPDATE, - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_DELETE, - ] - )) { - return $this->json([ - 'errors' => [ - $this->trans('Access denied.', 'Admin.Notifications.Error'), - ], - ]); - } - - $testEmailSendingForm = $this->createForm(TestEmailSendingType::class); - $testEmailSendingForm->handleRequest($request); - - $result = []; - - if ($testEmailSendingForm->isSubmitted()) { - $emailConfigurationTester = $this->get('prestashop.adapter.email.email_configuration_tester'); - $result['errors'] = $emailConfigurationTester->testConfiguration($testEmailSendingForm->getData()); - } - - return $this->json($result); - } - - /** - * Get email configuration form handler. - * - * @return FormHandlerInterface - */ - protected function getEmailConfigurationFormHandler() - { - return $this->get('prestashop.admin.email_configuration.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmployeeController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmployeeController.php deleted file mode 100644 index c6ba3413..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/EmployeeController.php +++ /dev/null @@ -1,562 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkDeleteEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkUpdateEmployeeStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\DeleteEmployeeCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Command\ToggleEmployeeStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\AdminEmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\CannotDeleteEmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmailAlreadyUsedException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeCannotChangeItselfException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\EmployeeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidEmployeeIdException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\InvalidProfileException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Exception\MissingShopAssociationException; -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeForEditing; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler; -use PrestaShop\PrestaShop\Core\Search\Filters\EmployeeFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class EmployeeController handles pages under "Configure > Advanced Parameters > Team > Employees". - */ -class EmployeeController extends FrameworkBundleAdminController -{ - /** - * Show employees list & options page. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * @param EmployeeFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, EmployeeFilters $filters) - { - $employeeOptionsFormHandler = $this->get('prestashop.admin.employee_options.form_handler'); - $employeeOptionsForm = $employeeOptionsFormHandler->getForm(); - - $employeeOptionsChecker = $this->get('prestashop.core.team.employee.configuration.options_checker'); - - $employeeGridFactory = $this->get('prestashop.core.grid.factory.employee'); - $employeeGrid = $employeeGridFactory->getGrid($filters); - - $helperCardDocumentationLinkProvider = - $this->get('prestashop.core.util.helper_card.documentation_link_provider'); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed((int) $this->getContext()->employee->id, ShowcaseCard::EMPLOYEES_CARD) - ); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Employee/index.html.twig', [ - 'employeeOptionsForm' => $employeeOptionsForm->createView(), - 'canOptionsBeChanged' => $employeeOptionsChecker->canBeChanged(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'employeeGrid' => $this->presentGrid($employeeGrid), - 'helperCardDocumentationLink' => $helperCardDocumentationLinkProvider->getLink('team'), - 'showcaseCardName' => ShowcaseCard::EMPLOYEES_CARD, - 'isShowcaseCardClosed' => $showcaseCardIsClosed, - ]); - } - - /** - * Save employee options. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $employeeOptionsFormHandler = $this->get('prestashop.admin.employee_options.form_handler'); - $employeeOptionsForm = $employeeOptionsFormHandler->getForm(); - $employeeOptionsForm->handleRequest($request); - - if ($employeeOptionsForm->isSubmitted()) { - $errors = $employeeOptionsFormHandler->save($employeeOptionsForm->getData()); - - if (!empty($errors)) { - $this->flashErrors($errors); - - return $this->redirectToRoute('admin_employees_index'); - } - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Toggle given employee status. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_employees_index") - * - * @param int $employeeId - * - * @return RedirectResponse - */ - public function toggleStatusAction($employeeId) - { - try { - $this->getCommandBus()->handle(new ToggleEmployeeStatusCommand((int) $employeeId)); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (EmployeeException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Bulk enables employee status action. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkStatusEnableAction(Request $request) - { - $employeeIds = $request->request->get('employee_employee_bulk'); - - try { - $this->getCommandBus()->handle( - new BulkUpdateEmployeeStatusCommand($employeeIds, true) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (EmployeeException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Bulk disables employee status action. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkStatusDisableAction(Request $request) - { - $employeeIds = $request->request->get('employee_employee_bulk'); - - try { - $this->getCommandBus()->handle( - new BulkUpdateEmployeeStatusCommand($employeeIds, false) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (EmployeeException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Delete employee. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))") - * - * @param int $employeeId - * - * @return RedirectResponse - */ - public function deleteAction($employeeId) - { - try { - $this->getCommandBus()->handle(new DeleteEmployeeCommand((int) $employeeId)); - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - } catch (EmployeeException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Delete employees in bulk actions. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $employeeIds = $request->request->get('employee_employee_bulk'); - - try { - $this->getCommandBus()->handle(new BulkDeleteEmployeeCommand($employeeIds)); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (EmployeeException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_employees_index'); - } - - /** - * Show employee creation form page and handle it's submit. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $employeeForm = $this->getEmployeeFormBuilder()->getForm(); - $employeeForm->handleRequest($request); - - try { - $result = $this->getEmployeeFormHandler()->handle($employeeForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_employees_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - $templateVars = [ - 'employeeForm' => $employeeForm->createView(), - 'showAddonsConnectButton' => false, - 'enableSidebar' => true, - ]; - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/create.html.twig', - $templateVars + $this->getFormTemplateVariables($request) - ); - } - - /** - * Show Employee edit page. - * - * @DemoRestricted(redirectRoute="admin_employees_index") - * - * @param int $employeeId - * @param Request $request - * - * @return Response - */ - public function editAction($employeeId, Request $request) - { - $contextEmployeeProvider = $this->get('prestashop.adapter.data_provider.employee'); - - // If employee is editing his own profile - he doesn't need to have access to the edit form. - if ($contextEmployeeProvider->getId() != $employeeId) { - if (!$this->isGranted(PageVoter::UPDATE, $request->get('_legacy_controller'))) { - $this->addFlash( - 'error', - $this->trans( - 'You do not have permission to update this.', - 'Admin.Notifications.Error' - ) - ); - - return $this->redirectToRoute('admin_employees_index'); - } - } - - $formAccessChecker = $this->get('prestashop.adapter.employee.form_access_checker'); - - if (!$formAccessChecker->canAccessEditFormFor($employeeId)) { - $this->addFlash( - 'error', - $this->trans('You cannot edit the SuperAdmin profile.', 'Admin.Advparameters.Notification') - ); - - return $this->redirectToRoute('admin_employees_index'); - } - - $isRestrictedAccess = $formAccessChecker->isRestrictedAccess((int) $employeeId); - $canAccessAddonsConnect = $formAccessChecker->canAccessAddonsConnect(); - - try { - $employeeForm = $this->getEmployeeFormBuilder()->getFormFor((int) $employeeId, [], [ - 'is_restricted_access' => $isRestrictedAccess, - 'is_for_editing' => true, - 'show_addons_connect_button' => $canAccessAddonsConnect, - ]); - - $employeeForm->handleRequest($request); - $result = $this->getEmployeeFormHandler()->handleFor((int) $employeeId, $employeeForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_employees_edit', [ - 'employeeId' => $result->getIdentifiableObjectId(), - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - try { - $editableEmployee = $this->getQueryBus()->handle(new GetEmployeeForEditing((int) $employeeId)); - } catch (EmployeeNotFoundException $e) { - return $this->redirectToRoute('admin_employees_index'); - } - - $templateVars = [ - 'employeeForm' => $employeeForm->createView(), - 'isRestrictedAccess' => $isRestrictedAccess, - 'showAddonsConnectButton' => $canAccessAddonsConnect, - 'editableEmployee' => $editableEmployee, - ]; - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/edit.html.twig', - $templateVars + $this->getFormTemplateVariables($request) - ); - } - - /** - * Change navigation menu status for employee. - * - * @param Request $request - * - * @return Response - */ - public function toggleNavigationMenuAction(Request $request) - { - $navigationToggler = $this->get('prestashop.adapter.employee.navigation_menu_toggler'); - $navigationToggler->toggleNavigationMenuInCookies($request->request->getBoolean('shouldCollapse')); - - return new Response('', Response::HTTP_NO_CONTENT); - } - - /** - * Change employee form language. - * - * @param Request $request - * - * @return Response - */ - public function changeFormLanguageAction(Request $request) - { - $configuration = $this->get('prestashop.adapter.legacy.configuration'); - - if ($configuration->getBoolean('PS_BO_ALLOW_EMPLOYEE_FORM_LANG')) { - $languageChanger = $this->get('prestashop.adapter.employee.form_language_changer'); - $languageChanger->changeLanguageInCookies($request->request->get('language_iso_code')); - } - - return new Response('', Response::HTTP_NO_CONTENT); - } - - /** - * Get tabs which are accessible for given profile. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * redirectRoute="admin_employees_index" - * ) - * - * @param Request $request - * - * @return JsonResponse - */ - public function getAccessibleTabsAction(Request $request) - { - $profileId = $request->query->get('profileId'); - $tabsDataProvider = $this->get('prestashop.adapter.data_provider.tab'); - $contextEmployeeProvider = $this->get('prestashop.adapter.data_provider.employee'); - - return $this->json( - $tabsDataProvider->getViewableTabs($profileId, $contextEmployeeProvider->getLanguageId()) - ); - } - - /** - * @return FormBuilderInterface - */ - protected function getEmployeeFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.employee_form_builder'); - } - - /** - * @return FormHandler - */ - protected function getEmployeeFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.employee_form_handler'); - } - - /** - * Get human readable error messages. - * - * @param Exception $e - * - * @return array - */ - protected function getErrorMessages(Exception $e) - { - return [ - InvalidEmployeeIdException::class => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - EmployeeNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - AdminEmployeeException::class => [ - AdminEmployeeException::CANNOT_CHANGE_LAST_ADMIN => $this->trans( - 'You cannot disable or delete the administrator account.', - 'Admin.Advparameters.Notification' - ), - ], - EmployeeCannotChangeItselfException::class => [ - EmployeeCannotChangeItselfException::CANNOT_CHANGE_STATUS => $this->trans( - 'You cannot disable or delete your own account.', - 'Admin.Advparameters.Notification' - ), - ], - CannotDeleteEmployeeException::class => $this->trans( - 'Can\'t delete #%id%', - 'Admin.Notifications.Error', - [ - '%id%' => $e instanceof CannotDeleteEmployeeException ? $e->getEmployeeId()->getValue() : 0, - ] - ), - MissingShopAssociationException::class => $this->trans( - 'The employee must be associated with at least one shop.', - 'Admin.Advparameters.Notification' - ), - InvalidProfileException::class => $this->trans( - 'The provided profile is invalid', - 'Admin.Advparameters.Notification' - ), - EmailAlreadyUsedException::class => sprintf( - '%s %s', - $this->trans( - 'An account already exists for this email address:', - 'Admin.Orderscustomers.Notification' - ), - $e instanceof EmailAlreadyUsedException ? $e->getEmail() : '' - ), - EmployeeConstraintException::class => [ - EmployeeConstraintException::INVALID_EMAIL => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Email', 'Admin.Global'))] - ), - EmployeeConstraintException::INVALID_FIRST_NAME => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('First name', 'Admin.Global'))] - ), - EmployeeConstraintException::INVALID_LAST_NAME => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Last name', 'Admin.Global'))] - ), - EmployeeConstraintException::INCORRECT_PASSWORD => $this->trans( - 'Your current password is invalid.', - 'Admin.Advparameters.Notification' - ), - ], - ]; - } - - /** - * Get template variables that are same between create and edit forms. - * - * @param Request $request - * - * @return array - */ - private function getFormTemplateVariables(Request $request) - { - $configuration = $this->get('prestashop.adapter.legacy.configuration'); - - return [ - 'level' => $this->authorizationLevel($request->attributes->get('_legacy_controller')), - 'requireAddonsSearch' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'superAdminProfileId' => $configuration->get('_PS_ADMIN_PROFILE_'), - 'getTabsUrl' => $this->generateUrl('admin_employees_get_tabs'), - 'errorMessage' => $this->trans('You need permission to add this.', 'Admin.Notifications.Error'), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportController.php deleted file mode 100644 index b9942e68..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportController.php +++ /dev/null @@ -1,417 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Core\Import\Exception\NotSupportedImportEntityException; -use PrestaShop\PrestaShop\Core\Import\Exception\UnavailableImportFileException; -use PrestaShop\PrestaShop\Core\Import\ImportDirectory; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Exception\FileUploadException; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\ResponseHeaderBag; - -/** - * Responsible of "Configure > Advanced Parameters > Import" page display. - */ -class ImportController extends FrameworkBundleAdminController -{ - /** - * Show import form & handle forwarding to legacy controller. - * - * @param Request $request - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return array|RedirectResponse|Response - */ - public function importAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $importDir = $this->get('prestashop.core.import.dir'); - - if (!$this->checkImportDirectory($importDir)) { - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig', - $this->getTemplateParams($request) - ); - } - - $formHandler = $this->get('prestashop.admin.import.form_handler'); - $finder = $this->get('prestashop.core.import.file_finder'); - $iniConfiguration = $this->get('prestashop.core.configuration.ini_configuration'); - $importConfigFactory = $this->get('prestashop.core.import.config_factory'); - - $importConfig = $importConfigFactory->buildFromRequest($request); - $form = $formHandler->getForm($importConfig); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - if (!$this->checkImportFormSubmitPermissions($legacyController)) { - return $this->redirectToRoute('admin_import'); - } - - $data = $form->getData(); - - if (!$errors = $formHandler->save($data)) { - // WIP import page 2 redirect - /*return $this->redirectToRoute( - 'admin_import_data_configuration_index', - [], - Response::HTTP_TEMPORARY_REDIRECT - );*/ - return $this->forwardRequestToLegacyResponse($request); - } - - $this->flashErrors($errors); - } - - $params = [ - 'importForm' => $form->createView(), - 'importFileUploadUrl' => $this->generateUrl('admin_import_file_upload'), - 'importFileNames' => $finder->getImportFileNames(), - 'importDirectory' => $importDir->getDir(), - 'maxFileUploadSize' => $iniConfiguration->getPostMaxSizeInBytes(), - ]; - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig', - $this->getTemplateParams($request) + $params - ); - } - - /** - * Handle import file upload via AJAX, sending authorization errors in JSON. - * - * @param Request $request - * - * @return JsonResponse - */ - public function uploadAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - if ($this->isDemoModeEnabled()) { - return $this->json([ - 'error' => $this->trans('This functionality has been disabled.', 'Admin.Notifications.Error'), - ]); - } - - if (!in_array($this->authorizationLevel($legacyController), [ - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_UPDATE, - PageVoter::LEVEL_DELETE, - ])) { - return $this->json([ - 'error' => $this->trans('You do not have permission to update this.', 'Admin.Notifications.Error'), - ]); - } - - $uploadedFile = $request->files->get('file'); - if (!$uploadedFile instanceof UploadedFile) { - return $this->json([ - 'error' => $this->trans('No file was uploaded.', 'Admin.Advparameters.Notification'), - ]); - } - - try { - $fileUploader = $this->get('prestashop.core.import.file_uploader'); - $file = $fileUploader->upload($uploadedFile); - } catch (FileUploadException $e) { - return $this->json(['error' => $e->getMessage()]); - } - - $response['file'] = [ - 'name' => $file->getFilename(), - 'size' => $file->getSize(), - ]; - - return $this->json($response); - } - - /** - * Delete import file. - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_import") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteAction(Request $request) - { - $filename = $request->query->get('filename', $request->query->get('csvfilename')); - if ($filename) { - $fileRemoval = $this->get('prestashop.core.import.file_removal'); - $fileRemoval->remove($filename); - } - - return $this->redirectToRoute('admin_import'); - } - - /** - * Download import file from history. - * - * @AdminSecurity("is_granted(['read','update', 'create','delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_import") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return Response - */ - public function downloadAction(Request $request) - { - if ($filename = $request->query->get('filename')) { - $importDirectory = $this->get('prestashop.core.import.dir'); - - $response = new BinaryFileResponse($importDirectory . $filename); - $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename); - - return $response; - } - - return $this->redirectToRoute('admin_import'); - } - - /** - * Download import sample file. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))", redirectRoute="admin_import") - * - * @param $sampleName - * - * @return Response - */ - public function downloadSampleAction($sampleName) - { - $sampleFileProvider = $this->get('prestashop.core.import.sample.file_provider'); - $sampleFile = $sampleFileProvider->getFile($sampleName); - - if (null === $sampleFile) { - return $this->redirectToRoute('admin_import'); - } - - $response = new BinaryFileResponse($sampleFile->getPathname()); - $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $sampleFile->getFilename()); - - return $response; - } - - /** - * Get available entity fields. - * - * @AdminSecurity( - * "is_granted('read', request.get('_legacy_controller'))", - * redirectRoute="admin_import" - * ) - * - * @param Request $request - * - * @return JsonResponse - */ - public function getAvailableEntityFieldsAction(Request $request) - { - $fieldsProviderFinder = $this->get('prestashop.core.import.fields_provider_finder'); - try { - $fieldsProvider = $fieldsProviderFinder->find($request->get('entity')); - $fieldsCollection = $fieldsProvider->getCollection(); - $entityFields = $fieldsCollection->toArray(); - } catch (NotSupportedImportEntityException $e) { - $entityFields = []; - } - - return $this->json($entityFields); - } - - /** - * Process the import. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", redirectRoute="admin_import") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return JsonResponse - */ - public function processImportAction(Request $request) - { - $errors = []; - $requestValidator = $this->get('prestashop.core.import.request_validator'); - - try { - $requestValidator->validate($request); - } catch (UnavailableImportFileException $e) { - $errors[] = $this->trans('To proceed, please upload a file first.', 'Admin.Advparameters.Notification'); - } - - if (!empty($errors)) { - return $this->json([ - 'errors' => $errors, - 'isFinished' => true, - ]); - } - - $importer = $this->get('prestashop.core.import.importer'); - $importConfigFactory = $this->get('prestashop.core.import.config_factory'); - $runtimeConfigFactory = $this->get('prestashop.core.import.runtime_config_factory'); - $importHandlerFinder = $this->get('prestashop.adapter.import.handler_finder'); - - $importConfig = $importConfigFactory->buildFromRequest($request); - $runtimeConfig = $runtimeConfigFactory->buildFromRequest($request); - - $importer->import( - $importConfig, - $runtimeConfig, - $importHandlerFinder->find($importConfig->getEntityType()) - ); - - return $this->json($runtimeConfig->toArray()); - } - - /** - * Get generic template parameters. - * - * @param Request $request - * - * @return array - */ - protected function getTemplateParams(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - return [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->get('translator')->trans('Import', [], 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - ]; - } - - /** - * Checks permissions of import form in step 1. - * - * @param $legacyController - * - * @return bool - */ - private function checkImportFormSubmitPermissions($legacyController) - { - if ($this->isDemoModeEnabled()) { - $this->addFlash( - 'error', - $this->trans( - 'This functionality has been disabled.', - 'Admin.Notifications.Error' - ) - ); - - return false; - } - - if (!in_array($this->authorizationLevel($legacyController), [ - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_UPDATE, - PageVoter::LEVEL_DELETE, - ])) { - $this->addFlash( - 'error', - $this->trans( - 'You do not have permission to update this.', - 'Admin.Notifications.Error' - ) - ); - - return false; - } - - return true; - } - - /** - * Check if the import directory exists and is accessible. - * - * @param ImportDirectory $importDir - * - * @return array|bool - */ - private function checkImportDirectory(ImportDirectory $importDir) - { - if (!$importDir->exists()) { - $this->addFlash( - 'error', - $this->trans( - 'The import directory doesn\'t exist. Please check your file path.', - 'Admin.Advparameters.Notification' - ) - ); - - return false; - } - - if (!$importDir->isWritable()) { - $this->addFlash( - 'warning', - $this->trans( - 'The import directory must be writable (CHMOD 755 / 777).', - 'Admin.Advparameters.Notification' - ) - ); - } - - return true; - } - - /** - * Forwards submitted form data to legacy import page. - * To be removed in 1.7.7 version. - * - * @param Request $request - * - * @return RedirectResponse - */ - private function forwardRequestToLegacyResponse(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - $legacyContext = $this->get('prestashop.adapter.legacy.context'); - - $legacyImportUrl = $legacyContext->getLegacyAdminLink($legacyController); - - return $this->redirect($legacyImportUrl, Response::HTTP_TEMPORARY_REDIRECT); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportDataConfigurationController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportDataConfigurationController.php deleted file mode 100644 index 5dcaa7d8..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ImportDataConfigurationController.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Core\Import\Exception\UnreadableFileException; -use PrestaShop\PrestaShop\Core\Import\ImportSettings; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use SplFileInfo; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Import" step 2 page display. - */ -class ImportDataConfigurationController extends FrameworkBundleAdminController -{ - /** - * Shows import data page where the configuration of importable data and the final step of import is handled. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return RedirectResponse|Response - */ - public function indexAction(Request $request) - { - $importDirectory = $this->get('prestashop.core.import.dir'); - $dataRowCollectionFactory = $this->get('prestashop.core.import.factory.data_row.collection_factory'); - $dataRowCollectionPresenter = $this->get('prestashop.core.import.data_row.collection_presenter'); - $entityFieldsProviderFinder = $this->get('prestashop.core.import.fields_provider_finder'); - $formHandler = $this->get('prestashop.admin.import_data_configuration.form_handler'); - $importConfigFactory = $this->get('prestashop.core.import.config_factory'); - - $importFile = new SplFileInfo($importDirectory . $request->getSession()->get('csv')); - $importConfig = $importConfigFactory->buildFromRequest($request); - $form = $formHandler->getForm($importConfig); - - try { - $dataRowCollection = $dataRowCollectionFactory->buildFromFile( - $importFile, - ImportSettings::MAX_VISIBLE_ROWS - ); - } catch (UnreadableFileException $e) { - $this->addFlash( - 'error', - $this->trans('The import file cannot be read.', 'Admin.Advparameters.Notification') - ); - - return $this->redirectToRoute('admin_import'); - } - - $presentedDataRowCollection = $dataRowCollectionPresenter->present($dataRowCollection); - $entityFieldsProvider = $entityFieldsProviderFinder->find($importConfig->getEntityType()); - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/ImportDataConfiguration/index.html.twig', - [ - 'importDataConfigurationForm' => $form->createView(), - 'dataRowCollection' => $presentedDataRowCollection, - 'maxVisibleColumns' => ImportSettings::MAX_VISIBLE_COLUMNS, - 'showPagingArrows' => $presentedDataRowCollection['row_size'] > ImportSettings::MAX_VISIBLE_COLUMNS, - 'requiredFields' => $entityFieldsProvider->getCollection()->getRequiredFields(), - ] - ); - } - - /** - * Create import data match configuration. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_import") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return JsonResponse - */ - public function createAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.import_data_configuration.form_handler'); - $importConfigFactory = $this->get('prestashop.core.import.config_factory'); - - $importConfig = $importConfigFactory->buildFromRequest($request); - $form = $formHandler->getForm($importConfig); - $form->setData([ - 'match_name' => $request->request->get('match_name'), - 'skip' => $request->request->get('skip'), - 'type_value' => $request->request->get('type_value'), - ]); - - $errors = $formHandler->save($form->getData()); - $matches = []; - - if (!$errors) { - $importMatchRepository = $this->get('prestashop.core.admin.import_match.repository'); - $matches = $importMatchRepository->findAll(); - } - - return $this->json([ - 'errors' => $errors, - 'matches' => $matches, - ]); - } - - /** - * Delete import data match configuration. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_import") - * @DemoRestricted(redirectRoute="admin_import") - * - * @param Request $request - * - * @return JsonResponse - */ - public function deleteAction(Request $request) - { - $importMatchRepository = $this->get('prestashop.core.admin.import_match.repository'); - $importMatchRepository->deleteById($request->get('import_match_id')); - - return $this->json([]); - } - - /** - * Get import data match configuration. - * - * @AdminSecurity( - * "is_granted('read', request.get('_legacy_controller'))", - * redirectRoute="admin_import" - * ) - * - * @param Request $request - * - * @return JsonResponse - */ - public function getAction(Request $request) - { - $importMatchRepository = $this->get('prestashop.core.admin.import_match.repository'); - $importMatch = $importMatchRepository->findOneById($request->get('import_match_id')); - - return $this->json($importMatch); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php deleted file mode 100644 index 5636d372..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/LogsController.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\LogsFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Entity\Repository\LogRepository; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Logs" page display. - */ -class LogsController extends FrameworkBundleAdminController -{ - /** - * @var string the controller name for routing - */ - const CONTROLLER_NAME = 'AdminLogs'; - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param LogsFilters $filters the list of filters from the request - * - * @return Response - */ - public function indexAction(LogsFilters $filters) - { - $gridLogFactory = $this->get('prestashop.core.grid.log_factory'); - $grid = $gridLogFactory->getGrid($filters); - - $logsByEmailForm = $this->getFormHandler()->getForm(); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/LogsPage/index.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Logs', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminLogs'), - 'logsByEmailForm' => $logsByEmailForm->createView(), - 'grid' => $this->presentGrid($grid), - ]); - } - - /** - * @AdminSecurity("is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_logs_index") - * @DemoRestricted(redirectRoute="admin_logs_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.logs'); - $logsDefinition = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $searchParametersForm = $gridFilterFormFactory->create($logsDefinition); - - $searchParametersForm->handleRequest($request); - $filters = []; - - $this->dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]); - - if ($searchParametersForm->isSubmitted()) { - $filters = $searchParametersForm->getData(); - } - - return $this->redirectToRoute('admin_logs_index', ['filters' => $filters]); - } - - /** - * @AdminSecurity("is_granted(['update', 'create','delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_logs_index") - * @DemoRestricted(redirectRoute="admin_logs_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveSettingsAction(Request $request) - { - $logsByEmailForm = $this->getFormHandler()->getForm(); - $logsByEmailForm->handleRequest($request); - - $this->dispatchHook('actionAdminLogsControllerPostProcessBefore', ['controller' => $this]); - - if ($logsByEmailForm->isSubmitted()) { - $data = $logsByEmailForm->getData(); - - $saveErrors = $this->getFormHandler()->save($data); - - if (0 === count($saveErrors)) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_logs_index'); - } - - $this->flashErrors($saveErrors); - } - - return $this->redirectToRoute('admin_logs_index'); - } - - /** - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_logs_index") - * - * @return RedirectResponse - * - * @throws \Doctrine\DBAL\Exception\InvalidArgumentException - */ - public function deleteAllAction() - { - $this->getLogRepository()->deleteAll(); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_logs_index'); - } - - /** - * @return FormHandlerInterface the form handler to set the severity level - */ - private function getFormHandler() - { - return $this->get('prestashop.adapter.logs.form_handler'); - } - - /** - * @return LogRepository the repository to retrieve logs from database - */ - private function getLogRepository() - { - return $this->get('prestashop.core.admin.log.repository'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/MemcacheServerController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/MemcacheServerController.php deleted file mode 100644 index 0118ba66..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/MemcacheServerController.php +++ /dev/null @@ -1,194 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShop\PrestaShop\Adapter\Cache\MemcacheServerManager; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Performance" servers block management. - */ -class MemcacheServerController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'AdminPerformance'; - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @return JsonResponse - */ - public function listAction() - { - return new JsonResponse($this->getMemcacheManager()->getServers()); - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * @DemoRestricted(redirectRoute="admin_servers_test") - * - * @param Request $request - * - * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse - */ - public function testAction(Request $request) - { - $queryValues = $request->query; - - if ($queryValues->has('server_ip') && $queryValues->has('server_port')) { - $isValid = $this->getMemcacheManager() - ->testConfiguration( - $queryValues->get('server_ip'), - $queryValues->getInt('server_port') - ); - - return new JsonResponse(['test' => $isValid]); - } - - return new JsonResponse(['errors' => 'error'], Response::HTTP_BAD_REQUEST); - } - - /** - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))", message="Access denied.") - * @DemoRestricted(redirectRoute="admin_servers_test") - * - * @param Request $request - * - * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse - */ - public function addAction(Request $request) - { - if (!in_array( - $this->authorizationLevel($this::CONTROLLER_NAME), - [ - PageVoter::LEVEL_READ, - PageVoter::LEVEL_UPDATE, - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_DELETE, - ] - )) { - return new JsonResponse( - [ - 'errors' => [ - $this->trans('You do not have permission to create this.', 'Admin.Notifications.Error'), - ], - ], - Response::HTTP_BAD_REQUEST - ); - } - - $postValues = $request->request; - - if ($postValues->has('server_ip') - && $postValues->has('server_port') - && $postValues->has('server_weight') - && $this->getMemcacheManager()->testConfiguration( - $postValues->get('server_ip'), - $postValues->getInt('server_port') - ) - ) { - $server = $this->getMemcacheManager() - ->addServer( - $postValues->get('server_ip'), - $postValues->getInt('server_port'), - $postValues->get('server_weight') - ); - - return new JsonResponse($server, 201); - } - - return new JsonResponse( - [ - 'errors' => [ - $this->trans('The Memcached server cannot be added.', 'Admin.Advparameters.Notification'), - ], - ], - Response::HTTP_BAD_REQUEST - ); - } - - /** - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="Access denied.") - * @DemoRestricted(redirectRoute="admin_servers_test") - * - * @param Request $request - * - * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse - */ - public function deleteAction(Request $request) - { - if (!in_array( - $this->authorizationLevel($this::CONTROLLER_NAME), - [ - PageVoter::LEVEL_READ, - PageVoter::LEVEL_UPDATE, - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_DELETE, - ] - )) { - return new JsonResponse( - [ - 'errors' => [ - $this->trans('You do not have permission to delete this.', 'Admin.Notifications.Error'), - ], - ], - Response::HTTP_BAD_REQUEST - ); - } - - if ($request->request->has('server_id')) { - $this->getMemcacheManager()->deleteServer($request->request->get('server_id')); - - return new JsonResponse([], Response::HTTP_NO_CONTENT); - } - - return new JsonResponse( - [ - 'errors' => [ - $this->trans( - 'There was an error when attempting to delete the Memcached server.', - 'Admin.Advparameters.Notification' - ), - ], - ], - Response::HTTP_BAD_REQUEST - ); - } - - /** - * @return MemcacheServerManager - */ - private function getMemcacheManager() - { - return $this->get('prestashop.adapter.memcache_server.manager'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php deleted file mode 100644 index 8ec42565..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/PerformanceController.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Performance" page display. - */ -class PerformanceController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'AdminPerformance'; - - /** - * Displays the Performance main page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param FormInterface $form - * - * @return Response - */ - public function indexAction(FormInterface $form = null): Response - { - $toolbarButtons = [ - 'clear_cache' => [ - 'href' => $this->generateUrl('admin_clear_cache'), - 'desc' => $this->trans('Clear cache', 'Admin.Advparameters.Feature'), - 'icon' => 'delete', - ], - ]; - - $form = null === $form ? $this->get('prestashop.adapter.performance.form_handler')->getForm() : $form; - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/performance.html.twig', [ - 'layoutHeaderToolbarBtn' => $toolbarButtons, - 'layoutTitle' => $this->trans('Performance', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminPerformance'), - 'requireFilterStatus' => false, - 'form' => $form->createView(), - 'servers' => $this->get('prestashop.adapter.memcache_server.manager')->getServers(), - ]); - } - - /** - * Process the Performance configuration form. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.") - * @DemoRestricted(redirectRoute="admin_performance") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $this->dispatchHook('actionAdminPerformanceControllerPostProcessBefore', ['controller' => $this]); - $form = $this->get('prestashop.adapter.performance.form_handler')->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - $saveErrors = $this->get('prestashop.adapter.performance.form_handler')->save($data); - - if (0 === count($saveErrors)) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_performance'); - } - - $this->flashErrors($saveErrors); - } - - return $this->redirectToRoute('admin_performance'); - } - - /** - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_performance" - * ) - * - * @return RedirectResponse - */ - public function clearCacheAction() - { - $this->get('prestashop.core.cache.clearer.cache_clearer_chain')->clear(); - $this->addFlash('success', $this->trans('All caches cleared successfully', 'Admin.Advparameters.Notification')); - - return $this->redirectToRoute('admin_performance'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ProfileController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ProfileController.php deleted file mode 100644 index f05574d2..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/ProfileController.php +++ /dev/null @@ -1,300 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\BulkDeleteProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\Command\DeleteProfileCommand; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\CannotDeleteSuperAdminProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\FailedToDeleteProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileException; -use PrestaShop\PrestaShop\Core\Domain\Profile\Exception\ProfileNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Profile\ProfileSettings; -use PrestaShop\PrestaShop\Core\Domain\Profile\Query\GetProfileForEditing; -use PrestaShop\PrestaShop\Core\Domain\Profile\QueryResult\EditableProfile; -use PrestaShop\PrestaShop\Core\Search\Filters\ProfileFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class ProfilesController is responsible for displaying the - * "Configure > Advanced parameters > Team > Profiles" page. - */ -class ProfileController extends FrameworkBundleAdminController -{ - /** - * Show profiles listing page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param ProfileFilters $filters - * - * @return Response - */ - public function indexAction(ProfileFilters $filters) - { - $profilesGridFactory = $this->get('prestashop.core.grid.factory.profiles'); - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Profiles/index.html.twig', - [ - 'layoutHeaderToolbarBtn' => [ - 'add' => [ - 'href' => $this->generateUrl('admin_profiles_create'), - 'desc' => $this->trans('Add new profile', 'Admin.Advparameters.Feature'), - 'icon' => 'add_circle_outline', - ], - ], - 'help_link' => $this->generateSidebarLink('AdminProfiles'), - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Profiles', 'Admin.Navigation.Menu'), - 'grid' => $this->presentGrid($profilesGridFactory->getGrid($filters)), - ] - ); - } - - /** - * Used for applying filtering actions. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.profile'); - $definitionFactory = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $searchParametersForm = $gridFilterFormFactory->create($definitionFactory); - $searchParametersForm->handleRequest($request); - - $filters = []; - - if ($searchParametersForm->isSubmitted()) { - $filters = $searchParametersForm->getData(); - } - - return $this->redirectToRoute('admin_profiles_index', ['filters' => $filters]); - } - - /** - * Show profile's create page - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_profiles_index") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $form = $this->get('prestashop.core.form.identifiable_object.builder.profile_form_builder')->getForm(); - $form->handleRequest($request); - - try { - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.profile_form_handler'); - $handlerResult = $formHandler->handle($form); - - if (null !== $handlerResult->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_profiles_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Profiles/create.html.twig', [ - 'profileForm' => $form->createView(), - 'layoutTitle' => $this->trans('Add new profile', 'Admin.Advparameters.Feature'), - 'help_link' => $this->generateSidebarLink('AdminProfiles'), - 'enableSidebar' => true, - ]); - } - - /** - * Shows profile edit form. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_profiles_index") - * - * @param int $profileId - * @param Request $request - * - * @return Response - */ - public function editAction($profileId, Request $request) - { - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.profile_form_handler'); - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.profile_form_builder'); - - try { - $form = $formBuilder->getFormFor((int) $profileId); - $form->handleRequest($request); - - $handlerResult = $formHandler->handleFor((int) $profileId, $form); - - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_profiles_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - if ($e instanceof ProfileNotFoundException) { - return $this->redirectToRoute('admin_profiles_index'); - } - } - - /** @var EditableProfile $editableProfiler */ - $editableProfiler = $this->getQueryBus()->handle(new GetProfileForEditing((int) $profileId)); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/Profiles/edit.html.twig', [ - 'profileForm' => $form->createView(), - 'layoutTitle' => $this->trans( - 'Edit: %value%', - 'Admin.Catalog.Feature', - [ - '%value%' => $editableProfiler->getLocalizedNames()[$this->getContextLangId()], - ] - ), - 'help_link' => $this->generateSidebarLink('AdminProfiles'), - 'enableSidebar' => true, - ]); - } - - /** - * Delete a profile. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller')~'_')", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_profiles_index") - * - * @param int $profileId - * - * @return RedirectResponse - */ - public function deleteAction($profileId) - { - try { - $deleteProfileCommand = new DeleteProfileCommand($profileId); - - $this->getCommandBus()->handle($deleteProfileCommand); - - $this->addFlash('success', $this->trans('Successful deletion', 'Admin.Notifications.Success')); - } catch (ProfileException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_profiles_index'); - } - - /** - * Bulk delete profiles. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller')~'_')", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_profiles_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $profileIds = $request->request->get('profile_bulk'); - - try { - $deleteProfilesCommand = new BulkDeleteProfileCommand($profileIds); - - $this->getCommandBus()->handle($deleteProfilesCommand); - - $this->addFlash('success', $this->trans('Successful deletion', 'Admin.Notifications.Success')); - } catch (ProfileException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_profiles_index'); - } - - /** - * Get human readable error for exception. - * - * @return array - */ - protected function getErrorMessages() - { - return [ - ProfileConstraintException::class => [ - ProfileConstraintException::INVALID_NAME => $this->trans( - 'This field cannot be longer than %limit% characters (incl. HTML tags)', - 'Admin.Notifications.Error', - ['%limit%' => ProfileSettings::NAME_MAX_LENGTH] - ), - ], - ProfileNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotDeleteSuperAdminProfileException::class => $this->trans( - 'For security reasons, you cannot delete the Administrator\'s profile.', - 'Admin.Advparameters.Notification' - ), - FailedToDeleteProfileException::class => [ - FailedToDeleteProfileException::UNEXPECTED_ERROR => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - FailedToDeleteProfileException::PROFILE_IS_ASSIGNED_TO_EMPLOYEE => $this->trans( - 'Profile(s) assigned to employee cannot be deleted', - 'Admin.Notifications.Error' - ), - FailedToDeleteProfileException::PROFILE_IS_ASSIGNED_TO_CONTEXT_EMPLOYEE => $this->trans( - 'You cannot delete your own profile', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SqlManagerController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SqlManagerController.php deleted file mode 100644 index f9fea315..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SqlManagerController.php +++ /dev/null @@ -1,594 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\BulkDeleteSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\DeleteSqlRequestCommand; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTableFields; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\DatabaseTablesList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\CannotDeleteSqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Exception\SqlRequestNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTableFieldsList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTablesList; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestSettings; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestExecutionResult; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\SqlRequestSettings; -use PrestaShop\PrestaShop\Core\Domain\SqlManagement\ValueObject\SqlRequestId; -use PrestaShop\PrestaShop\Core\Export\Exception\FileWritingException; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\RequestSqlFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\BinaryFileResponse; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\ResponseHeaderBag; - -/** - * Responsible of "Configure > Advanced Parameters > Database -> SQL Manager" page. - */ -class SqlManagerController extends FrameworkBundleAdminController -{ - /** - * Show list of saved SQL's. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * @param RequestSqlFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, RequestSqlFilters $filters) - { - // handle "Export to SQL manager" action from legacy pages - if ($request->query->has('addrequest_sql')) { - return $this->forward('PrestaShopBundle:Admin\Configure\AdvancedParameters\RequestSql:create'); - } - - $gridLogFactory = $this->get('prestashop.core.grid.factory.request_sql'); - $grid = $gridLogFactory->getGrid($filters); - - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - $presentedGrid = $gridPresenter->present($grid); - - $settingsForm = $this->getSettingsFormHandler()->getForm(); - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/index.html.twig', [ - 'layoutHeaderToolbarBtn' => [ - 'add' => [ - 'href' => $this->generateUrl('admin_sql_requests_create'), - 'desc' => $this->trans('Add new SQL query', 'Admin.Advparameters.Feature'), - 'icon' => 'add_circle_outline', - ], - ], - 'layoutTitle' => $this->trans('SQL Manager', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'requestSqlSettingsForm' => $settingsForm->createView(), - 'requestSqlGrid' => $presentedGrid, - ]); - } - - /** - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))", redirectRoute="admin_sql_requests_index") - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.request_sql'); - $emailLogsDefinition = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $filtersForm = $gridFilterFormFactory->create($emailLogsDefinition); - $filtersForm->handleRequest($request); - - $filters = []; - - if ($filtersForm->isSubmitted()) { - $filters = $filtersForm->getData(); - } - - return $this->redirectToRoute('admin_sql_requests_index', ['filters' => $filters]); - } - - /** - * Process Request SQL settings save. - * - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_sql_requests_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $handler = $this->getSettingsFormHandler(); - $settingForm = $handler->getForm(); - $settingForm->handleRequest($request); - - if ($settingForm->isSubmitted()) { - if (!$errors = $handler->save($settingForm->getData())) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } else { - $this->flashErrors($errors); - } - } - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - /** - * Show Request SQL create page. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * message="You do not have permission to create this.", - * redirectRoute="admin_sql_requests_index" - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $data = $this->getSqlRequestDataFromRequest($request); - - $sqlRequestForm = $this->getSqlRequestFormBuilder()->getForm($data); - $sqlRequestForm->handleRequest($request); - - $result = $this->getSqlRequestFormHandler()->handle($sqlRequestForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/create.html.twig', [ - 'layoutTitle' => $this->trans('SQL Manager', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'requestSqlForm' => $sqlRequestForm->createView(), - 'dbTableNames' => $this->getDatabaseTables(), - ]); - } - - /** - * Show Request SQL edit page. - * - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_sql_requests_index" - * ) - * - * @param int $sqlRequestId - * @param Request $request - * - * @return Response - */ - public function editAction($sqlRequestId, Request $request) - { - try { - $sqlRequestForm = $this->getSqlRequestFormBuilder()->getFormFor($sqlRequestId); - $sqlRequestForm->handleRequest($request); - - $result = $this->getSqlRequestFormHandler()->handleFor($sqlRequestId, $sqlRequestForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_sql_requests_index'); - } - } catch (SqlRequestNotFoundException $e) { - $this->addFlash( - 'error', - $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error') - ); - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/edit.html.twig', [ - 'layoutTitle' => $this->trans('SQL Manager', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'requestSqlForm' => $sqlRequestForm->createView(), - 'dbTableNames' => $this->getDatabaseTables(), - ]); - } - - /** - * Delete selected Request SQL. - * - * @AdminSecurity( - * "is_granted(['delete'], request.get('_legacy_controller'))", - * message="You do not have permission to delete this.", - * redirectRoute="admin_sql_requests_index" - * ) - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * - * @param int $sqlRequestId ID of selected Request SQL - * - * @return RedirectResponse - */ - public function deleteAction($sqlRequestId) - { - try { - $deleteSqlRequestCommand = new DeleteSqlRequestCommand( - new SqlRequestId($sqlRequestId) - ); - - $this->getCommandBus()->handle($deleteSqlRequestCommand); - - $this->addFlash('success', $this->trans('Successful deletion', 'Admin.Notifications.Success')); - } catch (SqlRequestException $e) { - $this->addFlash('error', $this->handleDeleteException($e)); - } - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - /** - * Process bulk action delete of RequestSql's. - * - * @AdminSecurity( - * "is_granted(['delete'], request.get('_legacy_controller'))", - * message="You do not have permission to delete this.", - * redirectRoute="admin_sql_requests_index" - * ) - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request) - { - try { - $requestSqlIds = $request->request->get('sql_request_bulk'); - $bulkDeleteSqlRequestCommand = new BulkDeleteSqlRequestCommand($requestSqlIds); - - $this->getCommandBus()->handle($bulkDeleteSqlRequestCommand); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (SqlRequestException $e) { - $this->addFlash('error', $this->handleDeleteException($e)); - } - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - /** - * View Request SQL query data. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * message="You do not have permission to view this.", - * redirectRoute="admin_sql_requests_index" - * ) - * - * @param Request $request - * @param int $sqlRequestId - * - * @return Response - */ - public function viewAction(Request $request, $sqlRequestId) - { - try { - $query = new GetSqlRequestExecutionResult($sqlRequestId); - - $sqlRequestExecutionResult = $this->getQueryBus()->handle($query); - } catch (SqlRequestException $e) { - $this->addFlash('error', $this->handleViewException($e)); - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - return $this->render('@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/view.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('SQL Manager', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'sqlRequestResult' => $sqlRequestExecutionResult, - ]); - } - - /** - * Export Request SQL data. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * redirectRoute="admin_sql_requests_index" - * ) - * @DemoRestricted(redirectRoute="admin_sql_requests_index") - * - * @param int $sqlRequestId Request SQL id - * - * @return RedirectResponse|BinaryFileResponse - */ - public function exportAction($sqlRequestId) - { - $requestSqlExporter = $this->get('prestashop.core.sql_manager.exporter.sql_request_exporter'); - - try { - $query = new GetSqlRequestExecutionResult($sqlRequestId); - /** @var SqlRequestExecutionResult $sqlRequestExecutionResult */ - $sqlRequestExecutionResult = $this->getQueryBus()->handle($query); - - $exportedFile = $requestSqlExporter->exportToFile( - $query->getSqlRequestId(), - $sqlRequestExecutionResult - ); - - /** @var SqlRequestSettings $sqlRequestSettings */ - $sqlRequestSettings = $this->getQueryBus()->handle(new GetSqlRequestSettings()); - } catch (SqlRequestException $e) { - $this->addFlash('error', $this->handleExportException($e)); - - return $this->redirectToRoute('admin_sql_requests_index'); - } - - $response = new BinaryFileResponse($exportedFile->getPathname()); - $response->setCharset($sqlRequestSettings->getFileEncoding()); - $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $exportedFile->getFilename()); - - return $response; - } - - /** - * Get MySQL table columns data. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * redirectRoute="admin_sql_requests_index" - * ) - * - * @param string $mySqlTableName Database table name - * - * @return JsonResponse - */ - public function ajaxTableColumnsAction($mySqlTableName) - { - $query = new GetDatabaseTableFieldsList($mySqlTableName); - /** @var DatabaseTableFields $databaseFields */ - $databaseFields = $this->getQueryBus()->handle($query); - - return $this->json(['columns' => $databaseFields->getFields()]); - } - - /** - * Get request sql repository. - * - * @return \PrestaShopBundle\Entity\Repository\RequestSqlRepository - */ - protected function getRepository() - { - return $this->get('prestashop.core.admin.request_sql.repository'); - } - - /** - * Get Request SQL settings form handler. - * - * @return FormHandlerInterface - */ - protected function getSettingsFormHandler() - { - return $this->get('prestashop.admin.request_sql_settings.form_handler'); - } - - /** - * @return \PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface - */ - protected function getSqlRequestFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.sql_request_form_handler'); - } - - /** - * @return FormBuilderInterface - */ - protected function getSqlRequestFormBuilder() - { - return $this->get('prestashop.core.form.builder.sql_request_form_builder'); - } - - /** - * When "Export to SQL Manager" feature is used, - * it adds "name" and "sql" to request's POST data - * which is used as default form data - * when creating SqlRequest. - * - * @param Request $request - * - * @return array - */ - protected function getSqlRequestDataFromRequest(Request $request) - { - if ($request->request->has('sql') || $request->request->has('name')) { - return [ - 'sql' => $request->request->get('sql'), - 'name' => $request->request->get('name'), - ]; - } - - return []; - } - - /** - * Get human readable error for exception. - * - * @param SqlRequestException $e - * - * @return string Error message - */ - protected function handleDeleteException(SqlRequestException $e) - { - $code = $e->getCode(); - $type = get_class($e); - - $exceptionMessages = [ - SqlRequestNotFoundException::class => $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error'), - SqlRequestException::class => $this->trans('An error occurred while deleting the object.', 'Admin.Notifications.Error'), - ]; - - $deleteExceptionMessages = [ - CannotDeleteSqlRequestException::CANNOT_SINGLE_DELETE => $this->trans('An error occurred while deleting the object.', 'Admin.Notifications.Error'), - CannotDeleteSqlRequestException::CANNOT_BULK_DELETE => $this->trans('An error occurred while deleting this selection.', 'Admin.Notifications.Error'), - ]; - - if (CannotDeleteSqlRequestException::class === $type - && isset($deleteExceptionMessages[$code]) - ) { - return $deleteExceptionMessages[$code]; - } - - if (isset($exceptionMessages[$type])) { - return $exceptionMessages[$type]; - } - - return $this->getFallbackErrorMessage($type, $code); - } - - /** - * Get error message when exception occurs on View action. - * - * @param SqlRequestException $e - * - * @return string - */ - protected function handleViewException(SqlRequestException $e) - { - $type = get_class($e); - - $exceptionMessages = [ - SqlRequestNotFoundException::class => $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error'), - ]; - - if (isset($exceptionMessages[$type])) { - return $exceptionMessages[$type]; - } - - return $this->getFallbackErrorMessage($type, $e->getCode()); - } - - /** - * @param Exception $e - * - * @return string Error message - */ - protected function handleExportException(Exception $e) - { - $type = get_class($e); - - if ($e instanceof FileWritingException) { - return $this->handleApplicationExportException($e); - } - - if ($e instanceof SqlRequestException) { - return $this->handleDomainExportException($e); - } - - return $this->getFallbackErrorMessage($type, $e->getCode()); - } - - /** - * @param FileWritingException $e - * - * @return string Error message - */ - protected function handleApplicationExportException(FileWritingException $e) - { - $code = $e->getCode(); - - $applicationErrors = [ - FileWritingException::CANNOT_OPEN_FILE_FOR_WRITING => $this->trans('Cannot open export file for writing', 'Admin.Notifications.Error'), - ]; - - if (isset($applicationErrors[$code])) { - return $applicationErrors[$code]; - } - - return $this->getFallbackErrorMessage(get_class($e), $code); - } - - /** - * @param SqlRequestException $e - * - * @return string - */ - protected function handleDomainExportException(SqlRequestException $e) - { - $type = get_class($e); - - $domainErrors = [ - SqlRequestNotFoundException::class => $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error'), - ]; - - if (isset($domainErrors[$type])) { - return $domainErrors[$type]; - } - - return $this->getFallbackErrorMessage($type, $e->getCode()); - } - - /** - * @return string[] Array of database tables - */ - protected function getDatabaseTables() - { - /** @var DatabaseTablesList $databaseTablesList */ - $databaseTablesList = $this->getQueryBus()->handle(new GetDatabaseTablesList()); - - return $databaseTablesList->getTables(); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SystemInformationController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SystemInformationController.php deleted file mode 100644 index b09962c6..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/SystemInformationController.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Responsible of "Configure > Advanced Parameters > Information" page display. - */ -class SystemInformationController extends FrameworkBundleAdminController -{ - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * @Template("@PrestaShop/Admin/Configure/AdvancedParameters/system_information.html.twig") - * - * @param Request $request - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->get('_legacy_controller'); - $requirementsSummary = $this->getRequirementsChecker()->getSummary(); - $systemInformationSummary = $this->getSystemInformation()->getSummary(); - - return [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Information', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'requireFilterStatus' => false, - 'errorMessage' => 'ok', - 'system' => $systemInformationSummary, - 'requirements' => $requirementsSummary, - 'userAgent' => $request->headers->get('User-Agent'), - ]; - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @return JsonResponse - */ - public function displayCheckFilesAction() - { - return new JsonResponse($this->getRequiredFilesChecker()->getListOfUpdatedFiles()); - } - - /** - * @return \PrestaShop\PrestaShop\Adapter\System\SystemInformation - */ - private function getSystemInformation() - { - return $this->get('prestashop.adapter.system_information'); - } - - /** - * @return \PrestaShop\PrestaShop\Adapter\Requirement\CheckRequirements - */ - private function getRequirementsChecker() - { - return $this->get('prestashop.adapter.check_requirements'); - } - - /** - * @return \PrestaShop\PrestaShop\Adapter\Requirement\CheckMissingOrUpdatedFiles - */ - private function getRequiredFilesChecker() - { - return $this->get('prestashop.adapter.check_missing_files'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php b/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php deleted file mode 100644 index 3c683fd8..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/AdvancedParameters/WebserviceController.php +++ /dev/null @@ -1,365 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\AdvancedParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\DuplicateWebserviceKeyException; -use PrestaShop\PrestaShop\Core\Domain\Webservice\Exception\WebserviceConstraintException; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\WebserviceKeyFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Advanced Parameters > Webservice" page. - * - * @todo: add unit tests - */ -class WebserviceController extends FrameworkBundleAdminController -{ - /** - * Displays the Webservice main page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param WebserviceKeyFilters $filters - filters for webservice list - * @param Request $request - * - * @return Response - */ - public function indexAction(WebserviceKeyFilters $filters, Request $request) - { - $form = $this->getFormHandler()->getForm(); - $gridWebserviceFactory = $this->get('prestashop.core.grid.factory.webservice_key'); - $grid = $gridWebserviceFactory->getGrid($filters); - - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - $presentedGrid = $gridPresenter->present($grid); - - $configurationWarnings = $this->lookForWarnings(); - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/index.html.twig', - [ - 'help_link' => $this->generateSidebarLink($request->get('_legacy_controller')), - 'form' => $form->createView(), - 'grid' => $presentedGrid, - 'configurationWarnings' => $configurationWarnings, - ] - ); - } - - /** - * Shows Webservice Key form and handles its submit - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.webservice_key_form_handler'); - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.webservice_key_form_builder'); - - $form = $formBuilder->getForm(); - $form->handleRequest($request); - - try { - $result = $formHandler->handle($form); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/create.html.twig', - [ - 'webserviceKeyForm' => $form->createView(), - ] - ); - } - - /** - * Redirects to webservice account form where existing webservice account record can be edited. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param int $webserviceKeyId - * @param Request $request - * - * @return Response - */ - public function editAction($webserviceKeyId, Request $request) - { - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.webservice_key_form_handler'); - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.webservice_key_form_builder'); - - $form = $formBuilder->getFormFor((int) $webserviceKeyId); - $form->handleRequest($request); - - try { - $result = $formHandler->handleFor((int) $webserviceKeyId, $form); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render( - '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig', - [ - 'webserviceKeyForm' => $form->createView(), - ] - ); - } - - /** - * Searches for specific records. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.webservice_key'); - $webserviceDefinition = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $searchParametersForm = $gridFilterFormFactory->create($webserviceDefinition); - - $searchParametersForm->handleRequest($request); - $filters = []; - - if ($searchParametersForm->isSubmitted()) { - $filters = $searchParametersForm->getData(); - } - - return $this->redirectToRoute('admin_webservice_keys_index', ['filters' => $filters]); - } - - /** - * Deletes single record. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") - * - * @param int $webserviceKeyId - * - * @return RedirectResponse - */ - public function deleteAction($webserviceKeyId) - { - $webserviceEraser = $this->get('prestashop.adapter.webservice.webservice_key_eraser'); - $errors = $webserviceEraser->erase([$webserviceKeyId]); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * Deletes selected records. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $webserviceToDelete = $request->request->get('webservice_key_bulk_action'); - - $webserviceEraser = $this->get('prestashop.adapter.webservice.webservice_key_eraser'); - $errors = $webserviceEraser->erase($webserviceToDelete); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * Enables status for selected rows. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkEnableAction(Request $request) - { - $webserviceToEnable = $request->request->get('webservice_key_bulk_action'); - $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); - - $statusModifier->setStatus($webserviceToEnable, 1); - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * Disables status for selected rows. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDisableAction(Request $request) - { - $webserviceToEnable = $request->request->get('webservice_key_bulk_action'); - $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); - - $statusModifier->setStatus($webserviceToEnable, 0); - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * Toggles webservice account status. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * - * @param int $webserviceKeyId - * - * @return RedirectResponse - */ - public function toggleStatusAction($webserviceKeyId) - { - $statusModifier = $this->get('prestashop.adapter.webservice.webservice_key_status_modifier'); - $errors = $statusModifier->toggleStatus($webserviceKeyId); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * Process the Webservice configuration form. - * - * @DemoRestricted(redirectRoute="admin_webservice_keys_index") - * @AdminSecurity("is_granted(['create', 'update', 'delete'], request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveSettingsAction(Request $request) - { - $this->dispatchHook('actionAdminAdminWebserviceControllerPostProcessBefore', ['controller' => $this]); - - $form = $this->getFormHandler()->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $saveErrors = $this->getFormHandler()->save($form->getData()); - - if (0 === count($saveErrors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } else { - $this->flashErrors($saveErrors); - } - } - - return $this->redirectToRoute('admin_webservice_keys_index'); - } - - /** - * @return FormHandlerInterface - */ - private function getFormHandler() - { - return $this->get('prestashop.adapter.webservice.form_handler'); - } - - /** - * @return string[] - */ - private function lookForWarnings() - { - $configurationChecker = $this->get('prestashop.core.webservice.server_requirements_checker'); - - return $configurationChecker->checkForErrors(); - } - - /** - * @return array - */ - private function getErrorMessages() - { - return [ - WebserviceConstraintException::class => [ - WebserviceConstraintException::INVALID_KEY => $this->trans('Key length must be 32 character long.', 'Admin.Advparameters.Notification'), - ], - DuplicateWebserviceKeyException::class => $this->trans('This key already exists.', 'Admin.Advparameters.Notification'), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php deleted file mode 100644 index 451347d1..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ContactsController.php +++ /dev/null @@ -1,321 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Contact\Exception\ContactNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainConstraintException; -use PrestaShop\PrestaShop\Core\Search\Filters\ContactFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * ContactsController is responsible for actions and rendering - * of "Shop Parameters > Contact > Contacts" page. - */ -class ContactsController extends FrameworkBundleAdminController -{ - /** - * Shows page content. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param ContactFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, ContactFilters $filters) - { - $contactGridFactory = $this->get('prestashop.core.grid.factory.contacts'); - $contactGrid = $contactGridFactory->getGrid($filters); - - return $this->render( - '@PrestaShop/Admin/Configure/ShopParameters/Contact/Contacts/index.html.twig', - [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Contacts', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'layoutHeaderToolbarBtn' => [ - 'add' => [ - 'desc' => $this->trans('Add new contact', 'Admin.Shopparameters.Feature'), - 'icon' => 'add_circle_outline', - 'href' => $this->generateUrl('admin_contacts_create'), - ], - ], - 'contactGrid' => $this->presentGrid($contactGrid), - ] - ); - } - - /** - * Grid search action. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $gridDefinitionFactory = $this->get('prestashop.core.grid.definition.factory.contacts'); - $contactsGridDefinition = $gridDefinitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $filtersForm = $gridFilterFormFactory->create($contactsGridDefinition); - $filtersForm->handleRequest($request); - - $filters = []; - - if ($filtersForm->isSubmitted()) { - $filters = $filtersForm->getData(); - } - - return $this->redirectToRoute('admin_contacts_index', ['filters' => $filters]); - } - - /** - * Display the Contact creation form. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_contacts_index", - * message="You do not have permission to add this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $contactFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.contact_form_builder'); - $contactForm = $contactFormBuilder->getForm(); - $contactForm->handleRequest($request); - - try { - $contactFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.contact_form_handler'); - $result = $contactFormHandler->handle($contactForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash( - 'success', - $this->trans('Successful creation.', 'Admin.Notifications.Success') - ); - - return $this->redirectToRoute('admin_contacts_index'); - } - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages($exception)) - ); - } - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/Contact/Contacts/create.html.twig', [ - 'contactForm' => $contactForm->createView(), - ]); - } - - /** - * Display the contact edit form. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_contacts_index", - * message="You do not have permission to edit this." - * ) - * - * @param int $contactId - * @param Request $request - * - * @return Response - */ - public function editAction($contactId, Request $request) - { - $contactFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.contact_form_builder'); - $contactForm = $contactFormBuilder->getFormFor((int) $contactId); - - $contactForm->handleRequest($request); - - try { - $contactFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.contact_form_handler'); - $result = $contactFormHandler->handleFor((int) $contactId, $contactForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_contacts_index'); - } - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages($exception)) - ); - } - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/Contact/Contacts/edit.html.twig', [ - 'contactForm' => $contactForm->createView(), - ]); - } - - /** - * Delete a contact. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_contacts_index", - * message="You do not have permission to delete this." - * ) - * - * @DemoRestricted(redirectRoute="admin_contacts_index") - * - * @param int $contactId - * - * @return RedirectResponse - */ - public function deleteAction($contactId) - { - $contactDeleter = $this->get('prestashop.adapter.contact.deleter'); - - if ($errors = $contactDeleter->delete([$contactId])) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_contacts_index'); - } - - /** - * Bulk delete contacts. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_contacts_index", - * message="You do not have permission to delete this." - * ) - * - * @DemoRestricted(redirectRoute="admin_contacts_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request) - { - $contactIds = $request->request->get('contact_bulk'); - $contactDeleter = $this->get('prestashop.adapter.contact.deleter'); - - if ($errors = $contactDeleter->delete($contactIds)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_contacts_index'); - } - - /** - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e) - { - return [ - ContactNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - ContactConstraintException::class => [ - ContactConstraintException::INVALID_SHOP_ASSOCIATION => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Shop association', 'Admin.Global') - ), - ] - ), - ContactConstraintException::INVALID_TITLE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Title', 'Admin.Global') - ), - ] - ), - ContactConstraintException::MISSING_TITLE_FOR_DEFAULT_LANGUAGE => $this->trans( - 'The field %field_name% is required at least in your default language.', - 'Admin.Notifications.Error', - [ - '%field_name%' => $this->trans('Title', 'Admin.Global'), - ] - ), - ContactConstraintException::INVALID_DESCRIPTION => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Description', 'Admin.Global') - ), - ] - ), - ], - DomainConstraintException::class => [ - DomainConstraintException::INVALID_EMAIL => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Email address', 'Admin.Global') - ), - ] - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/CustomerPreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/CustomerPreferencesController.php deleted file mode 100644 index 2c90db1b..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/CustomerPreferencesController.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Controller responsible of "Configure > Shop Parameters > Customer Settings" page. - */ -class CustomerPreferencesController extends FrameworkBundleAdminController -{ - /** - * Show customer preferences page. - * - * @Template("@PrestaShop/Admin/Configure/ShopParameters/customer_preferences.html.twig") - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return array Template parameters - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $form = $this->get('prestashop.admin.customer_preferences.form_handler')->getForm(); - - return [ - 'layoutTitle' => $this->trans('Customers', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'form' => $form->createView(), - ]; - } - - /** - * Process the Customer Preferences configuration form. - * - * @AdminSecurity("is_granted(['update', 'create','delete'], request.get('_legacy_controller'))", message="You do not have permission to update this.", redirectRoute="admin_customer_preferences") - * @DemoRestricted(redirectRoute="admin_customer_preferences") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.customer_preferences.form_handler'); - - $form = $formHandler->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - if ($errors = $formHandler->save($data)) { - $this->flashErrors($errors); - - return $this->redirectToRoute('admin_customer_preferences'); - } - - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } - - return $this->redirectToRoute('admin_customer_preferences'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php deleted file mode 100644 index 7754fc12..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MaintenanceController.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Shop Parameters > General > Maintenance" page. - */ -class MaintenanceController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'AdminMaintenance'; - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param FormInterface $form - * - * @return Response - */ - public function indexAction(Request $request, FormInterface $form = null) - { - if (null === $form) { - $form = $this->get('prestashop.adapter.maintenance.form_handler')->getForm(); - } - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/maintenance.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Maintenance', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminMaintenance'), - 'requireFilterStatus' => false, - 'form' => $form->createView(), - 'currentIp' => $request->getClientIp(), - ]); - } - - /** - * @param Request $request - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_maintenance") - * @DemoRestricted(redirectRoute="admin_maintenance") - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $redirectResponse = $this->redirectToRoute('admin_maintenance'); - - $this->dispatchHook('actionAdminMaintenanceControllerPostProcessBefore', ['controller' => $this]); - $form = $this->get('prestashop.adapter.maintenance.form_handler')->getForm(); - $form->handleRequest($request); - - if (!$form->isSubmitted()) { - return $redirectResponse; - } - - $data = $form->getData(); - $saveErrors = $this->get('prestashop.adapter.maintenance.form_handler')->save($data); - - if (0 === count($saveErrors)) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $redirectResponse; - } - - $this->flashErrors($saveErrors); - - return $redirectResponse; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php deleted file mode 100644 index 534d89c7..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/MetaController.php +++ /dev/null @@ -1,477 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Exception\MetaNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\MetaFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class MetaController is responsible for page display and all actions used in Configure -> Shop parameters -> - * Traffic & Seo -> Seo & Urls tab. - */ -class MetaController extends FrameworkBundleAdminController -{ - /** - * Shows index Meta page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param MetaFilters $filters - * - * @return Response - */ - public function indexAction(MetaFilters $filters, Request $request) - { - $seoUrlsGridFactory = $this->get('prestashop.core.grid.factory.meta'); - - $context = $this->get('prestashop.adapter.shop.context'); - - $isShopContext = $context->isShopContext(); - $isShopFeatureActive = $this->get('prestashop.adapter.multistore_feature')->isActive(); - - $isGridDisplayed = !($isShopFeatureActive && !$isShopContext); - - $presentedGrid = null; - if ($isGridDisplayed) { - $grid = $seoUrlsGridFactory->getGrid($filters); - - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - $presentedGrid = $gridPresenter->present($grid); - } - - $metaForm = $this->get('prestashop.admin.meta_settings.form_handler')->getForm(); - - $tools = $this->get('prestashop.adapter.tools'); - - $urlFileChecker = $this->get('prestashop.core.util.url.url_file_checker'); - - $hostingInformation = $this->get('prestashop.adapter.hosting_information'); - - $defaultRoutesProvider = $this->get('prestashop.adapter.data_provider.default_route'); - - $helperBlockLinkProvider = $this->get('prestashop.core.util.helper_card.documentation_link_provider'); - $metaDataProvider = $this->get('prestashop.adapter.meta.data_provider'); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed((int) $this->getContext()->employee->id, ShowcaseCard::SEO_URLS_CARD) - ); - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/index.html.twig', [ - 'layoutHeaderToolbarBtn' => [ - 'add' => [ - 'href' => $this->generateUrl('admin_metas_create'), - 'desc' => $this->trans('Add a new page', 'Admin.Shopparameters.Feature'), - 'icon' => 'add_circle_outline', - ], - ], - 'grid' => $presentedGrid, - 'metaForm' => $metaForm->createView(), - 'robotsForm' => $this->createFormBuilder()->getForm()->createView(), - 'routeKeywords' => $defaultRoutesProvider->getKeywords(), - 'isGridDisplayed' => $isGridDisplayed, - 'isModRewriteActive' => $tools->isModRewriteActive(), - 'isShopContext' => $isShopContext, - 'isHtaccessFileValid' => $urlFileChecker->isHtaccessFileWritable(), - 'isRobotsTextFileValid' => $urlFileChecker->isRobotsFileWritable(), - 'isShopFeatureActive' => $isShopFeatureActive, - 'isHostMode' => $hostingInformation->isHostMode(), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'helperDocLink' => $helperBlockLinkProvider->getLink('meta'), - 'indexPageId' => $metaDataProvider->getIdByPage('index'), - 'metaShowcaseCardName' => ShowcaseCard::SEO_URLS_CARD, - 'showcaseCardIsClosed' => $showcaseCardIsClosed, - ] - ); - } - - /** - * Used for applying filtering actions. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.meta'); - $definitionFactory = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $searchParametersForm = $gridFilterFormFactory->create($definitionFactory); - $searchParametersForm->handleRequest($request); - - $filters = []; - if ($searchParametersForm->isSubmitted()) { - $filters = $searchParametersForm->getData(); - } - - return $this->redirectToRoute('admin_metas_index', ['filters' => $filters]); - } - - /** - * Points to the form where new record of meta list can be created. - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))", message="You do not have permission to add this.") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $data = []; - $metaForm = $this->getMetaFormBuilder()->getForm($data); - $metaForm->handleRequest($request); - - try { - $result = $this->getMetaFormHandler()->handle($metaForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_metas_index'); - } - } catch (Exception $exception) { - $this->addFlash('error', $this->handleException($exception)); - } - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/create.html.twig', [ - 'meta_form' => $metaForm->createView(), - ] - ); - } - - /** - * Redirects to page where list record can be edited. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * - * @param int $metaId - * @param Request $request - * - * @return Response - */ - public function editAction($metaId, Request $request) - { - try { - $metaForm = $this->getMetaFormBuilder()->getFormFor($metaId); - $metaForm->handleRequest($request); - - $result = $this->getMetaFormHandler()->handleFor($metaId, $metaForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_metas_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->handleException($e)); - - return $this->redirectToRoute('admin_metas_index'); - } - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/edit.html.twig', [ - 'meta_form' => $metaForm->createView(), - ] - ); - } - - /** - * Removes single element from meta list. - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @param int $metaId - * - * @return RedirectResponse - */ - public function deleteAction($metaId) - { - $metaEraser = $this->get('prestashop.adapter.meta.meta_eraser'); - $errors = $metaEraser->erase([$metaId]); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_metas_index'); - } - - /** - * Removes multiple records from meta list. - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", message="You do not have permission to delete this.") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request) - { - $metaToDelete = $request->request->get('meta_bulk'); - - $metaEraser = $this->get('prestashop.adapter.meta.meta_eraser'); - $errors = $metaEraser->erase($metaToDelete); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } - - return $this->redirectToRoute('admin_metas_index'); - } - - /** - * Submits settings forms. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.meta_settings.form_handler'); - $configurationForm = $formHandler->getForm(); - - $configurationForm->handleRequest($request); - - if ($configurationForm->isSubmitted()) { - $errors = $formHandler->save($configurationForm->getData()); - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans('The settings have been successfully updated.', 'Admin.Notifications.Success') - ); - } - } - - return $this->redirectToRoute('admin_metas_index'); - } - - /** - * Generates robots.txt file for Front Office. - * - * @AdminSecurity("is_granted(['create', 'update', 'delete'], request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @return RedirectResponse - */ - public function generateRobotsFileAction() - { - $robotsTextFileGenerator = $this->get('prestashop.adapter.file.robots_text_file_generator'); - - $rootDir = $this->get('prestashop.adapter.legacy.configuration')->get('_PS_ROOT_DIR_'); - - if (!$robotsTextFileGenerator->generateFile()) { - $this->addFlash( - 'error', - $this->trans( - 'Cannot write into file: %filename%. Please check write permissions.', - 'Admin.Notifications.Error', - [ - '%filename%' => $rootDir . '/robots.txt', - ] - ) - ); - - return $this->redirectToRoute('admin_metas_index'); - } - - $this->addFlash( - 'success', - $this->trans('Successful update.', 'Admin.Notifications.Success') - ); - - return $this->redirectToRoute('admin_metas_index'); - } - - /** - * Gets form builder. - * - * @return FormBuilderInterface - */ - private function getMetaFormBuilder() - { - return $this->get('prestashop.core.form.builder.meta_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getMetaFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.meta_form_handler'); - } - - /** - * Handles exception by its type and status code or by its type only and returns error message. - * - * @param Exception $exception - * - * @return string - * - * @todo use FrameworkAdminBundleController::getErrorMessageForException() instead - */ - private function handleException(Exception $exception) - { - if (0 !== $exception->getCode()) { - return $this->getExceptionByClassAndErrorCode($exception); - } - - return $this->getExceptionByType($exception); - } - - /** - * Gets exception by class and error code. - * - * @param Exception $exception - * - * @return string - */ - private function getExceptionByClassAndErrorCode(Exception $exception) - { - $exceptionDictionary = [ - MetaConstraintException::class => [ - MetaConstraintException::INVALID_URL_REWRITE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Rewritten URL', 'Admin.Shopparameters.Feature') - ), - ] - ), - MetaConstraintException::INVALID_PAGE_NAME => $this->trans( - 'The %s field is required.', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Page name', 'Admin.Shopparameters.Feature') - ), - ] - ), - MetaConstraintException::INVALID_PAGE_TITLE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Page title', 'Admin.Shopparameters.Feature') - ), - ] - ), - MetaConstraintException::INVALID_META_DESCRIPTION => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Meta description', 'Admin.Global') - ), - ] - ), - MetaConstraintException::INVALID_META_KEYWORDS => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf( - '"%s"', - $this->trans('Meta keywords', 'Admin.Global') - ), - ] - ), - ], - ]; - - $exceptionClass = get_class($exception); - $exceptionCode = $exception->getCode(); - if (isset($exceptionDictionary[$exceptionClass][$exceptionCode])) { - return $exceptionDictionary[$exceptionClass][$exceptionCode]; - } - - return $this->getFallbackErrorMessage($exceptionClass, $exceptionCode); - } - - /** - * Gets exception by class type. - * - * @param Exception $exception - * - * @return string - */ - private function getExceptionByType(Exception $exception) - { - $exceptionDictionary = [ - MetaNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - ]; - - $exceptionClass = get_class($exception); - if (isset($exceptionDictionary[$exceptionClass])) { - return $exceptionDictionary[$exceptionClass]; - } - - return $this->getFallbackErrorMessage($exceptionClass, $exception->getCode()); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php deleted file mode 100644 index 84c44846..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/OrderPreferencesController.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Controller responsible of "Configure > Shop Parameters > Order Settings" page. - */ -class OrderPreferencesController extends FrameworkBundleAdminController -{ - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $form = $this->get('prestashop.admin.order_preferences.form_handler')->getForm(); - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/OrderPreferences/order_preferences.html.twig', [ - 'layoutTitle' => $this->trans('Order settings', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'form' => $form->createView(), - 'isMultishippingEnabled' => $this->configuration->getBoolean('PS_ALLOW_MULTISHIPPING'), - 'isAtcpShipWrapEnabled' => $this->configuration->getBoolean('PS_ATCP_SHIPWRAP'), - ]); - } - - /** - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_order_preferences") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.order_preferences.form_handler'); - - $form = $formHandler->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - if ($errors = $formHandler->save($form->getData())) { - $this->flashErrors($errors); - } else { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } - } - - return $this->redirectToRoute('admin_order_preferences'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php deleted file mode 100644 index 4e22e9f3..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/PreferencesController.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use Doctrine\ORM\EntityManager; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Entity\Repository\TabRepository; -use PrestaShopBundle\Entity\Tab; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Shop Parameters > General" page. - */ -class PreferencesController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'AdminPreferences'; - - /** - * @param Request $request - * @param FormInterface|null $form - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return Response - * - * @throws \LogicException - */ - public function indexAction(Request $request, FormInterface $form = null) - { - if (null === $form) { - $form = $this->get('prestashop.adapter.preferences.form_handler')->getForm(); - } - - /** @var Tools $toolsAdapter */ - $toolsAdapter = $this->get('prestashop.adapter.tools'); - - // SSL URI is used for the merchant to check if he has SSL enabled - $sslUri = 'https://' . $toolsAdapter->getShopDomainSsl() . $request->getRequestUri(); - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/preferences.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->get('translator')->trans('Preferences', [], 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminPreferences'), - 'requireFilterStatus' => false, - 'form' => $form->createView(), - 'isSslEnabled' => $this->configuration->get('PS_SSL_ENABLED'), - 'sslUri' => $sslUri, - ]); - } - - /** - * @param Request $request - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_preferences") - * - * @DemoRestricted(redirectRoute="admin_preferences") - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - * - * @throws \LogicException - */ - public function processFormAction(Request $request) - { - $this->dispatchHook('actionAdminPreferencesControllerPostProcessBefore', ['controller' => $this]); - - /** @var FormInterface $form */ - $form = $this->get('prestashop.adapter.preferences.form_handler')->getForm(); - $form->handleRequest($request); - - if (!$form->isSubmitted()) { - return $this->redirectToRoute('admin_preferences'); - } - - $data = $form->getData(); - $saveErrors = $this->get('prestashop.adapter.preferences.form_handler')->save($data); - - if (0 === count($saveErrors)) { - /** @var EntityManager $em */ - $em = $this->get('doctrine.orm.entity_manager'); - - /** @var TabRepository $tabRepository */ - $tabRepository = $em->getRepository(Tab::class); - - $tabRepository->changeStatusByClassName( - 'AdminShopGroup', - (bool) $this->configuration->get('PS_MULTISHOP_FEATURE_ACTIVE') - ); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_preferences'); - } - - $this->flashErrors($saveErrors); - - return $this->redirectToRoute('admin_preferences'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php deleted file mode 100644 index 66d1afca..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShopParameters/ProductPreferencesController.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure\ShopParameters; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Configure > Shop Parameters > Product Settings" page. - */ -class ProductPreferencesController extends FrameworkBundleAdminController -{ - /** - * @param Request $request - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $form = $this->get('prestashop.admin.product_preferences.form_handler')->getForm(); - - return $this->render('@PrestaShop/Admin/Configure/ShopParameters/product_preferences.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Product Settings', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkAction' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'requireFilterStatus' => false, - 'form' => $form->createView(), - ]); - } - - /** - * Process product preferences form. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_product_preferences" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.product_preferences.form_handler'); - - $form = $formHandler->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - $errors = $formHandler->save($data); - - if (0 === count($errors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } else { - $this->flashErrors($errors); - } - } - - return $this->redirectToRoute('admin_product_preferences'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Configure/ShowcaseCardController.php b/src/PrestaShopBundle/Controller/Admin/Configure/ShowcaseCardController.php deleted file mode 100644 index b19256d6..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Configure/ShowcaseCardController.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Configure; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Command\CloseShowcaseCardCommand; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Exception\InvalidShowcaseCardNameException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * @todo Move this to API - */ -class ShowcaseCardController extends FrameworkBundleAdminController -{ - /** - * Saves the user preference of closing the showcase card. - * - * This action should be performed via POST, and expects two parameters: - * - int $close=1 - * - string $name Name of the showcase card to close - * - * @see ShowcaseCard - * - * @AdminSecurity("is_granted(['create', 'update'], 'CONFIGURE')") - * @DemoRestricted(redirectRoute="admin_metas_index") - * - * @return JsonResponse - */ - public function closeShowcaseCardAction(Request $request) - { - // check prerequisites - if (!$request->isMethod('post') || !$request->request->get('close')) { - return $this->json( - [ - 'success' => false, - 'message' => '', - ], - Response::HTTP_BAD_REQUEST - ); - } - - try { - $employeeId = $this->getContext()->employee->id; - $closeShowcaseCard = new CloseShowcaseCardCommand($employeeId, $request->request->get('name')); - $this->getCommandBus()->handle($closeShowcaseCard); - - return $this->json( - [ - 'success' => true, - 'message' => '', - ] - ); - } catch (\Exception $e) { - return $this->json( - [ - 'success' => false, - 'message' => $e->getMessage(), - ], - ($e instanceof InvalidShowcaseCardNameException) ? Response::HTTP_BAD_REQUEST : Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/ErrorController.php b/src/PrestaShopBundle/Controller/Admin/ErrorController.php deleted file mode 100644 index f9593d15..00000000 --- a/src/PrestaShopBundle/Controller/Admin/ErrorController.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShop\PrestaShop\Core\Domain\Configuration\Command\SwitchDebugModeCommand; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Manages Error pages (e.g. 500) - */ -class ErrorController extends FrameworkBundleAdminController -{ - /** - * Enables debug mode from error page (500 for example) - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], 'AdminPerformance')") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function enableDebugModeAction(Request $request) - { - $this->getCommandBus()->handle(new SwitchDebugModeCommand(true)); - - return $this->redirect( - $request->request->get('_redirect_url') - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/FeatureController.php b/src/PrestaShopBundle/Controller/Admin/FeatureController.php deleted file mode 100644 index ed476994..00000000 --- a/src/PrestaShopBundle/Controller/Admin/FeatureController.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Symfony\Component\HttpFoundation\JsonResponse; - -/** - * Admin controller for the Feature pages. - */ -class FeatureController extends FrameworkBundleAdminController -{ - /** - * Get all values for a given feature. - * - * @param int $idFeature The feature Id - * - * @return JsonResponse features list - */ - public function getFeatureValuesAction($idFeature) - { - $response = new JsonResponse(); - $locales = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - $data = []; - - if ($idFeature == 0) { - return $response; - } - - $featuresValues = $this->get('prestashop.adapter.data_provider.feature')->getFeatureValuesWithLang($locales[0]['id_lang'], $idFeature); - - if (count($featuresValues) !== 0) { - $data['0'] = [ - 'id' => 0, - 'value' => $this->trans('Choose a value', 'Admin.Catalog.Feature'), - ]; - } - - foreach ($featuresValues as $featureValue) { - if (isset($featureValue['custom']) && $featureValue['custom'] == 1) { - continue; - } - $data[] = [ - 'id' => $featureValue['id_feature_value'], - 'value' => $featureValue['value'], - ]; - } - - $response->setData($data); - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php b/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php deleted file mode 100644 index de28b13d..00000000 --- a/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php +++ /dev/null @@ -1,529 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Exception; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Shop\Context; -use PrestaShop\PrestaShop\Core\ConfigurationInterface; -use PrestaShop\PrestaShop\Core\Grid\GridInterface; -use PrestaShop\PrestaShop\Core\Localization\Locale; -use PrestaShop\PrestaShop\Core\Localization\Locale\Repository as LocaleRepository; -use PrestaShop\PrestaShop\Core\Module\Exception\ModuleErrorInterface; -use PrestaShopBundle\Security\Voter\PageVoter; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\Form\Form; -use Symfony\Component\Form\FormError; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Response; - -/** - * Extends The Symfony framework bundle controller to add common functions for PrestaShop needs. - */ -class FrameworkBundleAdminController extends Controller -{ - const PRESTASHOP_CORE_CONTROLLERS_TAG = 'prestashop.core.controllers'; - - /** - * @var ConfigurationInterface|Configuration - */ - protected $configuration; - - /** - * @var string|null - */ - protected $layoutTitle; - - /** - * Constructor. - */ - public function __construct() - { - $this->configuration = new Configuration(); - } - - /** - * @Template - * - * @return array Template vars - */ - public function overviewAction() - { - return [ - 'is_shop_context' => (new Context())->isShopContext(), - 'layoutTitle' => empty($this->layoutTitle) ? '' : $this->trans($this->layoutTitle, 'Admin.Navigation.Menu'), - ]; - } - - /** - * Returns form errors for JS implementation. - * - * Parse all errors mapped by id html field - * - * @param Form $form The form - * - * @return array[array[string]] Errors - * - * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException - */ - public function getFormErrorsForJS(Form $form) - { - $errors = []; - - if (empty($form)) { - return $errors; - } - - $translator = $this->get('translator'); - - foreach ($form->getErrors(true) as $error) { - if (!$error->getCause()) { - $formId = 'bubbling_errors'; - } else { - $formId = str_replace( - ['.', 'children[', ']', '_data'], - ['_', '', '', ''], - $error->getCause()->getPropertyPath() - ); - } - - if ($error->getMessagePluralization()) { - $errors[$formId][] = $translator->transChoice( - $error->getMessageTemplate(), - $error->getMessagePluralization(), - $error->getMessageParameters(), - 'form_error' - ); - } else { - $errors[$formId][] = $translator->trans( - $error->getMessageTemplate(), - $error->getMessageParameters(), - 'form_error' - ); - } - } - - return $errors; - } - - /** - * Creates a HookEvent, sets its parameters, and dispatches it. - * - * Wrapper to: @see HookDispatcher::dispatchWithParameters() - * - * @param string $hookName The hook name - * @param array $parameters The hook parameters - */ - protected function dispatchHook($hookName, array $parameters) - { - $this->get('prestashop.core.hook.dispatcher')->dispatchWithParameters($hookName, $parameters); - } - - /** - * Creates a RenderingHookEvent, sets its parameters, and dispatches it. Returns the event with the response(s). - * - * Wrapper to: @see HookDispatcher::renderForParameters() - * - * @param string $hookName The hook name - * @param array $parameters The hook parameters - * - * @return array The responses of hooks - * - * @throws Exception - */ - protected function renderHook($hookName, array $parameters) - { - return $this->get('prestashop.core.hook.dispatcher')->renderForParameters($hookName, $parameters)->getContent(); - } - - /** - * Generates a documentation link. - * - * @param string $section Legacy controller name - * @param bool|string $title Help title - * - * @return string - */ - protected function generateSidebarLink($section, $title = false) - { - $version = $this->get('prestashop.core.foundation.version')->getVersion(); - $legacyContext = $this->get('prestashop.adapter.legacy.context'); - - if (empty($title)) { - $title = $this->trans('Help', 'Admin.Global'); - } - - $docLink = urlencode('https://help.prestashop.com/' . $legacyContext->getEmployeeLanguageIso() . '/doc/' - . $section . '?version=' . $version . '&country=' . $legacyContext->getEmployeeLanguageIso()); - - return $this->generateUrl('admin_common_sidebar', [ - 'url' => $docLink, - 'title' => $title, - ]); - } - - /** - * Get the old but still useful context. - * - * @return \Context - */ - protected function getContext() - { - return $this->get('prestashop.adapter.legacy.context')->getContext(); - } - - /** - * Get the locale based on the context - * - * @return Locale - */ - protected function getContextLocale(): Locale - { - $locale = $this->getContext()->getCurrentLocale(); - if (null !== $locale) { - return $locale; - } - - /** @var LocaleRepository $localeRepository */ - $localeRepository = $this->get('prestashop.core.localization.locale.repository'); - $locale = $localeRepository->getLocale( - $this->getContext()->language->getLocale() - ); - - return $locale; - } - - /** - * @param $lang - * - * @return mixed - */ - protected function langToLocale($lang) - { - return $this->get('prestashop.service.translation')->langToLocale($lang); - } - - /** - * @return bool - */ - protected function isDemoModeEnabled() - { - return $this->get('prestashop.adapter.legacy.configuration')->get('_PS_MODE_DEMO_'); - } - - /** - * @return string - */ - protected function getDemoModeErrorMessage() - { - return $this->trans('This functionality has been disabled.', 'Admin.Notifications.Error'); - } - - /** - * Checks if the attributes are granted against the current authentication token and optionally supplied object. - * - * @param string $controller name of the controller to valide access - * - * @return int - * - * @throws \LogicException - */ - protected function authorizationLevel($controller) - { - if ($this->isGranted(PageVoter::DELETE, $controller . '_')) { - return PageVoter::LEVEL_DELETE; - } - - if ($this->isGranted(PageVoter::CREATE, $controller . '_')) { - return PageVoter::LEVEL_CREATE; - } - - if ($this->isGranted(PageVoter::UPDATE, $controller . '_')) { - return PageVoter::LEVEL_UPDATE; - } - - if ($this->isGranted(PageVoter::READ, $controller . '_')) { - return PageVoter::LEVEL_READ; - } - - return 0; - } - - /** - * Get the translated chain from key. - * - * @param string $key the key to be translated - * @param string $domain the domain to be selected - * @param array $parameters Optional, pass parameters if needed (uncommon) - * - * @return string - */ - protected function trans($key, $domain, array $parameters = []) - { - return $this->get('translator')->trans($key, $parameters, $domain); - } - - /** - * Return errors as flash error messages. - * - * @param array $errorMessages - * - * @throws \LogicException - */ - protected function flashErrors(array $errorMessages) - { - foreach ($errorMessages as $error) { - $message = is_array($error) ? $this->trans($error['key'], $error['domain'], $error['parameters']) : $error; - $this->addFlash('error', $message); - } - } - - /** - * Redirect employee to default page. - * - * @return RedirectResponse - */ - protected function redirectToDefaultPage() - { - $legacyContext = $this->get('prestashop.adapter.legacy.context'); - $defaultTab = $legacyContext->getDefaultEmployeeTab(); - - return $this->redirect($legacyContext->getAdminLink($defaultTab)); - } - - /** - * Check if the connected user is granted to actions on a specific object. - * - * @param $action - * @param $object - * @param string $suffix - * - * @return bool - * - * @throws \LogicException - */ - protected function actionIsAllowed($action, $object = '', $suffix = '') - { - return ( - $action === 'delete' . $suffix && $this->isGranted(PageVoter::DELETE, $object) - ) || ( - ($action === 'activate' . $suffix || $action === 'deactivate' . $suffix) && - $this->isGranted(PageVoter::UPDATE, $object) - ) || ( - ($action === 'duplicate' . $suffix) && - ($this->isGranted(PageVoter::UPDATE, $object) || $this->isGranted(PageVoter::CREATE, $object)) - ); - } - - /** - * Display a message about permissions failure according to an action. - * - * @param $action - * @param string $suffix - * - * @return string - * - * @throws Exception - */ - protected function getForbiddenActionMessage($action, $suffix = '') - { - if ($action === 'delete' . $suffix) { - return $this->trans('You do not have permission to delete this.', 'Admin.Notifications.Error'); - } - - if ($action === 'deactivate' . $suffix || $action === 'activate' . $suffix) { - return $this->trans('You do not have permission to edit this.', 'Admin.Notifications.Error'); - } - - if ($action === 'duplicate' . $suffix) { - return $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'); - } - - throw new Exception(sprintf('Invalid action (%s)', $action . $suffix)); - } - - /** - * Get fallback error message when something unexpected happens. - * - * @param string $type - * @param string $code - * @param string $message - * - * @return string - */ - protected function getFallbackErrorMessage($type, $code, $message = '') - { - $isDebug = $this->get('kernel')->isDebug(); - if ($isDebug && !empty($message)) { - return $this->trans( - 'An unexpected error occurred. [%type% code %code%]: %message%', - 'Admin.Notifications.Error', - [ - '%type%' => $type, - '%code%' => $code, - '%message%' => $message, - ] - ); - } - - return $this->trans( - 'An unexpected error occurred. [%type% code %code%]', - 'Admin.Notifications.Error', - [ - '%type%' => $type, - '%code%' => $code, - ] - ); - } - - /** - * Get Admin URI from PrestaShop 1.6 Back Office. - * - * @param string $controller the old Controller name - * @param bool $withToken whether we add token or not - * @param array $params url parameters - * - * @return string the page URI (with token) - */ - protected function getAdminLink($controller, array $params, $withToken = true) - { - return $this->get('prestashop.adapter.legacy.context')->getAdminLink($controller, $withToken, $params); - } - - /** - * Present provided grid. - * - * @param GridInterface $grid - * - * @return array - */ - protected function presentGrid(GridInterface $grid) - { - return $this->get('prestashop.core.grid.presenter.grid_presenter')->present($grid); - } - - /** - * Get commands bus to execute commands. - * - * @return \PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface - */ - protected function getCommandBus() - { - return $this->get('prestashop.core.command_bus'); - } - - /** - * Get query bus to execute queries. - * - * @return \PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface - */ - protected function getQueryBus() - { - return $this->get('prestashop.core.query_bus'); - } - - /** - * @param array $errors - * @param int $httpStatusCode - * - * @return JsonResponse - */ - protected function returnErrorJsonResponse(array $errors, $httpStatusCode) - { - $response = new JsonResponse(); - $response->setStatusCode($httpStatusCode); - $response->setData($errors); - - return $response; - } - - /** - * @return int - */ - protected function getContextLangId() - { - return $this->getContext()->language->id; - } - - /** - * @return int - */ - protected function getContextShopId() - { - return $this->getContext()->shop->id; - } - - /** - * @param FormInterface $form - */ - protected function addFlashFormErrors(FormInterface $form) - { - /** @var FormError $formError */ - foreach ($form->getErrors(true) as $formError) { - $this->addFlash('error', $formError->getMessage()); - } - } - - /** - * Get error by exception from given messages - * - * @param Exception $e - * @param array $messages - * - * @return string - */ - protected function getErrorMessageForException(Exception $e, array $messages) - { - if ($e instanceof ModuleErrorInterface) { - return $e->getMessage(); - } - - $exceptionType = get_class($e); - $exceptionCode = $e->getCode(); - - if (isset($messages[$exceptionType])) { - $message = $messages[$exceptionType]; - - if (is_string($message)) { - return $message; - } - - if (is_array($message) && isset($message[$exceptionCode])) { - return $message[$exceptionCode]; - } - } - - return $this->getFallbackErrorMessage( - $exceptionType, - $exceptionCode, - $e->getMessage() - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Design/CmsPageController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Design/CmsPageController.php deleted file mode 100644 index dd0dcd2a..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Design/CmsPageController.php +++ /dev/null @@ -1,1201 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Design; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDeleteCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDisableCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkEnableCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\DeleteCmsPageCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\ToggleCmsPageStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotDeleteCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotDisableCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotEnableCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CannotToggleCmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Exception\CmsPageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsPageForEditing; -use PrestaShop\PrestaShop\Core\Domain\CmsPage\QueryResult\EditableCmsPage; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDeleteCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDisableCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkEnableCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\DeleteCmsPageCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\ToggleCmsPageCategoryStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotDeleteCmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CannotToggleCmsPageCategoryStatusException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Exception\CmsPageCategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageParentCategoryIdForRedirection; -use PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\ValueObject\CmsPageCategoryId; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageCategoryDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionDataException; -use PrestaShop\PrestaShop\Core\Grid\Position\Exception\PositionUpdateException; -use PrestaShop\PrestaShop\Core\Search\Filters\CmsPageCategoryFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\CmsPageFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class CmsPageController is responsible for handling the logic in "Improve -> Design -> pages" page. - */ -class CmsPageController extends FrameworkBundleAdminController -{ - /** - * Responsible for displaying page content. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param CmsPageCategoryFilters $categoryFilters - * @param CmsPageFilters $cmsFilters - * @param Request $request - * - * @return Response - */ - public function indexAction(CmsPageCategoryFilters $categoryFilters, CmsPageFilters $cmsFilters, Request $request) - { - $cmsCategoryParentId = (int) $categoryFilters->getFilters()['id_cms_category_parent']; - $viewData = []; - - try { - $viewData = $this - ->get('prestashop.core.cms_page.data_provider.cms_page_view') - ->getView($cmsCategoryParentId) - ; - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - - if ($exception instanceof CmsPageCategoryNotFoundException) { - return $this->redirectToRoute('admin_cms_pages_index'); - } - } - - $cmsCategoryGridFactory = $this->get('prestashop.core.grid.factory.cms_page_category'); - $cmsCategoryGrid = $cmsCategoryGridFactory->getGrid($categoryFilters); - - $cmsGridFactory = $this->get('prestashop.core.grid.factory.cms_page'); - $cmsGrid = $cmsGridFactory->getGrid($cmsFilters); - - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed( - (int) $this->getContext()->employee->id, - ShowcaseCard::CMS_PAGES_CARD - ) - ); - - $helperBlockLinkProvider = $this->get('prestashop.core.util.helper_card.documentation_link_provider'); - - return $this->render( - '@PrestaShop/Admin/Improve/Design/Cms/index.html.twig', - [ - 'cmsCategoryGrid' => $gridPresenter->present($cmsCategoryGrid), - 'cmsGrid' => $gridPresenter->present($cmsGrid), - 'cmsPageView' => $viewData, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'helperDocLink' => $helperBlockLinkProvider->getLink('cms_pages'), - 'cmsPageShowcaseCardName' => ShowcaseCard::CMS_PAGES_CARD, - 'showcaseCardIsClosed' => $showcaseCardIsClosed, - ] - ); - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $gridDefinitionFactory = 'prestashop.core.grid.definition.factory.cms_page_category'; - $filterId = CmsPageCategoryDefinitionFactory::GRID_ID; - if ($request->request->has(CmsPageDefinitionFactory::GRID_ID)) { - $gridDefinitionFactory = 'prestashop.core.grid.definition.factory.cms_page'; - $filterId = CmsPageDefinitionFactory::GRID_ID; - } - - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get($gridDefinitionFactory), - $request, - $filterId, - 'admin_cms_pages_index', - [ - 'id_cms_category', - ] - ); - } - - /** - * Creates cms page - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to add this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $formBuilder = $this->getCmsPageFormBuilder(); - $categoryParentId = $request->query->get('id_cms_category'); - $formData = []; - if ($categoryParentId) { - $formData['page_category_id'] = $categoryParentId; - } - $form = $formBuilder->getForm($formData, [ - 'cms_preview_url' => $this->get('prestashop.adapter.shop.url.cms_provider')->getUrl(0, '{friendy-url}'), - ]); - $form->handleRequest($request); - - try { - $result = $this->getCmsPageFormHandler()->handle($form); - $cmsPageId = $result->getIdentifiableObjectId(); - - if (null !== $cmsPageId) { - $this->addFlash( - 'success', - $this->trans('Successful creation.', 'Admin.Notifications.Success') - ); - if (!$request->request->has('save-and-preview')) { - return $this->redirectToParentIndexPageByCmsPageId($cmsPageId); - } - - return $this->redirectToRoute('admin_cms_pages_edit', [ - 'cmsPageId' => $cmsPageId, - 'open_preview' => 1, - ]); - } - } catch (Exception $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages()) - ); - } - - return $this->render( - 'PrestaShopBundle:Admin/Improve/Design/Cms:add.html.twig', - [ - 'cmsPageForm' => $form->createView(), - 'cmsCategoryParentId' => $categoryParentId, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ] - ); - } - - /** - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * - * @param Request $request - * @param $cmsPageId - * - * @return Response - */ - public function editAction(Request $request, $cmsPageId) - { - $cmsPageId = (int) $cmsPageId; - - try { - /** @var EditableCmsPage $editableCmsPage */ - $editableCmsPage = $this->getQueryBus()->handle(new GetCmsPageForEditing($cmsPageId)); - $previewUrl = $editableCmsPage->getPreviewUrl(); - - $form = $this->getCmsPageFormBuilder()->getFormFor($cmsPageId, [], [ - 'action' => $this->generateUrl('admin_cms_pages_edit', [ - 'cmsPageId' => $cmsPageId, - ]), - 'cms_preview_url' => $this->get('prestashop.adapter.shop.url.cms_provider') - ->getUrl($cmsPageId, '{friendy-url}'), - ]); - $form->handleRequest($request); - } catch (Exception $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages()) - ); - - return $this->redirectToRoute('admin_cms_pages_index'); - } - - try { - $result = $this->getCmsPageFormHandler()->handleFor($cmsPageId, $form); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash( - 'success', - $this->trans('Successful update.', 'Admin.Notifications.Success') - ); - - if ($request->request->has('save-and-preview')) { - return $this->redirectToRoute('admin_cms_pages_edit', [ - 'cmsPageId' => $cmsPageId, - 'open_preview' => 1, - ]); - } - - return $this->redirectToParentIndexPageByCmsPageId($cmsPageId); - } - } catch (Exception $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages()) - ); - } - - return $this->render( - '@PrestaShop/Admin/Improve/Design/Cms/edit.html.twig', - [ - 'cmsPageForm' => $form->createView(), - 'cmsCategoryParentId' => $request->get('id_cms_category'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'previewUrl' => $previewUrl, - ] - ); - } - - /** - * Displays cms category page form and handles create new cms page category logic. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to add this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createCmsCategoryAction(Request $request) - { - $cmsPageCategoryFormBuilder = $this->getCmsPageCategoryFormBuilder(); - $cmsPageCategoryForm = $cmsPageCategoryFormBuilder->getForm(); - - $cmsPageCategoryForm->handleRequest($request); - - try { - $result = $this->getCmsPageCategoryFormHandler()->handle($cmsPageCategoryForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash( - 'success', - $this->trans('Successful creation.', 'Admin.Notifications.Success') - ); - - return $this->redirectToIndexPageById($result->getIdentifiableObjectId()); - } - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->render( - '@PrestaShop/Admin/Improve/Design/Cms/create_category.html.twig', - [ - 'cmsPageCategoryForm' => $cmsPageCategoryForm->createView(), - ] - ); - } - - /** - * Displays cms category page form and handles update cms page category logic. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * - * @param int $cmsCategoryId - * @param Request $request - * - * @return Response - */ - public function editCmsCategoryAction($cmsCategoryId, Request $request) - { - $cmsPageCategoryFormBuilder = $this->getCmsPageCategoryFormBuilder(); - $cmsCategoryParentId = null; - - try { - $cmsPageCategoryForm = $cmsPageCategoryFormBuilder->getFormFor((int) $cmsCategoryId); - $cmsPageCategoryForm->handleRequest($request); - $result = $this->getCmsPageCategoryFormHandler()->handleFor((int) $cmsCategoryId, $cmsPageCategoryForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToIndexPageById($result->getIdentifiableObjectId()); - } - $cmsCategoryParentId = $this->getParentCategoryId((int) $cmsCategoryId)->getValue(); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - - if ($exception instanceof CmsPageCategoryNotFoundException) { - return $this->redirectToParentIndexPage((int) $cmsCategoryId); - } - } - - return $this->render( - '@PrestaShop/Admin/Improve/Design/Cms/edit_category.html.twig', - [ - 'cmsPageCategoryForm' => $cmsPageCategoryForm->createView(), - 'cmsCategoryParentId' => $cmsCategoryParentId, - ] - ); - } - - /** - * Deletes cms page category and all its children categories. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param int $cmsCategoryId - * - * @return RedirectResponse - */ - public function deleteCmsCategoryAction($cmsCategoryId) - { - try { - $this->getCommandBus()->handle( - new DeleteCmsPageCategoryCommand((int) $cmsCategoryId) - ); - - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPage((int) $cmsCategoryId); - } - - /** - * Deletes multiple cms page categories. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkCmsCategoryAction(Request $request) - { - $cmsCategoriesToDelete = $request->request->get('cms_page_category_bulk'); - - try { - $cmsCategoriesToDelete = array_map(function ($item) { return (int) $item; }, $cmsCategoriesToDelete); - - $this->getCommandBus()->handle( - new BulkDeleteCmsPageCategoryCommand($cmsCategoriesToDelete) - ); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByCategoryBulkIds($cmsCategoriesToDelete); - } - - /** - * Updates cms page category position. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function updateCmsCategoryPositionAction(Request $request) - { - $cmsCategoryParentId = $request->query->getInt('id_cms_category') ?: - CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID - ; - - $positionsData = [ - 'positions' => $request->request->get('positions'), - 'parentId' => $cmsCategoryParentId, - ]; - - $positionDefinition = $this->get('prestashop.core.grid.cms_page_category.position_definition'); - - $positionUpdateFactory = $this->get('prestashop.core.grid.position.position_update_factory'); - - try { - $positionUpdate = $positionUpdateFactory->buildPositionUpdate($positionsData, $positionDefinition); - } catch (PositionDataException $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - - return $this->redirectToIndexPageById($cmsCategoryParentId); - } - - $updater = $this->get('prestashop.core.grid.position.doctrine_grid_position_updater'); - - try { - $updater->update($positionUpdate); - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (PositionUpdateException $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - } - - return $this->redirectToIndexPageById($cmsCategoryParentId); - } - - /** - * Updates cms page listing position. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @return RedirectResponse - */ - public function updateCmsPositionAction(Request $request) - { - $cmsCategoryParentId = $request->query->getInt('id_cms_category') ?: - CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID - ; - - $positionsData = [ - 'positions' => $request->request->get('positions'), - 'parentId' => $cmsCategoryParentId, - ]; - - $positionDefinition = $this->get('prestashop.core.grid.cms_page.position_definition'); - $positionUpdateFactory = $this->get('prestashop.core.grid.position.position_update_factory'); - - try { - $positionUpdate = $positionUpdateFactory->buildPositionUpdate($positionsData, $positionDefinition); - } catch (PositionDataException $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - - return $this->redirectToParentIndexPage($cmsCategoryParentId); - } - - $updater = $this->get('prestashop.core.grid.position.doctrine_grid_position_updater'); - - try { - $updater->update($positionUpdate); - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (PositionUpdateException $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - } - - return $this->redirectToIndexPageById($cmsCategoryParentId); - } - - /** - * Toggles cms page category status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param int $cmsCategoryId - * - * @return RedirectResponse - */ - public function toggleCmsCategoryAction($cmsCategoryId) - { - try { - $this->getCommandBus()->handle( - new ToggleCmsPageCategoryStatusCommand((int) $cmsCategoryId) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPage((int) $cmsCategoryId); - } - - /** - * Changes multiple cms page category statuses to enabled. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkCmsPageCategoryStatusEnableAction(Request $request) - { - $cmsCategoriesToEnable = $request->request->get('cms_page_category_bulk'); - $cmsCategoryParentId = null; - try { - $cmsCategoriesToEnable = array_map(function ($item) { return (int) $item; }, $cmsCategoriesToEnable); - - $this->getCommandBus()->handle( - new BulkEnableCmsPageCategoryCommand($cmsCategoriesToEnable) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByCategoryBulkIds($cmsCategoriesToEnable); - } - - /** - * Changes multiple cms page category statuses to disabled. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkCmsPageCategoryStatusDisableAction(Request $request) - { - $cmsCategoriesToDisable = $request->request->get('cms_page_category_bulk'); - try { - $cmsCategoriesToDisable = array_map( - function ($item) { - return (int) $item; - }, - $cmsCategoriesToDisable - ); - $this->getCommandBus()->handle( - new BulkDisableCmsPageCategoryCommand($cmsCategoriesToDisable) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByCategoryBulkIds($cmsCategoriesToDisable); - } - - /** - * Toggles cms page listing status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param int $cmsId - * - * @return RedirectResponse - */ - public function toggleCmsAction($cmsId) - { - try { - $this->getCommandBus()->handle(new ToggleCmsPageStatusCommand((int) $cmsId)); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByCmsPageId($cmsId); - } - - /** - * Disables multiple cms pages. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDisableCmsPageStatusAction(Request $request) - { - $cmsPagesToDisable = $request->request->get('cms_page_bulk'); - - try { - $cmsPagesToDisable = array_map(function ($item) { return (int) $item; }, $cmsPagesToDisable); - - $this->getCommandBus()->handle( - new BulkDisableCmsPageCommand($cmsPagesToDisable) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByBulkIds($cmsPagesToDisable); - } - - /** - * Enables multiple cms pages. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkEnableCmsPageStatusAction(Request $request) - { - $cmsPagesToDisable = $request->request->get('cms_page_bulk'); - - try { - $cmsPagesToDisable = array_map( - function ($item) { - return (int) $item; - }, - $cmsPagesToDisable - ); - - $this->getCommandBus()->handle( - new BulkEnableCmsPageCommand($cmsPagesToDisable) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $this->redirectToParentIndexPageByBulkIds($cmsPagesToDisable); - } - - /** - * Deletes multiple cms pages. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteCmsPageAction(Request $request) - { - $cmsPagesToDisable = $request->request->get('cms_page_bulk'); - - $redirectResponse = $this->redirectToParentIndexPageByBulkIds($cmsPagesToDisable); - - try { - $cmsPagesToDisable = array_map( - function ($item) { - return (int) $item; - }, - $cmsPagesToDisable - ); - - $this->getCommandBus()->handle( - new BulkDeleteCmsPageCommand($cmsPagesToDisable) - ); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $redirectResponse; - } - - /** - * Deletes cms page by given id. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"}, - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_cms_pages_index", - * redirectQueryParamsToKeep={"id_cms_category"} - * ) - * - * @param int $cmsId - * - * @return RedirectResponse - */ - public function deleteCmsAction($cmsId) - { - $redirectResponse = $this->redirectToParentIndexPageByCmsPageId($cmsId); - - try { - $this->getCommandBus()->handle(new DeleteCmsPageCommand((int) $cmsId)); - - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $exception) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($exception, $this->getErrorMessages()) - ); - } - - return $redirectResponse; - } - - /** - * Gets cms page category form builder. - * - * @return FormBuilderInterface - */ - private function getCmsPageCategoryFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.cms_page_category_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getCmsPageCategoryFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.cms_page_category_form_handler'); - } - - /** - * This function is used for redirecting to the specific cms page category page. It uses bulk action ids which - * share the same parent cms category in all cases. - * - * @param array $cmsPageCategoryIds - * - * @return RedirectResponse - */ - private function redirectToParentIndexPageByCategoryBulkIds(array $cmsPageCategoryIds) - { - if (empty($cmsPageCategoryIds)) { - return $this->redirectToRoute('admin_cms_pages_index'); - } - - return $this->redirectToParentIndexPage((int) $cmsPageCategoryIds[0]); - } - - /** - * This function is used for redirecting to the specific cms page category page. - * - * @param array $cmsPageIds - * - * @return RedirectResponse - */ - private function redirectToParentIndexPageByBulkIds(array $cmsPageIds) - { - if (empty($cmsPageIds)) { - return $this->redirectToRoute('admin_cms_pages_index'); - } - - return $this->redirectToParentIndexPageByCmsPageId($cmsPageIds[0]); - } - - /** - * This function is used for redirecting to the specific cms page category page. - * - * @param int $cmsPageCategoryId - * - * @return RedirectResponse - */ - private function redirectToParentIndexPage($cmsPageCategoryId) - { - try { - $cmsPageCategoryParentId = $this->getParentCategoryId($cmsPageCategoryId)->getValue(); - } catch (CmsPageCategoryException $e) { - $cmsPageCategoryParentId = CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID; - } - - return $this->redirectToIndexPageById($cmsPageCategoryParentId); - } - - /** - * @param int $cmsPageId - * - * @return RedirectResponse - */ - private function redirectToParentIndexPageByCmsPageId($cmsPageId) - { - try { - $cmsCategoryId = $this->getQueryBus()->handle(new GetCmsCategoryIdForRedirection((int) $cmsPageId))->getValue(); - } catch (CmsPageException $e) { - $cmsCategoryId = CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID; - } - - return $this->redirectToIndexPageById($cmsCategoryId); - } - - /** - * Redirects to index page by given id. - * - * @param $cmsPageCategoryId - * - * @return RedirectResponse - */ - private function redirectToIndexPageById($cmsPageCategoryId) - { - $routeParameters = []; - - if ($cmsPageCategoryId !== CmsPageCategoryId::ROOT_CMS_PAGE_CATEGORY_ID) { - $routeParameters = [ - 'id_cms_category' => $cmsPageCategoryId, - ]; - } - - return $this->redirectToRoute('admin_cms_pages_index', $routeParameters); - } - - /** - * Gets parent id according to the given child - * - * @param int $cmsPageCategoryChildId - * - * @return CmsPageCategoryId - * - * @throws CmsPageCategoryException - */ - private function getParentCategoryId($cmsPageCategoryChildId) - { - /** @var CmsPageCategoryId $cmsPageCategoryParentId */ - $cmsPageCategoryParentId = $this->getQueryBus()->handle( - new GetCmsPageParentCategoryIdForRedirection($cmsPageCategoryChildId) - ); - - return $cmsPageCategoryParentId; - } - - /** - * @return FormBuilderInterface - */ - private function getCmsPageFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.cms_page_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getCmsPageFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.cms_page_form_handler'); - } - - /** - * Provides translatable error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - return [ - CmsPageNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotToggleCmsPageException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotDisableCmsPageException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotEnableCmsPageException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotDeleteCmsPageException::class => [ - CannotDeleteCmsPageException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - CannotDeleteCmsPageException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - ], - CmsPageCategoryConstraintException::class => [ - CmsPageCategoryConstraintException::INVALID_BULK_DATA => $this->trans( - 'You must select at least one element to delete.', - 'Admin.Notifications.Error' - ), - CmsPageCategoryConstraintException::CANNOT_MOVE_CATEGORY_TO_PARENT => $this->trans('The page Category cannot be moved here.', 'Admin.Design.Notification'), - CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_NAME => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Name', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::MISSING_DEFAULT_LANGUAGE_FOR_FRIENDLY_URL => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Friendly URL', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_CATEGORY_NAME => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Name', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_LINK_REWRITE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Friendly URL', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_META_TITLE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Meta title', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_DESCRIPTION => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Description', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_META_DESCRIPTION => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Meta description', 'Admin.Global')), - ] - ), - CmsPageCategoryConstraintException::INVALID_META_KEYWORDS => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Meta keywords', 'Admin.Global')), - ] - ), - ], - CmsPageCategoryNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotToggleCmsPageCategoryStatusException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotDeleteCmsPageCategoryException::class => [ - CannotDeleteCmsPageCategoryException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - CannotDeleteCmsPageCategoryException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Design/MailThemeController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Design/MailThemeController.php deleted file mode 100644 index fd42c2a3..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Design/MailThemeController.php +++ /dev/null @@ -1,548 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Design; - -use Mail; -use PrestaShop\PrestaShop\Adapter\MailTemplate\MailPreviewVariablesBuilder; -use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; -use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; -use PrestaShop\PrestaShop\Core\Employee\ContextEmployeeProviderInterface; -use PrestaShop\PrestaShop\Core\Exception\CoreException; -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Exception\InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Language\LanguageRepositoryInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateRendererInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface; -use PrestaShop\PrestaShop\Core\MailTemplate\Transformation\MailVariablesTransformation; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\GenerateMailsType; -use PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\TranslateMailsBodyType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Service\TranslationService; -use Symfony\Component\Form\Form; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - -/** - * Class MailThemeController manages mail theme generation, you can define the shop - * mail theme, and regenerate mail in a specific language. - * - * Accessible via "Design > Mail Theme" - */ -class MailThemeController extends FrameworkBundleAdminController -{ - /** - * Show mail theme settings and generation page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - $generateThemeMailsForm = $this->createForm(GenerateMailsType::class); - $translateMailsBodyForm = $this->createForm(TranslateMailsBodyType::class); - /** @var ThemeCatalogInterface $themeCatalog */ - $themeCatalog = $this->get('prestashop.core.mail_template.theme_catalog'); - $mailThemes = $themeCatalog->listThemes(); - - return $this->render('@PrestaShop/Admin/Improve/Design/MailTheme/index.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Email Theme', 'Admin.Navigation.Menu'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'mailThemeConfigurationForm' => $this->getMailThemeFormHandler()->getForm()->createView(), - 'generateMailsForm' => $generateThemeMailsForm->createView(), - 'translateMailsBodyForm' => $translateMailsBodyForm->createView(), - 'mailThemes' => $mailThemes, - ]); - } - - /** - * Manage generation form post and generate mails. - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function generateMailsAction(Request $request) - { - $generateThemeMailsForm = $this->createForm(GenerateMailsType::class); - $generateThemeMailsForm->handleRequest($request); - - if ($generateThemeMailsForm->isSubmitted()) { - if (!$generateThemeMailsForm->isValid()) { - $this->flashErrors($this->getFormErrorsForJS($generateThemeMailsForm)); - - return $this->redirectToRoute('admin_mail_theme_index'); - } - - $data = $generateThemeMailsForm->getData(); - try { - $coreMailsFolder = ''; - $modulesMailFolder = ''; - //Overwrite theme folder if selected - if (!empty($data['theme'])) { - $themeFolder = $this->getParameter('themes_dir') . '/' . $data['theme']; - if (is_dir($themeFolder . '/mails')) { - $coreMailsFolder = $themeFolder . '/mails'; - } - if (is_dir($themeFolder . '/modules')) { - $modulesMailFolder = $themeFolder . '/modules'; - } - } - - $generateCommand = new GenerateThemeMailTemplatesCommand( - $data['mailTheme'], - $data['language'], - $data['overwrite'], - $coreMailsFolder, - $modulesMailFolder - ); - - /** @var CommandBusInterface $commandBus */ - $commandBus = $this->get('prestashop.core.command_bus'); - $commandBus->handle($generateCommand); - - if ($data['overwrite']) { - $this->addFlash( - 'success', - $this->trans( - 'Successfully overwrote email templates for theme %s with locale %s', - 'Admin.Notifications.Success', - [ - $data['mailTheme'], - $data['language'], - ] - ) - ); - } else { - $this->addFlash( - 'success', - $this->trans( - 'Successfully generated email templates for theme %s with locale %s', - 'Admin.Notifications.Success', - [ - $data['mailTheme'], - $data['language'], - ] - ) - ); - } - } catch (CoreException $e) { - $this->flashErrors([ - $this->trans( - sprintf( - 'Cannot generate email templates for theme %s with locale %s', - $data['mailTheme'], - $data['language'] - ), - 'Admin.Notifications.Error' - ), - $e->getMessage(), - ]); - } - } - - return $this->redirectToRoute('admin_mail_theme_index'); - } - - /** - * Save mail theme configuration - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - * - * @throws \Exception - */ - public function saveConfigurationAction(Request $request) - { - /** @var FormHandlerInterface $formHandler */ - $formHandler = $this->getMailThemeFormHandler(); - /** @var Form $form */ - $form = $formHandler->getForm()->handleRequest($request); - - if ($form->isSubmitted()) { - if (!$form->isValid()) { - $this->flashErrors($this->getFormErrorsForJS($form)); - - return $this->redirectToRoute('admin_mail_theme_index'); - } - - $errors = $formHandler->save($form->getData()); - if (empty($errors)) { - $this->addFlash( - 'success', - $this->trans( - 'Email theme configuration saved successfully', - 'Admin.Notifications.Success' - ) - ); - } else { - $this->flashErrors($errors); - } - } - - return $this->redirectToRoute('admin_mail_theme_index'); - } - - /** - * Preview the list of layouts for a defined theme - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param string $theme - * - * @return Response - * - * @throws InvalidArgumentException - */ - public function previewThemeAction(Request $request, $theme) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - /** @var ThemeCatalogInterface $themeCatalog */ - $themeCatalog = $this->get('prestashop.core.mail_template.theme_catalog'); - /** @var ThemeInterface $mailTheme */ - $mailTheme = $themeCatalog->getByName($theme); - - return $this->render('@PrestaShop/Admin/Improve/Design/MailTheme/preview.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Preview Theme %s', 'Admin.Design.Feature', [$mailTheme->getName()]), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'mailTheme' => $mailTheme, - ]); - } - - /** - * This action allows to send a test mail of a specific email template, however the Mail - * class used to send emails is not modular enough to allow sending templates on the fly. - * This would require either: - * - a little modification of the Mail class to add an easy way to send a template content (rather than its name) - * - a full refacto of the Mail class which wouldn't be coupled to static files any more - * - * These modifications will be performed in a future release so for now we can only send test emails - * with the current email theme using generated static files. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param string $theme - * @param string $layout - * @param string $locale - * @param string $module - * - * @return Response - * - * @throws InvalidArgumentException - */ - public function sendTestMailAction($theme, $layout, $locale, $module = '') - { - if ($this->configuration->get('PS_MAIL_THEME') !== $theme) { - $this->addFlash( - 'error', - $this->trans( - 'Cannot send test email for theme %theme% because it is not your current theme', - 'Admin.Notifications.Error', - [ - '%theme%' => $theme, - ] - ) - ); - - return $this->redirectToRoute('admin_mail_theme_preview', ['theme' => $theme]); - } - - /** @var ContextEmployeeProviderInterface $employeeProvider */ - $employeeProvider = $this->get('prestashop.adapter.data_provider.employee'); - $employeeData = $employeeProvider->getData(); - - /** @var LanguageRepositoryInterface $languageRepository */ - $languageRepository = $this->get('prestashop.core.admin.lang.repository'); - /** @var LanguageInterface $language */ - $language = $languageRepository->getOneByLocaleOrIsoCode($locale); - if (null === $language) { - throw new InvalidArgumentException(sprintf('Cannot find Language with locale or isoCode %s', $locale)); - } - - if (empty($module)) { - $templatePath = _PS_MAIL_DIR_; - } else { - $templatePath = _PS_MODULE_DIR_ . $module . '/mails/'; - } - - /** @var MailPreviewVariablesBuilder $variableBuilder */ - $variablesBuilder = $this->get('prestashop.adapter.mail_template.preview_variables_builder'); - $mailLayout = $this->getMailLayout($theme, $layout, $module); - $mailVariables = $variablesBuilder->buildTemplateVariables($mailLayout); - - $mailSent = Mail::send( - $language->getId(), - $layout, - $this->trans('Test email %template%', 'Admin.Design.Feature', ['%template%' => $layout]), - $mailVariables, - $employeeData['email'], - $employeeData['firstname'] . ' ' . $employeeData['lastname'], - $employeeData['email'], - $employeeData['firstname'] . ' ' . $employeeData['lastname'], - null, - null, - $templatePath - ); - - if ($mailSent) { - $this->addFlash( - 'success', - $this->trans( - 'Test email for layout %layout% was successfully sent to %email%', - 'Admin.Notifications.Success', - [ - '%layout%' => $layout, - '%email%' => $employeeData['email'], - ] - ) - ); - } else { - $this->addFlash( - 'error', - $this->trans( - 'Cannot send test email for layout %layout%', - 'Admin.Notifications.Error', - [ - '%layout%' => $layout, - ] - ) - ); - } - - return $this->redirectToRoute('admin_mail_theme_preview', ['theme' => $theme]); - } - - /** - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * message="You do not have permission to update this." - * ) - * - * @param Request $request - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - */ - public function translateBodyAction(Request $request) - { - $translateMailsBodyForm = $this->createForm(TranslateMailsBodyType::class); - $translateMailsBodyForm->handleRequest($request); - - if (!$translateMailsBodyForm->isSubmitted() || !$translateMailsBodyForm->isValid()) { - $this->addFlash( - 'error', - $this->trans( - 'Cannot translate emails body content', - 'Admin.Notifications.Error' - ) - ); - - return $this->redirectToRoute('admin_mail_theme_index'); - } - - $translateData = $translateMailsBodyForm->getData(); - $language = $translateData['language']; - /** @var TranslationService $translationService */ - $translationService = $this->get('prestashop.service.translation'); - $locale = $translationService->langToLocale($language); - - return $this->redirectToRoute('admin_international_translation_overview', [ - 'lang' => $language, - 'locale' => $locale, - 'type' => 'mails_body', - ]); - } - - /** - * Preview a mail layout from a defined theme - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param string $theme - * @param string $layout - * @param string $type - * @param string $locale - * @param string $module - * - * @return Response - * - * @throws FileNotFoundException - * @throws InvalidArgumentException - */ - public function previewLayoutAction($theme, $layout, $type, $locale, $module = '') - { - $renderedLayout = $this->renderLayout($theme, $layout, $type, $locale, $module); - - return new Response($renderedLayout); - } - - /** - * Display the raw source of a theme layout (mainly useful for developers/integrators) - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param string $theme - * @param string $layout - * @param string $type - * @param string $locale - * @param string $module - * - * @return Response - * - * @throws FileNotFoundException - * @throws InvalidArgumentException - */ - public function rawLayoutAction($theme, $layout, $type, $locale, $module = '') - { - $renderedLayout = $this->renderLayout($theme, $layout, $type, $locale, $module); - - $response = new Response($renderedLayout, Response::HTTP_OK, [ - 'Content-Type' => 'text/plain', - ]); - - return $response; - } - - /** - * Dynamically display an email template, this is usually used by the MailGenerator but this action - * allows to display preview before generating the file (handy when you are developing an email theme) - * - * @param string $themeName - * @param string $layoutName - * @param string $type - * @param string $locale - * @param string $module - * - * @return string - * - * @throws FileNotFoundException - * @throws InvalidArgumentException - */ - private function renderLayout($themeName, $layoutName, $type, $locale = '', $module = '') - { - $layout = $this->getMailLayout($themeName, $layoutName, $module); - - /** @var LanguageRepositoryInterface $languageRepository */ - $languageRepository = $this->get('prestashop.core.admin.lang.repository'); - if (empty($locale)) { - $locale = $this->getContext()->language->locale; - } - /** @var LanguageInterface $language */ - $language = $languageRepository->getOneByLocaleOrIsoCode($locale); - if (null === $language) { - throw new InvalidArgumentException(sprintf('Cannot find Language with locale or isoCode %s', $locale)); - } - - /** @var MailPreviewVariablesBuilder $variableBuilder */ - $variablesBuilder = $this->get('prestashop.adapter.mail_template.preview_variables_builder'); - $mailLayoutVariables = $variablesBuilder->buildTemplateVariables($layout); - - /** @var MailTemplateRendererInterface $renderer */ - $renderer = $this->get('prestashop.core.mail_template.mail_template_renderer'); - //Special case for preview, we fill the mail variables - $renderer->addTransformation(new MailVariablesTransformation(MailTemplateInterface::HTML_TYPE, $mailLayoutVariables)); - $renderer->addTransformation(new MailVariablesTransformation(MailTemplateInterface::TXT_TYPE, $mailLayoutVariables)); - - switch ($type) { - case MailTemplateInterface::HTML_TYPE: - $renderedLayout = $renderer->renderHtml($layout, $language); - break; - case MailTemplateInterface::TXT_TYPE: - $renderedLayout = $renderer->renderTxt($layout, $language); - break; - default: - throw new NotFoundHttpException(sprintf('Requested type %s is not managed, please use one of these: %s', $type, implode(',', [MailTemplateInterface::HTML_TYPE, MailTemplateInterface::TXT_TYPE]))); - break; - } - - return $renderedLayout; - } - - /** - * @param string $themeName - * @param string $layoutName - * @param string $module - * - * @return LayoutInterface - * - * @throws FileNotFoundException - * @throws InvalidArgumentException - */ - private function getMailLayout($themeName, $layoutName, $module) - { - /** @var ThemeCatalogInterface $themeCatalog */ - $themeCatalog = $this->get('prestashop.core.mail_template.theme_catalog'); - /** @var ThemeInterface $theme */ - $theme = $themeCatalog->getByName($themeName); - - /** @var LayoutInterface $layout */ - $layout = null; - /* @var LayoutInterface $layoutInterface */ - foreach ($theme->getLayouts() as $layoutInterface) { - if ($layoutInterface->getName() == $layoutName - && $layoutInterface->getModuleName() == $module - ) { - $layout = $layoutInterface; - break; - } - } - - if (null === $layout) { - throw new FileNotFoundException(sprintf('Cannot find layout %s%s in theme %s', empty($module) ? '' : $module . ':', $layoutName, $themeName)); - } - - return $layout; - } - - /** - * @return FormHandlerInterface - */ - private function getMailThemeFormHandler() - { - return $this->get('prestashop.admin.mail_theme.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Design/PositionsController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Design/PositionsController.php deleted file mode 100644 index d5f6903f..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Design/PositionsController.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Design; - -use Hook; -use PrestaShop\PrestaShop\Adapter\Module\Module; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Configuration modules positions "Improve > Design > Positions". - */ -class PositionsController extends FrameworkBundleAdminController -{ - /** - * @var int - */ - protected $selectedModule = null; - - /** - * Display hooks positions. - * - * @Template("@PrestaShop/Admin/Improve/Design/positions.html.twig") - * @AdminSecurity("is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller')~'_')", message="Access denied.") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $moduleAdapter = $this->get('prestashop.adapter.legacy.module'); - $hookProvider = $this->get('prestashop.adapter.legacy.hook'); - $installedModules = $moduleAdapter->getModulesInstalled(); - - $selectedModule = $request->get('show_modules'); - if ($selectedModule && (string) $selectedModule != 'all') { - $this->selectedModule = (int) $selectedModule; - } - - $this->manageLegacyFlashes($request->query->get('conf')); - - $modules = []; - foreach ($installedModules as $installedModule) { - if ($module = $moduleAdapter->getInstanceById($installedModule['id_module'])) { - // We want to be able to sort modules by display name - $modules[(int) $module->id] = $module; - } - } - - $hooks = $hookProvider->getHooks(); - foreach ($hooks as $key => $hook) { - $hooks[$key]['modules'] = $hookProvider->getModulesFromHook( - $hook['id_hook'], - $this->selectedModule - ); - // No module found, no need to continue - if (!is_array($hooks[$key]['modules'])) { - unset($hooks[$key]); - - continue; - } - - foreach ($hooks[$key]['modules'] as $index => $module) { - if (empty($modules[(int) $module['id_module']])) { - unset($hooks[$key]['modules'][$index]); - } - } - - $hooks[$key]['modules_count'] = count($hooks[$key]['modules']); - // No module remaining after the check, no need to continue - if ($hooks[$key]['modules_count'] === 0) { - unset($hooks[$key]); - - continue; - } - - $hooks[$key]['position'] = $hookProvider->isDisplayHookName($hook['name']); - } - - $legacyContextService = $this->get('prestashop.adapter.legacy.context'); - $saveUrlParams = [ - 'addToHook' => '', - ]; - if ($this->selectedModule) { - $saveUrlParams['show_modules'] = $this->selectedModule; - } - $saveUrl = $legacyContextService->getAdminLink('AdminModulesPositions', true, $saveUrlParams); - - return [ - 'layoutHeaderToolbarBtn' => [ - 'save' => [ - 'href' => $saveUrl, - 'desc' => $this->trans('Transplant a module', 'Admin.Design.Feature'), - ], - ], - 'selectedModule' => $this->selectedModule, - 'layoutTitle' => $this->trans('Positions', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => false, - 'requireBulkActions' => false, - 'requireFilterStatus' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminModulesPositions'), - 'hooks' => $hooks, - 'modules' => $modules, - 'canMove' => $this->get('prestashop.adapter.shop.context')->isSingleShopContext(), - ]; - } - - /** - * Unhook module. - * - * @AdminSecurity("is_granted(['delete'], request.get('_legacy_controller')~'_')", message="Access denied.") - * - * @param Request $request - * - * @return Response - */ - public function unhookAction(Request $request) - { - $validateAdapter = $this->get('prestashop.adapter.validate'); - $unhooks = $request->request->get('unhooks'); - $context = null; - if (empty($unhooks)) { - $moduleId = $request->query->get('moduleId'); - $hookId = $request->query->get('hookId'); - $unhooks = [sprintf('%d_%d', $hookId, $moduleId)]; - $context = $this->get('prestashop.adapter.shop.context')->getContextListShopID(); - } - - $errors = []; - foreach ($unhooks as $unhook) { - $explode = explode('_', $unhook); - $hookId = (int) isset($explode[0]) ? $explode[0] : 0; - $moduleId = (int) isset($explode[1]) ? $explode[1] : 0; - $module = $this->get('prestashop.adapter.legacy.module')->getInstanceById($moduleId); - $hook = new Hook($hookId); - - if (!$module) { - $errors[] = $this->trans( - 'This module cannot be loaded.', - 'Admin.Modules.Notification' - ); - - continue; - } - - if (!$validateAdapter->isLoadedObject($hook)) { - $errors[] = $this->trans( - 'Hook cannot be loaded.', - 'Admin.Modules.Notification' - ); - - continue; - } - - if (!$module->unregisterHook($hookId, $context) || !$module->unregisterExceptions($hookId, $context)) { - $errors[] = $this->trans( - 'An error occurred while deleting the module from its hook.', - 'Admin.Modules.Notification' - ); - } - } - - if (!empty($errors)) { - $this->flashErrors($errors); - } else { - $this->addFlash( - 'success', - $this->trans( - 'The module was successfully removed from the hook.', - 'Admin.Modules.Notification' - ) - ); - } - - return $this->redirect( - $this->generateUrl('admin_modules_positions') - ); - } - - /** - * Manage legacy flashes, this code must be removed - * when legacy edit will be migrated. - * - * @param int $messageId The message id from legacy context - */ - private function manageLegacyFlashes($messageId) - { - if (empty($messageId)) { - return; - } - - $messages = [ - 16 => $this->trans('The module transplanted successfully to the hook.', 'Admin.Modules.Notification'), - 17 => $this->trans('The module was successfully removed from the hook.', 'Admin.Modules.Notification'), - ]; - - if (isset($messages[$messageId])) { - $this->addFlash( - 'success', - $messages[$messageId] - ); - } - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeCatalogController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeCatalogController.php deleted file mode 100644 index d95b2d35..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeCatalogController.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Design; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Request; - -/** - * Displays themes from Addons under "Improve > Design > Themes Catalog". - */ -class ThemeCatalogController extends FrameworkBundleAdminController -{ - /** - * Displays themes from Addons under "Improve > Design > Themes Catalog". - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function indexAction(Request $request) - { - $pageContent = file_get_contents($this->getAddonsUrl($request)); - - return $this->render('@PrestaShop/Admin/Improve/Design/ThemesCatalogPage/addons_store.html.twig', [ - 'pageContent' => $pageContent, - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Themes Catalog', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminThemesCatalog'), - 'requireFilterStatus' => false, - ]); - } - - /** - * @param Request $request - * - * @return string - */ - private function getAddonsUrl(Request $request) - { - $psVersion = $this->get('prestashop.core.foundation.version')->getVersion(); - $parent_domain = $request->getSchemeAndHttpHost(); - $context = $this->getContext(); - $currencyCode = $context->currency->iso_code; - $languageCode = $context->language->iso_code; - $countryCode = $context->country->iso_code; - $activity = $this->get('prestashop.adapter.legacy.configuration')->getInt('PS_SHOP_ACTIVITY'); - - return "https://addons.prestashop.com/iframe/search-1.7.php?psVersion=$psVersion" - . "&isoLang=$languageCode" - . "&isoCurrency=$currencyCode" - . "&isoCountry=$countryCode" - . "&activity=$activity" - . "&parentUrl=$parent_domain" - . '&onlyThemes=1'; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeController.php deleted file mode 100644 index 5ff6821c..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Design/ThemeController.php +++ /dev/null @@ -1,606 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Design; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; -use PrestaShop\PrestaShop\Core\Domain\Exception\FileUploadException; -use PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetPagesForLayoutCustomization; -use PrestaShop\PrestaShop\Core\Domain\Meta\QueryResult\LayoutCustomizationPage; -use PrestaShop\PrestaShop\Core\Domain\Shop\DTO\ShopLogoSettings; -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\NotSupportedFaviconExtensionException; -use PrestaShop\PrestaShop\Core\Domain\Shop\Exception\NotSupportedLogoImageExtensionException; -use PrestaShop\PrestaShop\Core\Domain\Shop\Query\GetLogosPaths; -use PrestaShop\PrestaShop\Core\Domain\Shop\QueryResult\LogosPaths; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\AdaptThemeToRTLLanguagesCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\DeleteThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\EnableThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ImportThemeCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Command\ResetThemeLayoutsCommand; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotAdaptThemeToRTLLanguagesException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotDeleteThemeException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\CannotEnableThemeException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\FailedToEnableThemeModuleException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ImportedThemeAlreadyExistsException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ThemeConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Theme\Exception\ThemeException; -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeImportSource; -use PrestaShop\PrestaShop\Core\Domain\Theme\ValueObject\ThemeName; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController as AbstractAdminController; -use PrestaShopBundle\Form\Admin\Improve\Design\Theme\AdaptThemeToRTLLanguagesType; -use PrestaShopBundle\Form\Admin\Improve\Design\Theme\ImportThemeType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class ThemeController manages "Improve > Design > Theme & Logo" pages. - */ -class ThemeController extends AbstractAdminController -{ - /** - * Show main themes page. - * - * @AdminSecurity( - * "is_granted('read', request.get('_legacy_controller'))", - * message="You do not have permission to edit this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $isHostMode = $this->get('prestashop.adapter.hosting_information')->isHostMode(); - $isoCode = strtoupper($this->get('prestashop.adapter.legacy.context')->getLanguage()->iso_code); - - $themeCatalogUrl = sprintf( - '%s?%s', - 'https://addons.prestashop.com/en/3-templates-prestashop', - http_build_query([ - 'utm_source' => 'back-office', - 'utm_medium' => 'theme-button', - 'utm_campaign' => 'back-office-' . $isoCode, - 'utm_content' => $isHostMode ? 'cloud' : 'download', - ]) - ); - - $themeProvider = $this->get('prestashop.core.addon.theme.theme_provider'); - $installedRtlLanguageChecker = $this->get('prestashop.adapter.language.rtl.installed_language_checker'); - /** @var LogosPaths $logoProvider */ - $logoProvider = $this->getQueryBus()->handle(new GetLogosPaths()); - - return $this->render('@PrestaShop/Admin/Improve/Design/Theme/index.html.twig', [ - 'themeCatalogUrl' => $themeCatalogUrl, - 'baseShopUrl' => $this->get('prestashop.adapter.shop.url.base_url_provider')->getUrl(), - 'shopLogosForm' => $this->getLogosUploadForm()->createView(), - 'headerLogoPath' => $logoProvider->getHeaderLogoPath(), - 'mailLogoPath' => $logoProvider->getMailLogoPath(), - 'invoiceLogoPath' => $logoProvider->getInvoiceLogoPath(), - 'faviconPath' => $logoProvider->getFaviconPath(), - 'currentlyUsedTheme' => $themeProvider->getCurrentlyUsedTheme(), - 'notUsedThemes' => $themeProvider->getNotUsedThemes(), - 'isDevModeOn' => $this->get('prestashop.adapter.legacy.configuration')->get('_PS_MODE_DEV_'), - 'isSingleShopContext' => $this->get('prestashop.adapter.shop.context')->isSingleShopContext(), - 'isMultiShopFeatureUsed' => $this->get('prestashop.adapter.multistore_feature')->isUsed(), - 'adaptThemeToRtlLanguagesForm' => $this->getAdaptThemeToRtlLanguageForm()->createView(), - 'isInstalledRtlLanguage' => $installedRtlLanguageChecker->isInstalledRtlLanguage(), - 'shopName' => $this->get('prestashop.adapter.shop.context')->getShopName(), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Upload shop logos. - * - * @AdminSecurity("is_granted(['update'], request.get('_legacy_controller'))", redirectRoute="admin_themes_index") - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function uploadLogosAction(Request $request) - { - $logosUploadForm = $this->getLogosUploadForm(); - $logosUploadForm->handleRequest($request); - - if ($logosUploadForm->isSubmitted()) { - $data = $logosUploadForm->getData(); - try { - $this->getShopLogosFormHandler()->save($data['shop_logos']); - - $this->addFlash( - 'success', - $this->trans('The settings have been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (DomainException $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException( - $e, - $this->getLogoUploadErrorMessages($e) - ) - ); - } - } - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Export current theme. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to view this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @return RedirectResponse - */ - public function exportAction() - { - $themeProvider = $this->get('prestashop.core.addon.theme.theme_provider'); - $exporter = $this->get('prestashop.core.addon.theme.exporter'); - - $path = $exporter->export($themeProvider->getCurrentlyUsedTheme()); - - $this->addFlash( - 'success', - $this->trans( - 'Your theme has been correctly exported: %path%', - 'Admin.Notifications.Success', - ['%path%' => $path] - ) - ); - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Import new theme. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to add this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param Request $request - * - * @return Response - */ - public function importAction(Request $request) - { - $importThemeForm = $this->createForm(ImportThemeType::class); - $importThemeForm->handleRequest($request); - - if ($importThemeForm->isSubmitted() && $importThemeForm->isValid()) { - $data = $importThemeForm->getData(); - $importSource = null; - - try { - if ($data['import_from_computer']) { - $importSource = ThemeImportSource::fromArchive($data['import_from_computer']); - } elseif ($data['import_from_web']) { - $importSource = ThemeImportSource::fromWeb($data['import_from_web']); - } elseif ($data['import_from_ftp']) { - $importSource = ThemeImportSource::fromFtp($data['import_from_ftp']); - } - - if (null === $importSource) { - $this->addFlash( - 'warning', - $this->trans('Please select theme\'s import source.', 'Admin.Notifications.Warning') - ); - - return $this->redirectToRoute('admin_themes_import'); - } - - $this->getCommandBus()->handle(new ImportThemeCommand($importSource)); - - return $this->redirectToRoute('admin_themes_index'); - } catch (ThemeException $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException( - $e, - $this->handleImportThemeException($e) - ) - ); - - return $this->redirectToRoute('admin_themes_import'); - } - } - - return $this->render('@PrestaShop/Admin/Improve/Design/Theme/import.html.twig', [ - 'importThemeForm' => $importThemeForm->createView(), - ]); - } - - /** - * Enable selected theme. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param string $themeName - * - * @return RedirectResponse - */ - public function enableAction($themeName) - { - try { - $this->getCommandBus()->handle(new EnableThemeCommand(new ThemeName($themeName))); - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (ThemeException $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException( - $e, - $this->handleEnableThemeException($e) - ) - ); - - return $this->redirectToRoute('admin_themes_index'); - } - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Delete selected theme. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to delete this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param string $themeName - * - * @return RedirectResponse - */ - public function deleteAction($themeName) - { - try { - $this->getCommandBus()->handle(new DeleteThemeCommand(new ThemeName($themeName))); - - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (ThemeException $e) { - $this->addFlash('error', $this->handleDeleteThemeException($e)); - - return $this->redirectToRoute('admin_themes_index'); - } - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Adapts selected theme to RTL languages. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function adaptToRTLLanguagesAction(Request $request) - { - $form = $this->getAdaptThemeToRtlLanguageForm(); - $form->handleRequest($request); - - if (!$form->isSubmitted()) { - return $this->redirectToRoute('admin_themes_index'); - } - - $data = $form->getData(); - - if (!$data['generate_rtl_css']) { - return $this->redirectToRoute('admin_themes_index'); - } - - try { - $this->getCommandBus()->handle(new AdaptThemeToRTLLanguagesCommand( - new ThemeName($data['theme_to_adapt']) - )); - - $this->addFlash( - 'success', - $this->trans('Your RTL stylesheets has been generated successfully', 'Admin.Design.Notification') - ); - } catch (ThemeException $e) { - $this->addFlash('error', $this->handleAdaptThemeToRTLLanguagesException($e)); - } - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Reset theme's page layouts. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_themes_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_themes_index") - * - * @param string $themeName - * - * @return RedirectResponse - */ - public function resetLayoutsAction($themeName) - { - $this->getCommandBus()->handle(new ResetThemeLayoutsCommand(new ThemeName($themeName))); - - $this->addFlash('success', $this->trans( - 'Your theme has been correctly reset to its default settings. You may want to regenerate your images. See the Improve > Design > Images Settings screen for the \'%regenerate_label%\' button.', - 'Admin.Design.Notification', - [ - '%regenerate_label%' => $this->trans('Regenerate thumbnails', 'Admin.Design.Feature'), - ] - )); - - return $this->redirectToRoute('admin_themes_index'); - } - - /** - * Show Front Office theme's pages layout customization. - * - * @param Request $request - * - * @return Response - */ - public function customizeLayoutsAction(Request $request) - { - $canCustomizeLayout = $this->canCustomizePageLayouts($request); - - if (!$canCustomizeLayout) { - $this->addFlash( - 'error', - $this->trans('You do not have permission to edit this.', 'Admin.Notifications.Error') - ); - } - - /** @var LayoutCustomizationPage[] $pages */ - $pages = $this->getQueryBus()->handle(new GetPagesForLayoutCustomization()); - - $pageLayoutCustomizationFormFactory = - $this->get('prestashop.bundle.form.admin.improve.design.theme.page_layout_customization_form_factory'); - $pageLayoutCustomizationForm = $pageLayoutCustomizationFormFactory->create($pages); - $pageLayoutCustomizationForm->handleRequest($request); - - if ($canCustomizeLayout && $pageLayoutCustomizationForm->isSubmitted()) { - if ($this->isDemoModeEnabled()) { - $this->addFlash('error', $this->getDemoModeErrorMessage()); - - return $this->redirectToRoute('admin_theme_customize_layouts'); - } - - $themePageLayoutsCustomizer = $this->get('prestashop.core.addon.theme.theme.page_layouts_customizer'); - $themePageLayoutsCustomizer->customize($pageLayoutCustomizationForm->getData()['layouts']); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_themes_index'); - } - - return $this->render('@PrestaShop/Admin/Improve/Design/Theme/customize_page_layouts.html.twig', [ - 'pageLayoutCustomizationForm' => $pageLayoutCustomizationForm->createView(), - 'pages' => $pages, - ]); - } - - /** - * @param Request $request - * - * @return bool - */ - protected function canCustomizePageLayouts(Request $request) - { - return !$this->isDemoModeEnabled() && - $this->isGranted(PageVoter::UPDATE, $request->attributes->get('_legacy_controller')); - } - - /** - * @return FormInterface - * - * @throws Exception - */ - protected function getLogosUploadForm() - { - return $this->getShopLogosFormHandler()->getForm(); - } - - /** - * @return FormInterface - */ - protected function getAdaptThemeToRtlLanguageForm() - { - return $this->createForm(AdaptThemeToRTLLanguagesType::class); - } - - /** - * @return FormHandlerInterface - */ - private function getShopLogosFormHandler() - { - return $this->get('prestashop.admin.shop_logos_settings.form_handler'); - } - - /** - * @param Exception $e - * - * @return array - */ - private function handleImportThemeException(Exception $e) - { - return [ - ImportedThemeAlreadyExistsException::class => $this->trans( - 'There is already a theme %theme_name% in your themes folder. Remove it if you want to continue.', - 'Admin.Design.Notification', - [ - '%theme_name%' => $e instanceof ImportedThemeAlreadyExistsException ? $e->getThemeName()->getValue() : '', - ] - ), - ]; - } - - /** - * @param ThemeException $e - * - * @return array - */ - private function handleEnableThemeException(ThemeException $e) - { - return [ - CannotEnableThemeException::class => $e->getMessage(), - ThemeConstraintException::class => [ - ThemeConstraintException::RESTRICTED_ONLY_FOR_SINGLE_SHOP => $this->trans( - 'You must select a shop from the above list if you wish to choose a theme.', - 'Admin.Design.Help' - ), - ], - FailedToEnableThemeModuleException::class => $this->trans( - 'Cannot %action% module %module%. %error_details%', - 'Admin.Modules.Notification', - [ - '%action%' => strtolower($this->trans('Install', 'Admin.Actions')), - '%module%' => ($e instanceof FailedToEnableThemeModuleException) ? $e->getModuleName() : '', - '%error_details%' => $e->getMessage(), - ] - ), - ]; - } - - /** - * @param ThemeException $e - * - * @return string - */ - private function handleDeleteThemeException(ThemeException $e) - { - $type = get_class($e); - - $errorMessages = [ - CannotDeleteThemeException::class => $this->trans( - 'Failed to delete theme. Make sure you have permissions and theme is not used.', - 'Admin.Design.Notification' - ), - ]; - - if (isset($errorMessages[$type])) { - return $errorMessages[$type]; - } - - return $this->getFallbackErrorMessage($type, $e->getCode()); - } - - /** - * @param ThemeException $e - * - * @return string - */ - private function handleAdaptThemeToRTLLanguagesException(ThemeException $e) - { - $type = get_class($e); - - $errorMessages = [ - CannotAdaptThemeToRTLLanguagesException::class => $this->trans('Cannot adapt theme to RTL languages.', 'Admin.Design.Notification'), - ]; - - if (isset($errorMessages[$type])) { - return $errorMessages[$type]; - } - - return $this->getFallbackErrorMessage($type, $e->getCode()); - } - - /** - * Gets exception or exception and its code error mapping. - * - * @param DomainException $exception - * - * @return array - */ - private function getLogoUploadErrorMessages(DomainException $exception) - { - $availableLogoFormatsImploded = implode(', .', ShopLogoSettings::AVAILABLE_LOGO_IMAGE_EXTENSIONS); - $availableIconFormat = ShopLogoSettings::AVAILABLE_ICON_IMAGE_EXTENSION; - - $logoImageFormatError = $this->trans( - 'Image format not recognized, allowed format(s) is(are): .%s', - 'Admin.Notifications.Error', - [$availableLogoFormatsImploded] - ); - - $iconFormatError = $this->trans( - 'Image format not recognized, allowed format(s) is(are): .%s', - 'Admin.Notifications.Error', - [$availableIconFormat] - ); - - return [ - NotSupportedLogoImageExtensionException::class => $logoImageFormatError, - NotSupportedFaviconExtensionException::class => $iconFormatError, - FileUploadException::class => [ - UPLOAD_ERR_INI_SIZE => $this->trans( - 'File too large (limit of %s bytes).', - 'Admin.Notifications.Error', - [ - UploadedFile::getMaxFilesize(), - ] - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/CurrencyController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/CurrencyController.php deleted file mode 100644 index eac6736d..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/CurrencyController.php +++ /dev/null @@ -1,567 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\DeleteCurrencyCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\RefreshExchangeRatesCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleCurrencyStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\AutomateExchangeRatesUpdateException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDeleteDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotDisableDefaultCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotRefreshExchangeRatesException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CannotToggleCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\CurrencyNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\DefaultCurrencyInMultiShopException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\ExchangeRateNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Exception\InvalidUnofficialCurrencyException; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyExchangeRate; -use PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetReferenceCurrency; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ExchangeRate as ExchangeRateResult; -use PrestaShop\PrestaShop\Core\Domain\Currency\QueryResult\ReferenceCurrency; -use PrestaShop\PrestaShop\Core\Domain\Currency\ValueObject\ExchangeRate; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CurrencyGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Language\LanguageInterface; -use PrestaShop\PrestaShop\Core\Localization\CLDR\ComputingPrecision; -use PrestaShop\PrestaShop\Core\Localization\CLDR\Currency; -use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository as CldrLocaleRepository; -use PrestaShop\PrestaShop\Core\Localization\Currency\PatternTransformer; -use PrestaShop\PrestaShop\Core\Localization\Locale\Repository as LocaleRepository; -use PrestaShop\PrestaShop\Core\Search\Filters\CurrencyFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Entity\Repository\LangRepository; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Security\Voter\PageVoter; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class CurrencyController is responsible for handling "Improve -> International -> Localization -> Currencies" page. - */ -class CurrencyController extends FrameworkBundleAdminController -{ - /** - * Show currency page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param CurrencyFilters $filters - * @param Request $request - * - * @return Response - */ - public function indexAction(CurrencyFilters $filters, Request $request) - { - $currencyGridFactory = $this->get('prestashop.core.grid.factory.currency'); - $currencyGrid = $currencyGridFactory->getGrid($filters); - - $settingsForm = $this->getSettingsFormHandler()->getForm(); - - return $this->render('@PrestaShop/Admin/Improve/International/Currency/index.html.twig', [ - 'currencyGrid' => $this->presentGrid($currencyGrid), - 'currencySettingsForm' => $settingsForm->createView(), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Provides filters functionality. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get('prestashop.core.grid.definition.factory.currency'), - $request, - CurrencyGridDefinitionFactory::GRID_ID, - 'admin_currencies_index' - ); - } - - /** - * Displays and handles currency form. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_currencies_index", - * message="You need permission to create this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $multiStoreFeature = $this->get('prestashop.adapter.multistore_feature'); - - $currencyForm = $this->getCurrencyFormBuilder()->getForm(); - $currencyForm->handleRequest($request); - - try { - $result = $this->getCurrencyFormHandler()->handle($currencyForm); - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_currencies_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Improve/International/Currency/create.html.twig', [ - 'isShopFeatureEnabled' => $multiStoreFeature->isUsed(), - 'currencyForm' => $currencyForm->createView(), - ]); - } - - /** - * Displays currency form. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_currencies_index", - * message="You need permission to edit this." - * ) - * - * @param int $currencyId - * @param Request $request - * - * @return Response - */ - public function editAction($currencyId, Request $request) - { - $multiStoreFeature = $this->get('prestashop.adapter.multistore_feature'); - $currencyForm = $this->getCurrencyFormBuilder()->getFormFor($currencyId); - - try { - $currencyForm->handleRequest($request); - - $result = $this->getCurrencyFormHandler()->handleFor($currencyId, $currencyForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_currencies_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Improve/International/Currency/edit.html.twig', [ - 'isShopFeatureEnabled' => $multiStoreFeature->isUsed(), - 'currencyForm' => null !== $currencyForm ? $currencyForm->createView() : null, - 'languages' => $this->getLanguagesData($currencyForm->getData()['iso_code']), - ]); - } - - /** - * @param string $currencyIsoCode - * - * @return array - */ - private function getLanguagesData(string $currencyIsoCode) - { - /** @var LangRepository $langRepository */ - $langRepository = $this->get('prestashop.core.admin.lang.repository'); - $languages = $langRepository->findAll(); - /** @var LocaleRepository $localeRepository */ - $localeRepository = $this->get('prestashop.core.localization.locale.repository'); - /** @var CldrLocaleRepository $cldrLocaleRepository */ - $cldrLocaleRepository = $this->get('prestashop.core.localization.cldr.locale_repository'); - - $languagesData = []; - /** @var LanguageInterface $language */ - foreach ($languages as $language) { - $locale = $localeRepository->getLocale($language->getLocale()); - $cldrLocale = $cldrLocaleRepository->getLocale($language->getLocale()); - $cldrCurrency = $cldrLocale->getCurrency($currencyIsoCode); - $priceSpecification = $locale->getPriceSpecification($currencyIsoCode); - - $transformer = new PatternTransformer(); - $transformations = []; - foreach (PatternTransformer::ALLOWED_TRANSFORMATIONS as $transformationType) { - $transformations[$transformationType] = $transformer->transform( - $cldrLocale->getCurrencyPattern(), - $transformationType - ); - } - - $languagesData[] = [ - 'id' => $language->getId(), - 'name' => $language->getName(), - 'currencyPattern' => $cldrLocale->getCurrencyPattern(), - 'currencySymbol' => null !== $cldrCurrency ? $cldrCurrency->getSymbol() : $currencyIsoCode, - 'priceSpecification' => $priceSpecification->toArray(), - 'transformations' => $transformations, - ]; - } - - return $languagesData; - } - - /** - * Deletes currency. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_currencies_index", - * message="You need permission to delete this." - * ) - * @DemoRestricted(redirectRoute="admin_currencies_index") - * - * @param int $currencyId - * - * @return RedirectResponse - */ - public function deleteAction($currencyId) - { - try { - $this->getCommandBus()->handle(new DeleteCurrencyCommand((int) $currencyId)); - } catch (CurrencyException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_currencies_index'); - } - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_currencies_index'); - } - - /** - * Get the data for a currency (from CLDR) - * - * @param string $currencyIsoCode - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * @DemoRestricted(redirectRoute="admin_currencies_index") - * - * @return JsonResponse - */ - public function getReferenceDataAction($currencyIsoCode) - { - try { - /** @var ReferenceCurrency $referenceCurrency */ - $referenceCurrency = $this->getQueryBus()->handle(new GetReferenceCurrency($currencyIsoCode)); - } catch (CurrencyException $e) { - return new JsonResponse([ - 'error' => $this->trans( - 'Cannot find reference data for currency %isoCode%', - 'Admin.International.Feature', - [ - '%isoCode%' => $currencyIsoCode, - ] - ), - ], 404); - } - - try { - /** @var ExchangeRateResult $exchangeRate */ - $exchangeRate = $this->getQueryBus()->handle(new GetCurrencyExchangeRate($currencyIsoCode)); - $computingPrecision = new ComputingPrecision(); - $exchangeRateValue = $exchangeRate->getValue()->round($computingPrecision->getPrecision(2)); - } catch (ExchangeRateNotFoundException $e) { - $exchangeRateValue = ExchangeRate::DEFAULT_RATE; - } - - return new JsonResponse([ - 'isoCode' => $referenceCurrency->getIsoCode(), - 'numericIsoCode' => $referenceCurrency->getNumericIsoCode(), - 'precision' => $referenceCurrency->getPrecision(), - 'names' => $referenceCurrency->getNames(), - 'symbols' => $referenceCurrency->getSymbols(), - 'patterns' => $referenceCurrency->getPatterns(), - 'exchangeRate' => $exchangeRateValue, - ]); - } - - /** - * Toggles status. - * - * @param int $currencyId - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_currencies_index", - * message="You need permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_currencies_index") - * - * @return RedirectResponse - */ - public function toggleStatusAction($currencyId) - { - try { - $this->getCommandBus()->handle(new ToggleCurrencyStatusCommand((int) $currencyId)); - } catch (CurrencyException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_currencies_index'); - } - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - - return $this->redirectToRoute('admin_currencies_index'); - } - - /** - * Refresh exchange rates. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_currencies_index", - * message="You need permission to edit this." - * ) - * @DemoRestricted(redirectRoute="admin_currencies_index") - * - * @return RedirectResponse - */ - public function refreshExchangeRatesAction() - { - try { - $this->getCommandBus()->handle(new RefreshExchangeRatesCommand()); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (CannotRefreshExchangeRatesException $exception) { - $this->addFlash('error', $exception->getMessage()); - } - - return $this->redirectToRoute('admin_currencies_index'); - } - - /** - * Handles ajax request which updates live exchange rates. - * - * @param Request $request - * - * @return JsonResponse - */ - public function updateLiveExchangeRatesAction(Request $request) - { - if ($this->isDemoModeEnabled()) { - return $this->json([ - 'status' => false, - 'message' => $this->getDemoModeErrorMessage(), - ], - Response::HTTP_UNAUTHORIZED - ); - } - - $authLevel = $this->authorizationLevel($request->attributes->get('_legacy_controller')); - - if (!in_array($authLevel, [PageVoter::LEVEL_UPDATE, PageVoter::LEVEL_DELETE])) { - return $this->json([ - 'status' => false, - 'message' => $this->trans( - 'You need permission to edit this.', - 'Admin.Notifications.Error' - ), - ], - Response::HTTP_UNAUTHORIZED - ); - } - - $settingsFormHandler = $this->getSettingsFormHandler(); - $settingsForm = $settingsFormHandler->getForm(); - - $settingsForm->handleRequest($request); - - $response = [ - 'status' => false, - 'message' => $this->trans('Unexpected error occurred.', 'Admin.Notifications.Error'), - ]; - $statusCode = Response::HTTP_BAD_REQUEST; - - if ($settingsForm->isSubmitted()) { - try { - $settingsFormHandler->save($settingsForm->getData()); - $response = [ - 'status' => true, - 'message' => $this->trans( - 'The status has been successfully updated.', - 'Admin.Notifications.Success' - ), - ]; - $statusCode = Response::HTTP_OK; - } catch (CurrencyException $e) { - $response['message'] = $this->getErrorMessageForException($e, $this->getErrorMessages($e)); - } - } - - return $this->json($response, $statusCode); - } - - /** - * Gets form builder. - * - * @return FormBuilderInterface - */ - private function getCurrencyFormBuilder() - { - return $this->get('prestashop.core.form.builder.currency_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getCurrencyFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.currency_form_handler'); - } - - /** - * @return \PrestaShop\PrestaShop\Core\Form\FormHandlerInterface - */ - private function getSettingsFormHandler() - { - return $this->get('prestashop.admin.currency_settings.form_handler'); - } - - /** - * Gets an error by exception class and its code. - * - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e) - { - $isoCode = $e instanceof InvalidUnofficialCurrencyException ? $e->getIsoCode() : ''; - - return [ - CurrencyConstraintException::class => [ - CurrencyConstraintException::INVALID_ISO_CODE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('ISO code', 'Admin.International.Feature')), - ] - ), - CurrencyConstraintException::INVALID_NUMERIC_ISO_CODE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Numeric ISO code', 'Admin.International.Feature')), - ] - ), - CurrencyConstraintException::INVALID_EXCHANGE_RATE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Exchange rate', 'Admin.International.Feature')), - ] - ), - CurrencyConstraintException::INVALID_NAME => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Currency name', 'Admin.International.Feature')), - ] - ), - CurrencyConstraintException::CURRENCY_ALREADY_EXISTS => $this->trans( - 'This currency already exists.', - 'Admin.International.Notification' - ), - ], - AutomateExchangeRatesUpdateException::class => [ - AutomateExchangeRatesUpdateException::CRON_TASK_MANAGER_MODULE_NOT_INSTALLED => $this->trans( - 'Please install the %module_name% module before using this feature.', - 'Admin.International.Notification', - [ - '%module_name%' => 'cronjobs', - ] - ), - ], - DefaultCurrencyInMultiShopException::class => [ - DefaultCurrencyInMultiShopException::CANNOT_REMOVE_CURRENCY => $this->trans( - '%currency% is the default currency for shop %shop_name%, and therefore cannot be removed from shop association', - 'Admin.International.Notification', - [ - '%currency%' => $e instanceof DefaultCurrencyInMultiShopException ? $e->getCurrencyName() : '', - '%shop_name%' => $e instanceof DefaultCurrencyInMultiShopException ? $e->getShopName() : '', - ] - ), - DefaultCurrencyInMultiShopException::CANNOT_DISABLE_CURRENCY => $this->trans( - '%currency% is the default currency for shop %shop_name%, and therefore cannot be disabled', - 'Admin.International.Notification', - [ - '%currency%' => $e instanceof DefaultCurrencyInMultiShopException ? $e->getCurrencyName() : '', - '%shop_name%' => $e instanceof DefaultCurrencyInMultiShopException ? $e->getShopName() : '', - ] - ), - ], - CurrencyNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotToggleCurrencyException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotDeleteDefaultCurrencyException::class => $this->trans( - 'You cannot delete the default currency', - 'Admin.International.Notification' - ), - CannotDisableDefaultCurrencyException::class => $this->trans( - 'You cannot disable the default currency', - 'Admin.International.Notification' - ), - InvalidUnofficialCurrencyException::class => $this->trans( - 'Oops... it looks like this ISO code already exists. If you are: [1][2]trying to create an alternative currency, you must type a different ISO code[/2][2]trying to modify the currency with ISO code %isoCode%, make sure you did not check the creation box[/2][/1]', - 'Admin.International.Notification', - [ - '%isoCode%' => $isoCode, - '[1]' => '
      ', - '[/1]' => '
    ', - '[2]' => '
  • ', - '[/2]' => '
  • ', - ] - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php deleted file mode 100644 index c5f2b7f5..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/GeolocationController.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class GeolocationController is responsible for "Improve > International > Localization > Geolocation" page. - */ -class GeolocationController extends FrameworkBundleAdminController -{ - /** - * Show geolocation page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $geolocationForm = $this->getGeolocationFormHandler()->getForm(); - $geoLiteCityChecker = $this->get('prestashop.core.geolocation.geo_lite_city.checker'); - - return $this->render('@PrestaShop/Admin/Improve/International/Geolocation/index.html.twig', [ - 'layoutTitle' => $this->trans('Geolocation', 'Admin.Navigation.Menu'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'geolocationForm' => $geolocationForm->createView(), - 'geolocationDatabaseAvailable' => $geoLiteCityChecker->isAvailable(), - ]); - } - - /** - * Process geolocation configuration form. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_geolocation" - * ) - * @DemoRestricted(redirectRoute="admin_geolocation_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $geolocationFormHandler = $this->getGeolocationFormHandler(); - - $geolocationForm = $geolocationFormHandler->getForm(); - $geolocationForm->handleRequest($request); - - if ($geolocationForm->isSubmitted()) { - $errors = $geolocationFormHandler->save($geolocationForm->getData()); - - if (empty($errors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_geolocation_index'); - } - - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_geolocation_index'); - } - - /** - * @return FormHandlerInterface - */ - protected function getGeolocationFormHandler() - { - return $this->get('prestashop.admin.geolocation.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php deleted file mode 100644 index 1086adcd..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/LanguageController.php +++ /dev/null @@ -1,399 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkDeleteLanguagesCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkToggleLanguagesStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\DeleteLanguageCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\Command\ToggleLanguageStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\CannotDisableDefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\CopyingNoPictureException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\DefaultLanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageImageUploadingException; -use PrestaShop\PrestaShop\Core\Domain\Language\Exception\LanguageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing; -use PrestaShop\PrestaShop\Core\Domain\Language\QueryResult\EditableLanguage; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\LanguageGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters\LanguageFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class LanguageController manages "Improve > International > Localization > Languages". - */ -class LanguageController extends FrameworkBundleAdminController -{ - /** - * Show languages listing page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param LanguageFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, LanguageFilters $filters) - { - $languageGridFactory = $this->get('prestashop.core.grid.factory.language'); - $languageGrid = $languageGridFactory->getGrid($filters); - - return $this->render('@PrestaShop/Admin/Improve/International/Language/index.html.twig', [ - 'languageGrid' => $this->presentGrid($languageGrid), - 'isHtaccessFileWriter' => $this->get('prestashop.core.util.url.url_file_checker')->isHtaccessFileWritable(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Process Grid search. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchGridAction(Request $request) - { - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get('prestashop.core.grid.definition.factory.language'), - $request, - LanguageGridDefinitionFactory::GRID_ID, - 'admin_languages_index' - ); - } - - /** - * Show language creation form page and handle its submit. - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $languageFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.language_form_handler'); - $languageFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.language_form_builder'); - - $languageForm = $languageFormBuilder->getForm(); - $languageForm->handleRequest($request); - - try { - $result = $languageFormHandler->handle($languageForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_languages_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Improve/International/Language/create.html.twig', [ - 'languageForm' => $languageForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - ]); - } - - /** - * Show language edit form page and handle its submit. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param int $languageId - * @param Request $request - * - * @return Response - */ - public function editAction($languageId, Request $request) - { - $languageFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.language_form_handler'); - $languageFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.language_form_builder'); - - try { - $languageForm = $languageFormBuilder->getFormFor((int) $languageId, [], [ - 'is_for_editing' => true, - ]); - $languageForm->handleRequest($request); - - $result = $languageFormHandler->handleFor((int) $languageId, $languageForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_languages_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - if ($e instanceof LanguageNotFoundException) { - return $this->redirectToRoute('admin_languages_index'); - } - } - - /** @var EditableLanguage $editableLanguage */ - $editableLanguage = $this->getQueryBus()->handle(new GetLanguageForEditing((int) $languageId)); - - return $this->render('@PrestaShop/Admin/Improve/International/Language/edit.html.twig', [ - 'languageForm' => $languageForm->createView(), - 'editableLanguage' => $editableLanguage, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - ]); - } - - /** - * Deletes language - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_languages_index") - * @DemoRestricted(redirectRoute="admin_languages_index") - * - * @param int $languageId - * - * @return RedirectResponse - */ - public function deleteAction($languageId) - { - try { - $this->getCommandBus()->handle(new DeleteLanguageCommand((int) $languageId)); - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - } catch (LanguageException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_languages_index'); - } - - /** - * Deletes languages in bulk action - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_languages_index") - * @DemoRestricted(redirectRoute="admin_languages_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $languageIds = $this->getBulkLanguagesFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteLanguagesCommand($languageIds)); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (LanguageException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_languages_index'); - } - - /** - * Toggles language status - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_languages_index") - * @DemoRestricted(redirectRoute="admin_languages_index") - * - * @param int $languageId - * - * @return RedirectResponse - */ - public function toggleStatusAction($languageId) - { - try { - /** @var EditableLanguage $editableLanguage */ - $editableLanguage = $this->getQueryBus()->handle(new GetLanguageForEditing((int) $languageId)); - - $this->getCommandBus()->handle(new ToggleLanguageStatusCommand( - (int) $languageId, - !$editableLanguage->isActive() - )); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (LanguageException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_languages_index'); - } - - /** - * Toggles languages status in bulk action - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_languages_index") - * @DemoRestricted(redirectRoute="admin_languages_index") - * - * @param Request $request - * @param string $status - * - * @return RedirectResponse - */ - public function bulkToggleStatusAction(Request $request, $status) - { - $languageIds = $this->getBulkLanguagesFromRequest($request); - $expectedStatus = 'enable' === $status; - - try { - $this->getCommandBus()->handle(new BulkToggleLanguagesStatusCommand( - $languageIds, - $expectedStatus - )); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (LanguageException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_languages_index'); - } - - /** - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e) - { - return [ - LanguageNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotDisableDefaultLanguageException::class => $this->trans( - 'You cannot change the status of the default language.', - 'Admin.International.Notification' - ), - CopyingNoPictureException::class => [ - CopyingNoPictureException::PRODUCT_IMAGE_COPY_ERROR => $this->trans( - 'An error occurred while copying "No Picture" image to your product folder.', - 'Admin.International.Notification' - ), - CopyingNoPictureException::CATEGORY_IMAGE_COPY_ERROR => $this->trans( - 'An error occurred while copying "No picture" image to your category folder.', - 'Admin.International.Notification' - ), - CopyingNoPictureException::BRAND_IMAGE_COPY_ERROR => $this->trans( - 'An error occurred while copying "No picture" image to your brand folder.', - 'Admin.International.Notification' - ), - ], - LanguageImageUploadingException::class => [ - LanguageImageUploadingException::MEMORY_LIMIT_RESTRICTION => $this->trans( - 'Due to memory limit restrictions, this image cannot be loaded. Please increase your memory_limit value via your server\'s configuration settings.', - 'Admin.Notifications.Error' - ), - LanguageImageUploadingException::UNEXPECTED_ERROR => $this->trans( - 'An error occurred while uploading the image.', - 'Admin.Notifications.Error' - ), - ], - LanguageConstraintException::class => [ - LanguageConstraintException::INVALID_ISO_CODE => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('ISO code', 'Admin.International.Feature'))] - ), - LanguageConstraintException::INVALID_IETF_TAG => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Language code', 'Admin.International.Feature'))] - ), - LanguageConstraintException::DUPLICATE_ISO_CODE => $this->trans( - 'This ISO code is already linked to another language.', - 'Admin.International.Notification' - ), - LanguageConstraintException::EMPTY_BULK_DELETE => $this->trans( - 'You must select at least one element to delete.', - 'Admin.Notifications.Error' - ), - ], - DefaultLanguageException::class => [ - DefaultLanguageException::CANNOT_DELETE_ERROR => $this->trans( - 'You cannot delete the default language.', - 'Admin.International.Notification' - ), - DefaultLanguageException::CANNOT_DISABLE_ERROR => $this->trans( - 'You cannot change the status of the default language.', - 'Admin.International.Notification' - ), - DefaultLanguageException::CANNOT_DELETE_IN_USE_ERROR => $this->trans( - 'You cannot delete the language currently in use. Please select a different language.', - 'Admin.International.Notification' - ), - ], - ]; - } - - /** - * Get language ids from request for bulk action - * - * @param Request $request - * - * @return int[] - */ - private function getBulkLanguagesFromRequest(Request $request) - { - $languageIds = $request->request->get('language_language_bulk'); - - if (!is_array($languageIds)) { - return []; - } - - foreach ($languageIds as $i => $languageId) { - $languageIds[$i] = (int) $languageId; - } - - return $languageIds; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php deleted file mode 100644 index 3f0d9664..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/LocalizationController.php +++ /dev/null @@ -1,161 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Localization\Pack\Import\LocalizationPackImportConfig; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Improve\International\Localization\ImportLocalizationPackType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class LocalizationController is responsible for handling "Improve > International > Localization" page. - */ -class LocalizationController extends FrameworkBundleAdminController -{ - /** - * Show localization settings page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", message="Access denied.") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - if (!extension_loaded('openssl')) { - $this->addFlash('warning', $this->trans('Importing a new language may fail without the OpenSSL module. Please enable "openssl.so" on your server configuration.', 'Admin.International.Notification')); - } - - $localizationPackImportForm = $this->createForm(ImportLocalizationPackType::class); - $localizationForm = $this->getLocalizationFormHandler()->getForm(); - - return $this->render('@PrestaShop/Admin/Improve/International/Localization/index.html.twig', [ - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Localization', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'localizationForm' => $localizationForm->createView(), - 'localizationPackImportForm' => $localizationPackImportForm->createView(), - ]); - } - - /** - * Save localization settings. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * @DemoRestricted(redirectRoute="admin_localization_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $localizationFormHandler = $this->getLocalizationFormHandler(); - - $localizationForm = $localizationFormHandler->getForm(); - $localizationForm->handleRequest($request); - - if ($localizationForm->isSubmitted()) { - $data = $localizationForm->getData(); - - $errors = $localizationFormHandler->save($data); - if (empty($errors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_localization_index'); - } - - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_localization_index'); - } - - /** - * Handles localization pack import. - * - * @AdminSecurity("is_granted(['update', 'create','delete'], request.get('_legacy_controller'))", message="You do not have permission to edit this.") - * @DemoRestricted(redirectRoute="admin_localization_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function importPackAction(Request $request) - { - $localizationPackImportForm = $this->createForm(ImportLocalizationPackType::class); - $localizationPackImportForm->handleRequest($request); - - if ($localizationPackImportForm->isSubmitted()) { - $data = $localizationPackImportForm->getData(); - - $localizationImportConfig = new LocalizationPackImportConfig( - $data['iso_localization_pack'], - $data['content_to_import'], - $data['download_pack_data'] - ); - - $localizationPackImporter = $this->get('prestashop.core.localization.pack.import.importer'); - $errors = $localizationPackImporter->import($localizationImportConfig); - - if (empty($errors)) { - $this->addFlash( - 'success', - $this->trans('Localization pack imported successfully.', 'Admin.International.Notification') - ); - - return $this->redirectToRoute('admin_localization_index'); - } - - foreach ($errors as $error) { - $this->addFlash('error', $error); - } - } - - return $this->redirectToRoute('admin_localization_index'); - } - - /** - * Returns localization settings form handler. - * - * @return FormHandlerInterface - */ - private function getLocalizationFormHandler() - { - return $this->get('prestashop.admin.localization.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/StateController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/StateController.php deleted file mode 100644 index cecc1935..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/StateController.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use Exception; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for handling country states data - */ -class StateController extends FrameworkBundleAdminController -{ - /** - * Provides country states in json response - * - * @param Request $request - * - * @return JsonResponse - */ - public function getStatesAction(Request $request) - { - try { - $countryId = (int) $request->query->get('id_country'); - $statesProvider = $this->get('prestashop.adapter.form.choice_provider.country_state_by_id'); - $states = $statesProvider->getChoices([ - 'id_country' => $countryId, - ]); - - return $this->json([ - 'states' => $states, - ]); - } catch (Exception $e) { - return $this->json([ - 'message' => $this->getErrorMessageForException($e, []), - ], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php deleted file mode 100644 index d471c45a..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxController.php +++ /dev/null @@ -1,414 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkDeleteTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkToggleTaxStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\DeleteTaxCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Command\ToggleTaxStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\DeleteTaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\TaxNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Exception\UpdateTaxException; -use PrestaShop\PrestaShop\Core\Domain\Tax\Query\GetTaxForEditing; -use PrestaShop\PrestaShop\Core\Domain\Tax\QueryResult\EditableTax; -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\TaxFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for handling "Improve > International > Taxes" page. - */ -class TaxController extends FrameworkBundleAdminController -{ - /** - * Show taxes page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param TaxFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, TaxFilters $filters) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $taxGridFactory = $this->get('prestashop.core.grid.factory.tax'); - $taxGrid = $taxGridFactory->getGrid($filters); - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - $taxOptionsForm = $this->getTaxOptionsFormHandler()->getForm(); - - return $this->render('@PrestaShop/Admin/Improve/International/Tax/index.html.twig', [ - 'taxGrid' => $gridPresenter->present($taxGrid), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'taxOptionsForm' => $taxOptionsForm->createView(), - ]); - } - - /** - * Process tax options configuration form. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index" - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @param Request $request - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse - */ - public function saveOptionsAction(Request $request) - { - $taxOptionsFormHandler = $this->getTaxOptionsFormHandler(); - - $taxOptionsForm = $taxOptionsFormHandler->getForm(); - $taxOptionsForm->handleRequest($request); - - if ($taxOptionsForm->isSubmitted()) { - $errors = $taxOptionsFormHandler->save($taxOptionsForm->getData()); - - if (empty($errors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_taxes_index'); - } - - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * Provides filters functionality. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $definitionFactory = $this->get('prestashop.core.grid.definition.factory.tax'); - $definitionFactory = $definitionFactory->getDefinition(); - - $gridFilterFormFactory = $this->get('prestashop.core.grid.filter.form_factory'); - $searchParametersForm = $gridFilterFormFactory->create($definitionFactory); - $searchParametersForm->handleRequest($request); - - $filters = []; - if ($searchParametersForm->isSubmitted()) { - $filters = $searchParametersForm->getData(); - } - - return $this->redirectToRoute('admin_taxes_index', ['filters' => $filters]); - } - - /** - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $taxFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.tax_form_handler'); - $taxFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.tax_form_builder'); - - try { - $taxForm = $taxFormBuilder->getForm(); - $taxForm->handleRequest($request); - $result = $taxFormHandler->handle($taxForm); - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_taxes_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Improve/International/Tax/create.html.twig', [ - 'taxForm' => $taxForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - ]); - } - - /** - * Handles tax edit - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * - * @param Request $request - * @param int $taxId - * - * @return Response - */ - public function editAction(Request $request, $taxId) - { - $taxFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.tax_form_handler'); - $taxFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.tax_form_builder'); - - try { - $taxForm = $taxFormBuilder->getFormFor((int) $taxId); - $taxForm->handleRequest($request); - $result = $taxFormHandler->handleFor((int) $taxId, $taxForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_taxes_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - if ($e instanceof TaxNotFoundException) { - return $this->redirectToRoute('admin_taxes_index'); - } - } - - /** @var EditableTax $editableTax */ - $editableTax = $this->getQueryBus()->handle(new GetTaxForEditing((int) $taxId)); - - return $this->render('@PrestaShop/Admin/Improve/International/Tax/edit.html.twig', [ - 'taxForm' => $taxForm->createView(), - 'taxName' => $editableTax->getLocalizedNames()[$this->getContextLangId()], - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - ]); - } - - /** - * Deletes tax. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @param int $taxId - * - * @return RedirectResponse - */ - public function deleteAction($taxId) - { - try { - $this->getCommandBus()->handle(new DeleteTaxCommand((int) $taxId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (TaxException $e) { - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * Toggles status. - * - * @param int $taxId - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @return RedirectResponse - */ - public function toggleStatusAction($taxId) - { - try { - /** @var EditableTax $editableTax */ - $editableTax = $this->getQueryBus()->handle(new GetTaxForEditing((int) $taxId)); - $this->getCommandBus()->handle(new ToggleTaxStatusCommand((int) $taxId, !$editableTax->isActive())); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (TaxException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * Enables taxes status on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @return RedirectResponse - */ - public function bulkEnableStatusAction(Request $request) - { - $taxIds = $request->request->get('tax_bulk'); - try { - $this->getCommandBus()->handle(new BulkToggleTaxStatusCommand($taxIds, true)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (TaxException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * Disables taxes status on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @return RedirectResponse - */ - public function bulkDisableStatusAction(Request $request) - { - $taxIds = $request->request->get('tax_bulk'); - try { - $this->getCommandBus()->handle(new BulkToggleTaxStatusCommand($taxIds, false)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (TaxException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * Delete taxes on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_taxes_index", - * ) - * @DemoRestricted(redirectRoute="admin_taxes_index") - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $taxIds = $request->request->get('tax_bulk'); - try { - $this->getCommandBus()->handle(new BulkDeleteTaxCommand($taxIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (TaxException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_taxes_index'); - } - - /** - * @return FormHandlerInterface - */ - private function getTaxOptionsFormHandler() - { - return $this->get('prestashop.admin.tax_options.form_handler'); - } - - /** - * Gets error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - return [ - TaxNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - UpdateTaxException::class => [ - UpdateTaxException::FAILED_BULK_UPDATE_STATUS => [ - $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - ], - UpdateTaxException::FAILED_UPDATE_STATUS => [ - $this->trans( - 'An error occurred while updating the status for an object.', - 'Admin.Notifications.Error' - ), - ], - ], - DeleteTaxException::class => [ - DeleteTaxException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - DeleteTaxException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxRulesGroupController.php b/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxRulesGroupController.php deleted file mode 100644 index 26011578..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/International/TaxRulesGroupController.php +++ /dev/null @@ -1,343 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\International; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkDeleteTaxRulesGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkSetTaxRulesGroupStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\DeleteTaxRulesGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\SetTaxRulesGroupStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotBulkDeleteTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotBulkUpdateTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotDeleteTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\CannotUpdateTaxRulesGroupException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupConstraintException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Exception\TaxRulesGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Query\GetTaxRulesGroupForEditing; -use PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\QueryResult\EditableTaxRulesGroup; -use PrestaShop\PrestaShop\Core\Search\Filters\TaxRulesGroupFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for handling "Improve > International > Tax Rules" page. - */ -class TaxRulesGroupController extends FrameworkBundleAdminController -{ - /** - * Show tax rules group page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param TaxRulesGroupFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, TaxRulesGroupFilters $filters): Response - { - $taxRulesGroupGridFactory = $this->get('prestashop.core.grid.factory.tax_rules_group'); - $taxRulesGroupGrid = $taxRulesGroupGridFactory->getGrid($filters); - - return $this->render('@PrestaShop/Admin/Improve/International/TaxRulesGroup/index.html.twig', [ - 'taxRulesGroupGrid' => $this->presentGrid($taxRulesGroupGrid), - 'enableSidebar' => true, - 'layoutHeaderToolbarBtn' => $this->getTaxRulesGroupToolbarButtons(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request): Response - { - return $this->redirect($this->getAdminLink('AdminTaxRulesGroup', [])); - } - - /** - * Handles tax rules group edit - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @param Request $request - * @param int $taxRulesGroupId - * - * @return Response - */ - public function editAction(Request $request, int $taxRulesGroupId): Response - { - return $this->redirect($this->getAdminLink('AdminTaxRulesGroup', [])); - } - - /** - * Deletes tax rules group. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @param int $taxRulesGroupId - * - * @return RedirectResponse - */ - public function deleteAction(int $taxRulesGroupId): RedirectResponse - { - try { - $this->getCommandBus()->handle(new DeleteTaxRulesGroupCommand((int) $taxRulesGroupId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_tax_rules_groups_index'); - } - - /** - * Toggles status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @param int $taxRulesGroupId - * - * @return RedirectResponse - */ - public function toggleStatusAction(int $taxRulesGroupId): RedirectResponse - { - try { - /** @var EditableTaxRulesGroup $editableTaxRulesGroup */ - $editableTaxRulesGroup = $this->getQueryBus()->handle( - new GetTaxRulesGroupForEditing((int) $taxRulesGroupId) - ); - - $this->getCommandBus()->handle( - new SetTaxRulesGroupStatusCommand((int) $taxRulesGroupId, !$editableTaxRulesGroup->isActive()) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_tax_rules_groups_index'); - } - - /** - * Enables tax rules groups status on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @return RedirectResponse - */ - public function bulkEnableStatusAction(Request $request): RedirectResponse - { - $taxRulesGroupIds = $this->getBulkTaxRulesGroupFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkSetTaxRulesGroupStatusCommand($taxRulesGroupIds, true)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_tax_rules_groups_index'); - } - - /** - * Disables tax rules groups status on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @return RedirectResponse - */ - public function bulkDisableStatusAction(Request $request): RedirectResponse - { - $taxRulesGroupIds = $this->getBulkTaxRulesGroupFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkSetTaxRulesGroupStatusCommand($taxRulesGroupIds, false)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_tax_rules_groups_index'); - } - - /** - * Delete tax rules groups on bulk action. - * - * @param Request $request - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_tax_rules_groups_index", - * ) - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request): RedirectResponse - { - $taxRulesGroupIds = $this->getBulkTaxRulesGroupFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteTaxRulesGroupCommand($taxRulesGroupIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_tax_rules_groups_index'); - } - - /** - * @param Request $request - * - * @return array - */ - private function getBulkTaxRulesGroupFromRequest(Request $request): array - { - $taxRulesGroupIds = $request->request->get('tax_rules_group_bulk'); - - if (!is_array($taxRulesGroupIds)) { - return []; - } - - foreach ($taxRulesGroupIds as $i => $taxRulesGroupId) { - $taxRulesGroupIds[$i] = (int) $taxRulesGroupId; - } - - return $taxRulesGroupIds; - } - - /** - * @return array - */ - private function getTaxRulesGroupToolbarButtons(): array - { - $toolbarButtons = []; - - $toolbarButtons['add'] = [ - 'href' => $this->generateUrl('admin_tax_rules_groups_create'), - 'desc' => $this->trans('Add new tax rules group', 'Admin.International.Feature'), - 'icon' => 'add_circle_outline', - ]; - - return $toolbarButtons; - } - - /** - * Gets error messages for exceptions - * - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e = null): array - { - return [ - CannotDeleteTaxRulesGroupException::class => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - TaxRulesGroupNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotUpdateTaxRulesGroupException::class => [ - CannotUpdateTaxRulesGroupException::FAILED_TOGGLE_STATUS => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - ], - CannotBulkDeleteTaxRulesGroupException::class => sprintf( - '%s: %s', - $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - $e instanceof CannotBulkDeleteTaxRulesGroupException ? implode(', ', $e->getTaxRulesGroupsIds()) : '' - ), - CannotBulkUpdateTaxRulesGroupException::class => sprintf( - '%s: %s', - $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - $e instanceof CannotBulkUpdateTaxRulesGroupException ? implode(', ', $e->getTaxRulesGroupsIds()) : '' - ), - TaxRulesGroupConstraintException::class => [ - TaxRulesGroupConstraintException::INVALID_ID => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/ModuleController.php b/src/PrestaShopBundle/Controller/Admin/Improve/ModuleController.php deleted file mode 100644 index 2846a2d9..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/ModuleController.php +++ /dev/null @@ -1,826 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve; - -use DateTime; -use Exception; -use Module; -use PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Module\Module as ModuleAdapter; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; -use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShop\PrestaShop\Core\Addon\Module\Exception\UnconfirmedModuleActionException; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository; -use PrestaShopBundle\Controller\Admin\Improve\Modules\ModuleAbstractController; -use PrestaShopBundle\Entity\ModuleHistory; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Voter\PageVoter; -use PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider; -use Profile; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * Responsible of "Improve > Modules > Modules & Services > Catalog / Manage" page display. - */ -class ModuleController extends ModuleAbstractController -{ - const CONTROLLER_NAME = 'ADMINMODULESSF'; - - const MAX_MODULES_DISPLAYED = 6; - - /** - * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") - * - * @return Response - */ - public function catalogAction() - { - return $this->render( - '@PrestaShop/Admin/Module/catalog.html.twig', - [ - 'layoutHeaderToolbarBtn' => $this->getToolbarButtons(), - 'layoutTitle' => $this->trans('Modules catalog', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminModules'), - 'requireFilterStatus' => false, - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - 'errorMessage' => $this->trans( - 'You do not have permission to add this.', - 'Admin.Notifications.Error' - ), - ] - ); - } - - /** - * Controller responsible for displaying "Catalog Module Grid" section of Module management pages with ajax. - * - * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") - * - * @param Request $request - * - * @return Response - */ - public function manageAction() - { - $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $shopService = $this->get('prestashop.adapter.shop.context'); - $moduleRepository = $this->get('prestashop.core.admin.module.repository'); - $themeRepository = $this->get('prestashop.core.addon.theme.repository'); - - // Retrieve current shop - $shopId = $shopService->getContextShopId(); - $shops = $shopService->getShops(); - $modulesTheme = []; - if (isset($shops[$shopId]) && is_array($shops[$shopId])) { - $shop = $shops[$shopId]; - $currentTheme = $themeRepository->getInstanceByName($shop['theme_name']); - $modulesTheme = $currentTheme->getModulesToEnable(); - } - - $filters = new AddonListFilter(); - $filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE) - ->removeStatus(AddonListFilterStatus::UNINSTALLED); - $installedProducts = $moduleRepository->getFilteredList($filters); - - $categories = $this->getCategories($modulesProvider, $installedProducts); - $bulkActions = [ - 'bulk-uninstall' => $this->trans('Uninstall', 'Admin.Actions'), - 'bulk-disable' => $this->trans('Disable', 'Admin.Actions'), - 'bulk-enable' => $this->trans('Enable', 'Admin.Actions'), - 'bulk-reset' => $this->trans('Reset', 'Admin.Actions'), - 'bulk-enable-mobile' => $this->trans('Enable Mobile', 'Admin.Modules.Feature'), - 'bulk-disable-mobile' => $this->trans('Disable Mobile', 'Admin.Modules.Feature'), - ]; - - return $this->render( - '@PrestaShop/Admin/Module/manage.html.twig', - [ - 'maxModulesDisplayed' => self::MAX_MODULES_DISPLAYED, - 'bulkActions' => $bulkActions, - 'layoutHeaderToolbarBtn' => $this->getToolbarButtons(), - 'layoutTitle' => $this->trans('Module manager', 'Admin.Modules.Feature'), - 'categories' => $categories['categories'], - 'topMenuData' => $this->getTopMenuData($categories), - 'requireAddonsSearch' => false, - 'requireBulkActions' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminModules'), - 'requireFilterStatus' => true, - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - 'errorMessage' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), - ] - ); - } - - /** - * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") - * - * @param Request $request - * - * @return Response - */ - public function getPreferredModulesAction(Request $request) - { - $tabModulesList = $request->get('tab_modules_list'); - - if ($tabModulesList) { - $tabModulesList = explode(',', $tabModulesList); - $modulesListUnsorted = $this->getModulesByInstallation( - $tabModulesList, - $request->request->get('admin_list_from_source') - ); - } - - $installed = $uninstalled = []; - - if (!empty($tabModulesList)) { - foreach ($tabModulesList as $key => $value) { - foreach ($modulesListUnsorted['installed'] as $moduleInstalled) { - if ($moduleInstalled['attributes']['name'] == $value) { - $installed[] = $moduleInstalled; - - continue 2; - } - } - - foreach ($modulesListUnsorted['not_installed'] as $moduleNotInstalled) { - if ($moduleNotInstalled['attributes']['name'] == $value) { - $uninstalled[] = $moduleNotInstalled; - - continue 2; - } - } - } - } - - $moduleListSorted = [ - 'installed' => $installed, - 'notInstalled' => $uninstalled, - ]; - - $twigParams = [ - 'currentIndex' => '', - 'modulesList' => $moduleListSorted, - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - ]; - - if ($request->request->has('admin_list_from_source')) { - $twigParams['adminListFromSource'] = $request->request->get('admin_list_from_source'); - } - - return $this->render( - '@PrestaShop/Admin/Module/tab-modules-list.html.twig', - $twigParams - ); - } - - /** - * @AdminSecurity("is_granted(['read', 'create', 'update', 'delete'], 'ADMINMODULESSF_')") - * - * @param Request $module_name - * - * @return Response - */ - public function configureModuleAction($module_name) - { - /** @var UrlGeneratorInterface $legacyUrlGenerator */ - $legacyUrlGenerator = $this->get('prestashop.core.admin.url_generator_legacy'); - $legacyContextProvider = $this->get('prestashop.adapter.legacy.context'); - $legacyContext = $legacyContextProvider->getContext(); - $moduleRepository = $this->get('prestashop.core.admin.module.repository'); - // Get accessed module object - $moduleAccessed = $moduleRepository->getModule($module_name); - - // Get current employee Id - $currentEmployeeId = $legacyContext->employee->id; - // Get accessed module DB Id - $moduleAccessedId = (int) $moduleAccessed->database->get('id'); - - // Save history for this module - $moduleHistory = $this->getDoctrine() - ->getRepository('PrestaShopBundle:ModuleHistory') - ->findOneBy( - [ - 'idEmployee' => $currentEmployeeId, - 'idModule' => $moduleAccessedId, - ] - ); - - if (null === $moduleHistory) { - $moduleHistory = new ModuleHistory(); - } - - $moduleHistory->setIdEmployee($currentEmployeeId); - $moduleHistory->setIdModule($moduleAccessedId); - $moduleHistory->setDateUpd(new DateTime()); - - $em = $this->getDoctrine()->getManager(); - $em->persist($moduleHistory); - $em->flush(); - - return $this->redirect( - $legacyUrlGenerator->generate( - 'admin_module_configure_action', - [ - // do not transmit limit & offset: go to the first page when redirecting - 'configure' => $module_name, - ] - ) - ); - } - - /** - * @AdminSecurity("is_granted(['read'], 'ADMINMODULESSF_')") - * - * @param Request $request - * - * @return Response - */ - public function getModuleCartAction($moduleId) - { - $moduleRepository = $this->get('prestashop.core.admin.module.repository'); - $module = $moduleRepository->getModuleById($moduleId); - - $addOnsAdminDataProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $addOnsAdminDataProvider->generateAddonsUrls( - AddonsCollection::createFrom([$module]) - ); - - $modulePresenter = $this->get('prestashop.adapter.presenter.module'); - $moduleToPresent = $modulePresenter->present($module); - - return $this->render( - '@PrestaShop/Admin/Module/Includes/modal_read_more_content.html.twig', - [ - 'module' => $moduleToPresent, - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - ] - ); - } - - /** - * Controller responsible for displaying "Catalog Module Grid" section of Module management pages with ajax. - * - * @param Request $request - * - * @return JsonResponse - */ - public function refreshCatalogAction(Request $request) - { - $deniedAccess = $this->checkPermissions( - [ - PageVoter::LEVEL_READ, - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_DELETE, - PageVoter::LEVEL_UPDATE, - ] - ); - if (null !== $deniedAccess) { - return $deniedAccess; - } - - $modulesProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $moduleRepository = $this->get('prestashop.core.admin.module.repository'); - $responseArray = []; - - $filters = new AddonListFilter(); - $filters->setType(AddonListFilterType::MODULE | AddonListFilterType::SERVICE) - ->setStatus(~AddonListFilterStatus::INSTALLED); - - try { - $modulesFromRepository = AddonsCollection::createFrom($moduleRepository->getFilteredList($filters)); - $modulesProvider->generateAddonsUrls($modulesFromRepository); - - $modules = $modulesFromRepository->toArray(); - shuffle($modules); - $categories = $this->getCategories($modulesProvider, $modules); - - $responseArray['domElements'][] = $this->constructJsonCatalogCategoriesMenuResponse($categories); - $responseArray['domElements'][] = $this->constructJsonCatalogBodyResponse( - $categories, - $modules - ); - $responseArray['status'] = true; - } catch (Exception $e) { - $responseArray['msg'] = $this->trans( - 'Cannot get catalog data, please try again later. Reason: %error_details%', - 'Admin.Modules.Notification', - ['%error_details%' => print_r($e->getMessage(), true)] - ); - $responseArray['status'] = false; - } - - return new JsonResponse($responseArray); - } - - /** - * @param Request $request - * - * @return JsonResponse - */ - public function moduleAction(Request $request) - { - $action = $request->get('action'); - - switch ($action) { - case ModuleAdapter::ACTION_UPGRADE: - case ModuleAdapter::ACTION_RESET: - case ModuleAdapter::ACTION_ENABLE: - case ModuleAdapter::ACTION_DISABLE: - case ModuleAdapter::ACTION_ENABLE_MOBILE: - case ModuleAdapter::ACTION_DISABLE_MOBILE: - $deniedAccess = $this->checkPermission(PageVoter::UPDATE); - break; - case ModuleAdapter::ACTION_INSTALL: - $deniedAccess = $this->checkPermission(PageVoter::CREATE); - break; - case ModuleAdapter::ACTION_UNINSTALL: - $deniedAccess = $this->checkPermission(PageVoter::DELETE); - break; - } - - if (null !== $deniedAccess) { - return $deniedAccess; - } - - if ($this->isDemoModeEnabled()) { - return $this->getDisabledFunctionalityResponse($request); - } - - $module = $request->get('module_name'); - $moduleManager = $this->container->get('prestashop.module.manager'); - $moduleManager->setActionParams($request->request->get('actionParams', [])); - $moduleRepository = $this->container->get('prestashop.core.admin.module.repository'); - $modulesProvider = $this->container->get('prestashop.core.admin.data_provider.module_interface'); - $response = [$module => []]; - - if (!method_exists($moduleManager, $action)) { - $response[$module]['status'] = false; - $response[$module]['msg'] = $this->trans('Invalid action', 'Admin.Notifications.Error'); - - return new JsonResponse($response); - } - - $actionTitle = str_replace('_', ' ', $action); - - try { - $response[$module]['status'] = $moduleManager->{$action}($module); - - if ($response[$module]['status'] === true) { - $response[$module]['msg'] = $this->trans( - '%action% action on module %module% succeeded.', - 'Admin.Modules.Notification', - [ - '%action%' => ucfirst($actionTitle), - '%module%' => $module, - ] - ); - - if ($action !== 'uninstall') { - $response[$module]['module_name'] = $module; - $response[$module]['is_configurable'] = (bool) $this - ->get('prestashop.core.admin.module.repository') - ->getModule($module) - ->attributes - ->get('is_configurable'); - } - } elseif ($response[$module]['status'] === false) { - $error = $moduleManager->getError($module); - $response[$module]['msg'] = $this->trans( - 'Cannot %action% module %module%. %error_details%', - 'Admin.Modules.Notification', - [ - '%action%' => $actionTitle, - '%module%' => $module, - '%error_details%' => $error, - ] - ); - } else { - $response[$module]['status'] = false; - $response[$module]['msg'] = $this->trans( - '%module% did not return a valid response on %action% action.', - 'Admin.Modules.Notification', - [ - '%module%' => $module, - '%action%' => $actionTitle, - ] - ); - } - } catch (UnconfirmedModuleActionException $e) { - $collection = AddonsCollection::createFrom([$e->getModule()]); - $modules = $modulesProvider->generateAddonsUrls($collection); - $response[$module] = array_replace( - $response[$module], - [ - 'status' => false, - 'confirmation_subject' => $e->getSubject(), - 'module' => $this - ->container - ->get('prestashop.adapter.presenter.module') - ->presentCollection($modules)[0], - 'msg' => $this->trans( - 'Confirmation needed by module %module% on %action% (%subject%).', - 'Admin.Modules.Notification', - [ - '%subject%' => $e->getSubject(), - '%action%' => $e->getAction(), - '%module%' => $module, - ] - ), - ] - ); - } catch (Exception $e) { - $response[$module]['status'] = false; - $response[$module]['msg'] = $this->trans( - 'Exception thrown by module %module% on %action%. %error_details%', - 'Admin.Modules.Notification', - [ - '%action%' => $actionTitle, - '%module%' => $module, - '%error_details%' => $e->getMessage(), - ] - ); - - $logger = $this->container->get('logger'); - $logger->error($response[$module]['msg']); - } - - if ($response[$module]['status'] === true && $action != 'uninstall') { - $moduleInstance = $moduleRepository->getModule($module); - $collection = AddonsCollection::createFrom([$moduleInstance]); - $response[$module]['action_menu_html'] = $this->container->get('templating')->render( - '@PrestaShop/Admin/Module/Includes/action_menu.html.twig', - [ - 'module' => $this->container->get('prestashop.adapter.presenter.module') - ->presentCollection($modulesProvider->generateAddonsUrls($collection))[0], - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - ] - ); - } - - return new JsonResponse($response); - } - - /** - * Controller responsible for importing new module from DropFile zone in BO. - * - * @param Request $request - * - * @return JsonResponse - */ - public function importModuleAction(Request $request) - { - if ($this->isDemoModeEnabled()) { - return new JsonResponse( - [ - 'status' => false, - 'msg' => $this->getDemoModeErrorMessage(), - ] - ); - } - - $deniedAccess = $this->checkPermissions( - [ - PageVoter::LEVEL_CREATE, - PageVoter::LEVEL_DELETE, - ] - ); - if (null !== $deniedAccess) { - return $deniedAccess; - } - - $moduleManager = $this->get('prestashop.module.manager'); - $moduleZipManager = $this->get('prestashop.module.zip.manager'); - - try { - $fileUploaded = $request->files->get('file_uploaded'); - $constraints = [ - new Assert\NotNull(), - new Assert\File( - [ - 'maxSize' => ini_get('upload_max_filesize'), - 'mimeTypes' => [ - 'application/zip', - 'application/x-gzip', - 'application/gzip', - 'application/x-gtar', - 'application/x-tgz', - ], - ] - ), - ]; - - $violations = $this->get('validator')->validate($fileUploaded, $constraints); - if (0 !== count($violations)) { - $violationsMessages = []; - foreach ($violations as $violation) { - $violationsMessages[] = $violation->getMessage(); - } - - throw new Exception(implode(PHP_EOL, $violationsMessages)); - } - - $moduleName = $moduleZipManager->getName($fileUploaded->getPathname()); - - // Install the module - $installationResponse = [ - 'status' => $moduleManager->install($fileUploaded->getPathname()), - 'msg' => '', - 'module_name' => $moduleName, - ]; - - if ($installationResponse['status'] === null) { - $installationResponse['status'] = false; - $installationResponse['msg'] = $this->trans( - '%module% did not return a valid response on installation.', - 'Admin.Modules.Notification', - ['%module%' => $moduleName] - ); - } elseif ($installationResponse['status'] === true) { - $installationResponse['msg'] = $this->trans( - 'Installation of module %module% was successful.', - 'Admin.Modules.Notification', - ['%module%' => $moduleName] - ); - $installationResponse['is_configurable'] = (bool) $this->get('prestashop.core.admin.module.repository') - ->getModule($moduleName) - ->attributes - ->get('is_configurable'); - } else { - $error = $moduleManager->getError($moduleName); - $installationResponse['msg'] = $this->trans( - 'Installation of module %module% failed. %error%', - 'Admin.Modules.Notification', - [ - '%module%' => $moduleName, - '%error%' => $error, - ] - ); - } - } catch (UnconfirmedModuleActionException $e) { - $collection = AddonsCollection::createFrom([$e->getModule()]); - $modules = $this->get('prestashop.core.admin.data_provider.module_interface') - ->generateAddonsUrls($collection); - $installationResponse = [ - 'status' => false, - 'confirmation_subject' => $e->getSubject(), - 'module' => $this->get('prestashop.adapter.presenter.module')->presentCollection($modules)[0], - 'msg' => $this->trans( - 'Confirmation needed by module %module% on %action% (%subject%).', - 'Admin.Modules.Notification', - [ - '%subject%' => $e->getSubject(), - '%action%' => $e->getAction(), - '%module%' => $moduleName, - ] - ), - ]; - } catch (Exception $e) { - if (isset($moduleName)) { - $moduleManager->disable($moduleName); - } - - $installationResponse = [ - 'status' => false, - 'msg' => $e->getMessage(), - ]; - } - - return new JsonResponse($installationResponse); - } - - private function getModulesByInstallation($modulesSelectList = null) - { - $addonsProvider = $this->get('prestashop.core.admin.data_provider.module_interface'); - $moduleRepository = $this->get('prestashop.core.admin.module.repository'); - $modulePresenter = $this->get('prestashop.adapter.presenter.module'); - $tabRepository = $this->get('prestashop.core.admin.tab.repository'); - - $modulesOnDisk = AddonsCollection::createFrom($moduleRepository->getList()); - - $modulesList = [ - 'installed' => [], - 'not_installed' => [], - ]; - - $modulesOnDisk = $addonsProvider->generateAddonsUrls($modulesOnDisk); - foreach ($modulesOnDisk as $module) { - if (!isset($modulesSelectList) || in_array($module->get('name'), $modulesSelectList)) { - $perm = true; - if ($module->get('id')) { - $perm &= Module::getPermissionStatic( - $module->get('id'), - 'configure', - $this->getContext()->employee - ); - } else { - $id_admin_module = $tabRepository->findOneIdByClassName('AdminModules'); - $access = Profile::getProfileAccess( - $this->getContext()->employee->id_profile, - $id_admin_module - ); - - $perm &= !$access['edit']; - } - - if ($module->get('author') === ModuleRepository::PARTNER_AUTHOR) { - $module->set('type', 'addonsPartner'); - } - - if ($perm) { - $module->fillLogo(); - if ($module->database->get('installed') == 1) { - $modulesList['installed'][] = $modulePresenter->present($module); - } else { - $modulesList['not_installed'][] = $modulePresenter->present($module); - } - } - } - } - - return $modulesList; - } - - private function getTopMenuData(array $topMenuData, $activeMenu = null) - { - if (isset($activeMenu)) { - if (!isset($topMenuData[$activeMenu])) { - throw new Exception(sprintf('Menu \'%s\' not found in Top Menu data', $activeMenu), 1); - } - - $topMenuData[$activeMenu]->class = 'active'; - } - - return $topMenuData; - } - - /** - * @param Request $request - * - * @return JsonResponse - */ - private function getDisabledFunctionalityResponse(Request $request) - { - $content = [ - $request->get('module_name') => [ - 'status' => false, - 'msg' => $this->getDemoModeErrorMessage(), - ], - ]; - - return new JsonResponse($content); - } - - /** - * Construct Json struct for catalog body response. - * - * @param array $categories - * @param array $modules - * - * @return array - */ - private function constructJsonCatalogBodyResponse( - array $categories, - array $modules - ) { - $formattedContent = []; - $formattedContent['selector'] = '.module-catalog-page'; - $formattedContent['content'] = $this->render( - '@PrestaShop/Admin/Module/Includes/sorting.html.twig', - [ - 'totalModules' => count($modules), - ] - )->getContent(); - - $errorMessage = $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'); - - $formattedContent['content'] .= $this->render( - '@PrestaShop/Admin/Module/catalog-refresh.html.twig', - [ - 'categories' => $categories['categories'], - 'requireAddonsSearch' => true, - 'level' => $this->authorizationLevel(self::CONTROLLER_NAME), - 'errorMessage' => $errorMessage, - ] - )->getContent(); - - return $formattedContent; - } - - /** - * Construct json struct from top menu. - * - * @param array $categories - * - * @return array - */ - private function constructJsonCatalogCategoriesMenuResponse(array $categories) - { - $formattedContent = []; - $formattedContent['selector'] = '.module-menu-item'; - $formattedContent['content'] = $this->render( - '@PrestaShop/Admin/Module/Includes/dropdown_categories_catalog.html.twig', - [ - 'topMenuData' => $this->getTopMenuData($categories), - ] - )->getContent(); - - return $formattedContent; - } - - /** - * Check user permission. - * - * @param array $pageVoter - * - * @return void|JsonResponse - */ - private function checkPermissions(array $pageVoter) - { - if (!in_array( - $this->authorizationLevel(self::CONTROLLER_NAME), - $pageVoter - ) - ) { - return new JsonResponse( - [ - 'status' => false, - 'msg' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), - ] - ); - } - } - - /** - * @param string $pageVoter - * - * @return JsonResponse - */ - private function checkPermission($pageVoter) - { - if (!$this->isGranted($pageVoter, self::CONTROLLER_NAME)) { - return new JsonResponse( - [ - 'status' => false, - 'msg' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), - ] - ); - } - } - - /** - * Get categories and its modules. - * - * @param array $modules List of installed modules - * - * @return array - */ - private function getCategories(AdminModuleDataProvider $modulesProvider, array $modules) - { - /** @var CategoriesProvider */ - $categories = $this->get('prestashop.categories_provider')->getCategoriesMenu($modules); - - foreach ($categories['categories']->subMenu as $category) { - $collection = AddonsCollection::createFrom($category->modules); - $modulesProvider->generateAddonsUrls($collection); - $category->modules = $this->get('prestashop.adapter.presenter.module') - ->presentCollection($category->modules); - } - - return $categories; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AddonsStoreController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AddonsStoreController.php deleted file mode 100644 index 2e25c677..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AddonsStoreController.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Modules; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Request; - -/** - * Responsible of "Improve > Modules > Modules Catalog" page display. - */ -class AddonsStoreController extends FrameworkBundleAdminController -{ - /** - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function indexAction(Request $request) - { - $pageContent = @file_get_contents($this->getAddonsUrl($request)); - - if (!$pageContent) { - $this->addFlash('error', $this->trans( - 'It looks like we have trouble connecting to Addons. Please refresh the page or check your firewall configuration.', - 'Admin.Notifications.Error' - )); - - return $this->redirectToRoute('admin_module_catalog'); - } - - return $this->render('@PrestaShop/Admin/Improve/Module/addons_store.html.twig', [ - 'pageContent' => $pageContent, - 'layoutHeaderToolbarBtn' => [], - 'layoutTitle' => $this->trans('Module selection', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'requireBulkActions' => false, - 'showContentHeader' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'requireFilterStatus' => false, - 'level' => $this->authorizationLevel($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * @param Request $request - * - * @return string - */ - private function getAddonsUrl(Request $request) - { - $psVersion = $this->get('prestashop.core.foundation.version')->getVersion(); - $parent_domain = $request->getSchemeAndHttpHost(); - $context = $this->getContext(); - $currencyCode = $context->currency->iso_code; - $languageCode = $context->language->iso_code; - $countryCode = $context->country->iso_code; - $activity = (int) $this->get('prestashop.adapter.legacy.configuration')->get('PS_SHOP_ACTIVITY'); - - // GET parameters are concatenated this way in order to ensure they are not encoded - return "https://addons.prestashop.com/iframe/search-1.7.php?psVersion=$psVersion&isoLang=$languageCode&isoCurrency=$currencyCode&isoCountry=$countryCode&activity=$activity&parentUrl=$parent_domain"; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AlertsController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AlertsController.php deleted file mode 100644 index 35538e8c..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/AlertsController.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Modules; - -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Improve > Modules > Modules & Services > Alerts" page display. - */ -class AlertsController extends ModuleAbstractController -{ - /** - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @return Response - */ - public function indexAction() - { - return $this->render( - '@PrestaShop/Admin/Module/alerts.html.twig', - $this->getNotificationPageData('to_configure') - ); - } - - /** - * @return JsonResponse with number of modules having at least one notification - */ - public function notificationsCountAction() - { - return new JsonResponse( - $this->get('prestashop.module.manager') - ->countModulesWithNotificationsDetailed() - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/ModuleAbstractController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Modules/ModuleAbstractController.php deleted file mode 100644 index 77f7c205..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/ModuleAbstractController.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Modules; - -use PrestaShop\PrestaShop\Core\Addon\AddonsCollection; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Voter\PageVoter; - -abstract class ModuleAbstractController extends FrameworkBundleAdminController -{ - const CONTROLLER_NAME = 'ADMINMODULESSF'; - - /** - * Common method of alerts & updates routes for getting template variables. - * - * @param string $type Type of alert to display (to_configure / to_update ...) - * - * @return array - */ - protected function getNotificationPageData($type) - { - $modulePresenter = $this->get('prestashop.adapter.presenter.module'); - $modulesPresenterCallback = function (AddonsCollection &$modules) use ($modulePresenter) { - return $modulePresenter->presentCollection($modules); - }; - - $moduleManager = $this->get('prestashop.module.manager'); - $modules = $moduleManager->getModulesWithNotifications($modulesPresenterCallback); - - return [ - 'enableSidebar' => true, - 'layoutHeaderToolbarBtn' => $this->getToolbarButtons(), - 'layoutTitle' => $this->trans('Module notifications', 'Admin.Modules.Feature'), - 'help_link' => $this->generateSidebarLink('AdminModules'), - 'modules' => $modules->{$type}, - 'requireAddonsSearch' => false, - 'requireBulkActions' => false, - 'requireFilterStatus' => false, - 'level' => $this->authorizationLevel($this::CONTROLLER_NAME), - 'errorMessage' => $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'), - ]; - } - - /** - * Common method for all module related controller for getting the header buttons. - * - * @return array - */ - protected function getToolbarButtons() - { - // toolbarButtons - $toolbarButtons = []; - - if (!in_array( - $this->authorizationLevel($this::CONTROLLER_NAME), - [ - PageVoter::LEVEL_READ, - PageVoter::LEVEL_UPDATE, - ] - )) { - $toolbarButtons['add_module'] = [ - 'href' => '#', - 'desc' => $this->trans('Upload a module', 'Admin.Modules.Feature'), - 'icon' => 'cloud_upload', - 'help' => $this->trans('Upload a module', 'Admin.Modules.Feature'), - ]; - } - - return array_merge($toolbarButtons, $this->getAddonsConnectToolbar()); - } - - /** - * Create a button in the header for the marketplace account (login or logout). - * - * @return array - */ - protected function getAddonsConnectToolbar() - { - $addonsProvider = $this->get('prestashop.core.admin.data_provider.addons_interface'); - if ($addonsProvider->isAddonsAuthenticated()) { - $addonsEmail = $addonsProvider->getAddonsEmail(); - - return [ - 'addons_logout' => [ - 'href' => '#', - 'desc' => $addonsEmail['username_addons'], - 'icon' => 'exit_to_app', - 'help' => $this->trans('Synchronized with Addons marketplace!', 'Admin.Modules.Notification'), - ], - ]; - } - - return [ - 'addons_connect' => [ - 'href' => '#', - 'desc' => $this->trans('Connect to Addons marketplace', 'Admin.Modules.Feature'), - 'icon' => 'vpn_key', - 'help' => $this->trans('Connect to Addons marketplace', 'Admin.Modules.Feature'), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/UpdatesController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Modules/UpdatesController.php deleted file mode 100644 index 0dbaf9d4..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Modules/UpdatesController.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Modules; - -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible of "Improve > Modules > Modules & Services > Updates" page display. - */ -class UpdatesController extends ModuleAbstractController -{ - /** - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @return Response - */ - public function indexAction() - { - return $this->render( - '@PrestaShop/Admin/Module/updates.html.twig', - $this->getNotificationPageData('to_update') - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentMethodsController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentMethodsController.php deleted file mode 100644 index d395a3a3..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentMethodsController.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Payment; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class PaymentMethodsController is responsible for 'Improve > Payment > Payment Methods' page. - */ -class PaymentMethodsController extends FrameworkBundleAdminController -{ - /** - * Show payment method modules. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $shopContext = $this->get('prestashop.adapter.shop.context'); - $isSingleShopContext = $shopContext->isSingleShopContext(); - $paymentModules = []; - - if ($isSingleShopContext) { - $paymentMethodsPresenter = $this->get('prestashop.adapter.module.presenter.payment'); - $paymentModules = $paymentMethodsPresenter->present(); - } - - return $this->render('@PrestaShop/Admin/Improve/Payment/PaymentMethods/payment_methods.html.twig', [ - 'paymentModules' => $paymentModules, - 'isSingleShopContext' => $isSingleShopContext, - 'layoutTitle' => $this->trans('Payment Methods', 'Admin.Navigation.Menu'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - ]); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentPreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentPreferencesController.php deleted file mode 100644 index 866d92ad..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Payment/PaymentPreferencesController.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Payment; - -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class PaymentPreferencesController is responsible for "Improve > Payment > Preferences" page. - */ -class PaymentPreferencesController extends FrameworkBundleAdminController -{ - /** - * Show payment preferences page. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * message="Access denied." - * ) - * - * @param Request $request - * - * @return Response - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $paymentModulesListProvider = $this->get('prestashop.adapter.module.payment_module_provider'); - $shopContext = $this->get('prestashop.adapter.shop.context'); - - $isSingleShopContext = $shopContext->isSingleShopContext(); - - $paymentPreferencesForm = null; - $paymentModulesCount = 0; - - if ($isSingleShopContext) { - $paymentModulesCount = count($paymentModulesListProvider->getPaymentModuleList()); - $paymentPreferencesForm = $this->getPaymentPreferencesFormHandler()->getForm()->createView(); - } - - return $this->render('@PrestaShop/Admin/Improve/Payment/Preferences/payment_preferences.html.twig', [ - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'paymentPreferencesForm' => $paymentPreferencesForm, - 'isSingleShopContext' => $isSingleShopContext, - 'paymentModulesCount' => $paymentModulesCount, - ]); - } - - /** - * Process payment modules preferences form. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="Access denied.", - * redirectRoute="admin_payment_preferences" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $paymentPreferencesFormHandler = $this->getPaymentPreferencesFormHandler(); - - $paymentPreferencesForm = $paymentPreferencesFormHandler->getForm(); - $paymentPreferencesForm->handleRequest($request); - - if ($paymentPreferencesForm->isSubmitted()) { - $paymentPreferences = $paymentPreferencesForm->getData(); - - $errors = $paymentPreferencesFormHandler->save($paymentPreferences); - if (empty($errors)) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_payment_preferences'); - } - - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_payment_preferences'); - } - - /** - * @return FormHandlerInterface - */ - private function getPaymentPreferencesFormHandler() - { - return $this->get('prestashop.admin.payment_preferences.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php b/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php deleted file mode 100644 index 93c2ee8c..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Improve/Shipping/PreferencesController.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Improve\Shipping; - -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; - -/** - * Controller responsible of "Improve > Shipping > Preferences" page. - */ -class PreferencesController extends FrameworkBundleAdminController -{ - /** - * Show shipping preferences page. - * - * @param Request $request - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return array Template parameters - */ - public function indexAction(Request $request) - { - $legacyController = $request->attributes->get('_legacy_controller'); - - $form = $this->get('prestashop.admin.shipping_preferences.form_handler')->getForm(); - - return $this->render('@PrestaShop/Admin/Improve/Shipping/Preferences/preferences.html.twig', [ - 'layoutTitle' => $this->trans('Preferences', 'Admin.Navigation.Menu'), - 'requireAddonsSearch' => true, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($legacyController), - 'form' => $form->createView(), - ]); - } - - /** - * Handle form submit. - * - * @AdminSecurity("is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_shipping_preferences") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function processFormAction(Request $request) - { - $formHandler = $this->get('prestashop.admin.shipping_preferences.form_handler'); - - $form = $formHandler->getForm(); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - if ($errors = $formHandler->save($form->getData())) { - $this->flashErrors($errors); - } else { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } - } - - return $this->redirectToRoute('admin_shipping_preferences'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/ProductController.php b/src/PrestaShopBundle/Controller/Admin/ProductController.php deleted file mode 100644 index 72673fbd..00000000 --- a/src/PrestaShopBundle/Controller/Admin/ProductController.php +++ /dev/null @@ -1,1307 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Category; -use Exception; -use PrestaShop\PrestaShop\Adapter\Product\ListParametersUpdater; -use PrestaShop\PrestaShop\Adapter\Tax\TaxRuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Warehouse\WarehouseDataProvider; -use PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\CannotUpdateProductException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductException; -use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductIsEnabled; -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Entity\AdminFilter; -use PrestaShopBundle\Exception\UpdateProductException; -use PrestaShopBundle\Form\Admin\Product\ProductCategories; -use PrestaShopBundle\Form\Admin\Product\ProductCombination; -use PrestaShopBundle\Form\Admin\Product\ProductCombinationBulk; -use PrestaShopBundle\Form\Admin\Product\ProductInformation; -use PrestaShopBundle\Form\Admin\Product\ProductOptions; -use PrestaShopBundle\Form\Admin\Product\ProductPrice; -use PrestaShopBundle\Form\Admin\Product\ProductQuantity; -use PrestaShopBundle\Form\Admin\Product\ProductSeo; -use PrestaShopBundle\Form\Admin\Product\ProductShipping; -use PrestaShopBundle\Model\Product\AdminModelAdapter; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Voter\PageVoter; -use PrestaShopBundle\Service\DataProvider\Admin\ProductInterface as ProductInterfaceProvider; -use PrestaShopBundle\Service\DataProvider\StockInterface; -use PrestaShopBundle\Service\DataUpdater\Admin\ProductInterface as ProductInterfaceUpdater; -use PrestaShopBundle\Service\Hook\HookFinder; -use Product; -use Psr\Log\LoggerInterface; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Form; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\File\UploadedFile; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Tools; - -/** - * Admin controller for the Product pages using the Symfony architecture: - * - categories - * - product list - * - product details - * - product attributes - * - ... - * - * This controller is the first one to be refactored to the new Symfony Architecture. - * The retro-compatibility is dropped for the corresponding Admin pages. - * A set of hooks are integrated and an Adapter is made to wrap the new EventDispatcher - * component to the existing hook system. So existing hooks are always triggered, but from the new - * code (and so needs to be adapted on the module side ton comply on the new parameters formats, - * the new UI style, etc...). - */ -class ProductController extends FrameworkBundleAdminController -{ - /** - * Used to validate connected user authorizations. - */ - const PRODUCT_OBJECT = 'ADMINPRODUCTS_'; - - /** - * Get the Catalog page with KPI banner, product list, bulk actions, filters, search, etc... - * - * URL example: /product/catalog/40/20/id_product/asc - * - * @Template("@PrestaShop/Admin/Product/CatalogPage/catalog.html.twig") - * - * @param Request $request - * @param int $limit The size of the listing - * @param int $offset The offset of the listing - * @param string $orderBy To order product list - * @param string $sortOrder To order product list - * - * @return array|Template|RedirectResponse|Response - * - * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException - * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException - * @throws \LogicException - * @throws \Symfony\Component\Routing\Exception\MissingMandatoryParametersException - * @throws \Symfony\Component\Routing\Exception\InvalidParameterException - * @throws \Symfony\Component\Form\Exception\LogicException - * @throws \Symfony\Component\Form\Exception\AlreadySubmittedException - */ - public function catalogAction( - Request $request, - $limit = 10, - $offset = 0, - $orderBy = 'id_product', - $sortOrder = 'desc' - ) { - if (!$this->isGranted([PageVoter::READ, PageVoter::UPDATE, PageVoter::CREATE], self::PRODUCT_OBJECT)) { - return $this->redirect('admin_dashboard'); - } - - $language = $this->getContext()->language; - $request->getSession()->set('_locale', $language->locale); - $request = $this->get('prestashop.adapter.product.filter_categories_request_purifier')->purify($request); - - /** @var $productProvider ProductInterfaceProvider */ - $productProvider = $this->get('prestashop.core.admin.data_provider.product_interface'); - - // Set values from persistence and replace in the request - $persistedFilterParameters = $productProvider->getPersistedFilterParameters(); - /** @var ListParametersUpdater $listParametersUpdater */ - $listParametersUpdater = $this->get('prestashop.adapter.product.list_parameters_updater'); - $listParameters = $listParametersUpdater->buildListParameters( - $request->query->all(), - $persistedFilterParameters, - compact('offset', 'limit', 'orderBy', 'sortOrder') - ); - $offset = $listParameters['offset']; - $limit = $listParameters['limit']; - $orderBy = $listParameters['orderBy']; - $sortOrder = $listParameters['sortOrder']; - - //The product provider performs the same merge internally, so we do the same so that the displayed filters are - //consistent with the request ones - $combinedFilterParameters = array_replace($persistedFilterParameters, $request->request->all()); - - $toolbarButtons = $this->getToolbarButtons(); - - // Fetch product list (and cache it into view subcall to listAction) - $products = $productProvider->getCatalogProductList( - $offset, - $limit, - $orderBy, - $sortOrder, - $request->request->all() - ); - $lastSql = $productProvider->getLastCompiledSql(); - - $hasCategoryFilter = $productProvider->isCategoryFiltered(); - $hasColumnFilter = $productProvider->isColumnFiltered(); - $totalFilteredProductCount = (count($products) > 0) ? $products[0]['total'] : 0; - // Alternative layout for empty list - if ((!$hasCategoryFilter && !$hasColumnFilter && $totalFilteredProductCount === 0) - || ($totalProductCount = $productProvider->countAllProducts()) === 0 - ) { - // no filter, total filtered == 0, and then total count == 0 too. - $legacyUrlGenerator = $this->get('prestashop.core.admin.url_generator_legacy'); - - return $this->render( - '@PrestaShop/Admin/Product/CatalogPage/catalog_empty.html.twig', - [ - 'layoutHeaderToolbarBtn' => $toolbarButtons, - 'import_url' => $legacyUrlGenerator->generate('AdminImport'), - ] - ); - } - - // Pagination - $paginationParameters = $request->attributes->all(); - $paginationParameters['_route'] = 'admin_product_catalog'; - $categoriesForm = $this->createForm(ProductCategories::class); - if (!empty($persistedFilterParameters['filter_category'])) { - $categoriesForm->setData( - [ - 'categories' => [ - 'tree' => [0 => $combinedFilterParameters['filter_category']], - ], - ] - ); - } - - $cleanFilterParameters = $listParametersUpdater->cleanFiltersForPositionOrdering( - $combinedFilterParameters, - $orderBy, - $hasCategoryFilter - ); - - $permissionError = null; - if ($this->get('session')->getFlashBag()->has('permission_error')) { - $permissionError = $this->get('session')->getFlashBag()->get('permission_error')[0]; - } - - $categoriesFormView = $categoriesForm->createView(); - $selectedCategory = !empty($combinedFilterParameters['filter_category']) ? new Category($combinedFilterParameters['filter_category']) : null; - - //Drag and drop is ONLY activated when EXPLICITLY requested by the user - //Meaning a category is selected and the user clicks on REORDER button - $activateDragAndDrop = 'position_ordering' === $orderBy && $hasCategoryFilter; - - // Template vars injection - return array_merge( - $cleanFilterParameters, - [ - 'limit' => $limit, - 'offset' => $offset, - 'orderBy' => $orderBy, - 'sortOrder' => $sortOrder, - 'has_filter' => $hasCategoryFilter || $hasColumnFilter, - 'has_category_filter' => $hasCategoryFilter, - 'selected_category' => $selectedCategory, - 'has_column_filter' => $hasColumnFilter, - 'products' => $products, - 'last_sql' => $lastSql, - 'product_count_filtered' => $totalFilteredProductCount, - 'product_count' => $totalProductCount, - 'activate_drag_and_drop' => $activateDragAndDrop, - 'pagination_parameters' => $paginationParameters, - 'layoutHeaderToolbarBtn' => $toolbarButtons, - 'categories' => $categoriesFormView, - 'pagination_limit_choices' => $productProvider->getPaginationLimitChoices(), - 'import_link' => $this->generateUrl('admin_import', ['import_type' => 'products']), - 'sql_manager_add_link' => $this->generateUrl('admin_sql_requests_create'), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink('AdminProducts'), - 'is_shop_context' => $this->get('prestashop.adapter.shop.context')->isShopContext(), - 'permission_error' => $permissionError, - 'layoutTitle' => $this->trans('Products', 'Admin.Global'), - ] - ); - } - - /** - * Get only the list of products to display on the main Admin Product page. - * The full page that shows products list will subcall this action (from catalogAction). - * URL example: /product/list/html/40/20/id_product/asc. - * - * @Template("@PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig") - * - * @param Request $request - * @param int $limit The size of the listing - * @param int $offset The offset of the listing - * @param string $orderBy To order product list - * @param string $sortOrder To order product list - * @param string $view full|quicknav To change default template used to render the content - * - * @return array|Template|Response - */ - public function listAction( - Request $request, - $limit = 10, - $offset = 0, - $orderBy = 'id_product', - $sortOrder = 'asc', - $view = 'full' - ) { - if (!$this->isGranted([PageVoter::READ], self::PRODUCT_OBJECT)) { - return $this->redirect('admin_dashboard'); - } - - /** @var $productProvider ProductInterfaceProvider */ - $productProvider = $this->get('prestashop.core.admin.data_provider.product_interface'); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - $totalCount = 0; - - $this->get('prestashop.service.product')->cleanupOldTempProducts(); - - $products = $request->attributes->get('products', null); // get from action subcall data, if any - $lastSql = $request->attributes->get('last_sql', null); // get from action subcall data, if any - - if ($products === null) { - // get old values from persistence (before the current update) - $persistedFilterParameters = $productProvider->getPersistedFilterParameters(); - /** @var ListParametersUpdater $listParametersUpdater */ - $listParametersUpdater = $this->get('prestashop.adapter.product.list_parameters_updater'); - $listParameters = $listParametersUpdater->buildListParameters( - $request->query->all(), - $persistedFilterParameters, - compact('offset', 'limit', 'orderBy', 'sortOrder') - ); - $offset = $listParameters['offset']; - $limit = $listParameters['limit']; - $orderBy = $listParameters['orderBy']; - $sortOrder = $listParameters['sortOrder']; - - /** - * 2 hooks are triggered here: - * - actionAdminProductsListingFieldsModifier - * - actionAdminProductsListingResultsModifier. - */ - $products = $productProvider->getCatalogProductList($offset, $limit, $orderBy, $sortOrder); - $lastSql = $productProvider->getLastCompiledSql(); - } - - $hasCategoryFilter = $productProvider->isCategoryFiltered(); - - // Adds controller info (URLs, etc...) to product list - foreach ($products as &$product) { - $totalCount = isset($product['total']) ? $product['total'] : $totalCount; - $product['url'] = $this->generateUrl( - 'admin_product_form', - ['id' => $product['id_product']] - ); - $product['unit_action_url'] = $this->generateUrl( - 'admin_product_unit_action', - [ - 'action' => 'duplicate', - 'id' => $product['id_product'], - ] - ); - $product['preview_url'] = $adminProductWrapper->getPreviewUrlFromId($product['id_product']); - } - - //Drag and drop is ONLY activated when EXPLICITLY requested by the user - //Meaning a category is selected and the user clicks on REORDER button - $activateDragAndDrop = 'position_ordering' === $orderBy && $hasCategoryFilter; - - // Template vars injection - $vars = [ - 'activate_drag_and_drop' => $activateDragAndDrop, - 'products' => $products, - 'product_count' => $totalCount, - 'last_sql_query' => $lastSql, - 'has_category_filter' => $productProvider->isCategoryFiltered(), - 'is_shop_context' => $this->get('prestashop.adapter.shop.context')->isShopContext(), - ]; - if ($view !== 'full') { - return $this->render( - '@Product/CatalogPage/Lists/list_' . $view . '.html.twig', - array_merge( - $vars, - [ - 'limit' => $limit, - 'offset' => $offset, - 'total' => $totalCount, - ] - ) - ); - } - - return $vars; - } - - /** - * Gets the header toolbar buttons. - * - * @return array - */ - private function getToolbarButtons() - { - $toolbarButtons = []; - $toolbarButtons['add'] = [ - 'href' => $this->generateUrl('admin_product_new'), - 'desc' => $this->trans('New product', 'Admin.Actions'), - 'icon' => 'add_circle_outline', - 'help' => $this->trans('Create a new product: CTRL+P', 'Admin.Catalog.Help'), - ]; - - return $toolbarButtons; - } - - /** - * Create a new basic product - * Then return to form action. - * - * @return RedirectResponse - * - * @throws \LogicException - * @throws \PrestaShopException - */ - public function newAction() - { - if (!$this->isGranted(PageVoter::CREATE, self::PRODUCT_OBJECT)) { - $errorMessage = $this->trans('You do not have permission to add this.', 'Admin.Notifications.Error'); - $this->get('session')->getFlashBag()->add('permission_error', $errorMessage); - - return $this->redirectToRoute('admin_product_catalog'); - } - - $productProvider = $this->get('prestashop.core.admin.data_provider.product_interface'); - $languages = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - - /** @var $productProvider ProductInterfaceProvider */ - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $productShopCategory = $this->getContext()->shop->id_category; - - /** @var Product $product */ - $product = $productAdapter->getProductInstance(); - $product->id_category_default = $productShopCategory; - - /** @var TaxRuleDataProvider $taxRuleDataProvider */ - $taxRuleDataProvider = $this->get('prestashop.adapter.data_provider.tax'); - $product->id_tax_rules_group = $taxRuleDataProvider->getIdTaxRulesGroupMostUsed(); - $product->active = $productProvider->isNewProductDefaultActivated() ? 1 : 0; - $product->state = Product::STATE_TEMP; - - //set name and link_rewrite in each lang - foreach ($languages as $lang) { - $product->name[$lang['id_lang']] = ''; - $product->link_rewrite[$lang['id_lang']] = ''; - } - - $product->save(); - $product->addToCategories([$productShopCategory]); - - return $this->redirectToRoute('admin_product_form', ['id' => $product->id]); - } - - /** - * Product form. - * - * @Template("@PrestaShop/Admin/Product/ProductPage/product.html.twig") - * - * @param int $id The product ID - * @param Request $request - * - * @return array|Response Template vars - * - * @throws \LogicException - */ - public function formAction($id, Request $request) - { - gc_disable(); - - if (!$this->isGranted([PageVoter::READ, PageVoter::UPDATE, PageVoter::CREATE], self::PRODUCT_OBJECT)) { - return $this->redirect('admin_dashboard'); - } - - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $product = $productAdapter->getProduct($id); - - if (!$product || empty($product->id)) { - return $this->redirectToRoute('admin_product_catalog'); - } - - $shopContext = $this->get('prestashop.adapter.shop.context'); - $legacyContextService = $this->get('prestashop.adapter.legacy.context'); - $isMultiShopContext = count($shopContext->getContextListShopID()) > 1; - - $modelMapper = $this->get('prestashop.adapter.admin.model.product'); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - - $form = $this->createProductForm($product, $modelMapper); - - $formBulkCombinations = $this->createForm( - ProductCombinationBulk::class, - null, - [ - 'iso_code' => $this - ->get('prestashop.adapter.legacy.context') - ->getContext()->currency->iso_code, - ] - ); - - // Legacy code. To fix when Object model will change. But report Hooks. - $postData = $request->request->all(); - $combinationsList = []; - if (!empty($postData)) { - foreach ($postData as $postKey => $postValue) { - if (preg_match('/^combination_.*/', $postKey)) { - $combinationsList[$postKey] = $postValue; - $postData['form'][$postKey] = $postValue; // need to validate the form - } - } - - // Duplicate Request to be a valid form (like it was real) with postData modified .. - $request = $request->duplicate( - $request->query->all(), - $postData, - $request->attributes->all(), - $request->cookies->all(), - $request->files->all(), - $request->server->all() - ); - } - - /* @var Form $form */ - $form->handleRequest($request); - $formData = $form->getData(); - $formData['step3']['combinations'] = $combinationsList; - - try { - if ($form->isSubmitted()) { - if ($this->isDemoModeEnabled() && $request->isXmlHttpRequest()) { - $errorMessage = $this->getDemoModeErrorMessage(); - - return $this->returnErrorJsonResponse( - ['error' => [$errorMessage]], - Response::HTTP_SERVICE_UNAVAILABLE - ); - } - - if ($form->isValid()) { - //define POST values for keeping legacy adminController skills - $_POST = $modelMapper->getModelData($formData, $isMultiShopContext) + $_POST; - $_POST['form'] = $formData; - $_POST['state'] = Product::STATE_SAVED; - - $adminProductController = $adminProductWrapper->getInstance(); - $adminProductController->setIdObject($formData['id_product']); - $adminProductController->setAction('save'); - - // Hooks: this will trigger legacy AdminProductController, postProcess(): - // actionAdminSaveBefore; actionAdminProductsControllerSaveBefore - // actionProductAdd or actionProductUpdate (from processSave() -> processAdd() or processUpdate()) - // actionAdminSaveAfter; actionAdminProductsControllerSaveAfter - $productSaveResult = $adminProductController->postCoreProcess(); - - if (false == $productSaveResult) { - return $this->returnErrorJsonResponse( - ['error' => $adminProductController->errors], - Response::HTTP_BAD_REQUEST - ); - } - - $product = $productSaveResult; - - /* @var Product $product */ - $adminProductController->processSuppliers($product->id); - $adminProductController->processFeatures($product->id); - $adminProductController->processSpecificPricePriorities(); - foreach ($_POST['combinations'] as $combinationValues) { - $adminProductWrapper->processProductAttribute($product, $combinationValues); - // For now, each attribute set the same value. - $adminProductWrapper->processDependsOnStock( - $product, - ($_POST['depends_on_stock'] == '1'), - $combinationValues['id_product_attribute'] - ); - } - $adminProductWrapper->processDependsOnStock($product, ($_POST['depends_on_stock'] == '1')); - - // If there is no combination, then quantity and location are managed for the whole product (as combination ID 0) - // In all cases, legacy hooks are triggered: actionProductUpdate and actionUpdateQuantity - if (count($_POST['combinations']) === 0 && isset($_POST['qty_0'])) { - $adminProductWrapper->processQuantityUpdate($product, $_POST['qty_0']); - $adminProductWrapper->processLocation($product, (string) $_POST['location']); - } - // else quantities are managed from $adminProductWrapper->processProductAttribute() above. - - $adminProductWrapper->processProductOutOfStock($product, $_POST['out_of_stock']); - - $customizationFieldsIds = $adminProductWrapper - ->processProductCustomization($product, $_POST['custom_fields']); - - $adminProductWrapper->processAttachments($product, $_POST['attachments']); - - $adminProductController->processWarehouses(); - - $response = new JsonResponse(); - $response->setData([ - 'product' => $product, - 'customization_fields_ids' => $customizationFieldsIds, - ]); - - if ($request->isXmlHttpRequest()) { - return $response; - } - } elseif ($request->isXmlHttpRequest()) { - return $this->returnErrorJsonResponse( - $this->getFormErrorsForJS($form), - Response::HTTP_BAD_REQUEST - ); - } - } - } catch (Exception $e) { - // this controller can be called as an AJAX JSON route or a HTML page - // so we need to return the right type of response if an exception it thrown - if ($request->isXmlHttpRequest()) { - return $this->returnErrorJsonResponse( - [], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - - throw $e; - } - - /** @var $stockManager StockInterface */ - $stockManager = $this->get('prestashop.core.data_provider.stock_interface'); - - /** @var WarehouseDataProvider $warehouseProvider */ - $warehouseProvider = $this->get('prestashop.adapter.data_provider.warehouse'); - - //If context shop is define to a group shop, disable the form - if ($shopContext->isShopGroupContext()) { - return $this->render('@Product/ProductPage/disabled_form_alert.html.twig', ['showContentHeader' => false]); - } - - // languages for switch dropdown - $languages = $legacyContextService->getLanguages(); - - // generate url preview - if ($product->active) { - $preview_url = $adminProductWrapper->getPreviewUrl($product); - $preview_url_deactive = $adminProductWrapper->getPreviewUrlDeactivate($preview_url); - } else { - $preview_url_deactive = $adminProductWrapper->getPreviewUrl($product, false); - $preview_url = $adminProductWrapper->getPreviewUrlDeactivate($preview_url_deactive); - } - - $doctrine = $this->getDoctrine()->getManager(); - $language = empty($languages[0]) ? ['id_lang' => 1, 'id_shop' => 1] : $languages[0]; - $attributeGroups = $doctrine->getRepository('PrestaShopBundle:Attribute')->findByLangAndShop((int) $language['id_lang'], (int) $language['id_shop']); - - $drawerModules = (new HookFinder())->setHookName('displayProductPageDrawer') - ->setParams(['product' => $product]) - ->addExpectedInstanceClasses('PrestaShop\PrestaShop\Core\Product\ProductAdminDrawer') - ->present(); - - return [ - 'form' => $form->createView(), - 'formCombinations' => $formBulkCombinations->createView(), - 'categories' => $this->get('prestashop.adapter.data_provider.category')->getCategoriesWithBreadCrumb(), - 'id_product' => $id, - 'ids_product_attribute' => (isset($formData['step3']['id_product_attributes']) ? implode(',', $formData['step3']['id_product_attributes']) : ''), - 'has_combinations' => (isset($formData['step3']['id_product_attributes']) && count($formData['step3']['id_product_attributes']) > 0), - 'combinations_count' => isset($formData['step3']['id_product_attributes']) ? count($formData['step3']['id_product_attributes']) : 0, - 'asm_globally_activated' => $stockManager->isAsmGloballyActivated(), - 'warehouses' => ($stockManager->isAsmGloballyActivated()) ? $warehouseProvider->getWarehouses() : [], - 'is_multishop_context' => $isMultiShopContext, - 'is_combination_active' => $this->get('prestashop.adapter.legacy.configuration')->combinationIsActive(), - 'showContentHeader' => false, - 'seo_link' => $adminProductWrapper->getPreviewUrl($product, false), - 'preview_link' => $preview_url, - 'preview_link_deactivate' => $preview_url_deactive, - 'stats_link' => $this->getAdminLink('AdminStats', ['module' => 'statsproduct', 'id_product' => $id]), - 'help_link' => $this->generateSidebarLink('AdminProducts'), - 'languages' => $languages, - 'default_language_iso' => $languages[0]['iso_code'], - 'attribute_groups' => $attributeGroups, - 'max_upload_size' => Tools::formatBytes(UploadedFile::getMaxFilesize()), - 'is_shop_context' => $this->get('prestashop.adapter.shop.context')->isShopContext(), - 'editable' => $this->isGranted(PageVoter::UPDATE, self::PRODUCT_OBJECT), - 'drawerModules' => $drawerModules, - 'layoutTitle' => $this->trans('Product', 'Admin.Global'), - ]; - } - - /** - * Builds the product form. - * - * @param Product $product - * @param AdminModelAdapter $modelMapper - * - * @return FormInterface - * - * @throws \Symfony\Component\Process\Exception\LogicException - */ - private function createProductForm(Product $product, AdminModelAdapter $modelMapper) - { - $formBuilder = $this->createFormBuilder( - $modelMapper->getFormData($product), - ['allow_extra_fields' => true] - ) - ->add('id_product', HiddenType::class) - ->add('step1', ProductInformation::class) - ->add('step2', ProductPrice::class, ['id_product' => $product->id]) - ->add('step3', ProductQuantity::class) - ->add('step4', ProductShipping::class) - ->add('step5', ProductSeo::class, [ - 'mapping_type' => $product->getRedirectType(), - ]) - ->add('step6', ProductOptions::class); - - // Prepare combination form (fake but just to validate the form) - $combinations = $product->getAttributesResume( - $this->getContext()->language->id - ); - - if (is_array($combinations)) { - $maxInputVars = (int) ini_get('max_input_vars'); - $combinationsCount = count($combinations) * 25; - $combinationsInputs = ceil($combinationsCount / 1000) * 1000; - - if ($combinationsInputs > $maxInputVars) { - $this->addFlash( - 'error', - $this->trans( - 'The value of the PHP.ini setting "max_input_vars" must be increased to %value% in order to be able to submit the product form.', - 'Admin.Notifications.Error', - ['%value%' => $combinationsInputs] - ) - ); - } - - foreach ($combinations as $combination) { - $formBuilder->add( - 'combination_' . $combination['id_product_attribute'], - ProductCombination::class - ); - } - } - - return $formBuilder->getForm(); - } - - /** - * Do bulk action on a list of Products. Used with the 'selection action' dropdown menu on the Catalog page. - * - * @param Request $request - * @param string $action The action to apply on the selected products - * - * @throws Exception if action not properly set or unknown - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function bulkAction(Request $request, $action) - { - if (!$this->actionIsAllowed($action, self::PRODUCT_OBJECT, '_all')) { - $this->addFlash('permission_error', $this->getForbiddenActionMessage($action)); - - return $this->redirectToRoute('admin_product_catalog'); - } - - $productIdList = $request->request->get('bulk_action_selected_products'); - /** @var $productUpdater ProductInterfaceUpdater */ - $productUpdater = $this->get('prestashop.core.admin.data_updater.product_interface'); - - /** @var $logger LoggerInterface */ - $logger = $this->get('logger'); - - $hookEventParameters = ['product_list_id' => $productIdList]; - /** @var HookDispatcher $hookDispatcher */ - $hookDispatcher = $this->get('prestashop.core.hook.dispatcher'); - - try { - $hasMessages = $this->get('session')->getFlashBag()->has('success'); - - if ($this->isDemoModeEnabled()) { - throw new UpdateProductException($this->getDemoModeErrorMessage()); - } - - switch ($action) { - case 'activate_all': - $hookDispatcher->dispatchWithParameters( - 'actionAdminActivateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerActivateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->activateProductIdList($productIdList); - if (empty($hasMessages)) { - $this->addFlash( - 'success', - $this->trans('Product(s) successfully activated.', 'Admin.Catalog.Notification') - ); - } - - $logger->info('Products activated: (' . implode(',', $productIdList) . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminActivateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerActivateAfter', - $hookEventParameters - ); - - break; - case 'deactivate_all': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeactivateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeactivateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->activateProductIdList($productIdList, false); - if (empty($hasMessages)) { - $this->addFlash( - 'success', - $this->trans('Product(s) successfully deactivated.', 'Admin.Catalog.Notification') - ); - } - - $logger->info('Products deactivated: (' . implode(',', $productIdList) . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeactivateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeactivateAfter', - $hookEventParameters - ); - - break; - case 'delete_all': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeleteBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeleteBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->deleteProductIdList($productIdList); - if (empty($hasMessages)) { - $this->addFlash( - 'success', - $this->trans('Product(s) successfully deleted.', 'Admin.Catalog.Notification') - ); - } - - $logger->info('Products deleted: (' . implode(',', $productIdList) . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeleteAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeleteAfter', - $hookEventParameters - ); - - break; - case 'duplicate_all': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDuplicateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDuplicateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->duplicateProductIdList($productIdList); - if (empty($hasMessages)) { - $this->addFlash( - 'success', - $this->trans('Product(s) successfully duplicated.', 'Admin.Catalog.Notification') - ); - } - - $logger->info('Products duplicated: (' . implode(',', $productIdList) . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDuplicateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDuplicateAfter', - $hookEventParameters - ); - - break; - default: - /* - * should never happens since the route parameters are - * restricted to a set of action values in YML file. - */ - $logger->error('Bulk action from ProductController received a bad parameter.'); - - throw new Exception('Bad action received from call to ProductController::bulkAction: "' . $action . '"', 2001); - } - } catch (UpdateProductException $due) { - //TODO : need to translate this with an domain name - $message = $due->getMessage(); - $this->addFlash('failure', $message); - $logger->warning($message); - } - - return new Response(json_encode(['result' => 'ok'])); - } - - /** - * Do mass edit action on the current page of products. - * Used with the 'grouped action' dropdown menu on the Catalog page. - * - * @param Request $request - * @param string $action The action to apply on the selected products - * - * @throws Exception if action not properly set or unknown - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function massEditAction(Request $request, $action) - { - if (!$this->isGranted(PageVoter::UPDATE, self::PRODUCT_OBJECT)) { - $errorMessage = $this->trans( - 'You do not have permission to edit this.', - 'Admin.Notifications.Error' - ); - $this->get('session')->getFlashBag()->add('permission_error', $errorMessage); - - return $this->redirectToRoute('admin_product_catalog'); - } - - /** @var $productProvider ProductInterfaceProvider */ - $productProvider = $this->get('prestashop.core.admin.data_provider.product_interface'); - - /** @var $productUpdater ProductInterfaceUpdater */ - $productUpdater = $this->get('prestashop.core.admin.data_updater.product_interface'); - - /** @var $logger LoggerInterface */ - $logger = $this->get('logger'); - - /* @var HookDispatcher $hookDispatcher */ - $hookDispatcher = $this->get('prestashop.core.hook.dispatcher'); - - /* Initialize router params variable. */ - $routerParams = []; - - try { - switch ($action) { - case 'sort': - /* Change position_ordering to position */ - $routerParams['orderBy'] = 'position'; - - $productIdList = $request->request->get('mass_edit_action_sorted_products'); - $productPositionList = $request->request->get('mass_edit_action_sorted_positions'); - $hookEventParameters = [ - 'product_list_id' => $productIdList, - 'product_list_position' => $productPositionList, - ]; - - $hookDispatcher->dispatchWithParameters( - 'actionAdminSortBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerSortBefore', - $hookEventParameters - ); - - // Hooks: managed in ProductUpdater - $persistedFilterParams = $productProvider->getPersistedFilterParameters(); - $productList = array_combine($productIdList, $productPositionList); - $productUpdater->sortProductIdList( - $productList, - ['filter_category' => $persistedFilterParams['filter_category']] - ); - - $this->addFlash( - 'success', - $this->trans('Products successfully sorted.', 'Admin.Catalog.Notification') - ); - $logger->info( - 'Products sorted: (' . implode(',', $productIdList) . - ') with positions (' . implode(',', $productPositionList) . ').' - ); - $hookEventParameters = [ - 'product_list_id' => $productIdList, - 'product_list_position' => $productPositionList, - ]; - $hookDispatcher->dispatchWithParameters( - 'actionAdminSortAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerSortAfter', - $hookEventParameters - ); - - break; - default: - /* - * should never happens since the route parameters are - * restricted to a set of action values in YML file. - */ - $logger->error('Mass edit action from ProductController received a bad parameter.'); - - throw new Exception('Bad action received from call to ProductController::massEditAction: "' . $action . '"', 2001); - } - } catch (UpdateProductException $due) { - //TODO : need to translate with domain name - $message = $due->getMessage(); - $this->addFlash('failure', $message); - $logger->warning($message); - } - - $urlGenerator = $this->get('prestashop.core.admin.url_generator'); - - return $this->redirect($urlGenerator->generate('admin_product_catalog', $routerParams)); - } - - /** - * Do action on one product at a time. Can be used at many places in the controller's page. - * - * @param string $action The action to apply on the selected product - * @param int $id the product ID to apply the action on - * - * @throws Exception if action not properly set or unknown - * - * @return \Symfony\Component\HttpFoundation\Response - */ - public function unitAction($action, $id) - { - if (!$this->actionIsAllowed($action, self::PRODUCT_OBJECT)) { - $this->addFlash('permission_error', $this->getForbiddenActionMessage($action)); - - return $this->redirectToRoute('admin_product_catalog'); - } - - $productUpdater = $this->get('prestashop.core.admin.data_updater.product_interface'); - /** @var $productUpdater ProductInterfaceUpdater */ - - /** @var $logger LoggerInterface */ - $logger = $this->get('logger'); - - $hookEventParameters = ['product_id' => $id]; - /** @var HookDispatcher $hookDispatcher */ - $hookDispatcher = $this->get('prestashop.core.hook.dispatcher'); - - try { - if ($this->isDemoModeEnabled()) { - throw new UpdateProductException($this->getDemoModeErrorMessage()); - } - - switch ($action) { - case 'delete': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeleteBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeleteBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->deleteProduct($id); - $this->addFlash( - 'success', - $this->trans('Product successfully deleted.', 'Admin.Catalog.Notification') - ); - $logger->info('Product deleted: (' . $id . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeleteAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeleteAfter', - $hookEventParameters - ); - - break; - case 'duplicate': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDuplicateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDuplicateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $duplicateProductId = $productUpdater->duplicateProduct($id); - $this->addFlash( - 'success', - $this->trans('Product successfully duplicated.', 'Admin.Catalog.Notification') - ); - $logger->info('Product duplicated: (from ' . $id . ' to ' . $duplicateProductId . ').'); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDuplicateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDuplicateAfter', - $hookEventParameters - ); - // stops here and redirect to the new product's page. - return $this->redirectToRoute('admin_product_form', ['id' => $duplicateProductId]); - case 'activate': - $hookDispatcher->dispatchWithParameters( - 'actionAdminActivateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerActivateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->activateProductIdList([$id]); - $this->addFlash( - 'success', - $this->trans('Product successfully activated.', 'Admin.Catalog.Notification') - ); - $logger->info('Product activated: ' . $id); - $hookDispatcher->dispatchWithParameters( - 'actionAdminActivateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerActivateAfter', - $hookEventParameters - ); - - break; - case 'deactivate': - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeactivateBefore', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeactivateBefore', - $hookEventParameters - ); - // Hooks: managed in ProductUpdater - $productUpdater->activateProductIdList([$id], false); - $this->addFlash( - 'success', - $this->trans('Product successfully deactivated.', 'Admin.Catalog.Notification') - ); - $logger->info('Product deactivated: ' . $id); - $hookDispatcher->dispatchWithParameters( - 'actionAdminDeactivateAfter', - $hookEventParameters - ); - $hookDispatcher->dispatchWithParameters( - 'actionAdminProductsControllerDeactivateAfter', - $hookEventParameters - ); - - break; - default: - /* - * should never happens since the route parameters are - * restricted to a set of action values in YML file. - */ - $logger->error('Unit action from ProductController received a bad parameter.'); - - throw new Exception('Bad action received from call to ProductController::unitAction: "' . $action . '"', 2002); - } - } catch (UpdateProductException $due) { - //TODO : need to translate with a domain name - $message = $due->getMessage(); - $this->addFlash('failure', $message); - $logger->warning($message); - } - - return $this->redirect($this->get('prestashop.core.admin.url_generator')->generate('admin_product_catalog')); - } - - /** - * Toggle product status - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this." - * ) - * - * @param $productId - * - * @return JsonResponse - */ - public function toggleStatusAction($productId) - { - if ($this->isDemoModeEnabled()) { - return $this->json([ - 'status' => false, - 'message' => $this->getDemoModeErrorMessage(), - ]); - } - - try { - $isEnabled = $this->getQueryBus()->handle(new GetProductIsEnabled($productId)); - - $this->getCommandBus()->handle(new UpdateProductStatusCommand($productId, !$isEnabled)); - $response = [ - 'status' => true, - 'message' => $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success'), - ]; - } catch (ProductException $e) { - $response = [ - 'status' => false, - 'message' => $this->getErrorMessageForException($e, $this->getErrorMessages()), - ]; - } - - return $this->json($response); - } - - /** - * @return CsvResponse - * - * @throws \Symfony\Component\Translation\Exception\InvalidArgumentException - */ - public function exportAction() - { - return $this->get('prestashop.core.product.csv_exporter')->export(); - } - - /** - * Set the Catalog filters values and redirect to the catalogAction. - * - * URL example: /product/catalog_filters/42/last/32 - * - * @param int|string $quantity the quantity to set on the catalog filters persistence - * @param string $active the activation state to set on the catalog filters persistence - * - * @return RedirectResponse - */ - public function catalogFiltersAction($quantity = 'none', $active = 'none') - { - $quantity = urldecode($quantity); - - /** @var ProductInterfaceProvider $productProvider */ - $productProvider = $this->get('prestashop.core.admin.data_provider.product_interface'); - - // we merge empty filter set with given values, to reset the other filters! - $productProvider->persistFilterParameters( - array_merge( - AdminFilter::getProductCatalogEmptyFilter(), - [ - 'filter_column_sav_quantity' => ($quantity == 'none') ? '' : $quantity, - 'filter_column_active' => ($active == 'none') ? '' : $active, - ] - ) - ); - - return $this->redirectToRoute('admin_product_catalog'); - } - - /** - * @deprecated since 1.7.5.0, to be removed in 1.8 rely on CommonController::renderFieldAction - * - * @throws \OutOfBoundsException - * @throws \LogicException - * @throws \PrestaShopException - */ - public function renderFieldAction($productId, $step, $fieldName) - { - @trigger_error( - 'This function is deprecated, use CommonController::renderFieldAction instead.', - E_USER_DEPRECATED - ); - - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - $product = $productAdapter->getProduct($productId); - $modelMapper = new AdminModelAdapter( - $product, - $this->get('prestashop.adapter.legacy.context'), - $this->get('prestashop.adapter.admin.wrapper.product'), - $this->get('prestashop.adapter.tools'), - $productAdapter, - $this->get('prestashop.adapter.data_provider.supplier'), - $this->get('prestashop.adapter.data_provider.warehouse'), - $this->get('prestashop.adapter.data_provider.feature'), - $this->get('prestashop.adapter.data_provider.pack'), - $this->get('prestashop.adapter.shop.context'), - $this->get('prestashop.adapter.data_provider.tax'), - $this->get('router') - ); - $form = $this->createFormBuilder($modelMapper->getFormData()); - switch ($step) { - case 'step1': - $form->add('step1', 'PrestaShopBundle\Form\Admin\Product\ProductInformation'); - - break; - case 'step2': - $form->add('step2', 'PrestaShopBundle\Form\Admin\Product\ProductPrice'); - - break; - case 'step3': - $form->add('step3', 'PrestaShopBundle\Form\Admin\Product\ProductQuantity'); - - break; - case 'step4': - $form->add('step4', 'PrestaShopBundle\Form\Admin\Product\ProductShipping'); - - break; - case 'step5': - $form->add('step5', 'PrestaShopBundle\Form\Admin\Product\ProductSeo'); - - break; - case 'step6': - $form->add('step6', 'PrestaShopBundle\Form\Admin\Product\ProductOptions'); - - break; - case 'default': - } - - return $this->render('@PrestaShop/Admin/Common/_partials/_form_field.html.twig', [ - 'form' => $form->getForm()->get($step)->get($fieldName)->createView(), - 'formId' => $step . '_' . $fieldName . '_rendered', - ]); - } - - /** - * @return array - */ - private function getErrorMessages(): array - { - return [ - ProductNotFoundException::class => $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error'), - CannotUpdateProductException::class => $this->trans('An error occurred while updating the status for an object.', 'Admin.Notifications.Error'), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/ProductImageController.php b/src/PrestaShopBundle/Controller/Admin/ProductImageController.php deleted file mode 100644 index fce00018..00000000 --- a/src/PrestaShopBundle/Controller/Admin/ProductImageController.php +++ /dev/null @@ -1,195 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; -use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * Admin controller for product images. - */ -class ProductImageController extends FrameworkBundleAdminController -{ - /** - * Manage upload for product image. - * - * @param int $idProduct - * @param Request $request - * - * @return string - */ - public function uploadImageAction($idProduct, Request $request) - { - $response = new JsonResponse(); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - $return_data = []; - - if ($idProduct == 0 || !$request->isXmlHttpRequest()) { - return $response; - } - - $form = $this->createFormBuilder(null, ['csrf_protection' => false]) - ->add('file', 'Symfony\Component\Form\Extension\Core\Type\FileType', [ - 'error_bubbling' => true, - 'constraints' => [ - new Assert\NotNull(['message' => $this->trans('Please select a file', 'Admin.Catalog.Feature')]), - new Assert\Image(['maxSize' => $this->configuration->get('PS_ATTACHMENT_MAXIMUM_SIZE') . 'M']), - ], - ]) - ->getForm(); - - $form->handleRequest($request); - - if ($request->isMethod('POST')) { - if ($form->isValid()) { - $return_data = $adminProductWrapper->getInstance()->ajaxProcessaddProductImage($idProduct, 'form', false)[0]; - $return_data = array_merge($return_data, [ - 'url_update' => $this->generateUrl('admin_product_image_form', ['idImage' => $return_data['id']]), - 'url_delete' => $this->generateUrl('admin_product_image_delete', ['idImage' => $return_data['id']]), - ]); - } else { - $error_msg = []; - foreach ($form->getErrors() as $error) { - $error_msg[] = $error->getMessage(); - } - $return_data = ['message' => implode(' ', $error_msg)]; - $response->setStatusCode(400); - } - } - - return $response->setData($return_data); - } - - /** - * Update images positions. - * - * @param Request $request - * - * @return JsonResponse - */ - public function updateImagePositionAction(Request $request) - { - $response = new JsonResponse(); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - $json = $request->request->get('json'); - - if (!empty($json) && $request->isXmlHttpRequest()) { - $adminProductWrapper->ajaxProcessUpdateImagePosition(json_decode($json, true)); - } - - return $response; - } - - /** - * Manage form image. - * - * @Template("@PrestaShop/Admin/ProductImage/form.html.twig") - * - * @param $idImage - * @param Request $request - * - * @return array|JsonResponse|Response - */ - public function formAction($idImage, Request $request) - { - $locales = $this->get('prestashop.adapter.legacy.context')->getLanguages(); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - $productAdapter = $this->get('prestashop.adapter.data_provider.product'); - - if ($idImage == 0 || !$request->isXmlHttpRequest()) { - return new Response(); - } - - $image = $productAdapter->getImage((int) $idImage); - - $form = $this->get('form.factory')->createNamedBuilder('form_image', FormType::class, $image, ['csrf_protection' => false]) - ->add('legend', 'PrestaShopBundle\Form\Admin\Type\TranslateType', [ - 'type' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType', - 'options' => [], - 'locales' => $locales, - 'hideTabs' => true, - 'label' => $this->trans('Caption', 'Admin.Catalog.Feature'), - 'required' => false, - ]) - ->add('cover', 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', [ - 'label' => $this->trans('Cover image', 'Admin.Catalog.Feature'), - 'required' => false, - ]) - ->getForm(); - - $form->handleRequest($request); - - if ($request->isMethod('POST')) { - $jsonResponse = new JsonResponse(); - - if ($form->isValid()) { - $jsonResponse->setData($adminProductWrapper->ajaxProcessUpdateImage($idImage, $form->getData())); - } else { - $error_msg = []; - foreach ($form->getErrors() as $error) { - $error_msg[] = $error->getMessage(); - } - - $jsonResponse->setData(['message' => implode(' ', $error_msg)]); - $jsonResponse->setStatusCode(400); - } - - return $jsonResponse; - } - - return [ - 'image' => $image, - 'form' => $form->createView(), - ]; - } - - /** - * Delete an image from its ID. - * - * @param int $idImage - * @param Request $request - * - * @return JsonResponse - */ - public function deleteAction($idImage, Request $request) - { - $response = new JsonResponse(); - $adminProductWrapper = $this->get('prestashop.adapter.admin.wrapper.product'); - - if (!$request->isXmlHttpRequest()) { - return $response; - } - - $adminProductWrapper->getInstance()->ajaxProcessDeleteProductImage($idImage); - - return $response; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/SecurityController.php b/src/PrestaShopBundle/Controller/Admin/SecurityController.php deleted file mode 100644 index 053affe1..00000000 --- a/src/PrestaShopBundle/Controller/Admin/SecurityController.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin; - -use PrestaShopBundle\Service\Routing\Router as PrestaShopRouter; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * Admin controller to manage security pages. - */ -class SecurityController extends FrameworkBundleAdminController -{ - public function compromisedAccessAction(Request $request) - { - $requestUri = urldecode($request->query->get('uri')); - $url = new Assert\Url(); - $violations = $this->get('validator')->validate($requestUri, [$url]); - if ($violations->count()) { - return $this->redirect('dashboard'); - } - - // getToken() actually generate a new token - $username = $this->get('prestashop.user_provider')->getUsername(); - - $newToken = $this->get('security.csrf.token_manager') - ->getToken($username) - ->getValue(); - - $newUri = PrestaShopRouter::generateTokenizedUrl($requestUri, $newToken); - - return $this->render( - '@PrestaShop/Admin/Security/compromised.html.twig', - [ - 'requestUri' => $newUri, - ] - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Address/AddressController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Address/AddressController.php deleted file mode 100644 index 3574b52b..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Address/AddressController.php +++ /dev/null @@ -1,685 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Address; - -use Cart; -use Exception; -use Order; -use PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\BulkDeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\DeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\SetRequiredFieldsForAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\BulkDeleteAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotAddAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotSetRequiredFieldsForAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\CannotUpdateAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\DeleteAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\InvalidAddressFieldException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\InvalidAddressRequiredFieldsException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetRequiredFieldsForAddress; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableCustomerAddress; -use PrestaShop\PrestaShop\Core\Domain\Cart\CartAddressType; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerByEmailNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Order\OrderAddressType; -use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException; -use PrestaShop\PrestaShop\Core\Search\Filters\AddressFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Sell\Address\RequiredFieldsAddressType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class manages "Sell > Customers > Addresses" page. - */ -class AddressController extends FrameworkBundleAdminController -{ - /** - * Show addresses listing page - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param AddressFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, AddressFilters $filters): Response - { - $addressGridFactory = $this->get('prestashop.core.grid.grid_factory.address'); - $addressGrid = $addressGridFactory->getGrid($filters); - $requiredFieldsForm = $this->getRequiredFieldsForm(); - - return $this->render('@PrestaShop/Admin/Sell/Address/index.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'addressGrid' => $this->presentGrid($addressGrid), - 'enableSidebar' => true, - 'layoutHeaderToolbarBtn' => $this->getAddressToolbarButtons(), - 'requiredFieldsForm' => $requiredFieldsForm->createView(), - ]); - } - - /** - * Process addresses required fields configuration form. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_addresses_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - * - * @throws Exception - */ - public function saveRequiredFieldsAction(Request $request): RedirectResponse - { - $addressRequiredFieldsForm = $this->getRequiredFieldsForm(); - $addressRequiredFieldsForm->handleRequest($request); - - if ($addressRequiredFieldsForm->isSubmitted() && $addressRequiredFieldsForm->isValid()) { - $data = $addressRequiredFieldsForm->getData(); - - try { - $this->getCommandBus()->handle(new SetRequiredFieldsForAddressCommand($data['required_fields'])); - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - } - - return $this->redirectToRoute('admin_addresses_index'); - } - - /** - * Deletes address - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_addresses_index") - * - * @param int $addressId - * - * @return RedirectResponse - */ - public function deleteAction(Request $request, int $addressId): RedirectResponse - { - try { - $this->getCommandBus()->handle(new DeleteAddressCommand($addressId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $request->query->has('redirectUrl') ? - $this->redirect($request->query->get('redirectUrl')) : - $this->redirectToRoute('admin_addresses_index'); - } - - /** - * Delete addresses in bulk action. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_addresses_index", - * message="You do not have permission to delete this." - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request): RedirectResponse - { - $addressIds = $this->getBulkAddressesFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteAddressCommand($addressIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_addresses_index'); - } - - /** - * @return array - */ - private function getAddressToolbarButtons(): array - { - $toolbarButtons = []; - - $toolbarButtons['add'] = [ - 'href' => $this->generateUrl('admin_addresses_create'), - 'desc' => $this->trans('Add new address', 'Admin.Orderscustomers.Feature'), - 'icon' => 'add_circle_outline', - ]; - - return $toolbarButtons; - } - - /** - * @return FormInterface - */ - private function getRequiredFieldsForm(): FormInterface - { - $requiredFields = $this->getQueryBus()->handle(new GetRequiredFieldsForAddress()); - - return $this->createForm(RequiredFieldsAddressType::class, ['required_fields' => $requiredFields]); - } - - /** - * @param Request $request - * - * @return array - */ - private function getBulkAddressesFromRequest(Request $request): array - { - $addressIds = $request->request->get('address_addresses_bulk'); - - if (!is_array($addressIds)) { - return []; - } - - foreach ($addressIds as $i => $addressId) { - $addressIds[$i] = (int) $addressId; - } - - return $addressIds; - } - - /** - * Show "Add new" form and handle form submit. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * redirectRoute="admin_addresses_index", - * message="You do not have permission to create this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request): Response - { - $addressFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.address_form_builder' - ); - - $addressFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.address_form_handler' - ); - - $formData = []; - $customerInfo = null; - $customerId = null; - if ($request->request->has('customer_address')) { - if (isset($request->request->get('customer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('customer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - if (isset($request->request->get('customer_address')['id_customer'])) { - $idCustomer = (int) $request->request->get('customer_address')['id_customer']; - $formData['id_customer'] = $idCustomer; - } - } - - if (empty($formData['id_customer']) && $request->query->has('id_customer')) { - $formData['id_customer'] = (int) $request->query->get('id_customer'); - } - - if (!empty($formData['id_customer'])) { - /** @var CustomerDataProvider $customerDataProvider */ - $customerDataProvider = $this->get('prestashop.adapter.data_provider.customer'); - $customerId = $formData['id_customer']; - $customer = $customerDataProvider->getCustomer($customerId); - $formData['first_name'] = $customer->firstname; - $formData['last_name'] = $customer->lastname; - $formData['company'] = $customer->company; - $customerInfo = $customer->firstname . ' ' . $customer->lastname . ' (' . $customer->email . ')'; - } - - $addressForm = $addressFormBuilder->getForm($formData); - $addressForm->handleRequest($request); - - try { - $handlerResult = $addressFormHandler->handle($addressForm); - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - if ($request->query->has('submitFormAjax')) { - return $this->render( - '@PrestaShop/Admin/Sell/Address/modal_create_success.html.twig', - ['refreshCartAddresses' => 'true'] - ); - } - - return $this->redirectToRoute('admin_addresses_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Sell/Address/add.html.twig', [ - 'customerId' => $customerId, - 'customerInformation' => $customerInfo, - 'enableSidebar' => true, - 'displayInIframe' => $request->query->has('submitFormAjax'), - 'addressForm' => $addressForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'cancelPath' => $request->query->has('back') ? $request->query->get('back') : $this->generateUrl('admin_addresses_index'), - ]); - } - - /** - * Handles edit form rendering and submission - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_addresses_index" - * ) - * - * @param int $addressId - * @param Request $request - * - * @return Response - */ - public function editAction(int $addressId, Request $request): Response - { - try { - /** @var EditableCustomerAddress $editableAddress */ - $editableAddress = $this->getQueryBus()->handle(new GetCustomerAddressForEditing((int) $addressId)); - - $addressFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.address_form_builder' - ); - $addressFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.address_form_handler' - ); - - $formData = []; - // Country needs to be preset before building form type because it is used to build state field choices - if ($request->request->has('customer_address') && isset($request->request->get('customer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('customer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - - $addressForm = $addressFormBuilder->getFormFor($addressId, $formData); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_addresses_index'); - } - - try { - $addressForm->handleRequest($request); - $result = $addressFormHandler->handleFor($addressId, $addressForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - if ($request->query->has('submitFormAjax')) { - return $this->render( - '@PrestaShop/Admin/Sell/Address/modal_create_success.html.twig', - ['refreshCartAddresses' => 'false'] - ); - } - - return $this->redirectToRoute('admin_addresses_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - $customerInfo = $editableAddress->getLastName() . ' ' . - $editableAddress->getFirstName() . ' (' . - $editableAddress->getCustomerEmail() . ')'; - - return $this->render('@PrestaShop/Admin/Sell/Address/edit.html.twig', [ - 'enableSidebar' => true, - 'customerId' => $editableAddress->getCustomerId()->getValue(), - 'customerInformation' => $customerInfo, - 'layoutTitle' => $this->trans('Edit', 'Admin.Actions'), - 'displayInIframe' => $request->query->has('submitFormAjax'), - 'addressForm' => $addressForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Handles edit form rendering and submission for order address - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_orders_index" - * ) - * - * @param int $orderId - * @param string $addressType - * @param Request $request - * - * @return Response - */ - public function editOrderAddressAction(int $orderId, string $addressType, Request $request): Response - { - // @todo: don't rely on Order ObjectModel, use a Adapter DataProvider - $order = new Order($orderId); - $addressId = null; - switch ($addressType) { - case 'delivery': - $addressType = OrderAddressType::DELIVERY_ADDRESS_TYPE; - $addressId = $order->id_address_delivery; - break; - case 'invoice': - $addressType = OrderAddressType::INVOICE_ADDRESS_TYPE; - $addressId = $order->id_address_invoice; - break; - } - - try { - /** @var EditableCustomerAddress $editableAddress */ - $editableAddress = $this->getQueryBus()->handle(new GetCustomerAddressForEditing((int) $addressId)); - - $addressFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.address_form_builder' - ); - // Special order handler - $addressFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.order_address_form_handler' - ); - - // Address type required for EditOrderAddressCommand - $formData = [ - 'address_type' => $addressType, - ]; - // Country needs to be preset before building form type because it is used to build state field choices - if ($request->request->has('customer_address') && isset($request->request->get('customer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('customer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - - // Address form is built based on address id to fill the data related to this address - $addressForm = $addressFormBuilder->getFormFor($addressId, $formData); - } catch (Exception $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages($e)) - ); - - return $this->redirectToRoute('admin_orders_view', ['orderId' => $orderId]); - } - - try { - $addressForm->handleRequest($request); - - // Form is handled based on Order ID because that's the order that needs update - $result = $addressFormHandler->handleFor($orderId, $addressForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - if ($request->query->has('submitFormAjax')) { - return $this->render( - '@PrestaShop/Admin/Sell/Address/modal_create_success.html.twig', - ['refreshCartAddresses' => 'false'] - ); - } - - return $this->redirectToRoute('admin_orders_view', ['orderId' => $orderId]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - $customerInfo = $editableAddress->getLastName() . ' ' . - $editableAddress->getFirstName() . ' (' . - $editableAddress->getCustomerEmail() . ')'; - - return $this->render('@PrestaShop/Admin/Sell/Address/edit.html.twig', [ - 'enableSidebar' => true, - 'customerId' => $editableAddress->getCustomerId()->getValue(), - 'customerInformation' => $customerInfo, - 'layoutTitle' => $this->trans('Edit', 'Admin.Actions'), - 'addressForm' => $addressForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'cancelPath' => $this->generateUrl('admin_orders_view', ['orderId' => $orderId]), - 'displayInIframe' => $request->query->has('submitFormAjax'), - ]); - } - - /** - * Handles edit form rendering and submission for cart address - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_orders_index" - * ) - * - * @param int $cartId - * @param string $addressType - * @param Request $request - * - * @return Response - */ - public function editCartAddressAction(int $cartId, string $addressType, Request $request): Response - { - // @todo: don't rely on Cart ObjectModel, use a Adapter DataProvider - $cart = new Cart($cartId); - $addressId = null; - switch ($addressType) { - case 'delivery': - $addressType = CartAddressType::DELIVERY_ADDRESS_TYPE; - $addressId = $cart->id_address_delivery; - break; - case 'invoice': - $addressType = CartAddressType::INVOICE_ADDRESS_TYPE; - $addressId = $cart->id_address_invoice; - break; - } - - try { - /** @var EditableCustomerAddress $editableAddress */ - $editableAddress = $this->getQueryBus()->handle(new GetCustomerAddressForEditing((int) $addressId)); - - $addressFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.address_form_builder' - ); - // Special cart handler - $addressFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.cart_address_form_handler' - ); - - // Address type required for EditCartAddressCommand - $formData = [ - 'address_type' => $addressType, - ]; - // Country needs to be preset before building form type because it is used to build state field choices - if ($request->request->has('customer_address') && isset($request->request->get('customer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('customer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - - // Address form is built based on address id to fill the data related to this address - $addressForm = $addressFormBuilder->getFormFor($addressId, $formData); - } catch (Exception $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages($e)) - ); - - return $this->redirectToRoute('admin_carts_view', ['cartId' => $cartId]); - } - - try { - $addressForm->handleRequest($request); - - // Form is handled based on Cart ID because that's the cart that needs update - $result = $addressFormHandler->handleFor($cartId, $addressForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - - if ($request->query->has('submitFormAjax')) { - return $this->render( - '@PrestaShop/Admin/Sell/Address/modal_create_success.html.twig', - ['refreshCartAddresses' => 'true'] - ); - } - - return $this->redirectToRoute('admin_carts_view', ['cartId' => $cartId]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - $customerInfo = $editableAddress->getLastName() . ' ' . - $editableAddress->getFirstName() . ' (' . - $editableAddress->getCustomerEmail() . ')'; - - return $this->render('@PrestaShop/Admin/Sell/Address/edit.html.twig', [ - 'enableSidebar' => true, - 'customerId' => $editableAddress->getCustomerId()->getValue(), - 'customerInformation' => $customerInfo, - 'layoutTitle' => $this->trans('Edit', 'Admin.Actions'), - 'addressForm' => $addressForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'cancelPath' => $this->generateUrl('admin_carts_view', ['cartId' => $cartId]), - 'displayInIframe' => $request->query->has('submitFormAjax'), - ]); - } - - /** - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e): array - { - return [ - DeleteAddressException::class => [ - DeleteAddressException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - ], - BulkDeleteAddressException::class => sprintf( - '%s: %s', - $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - $e instanceof BulkDeleteAddressException ? $e->getAddressIds() : '' - ), - AddressNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CannotSetRequiredFieldsForAddressException::class => $this->trans( - 'An error occurred when attempting to update the required fields.', - 'Admin.Notifications.Error' - ), - AddressException::class => sprintf( - $this->trans( - 'Internal error #%s', - 'Admin.Notifications.Error' - ), - $e->getMessage() - ), - InvalidAddressRequiredFieldsException::class => $this->trans( - 'Invalid data supplied.', - 'Admin.Notifications.Error' - ), - AddressConstraintException::class => [ - AddressConstraintException::INVALID_ID => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - AddressConstraintException::INVALID_REQUIRED_FIELDS => $this->trans( - 'An error occurred when attempting to update the required fields.', - 'Admin.Notifications.Error' - ), - ], - InvalidAddressFieldException::class => $this->trans( - 'Address fields contain invalid values.', - 'Admin.Notifications.Error' - ), - StateConstraintException::class => [ - StateConstraintException::INVALID_ID => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - ], - CannotUpdateAddressException::class => $this->trans( - 'An error occurred while attempting to save.', - 'Admin.Notifications.Error' - ), - CannotAddAddressException::class => $this->trans( - 'An error occurred while attempting to save.', - 'Admin.Notifications.Error' - ), - CustomerException::class => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - CountryConstraintException::class => [ - CountryConstraintException::INVALID_ID => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - ], - CustomerNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CountryNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - CustomerByEmailNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttachmentController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttachmentController.php deleted file mode 100644 index 9fa7a1f5..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttachmentController.php +++ /dev/null @@ -1,361 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\BulkDeleteAttachmentsCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Command\DeleteAttachmentCommand; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\AttachmentUploadFailedException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\BulkDeleteAttachmentsException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotAddAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotUnlinkAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\CannotUpdateAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\DeleteAttachmentException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Exception\EmptyFileException; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachment; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachmentForEditing; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\Attachment; -use PrestaShop\PrestaShop\Core\Domain\Attachment\QueryResult\EditableAttachment; -use PrestaShop\PrestaShop\Core\Search\Filters\AttachmentFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class is responsible for "Sell > Catalog > Files" page. - */ -class AttachmentController extends FrameworkBundleAdminController -{ - /** - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - */ - public function indexAction(Request $request, AttachmentFilters $filters): Response - { - $attachmentGridFactory = $this->get('prestashop.core.grid.factory.attachment'); - $attachmentGrid = $attachmentGridFactory->getGrid($filters); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Attachment/index.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'attachmentGrid' => $this->presentGrid($attachmentGrid), - 'enableSidebar' => true, - 'layoutHeaderToolbarBtn' => $this->getAttachmentToolbarButtons(), - ]); - } - - /** - * Show "Add new" form and handle form submit. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * redirectRoute="admin_attachments_index", - * message="You do not have permission to create this." - * ) - * - * @return Response - */ - public function createAction(Request $request) - { - $attachmentFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.attachment_form_builder' - ); - $attachmentFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.attachment_form_handler' - ); - - $attachmentForm = $attachmentFormBuilder->getForm(); - - $attachmentForm->handleRequest($request); - - try { - $handlerResult = $attachmentFormHandler->handle($attachmentForm); - - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_attachments_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Attachment/add.html.twig', [ - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Add new file', 'Admin.Catalog.Feature'), - 'attachmentForm' => $attachmentForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Show & process attachment editing. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * redirectRoute="admin_attachments_index", - * message="You do not have permission to edit this." - * ) - * - * @param int $attachmentId - * - * @return Response - */ - public function editAction($attachmentId, Request $request) - { - try { - /** @var EditableAttachment $attachmentInformation */ - $attachmentInformation = $this->getQueryBus()->handle(new GetAttachmentForEditing((int) $attachmentId)); - - $attachmentFormBuilder = $this->get( - 'prestashop.core.form.identifiable_object.builder.attachment_form_builder' - ); - $attachmentFormHandler = $this->get( - 'prestashop.core.form.identifiable_object.handler.attachment_form_handler' - ); - - $attachmentForm = $attachmentFormBuilder->getFormFor((int) $attachmentId); - - $attachmentForm->handleRequest($request); - $result = $attachmentFormHandler->handleFor((int) $attachmentId, $attachmentForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_attachments_index'); - } - } catch (CannotUnlinkAttachmentException $e) { - $this->addFlash('warning', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - return $this->redirectToRoute('admin_attachments_index'); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - - if ($e instanceof AttachmentNotFoundException) { - return $this->redirectToRoute('admin_attachments_index'); - } - } - - if (!isset($attachmentInformation) || !isset($attachmentForm)) { - return $this->redirectToRoute('admin_attachments_index'); - } - - $names = $attachmentInformation->getName(); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Attachment/edit.html.twig', [ - 'enableSidebar' => true, - 'layoutTitle' => $this->trans( - 'Edit: %value%', - 'Admin.Catalog.Feature', - ['%value%' => reset($names)] - ), - 'attachmentForm' => $attachmentForm->createView(), - 'attachmentId' => $attachmentId, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * View attachment. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * redirectRoute="admin_attachments_index", - * message="You do not have permission to edit this." - * ) - */ - public function viewAction(int $attachmentId): Response - { - try { - /** @var Attachment $attachment */ - $attachment = $this->getCommandBus()->handle(new GetAttachment((int) $attachmentId)); - - return $this->file($attachment->getPath(), $attachment->getName()); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_attachments_index'); - } - - /** - * Deletes attachment - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_attachments_index") - * @DemoRestricted(redirectRoute="admin_attachments_index") - */ - public function deleteAction(int $attachmentId): RedirectResponse - { - try { - $this->getCommandBus()->handle(new DeleteAttachmentCommand((int) $attachmentId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_attachments_index'); - } - - /** - * Delete attachments in bulk action. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_attachments_index", - * message="You do not have permission to delete this." - * ) - */ - public function deleteBulkAction(Request $request): RedirectResponse - { - $attachmentIds = $this->getBulkAttachmentsFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteAttachmentsCommand($attachmentIds)); - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_attachments_index'); - } - - /** - * @param Exception $e - */ - private function getErrorMessages(Exception $e = null): array - { - return [ - DeleteAttachmentException::class => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - AttachmentNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - AttachmentConstraintException::class => [ - AttachmentConstraintException::INVALID_ID => $this->trans( - 'The object cannot be loaded (the identifier is missing or invalid)', - 'Admin.Notifications.Error' - ), - AttachmentConstraintException::INVALID_FILE_SIZE => $this->trans( - 'Upload error. Please check your server configurations for the maximum upload size allowed.', - 'Admin.Catalog.Notification' - ), - AttachmentConstraintException::EMPTY_NAME => $this->trans( - 'An attachment name is required.', - 'Admin.Catalog.Notification' - ), - AttachmentConstraintException::EMPTY_DESCRIPTION => $this->trans( - 'Invalid description for %s language', - 'Admin.Catalog.Notification' - ), - AttachmentConstraintException::INVALID_FIELDS => $this->trans( - 'An error occurred when attempting to update the required fields.', - 'Admin.Notifications.Error' - ), - AttachmentConstraintException::INVALID_DESCRIPTION => $this->trans( - 'Invalid description for %s language', - 'Admin.Catalog.Notification' - ), - AttachmentConstraintException::MISSING_NAME_IN_DEFAULT_LANGUAGE => $this->trans( - 'The %s field is not valid', - 'Admin.Notifications.Error', - [ - sprintf('"%s"', $this->trans('Name', 'Admin.Global')), - ] - ), - ], - AttachmentUploadFailedException::class => $this->trans( - 'Failed to copy the file.', - 'Admin.Catalog.Notification' - ), - CannotAddAttachmentException::class => $this->trans( - 'This attachment was unable to be loaded into the database.', - 'Admin.Catalog.Notification' - ), - CannotUpdateAttachmentException::class => $this->trans( - 'This attachment was unable to be loaded into the database.', - 'Admin.Catalog.Notification' - ), - BulkDeleteAttachmentsException::class => sprintf( - '%s: %s', - $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - $e instanceof BulkDeleteAttachmentsException ? implode(', ', $e->getAttachmentIds()) : '' - ), - EmptyFileException::class => $this->trans('No file has been selected', 'Admin.Notifications.Error'), - ]; - } - - /** - * @param Request $request - * - * @return array - */ - private function getBulkAttachmentsFromRequest(Request $request): array - { - $attachmentIds = $request->request->get('attachment_files_bulk'); - - if (!is_array($attachmentIds)) { - return []; - } - - foreach ($attachmentIds as $i => $attachmentId) { - $attachmentIds[$i] = (int) $attachmentId; - } - - return $attachmentIds; - } - - /** - * @return array - */ - private function getAttachmentToolbarButtons(): array - { - $toolbarButtons = []; - - $toolbarButtons['add'] = [ - 'href' => $this->generateUrl('admin_attachments_create'), - 'desc' => $this->trans('Add new file', 'Admin.Catalog.Feature'), - 'icon' => 'add_circle_outline', - ]; - - return $toolbarButtons; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeController.php deleted file mode 100644 index fa07b4b5..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeController.php +++ /dev/null @@ -1,262 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\BulkDeleteAttributeCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\DeleteAttributeCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\AttributeNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Exception\DeleteAttributeException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Search\Filters\AttributeFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for Sell > Catalog > Attributes & Features > Attributes > Attribute - */ -class AttributeController extends FrameworkBundleAdminController -{ - /** - * Displays Attribute groups > attributes page - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", - * redirectRoute="admin_attributes_index", - * redirectQueryParamsToKeep={"attributeGroupId"} - * ) - * - * @param Request $request - * @param $attributeGroupId - * @param AttributeFilters $attributeFilters - * - * @return Response - */ - public function indexAction(Request $request, $attributeGroupId, AttributeFilters $attributeFilters) - { - try { - $attributeGridFactory = $this->get('prestashop.core.grid.factory.attribute'); - $attributeGrid = $attributeGridFactory->getGrid($attributeFilters); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Attribute/index.html.twig', [ - 'attributeGrid' => $this->presentGrid($attributeGrid), - 'attributeGroupId' => $attributeGroupId, - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Updates attributes positioning order - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_attributes_index", - * redirectQueryParamsToKeep={"attributeGroupId"} - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function updatePositionAction(Request $request, $attributeGroupId) - { - $positionsData = [ - 'positions' => $request->request->get('positions'), - 'parentId' => $attributeGroupId, - ]; - - $positionDefinition = $this->get('prestashop.core.grid.attribute.position_definition'); - $positionUpdateFactory = $this->get('prestashop.core.grid.position.position_update_factory'); - - try { - $positionUpdate = $positionUpdateFactory->buildPositionUpdate($positionsData, $positionDefinition); - $updater = $this->get('prestashop.core.grid.position.doctrine_grid_position_updater'); - $updater->update($positionUpdate); - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (Exception $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_attributes_index', [ - 'attributeGroupId' => $attributeGroupId, - ]); - } - - /** - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * message="You do not have permission to create this." - * ) - * - * @param $attributeGroupId - * - * @return RedirectResponse - */ - public function createAction($attributeGroupId) - { - // @todo: implement in another pr - return $this->redirectToRoute('admin_attributes_index', [ - 'attributeGroupId' => $attributeGroupId, - ]); - } - - /** - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this." - * ) - * - * @param $attributeGroupId - * - * @return RedirectResponse - */ - public function editAction($attributeId, $attributeGroupId) - { - // @todo: implement in another pr - return $this->redirectToRoute('admin_attributes_index', [ - 'attributeGroupId' => $attributeGroupId, - ]); - } - - /** - * Deletes attribute - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_attributes_index", - * redirectQueryParamsToKeep={"attributeGroupId"} - * ) - * - * @param int $attributeGroupId - * @param int $attributeId - * - * @return RedirectResponse - */ - public function deleteAction($attributeGroupId, $attributeId) - { - try { - $this->getCommandBus()->handle(new DeleteAttributeCommand((int) $attributeId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_attributes_index', [ - 'attributeGroupId' => $attributeGroupId, - ]); - } - - /** - * Deletes multiple attributes by provided ids from request - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_attributes_index", - * redirectQueryParamsToKeep={"attributeGroupId"} - * ) - * - * @param int $attributeGroupId - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction($attributeGroupId, Request $request) - { - try { - $this->getCommandBus()->handle(new BulkDeleteAttributeCommand( - $this->getAttributeIdsFromRequest($request)) - ); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_attributes_index', [ - 'attributeGroupId' => $attributeGroupId, - ]); - } - - /** - * @param Request $request - * - * @return array - */ - private function getAttributeIdsFromRequest(Request $request) - { - $attributeIds = $request->request->get('attribute_bulk'); - - if (!is_array($attributeIds)) { - return []; - } - - foreach ($attributeIds as $i => $attributeId) { - $attributeIds[$i] = (int) $attributeId; - } - - return $attributeIds; - } - - /** - * Provides translated error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - $notFoundMessage = $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ); - - return [ - AttributeNotFoundException::class => $notFoundMessage, - AttributeGroupNotFoundException::class => $notFoundMessage, - DeleteAttributeException::class => [ - DeleteAttributeException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - DeleteAttributeException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeGroupController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeGroupController.php deleted file mode 100644 index 3f157d72..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/AttributeGroupController.php +++ /dev/null @@ -1,251 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\BulkDeleteAttributeGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\DeleteAttributeGroupCommand; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\AttributeGroupNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Exception\DeleteAttributeGroupException; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Search\Filters\AttributeGroupFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -class AttributeGroupController extends FrameworkBundleAdminController -{ - /** - * Displays Attribute groups page - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param AttributeGroupFilters $attributeGroupFilters - * - * @return Response - */ - public function indexAction(Request $request, AttributeGroupFilters $attributeGroupFilters) - { - $attributeGroupGridFactory = $this->get('prestashop.core.grid.factory.attribute_group'); - $attributeGroupGrid = $attributeGroupGridFactory->getGrid($attributeGroupFilters); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed((int) $this->getContext()->employee->id, ShowcaseCard::ATTRIBUTES_CARD) - ); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/AttributeGroup/index.html.twig', [ - 'attributeGroupGrid' => $this->presentGrid($attributeGroupGrid), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'showcaseCardName' => ShowcaseCard::ATTRIBUTES_CARD, - 'isShowcaseCardClosed' => $showcaseCardIsClosed, - ]); - } - - /** - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * message="You do not have permission to create this." - * ) - * - * @return RedirectResponse - */ - public function createAction() - { - //@todo: implement in antoher pr - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this." - * ) - * - * @param $attributeGroupId - * - * @return RedirectResponse - */ - public function editAction($attributeGroupId) - { - //@todo: implement in antoher pr - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * message="You do not have permission to export this." - * ) - - * - * @param $attributeGroupId - * - * @return RedirectResponse - */ - public function exportAction($attributeGroupId) - { - //@todo: implement in antoher pr - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * Updates attribute groups positioning order - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_attribute_groups_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function updatePositionAction(Request $request) - { - $positionsData = [ - 'positions' => $request->request->get('positions'), - ]; - - $positionDefinition = $this->get('prestashop.core.grid.attribute_group.position_definition'); - $positionUpdateFactory = $this->get('prestashop.core.grid.position.position_update_factory'); - - try { - $positionUpdate = $positionUpdateFactory->buildPositionUpdate($positionsData, $positionDefinition); - $updater = $this->get('prestashop.core.grid.position.doctrine_grid_position_updater'); - $updater->update($positionUpdate); - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (Exception $e) { - $errors = [$e->toArray()]; - $this->flashErrors($errors); - } - - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * Deletes attribute group - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_attribute_groups_index", - * ) - * - * @param int $attributeGroupId - * - * @return RedirectResponse - */ - public function deleteAction($attributeGroupId) - { - try { - $this->getCommandBus()->handle(new DeleteAttributeGroupCommand((int) $attributeGroupId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * Deletes multiple attribute groups by provided ids from request - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_attribute_groups_index", - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - try { - $this->getCommandBus()->handle(new BulkDeleteAttributeGroupCommand( - $this->getAttributeGroupIdsFromRequest($request)) - ); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_attribute_groups_index'); - } - - /** - * @param Request $request - * - * @return array - */ - private function getAttributeGroupIdsFromRequest(Request $request) - { - $attributeGroupIds = $request->request->get('attribute_group_bulk'); - - if (!is_array($attributeGroupIds)) { - return []; - } - - foreach ($attributeGroupIds as $i => $attributeGroupId) { - $attributeGroupIds[$i] = (int) $attributeGroupId; - } - - return $attributeGroupIds; - } - - /** - * Provides translated error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - return [ - AttributeGroupNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - DeleteAttributeGroupException::class => [ - DeleteAttributeGroupException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - DeleteAttributeGroupException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php deleted file mode 100644 index 358307a2..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CartRuleController.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\CartRule\Query\SearchCartRules; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for Cart rules (a.k.a cart discounts/vouchers) actions in Back Office - */ -class CartRuleController extends FrameworkBundleAdminController -{ - /** - * Searches for cart rules by provided search phrase - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller')) || is_granted('create', 'AdminOrders')") - * - * @param Request $request - * - * @return JsonResponse - */ - public function searchAction(Request $request): JsonResponse - { - $searchPhrase = $request->query->get('search_phrase'); - $cartRules = []; - - if ($searchPhrase) { - try { - $cartRules = $this->getQueryBus()->handle(new SearchCartRules($searchPhrase)); - } catch (Exception $e) { - return $this->json( - ['message' => $this->getFallbackErrorMessage(get_class($e), $e->getCode())], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - } - - return $this->json([ - 'cart_rules' => $cartRules, - ]); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CatalogPriceRuleController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CatalogPriceRuleController.php deleted file mode 100644 index b568f20c..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CatalogPriceRuleController.php +++ /dev/null @@ -1,292 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\BulkDeleteCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\DeleteCatalogPriceRuleCommand; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CannotDeleteCatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CannotUpdateCatalogPriceRuleException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Exception\CatalogPriceRuleNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query\GetCatalogPriceRuleForEditing; -use PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\QueryResult\EditableCatalogPriceRule; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CatalogPriceRuleGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters\CatalogPriceRuleFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for Sell > Catalog > Discounts > Catalog Price Rules page - */ -class CatalogPriceRuleController extends FrameworkBundleAdminController -{ - /** - * Displays catalog price rule listing page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param CatalogPriceRuleFilters $catalogPriceRuleFilters - * - * @return Response - */ - public function indexAction( - Request $request, - CatalogPriceRuleFilters $catalogPriceRuleFilters - ) { - $catalogPriceRuleGridFactory = $this->get('prestashop.core.grid.grid_factory.catalog_price_rule'); - $catalogPriceRuleGrid = $catalogPriceRuleGridFactory->getGrid($catalogPriceRuleFilters); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/CatalogPriceRule/index.html.twig', [ - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'catalogPriceRuleGrid' => $this->presentGrid($catalogPriceRuleGrid), - ]); - } - - /** - * Provides filters functionality. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get('prestashop.core.grid.definition.factory.catalog_price_rule'), - $request, - CatalogPriceRuleGridDefinitionFactory::GRID_ID, - 'admin_catalog_price_rules_index' - ); - } - - /** - * Deletes catalog price rule - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_catalog_price_rules_index") - * @DemoRestricted(redirectRoute="admin_catalog_price_rules_index") - * - * @param $catalogPriceRuleId - * - * @return RedirectResponse - */ - public function deleteAction($catalogPriceRuleId) - { - try { - $this->getCommandBus()->handle(new DeleteCatalogPriceRuleCommand((int) $catalogPriceRuleId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_catalog_price_rules_index'); - } - - /** - * Deletes catalogPriceRules on bulk action - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_catalog_price_rules_index") - * @DemoRestricted(redirectRoute="admin_catalog_price_rules_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $catalogPriceRuleIds = $this->getBulkCatalogPriceRulesFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteCatalogPriceRuleCommand($catalogPriceRuleIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_catalog_price_rules_index'); - } - - /** - * Show & process catalog price rule creation. - * - * @AdminSecurity("is_granted(['create'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request): Response - { - $catalogPriceRuleForm = $this->getFormBuilder()->getForm(); - $catalogPriceRuleForm->handleRequest($request); - $result = $this->getFormHandler()->handle($catalogPriceRuleForm); - - try { - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_catalog_price_rules_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/CatalogPriceRule/create.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'catalogPriceRuleForm' => $catalogPriceRuleForm->createView(), - ]); - } - - /** - * Show & process catalog price rule editing. - * - * @AdminSecurity("is_granted(['update'], request.get('_legacy_controller'))") - * - * @param int $catalogPriceRuleId - * @param Request $request - * - * @return Response - */ - public function editAction(Request $request, int $catalogPriceRuleId): Response - { - $catalogPriceRuleId = (int) $catalogPriceRuleId; - - try { - /** @var EditableCatalogPriceRule $editableCatalogPriceRule */ - $editableCatalogPriceRule = $this->getQueryBus()->handle(new GetCatalogPriceRuleForEditing($catalogPriceRuleId)); - - $catalogPriceRuleForm = $this->getFormBuilder()->getFormFor($catalogPriceRuleId); - $catalogPriceRuleForm->handleRequest($request); - - $result = $this->getFormHandler()->handleFor($catalogPriceRuleId, $catalogPriceRuleForm); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_catalog_price_rules_index'); - } - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_catalog_price_rules_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/CatalogPriceRule/edit.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'catalogPriceRuleForm' => $catalogPriceRuleForm->createView(), - 'catalogPriceRuleName' => $editableCatalogPriceRule->getName(), - ]); - } - - /** - * Provides translated error messages for exceptions - * - * @return array - */ - private function getErrorMessages(): array - { - return [ - CannotDeleteCatalogPriceRuleException::class => [ - CannotDeleteCatalogPriceRuleException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - CannotDeleteCatalogPriceRuleException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - CannotUpdateCatalogPriceRuleException::class => $this->trans( - 'An error occurred while updating an object.', - 'Admin.Notifications.Error' - ), - CatalogPriceRuleNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - ]; - } - - /** - * Provides catalog price rule ids from request of bulk action - * - * @param Request $request - * - * @return array - */ - private function getBulkCatalogPriceRulesFromRequest(Request $request) - { - $catalogPriceRuleIds = $request->request->get('catalog_price_rule_bulk'); - - if (!is_array($catalogPriceRuleIds)) { - return []; - } - - foreach ($catalogPriceRuleIds as &$catalogPriceRuleId) { - $catalogPriceRuleId = (int) $catalogPriceRuleId; - } - - return $catalogPriceRuleIds; - } - - /** - * @return FormHandlerInterface - */ - private function getFormHandler(): FormHandlerInterface - { - return $this->get('prestashop.core.form.identifiable_object.handler.catalog_price_rule_form_handler'); - } - - /** - * @return FormBuilderInterface - */ - private function getFormBuilder(): FormBuilderInterface - { - return $this->get('prestashop.core.form.identifiable_object.builder.catalog_price_rule_form_builder'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CategoryController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CategoryController.php deleted file mode 100644 index 50a2df1d..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CategoryController.php +++ /dev/null @@ -1,842 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDeleteCategoriesCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDisableCategoriesCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkEnableCategoriesCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCoverImageCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryMenuThumbnailImageCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\SetCategoryIsEnabledCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Command\UpdateCategoryPositionCommand; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotAddCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteImageException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotDeleteRootCategoryForShopException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotEditCategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CannotUpdateCategoryStatusException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\CategoryNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Category\Exception\MenuThumbnailsLimitException; -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing; -use PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryIsEnabled; -use PrestaShop\PrestaShop\Core\Domain\Category\QueryResult\EditableCategory; -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\MenuThumbnailId; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CategoryGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters\CategoryFilters; -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Sell\Category\DeleteCategoriesType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * Class CategoryController is responsible for "Sell > Catalog > Categories" page. - */ -class CategoryController extends FrameworkBundleAdminController -{ - /** - * Show categories listing. - * - * @AdminSecurity( - * "is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller'))", - * message="You do not have permission to list this." - * ) - * - * @param Request $request - * @param CategoryFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, CategoryFilters $filters) - { - $categoriesKpiFactory = $this->get('prestashop.core.kpi_row.factory.categories'); - - $currentCategoryId = $filters->getFilters()['id_category_parent']; - $categoryViewDataProvider = $this->get('prestashop.adapter.category.category_view_data_provider'); - $categoryViewData = $categoryViewDataProvider->getViewData($currentCategoryId); - - $isItASearchRequest = $this->requestHasSearchParameters($request); - - $filters->addFilter(['is_home_category' => $categoryViewData['is_home_category']]); - $filters->addFilter(['is_search_request' => $isItASearchRequest]); - - $categoryGridFactory = $this->get('prestashop.core.grid.factory.category_decorator'); - $categoryGrid = $categoryGridFactory->getGrid($filters); - - $deleteCategoriesForm = $this->createForm(DeleteCategoriesType::class); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed((int) $this->getContext()->employee->id, ShowcaseCard::CATEGORIES_CARD) - ); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Categories/index.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'categoriesGrid' => $this->presentGrid($categoryGrid), - 'categoriesKpi' => $categoriesKpiFactory->build(), - 'layoutHeaderToolbarBtn' => $this->getCategoryToolbarButtons($request), - 'currentCategoryView' => $categoryViewData, - 'deleteCategoriesForm' => $deleteCategoriesForm->createView(), - 'isSingleShopContext' => $this->get('prestashop.adapter.shop.context')->isSingleShopContext(), - 'showcaseCardName' => ShowcaseCard::CATEGORIES_CARD, - 'isShowcaseCardClosed' => $showcaseCardIsClosed, - ]); - } - - /** - * Process Grid search. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchGridAction(Request $request) - { - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get('prestashop.core.grid.definition.factory.category'), - $request, - CategoryGridDefinitionFactory::GRID_ID, - 'admin_categories_index', - ['categoryId'] - ); - } - - /** - * Show "Add new" form and handle form submit. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * message="You do not have permission to create this.", - * redirectRoute="admin_categories_index" - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $categoryFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.category_form_builder'); - $categoryFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.category_form_handler'); - - $parentId = (int) $request->query->get('id_parent', $this->configuration->getInt('PS_HOME_CATEGORY')); - - $categoryForm = $categoryFormBuilder->getForm(['id_parent' => $parentId]); - $categoryForm->handleRequest($request); - - try { - $handlerResult = $categoryFormHandler->handle($categoryForm); - - if (null !== $handlerResult->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_categories_index', [ - 'categoryId' => $categoryForm->getData()['id_parent'], - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - $defaultGroups = $this->get('prestashop.adapter.group.provider.default_groups_provider')->getGroups(); - - return $this->render( - '@PrestaShop/Admin/Sell/Catalog/Categories/create.html.twig', - [ - 'allowMenuThumbnailsUpload' => true, - 'categoryForm' => $categoryForm->createView(), - 'defaultGroups' => $defaultGroups, - 'categoryUrl' => $this->get('prestashop.adapter.shop.url.category_provider') - ->getUrl(0, '{friendy-url}'), - ] - ); - } - - /** - * Show "Add new root category" page & process adding. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * message="You do not have permission to create this.", - * redirectRoute="admin_categories_index" - * ) - * - * @param Request $request - * - * @return Response - */ - public function createRootAction(Request $request) - { - $rootCategoryFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.root_category_form_builder'); - $rootCategoryFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.root_category_form_handler'); - - $rootCategoryForm = $rootCategoryFormBuilder->getForm(); - $rootCategoryForm->handleRequest($request); - - try { - $handlerResult = $rootCategoryFormHandler->handle($rootCategoryForm); - - if (null !== $handlerResult->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_categories_index', [ - 'categoryId' => $this->configuration->getInt('PS_ROOT_CATEGORY'), - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - $defaultGroups = $this->get('prestashop.adapter.group.provider.default_groups_provider')->getGroups(); - - return $this->render( - '@PrestaShop/Admin/Sell/Catalog/Categories/create_root.html.twig', - [ - 'allowMenuThumbnailsUpload' => true, - 'rootCategoryForm' => $rootCategoryForm->createView(), - 'defaultGroups' => $defaultGroups, - 'categoryUrl' => $this->get('prestashop.adapter.shop.url.category_provider') - ->getUrl(0, '{friendy-url}'), - ] - ); - } - - /** - * Show & process category editing. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_categories_index" - * ) - * - * @param int $categoryId - * @param Request $request - * - * @return Response - */ - public function editAction($categoryId, Request $request) - { - try { - /** @var EditableCategory $editableCategory */ - $editableCategory = $this->getQueryBus()->handle(new GetCategoryForEditing((int) $categoryId)); - - if ($editableCategory->isRootCategory()) { - return $this->redirectToRoute('admin_categories_edit_root', ['categoryId' => $categoryId]); - } - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_categories_index'); - } - - try { - $categoryFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.category_form_builder'); - $categoryFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.category_form_handler'); - - $categoryFormOptions = [ - 'id_category' => (int) $categoryId, - 'subcategories' => $editableCategory->getSubCategories(), - ]; - - $categoryForm = $categoryFormBuilder->getFormFor((int) $categoryId, [], $categoryFormOptions); - $categoryForm->handleRequest($request); - - $handlerResult = $categoryFormHandler->handleFor((int) $categoryId, $categoryForm); - - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_categories_index', [ - 'categoryId' => $categoryForm->getData()['id_parent'], - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - $defaultGroups = $this->get('prestashop.adapter.group.provider.default_groups_provider')->getGroups(); - - return $this->render( - '@PrestaShop/Admin/Sell/Catalog/Categories/edit.html.twig', - [ - 'allowMenuThumbnailsUpload' => $editableCategory->canContainMoreMenuThumbnails(), - 'maxMenuThumbnails' => count(MenuThumbnailId::ALLOWED_ID_VALUES), - 'contextLangId' => $this->getContextLangId(), - 'editCategoryForm' => $categoryForm->createView(), - 'editableCategory' => $editableCategory, - 'defaultGroups' => $defaultGroups, - 'categoryUrl' => $this->get('prestashop.adapter.shop.url.category_provider') - ->getUrl($categoryId, '{friendy-url}'), - ] - ); - } - - /** - * Show and process category editing. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_categories_index" - * ) - * - * @param int $categoryId - * @param Request $request - * - * @return Response - */ - public function editRootAction($categoryId, Request $request) - { - try { - /** @var EditableCategory $editableCategory */ - $editableCategory = $this->getQueryBus()->handle(new GetCategoryForEditing((int) $categoryId)); - - if (!$editableCategory->isRootCategory()) { - return $this->redirectToRoute('admin_categories_edit', ['categoryId' => $categoryId]); - } - } catch (CategoryNotFoundException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_categories_index'); - } - - $rootCategoryFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.root_category_form_builder'); - $rootCategoryFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.root_category_form_handler'); - - try { - $rootCategoryForm = $rootCategoryFormBuilder->getFormFor((int) $categoryId); - $rootCategoryForm->handleRequest($request); - - $handlerResult = $rootCategoryFormHandler->handleFor((int) $categoryId, $rootCategoryForm); - - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_categories_index', [ - 'categoryId' => $this->configuration->getInt('PS_ROOT_CATEGORY'), - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - $defaultGroups = $this->get('prestashop.adapter.group.provider.default_groups_provider')->getGroups(); - - return $this->render( - '@PrestaShop/Admin/Sell/Catalog/Categories/edit_root.html.twig', - [ - 'allowMenuThumbnailsUpload' => $editableCategory->canContainMoreMenuThumbnails(), - 'maxMenuThumbnails' => count(MenuThumbnailId::ALLOWED_ID_VALUES), - 'contextLangId' => $this->getContextLangId(), - 'editRootCategoryForm' => $rootCategoryForm->createView(), - 'editableCategory' => $editableCategory, - 'defaultGroups' => $defaultGroups, - 'categoryUrl' => $this->get('prestashop.adapter.shop.url.category_provider') - ->getUrl($categoryId, '{friendy-url}'), - ] - ); - } - - /** - * Deletes category cover image. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_categories_edit", - * redirectQueryParamsToKeep={"categoryId"} - * ) - * - * @param Request $request - * @param int $categoryId - * - * @return RedirectResponse - */ - public function deleteCoverImageAction(Request $request, $categoryId) - { - if (!$this->isCsrfTokenValid('delete-cover-image', $request->request->get('_csrf_token'))) { - return $this->redirectToRoute('admin_security_compromised', [ - 'uri' => $this->generateUrl('admin_categories_edit', [ - 'categoryId' => $categoryId, - ], UrlGeneratorInterface::ABSOLUTE_URL), - ]); - } - - try { - $this->getCommandBus()->handle(new DeleteCategoryCoverImageCommand((int) $categoryId)); - - $this->addFlash( - 'success', - $this->trans('The image was successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_categories_edit', [ - 'categoryId' => $categoryId, - ]); - } - - /** - * Delete given menu thumbnail for category. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to edit this.", - * redirectRoute="admin_categories_edit", - * redirectQueryParamsToKeep={"categoryId"} - * ) - * - * @param Request $request - * @param int $categoryId - * @param int $menuThumbnailId - * - * @return RedirectResponse - */ - public function deleteMenuThumbnailAction(Request $request, $categoryId, $menuThumbnailId) - { - if (!$this->isCsrfTokenValid('delete-menu-thumbnail', $request->request->get('_csrf_token'))) { - return $this->redirectToRoute('admin_security_compromised', [ - 'uri' => $this->generateUrl('admin_categories_edit', [ - 'categoryId' => $categoryId, - ], UrlGeneratorInterface::ABSOLUTE_URL), - ]); - } - - try { - $this->getCommandBus()->handle(new DeleteCategoryMenuThumbnailImageCommand( - (int) $categoryId, - (int) $menuThumbnailId - )); - - $this->addFlash( - 'success', - $this->trans('The image was successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_categories_edit', [ - 'categoryId' => $categoryId, - ]); - } - - /** - * Toggle category status. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this." - * ) - * - * @param int $categoryId - * - * @return JsonResponse - */ - public function toggleStatusAction($categoryId) - { - if ($this->isDemoModeEnabled()) { - return $this->json([ - 'status' => false, - 'message' => $this->getDemoModeErrorMessage(), - ]); - } - - try { - $isEnabled = $this->getQueryBus()->handle(new GetCategoryIsEnabled((int) $categoryId)); - - $this->getCommandBus()->handle( - new SetCategoryIsEnabledCommand((int) $categoryId, !$isEnabled) - ); - - $response = [ - 'status' => true, - 'message' => $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success'), - ]; - } catch (CategoryException $e) { - $response = [ - 'status' => false, - 'message' => $this->getErrorMessageForException($e, $this->getErrorMessages()), - ]; - } - - return $this->json($response); - } - - /** - * Process bulk action for categories status enabling. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * message="You do not have permission to update this." - * ) - * @DemoRestricted(redirectRoute="admin_categories_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkEnableStatusAction(Request $request) - { - try { - $categoryIds = $this->getBulkCategoriesFromRequest($request); - - $command = new BulkEnableCategoriesCommand($categoryIds); - - $this->getCommandBus()->handle($command); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_categories_index'); - } - - /** - * Process bulk action for categories status disabling. - * - * @AdminSecurity( - * "is_granted(['update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * message="You do not have permission to update this." - * ) - * @DemoRestricted(redirectRoute="admin_categories_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDisableStatusAction(Request $request) - { - try { - $categoryIds = $this->getBulkCategoriesFromRequest($request); - - $command = new BulkDisableCategoriesCommand($categoryIds); - - $this->getCommandBus()->handle($command); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_categories_index'); - } - - /** - * Processes bulk categories deleting. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * message="You do not have permission to delete this." - * ) - * @DemoRestricted(redirectRoute="admin_categories_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $deleteCategoriesForm = $this->createForm(DeleteCategoriesType::class); - $deleteCategoriesForm->handleRequest($request); - - if ($deleteCategoriesForm->isSubmitted()) { - try { - $categoriesDeleteData = $deleteCategoriesForm->getData(); - $categoryIds = array_map(function ($categoryId) { - return (int) $categoryId; - }, $categoriesDeleteData['categories_to_delete']); - - $command = new BulkDeleteCategoriesCommand( - $categoryIds, - $categoriesDeleteData['delete_mode'] - ); - - $this->getCommandBus()->handle($command); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - } - - return $this->redirectToRoute('admin_categories_index'); - } - - /** - * Process single category deleting. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * message="You do not have permission to delete this." - * ) - * @DemoRestricted(redirectRoute="admin_categories_index") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteAction(Request $request) - { - $deleteCategoriesForm = $this->createForm(DeleteCategoriesType::class); - $deleteCategoriesForm->handleRequest($request); - - if ($deleteCategoriesForm->isSubmitted()) { - $categoriesDeleteData = $deleteCategoriesForm->getData(); - - try { - $command = new DeleteCategoryCommand( - (int) reset($categoriesDeleteData['categories_to_delete']), - $categoriesDeleteData['delete_mode'] - ); - - $this->getCommandBus()->handle($command); - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - } catch (CategoryException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - } - - return $this->redirectToRoute('admin_categories_index'); - } - - /** - * Export filtered categories. - * - * @AdminSecurity( - * "is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * message="You do not have permission to view this." - * ) - * @DemoRestricted(redirectRoute="admin_categories_index") - * - * @param CategoryFilters $filters - * - * @return Response - */ - public function exportAction(CategoryFilters $filters) - { - $filters = new CategoryFilters(['limit' => null] + $filters->all()); - $categoriesGridFactory = $this->get('prestashop.core.grid.factory.category'); - $categoriesGrid = $categoriesGridFactory->getGrid($filters); - - $headers = [ - 'id_category' => $this->trans('ID', 'Admin.Global'), - 'name' => $this->trans('Name', 'Admin.Global'), - 'description' => $this->trans('Description', 'Admin.Global'), - 'position' => $this->trans('Position', 'Admin.Global'), - 'active' => $this->trans('Displayed', 'Admin.Global'), - ]; - - $data = []; - - foreach ($categoriesGrid->getData()->getRecords()->all() as $record) { - $data[] = [ - 'id_category' => $record['id_category'], - 'name' => $record['name'], - 'description' => $record['description'], - 'position' => $record['position'], - 'active' => $record['active'], - ]; - } - - return (new CsvResponse()) - ->setData($data) - ->setHeadersData($headers) - ->setFileName('category_' . date('Y-m-d_His') . '.csv'); - } - - /** - * Updates category position - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_categories_index", - * ) - * - * @param Request $request - * - * @return JsonResponse - */ - public function updatePositionAction(Request $request) - { - try { - $this->getCommandBus()->handle(new UpdateCategoryPositionCommand( - $request->request->getInt('id_category_to_move'), - $request->request->getInt('id_category_parent'), - $request->request->getInt('way'), - $request->request->get('positions'), - $request->request->getBoolean('found_first') - )); - } catch (CategoryException $e) { - return $this->json([ - 'success' => false, - 'message' => $this->getErrorMessageForException($e, $this->getErrorMessages()), - ]); - } - - return $this->json([ - 'success' => true, - 'message' => $this->trans('Successful update.', 'Admin.Notifications.Success'), - ]); - } - - /** - * @param Request $request - * - * @return array - */ - private function getCategoryToolbarButtons(Request $request) - { - $toolbarButtons = []; - - if ($this->get('prestashop.adapter.feature.multistore')->isUsed()) { - $toolbarButtons['add_root'] = [ - 'href' => $this->generateUrl('admin_categories_create_root'), - 'desc' => $this->trans('Add new root category', 'Admin.Catalog.Feature'), - 'icon' => 'add_circle_outline', - ]; - } - - $categoryId = $request->attributes->get('categoryId'); - if (empty($categoryId)) { - $categoryId = $this->configuration->getInt('PS_HOME_CATEGORY'); - } - - $toolbarButtons['add'] = [ - 'href' => $this->generateUrl('admin_categories_create', ['id_parent' => $categoryId]), - 'desc' => $this->trans('Add new category', 'Admin.Catalog.Feature'), - 'icon' => 'add_circle_outline', - ]; - - return $toolbarButtons; - } - - /** - * Get translated error messages for category exceptions - * - * @return array - */ - private function getErrorMessages() - { - return [ - CannotDeleteImageException::class => $this->trans('Unable to delete associated images.', 'Admin.Notifications.Error'), - CategoryNotFoundException::class => $this->trans('The object cannot be loaded (or found)', 'Admin.Notifications.Error'), - CategoryConstraintException::class => [ - CategoryConstraintException::EMPTY_BULK_DELETE_DATA => $this->trans('You must select at least one element to delete.', 'Admin.Notifications.Error'), - CategoryConstraintException::TOO_MANY_MENU_THUMBNAILS => sprintf( - '%s %s', - $this->trans('An error occurred while uploading the image:', 'Admin.Catalog.Notification'), - $this->trans('You cannot upload more files', 'Admin.Notifications.Error') - ), - ], - CannotDeleteRootCategoryForShopException::class => $this->trans( - 'You cannot remove this category because one of your shops uses it as a root category.', - 'Admin.Catalog.Notification' - ), - CannotAddCategoryException::class => $this->trans( - 'An error occurred while creating the category.', - 'Admin.Catalog.Notification' - ), - CannotEditCategoryException::class => $this->trans( - 'An error occurred while editing the category.', - 'Admin.Catalog.Notification' - ), - CannotUpdateCategoryStatusException::class => $this->trans( - 'An error occurred while updating the status for an object.', - 'Admin.Notifications.Error' - ), - MenuThumbnailsLimitException::class => sprintf( - '%s %s', - $this->trans('An error occurred while uploading the image:', 'Admin.Catalog.Notification'), - $this->trans('You cannot upload more files', 'Admin.Notifications.Error') - ), - ]; - } - - /** - * @param Request $request - * - * @return array - */ - private function getBulkCategoriesFromRequest(Request $request) - { - $categoryIds = $request->request->get('category_id_category'); - - if (!is_array($categoryIds)) { - return []; - } - - foreach ($categoryIds as $i => $categoryId) { - $categoryIds[$i] = (int) $categoryId; - } - - return $categoryIds; - } - - /** - * @param Request $request - * - * @return bool - */ - private function requestHasSearchParameters(Request $request) - { - return !empty($request->query->get('category')['filters']); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/FeatureController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/FeatureController.php deleted file mode 100644 index a03a53ea..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/FeatureController.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Exception\FeatureNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Feature\Query\GetFeatureForEditing; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Controller responsible for "Sell > Catalog > Attributes & Features > Features" page - */ -class FeatureController extends FrameworkBundleAdminController -{ - /** - * Create feature action. - * - * @AdminSecurity("is_granted(['create'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - if (!$this->isFeatureEnabled()) { - return $this->render('@PrestaShop/Admin/Sell/Catalog/Features/create.html.twig', [ - 'showDisabledFeatureWarning' => true, - ]); - } - - $featureFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.feature_form_builder'); - $featureFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.feature_form_handler'); - - $featureForm = $featureFormBuilder->getForm(); - $featureForm->handleRequest($request); - - try { - $handlerResult = $featureFormHandler->handle($featureForm); - - if (null !== $handlerResult->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - //@todo change route to index when it's migrated - return $this->redirectToRoute('admin_features_create'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Features/create.html.twig', [ - 'featureForm' => $featureForm->createView(), - ]); - } - - /** - * Edit feature action. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param int $featureId - * @param Request $request - * - * @return Response - */ - public function editAction($featureId, Request $request) - { - try { - $editableFeature = $this->getQueryBus()->handle(new GetFeatureForEditing((int) $featureId)); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - // @todo change route to features index when it's migrated - return $this->redirectToRoute('admin_features_create'); - } - - if (!$this->isFeatureEnabled()) { - return $this->renderEditForm([ - 'showDisabledFeatureWarning' => true, - 'editableFeature' => $editableFeature, - ]); - } - - $featureFormBuilder = $this->get('prestashop.core.form.identifiable_object.builder.feature_form_builder'); - $featureFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.feature_form_handler'); - - $featureForm = $featureFormBuilder->getFormFor($featureId); - $featureForm->handleRequest($request); - - try { - $handlerResult = $featureFormHandler->handleFor($featureId, $featureForm); - - if ($handlerResult->isSubmitted() && $handlerResult->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_features_edit', [ - 'featureId' => $featureId, - ]); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->renderEditForm([ - 'featureForm' => $featureForm->createView(), - 'editableFeature' => $editableFeature, - ]); - } - - /** - * Render feature edit form - * - * @param array $parameters - * - * @return Response - */ - private function renderEditForm(array $parameters = []) - { - return $this->render('@PrestaShop/Admin/Sell/Catalog/Features/edit.html.twig', $parameters + [ - 'contextLangId' => $this->configuration->get('PS_LANG_DEFAULT'), - ]); - } - - /** - * Get translated error messages for feature exceptions - * - * @return array - */ - private function getErrorMessages() - { - return [ - FeatureNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - FeatureConstraintException::class => [ - FeatureConstraintException::EMPTY_NAME => $this->trans( - 'The field %field_name% is required at least in your default language.', - 'Admin.Notifications.Error', - ['%field_name%' => $this->trans('Name', 'Admin.Global')] - ), - FeatureConstraintException::INVALID_NAME => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Name', 'Admin.Global'))] - ), - ], - ]; - } - - /** - * Check if Features functionality is enabled in the shop. - * - * @return bool - */ - private function isFeatureEnabled() - { - return $this->get('prestashop.adapter.feature.feature')->isActive(); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/ManufacturerController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/ManufacturerController.php deleted file mode 100644 index 664290c6..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/ManufacturerController.php +++ /dev/null @@ -1,786 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\BulkDeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Command\DeleteAddressCommand; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\DeleteAddressException; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\InvalidAddressFieldException; -use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetManufacturerAddressForEditing; -use PrestaShop\PrestaShop\Core\Domain\Address\QueryResult\EditableManufacturerAddress; -use PrestaShop\PrestaShop\Core\Domain\Exception\DomainException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkDeleteManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkToggleManufacturerStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\DeleteManufacturerCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\ToggleManufacturerStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\DeleteManufacturerException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\ManufacturerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Exception\UpdateManufacturerException; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\EditableManufacturer; -use PrestaShop\PrestaShop\Core\Domain\Manufacturer\QueryResult\ViewableManufacturer; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerAddressGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException; -use PrestaShop\PrestaShop\Core\Search\Filters\ManufacturerAddressFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\ManufacturerFilters; -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Manages "Sell > Catalog > Brands & Suppliers > Brands" page - */ -class ManufacturerController extends FrameworkBundleAdminController -{ - /** - * Show manufacturers listing page. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return Response - */ - public function indexAction( - Request $request, - ManufacturerFilters $manufacturerFilters, - ManufacturerAddressFilters $manufacturerAddressFilters - ) { - $manufacturerGridFactory = $this->get('prestashop.core.grid.grid_factory.manufacturer'); - $manufacturerGrid = $manufacturerGridFactory->getGrid($manufacturerFilters); - - $manufacturerAddressFactory = $this->get('prestashop.core.grid.grid_factory.manufacturer_address'); - $manufacturerAddressGrid = $manufacturerAddressFactory->getGrid($manufacturerAddressFilters); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/index.html.twig', [ - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'manufacturerGrid' => $this->presentGrid($manufacturerGrid), - 'manufacturerAddressGrid' => $this->presentGrid($manufacturerAddressGrid), - 'settingsTipMessage' => $this->getSettingsTipMessage(), - ]); - } - - /** - * Provides filters functionality - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $gridDefinitionFactory = 'prestashop.core.grid.definition.factory.manufacturer'; - $filterId = ManufacturerGridDefinitionFactory::GRID_ID; - if ($request->request->has(ManufacturerAddressGridDefinitionFactory::GRID_ID)) { - $gridDefinitionFactory = 'prestashop.core.grid.definition.factory.manufacturer_address'; - $filterId = ManufacturerAddressGridDefinitionFactory::GRID_ID; - } - - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get($gridDefinitionFactory), - $request, - $filterId, - 'admin_manufacturers_index' - ); - } - - /** - * Show & process manufacturer creation. - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))" - * ) - * - * @return Response - */ - public function createAction(Request $request) - { - $manufacturerForm = $this->getFormBuilder()->getForm(); - $manufacturerForm->handleRequest($request); - - try { - $result = $this->getFormHandler()->handle($manufacturerForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_manufacturers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/add.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'manufacturerForm' => $manufacturerForm->createView(), - ]); - } - - /** - * View single manufacturer details - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param int $manufacturerId - * - * @return Response - */ - public function viewAction(Request $request, $manufacturerId) - { - try { - /** @var ViewableManufacturer $viewableManufacturer */ - $viewableManufacturer = $this->getQueryBus()->handle(new GetManufacturerForViewing( - (int) $manufacturerId, - (int) $this->getContextLangId() - )); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/view.html.twig', [ - 'layoutTitle' => $viewableManufacturer->getName(), - 'viewableManufacturer' => $viewableManufacturer, - 'isStockManagementEnabled' => $this->configuration->get('PS_STOCK_MANAGEMENT'), - 'isAllShopContext' => $this->get('prestashop.adapter.shop.context')->isAllShopContext(), - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Show & process manufacturer editing. - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))" - * ) - * - * @param int $manufacturerId - * - * @return Response - */ - public function editAction(Request $request, $manufacturerId) - { - try { - /** @var EditableManufacturer $editableManufacturer */ - $editableManufacturer = $this->getQueryBus()->handle(new GetManufacturerForEditing((int) $manufacturerId)); - - $manufacturerForm = $this->getFormBuilder()->getFormFor((int) $manufacturerId); - $manufacturerForm->handleRequest($request); - - $result = $this->getFormHandler()->handleFor((int) $manufacturerId, $manufacturerForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_manufacturers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - if ($e instanceof ManufacturerNotFoundException) { - return $this->redirectToRoute('admin_manufacturers_index'); - } - } - - if (!isset($editableManufacturer) || !isset($manufacturerForm)) { - return $this->redirectToRoute('admin_manufacturers_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/edit.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'manufacturerForm' => $manufacturerForm->createView(), - 'manufacturerName' => $editableManufacturer->getName(), - 'logoImage' => $editableManufacturer->getLogoImage(), - ]); - } - - /** - * Deletes manufacturer - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @param $manufacturerId - * - * @return RedirectResponse - */ - public function deleteAction($manufacturerId) - { - try { - $this->getCommandBus()->handle(new DeleteManufacturerCommand((int) $manufacturerId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Deletes manufacturers on bulk action - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $manufacturerIds = $this->getBulkManufacturersFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteManufacturerCommand($manufacturerIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Enables manufacturers on bulk action - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return RedirectResponse - */ - public function bulkEnableAction(Request $request) - { - $manufacturerIds = $this->getBulkManufacturersFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkToggleManufacturerStatusCommand($manufacturerIds, true)); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Disables manufacturers on bulk action - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return RedirectResponse - */ - public function bulkDisableAction(Request $request) - { - $manufacturerIds = $this->getBulkManufacturersFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkToggleManufacturerStatusCommand($manufacturerIds, false)); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Toggles manufacturer status - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @param int $manufacturerId - * - * @return RedirectResponse - */ - public function toggleStatusAction($manufacturerId) - { - try { - /** @var EditableManufacturer $editableManufacturer */ - $editableManufacturer = $this->getQueryBus()->handle(new GetManufacturerForEditing((int) $manufacturerId)); - $this->getCommandBus()->handle( - new ToggleManufacturerStatusCommand((int) $manufacturerId, !$editableManufacturer->isEnabled()) - ); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (ManufacturerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Export filtered manufacturers. - * - * @AdminSecurity( - * "is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_manufacturers_index" - * ) - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return Response - */ - public function exportAction(ManufacturerFilters $filters) - { - $filters = new ManufacturerFilters(['limit' => null] + $filters->all()); - $manufacturersGridFactory = $this->get('prestashop.core.grid.grid_factory.manufacturer'); - $manufacturersGrid = $manufacturersGridFactory->getGrid($filters); - - $headers = [ - 'id_manufacturer' => $this->trans('ID', 'Admin.Global'), - 'logo' => $this->trans('Logo', 'Admin.Global'), - 'name' => $this->trans('Name', 'Admin.Global'), - 'addresses_count' => $this->trans('Addresses', 'Admin.Global'), - 'products_count' => $this->trans('Products', 'Admin.Global'), - 'active' => $this->trans('Enabled', 'Admin.Global'), - ]; - - $data = []; - - foreach ($manufacturersGrid->getData()->getRecords()->all() as $record) { - $data[] = [ - 'id_manufacturer' => $record['id_manufacturer'], - 'logo' => $record['logo'], - 'name' => $record['name'], - 'addresses_count' => $record['addresses_count'], - 'products_count' => $record['products_count'], - 'active' => $record['active'], - ]; - } - - return (new CsvResponse()) - ->setData($data) - ->setHeadersData($headers) - ->setFileName('manufacturer_' . date('Y-m-d_His') . '.csv') - ; - } - - /** - * Deletes address - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @param int $addressId - * - * @return RedirectResponse - */ - public function deleteAddressAction($addressId) - { - try { - $this->getCommandBus()->handle(new DeleteAddressCommand((int) $addressId)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (AddressException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Export filtered manufacturer addresses. - * - * @AdminSecurity( - * "is_granted(['read', 'update', 'create', 'delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_manufacturers_index" - * ) - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return Response - */ - public function exportAddressAction(ManufacturerAddressFilters $filters) - { - $addressesGridFactory = $this->get('prestashop.core.grid.grid_factory.manufacturer_address'); - $addressesGrid = $addressesGridFactory->getGrid($filters); - - $headers = [ - 'id_address' => $this->trans('ID', 'Admin.Global'), - 'name' => $this->trans('Brand', 'Admin.Global'), - 'firstname' => $this->trans('First name', 'Admin.Global'), - 'lastname' => $this->trans('Last name', 'Admin.Global'), - 'postcode' => $this->trans('Zip/Postal code', 'Admin.Global'), - 'city' => $this->trans('City', 'Admin.Global'), - 'country' => $this->trans('Country', 'Admin.Global'), - ]; - - $data = []; - - foreach ($addressesGrid->getData()->getRecords()->all() as $record) { - $data[] = [ - 'id_address' => $record['id_address'], - 'name' => $record['name'], - 'firstname' => $record['firstname'], - 'lastname' => $record['lastname'], - 'postcode' => $record['postcode'], - 'city' => $record['city'], - 'country' => $record['country'], - ]; - } - - return (new CsvResponse()) - ->setData($data) - ->setHeadersData($headers) - ->setFileName('address_' . date('Y-m-d_His') . '.csv') - ; - } - - /** - * Deletes adresses in bulk action - * - * @AdminSecurity("is_granted('delete', request.get('_legacy_controller'))", redirectRoute="admin_manufacturers_index") - * @DemoRestricted(redirectRoute="admin_manufacturers_index") - * - * @return RedirectResponse - */ - public function bulkDeleteAddressAction(Request $request) - { - $addressIds = $this->getBulkAddressesFromRequest($request); - - try { - $this->getCommandBus()->handle(new BulkDeleteAddressCommand($addressIds)); - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (AddressException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_manufacturers_index'); - } - - /** - * Show & process address creation. - * - * @AdminSecurity("is_granted('create', request.get('_legacy_controller'))") - * - * @return Response - */ - public function createAddressAction(Request $request) - { - $addressFormBuilder = $this->getAddressFormBuilder(); - $addressFormHandler = $this->getAddressFormHandler(); - - $formData = []; - if ($request->request->has('manufacturer_address') && isset($request->request->get('manufacturer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('manufacturer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - - $addressForm = $addressFormBuilder->getForm($formData); - $addressForm->handleRequest($request); - - try { - $result = $addressFormHandler->handle($addressForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_manufacturers_index'); - } - } catch (DomainException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - if ($e instanceof ManufacturerConstraintException) { - return $this->redirectToRoute('admin_manufacturers_index'); - } - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/Address/create.html.twig', [ - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Add new address', 'Admin.Orderscustomers.Feature'), - 'addressForm' => $addressForm->createView(), - ]); - } - - /** - * Show & process address editing. - * - * @AdminSecurity("is_granted('update', request.get('_legacy_controller'))") - * - * @param int $addressId - * - * @return Response - */ - public function editAddressAction(Request $request, $addressId) - { - $addressId = (int) $addressId; - - $addressFormBuilder = $this->getAddressFormBuilder(); - $addressFormHandler = $this->getAddressFormHandler(); - - $formData = []; - if ($request->request->has('manufacturer_address') && isset($request->request->get('manufacturer_address')['id_country'])) { - $formCountryId = (int) $request->request->get('manufacturer_address')['id_country']; - $formData['id_country'] = $formCountryId; - } - - try { - /** @var EditableManufacturerAddress $editableAddress */ - $editableAddress = $this->getQueryBus()->handle(new GetManufacturerAddressForEditing($addressId)); - $addressForm = $addressFormBuilder->getFormFor($addressId, $formData); - $addressForm->handleRequest($request); - - $result = $addressFormHandler->handleFor($addressId, $addressForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_manufacturers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - if ($e instanceof AddressNotFoundException || $e instanceof AddressConstraintException) { - return $this->redirectToRoute('admin_manufacturers_index'); - } - } - - if (!isset($editableAddress) || !isset($addressForm)) { - return $this->redirectToRoute('admin_manufacturers_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Manufacturer/Address/edit.html.twig', [ - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Brands', 'Admin.Catalog.Feature'), - 'addressForm' => $addressForm->createView(), - 'address' => $editableAddress->getAddress(), - ]); - } - - /** - * Provides error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - $iniConfig = $this->get('prestashop.core.configuration.ini_configuration'); - - return [ - DeleteManufacturerException::class => [ - DeleteManufacturerException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - DeleteManufacturerException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - UpdateManufacturerException::class => [ - UpdateManufacturerException::FAILED_BULK_UPDATE_STATUS => [ - $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - ], - UpdateManufacturerException::FAILED_UPDATE_STATUS => [ - $this->trans( - 'An error occurred while updating the status for an object.', - 'Admin.Notifications.Error' - ), - ], - ], - DeleteAddressException::class => [ - DeleteAddressException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - DeleteAddressException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - ManufacturerNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - MemoryLimitException::class => $this->trans( - 'Due to memory limit restrictions, this image cannot be loaded. Please increase your memory_limit value via your server\'s configuration settings.', - 'Admin.Notifications.Error' - ), - ImageUploadException::class => $this->trans( - 'An error occurred while uploading the image.', - 'Admin.Notifications.Error' - ), - ImageOptimizationException::class => $this->trans( - 'Unable to resize one or more of your pictures.', - 'Admin.Catalog.Notification' - ), - UploadedImageConstraintException::class => [ - UploadedImageConstraintException::EXCEEDED_SIZE => $this->trans( - 'Max file size allowed is "%s" bytes.', 'Admin.Notifications.Error', [ - $iniConfig->getUploadMaxSizeInBytes(), - ]), - UploadedImageConstraintException::UNRECOGNIZED_FORMAT => $this->trans( - 'Image format not recognized, allowed formats are: .gif, .jpg, .png', - 'Admin.Notifications.Error' - ), - ], - AddressNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - InvalidAddressFieldException::class => $this->trans( - 'Address fields contain invalid values.', - 'Admin.Notifications.Error' - ), - ]; - } - - /** - * @return array - */ - private function getBulkManufacturersFromRequest(Request $request) - { - $manufacturerIds = $request->request->get('manufacturer_bulk'); - - if (!is_array($manufacturerIds)) { - return []; - } - - foreach ($manufacturerIds as $i => $manufacturerId) { - $manufacturerIds[$i] = (int) $manufacturerId; - } - - return $manufacturerIds; - } - - /** - * @return array - */ - private function getBulkAddressesFromRequest(Request $request) - { - $addressIds = $request->request->get('manufacturer_address_bulk'); - - if (!is_array($addressIds)) { - return []; - } - - foreach ($addressIds as $i => $addressId) { - $addressIds[$i] = (int) $addressId; - } - - return $addressIds; - } - - /** - * @return FormHandlerInterface - */ - private function getFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.manufacturer_form_handler'); - } - - /** - * @return FormBuilderInterface - */ - private function getFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.manufacturer_form_builder'); - } - - /** - * @return FormBuilderInterface - */ - private function getAddressFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.manufacturer_address_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getAddressFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.manufacturer_address_form_handler'); - } - - private function getSettingsTipMessage() - { - $urlOpening = sprintf('', $this->get('router')->generate('admin_preferences')); - $urlEnding = ''; - - if ($this->configuration->get('PS_DISPLAY_MANUFACTURERS')) { - return $this->trans( - 'The display of your brands is enabled on your store. Go to %sShop Parameters > General%s to edit settings.', - 'Admin.Catalog.Notification', - [$urlOpening, $urlEnding] - ); - } - - return $this->trans( - 'The display of your brands is disabled on your store. Go to %sShop Parameters > General%s to edit settings.', - 'Admin.Catalog.Notification', - [$urlOpening, $urlEnding] - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/MonitoringController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/MonitoringController.php deleted file mode 100644 index 2db55be8..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/MonitoringController.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\DisabledProductGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\EmptyCategoryGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithCombinationGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithoutCombinationGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutDescriptionGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutImageGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutPriceGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Grid\GridInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\DisabledProductFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\EmptyCategoryFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\NoQtyProductWithCombinationFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\NoQtyProductWithoutCombinationFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\ProductWithoutDescriptionFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\ProductWithoutImageFilters; -use PrestaShop\PrestaShop\Core\Search\Filters\Monitoring\ProductWithoutPriceFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\Sell\Category\DeleteCategoriesType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Service\Grid\ResponseBuilder; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Responsible for Sell > Catalog > Monitoring page - */ -class MonitoringController extends FrameworkBundleAdminController -{ - /** - * Shows Monitoring listing page - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param EmptyCategoryFilters $emptyCategoryFilters - * @param NoQtyProductWithCombinationFilters $noQtyProductWithCombinationFilters - * @param NoQtyProductWithoutCombinationFilters $noQtyProductWithoutCombinationFilters - * @param DisabledProductFilters $disabledProductFilters - * @param ProductWithoutImageFilters $productWithoutImageFilters - * @param ProductWithoutDescriptionFilters $productWithoutDescriptionFilters - * @param ProductWithoutPriceFilters $productWithoutPriceFilters - * - * @return Response - */ - public function indexAction( - Request $request, - EmptyCategoryFilters $emptyCategoryFilters, - NoQtyProductWithCombinationFilters $noQtyProductWithCombinationFilters, - NoQtyProductWithoutCombinationFilters $noQtyProductWithoutCombinationFilters, - DisabledProductFilters $disabledProductFilters, - ProductWithoutImageFilters $productWithoutImageFilters, - ProductWithoutDescriptionFilters $productWithoutDescriptionFilters, - ProductWithoutPriceFilters $productWithoutPriceFilters - ) { - $deleteCategoryForm = $this->createForm(DeleteCategoriesType::class); - - $emptyCategoryGrid = $this->getEmptyCategoryGrid($emptyCategoryFilters); - $noQtyProductWithCombinationGrid = $this->getNoQtyProductWithCombinationGrid($noQtyProductWithCombinationFilters); - $noQtyProductWithoutCombinationGrid = $this->getNoQtyProductWithoutCombinationGrid($noQtyProductWithoutCombinationFilters); - $disabledProductGrid = $this->getDisabledProductGrid($disabledProductFilters); - $productWithoutImageGrid = $this->getProductWithoutImageGrid($productWithoutImageFilters); - $productWithoutDescriptionGrid = $this->getProductWithoutDescriptionGrid($productWithoutDescriptionFilters); - $productWithoutPriceGrid = $this->getProductWithoutPriceGrid($productWithoutPriceFilters); - - $isShowcaseCardClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed($this->getContext()->employee->id, ShowcaseCard::MONITORING_CARD) - ); - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Monitoring/index.html.twig', [ - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'emptyCategoryGrid' => $this->presentGrid($emptyCategoryGrid), - 'deleteCategoryForm' => $deleteCategoryForm->createView(), - 'noQtyProductWithCombinationGrid' => $this->presentGrid($noQtyProductWithCombinationGrid), - 'noQtyProductWithoutCombinationGrid' => $this->presentGrid($noQtyProductWithoutCombinationGrid), - 'disabledProductGrid' => $this->presentGrid($disabledProductGrid), - 'productWithoutImageGrid' => $this->presentGrid($productWithoutImageGrid), - 'productWithoutDescriptionGrid' => $this->presentGrid($productWithoutDescriptionGrid), - 'productWithoutPriceGrid' => $this->presentGrid($productWithoutPriceGrid), - 'showcaseCardName' => ShowcaseCard::MONITORING_CARD, - 'isShowcaseCardClosed' => $isShowcaseCardClosed, - ]); - } - - /** - * Provides filters functionality - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchAction(Request $request) - { - $gridIdentifiers = $this->identifySearchableGrid($request); - - /** @var ResponseBuilder $responseBuilder */ - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $gridIdentifiers['grid_definition'], - $request, - $gridIdentifiers['grid_id'], - 'admin_monitorings_index' - ); - } - - /** - * Parses grid identifying parts from request in order to recognize which grid is being filtered - * - * @param Request $request - * - * @return array - */ - private function identifySearchableGrid(Request $request) - { - $gridDefinition = 'prestashop.core.grid.definition.factory.monitoring.empty_category'; - $gridId = EmptyCategoryGridDefinitionFactory::GRID_ID; - - $definitionMap = [ - NoQtyProductWithCombinationGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.no_qty_product_with_combination', - NoQtyProductWithoutCombinationGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.no_qty_product_without_combination', - DisabledProductGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.disabled_product', - ProductWithoutImageGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.product_without_image', - ProductWithoutDescriptionGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.product_without_description', - ProductWithoutPriceGridDefinitionFactory::GRID_ID => 'prestashop.core.grid.definition.factory.monitoring.product_without_price', - ]; - - foreach ($definitionMap as $id => $definition) { - if ($request->request->has($id)) { - $gridId = $id; - $gridDefinition = $definition; - - break; - } - } - - return [ - 'grid_id' => $gridId, - 'grid_definition' => $this->get($gridDefinition), - ]; - } - - /** - * @param EmptyCategoryFilters $filters - * - * @return GridInterface - */ - private function getEmptyCategoryGrid(EmptyCategoryFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.empty_category'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param NoQtyProductWithCombinationFilters $filters - * - * @return GridInterface - */ - private function getNoQtyProductWithCombinationGrid(NoQtyProductWithCombinationFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.no_qty_product_with_combination'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param NoQtyProductWithoutCombinationFilters $filters - * - * @return GridInterface - */ - private function getNoQtyProductWithoutCombinationGrid(NoQtyProductWithoutCombinationFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.no_qty_product_without_combination'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param DisabledProductFilters $filters - * - * @return GridInterface - */ - private function getDisabledProductGrid(DisabledProductFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.disabled_product'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param ProductWithoutImageFilters $filters - * - * @return GridInterface - */ - private function getProductWithoutImageGrid(ProductWithoutImageFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.product_without_image'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param ProductWithoutDescriptionFilters $filters - * - * @return GridInterface - */ - private function getProductWithoutDescriptionGrid(ProductWithoutDescriptionFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.product_without_description'); - - return $gridFactory->getGrid($filters); - } - - /** - * @param ProductWithoutPriceFilters $filters - * - * @return GridInterface - */ - private function getProductWithoutPriceGrid(ProductWithoutPriceFilters $filters) - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.product_without_price'); - - return $gridFactory->getGrid($filters); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/SupplierController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/SupplierController.php deleted file mode 100644 index 09cd0dfc..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Catalog/SupplierController.php +++ /dev/null @@ -1,547 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Catalog; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDeleteSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDisableSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkEnableSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\DeleteSupplierCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Command\ToggleSupplierStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotDeleteSupplierException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotToggleSupplierStatusException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\CannotUpdateSupplierStatusException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Exception\SupplierNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForEditing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForViewing; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\EditableSupplier; -use PrestaShop\PrestaShop\Core\Domain\Supplier\QueryResult\ViewableSupplier; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderInterface; -use PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageOptimizationException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\ImageUploadException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\MemoryLimitException; -use PrestaShop\PrestaShop\Core\Image\Uploader\Exception\UploadedImageConstraintException; -use PrestaShop\PrestaShop\Core\Search\Filters\SupplierFilters; -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class SupplierController is responsible for "Sell > Catalog > Brands & Suppliers > Suppliers" page. - */ -class SupplierController extends FrameworkBundleAdminController -{ - /** - * Show suppliers listing. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param SupplierFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, SupplierFilters $filters) - { - $supplierGridFactory = $this->get('prestashop.core.grid.factory.supplier'); - $supplierGrid = $supplierGridFactory->getGrid($filters); - - return $this->render( - '@PrestaShop/Admin/Sell/Catalog/Suppliers/index.html.twig', - [ - 'supplierGrid' => $this->presentGrid($supplierGrid), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'settingsTipMessage' => $this->getSettingsTipMessage(), - ] - ); - } - - /** - * Displays supplier creation form and handles form submit which creates new supplier. - * - * @AdminSecurity( - * "is_granted('create', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to add this." - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - $formData = []; - if ($request->request->has('supplier') && isset($request->request->get('supplier')['id_country'])) { - $formCountryId = (int) $request->request->get('supplier')['id_country']; - $formData['id_country'] = $formCountryId; - } - - $supplierForm = $this->getFormBuilder()->getForm($formData); - $supplierForm->handleRequest($request); - - try { - $result = $this->getFormHandler()->handle($supplierForm); - - if (null !== $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_suppliers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Suppliers/add.html.twig', [ - 'supplierForm' => $supplierForm->createView(), - ]); - } - - /** - * Deletes supplier. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_suppliers_index" - * ) - * - * @param int $supplierId - * - * @return RedirectResponse - */ - public function deleteAction($supplierId) - { - try { - $this->getCommandBus()->handle(new DeleteSupplierCommand((int) $supplierId)); - - $this->addFlash( - 'success', - $this->trans('Successful deletion.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_suppliers_index'); - } - - /** - * Bulk deletion of suppliers. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to delete this." - * ) - * @DemoRestricted( - * redirectRoute="admin_suppliers_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request) - { - $suppliersToDelete = $request->request->get('supplier_bulk'); - - try { - $suppliersToDelete = array_map( - function ($item) { - return (int) $item; - }, - $suppliersToDelete - ); - $this->getCommandBus()->handle(new BulkDeleteSupplierCommand($suppliersToDelete)); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_suppliers_index'); - } - - /** - * Bulk disables supplier statuses. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_suppliers_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDisableAction(Request $request) - { - $suppliersToDisable = $request->request->get('supplier_bulk'); - - try { - $suppliersToDisable = array_map( - function ($item) { - return (int) $item; - }, - $suppliersToDisable - ); - $this->getCommandBus()->handle(new BulkDisableSupplierCommand($suppliersToDisable)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_suppliers_index'); - } - - /** - * Bulk enables supplier statuses. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_suppliers_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkEnableAction(Request $request) - { - $suppliersToEnable = $request->request->get('supplier_bulk'); - - try { - $suppliersToEnable = array_map( - function ($item) { - return (int) $item; - }, - $suppliersToEnable - ); - $this->getCommandBus()->handle(new BulkEnableSupplierCommand($suppliersToEnable)); - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_suppliers_index'); - } - - /** - * Displays edit supplier form and submits form. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to edit this." - * ) - * - * @param Request $request - * @param int $supplierId - * - * @return Response - */ - public function editAction(Request $request, $supplierId) - { - $formData = []; - if ($request->request->has('supplier') && isset($request->request->get('supplier')['id_country'])) { - $formCountryId = (int) $request->request->get('supplier')['id_country']; - $formData['id_country'] = $formCountryId; - } - - try { - /** @var EditableSupplier $editableSupplier */ - $editableSupplier = $this->getQueryBus()->handle(new GetSupplierForEditing((int) $supplierId)); - - $supplierForm = $this->getFormBuilder()->getFormFor((int) $supplierId, $formData); - $supplierForm->handleRequest($request); - - $result = $this->getFormHandler()->handleFor((int) $supplierId, $supplierForm); - - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_suppliers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - if (!isset($supplierForm) || !isset($editableSupplier)) { - return $this->redirectToRoute('admin_suppliers_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Suppliers/edit.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'supplierForm' => $supplierForm->createView(), - 'supplierName' => $editableSupplier->getName(), - 'logoImage' => $editableSupplier->getLogoImage(), - ]); - } - - /** - * Toggles supplier active status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_suppliers_index", - * message="You do not have permission to edit this." - * ) - * @DemoRestricted( - * redirectRoute="admin_suppliers_index" - * ) - * - * @param int $supplierId - * - * @return RedirectResponse - */ - public function toggleStatusAction($supplierId) - { - try { - $this->getCommandBus()->handle(new ToggleSupplierStatusCommand((int) $supplierId)); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_suppliers_index'); - } - - /** - * Views supplier products information. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * @param int $supplierId - * - * @return Response - */ - public function viewAction(Request $request, $supplierId) - { - try { - /** @var ViewableSupplier $viewableSupplier */ - $viewableSupplier = $this->getQueryBus()->handle(new GetSupplierForViewing( - (int) $supplierId, - (int) $this->getContextLangId() - )); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - - return $this->redirectToRoute('admin_suppliers_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/Catalog/Suppliers/view.html.twig', [ - 'layoutTitle' => $viewableSupplier->getName(), - 'viewableSupplier' => $viewableSupplier, - 'isStockManagementEnabled' => $this->configuration->get('PS_STOCK_MANAGEMENT'), - 'isAllShopContext' => $this->get('prestashop.adapter.shop.context')->isAllShopContext(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - ]); - } - - /** - * Exports to csv visible suppliers list data. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param SupplierFilters $filters - * - * @return CsvResponse - */ - public function exportAction(SupplierFilters $filters) - { - $filters = new SupplierFilters(['limit' => null] + $filters->all()); - $supplierGridFactory = $this->get('prestashop.core.grid.factory.supplier'); - $supplierGrid = $supplierGridFactory->getGrid($filters); - - $headers = [ - 'id_supplier' => $this->trans('ID', 'Admin.Global'), - 'name' => $this->trans('Name', 'Admin.Global'), - 'products_count' => $this->trans('Number of products', 'Admin.Catalog.Feature'), - 'active' => $this->trans('Enabled', 'Admin.Global'), - ]; - - $data = []; - - foreach ($supplierGrid->getData()->getRecords()->all() as $record) { - $data[] = [ - 'id_supplier' => $record['id_supplier'], - 'name' => $record['name'], - 'products_count' => $record['products_count'], - 'active' => $record['active'], - ]; - } - - return (new CsvResponse()) - ->setData($data) - ->setHeadersData($headers) - ->setFileName('supplier_' . date('Y-m-d_His') . '.csv') - ; - } - - /** - * Provides error messages for exceptions - * - * @return array - */ - private function getErrorMessages() - { - $iniConfig = $this->get('prestashop.core.configuration.ini_configuration'); - - return [ - SupplierNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found).', - 'Admin.Notifications.Error' - ), - AddressNotFoundException::class => $this->trans( - 'The address for this supplier has been deleted.', - 'Admin.Notifications.Error' - ), - CannotToggleSupplierStatusException::class => $this->trans( - 'An error occurred while updating the status.', - 'Admin.Notifications.Error' - ), - CannotUpdateSupplierStatusException::class => $this->trans( - 'An error occurred while updating the status for an object.', - 'Admin.Notifications.Error' - ), - SupplierConstraintException::class => [ - SupplierConstraintException::INVALID_BULK_DATA => $this->trans( - 'You must select at least one element to delete.', - 'Admin.Notifications.Error' - ), - ], - CannotDeleteSupplierException::class => [ - CannotDeleteSupplierException::HAS_PENDING_ORDERS => $this->trans( - 'It is not possible to delete a supplier if there are pending supplier orders.', - 'Admin.Catalog.Notification' - ), - CannotDeleteSupplierException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - CannotDeleteSupplierException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - MemoryLimitException::class => $this->trans( - 'Due to memory limit restrictions, this image cannot be loaded. Please increase your memory_limit value via your server\'s configuration settings.', - 'Admin.Notifications.Error' - ), - ImageUploadException::class => $this->trans( - 'An error occurred while uploading the image.', - 'Admin.Notifications.Error' - ), - ImageOptimizationException::class => $this->trans( - 'Unable to resize one or more of your pictures.', - 'Admin.Catalog.Notification' - ), - UploadedImageConstraintException::class => [ - UploadedImageConstraintException::EXCEEDED_SIZE => $this->trans( - 'Maximum image size: %s.', 'Admin.Global', [ - $iniConfig->getUploadMaxSizeInBytes(), - ]), - UploadedImageConstraintException::UNRECOGNIZED_FORMAT => $this->trans( - 'Image format not recognized, allowed formats are: .gif, .jpg, .png', - 'Admin.Notifications.Error' - ), - ], - ]; - } - - /** - * @return FormBuilderInterface - */ - private function getFormBuilder() - { - return $this->get('prestashop.core.form.identifiable_object.builder.supplier_form_builder'); - } - - /** - * @return FormHandlerInterface - */ - private function getFormHandler() - { - return $this->get('prestashop.core.form.identifiable_object.handler.supplier_form_handler'); - } - - protected function getSettingsTipMessage() - { - $urlOpening = sprintf('', $this->get('router')->generate('admin_preferences')); - $urlEnding = ''; - - if ($this->configuration->get('PS_DISPLAY_SUPPLIERS')) { - return $this->trans( - 'The display of your suppliers is enabled on your store. Go to %sShop Parameters > General%s to edit settings.', - 'Admin.Catalog.Notification', - [$urlOpening, $urlEnding] - ); - } - - return $this->trans( - 'The display of your suppliers is disabled on your store. Go to %sShop Parameters > General%s to edit settings.', - 'Admin.Catalog.Notification', - [$urlOpening, $urlEnding] - ); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php b/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php deleted file mode 100644 index 1d28ee84..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Customer/CustomerController.php +++ /dev/null @@ -1,963 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Customer; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDeleteCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDisableCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkEnableCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\DeleteCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\EditCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetPrivateNoteAboutCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetRequiredFieldsForCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Command\TransformGuestToCustomerCommand; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerByEmailNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerConstraintException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerDefaultGroupAccessException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\CustomerTransformationException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\DuplicateCustomerEmailException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Exception\MissingCustomerRequiredFieldsException; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerCarts; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForAddressCreation; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForEditing; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForViewing; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerOrders; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetRequiredFieldsForCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\Query\SearchCustomers; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\AddressCreationCustomerInformation; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\EditableCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\QueryResult\ViewableCustomer; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Password; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed; -use PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ValueObject\ShowcaseCard; -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CustomerGridDefinitionFactory; -use PrestaShop\PrestaShop\Core\Search\Filters\CustomerFilters; -use PrestaShopBundle\Component\CsvResponse; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController as AbstractAdminController; -use PrestaShopBundle\Form\Admin\Sell\Customer\DeleteCustomersType; -use PrestaShopBundle\Form\Admin\Sell\Customer\PrivateNoteType; -use PrestaShopBundle\Form\Admin\Sell\Customer\RequiredFieldsType; -use PrestaShopBundle\Form\Admin\Sell\Customer\TransferGuestAccountType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use PrestaShopBundle\Security\Annotation\DemoRestricted; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class CustomerController manages "Sell > Customers" page. - */ -class CustomerController extends AbstractAdminController -{ - /** - * Show customers listing. - * - * @AdminSecurity( - * "is_granted('read', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to view this." - * ) - * - * @param Request $request - * @param CustomerFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, CustomerFilters $filters) - { - $customersKpiFactory = $this->get('prestashop.core.kpi_row.factory.customers'); - - $customerGridFactory = $this->get('prestashop.core.grid.factory.customer'); - $customerGrid = $customerGridFactory->getGrid($filters); - - $deleteCustomerForm = $this->createForm(DeleteCustomersType::class); - - $showcaseCardIsClosed = $this->getQueryBus()->handle( - new GetShowcaseCardIsClosed((int) $this->getContext()->employee->id, ShowcaseCard::CUSTOMERS_CARD) - ); - - return $this->render('@PrestaShop/Admin/Sell/Customer/index.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'customerGrid' => $this->presentGrid($customerGrid), - 'customersKpi' => $customersKpiFactory->build(), - 'customerRequiredFieldsForm' => $this->getRequiredFieldsForm()->createView(), - 'isSingleShopContext' => $this->get('prestashop.adapter.shop.context')->isSingleShopContext(), - 'deleteCustomersForm' => $deleteCustomerForm->createView(), - 'showcaseCardName' => ShowcaseCard::CUSTOMERS_CARD, - 'isShowcaseCardClosed' => $showcaseCardIsClosed, - ]); - } - - /** - * Process Grid search. - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return RedirectResponse - */ - public function searchGridAction(Request $request) - { - $responseBuilder = $this->get('prestashop.bundle.grid.response_builder'); - - return $responseBuilder->buildSearchResponse( - $this->get('prestashop.core.grid.definition.factory.customer'), - $request, - CustomerGridDefinitionFactory::GRID_ID, - 'admin_customers_index' - ); - } - - /** - * Show customer create form & handle processing of it. - * - * @AdminSecurity("is_granted(['create'], request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request) - { - if (!$this->get('prestashop.adapter.shop.context')->isSingleShopContext()) { - return $this->redirectToRoute('admin_customers_index'); - } - - $this->addGroupSelectionToRequest($request); - - $customerForm = $this->get('prestashop.core.form.identifiable_object.builder.customer_form_builder')->getForm(); - $customerForm->handleRequest($request); - - $customerFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.customer_form_handler'); - - try { - $result = $customerFormHandler->handle($customerForm); - - if ($customerId = $result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - if ($request->query->has('submitFormAjax')) { - /** @var ViewableCustomer $customerInformation */ - $customerInformation = $this->getQueryBus()->handle(new GetCustomerForViewing((int) $customerId)); - - return $this->render('@PrestaShop/Admin/Sell/Customer/modal_create_success.html.twig', [ - 'customerId' => $customerId, - 'customerEmail' => $customerInformation->getPersonalInformation()->getEmail(), - ]); - } - - return $this->redirectToRoute('admin_customers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->render('@PrestaShop/Admin/Sell/Customer/create.html.twig', [ - 'customerForm' => $customerForm->createView(), - 'isB2bFeatureActive' => $this->get('prestashop.core.b2b.b2b_feature')->isActive(), - 'minPasswordLength' => Password::MIN_LENGTH, - 'displayInIframe' => $request->query->has('submitFormAjax'), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * Show customer edit form & handle processing of it. - * - * @AdminSecurity("is_granted(['update'], request.get('_legacy_controller'))") - * - * @param int $customerId - * @param Request $request - * - * @return Response - */ - public function editAction($customerId, Request $request) - { - $this->addGroupSelectionToRequest($request); - try { - /** @var ViewableCustomer $customerInformation */ - $customerInformation = $this->getQueryBus()->handle(new GetCustomerForViewing((int) $customerId)); - $customerFormOptions = [ - 'is_password_required' => false, - ]; - $customerForm = $this->get('prestashop.core.form.identifiable_object.builder.customer_form_builder') - ->getFormFor((int) $customerId, [], $customerFormOptions); - $customerForm->handleRequest($request); - $customerFormHandler = $this->get('prestashop.core.form.identifiable_object.handler.customer_form_handler'); - $result = $customerFormHandler->handleFor((int) $customerId, $customerForm); - if ($result->isSubmitted() && $result->isValid()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_customers_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - if ($e instanceof CustomerNotFoundException) { - return $this->redirectToRoute('admin_customers_index'); - } - } - - return $this->render('@PrestaShop/Admin/Sell/Customer/edit.html.twig', [ - 'customerForm' => $customerForm->createView(), - 'customerInformation' => $customerInformation, - 'isB2bFeatureActive' => $this->get('prestashop.core.b2b.b2b_feature')->isActive(), - 'minPasswordLength' => Password::MIN_LENGTH, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - ]); - } - - /** - * View customer information. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))", redirectRoute="admin_customers_index") - * @DemoRestricted(redirectRoute="admin_customers_index") - * - * @param int $customerId - * @param Request $request - * - * @return Response - */ - public function viewAction($customerId, Request $request) - { - try { - /** @var ViewableCustomer $customerInformation */ - $customerInformation = $this->getQueryBus()->handle(new GetCustomerForViewing((int) $customerId)); - } catch (CustomerNotFoundException $e) { - $this->addFlash( - 'error', - $this->trans('This customer does not exist.', 'Admin.Orderscustomers.Notification') - ); - - return $this->redirectToRoute('admin_customers_index'); - } - - $transferGuestAccountForm = null; - if ($customerInformation->getPersonalInformation()->isGuest()) { - $transferGuestAccountForm = $this->createForm(TransferGuestAccountType::class, [ - 'id_customer' => $customerId, - ])->createView(); - } - - $privateNoteForm = $this->createForm(PrivateNoteType::class, [ - 'note' => $customerInformation->getGeneralInformation()->getPrivateNote(), - ]); - - if ($request->query->has('conf')) { - $this->manageLegacyFlashes($request->query->get('conf')); - } - - return $this->render('@PrestaShop/Admin/Sell/Customer/view.html.twig', [ - 'enableSidebar' => true, - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'customerInformation' => $customerInformation, - 'isMultistoreEnabled' => $this->get('prestashop.adapter.feature.multistore')->isActive(), - 'transferGuestAccountForm' => $transferGuestAccountForm, - 'privateNoteForm' => $privateNoteForm->createView(), - ]); - } - - /** - * Set private note about customer. - * - * @AdminSecurity( - * "is_granted(['update', 'create'], request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index" - * ) - * - * @param int $customerId - * @param Request $request - * - * @return Response - */ - public function setPrivateNoteAction($customerId, Request $request) - { - $privateNoteForm = $this->createForm(PrivateNoteType::class); - $privateNoteForm->handleRequest($request); - - if ($privateNoteForm->isSubmitted()) { - $data = $privateNoteForm->getData(); - - try { - $this->getCommandBus()->handle(new SetPrivateNoteAboutCustomerCommand( - (int) $customerId, - $data['note'] - )); - - if ($request->isXmlHttpRequest()) { - return $this->json([ - 'success' => true, - 'message' => $this->trans('Successful update.', 'Admin.Notifications.Success'), - ]); - } - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (CustomerException $e) { - $this->addFlash( - 'error', - $this->getErrorMessageForException($e, $this->getErrorMessages($e)) - ); - } - } - - return $this->redirectToRoute('admin_customers_view', [ - 'customerId' => $customerId, - ]); - } - - /** - * Transforms guest to customer - * - * @AdminSecurity( - * "is_granted(['update', 'create'], request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index" - * ) - * - * @param int $customerId - * @param Request $request - * - * @return RedirectResponse - */ - public function transformGuestToCustomerAction($customerId, Request $request) - { - try { - $this->getCommandBus()->handle(new TransformGuestToCustomerCommand((int) $customerId)); - - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - if ($request->query->get('id_order')) { - $legacyLink = $this->getAdminLink('AdminOrders', [ - 'id_order' => $request->query->get('id_order'), - 'vieworder' => true, - ]); - - return $this->redirect($legacyLink); - } - - return $this->redirectToRoute('admin_customers_view', [ - 'customerId' => $customerId, - ]); - } - - /** - * Sets required fields for customer - * - * @AdminSecurity( - * "is_granted(['update', 'create'], request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function setRequiredFieldsAction(Request $request) - { - $requiredFieldsForm = $this->getRequiredFieldsForm(); - $requiredFieldsForm->handleRequest($request); - - if ($requiredFieldsForm->isSubmitted()) { - $data = $requiredFieldsForm->getData(); - - $this->getCommandBus()->handle(new SetRequiredFieldsForCustomerCommand($data['required_fields'])); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Search for customers by query. - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller')) || is_granted('create', 'AdminOrders')") - * - * @param Request $request - * - * @return JsonResponse - */ - public function searchAction(Request $request) - { - $query = $request->query->get('customer_search'); - $phrases = explode(' ', $query); - $isRequestFromLegacyPage = !$request->query->has('sf2'); - - try { - $customers = $this->getQueryBus()->handle(new SearchCustomers($phrases)); - } catch (Exception $e) { - return $this->json( - ['message' => $this->getErrorMessageForException($e, $this->getErrorMessages($e))], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - - // if call is made from legacy page - // it will return response so legacy can understand it - if ($isRequestFromLegacyPage) { - return $this->json([ - 'found' => !empty($customers), - 'customers' => $customers, - ]); - } - - return $this->json($customers); - } - - /** - * Provides customer information for address creation in json format - * - * @AdminSecurity("is_granted('read', request.get('_legacy_controller'))") - * - * @param Request $request - * - * @return JsonResponse - */ - public function getCustomerInformationAction(Request $request): Response - { - try { - $email = $request->query->get('email'); - - /** @var AddressCreationCustomerInformation $customerInformation */ - $customerInformation = $this->getQueryBus()->handle(new GetCustomerForAddressCreation($email)); - - return $this->json($customerInformation); - } catch (Exception $e) { - $code = Response::HTTP_INTERNAL_SERVER_ERROR; - - if ($e instanceof CustomerException) { - $code = Response::HTTP_NOT_FOUND; - } - - return $this->json([ - 'message' => $this->getErrorMessageForException($e, $this->getErrorMessages($e)), - ], - $code - ); - } - } - - /** - * Toggle customer status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to edit this." - * ) - * - * @param int $customerId - * - * @return RedirectResponse - */ - public function toggleStatusAction($customerId) - { - try { - /** @var EditableCustomer $editableCustomer */ - $editableCustomer = $this->getQueryBus()->handle(new GetCustomerForEditing((int) $customerId)); - - $editCustomerCommand = new EditCustomerCommand((int) $customerId); - $editCustomerCommand->setIsEnabled(!$editableCustomer->isEnabled()); - - $this->getCommandBus()->handle($editCustomerCommand); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Toggle customer newsletter subscription status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to edit this." - * ) - * - * @param int $customerId - * - * @return RedirectResponse - */ - public function toggleNewsletterSubscriptionAction($customerId) - { - try { - /** @var EditableCustomer $editableCustomer */ - $editableCustomer = $this->getQueryBus()->handle(new GetCustomerForEditing((int) $customerId)); - - $editCustomerCommand = new EditCustomerCommand((int) $customerId); - - // toggle newsletter subscription - $editCustomerCommand->setNewsletterSubscribed(!$editableCustomer->isNewsletterSubscribed()); - - $this->getCommandBus()->handle($editCustomerCommand); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Toggle customer partner offer subscription status. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to edit this." - * ) - * - * @param int $customerId - * - * @return RedirectResponse - */ - public function togglePartnerOfferSubscriptionAction($customerId) - { - try { - /** @var EditableCustomer $editableCustomer */ - $editableCustomer = $this->getQueryBus()->handle(new GetCustomerForEditing((int) $customerId)); - - $editCustomerCommand = new EditCustomerCommand((int) $customerId); - $editCustomerCommand->setIsPartnerOffersSubscribed(!$editableCustomer->isPartnerOffersSubscribed()); - - $this->getCommandBus()->handle($editCustomerCommand); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Delete customers in bulk action. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to delete this." - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteBulkAction(Request $request) - { - $form = $this->createForm(DeleteCustomersType::class); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - $customerIds = array_map(function ($customerId) { - return (int) $customerId; - }, $data['customers_to_delete']); - - try { - $command = new BulkDeleteCustomerCommand( - $customerIds, - $data['delete_method'] - ); - - $this->getCommandBus()->handle($command); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Delete customer. - * - * @AdminSecurity( - * "is_granted('delete', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to delete this." - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function deleteAction(Request $request) - { - $form = $this->createForm(DeleteCustomersType::class); - $form->handleRequest($request); - - if ($form->isSubmitted()) { - $data = $form->getData(); - - $customerId = (int) reset($data['customers_to_delete']); - - try { - $command = new DeleteCustomerCommand( - $customerId, - $data['delete_method'] - ); - - $this->getCommandBus()->handle($command); - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Enable customers in bulk action. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to edit this." - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function enableBulkAction(Request $request) - { - $customerIds = array_map(function ($customerId) { - return (int) $customerId; - }, $request->request->get('customer_customers_bulk', [])); - - try { - $command = new BulkEnableCustomerCommand($customerIds); - - $this->getCommandBus()->handle($command); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Disable customers in bulk action. - * - * @AdminSecurity( - * "is_granted('update', request.get('_legacy_controller'))", - * redirectRoute="admin_customers_index", - * message="You do not have permission to edit this." - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function disableBulkAction(Request $request) - { - try { - $customerIds = array_map(function ($customerId) { - return (int) $customerId; - }, $request->request->get('customer_customers_bulk', [])); - - $command = new BulkDisableCustomerCommand($customerIds); - - $this->getCommandBus()->handle($command); - - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - } catch (CustomerException $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages($e))); - } - - return $this->redirectToRoute('admin_customers_index'); - } - - /** - * Export filtered customers - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param CustomerFilters $filters - * - * @return CsvResponse - */ - public function exportAction(CustomerFilters $filters) - { - $filters = new CustomerFilters(['limit' => null] + $filters->all()); - $gridFactory = $this->get('prestashop.core.grid.factory.customer'); - $grid = $gridFactory->getGrid($filters); - - $headers = [ - 'id_customer' => $this->trans('ID', 'Admin.Global'), - 'social_title' => $this->trans('Social title', 'Admin.Global'), - 'firstname' => $this->trans('First name', 'Admin.Global'), - 'lastname' => $this->trans('Last name', 'Admin.Global'), - 'email' => $this->trans('Email address', 'Admin.Global'), - 'company' => $this->trans('Company', 'Admin.Global'), - 'total_spent' => $this->trans('Sales', 'Admin.Global'), - 'enabled' => $this->trans('Enabled', 'Admin.Global'), - 'newsletter' => $this->trans('Newsletter', 'Admin.Global'), - 'partner_offers' => $this->trans('Partner offers', 'Admin.Orderscustomers.Feature'), - 'registration' => $this->trans('Registration', 'Admin.Orderscustomers.Feature'), - 'connect' => $this->trans('Last visit', 'Admin.Orderscustomers.Feature'), - ]; - - $data = []; - - foreach ($grid->getData()->getRecords()->all() as $record) { - $data[] = [ - 'id_customer' => $record['id_customer'], - 'social_title' => '--' === $record['social_title'] ? '' : $record['social_title'], - 'firstname' => $record['firstname'], - 'lastname' => $record['lastname'], - 'email' => $record['email'], - 'company' => '--' === $record['company'] ? '' : $record['company'], - 'total_spent' => '--' === $record['total_spent'] ? '' : $record['total_spent'], - 'enabled' => $record['active'], - 'newsletter' => $record['newsletter'], - 'partner_offers' => $record['optin'], - 'registration' => $record['date_add'], - 'connect' => '--' === $record['connect'] ? '' : $record['connect'], - ]; - } - - return (new CsvResponse()) - ->setData($data) - ->setHeadersData($headers) - ->setFileName('customer_' . date('Y-m-d_His') . '.csv'); - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller')) || is_granted('create', 'AdminOrders')") - * - * @param int $customerId - * - * @return JsonResponse - */ - public function getCartsAction(int $customerId) - { - try { - $carts = $this->getQueryBus()->handle(new GetCustomerCarts($customerId)); - } catch (Exception $e) { - return $this->json( - ['message' => $this->getErrorMessageForException($e, $this->getErrorMessages($e))], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - - return $this->json([ - 'carts' => $carts, - ]); - } - - /** - * @AdminSecurity("is_granted('read', request.get('_legacy_controller')) || is_granted('create', 'AdminOrders')") - * - * @param int $customerId - * - * @return JsonResponse - */ - public function getOrdersAction(int $customerId) - { - try { - $orders = $this->getQueryBus()->handle(new GetCustomerOrders($customerId)); - } catch (Exception $e) { - return $this->json( - ['message' => $this->getErrorMessageForException($e, $this->getErrorMessages($e))], - Response::HTTP_INTERNAL_SERVER_ERROR - ); - } - - return $this->json([ - 'orders' => $orders, - ]); - } - - /** - * @return FormInterface - */ - private function getRequiredFieldsForm() - { - $requiredFields = $this->getQueryBus()->handle(new GetRequiredFieldsForCustomer()); - - return $this->createForm(RequiredFieldsType::class, ['required_fields' => $requiredFields]); - } - - /** - * If customer form is submitted and groups are not selected - * we add empty groups to request - * - * @param Request $request - */ - private function addGroupSelectionToRequest(Request $request) - { - if (!$request->isMethod(Request::METHOD_POST)) { - return; - } - - if (!$request->request->has('customer') - || isset($request->request->get('customer')['group_ids']) - ) { - return; - } - - $customerData = $request->request->get('customer'); - $customerData['group_ids'] = []; - - $request->request->set('customer', $customerData); - } - - /** - * Get errors that can be used to translate exceptions into user friendly messages - * - * @param Exception $e - * - * @return array - */ - private function getErrorMessages(Exception $e) - { - return [ - CustomerNotFoundException::class => $this->trans( - 'This customer does not exist.', - 'Admin.Orderscustomers.Notification' - ), - DuplicateCustomerEmailException::class => sprintf( - '%s %s', - $this->trans('An account already exists for this email address:', 'Admin.Orderscustomers.Notification'), - $e instanceof DuplicateCustomerEmailException ? $e->getEmail()->getValue() : '' - ), - CustomerDefaultGroupAccessException::class => $this->trans( - 'A default customer group must be selected in group box.', - 'Admin.Orderscustomers.Notification' - ), - CustomerByEmailNotFoundException::class => $this->trans( - 'This email address is not registered.', - 'Admin.Orderscustomers.Notification' - ), - CustomerConstraintException::class => [ - CustomerConstraintException::INVALID_PASSWORD => $this->trans( - 'Password should be at least %length% characters long.', - 'Admin.Orderscustomers.Help', - ['%length%' => Password::MIN_LENGTH] - ), - CustomerConstraintException::INVALID_FIRST_NAME => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('First name', 'Admin.Global'))] - ), - CustomerConstraintException::INVALID_LAST_NAME => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Last name', 'Admin.Global'))] - ), - CustomerConstraintException::INVALID_EMAIL => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Email', 'Admin.Global'))] - ), - CustomerConstraintException::INVALID_BIRTHDAY => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('Birthday', 'Admin.Orderscustomers.Feature'))] - ), - CustomerConstraintException::INVALID_APE_CODE => $this->trans( - 'The %s field is invalid.', - 'Admin.Notifications.Error', - [sprintf('"%s"', $this->trans('APE', 'Admin.Orderscustomers.Feature'))] - ), - ], - CustomerTransformationException::class => [ - CustomerTransformationException::CUSTOMER_IS_NOT_GUEST => $this->trans( - 'This customer already exists as a non-guest.', - 'Admin.Orderscustomers.Notification' - ), - CustomerTransformationException::TRANSFORMATION_FAILED => $this->trans( - 'An error occurred while updating customer information.', - 'Admin.Orderscustomers.Notification' - ), - ], - MissingCustomerRequiredFieldsException::class => $this->trans( - 'The field %s is required.', - 'Admin.Notifications.Error', - [ - implode( - ',', - $e instanceof MissingCustomerRequiredFieldsException ? $e->getMissingRequiredFields() : [] - ), - ] - ), - ]; - } - - /** - * Manage legacy flashes - * - * @todo Remove this code when legacy edit will be migrated. - * - * @param int $messageId The message id from legacy context - */ - private function manageLegacyFlashes($messageId) - { - $messages = [ - 4 => $this->trans('Update successful.', 'Admin.Notifications.Success'), - ]; - - if (isset($messages[$messageId])) { - $this->addFlash( - 'success', - $messages[$messageId] - ); - } - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/CustomerThreadController.php b/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/CustomerThreadController.php deleted file mode 100644 index 21c38036..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/CustomerThreadController.php +++ /dev/null @@ -1,265 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\CustomerService; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ForwardCustomerThreadCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ReplyToCustomerThreadCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\UpdateCustomerThreadStatusCommand; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerServiceSignature; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerThreadForViewing; -use PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryResult\CustomerThreadView; -use PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeEmailById; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Email; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Form\Admin\CustomerService\CustomerThread\ForwardCustomerThreadType; -use PrestaShopBundle\Form\Admin\Sell\CustomerService\ReplyToCustomerThreadType; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Manages page under "Sell > Customer Service > Customer Service" - */ -class CustomerThreadController extends FrameworkBundleAdminController -{ - /** - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * message="You do not have permission to view this.", - * redirectRoute="admin_customer_threads_index" - * ) - * - * @param Request $request - * @param int $customerThreadId - * - * @return Response - */ - public function viewAction(Request $request, $customerThreadId) - { - /** @var CustomerThreadView $customerThreadView */ - $customerThreadView = $this->getQueryBus()->handle( - new GetCustomerThreadForViewing((int) $customerThreadId) - ); - - /** @var string $customerServiceSignature */ - $customerServiceSignature = $this->getQueryBus()->handle( - new GetCustomerServiceSignature($customerThreadView->getLanguageId()->getValue()) - ); - - $replyToCustomerThreadForm = $this->createForm(ReplyToCustomerThreadType::class, [ - 'reply_message' => $customerServiceSignature, - ]); - - $forwardCustomerThreadForm = $this->createForm(ForwardCustomerThreadType::class); - - return $this->render('@PrestaShop/Admin/Sell/CustomerService/CustomerThread/view.html.twig', [ - 'customerThreadView' => $customerThreadView, - 'employeeAvatarUrl' => $this->getContext()->employee->getImage(), - 'customerServiceSignature' => $customerServiceSignature, - 'replyToCustomerThreadForm' => $replyToCustomerThreadForm->createView(), - 'forwardCustomerThreadForm' => $forwardCustomerThreadForm->createView(), - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('View', 'Admin.Actions'), - ]); - } - - /** - * Reply to customer thread - * - * @AdminSecurity( - * "is_granted(['create', 'update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_customer_threads_index" - * ) - * - * @param Request $request - * @param int $customerThreadId - * - * @return RedirectResponse - */ - public function replyAction(Request $request, $customerThreadId) - { - $replyToCustomerThreadForm = $this->createForm(ReplyToCustomerThreadType::class); - $replyToCustomerThreadForm->handleRequest($request); - - if (!$replyToCustomerThreadForm->isSubmitted()) { - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - if (!$replyToCustomerThreadForm->isValid()) { - foreach ($replyToCustomerThreadForm->getErrors(true) as $error) { - $this->addFlash('error', $error->getMessage()); - } - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - $data = $replyToCustomerThreadForm->getData(); - - try { - $this->getCommandBus()->handle( - new ReplyToCustomerThreadCommand((int) $customerThreadId, $data['reply_message']) - ); - - $this->addFlash( - 'success', - $this->trans( - 'The message was successfully sent to the customer.', - 'Admin.Orderscustomers.Notification' - ) - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, [])); - } - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - /** - * Update customer thread status - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_customer_threads_index" - * ) - * - * @param int $customerThreadId - * @param string $newStatus - * - * @return RedirectResponse - */ - public function updateStatusAction($customerThreadId, $newStatus) - { - try { - $this->getCommandBus()->handle( - new UpdateCustomerThreadStatusCommand((int) $customerThreadId, $newStatus) - ); - - $this->addFlash( - 'success', - $this->trans('The status has been successfully updated.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, [])); - } - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - /** - * Forward customer thread to another employee - * - * @AdminSecurity( - * "is_granted(['create', 'update'], request.get('_legacy_controller'))", - * message="You do not have permission to update this.", - * redirectRoute="admin_customer_threads_index" - * ) - * - * @param Request $request - * @param int $customerThreadId - * - * @return RedirectResponse - */ - public function forwardAction(Request $request, $customerThreadId) - { - $forwardCustomerThreadForm = $this->createForm(ForwardCustomerThreadType::class); - $forwardCustomerThreadForm->handleRequest($request); - - if (!$forwardCustomerThreadForm->isSubmitted()) { - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - if (!$forwardCustomerThreadForm->isValid()) { - foreach ($forwardCustomerThreadForm->getErrors(true) as $error) { - $this->addFlash('error', $error->getMessage()); - } - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - $data = $forwardCustomerThreadForm->getData(); - - if (!$data['employee_id'] && empty($data['someone_else_email'])) { - $this->addFlash('error', $this->trans('The email address is invalid.', 'Admin.Notifications.Error')); - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } - - if ($data['employee_id']) { - /** @var Email $employeeEmail */ - $employeeEmail = $this->getQueryBus()->handle(new GetEmployeeEmailById((int) $data['employee_id'])); - $forwardEmail = $employeeEmail->getValue(); - - $command = ForwardCustomerThreadCommand::toAnotherEmployee( - (int) $customerThreadId, - (int) $data['employee_id'], - $data['comment'] - ); - } else { - $forwardEmail = $data['someone_else_email']; - - $command = ForwardCustomerThreadCommand::toSomeoneElse( - (int) $customerThreadId, - $data['someone_else_email'], - $data['comment'] - ); - } - - try { - $this->getCommandBus()->handle($command); - - $this->addFlash( - 'success', - sprintf('%s %s', $this->trans('Message forwarded to', 'Admin.Catalog.Feature'), $forwardEmail) - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, [])); - } - - return $this->redirectToRoute('admin_customer_threads_view', [ - 'customerThreadId' => $customerThreadId, - ]); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/MerchandiseReturnController.php b/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/MerchandiseReturnController.php deleted file mode 100644 index fab604f8..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/MerchandiseReturnController.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\CustomerService; - -use PrestaShop\PrestaShop\Core\Form\FormHandlerInterface; -use PrestaShop\PrestaShop\Core\Search\Filters\MerchandiseReturnFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Class MerchandiseReturnController responsible for "Sell > Customer Service > Merchandise Returns" page - */ -class MerchandiseReturnController extends FrameworkBundleAdminController -{ - /** - * Render merchandise returns grid and options. - * - * @AdminSecurity( - * "is_granted(['read'], request.get('_legacy_controller'))", - * redirectRoute="admin_merchandise_return_index" - * ) - * - * @param Request $request - * @param MerchandiseReturnFilters $filters - * - * @return Response - */ - public function indexAction(Request $request, MerchandiseReturnFilters $filters): Response - { - $gridFactory = $this->get('prestashop.core.grid.factory.merchandise_return'); - $gridPresenter = $this->get('prestashop.core.grid.presenter.grid_presenter'); - - $optionsFormHandler = $this->getOptionsFormHandler(); - $optionsForm = $optionsFormHandler->getForm(); - $optionsForm->handleRequest($request); - - if ($optionsForm->isSubmitted() && $optionsForm->isValid()) { - $errors = $optionsFormHandler->save($optionsForm->getData()); - - if (empty($errors)) { - $this->addFlash('success', $this->trans('Update successful', 'Admin.Notifications.Success')); - } else { - $this->flashErrors($errors); - } - } - - return $this->render('@PrestaShop/Admin/Sell/CustomerService/MerchandiseReturn/index.html.twig', [ - 'merchandiseReturnsGrid' => $gridPresenter->present($gridFactory->getGrid($filters)), - 'merchandiseReturnsOptionsForm' => $optionsForm->createView(), - ]); - } - - /** - * @return FormHandlerInterface - */ - private function getOptionsFormHandler(): FormHandlerInterface - { - return $this->get('prestashop.admin.merchandise_return_options.form_handler'); - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/OrderMessageController.php b/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/OrderMessageController.php deleted file mode 100644 index d561c044..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/CustomerService/OrderMessageController.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\CustomerService; - -use Exception; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\BulkDeleteOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\DeleteOrderMessageCommand; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageException; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Exception\OrderMessageNotFoundException; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query\GetOrderMessageForEditing; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\QueryResult\EditableOrderMessage; -use PrestaShop\PrestaShop\Core\Search\Filters\OrderMessageFilters; -use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * Manages page under "Sell > Customer Service > Order Messages" - */ -class OrderMessageController extends FrameworkBundleAdminController -{ - /** - * Show list of Order messages - * - * @AdminSecurity("is_granted(['read'], request.get('_legacy_controller'))") - * - * @param OrderMessageFilters $filters - * @param Request $request - * - * @return Response - */ - public function indexAction(OrderMessageFilters $filters, Request $request): Response - { - $gridFactory = $this->get('prestashop.core.grid.grid_factory.order_message'); - $grid = $gridFactory->getGrid($filters); - - return $this->render('@PrestaShop/Admin/Sell/CustomerService/OrderMessage/index.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Order Messages', 'Admin.Navigation.Menu'), - 'layoutHeaderToolbarBtn' => [ - 'add' => [ - 'href' => $this->generateUrl('admin_order_messages_create'), - 'desc' => $this->trans('Add new order message', 'Admin.Orderscustomers.Feature'), - 'icon' => 'add_circle_outline', - ], - ], - 'orderMessageGrid' => $this->presentGrid($grid), - ]); - } - - /** - * Create new order message - * - * @AdminSecurity( - * "is_granted(['create'], request.get('_legacy_controller'))", - * redirectRoute="admin_order_messages_index" - * ) - * - * @param Request $request - * - * @return Response - */ - public function createAction(Request $request): Response - { - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.order_message_form_builder'); - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.order_message_form_handler'); - - $form = $formBuilder->getForm(); - $form->handleRequest($request); - - try { - $result = $formHandler->handle($form); - - if ($result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful creation.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_order_messages_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->render('@PrestaShop/Admin/Sell/CustomerService/OrderMessage/create.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'layoutTitle' => $this->trans('Add new', 'Admin.Actions'), - 'orderMessageForm' => $form->createView(), - ]); - } - - /** - * Edit existing order message - * - * @AdminSecurity( - * "is_granted(['update'], request.get('_legacy_controller'))", - * redirectRoute="admin_order_messages_index" - * ) - * - * @param int $orderMessageId - * @param Request $request - * - * @return Response - */ - public function editAction(int $orderMessageId, Request $request): Response - { - $formBuilder = $this->get('prestashop.core.form.identifiable_object.builder.order_message_form_builder'); - $formHandler = $this->get('prestashop.core.form.identifiable_object.handler.order_message_form_handler'); - - try { - /** @var EditableOrderMessage $editableOrderMessage */ - $editableOrderMessage = $this->getQueryBus()->handle(new GetOrderMessageForEditing($orderMessageId)); - - $orderMessageName = $editableOrderMessage->getLocalizedName()[$this->getContextLangId()]; - - $form = $formBuilder->getFormFor($orderMessageId); - $form->handleRequest($request); - - $result = $formHandler->handleFor($orderMessageId, $form); - - if ($result->getIdentifiableObjectId()) { - $this->addFlash('success', $this->trans('Successful update.', 'Admin.Notifications.Success')); - - return $this->redirectToRoute('admin_order_messages_index'); - } - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - if (!isset($form) || !isset($orderMessageName)) { - return $this->redirectToRoute('admin_order_messages_index'); - } - - return $this->render('@PrestaShop/Admin/Sell/CustomerService/OrderMessage/edit.html.twig', [ - 'help_link' => $this->generateSidebarLink($request->attributes->get('_legacy_controller')), - 'enableSidebar' => true, - 'layoutTitle' => sprintf($this->trans('Edit: %s', 'Admin.Actions'), $orderMessageName), - 'orderMessageForm' => $form->createView(), - ]); - } - - /** - * Delete single order message - * - * @AdminSecurity( - * "is_granted(['delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_order_messages_index" - * ) - * - * @param int $orderMessageId - * - * @return RedirectResponse - */ - public function deleteAction(int $orderMessageId): RedirectResponse - { - try { - $this->getCommandBus()->handle(new DeleteOrderMessageCommand($orderMessageId)); - - $this->addFlash('success', $this->trans('Successful deletion.', 'Admin.Notifications.Success')); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_order_messages_index'); - } - - /** - * Delete order messages in bulk action - * - * @AdminSecurity( - * "is_granted(['delete'], request.get('_legacy_controller'))", - * redirectRoute="admin_order_messages_index" - * ) - * - * @param Request $request - * - * @return RedirectResponse - */ - public function bulkDeleteAction(Request $request): RedirectResponse - { - try { - $orderMessageIds = array_map(static function ($orderMessageId) { - return (int) $orderMessageId; - }, $request->request->get('order_message_order_messages_bulk')); - - $this->getCommandBus()->handle(new BulkDeleteOrderMessageCommand($orderMessageIds)); - - $this->addFlash( - 'success', - $this->trans('The selection has been successfully deleted.', 'Admin.Notifications.Success') - ); - } catch (Exception $e) { - $this->addFlash('error', $this->getErrorMessageForException($e, $this->getErrorMessages())); - } - - return $this->redirectToRoute('admin_order_messages_index'); - } - - /** - * Get user friendly errors for exception - * - * @return array - */ - private function getErrorMessages(): array - { - return [ - OrderMessageException::class => [ - OrderMessageException::FAILED_DELETE => $this->trans( - 'An error occurred while deleting the object.', - 'Admin.Notifications.Error' - ), - OrderMessageException::FAILED_BULK_DELETE => $this->trans( - 'An error occurred while deleting this selection.', - 'Admin.Notifications.Error' - ), - ], - OrderMessageNotFoundException::class => $this->trans( - 'The object cannot be loaded (or found)', - 'Admin.Notifications.Error' - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButton.php b/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButton.php deleted file mode 100644 index 35a0f492..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButton.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Order; - -class ActionsBarButton implements ActionsBarButtonInterface -{ - /** - * @var string - */ - protected $class; - - /** - * @var string[] - */ - protected $properties; - - /** - * @var string - */ - protected $content; - - /** - * @param string $class - * @param string[] $properties - * @param string $content - */ - public function __construct(string $class = '', array $properties = [], string $content = '') - { - $this->class = $class; - $this->properties = $properties; - $this->content = $content; - } - - /** - * @return string - */ - public function getClass(): string - { - return $this->class; - } - - /** - * @return string[] - */ - public function getProperties(): array - { - return $this->properties; - } - - /** - * @return string - */ - public function getContent(): string - { - return $this->content; - } -} diff --git a/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButtonInterface.php b/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButtonInterface.php deleted file mode 100644 index 85998201..00000000 --- a/src/PrestaShopBundle/Controller/Admin/Sell/Order/ActionsBarButtonInterface.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Controller\Admin\Sell\Order; - -/** - * This class represents buttons to be rendered in Twig - * - * They will be rendered following this structure: - * - * If this is the 1st button or there are only 2 buttons displayed: - * - * - * {{ button.content|raw }} - * - * - * However if there is more than 2 buttons displayed, then they are rendered into a drop-down list: - * - * - * {{ button.content|raw }} - * - */ -interface ActionsBarButtonInterface -{ - /** - * This function will provide content to add extra CSS classes - * - * @return string - */ - public function getClass(): string; - - /** - * Use this property to add extra properties to - ', - 'required' => false, - 'label' => $this->translator->trans('Add products to your pack', [], 'Admin.Catalog.Feature'), - ]) - ->add('name', TranslateType::class, [ - 'type' => FormType\TextType::class, - 'options' => [ - 'constraints' => [ - new Assert\Regex([ - 'pattern' => '/[<>;=#{}]/', - 'match' => false, - ]), - new Assert\NotBlank(), - new Assert\Length(['min' => 3, 'max' => 128]), - ], - 'attr' => [ - 'placeholder' => $this->translator->trans('Enter your product name', [], 'Admin.Catalog.Help'), - 'class' => 'edit js-edit serp-default-title', - ], - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Name', [], 'Admin.Global'), - ]) - ->add('description', TranslateType::class, [ - 'type' => FormattedTextareaType::class, - 'options' => [ - 'required' => false, - 'attr' => [ - 'class' => 'serp-default-description', - ], - 'constraints' => [ - new TinyMceMaxLength([ - 'max' => FormattedTextareaType::LIMIT_TEXT_UTF8, - ]), - ], - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Description', [], 'Admin.Global'), - 'required' => false, - ]) - ->add('description_short', TranslateType::class, [ - 'type' => FormType\TextareaType::class, // https://github.com/symfony/symfony/issues/5906 - 'options' => [ - 'attr' => [ - 'class' => 'autoload_rte', - 'placeholder' => $this->translator->trans('The summary is a short sentence describing your product.
    It will appears at the top of your shop\'s product page, in product lists, and in search engines\' results page (so it\'s important for SEO). To give more details about your product, use the "Description" tab.', [], 'Admin.Catalog.Help'), - 'counter' => (int) $this->configuration->get('PS_PRODUCT_SHORT_DESC_LIMIT') <= 0 ? 800 : (int) $this->configuration->get('PS_PRODUCT_SHORT_DESC_LIMIT'), - ], - 'constraints' => [ - new TinyMceMaxLength([ - 'max' => (int) $this->configuration->get('PS_PRODUCT_SHORT_DESC_LIMIT') <= 0 ? 800 : (int) $this->configuration->get('PS_PRODUCT_SHORT_DESC_LIMIT'), - ]), - ], - 'required' => false, - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Short description', [], 'Admin.Catalog.Feature'), - 'required' => false, - ]) - //FEATURES & ATTRIBUTES - ->add('features', FormType\CollectionType::class, [ - 'entry_type' => ProductFeature::class, - 'prototype' => true, - 'allow_add' => true, - 'allow_delete' => true, - ]) - ->add('id_manufacturer', FormType\ChoiceType::class, [ - 'choices' => $this->manufacturers, - 'required' => false, - 'attr' => [ - 'data-toggle' => 'select2', - 'data-minimumResultsForSearch' => '7', - ], - 'label' => $this->translator->trans('Brand', [], 'Admin.Catalog.Feature'), - ]) - //RIGHT COL - ->add('active', FormType\CheckboxType::class, [ - 'label' => $this->translator->trans('Enabled', [], 'Admin.Global'), - 'required' => false, - ]) - ->add('price_shortcut', FormType\MoneyType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Pre-tax retail price', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'float']), - ], - 'attr' => [], - ]) - ->add('price_ttc_shortcut', FormType\MoneyType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Retail price with tax', [], 'Admin.Catalog.Feature'), - 'mapped' => false, - 'currency' => $this->currency->iso_code, - ]); - if ($is_stock_management) { - $builder->add('qty_0_shortcut', FormType\NumberType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Quantity', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ]); - } - $builder->add('categories', ChoiceCategoriesTreeType::class, [ - 'label' => $this->translator->trans('Associated categories', [], 'Admin.Catalog.Feature'), - 'list' => $this->nested_categories, - 'valid_list' => $this->categories, - 'multiple' => true, - ]) - ->add('id_category_default', FormType\ChoiceType::class, [ - 'choices' => $this->categories, - 'expanded' => true, - 'multiple' => false, - 'required' => true, - 'label' => $this->translator->trans('Default category', [], 'Admin.Catalog.Feature'), - ]) - ->add('new_category', SimpleCategory::class, [ - 'ajax' => true, - 'required' => false, - 'mapped' => false, - 'constraints' => [], - 'label' => $this->translator->trans('Add a new category', [], 'Admin.Catalog.Feature'), - ]) - ->add('ignore', null, [ - 'mapped' => false, - ]) - ->add('related_products', TypeaheadProductCollectionType::class, [ - 'remote_url' => $this->context->getLegacyAdminLink('AdminProducts', true, ['ajax' => 1, 'action' => 'productsList', 'forceJson' => 1, 'disableCombination' => 1, 'exclude_packs' => 0, 'excludeVirtuals' => 0, 'limit' => 20]) . '&q=%QUERY', - 'mapping_value' => 'id', - 'mapping_name' => 'name', - 'placeholder' => $this->translator->trans('Search and add a related product', [], 'Admin.Catalog.Help'), - 'template_collection' => '%sclear', - 'required' => false, - 'label' => $this->translator->trans('Accessories', [], 'Admin.Catalog.Feature'), - ]); - - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { - $data = $event->getData(); - - if (!isset($data['type_product'])) { - $data['type_product'] = 0; - $event->setData($data); - } - - /* - * Remove duplicates to prevent SQL errors. - */ - if (isset($data['features'])) { - $ids = []; - foreach ($data['features'] as $idx => $feature) { - if (empty($feature['value'])) { - continue; - } - - $id = sprintf('%d-%d', $feature['feature'], $feature['value']); - if (in_array($id, $ids)) { - unset($data['features'][$idx]); - } else { - $ids[] = $id; - } - } - - $event->setData($data); - } - - //if product type is pack, check if inputPackItems is not empty - if ($data['type_product'] == 1) { - if (!isset($data['inputPackItems']) || empty($data['inputPackItems']['data'])) { - $form = $event->getForm(); - $error = $this->translator->trans( - 'This pack is empty. You must add at least one product item.', - [], - 'Admin.Catalog.Notification' - ); - $form->get('inputPackItems')->addError(new FormError($error)); - } - } - }); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_step1'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductOptions.php b/src/PrestaShopBundle/Form/Admin/Product/ProductOptions.php deleted file mode 100644 index cf08de59..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductOptions.php +++ /dev/null @@ -1,310 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormEvent; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the product options form. - */ -class ProductOptions extends CommonAbstractType -{ - private $translator; - private $suppliers; - private $context; - private $productAdapter; - private $router; - private $locales; - private $currencyDataprovider; - private $fullAttachmentList; - private $attachmentList; - - /** - * Constructor. - * - * @param object $translator - * @param object $legacyContext - * @param object $productDataProvider - * @param object $supplierDataProvider - * @param object $currencyDataprovider - * @param object $attachmentDataprovider - * @param object $router - */ - public function __construct( - $translator, - $legacyContext, - $productDataProvider, - $supplierDataProvider, - $currencyDataprovider, - $attachmentDataprovider, - $router - ) { - $this->context = $legacyContext; - $this->translator = $translator; - $this->productAdapter = $productDataProvider; - $this->currencyDataprovider = $currencyDataprovider; - $this->locales = $legacyContext->getLanguages(); - $this->router = $router; - - $this->suppliers = $this->formatDataChoicesList( - $supplierDataProvider->getSuppliers(), - 'id_supplier' - ); - - $this->fullAttachmentList = $attachmentDataprovider->getAllAttachments( - $this->context->getLanguages()[0]['id_lang'] - ); - $this->attachmentList = $this->formatDataChoicesList( - $this->fullAttachmentList, - 'id_attachment', - 'file' - ); - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('visibility', FormType\ChoiceType::class, [ - 'choices' => [ - $this->translator->trans('Everywhere', [], 'Admin.Catalog.Feature') => 'both', - $this->translator->trans('Catalog only', [], 'Admin.Catalog.Feature') => 'catalog', - $this->translator->trans('Search only', [], 'Admin.Catalog.Feature') => 'search', - $this->translator->trans('Nowhere', [], 'Admin.Catalog.Feature') => 'none', - ], - 'attr' => [ - 'class' => 'custom-select', - ], - 'required' => true, - 'label' => $this->translator->trans('Visibility', [], 'Admin.Catalog.Feature'), - ]) - ->add('tags', TranslateType::class, [ - 'type' => FormType\TextType::class, - 'options' => [ - 'attr' => [ - 'class' => 'tokenfield', - 'placeholder' => $this->translator->trans('Use a comma to create separate tags. E.g.: dress, cotton, party dresses.', [], 'Admin.Catalog.Help'), - ], - ], - 'locales' => $this->locales, - 'label' => $this->translator->trans('Tags', [], 'Admin.Catalog.Feature'), - ]) - ->add( - $builder->create( - 'display_options', - FormType\FormType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Display options', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'available_for_order', - FormType\CheckboxType::class, - [ - 'label' => $this->translator->trans('Available for order', [], 'Admin.Catalog.Feature'), - 'required' => false, - ] - ) - ->add( - 'show_price', - FormType\CheckboxType::class, - [ - 'label' => $this->translator->trans('Show price', [], 'Admin.Catalog.Feature'), - 'required' => false, - ] - ) - ->add( - 'online_only', - FormType\CheckboxType::class, - [ - 'label' => $this->translator->trans( - 'Web only (not sold in your retail store)', - [], - 'Admin.Catalog.Feature' - ), - 'required' => false, - ] - ) - ) - ->add('mpn', FormType\TextType::class, [ - 'required' => false, - 'label' => $this->translator->trans('MPN', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\Length(['max' => 40]), - ], - 'empty_data' => '', - ]) - ->add('upc', FormType\TextType::class, [ - 'required' => false, - 'label' => $this->translator->trans('UPC barcode', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\Regex('/^[0-9]{0,12}$/'), - ], - 'empty_data' => '', - ]) - ->add('ean13', FormType\TextType::class, [ - 'required' => false, - 'error_bubbling' => true, - 'label' => $this->translator->trans('EAN-13 or JAN barcode', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\Regex('/^[0-9]{0,13}$/'), - ], - 'empty_data' => '', - ]) - ->add('isbn', FormType\TextType::class, [ - 'required' => false, - 'label' => $this->translator->trans('ISBN', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\Regex('/^[0-9-]{0,32}$/'), - ], - 'empty_data' => '', - ]) - ->add('reference', FormType\TextType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Reference', [], 'Admin.Global'), - 'empty_data' => '', - ]) - ->add('show_condition', FormType\CheckboxType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Display condition on product page', [], 'Admin.Catalog.Feature'), - ]) - ->add('condition', FormType\ChoiceType::class, [ - 'choices' => [ - $this->translator->trans('New', [], 'Shop.Theme.Catalog') => 'new', - $this->translator->trans('Used', [], 'Shop.Theme.Catalog') => 'used', - $this->translator->trans('Refurbished', [], 'Shop.Theme.Catalog') => 'refurbished', - ], - 'attr' => [ - 'class' => 'custom-select', - ], - 'required' => true, - 'label' => $this->translator->trans('Condition', [], 'Admin.Catalog.Feature'), - ]) - ->add('suppliers', FormType\ChoiceType::class, [ - 'choices' => $this->suppliers, - 'expanded' => true, - 'multiple' => true, - 'required' => false, - 'attr' => [ - 'class' => 'custom-select', - ], - 'label' => $this->translator->trans('Suppliers', [], 'Admin.Global'), - ]) - ->add('default_supplier', FormType\ChoiceType::class, [ - 'choices' => $this->suppliers, - 'expanded' => true, - 'multiple' => false, - 'required' => true, - 'attr' => [ - 'class' => 'custom-select', - ], - 'label' => $this->translator->trans('Default suppliers', [], 'Admin.Catalog.Feature'), - ]); - - foreach ($this->suppliers as $supplier => $id) { - $builder->add( - 'supplier_combination_' . $id, - FormType\CollectionType::class, - [ - 'entry_type' => ProductSupplierCombination::class, - 'entry_options' => [ - 'id_supplier' => $id, - ], - 'prototype' => true, - 'allow_add' => true, - 'required' => false, - 'label' => $supplier, - ] - ); - } - - $builder->add('custom_fields', FormType\CollectionType::class, [ - 'entry_type' => ProductCustomField::class, - 'label' => $this->translator->trans('Customization', [], 'Admin.Catalog.Feature'), - 'prototype' => true, - 'allow_add' => true, - 'allow_delete' => true, - ]); - - //Add product attachment form - $builder->add('attachment_product', ProductAttachement::class, [ - 'required' => false, - 'label' => $this->translator->trans('Attachment', [], 'Admin.Catalog.Feature'), - 'attr' => ['data-action' => $this->router->generate('admin_product_attachement_add_action', ['idProduct' => 1])], - ]); - - //Add attachment selectors - $builder->add('attachments', FormType\ChoiceType::class, [ - 'expanded' => true, - 'multiple' => true, - 'choices' => $this->attachmentList, - 'choice_label' => function ($choice, $key, $value) { - $attachmentKey = array_search($key, array_column($this->fullAttachmentList, 'file')); - - return $this->fullAttachmentList[$attachmentKey]['name']; - }, - 'required' => false, - 'attr' => [ - 'class' => 'custom-select', - 'data' => $this->fullAttachmentList, - ], - 'label' => $this->translator->trans('Attachments for this product:', [], 'Admin.Catalog.Feature'), - ]); - - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { - $data = $event->getData(); - - //If not supplier selected, remove all supplier combinations collection form - if (!isset($data['suppliers']) || count($data['suppliers']) == 0) { - $form = $event->getForm(); - foreach ($this->suppliers as $supplier => $id) { - $form->remove('supplier_combination_' . $id); - } - } - }); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_options'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductPrice.php b/src/PrestaShopBundle/Form/Admin/Product/ProductPrice.php deleted file mode 100644 index 4f0bf7f6..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductPrice.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the product price form. - */ -class ProductPrice extends CommonAbstractType -{ - // When the form is used to create, the product does not yet exists - // however the ID is required for some fields so we use a default one: - const DEFAULT_PRODUCT_ID_FOR_FORM_CREATION = 1; - - private $translator; - private $tax_rules; - private $tax_rules_rates; - private $configuration; - private $eco_tax_rate; - private $customerDataprovider; - - /** - * Constructor. - * - * @param object $translator - * @param object $taxDataProvider - * @param object $router - * @param object $shopContextAdapter - * @param object $countryDataprovider - * @param object $currencyDataprovider - * @param object $groupDataprovider - * @param object $legacyContext - * @param object $customerDataprovider - */ - public function __construct($translator, $taxDataProvider, $router, $shopContextAdapter, $countryDataprovider, $currencyDataprovider, $groupDataprovider, $legacyContext, $customerDataprovider) - { - $this->translator = $translator; - $this->router = $router; - $this->configuration = $this->getConfiguration(); - $this->shopContextAdapter = $shopContextAdapter; - $this->countryDataprovider = $countryDataprovider; - $this->currencyDataprovider = $currencyDataprovider; - $this->groupDataprovider = $groupDataprovider; - $this->customerDataprovider = $customerDataprovider; - $this->legacyContext = $legacyContext; - $this->tax_rules_rates = $taxDataProvider->getTaxRulesGroupWithRates(); - $this->eco_tax_rate = $taxDataProvider->getProductEcotaxRate(); - $this->currency = $legacyContext->getContext()->currency; - $this->tax_rules = $this->formatDataChoicesList( - $taxDataProvider->getTaxRulesGroups(true), - 'id_tax_rules_group' - ); - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $this->tax_rules = [$this->translator->trans('No tax', [], 'Admin.Catalog.Feature') => 0] + $this->tax_rules; - - $builder->add( - 'price', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Price (tax excl.)', [], 'Admin.Catalog.Feature'), - 'attr' => ['data-display-price-precision' => self::PRESTASHOP_DECIMALS], - 'currency' => $this->currency->iso_code, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'float']), - ], - ] - ) - ->add( - 'price_ttc', - FormType\MoneyType::class, - [ - 'required' => false, - 'mapped' => false, - 'label' => $this->translator->trans('Price (tax incl.)', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - ] - ) - ->add( - 'ecotax', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Ecotax (tax incl.)', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'float']), - ], - 'attr' => ['data-eco-tax-rate' => $this->eco_tax_rate], - ] - ) - ->add( - 'id_tax_rules_group', - FormType\ChoiceType::class, - [ - 'choices' => $this->tax_rules, - 'required' => true, - 'choice_attr' => function ($val) { - return [ - 'data-rates' => implode(',', $this->tax_rules_rates[$val]['rates']), - 'data-computation-method' => $this->tax_rules_rates[$val]['computation_method'], - ]; - }, - 'attr' => [ - 'data-toggle' => 'select2', - 'data-minimumResultsForSearch' => '7', - ], - 'label' => $this->translator->trans('Tax rule', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'on_sale', - FormType\CheckboxType::class, - [ - 'required' => false, - 'label' => $this->translator->trans( - 'Display the "On sale!" flag on the product page, and on product listings.', - [], - 'Admin.Catalog.Feature' - ), - ] - ) - ->add( - 'wholesale_price', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Price (tax excl.)', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - ] - ) - ->add( - 'unit_price', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Price per unit (tax excl.)', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - ] - ) - ->add( - 'unity', - FormType\TextType::class, - [ - 'required' => false, - 'attr' => ['placeholder' => $this->translator->trans('Per kilo, per litre', [], 'Admin.Catalog.Help')], - ] - ) - ->add( - 'specific_price', - ProductSpecificPrice::class, - [ - 'id_product' => $options['id_product'], - ] - ) - ->add( - 'specificPricePriorityToAll', - FormType\CheckboxType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Apply to all products', [], 'Admin.Catalog.Feature'), - ] - ); - - //generates fields for price priority - $specificPricePriorityChoices = [ - $this->translator->trans('Shop', [], 'Admin.Global') => 'id_shop', - $this->translator->trans('Currency', [], 'Admin.Global') => 'id_currency', - $this->translator->trans('Country', [], 'Admin.Global') => 'id_country', - $this->translator->trans('Group', [], 'Admin.Global') => 'id_group', - ]; - - for ($i = 0, $iMax = count($specificPricePriorityChoices); $i < $iMax; ++$i) { - $builder->add( - 'specificPricePriority_' . $i, - FormType\ChoiceType::class, - [ - 'choices' => $specificPricePriorityChoices, - 'required' => true, - ] - ); - } - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'id_product' => self::DEFAULT_PRODUCT_ID_FOR_FORM_CREATION, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_price'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductQuantity.php b/src/PrestaShopBundle/Form/Admin/Product/ProductQuantity.php deleted file mode 100644 index 7a68d501..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductQuantity.php +++ /dev/null @@ -1,338 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use Pack; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormEvent; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the product quantity form. - */ -class ProductQuantity extends CommonAbstractType -{ - private $router; - private $translator; - private $configuration; - - /** - * Constructor. - * - * @param object $translator - * @param object $router - * @param object $legacyContext - */ - public function __construct($translator, $router, $legacyContext) - { - $this->router = $router; - $this->translator = $translator; - $this->legacyContext = $legacyContext; - $this->locales = $this->legacyContext->getLanguages(); - $this->configuration = $this->getConfiguration(); - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $is_stock_management = $this->configuration->get('PS_STOCK_MANAGEMENT'); - $builder - ->add( - 'attributes', - FormType\TextType::class, - [ - 'attr' => [ - 'class' => 'tokenfield', - 'data-minLength' => 1, - 'placeholder' => $this->translator->trans( - 'Combine several attributes, e.g.: "Size: all", "Color: red".', - [], - 'Admin.Catalog.Help' - ), - 'data-prefetch' => $this->router->generate('admin_attribute_get_all'), - 'data-action' => $this->router->generate('admin_attribute_generator'), - ], - 'label' => $this->translator->trans('Create combinations', [], 'Admin.Catalog.Feature'), - 'empty_data' => '', - ] - ) - ->add( - 'advanced_stock_management', - FormType\CheckboxType::class, - [ - 'required' => false, - 'label' => $this->translator->trans( - 'I want to use the advanced stock management system for this product.', - [], - 'Admin.Catalog.Feature' - ), - ] - ) - ->add( - 'pack_stock_type', - FormType\ChoiceType::class - )//see eventListener for details - ->add( - 'depends_on_stock', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans( - 'The available quantities for the current product and its combinations are based on the stock in your warehouse (using the advanced stock management system). ', - [], - 'Admin.Catalog.Feature' - ) => 1, - $this->translator->trans( - 'I want to specify available quantities manually.', - [], - 'Admin.Catalog.Feature' - ) => 0, - ], - 'expanded' => true, - 'required' => true, - 'multiple' => false, - ] - ); - - if ($is_stock_management) { - $builder->add( - 'qty_0', - FormType\NumberType::class, - [ - 'required' => true, - 'label' => $this->translator->trans('Quantity', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ); - } - $builder - ->add( - 'out_of_stock', - FormType\ChoiceType::class - ) - ->add( - 'minimal_quantity', - FormType\NumberType::class, - [ - 'required' => true, - 'label' => $this->translator->trans('Minimum quantity for sale', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'location', - FormType\TextType::class, - [ - 'label' => $this->translator->trans('Stock location', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'low_stock_threshold', - FormType\NumberType::class, - [ - 'label' => $this->translator->trans('Low stock level', [], 'Admin.Catalog.Feature'), - 'attr' => [ - 'placeholder' => $this->translator->trans('Leave empty to disable', [], 'Admin.Catalog.Help'), - ], - 'constraints' => [ - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'low_stock_alert', - FormType\CheckboxType::class, - [ - 'label' => $this->translator->trans( - 'Send me an email when the quantity is below or equals this level', - [], - 'Admin.Catalog.Feature' - ), - 'constraints' => [ - new Assert\Type(['type' => 'bool']), - ], - ] - ) - ->add( - 'available_now', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Label when in stock', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'available_later', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans( - 'Label when out of stock (and back order allowed)', - [], - 'Admin.Catalog.Feature' - ), - ] - ) - ->add( - 'available_date', - DatePickerType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Availability date', [], 'Admin.Catalog.Feature'), - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - ] - ) - ->add( - 'virtual_product', - ProductVirtual::class, - [ - 'required' => false, - 'label' => $this->translator->trans( - 'Does this product have an associated file?', - [], - 'Admin.Catalog.Feature' - ), - ] - ); - - $builder->addEventListener( - FormEvents::PRE_SET_DATA, - function (FormEvent $event) { - $form = $event->getForm(); - - //Manage out_of_stock field with contextual values/label - $defaultChoiceLabel = $this->translator->trans( - 'Use default behavior', - [], - 'Admin.Catalog.Feature' - ) . ' ('; - $defaultChoiceLabel .= $this->configuration->get('PS_ORDER_OUT_OF_STOCK') == 1 ? - $this->translator->trans('Allow orders', [], 'Admin.Catalog.Feature') : - $this->translator->trans('Deny orders', [], 'Admin.Catalog.Feature'); - $defaultChoiceLabel .= ')'; - - $form->add( - 'out_of_stock', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans('Deny orders', [], 'Admin.Catalog.Feature') => '0', - $this->translator->trans('Allow orders', [], 'Admin.Catalog.Feature') => '1', - $defaultChoiceLabel => '2', - ], - 'expanded' => true, - 'required' => false, - 'placeholder' => false, - 'label' => $this->translator->trans('When out of stock', [], 'Admin.Catalog.Feature'), - ] - ); - - //Manage out_of_stock field with contextual values/label - $pack_stock_type = $this->configuration->get('PS_PACK_STOCK_TYPE'); - $defaultChoiceLabel = $this->translator->trans('Default', [], 'Admin.Global') . ': '; - if ($pack_stock_type == Pack::STOCK_TYPE_PACK_ONLY) { - $defaultChoiceLabel .= $this->translator->trans( - 'Decrement pack only.', - [], - 'Admin.Catalog.Feature' - ); - } elseif ($pack_stock_type == Pack::STOCK_TYPE_PRODUCTS_ONLY) { - $defaultChoiceLabel .= $this->translator->trans( - 'Decrement products in pack only.', - [], - 'Admin.Catalog.Feature' - ); - } else { - $defaultChoiceLabel .= $this->translator->trans('Decrement both.', [], 'Admin.Catalog.Feature'); - } - - $form->add( - 'pack_stock_type', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans('Decrement pack only.', [], 'Admin.Catalog.Feature') => 0, - $this->translator->trans('Decrement products in pack only.', [], 'Admin.Catalog.Feature') => 1, - $this->translator->trans('Decrement both.', [], 'Admin.Catalog.Feature') => 2, - $defaultChoiceLabel => 3, - ], - 'expanded' => false, - 'required' => true, - 'placeholder' => false, - 'label' => $this->translator->trans('Pack quantities', [], 'Admin.Catalog.Feature'), - ] - ); - } - ); - } - - /** - * {@inheritdoc} - * - * Configure options - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults( - [ - 'allow_extra_fields' => true, - ] - ); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_quantity'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductSeo.php b/src/PrestaShopBundle/Form/Admin/Product/ProductSeo.php deleted file mode 100644 index 38e4bbc5..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductSeo.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShop\PrestaShop\Core\Product\ProductInterface; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use PrestaShopBundle\Form\Admin\Type\TypeaheadProductCollectionType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to generate the product SEO form. - */ -class ProductSeo extends CommonAbstractType -{ - private $translator; - private $locales; - private $router; - - /** - * Constructor. - * - * @param object $translator - * @param object $legacyContext - */ - public function __construct($translator, $legacyContext, $router) - { - $this->translator = $translator; - $this->context = $legacyContext; - $this->locales = $legacyContext->getLanguages(); - $this->router = $router; - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $remoteUrls = [ - ProductInterface::REDIRECT_TYPE_PRODUCT_MOVED_PERMANENTLY => $this->context->getLegacyAdminLink('AdminProducts', true, ['ajax' => 1, 'action' => 'productsList', 'forceJson' => 1, 'disableCombination' => 1, 'exclude_packs' => 0, 'excludeVirtuals' => 0, 'limit' => 20]) . '&q=%QUERY', - ProductInterface::REDIRECT_TYPE_PRODUCT_FOUND => $this->context->getLegacyAdminLink('AdminProducts', true, ['ajax' => 1, 'action' => 'productsList', 'forceJson' => 1, 'disableCombination' => 1, 'exclude_packs' => 0, 'excludeVirtuals' => 0, 'limit' => 20]) . '&q=%QUERY', - ProductInterface::REDIRECT_TYPE_CATEGORY_MOVED_PERMANENTLY => $this->router->generate('admin_get_ajax_categories') . '&query=%QUERY', - ProductInterface::REDIRECT_TYPE_CATEGORY_FOUND => $this->router->generate('admin_get_ajax_categories') . '&query=%QUERY', - ]; - - $builder->add( - 'meta_title', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [ - 'attr' => [ - 'placeholder' => $this->translator->trans('To have a different title from the product name, enter it here.', [], 'Admin.Catalog.Help'), - 'counter' => 70, - 'counter_type' => 'recommended', - 'class' => 'serp-watched-title', - ], - 'required' => false, - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Meta title', [], 'Admin.Catalog.Feature'), - 'label_attr' => [ - 'popover' => $this->translator->trans('Public title for the product\'s page, and for search engines. Leave blank to use the product name. The number of remaining characters is displayed to the left of the field.', [], 'Admin.Catalog.Help'), - 'popover_placement' => 'right', - 'class' => 'px-0', - ], - 'required' => false, - ] - ) - ->add( - 'meta_description', - TranslateType::class, - [ - 'type' => FormType\TextareaType::class, - 'options' => [ - 'attr' => [ - 'placeholder' => $this->translator->trans('To have a different description than your product summary in search results pages, write it here.', [], 'Admin.Catalog.Help'), - 'counter' => 160, - 'counter_type' => 'recommended', - 'class' => 'serp-watched-description', - ], - 'required' => false, - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Meta description', [], 'Admin.Catalog.Feature'), - 'label_attr' => [ - 'popover' => $this->translator->trans('This description will appear in search engines. You need a single sentence, shorter than 160 characters (including spaces)', [], 'Admin.Catalog.Help'), - 'popover_placement' => 'right', - 'class' => 'px-0', - ], - 'required' => false, - ] - ) - ->add( - 'link_rewrite', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [ - 'attr' => [ - 'class' => 'serp-watched-url', - ], - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'label' => $this->translator->trans('Friendly URL', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'redirect_type', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans('Permanent redirection to a category (301)', [], 'Admin.Catalog.Feature') => ProductInterface::REDIRECT_TYPE_CATEGORY_MOVED_PERMANENTLY, - $this->translator->trans('Temporary redirection to a category (302)', [], 'Admin.Catalog.Feature') => ProductInterface::REDIRECT_TYPE_CATEGORY_FOUND, - $this->translator->trans('Permanent redirection to a product (301)', [], 'Admin.Catalog.Feature') => ProductInterface::REDIRECT_TYPE_PRODUCT_MOVED_PERMANENTLY, - $this->translator->trans('Temporary redirection to a product (302)', [], 'Admin.Catalog.Feature') => ProductInterface::REDIRECT_TYPE_PRODUCT_FOUND, - $this->translator->trans('No redirection (404)', [], 'Admin.Catalog.Feature') => ProductInterface::REDIRECT_TYPE_NOT_FOUND, - ], - 'choice_attr' => function ($val, $key, $index) use ($remoteUrls) { - if (array_key_exists($index, $remoteUrls)) { - return ['data-remoteurl' => $remoteUrls[$index]]; - } - - return []; - }, - 'required' => true, - 'label' => $this->translator->trans('Redirection when offline', [], 'Admin.Catalog.Feature'), - 'attr' => [ - 'data-labelproduct' => $this->translator->trans('Target product', [], 'Admin.Catalog.Feature'), - 'data-placeholderproduct' => $this->translator->trans('To which product the page should redirect?', [], 'Admin.Catalog.Help'), - 'data-labelcategory' => $this->translator->trans('Target category', [], 'Admin.Catalog.Feature'), - 'data-placeholdercategory' => $this->translator->trans('To which category the page should redirect?', [], 'Admin.Catalog.Help'), - 'data-hintcategory' => $this->translator->trans('If no category is selected the Main Category is used', [], 'Admin.Catalog.Help'), - ], - ] - ) - ->add( - 'id_type_redirected', - TypeaheadProductCollectionType::class, - [ - 'remote_url' => $this->context->getLegacyAdminLink('AdminProducts', true, ['ajax' => 1, 'action' => 'productsList', 'forceJson' => 1, 'disableCombination' => 1, 'exclude_packs' => 0, 'excludeVirtuals' => 0, 'limit' => 20]) . '&q=%QUERY', - 'mapping_value' => 'id', - 'mapping_name' => 'name', - 'mapping_type' => $options['mapping_type'], - 'template_collection' => '%sclear', - 'limit' => 1, - 'required' => false, - 'label' => $this->translator->trans('Target', [], 'Admin.Catalog.Feature'), - ] - ); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_seo'; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'mapping_type' => 'product', - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductShipping.php b/src/PrestaShopBundle/Form/Admin/Product/ProductShipping.php deleted file mode 100644 index 53072cac..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductShipping.php +++ /dev/null @@ -1,240 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the product shipping form. - */ -class ProductShipping extends CommonAbstractType -{ - private $translator; - private $carriersChoices; - private $warehouses; - - /** - * Constructor. - * - * @param object $translator - * @param object $legacyContext - * @param object $warehouseDataProvider - * @param object $carrierDataProvider - */ - public function __construct($translator, $legacyContext, $warehouseDataProvider, $carrierDataProvider) - { - $this->translator = $translator; - $this->legacyContext = $legacyContext; - $this->currency = $legacyContext->getContext()->currency; - $this->locales = $this->legacyContext->getLanguages(); - $this->warehouses = $warehouseDataProvider->getWarehouses(); - - $carriers = $carrierDataProvider->getCarriers( - $this->locales[0]['id_lang'], - false, - false, - false, - null, - $carrierDataProvider->getAllCarriersConstant() - ); - $this->carriersChoices = []; - foreach ($carriers as $carrier) { - $choiceId = $carrier['id_carrier'] . ' - ' . $carrier['name']; - if ($carrier['name']) { - $choiceId .= ' (' . $carrier['delay'] . ')'; - } - - $this->carriersChoices[$choiceId] = $carrier['id_reference']; - } - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add( - 'width', - FormType\NumberType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Width', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'height', - FormType\NumberType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Height', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'depth', - FormType\NumberType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Depth', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'weight', - FormType\NumberType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Weight', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'additional_shipping_cost', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Shipping fees', [], 'Admin.Catalog.Feature'), - 'currency' => $this->currency->iso_code, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'float']), - ], - ] - ) - ->add( - 'selectedCarriers', - FormType\ChoiceType::class, - [ - 'choices' => $this->carriersChoices, - 'expanded' => true, - 'multiple' => true, - 'required' => false, - 'label' => $this->translator->trans('Available carriers', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'additional_delivery_times', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans('None', [], 'Admin.Catalog.Feature') => 0, - $this->translator->trans('Default delivery time', [], 'Admin.Catalog.Feature') => 1, - $this->translator->trans('Specific delivery time to this product', [], 'Admin.Catalog.Feature') => 2, - ], - 'expanded' => true, - 'multiple' => false, - 'required' => false, - 'placeholder' => null, - 'preferred_choices' => ['default'], - 'label' => $this->translator->trans('Delivery Time', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'delivery_out_stock', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [ - 'attr' => [ - 'placeholder' => $this->translator->trans('Delivered within 5-7 days', [], 'Admin.Catalog.Feature'), - ], - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'required' => false, - 'label' => $this->translator->trans( - 'Delivery time of out-of-stock products with allowed orders:', - [], - 'Admin.Catalog.Feature' - ), - ] - ) - ->add( - 'delivery_in_stock', - TranslateType::class, - [ - 'type' => FormType\TextType::class, - 'options' => [ - 'attr' => [ - 'placeholder' => $this->translator->trans('Delivered within 3-4 days', [], 'Admin.Catalog.Feature'), - ], - ], - 'locales' => $this->locales, - 'hideTabs' => true, - 'required' => false, - 'label' => $this->translator->trans('Delivery time of in-stock products:', [], 'Admin.Catalog.Feature'), - ] - ); - - foreach ($this->warehouses as $warehouse) { - $builder->add( - 'warehouse_combination_' . $warehouse['id_warehouse'], - CollectionType::class, - [ - 'entry_type' => 'PrestaShopBundle\Form\Admin\Product\ProductWarehouseCombination', - 'entry_options' => [ - 'id_warehouse' => $warehouse['id_warehouse'], - ], - 'prototype' => true, - 'allow_add' => true, - 'required' => false, - 'label' => $warehouse['name'], - ] - ); - } - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_shipping'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductSpecificPrice.php b/src/PrestaShopBundle/Form/Admin/Product/ProductSpecificPrice.php deleted file mode 100644 index e8f02894..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductSpecificPrice.php +++ /dev/null @@ -1,337 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use PrestaShopBundle\Form\Admin\Type\TypeaheadCustomerCollectionType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormEvent; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the basic product specific prices form. - */ -class ProductSpecificPrice extends CommonAbstractType -{ - private $translator; - private $locales; - private $shops; - private $countries; - private $currencies; - private $groups; - private $customerDataprovider; - - /** - * Constructor. - * - * @param object $router - * @param object $translator - * @param object $shopContextAdapter - * @param object $countryDataprovider - * @param object $currencyDataprovider - * @param object $groupDataprovider - * @param object $legacyContext - */ - public function __construct( - $router, - $translator, - $shopContextAdapter, - $countryDataprovider, - $currencyDataprovider, - $groupDataprovider, - $legacyContext, - $customerDataprovider - ) { - $this->router = $router; - $this->translator = $translator; - $this->context = $legacyContext; - $this->locales = $legacyContext->getLanguages(); - $this->shops = $this->formatDataChoicesList($shopContextAdapter->getShops(), 'id_shop'); - $this->countries = $this->formatDataChoicesList( - $countryDataprovider->getCountries($this->locales[0]['id_lang']), - 'id_country' - ); - $this->currencies = $this->formatDataChoicesList($currencyDataprovider->getCurrencies(), 'id_currency'); - $this->groups = $this->formatDataChoicesList( - $groupDataprovider->getGroups($this->locales[0]['id_lang']), - 'id_group' - ); - $this->currency = $legacyContext->getContext()->currency; - $this->customerDataprovider = $customerDataprovider; - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - //If context multi-shop, hide shop selector - //Else show selector - if (count($this->shops) == 1) { - $builder->add( - 'sp_id_shop', - FormType\HiddenType::class, - [ - 'required' => false, - ] - ); - } else { - $builder->add( - 'sp_id_shop', - FormType\ChoiceType::class, - [ - 'choices' => $this->shops, - 'required' => false, - 'label' => false, - 'placeholder' => $this->translator->trans('All shops', [], 'Admin.Global'), - ] - ); - } - - $builder->add( - 'sp_id_currency', - FormType\ChoiceType::class, - [ - 'choices' => $this->currencies, - 'required' => false, - 'label' => false, - 'attr' => [ - 'data-toggle' => 'select2', - 'data-minimumResultsForSearch' => '7', - ], - 'placeholder' => $this->translator->trans('All currencies', [], 'Admin.Global'), - ] - ) - ->add( - 'sp_id_country', - FormType\ChoiceType::class, - [ - 'choices' => $this->countries, - 'required' => false, - 'label' => false, - 'attr' => [ - 'data-toggle' => 'select2', - 'data-minimumResultsForSearch' => '7', - ], - 'placeholder' => $this->translator->trans('All countries', [], 'Admin.Global'), - ] - ) - ->add( - 'sp_id_group', - FormType\ChoiceType::class, - [ - 'choices' => $this->groups, - 'required' => false, - 'label' => false, - 'attr' => [ - 'data-toggle' => 'select2', - 'data-minimumResultsForSearch' => '7', - ], - 'placeholder' => $this->translator->trans('All groups', [], 'Admin.Global'), - ] - ) - ->add( - 'sp_id_customer', - TypeaheadCustomerCollectionType::class, - [ - // "%QUERY" is appended to url in order to avoid "%" sign being encoded into "%25", - // it used as a placeholder to replace with actual query in JS - 'remote_url' => $this->router->generate('admin_customers_search', ['sf2' => 1]) . '&customer_search=%QUERY', - 'mapping_value' => 'id_customer', - 'mapping_name' => 'fullname_and_email', - 'placeholder' => $this->translator->trans('All customers', [], 'Admin.Global'), - 'template_collection' => '
    %s
    clear
    ', - 'limit' => 1, - 'required' => false, - 'label' => $this->translator->trans('Add customer', [], 'Admin.Catalog.Feature'), - ] - ) - ->add( - 'sp_id_product_attribute', - FormType\ChoiceType::class, - [ - 'choices' => [], - 'required' => false, - 'placeholder' => $this->translator->trans('Apply to all combinations', [], 'Admin.Catalog.Feature'), - 'label' => $this->translator->trans('Combinations', [], 'Admin.Catalog.Feature'), - 'attr' => [ - 'data-action' => $this->router->generate('admin_get_product_combinations', ['idProduct' => $options['id_product']]), - // used to force selected select option after options have been loaded - 'data-selected-attribute' => (array_keys($options, 'selected_product_attribute')) ? $options['selected_product_attribute'] : '0', - ], - ] - ) - ->add( - 'sp_from', - DatePickerType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Available from', [], 'Admin.Catalog.Feature'), - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - ] - ) - ->add( - 'sp_to', - DatePickerType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('to', [], 'Admin.Global'), - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - ] - ) - ->add( - 'sp_from_quantity', - FormType\NumberType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Starting at', [], 'Admin.Catalog.Feature'), - 'constraints' => [ - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'sp_price', - FormType\MoneyType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('Product price (tax excl.)', [], 'Admin.Catalog.Feature'), - 'attr' => ['class' => 'price'], - 'currency' => $this->currency->iso_code, - 'disabled' => true, - ] - ) - ->add( - 'leave_bprice', - FormType\CheckboxType::class, - [ - 'label' => $this->translator->trans('Leave initial price', [], 'Admin.Catalog.Feature'), - 'required' => false, - ] - ) - ->add( - 'sp_reduction', - FormType\NumberType::class, - [ - 'label' => $this->translator->trans('Reduction', [], 'Admin.Catalog.Feature'), - 'required' => false, - ] - ) - ->add( - 'sp_reduction_type', - FormType\ChoiceType::class, - [ - 'label' => $this->translator->trans('Reduction type', [], 'Admin.Catalog.Feature'), - 'choices' => [ - $this->currency->getSign() => 'amount', - $this->translator->trans('%', [], 'Admin.Global') => 'percentage', - ], - 'required' => true, - ] - ) - ->add( - 'sp_reduction_tax', - FormType\ChoiceType::class, - [ - 'label' => $this->translator->trans('Reduction tax', [], 'Admin.Catalog.Feature'), - 'choices' => [ - $this->translator->trans('Tax excluded', [], 'Admin.Catalog.Feature') => '0', - $this->translator->trans('Tax included', [], 'Admin.Catalog.Feature') => '1', - ], - 'required' => true, - ] - ) - ->add( - 'save', - FormType\ButtonType::class, - [ - 'label' => $this->translator->trans('Apply', [], 'Admin.Actions'), - 'attr' => ['class' => 'btn-outline-primary js-save'], - ] - ) - ->add( - 'cancel', - FormType\ButtonType::class, - [ - 'label' => $this->translator->trans('Cancel', [], 'Admin.Actions'), - 'attr' => ['class' => 'btn-outline-secondary js-cancel'], - ] - ); - // - // ResetType can't be used because the product page is wrapped - // inside a big form: reset a specific price form the "right" way - // will reset the global form. - // - - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { - $data = $event->getData(); - - if (empty($data['sp_id_product_attribute'])) { - return; - } - - $form = $event->getForm(); - - //bypass SF validation, define submitted value in choice list - $form->add( - 'sp_id_product_attribute', - FormType\ChoiceType::class, - [ - 'choices' => [$data['sp_id_product_attribute'] => ''], - 'required' => false, - ] - ); - }); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'id_product' => 1, // 1 is default value for new form - 'selected_product_attribute' => '0', // used to force selected select option after options have been loaded - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_combination'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductSupplierCombination.php b/src/PrestaShopBundle/Form/Admin/Product/ProductSupplierCombination.php deleted file mode 100644 index 2993a11d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductSupplierCombination.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the basic product suppliers form. - */ -class ProductSupplierCombination extends CommonAbstractType -{ - private $translator; - private $contextLegacy; - private $currencyAdapter; - - /** - * Constructor. - * - * @param object $translator - * @param object $contextLegacy - * @param object $currencyAdapter - */ - public function __construct($translator, $contextLegacy, $currencyAdapter) - { - $this->translator = $translator; - $this->contextLegacy = $contextLegacy->getContext(); - $this->currencyAdapter = $currencyAdapter; - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add( - 'supplier_reference', - FormType\TextType::class, - [ - 'required' => false, - 'label' => null, - 'empty_data' => '', - ] - ) - ->add( - 'product_price', - FormType\MoneyType::class, - [ - 'required' => false, - 'constraints' => [ - new Assert\NotBlank(), - new Assert\Type(['type' => 'float']), - ], - ] - ) - ->add( - 'product_price_currency', - FormType\ChoiceType::class, - [ - 'choices' => $this->formatDataChoicesList($this->currencyAdapter->getCurrencies(), 'id_currency'), - 'required' => true, - 'attr' => [ - 'class' => 'custom-select', - ], - ] - ) - ->add('id_product_attribute', FormType\HiddenType::class) - ->add('product_id', FormType\HiddenType::class) - ->add('supplier_id', FormType\HiddenType::class); - - //set default minimal values for collection prototype - $builder->setData([ - 'product_price' => 0, - 'supplier_id' => $options['id_supplier'], - 'product_price_currency' => $this->contextLegacy->currency->id, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'id_supplier' => null, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_supplier_combination'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductVirtual.php b/src/PrestaShopBundle/Form/Admin/Product/ProductVirtual.php deleted file mode 100644 index 4af1eb42..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductVirtual.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormEvent; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\Validator\Constraints as Assert; - -/** - * This form class is responsible to generate the virtual product. - */ -class ProductVirtual extends CommonAbstractType -{ - private $translator; - private $legacyContext; - private $configuration; - - /** - * Constructor. - * - * @param object $translator - * @param object $legacyContext - */ - public function __construct($translator, $legacyContext) - { - $this->translator = $translator; - $this->legacyContext = $legacyContext; - $this->configuration = $this->getConfiguration(); - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add( - 'is_virtual_file', - FormType\ChoiceType::class, - [ - 'choices' => [ - $this->translator->trans('Yes', [], 'Admin.Global') => 1, - $this->translator->trans('No', [], 'Admin.Global') => 0, - ], - 'expanded' => true, - 'required' => true, - 'multiple' => false, - ] - ) - ->add( - 'file', - FormType\FileType::class, - [ - 'required' => false, - 'label' => $this->translator->trans('File', [], 'Admin.Global'), - 'constraints' => [ - new Assert\File(['maxSize' => $this->configuration->get('PS_ATTACHMENT_MAXIMUM_SIZE') . 'M']), - ], - ] - ) - ->add( - 'name', - FormType\TextType::class, - [ - 'label' => $this->translator->trans('Filename', [], 'Admin.Global'), - 'constraints' => [ - new Assert\NotBlank(), - ], - ] - ) - ->add( - 'nb_downloadable', - FormType\NumberType::class, - [ - 'label' => $this->translator->trans('Number of allowed downloads', [], 'Admin.Catalog.Feature'), - 'required' => false, - 'constraints' => [ - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'expiration_date', - DatePickerType::class, - [ - 'label' => $this->translator->trans('Expiration date', [], 'Admin.Catalog.Feature'), - 'required' => false, - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - ] - ) - ->add( - 'nb_days', - FormType\NumberType::class, - [ - 'label' => $this->translator->trans('Number of days', [], 'Admin.Catalog.Feature'), - 'required' => false, - 'constraints' => [ - new Assert\Type(['type' => 'numeric']), - ], - ] - ) - ->add( - 'save', - FormType\ButtonType::class, - [ - 'label' => $this->translator->trans('Save', [], 'Admin.Actions'), - 'attr' => ['class' => 'btn-primary pull-right'], - ] - ); - - $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { - $form = $event->getForm(); - $data = $event->getData(); - - //if this partial form is submit from a parent form, disable it - if ($form->getParent()) { - $event->setData([]); - $form->add('name', FormType\TextType::class, ['mapped' => false]); - } elseif ($data['is_virtual_file'] == 0) { - //disable name mapping when is virtual not defined to yes - $form->add('name', FormType\TextType::class, ['mapped' => false]); - } - }); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_virtual'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Product/ProductWarehouseCombination.php b/src/PrestaShopBundle/Form/Admin/Product/ProductWarehouseCombination.php deleted file mode 100644 index 4e3e7a0c..00000000 --- a/src/PrestaShopBundle/Form/Admin/Product/ProductWarehouseCombination.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Product; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to generate the basic product Warehouse combinations form. - */ -class ProductWarehouseCombination extends CommonAbstractType -{ - private $translator; - private $contextLegacy; - - /** - * Constructor. - * - * @param object $translator - * @param object $legacyContext - */ - public function __construct($translator, $legacyContext) - { - $this->translator = $translator; - $this->contextLegacy = $legacyContext->getContext(); - } - - /** - * {@inheritdoc} - * - * Builds form - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('activated', CheckboxType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Stored', [], 'Admin.Catalog.Feature'), - ]) - ->add('id_product_attribute', HiddenType::class) - ->add('product_id', HiddenType::class) - ->add('warehouse_id', HiddenType::class) - ->add('location', TextType::class, [ - 'required' => false, - 'label' => $this->translator->trans('Location (optional)', [], 'Admin.Catalog.Feature'), - 'empty_data' => '', - ]); - - //set default minimal values for collection prototype - $builder->setData([ - 'warehouse_id' => $options['id_warehouse'], - 'warehouse_activated' => false, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'id_warehouse' => null, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'product_warehouse_combination'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Address/CustomerAddressType.php b/src/PrestaShopBundle/Form/Admin/Sell/Address/CustomerAddressType.php deleted file mode 100644 index e3be2bb6..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Address/CustomerAddressType.php +++ /dev/null @@ -1,393 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Address; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressStateRequired; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressZipCode; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\ExistingCustomerEmail; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\Address\Configuration\AddressConstraint; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\CountryChoiceType; -use PrestaShopBundle\Form\Admin\Type\EmailType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Email; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; - -/** - * Form type for address add/edit - */ -class CustomerAddressType extends AbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $stateChoiceProvider; - - /** - * @var int - */ - private $contextCountryId; - - /** - * @param TranslatorInterface $translator - * @param ConfigurableFormChoiceProviderInterface $stateChoiceProvider - */ - public function __construct( - TranslatorInterface $translator, - ConfigurableFormChoiceProviderInterface $stateChoiceProvider, - $contextCountryId - ) { - $this->translator = $translator; - $this->stateChoiceProvider = $stateChoiceProvider; - $this->contextCountryId = $contextCountryId; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $data = $builder->getData(); - $countryId = 0 !== $data['id_country'] ? $data['id_country'] : $this->contextCountryId; - $stateChoices = $this->stateChoiceProvider->getChoices(['id_country' => $countryId]); - - $hideStates = empty($stateChoices); - - if (!isset($data['id_customer'])) { - $builder->add('customer_email', EmailType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new Email([ - 'message' => $this->translator->trans('This field is invalid', [], 'Admin.Notifications.Error'), - ]), - new ExistingCustomerEmail(), - ], - ]); - } else { - $builder->add('id_customer', HiddenType::class); - } - - $builder->add('phone_mobile', TextType::class, [ - 'required' => false, - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_PHONE_NUMBER, - ]), - new Length([ - 'max' => AddressConstraint::MAX_PHONE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_PHONE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('dni', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_DNI_LITE, - ]), - new Length([ - 'max' => AddressConstraint::MAX_DNI_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_DNI_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('alias', TextType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_ALIAS_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_ALIAS_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('first_name', TextType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_FIRST_NAME_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_FIRST_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('last_name', TextType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_LAST_NAME_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_LAST_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('company', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_COMPANY_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_COMPANY_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('vat_number', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_VAT_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_VAT_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('address1', TextType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_ADDRESS, - ]), - new Length([ - 'max' => AddressConstraint::MAX_ADDRESS_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_ADDRESS_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('address2', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_ADDRESS, - ]), - new Length([ - 'max' => AddressConstraint::MAX_ADDRESS_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_ADDRESS_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('city', TextType::class, [ - 'required' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_CITY_NAME, - ]), - new Length([ - 'max' => AddressConstraint::MAX_CITY_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_CITY_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('postcode', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new AddressZipCode([ - 'id_country' => $countryId, - 'required' => false, - ]), - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_POST_CODE, - ]), - new Length([ - 'max' => AddressConstraint::MAX_POSTCODE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_POSTCODE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_country', CountryChoiceType::class, [ - 'required' => true, - 'with_dni_attr' => true, - 'with_postcode_attr' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_state', ChoiceType::class, [ - 'required' => true, - 'choices' => $stateChoices, - 'constraints' => [ - new AddressStateRequired([ - 'id_country' => $countryId, - ]), - ], - ]) - ->add('phone', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_PHONE_NUMBER, - ]), - new Length([ - 'max' => AddressConstraint::MAX_PHONE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_PHONE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('other', TextareaType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new CleanHtml(), - new TypedRegex([ - 'type' => TypedRegex::TYPE_MESSAGE, - ]), - new Length([ - 'max' => AddressConstraint::MAX_OTHER_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressConstraint::MAX_OTHER_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Address/ManufacturerAddressType.php b/src/PrestaShopBundle/Form/Admin/Sell/Address/ManufacturerAddressType.php deleted file mode 100644 index f491e4bd..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Address/ManufacturerAddressType.php +++ /dev/null @@ -1,334 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Address; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressDniRequired; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressStateRequired; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\Address\AddressSettings; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\CountryChoiceType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; - -/** - * Defines form for address create/edit actions (Sell > Catalog > Brands & Suppliers) - */ -class ManufacturerAddressType extends AbstractType -{ - /** - * @var array - */ - private $manufacturerChoices; - - /** - * @var array - */ - private $countryChoices; - - /** - * @var array - */ - private $countryChoicesAttributes; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $statesChoiceProvider; - - /** - * @var int - */ - private $contextCountryId; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param array $manufacturerChoices - * @param array $countryChoices - * @param ConfigurableFormChoiceProviderInterface $statesChoiceProvider - * @param int $contextCountryId - * @param TranslatorInterface $translator - * @param array $countryChoicesAttributes - */ - public function __construct( - array $manufacturerChoices, - array $countryChoices, - ConfigurableFormChoiceProviderInterface $statesChoiceProvider, - $contextCountryId, - TranslatorInterface $translator, - array $countryChoicesAttributes - ) { - $this->manufacturerChoices = $manufacturerChoices; - $this->countryChoices = $countryChoices; - $this->statesChoiceProvider = $statesChoiceProvider; - $this->contextCountryId = $contextCountryId; - $this->translator = $translator; - $this->countryChoicesAttributes = $countryChoicesAttributes; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $data = $builder->getData(); - $countryId = 0 !== $data['id_country'] ? $data['id_country'] : $this->contextCountryId; - $stateChoices = $this->statesChoiceProvider->getChoices(['id_country' => $countryId]); - - $builder - ->add('id_manufacturer', ChoiceType::class, [ - 'choices' => $this->getManufacturersChoiceList(), - 'translation_domain' => false, - 'placeholder' => false, - 'required' => false, - ]) - ->add('last_name', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new TypedRegex([ - 'type' => 'name', - ]), - new Length([ - 'max' => AddressSettings::MAX_NAME_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('first_name', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new TypedRegex([ - 'type' => 'name', - ]), - new Length([ - 'max' => AddressSettings::MAX_NAME_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('address', TextType::class, [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'address', - ]), - new Length([ - 'max' => AddressSettings::MAX_ADDRESS_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_ADDRESS_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('address2', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new TypedRegex([ - 'type' => 'address', - ]), - new Length([ - 'max' => AddressSettings::MAX_ADDRESS_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_ADDRESS_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('post_code', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new TypedRegex([ - 'type' => 'post_code', - ]), - new Length([ - 'max' => AddressSettings::MAX_POST_CODE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_POST_CODE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('city', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new TypedRegex([ - 'type' => 'city_name', - ]), - new Length([ - 'max' => AddressSettings::MAX_CITY_NAME_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_CITY_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_country', CountryChoiceType::class, [ - 'required' => true, - 'with_dni_attr' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_state', ChoiceType::class, [ - 'required' => true, - 'choices' => $stateChoices, - 'constraints' => [ - new AddressStateRequired([ - 'id_country' => $countryId, - ]), - ], - ]) - ->add('home_phone', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new TypedRegex([ - 'type' => 'phone_number', - ]), - new Length([ - 'max' => AddressSettings::MAX_PHONE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_PHONE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('mobile_phone', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new TypedRegex([ - 'type' => 'phone_number', - ]), - new Length([ - 'max' => AddressSettings::MAX_PHONE_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_PHONE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('dni', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new AddressDniRequired([ - 'required' => false, - 'id_country' => $countryId, - ]), - new TypedRegex([ - 'type' => 'dni_lite', - ]), - new Length([ - 'max' => 16, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => 16], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('other', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new TypedRegex([ - 'type' => 'message', - ]), - new Length([ - 'max' => AddressSettings::MAX_OTHER_LENGTH, - 'maxMessage' => $this->translator->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AddressSettings::MAX_OTHER_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ; - } - - /** - * Get manufacturers array for choice list - * List is modified to enable selecting -no manufacturer- - * - * @return array - */ - private function getManufacturersChoiceList() - { - $this->manufacturerChoices['--'] = 0; - - return $this->manufacturerChoices; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Address/RequiredFieldsAddressType.php b/src/PrestaShopBundle/Form/Admin/Sell/Address/RequiredFieldsAddressType.php deleted file mode 100644 index 84291c35..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Address/RequiredFieldsAddressType.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Address; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTableType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Defines form for address required fields modification (Sell > Customers > Addresses) - */ -class RequiredFieldsAddressType extends AbstractType -{ - /** - * @var FormChoiceProviderInterface - */ - private $addressRequiredFieldsChoicesProvider; - - /** - * @param FormChoiceProviderInterface $addressRequiredFieldsChoicesProvider - */ - public function __construct(FormChoiceProviderInterface $addressRequiredFieldsChoicesProvider) - { - $this->addressRequiredFieldsChoicesProvider = $addressRequiredFieldsChoicesProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('required_fields', MaterialChoiceTableType::class, [ - 'label' => false, - 'choices' => $this->addressRequiredFieldsChoicesProvider->getChoices(), - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Attachment/AttachmentType.php b/src/PrestaShopBundle/Form/Admin/Sell/Attachment/AttachmentType.php deleted file mode 100644 index 04177803..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Attachment/AttachmentType.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Attachment; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\Attachment\Configuration\AttachmentConstraint; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\FileType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Constraints\Length; - -/** - * Attachment form type definition - */ -class AttachmentType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('name', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => true, - 'options' => [ - 'constraints' => [ - new TypedRegex( - [ - 'type' => 'generic_name', - ] - ), - new Length( - [ - 'max' => AttachmentConstraint::MAX_NAME_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => AttachmentConstraint::MAX_NAME_LENGTH], - 'Admin.Notifications.Error' - ), - ] - ), - ], - ], - 'constraints' => [ - new DefaultLanguage(), - ], - ]) - ->add('file_description', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => false, - 'options' => [ - 'constraints' => [ - new CleanHtml(), - ], - ], - ]) - ->add('file', FileType::class, [ - 'required' => false, - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Catalog/FeatureType.php b/src/PrestaShopBundle/Form/Admin/Sell/Catalog/FeatureType.php deleted file mode 100644 index 07eff9a7..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Catalog/FeatureType.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Catalog; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShopBundle\Form\Admin\Type\ShopChoiceTreeType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Type that builds a product feature add/edit form. - */ -class FeatureType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * @var bool - */ - private $isMultistoreFeatureActive; - - /** - * @param bool $isMultistoreFeatureActive - */ - public function __construct($isMultistoreFeatureActive) - { - $this->isMultistoreFeatureActive = $isMultistoreFeatureActive; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('name', TranslatableType::class, [ - 'type' => TextType::class, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'generic_name', - ]), - ], - ], - ]); - - if ($this->isMultistoreFeatureActive) { - $builder->add('shop_association', ShopChoiceTreeType::class); - } - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/CatalogPriceRule/CatalogPriceRuleType.php b/src/PrestaShopBundle/Form/Admin/Sell/CatalogPriceRule/CatalogPriceRuleType.php deleted file mode 100644 index 6c9c3f7a..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/CatalogPriceRule/CatalogPriceRuleType.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\CatalogPriceRule; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DateRange; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\Reduction; -use PrestaShop\PrestaShop\Core\Domain\ValueObject\Reduction as ReductionVO; -use PrestaShopBundle\Form\Admin\Type\DateRangeType; -use PrestaShopBundle\Form\Admin\Type\ReductionType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; - -/** - * Defines catalog price rule form for create/edit actions - */ -class CatalogPriceRuleType extends AbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var bool - */ - private $isMultishopEnabled; - - /** - * @var array - */ - private $currencyByIdChoices; - - /** - * @var array - */ - private $countryByIdChoices; - - /** - * @var array - */ - private $groupByIdChoices; - - /** - * @var array - */ - private $shopByIdChoices; - - /** - * @var array - */ - private $taxInclusionChoices; - - /** - * @param TranslatorInterface $translator - * @param bool $isMultishopEnabled - * @param array $currencyByIdChoices - * @param array $countryByIdChoices - * @param array $groupByIdChoices - * @param array $shopByIdChoices - * @param array $taxInclusionChoices - */ - public function __construct( - TranslatorInterface $translator, - bool $isMultishopEnabled, - array $currencyByIdChoices, - array $countryByIdChoices, - array $groupByIdChoices, - array $shopByIdChoices, - array $taxInclusionChoices - ) { - $this->translator = $translator; - $this->isMultishopEnabled = $isMultishopEnabled; - $this->currencyByIdChoices = $currencyByIdChoices; - $this->countryByIdChoices = $countryByIdChoices; - $this->groupByIdChoices = $groupByIdChoices; - $this->shopByIdChoices = $shopByIdChoices; - $this->taxInclusionChoices = $taxInclusionChoices; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('name', TextType::class, [ - 'constraints' => [ - new CleanHtml(), - ], - ]) - ->add('id_currency', ChoiceType::class, [ - 'required' => false, - 'placeholder' => false, - 'choices' => $this->getModifiedCurrencyChoices(), - ]) - ->add('id_country', ChoiceType::class, [ - 'required' => false, - 'placeholder' => false, - 'choices' => $this->getModifiedCountryChoices(), - ]) - ->add('id_group', ChoiceType::class, [ - 'required' => false, - 'placeholder' => false, - 'choices' => $this->getModifiedGroupChoices(), - ]) - ->add('from_quantity', NumberType::class, [ - 'scale' => 0, - 'constraints' => [ - new GreaterThanOrEqual([ - 'value' => 0, - 'message' => $this->translator->trans( - '%s is invalid.', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('price', NumberType::class, [ - 'required' => false, - 'scale' => 6, - 'constraints' => [ - new GreaterThanOrEqual([ - 'value' => 0, - 'message' => $this->translator->trans( - '%s is invalid.', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('leave_initial_price', CheckboxType::class, [ - 'required' => false, - ]) - ->add('date_range', DateRangeType::class, [ - 'date_format' => 'YYYY-MM-DD HH:mm:ss', - 'constraints' => [ - new DateRange([ - 'message' => $this->translator->trans( - 'The selected date range is not valid.', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('include_tax', ChoiceType::class, [ - 'placeholder' => false, - 'required' => false, - 'choices' => $this->taxInclusionChoices, - ]) - ->add('reduction', ReductionType::class, [ - 'constraints' => [ - new Reduction([ - 'invalidPercentageValueMessage' => $this->translator->trans( - 'Reduction value "%value%" is invalid. Allowed values from 0 to %max%', - ['%max%' => ReductionVO::MAX_ALLOWED_PERCENTAGE . '%'], - 'Admin.Notifications.Error' - ), - 'invalidAmountValueMessage' => $this->translator->trans( - 'Reduction value "%value%" is invalid. Value cannot be negative', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ; - - if ($this->isMultishopEnabled) { - $builder->add('id_shop', ChoiceType::class, [ - 'required' => false, - 'placeholder' => false, - 'choices' => $this->shopByIdChoices, - ]); - } - } - - /** - * Prepends 'All currencies' option with id of 0 to currency choices - * - * @return array - */ - private function getModifiedCurrencyChoices(): array - { - return array_merge( - [$this->translator->trans('All currencies', [], 'Admin.Global') => 0], - $this->currencyByIdChoices - ); - } - - /** - * Prepends 'All countries' option with id of 0 to country choices - * - * @return array - */ - private function getModifiedCountryChoices(): array - { - return array_merge( - [$this->translator->trans('All countries', [], 'Admin.Global') => 0], - $this->countryByIdChoices - ); - } - - /** - * Prepends 'All groups' option with id of 0 to group choices - * - * @return array - */ - private function getModifiedGroupChoices(): array - { - return array_merge( - [$this->translator->trans('All groups', [], 'Admin.Global') => 0], - $this->groupByIdChoices - ); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Category/DeleteCategoriesType.php b/src/PrestaShopBundle/Form/Admin/Sell/Category/DeleteCategoriesType.php deleted file mode 100644 index e974e85d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Category/DeleteCategoriesType.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Category; - -use PrestaShop\PrestaShop\Core\Domain\Category\ValueObject\CategoryDeleteMode; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Class DeleteCategoriesType. - */ -class DeleteCategoriesType extends AbstractType -{ - /** - * @var array - */ - private $categoryDeleteModelChoices; - - /** - * @param array $categoryDeleteModelChoices - */ - public function __construct(array $categoryDeleteModelChoices) - { - $this->categoryDeleteModelChoices = $categoryDeleteModelChoices; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('delete_mode', ChoiceType::class, [ - 'expanded' => true, - 'choices' => $this->categoryDeleteModelChoices, - 'label' => false, - 'data' => CategoryDeleteMode::ASSOCIATE_PRODUCTS_WITH_PARENT_AND_DISABLE, - ]) - ->add('categories_to_delete', CollectionType::class, [ - 'entry_type' => HiddenType::class, - 'label' => false, - 'allow_add' => true, - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Customer/CustomerType.php b/src/PrestaShopBundle/Form/Admin/Sell/Customer/CustomerType.php deleted file mode 100644 index 73de325a..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Customer/CustomerType.php +++ /dev/null @@ -1,257 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Customer; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CustomerName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\FirstName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\LastName; -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\Password; -use PrestaShopBundle\Form\Admin\Type\EmailType; -use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTableType; -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\BirthdayType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\IntegerType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\PasswordType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints\Email; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\Constraints\Type; - -/** - * Type is used to created form for customer add/edit actions - */ -class CustomerType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * @var array - */ - private $genderChoices; - - /** - * @var array - */ - private $groupChoices; - - /** - * @var bool - */ - private $isB2bFeatureEnabled; - - /** - * @var array - */ - private $riskChoices; - - /** - * @var bool - */ - private $isPartnerOffersEnabled; - - /** - * @param array $genderChoices - * @param array $groupChoices - * @param array $riskChoices - * @param bool $isB2bFeatureEnabled - * @param bool $isPartnerOffersEnabled - */ - public function __construct( - array $genderChoices, - array $groupChoices, - array $riskChoices, - $isB2bFeatureEnabled, - $isPartnerOffersEnabled - ) { - $this->genderChoices = $genderChoices; - $this->groupChoices = $groupChoices; - $this->isB2bFeatureEnabled = $isB2bFeatureEnabled; - $this->riskChoices = $riskChoices; - $this->isPartnerOffersEnabled = $isPartnerOffersEnabled; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('gender_id', ChoiceType::class, [ - 'choices' => $this->genderChoices, - 'multiple' => false, - 'expanded' => true, - 'required' => false, - 'placeholder' => null, - ]) - ->add('first_name', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans('This field cannot be empty', [], 'Admin.Notifications.Error'), - ]), - new Length([ - 'max' => FirstName::MAX_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => FirstName::MAX_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - new CustomerName([ - 'message' => $this->trans('The %s field is invalid.', [sprintf('"%s"', $this->trans('First name', [], 'Admin.Global'))], 'Admin.Notifications.Error'), - ]), - ], - ]) - ->add('last_name', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans('This field cannot be empty', [], 'Admin.Notifications.Error'), - ]), - new Length([ - 'max' => LastName::MAX_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => LastName::MAX_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - new CustomerName([ - 'message' => $this->trans('The %s field is invalid.', [sprintf('"%s"', $this->trans('Last name', [], 'Admin.Global'))], 'Admin.Notifications.Error'), - ]), - ], - ]) - ->add('email', EmailType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans('This field cannot be empty', [], 'Admin.Notifications.Error'), - ]), - new Email([ - 'message' => $this->trans('This field is invalid', [], 'Admin.Notifications.Error'), - ]), - ], - ]) - ->add('password', PasswordType::class, [ - 'constraints' => [ - new Length([ - 'max' => Password::MAX_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => Password::MAX_LENGTH], - 'Admin.Notifications.Error' - ), - 'min' => Password::MIN_LENGTH, - 'minMessage' => $this->trans( - 'This field cannot be shorter than %limit% characters', - ['%limit%' => Password::MIN_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - 'required' => $options['is_password_required'], - ]) - ->add('birthday', BirthdayType::class, [ - 'required' => false, - 'format' => 'yyyy MM dd', - 'input' => 'string', - ]) - ->add('is_enabled', SwitchType::class, [ - 'required' => false, - ]) - ->add('is_partner_offers_subscribed', SwitchType::class, [ - 'required' => false, - 'disabled' => !$this->isPartnerOffersEnabled, - ]) - ->add('group_ids', MaterialChoiceTableType::class, [ - 'empty_data' => [], - 'choices' => $this->groupChoices, - ]) - ->add('default_group_id', ChoiceType::class, [ - 'required' => false, - 'placeholder' => null, - 'choices' => $this->groupChoices, - ]) - ; - - if ($this->isB2bFeatureEnabled) { - $builder - ->add('company_name', TextType::class, [ - 'required' => false, - ]) - ->add('siret_code', TextType::class, [ - 'required' => false, - ]) - ->add('ape_code', TextType::class, [ - 'required' => false, - 'constraints' => [ - new Type([ - 'type' => 'alnum', - 'message' => $this->trans('This field is invalid', [], 'Admin.Notifications.Error'), - ]), - ], - ]) - ->add('website', TextType::class, [ - 'required' => false, - ]) - ->add('allowed_outstanding_amount', NumberType::class, [ - 'scale' => 6, - 'required' => false, - 'invalid_message' => $this->trans('This field is invalid', [], 'Admin.Notifications.Error'), - ]) - ->add('max_payment_days', IntegerType::class, [ - 'required' => false, - 'invalid_message' => $this->trans('This field is invalid', [], 'Admin.Notifications.Error'), - ]) - ->add('risk_id', ChoiceType::class, [ - 'required' => false, - 'placeholder' => null, - 'choices' => $this->riskChoices, - ]) - ; - } - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - // password is configurable - // so it may be optional when editing customer - 'is_password_required' => true, - ]) - ->setAllowedTypes('is_password_required', 'bool') - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Customer/DeleteCustomersType.php b/src/PrestaShopBundle/Form/Admin/Sell/Customer/DeleteCustomersType.php deleted file mode 100644 index c6da2861..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Customer/DeleteCustomersType.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Customer; - -use PrestaShop\PrestaShop\Core\Domain\Customer\ValueObject\CustomerDeleteMethod; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Class DeleteCustomersType - */ -class DeleteCustomersType extends AbstractType -{ - /** - * @var array - */ - private $customerDeleteMethodChoices; - - /** - * @param array $customerDeleteMethodChoices - */ - public function __construct(array $customerDeleteMethodChoices) - { - $this->customerDeleteMethodChoices = $customerDeleteMethodChoices; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('delete_method', ChoiceType::class, [ - 'choices' => $this->customerDeleteMethodChoices, - 'expanded' => true, - 'multiple' => false, - 'translation_domain' => false, - 'data' => CustomerDeleteMethod::ALLOW_CUSTOMER_REGISTRATION, - ]) - ->add('customers_to_delete', CollectionType::class, [ - 'entry_type' => HiddenType::class, - 'label' => false, - 'allow_add' => true, - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Customer/PrivateNoteType.php b/src/PrestaShopBundle/Form/Admin/Sell/Customer/PrivateNoteType.php deleted file mode 100644 index 55ed027f..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Customer/PrivateNoteType.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Customer; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class PrivateNoteType is used to add private notes about customer. - */ -class PrivateNoteType extends AbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * PrivateNoteType constructor. - * - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('note', TextareaType::class, [ - 'required' => false, - 'empty_data' => '', - 'attr' => [ - 'placeholder' => $this->translator->trans('Add a note on this customer. It will only be visible to you.', [], 'Admin.Orderscustomers.Feature'), - ], - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Customer/RequiredFieldsType.php b/src/PrestaShopBundle/Form/Admin/Sell/Customer/RequiredFieldsType.php deleted file mode 100644 index 0cccff7a..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Customer/RequiredFieldsType.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Customer; - -use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTableType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Defines form for customer required fields - */ -class RequiredFieldsType extends AbstractType -{ - /** - * @var array - */ - private $customerRequiredFieldsChoices; - - /** - * @param array $customerRequiredFieldsChoices - */ - public function __construct(array $customerRequiredFieldsChoices) - { - $this->customerRequiredFieldsChoices = $customerRequiredFieldsChoices; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('required_fields', MaterialChoiceTableType::class, [ - 'label' => false, - 'choices' => $this->customerRequiredFieldsChoices, - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Customer/TransferGuestAccountType.php b/src/PrestaShopBundle/Form/Admin/Sell/Customer/TransferGuestAccountType.php deleted file mode 100644 index 03a458e1..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Customer/TransferGuestAccountType.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Customer; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Class TransferGuestAccountType is type used to submit guest customer transformation - * into actual customer with password. - */ -class TransferGuestAccountType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('id_customer', HiddenType::class); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsFormDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsFormDataProvider.php deleted file mode 100644 index e1ac0f8e..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsFormDataProvider.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\CustomerService\MerchandiseReturn; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * Provides merchandise return options form with data - */ -final class MerchandiseReturnOptionsFormDataProvider implements FormDataProviderInterface -{ - /** - * @var DataConfigurationInterface - */ - private $optionsDataConfiguration; - - /** - * @param DataConfigurationInterface $optionsDataConfiguration - */ - public function __construct(DataConfigurationInterface $optionsDataConfiguration) - { - $this->optionsDataConfiguration = $optionsDataConfiguration; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return [ - 'options' => $this->optionsDataConfiguration->getConfiguration(), - ]; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - return $this->optionsDataConfiguration->updateConfiguration($data['options']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsType.php b/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsType.php deleted file mode 100644 index 32078031..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/MerchandiseReturn/MerchandiseReturnOptionsType.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\CustomerService\MerchandiseReturn; - -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\IntegerType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; - -/** - * Form type for merchandise returns options - */ -class MerchandiseReturnOptionsType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('enable_order_return', SwitchType::class, [ - 'required' => false, - ]) - ->add('order_return_period_in_days', IntegerType::class, [ - 'required' => false, - 'constraints' => new GreaterThanOrEqual([ - 'value' => 0, - ]), - ]) - ->add('order_return_prefix', TranslatableType::class, [ - 'required' => false, - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/OrderMessageType.php b/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/OrderMessageType.php deleted file mode 100644 index 3572b7b8..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/OrderMessageType.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\CustomerService; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\DefaultLanguage; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\OrderMessageConstraint; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Validator\Constraints\Length; - -/** - * Builds add/edit form for order message - */ -class OrderMessageType extends AbstractType -{ - /** - * @param FormBuilderInterface $builder - * @param array $options - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('name', TranslatableType::class, [ - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'generic_name', - ]), - new Length([ - 'max' => OrderMessageConstraint::MAX_NAME_LENGTH, - ]), - ], - ], - 'constraints' => [ - new DefaultLanguage(), - ], - ]) - ->add('message', TranslatableType::class, [ - 'type' => TextareaType::class, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'message', - ]), - new Length([ - 'max' => OrderMessageConstraint::MAX_MESSAGE_LENGTH, - ]), - ], - 'attr' => [ - 'rows' => 5, - ], - ], - 'constraints' => [ - new DefaultLanguage(), - ], - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/ReplyToCustomerThreadType.php b/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/ReplyToCustomerThreadType.php deleted file mode 100644 index 6b402b7c..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/CustomerService/ReplyToCustomerThreadType.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\CustomerService; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\NotBlank; - -class ReplyToCustomerThreadType extends AbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param TranslatorInterface $translator - */ - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('reply_message', TextareaType::class, [ - 'required' => false, - 'constraints' => [ - new NotBlank([ - 'message' => $this->translator->trans( - 'Reply message is required', - [], - 'Admin.Notifications.Error' - ), - ]), - new CleanHtml([ - 'message' => $this->translator->trans( - 'Reply message is invalid', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Manufacturer/ManufacturerType.php b/src/PrestaShopBundle/Form/Admin/Sell/Manufacturer/ManufacturerType.php deleted file mode 100644 index 020e46bf..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Manufacturer/ManufacturerType.php +++ /dev/null @@ -1,201 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Manufacturer; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType; -use PrestaShopBundle\Form\Admin\Type\ShopChoiceTreeType; -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\FileType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; - -/** - * Defines form for manufacturer create/edit actions (Sell > Catalog > Brands & Suppliers) - */ -class ManufacturerType extends TranslatorAwareType -{ - /** - * @var bool - */ - private $isMultistoreEnabled; - - /** - * @param TranslatorInterface $translator - * @param array $locales - * @param bool $isMultistoreEnabled - */ - public function __construct( - TranslatorInterface $translator, - array $locales, - $isMultistoreEnabled - ) { - parent::__construct($translator, $locales); - - $this->isMultistoreEnabled = $isMultistoreEnabled; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('name', TextType::class, [ - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - new Length([ - 'max' => 64, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => 64] - ), - ]), - new TypedRegex([ - 'type' => 'catalog_name', - ]), - ], - ]) - ->add('short_description', TranslateType::class, [ - 'type' => FormattedTextareaType::class, - 'locales' => $this->locales, - 'hideTabs' => false, - 'required' => false, - 'options' => [ - 'constraints' => [ - new CleanHtml([ - 'message' => $this->trans( - '%s is invalid.', - 'Admin.Notifications.Error' - ), - ]), - ], - ], - ]) - ->add('description', TranslateType::class, [ - 'type' => FormattedTextareaType::class, - 'locales' => $this->locales, - 'hideTabs' => false, - 'required' => false, - 'options' => [ - 'constraints' => [ - new CleanHtml([ - 'message' => $this->trans( - '%s is invalid.', - 'Admin.Notifications.Error' - ), - ]), - ], - ], - ]) - ->add('logo', FileType::class, [ - 'required' => false, - ]) - ->add('meta_title', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => false, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'generic_name', - ]), - new Length([ - 'max' => 255, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => 255] - ), - ]), - ], - ], - ]) - ->add('meta_description', TranslatableType::class, [ - 'type' => TextareaType::class, - 'required' => false, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'generic_name', - ]), - new Length([ - 'max' => 512, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => 512] - ), - ]), - ], - ], - ]) - ->add('meta_keyword', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => false, - 'options' => [ - 'attr' => [ - 'class' => 'js-taggable-field', - 'placeholder' => $this->trans('Add tag', 'Admin.Actions'), - ], - 'constraints' => [ - new TypedRegex([ - 'type' => 'generic_name', - ]), - ], - ], - ]) - ->add('is_enabled', SwitchType::class, [ - 'required' => false, - ]); - - if ($this->isMultistoreEnabled) { - $builder->add('shop_association', ShopChoiceTreeType::class, [ - 'required' => false, - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - ], - ]); - } - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/AddOrderCartRuleType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/AddOrderCartRuleType.php deleted file mode 100644 index 7a0dd80d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/AddOrderCartRuleType.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Type; - -class AddOrderCartRuleType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * @var FormChoiceProviderInterface - */ - private $orderDiscountTypeChoiceProvider; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $orderInvoiceByIdChoiceProvider; - - /** - * @var int - */ - private $contextLangId; - - /** - * @param FormChoiceProviderInterface $orderDiscountTypeChoiceProvider - * @param ConfigurableFormChoiceProviderInterface $orderInvoiceByIdChoiceProvider - * @param int $contextLangId - * @param TranslatorInterface $translator - */ - public function __construct( - FormChoiceProviderInterface $orderDiscountTypeChoiceProvider, - ConfigurableFormChoiceProviderInterface $orderInvoiceByIdChoiceProvider, - int $contextLangId, - TranslatorInterface $translator - ) { - $this->orderDiscountTypeChoiceProvider = $orderDiscountTypeChoiceProvider; - $this->orderInvoiceByIdChoiceProvider = $orderInvoiceByIdChoiceProvider; - $this->contextLangId = $contextLangId; - $this->setTranslator($translator); - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $invoices = $options['order_id'] ? - $this->orderInvoiceByIdChoiceProvider->getChoices([ - 'id_order' => $options['order_id'], - 'id_lang' => $this->contextLangId, - 'display_total' => true, - ]) : []; - - $builder - ->add('name', TextType::class, [ - 'constraints' => [ - new CleanHtml([ - 'message' => $this->trans( - 'Cart rule name must contain clean HTML', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('type', ChoiceType::class, [ - 'choices' => $this->orderDiscountTypeChoiceProvider->getChoices(), - ]) - ->add('value', TextType::class, [ - 'constraints' => new Type([ - 'type' => 'numeric', - 'message' => $this->trans('Discount value must be a number', [], 'Admin.Notifications.Error'), - ]), - ]) - ->add('invoice_id', ChoiceType::class, [ - 'choices' => $invoices, - 'required' => false, - 'placeholder' => false, - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setDefaults([ - 'order_id' => null, - ]) - ->setAllowedTypes('order_id', ['int', 'null']) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/AddProductRowType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/AddProductRowType.php deleted file mode 100644 index a61f207e..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/AddProductRowType.php +++ /dev/null @@ -1,173 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\TextWithUnitType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\ButtonType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Form type used to add a product row - */ -class AddProductRowType extends TranslatorAwareType -{ - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $orderInvoiceByIdChoiceProvider; - - /** - * @var int - */ - private $contextLangId; - - public function __construct( - TranslatorInterface $translator, - array $locales, - ConfigurableFormChoiceProviderInterface $orderInvoiceByIdChoiceProvider, - int $contextLangId - ) { - parent::__construct($translator, $locales); - - $this->orderInvoiceByIdChoiceProvider = $orderInvoiceByIdChoiceProvider; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $invoices = $options['order_id'] ? - $this->orderInvoiceByIdChoiceProvider->getChoices([ - 'id_order' => $options['order_id'], - 'id_lang' => $this->contextLangId, - 'display_total' => false, - ]) : []; - - $builder - ->add('product_id', HiddenType::class) - ->add('tax_rate', HiddenType::class) - ->add('search', TextType::class, [ - 'label' => $this->trans('Add a product', 'Admin.Orderscustomers.Feature'), - 'attr' => [ - 'class' => 'col-sm-12', - 'autocomplete' => 'off', - 'placeholder' => $this->trans('Search for a product', 'Admin.Orderscustomers.Feature'), - 'data-currency' => $options['currency_id'], - 'data-order' => $options['order_id'], - ], - ]) - ->add('addProductCombinations', ChoiceType::class, [ - 'attr' => [ - 'class' => 'custom-select', - ], - ]) - ->add('price_tax_excluded', TextWithUnitType::class, [ - 'label' => false, - 'unit' => sprintf('%s %s', - $options['symbol'], - $this->trans('tax excl.', 'Admin.Global') - ), - ]) - ->add('price_tax_included', TextWithUnitType::class, [ - 'label' => false, - 'unit' => sprintf('%s %s', - $options['symbol'], - $this->trans('tax incl.', 'Admin.Global') - ), - ]) - ->add('quantity', NumberType::class, [ - 'label' => false, - 'data' => 1, - 'scale' => 0, - 'attr' => [ - 'min' => 1, - ], - ]) - ->add('invoice', ChoiceType::class, [ - 'label' => false, - 'disabled' => true, - 'choices' => [ - $this->trans('Existing', 'Admin.Global') => $invoices, - $this->trans('New', 'Admin.Global') => [ - $this->trans('Create a new invoice', 'Admin.Orderscustomers.Feature') => 0, - ], - ], - ]) - ->add('free_shipping', CheckboxType::class, - [ - 'required' => false, - 'label' => $this->trans('Free shipping', 'Admin.Orderscustomers.Feature', []), - 'attr' => [ - 'material_design' => true, - ], - ] - ) - ->add('cancel', ButtonType::class, [ - 'label' => $this->trans('Cancel', 'Admin.Actions'), - 'attr' => [ - 'class' => 'btn btn-sm btn-secondary js-product-add-action-btn mr-2 mt-2 mb-2', - ], - ]) - ->add('add', ButtonType::class, [ - 'label' => $this->trans('Add', 'Admin.Actions'), - 'disabled' => true, - 'attr' => [ - 'class' => 'btn btn-sm btn-primary js-product-add-action-btn mt-2 mb-2', - 'data-order-id' => $options['order_id'], - ], - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setRequired(['symbol']) - ->setDefaults([ - 'order_id' => null, - 'currency_id' => null, - ]) - ->setAllowedTypes('order_id', ['int', 'null']) - ->setAllowedTypes('currency_id', ['int', 'null']) - ->setAllowedTypes('symbol', ['string']) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/CancelProductType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/CancelProductType.php deleted file mode 100644 index f8494f9d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/CancelProductType.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\Decimal\Number; -use PrestaShop\PrestaShop\Core\Domain\Order\VoucherRefundType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; - -class CancelProductType extends TranslatorAwareType -{ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $products = $options['data']['products']; - $taxMethod = $options['data']['taxMethod']; - $precision = $options['data']['precision']; - - foreach ($products as $product) { - $builder - ->add('selected_' . $product->getOrderDetailId(), CheckboxType::class, - [ - 'required' => false, - 'label' => false, - 'attr' => [ - 'material_design' => true, - ], - ] - ) - ->add('quantity_' . $product->getOrderDetailId(), NumberType::class, [ - 'attr' => ['max' => $product->getQuantity(), 'class' => 'refund-quantity'], - 'label' => $this->trans('Quantity', 'Admin.Global', []), - 'invalid_message' => $this->trans('This field is invalid, it must contain numeric values', 'Admin.Notifications.Error', []), - 'required' => false, - 'data' => 0, - 'scale' => 0, - ]) - ->add('amount_' . $product->getOrderDetailId(), TextType::class, [ - 'attr' => ['max' => $product->getTotalPrice(), 'class' => 'refund-amount'], - 'label' => sprintf( - '%s (%s)', - $this->trans('Amount', 'Admin.Global', []), - $taxMethod - ), - 'invalid_message' => $this->trans('This field is invalid, it must contain numeric values', 'Admin.Notifications.Error', []), - 'required' => false, - 'data' => (new Number('0'))->toPrecision($precision), - ]); - } - $builder - ->add('shipping_amount', TextType::class, - [ - 'label' => $this->trans('Shipping', 'Admin.Catalog.Feature', []), - 'invalid_message' => $this->trans('The "shipping" field must be a valid number', 'Admin.Orderscustomers.Feature', []), - 'required' => false, - 'data' => (new Number('0'))->toPrecision($precision), - ] - ) - ->add('shipping', CheckboxType::class, - [ - 'label' => $this->trans('Shipping', 'Admin.Catalog.Feature', []), - 'required' => false, - 'attr' => [ - 'material_design' => true, - ], - ] - ) - ->add('restock', CheckboxType::class, - [ - 'required' => false, - 'label' => $this->trans('Re-stock products', 'Admin.Orderscustomers.Feature', []), - 'attr' => [ - 'material_design' => true, - ], - ] - ) - ->add('credit_slip', CheckboxType::class, - [ - 'required' => false, - 'label' => $this->trans('Generate a credit slip', 'Admin.Orderscustomers.Feature', []), - 'attr' => [ - 'material_design' => true, - ], - 'data' => true, - ] - ) - ->add('voucher', CheckboxType::class, - [ - 'required' => false, - 'label' => $this->trans('Generate a voucher', 'Admin.Orderscustomers.Feature', []), - 'attr' => [ - 'material_design' => true, - ], - ] - ) - ->add('voucher_refund_type', ChoiceType::class, - [ - 'required' => true, - 'multiple' => false, - 'expanded' => true, - 'choices' => [ - $this->trans('Product(s) price:', 'Admin.Orderscustomers.Feature') => VoucherRefundType::PRODUCT_PRICES_REFUND, - $this->trans('Product(s) price, excluding amount of initial voucher:', 'Admin.Orderscustomers.Feature') => VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND, - ], - 'choice_attr' => function ($choice, $key) { - return [ - 'voucher-refund-type' => $choice, - 'data-default-label' => $key, - ]; - }, - 'data' => VoucherRefundType::PRODUCT_PRICES_EXCLUDING_VOUCHER_REFUND, - ] - ) - ->add('cancel', SubmitType::class, [ - 'label' => $this->trans('Cancel', 'Admin.Actions'), - 'attr' => [ - 'class' => 'cancel-product-element cancel-product-element-abort btn btn-outline-secondary', - ], - ]) - ->add('save', SubmitType::class, [ - 'attr' => [ - 'class' => 'cancel-product-element save btn btn-primary ml-3', - 'formnovalidate' => true, - 'data-partial-refund-label' => $this->trans('Partial refund', 'Admin.Orderscustomers.Feature'), - 'data-standard-refund-label' => $this->trans('Standard refund', 'Admin.Orderscustomers.Feature'), - 'data-return-product-label' => $this->trans('Return products', 'Admin.Orderscustomers.Feature'), - 'data-cancel-label' => $this->trans('Cancel products', 'Admin.Orderscustomers.Feature'), - ], - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/CartSummaryType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/CartSummaryType.php deleted file mode 100644 index 77a120bd..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/CartSummaryType.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Form type for cart summary block of order create page - */ -class CartSummaryType extends AbstractType -{ - /** - * @var FormChoiceProviderInterface - */ - private $orderStatesChoiceProvider; - - /** - * @var FormChoiceProviderInterface - */ - private $paymentModulesChoiceProvider; - - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @param FormChoiceProviderInterface $orderStatesChoiceProvider - * @param FormChoiceProviderInterface $paymentModulesChoiceProvider - * @param TranslatorInterface $translator - */ - public function __construct( - FormChoiceProviderInterface $orderStatesChoiceProvider, - FormChoiceProviderInterface $paymentModulesChoiceProvider, - TranslatorInterface $translator - ) { - $this->orderStatesChoiceProvider = $orderStatesChoiceProvider; - $this->paymentModulesChoiceProvider = $paymentModulesChoiceProvider; - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('cart_id', HiddenType::class, [ - 'required' => false, - ]) - ->add('order_message', TextareaType::class, [ - 'required' => false, - ]) - ->add('payment_module', ChoiceType::class, [ - 'choices' => $this->getPaymentModuleChoices(), - 'required' => true, - 'placeholder' => $this->translator->trans( - '-- Choose --', - [], - 'Admin.Actions' - ), - ]) - ->add('order_state', ChoiceType::class, [ - 'choices' => $this->orderStatesChoiceProvider->getChoices(), - 'required' => true, - 'placeholder' => $this->translator->trans( - '-- Choose --', - [], - 'Admin.Actions' - ), - ]); - } - - /** - * Gets payment module choices - * - * @return array - */ - private function getPaymentModuleChoices(): array - { - $choices = []; - - foreach ($this->paymentModulesChoiceProvider->getChoices() as $name => $displayName) { - $choices[$displayName] = $name; - } - - return $choices; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderAddressType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderAddressType.php deleted file mode 100644 index aad5d173..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderAddressType.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints\Choice; - -class ChangeOrderAddressType extends AbstractType -{ - const SHIPPING_TYPE = 'shipping'; - const INVOICE_TYPE = 'invoice'; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $customerAddressProvider; - - /** - * @param ConfigurableFormChoiceProviderInterface $customerAddressProvider - */ - public function __construct(ConfigurableFormChoiceProviderInterface $customerAddressProvider) - { - $this->customerAddressProvider = $customerAddressProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('new_address_id', ChoiceType::class, [ - 'choices' => $this->customerAddressProvider->getChoices($options), - ]) - ->add('address_type', HiddenType::class, [ - 'constraints' => [ - new Choice($this->getAvailableAddressTypes()), - ], - ] - ); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setRequired([ - 'customer_id', - ]) - ->setAllowedTypes('customer_id', 'int'); - } - - /** - * @return array - */ - public function getAvailableAddressTypes() - { - return [ - self::SHIPPING_TYPE, - self::INVOICE_TYPE, - ]; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderCurrencyType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderCurrencyType.php deleted file mode 100644 index 0854a570..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrderCurrencyType.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class ChangeOrderCurrencyType extends AbstractType -{ - /** - * @var FormChoiceProviderInterface - */ - private $currencyChoiceProvider; - - /** - * @param FormChoiceProviderInterface $currencyChoiceProvider - */ - public function __construct(FormChoiceProviderInterface $currencyChoiceProvider) - { - $this->currencyChoiceProvider = $currencyChoiceProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('new_currency_id', ChoiceType::class, [ - 'choices' => $this->getCurrencyChoices($options['current_currency_id']), - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setDefaults([ - 'current_currency_id' => null, - ]) - ->setAllowedTypes('current_currency_id', ['int', 'null']) - ; - } - - /** - * @param int|null $currentCurrencyId - * - * @return array - */ - private function getCurrencyChoices(?int $currentCurrencyId): array - { - $choices = $this->currencyChoiceProvider->getChoices(); - - if (null === $currentCurrencyId) { - return $choices; - } - - $currentCurrencyKey = array_search($currentCurrencyId, $choices, true); - - if ($currentCurrencyKey) { - unset($choices[$currentCurrencyKey]); - } - - return $choices; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrdersStatusType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrdersStatusType.php deleted file mode 100644 index 501899dc..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/ChangeOrdersStatusType.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\CallbackTransformer; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; - -class ChangeOrdersStatusType extends AbstractType -{ - /** - * @var FormChoiceProviderInterface - */ - private $orderStatusChoiceProvider; - - /** - * @param FormChoiceProviderInterface $orderStatusChoiceProvider - */ - public function __construct(FormChoiceProviderInterface $orderStatusChoiceProvider) - { - $this->orderStatusChoiceProvider = $orderStatusChoiceProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('new_order_status_id', ChoiceType::class, [ - 'choices' => $this->orderStatusChoiceProvider->getChoices(), - 'translation_domain' => false, - ]) - ->add('order_ids', CollectionType::class, [ - 'allow_add' => true, - 'entry_type' => HiddenType::class, - 'label' => false, - ]) - ; - - $builder->get('order_ids') - ->addModelTransformer(new CallbackTransformer( - static function ($orderIds) { - return $orderIds; - }, - static function (array $orderIds) { - return array_map(static function ($orderId) { - return (int) $orderId; - }, $orderIds); - } - )) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsFormDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsFormDataProvider.php deleted file mode 100644 index 115eb8fa..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsFormDataProvider.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * Provides data for credit slip options form - */ -final class CreditSlipOptionsFormDataProvider implements FormDataProviderInterface -{ - /** - * @var DataConfigurationInterface - */ - private $creditSlipOptionsConfiguration; - - /** - * @param DataConfigurationInterface $creditSlipOptionsConfiguration - */ - public function __construct(DataConfigurationInterface $creditSlipOptionsConfiguration) - { - $this->creditSlipOptionsConfiguration = $creditSlipOptionsConfiguration; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return [ - 'options' => $this->creditSlipOptionsConfiguration->getConfiguration(), - ]; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - return $this->creditSlipOptionsConfiguration->updateConfiguration($data['options']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsType.php deleted file mode 100644 index d37fac45..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/CreditSlipOptionsType.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Defines credit slips options form - */ -final class CreditSlipOptionsType extends CommonAbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('slip_prefix', TranslatableType::class, [ - 'required' => false, - 'error_bubbling' => true, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => 'file_name', - 'message' => $this->translator->trans( - '%s is invalid.', - [], - 'Admin.Notifications.Error' - ), - ]), - ], - ], - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/GeneratePdfByDateType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/GeneratePdfByDateType.php deleted file mode 100644 index fd5a4675..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/CreditSlip/GeneratePdfByDateType.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\DateTime; -use Symfony\Component\Validator\Constraints\NotBlank; -use Symfony\Component\Validator\Constraints\Valid; - -/** - * Defines form for generating Credit slip PDF - */ -final class GeneratePdfByDateType extends CommonAbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - public function __construct(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $dateFormat = 'Y-m-d'; - $nowDate = (new \DateTime())->format($dateFormat); - - $blankMessage = $this->translator->trans('This field is required', [], 'Admin.Notifications.Error'); - $invalidDateMessage = $this->translator->trans('Invalid date format.', [], 'Admin.Notifications.Error'); - - $builder - ->add('from', DatePickerType::class, [ - 'data' => $nowDate, - 'constraints' => [ - new NotBlank([ - 'message' => $blankMessage, - ]), - new DateTime([ - 'format' => $dateFormat, - 'message' => $invalidDateMessage, - ]), - ], - ]) - ->add('to', DatePickerType::class, [ - 'data' => $nowDate, - 'constraints' => [ - new NotBlank([ - 'message' => $blankMessage, - ]), - new DateTime([ - 'format' => $dateFormat, - 'message' => $invalidDateMessage, - ]), - ], - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'constraints' => [ - new Valid(), - ], - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsFormDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsFormDataProvider.php deleted file mode 100644 index 7a351989..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsFormDataProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Delivery; - -use PrestaShop\PrestaShop\Adapter\Order\Delivery\SlipOptionsConfiguration; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * This class is responsible of managing the data manipulated options form - * in "Sells > Orders > Delivery Slips" page. - */ -final class SlipOptionsFormDataProvider implements FormDataProviderInterface -{ - /** - * @var SlipOptionsConfiguration - */ - private $configuration; - - public function __construct(SlipOptionsConfiguration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return [ - 'options' => $this->configuration->getConfiguration(), - ]; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - return $this->configuration->updateConfiguration($data['options']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsType.php deleted file mode 100644 index d0f0c98f..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipOptionsType.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Delivery; - -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type as FormType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * This form class generates the "Options" form in Delivery slips page. - */ -class SlipOptionsType extends TranslatorAwareType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add( - 'prefix', - TranslatableType::class, - [ - 'type' => TextType::class, - ] - ) - ->add( - 'number', - FormType\NumberType::class - ) - ->add( - 'enable_product_image', - SwitchType::class - ); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'order_delivery_slip_options'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfFormDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfFormDataProvider.php deleted file mode 100644 index 8661900f..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfFormDataProvider.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Delivery; - -use PrestaShop\PrestaShop\Adapter\Order\Delivery\SlipPdfConfiguration; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * This class is responsible of managing the data manipulated pdf form - * in "Sells > Orders > Delivery Slips" page. - */ -final class SlipPdfFormDataProvider implements FormDataProviderInterface -{ - /** - * @var SlipPdfConfiguration - */ - private $configuration; - - public function __construct(SlipPdfConfiguration $configuration) - { - $this->configuration = $configuration; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return []; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - return $this->configuration->updateConfiguration($data['pdf']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfType.php deleted file mode 100644 index 2f5684fe..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Delivery/SlipPdfType.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Delivery; - -use DateTime; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * This form class generates the "Pdf" form in Delivery slips page. - */ -class SlipPdfType extends CommonAbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $now = (new DateTime())->format('Y-m-d'); - $builder - ->add( - 'date_from', - DatePickerType::class, - [ - 'required' => false, - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - 'data' => $now, - 'empty_data' => $now, - ] - ) - ->add( - 'date_to', - DatePickerType::class, - [ - 'required' => false, - 'attr' => ['placeholder' => 'YYYY-MM-DD'], - 'data' => $now, - 'empty_data' => $now, - ] - ); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'order_delivery_slip_options'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/EditProductRowType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/EditProductRowType.php deleted file mode 100644 index b6d124ca..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/EditProductRowType.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\TextWithUnitType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\ButtonType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; - -class EditProductRowType extends TranslatorAwareType -{ - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $orderInvoiceByIdChoiceProvider; - - /** - * @var int - */ - private $contextLangId; - - /** - * EditProductRowType constructor. - * - * @param TranslatorInterface $translator - * @param array $locales - * @param ConfigurableFormChoiceProviderInterface $orderInvoiceByIdChoiceProvider - * @param int $contextLangId - */ - public function __construct( - TranslatorInterface $translator, - array $locales, - ConfigurableFormChoiceProviderInterface $orderInvoiceByIdChoiceProvider, - int $contextLangId - ) { - parent::__construct($translator, $locales); - - $this->orderInvoiceByIdChoiceProvider = $orderInvoiceByIdChoiceProvider; - $this->contextLangId = $contextLangId; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $invoices = $options['order_id'] ? - $this->orderInvoiceByIdChoiceProvider->getChoices([ - 'id_order' => $options['order_id'], - 'id_lang' => $this->contextLangId, - 'display_total' => false, - ]) : []; - - $builder - ->add('price_tax_excluded', TextWithUnitType::class, [ - 'label' => false, - 'unit' => sprintf('%s %s', - $options['symbol'], - $this->trans('tax excl.', 'Admin.Global') - ), - 'attr' => [ - 'class' => 'editProductPriceTaxExcl', - ], - ]) - ->add('price_tax_included', TextWithUnitType::class, [ - 'label' => false, - 'unit' => sprintf('%s %s', - $options['symbol'], - $this->trans('tax incl.', 'Admin.Global') - ), - 'attr' => [ - 'class' => 'editProductPriceTaxIncl', - ], - ]) - ->add('quantity', NumberType::class, [ - 'label' => false, - 'data' => 1, - 'scale' => 0, - 'attr' => [ - 'min' => 1, - 'class' => 'editProductQuantity', - ], - ]) - ->add('invoice', ChoiceType::class, [ - 'choices' => $invoices, - 'label' => false, - 'attr' => [ - 'class' => 'editProductInvoice custom-select', - ], - ]) - ->add('cancel', ButtonType::class, [ - 'label' => $this->trans('Cancel', 'Admin.Actions'), - 'attr' => [ - 'class' => 'btn btn-sm btn-secondary js-product-edit-action-btn mr-2 mt-2 mb-2 productEditCancelBtn', - ], - ]) - ->add('save', ButtonType::class, [ - 'label' => $this->trans('Save', 'Admin.Actions'), - 'disabled' => true, - 'attr' => [ - 'class' => 'btn btn-sm btn-primary js-product-edit-action-btn mt-2 mb-2 productEditSaveBtn', - 'data-order-id' => $options['order_id'], - 'data-update-message' => $this->trans('Are you sure?', 'Admin.Notifications.Warning'), - ], - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setRequired(['symbol']) - ->setDefaults([ - 'order_id' => null, - ]) - ->setAllowedTypes('order_id', ['int', 'null']) - ->setAllowedTypes('symbol', ['string']) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByDateType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByDateType.php deleted file mode 100644 index 3dc3d757..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByDateType.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class generates "By Date" form - * in "Sell > Orders > Invoices" page. - */ -class GenerateByDateType extends CommonAbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('date_from', DatePickerType::class) - ->add('date_to', DatePickerType::class); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'translation_domain' => 'Admin.Orderscustomers.Feature', - ]); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'orders_invoices_by_date_block'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByStatusType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByStatusType.php deleted file mode 100644 index 785e10dd..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/GenerateByStatusType.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\CommonAbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class generates "By order status" form - * in "Sell > Orders > Invoices" page. - */ -class GenerateByStatusType extends CommonAbstractType -{ - /** - * @var array - */ - private $orderCountsByState; - /** - * @var FormChoiceProviderInterface - */ - private $orderStateChoiceProvider; - - /** - * @param FormChoiceProviderInterface $orderStateChoiceProvider - * @param array $orderCountsByState - */ - public function __construct(FormChoiceProviderInterface $orderStateChoiceProvider, array $orderCountsByState) - { - $this->orderCountsByState = $orderCountsByState; - $this->orderStateChoiceProvider = $orderStateChoiceProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('order_states', ChoiceType::class, [ - 'expanded' => true, - 'multiple' => true, - 'choices' => $this->orderStateChoiceProvider->getChoices(), - ]); - } - - /** - * {@inheritdoc} - */ - public function finishView(FormView $view, FormInterface $form, array $options) - { - /** @var FormView $child */ - foreach ($view->children['order_states'] as $child) { - $child->vars['orders_count'] = 0; - - if (array_key_exists($child->vars['value'], $this->orderCountsByState)) { - $child->vars['orders_count'] = $this->orderCountsByState[$child->vars['value']]; - } - } - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'translation_domain' => 'Admin.Orderscustomers.Feature', - ]); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'orders_invoices_by_status_block'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByDateFormHandler.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByDateFormHandler.php deleted file mode 100644 index 8a2d77a6..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByDateFormHandler.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use DateTime; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormHandler; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Order\OrderInvoiceDataProviderInterface; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Class InvoiceByDateFormHandler manages the data manipulated using "By date" form - * in "Sell > Orders > Invoices" page. - */ -final class InvoiceByDateFormHandler extends FormHandler -{ - /** - * @var OrderInvoiceDataProviderInterface - */ - private $orderInvoiceDataProvider; - - /** - * @var PDFGeneratorInterface - */ - private $pdfGenerator; - - /** - * @param FormBuilderInterface $formBuilder - * @param HookDispatcherInterface $hookDispatcher - * @param FormDataProviderInterface $formDataProvider - * @param array $formTypes - * @param string $hookName - * @param OrderInvoiceDataProviderInterface $orderInvoiceDataProvider - * @param PDFGeneratorInterface $pdfGenerator - */ - public function __construct( - FormBuilderInterface $formBuilder, - HookDispatcherInterface $hookDispatcher, - FormDataProviderInterface $formDataProvider, - array $formTypes, - $hookName, - OrderInvoiceDataProviderInterface $orderInvoiceDataProvider, - PDFGeneratorInterface $pdfGenerator - ) { - parent::__construct($formBuilder, $hookDispatcher, $formDataProvider, $formTypes, $hookName); - $this->orderInvoiceDataProvider = $orderInvoiceDataProvider; - $this->pdfGenerator = $pdfGenerator; - } - - /** - * {@inheritdoc} - */ - public function save(array $data) - { - if ($errors = parent::save($data)) { - return $errors; - } - - // Get invoices by submitted date interval - $invoiceCollection = $this->orderInvoiceDataProvider->getByDateInterval( - new DateTime($data['generate_by_date']['date_from']), - new DateTime($data['generate_by_date']['date_to']) - ); - - // Generate PDF out of found invoices - $this->pdfGenerator->generatePDF($invoiceCollection); - - return []; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByStatusFormHandler.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByStatusFormHandler.php deleted file mode 100644 index 89ff1a0b..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceByStatusFormHandler.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormHandler; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; -use PrestaShop\PrestaShop\Core\Order\OrderInvoiceDataProviderInterface; -use PrestaShop\PrestaShop\Core\PDF\PDFGeneratorInterface; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * Class InvoiceByStatusFormHandler manages the data manipulated using "By status" form - * in "Sell > Orders > Invoices" page. - */ -final class InvoiceByStatusFormHandler extends FormHandler -{ - /** - * @var OrderInvoiceDataProviderInterface - */ - private $orderInvoiceDataProvider; - - /** - * @var PDFGeneratorInterface - */ - private $pdfGenerator; - - /** - * @param FormBuilderInterface $formBuilder - * @param HookDispatcherInterface $hookDispatcher - * @param FormDataProviderInterface $formDataProvider - * @param array $formTypes - * @param string $hookName - * @param OrderInvoiceDataProviderInterface $orderInvoiceDataProvider - * @param PDFGeneratorInterface $pdfGenerator - */ - public function __construct( - FormBuilderInterface $formBuilder, - HookDispatcherInterface $hookDispatcher, - FormDataProviderInterface $formDataProvider, - array $formTypes, - $hookName, - OrderInvoiceDataProviderInterface $orderInvoiceDataProvider, - PDFGeneratorInterface $pdfGenerator - ) { - parent::__construct($formBuilder, $hookDispatcher, $formDataProvider, $formTypes, $hookName); - $this->orderInvoiceDataProvider = $orderInvoiceDataProvider; - $this->pdfGenerator = $pdfGenerator; - } - - /** - * {@inheritdoc} - */ - public function save(array $data) - { - if ($errors = parent::save($data)) { - return $errors; - } - - $invoiceCollection = []; - - foreach ($data['generate_by_status']['order_states'] as $orderStateId) { - // Put invoices for each selected status into one collection - $invoiceCollection = array_merge( - $invoiceCollection, - $this->orderInvoiceDataProvider->getByStatus($orderStateId) - ); - } - - if (empty($invoiceCollection)) { - $errors[] = [ - 'key' => 'No invoice has been found for this status.', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } else { - // Generate PDF out of found invoices - $this->pdfGenerator->generatePDF($invoiceCollection); - } - - return $errors; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsDataProvider.php deleted file mode 100644 index 34b7a15b..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsDataProvider.php +++ /dev/null @@ -1,104 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * Class is responsible of managing the data manipulated using invoice options form - * in "Sell > Orders > Invoices" page. - */ -final class InvoiceOptionsDataProvider implements FormDataProviderInterface -{ - /** - * @var DataConfigurationInterface - */ - private $invoiceOptionsConfiguration; - - /** - * @var int - */ - private $nextInvoiceNumber; - - /** - * @param DataConfigurationInterface $invoiceOptionsConfiguration - * @param int $nextInvoiceNumber next available invoice number - */ - public function __construct( - DataConfigurationInterface $invoiceOptionsConfiguration, - $nextInvoiceNumber - ) { - $this->invoiceOptionsConfiguration = $invoiceOptionsConfiguration; - $this->nextInvoiceNumber = $nextInvoiceNumber; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - return [ - 'invoice_options' => $this->invoiceOptionsConfiguration->getConfiguration(), - ]; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - if ($errors = $this->validate($data)) { - return $errors; - } - - return $this->invoiceOptionsConfiguration->updateConfiguration($data['invoice_options']); - } - - /** - * Perform validations on form data. - * - * @param array $data - * - * @return array Array of errors if any - */ - private function validate(array $data) - { - $errors = []; - $invoiceNumber = $data['invoice_options']['invoice_number']; - - if ($invoiceNumber > 0 && $invoiceNumber <= $this->nextInvoiceNumber) { - $errors[] = [ - 'key' => 'Invalid invoice number.', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - - return $errors; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsType.php deleted file mode 100644 index 7e0b2454..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoiceOptionsType.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Class InvoiceOptionsType generates "Invoice options" form - * in "Sell > Orders > Invoices" page. - */ -class InvoiceOptionsType extends TranslatorAwareType -{ - /** - * @var FormChoiceProviderInterface - */ - private $invoiceModelChoiceProvider; - - /** - * @var int the next available invoice number - */ - private $nextInvoiceNumber; - - /** - * @param TranslatorInterface $translator - * @param array $locales - * @param FormChoiceProviderInterface $invoiceModelChoiceProvider - * @param int $nextInvoiceNumber the next available invoice number - */ - public function __construct( - TranslatorInterface $translator, - array $locales, - FormChoiceProviderInterface $invoiceModelChoiceProvider, - $nextInvoiceNumber - ) { - parent::__construct($translator, $locales); - $this->invoiceModelChoiceProvider = $invoiceModelChoiceProvider; - $this->nextInvoiceNumber = $nextInvoiceNumber; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('enable_invoices', SwitchType::class) - ->add('enable_tax_breakdown', SwitchType::class) - ->add('enable_product_images', SwitchType::class) - ->add('invoice_prefix', TranslatableType::class, [ - 'type' => TextType::class, - ]) - ->add('add_current_year', SwitchType::class) - ->add('reset_number_annually', SwitchType::class) - ->add('year_position', ChoiceType::class, [ - 'choices' => [ - $this->trans('After the sequential number', 'Admin.Orderscustomers.Feature') => 0, - $this->trans('Before the sequential number', 'Admin.Orderscustomers.Feature') => 1, - ], - 'expanded' => true, - ]) - ->add('invoice_number', NumberType::class, [ - 'required' => false, - ]) - ->add('legal_free_text', TranslatableType::class, [ - 'type' => TextareaType::class, - ]) - ->add('footer_text', TranslatableType::class, [ - 'type' => TextType::class, - ]) - ->add('invoice_model', ChoiceType::class, [ - 'choices' => $this->invoiceModelChoiceProvider->getChoices(), - 'translation_domain' => false, - ]) - ->add('use_disk_cache', SwitchType::class); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['next_invoice_number'] = $this->nextInvoiceNumber; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'translation_domain' => 'Admin.Orderscustomers.Feature', - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByDateDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByDateDataProvider.php deleted file mode 100644 index 7155bbb6..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByDateDataProvider.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use DateTime; -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; -use PrestaShop\PrestaShop\Core\Order\OrderInvoiceDataProviderInterface; - -/** - * Class is responsible of managing the data manipulated using invoice generation by date form - * in "Sell > Orders > Invoices" page. - */ -final class InvoicesByDateDataProvider implements FormDataProviderInterface -{ - /** - * @var OrderInvoiceDataProviderInterface - */ - private $orderInvoiceDataProvider; - - public function __construct(OrderInvoiceDataProviderInterface $orderInvoiceDataProvider) - { - $this->orderInvoiceDataProvider = $orderInvoiceDataProvider; - } - - /** - * {@inheritdoc} - */ - public function getData() - { - $date = (new DateTime())->format('Y-m-d'); - - return [ - 'generate_by_date' => [ - 'date_from' => $date, - 'date_to' => $date, - ], - ]; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - // This form doesn't need to save any data, so it only validates the data - return $this->validate($data); - } - - /** - * Perform validations on form data. - * - * @param array $data - * - * @return array Array of errors if any - */ - private function validate(array $data) - { - $errors = []; - - $dateFrom = date_create($data['generate_by_date']['date_from']); - $dateTo = date_create($data['generate_by_date']['date_to']); - - if (false === $dateFrom) { - $errors[] = [ - 'key' => 'Invalid "From" date', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - - if (false === $dateTo) { - $errors[] = [ - 'key' => 'Invalid "To" date', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - - if (empty($errors) && !$this->orderInvoiceDataProvider->getByDateInterval($dateFrom, $dateTo)) { - $errors[] = [ - 'key' => 'No invoice has been found for this period.', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - - return $errors; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByStatusDataProvider.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByStatusDataProvider.php deleted file mode 100644 index d0101cba..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/Invoices/InvoicesByStatusDataProvider.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order\Invoices; - -use PrestaShop\PrestaShop\Core\Form\FormDataProviderInterface; - -/** - * Class is responsible of managing the data manipulated using invoice generation by order status form - * in "Sell > Orders > Invoices" page. - */ -final class InvoicesByStatusDataProvider implements FormDataProviderInterface -{ - /** - * {@inheritdoc} - */ - public function getData() - { - return []; - } - - /** - * {@inheritdoc} - */ - public function setData(array $data) - { - // This form doesn't need to save any data, so it only validates the data - return $this->validate($data); - } - - /** - * Perform validations on form data. - * - * @param array $data - * - * @return array Array of errors if any - */ - private function validate(array $data) - { - $errors = []; - $orderStates = $data['generate_by_status']['order_states']; - - if (!is_array($orderStates) || !count($orderStates)) { - $errors[] = [ - 'key' => 'You must select at least one order status.', - 'domain' => 'Admin.Orderscustomers.Notification', - 'parameters' => [], - ]; - } - - return $errors; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderMessageType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderMessageType.php deleted file mode 100644 index 9d449767..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderMessageType.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\Domain\OrderMessage\OrderMessageConstraint; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\TextWithLengthCounterType; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; - -/** - * Helps to render messages block in orders view page. - */ -class OrderMessageType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * @var FormChoiceProviderInterface - */ - private $orderMessageNameChoiceProvider; - - /** - * @var FormChoiceProviderInterface - */ - private $orderMessageChoiceProvider; - - public function __construct( - FormChoiceProviderInterface $orderMessageNameChoiceProvider, - FormChoiceProviderInterface $orderMessageChoiceProvider - ) { - $this->orderMessageNameChoiceProvider = $orderMessageNameChoiceProvider; - $this->orderMessageChoiceProvider = $orderMessageChoiceProvider; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('order_message', ChoiceType::class, [ - 'choices' => $this->orderMessageNameChoiceProvider->getChoices(), - 'required' => false, - ]) - ->add('is_displayed_to_customer', CheckboxType::class, [ - 'required' => false, - 'label' => $this->trans('Display to customer?', [], 'Admin.Orderscustomers.Feature'), - ]) - ->add('message', TextWithLengthCounterType::class, [ - 'input' => 'textarea', - 'max_length' => OrderMessageConstraint::MAX_MESSAGE_LENGTH, - 'position' => 'after', - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', [], 'Admin.Notifications.Error' - ), - ]), - new CleanHtml([ - 'message' => $this->trans( - 'The %s field is not valid', - [ - sprintf('"%s"', $this->trans('Message', [], 'Admin.Global')), - ], - 'Admin.Notifications.Error' - ), - ] - ), - new Length([ - 'max' => OrderMessageConstraint::MAX_MESSAGE_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => OrderMessageConstraint::MAX_MESSAGE_LENGTH], - 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ; - } - - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['messages'] = $this->orderMessageChoiceProvider->getChoices(); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderPaymentType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderPaymentType.php deleted file mode 100644 index 729a8451..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/OrderPaymentType.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\DatePickerType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\GreaterThan; - -class OrderPaymentType extends AbstractType -{ - /** - * @var TranslatorInterface - */ - private $translator; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $currencySymbolByIdChoiceProvider; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $orderInvoiceChoiceProvider; - - /** - * @var int - */ - private $contextLanguageId; - - /** - * @var int - */ - private $contextShopId; - - /** - * @var FormChoiceProviderInterface - */ - private $installedPaymentModulesChoiceProvider; - - /** - * @param ConfigurableFormChoiceProviderInterface $currencySymbolByIdChoiceProvider - * @param ConfigurableFormChoiceProviderInterface $orderInvoiceChoiceProvider - * @param FormChoiceProviderInterface $installedPaymentModulesChoiceProvider - * @param int $contextLanguageId - * @param int $contextShopId - */ - public function __construct( - TranslatorInterface $translator, - ConfigurableFormChoiceProviderInterface $currencySymbolByIdChoiceProvider, - ConfigurableFormChoiceProviderInterface $orderInvoiceChoiceProvider, - FormChoiceProviderInterface $installedPaymentModulesChoiceProvider, - int $contextLanguageId, - int $contextShopId - ) { - $this->translator = $translator; - $this->currencySymbolByIdChoiceProvider = $currencySymbolByIdChoiceProvider; - $this->orderInvoiceChoiceProvider = $orderInvoiceChoiceProvider; - $this->contextLanguageId = $contextLanguageId; - $this->contextShopId = $contextShopId; - $this->installedPaymentModulesChoiceProvider = $installedPaymentModulesChoiceProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('date', DatePickerType::class, [ - 'date_format' => 'YYYY-MM-DD H:m:s', - ]) - ->add('payment_method', TextType::class, [ - 'data_list' => $this->installedPaymentModulesChoiceProvider->getChoices(), - ]) - ->add('transaction_id', TextType::class, [ - 'required' => false, - ]) - ->add('amount', TextType::class, [ - 'constraints' => [ - new GreaterThan([ - 'value' => 0, - 'message' => $this->translator->trans( - 'Invalid value: the payment must be a positive amount.', [], 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_currency', ChoiceType::class, [ - 'choices' => $this->currencySymbolByIdChoiceProvider->getChoices([ - 'id_shop' => $this->contextShopId, - ]), - ]) - ->add('id_invoice', ChoiceType::class, [ - 'choices' => $this->orderInvoiceChoiceProvider->getChoices([ - 'id_order' => $options['id_order'], - 'id_lang' => $this->contextLanguageId, - ]), - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setRequired([ - 'id_order', - ]) - ->setAllowedTypes('id_order', 'int') - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderShippingType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderShippingType.php deleted file mode 100644 index 3d8a1517..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderShippingType.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class UpdateOrderShippingType extends AbstractType -{ - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $carrierForOrderChoiceProvider; - - /** - * @param ConfigurableFormChoiceProviderInterface $carrierForOrderChoiceProvider - */ - public function __construct(ConfigurableFormChoiceProviderInterface $carrierForOrderChoiceProvider) - { - $this->carrierForOrderChoiceProvider = $carrierForOrderChoiceProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder - ->add('new_carrier_id', ChoiceType::class, [ - 'choices' => $this->carrierForOrderChoiceProvider->getChoices([ - 'order_id' => $options['order_id'], - ]), - ]) - ->add('current_order_carrier_id', HiddenType::class) - ->add('tracking_number', TextType::class, [ - 'required' => false, - ]) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setRequired([ - 'order_id', - ]) - ->setAllowedTypes('order_id', 'int') - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderStatusType.php b/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderStatusType.php deleted file mode 100644 index 481224f3..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Order/UpdateOrderStatusType.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Order; - -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; - -class UpdateOrderStatusType extends AbstractType -{ - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $statusChoiceProvider; - - /** - * @var array - */ - private $statusChoiceAttributes; - - /** - * @param ConfigurableFormChoiceProviderInterface $statusChoices - * @param array $statusChoiceAttributes - */ - public function __construct( - ConfigurableFormChoiceProviderInterface $statusChoiceProvider, - array $statusChoiceAttributes - ) { - $this->statusChoiceProvider = $statusChoiceProvider; - $this->statusChoiceAttributes = $statusChoiceAttributes; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $choiceProviderParams = []; - if (!empty($options['data']['new_order_status_id'])) { - $choiceProviderParams = ['current_state' => $options['data']['new_order_status_id']]; - } - $builder - ->add('new_order_status_id', ChoiceType::class, [ - 'required' => false, - 'placeholder' => false, - 'choices' => $this->statusChoiceProvider->getChoices($choiceProviderParams), - 'choice_attr' => $this->statusChoiceAttributes, - 'translation_domain' => false, - ]) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Sell/Supplier/SupplierType.php b/src/PrestaShopBundle/Form/Admin/Sell/Supplier/SupplierType.php deleted file mode 100644 index 10e5ff41..00000000 --- a/src/PrestaShopBundle/Form/Admin/Sell/Supplier/SupplierType.php +++ /dev/null @@ -1,376 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Sell\Supplier; - -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressDniRequired; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\AddressStateRequired; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\CleanHtml; -use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex; -use PrestaShop\PrestaShop\Core\Domain\Address\AddressSettings; -use PrestaShop\PrestaShop\Core\Domain\Supplier\SupplierSettings; -use PrestaShop\PrestaShop\Core\Form\ConfigurableFormChoiceProviderInterface; -use PrestaShopBundle\Form\Admin\Type\CountryChoiceType; -use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType; -use PrestaShopBundle\Form\Admin\Type\ShopChoiceTreeType; -use PrestaShopBundle\Form\Admin\Type\SwitchType; -use PrestaShopBundle\Form\Admin\Type\TranslatableType; -use PrestaShopBundle\Form\Admin\Type\TranslateType; -use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\FileType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Translation\TranslatorInterface; -use Symfony\Component\Validator\Constraints\Length; -use Symfony\Component\Validator\Constraints\NotBlank; - -/** - * Defines form for supplier create/edit actions (Sell > Catalog > Brands & Suppliers > Supplier) - */ -class SupplierType extends TranslatorAwareType -{ - /** - * @var array - */ - private $countryChoices; - - /** - * @var array - */ - private $countryChoicesAttributes; - - /** - * @var ConfigurableFormChoiceProviderInterface - */ - private $statesChoiceProvider; - - /** - * @var int - */ - private $contextCountryId; - - /** - * @var bool - */ - private $isMultistoreEnabled; - - /** - * @param array $countryChoices - * @param ConfigurableFormChoiceProviderInterface $statesChoiceProvider - * @param $contextCountryId - * @param TranslatorInterface $translator - * @param $isMultistoreEnabled - * @param array $locales - */ - public function __construct( - array $countryChoices, - array $countryChoicesAttributes, - ConfigurableFormChoiceProviderInterface $statesChoiceProvider, - $contextCountryId, - TranslatorInterface $translator, - $isMultistoreEnabled, - array $locales = [] - ) { - parent::__construct($translator, $locales); - - $this->countryChoices = $countryChoices; - $this->countryChoicesAttributes = $countryChoicesAttributes; - $this->statesChoiceProvider = $statesChoiceProvider; - $this->contextCountryId = $contextCountryId; - $this->isMultistoreEnabled = $isMultistoreEnabled; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $data = $builder->getData(); - $countryId = 0 !== $data['id_country'] ? $data['id_country'] : $this->contextCountryId; - $stateChoices = $this->statesChoiceProvider->getChoices(['id_country' => $countryId]); - - $builder - ->add('name', TextType::class, [ - 'empty_data' => '', - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - new Length([ - 'max' => SupplierSettings::MAX_NAME_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => SupplierSettings::MAX_NAME_LENGTH] - ), - ]), - new TypedRegex([ - 'type' => TypedRegex::TYPE_CATALOG_NAME, - ]), - ], - ]) - ->add('description', TranslateType::class, [ - 'required' => false, - 'type' => FormattedTextareaType::class, - 'locales' => $this->locales, - 'hideTabs' => false, - 'options' => [ - 'constraints' => [ - new CleanHtml([ - 'message' => $this->trans( - '%s is invalid.', - 'Admin.Notifications.Error' - ), - ]), - ], - ], - ]) - ->add('phone', TextType::class, [ - 'empty_data' => '', - 'required' => false, - 'constraints' => $this->getPhoneCommonConstraints(), - ]) - ->add('mobile_phone', TextType::class, [ - 'empty_data' => '', - 'required' => false, - 'constraints' => $this->getPhoneCommonConstraints(), - ]) - ->add('address', TextType::class, [ - 'empty_data' => '', - 'constraints' => $this->getAddressCommonConstraints(), - ]) - ->add('address2', TextType::class, [ - 'empty_data' => '', - 'required' => false, - 'constraints' => $this->getAddressCommonConstraints(), - ]) - ->add('post_code', TextType::class, [ - 'empty_data' => '', - 'required' => false, - 'constraints' => [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_POST_CODE, - ]), - new Length([ - 'max' => AddressSettings::MAX_POST_CODE_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => AddressSettings::MAX_POST_CODE_LENGTH] - ), - ]), - ], - ]) - ->add('city', TextType::class, [ - 'empty_data' => '', - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - new TypedRegex([ - 'type' => TypedRegex::TYPE_CITY_NAME, - ]), - new Length([ - 'max' => AddressSettings::MAX_CITY_NAME_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => AddressSettings::MAX_CITY_NAME_LENGTH] - ), - ]), - ], - ]) - ->add('id_country', CountryChoiceType::class, [ - 'required' => true, - 'with_dni_attr' => true, - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - ], - ]) - ->add('id_state', ChoiceType::class, [ - 'required' => true, - 'choices' => $stateChoices, - 'constraints' => [ - new AddressStateRequired([ - 'id_country' => $countryId, - ]), - ], - ]) - ->add('dni', TextType::class, [ - 'required' => false, - 'empty_data' => '', - 'constraints' => [ - new AddressDniRequired([ - 'required' => false, - 'id_country' => $countryId, - ]), - new TypedRegex([ - 'type' => 'dni_lite', - ]), - new Length([ - 'max' => 16, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => 16] - ), - ]), - ], - ]) - ->add('logo', FileType::class, [ - 'required' => false, - ]) - ->add('meta_title', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => false, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => SupplierSettings::MAX_META_TITLE_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => SupplierSettings::MAX_META_TITLE_LENGTH] - ), - ]), - ], - ], - ]) - ->add('meta_description', TranslatableType::class, [ - 'type' => TextareaType::class, - 'required' => false, - 'options' => [ - 'constraints' => [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => SupplierSettings::MAX_META_DESCRIPTION_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => SupplierSettings::MAX_META_DESCRIPTION_LENGTH] - ), - ]), - ], - ], - ]) - ->add('meta_keyword', TranslatableType::class, [ - 'type' => TextType::class, - 'required' => false, - 'options' => [ - 'attr' => [ - 'class' => 'js-taggable-field', - 'placeholder' => $this->trans('Add tag', 'Admin.Actions'), - ], - 'constraints' => [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_GENERIC_NAME, - ]), - new Length([ - 'max' => SupplierSettings::MAX_META_KEYWORD_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => SupplierSettings::MAX_META_KEYWORD_LENGTH] - ), - ]), - ], - ], - ]) - ->add('is_enabled', SwitchType::class, [ - 'required' => false, - ]) - ; - - if ($this->isMultistoreEnabled) { - $builder->add('shop_association', ShopChoiceTreeType::class, [ - 'required' => false, - 'constraints' => [ - new NotBlank([ - 'message' => $this->trans( - 'This field cannot be empty', 'Admin.Notifications.Error' - ), - ]), - ], - ]); - } - } - - /** - * Provides reusable address constraints - * - * @return array - */ - private function getAddressCommonConstraints() - { - return [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_ADDRESS, - ]), - new Length([ - 'max' => AddressSettings::MAX_ADDRESS_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => AddressSettings::MAX_ADDRESS_LENGTH] - ), - ]), - ]; - } - - /** - * Provides reusable phone constraints - * - * @return array - */ - private function getPhoneCommonConstraints() - { - return [ - new TypedRegex([ - 'type' => TypedRegex::TYPE_PHONE_NUMBER, - ]), - new Length([ - 'max' => AddressSettings::MAX_PHONE_LENGTH, - 'maxMessage' => $this->trans( - 'This field cannot be longer than %limit% characters', - 'Admin.Notifications.Error', - ['%limit%' => AddressSettings::MAX_PHONE_LENGTH] - ), - ]), - ]; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/AddonsConnectType.php b/src/PrestaShopBundle/Form/Admin/Type/AddonsConnectType.php deleted file mode 100644 index fcd810f2..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/AddonsConnectType.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ButtonType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; - -/** - * Class AddonsConnectType defines addons connection form type. - * When not connected to addons, it shows a button to sign in. - * When connected to addons it shows the connected email and sign out button. - */ -class AddonsConnectType extends AbstractType -{ - /** - * @var bool - */ - private $isAddonsConnected; - - /** - * @var string - */ - private $addonsUsername; - - /** - * @param bool $isAddonsConnected - * @param string $addonsUsername - */ - public function __construct($isAddonsConnected, $addonsUsername) - { - $this->isAddonsConnected = $isAddonsConnected; - $this->addonsUsername = $addonsUsername; - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['is_addons_connected'] = $this->isAddonsConnected; - $view->vars['addons_username'] = $this->addonsUsername; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ButtonType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/CategoryChoiceTreeType.php b/src/PrestaShopBundle/Form/Admin/Type/CategoryChoiceTreeType.php deleted file mode 100644 index 5e0a836d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/CategoryChoiceTreeType.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTreeType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class CategoryChoiceTreeType. - */ -class CategoryChoiceTreeType extends AbstractType -{ - /** - * @var array - */ - private $categoryTreeChoices; - - /** - * @param array $categoryTreeChoices - */ - public function __construct(array $categoryTreeChoices) - { - $this->categoryTreeChoices = $categoryTreeChoices; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices_tree' => $this->categoryTreeChoices, - 'choice_label' => 'name', - 'choice_value' => 'id_category', - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return MaterialChoiceTreeType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ChangePasswordType.php b/src/PrestaShopBundle/Form/Admin/Type/ChangePasswordType.php deleted file mode 100644 index 0b62797d..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ChangePasswordType.php +++ /dev/null @@ -1,145 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShop\PrestaShop\Core\Domain\Employee\ValueObject\Password; -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ButtonType; -use Symfony\Component\Form\Extension\Core\Type\PasswordType; -use Symfony\Component\Form\Extension\Core\Type\RepeatedType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Validator\Constraints\Length; - -/** - * Class ChangePasswordType is responsible for defining "change password" form type. - */ -class ChangePasswordType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('change_password_button', ButtonType::class, [ - 'label' => false, - ]) - ->add('old_password', PasswordType::class) - ->add('new_password', RepeatedType::class, [ - 'type' => PasswordType::class, - 'constraints' => [ - $this->getLengthConstraint(Password::MAX_LENGTH, Password::MIN_LENGTH), - ], - 'first_options' => [ - 'attr' => [ - 'data-password-too-short' => $this->getMinLengthValidationMessage(Password::MIN_LENGTH), - 'data-password-too-long' => $this->getMaxLengthValidationMessage(Password::MAX_LENGTH), - ], - ], - 'second_options' => [ - 'attr' => [ - 'data-invalid-password' => $this->trans( - 'Invalid password confirmation', - [], - 'Admin.Notifications.Error' - ), - ], - ], - ]) - ->add('generated_password', TextType::class, [ - 'label' => false, - 'disabled' => true, - ]) - ->add('generate_password_button', ButtonType::class) - ->add('cancel_button', ButtonType::class) - ; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'required' => false, - ]); - } - - /** - * @param int $maxLength - * @param int|null $minLength - * - * @return Length - */ - private function getLengthConstraint($maxLength, $minLength = null) - { - $options = [ - 'max' => $maxLength, - 'maxMessage' => $this->getMaxLengthValidationMessage($maxLength), - ]; - - if (null !== $minLength) { - $options['min'] = $minLength; - $options['minMessage'] = $this->getMinLengthValidationMessage($minLength); - } - - return new Length($options); - } - - /** - * @param int $minLength - * - * @return string - */ - private function getMinLengthValidationMessage($minLength) - { - return $this->trans( - 'This field cannot be shorter than %limit% characters', - ['%limit%' => $minLength], - 'Admin.Notifications.Error' - ); - } - - /** - * @param int $maxLength - * - * @return string - */ - private function getMaxLengthValidationMessage($maxLength) - { - return $this->trans( - 'This field cannot be longer than %limit% characters', - ['%limit%' => $maxLength], - 'Admin.Notifications.Error' - ); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ChoiceCategoriesTreeType.php b/src/PrestaShopBundle/Form/Admin/Type/ChoiceCategoriesTreeType.php deleted file mode 100644 index 35d36b22..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ChoiceCategoriesTreeType.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to create a category selector using Nested sets. - */ -class ChoiceCategoriesTreeType extends CommonAbstractType -{ - /** - * {@inheritdoc} - * - * Add the var choices to the view - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['choices'] = $options['list']; - $view->vars['multiple'] = $options['multiple']; - $view->vars['expanded'] = $options['expanded']; - - //if form is submitted, inject categories values array to check or not each field - if (!empty($view->vars['value']) && !empty($view->vars['value']['tree'])) { - $view->vars['submitted_values'] = array_flip($view->vars['value']['tree']); - } - } - - /** - * {@inheritdoc} - * - * Builds the form. - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('tree', ChoiceType::class, [ - 'label' => false, - 'choices' => $options['valid_list'], - 'required' => false, - 'multiple' => true, - 'expanded' => true, - 'error_bubbling' => true, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'label' => '', - 'list' => [], - 'valid_list' => [], - 'multiple' => true, - 'expanded' => true, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'choice_tree'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/Common/Team/ProfileChoiceType.php b/src/PrestaShopBundle/Form/Admin/Type/Common/Team/ProfileChoiceType.php deleted file mode 100644 index 0b0ffaad..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/Common/Team/ProfileChoiceType.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type\Common\Team; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ProfileChoiceType is choice type for selecting employee's profile. - */ -class ProfileChoiceType extends AbstractType -{ - /** - * @var array - */ - private $profileChoices; - - /** - * @param array $profileChoices - */ - public function __construct(array $profileChoices) - { - $this->profileChoices = $profileChoices; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'choices' => $this->profileChoices, - 'translation_domain' => false, - 'expanded' => false, - 'multiple' => false, - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/CommonAbstractType.php b/src/PrestaShopBundle/Form/Admin/Type/CommonAbstractType.php deleted file mode 100644 index 5a4f2d41..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/CommonAbstractType.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShop\PrestaShop\Adapter\Configuration; -use Symfony\Component\Form\AbstractType; - -/** - * This subclass contains common functions for specific Form types needs. - */ -abstract class CommonAbstractType extends AbstractType -{ - const PRESTASHOP_DECIMALS = 6; - - /** - * Get the configuration adapter. - * - * @return object Configuration adapter - */ - protected function getConfiguration() - { - return new Configuration(); - } - - /** - * Format legacy data list to mapping SF2 form field choice. - * - * @param array $list - * @param string $mapping_value - * @param string $mapping_name - * - * @return array - */ - protected function formatDataChoicesList($list, $mapping_value = 'id', $mapping_name = 'name') - { - $new_list = []; - foreach ($list as $item) { - if (array_key_exists($item[$mapping_name], $new_list)) { - return $this->formatDataDuplicateChoicesList($list, $mapping_value, $mapping_name); - } else { - $new_list[$item[$mapping_name]] = $item[$mapping_value]; - } - } - - return $new_list; - } - - /** - * Format legacy data list to mapping SF2 form field choice (possibility to have 2 name equals). - * - * @param array $list - * @param string $mapping_value - * @param string $mapping_name - * - * @return array - */ - protected function formatDataDuplicateChoicesList($list, $mapping_value = 'id', $mapping_name = 'name') - { - $new_list = []; - foreach ($list as $item) { - $new_list[$item[$mapping_value] . ' - ' . $item[$mapping_name]] = $item[$mapping_value]; - } - - return $new_list; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/CountryChoiceType.php b/src/PrestaShopBundle/Form/Admin/Type/CountryChoiceType.php deleted file mode 100644 index 121168f9..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/CountryChoiceType.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShop\PrestaShop\Core\Form\FormChoiceAttributeProviderInterface; -use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class CountryChoiceType is responsible for providing country choices with -- symbol in front of array. - */ -class CountryChoiceType extends AbstractType -{ - /** - * @var FormChoiceProviderInterface - */ - private $countriesChoiceProvider; - - /** - * @var FormChoiceAttributeProviderInterface - */ - private $countriesAttrChoicesProvider; - - /** - * @var array - */ - private $countriesAttr = []; - - /** - * @var bool - */ - private $needDni = false; - - /** - * @var bool - */ - private $needPostcode = false; - - /** - * @param FormChoiceProviderInterface $countriesChoiceProvider - */ - public function __construct(FormChoiceProviderInterface $countriesChoiceProvider, FormChoiceAttributeProviderInterface $countriesAttrChoicesProvider) - { - $this->countriesChoiceProvider = $countriesChoiceProvider; - $this->countriesAttrChoicesProvider = $countriesAttrChoicesProvider; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - if ($options['with_dni_attr'] || $options['with_postcode_attr']) { - $this->needDni = $options['with_dni_attr']; - $this->needPostcode = $options['with_postcode_attr']; - $this->countriesAttr = $this->countriesAttrChoicesProvider->getChoicesAttributes(); - } - parent::buildForm($builder, $options); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $choices = array_merge( - ['--' => ''], - $this->countriesChoiceProvider->getChoices() - ); - - $resolver->setDefaults([ - 'choices' => $choices, - 'choice_attr' => [$this, 'getChoiceAttr'], - 'with_dni_attr' => false, - 'with_postcode_attr' => false, - ]); - - $resolver - ->setAllowedTypes('with_dni_attr', 'boolean') - ->setAllowedTypes('with_postcode_attr', 'boolean'); - } - - public function getChoiceAttr($value, $key) - { - $attr = []; - if ($this->needDni && isset($this->countriesAttr[$key], $this->countriesAttr[$key]['need_dni'])) { - $attr['need_dni'] = 1; - } - if ($this->needPostcode && isset($this->countriesAttr[$key], $this->countriesAttr[$key]['need_postcode'])) { - $attr['need_postcode'] = 1; - } - - return $attr; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/CustomContentType.php b/src/PrestaShopBundle/Form/Admin/Type/CustomContentType.php deleted file mode 100644 index 43be8e3c..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/CustomContentType.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Type is used to add any content in any position of the form rather than actual field. - */ -final class CustomContentType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['data'] = $options['data']; - $view->vars['template'] = $options['template']; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'template', - ]) - ->setDefaults([ - 'required' => false, - 'data' => [], - ]) - ->setAllowedTypes('template', 'string') - ->setAllowedTypes('data', 'array') - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/CustomMoneyType.php b/src/PrestaShopBundle/Form/Admin/Type/CustomMoneyType.php deleted file mode 100644 index 9872d672..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/CustomMoneyType.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class CustomMoneyType extends AbstractTypeExtension -{ - const PRESTASHOP_DECIMALS = 6; - - public function getExtendedType() - { - return 'Symfony\Component\Form\Extension\Core\Type\MoneyType'; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'precision' => null, - 'scale' => self::PRESTASHOP_DECIMALS, - 'grouping' => false, - 'divisor' => 1, - 'currency' => 'EUR', - 'compound' => false, - ]); - - $resolver->setAllowedTypes('scale', 'int'); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/DatePickerType.php b/src/PrestaShopBundle/Form/Admin/Type/DatePickerType.php deleted file mode 100644 index 19f22731..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/DatePickerType.php +++ /dev/null @@ -1,95 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to create a date picker field. - */ -class DatePickerType extends AbstractType -{ - /** - * @var DataTransformerInterface - */ - private $arabicToLatinDigitDataTransformer; - - public function __construct(DataTransformerInterface $arabicToLatinDigitDataTransformer) - { - $this->arabicToLatinDigitDataTransformer = $arabicToLatinDigitDataTransformer; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return TextType::class; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->addViewTransformer($this->arabicToLatinDigitDataTransformer); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['date_format'] = $options['date_format']; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'widget' => 'single_text', - // date_format must be provided in javascript supported type - 'date_format' => 'YYYY-MM-DD', - ]); - $resolver->setAllowedTypes('date_format', 'string'); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'date_picker'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/DateRangeType.php b/src/PrestaShopBundle/Form/Admin/Type/DateRangeType.php deleted file mode 100644 index 7d3f70d5..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/DateRangeType.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class DateRangeType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('from', DatePickerType::class, [ - 'required' => false, - 'attr' => [ - 'placeholder' => 'From', - ], - 'translation_domain' => 'Admin.Global', - 'date_format' => $options['date_format'], - ]) - ->add('to', DatePickerType::class, [ - 'required' => false, - 'attr' => [ - 'placeholder' => 'To', - ], - 'translation_domain' => 'Admin.Global', - 'date_format' => $options['date_format'], - ]); - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'date_format' => 'YYYY-MM-DD', - ]); - $resolver->setAllowedTypes('date_format', 'string'); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'date_range'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/EmailType.php b/src/PrestaShopBundle/Form/Admin/Type/EmailType.php deleted file mode 100644 index 3763c917..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/EmailType.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Form\DataTransformer\IDNConverterDataTransformer; -use Symfony\Component\Form\Extension\Core\Type\EmailType as BaseEmailType; -use Symfony\Component\Form\FormBuilderInterface; - -class EmailType extends BaseEmailType -{ - /** - * @var IDNConverterDataTransformer - */ - private $IDNConverterDataTransformer; - - public function __construct(IDNConverterDataTransformer $IDNConverterDataTransformer) - { - $this->IDNConverterDataTransformer = $IDNConverterDataTransformer; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->addViewTransformer($this->IDNConverterDataTransformer); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/FormattedTextareaType.php b/src/PrestaShopBundle/Form/Admin/Type/FormattedTextareaType.php deleted file mode 100644 index 3892cba6..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/FormattedTextareaType.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Form\Validator\Constraints\TinyMceMaxLength; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextareaType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class enabling TinyMCE on a Textarea field. - */ -class FormattedTextareaType extends AbstractType -{ - /** - * Max size of UTF-8 content in MySQL text column - */ - const LIMIT_TEXT_UTF8 = 21844; - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'autoload' => true, // Start automatically TinyMCE - 'limit' => self::LIMIT_TEXT_UTF8, - ]); - $resolver->setAllowedTypes('limit', 'int'); - $resolver->setAllowedTypes('autoload', 'bool'); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - if (!isset($view->vars['attr']['class'])) { - $view->vars['attr']['class'] = ''; - } - - if (true === $options['autoload']) { - $view->vars['attr']['class'] .= ' autoload_rte'; - } - $view->vars['attr']['counter'] = $options['limit']; - $view->vars['constraints'] = [ - new TinyMceMaxLength([ - 'max' => $options['limit'], - ]), - ]; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return TextareaType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/GeneratableTextType.php b/src/PrestaShopBundle/Form/Admin/Type/GeneratableTextType.php deleted file mode 100644 index 4c8dba88..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/GeneratableTextType.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * It is extension of TextType that adds additonal button which allows generating value for input - */ -class GeneratableTextType extends AbstractType -{ - const DEFAULT_GENERATED_VALUE_LENGTH = 32; - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'generated_value_length' => self::DEFAULT_GENERATED_VALUE_LENGTH, - ]) - ->setAllowedTypes('generated_value_length', 'int') - ; - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['generated_value_length'] = $options['generated_value_length']; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return TextType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/IntegerMinMaxFilterType.php b/src/PrestaShopBundle/Form/Admin/Type/IntegerMinMaxFilterType.php deleted file mode 100644 index 7c415e20..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/IntegerMinMaxFilterType.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\IntegerType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Defines the integer type two inputs of min and max value - designed to fit grid in grid filter. - */ -final class IntegerMinMaxFilterType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'min_field_options' => [], - 'max_field_options' => [], - ]); - - $resolver->setAllowedTypes('min_field_options', 'array'); - $resolver->setAllowedTypes('max_field_options', 'array'); - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - if (!isset($options['min_field_options']['attr']['placeholder'])) { - $options['min_field_options']['attr']['placeholder'] = $this->trans('Min', [], 'Admin.Global'); - } - - if (!isset($options['max_field_options']['attr']['placeholder'])) { - $options['max_field_options']['attr']['placeholder'] = $this->trans('Max', [], 'Admin.Global'); - } - - if (!isset($options['min_field_options']['attr']['min'])) { - $options['min_field_options']['attr']['min'] = 0; - } - - if (!isset($options['max_field_options']['attr']['min'])) { - $options['max_field_options']['attr']['min'] = 0; - } - - $options['min_field_options']['attr']['step'] = 1; - $options['max_field_options']['attr']['step'] = 1; - - $builder->add('min_field', IntegerType::class, $options['min_field_options']); - $builder->add('max_field', IntegerType::class, $options['max_field_options']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/IpAddressType.php b/src/PrestaShopBundle/Form/Admin/Type/IpAddressType.php deleted file mode 100644 index f6bf29d2..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/IpAddressType.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\TextType; - -/** - * Extended input type for IP addresses - * Displays a bouton to add the user's one to the list. - */ -class IpAddressType extends TextType -{ - /** - * {@inheritdoc} - */ - public function getExtendedType() - { - return TextType::class; - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'ip_address_text'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTableType.php b/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTableType.php deleted file mode 100644 index 6753e647..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTableType.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type\Material; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class MaterialChoiceTableType renders checkbox choices using table layout. - */ -class MaterialChoiceTableType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'expanded' => true, - 'multiple' => true, - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'material_choice_table'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTreeType.php b/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTreeType.php deleted file mode 100644 index da03168a..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialChoiceTreeType.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type\Material; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class MaterialChoiceTreeType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $selectedData = []; - if (null !== $form->getData()) { - $selectedData = is_array($form->getData()) ? $form->getData() : [$form->getData()]; - } - - $view->vars['multiple'] = $options['multiple']; - $view->vars['choices_tree'] = $this->getFormattedChoicesTree($options, $selectedData); - $view->vars['choice_label'] = $options['choice_label']; - $view->vars['choice_value'] = $options['choice_value']; - $view->vars['choice_children'] = $options['choice_children']; - $view->vars['disabled_values'] = $options['disabled_values']; - $view->vars['selected_values'] = $selectedData; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'choices_tree' => [], - 'choice_label' => 'name', - 'choice_value' => 'id', - 'choice_children' => 'children', - 'disabled_values' => [], - 'disabled' => false, - 'multiple' => false, - 'compound' => false, - ]) - ->setAllowedTypes('choices_tree', 'array') - ->setAllowedTypes('multiple', 'bool') - ->setAllowedTypes('choice_value', 'string') - ->setAllowedTypes('choice_label', 'string') - ->setAllowedTypes('choice_children', 'string') - ->setAllowedTypes('disabled_values', 'array') - ->setAllowedTypes('disabled', 'bool') - ->addAllowedValues('compound', false); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'material_choice_tree'; - } - - /** - * @param array $options - * @param array $selectedData - * - * @return array - */ - private function getFormattedChoicesTree(array $options, array $selectedData) - { - $tree = $options['choices_tree']; - - foreach ($tree as &$choice) { - $this->fillChoiceWithChildrenSelection( - $choice, - $options['choice_value'], - $options['choice_children'], - $selectedData - ); - } - - return $tree; - } - - /** - * @param array $choice - * @param string $choiceValueName - * @param string $choiceChildrenName - * @param array $selectedValues - * - * @return bool - */ - private function fillChoiceWithChildrenSelection( - array &$choice, - $choiceValueName, - $choiceChildrenName, - array $selectedValues - ) { - $isSelected = false; - $isChildrenSelected = false; - - if (in_array($choice[$choiceValueName], $selectedValues)) { - $isSelected = true; - } - - if (isset($choice[$choiceChildrenName])) { - foreach ($choice[$choiceChildrenName] as &$child) { - $selected = $this->fillChoiceWithChildrenSelection( - $child, - $choiceValueName, - $choiceChildrenName, - $selectedValues - ); - - if ($selected) { - $isChildrenSelected = true; - } - } - - unset($child); - } - - $choice['has_selected_children'] = $isChildrenSelected; - - return $isSelected || $isChildrenSelected; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialMultipleChoiceTableType.php b/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialMultipleChoiceTableType.php deleted file mode 100644 index 95baa5d9..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/Material/MaterialMultipleChoiceTableType.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type\Material; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\CallbackTransformer; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class MaterialMultipleChoiceTableType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - foreach ($options['multiple_choices'] as $choices) { - $builder->add($choices['name'], ChoiceType::class, [ - 'label' => $choices['label'], - 'choices' => $choices['choices'], - 'expanded' => true, - 'multiple' => $choices['multiple'], - 'choice_label' => false, - 'choice_translation_domain' => false, - ]); - - $builder->get($choices['name'])->addModelTransformer(new CallbackTransformer( - function ($value) use ($choices) { - if (is_array($value) && false === $choices['multiple']) { - return reset($value); - } - - return $value; - }, - function ($value) { - return $value; - } - )); - } - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['choices'] = $options['choices']; - $view->vars['scrollable'] = $options['scrollable']; - $view->vars['headers_to_disable'] = $options['headers_to_disable']; - } - - /** - * {@inheritdoc} - */ - public function finishView(FormView $view, FormInterface $form, array $options) - { - $entryIndexMapping = []; - - foreach ($view->children as $childChoiceName => $childChoiceView) { - foreach ($childChoiceView->children as $index => $childChoiceEntryView) { - $entryIndexMapping[$childChoiceEntryView->vars['value']][$childChoiceName] = $index; - } - } - - $view->vars['child_choice_entry_index_mapping'] = $entryIndexMapping; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'multiple_choices', - 'choices', - // in some cases we want to disable - // header for columns - 'headers_to_disable', - ]) - ->setDefaults([ - 'scrollable' => true, - 'headers_to_disable' => [], - ]) - ; - - $resolver->setAllowedTypes('choices', 'array'); - $resolver->setAllowedTypes('multiple_choices', 'array'); - $resolver->setAllowedTypes('scrollable', 'bool'); - $resolver->setAllowedTypes('headers_to_disable', 'array'); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'material_multiple_choice_table'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/MoneyWithSuffixType.php b/src/PrestaShopBundle/Form/Admin/Type/MoneyWithSuffixType.php deleted file mode 100644 index 9ee0db14..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/MoneyWithSuffixType.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\MoneyType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class MoneyWithSuffixType is a money type, - * which also has a suffix string right after the currency sign. - */ -class MoneyWithSuffixType extends MoneyType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $pattern = self::getPattern($options['currency']); - - // Currency sign in the pattern string can be either to the left, - // or to the right of the {{ widget }}, depending on the currency. - $tokens = explode('{{ widget }}', $pattern); - - // The only non-empty token will be the currency sign - append the suffix to it - array_walk($tokens, [$this, 'applySuffix'], $options['suffix']); - - // Restore the pattern as it was before, - // just the suffix is already appended after the currency sign - $view->vars['money_pattern'] = implode('{{ widget }}', $tokens); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - parent::configureOptions($resolver); - - $resolver->setDefault('suffix', ''); - } - - /** - * Appends the suffix to the value, if the value is not empty. - * Can be used with array_walk(). - * - * @param string $value - * @param int $key not used, it's only here to make this method compatible with array_walk - * @param string $suffix - */ - private function applySuffix(&$value, $key, $suffix) - { - if (strlen($value) > 0) { - $value = rtrim($value) . ' ' . $suffix; - } - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/NumberMinMaxFilterType.php b/src/PrestaShopBundle/Form/Admin/Type/NumberMinMaxFilterType.php deleted file mode 100644 index 77bdcee8..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/NumberMinMaxFilterType.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Translation\TranslatorAwareTrait; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Defines the number type two inputs of min and max value - designed to fit grid in grid filter. - */ -final class NumberMinMaxFilterType extends AbstractType -{ - use TranslatorAwareTrait; - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'min_field_options' => [], - 'max_field_options' => [], - ]); - - $resolver->setAllowedTypes('min_field_options', 'array'); - $resolver->setAllowedTypes('max_field_options', 'array'); - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - if (!isset($options['min_field_options']['attr']['placeholder'])) { - $options['min_field_options']['attr']['placeholder'] = $this->trans('Min', [], 'Admin.Global'); - } - - if (!isset($options['max_field_options']['attr']['placeholder'])) { - $options['max_field_options']['attr']['placeholder'] = $this->trans('Max', [], 'Admin.Global'); - } - - $builder->add('min_field', NumberType::class, $options['min_field_options']); - $builder->add('max_field', NumberType::class, $options['max_field_options']); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ReductionType.php b/src/PrestaShopBundle/Form/Admin/Type/ReductionType.php deleted file mode 100644 index b29885ef..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ReductionType.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\Extension\Core\Type\NumberType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Responsible for creating form for price reduction - */ -class ReductionType extends CommonAbstractType -{ - /** - * @var array - */ - private $priceReductionTypeChoices; - - /** - * @param array $priceReductionTypeChoices - */ - public function __construct( - array $priceReductionTypeChoices - ) { - $this->priceReductionTypeChoices = $priceReductionTypeChoices; - } - - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('type', ChoiceType::class, [ - 'placeholder' => false, - 'required' => false, - 'choices' => $options['choices'], - ]) - ->add('value', NumberType::class, [ - 'scale' => $options['scale'], - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices' => $this->priceReductionTypeChoices, - 'scale' => 6, - ]); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ResizableTextType.php b/src/PrestaShopBundle/Form/Admin/Type/ResizableTextType.php deleted file mode 100644 index e367f5fc..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ResizableTextType.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ResizableTextType adds new sizing options to TextType. - */ -class ResizableTextType extends AbstractTypeExtension -{ - /** - * {@inheritdoc} - */ - public function getExtendedType() - { - return TextType::class; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefined('size') - ->setAllowedValues( - 'size', - [ - 'small', - ] - ) - ; - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - if (isset($options['size'])) { - $sizeClass = 'size-' . $options['size']; - - if (!isset($view->vars['attr']['class'])) { - $view->vars['attr']['class'] = ''; - } - - $view->vars['attr']['class'] = trim($view->vars['attr']['class'] . ' ' . $sizeClass); - } - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/SearchAndResetType.php b/src/PrestaShopBundle/Form/Admin/Type/SearchAndResetType.php deleted file mode 100644 index aab02ec8..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/SearchAndResetType.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use LogicException; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * FormType used in rendering of "Search and Reset" action in Grids. - */ -class SearchAndResetType extends AbstractType -{ - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @param UrlGeneratorInterface $urlGenerator - */ - public function __construct(UrlGeneratorInterface $urlGenerator) - { - $this->urlGenerator = $urlGenerator; - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $showResetButton = false; - - if (null !== $form->getParent()) { - $configuredTypeNames = array_keys($form->getParent()->all()); - $availableValueNames = array_keys($form->getParent()->getData()); - - $configuredData = array_intersect($configuredTypeNames, $availableValueNames); - if (!empty($configuredData)) { - $showResetButton = true; - } - } - - $resetUrl = isset($options['attr']['data-url']) ? $options['attr']['data-url'] : null; - $redirectUrl = isset($options['attr']['data-redirect']) ? $options['attr']['data-redirect'] : null; - - if (null !== $options['reset_route']) { - $resetUrl = $this->urlGenerator->generate( - $options['reset_route'], - $options['reset_route_params'] - ); - } - - if (null !== $options['redirect_route']) { - $redirectUrl = $this->urlGenerator->generate( - $options['redirect_route'], - $options['redirect_route_params'] - ); - } - - if (in_array(null, [$resetUrl, $redirectUrl])) { - throw new LogicException(sprintf('You must configure "reset_route" and "redirect_route" options for "%s" type.', self::class)); - } - - $view->vars['show_reset_button'] = $showResetButton; - $view->vars['redirect_url'] = $redirectUrl; - $view->vars['reset_url'] = $resetUrl; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'reset_route' => null, - 'reset_route_params' => [], - 'redirect_route' => null, - 'redirect_route_params' => [], - ]) - ->setAllowedTypes('reset_route', ['string', 'null']) - ->setAllowedTypes('reset_route_params', 'array') - ->setAllowedTypes('redirect_route', ['string', 'null']) - ->setAllowedTypes('redirect_route_params', 'array'); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'search_and_reset'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ShopChoiceTreeType.php b/src/PrestaShopBundle/Form/Admin/Type/ShopChoiceTreeType.php deleted file mode 100644 index 51370729..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ShopChoiceTreeType.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTreeType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class ShopChoiceTreeType. - */ -class ShopChoiceTreeType extends AbstractType -{ - /** - * @var array - */ - private $shopTreeChoices; - - /** - * @var DataTransformerInterface - */ - private $stringArrayToIntegerArrayDataTransformer; - - /** - * @param array $shopTreeChoices - * @param DataTransformerInterface $stringArrayToIntegerArrayDataTransformer - */ - public function __construct( - array $shopTreeChoices, - DataTransformerInterface $stringArrayToIntegerArrayDataTransformer - ) { - $this->shopTreeChoices = $shopTreeChoices; - $this->stringArrayToIntegerArrayDataTransformer = $stringArrayToIntegerArrayDataTransformer; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->addModelTransformer($this->stringArrayToIntegerArrayDataTransformer); - - parent::buildForm($builder, $options); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices_tree' => $this->shopTreeChoices, - 'multiple' => true, - 'choice_label' => 'name', - 'choice_value' => 'id_shop', - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return MaterialChoiceTreeType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/ShopRestrictionCheckboxType.php b/src/PrestaShopBundle/Form/Admin/Type/ShopRestrictionCheckboxType.php deleted file mode 100644 index 3ce2329a..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/ShopRestrictionCheckboxType.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This class displays customized checkbox which is used for shop restriction functionality. - */ -class ShopRestrictionCheckboxType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $isChecked = $form->getData(); - - if ($isChecked) { - $view->vars['attr']['checked'] = true; - } - - parent::buildView($view, $form, $options); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'required' => false, - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return CheckboxType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/SwitchType.php b/src/PrestaShopBundle/Form/Admin/Type/SwitchType.php deleted file mode 100644 index b506e5b1..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/SwitchType.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Displays a switch (ON / OFF by default). - */ -class SwitchType extends AbstractType -{ - const TRANS_DOMAIN = 'Admin.Global'; - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices' => [ - 'No' => false, - 'Yes' => true, - ], - 'multiple' => false, - 'expanded' => false, - 'disabled' => false, - 'choice_translation_domain' => self::TRANS_DOMAIN, - ]); - $resolver->setAllowedTypes('disabled', 'bool'); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - if (true === $options['disabled']) { - $view->vars['disabled'] = true; - } - $view->vars['attr']['class'] = 'ps-switch'; - if (isset($options['attr']['class'])) { - $view->vars['attr']['class'] .= ' ' . $options['attr']['class']; - } - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TextEmptyType.php b/src/PrestaShopBundle/Form/Admin/Type/TextEmptyType.php deleted file mode 100644 index 0f6dedab..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TextEmptyType.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * @deprecated 1.7.5, to be removed in 1.8 - */ -class TextEmptyType extends AbstractTypeExtension implements DataTransformerInterface -{ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->addModelTransformer($this); - } - - public function getExtendedType() - { - return 'Symfony\Component\Form\Extension\Core\Type\TextType'; - } - - public function transform($data) - { - return $data; - } - - public function reverseTransform($data) - { - return empty($data) ? '' : $data; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TextWithLengthCounterType.php b/src/PrestaShopBundle/Form/Admin/Type/TextWithLengthCounterType.php deleted file mode 100644 index 69170fc8..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TextWithLengthCounterType.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Defines reusable text input with max length counter - */ -class TextWithLengthCounterType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['max_length'] = $options['max_length']; - $view->vars['position'] = $options['position']; - $view->vars['input'] = $options['input']; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setRequired([ - 'max_length', - ]) - ->setDefaults([ - 'position' => 'before', - 'input' => 'text', - 'compound' => false, - ]) - ->setAllowedTypes('max_length', 'int') - ->setAllowedValues('position', ['before', 'after']) - ->setAllowedValues('input', ['text', 'textarea']); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'text_with_length_counter'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TextWithRecommendedLengthType.php b/src/PrestaShopBundle/Form/Admin/Type/TextWithRecommendedLengthType.php deleted file mode 100644 index 95632fd1..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TextWithRecommendedLengthType.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Is used to add field with recommended input length counter to the form. - * - * Requires Javasript text-with-recommended-lenght-counter.js to work properly. - */ -class TextWithRecommendedLengthType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['recommended_length'] = $options['recommended_length']; - $view->vars['input_type'] = $options['input_type']; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefaults([ - 'input_type' => 'text', - 'compound' => false, - ]) - ->setRequired([ - 'recommended_length', - ]) - ->setAllowedTypes('recommended_length', 'int') - ->setAllowedValues('input_type', ['text', 'textarea']) - ; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TextWithUnitType.php b/src/PrestaShopBundle/Form/Admin/Type/TextWithUnitType.php deleted file mode 100644 index e1e9eb2b..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TextWithUnitType.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class TextWithUnitType extends AbstractType -{ - /** - * {@inheritdoc} - */ - public function getParent() - { - return TextType::class; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'widget' => 'single_text', - 'unit' => 'unit', - ]); - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - parent::buildView($view, $form, $options); - - $view->vars = array_merge($view->vars, [ - 'unit' => $options['unit'], - ]); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'text_with_unit'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TextareaEmptyType.php b/src/PrestaShopBundle/Form/Admin/Type/TextareaEmptyType.php deleted file mode 100644 index cea82546..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TextareaEmptyType.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\FormBuilderInterface; - -/** - * @deprecated 1.7.5, to be removed in 1.8 - */ -class TextareaEmptyType extends AbstractTypeExtension implements DataTransformerInterface -{ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->addModelTransformer($this); - } - - public function getExtendedType() - { - return 'Symfony\Component\Form\Extension\Core\Type\TextareaType'; - } - - public function transform($data) - { - return $data; - } - - public function reverseTransform($data) - { - return empty($data) ? '' : $data; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TranslatableType.php b/src/PrestaShopBundle/Form/Admin/Type/TranslatableType.php deleted file mode 100644 index 6f04b7ce..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TranslatableType.php +++ /dev/null @@ -1,351 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormErrorIterator; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\Options; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * Class TranslatableType adds translatable inputs with custom inner type to forms. - * Language selection uses a dropdown. - */ -class TranslatableType extends AbstractType -{ - /** - * @var array List of enabled locales - */ - private $enabledLocales; - - /** - * @var array List of all available locales - */ - private $availableLocales; - - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @var bool indicates whether to save the selected form language or not - */ - private $saveFormLocaleChoice; - - /** - * @var string default form language ID - */ - private $defaultFormLanguageId; - - /** - * @var int default language of the shop, used as a fallback when default form language is not set - */ - private $defaultShopLanguageId; - - /** - * @param array $availableLocales - * @param UrlGeneratorInterface $urlGenerator - * @param bool $saveFormLocaleChoice - * @param int $defaultFormLanguageId - * @param int $defaultShopLanguageId - */ - public function __construct( - array $availableLocales, - UrlGeneratorInterface $urlGenerator, - $saveFormLocaleChoice, - $defaultFormLanguageId, - $defaultShopLanguageId - ) { - $this->enabledLocales = $this->filterEnableLocales($availableLocales); - $this->availableLocales = $availableLocales; - $this->urlGenerator = $urlGenerator; - $this->saveFormLocaleChoice = $saveFormLocaleChoice; - $this->defaultFormLanguageId = $defaultFormLanguageId; - $this->defaultShopLanguageId = $defaultShopLanguageId; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - foreach ($options['locales'] as $locale) { - $typeOptions = $options['options']; - $typeOptions['label'] = $locale['iso_code']; - - if (!isset($typeOptions['required'])) { - $typeOptions['required'] = false; - } - - $builder->add($locale['id_lang'], $options['type'], $typeOptions); - } - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['locales'] = $options['locales']; - $view->vars['default_locale'] = $this->getDefaultLocale($options['locales']); - $view->vars['hide_locales'] = 1 >= count($options['locales']); - - if ($this->saveFormLocaleChoice) { - $view->vars['change_form_language_url'] = $this->urlGenerator->generate( - 'admin_employees_change_form_language' - ); - } - - $this->setErrorsByLocale($view, $form, $options['locales']); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'type' => TextType::class, - 'options' => [], - 'error_bubbling' => false, - 'only_enabled_locales' => false, - 'locales' => function (Options $options) { - return $options['only_enabled_locales'] ? - $this->enabledLocales : - $this->availableLocales - ; - }, - ]); - - $resolver->setAllowedTypes('locales', 'array'); - $resolver->setAllowedTypes('options', 'array'); - $resolver->setAllowedTypes('type', 'string'); - $resolver->setAllowedTypes('error_bubbling', 'bool'); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'translatable'; - } - - /** - * If there are more then one locale it gets nested errors and if found prepares the errors for usage in twig. - * If there are only one error which is not assigned to the default language then the error is being localised. - * - * @param FormView $view - * @param FormInterface $form - * @param array $locales - */ - private function setErrorsByLocale(FormView $view, FormInterface $form, array $locales) - { - if (count($locales) <= 1) { - return; - } - - $formErrors = $form->getErrors(true); - - if (empty($formErrors)) { - return; - } - - if (1 === count($formErrors)) { - $errorByLocale = $this->getSingleTranslatableErrorExcludingDefaultLocale( - $formErrors, - $form, - $locales - ); - - if (null !== $errorByLocale) { - $view->vars['error_by_locale'] = $errorByLocale; - } - - return; - } - - $errorsByLocale = $this->getTranslatableErrors( - $formErrors, - $form, - $locales - ); - - if (null !== $errorsByLocale) { - $view->vars['errors_by_locale'] = $errorsByLocale; - } - } - - /** - * Gets single error excluding the default locales error since for default locale a language name prefix is not - * required. - * - * @param FormErrorIterator $formErrors - * @param FormInterface $form - * @param array $locales - * - * @return array|null - */ - private function getSingleTranslatableErrorExcludingDefaultLocale( - FormErrorIterator $formErrors, - FormInterface $form, - array $locales - ) { - $errorByLocale = null; - $formError = $formErrors[0]; - $nonDefaultLanguageFormKey = null; - $iteration = 0; - - foreach ($form as $formItem) { - if (0 === $iteration) { - ++$iteration; - - continue; - } - - if ($this->doesErrorFormAndCurrentFormMatches($formError->getOrigin(), $formItem)) { - $nonDefaultLanguageFormKey = $iteration; - - break; - } - - ++$iteration; - } - - if (isset($locales[$nonDefaultLanguageFormKey])) { - $errorByLocale = [ - 'locale_name' => $locales[$nonDefaultLanguageFormKey]['name'], - 'error_message' => $formError->getMessage(), - ]; - } - - return $errorByLocale; - } - - /** - * Gets translatable errors ready for popover display and assigned to each language - * - * @param FormErrorIterator $formErrors - * @param FormInterface $form - * @param array $locales - * - * @return array|null - */ - private function getTranslatableErrors( - FormErrorIterator $formErrors, - FormInterface $form, - array $locales - ) { - $errorsByLocale = null; - $iteration = 0; - foreach ($form as $formItem) { - $doesLocaleExistForInvalidForm = isset($locales[$iteration]) && !$formItem->isValid(); - - if ($doesLocaleExistForInvalidForm) { - foreach ($formErrors as $formError) { - if ($this->doesErrorFormAndCurrentFormMatches($formError->getOrigin(), $formItem)) { - $errorsByLocale[$locales[$iteration]['iso_code']] = [ - 'locale_name' => $locales[$iteration]['name'], - 'error_message' => $formError->getMessage(), - ]; - } - } - } - - ++$iteration; - } - - return $errorsByLocale; - } - - /** - * Determines if the error form matches the given form. Used for mapping the locales for the form fields. - * - * @param FormInterface $errorForm - * @param FormInterface $currentForm - * - * @return bool - */ - private function doesErrorFormAndCurrentFormMatches(FormInterface $errorForm, FormInterface $currentForm) - { - return $errorForm === $currentForm; - } - - /** - * Get default locale. - * - * @param array $locales - * - * @return array - */ - private function getDefaultLocale(array $locales) - { - if ($this->defaultFormLanguageId) { - // Searching for a locale that matches default form language - foreach ($locales as $locale) { - if ($locale['id_lang'] == $this->defaultFormLanguageId) { - return $locale; - } - } - } - - // Searching for locale that matches default shop language - foreach ($locales as $locale) { - if ($locale['id_lang'] == $this->defaultShopLanguageId) { - return $locale; - } - } - - return reset($locales); - } - - /** - * Filters only enabled locales - * - * @param array $availableLocales - * - * @return array - */ - private function filterEnableLocales(array $availableLocales) - { - $enabledLocales = []; - - foreach ($availableLocales as $locale) { - if ($locale['active']) { - $enabledLocales[] = $locale; - } - } - - return $enabledLocales; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TranslateTextType.php b/src/PrestaShopBundle/Form/Admin/Type/TranslateTextType.php deleted file mode 100644 index 9a4ffd2c..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TranslateTextType.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class is responsible for creating translatable text inputs. - * - * @deprecated since version 1.7.6 and will be removed in 1.8. Use the TranslatableType instead. - */ -class TranslateTextType extends AbstractType -{ - public function __construct() - { - @trigger_error( - sprintf( - 'The %s class is deprecated since version 1.7.6 and will be removed in 1.8. Use the %s class instead.', - __CLASS__, - TranslatableType::class - ), - E_USER_DEPRECATED - ); - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - foreach ($options['locales'] as $locale) { - $localeOptions = $options['options']; - $localeOptions['label'] = $locale['iso_code']; - - if (!isset($localeOptions['required'])) { - $localeOptions['required'] = false; - } - - $builder->add($locale['id_lang'], TextType::class, $localeOptions); - } - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['locales'] = $options['locales']; - $view->vars['default_locale'] = reset($options['locales']); - $view->vars['hide_locales'] = 1 >= count($options['locales']); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'options' => [], - 'locales' => [], - ]); - - $resolver->setAllowedTypes('locales', 'array'); - $resolver->setAllowedTypes('options', 'array'); - } - - /** - * {@inheritdoc} - */ - public function getBlockPrefix() - { - return 'translate_text'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TranslateType.php b/src/PrestaShopBundle/Form/Admin/Type/TranslateType.php deleted file mode 100644 index 223226fb..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TranslateType.php +++ /dev/null @@ -1,163 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; - -/** - * This form class is responsible to create a translatable form. - * Language selection uses tabs. - */ -class TranslateType extends CommonAbstractType -{ - /** - * @var UrlGeneratorInterface - */ - private $urlGenerator; - - /** - * @var bool - */ - private $saveFormLocaleChoice; - - /** - * @var int - */ - private $defaultFormLanguageId; - - /** - * @var int - */ - private $defaultShopLanguageId; - - /** - * @param UrlGeneratorInterface $urlGenerator - * @param bool $saveFormLocaleChoice - * @param int $defaultFormLanguageId - * @param int $defaultShopLanguageId - */ - public function __construct( - UrlGeneratorInterface $urlGenerator, - $saveFormLocaleChoice, - $defaultFormLanguageId, - $defaultShopLanguageId - ) { - $this->urlGenerator = $urlGenerator; - $this->saveFormLocaleChoice = $saveFormLocaleChoice; - $this->defaultFormLanguageId = $defaultFormLanguageId; - $this->defaultShopLanguageId = $defaultShopLanguageId; - } - - /** - * {@inheritdoc} - * - * Builds form fields for each locales - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $i = 0; - foreach ($options['locales'] as $locale) { - $options['options']['empty_data'] = ''; - $locale_options = $options['options']; - $locale_options['label'] = $locale['iso_code']; - if ($i > 0) { - $locale_options['required'] = false; - unset($locale_options['constraints']); - } - - $builder->add($locale['id_lang'], $options['type'], $locale_options); - ++$i; - } - } - - /** - * {@inheritdoc} - * - * Add the var locales and defaultLocale to the view - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['locales'] = $options['locales']; - $view->vars['defaultLocale'] = $this->getDefaultLocale($options['locales']); - $view->vars['hideTabs'] = $options['hideTabs']; - - if ($this->saveFormLocaleChoice) { - $view->vars['change_form_language_url'] = $this->urlGenerator->generate( - 'admin_employees_change_form_language' - ); - } - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'type' => null, - 'options' => [], - 'locales' => [], - 'hideTabs' => true, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'translatefields'; - } - - /** - * Get default locale. - * - * @param array $locales - * - * @return array - */ - private function getDefaultLocale(array $locales) - { - // If default form language is not available we will use default shop language - $languageId = $this->defaultFormLanguageId ?: $this->defaultShopLanguageId; - - // Searching for a locale that matches the selected language - foreach ($locales as $locale) { - if ($locale['id_lang'] == $languageId) { - return $locale; - } - } - - return reset($locales); - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TranslatorAwareType.php b/src/PrestaShopBundle/Form/Admin/Type/TranslatorAwareType.php deleted file mode 100644 index caa613f9..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TranslatorAwareType.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Translation\TranslatorInterface; - -/** - * PrestaShop forms needs custom domain name for field constraints - * This feature is not available in Symfony so we need to inject the translator - * for constraints messages only. - */ -abstract class TranslatorAwareType extends CommonAbstractType -{ - private $translator; - - /** - * All languages available on shop. Used for translations. - * - * @param array $locales - */ - protected $locales; - - public function __construct(TranslatorInterface $translator, array $locales) - { - $this->translator = $translator; - $this->locales = $locales; - } - - /** - * Get the translated chain from key. - * - * @param string $key the key to be translated - * @param string $domain the domain to be selected - * @param array $parameters Optional, pass parameters if needed (uncommon) - * - * @returns string - */ - protected function trans($key, $domain, $parameters = []) - { - return $this->translator->trans($key, $parameters, $domain); - } - - /** - * Get locales to be used in form type. - * - * @return array - */ - protected function getLocaleChoices() - { - $locales = []; - - foreach ($this->locales as $locale) { - $locales[$locale['name']] = $locale['iso_code']; - } - - return $locales; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadCustomerCollectionType.php b/src/PrestaShopBundle/Form/Admin/Type/TypeaheadCustomerCollectionType.php deleted file mode 100644 index cb69a3bd..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadCustomerCollectionType.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to create a customer. - */ -class TypeaheadCustomerCollectionType extends CommonAbstractType -{ - protected $customerAdapter; - - /** - * {@inheritdoc} - * - * @param object $customerAdapter - */ - public function __construct($customerAdapter) - { - $this->customerAdapter = $customerAdapter; - } - - /** - * {@inheritdoc} - * - * Add the vars to the view - * Inject collection customer - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['placeholder'] = $options['placeholder']; - $view->vars['remote_url'] = $options['remote_url']; - $view->vars['mapping_value'] = $options['mapping_value']; - $view->vars['mapping_name'] = $options['mapping_name']; - $view->vars['template_collection'] = $options['template_collection']; - $view->vars['limit'] = $options['limit']; - - //if form is submitted, inject datas to display collection - if (!empty($view->vars['value']) && !empty($view->vars['value']['data'])) { - $collection = []; - - $i = 0; - foreach ($view->vars['value']['data'] as $id) { - if (!$id) { - continue; - } - $customer = $this->customerAdapter->getCustomer($id); - $collection[] = [ - 'id' => $id, - 'name' => $customer->firstname . ' ' . $customer->lastname . ' - ' . $customer->email, - ]; - ++$i; - - //if collection length is up to limit, break - if ($options['limit'] != 0 && $i >= $options['limit']) { - break; - } - } - $view->vars['collection'] = $collection; - } - } - - /** - * {@inheritdoc} - * - * Builds the form. - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('data', 'Symfony\Component\Form\Extension\Core\Type\CollectionType', [ - 'entry_type' => 'Symfony\Component\Form\Extension\Core\Type\HiddenType', - 'allow_add' => true, - 'allow_delete' => true, - 'label' => false, - 'required' => false, - 'prototype' => true, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'remote_url' => '', - 'mapping_value' => 'id', - 'mapping_name' => 'name', - 'placeholder' => '', - 'template_collection' => '', - 'limit' => 0, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'typeahead_customer_collection'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductCollectionType.php b/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductCollectionType.php deleted file mode 100644 index e4a6aed2..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductCollectionType.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to create a product, with or without attribute field. - */ -class TypeaheadProductCollectionType extends CommonAbstractType -{ - protected $productAdapter; - protected $categoryAdapter; - - /** - * {@inheritdoc} - * - * @param object $productAdapter - */ - public function __construct($productAdapter, $categoryAdapter) - { - $this->productAdapter = $productAdapter; - $this->categoryAdapter = $categoryAdapter; - } - - /** - * {@inheritdoc} - * - * Add the vars to the view - * Inject collection products - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['placeholder'] = $options['placeholder']; - $view->vars['remote_url'] = $options['remote_url']; - $view->vars['mapping_value'] = $options['mapping_value']; - $view->vars['mapping_name'] = $options['mapping_name']; - $view->vars['mapping_type'] = $options['mapping_type']; - $view->vars['template_collection'] = $options['template_collection']; - $view->vars['limit'] = $options['limit']; - - //if form is submitted, inject datas to display collection - if (!empty($view->vars['value']) && !empty($view->vars['value']['data'])) { - $collection = []; - - $i = 0; - foreach ($view->vars['value']['data'] as $id) { - if (!$id) { - continue; - } - - switch ($view->vars['mapping_type']) { - case 'category': - $category = $this->categoryAdapter->getCategory($id); - $collection[] = [ - 'id' => $id, - 'name' => $this->categoryAdapter->getBreadCrumb($category->id), - 'image' => $category->image, - ]; - - break; - - default: - $product = $this->productAdapter->getProduct($id); - $collection[] = [ - 'id' => $id, - 'name' => reset($product->name) . ' (ref:' . $product->reference . ')', - 'image' => $product->image, - ]; - - break; - } - ++$i; - - //if collection length is up to limit, break - if ($options['limit'] != 0 && $i >= $options['limit']) { - break; - } - } - $view->vars['collection'] = $collection; - } - } - - /** - * {@inheritdoc} - * - * Builds the form. - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('data', CollectionType::class, [ - 'entry_type' => HiddenType::class, - 'allow_add' => true, - 'allow_delete' => true, - 'label' => false, - 'required' => false, - 'prototype' => true, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'remote_url' => '', - 'mapping_value' => 'id', - 'mapping_name' => 'name', - 'mapping_type' => 'product', - 'placeholder' => '', - 'template_collection' => '', - 'limit' => 0, - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'typeahead_product_collection'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductPackCollectionType.php b/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductPackCollectionType.php deleted file mode 100644 index 0707c4df..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/TypeaheadProductPackCollectionType.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * This form class is responsible to create a product, with or without attribute field. - */ -class TypeaheadProductPackCollectionType extends CommonAbstractType -{ - private $productAdapter; - - /** - * {@inheritdoc} - * - * @param object $productAdapter - */ - public function __construct($productAdapter) - { - $this->productAdapter = $productAdapter; - } - - /** - * {@inheritdoc} - * - * Add the vars to the view - * Inject collection products - */ - public function buildView(FormView $view, FormInterface $form, array $options) - { - $view->vars['placeholder'] = $options['placeholder']; - $view->vars['remote_url'] = $options['remote_url']; - $view->vars['mapping_value'] = $options['mapping_value']; - $view->vars['mapping_name'] = $options['mapping_name']; - $view->vars['template_collection'] = $options['template_collection']; - - //if form is submitted, inject datas to display collection - if (!empty($view->vars['value']) && !empty($view->vars['value']['data'])) { - $view->vars['collection'] = $view->vars['value']['data']; - } - } - - /** - * {@inheritdoc} - * - * Builds the form. - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('data', CollectionType::class, [ - 'entry_type' => HiddenType::class, - 'allow_add' => true, - 'allow_delete' => true, - 'label' => false, - 'required' => false, - 'prototype' => true, - ]); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'remote_url' => '', - 'mapping_value' => 'id', - 'mapping_name' => 'name', - 'placeholder' => '', - 'template_collection' => '', - ]); - } - - /** - * Returns the block prefix of this type. - * - * @return string The prefix name - */ - public function getBlockPrefix() - { - return 'typeahead_product_pack_collection'; - } -} diff --git a/src/PrestaShopBundle/Form/Admin/Type/YesAndNoChoiceType.php b/src/PrestaShopBundle/Form/Admin/Type/YesAndNoChoiceType.php deleted file mode 100644 index 267c5b3e..00000000 --- a/src/PrestaShopBundle/Form/Admin/Type/YesAndNoChoiceType.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Admin\Type; - -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Class YesAndNoChoiceType. - */ -class YesAndNoChoiceType extends TranslatorAwareType -{ - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'choices' => [ - $this->trans('Yes', 'Admin.Global') => 1, - $this->trans('No', 'Admin.Global') => 0, - ], - 'required' => false, - 'choice_translation_domain' => false, - ]); - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return ChoiceType::class; - } -} diff --git a/src/PrestaShopBundle/Form/DataTransformer/ArabicToLatinDigitDataTransformer.php b/src/PrestaShopBundle/Form/DataTransformer/ArabicToLatinDigitDataTransformer.php deleted file mode 100644 index 6e8652c3..00000000 --- a/src/PrestaShopBundle/Form/DataTransformer/ArabicToLatinDigitDataTransformer.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShopBundle\Form\DataTransformer; - -use PrestaShop\PrestaShop\Core\Util\ArabicToLatinDigitConverter; -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class ArabicToLatinDigitDataTransformer is responsible for converting arabic/persian digits to latin digits - */ -final class ArabicToLatinDigitDataTransformer implements DataTransformerInterface -{ - /** - * @var ArabicToLatinDigitConverter - */ - private $arabicToLatinDigitConverter; - - public function __construct(ArabicToLatinDigitConverter $arabicToLatinDigitConverter) - { - $this->arabicToLatinDigitConverter = $arabicToLatinDigitConverter; - } - - /** - * Do not transform latin number to arabic/persian number as - * the javascript datepicker will handle that on its side - * - * {@inheritdoc} - */ - public function transform($value) - { - return $value; - } - - /** - * {@inheritdoc} - */ - public function reverseTransform($value) - { - if (null === $value || '' === $value) { - return null; - } - - return $this->arabicToLatinDigitConverter->convert($value); - } -} diff --git a/src/PrestaShopBundle/Form/DataTransformer/DefaultLanguageToFilledArrayDataTransformer.php b/src/PrestaShopBundle/Form/DataTransformer/DefaultLanguageToFilledArrayDataTransformer.php deleted file mode 100644 index 2c64c442..00000000 --- a/src/PrestaShopBundle/Form/DataTransformer/DefaultLanguageToFilledArrayDataTransformer.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\DataTransformer; - -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class DefaultLanguageToFilledArrayDataTransformer is responsible for filling empty array values with - * default language value if such exists. - */ -final class DefaultLanguageToFilledArrayDataTransformer implements DataTransformerInterface -{ - /** - * @var int - */ - private $defaultLanguageId; - - /** - * @param int $defaultLanguageId - */ - public function __construct($defaultLanguageId) - { - $this->defaultLanguageId = $defaultLanguageId; - } - - /** - * {@inheritdoc} - */ - public function transform($value) - { - // No transformation is required here due to this data is being sent to template - return $value; - } - - /** - * {@inheritdoc} - * - * @param array $values - */ - public function reverseTransform($values) - { - if (!$this->assertIsValidForDataTransforming($values)) { - return $values; - } - - $defaultValue = $values[$this->defaultLanguageId]; - foreach ($values as $languageId => $item) { - if (!$item) { - $values[$languageId] = $defaultValue; - } - } - - return $values; - } - - /** - * Checks if the value is array and default language key exists in array. - * - * @param array $values - * - * @return bool - */ - private function assertIsValidForDataTransforming($values) - { - return is_array($values) && isset($values[$this->defaultLanguageId]) && $values[$this->defaultLanguageId]; - } -} diff --git a/src/PrestaShopBundle/Form/DataTransformer/IDNConverterDataTransformer.php b/src/PrestaShopBundle/Form/DataTransformer/IDNConverterDataTransformer.php deleted file mode 100644 index 80a40500..00000000 --- a/src/PrestaShopBundle/Form/DataTransformer/IDNConverterDataTransformer.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShopBundle\Form\DataTransformer; - -use PrestaShop\PrestaShop\Core\Util\InternationalizedDomainNameConverter; -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class DefaultLanguageToFilledArrayDataTransformer is responsible for filling empty array values with - * default language value if such exists. - */ -final class IDNConverterDataTransformer implements DataTransformerInterface -{ - /** - * @var InternationalizedDomainNameConverter - */ - private $converter; - - public function __construct(InternationalizedDomainNameConverter $converter) - { - $this->converter = $converter; - } - - /** - * {@inheritdoc} - * - * Do not convert utf8 to punycode, should be done on the client side - */ - public function transform($value) - { - return $value; - } - - /** - * {@inheritdoc} - * - * Convert punycode to utf8 (prestashop@xn--80aswg.xn--p1ai -> prestashop@сайт.рф) - */ - public function reverseTransform($value) - { - return is_string($value) ? $this->converter->emailToUtf8($value) : $value; - } -} diff --git a/src/PrestaShopBundle/Form/DataTransformer/StringArrayToIntegerArrayDataTransformer.php b/src/PrestaShopBundle/Form/DataTransformer/StringArrayToIntegerArrayDataTransformer.php deleted file mode 100644 index 91a0fe4d..00000000 --- a/src/PrestaShopBundle/Form/DataTransformer/StringArrayToIntegerArrayDataTransformer.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\DataTransformer; - -use Symfony\Component\Form\DataTransformerInterface; - -/** - * Class StringArrayToIntegerArrayTransformer is responsible for applying reverse transformation when form is being - * submitted. If its array, it casts all elements to integer. - */ -final class StringArrayToIntegerArrayDataTransformer implements DataTransformerInterface -{ - /** - * {@inheritdoc} - */ - public function transform($value) - { - // No transformation is required here due to this data is being sent to template - return $value; - } - - /** - * {@inheritdoc} - */ - public function reverseTransform($value) - { - if (!is_array($value)) { - return $value; - } - - return array_map(function ($item) { - return (int) $item; - }, $value); - } -} diff --git a/src/PrestaShopBundle/Form/Extension/DataListExtension.php b/src/PrestaShopBundle/Form/Extension/DataListExtension.php deleted file mode 100644 index 47f26ab9..00000000 --- a/src/PrestaShopBundle/Form/Extension/DataListExtension.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Extension; - -use Symfony\Component\Form\AbstractTypeExtension; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\Form\FormView; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * Extends TextType with tag feature - */ -class DataListExtension extends AbstractTypeExtension -{ - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver): void - { - $resolver - ->setDefaults([ - 'data_list' => null, - ]) - ->setAllowedTypes('data_list', ['null', 'array']) - ; - } - - /** - * {@inheritdoc} - */ - public function buildView(FormView $view, FormInterface $form, array $options): void - { - $view->vars['data_list'] = $options['data_list']; - } - - /** - * {@inheritdoc} - */ - public function getExtendedType(): string - { - return TextType::class; - } -} diff --git a/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLength.php b/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLength.php deleted file mode 100644 index 5198544f..00000000 --- a/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLength.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Validator\Constraints; - -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\Exception\MissingOptionsException; - -class TinyMceMaxLength extends Constraint -{ - public $max; - - public function __construct($options = null) - { - if (null !== $options && !is_array($options)) { - $options = [ - 'max' => $options, - ]; - } - - parent::__construct($options); - - if (null === $this->max) { - throw new MissingOptionsException(sprintf('Option "max" must be given for constraint %s', __CLASS__), ['max']); - } - } -} diff --git a/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLengthValidator.php b/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLengthValidator.php deleted file mode 100644 index 78f1eae1..00000000 --- a/src/PrestaShopBundle/Form/Validator/Constraints/TinyMceMaxLengthValidator.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Form\Validator\Constraints; - -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; - -class TinyMceMaxLengthValidator extends ConstraintValidator -{ - public function validate($value, Constraint $constraint) - { - $replaceArray = [ - "\n", - "\r", - "\n\r", - ]; - $str = str_replace($replaceArray, [''], strip_tags($value)); - - if (iconv_strlen($str) > $constraint->max) { - $this->context->addViolation( - (new LegacyContext())->getContext()->getTranslator()->trans('This value is too long. It should have %limit% characters or less.', [], 'Admin.Catalog.Notification'), - ['%limit%' => $constraint->max] - ); - } - } -} diff --git a/src/PrestaShopBundle/Install/AbstractInstall.php b/src/PrestaShopBundle/Install/AbstractInstall.php deleted file mode 100644 index 5c88726a..00000000 --- a/src/PrestaShopBundle/Install/AbstractInstall.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -abstract class AbstractInstall -{ - /** - * @var LanguageList - */ - public $language; - - /** - * @var \PrestaShopBundle\Translation\Translator - */ - public $translator; - - /** - * @var array List of errors - */ - protected $errors = []; - - public function __construct() - { - $this->language = LanguageList::getInstance(); - } - - public function setError($errors) - { - if (!is_array($errors)) { - $errors = [$errors]; - } - - $this->errors = array_merge($this->errors, $errors); - } - - public function getErrors() - { - return $this->errors; - } - - public function setTranslator($translator) - { - $this->translator = $translator; - - return $this; - } -} diff --git a/src/PrestaShopBundle/Install/Database.php b/src/PrestaShopBundle/Install/Database.php deleted file mode 100644 index 497d9c7b..00000000 --- a/src/PrestaShopBundle/Install/Database.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use PrestaShop\PrestaShop\Adapter\Entity\Db; -use PrestaShop\PrestaShop\Adapter\Entity\Validate; - -class Database extends AbstractInstall -{ - /** - * Check database configuration and try a connection. - * - * @param string $server - * @param string $database - * @param string $login - * @param string $password - * @param string $prefix - * @param bool $clear - * - * @return array List of errors - */ - public function testDatabaseSettings($server, $database, $login, $password, $prefix, $clear = false) - { - $errors = []; - - // Check if fields are correctly typed - if (!$server || !Validate::isUrl($server)) { - $errors[] = $this->translator->trans('Server name is not valid', [], 'Install'); - } - - if (!$database) { - $errors[] = $this->translator->trans('You must enter a database name', [], 'Install'); - } - - if (!$login) { - $errors[] = $this->translator->trans('You must enter a database login', [], 'Install'); - } - - if ($prefix && !Validate::isTablePrefix($prefix)) { - $errors[] = $this->translator->trans('Tables prefix is invalid', [], 'Install'); - } - - if (!$errors) { - $dbtype = ' (' . Db::getClass() . ')'; - // Try to connect to database - switch (Db::checkConnection($server, $login, $password, $database, true)) { - case 0: - if (!Db::checkEncoding($server, $login, $password)) { - $errors[] = $this->translator->trans('Cannot convert database data to utf-8', [], 'Install') . $dbtype; - } - - // Check if a table with same prefix already exists - if (!$clear && Db::hasTableWithSamePrefix($server, $login, $password, $database, $prefix)) { - $errors[] = $this->translator->trans('At least one table with same prefix was already found, please change your prefix or drop your database', [], 'Install'); - } - if (!Db::checkAutoIncrement($server, $login, $password)) { - $errors[] = $this->translator->trans('The values of auto_increment increment and offset must be set to 1', [], 'Install'); - } - if (($create_error = Db::checkCreatePrivilege($server, $login, $password, $database, $prefix)) !== true) { - $errors[] = $this->translator->trans('Your database login does not have the privileges to create table on the database "%s". Ask your hosting provider:', ['%database%' => $database], 'Install'); - if ($create_error != false) { - $errors[] = $create_error; - } - } - - break; - - case 1: - $errors[] = $this->translator->trans('Database Server is not found. Please verify the login, password and server fields', [], 'Install') . $dbtype; - - break; - - case 2: - $error = $this->translator->trans('Connection to MySQL server succeeded, but database "%database%" not found', ['%database%' => $database], 'Install') . $dbtype; - if ($this->createDatabase($server, $database, $login, $password, true)) { - $error .= '

    ' . sprintf('', $this->translator->trans('Attempt to create the database automatically', [], 'Install')) . '

    - '; - } - $errors[] = $error; - - break; - } - } - - if (count($errors)) { - $this->setError($errors); - } - - return $errors; - } - - public function createDatabase($server, $database, $login, $password, $dropit = false) - { - $class = '\\' . Db::getClass(); - - return call_user_func([$class, 'createDatabase'], $server, $login, $password, $database, $dropit); - } - - public function getBestEngine($server, $database, $login, $password) - { - $class = '\\' . Db::getClass(); - $instance = new $class($server, $login, $password, $database, true); - $engine = $instance->getBestEngine(); - unset($instance); - - return $engine; - } -} diff --git a/src/PrestaShopBundle/Install/DatabaseDump.php b/src/PrestaShopBundle/Install/DatabaseDump.php deleted file mode 100644 index 751c5451..00000000 --- a/src/PrestaShopBundle/Install/DatabaseDump.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use Exception; - -class DatabaseDump -{ - private $host; - private $port; - private $user; - private $password; - private $databaseName; - private $dumpFile; - - /** - * Constructor extracts database connection info from PrestaShop's configuration, - * but we use mysqldump and mysql for dump / restore. - * - * @param string $dumpFile dump file name - */ - private function __construct($dumpFile = null) - { - $host_and_maybe_port = explode(':', _DB_SERVER_); - - if (count($host_and_maybe_port) === 1) { - $this->host = $host_and_maybe_port[0]; - $this->port = 3306; - } elseif (count($host_and_maybe_port) === 2) { - $this->host = $host_and_maybe_port[0]; - $this->port = $host_and_maybe_port[1]; - } - - if ($dumpFile === null) { - $this->dumpFile = sys_get_temp_dir() . '/' . 'ps_dump.sql'; - } else { - $this->dumpFile = $dumpFile; - } - $this->databaseName = _DB_NAME_; - $this->user = _DB_USER_; - $this->password = _DB_PASSWD_; - } - - /** - * Wrapper to easily build mysql commands: sets password, port, user. - * - * @param string $executable - * @param array $arguments - * - * @return string - */ - private function buildMySQLCommand($executable, array $arguments = []) - { - $parts = [ - escapeshellarg($executable), - '-u', escapeshellarg($this->user), - '-P', escapeshellarg($this->port), - '-h', escapeshellarg($this->host), - ]; - - if ($this->password) { - $parts[] = '-p' . escapeshellarg($this->password); - } - - $parts = array_merge($parts, array_map('escapeshellarg', $arguments)); - - return implode(' ', $parts); - } - - /** - * Like exec, but will raise an exception if the command failed. - * - * @param string $command - * - * @return array - * - * @throws Exception - */ - private function exec($command) - { - $output = []; - $ret = 1; - exec($command, $output, $ret); - - if ($ret !== 0) { - throw new Exception(sprintf('Unable to exec command: `%s`, missing a binary?', $command)); - } - - return $output; - } - - /** - * The actual dump function. - */ - private function dump() - { - $dumpCommand = $this->buildMySQLCommand('mysqldump', [$this->databaseName]); - $dumpCommand .= ' > ' . escapeshellarg($this->dumpFile) . ' 2> /dev/null'; - $this->exec($dumpCommand); - } - - /** - * Restore the dump to the actual database. - */ - public function restore() - { - $restoreCommand = $this->buildMySQLCommand('mysql', [$this->databaseName]); - $restoreCommand .= ' < ' . escapeshellarg($this->dumpFile) . ' 2> /dev/null'; - $this->exec($restoreCommand); - } - - /** - * Make a database dump. - */ - public static function create() - { - $dump = new static(); - - $dump->dump(); - } - - /** - * Restore a database dump. - */ - public static function restoreDb() - { - $dump = new static(); - - $dump->restore(); - } -} diff --git a/src/PrestaShopBundle/Install/Install.php b/src/PrestaShopBundle/Install/Install.php deleted file mode 100644 index 2ce6df8f..00000000 --- a/src/PrestaShopBundle/Install/Install.php +++ /dev/null @@ -1,1174 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use AppKernel; -use InstallSession; -use Language as LanguageLegacy; -use PhpEncryption; -use PrestaShop\PrestaShop\Adapter\Entity\Cache; -use PrestaShop\PrestaShop\Adapter\Entity\Cart; -use PrestaShop\PrestaShop\Adapter\Entity\Category; -use PrestaShop\PrestaShop\Adapter\Entity\Configuration; -use PrestaShop\PrestaShop\Adapter\Entity\Context; -use PrestaShop\PrestaShop\Adapter\Entity\Cookie; -use PrestaShop\PrestaShop\Adapter\Entity\Country; -use PrestaShop\PrestaShop\Adapter\Entity\Currency; -use PrestaShop\PrestaShop\Adapter\Entity\Db; -use PrestaShop\PrestaShop\Adapter\Entity\Employee; -use PrestaShop\PrestaShop\Adapter\Entity\FileLogger; -use PrestaShop\PrestaShop\Adapter\Entity\Group; -use PrestaShop\PrestaShop\Adapter\Entity\ImageManager; -use PrestaShop\PrestaShop\Adapter\Entity\ImageType; -use PrestaShop\PrestaShop\Adapter\Entity\Language as EntityLanguage; -use PrestaShop\PrestaShop\Adapter\Entity\LocalizationPack; -use PrestaShop\PrestaShop\Adapter\Entity\Module; -use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopCollection; -use PrestaShop\PrestaShop\Adapter\Entity\Search; -use PrestaShop\PrestaShop\Adapter\Entity\Shop; -use PrestaShop\PrestaShop\Adapter\Entity\ShopGroup; -use PrestaShop\PrestaShop\Adapter\Entity\ShopUrl; -use PrestaShop\PrestaShop\Adapter\Entity\Tools; -use PrestaShop\PrestaShop\Adapter\Entity\Validate; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder; -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder; -use PrestaShopBundle\Cache\LocalizationWarmer; -use PrestaShopBundle\Service\Database\Upgrade as UpgradeDatabase; -use PrestashopInstallerException; -use Symfony\Component\Yaml\Yaml; - -class Install extends AbstractInstall -{ - const SETTINGS_FILE = 'config/settings.inc.php'; - const BOOTSTRAP_FILE = 'config/bootstrap.php'; - - protected $logger; - - /** - * The path of the bootsrap file we want to use for the installation. - * - * @var string - */ - protected $bootstrapFile = null; - - /** - * The path of the settings file we want to use for the installation. - * - * @var string - */ - protected $settingsFile = null; - - public function __construct($settingsFile = null, $bootstrapFile = null) - { - if ($bootstrapFile === null) { - $bootstrapFile = static::BOOTSTRAP_FILE; - } - - if ($settingsFile === null) { - $settingsFile = static::SETTINGS_FILE; - } - - $this->settingsFile = $settingsFile; - $this->bootstrapFile = $bootstrapFile; - parent::__construct(); - } - - public function setError($errors) - { - static $logger = null; - - if (null === $logger) { - $logger = new FileLogger(); - $logger->setFilename( - _PS_ROOT_DIR_ . '/var/logs/' . _PS_ENV_ . '_' . @date('Ymd') . '_installation.log' - ); - $this->logger = $logger; - } - - if (!is_array($errors)) { - $errors = [$errors]; - } - - parent::setError($errors); - - foreach ($errors as $error) { - $this->logger->logError($error); - } - } - - /** - * Generate the settings file. - */ - public function generateSettingsFile( - $database_host, - $database_user, - $database_password, - $database_name, - $database_prefix, - $database_engine - ) { - // Check permissions for settings file - if ( - file_exists(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $this->settingsFile) - && !is_writable(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $this->settingsFile) - ) { - $this->setError($this->translator->trans('%file% file is not writable (check permissions)', ['%file%' => $this->settingsFile], 'Install')); - - return false; - } elseif ( - !file_exists(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . $this->settingsFile) - && !is_writable(_PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . dirname($this->settingsFile)) - ) { - $this->setError( - $this->translator->trans( - '%folder% folder is not writable (check permissions)', - ['%folder%' => dirname($this->settingsFile)], - 'Install' - ) - ); - - return false; - } - - $secret = Tools::passwdGen(64); - $cookie_key = defined('_COOKIE_KEY_') ? _COOKIE_KEY_ : Tools::passwdGen(64); - $cookie_iv = defined('_COOKIE_IV_') ? _COOKIE_IV_ : Tools::passwdGen(32); - $database_port = null; - - $splits = preg_split('#:#', $database_host); - $nbSplits = count($splits); - - if ($nbSplits >= 2) { - $database_port = array_pop($splits); - $database_host = implode(':', $splits); - } - - $key = PhpEncryption::createNewRandomKey(); - - $parameters = [ - 'parameters' => [ - 'database_host' => $database_host, - 'database_port' => $database_port, - 'database_user' => $database_user, - 'database_password' => $database_password, - 'database_name' => $database_name, - 'database_prefix' => $database_prefix, - 'database_engine' => $database_engine, - 'cookie_key' => $cookie_key, - 'cookie_iv' => $cookie_iv, - 'new_cookie_key' => $key, - 'ps_creation_date' => date('Y-m-d'), - 'secret' => $secret, - 'locale' => $this->language->getLanguage()->getLocale(), - ], - ]; - - array_walk($parameters['parameters'], function (&$param) { - $param = str_replace('%', '%%', $param); - }); - - $parameters = array_replace_recursive( - Yaml::parse(file_get_contents(_PS_ROOT_DIR_ . '/app/config/parameters.yml.dist')), - $parameters - ); - - $settings_content = "settingsFile, $settings_content)) { - $this->setError($this->translator->trans('Cannot write settings file', [], 'Install')); - - return false; - } - - if (!$this->processParameters($parameters)) { - return false; - } - - return true; - } - - /** - * Replace "parameters.yml" with "parameters.php" in "app/config". - * - * @param $parameters - * - * @return bool|int - */ - public function processParameters($parameters) - { - $parametersContent = sprintf('setError($this->translator->trans('Cannot write app/config/parameters.php file', [], 'Install')); - - return false; - } else { - return $this->emptyYamlParameters(); - } - } - - /** - * Prevent availability of YAML parameters. - */ - protected function emptyYamlParameters() - { - if (!file_put_contents(_PS_ROOT_DIR_ . '/app/config/parameters.yml', 'parameters:')) { - $this->setError($this->translator->trans('Cannot write app/config/parameters.yml file', [], 'Install')); - - return false; - } - - return $this->clearCache(); - } - - protected function clearCache() - { - if (defined('_PS_IN_TEST_')) { - return true; - } - - try { - Tools::clearSf2Cache('prod'); - Tools::clearSf2Cache('dev'); - } catch (\Exception $e) { - $this->setError($e->getMessage()); - - return false; - } - - return true; - } - - /** - * PROCESS : installDatabase - * Generate settings file and create database structure. - */ - public function installDatabase($clear_database = false) - { - // Clear database (only tables with same prefix) - require_once _PS_ROOT_DIR_ . '/' . $this->bootstrapFile; - if ($clear_database) { - $this->clearDatabase(); - } - - $allowed_collation = ['utf8mb4_general_ci', 'utf8mb4_unicode_ci']; - $collation_database = Db::getInstance()->getValue('SELECT @@collation_database'); - // Install database structure - $sql_loader = new SqlLoader(); - $sql_loader->setMetaData([ - 'PREFIX_' => _DB_PREFIX_, - 'ENGINE_TYPE' => _MYSQL_ENGINE_, - 'COLLATION' => (empty($collation_database) || !in_array($collation_database, $allowed_collation)) ? '' : 'COLLATE ' . $collation_database, - ]); - - try { - $sql_loader->parse_file(_PS_INSTALL_DATA_PATH_ . 'db_structure.sql'); - } catch (PrestashopInstallerException $e) { - $this->setError($this->translator->trans('Database structure file not found', [], 'Install')); - - return false; - } - - if ($errors = $sql_loader->getErrors()) { - foreach ($errors as $error) { - $this->setError($this->translator->trans('SQL error on query %query%', ['%query%' => $error['error']], 'Install')); - } - - return false; - } - - return $this->generateSf2ProductionEnv(); - } - - /** - * Pass SF2 to production - * cache:clear - * assetic:dump - * doctrine:schema:update. - * - * @return bool - */ - public function generateSf2ProductionEnv() - { - if (defined('_PS_IN_TEST_')) { - return true; - } - $schemaUpgrade = new UpgradeDatabase(); - $schemaUpgrade->addDoctrineSchemaUpdate(); - $output = $schemaUpgrade->execute(); - - if (0 !== $output['prestashop:schema:update-without-foreign']['exitCode']) { - $this->setError(explode("\n", $output['prestashop:schema:update-without-foreign']['output'])); - - return false; - } - - return true; - } - - /** - * Clear database (only tables with same prefix). - * - * @param bool $truncate If true truncate the table, if false drop the table - */ - public function clearDatabase($truncate = false) - { - $instance = Db::getInstance(); - $instance->execute('SET FOREIGN_KEY_CHECKS=0'); - foreach ($instance->executeS('SHOW TABLES') as $row) { - $table = current($row); - if (!_DB_PREFIX_ || preg_match('#^' . _DB_PREFIX_ . '#i', $table)) { - $instance->execute((($truncate) ? 'TRUNCATE TABLE ' : 'DROP TABLE ') . '`' . $table . '`'); - } - } - - $instance->execute('SET FOREIGN_KEY_CHECKS=1'); - } - - /** - * Initialize the prestashop context with default values during tests. - */ - public function initializeTestContext() - { - $smarty = null; - // Clean all cache values - Cache::clean('*'); - - $_SERVER['HTTP_HOST'] = 'localhost'; - $this->language->setLanguage('en'); - $context = Context::getContext(); - $context->shop = new Shop(1); - Shop::setContext(Shop::CONTEXT_SHOP, 1); - Configuration::loadConfiguration(); - if (!isset($context->language) || !Validate::isLoadedObject($context->language)) { - $context->language = new Language('en'); - } - - if (!isset($context->country) || !Validate::isLoadedObject($context->country)) { - if ($id_country = (int) Configuration::get('PS_COUNTRY_DEFAULT')) { - $context->country = new Country((int) $id_country); - } - } - if (!isset($context->currency) || !Validate::isLoadedObject($context->currency)) { - if ($id_currency = (int) Configuration::get('PS_CURRENCY_DEFAULT')) { - $context->currency = new Currency((int) $id_currency); - } - } - - /* Instantiate cookie */ - $cookie_lifetime = defined('_PS_ADMIN_DIR_') ? (int) Configuration::get('PS_COOKIE_LIFETIME_BO') : (int) Configuration::get('PS_COOKIE_LIFETIME_FO'); - if ($cookie_lifetime > 0) { - $cookie_lifetime = time() + (max($cookie_lifetime, 1) * 3600); - } - - $cookie = new Cookie('ps-s' . $context->shop->id, '', $cookie_lifetime, 'localhost', false, false); - - $context->cookie = $cookie; - - $context->cart = new Cart(); - $context->employee = new Employee(1); - if (!defined('_PS_SMARTY_FAST_LOAD_')) { - define('_PS_SMARTY_FAST_LOAD_', true); - } - require_once _PS_ROOT_DIR_ . '/config/smarty.config.inc.php'; - - $context->smarty = $smarty; - } - - /** - * PROCESS : installDefaultData - * Create default shop and languages. - */ - public function installDefaultData($shop_name, $iso_country = false, $all_languages = false, $clear_database = false) - { - if ($clear_database) { - $this->clearDatabase(true); - } - - // Install first shop - if (!$this->createShop($shop_name)) { - return false; - } - - // Install languages - try { - if (!$all_languages) { - $iso_codes_to_install = [$this->language->getLanguageIso()]; - if ($iso_country) { - $version = str_replace('.', '', AppKernel::VERSION); - $version = substr($version, 0, 2); - $localization_file_content = $this->getLocalizationPackContent($version, $iso_country); - - if ($xml = @simplexml_load_string($localization_file_content)) { - foreach ($xml->languages->language as $language) { - $iso_codes_to_install[] = (string) $language->attributes()->iso_code; - } - } - } - $iso_codes_to_install = array_unique($iso_codes_to_install); - } else { - $iso_codes_to_install = null; - } - $languages = $this->installLanguages($iso_codes_to_install); - } catch (PrestashopInstallerException $e) { - $this->setError($e->getMessage()); - - return false; - } - - $flip_languages = array_flip($languages); - $id_lang = (!empty($flip_languages[$this->language->getLanguageIso()])) ? $flip_languages[$this->language->getLanguageIso()] : 1; - Configuration::updateGlobalValue('PS_LANG_DEFAULT', $id_lang); - Configuration::updateGlobalValue('PS_VERSION_DB', _PS_INSTALL_VERSION_); - Configuration::updateGlobalValue('PS_INSTALL_VERSION', _PS_INSTALL_VERSION_); - - Context::getContext()->language = new LanguageLegacy($id_lang); - - return true; - } - - /** - * PROCESS : populateDatabase - * Populate database with default data. - */ - public function populateDatabase($entity = null) - { - $languages = []; - foreach (EntityLanguage::getLanguages(true) as $lang) { - $languages[$lang['id_lang']] = $lang['iso_code']; - } - - // Install XML data (data/xml/ folder) - $xml_loader = new XmlLoader(); - $xml_loader->setTranslator($this->translator); - $xml_loader->setLanguages($languages); - - if (isset($this->xml_loader_ids) && $this->xml_loader_ids) { - $xml_loader->setIds($this->xml_loader_ids); - } - - try { - if ($entity) { - $xml_loader->populateEntity($entity); - } else { - $xml_loader->populateFromXmlFiles(); - } - if ($errors = $xml_loader->getErrors()) { - $this->setError($errors); - - return false; - } - - // IDS from xmlLoader are stored in order to use them for fixtures - $this->xml_loader_ids = $xml_loader->getIds(); - unset($xml_loader); - - // Install custom SQL data (db_data.sql file) - if (file_exists(_PS_INSTALL_DATA_PATH_ . 'db_data.sql')) { - $sql_loader = new SqlLoader(); - $sql_loader->setMetaData([ - 'PREFIX_' => _DB_PREFIX_, - 'ENGINE_TYPE' => _MYSQL_ENGINE_, - ]); - - $sql_loader->parse_file(_PS_INSTALL_DATA_PATH_ . 'db_data.sql', false); - if ($errors = $sql_loader->getErrors()) { - $this->setError($errors); - - return false; - } - } - } catch (PrestashopInstallerException $e) { - $this->setError($e->getMessage()); - - return false; - } - - return true; - } - - public function createShop($shop_name) - { - // Create default group shop - $shop_group = new ShopGroup(); - $shop_group->name = 'Default'; - $shop_group->active = true; - if (!$shop_group->add()) { - $this->setError($this->translator->trans('Cannot create group shop', [], 'Install') . ' / ' . Db::getInstance()->getMsgError()); - - return false; - } - - // Create default shop - $shop = new Shop(); - $shop->active = true; - $shop->id_shop_group = $shop_group->id; - $shop->id_category = 2; - $shop->theme_name = _THEME_NAME_; - $shop->name = $shop_name; - if (!$shop->add()) { - $this->setError($this->translator->trans('Cannot create shop', [], 'Install') . ' / ' . Db::getInstance()->getMsgError()); - - return false; - } - $shop->setTheme(); - Context::getContext()->shop = $shop; - - // Create default shop URL - $shop_url = new ShopUrl(); - $shop_url->domain = Tools::getHttpHost(); - $shop_url->domain_ssl = Tools::getHttpHost(); - $shop_url->physical_uri = __PS_BASE_URI__; - $shop_url->id_shop = $shop->id; - $shop_url->main = true; - $shop_url->active = true; - if (!$shop_url->add()) { - $this->setError($this->translator->trans('Cannot create shop URL', [], 'Install') . ' / ' . Db::getInstance()->getMsgError()); - - return false; - } - - return true; - } - - /** - * Install languages. - * - * @return array Association between ID and iso array(id_lang => iso, ...) - */ - public function installLanguages($languages_list = null) - { - if ($languages_list == null || !is_array($languages_list) || !count($languages_list)) { - $languages_list = $this->language->getIsoList(); - } - - $languages_list = array_unique($languages_list); - - $languages_available = $this->language->getIsoList(); - $languages = []; - - foreach ($languages_list as $iso) { - if (!in_array($iso, $languages_available)) { - EntityLanguage::downloadAndInstallLanguagePack($iso); - - continue; - } - - if (!file_exists(_PS_INSTALL_LANGS_PATH_ . $iso . '/language.xml')) { - throw new PrestashopInstallerException($this->translator->trans('File "language.xml" not found for language iso "%iso%"', ['%iso%' => $iso], 'Install')); - } - - if (!$xml = @simplexml_load_file(_PS_INSTALL_LANGS_PATH_ . $iso . '/language.xml')) { - throw new PrestashopInstallerException($this->translator->trans('File "language.xml" not valid for language iso "%iso%"', ['%iso%' => $iso], 'Install')); - } - - $params_lang = [ - 'name' => (string) $xml->name, - 'iso_code' => substr((string) $xml->language_code, 0, 2), - 'allow_accented_chars_url' => (string) $xml->allow_accented_chars_url, - 'language_code' => (string) $xml->language_code, - 'locale' => (string) $xml->locale, - ]; - - if (InstallSession::getInstance()->safe_mode) { - EntityLanguage::checkAndAddLanguage($iso, false, true, $params_lang); - } else { - if (file_exists(_PS_TRANSLATIONS_DIR_ . (string) $iso . '.gzip') == false) { - $language = EntityLanguage::downloadLanguagePack($iso, _PS_INSTALL_VERSION_); - - if ($language == false) { - throw new PrestashopInstallerException($this->translator->trans('Cannot download language pack "%iso%"', ['%iso%' => $iso], 'Install')); - } - } - - $errors = []; - EntityLanguage::installLanguagePack($iso, $params_lang, $errors); - } - - EntityLanguage::loadLanguages(); - - Tools::clearCache(); - - if (!$id_lang = EntityLanguage::getIdByIso($iso, true)) { - throw new PrestashopInstallerException($this->translator->trans('Cannot install language "%iso%"', ['%iso%' => ($xml->name ? $xml->name : $iso)], 'Install')); - } - - $languages[$id_lang] = $iso; - - // Copy language flag - if (is_writable(_PS_IMG_DIR_ . 'l/')) { - if (!copy(_PS_INSTALL_LANGS_PATH_ . $iso . '/flag.jpg', _PS_IMG_DIR_ . 'l/' . $id_lang . '.jpg')) { - throw new PrestashopInstallerException($this->translator->trans('Cannot copy flag language "%flag%"', ['%flag%' => _PS_INSTALL_LANGS_PATH_ . $iso . '/flag.jpg => ' . _PS_IMG_DIR_ . 'l/' . $id_lang . '.jpg'], 'Install')); - } - } - } - - return $languages; - } - - public function copyLanguageImages($iso) - { - $img_path = _PS_INSTALL_LANGS_PATH_ . $iso . '/img/'; - if (!is_dir($img_path)) { - return; - } - - $list = [ - 'products' => _PS_PROD_IMG_DIR_, - 'categories' => _PS_CAT_IMG_DIR_, - 'manufacturers' => _PS_MANU_IMG_DIR_, - 'suppliers' => _PS_SUPP_IMG_DIR_, - 'stores' => _PS_STORE_IMG_DIR_, - null => _PS_IMG_DIR_ . 'l/', // Little trick to copy images in img/l/ path with all types - ]; - - foreach ($list as $cat => $dst_path) { - if (!is_writable($dst_path)) { - continue; - } - - copy($img_path . $iso . '.jpg', $dst_path . $iso . '.jpg'); - - $types = ImageType::getImagesTypes($cat); - foreach ($types as $type) { - if (file_exists($img_path . $iso . '-default-' . $type['name'] . '.jpg')) { - copy( - $img_path . $iso . '-default-' . $type['name'] . '.jpg', - $dst_path . $iso . '-default-' . $type['name'] . '.jpg' - ); - } else { - ImageManager::resize( - $img_path . $iso . '.jpg', - $dst_path . $iso . '-default-' . $type['name'] . '.jpg', - $type['width'], - $type['height'] - ); - } - } - } - } - - private static $_cache_localization_pack_content = null; - - public function getLocalizationPackContent($version, $country) - { - if (static::$_cache_localization_pack_content === null || array_key_exists($country, static::$_cache_localization_pack_content)) { - $localizationWarmer = new LocalizationWarmer($version, $country); - $localization_file_content = $localizationWarmer->warmUp(_PS_CACHE_DIR_ . 'sandbox' . DIRECTORY_SEPARATOR); - - static::$_cache_localization_pack_content[$country] = $localization_file_content; - } - - return isset(static::$_cache_localization_pack_content[$country]) ? static::$_cache_localization_pack_content[$country] : false; - } - - /** - * PROCESS : configureShop - * Set default shop configuration. - */ - public function configureShop(array $data = []) - { - //clear image cache in tmp folder - if (file_exists(_PS_TMP_IMG_DIR_)) { - foreach (scandir(_PS_TMP_IMG_DIR_, SCANDIR_SORT_NONE) as $file) { - if ($file[0] != '.' && $file != 'index.php') { - Tools::deleteFile(_PS_TMP_IMG_DIR_ . $file); - } - } - } - - $default_data = [ - 'shop_name' => 'My Shop', - 'shop_activity' => '', - 'shop_country' => 'us', - 'shop_timezone' => 'US/Eastern', // TODO : this timezone is deprecated - 'use_smtp' => false, - 'smtp_encryption' => 'off', - 'smtp_port' => 25, - 'rewrite_engine' => false, - 'enable_ssl' => false, - ]; - - foreach ($default_data as $k => $v) { - if (!isset($data[$k])) { - $data[$k] = $v; - } - } - - Context::getContext()->shop = new Shop(1); - Configuration::loadConfiguration(); - - $id_country = (int) Country::getByIso($data['shop_country']); - - // Set default configuration - Configuration::updateGlobalValue('PS_SHOP_DOMAIN', Tools::getHttpHost()); - Configuration::updateGlobalValue('PS_SHOP_DOMAIN_SSL', Tools::getHttpHost()); - Configuration::updateGlobalValue('PS_INSTALL_VERSION', _PS_INSTALL_VERSION_); - Configuration::updateGlobalValue('PS_LOCALE_LANGUAGE', $this->language->getLanguageIso()); - Configuration::updateGlobalValue('PS_SHOP_NAME', $data['shop_name']); - Configuration::updateGlobalValue('PS_SHOP_ACTIVITY', $data['shop_activity']); - Configuration::updateGlobalValue('PS_COUNTRY_DEFAULT', $id_country); - Configuration::updateGlobalValue('PS_LOCALE_COUNTRY', $data['shop_country']); - Configuration::updateGlobalValue('PS_TIMEZONE', $data['shop_timezone']); - Configuration::updateGlobalValue('PS_CONFIGURATION_AGREMENT', (int) $data['configuration_agrement']); - - // Set SSL configuration - Configuration::updateGlobalValue('PS_SSL_ENABLED', (int) $data['enable_ssl']); - Configuration::updateGlobalValue('PS_SSL_ENABLED_EVERYWHERE', (int) $data['enable_ssl']); - - // Set mails configuration - Configuration::updateGlobalValue('PS_MAIL_METHOD', ($data['use_smtp']) ? 2 : 1); - Configuration::updateGlobalValue('PS_MAIL_SMTP_ENCRYPTION', $data['smtp_encryption']); - Configuration::updateGlobalValue('PS_MAIL_SMTP_PORT', $data['smtp_port']); - - // Set default rewriting settings - Configuration::updateGlobalValue('PS_REWRITING_SETTINGS', $data['rewrite_engine']); - - $groups = Group::getGroups((int) Configuration::get('PS_LANG_DEFAULT')); - $groups_default = Db::getInstance()->executeS('SELECT `name` FROM ' . _DB_PREFIX_ . 'configuration WHERE `name` LIKE "PS_%_GROUP" ORDER BY `id_configuration`'); - foreach ($groups_default as &$group_default) { - if (is_array($group_default) && isset($group_default['name'])) { - $group_default = $group_default['name']; - } - } - - if (is_array($groups) && count($groups)) { - foreach ($groups as $key => $group) { - if (Configuration::get($groups_default[$key]) != $groups[$key]['id_group']) { - Configuration::updateGlobalValue($groups_default[$key], (int) $groups[$key]['id_group']); - } - } - } - - $states = Db::getInstance()->executeS('SELECT `id_order_state` FROM ' . _DB_PREFIX_ . 'order_state ORDER by `id_order_state`'); - $states_default = Db::getInstance()->executeS('SELECT MIN(`id_configuration`), `name` FROM ' . _DB_PREFIX_ . 'configuration WHERE `name` LIKE "PS_OS_%" GROUP BY `value` ORDER BY`id_configuration`'); - - foreach ($states_default as &$state_default) { - if (is_array($state_default) && isset($state_default['name'])) { - $state_default = $state_default['name']; - } - } - - if (is_array($states) && count($states)) { - foreach ($states as $key => $state) { - if (Configuration::get($states_default[$key]) != $states[$key]['id_order_state']) { - Configuration::updateGlobalValue($states_default[$key], (int) $states[$key]['id_order_state']); - } - } - /* deprecated order state */ - Configuration::updateGlobalValue('PS_OS_OUTOFSTOCK_PAID', (int) Configuration::get('PS_OS_OUTOFSTOCK')); - } - - // Set logo configuration - if (file_exists(_PS_IMG_DIR_ . 'logo.png')) { - list($width, $height) = getimagesize(_PS_IMG_DIR_ . 'logo.png'); - Configuration::updateGlobalValue('SHOP_LOGO_WIDTH', round($width)); - Configuration::updateGlobalValue('SHOP_LOGO_HEIGHT', round($height)); - } - - // Disable cache for debug mode - if (_PS_MODE_DEV_) { - Configuration::updateGlobalValue('PS_SMARTY_CACHE', 1); - } - - // Active only the country selected by the merchant - Db::getInstance()->execute('UPDATE ' . _DB_PREFIX_ . 'country SET active = 0 WHERE id_country != ' . (int) $id_country); - - // Set localization configuration - $version = str_replace('.', '', AppKernel::VERSION); - $version = substr($version, 0, 2); - $localization_file_content = $this->getLocalizationPackContent($version, $data['shop_country']); - - $locale = new LocalizationPack(); - $locale->loadLocalisationPack($localization_file_content, false, true); - - // Create default employee - if (isset($data['admin_firstname'], $data['admin_lastname'], $data['admin_password'], $data['admin_email'])) { - $employee = new Employee(); - $employee->firstname = Tools::ucfirst($data['admin_firstname']); - $employee->lastname = Tools::ucfirst($data['admin_lastname']); - $employee->email = $data['admin_email']; - $employee->setWsPasswd($data['admin_password']); - $employee->last_passwd_gen = date('Y-m-d h:i:s', strtotime('-360 minutes')); - $employee->bo_theme = 'default'; - $employee->default_tab = 1; - $employee->active = true; - $employee->id_profile = 1; - $employee->id_lang = Configuration::get('PS_LANG_DEFAULT'); - $employee->bo_menu = 1; - if (!$employee->add()) { - $this->setError($this->translator->trans('Cannot create admin account', [], 'Install')); - - return false; - } - } else { - $this->setError($this->translator->trans('Cannot create admin account', [], 'Install')); - - return false; - } - - // Update default contact - if (isset($data['admin_email'])) { - Configuration::updateGlobalValue('PS_SHOP_EMAIL', $data['admin_email']); - - $contacts = new PrestaShopCollection('Contact'); - foreach ($contacts as $contact) { - $contact->email = $data['admin_email']; - $contact->update(); - } - } - - if (!@Tools::generateHtaccess(null, $data['rewrite_engine'])) { - Configuration::updateGlobalValue('PS_REWRITING_SETTINGS', 0); - } - - Tools::generateRobotsFile(); - - return true; - } - - public function getModulesList() - { - $modules = []; - if (false) { - foreach (scandir(_PS_MODULE_DIR_, SCANDIR_SORT_NONE) as $module) { - if ($module[0] != '.' && is_dir(_PS_MODULE_DIR_ . $module) && file_exists(_PS_MODULE_DIR_ . $module . '/' . $module . '.php')) { - $modules[] = $module; - } - } - } else { - $modules = [ - 'contactform', - 'dashactivity', - 'dashgoals', - 'dashproducts', - 'dashtrends', - 'graphnvd3', - 'gridhtml', - 'gsitemap', - 'pagesnotfound', - 'productcomments', - 'ps_banner', - 'ps_categorytree', - 'ps_checkpayment', - 'ps_contactinfo', - 'ps_crossselling', - 'ps_currencyselector', - 'ps_customeraccountlinks', - 'ps_customersignin', - 'ps_customtext', - 'ps_dataprivacy', - 'ps_emailsubscription', - 'ps_facetedsearch', - 'ps_faviconnotificationbo', - 'ps_featuredproducts', - 'ps_imageslider', - 'ps_languageselector', - 'ps_linklist', - 'ps_mainmenu', - 'ps_searchbar', - 'ps_sharebuttons', - 'ps_shoppingcart', - 'ps_socialfollow', - 'ps_themecusto', - 'ps_wirepayment', - 'sekeywords', - 'statsbestcategories', - 'statsbestcustomers', - 'statsbestproducts', - 'statsbestsuppliers', - 'statsbestvouchers', - 'statscarrier', - 'statscatalog', - 'statscheckup', - 'statsdata', - 'statsequipment', - 'statsforecast', - 'statslive', - 'statsnewsletter', - 'statsorigin', - 'statspersonalinfos', - 'statsproduct', - 'statsregistrations', - 'statssales', - 'statssearch', - 'statsstock', - 'statsvisits', - 'welcome', - ]; - } - - return $modules; - } - - public function getAddonsModulesList($params = []) - { - /** - * TODO: Remove blacklist once 1.7 is out. - */ - $blacklist = [ - 'bankwire', - 'blockadvertising', - 'blockbanner', - 'blockbestsellers', - 'blockcart', - 'blockcategories', - 'blockcms', - 'blockcmsinfo', - 'blockcontact', - 'blockcontactinfos', - 'blockcurrencies', - 'blockcustomerprivacy', - 'blockfacebook', - 'blocklanguages', - 'blocklayered', - 'blocklink', - 'blockmanufacturer', - 'blockmyaccount', - 'blockmyaccountfooter', - 'blocknewproducts', - 'blocknewsletter', - 'blockpaymentlogo', - 'blockpermanentlinks', - 'blockrss', - 'blocksearch', - 'blocksharefb', - 'blocksocial', - 'blockstore', - 'blockspecials', - 'blocksupplier', - 'blocktags', - 'blocktopmenu', - 'blockuserinfo', - 'blockviewed', - 'blockwishlist', - 'cheque', - 'crossselling', - 'homefeatured', - 'homeslider', - 'onboarding', - 'productscategory', - 'producttooltip', - 'sendtoafriend', - 'socialsharing', - ]; - - $addons_modules = []; - $content = Tools::addonsRequest('install-modules', $params); - $xml = @simplexml_load_string($content, null, LIBXML_NOCDATA); - - if ($xml !== false && isset($xml->module)) { - foreach ($xml->module as $modaddons) { - if (in_array($modaddons->name, $blacklist)) { - continue; - } - $addons_modules[] = ['id_module' => $modaddons->id, 'name' => $modaddons->name]; - } - } - - return $addons_modules; - } - - /** - * PROCESS : installModules - * Download module from addons and Install all modules in ~/modules/ directory. - */ - public function installModulesAddons($module = null) - { - $addons_modules = $module ? [$module] : $this->getAddonsModulesList(); - $modules = []; - - foreach ($addons_modules as $addons_module) { - if (file_put_contents(_PS_MODULE_DIR_ . $addons_module['name'] . '.zip', Tools::addonsRequest('module', ['id_module' => $addons_module['id_module']]))) { - if (Tools::ZipExtract(_PS_MODULE_DIR_ . $addons_module['name'] . '.zip', _PS_MODULE_DIR_)) { - $modules[] = (string) $addons_module['name']; //if the module has been unziped we add the name in the modules list to install - unlink(_PS_MODULE_DIR_ . $addons_module['name'] . '.zip'); - } - } - } - - return count($modules) ? $this->installModules($modules) : true; - } - - /** - * PROCESS : installModules - * Download module from addons and Install all modules in ~/modules/ directory. - */ - public function installModules($module = null) - { - if ($module && !is_array($module)) { - $module = [$module]; - } - - $modules = $module ? $module : $this->getModulesList(); - - Module::updateTranslationsAfterInstall(false); - - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManager = $moduleManagerBuilder->build(); - - $errors = []; - foreach ($modules as $module_name) { - if (!file_exists(_PS_MODULE_DIR_ . $module_name . '/' . $module_name . '.php')) { - continue; - } - - $moduleException = null; - - try { - $moduleInstalled = $moduleManager->install($module_name); - } catch (\PrestaShopException $e) { - $moduleInstalled = false; - $moduleException = $e->getMessage(); - } - - if (!$moduleInstalled) { - $module_errors = [$this->translator->trans('Cannot install module "%module%"', ['%module%' => $module_name], 'Install')]; - if (null !== $moduleException) { - $module_errors[] = $moduleException; - } - $errors[$module_name] = $module_errors; - } - } - - if ($errors) { - $this->setError($errors); - - return false; - } - - Module::updateTranslationsAfterInstall(true); - EntityLanguage::updateModulesTranslations($modules); - - return true; - } - - /** - * PROCESS : installFixtures - * Install fixtures (E.g. demo products). - */ - public function installFixtures($entity = null, array $data = []) - { - $fixtures_path = _PS_INSTALL_FIXTURES_PATH_ . 'fashion/'; - $fixtures_name = 'fashion'; - $zip_file = _PS_ROOT_DIR_ . '/download/fixtures.zip'; - $temp_dir = _PS_ROOT_DIR_ . '/download/fixtures/'; - - // Load class (use fixture class if one exists, or use InstallXmlLoader) - if (file_exists($fixtures_path . '/install.php')) { - require_once $fixtures_path . '/install.php'; - $class = 'InstallFixtures' . Tools::toCamelCase($fixtures_name); - if (!class_exists($class, false)) { - $this->setError($this->translator->trans('Fixtures class "%class%" not found', ['%class%' => $class], 'Install')); - - return false; - } - - $xml_loader = new $class(); - if (!$xml_loader instanceof XmlLoader) { - $this->setError($this->translator->trans('"%class%" must be an instance of "InstallXmlLoader"', ['%class%' => $class], 'Install')); - - return false; - } - } else { - $xml_loader = new XmlLoader(); - $xml_loader->setTranslator($this->translator); - } - - // Install XML data (data/xml/ folder) - $xml_loader->setFixturesPath($fixtures_path); - if (isset($this->xml_loader_ids) && $this->xml_loader_ids) { - $xml_loader->setIds($this->xml_loader_ids); - } - - $languages = []; - foreach (EntityLanguage::getLanguages(false) as $lang) { - $languages[$lang['id_lang']] = $lang['iso_code']; - } - $xml_loader->setLanguages($languages); - - if ($entity) { - $xml_loader->populateEntity($entity); - } else { - $xml_loader->populateFromXmlFiles(); - Tools::deleteDirectory($temp_dir, true); - @unlink($zip_file); - } - - if ($errors = $xml_loader->getErrors()) { - $this->setError($errors); - - return false; - } - - // IDS from xmlLoader are stored in order to use them for fixtures - $this->xml_loader_ids = $xml_loader->getIds(); - unset($xml_loader); - - if ($entity === 'category' || $entity === null) { - Category::regenerateEntireNtree(); - } - - if ($entity === null) { - Search::indexation(true); - } - - // Update fixtures lang - foreach ($languages as $lang) { - LanguageLegacy::updateMultilangTable($lang); - } - - return true; - } - - public function installTheme($themeName = null) - { - $themeName = $themeName ?: _THEME_NAME_; - $builder = new ThemeManagerBuilder( - Context::getContext(), - Db::getInstance() - ); - - $theme_manager = $builder->build(); - - if (!($theme_manager->install($themeName) && $theme_manager->enable($themeName))) { - return false; - } - - /* - * Copy language default images. - * We do this action after install theme because we - * need image types information. - */ - $languages = $this->language->getIsoList(); - foreach ($languages as $iso) { - $this->copyLanguageImages($iso); - } - - return true; - } -} diff --git a/src/PrestaShopBundle/Install/Language.php b/src/PrestaShopBundle/Install/Language.php deleted file mode 100644 index 544f3845..00000000 --- a/src/PrestaShopBundle/Install/Language.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -class Language -{ - public $id; - public $name; - public $locale; - public $iso_code; - public $language_code; - public $is_rtl; - public $date_format_lite; - public $date_format_full; - public $countries; - - public function __construct($iso) - { - $this->iso_code = strtolower($iso); - $xmlPath = _PS_INSTALL_LANGS_PATH_ . $iso . '/'; - $this->setPropertiesFromXml($xmlPath); - $this->is_rtl = ($this->is_rtl === 'true') ? true : false; - } - - public function setPropertiesFromXml($xmlPath) - { - $xml = @simplexml_load_file($xmlPath . '/language.xml'); - if ($xml) { - foreach ($xml->children() as $node) { - $this->{$node->getName()} = (string) $node; - } - } - } - - /** - * Get name. - * - * @return mixed - */ - public function getName() - { - return $this->name; - } - - /** - * Get locale. - * - * @return mixed - */ - public function getLocale() - { - return $this->locale; - } - - /** - * Get language_code. - * - * @return mixed - */ - public function getLanguageCode() - { - return $this->language_code; - } - - /** - * Get is_rtl. - * - * @return mixed - */ - public function isRtl() - { - return $this->is_rtl; - } - - /** - * Get date_format_lite. - * - * @return mixed - */ - public function getDateFormatLite() - { - return $this->date_format_lite; - } - - /** - * Get date_format_full. - * - * @return mixed - */ - public function getDateFormatFull() - { - return $this->date_format_full; - } - - public function getCountries() - { - if (!is_array($this->countries)) { - $this->countries = []; - $filename = _PS_INSTALL_LANGS_PATH_ . substr($this->language_code, 0, 2) . '/data/country.xml'; - - if (!file_exists($filename)) { - $filename = _PS_INSTALL_LANGS_PATH_ . 'en/data/country.xml'; - } - - if ($xml = @simplexml_load_file($filename)) { - foreach ($xml->country as $country) { - $this->countries[strtolower((string) $country['id'])] = (string) $country->name; - } - } - } - - return $this->countries; - } -} diff --git a/src/PrestaShopBundle/Install/LanguageList.php b/src/PrestaShopBundle/Install/LanguageList.php deleted file mode 100644 index 19109d08..00000000 --- a/src/PrestaShopBundle/Install/LanguageList.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use PrestashopInstallerException; -use Symfony\Component\Finder\Finder; - -class LanguageList -{ - const DEFAULT_ISO = 'en'; - - /** - * @var array List of available languages - */ - protected $languages; - - /** - * @var string Current language - */ - protected $language; - - public $locale; - - public $id; - - /** - * @var Language Default language (english) - */ - protected $default; - - protected static $_instance; - - public static function getInstance() - { - if (!self::$_instance) { - self::$_instance = new self(); - } - - return self::$_instance; - } - - public function __construct() - { - // English language is required - if (!file_exists(_PS_INSTALL_LANGS_PATH_ . 'en/language.xml')) { - throw new PrestashopInstallerException('English language is missing'); - } - - $this->languages = [ - self::DEFAULT_ISO => new Language(self::DEFAULT_ISO), - ]; - - // Load other languages - foreach ((new Finder())->files()->name('language.xml')->in(_PS_INSTALL_LANGS_PATH_) as $langFile) { - $this->languages[$langFile->getRelativePath()] = new Language($langFile->getRelativePath()); - } - uasort($this->languages, function ($a, $b) { - $aname = $a->getName(); - $bname = $b->getName(); - if ($aname == $bname) { - return 0; - } - - return ($aname < $bname) ? -1 : 1; - }); - } - - /** - * Set current language. - * - * @param string $iso Language iso - */ - public function setLanguage($iso) - { - if (!in_array($iso, $this->getIsoList())) { - throw new PrestashopInstallerException('Language ' . $iso . ' not found'); - } - $this->language = $iso; - } - - /** - * Get current language. - * - * @return string - */ - public function getLanguageIso() - { - return $this->language; - } - - /** - * Get current language. - * - * @return Language - */ - public function getLanguage($iso = null) - { - if (!$iso) { - $iso = $this->language; - } - - return $this->languages[$iso]; - } - - public function getIsoList() - { - return array_keys($this->languages); - } - - /** - * Get list of languages iso supported by installer. - * - * @return array - */ - public function getLanguages() - { - return $this->languages; - } - - /** - * Get list of countries for current language. - * - * @return array - */ - public function getCountries() - { - static $countries = null; - - if (null === $countries) { - $countries = []; - $countries_lang = $this->getLanguage()->getCountries(); - $countries_default = $this->getLanguage(self::DEFAULT_ISO)->getCountries(); - $xml = @simplexml_load_file(_PS_INSTALL_DATA_PATH_ . 'xml/country.xml'); - if ($xml) { - foreach ($xml->entities->country as $country) { - $iso = strtolower((string) $country['iso_code']); - $countries[$iso] = isset($countries_lang[$iso]) ? $countries_lang[$iso] : $countries_default[$iso]; - } - } - asort($countries); - } - - return $countries; - } - - /** - * Parse HTTP_ACCEPT_LANGUAGE and get first data matching list of available languages. - * - * @return bool|array - */ - public function detectLanguage() - { - // This code is from a php.net comment : http://www.php.net/manual/fr/reserved.variables.server.php#94237 - $split_languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); - if (!is_array($split_languages)) { - return false; - } - - foreach ($split_languages as $lang) { - $pattern = '/^(?P[a-zA-Z]{2,8})' . - '(?:-(?P[a-zA-Z]{2,8}))?(?:(?:;q=)' . - '(?P\d\.\d))?$/'; - if (preg_match($pattern, $lang, $m)) { - if (in_array($m['primarytag'], $this->getIsoList())) { - return $m; - } - } - } - - return false; - } -} diff --git a/src/PrestaShopBundle/Install/Simplexml.php b/src/PrestaShopBundle/Install/Simplexml.php deleted file mode 100644 index 55abeade..00000000 --- a/src/PrestaShopBundle/Install/Simplexml.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use DOMDocument; - -class SimplexmlElement extends \SimpleXMLElement -{ - /** - * Can add SimpleXMLElement values in XML tree. - * - * @see SimpleXMLElement::addChild() - */ - public function addChild($name, $value = null, $namespace = null) - { - if ($value instanceof static) { - $content = trim((string) $value); - if (strlen($content) > 0) { - $new_element = parent::addChild($name, str_replace('&', '&', $content), $namespace); - } else { - $new_element = parent::addChild($name); - foreach ($value->attributes() as $k => $v) { - $new_element->addAttribute($k, $v); - } - } - - foreach ($value->children() as $child) { - $new_element->addChild($child->getName(), $child); - } - } else { - return parent::addChild($name, str_replace('&', '&', $value), $namespace); - } - } - - /** - * Generate nice and sweet XML. - * - * @see SimpleXMLElement::asXML() - */ - public function asXML($filename = null) - { - $dom = new DOMDocument('1.0'); - $dom->preserveWhiteSpace = false; - $dom->formatOutput = true; - $dom->loadXML(parent::asXML()); - - if ($filename) { - return (bool) file_put_contents($filename, $dom->saveXML()); - } - - return $dom->saveXML(); - } -} diff --git a/src/PrestaShopBundle/Install/SqlLoader.php b/src/PrestaShopBundle/Install/SqlLoader.php deleted file mode 100644 index 698cde8d..00000000 --- a/src/PrestaShopBundle/Install/SqlLoader.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use PrestaShop\PrestaShop\Adapter\Entity\Db; -use PrestashopInstallerException; - -class SqlLoader -{ - /** - * @var Db - */ - protected $db; - - /** - * @var array List of keywords which will be replaced in queries - */ - protected $metadata = []; - - /** - * @var array List of errors during last parsing - */ - protected $errors = []; - - /** - * @param Db $db - */ - public function __construct(Db $db = null) - { - if (null === $db) { - $db = Db::getInstance(); - } - $this->db = $db; - } - - /** - * Set a list of keywords which will be replaced in queries. - * - * @param array $data - */ - public function setMetaData(array $data) - { - foreach ($data as $k => $v) { - $this->metadata[$k] = $v; - } - } - - /** - * Parse a SQL file and execute queries. - * - * @deprecated use parseFile() - * - * @param string $filename - * @param bool $stop_when_fail - */ - public function parse_file($filename, $stop_when_fail = true) - { - return $this->parseFile($filename, $stop_when_fail); - } - - /** - * Parse a SQL file and execute queries. - * - * @param string $filename - * @param bool $stop_when_fail - */ - public function parseFile($filename, $stop_when_fail = true) - { - if (!file_exists($filename)) { - throw new PrestashopInstallerException("File $filename not found"); - } - - return $this->parse(file_get_contents($filename), $stop_when_fail); - } - - /** - * Parse and execute a list of SQL queries. - * - * @param string $content - * @param bool $stop_when_fail - */ - public function parse($content, $stop_when_fail = true) - { - $this->errors = []; - - $content = str_replace(array_keys($this->metadata), array_values($this->metadata), $content); - $queries = preg_split('#;\s*[\r\n]+#', $content); - foreach ($queries as $query) { - $query = trim($query); - if (!$query) { - continue; - } - - if (!$this->db->execute($query)) { - $this->errors[] = [ - 'errno' => $this->db->getNumberError(), - 'error' => $this->db->getMsgError(), - 'query' => $query, - ]; - - if ($stop_when_fail) { - return false; - } - } - } - - return count($this->errors) ? false : true; - } - - /** - * Get list of errors from last parsing. - * - * @return array - */ - public function getErrors() - { - return $this->errors; - } -} diff --git a/src/PrestaShopBundle/Install/System.php b/src/PrestaShopBundle/Install/System.php deleted file mode 100644 index 219f30d5..00000000 --- a/src/PrestaShopBundle/Install/System.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use ConfigurationTest; -use Requirement; -use SymfonyRequirements; - -require_once __DIR__ . '/../../../var/SymfonyRequirements.php'; - -class System extends AbstractInstall -{ - public function checkRequiredTests() - { - return self::checkTests(ConfigurationTest::getDefaultTests(), 'required'); - } - - public function checkOptionalTests() - { - return self::checkTests(ConfigurationTest::getDefaultTestsOp(), 'optional'); - } - - //get symfony requirements - public function checkSf2Requirements() - { - $symfonyRequirements = new SymfonyRequirements(); - $errors = $symfonyRequirements->getFailedRequirements(); - - return $errors; - } - - //get symfony recommendations - public function checkSf2Recommendations() - { - $symfonyRequirements = new SymfonyRequirements(); - - $failedRecommendations = $symfonyRequirements->getFailedRecommendations(); - - return array_filter($failedRecommendations, function (Requirement $requirement) { - if ($requirement->getTestMessage() === 'Requirements file should be up-to-date') { - // this warning is not relevant - return false; - } - - return true; - }); - } - - public function checkTests($list, $type) - { - $tests = ConfigurationTest::check($list); - - $success = true; - foreach ($tests as $result) { - $success &= ($result == 'ok') ? true : false; - } - - return [ - 'checks' => $tests, - 'success' => $success, - ]; - } -} diff --git a/src/PrestaShopBundle/Install/Upgrade.php b/src/PrestaShopBundle/Install/Upgrade.php deleted file mode 100644 index 97326d6a..00000000 --- a/src/PrestaShopBundle/Install/Upgrade.php +++ /dev/null @@ -1,1237 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace { - $root_dir = realpath(__DIR__ . '/../../..'); - - require_once $root_dir . '/vendor/paragonie/random_compat/lib/random.php'; - - if (!class_exists('PhpEncryptionEngine')) { - require_once $root_dir . '/classes/PhpEncryptionEngine.php'; - class PhpEncryptionEngine extends \PhpEncryptionEngineCore - { - } - } - - if (!class_exists('PhpEncryptionLegacyEngine')) { - require_once $root_dir . '/classes/PhpEncryptionLegacyEngine.php'; - class PhpEncryptionLegacyEngine extends \PhpEncryptionLegacyEngineCore - { - } - } - - if (!class_exists('PhpEncryption')) { - require_once $root_dir . '/classes/PhpEncryption.php'; - class PhpEncryption extends \PhpEncryptionCore - { - } - } -} - -namespace PrestaShopBundle\Install { - use AppKernel; - use Cache; - use Cart; - use Composer\Script\Event; - use Configuration; - use Context; - use Country; - use Db; - use Employee; - use FileLogger; - use Language; - use Module; - use PhpEncryption; - use PrestaShop\PrestaShop\Adapter\SymfonyContainer; - use PrestaShop\PrestaShop\Core\Addon\AddonListFilter; - use PrestaShop\PrestaShop\Core\Addon\AddonListFilterOrigin; - use PrestaShop\PrestaShop\Core\Addon\AddonListFilterStatus; - use PrestaShop\PrestaShop\Core\Addon\AddonListFilterType; - use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder; - use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder; - use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; - use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; - use PrestaShop\PrestaShop\Core\Exception\CoreException; - use PrestaShopBundle\Service\Database\Upgrade as UpgradeDatabase; - use RandomLib; - use Shop; - use Symfony\Component\Filesystem\Exception\IOException; - use Symfony\Component\Filesystem\Filesystem; - use Symfony\Component\Yaml\Yaml; - use Tools; - use Validate; - - class Upgrade - { - /** @var \FileLogger */ - private $logger; - private $infoList = []; - private $warningList = []; - private $failureList = []; - private $nextQuickInfo = []; - private $nextErrors = []; - private $next; - private $nextDesc; - private $inAutoUpgrade = false; - private $translator; - private $installDir; - private $adminDir = null; - private $oldVersion; - private $db; - private $idEmployee = 0; - private $disableCustomModules = false; - private $changeToDefaultTheme = false; - private $updateDefaultTheme = false; - // used for translations - public static $l_cache; - - const FILE_PREFIX = 'PREFIX_'; - const ENGINE_TYPE = 'ENGINE_TYPE'; - const DB_NAME = 'DB_NAME'; - - private static $classes14 = ['Cache', 'CacheFS', 'CarrierModule', 'Db', 'FrontController', 'Helper', 'ImportModule', - 'MCached', 'Module', 'ModuleGraph', 'ModuleGraphEngine', 'ModuleGrid', 'ModuleGridEngine', - 'MySQL', 'Order', 'OrderDetail', 'OrderDiscount', 'OrderHistory', 'OrderMessage', 'OrderReturn', - 'OrderReturnState', 'OrderSlip', 'OrderState', 'PDF', 'RangePrice', 'RangeWeight', 'StockMvt', - 'StockMvtReason', 'SubDomain', 'Shop', 'Tax', 'TaxRule', 'TaxRulesGroup', 'WebserviceKey', 'WebserviceRequest', '', ]; - - private static $incompatibleModules = [ - 'bankwire', - 'blockbanner', - 'blockcart', - 'blockcategories', - 'blockcms', - 'blockcmsinfo', - 'blockcontact', - 'blockcurrencies', - 'blocklanguages', - 'blocklayered', - 'blockmyaccount', - 'blocknewsletter', - 'blocksearch', - 'blocksocial', - 'blocktopmenu', - 'blockuserinfo', - 'cheque', - 'homefeatured', - 'homeslider', - 'onboarding', - 'socialsharing', - 'vatnumber', - 'blockadvertising', - 'blockbestsellers', - 'blockcustomerprivacy', - 'blocklink', - 'blockmanufacturer', - 'blocknewproducts', - 'blockpermanentlinks', - 'blockrss', - 'blocksharefb', - 'blockspecials', - 'blocksupplier', - 'blockviewed', - 'crossselling', - 'followup', - 'productscategory', - 'producttooltip', - 'mailalert', - 'blockcontactinfos', - 'blockfacebook', - 'blockmyaccountfooter', - 'blockpaymentlogo', - 'blockstore', - 'blocktags', - 'blockwishlist', - 'productpaymentlogos', - 'sendtoafriend', - 'themeconfigurator', - ]; - - public function __construct($cacheDir, $installDir) - { - $this->logger = new FileLogger(); - $this->logger->setFilename($cacheDir . @date('Ymd') . '_upgrade.log'); - $this->installDir = $installDir; - $this->db = Db::getInstance(); - } - - public function setDisableCustomModules($value) - { - $this->disableCustomModules = (bool) $value; - } - - public function setUpdateDefaultTheme($value) - { - $this->updateDefaultTheme = (bool) $value; - } - - public function setAdminDir($value) - { - $this->adminDir = $value; - } - - public function setIdEmployee($id) - { - $this->idEmployee = (int) $id; - } - - public function setChangeToDefaultTheme($value) - { - $this->changeToDefaultTheme = (bool) $value; - } - - private function defineConst() - { - // retrocompatibility (is present in some upgrade scripts) - if (!defined('INSTALL_PATH')) { - define('INSTALL_PATH', $this->installDir); - } - require_once INSTALL_PATH . 'install_version.php'; - // needed for upgrade before 1.5 - if (!defined('__PS_BASE_URI__')) { - define('__PS_BASE_URI__', str_replace('//', '/', '/' . trim(preg_replace('#/(install(-dev)?/upgrade)$#', '/', str_replace('\\', '/', dirname($_SERVER['REQUEST_URI']))), '/') . '/')); - } - if (!defined('_THEME_NAME_')) { - define('_THEME_NAME_', 'default'); - } - if (!defined('_PS_SMARTY_FAST_LOAD_')) { - define('_PS_SMARTY_FAST_LOAD_', true); - } - - // if _PS_ROOT_DIR_ is defined, use it instead of "guessing" the module dir. - if (defined('_PS_ROOT_DIR_') && !defined('_PS_MODULE_DIR_')) { - define('_PS_MODULE_DIR_', _PS_ROOT_DIR_ . '/modules/'); - } elseif (!defined('_PS_MODULE_DIR_')) { - define('_PS_MODULE_DIR_', _PS_INSTALL_PATH_ . '/../modules/'); - } - - if (!defined('_PS_INSTALLER_PHP_UPGRADE_DIR_')) { - define('_PS_INSTALLER_PHP_UPGRADE_DIR_', _PS_INSTALL_PATH_ . 'upgrade/php/'); - } - - if (!defined('_PS_INSTALLER_SQL_UPGRADE_DIR_')) { - define('_PS_INSTALLER_SQL_UPGRADE_DIR_', _PS_INSTALL_PATH_ . 'upgrade/sql/'); - } - - if (!defined('_THEMES_DIR_')) { - define('_THEMES_DIR_', __PS_BASE_URI__ . 'themes/'); - } - if (!defined('_PS_IMG_')) { - define('_PS_IMG_', __PS_BASE_URI__ . 'img/'); - } - if (!defined('_PS_JS_DIR_')) { - define('_PS_JS_DIR_', __PS_BASE_URI__ . 'js/'); - } - if (!defined('_PS_CSS_DIR_')) { - define('_PS_CSS_DIR_', __PS_BASE_URI__ . 'css/'); - } - - $this->oldVersion = Configuration::get('PS_VERSION_DB'); - if (empty($this->oldVersion)) { - $this->oldVersion = Configuration::get('PS_INSTALL_VERSION'); - } - // Since 1.4.4.0 - // Fix complete version number if there is not all 4 numbers - // Eg. replace 1.4.3 by 1.4.3.0 - // Will result in file 1.4.3.0.sql will be skipped if oldversion is 1.4.3 - $arrayVersion = preg_split('#\.#', $this->oldVersion); - $versionNumbers = count($arrayVersion); - - if ($versionNumbers != 4) { - $arrayVersion = array_pad($arrayVersion, 4, '0'); - } - - $this->oldVersion = implode('.', $arrayVersion); - // End of fix - - if (!defined('_PS_CACHE_ENABLED_')) { - define('_PS_CACHE_ENABLED_', '0'); - } - if (!defined('_MYSQL_ENGINE_')) { - define('_MYSQL_ENGINE_', 'MyISAM'); - } - - if (!defined('_PS_TOOL_DIR_')) { - define('_PS_TOOL_DIR_', _PS_ROOT_DIR_ . '/tools/'); - } - if (!defined('_PS_TRANSLATIONS_DIR_')) { - define('_PS_TRANSLATIONS_DIR_', _PS_ROOT_DIR_ . '/translations/'); - } - if (!defined('_PS_MODULES_DIR_')) { - define('_PS_MODULES_DIR_', _PS_ROOT_DIR_ . '/modules/'); - } - if (!defined('_PS_MAILS_DIR_')) { - define('_PS_MAILS_DIR_', _PS_ROOT_DIR_ . '/mails/'); - } - if (!defined('_MEDIA_SERVER_1_')) { - define('_MEDIA_SERVER_1_', ''); - } - - if (!defined('_PS_USE_SQL_SLAVE_')) { - define('_PS_USE_SQL_SLAVE_', false); - } - } - - private function initContext() - { - $smarty = null; - Cache::clean('*'); - - Context::getContext()->shop = new Shop(1); - Shop::setContext(Shop::CONTEXT_SHOP, 1); - - if (!isset(Context::getContext()->language) || !Validate::isLoadedObject(Context::getContext()->language)) { - $idLang = (int) $this->getConfValue('PS_LANG_DEFAULT'); - Context::getContext()->language = new Language($idLang ? $idLang : null); - } - if (!isset(Context::getContext()->country) || !Validate::isLoadedObject(Context::getContext()->country)) { - if ($id_country = (int) $this->getConfValue('PS_COUNTRY_DEFAULT')) { - Context::getContext()->country = new Country((int) $id_country); - } - } - - Context::getContext()->cart = new Cart(); - Context::getContext()->employee = new Employee(1); - - require_once _PS_ROOT_DIR_ . '/config/smarty.config.inc.php'; - - Context::getContext()->smarty = $smarty; - Language::loadLanguages(); - - $this->translator = Context::getContext()->getTranslator(); - } - - private function getConfValue($name) - { - $full = version_compare('1.5.0.10', AppKernel::VERSION) < 0; - - $sql = 'SELECT IF(cl.`id_lang` IS NULL, c.`value`, cl.`value`) AS value - FROM `' . _DB_PREFIX_ . 'configuration` c - LEFT JOIN `' . _DB_PREFIX_ . 'configuration_lang` cl ON (c.`id_configuration` = cl.`id_configuration`) - WHERE c.`name`=\'' . pSQL($name) . '\''; - - if ($full) { - $id_shop = Shop::getContextShopID(true); - $id_shop_group = Shop::getContextShopGroupID(true); - if ($id_shop) { - $sql .= ' AND c.`id_shop` = ' . (int) $id_shop; - } - if ($id_shop_group) { - $sql .= ' AND c.`id_shop_group` = ' . (int) $id_shop_group; - } - } - - return $this->db->getValue($sql); - } - - private function getThemeManager($idEmployee) - { - $context = Context::getContext(); - $context->employee = new Employee((int) $idEmployee); - - return (new ThemeManagerBuilder($context, Db::getInstance()))->build(); - } - - private function checkVersion() - { - $versionCompare = version_compare(_PS_INSTALL_VERSION_, $this->oldVersion); - if ($versionCompare == '-1') { - $this->logError('Current version: %current%. Version to install: %future%.', 27, ['%current%' => $this->oldVersion, '%future%' => _PS_INSTALL_VERSION_]); - } elseif ($versionCompare == 0) { - $this->logError('You already have the %future% version.', 28, ['%future%' => _PS_INSTALL_VERSION_]); - } elseif ($versionCompare === false) { - $this->logError('There is no older version. Did you delete or rename the app/config/parameters.php file?', 29); - } - - if (strpos(_PS_INSTALL_VERSION_, '.') === false) { - $this->logError( - '%install_version% is not a valid version number.', - 40, - ['%install_version%' => _PS_INSTALL_VERSION_] - ); - } - } - - private function getSQLFiles() - { - //custom sql file creation - $neededUpgradeFiles = []; - if (!$this->hasFailure()) { - $upgradeFiles = []; - if (!file_exists(_PS_INSTALLER_SQL_UPGRADE_DIR_)) { - $this->logError('Unable to find upgrade directory in the installation path.', 31); - } - - if ($handle = opendir(_PS_INSTALLER_SQL_UPGRADE_DIR_)) { - while (false !== ($file = readdir($handle))) { - if (!in_array($file, ['.', '..', 'index.php'])) { - $upgradeFiles[] = str_replace('.sql', '', $file); - } - } - closedir($handle); - } - if (empty($upgradeFiles)) { - $this->logError('Cannot find the SQL upgrade files. Please verify that the %folder% folder is not empty)', 31, ['%folder%' => _PS_INSTALLER_SQL_UPGRADE_DIR_]); - } - natcasesort($upgradeFiles); - - $neededUpgradeFiles = []; - foreach ($upgradeFiles as $version) { - if (version_compare($version, $this->oldVersion) == 1 && version_compare(_PS_INSTALL_VERSION_, $version) != -1) { - $neededUpgradeFiles[] = $version; - } - } - } - if (!$this->hasFailure() && empty($neededUpgradeFiles)) { - $this->logError('No upgrade is possible.', 32); - } - - $sqlContentVersion = []; - $mysqlEngine = (defined('_MYSQL_ENGINE_') ? _MYSQL_ENGINE_ : 'MyISAM'); - if (!$this->hasFailure()) { - foreach ($neededUpgradeFiles as $version) { - $file = _PS_INSTALLER_SQL_UPGRADE_DIR_ . $version . '.sql'; - if (!file_exists($file)) { - $this->logError('Error while loading SQL upgrade file "%file%.sql".', 33, ['%file%' => $version]); - } - if (!$sqlContent = file_get_contents($file)) { - $this->logError('Error while loading SQL upgrade file "%file%.sql".', 33, ['%file%' => $version]); - } - $sqlContent .= "\n"; - $sqlContent = str_replace([self::FILE_PREFIX, self::ENGINE_TYPE, self::DB_NAME], [_DB_PREFIX_, $mysqlEngine, _DB_NAME_], $sqlContent); - $sqlContent = preg_split("/;\s*[\r\n]+/", $sqlContent); - - $sqlContentVersion[$version] = $sqlContent; - } - } - - return $sqlContentVersion; - } - - private function upgradeDoctrineSchema() - { - $schemaUpgrade = new UpgradeDatabase(); - $schemaUpgrade->addDoctrineSchemaUpdate(); - $output = $schemaUpgrade->execute(); - if (0 !== $output['prestashop:schema:update-without-foreign']['exitCode']) { - $msgErrors = explode("\n", $output['prestashop:schema:update-without-foreign']['output']); - $this->logError('Error upgrading doctrine schema', 43); - foreach ($msgErrors as $msgError) { - $this->logError('Doctrine SQL Error : ' . $msgError, 43); - } - } - } - - public function upgradeDb($sqlContentVersion) - { - $db = $this->db; - foreach ($sqlContentVersion as $version => $sqlContent) { - foreach ($sqlContent as $query) { - $query = trim($query); - if (!empty($query)) { - /* If php code have to be executed */ - if (strpos($query, '/* PHP:') !== false) { - /* Parsing php code */ - $pos = strpos($query, '/* PHP:') + strlen('/* PHP:'); - $phpString = substr($query, $pos, strlen($query) - $pos - strlen(' */;')); - $php = explode('::', $phpString); - preg_match('/\((.*)\)/', $phpString, $pattern); - $paramsString = trim($pattern[0], '()'); - preg_match_all('/([^,]+),? ?/', $paramsString, $parameters); - if (isset($parameters[1])) { - $parameters = $parameters[1]; - } else { - $parameters = []; - } - if (is_array($parameters)) { - foreach ($parameters as &$parameter) { - $parameter = str_replace('\'', '', $parameter); - } - } - - $phpRes = null; - /* Call a simple function */ - if (strpos($phpString, '::') === false) { - $func_name = str_replace($pattern[0], '', $php[0]); - if (!file_exists(_PS_INSTALLER_PHP_UPGRADE_DIR_ . strtolower($func_name) . '.php')) { - $this->logWarning('[ERROR] ' . $version . ' PHP - missing file ' . $query, 41, [], true); - } else { - require_once _PS_INSTALLER_PHP_UPGRADE_DIR_ . Tools::strtolower($func_name) . '.php'; - $phpRes = call_user_func_array($func_name, $parameters); - } - } else { - /* Or an object method, not supported */ - $this->logWarning('[ERROR] ' . $version . ' PHP - Object Method call is forbidden (' . $php[0] . '::' . str_replace($pattern[0], '', $php[1]) . ')', 42, [], true); - } - if ((is_array($phpRes) && !empty($phpRes['error'])) || $phpRes === false) { - $this->logWarning('[ERROR] PHP ' . $version . ' ' . $query . "\n" . ' - ' . (empty($phpRes['error']) ? '' : $phpRes['error'] . "\n") . ' - ' . (empty($phpRes['msg']) ? '' : ' - ' . $phpRes['msg']), $version, [], true); - } else { - $this->logInfo('[OK] PHP ' . $version . ' : ' . $query, $version, [], true); - } - } else { - if (!$db->execute($query)) { - $error = $db->getMsgError(); - $error_number = $db->getNumberError(); - - $duplicates = ['1050', '1054', '1060', '1061', '1062', '1091']; - if (!in_array($error_number, $duplicates)) { - $this->logWarning('SQL ' . $version . ' - ' . $error_number . ' in ' . $query . ': ' . $error, $version, [], true); - } else { - $this->logInfo('SQL ' . $version . ' - ' . $error_number . ' in ' . $query . ': ' . $error, $version, [], true); - } - } else { - $this->logInfo('[OK] SQL ' . $version . ' : ' . $query, $version, [], true); - } - } - } - } - } - // reload config after DB upgrade - Configuration::loadConfiguration(); - } - - private function disableCustomModules() - { - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleRepository = $moduleManagerBuilder->buildRepository(); - $moduleRepository->clearCache(); - - $filters = new AddonListFilter(); - $filters->setType(AddonListFilterType::MODULE) - ->removeStatus(AddonListFilterStatus::UNINSTALLED); - - $installedProducts = $moduleRepository->getFilteredList($filters); - foreach ($installedProducts as $installedProduct) { - if (!( - $installedProduct->attributes->has('origin_filter_value') - && in_array( - $installedProduct->attributes->get('origin_filter_value'), - [ - AddonListFilterOrigin::ADDONS_NATIVE, - AddonListFilterOrigin::ADDONS_NATIVE_ALL, - ] - ) - && 'PrestaShop' === $installedProduct->attributes->get('author') - ) - && 'autoupgrade' !== $installedProduct->attributes->get('name')) { - $moduleName = $installedProduct->attributes->get('name'); - $this->logInfo('Disabling custom module ' . $moduleName); - Module::disableAllByName($moduleName); - } - } - - return true; - } - - private function disableIncompatibleModules() - { - $fs = new Filesystem(); - - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManagerRepository = $moduleManagerBuilder->buildRepository(); - $moduleManagerRepository->clearCache(); - - $filters = new AddonListFilter(); - $filters->setStatus(AddonListFilterStatus::ON_DISK | AddonListFilterStatus::INSTALLED); - - $list = $moduleManagerRepository->getFilteredList($filters, true); - foreach ($list as $moduleName => $module) { - if (in_array($moduleName, self::$incompatibleModules)) { - $this->logInfo("Uninstalling module $moduleName, not supported in this PrestaShop version."); - $module->onUninstall(); - $fs->remove(_PS_MODULE_DIR_ . $moduleName); - } else { - $attributes = $module->attributes; - if ($attributes->get('compatibility')) { - $maxVersion = $attributes->get('compatibility')->to; - if (version_compare($maxVersion, _PS_INSTALL_VERSION_) == -1 && Module::isEnabled($moduleName)) { - $this->logInfo("Disabling module $moduleName. Max supported version : " . $maxVersion); - Module::disableAllByName($moduleName); - } - } - } - } - - return true; - } - - private function enableNativeModules() - { - $moduleManagerBuilder = ModuleManagerBuilder::getInstance(); - $moduleManagerRepository = $moduleManagerBuilder->buildRepository(); - $moduleManagerRepository->clearCache(); - - $filters = new AddonListFilter(); - $filters->setOrigin(AddonListFilterOrigin::ADDONS_NATIVE | AddonListFilterOrigin::ADDONS_NATIVE_ALL); - - $list = $moduleManagerRepository->getFilteredList($filters, true); - foreach ($list as $moduleName => $module) { - if ('PrestaShop' === $module->attributes->get('author')) { - if (!$moduleManagerBuilder->build()->isInstalled($moduleName)) { - $this->logInfo('Installing native module ' . $moduleName); - $module = $moduleManagerRepository->getModule($moduleName); - $module->onInstall(); - $module->onEnable(); - } else { - $this->logInfo('Native module ' . $moduleName . ' already installed'); - } - } - } - - return true; - } - - private function cleanCache() - { - // Settings updated, compile and cache directories must be emptied - $install_dir = realpath(rtrim(_PS_INSTALL_PATH_, '\\/') . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - $tools_dir = $install_dir . 'tools' . DIRECTORY_SEPARATOR; - $arrayToClean = [ - $tools_dir . 'smarty' . DIRECTORY_SEPARATOR . 'cache', - $tools_dir . 'smarty' . DIRECTORY_SEPARATOR . 'compile', - $tools_dir . 'smarty_v2' . DIRECTORY_SEPARATOR . 'cache', - $tools_dir . 'smarty_v2' . DIRECTORY_SEPARATOR . 'compile', - $install_dir . 'app' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR, - $install_dir . 'cache' . DIRECTORY_SEPARATOR . 'smarty' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR, - $install_dir . 'cache' . DIRECTORY_SEPARATOR . 'smarty' . DIRECTORY_SEPARATOR . 'compile' . DIRECTORY_SEPARATOR, - ]; - - foreach ($arrayToClean as $dir) { - if (file_exists($dir)) { - foreach (scandir($dir, SCANDIR_SORT_NONE) as $file) { - if ($file[0] != '.' && $file != 'index.php' && $file != '.htaccess') { - if (is_file($dir . $file)) { - unlink($dir . $file); - } elseif (is_dir($dir . $file . DIRECTORY_SEPARATOR)) { - //\Tools14::deleteDirectory($dir . $file . DIRECTORY_SEPARATOR, true); - } - // To more log - //$this->logInfo('[CLEANING CACHE] File %file% removed', null, array('%file%' => $file)); - } - } - } else { - $this->logInfo('[SKIP] directory "%directory%" does not exist and cannot be emptied.', null, ['%directory%' => str_replace($tools_dir, '', $dir)]); - } - } - - if (file_exists(_PS_ROOT_DIR_ . '/var/cache/dev/class_index.php')) { - unlink(_PS_ROOT_DIR_ . '/var/cache/dev/class_index.php'); - } - if (file_exists(_PS_ROOT_DIR_ . '/var/cache/prod/class_index.php')) { - unlink(_PS_ROOT_DIR_ . '/var/cache/prod/class_index.php'); - } - - // Clear XML files - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/blog-fr.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/blog-fr.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/default_country_modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/default_country_modules_list.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/modules_list.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/modules_native_addons.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/modules_native_addons.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/must_have_modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/must_have_modules_list.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/tab_modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/tab_modules_list.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/trusted_modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/trusted_modules_list.xml'); - } - if (file_exists(_PS_ROOT_DIR_ . '/config/xml/untrusted_modules_list.xml')) { - unlink(_PS_ROOT_DIR_ . '/config/xml/untrusted_modules_list.xml'); - } - } - - private function cleanDefaultThemeCache() - { - $separator = addslashes(DIRECTORY_SEPARATOR); - $file = _PS_ROOT_DIR_ . $separator . 'themes' . $separator . _THEME_NAME_ . $separator . 'cache' . $separator; - if (file_exists($file)) { - foreach (scandir($file, SCANDIR_SORT_NONE) as $cache) { - if ($cache[0] != '.' && $cache != 'index.php' && $cache != '.htaccess' && file_exists($file . $cache) && !is_dir($file . $cache)) { - if (file_exists($file . $cache)) { - unlink($file . $cache); - } - } - } - } - } - - private function updateDbImagesLegacy() - { - $db = $this->db; - $db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `name` = \'PS_LEGACY_IMAGES\' WHERE name LIKE \'0\' AND `value` = 1'); - $db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `value` = 0 WHERE `name` LIKE \'PS_LEGACY_IMAGES\''); - if ($db->getValue('SELECT COUNT(id_product_download) FROM `' . _DB_PREFIX_ . 'product_download` WHERE `active` = 1') > 0) { - $db->execute('UPDATE `' . _DB_PREFIX_ . 'configuration` SET `value` = 1 WHERE `name` LIKE \'PS_VIRTUAL_PROD_FEATURE_ACTIVE\''); - } - } - - private function cleanupOldDirectories() - { - if ($this->adminDir) { - $path = $this->adminDir . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR - . 'template' . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . 'modules' - . DIRECTORY_SEPARATOR . 'header.tpl'; - if (file_exists($path)) { - unlink($path); - } - } - } - - private function updateLangs() - { - $langs = $this->db->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'lang` WHERE `active` = 1'); - - if (is_array($langs)) { - foreach ($langs as $lang) { - $isoCode = $lang['iso_code']; - - if (Validate::isLangIsoCode($isoCode)) { - $errorsLanguage = []; - - Language::downloadLanguagePack($isoCode, AppKernel::VERSION, $errorsLanguage); - - $lang_pack = Language::getLangDetails($isoCode); - Language::installSfLanguagePack($lang_pack['locale'], $errorsLanguage); - self::generateEmailsLanguagePack($lang_pack, $errorsLanguage); - - if (empty($errorsLanguage)) { - Language::loadLanguages(); - } else { - $this->logError('Error updating translations', 44); - } - - Language::updateMultilangTable($isoCode); - } - } - } - } - - /** - * @param array $langPack - * @param array $errors - */ - private static function generateEmailsLanguagePack($langPack, &$errors = []) - { - $locale = $langPack['locale']; - $sfContainer = SymfonyContainer::getInstance(); - if (null === $sfContainer) { - $errors[] = Context::getContext()->getTranslator()->trans( - 'Cannot generate emails because the Symfony container is unavailable.', - [], - 'Admin.Notifications.Error' - ); - - return; - } - - $mailTheme = Configuration::get('PS_MAIL_THEME'); - /** @var GenerateThemeMailTemplatesCommand $generateCommand */ - $generateCommand = new GenerateThemeMailTemplatesCommand( - $mailTheme, - $locale, - false, - !empty($coreOutputFolder) ? $coreOutputFolder : '', - !empty($modulesOutputFolder) ? $modulesOutputFolder : '' - ); - /** @var CommandBusInterface $commandBus */ - $commandBus = $sfContainer->get('prestashop.core.command_bus'); - try { - $commandBus->handle($generateCommand); - } catch (CoreException $e) { - $errors[] = Context::getContext()->getTranslator()->trans( - 'Cannot generate email templates: %s.', - [$e->getMessage()], - 'Admin.Notifications.Error' - ); - } - } - - private function updateHtaccess() - { - if (!class_exists('\Tools2', false) && class_exists('\ToolsCore')) { - eval('class Tools2 extends \ToolsCore{}'); - } - - if (class_exists('\Tools2') && method_exists('\Tools2', 'generateHtaccess')) { - $url_rewrite = (bool) $this->db->getValue('SELECT `value` FROM `' . _DB_PREFIX_ . 'configuration` WHERE name=\'PS_REWRITING_SETTINGS\''); - - \Tools2::generateHtaccess(null, $url_rewrite); - } - } - - private function updateTheme() - { - $themeManager = $this->getThemeManager($this->idEmployee); - $themeName = ($this->changeToDefaultTheme ? 'classic' : _THEME_NAME_); - - $isThemeEnabled = $themeManager->enable($themeName, true); - if (!$isThemeEnabled) { - $themeErrors = $themeManager->getErrors($themeName); - $this->logError($themeErrors, 45); - } - } - - public function run() - { - Tools::clearAllCache(); - - $this->defineConst(); - $this->initContext(); - $this->checkVersion(); - - $sqlContentVersion = $this->getSQLFiles(); - - if (!$this->hasFailure()) { - $this->disableIncompatibleModules(); - - if ($this->disableCustomModules) { - $this->disableCustomModules(); - } - - $this->upgradeDb($sqlContentVersion); - $this->upgradeDoctrineSchema(); - - $this->enableNativeModules(); - - $this->cleanCache(); - - $this->updateDbImagesLegacy(); - if ($this->updateDefaultTheme) { - $this->cleanDefaultThemeCache(); - } - $this->cleanupOldDirectories(); - $this->updateLangs(); - $this->updateHtaccess(); - - if ($this->idEmployee) { - $this->updateTheme(); - } - } - } - - public function doUpgradeDb() - { - Tools::clearAllCache(); - - $this->defineConst(); - $this->initContext(); - $this->checkVersion(); - - $sqlContentVersion = $this->getSQLFiles(); - - if (!$this->hasFailure()) { - $this->upgradeDb($sqlContentVersion); - $this->upgradeDoctrineSchema(); - } - - $this->next = 'DisableModules'; - $this->nextDesc = $this->getTranslator()->trans('Database upgrade completed.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Database upgrade completed.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Disabling modules now...', [], 'Install'); - } - - public function doDisableModules() - { - $this->defineConst(); - $this->initContext(); - - $this->disableIncompatibleModules(); - - if ($this->disableCustomModules) { - $this->disableCustomModules(); - } - - $this->next = 'EnableModules'; - $this->nextDesc = $this->getTranslator()->trans('Modules successfully disabled.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Modules successfully disabled.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Enabling modules now...', [], 'Install'); - } - - public function doEnableModules() - { - $this->defineConst(); - $this->initContext(); - - $this->enableNativeModules(); - - $this->next = 'UpdateImage'; - $this->nextDesc = $this->getTranslator()->trans('Modules successfully enabled.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Modules successfully enabled.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Upgrading images now...', [], 'Install'); - } - - public function doUpdateImage() - { - $this->defineConst(); - $this->initContext(); - - $this->cleanCache(); - - $this->updateDbImagesLegacy(); - if ($this->updateDefaultTheme) { - $this->cleanDefaultThemeCache(); - } - $this->cleanupOldDirectories(); - - $this->next = 'UpdateLangHtaccess'; - $this->nextDesc = $this->getTranslator()->trans('Images successfully upgraded.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Images successfully upgraded.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Upgrading languages now...', [], 'Install'); - } - - public function doUpdateLangHtaccess() - { - $this->defineConst(); - $this->initContext(); - - $this->updateLangs(); - $this->updateHtaccess(); - - $this->next = 'UpdateTheme'; - $this->nextDesc = $this->getTranslator()->trans('Languages successfully upgraded.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Languages successfully upgraded.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Upgrading theme now...', [], 'Install'); - } - - public function doUpdateTheme() - { - $this->defineConst(); - $this->initContext(); - - if ($this->idEmployee) { - $this->updateTheme(); - } - - $this->next = 'UpgradeComplete'; - $this->nextDesc = $this->getTranslator()->trans('Theme successfully upgraded.', [], 'Install'); - $this->nextQuickInfo[] = $this->getTranslator()->trans('Theme successfully upgraded.', [], 'Install'); - } - - public function getTranslator() - { - return $this->translator; - } - - public function logInfo($quickInfo, $id = null, $transVariables = [], $dbInfo = false) - { - $info = $this->getTranslator()->trans($quickInfo, $transVariables, 'Install'); - if ($this->inAutoUpgrade) { - if ($dbInfo) { - $this->nextQuickInfo[] = '
    ' . $info . '
    '; - } else { - $this->nextQuickInfo[] = $info; - } - $this->infoList[] = $info; - } else { - if (!empty($quickInfo)) { - $this->logger->logInfo($info); - } - if ($id !== null) { - if (!is_numeric($id)) { - $customInfo = '\n"; - } else { - $customInfo = '' . "\n"; - } - $this->infoList[] = $customInfo; - } - } - } - - public function logWarning($quickInfo, $id, $transVariables = [], $dbInfo = false) - { - $info = $this->getTranslator()->trans($quickInfo, $transVariables, 'Install'); - if ($this->inAutoUpgrade) { - if ($dbInfo) { - $this->nextQuickInfo[] = '
    ' . $info . '
    '; - } else { - $this->nextQuickInfo[] = $info; - } - $this->nextErrors[] = $info; - $this->warningList[] = $info; - if (empty($this->failureList)) { - $this->nextDesc = $this->getTranslator()->trans('Warning detected during upgrade.', [], 'Install'); - } - } else { - if (!empty($quickInfo)) { - $this->logger->logWarning($info); - } - if ($id !== null) { - if (!is_numeric($id)) { - $customWarning = '\n"; - } else { - $customWarning = '' . "\n"; - } - $this->warningList[] = $customWarning; - } - } - } - - public function logError($quickInfo, $id, $transVariables = [], $dbInfo = false) - { - $info = $this->getTranslator()->trans($quickInfo, $transVariables, 'Install'); - if ($this->inAutoUpgrade) { - if ($dbInfo) { - $this->nextQuickInfo[] = '
    ' . $info . '
    '; - } else { - $this->nextQuickInfo[] = $info; - } - $this->nextErrors[] = $info; - $this->failureList[] = $info; - $this->nextDesc = $this->getTranslator()->trans('Error detected during upgrade.', [], 'Install'); - $this->next = 'error'; - } else { - if (!empty($quickInfo)) { - $this->logger->logError($info); - } - if ($id !== null) { - if (!is_numeric($id)) { - $customError = '\n"; - } else { - $customError = '' . "\n"; - } - $this->failureList[] = $customError; - } - } - } - - public function getInAutoUpgrade() - { - return $this->inAutoUpgrade; - } - - public function setInAutoUpgrade($value) - { - $this->inAutoUpgrade = $value; - } - - public function getNext() - { - return $this->next; - } - - public function getNextDesc() - { - return $this->nextDesc; - } - - public function getInfoList() - { - return $this->infoList; - } - - public function getWarningList() - { - return $this->warningList; - } - - public function getFailureList() - { - return $this->failureList; - } - - public function getNextQuickInfo() - { - return $this->nextQuickInfo; - } - - public function getNextErrors() - { - return $this->nextErrors; - } - - public function hasInfo() - { - return !empty($this->infoList); - } - - public function hasWarning() - { - return !empty($this->warningList); - } - - public function hasFailure() - { - return !empty($this->failureList); - } - - const SETTINGS_FILE = 'config/settings.inc.php'; - - public static function migrateSettingsFile(Event $event = null) - { - if ($event !== null) { - $event->getIO()->write('Migrating old setting file...'); - } - - $root_dir = realpath(__DIR__ . '/../../../'); - - $phpParametersFilepath = $root_dir . '/app/config/parameters.php'; - $addNewCookieKey = false; - if (file_exists($phpParametersFilepath)) { - $default_parameters = require $phpParametersFilepath; - if (!array_key_exists('new_cookie_key', $default_parameters['parameters'])) { - $addNewCookieKey = true; - } else { - if ($event !== null) { - $event->getIO()->write('parameters file already exists!'); - $event->getIO()->write('Finished...'); - } - - return false; - } - } - - if (!file_exists($phpParametersFilepath) && !file_exists($root_dir . '/app/config/parameters.yml') - && !file_exists($root_dir . '/' . self::SETTINGS_FILE)) { - if ($event !== null) { - $event->getIO()->write('No file to migrate!'); - $event->getIO()->write('Finished...'); - } - - return false; - } - - $filesystem = new Filesystem(); - $exportPhpConfigFile = function ($config, $destination) use ($filesystem) { - try { - $filesystem->dumpFile($destination, 'getIO()->write('parameters file already exists!'); - $event->getIO()->write("add new parameter 'new_cookie_key'"); - $event->getIO()->write('Finished...'); - } - - return false; - } - - if (file_exists($root_dir . '/' . self::SETTINGS_FILE)) { - $tmp_settings = file_get_contents($root_dir . '/' . self::SETTINGS_FILE); - } else { - $tmp_settings = null; - } - - if (!file_exists($root_dir . '/app/config/parameters.yml') && $tmp_settings && strpos($tmp_settings, '_DB_SERVER_') !== false) { - $tmp_settings = preg_replace('/(\'|")\_/', '$1_LEGACY_', $tmp_settings); - $tmp_settings_file = str_replace('/settings', '/tmp_settings', $root_dir . '/' . self::SETTINGS_FILE); - file_put_contents($tmp_settings_file, $tmp_settings); - include $tmp_settings_file; - @unlink($tmp_settings_file); - $factory = new RandomLib\Factory(); - $generator = $factory->getLowStrengthGenerator(); - $secret = $generator->generateString(64); - - if (!defined('_LEGACY_NEW_COOKIE_KEY_')) { - define('_LEGACY_NEW_COOKIE_KEY_', $default_parameters['parameters']['new_cookie_key']); - } - - $db_server_port = explode(':', _LEGACY_DB_SERVER_); - if (count($db_server_port) == 1) { - $db_server = $db_server_port[0]; - $db_port = 3306; - } else { - $db_server = $db_server_port[0]; - $db_port = $db_server_port[1]; - } - - $parameters = [ - 'parameters' => [ - 'database_host' => $db_server, - 'database_port' => $db_port, - 'database_user' => _LEGACY_DB_USER_, - 'database_password' => _LEGACY_DB_PASSWD_, - 'database_name' => _LEGACY_DB_NAME_, - 'database_prefix' => _LEGACY_DB_PREFIX_, - 'database_engine' => defined(_LEGACY_MYSQL_ENGINE_) ? _LEGACY_MYSQL_ENGINE_ : 'InnoDB', - 'cookie_key' => _LEGACY_COOKIE_KEY_, - 'cookie_iv' => _LEGACY_COOKIE_IV_, - 'new_cookie_key' => _LEGACY_NEW_COOKIE_KEY_, - 'ps_caching' => defined(_LEGACY_PS_CACHING_SYSTEM_) ? _LEGACY_PS_CACHING_SYSTEM_ : 'CacheMemcache', - 'ps_cache_enable' => defined(_LEGACY_PS_CACHE_ENABLED_) ? _LEGACY_PS_CACHE_ENABLED_ : false, - 'ps_creation_date' => defined(_LEGACY_PS_CREATION_DATE_) ? _LEGACY_PS_CREATION_DATE_ : date('Y-m-d H:i:s'), - 'secret' => $secret, - 'mailer_transport' => 'smtp', - 'mailer_host' => '127.0.0.1', - 'mailer_user' => '', - 'mailer_password' => '', - ] + $default_parameters['parameters'], - ]; - } elseif (file_exists($root_dir . '/app/config/parameters.yml')) { - $parameters = Yaml::parse(file_get_contents($root_dir . '/app/config/parameters.yml')); - if (empty($parameters['parameters'])) { - $parameters['parameters'] = []; - } - // add potentially missing default entries - $parameters['parameters'] = $parameters['parameters'] + $default_parameters['parameters']; - } else { - $parameters = $default_parameters; - } - - if (!empty($parameters) && $exportPhpConfigFile($parameters, $phpParametersFilepath)) { - $fileMigrated = true; - $settings_content = "getIO()->write('No old config file present!'); - } - $event->getIO()->write('Finished...'); - } - - return true; - } - } -} diff --git a/src/PrestaShopBundle/Install/XmlLoader.php b/src/PrestaShopBundle/Install/XmlLoader.php deleted file mode 100644 index c53984a1..00000000 --- a/src/PrestaShopBundle/Install/XmlLoader.php +++ /dev/null @@ -1,1434 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Install; - -use PrestaShop\PrestaShop\Adapter\Entity\Db; -use PrestaShop\PrestaShop\Adapter\Entity\DbQuery; -use PrestaShop\PrestaShop\Adapter\Entity\Image; -use PrestaShop\PrestaShop\Adapter\Entity\ImageManager; -use PrestaShop\PrestaShop\Adapter\Entity\ImageType; -use PrestaShop\PrestaShop\Adapter\Entity\Pack; -use PrestaShop\PrestaShop\Adapter\Entity\Shop; -use PrestaShop\PrestaShop\Adapter\Entity\StockAvailable; -use PrestaShop\PrestaShop\Adapter\Entity\Tag; -use PrestaShop\PrestaShop\Adapter\Entity\Tools; -use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem; -use PrestaShopDatabaseException; -use PrestashopInstallerException; - -class XmlLoader -{ - /** - * @var LanguageList - */ - protected $language; - - /** - * @var \Symfony\Bundle\FrameworkBundle\Translation\Translator - */ - protected $translator; - - /** - * @var array List of languages stored as array(id_lang => iso) - */ - protected $languages = []; - - /** - * @var array Store in cache all loaded XML files - */ - protected $cache_xml_entity = []; - - /** - * @var array List of errors - */ - protected $errors = []; - - protected $data_path; - protected $lang_path; - protected $img_path; - public $path_type; - - protected $ids = []; - - protected $primaries = []; - - protected $delayed_inserts = []; - - public function __construct() - { - $this->language = LanguageList::getInstance(); - $this->setDefaultPath(); - } - - /** - * Set list of installed languages. - * - * @param array $languages array(id_lang => iso) - */ - public function setLanguages(array $languages) - { - $this->languages = $languages; - } - - public function setTranslator($translator) - { - $this->translator = $translator; - - return $translator; - } - - public function setDefaultPath() - { - $this->path_type = 'common'; - $this->data_path = _PS_INSTALL_DATA_PATH_ . 'xml/'; - $this->lang_path = _PS_INSTALL_LANGS_PATH_; - $this->img_path = _PS_INSTALL_DATA_PATH_ . 'img/'; - } - - public function setFixturesPath($path = null) - { - if ($path === null) { - $path = _PS_INSTALL_FIXTURES_PATH_ . 'fashion/'; - } - - $this->path_type = 'fixture'; - $this->data_path = $path . 'data/'; - $this->lang_path = $path . 'langs/'; - $this->img_path = $path . 'img/'; - } - - /** - * Get list of errors. - * - * @return array - */ - public function getErrors() - { - return $this->errors; - } - - /** - * Add an error. - * - * @param string $error - */ - public function setError($error) - { - $this->errors[] = $error; - } - - /** - * Store an ID related to an entity and its identifier (E.g. we want to save that product with ID "ipod_nano" has the ID 1). - * - * @param string $entity - * @param string $identifier - * @param int $id - */ - public function storeId($entity, $identifier, $id) - { - $this->ids[$entity . ':' . $identifier] = $id; - } - - /** - * Retrieve an ID related to an entity and its identifier. - * - * @param string $entity - * @param string $identifier - */ - public function retrieveId($entity, $identifier) - { - return isset($this->ids[$entity . ':' . $identifier]) ? $this->ids[$entity . ':' . $identifier] : 0; - } - - public function getIds() - { - return $this->ids; - } - - public function setIds($ids) - { - $this->ids = $ids; - } - - public function getSortedEntities() - { - // Browse all XML files from data/xml directory - $entities = []; - $dependencies = []; - foreach (scandir($this->data_path) as $file) { - if (preg_match('#^(.+)\.xml$#', $file, $m)) { - $entity = $m[1]; - $xml = $this->loadEntity($entity); - - // Store entities dependencies (with field type="relation") - if ($xml->fields) { - foreach ($xml->fields->field as $field) { - if ($field['relation'] && $field['relation'] != $entity) { - if (!isset($dependencies[(string) $field['relation']])) { - $dependencies[(string) $field['relation']] = []; - } - $dependencies[(string) $field['relation']][] = $entity; - } - } - } - $entities[] = $entity; - } - } - - // Sort entities to populate database in good order (E.g. zones before countries) - do { - $current = (isset($sort_entities)) ? $sort_entities : []; - $sort_entities = []; - foreach ($entities as $key => $entity) { - if (isset($dependencies[$entity])) { - $min = count($entities) - 1; - foreach ($dependencies[$entity] as $item) { - if (($key = array_search($item, $sort_entities)) !== false) { - $min = min($min, $key); - } - } - if ($min == 0) { - array_unshift($sort_entities, $entity); - } else { - array_splice($sort_entities, $min, 0, [$entity]); - } - } else { - $sort_entities[] = $entity; - } - } - $entities = $sort_entities; - } while ($current != $sort_entities); - - return $sort_entities; - } - - /** - * Read all XML files from data folder and populate tables. - */ - public function populateFromXmlFiles() - { - $entities = $this->getSortedEntities(); - - // Populate entities - foreach ($entities as $entity) { - $this->populateEntity($entity); - } - } - - /** - * Populate an entity. - * - * @param string $entity - */ - public function populateEntity($entity) - { - if (method_exists($this, 'populateEntity' . Tools::toCamelCase($entity))) { - $this->{'populateEntity' . Tools::toCamelCase($entity)}(); - - return; - } - - if (substr($entity, 0, 1) == '.' || substr($entity, 0, 1) == '_') { - return; - } - - $xml = $this->loadEntity($entity); - - // Read list of fields - if (!is_object($xml) || !$xml->fields) { - throw new PrestashopInstallerException('List of fields not found for entity ' . $entity); - } - - $is_multi_lang_entity = $this->isMultilang($entity); - if ($is_multi_lang_entity) { - $multilang_columns = $this->getColumns($entity, true); - $xml_langs = []; - $default_lang = null; - foreach ($this->languages as $id_lang => $iso) { - if ($iso == $this->language->getLanguageIso()) { - $default_lang = $id_lang; - } - - try { - $xml_langs[$id_lang] = $this->loadEntity($entity, $iso); - } catch (PrestashopInstallerException $e) { - $xml_langs[$id_lang] = null; - } - } - } - - // Load all row for current entity and prepare data to be populated - $i = 0; - foreach ($xml->entities->$entity as $node) { - $data = []; - $identifier = (string) $node['id']; - - // Read attributes - foreach ($node->attributes() as $k => $v) { - if ($k != 'id') { - $data[$k] = (string) $v; - } - } - - // Read cdatas - foreach ($node->children() as $child) { - $data[$child->getName()] = (string) $child; - } - - // Load multilang data - $data_lang = []; - if ($is_multi_lang_entity) { - $xpath_query = $entity . '[@id="' . $identifier . '"]'; - foreach ($xml_langs as $id_lang => $xml_lang) { - if (!$xml_lang) { - continue; - } - - if (($node_lang = $xml_lang->xpath($xpath_query)) || ($node_lang = $xml_langs[$default_lang]->xpath($xpath_query))) { - $node_lang = $node_lang[0]; - foreach ($multilang_columns as $column => $is_text) { - $value = ''; - if ($node_lang[$column]) { - $value = (string) $node_lang[$column]; - } - - if ($node_lang->$column) { - $value = (string) $node_lang->$column; - } - $data_lang[$column][$id_lang] = $value; - } - } - } - } - - $data = $this->rewriteRelationedData($entity, $data); - if (method_exists($this, 'createEntity' . Tools::toCamelCase($entity))) { - // Create entity with custom method in current class - $method = 'createEntity' . Tools::toCamelCase($entity); - $this->$method($identifier, $data, $data_lang); - } else { - $this->createEntity($entity, $identifier, (string) $xml->fields['class'], $data, $data_lang); - } - - if ($xml->fields['image']) { - if (method_exists($this, 'copyImages' . Tools::toCamelCase($entity))) { - $this->{'copyImages' . Tools::toCamelCase($entity)}($identifier, $data); - } else { - $this->copyImages($entity, $identifier, (string) $xml->fields['image'], $data); - } - } - ++$i; - - if ($i >= 100) { - $this->flushDelayedInserts(); - $i = 0; - } - } - - $this->flushDelayedInserts(); - unset($this->cache_xml_entity[$this->path_type][$entity]); - } - - protected function getFallBackToDefaultLanguage($iso) - { - return file_exists($this->lang_path . $iso . '/data/') ? $iso : 'en'; - } - - protected function getFallBackToDefaultEntityLanguage($iso, $entity) - { - if ($this->getFallBackToDefaultLanguage($iso) === 'en') { - return 'en'; - } - - return file_exists($this->lang_path . $this->getFallBackToDefaultLanguage($iso) . '/data/' . $entity . '.xml') ? $iso : 'en'; - } - - /** - * Special case for "tag" entity. - */ - public function populateEntityTag() - { - foreach ($this->languages as $id_lang => $iso) { - if (!file_exists($this->lang_path . $this->getFallBackToDefaultLanguage($iso) . '/data/tag.xml')) { - continue; - } - - $xml = $this->loadEntity('tag', $this->getFallBackToDefaultLanguage($iso)); - $tags = []; - foreach ($xml->tag as $tag_node) { - $products = trim((string) $tag_node['products']); - if (!$products) { - continue; - } - - foreach (explode(',', $products) as $product) { - $product = trim($product); - $product_id = $this->retrieveId('product', $product); - if (!isset($tags[$product_id])) { - $tags[$product_id] = []; - } - $tags[$product_id][] = trim((string) $tag_node['name']); - } - } - - foreach ($tags as $id_product => $tag_list) { - Tag::addTags($id_lang, $id_product, $tag_list); - } - } - } - - /** - * Load an entity XML file. - * - * @param string $entity - * - * @return \SimpleXMLElement - */ - protected function loadEntity($entity, $iso = null) - { - if (!isset($this->cache_xml_entity[$this->path_type][$entity][$iso])) { - if (substr($entity, 0, 1) == '.' || substr($entity, 0, 1) == '_') { - return; - } - - $path = $this->data_path . $entity . '.xml'; - if ($iso) { - $path = $this->lang_path . $this->getFallBackToDefaultEntityLanguage($iso, $entity) . '/data/' . $entity . '.xml'; - } - - if (!file_exists($path)) { - throw new PrestashopInstallerException('XML data file ' . $entity . '.xml not found'); - } - - $this->cache_xml_entity[$this->path_type][$entity][$iso] = @simplexml_load_file($path, 'SimplexmlElement'); - if (!$this->cache_xml_entity[$this->path_type][$entity][$iso]) { - throw new PrestashopInstallerException('XML data file ' . $entity . '.xml invalid'); - } - } - - return $this->cache_xml_entity[$this->path_type][$entity][$iso]; - } - - /** - * Check fields related to an other entity, and replace their values by the ID created by the other entity. - * - * @param string $entity - * @param array $data - */ - protected function rewriteRelationedData($entity, array $data) - { - $xml = $this->loadEntity($entity); - foreach ($xml->fields->field as $field) { - if ($field['relation']) { - $id = $this->retrieveId((string) $field['relation'], $data[(string) $field['name']]); - if (!$id && $data[(string) $field['name']] && is_numeric($data[(string) $field['name']])) { - $id = $data[(string) $field['name']]; - } - $data[(string) $field['name']] = $id; - } - } - - return $data; - } - - public function flushDelayedInserts() - { - foreach ($this->delayed_inserts as $entity => $queries) { - $type = Db::INSERT_IGNORE; - if ($entity == 'access') { - $type = Db::REPLACE; - } - - if (!Db::getInstance()->insert($entity, $queries, false, true, $type)) { - $this->setError($this->translator->trans('An SQL error occurred for entity %entity%: %message%', ['%entity%' => $entity, '%message%' => Db::getInstance()->getMsgError()], 'Install')); - } - unset($this->delayed_inserts[$entity]); - } - } - - /** - * Create a simple entity with all its data and lang data - * If a methode createEntity$entity exists, use it. Else if $classname is given, use it. Else do a simple insert in database. - * - * @param string $entity - * @param string $identifier - * @param string $classname - * @param array $data - * @param array $data_lang - */ - public function createEntity($entity, $identifier, $classname, array $data, array $data_lang = []) - { - $xml = $this->loadEntity($entity); - if ($classname) { - $classname = '\\' . $classname; - // Create entity with ObjectModel class - $object = new $classname(); - $object->hydrate($data); - if ($data_lang) { - $object->hydrate($data_lang); - } - $object->add(true, (isset($xml->fields['null'])) ? true : false); - $entity_id = $object->id; - unset($object); - } else { - // Generate primary key manually - $primary = ''; - $entity_id = 0; - if (!$xml->fields['primary']) { - $primary = 'id_' . $entity; - } elseif (strpos((string) $xml->fields['primary'], ',') === false) { - $primary = (string) $xml->fields['primary']; - } - unset($xml); - - if ($primary) { - $entity_id = $this->generatePrimary($entity, $primary); - $data[$primary] = $entity_id; - } - - // Store INSERT queries in order to optimize install with grouped inserts - $this->delayed_inserts[$entity][] = array_map('pSQL', $data); - if ($data_lang) { - $real_data_lang = []; - foreach ($data_lang as $field => $list) { - foreach ($list as $id_lang => $value) { - $real_data_lang[$id_lang][$field] = $value; - } - } - - foreach ($real_data_lang as $id_lang => $insert_data_lang) { - $insert_data_lang['id_' . $entity] = $entity_id; - $insert_data_lang['id_lang'] = $id_lang; - $this->delayed_inserts[$entity . '_lang'][] = array_map('pSQL', $insert_data_lang); - } - - // Store INSERT queries for _shop associations - $entity_asso = Shop::getAssoTable($entity); - if ($entity_asso !== false && $entity_asso['type'] == 'shop') { - $this->delayed_inserts[$entity . '_shop'][] = [ - 'id_shop' => 1, - 'id_' . $entity => $entity_id, - ]; - } - } - } - - $this->storeId($entity, $identifier, $entity_id); - } - - public function createEntityConfiguration($identifier, array $data, array $data_lang) - { - if (Db::getInstance()->getValue('SELECT id_configuration FROM ' . _DB_PREFIX_ . 'configuration WHERE name = \'' . pSQL($data['name']) . '\'')) { - return; - } - - $entity = 'configuration'; - $entity_id = $this->generatePrimary($entity, 'id_configuration'); - $data['id_configuration'] = $entity_id; - - // Store INSERT queries in order to optimize install with grouped inserts - $this->delayed_inserts[$entity][] = array_map('pSQL', $data); - if ($data_lang) { - $real_data_lang = []; - foreach ($data_lang as $field => $list) { - foreach ($list as $id_lang => $value) { - $real_data_lang[$id_lang][$field] = $value; - } - } - - foreach ($real_data_lang as $id_lang => $insert_data_lang) { - $insert_data_lang['id_' . $entity] = $entity_id; - $insert_data_lang['id_lang'] = $id_lang; - $this->delayed_inserts[$entity . '_lang'][] = array_map('pSQL', $insert_data_lang); - } - } - - $this->storeId($entity, $identifier, $entity_id); - } - - /** - * @param string $identifier - * @param array $data - * @param array $data_lang - * - * @return $this - * - * @throws PrestaShopDatabaseException - */ - public function createEntityPack($identifier, array $data, array $data_lang) - { - Pack::addItem($data['id_product_pack'], $data['id_product_item'], $data['quantity']); - - return $this; - } - - public function createEntityStockAvailable($identifier, array $data, array $data_lang) - { - $stock_available = new StockAvailable(); - $stock_available->updateQuantity($data['id_product'], $data['id_product_attribute'], $data['quantity'], $data['id_shop']); - } - - public function createEntityTab($identifier, array $data, array $data_lang) - { - static $position = []; - - $entity = 'tab'; - $xml = $this->loadEntity($entity); - - if (!isset($position[$data['id_parent']])) { - $position[$data['id_parent']] = 0; - } - $data['position'] = $position[$data['id_parent']]++; - - // Generate primary key manually - $primary = ''; - $entity_id = 0; - if (!$xml->fields['primary']) { - $primary = 'id_' . $entity; - } elseif (strpos((string) $xml->fields['primary'], ',') === false) { - $primary = (string) $xml->fields['primary']; - } - - if ($primary) { - $entity_id = $this->generatePrimary($entity, $primary); - $data[$primary] = $entity_id; - } - - // Store INSERT queries in order to optimize install with grouped inserts - $this->delayed_inserts[$entity][] = array_map('pSQL', $data); - if ($data_lang) { - $real_data_lang = []; - foreach ($data_lang as $field => $list) { - foreach ($list as $id_lang => $value) { - $real_data_lang[$id_lang][$field] = $value; - } - } - - foreach ($real_data_lang as $id_lang => $insert_data_lang) { - $insert_data_lang['id_' . $entity] = $entity_id; - $insert_data_lang['id_lang'] = $id_lang; - $this->delayed_inserts[$entity . '_lang'][] = array_map('pSQL', $insert_data_lang); - } - } - - $this->storeId($entity, $identifier, $entity_id); - } - - public function generatePrimary($entity, $primary) - { - if (!isset($this->primaries[$entity])) { - $entity = Db::getInstance()->escape($entity, false, true); - $primary = Db::getInstance()->escape($primary, false, true); - $this->primaries[$entity] = (int) Db::getInstance()->getValue( - 'SELECT ' . $primary . ' FROM `' . _DB_PREFIX_ . $entity . '` ORDER BY `' . $primary . '` DESC' - ); - } - - return ++$this->primaries[$entity]; - } - - public function copyImages($entity, $identifier, $path, array $data, $extension = 'jpg') - { - // Get list of image types - $reference = [ - 'product' => 'products', - 'category' => 'categories', - 'manufacturer' => 'manufacturers', - 'supplier' => 'suppliers', - 'store' => 'stores', - ]; - - $types = []; - if (isset($reference[$entity])) { - $types = ImageType::getImagesTypes($reference[$entity]); - } - - // For each path copy images - $path = array_map('trim', explode(',', $path)); - foreach ($path as $p) { - $from_path = $this->img_path . $p . '/'; - $dst_path = _PS_IMG_DIR_ . $p . '/'; - $entity_id = $this->retrieveId($entity, $identifier); - - if (!@copy($from_path . $identifier . '.' . $extension, $dst_path . $entity_id . '.' . $extension)) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" for entity "%entity%"', - ['%entity%' => $entity, '%identifier%' => $identifier], - 'Install' - ) - ); - - return; - } - - foreach ($types as $type) { - $origin_file = $from_path . $identifier . '-' . $type['name'] . '.' . $extension; - $target_file = $dst_path . $entity_id . '-' . $type['name'] . '.' . $extension; - - // Test if dest folder is writable - if (!is_writable(dirname($target_file))) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" (bad permissions on folder "%folder%")', - ['%identifier%' => $identifier . '-' . $type['name'], '%folder%' => dirname($target_file)], - 'Install' - ) - ); - } elseif (file_exists($origin_file)) { - // If a file named folder/entity-type.extension exists just copy it - // this is an optimisation in order to prevent to much resize - if (!@copy($origin_file, $target_file)) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%"', - ['%identifier%' => $identifier . '-' . $type['name']], - 'Install' - ) - ); - } - @chmod($target_file, FileSystem::DEFAULT_MODE_FILE); - } elseif (!ImageManager::resize( - $from_path . $identifier . '.' . $extension, - $target_file, - $type['width'], - $type['height'] - )) { - // Resize the image if no cache was prepared in fixtures - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" for entity "%entity%"', - ['%identifier%' => $identifier . '-' . $type['name'], '%entity%' => $entity], - 'Install' - ) - ); - } - } - } - Image::moveToNewFileSystem(); - } - - public function copyImagesOrderState($identifier, array $data) - { - $this->copyImages('order_state', $identifier, 'os', $data, 'gif'); - } - - public function copyImagesTab($identifier, array $data) - { - $from_path = $this->img_path . 't/'; - $dst_path = _PS_IMG_DIR_ . 't/'; - if (file_exists($from_path . $data['class_name'] . '.gif') && !file_exists($dst_path . $data['class_name'] . '.gif')) { - //test if file exist in install dir and if do not exist in dest folder. - if (!@copy($from_path . $data['class_name'] . '.gif', $dst_path . $data['class_name'] . '.gif')) { - $this->setError($this->translator->trans('Cannot create image "%identifier%" for entity "%entity%"', ['%identifier%' => $identifier, '%tab%' => 'tab'], 'Install')); - - return; - } - } - } - - public function copyImagesImage($identifier) - { - $path = $this->img_path . 'p/'; - $image = new Image($this->retrieveId('image', $identifier)); - $dst_path = $image->getPathForCreation(); - if (!@copy($path . $identifier . '.jpg', $dst_path . '.' . $image->image_format)) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" for entity "%entity%"', - ['%identifier%' => $identifier, '%entity%' => 'product'], - 'Install' - ) - ); - - return; - } - @chmod($dst_path . '.' . $image->image_format, FileSystem::DEFAULT_MODE_FILE); - - $types = ImageType::getImagesTypes('products'); - foreach ($types as $type) { - $origin_file = $path . $identifier . '-' . $type['name'] . '.jpg'; - $target_file = $dst_path . '-' . $type['name'] . '.' . $image->image_format; - - // Test if dest folder is writable - if (!is_writable(dirname($target_file))) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" (bad permissions on folder "%folder%")', - ['%identifier%' => $identifier . '-' . $type['name'], '%folder%' => dirname($target_file)], - 'Install' - ) - ); - } elseif (file_exists($origin_file)) { - // If a file named folder/entity-type.jpg exists just copy it - // this is an optimisation in order to prevent to much resize - if (!@copy($origin_file, $target_file)) { - $this->setError( - $this->translator->trans( - 'Cannot create image "%1$s" for entity "%2$s"', - ['%identifier%' => $identifier . '-' . $type['name'], '%entity%' => 'product'], - 'Install' - ) - ); - } - @chmod($target_file, FileSystem::DEFAULT_MODE_FILE); - } elseif (!ImageManager::resize($path . $identifier . '.jpg', $target_file, $type['width'], $type['height'])) { - // Resize the image if no cache was prepared in fixtures - $this->setError( - $this->translator->trans( - 'Cannot create image "%identifier%" for entity "%entity%"', - ['%identifier%' => $identifier . '-' . $type['name'], '%entity%' => 'product'], - 'Install' - ) - ); - } - } - } - - public function getTables() - { - static $tables = null; - - if (null === $tables) { - $tables = []; - foreach (Db::getInstance()->executeS('SHOW TABLES') as $row) { - $table = current($row); - if (preg_match('#^' . _DB_PREFIX_ . '(.+?)(_lang)?$#i', $table, $m)) { - $tables[$m[1]] = (isset($m[2]) && $m[2]) ? true : false; - } - } - } - - return $tables; - } - - public function hasElements($table) - { - $table = Db::getInstance()->escape($table, false, true); - - return (bool) Db::getInstance()->getValue('SELECT COUNT(*) FROM `' . _DB_PREFIX_ . $table . '`'); - } - - public function getColumns($table, $multilang = false, array $exclude = []) - { - static $columns = []; - - if ($multilang) { - return ($this->isMultilang($table)) ? $this->getColumns($table . '_lang', false, ['id_' . $table]) : []; - } - - if (!isset($columns[$table])) { - $columns[$table] = []; - $sql = 'SHOW COLUMNS FROM `' . _DB_PREFIX_ . bqSQL($table) . '`'; - foreach (Db::getInstance()->executeS($sql) as $row) { - $columns[$table][$row['Field']] = $this->checkIfTypeIsText($row['Type']); - } - } - - $exclude = array_merge(['id_' . $table, 'date_add', 'date_upd', 'deleted', 'id_lang'], $exclude); - - $list = []; - foreach ($columns[$table] as $k => $v) { - if (!in_array($k, $exclude)) { - $list[$k] = $v; - } - } - - return $list; - } - - public function getClasses($path = null) - { - static $cache = null; - - if (null !== $cache) { - return $cache; - } - - $dir = $path; - if (null === $dir) { - $dir = _PS_CLASS_DIR_; - } - - $classes = []; - foreach (scandir($dir, SCANDIR_SORT_NONE) as $file) { - if ($file[0] != '.' && $file != 'index.php') { - if (is_dir($dir . $file)) { - $classes = array_merge($classes, $this->getClasses($dir . $file . '/')); - } elseif (preg_match('#^(.+)\.php$#', $file, $m)) { - $classes[] = $m[1]; - } - } - } - - sort($classes); - if (null === $path) { - $cache = $classes; - } - - return $classes; - } - - public function checkIfTypeIsText($type) - { - if (preg_match('#^(longtext|text|tinytext)#i', $type)) { - return true; - } - - if (preg_match('#^varchar\(([0-9]+)\)$#i', $type, $m)) { - return (int) ($m[1]) >= 64 ? true : false; - } - - return false; - } - - public function isMultilang($entity) - { - $tables = $this->getTables(); - - return isset($tables[$entity]) && $tables[$entity]; - } - - public function entityExists($entity) - { - return file_exists($this->data_path . $entity . '.xml'); - } - - public function getEntitiesList() - { - $entities = []; - foreach (scandir($this->data_path, SCANDIR_SORT_NONE) as $file) { - if ($file[0] != '.' && preg_match('#^(.+)\.xml$#', $file, $m)) { - $entities[] = $m[1]; - } - } - - return $entities; - } - - public function getEntityInfo($entity) - { - $info = [ - 'config' => [ - 'id' => '', - 'primary' => '', - 'class' => '', - 'sql' => '', - 'ordersql' => '', - 'image' => '', - 'null' => '', - ], - 'fields' => [], - ]; - - if (!$this->entityExists($entity)) { - return $info; - } - - $xml = @simplexml_load_file($this->data_path . $entity . '.xml', 'SimplexmlElement'); - if (!$xml) { - return $info; - } - - if ($xml->fields['id']) { - $info['config']['id'] = (string) $xml->fields['id']; - } - - if ($xml->fields['primary']) { - $info['config']['primary'] = (string) $xml->fields['primary']; - } - - if ($xml->fields['class']) { - $info['config']['class'] = (string) $xml->fields['class']; - } - - if ($xml->fields['sql']) { - $info['config']['sql'] = (string) $xml->fields['sql']; - } - - if ($xml->fields['ordersql']) { - $info['config']['ordersql'] = (string) $xml->fields['ordersql']; - } - - if ($xml->fields['null']) { - $info['config']['null'] = (string) $xml->fields['null']; - } - - if ($xml->fields['image']) { - $info['config']['image'] = (string) $xml->fields['image']; - } - - foreach ($xml->fields->field as $field) { - $column = (string) $field['name']; - $info['fields'][$column] = []; - if (isset($field['relation'])) { - $info['fields'][$column]['relation'] = (string) $field['relation']; - } - } - - return $info; - } - - public function getDependencies() - { - $entities = []; - foreach ($this->getEntitiesList() as $entity) { - $entities[$entity] = $this->getEntityInfo($entity); - } - - $dependencies = []; - foreach ($entities as $entity => $info) { - foreach ($info['fields'] as $field => $info_field) { - if (isset($info_field['relation']) && $info_field['relation'] != $entity) { - if (!isset($dependencies[$info_field['relation']])) { - $dependencies[$info_field['relation']] = []; - } - $dependencies[$info_field['relation']][] = $entity; - } - } - } - - return $dependencies; - } - - public function generateEntitySchema($entity, array $fields, array $config) - { - if ($this->entityExists($entity)) { - $xml = $this->loadEntity($entity); - } else { - $xml = new SimplexmlElement(''); - } - unset($xml->fields); - - // Fill attributes (config) - $xml_fields = $xml->addChild('fields'); - foreach ($config as $k => $v) { - if ($v) { - $xml_fields[$k] = $v; - } - } - - // Create list of fields - foreach ($fields as $column => $info) { - $field = $xml_fields->addChild('field'); - $field['name'] = $column; - if (isset($info['relation'])) { - $field['relation'] = $info['relation']; - } - } - - // Recreate entities nodes, in order to have the node after the node - $store_entities = clone $xml->entities; - unset($xml->entities); - $xml->addChild('entities', $store_entities); - - $xml->asXML($this->data_path . $entity . '.xml'); - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function generateAllEntityFiles() - { - $entities = []; - foreach ($this->getEntitiesList() as $entity) { - $entities[$entity] = $this->getEntityInfo($entity); - } - $this->generateEntityFiles($entities); - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function generateEntityFiles($entities) - { - $dependencies = $this->getDependencies(); - - // Sort entities to populate database in good order (E.g. zones before countries) - do { - $current = (isset($sort_entities)) ? $sort_entities : []; - $sort_entities = []; - foreach ($entities as $entity) { - if (isset($dependencies[$entity])) { - $min = count($entities) - 1; - foreach ($dependencies[$entity] as $item) { - if (($key = array_search($item, $sort_entities)) !== false) { - $min = min($min, $key); - } - } - if ($min == 0) { - array_unshift($sort_entities, $entity); - } else { - array_splice($sort_entities, $min, 0, [$entity]); - } - } else { - $sort_entities[] = $entity; - } - } - $entities = $sort_entities; - } while ($current != $sort_entities); - - foreach ($sort_entities as $entity) { - $this->generateEntityContent($entity); - } - } - - public function generateEntityContent($entity) - { - $xml = $this->loadEntity($entity); - if (method_exists($this, 'getEntityContents' . Tools::toCamelCase($entity))) { - $content = $this->{'getEntityContents' . Tools::toCamelCase($entity)}($entity); - } else { - $content = $this->getEntityContents($entity); - } - - unset($xml->entities); - $entities = $xml->addChild('entities'); - $this->createXmlEntityNodes($entity, $content['nodes'], $entities); - $xml->asXML($this->data_path . $entity . '.xml'); - - // Generate multilang XML files - if ($content['nodes_lang']) { - foreach ($content['nodes_lang'] as $id_lang => $nodes) { - if (!isset($this->languages[$id_lang])) { - continue; - } - - $iso = $this->languages[$id_lang]; - if (!is_dir($this->lang_path . $this->getFallBackToDefaultLanguage($iso) . '/data')) { - mkdir($this->lang_path . $this->getFallBackToDefaultLanguage($iso) . '/data'); - } - - $xml_node = new SimplexmlElement(''); - $this->createXmlEntityNodes($entity, $nodes, $xml_node); - $xml_node->asXML($this->lang_path . $this->getFallBackToDefaultEntityLanguage($iso, $entity) . '/data/' . $entity . '.xml'); - } - } - - if ($xml->fields['image']) { - if (method_exists($this, 'backupImage' . Tools::toCamelCase($entity))) { - $this->{'backupImage' . Tools::toCamelCase($entity)}((string) $xml->fields['image']); - } else { - $this->backupImage($entity, (string) $xml->fields['image']); - } - } - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function getEntityContents($entity) - { - $xml = $this->loadEntity($entity); - $primary = (isset($xml->fields['primary']) && $xml->fields['primary']) ? (string) $xml->fields['primary'] : 'id_' . $entity; - $is_multilang = $this->isMultilang($entity); - - // Check if current table is an association table (if multiple primary keys) - $is_association = false; - if (strpos($primary, ',') !== false) { - $is_association = true; - $primary = array_map('trim', explode(',', $primary)); - } - - // Build query - $sql = new DbQuery(); - $sql->select('a.*'); - $sql->from($entity, 'a'); - if ($is_multilang) { - $sql->select('b.*'); - $sql->leftJoin($entity . '_lang', 'b', 'a.' . $primary . ' = b.' . $primary); - } - - if (isset($xml->fields['sql']) && $xml->fields['sql']) { - $sql->where((string) $xml->fields['sql']); - } - - if (!$is_association) { - $sql->select('a.' . $primary); - if (!isset($xml->fields['ordersql']) || !$xml->fields['ordersql']) { - $sql->orderBy('a.' . $primary); - } - } - - if ($is_multilang && (!isset($xml->fields['ordersql']) || !$xml->fields['ordersql'])) { - $sql->orderBy('b.id_lang'); - } - - if (isset($xml->fields['ordersql']) && $xml->fields['ordersql']) { - $sql->orderBy((string) $xml->fields['ordersql']); - } - - // Get multilang columns - $alias_multilang = []; - if ($is_multilang) { - $columns = $this->getColumns($entity); - $multilang_columns = $this->getColumns($entity, true); - - // If some columns from _lang table have same name than original table, rename them (E.g. value in configuration) - foreach ($multilang_columns as $c => $is_text) { - if (isset($columns[$c])) { - $alias = $c . '_alias'; - $alias_multilang[$c] = $alias; - $sql->select('a.' . $c . ' as ' . $c . ', b.' . $c . ' as ' . $alias); - } - } - } - - // Get all results - $nodes = $nodes_lang = []; - $results = Db::getInstance()->executeS($sql); - if (Db::getInstance()->getNumberError()) { - $this->setError($this->translator->trans('SQL error on query %query%', ['%sql%' => $sql], 'Install')); - } else { - foreach ($results as $row) { - // Store common columns - if ($is_association) { - $id = $entity; - foreach ($primary as $key) { - $id .= '_' . $row[$key]; - } - } else { - $id = $this->generateId($entity, $row[$primary], $row, (isset($xml->fields['id']) && $xml->fields['id']) ? (string) $xml->fields['id'] : null); - } - - if (!isset($nodes[$id])) { - $node = []; - foreach ($xml->fields->field as $field) { - $column = (string) $field['name']; - if (isset($field['relation'])) { - $sql = 'SELECT `id_' . bqSQL($field['relation']) . '` - FROM `' . bqSQL(_DB_PREFIX_ . $field['relation']) . '` - WHERE `id_' . bqSQL($field['relation']) . '` = ' . (int) $row[$column]; - $node[$column] = $this->generateId((string) $field['relation'], Db::getInstance()->getValue($sql)); - - // A little trick to allow storage of some hard values, like '-1' for tab.id_parent - if (!$node[$column] && $row[$column]) { - $node[$column] = $row[$column]; - } - } else { - $node[$column] = $row[$column]; - } - } - $nodes[$id] = $node; - } - - // Store multilang columns - if ($is_multilang && $row['id_lang']) { - $node = []; - foreach ($multilang_columns as $column => $is_text) { - $node[$column] = $row[isset($alias_multilang[$column]) ? $alias_multilang[$column] : $column]; - } - $nodes_lang[$row['id_lang']][$id] = $node; - } - } - } - - return [ - 'nodes' => $nodes, - 'nodes_lang' => $nodes_lang, - ]; - } - - public function getEntityContentsTag() - { - $nodes_lang = []; - - $sql = 'SELECT t.id_tag, t.id_lang, t.name, pt.id_product - FROM ' . _DB_PREFIX_ . 'tag t - LEFT JOIN ' . _DB_PREFIX_ . 'product_tag pt ON t.id_tag = pt.id_tag - ORDER BY id_lang'; - foreach (Db::getInstance()->executeS($sql) as $row) { - $identifier = $this->generateId('tag', $row['id_tag']); - if (!isset($nodes_lang[$row['id_lang']])) { - $nodes_lang[$row['id_lang']] = []; - } - - if (!isset($nodes_lang[$row['id_lang']][$identifier])) { - $nodes_lang[$row['id_lang']][$identifier] = [ - 'name' => $row['name'], - 'products' => '', - ]; - } - - $nodes_lang[$row['id_lang']][$identifier]['products'] .= (($nodes_lang[$row['id_lang']][$identifier]['products']) ? ',' : '') . $this->generateId('product', $row['id_product']); - } - - return [ - 'nodes' => [], - 'nodes_lang' => $nodes_lang, - ]; - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function generateId($entity, $primary, array $row = [], $id_format = null) - { - static $ids = []; - - if (isset($ids[$entity][$primary])) { - return $ids[$entity][$primary]; - } - - if (!isset($ids[$entity])) { - $ids[$entity] = []; - } - - if (!$primary) { - return ''; - } - - if (!$id_format || !$row || !$row[$id_format]) { - $ids[$entity][$primary] = $entity . '_' . $primary; - } else { - $value = $row[$id_format]; - $value = preg_replace('#[^a-z0-9_-]#i', '_', $value); - $value = preg_replace('#_+#', '_', $value); - $value = preg_replace('#^_+#', '', $value); - $value = preg_replace('#_+$#', '', $value); - - $store_identifier = $value; - $i = 1; - while (in_array($store_identifier, $ids[$entity])) { - $store_identifier = $value . '_' . $i++; - } - $ids[$entity][$primary] = $store_identifier; - } - - return $ids[$entity][$primary]; - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function createXmlEntityNodes($entity, array $nodes, \SimpleXMLElement $entities) - { - $types = array_merge($this->getColumns($entity), $this->getColumns($entity, true)); - foreach ($nodes as $id => $node) { - $entity_node = $entities->addChild($entity); - $entity_node['id'] = $id; - foreach ($node as $k => $v) { - if (isset($types[$k]) && $types[$k]) { - $entity_node->addChild($k, $v); - } else { - $entity_node[$k] = $v; - } - } - } - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function backupImage($entity, $path) - { - $reference = [ - 'product' => 'products', - 'category' => 'categories', - 'manufacturer' => 'manufacturers', - 'supplier' => 'suppliers', - 'store' => 'stores', - ]; - - $types = []; - if (isset($reference[$entity])) { - $types = []; - foreach (ImageType::getImagesTypes($reference[$entity]) as $type) { - $types[] = $type['name']; - } - } - - $path_list = array_map('trim', explode(',', $path)); - foreach ($path_list as $p) { - $backup_path = $this->img_path . $p . '/'; - $from_path = _PS_IMG_DIR_ . $p . '/'; - - if (!is_dir($backup_path) && !mkdir($backup_path)) { - $this->setError(sprintf('Cannot create directory %s', $backup_path)); - } - - foreach (scandir($from_path, SCANDIR_SORT_NONE) as $file) { - if ($file[0] != '.' && preg_match('#^(([0-9]+)(-(' . implode('|', $types) . '))?)\.(gif|jpg|jpeg|png)$#i', $file, $m)) { - $file_id = $m[2]; - $file_type = $m[3]; - $file_extension = $m[5]; - copy($from_path . $file, $backup_path . $this->generateId($entity, $file_id) . $file_type . '.' . $file_extension); - } - } - } - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function backupImageImage() - { - $types = []; - foreach (ImageType::getImagesTypes('products') as $type) { - $types[] = $type['name']; - } - - $backup_path = $this->img_path . 'p/'; - $from_path = _PS_PROD_IMG_DIR_; - if (!is_dir($backup_path) && !mkdir($backup_path)) { - $this->setError(sprintf('Cannot create directory %s', $backup_path)); - } - - foreach (Image::getAllImages() as $image) { - $image = new Image($image['id_image']); - $image_path = $image->getExistingImgPath(); - if (file_exists($from_path . $image_path . '.' . $image->image_format)) { - copy($from_path . $image_path . '.' . $image->image_format, $backup_path . $this->generateId('image', $image->id) . '.' . $image->image_format); - } - - foreach ($types as $type) { - if (file_exists($from_path . $image_path . '-' . $type . '.' . $image->image_format)) { - copy($from_path . $image_path . '-' . $type . '.' . $image->image_format, $backup_path . $this->generateId('image', $image->id) . '-' . $type . '.' . $image->image_format); - } - } - } - } - - /** - * ONLY FOR DEVELOPMENT PURPOSE. - */ - public function backupImageTab() - { - $backup_path = $this->img_path . 't/'; - $from_path = _PS_IMG_DIR_ . 't/'; - if (!is_dir($backup_path) && !mkdir($backup_path)) { - $this->setError(sprintf('Cannot create directory %s', $backup_path)); - } - - $xml = $this->loadEntity('tab'); - foreach ($xml->entities->tab as $tab) { - if (file_exists($from_path . $tab->class_name . '.gif')) { - copy($from_path . $tab->class_name . '.gif', $backup_path . $tab->class_name . '.gif'); - } - } - } -} diff --git a/src/PrestaShopBundle/Kernel/ModuleRepository.php b/src/PrestaShopBundle/Kernel/ModuleRepository.php deleted file mode 100644 index 6da244a0..00000000 --- a/src/PrestaShopBundle/Kernel/ModuleRepository.php +++ /dev/null @@ -1,99 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Kernel; - -use Doctrine\DBAL\Connection; -use Symfony\Component\Finder\Finder; - -/** - * Before booting the PrestaShop application in Symfony context, - * we register every installed modules. - */ -final class ModuleRepository -{ - /** - * @var Connection - */ - private $connection; - - /** - * @var string the `modules` table name - */ - private $tableName; - - /** - * @var array - */ - private $activeModules; - - /** - * @var array - */ - private $activeModulesPaths; - - public function __construct(Connection $connection, $databasePrefix) - { - $this->connection = $connection; - $this->tableName = $databasePrefix . 'module'; - } - - /** - * @return array the list of installed modules - */ - public function getActiveModules() - { - if (null === $this->activeModules) { - $sth = $this->connection->query('SELECT name FROM ' . $this->tableName . ' WHERE active = 1'); - - $this->activeModules = $sth->fetchAll(\PDO::FETCH_COLUMN); - } - - return $this->activeModules; - } - - /** - * Returns installed module file paths. - * - * @return array - */ - public function getActiveModulesPaths() - { - if (null === $this->activeModulesPaths) { - $this->activeModulesPaths = []; - $modulesFiles = Finder::create()->directories()->in(__DIR__ . '/../../../modules')->depth(0); - $activeModules = $this->getActiveModules(); - - foreach ($modulesFiles as $moduleFile) { - if (in_array($moduleFile->getFilename(), $activeModules)) { - $this->activeModulesPaths[] = $moduleFile->getPathname(); - } - } - } - - return $this->activeModulesPaths; - } -} diff --git a/src/PrestaShopBundle/Kernel/ModuleRepositoryFactory.php b/src/PrestaShopBundle/Kernel/ModuleRepositoryFactory.php deleted file mode 100644 index bc57fff5..00000000 --- a/src/PrestaShopBundle/Kernel/ModuleRepositoryFactory.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Kernel; - -use Doctrine\DBAL\DriverManager; -use PrestaShop\PrestaShop\Adapter\Environment; - -/** - * Class ModuleRepositoryFactory is used to build the ModuleRepository in context where symfony container is not - * available or not yet initialised (ex: AppKernel, PrestaShop\PrestaShop\Adapter\ContainerBuilder). - * This factory is able to fetch the necessary parameters itself and builds the database connection for ModuleRepository. - * - * WARNING: this factory is only to be used in the specific cases mentioned above, for any other case please use the - * 'prestashop.module_kernel.repository' or 'prestashop.bundle.repository.module' depending on your needs. - */ -class ModuleRepositoryFactory -{ - /** - * @var self - */ - private static $instance; - - /** - * @var string - */ - private $parameters; - - /** - * @var string - */ - private $environment; - - /** - * @var ModuleRepository - */ - private $moduleRepository; - - /** - * @var string - */ - private $parametersFile = ''; - - public static function getInstance() - { - if (!self::$instance) { - self::$instance = new ModuleRepositoryFactory(); - } - - return self::$instance; - } - - /** - * @param array|null $parameters - * @param string|null $environment - */ - public function __construct(array $parameters = null, $environment = null) - { - $this->parameters = $parameters; - $this->environment = $environment; - if (null === $environment) { - $this->environment = (new Environment())->getName(); - } - } - - /** - * @return ModuleRepository - * - * @throws \Doctrine\DBAL\DBALException - */ - public function getRepository() - { - $parameters = $this->getParameters(); - if (null !== $parameters && null === $this->moduleRepository) { - $databasePrefix = $parameters['database_prefix']; - $this->moduleRepository = new ModuleRepository( - $this->getConnection($parameters), - $databasePrefix - ); - } - - return $this->moduleRepository; - } - - /** - * @param array $parameters - * - * @return \Doctrine\DBAL\Connection - * - * @throws \Doctrine\DBAL\DBALException - */ - private function getConnection(array $parameters) - { - return DriverManager::getConnection([ - 'dbname' => $parameters['database_name'], - 'user' => $parameters['database_user'], - 'password' => $parameters['database_password'], - 'host' => $parameters['database_host'], - 'port' => $parameters['database_port'], - 'charset' => 'utf8', - 'driver' => 'pdo_mysql', - ]); - } - - /** - * @return string file path to PrestaShop configuration parameters - */ - private function getParametersFile() - { - if (empty($this->parametersFile) && file_exists(__DIR__ . '/../../../app/config/parameters.php')) { - $this->parametersFile = realpath(__DIR__ . '/../../../app/config/parameters.php'); - } - - return $this->parametersFile; - } - - /** - * @return array - */ - private function getParameters() - { - if (null === $this->parameters && !empty($this->getParametersFile())) { - $config = require $this->getParametersFile(); - $this->parameters = $config['parameters']; - } - - return $this->parameters; - } -} diff --git a/src/PrestaShopBundle/Model/AdminModelAdapter.php b/src/PrestaShopBundle/Model/AdminModelAdapter.php deleted file mode 100644 index a536ff39..00000000 --- a/src/PrestaShopBundle/Model/AdminModelAdapter.php +++ /dev/null @@ -1,55 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Model; - -/** - * This form class is responsible to map the form data to the posted object. - * - * For this parent class, only hook sub fields are handled. - */ -class AdminModelAdapter -{ - /** - * modelMapper - * Map form data to object model. - * - * This parent method will return only hook sub array. - * - * @return array Transformed form data to model attempt - */ - public function getHookData() - { - // Hook fields are kept. - if (array_key_exists('hook', $_POST)) { - $hookFields = $_POST['hook']; - - return ['hook' => $hookFields]; - } - - return []; - } -} diff --git a/src/PrestaShopBundle/Model/Product/AdminModelAdapter.php b/src/PrestaShopBundle/Model/Product/AdminModelAdapter.php deleted file mode 100644 index 1af007b4..00000000 --- a/src/PrestaShopBundle/Model/Product/AdminModelAdapter.php +++ /dev/null @@ -1,969 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Model\Product; - -use Attachment; -use Configuration as ConfigurationLegacy; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Feature\FeatureDataProvider; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use PrestaShop\PrestaShop\Adapter\Pack\PackDataProvider; -use PrestaShop\PrestaShop\Adapter\Product\AdminProductWrapper; -use PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider; -use PrestaShop\PrestaShop\Adapter\Shop\Context as ShopContext; -use PrestaShop\PrestaShop\Adapter\Supplier\SupplierDataProvider; -use PrestaShop\PrestaShop\Adapter\Tax\TaxRuleDataProvider; -use PrestaShop\PrestaShop\Adapter\Tools; -use PrestaShop\PrestaShop\Adapter\Warehouse\WarehouseDataProvider; -use PrestaShop\PrestaShop\Core\Product\ProductInterface; -use PrestaShopBundle\Utils\FloatParser; -use Product; -use ProductDownload; -use Symfony\Component\Routing\Router; - -/** - * This form class is responsible to map the form data to the product object. - */ -class AdminModelAdapter extends \PrestaShopBundle\Model\AdminModelAdapter -{ - /** @var LegacyContext */ - private $context; - /** @var \Context */ - private $contextShop; - /** @var AdminProductWrapper */ - private $adminProductWrapper; - /** @var array */ - private $locales; - /** @var string */ - private $defaultLocale; - /** @var Tools */ - private $tools; - /** @var ProductDataProvider */ - private $productAdapter; - /** @var SupplierDataProvider */ - private $supplierAdapter; - /** @var FeatureDataProvider */ - private $featureAdapter; - /** @var PackDataProvider */ - private $packAdapter; - /** @var Configuration */ - private $configuration; - /** @var ShopContext */ - private $shopContext; - /** @var TaxRuleDataProvider */ - private $taxRuleDataProvider; - /** @var array */ - private $productPricePriority; - /** @var WarehouseDataProvider */ - private $warehouseAdapter; - /** @var Router */ - private $router; - - /** - * @var FloatParser - */ - private $floatParser; - - /** @var array */ - private $multiShopKeys = [ - 'category_box', - 'id_category_default', - 'attribute_wholesale_price', - 'attribute_price_impact', - 'attribute_weight_impact', - 'attribute_unit_impact', - 'attribute_ecotax', - 'attribute_minimal_quantity', - 'attribute_low_stock_threshold', - 'attribute_low_stock_alert', - 'available_date_attribute', - 'attribute_default', - 'uploadable_files', - 'text_fields', - 'active', - 'redirect_type', - 'id_type_redirected', - 'visibility', - 'available_for_order', - 'show_price', - 'online_only', - 'show_condition', - 'condition', - 'wholesale_price', - 'price', - 'id_tax_rules_group', - 'ecotax', - 'unit_price', - 'on_sale', - 'minimal_quantity', - 'low_stock_threshold', - 'low_stock_alert', - 'available_date', - 'ecotax', - ]; - - /** - * Defines translatable key. - * - * @var array - */ - private $translatableKeys = [ - 'name', - 'description', - 'description_short', - 'link_rewrite', - 'meta_title', - 'meta_description', - 'available_now', - 'available_later', - 'tags', - 'delivery_in_stock', - 'delivery_out_stock', - ]; - - /** - * Defines unused key for manual binding. - * - * @var array - */ - private $unmapKeys = [ - 'name', - 'description', - 'description_short', - 'images', - 'related_products', - 'categories', - 'suppliers', - 'display_options', - 'features', - 'specific_price', - 'virtual_product', - 'attachment_product', - ]; - - /** - * Array containing all the data to be mapped with the form. - * - * @var array - */ - private $formData; - - /** - * Constructor - * Set all adapters needed and get product. - * - * @param LegacyContext $legacyContext - * @param AdminProductWrapper $adminProductWrapper - * @param Tools $toolsAdapter - * @param ProductDataProvider $productDataProvider - * @param SupplierDataProvider $supplierDataProvider - * @param WarehouseDataProvider $warehouseDataProvider - * @param FeatureDataProvider $featureDataProvider - * @param PackDataProvider $packDataProvider - * @param ShopContext $shopContext - * @param TaxRuleDataProvider $taxRuleDataProvider - * @param Router $router - * @param FloatParser|null $floatParser - */ - public function __construct( - LegacyContext $legacyContext, - AdminProductWrapper $adminProductWrapper, - Tools $toolsAdapter, - ProductDataProvider $productDataProvider, - SupplierDataProvider $supplierDataProvider, - WarehouseDataProvider $warehouseDataProvider, - FeatureDataProvider $featureDataProvider, - PackDataProvider $packDataProvider, - ShopContext $shopContext, - TaxRuleDataProvider $taxRuleDataProvider, - Router $router, - FloatParser $floatParser = null - ) { - $this->context = $legacyContext; - $this->contextShop = $this->context->getContext(); - $this->adminProductWrapper = $adminProductWrapper; - $this->locales = $this->context->getLanguages(); - $this->defaultLocale = $this->locales[0]['id_lang']; - $this->tools = $toolsAdapter; - $this->productAdapter = $productDataProvider; - $this->supplierAdapter = $supplierDataProvider; - $this->warehouseAdapter = $warehouseDataProvider; - $this->featureAdapter = $featureDataProvider; - $this->packAdapter = $packDataProvider; - $this->configuration = new Configuration(); - $this->shopContext = $shopContext; - $this->taxRuleDataProvider = $taxRuleDataProvider; - $this->router = $router; - $this->floatParser = $floatParser ?? new FloatParser(); - } - - /** - * modelMapper - * Map form data to object model. - * - * @param array $form_data - * @param bool $isMultiShopContext If the context is define to multishop, force data to be apply on all shops - * - * @return array Transformed form data to model attempt - */ - public function getModelData($form_data, $isMultiShopContext = false) - { - //merge all form steps - $form_data = array_merge( - ['id_product' => $form_data['id_product']], - $form_data['step1'], - $form_data['step2'], - $form_data['step3'], - $form_data['step4'], - $form_data['step5'], - $form_data['step6'] - ); - - //add some legacy field to execute some add/update methods - $form_data['submitted_tabs'] = ['Shipping']; - $form_data['submitted_tabs'][] = 'Associations'; - - //map translatable - foreach ($this->translatableKeys as $field) { - foreach ($form_data[$field] as $lang_id => $translate_value) { - $form_data[$field . '_' . $lang_id] = $translate_value; - } - } - - //Product type - if ($form_data['type_product'] == 2) { - $form_data['condition'] = 'new'; - $form_data['is_virtual'] = 1; - } else { - $form_data['is_virtual'] = 0; - } - - // Product redirection - $form_data['redirect_type'] = (string) $form_data['redirect_type']; - if ($form_data['redirect_type'] != ProductInterface::REDIRECT_TYPE_NOT_FOUND) { - if (isset($form_data['id_type_redirected']) && !empty($form_data['id_type_redirected']['data'])) { - $form_data['id_type_redirected'] = $form_data['id_type_redirected']['data'][0]; - } elseif (ProductInterface::REDIRECT_TYPE_CATEGORY_MOVED_PERMANENTLY == $form_data['redirect_type'] || ProductInterface::REDIRECT_TYPE_CATEGORY_FOUND == $form_data['redirect_type']) { - $form_data['id_type_redirected'] = 0; - } else { - $form_data['id_type_redirected'] = 0; - $form_data['redirect_type'] = ProductInterface::REDIRECT_TYPE_CATEGORY_MOVED_PERMANENTLY; - } - } else { - $form_data['id_type_redirected'] = 0; - } - - //map inputPackItems - if ($form_data['type_product'] == 1 - && !empty($form_data['inputPackItems']) - && !empty($form_data['inputPackItems']['data']) - ) { - $inputPackItems = ''; - foreach ($form_data['inputPackItems']['data'] as $productIds) { - $inputPackItems .= $productIds . '-'; - } - $form_data['inputPackItems'] = $inputPackItems; - } else { - $form_data['inputPackItems'] = ''; - } - - //map categories - foreach ($form_data['categories']['tree'] as $category) { - $form_data['categoryBox'][] = $category; - } - - //if empty categories, set default one - if (empty($form_data['categoryBox'])) { - $form_data['categoryBox'][] = $this->contextShop->shop->id_category; - } - - //if default category not define, set the default one - if (empty($form_data['id_category_default'])) { - $form_data['id_category_default'] = $this->contextShop->shop->id_category; - } - - //map combinations and impact price/weight/unit price - foreach ($form_data['combinations'] as $k => $combination) { - $form_data['combinations'][$k]['attribute_price_impact'] = 0; - $form_data['combinations'][$k]['attribute_weight_impact'] = 0; - $form_data['combinations'][$k]['attribute_unit_impact'] = 0; - - if ($this->floatParser->fromString($combination['attribute_price']) > 0) { - $form_data['combinations'][$k]['attribute_price_impact'] = 1; - } elseif ($this->floatParser->fromString($combination['attribute_price']) < 0) { - $form_data['combinations'][$k]['attribute_price_impact'] = -1; - } - - if ($this->floatParser->fromString($combination['attribute_weight']) > 0) { - $form_data['combinations'][$k]['attribute_weight_impact'] = 1; - } elseif ($this->floatParser->fromString($combination['attribute_weight']) < 0) { - $form_data['combinations'][$k]['attribute_weight_impact'] = -1; - } - - if ($this->floatParser->fromString($combination['attribute_unity']) > 0) { - $form_data['combinations'][$k]['attribute_unit_impact'] = 1; - } elseif ($this->floatParser->fromString($combination['attribute_unity']) < 0) { - $form_data['combinations'][$k]['attribute_unit_impact'] = -1; - } - - $form_data['combinations'][$k]['attribute_price'] = abs( - $this->floatParser->fromString($combination['attribute_price']) - ); - $form_data['combinations'][$k]['attribute_weight'] = abs( - $this->floatParser->fromString($combination['attribute_weight']) - ); - $form_data['combinations'][$k]['attribute_unity'] = abs( - $this->floatParser->fromString($combination['attribute_unity']) - ); - } - - //map suppliers - $form_data['supplier_loaded'] = 1; - if (!empty($form_data['suppliers'])) { - foreach ($form_data['suppliers'] as $id_supplier) { - $form_data['check_supplier_' . $id_supplier] = 1; - - //map supplier combinations - foreach ($form_data['supplier_combination_' . $id_supplier] as $combination) { - $key = $form_data['id_product'] . '_' . $combination['id_product_attribute'] . '_' . $id_supplier; - $form_data['supplier_reference_' . $key] = $combination['supplier_reference']; - $form_data['product_price_' . $key] = $combination['product_price']; - $form_data['product_price_currency_' . $key] = $combination['product_price_currency']; - - unset($form_data['supplier_combination_' . $id_supplier]); - } - } - } - - //map display options - foreach ($form_data['display_options'] as $option => $value) { - $form_data[$option] = $value; - } - - //if empty, set link_rewrite for default locale - $linkRewriteKey = 'link_rewrite_' . $this->locales[0]['id_lang']; - if (empty($form_data[$linkRewriteKey])) { - $form_data[$linkRewriteKey] = $this->tools->link_rewrite($form_data['name_' . $this->locales[0]['id_lang']]); - } - - //map inputAccessories - if (!empty($form_data['related_products']) && !empty($form_data['related_products']['data'])) { - $inputAccessories = ''; - foreach ($form_data['related_products']['data'] as $accessoryIds) { - $accessoryIds = explode(',', $accessoryIds); - $inputAccessories .= $accessoryIds[0] . '-'; - } - $form_data['inputAccessories'] = $inputAccessories; - } - - //map warehouseProductLocations - $form_data['warehouse_loaded'] = 1; - $warehouses = $this->warehouseAdapter->getWarehouses(); - foreach ($warehouses as $warehouse) { - foreach ($form_data['warehouse_combination_' . $warehouse['id_warehouse']] as $combination) { - $key = $combination['warehouse_id'] - . '_' . $combination['product_id'] - . '_' . $combination['id_product_attribute']; - if ($combination['activated']) { - $form_data['check_warehouse_' . $key] = '1'; - } - $form_data['location_warehouse_' . $key] = $combination['location']; - - unset($form_data['warehouse_combination_' . $warehouse['id_warehouse']]); - } - } - - //force customization fields values - $form_data['uploadable_files'] = 0; - $form_data['text_fields'] = 0; - - //map all - $new_form_data = []; - foreach ($form_data as $k => $v) { - if (in_array($k, $this->unmapKeys) || in_array($k, $this->translatableKeys)) { - continue; - } - $new_form_data[$k] = $v; - } - - //map specific price priority - $new_form_data['specificPricePriority'] = [ - $new_form_data['specificPricePriority_0'], - $new_form_data['specificPricePriority_1'], - $new_form_data['specificPricePriority_2'], - $new_form_data['specificPricePriority_3'], - ]; - - $new_form_data = array_merge(parent::getHookData(), $new_form_data); - - //if multiShop context is defined, simulate multiShop checkbox for all POST DATA - if ($isMultiShopContext) { - foreach ($this->multiShopKeys as $multishopKey) { - $new_form_data['multishop_check'][$multishopKey] = 1; - } - - //apply multishop rules for translatables fields - foreach ($this->translatableKeys as $field) { - foreach ($form_data[$field] as $lang_id => $translate_value) { - $new_form_data['multishop_check'][$field][$lang_id] = 1; - } - } - } - - return $new_form_data; - } - - /** - * formMapper - * Map object model to form data. - * - * @param Product $product - * - * @return array Transformed model data to form attempt - */ - public function getFormData(Product $product) - { - $product->loadStockData(); - $this->productPricePriority = $this->adminProductWrapper->getPricePriority($product->id); - - $this->formData['id_product'] = $product->id; - $this->formData['step1'] = $this->mapStep1FromData($product); - $this->formData['step2'] = $this->mapStep2FormData($product); - $this->formData['step3'] = $this->mapStep3FormData($product); - $this->formData['step4'] = $this->mapStep4FormData($product); - $this->formData['step5'] = $this->mapStep5FormData($product); - $this->formData['step6'] = $this->mapStep6FormData($product); - - //Inject data form for supplier combinations - $this->formData['step6'] = array_merge($this->formData['step6'], $this->getDataSuppliersCombinations($product)); - - //Inject data form for warehouse combinations - $this->formData['step4'] = array_merge( - $this->formData['step4'], - $this->getDataWarehousesCombinations($product) - ); - - return $this->formData; - } - - /** - * Maps the existing products data to the form for Step 1. - * - * @param Product $product - * - * @return array - */ - private function mapStep1FromData(Product $product) - { - return [ - 'type_product' => $product->getType(), - 'inputPackItems' => [ - 'data' => array_map( - function ($p) { - return [ - 'id' => $p->id, - 'id_product_attribute' => isset($p->id_pack_product_attribute) - ? $p->id_pack_product_attribute - : 0, - 'name' => $p->name, - 'ref' => $p->reference, - 'quantity' => $p->pack_quantity, - 'image' => $p->image, - ]; - }, - $this->packAdapter->getItems($product->id, $this->locales[0]['id_lang']) - ), - ], - 'name' => $product->name, - 'description' => $product->description, - 'description_short' => $product->description_short, - 'active' => $product->active == 0 ? false : true, - 'price_shortcut' => $product->price, - 'qty_0_shortcut' => $product->getQuantity($product->id), - 'categories' => ['tree' => $product->getCategories()], - 'id_category_default' => $product->id_category_default, - 'related_products' => [ - 'data' => array_map( - function ($p) { - return $p['id_product']; - }, - call_user_func_array( - [$product, 'getAccessoriesLight'], - [$this->locales[0]['id_lang'], $product->id] - ) - ), - ], - 'id_manufacturer' => $product->id_manufacturer, - 'features' => $this->getFormFeatures($product), - 'images' => $this->productAdapter->getImages($product->id, $this->locales[0]['id_lang']), - ]; - } - - /** - * Maps the existing products data to the form for Step 2. - * - * @param Product $product - * - * @return array - */ - private function mapStep2FormData(Product $product) - { - // ecotax is stored with tax included but form uses the tax excluded value - // using a precision of 6 digits as `AdminProductsController::_removeTaxFromEcotax()` - // which does the opposite uses 6 digits too - $ecotax = $this->tools->round( - $product->ecotax * (1 + $this->taxRuleDataProvider->getProductEcotaxRate() / 100), - 6 - ); - - return [ - 'price' => $product->price, - 'ecotax' => $ecotax, - 'id_tax_rules_group' => isset($product->id_tax_rules_group) - ? (int) $product->id_tax_rules_group - : $this->taxRuleDataProvider->getIdTaxRulesGroupMostUsed(), - 'on_sale' => (bool) $product->on_sale, - 'wholesale_price' => $product->wholesale_price, - 'unit_price' => $product->unit_price_ratio != 0 - ? $product->price / $product->unit_price_ratio - : 0, - 'unity' => $product->unity, - 'specific_price' => [ // extra form to be saved separately. Here this is the default form values. - 'sp_from_quantity' => 1, - 'sp_reduction' => 0, - 'sp_reduction_tax' => 1, - 'leave_bprice' => true, - 'sp_id_shop' => $this->shopContext->getContextShopID(), - ], - 'specificPricePriority_0' => $this->productPricePriority[0], - 'specificPricePriority_1' => $this->productPricePriority[1], - 'specificPricePriority_2' => $this->productPricePriority[2], - 'specificPricePriority_3' => $this->productPricePriority[3], - ]; - } - - /** - * Maps the existing products data to the form for Step 3. - * - * @param Product $product - * - * @return array - */ - private function mapStep3FormData(Product $product) - { - return [ - 'advanced_stock_management' => (bool) $product->advanced_stock_management, - 'depends_on_stock' => $product->depends_on_stock ? '1' : '0', - 'qty_0' => $product::getQuantity($product->id), - 'id_product_attributes' => $this->getProductAttributes($product), - 'out_of_stock' => $product->out_of_stock, - 'minimal_quantity' => $product->minimal_quantity, - 'location' => $product->location, - 'low_stock_threshold' => $product->low_stock_threshold, - 'low_stock_alert' => (bool) $product->low_stock_alert, - 'available_now' => $product->available_now, - 'available_later' => $product->available_later, - 'available_date' => $product->available_date, - 'pack_stock_type' => $product->pack_stock_type, - 'virtual_product' => $this->getVirtualProductData($product), - ]; - } - - /** - * Maps the existing products data to the form for Step 4. - * - * @param Product $product - * - * @return array - */ - private function mapStep4FormData(Product $product) - { - return [ - 'width' => $product->width, - 'height' => $product->height, - 'depth' => $product->depth, - 'weight' => $product->weight, - 'additional_shipping_cost' => $product->additional_shipping_cost, - 'selectedCarriers' => $this->getFormProductCarriers($product), - 'additional_delivery_times' => $product->additional_delivery_times, - 'delivery_in_stock' => $product->delivery_in_stock, - 'delivery_out_stock' => $product->delivery_out_stock, - ]; - } - - /** - * Maps the existing products data to the form for Step 5. - * - * @param Product $product - * - * @return array - */ - private function mapStep5FormData(Product $product) - { - return [ - 'link_rewrite' => $product->link_rewrite, - 'meta_title' => $product->meta_title, - 'meta_description' => $product->meta_description, - 'redirect_type' => $product->redirect_type, - 'id_type_redirected' => [ - 'data' => [$product->id_type_redirected], - ], - ]; - } - - /** - * Maps the existing products data to the form for Step 6. - * - * @param Product $product - * - * @return array - */ - private function mapStep6FormData(Product $product) - { - return [ - 'visibility' => $product->visibility, - 'tags' => $this->getTags($product), - 'display_options' => [ - 'available_for_order' => (bool) $product->available_for_order, - 'show_price' => (bool) $product->show_price, - 'online_only' => (bool) $product->online_only, - ], - 'upc' => $product->upc, - 'mpn' => $product->mpn, - 'ean13' => $product->ean13, - 'isbn' => $product->isbn, - 'reference' => $product->reference, - 'show_condition' => (bool) $product->show_condition, - 'condition' => $product->condition, - 'suppliers' => array_map( - function ($s) { - return $s->id_supplier; - }, - $this->supplierAdapter->getProductSuppliers($product->id) - ), - 'default_supplier' => $product->id_supplier, - 'custom_fields' => $this->getCustomFields($product), - 'attachments' => $this->getProductAttachments($product), - ]; - } - - /** - * Get all available product attributes resume. - * - * @param Product $product - * - * @return array Product attributes combinations - */ - public function getAttributesResume(Product $product) - { - return $product->getAttributesResume($this->context->getContext()->language->id); - } - - /** - * Get product attachments. - * - * @param Product $product - * - * @return array - */ - private function getProductAttachments(Product $product) - { - return array_map( - function ($attachment) { - return $attachment['id_attachment']; - }, - Attachment::getAttachments($this->locales[0]['id_lang'], $product->id) - ); - } - - /** - * Get virtual product data. - * - * @param Product $product - * - * @return array - */ - private function getVirtualProductData(Product $product) - { - //force virtual product feature - ConfigurationLegacy::updateGlobalValue('PS_VIRTUAL_PROD_FEATURE_ACTIVE', '1'); - - $id_product_download = ProductDownload::getIdFromIdProduct((int) $product->id, false); - if ($id_product_download) { - $download = new ProductDownload($id_product_download); - $dateValue = $download->date_expiration == '0000-00-00 00:00:00' - ? '' - : date('Y-m-d', strtotime($download->date_expiration)); - - $res = [ - 'is_virtual_file' => $download->active, - 'name' => $download->display_filename, - 'nb_downloadable' => $download->nb_downloadable, - 'expiration_date' => $dateValue, - 'nb_days' => $download->nb_days_accessible, - ]; - - if ($download->filename) { - $res['filename'] = $download->filename; - $res['file_download_link'] = $this->router->generate( - 'admin_product_virtual_download_file_action', - ['idProduct' => $download->id_product] - ); - } - - return $res; - } - - return [ - 'is_virtual_file' => 0, - 'nb_days' => 0, - ]; - } - - /** - * Generate form custom fields configuration. - * - * @param Product $product - * - * @return array - */ - private function getCustomFields(Product $product) - { - $finalCustomFields = []; - $customizationFields = []; - $productCustomizationFields = $product->getCustomizationFields(); - - if (!$productCustomizationFields) { - return []; - } - - foreach ($productCustomizationFields as $customizationField) { - $customizationFields = array_merge($customizationFields, $customizationField); - } - - foreach ($customizationFields as $customizationField) { - $baseObject = [ - 'id_customization_field' => $customizationField[$this->locales[0]['id_lang']]['id_customization_field'], - 'label' => [], - 'type' => $customizationField[$this->locales[0]['id_lang']]['type'], - 'require' => $customizationField[$this->locales[0]['id_lang']]['required'] == 1 ? true : false, - ]; - - //add translation name - foreach ($this->locales as $locale) { - $baseObject['label'][$locale['id_lang']] = $customizationField[$locale['id_lang']]['name']; - } - $finalCustomFields[] = $baseObject; - } - - return $finalCustomFields; - } - - /** - * Generate form supplier/combinations references. - * - * @param Product $product - * - * @return array filled data form references combinations - */ - private function getDataSuppliersCombinations(Product $product) - { - $combinations = $product->getAttributesResume($this->locales[0]['id_lang']); - if (!$combinations || empty($combinations)) { - $combinations[] = [ - 'id_product' => $product->id, - 'id_product_attribute' => 0, - 'attribute_designation' => $product->name[$this->locales[0]['id_lang']], - ]; - } - - //for each supplier, generate combinations list - $dataSuppliersCombinations = []; - - foreach ($this->supplierAdapter->getProductSuppliers($product->id) as $supplier) { - foreach ($combinations as $combination) { - $productSupplierData = $this->supplierAdapter->getProductSupplierData( - $product->id, - $combination['id_product_attribute'], - $supplier->id_supplier - ); - $dataSuppliersCombinations['supplier_combination_' . $supplier->id_supplier][] = [ - 'label' => $combination['attribute_designation'], - 'supplier_reference' => isset($productSupplierData['product_supplier_reference']) - ? $productSupplierData['product_supplier_reference'] - : '', - 'product_price' => isset($productSupplierData['price']) - ? $productSupplierData['price'] - : 0, - 'product_price_currency' => isset($productSupplierData['id_currency']) - ? $productSupplierData['id_currency'] - : 1, - 'supplier_id' => $supplier->id_supplier, - 'product_id' => $product->id, - 'id_product_attribute' => $combination['id_product_attribute'], - ]; - } - } - - return $dataSuppliersCombinations; - } - - /** - * Generate form warehouses/combinations references. - * - * @param Product $product - * - * @return array filled data form references combinations - */ - private function getDataWarehousesCombinations(Product $product) - { - $combinations = $product->getAttributesResume($this->locales[0]['id_lang']); - if (!$combinations || empty($combinations)) { - $combinations[] = [ - 'id_product' => $product->id, - 'id_product_attribute' => 0, - 'attribute_designation' => $product->name[$this->locales[0]['id_lang']], - ]; - } - - //for each warehouse, generate combinations list - $dataWarehousesCombinations = []; - - foreach ($this->warehouseAdapter->getWarehouses() as $warehouse) { - $warehouseId = $warehouse['id_warehouse']; - foreach ($combinations as $combination) { - $warehouseProductLocationData = $this->warehouseAdapter->getWarehouseProductLocationData( - $product->id, - $combination['id_product_attribute'], - $warehouseId - ); - $dataWarehousesCombinations['warehouse_combination_' . $warehouseId][] = [ - 'label' => $combination['attribute_designation'], - 'activated' => (bool) $warehouseProductLocationData['activated'], - 'warehouse_id' => $warehouseId, - 'product_id' => $product->id, - 'id_product_attribute' => $combination['id_product_attribute'], - 'location' => isset($warehouseProductLocationData['location']) - ? $warehouseProductLocationData['location'] - : '', - ]; - } - } - - return $dataWarehousesCombinations; - } - - /** - * get form product features. - * - * @param Product $product - * - * @return array features with translation - */ - private function getFormFeatures(Product $product) - { - $formFeaturesData = []; - foreach ($product->getFeatures() as $featureData) { - $itemForm = [ - 'feature' => $featureData['id_feature'], - 'value' => null, - 'custom_value' => null, - ]; - - if ($featureData['custom'] == 0) { - // use id_feature_value only if this value isn't custom - $itemForm['value'] = $featureData['id_feature_value']; - } else { - $customLangs = []; - $featureLangsData = $this->featureAdapter->getFeatureValueLang($featureData['id_feature_value']); - foreach ($featureLangsData as $langData) { - $customLangs[$langData['id_lang']] = $langData['value']; - } - $itemForm['custom_value'] = $customLangs; - } - - $formFeaturesData[] = $itemForm; - } - - return $formFeaturesData; - } - - /** - * get product carrier. - * - * @param Product $product - * - * @return array carrier - */ - private function getFormProductCarriers(Product $product) - { - $formDataCarriers = []; - foreach ($product->getCarriers() as $carrier) { - $formDataCarriers[] = $carrier['id_reference']; - } - - return $formDataCarriers; - } - - /** - * Get all product id_product_attribute. - * - * @param Product $product - * - * @return array id_product_attribute - */ - private function getProductAttributes(Product $product) - { - $combinations = $product->getAttributesResume($this->context->getContext()->language->id); - $idsProductAttribute = []; - - if (is_array($combinations)) { - foreach ($combinations as $combination) { - $idsProductAttribute[] = $combination['id_product_attribute']; - } - } - - return $idsProductAttribute; - } - - /** - * Get a localized tags for product. - * - * @param Product $product - * - * @return array - */ - private function getTags(Product $product) - { - $tags = []; - foreach ($this->locales as $locale) { - $tags[$locale['id_lang']] = $product->getTags($locale['id_lang']); - } - - return $tags; - } -} diff --git a/src/PrestaShopBundle/PrestaShopBundle.php b/src/PrestaShopBundle/PrestaShopBundle.php deleted file mode 100644 index de50e119..00000000 --- a/src/PrestaShopBundle/PrestaShopBundle.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle; - -use PrestaShopBundle\DependencyInjection\Compiler\CommandAndQueryCollectorPass; -use PrestaShopBundle\DependencyInjection\Compiler\ContainerInjectionPass; -use PrestaShopBundle\DependencyInjection\Compiler\DynamicRolePass; -use PrestaShopBundle\DependencyInjection\Compiler\GridDefinitionServiceIdsCollectorPass; -use PrestaShopBundle\DependencyInjection\Compiler\IdentifiableObjectFormTypesCollectorPass; -use PrestaShopBundle\DependencyInjection\Compiler\LoadServicesFromModulesPass; -use PrestaShopBundle\DependencyInjection\Compiler\ModulesDoctrineCompilerPass; -use PrestaShopBundle\DependencyInjection\Compiler\OptionsFormHookNameCollectorPass; -use PrestaShopBundle\DependencyInjection\Compiler\OverrideTranslatorServiceCompilerPass; -use PrestaShopBundle\DependencyInjection\Compiler\OverrideTwigServiceCompilerPass; -use PrestaShopBundle\DependencyInjection\Compiler\PopulateTranslationProvidersPass; -use PrestaShopBundle\DependencyInjection\Compiler\RemoveXmlCompiledContainerPass; -use PrestaShopBundle\DependencyInjection\Compiler\RouterPass; -use PrestaShopBundle\DependencyInjection\PrestaShopExtension; -use Symfony\Component\DependencyInjection\Compiler\PassConfig; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Bundle\Bundle; - -class PrestaShopBundle extends Bundle -{ - /** - * {@inheritdoc} - */ - public function getContainerExtension() - { - return new PrestaShopExtension(); - } - - /** - * {@inheritdoc} - */ - public function build(ContainerBuilder $container) - { - $container->addCompilerPass(new DynamicRolePass()); - $container->addCompilerPass(new PopulateTranslationProvidersPass()); - $container->addCompilerPass(new LoadServicesFromModulesPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1); - $container->addCompilerPass(new LoadServicesFromModulesPass('admin'), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1); - $container->addCompilerPass(new RemoveXmlCompiledContainerPass(), PassConfig::TYPE_AFTER_REMOVING); - $container->addCompilerPass(new RouterPass(), PassConfig::TYPE_AFTER_REMOVING); - $container->addCompilerPass(new OverrideTranslatorServiceCompilerPass()); - $container->addCompilerPass(new OverrideTwigServiceCompilerPass()); - $container->addCompilerPass(new ModulesDoctrineCompilerPass()); - $container->addCompilerPass(new CommandAndQueryCollectorPass()); - $container->addCompilerPass(new OptionsFormHookNameCollectorPass()); - $container->addCompilerPass(new GridDefinitionServiceIdsCollectorPass()); - $container->addCompilerPass(new IdentifiableObjectFormTypesCollectorPass()); - $container->addCompilerPass(new ContainerInjectionPass()); - } -} diff --git a/src/PrestaShopBundle/Resources/config/routing.yml b/src/PrestaShopBundle/Resources/config/routing.yml deleted file mode 100644 index 01d75f0d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Admin Back Office routing -_admin_routing: - resource: "@PrestaShopBundle/Resources/config/routing/admin.yml" - -# Api-like Back Office routing -_api_routing: - resource: "@PrestaShopBundle/Resources/config/routing/api.yml" - prefix: /api diff --git a/src/PrestaShopBundle/Resources/config/routing/admin.yml b/src/PrestaShopBundle/Resources/config/routing/admin.yml deleted file mode 100644 index 186ae293..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin.yml +++ /dev/null @@ -1,23 +0,0 @@ -_admin_common_routing: - resource: "admin/_common.yml" - prefix: /common - -_admin_security_routing: - resource: "admin/_security.yml" - prefix: /security - -_admin_sell_routing: - resource: "admin/sell/_sell.yml" - prefix: /sell - -_admin_configure_routing: - resource: "admin/configure/_configure.yml" - prefix: /configure - -_admin_improve_routing: - resource: "admin/improve/_improve.yml" - prefix: /improve - -_admin_errors: - resource: "admin/_errors.yml" - prefix: /errors diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/_common.yml b/src/PrestaShopBundle/Resources/config/routing/admin/_common.yml deleted file mode 100644 index 54daa5fd..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/_common.yml +++ /dev/null @@ -1,62 +0,0 @@ -admin_common_notifications: - path: /notifications - methods: [POST] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::notificationsAction' - _legacy_controller: AdminCommon - _legacy_link: AdminCommon - -admin_common_notifications_ack: - path: /notifications/ack - methods: [POST] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::notificationsAckAction' - -admin_common_pagination: - path: /pagination/{offset}/{limit}/{total}/{view} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::paginationAction' - offset: 0 - limit: 20 - total: 0 - view: full - requirements: - offset: \d+ - limit: \d+ - total: \d+ - view: full|quicknav - -admin_common_recommended_modules: - path: /recommended_modules/{domain}/{limit}/{randomize} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::recommendedModulesAction' - limit: 0 - randomize: 0 - requirements: - limit: \d+ - randomize: 0|1 - -admin_common_sidebar: - path: /sidebar/{url}/{title}/{footer} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::renderSidebarAction' - title: '' - footer: '' - -admin_common_reset_search: - path: /reset_search/{controller}/{action} - methods: [POST] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::resetSearchAction' - filterId: '' - -admin_common_reset_search_by_filter_id: - path: /reset_search/{filterId} - methods: [POST] - defaults: - _controller: 'PrestaShopBundle\Controller\Admin\CommonController::resetSearchAction' - controller: '' - action: '' diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/_errors.yml b/src/PrestaShopBundle/Resources/config/routing/admin/_errors.yml deleted file mode 100644 index fac337bc..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/_errors.yml +++ /dev/null @@ -1,5 +0,0 @@ -admin_errors_enable_debug_mode: - path: /enable-debug-mode - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Error:enableDebugMode diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/_security.yml b/src/PrestaShopBundle/Resources/config/routing/admin/_security.yml deleted file mode 100644 index 77913e8b..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/_security.yml +++ /dev/null @@ -1,5 +0,0 @@ -admin_security_compromised: - path: /compromised - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Security:compromisedAccess diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/_configure.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/_configure.yml deleted file mode 100644 index f2f7f23f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/_configure.yml +++ /dev/null @@ -1,16 +0,0 @@ -_admin_advanced_parameters_routing: - resource: "advanced_parameters/_advanced_parameters.yml" - prefix: /advanced/ - -_admin_shop_parameters_routing: - resource: "shop_parameters/_shop_parameters.yml" - prefix: /shop/ - -admin_close_showcase_card: - path: /showcase-card/close - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShowcaseCard:closeShowcaseCard' - requirements: - close: \d+ - name: \w+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/_advanced_parameters.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/_advanced_parameters.yml deleted file mode 100644 index c40a475a..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/_advanced_parameters.yml +++ /dev/null @@ -1,43 +0,0 @@ -_logs: - resource: "logs.yml" - prefix: /logs/ - -_administration: - resource: "administration.yml" - prefix: /administration/ - -_import: - resource: "import.yml" - prefix: /import/ - -_performance: - resource: "performance.yml" - prefix: /performance/ - -_system_information: - resource: "system_information.yml" - prefix: /system-information/ - -_email: - resource: "email.yml" - prefix: /emails - -_sql_manager: - resource: "sql_request.yml" - prefix: /sql-requests/ - -_webservice: - resource: "webservice.yml" - prefix: /webservice-keys/ - -_backup: - resource: "backup.yml" - prefix: /backups - -_employee: - resource: "employee.yml" - prefix: /employees - -_profiles: - resource: "profiles.yml" - prefix: /profiles diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/administration.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/administration.yml deleted file mode 100644 index 21e42b19..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/administration.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_administration: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Administration:index' - _legacy_controller: AdminAdminPreferences - _legacy_link: AdminAdminPreferences - -admin_administration_save: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Administration:processForm' - _legacy_controller: AdminAdminPreferences - _legacy_link: AdminAdminPreferences:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/backup.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/backup.yml deleted file mode 100644 index dac83fc1..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/backup.yml +++ /dev/null @@ -1,55 +0,0 @@ -admin_backups_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:index' - _legacy_controller: 'AdminBackup' - _legacy_link: 'AdminBackup' - -admin_backups_save_options: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:saveOptions' - _legacy_controller: 'AdminBackup' - _legacy_link: 'AdminBackup:update' - -admin_backups_create: - path: /new - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:create' - _legacy_controller: 'AdminBackup' - _legacy_link: 'AdminBackup:addbackup' - -admin_backups_download_view: - path: /view/{downloadFileName} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:downloadView' - _legacy_controller: 'AdminBackup' - -admin_backup_download: - path: /download/{downloadFileName} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:downloadContent' - _legacy_controller: 'AdminBackup' - -admin_backups_delete: - path: /{deleteFileName} - methods: [DELETE] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:delete' - _legacy_controller: 'AdminBackup' - _legacy_link: 'AdminBackup:delete' - _legacy_parameters: - filename: deleteFileName - -admin_backups_bulk_delete: - path: /bulk-delete/ - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Backup:bulkDelete' - _legacy_controller: 'AdminBackup' - _legacy_link: 'AdminBackup:submitBulkdeletebackup' diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/email.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/email.yml deleted file mode 100644 index dc9734ee..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/email.yml +++ /dev/null @@ -1,60 +0,0 @@ -admin_emails_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:index' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails - -admin_emails_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:search' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:search - -admin_emails_save_options: - path: /options - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:saveOptions' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:update - -admin_emails_send_test: - path: /send-testing-email - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:sendTest' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:testEmail - condition: 'request.isXmlHttpRequest()' - -admin_emails_delete_bulk: - path: /delete-bulk - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:deleteBulk' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:submitBulkdeletemail - -admin_emails_delete_all: - path: /delete-all - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:deleteAll' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:deleteAll - -admin_emails_delete: - path: /delete/{mailId} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Email:delete' - _legacy_controller: AdminEmails - _legacy_link: AdminEmails:deletemail - _legacy_parameters: - id_mail: mailId - requirements: - mailId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/employee.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/employee.yml deleted file mode 100644 index 4a0e9dd2..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/employee.yml +++ /dev/null @@ -1,108 +0,0 @@ -admin_employees_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:index' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees - -admin_employees_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Common:searchGrid' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:submitFilteremployee - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.employee - redirectRoute: admin_employees_index - -admin_employees_save_options: - path: /save-options - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:saveOptions' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:submitOptionsemployee - -admin_employees_toggle_status: - path: /{employeeId}/toggle-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:toggleStatus' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:statusemployee - _legacy_parameters: - id_employee: employeeId - -admin_employees_bulk_enable_status: - path: /bulk-enable-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:bulkStatusEnable' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:submitBulkenableSelectionemployee - -admin_employees_bulk_disable_status: - path: /bulk-disable-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:bulkStatusDisable' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:submitBulkdisableSelectionemployee - -admin_employees_delete: - path: /{employeeId}/delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:delete' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:deleteemployee - _legacy_parameters: - id_employee: employeeId - -admin_employees_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:bulkDelete' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:submitBulkdeleteemployee - -admin_employees_create: - path: /new - methods: [GET,POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:create' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:addemployee - -admin_employees_edit: - path: /{employeeId}/edit - methods: [GET,POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:edit' - _legacy_controller: AdminEmployees - _legacy_link: AdminEmployees:updateemployee - _legacy_parameters: - id_employee: employeeId - requirements: - employeeId: \d+ - -admin_employees_toggle_navigation: - path: /toggle-navigation - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:toggleNavigationMenu' - -admin_employees_change_form_language: - path: /change-form-language - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:changeFormLanguage' - -admin_employees_get_tabs: - path: /tabs - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Employee:getAccessibleTabs' - _legacy_controller: AdminEmployees diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/import.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/import.yml deleted file mode 100644 index ddcaa8bf..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/import.yml +++ /dev/null @@ -1,96 +0,0 @@ -admin_import: - path: / - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:import' - _legacy_controller: AdminImport - _legacy_link: AdminImport - -admin_import_data_configuration_index: - path: /data - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\ImportDataConfiguration:index' - _legacy_controller: AdminImport - -# This redirect prevents an error (redirects to import first page instead) when -# trying to access import data page with GET http method. -# It happens on direct access or when the session token expires and -# the user clicks "I understand the risk" in the warning page. -admin_import_data_configuration_index_redirect: - path: /data - methods: [GET] - controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction' - defaults: - route: 'admin_import' - -admin_import_process: - path: /process - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:processImport' - _legacy_controller: AdminImport - -admin_import_file_upload: - path: /file/upload - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:upload' - _legacy_controller: AdminImport - _legacy_link: AdminImport:uploadCsv - -admin_import_file_delete: - path: /file/delete - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:delete' - _legacy_controller: AdminImport - _legacy_link: AdminImport:delete - -admin_import_file_download: - path: /file/download - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:download' - _legacy_controller: AdminImport - _legacy_link: AdminImport:download - -admin_import_sample_download: - path: /sample/download/{sampleName} - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:downloadSample' - _legacy_controller: AdminImport - _legacy_link: AdminImport:sampleDownload - -admin_import_data_configuration_create: - path: /match - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\ImportDataConfiguration:create' - _legacy_controller: AdminImport - _legacy_link: AdminImport:saveImportMatch - -admin_import_data_configuration_get: - path: /match - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\ImportDataConfiguration:get' - _legacy_controller: AdminImport - _legacy_link: AdminImport:getImportMatch - -admin_import_data_configuration_delete: - path: /match - methods: [DELETE] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\ImportDataConfiguration:delete' - _legacy_controller: AdminImport - _legacy_link: AdminImport:deleteImportMatch - -admin_import_get_available_fields: - path: /fields - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Import:getAvailableEntityFields' - _legacy_controller: AdminImport - _legacy_link: AdminImport:getAvailableEntityFields diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/logs.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/logs.yml deleted file mode 100644 index 6a3351c4..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/logs.yml +++ /dev/null @@ -1,30 +0,0 @@ -admin_logs_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Logs:index' - _legacy_controller: AdminLogs - _legacy_link: AdminLogs - -admin_logs_save_settings: - path: /settings - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Logs:saveSettings' - _legacy_controller: AdminLogs - _legacy_link: AdminLogs:update - -admin_logs_delete_all: - path: /delete-all - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Logs:deleteAll' - _legacy_controller: AdminLogs - _legacy_link: AdminLogs:deletelog - -admin_logs_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Logs:search' - _legacy_controller: AdminLogs diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/performance.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/performance.yml deleted file mode 100644 index 763f6746..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/performance.yml +++ /dev/null @@ -1,58 +0,0 @@ -admin_performance: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Performance:index' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance - -admin_performance_save: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Performance:processForm' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance:update - -admin_clear_cache: - path: /clear-cache - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Performance:clearCache' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance:empty_smarty_cache - -admin_servers: - path: /memcache/servers - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\MemcacheServer:list' - _legacy_controller: AdminPerformance - condition: 'request.isXmlHttpRequest()' - -admin_servers_add: - path: /memcache/servers - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\MemcacheServer:add' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance:submitAddServer - condition: 'request.isXmlHttpRequest()' - -admin_servers_delete: - path: /memcache/servers - methods: [DELETE] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\MemcacheServer:delete' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance:deleteMemcachedServer - condition: 'request.isXmlHttpRequest()' - -admin_servers_test: - path: /memcache/servers/test - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\MemcacheServer:test' - _legacy_controller: AdminPerformance - _legacy_link: AdminPerformance:test_server - condition: 'request.isXmlHttpRequest()' diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/profiles.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/profiles.yml deleted file mode 100644 index 4d702055..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/profiles.yml +++ /dev/null @@ -1,55 +0,0 @@ -admin_profiles_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:index' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles - -admin_profiles_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:search' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles:submitFilterprofile - -admin_profiles_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:create' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles:addprofile - -admin_profiles_edit: - path: /{profileId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:edit' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles:updateprofile - _legacy_parameters: - id_profile: profileId - requirements: - profileId: \d+ - -admin_profiles_delete: - path: /{profileId}/delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:delete' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles:deleteprofile - _legacy_parameters: - id_profile: profileId - requirements: - profileId: \d+ - -admin_profiles_bulk_delete: - path: /delete/bulk - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Profile:bulkDelete' - _legacy_controller: AdminProfiles - _legacy_link: AdminProfiles:submitBulkdeleteprofile diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/sql_request.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/sql_request.yml deleted file mode 100644 index 85a13f6d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/sql_request.yml +++ /dev/null @@ -1,97 +0,0 @@ -admin_sql_requests_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:index' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql - -admin_sql_requests_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:search' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:search - -admin_sql_requests_process_settings: - path: /process-settings - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:processForm' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:update - -admin_sql_requests_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:create' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:addrequest_sql - -admin_sql_requests_edit: - path: /{sqlRequestId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:edit' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:updaterequest_sql - _legacy_parameters: - id_request_sql: sqlRequestId - requirements: - sqlRequestId: \d+ - -admin_sql_requests_delete: - path: /{sqlRequestId}/delete - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:delete' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:deleterequest_sql - _legacy_parameters: - id_request_sql: sqlRequestId - requirements: - sqlRequestId: \d+ - -admin_sql_requests_delete_bulk: - path: /delete-bulk - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:deleteBulk' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:submitBulkdeleterequest_sql - -admin_sql_requests_table_columns: - path: /tables/{mySqlTableName}/columns - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:ajaxTableColumns' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:ajax - _legacy_parameters: - table: mySqlTableName - -admin_sql_requests_view: - path: /{sqlRequestId}/view - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:view' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:viewsql_request - _legacy_parameters: - id_request_sql: sqlRequestId - requirements: - sqlRequestId: \d+ - -admin_sql_requests_export: - path: /{sqlRequestId}/export - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SqlManager:export' - _legacy_controller: AdminRequestSql - _legacy_link: AdminRequestSql:exportsql_request - _legacy_parameters: - id_request_sql: sqlRequestId - requirements: - sqlRequestId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/system_information.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/system_information.yml deleted file mode 100644 index 9a400605..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/system_information.yml +++ /dev/null @@ -1,16 +0,0 @@ -admin_system_information: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SystemInformation:index' - _legacy_controller: AdminInformation - _legacy_link: AdminInformation - -admin_system_information_check_files: - path: /files - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\SystemInformation:displayCheckFiles' - _legacy_controller: AdminInformation - _legacy_link: AdminInformation:checkFiles - condition: 'request.isXmlHttpRequest()' diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/webservice.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/webservice.yml deleted file mode 100644 index 7dc759e7..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/advanced_parameters/webservice.yml +++ /dev/null @@ -1,91 +0,0 @@ -admin_webservice_keys_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:index' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice - -admin_webservice_keys_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:search' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:submitFilterwebservice_account - -admin_webservice_save_settings: - path: /settings - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:saveSettings' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:submitOptionswebservice_account - -admin_webservice_keys_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:create' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:addwebservice_account - -admin_webservice_keys_edit: - path: /{webserviceKeyId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:edit' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:updatewebservice_account - _legacy_parameters: - id_webservice_account: webserviceKeyId - requirements: - webserviceKeyId: \d+ - -admin_webservice_keys_delete: - path: /{webserviceKeyId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:delete' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:deletewebservice_account - _legacy_parameters: - id_webservice_account: webserviceKeyId - requirements: - webserviceKeyId: \d+ - -admin_webservice_keys_bulk_delete: - path: /bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:bulkDelete' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:submitBulkdeletewebservice_account - -admin_webservice_keys_toggle_status: - path: /{webserviceKeyId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:toggleStatus' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:statuswebservice_account - _legacy_parameters: - id_webservice_account: webserviceKeyId - requirements: - webserviceKeyId: \d+ - -admin_webservice_keys_bulk_enable: - path: /bulk-enable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:bulkEnable' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:submitBulkenableSelectionwebservice_account - -admin_webservice_keys_bulk_disable: - path: /bulk-disable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\AdvancedParameters\Webservice:bulkDisable' - _legacy_controller: AdminWebservice - _legacy_link: AdminWebservice:submitBulkdisableSelectionwebservice_account diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/_shop_parameters.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/_shop_parameters.yml deleted file mode 100644 index 582687b0..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/_shop_parameters.yml +++ /dev/null @@ -1,27 +0,0 @@ -_preferences: - resource: "preferences.yml" - prefix: /preferences/ - -_order_preferences: - resource: "order_preferences.yml" - prefix: /order-preferences/ - -_product_preferences: - resource: "product_preferences.yml" - prefix: /product-preferences/ - -_customer_preferences: - resource: "customer_preferences.yml" - prefix: /customer-preferences/ - -_maintenance: - resource: "maintenance.yml" - prefix: /maintenance/ - -_seo_urls: - resource: "meta.yml" - prefix: /seo-urls/ - -_contacts: - resource: "contacts.yml" - prefix: /contacts/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/contacts.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/contacts.yml deleted file mode 100644 index eaf6b39a..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/contacts.yml +++ /dev/null @@ -1,51 +0,0 @@ -admin_contacts_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:index' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts - -admin_contacts_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:search' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts:submitFiltercontact - -admin_contacts_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:create' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts:addcontact - -admin_contacts_edit: - path: /{contactId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:edit' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts:updatecontact - requirements: - contactId: \d+ - -admin_contacts_delete: - path: /{contactId}/delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:delete' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts:deletecontact - requirements: - contactId: \d+ - -admin_contacts_delete_bulk: - path: /delete/bulk - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Contacts:deleteBulk' - _legacy_controller: AdminContacts - _legacy_link: AdminContacts:submitBulkdeletecontact diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/customer_preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/customer_preferences.yml deleted file mode 100644 index 77dc8d0d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/customer_preferences.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_customer_preferences: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\CustomerPreferences:index' - _legacy_controller: AdminCustomerPreferences - _legacy_link: AdminCustomerPreferences - -admin_customer_preferences_process: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\CustomerPreferences:process' - _legacy_controller: AdminCustomerPreferences - _legacy_link: AdminCustomerPreferences:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/maintenance.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/maintenance.yml deleted file mode 100644 index dc97437d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/maintenance.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_maintenance: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Maintenance:index' - _legacy_controller: AdminMaintenance - _legacy_link: AdminMaintenance - -admin_maintenance_save: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Maintenance:processForm' - _legacy_controller: AdminMaintenance - _legacy_link: AdminMaintenance:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/meta.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/meta.yml deleted file mode 100644 index 34ac71ef..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/meta.yml +++ /dev/null @@ -1,67 +0,0 @@ -admin_metas_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:index' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta - -admin_metas_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:search' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:submitFiltermeta - -admin_metas_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:create' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:addmeta - -admin_metas_edit: - path: /{metaId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:edit' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:updatemeta - _legacy_parameters: - id_meta: metaId - -admin_metas_delete: - path: /{metaId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:delete' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:deletemeta - _legacy_parameters: - id_meta: metaId - -admin_metas_delete_bulk: - path: /delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:deleteBulk' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:submitBulkdeletemeta - -admin_metas_save_options: - path: /options - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:saveOptions' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:submitOptionsmeta - -admin_metas_generate_robots_text_file: - path: /generate/robots - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Meta:generateRobotsFile' - _legacy_controller: AdminMeta - _legacy_link: AdminMeta:submitRobots diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/order_preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/order_preferences.yml deleted file mode 100644 index 0d8726dc..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/order_preferences.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_order_preferences: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\OrderPreferences:index' - _legacy_controller: AdminOrderPreferences - _legacy_link: AdminOrderPreferences - -admin_order_preferences_save: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\OrderPreferences:process' - _legacy_controller: AdminOrderPreferences - _legacy_link: AdminOrderPreferences:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/preferences.yml deleted file mode 100644 index baa945a4..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/preferences.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_preferences: - path: preferences - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Preferences:index' - _legacy_controller: AdminPreferences - _legacy_link: AdminPreferences - -admin_preferences_save: - path: preferences - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\Preferences:processForm' - _legacy_controller: AdminPreferences - _legacy_link: AdminPreferences:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/product_preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/product_preferences.yml deleted file mode 100644 index 7c65b09d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/configure/shop_parameters/product_preferences.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_product_preferences: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\ProductPreferences:index' - _legacy_controller: AdminPPreferences - _legacy_link: AdminPPreferences - -admin_product_preferences_process: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Configure\ShopParameters\ProductPreferences:process' - _legacy_controller: AdminPPreferences - _legacy_link: AdminPPreferences:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/_improve.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/_improve.yml deleted file mode 100644 index 96fd427e..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/_improve.yml +++ /dev/null @@ -1,19 +0,0 @@ -_international: - resource: "international/_international.yml" - prefix: /international/ - -_modules: - resource: "modules/_modules.yml" - prefix: /modules/ - -_design: - resource: "design/_design.yml" - prefix: /design/ - -_payment: - resource: "payment/*.yml" - prefix: /payment/ - -_shipping: - resource: "shipping/*.yml" - prefix: /shipping/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_design.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_design.yml deleted file mode 100644 index edb67a33..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_design.yml +++ /dev/null @@ -1,19 +0,0 @@ -_theme_catalog: - resource: "theme_catalog.yml" - prefix: /themes-catalog - -_positions: - resource: "positions.yml" - prefix: /modules/positions - -_theme: - resource: "theme.yml" - prefix: /themes - -_cms_page: - resource: "cms_pages.yml" - prefix: /cms-pages - -_mail_theme: - resource: "mail_theme.yml" - prefix: /mail_theme/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_mail_theme_deprecated.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_mail_theme_deprecated.yml deleted file mode 100644 index 5e46523f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/_mail_theme_deprecated.yml +++ /dev/null @@ -1,22 +0,0 @@ -# These are alias routes used to manage legacy urls that were badly formatted (camel case) -admin_mail_theme_save_configuration_deprecated: - path: /saveConfiguration - defaults: - _controller: FrameworkBundle:Redirect:redirect - route: admin_mail_theme_save_configuration - permanent: true - -admin_mail_theme_send_test_mail_deprecated: - path: /sendTestMail/{locale}/{theme}/{layout} - defaults: - _controller: FrameworkBundle:Redirect:redirect - route: admin_mail_theme_send_test_mail - permanent: true - -admin_mail_theme_send_test_module_mail_deprecated: - path: /sendTestMail/{locale}/{theme}/{module}/{layout} - methods: [GET] - defaults: - _controller: FrameworkBundle:Redirect:redirect - route: admin_mail_theme_send_test_module_mail - permanent: true diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/cms_pages.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/cms_pages.yml deleted file mode 100644 index 9931a921..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/cms_pages.yml +++ /dev/null @@ -1,178 +0,0 @@ -admin_cms_pages_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:index' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent - -admin_cms_pages_search: - path: /search - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:search' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitFiltercms - -admin_cms_pages_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:create' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:addcms - -admin_cms_pages_edit: - path: /{cmsPageId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:edit' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:updatecms - _legacy_parameters: - id_cms: cmsPageId - requirements: - cmsPageId: \d+ - -admin_cms_pages_toggle: - path: /{cmsId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:toggleCms' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:statuscms - _legacy_parameters: - id_cms: cmsId - requirements: - cmsId: \d+ - -admin_cms_pages_delete: - path: /{cmsId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:deleteCms' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:deletecms - _legacy_parameters: - id_cms: cmsId - requirements: - cmsId: \d+ - -admin_cms_pages_bulk_enable_status: - path: /bulk-enable-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:bulkEnableCmsPageStatus' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkenableSelectioncms - -admin_cms_pages_bulk_disable_status: - path: /bulk-disable-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:bulkDisableCmsPageStatus' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkdisableSelectioncms - -admin_cms_pages_bulk_delete: - path: /bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:bulkDeleteCmsPage' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkdeletecms - -admin_cms_pages_search_cms_category: - path: /category/search - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Common:searchGrid' - gridDefinitionFactoryService: prestashop.core.grid.definition.factory.cms_page_category - redirectRoute: admin_cms_pages_index - redirectQueryParamsToKeep: - - 'id_cms_category' - _legacy_link: AdminCmsContent:submitFiltercms_category - -admin_cms_pages_category_create: - path: /category/new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:createCmsCategory' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:addcms_category - -admin_cms_pages_category_edit: - path: /category/{cmsCategoryId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:editCmsCategory' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:updatecms_category - _legacy_parameters: - id_cms_category: cmsCategoryId - requirements: - cmsCategoryId: \d+ - -admin_cms_pages_category_delete: - path: /category/{cmsCategoryId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:deleteCmsCategory' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:deletecms_category - _legacy_parameters: - id_cms_category: cmsCategoryId - requirements: - cmsCategoryId: \d+ - -admin_cms_pages_category_delete_bulk: - path: /category/delete-bulk - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:deleteBulkCmsCategory' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkdeletecms_category - -admin_cms_pages_category_toggle: - path: /category/{cmsCategoryId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:toggleCmsCategory' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:statuscms_category - _legacy_parameters: - id_cms_category: cmsCategoryId - requirements: - cmsCategoryId: \d+ - -admin_cms_pages_category_bulk_status_enable: - path: /category/bulk-enable-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:bulkCmsPageCategoryStatusEnable' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkenableSelectioncms_category - -admin_cms_pages_category_bulk_status_disable: - path: /category/bulk-disable-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:bulkCmsPageCategoryStatusDisable' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:submitBulkdisableSelectioncms_category - -admin_cms_pages_category_update_position: - path: /category/update-position - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:updateCmsCategoryPosition' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:updatecms_category - -admin_cms_pages_update_position: - path: /update-position - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\CmsPage:updateCmsPosition' - _legacy_controller: AdminCmsContent - _legacy_link: AdminCmsContent:updatecms diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/mail_theme.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/mail_theme.yml deleted file mode 100644 index bb3d50ab..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/mail_theme.yml +++ /dev/null @@ -1,95 +0,0 @@ -_mail_theme_deprecated: - resource: "_mail_theme_deprecated.yml" - prefix: / - -admin_mail_theme_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:index - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme - -admin_mail_theme_generate: - path: /generate - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:generateMails - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:postGenerateMails - -admin_mail_theme_save_configuration: - path: /save-configuration - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:saveConfiguration - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:saveConfiguration - -admin_mail_theme_preview: - path: /preview/{theme} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:previewTheme - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:previewTheme - -# Preview layout routes -admin_mail_theme_preview_layout: - path: /preview/{locale}/{theme}/{layout}.{type} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:previewLayout - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:previewLayout - module: '' - -admin_mail_theme_preview_module_layout: - path: /preview/{locale}/{theme}/{module}/{layout}.{type} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:previewLayout - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:previewModuleLayout - -admin_mail_theme_raw_layout: - path: /raw/{locale}/{theme}/{layout}.{type} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:rawLayout - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:rawLayout - module: '' - -admin_mail_theme_raw_module_layout: - path: /raw/{locale}/{theme}/{module}/{layout}.{type} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:rawLayout - _legacy_link: AdminMailTheme:rawModuleLayout - _legacy_controller: AdminMailTheme - -admin_mail_theme_send_test_mail: - path: /send-test-mail/{locale}/{theme}/{layout} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:sendTestMail - _legacy_link: AdminMailTheme:rawModuleLayout - _legacy_controller: AdminMailTheme - module: '' - -admin_mail_theme_send_test_module_mail: - path: /send-test-mail/{locale}/{theme}/{module}/{layout} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:sendTestMail - _legacy_link: AdminMailTheme:rawModuleLayout - _legacy_controller: AdminMailTheme - -admin_mail_theme_translate_body: - path: /translate-body - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\MailTheme:translateBody - _legacy_controller: AdminMailTheme - _legacy_link: AdminMailTheme:translateBody diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/positions.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/positions.yml deleted file mode 100644 index 9bbdb0ce..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/positions.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_modules_positions: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\Positions:index' - _legacy_controller: AdminModulesPositions - _legacy_link: AdminModulesPositions - -admin_modules_positions_unhook: - path: /unhook - methods: [POST,GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\Positions:unhook' - _legacy_controller: AdminModulesPositions - _legacy_link: AdminModulesPositions:unhook diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme.yml deleted file mode 100644 index bb421ad9..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme.yml +++ /dev/null @@ -1,85 +0,0 @@ -admin_themes_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:index - _legacy_controller: AdminThemes - _legacy_link: AdminThemes - -admin_themes_upload_logos: - path: /upload-logos - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:uploadLogos - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:submitOptionsconfiguration - -admin_themes_export_current: - path: /export - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:export - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:exporttheme - -admin_themes_import: - path: /import - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:import - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:importtheme - -admin_themes_enable: - path: /{themeName}/enable - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:enable - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:enableTheme - _legacy_parameters: - theme_name: themeName - requirements: - themeName: "^[a-zA-Z0-9_.-]+$" - -admin_themes_delete: - path: /{themeName}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:delete - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:deleteTheme - _legacy_parameters: - theme_name: themeName - requirements: - themeName: "^[a-zA-Z0-9_.-]+$" - -admin_themes_adapt_to_rtl_languages: - path: /adapt-to-rtl-languages - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:adaptToRTLLanguages - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:submitGenerateRTL - requirements: - themeName: "^[a-zA-Z0-9_.-]+$" - -admin_theme_customize_layouts: - path: /customize-layouts - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:customizeLayouts - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:submitConfigureLayouts - -admin_themes_reset_layouts: - path: /{themeName}/reset-layouts - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Design\Theme:resetLayouts - _legacy_controller: AdminThemes - _legacy_link: AdminThemes:resetToDefaults - _legacy_parameters: - theme_name: themeName - requirements: - themeName: "^[a-zA-Z0-9_.-]+$" diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme_catalog.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme_catalog.yml deleted file mode 100644 index 49698a40..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/design/theme_catalog.yml +++ /dev/null @@ -1,7 +0,0 @@ -admin_theme_catalog: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Design\ThemeCatalog:index' - _legacy_controller: AdminThemesCatalog - _legacy_link: AdminThemesCatalog diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/_international.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/_international.yml deleted file mode 100644 index b4b61a48..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/_international.yml +++ /dev/null @@ -1,31 +0,0 @@ -_translations: - resource: "translations.yml" - prefix: /translations/ - -_localization: - resource: "localization.yml" - prefix: /localization/ - -_geolocation: - resource: "geolocation.yml" - prefix: /geolocation/ - -_language: - resource: "language.yml" - prefix: /languages/ - -_currency: - resource: "currencies.yml" - prefix: /currencies/ - -_tax: - resource: "tax.yml" - prefix: /taxes/ - -_state: - resource: "state.yml" - prefix: /states/ - -_tax_rules_groups: - resource: "tax_rules_groups.yml" - prefix: /tax_rules_groups/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/currencies.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/currencies.yml deleted file mode 100644 index 8ab88361..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/currencies.yml +++ /dev/null @@ -1,82 +0,0 @@ -admin_currencies_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:index' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies - -admin_currencies_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:search' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:submitFiltercurrency - -admin_currencies_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:create' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:addcurrency - -admin_currencies_edit: - path: /{currencyId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:edit' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:updatecurrency - _legacy_parameters: - id_currency: currencyId - requirements: - currencyId: \d+ - -admin_currencies_delete: - path: /{currencyId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:delete' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:deletecurrency - _legacy_parameters: - id_currency: currencyId - requirements: - currencyId: \d+ - -admin_currencies_toggle_status: - path: /{currencyId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:toggleStatus' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:statuscurrency - _legacy_parameters: - id_currency: currencyId - requirements: - currencyId: \d+ - -admin_currencies_update_live_exchange_rates: - path: /update-live-exchange-rates - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:updateLiveExchangeRates' - _legacy_controller: AdminCurrencies - -admin_currencies_refresh_exchange_rates: - path: /refresh-exchange-rates - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:refreshExchangeRates' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:SubmitExchangesRates - -admin_currencies_get_reference_data: - path: /reference-data/{currencyIsoCode} - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Currency:getReferenceData' - _legacy_controller: AdminCurrencies - _legacy_link: AdminCurrencies:getReferenceData diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/geolocation.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/geolocation.yml deleted file mode 100644 index c91a4e35..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/geolocation.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_geolocation_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\Geolocation:index - _legacy_controller: AdminGeolocation - _legacy_link: AdminGeolocation - -admin_geolocation_save_options: - path: /process_form - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\Geolocation:saveOptions - _legacy_controller: AdminGeolocation - _legacy_link: AdminGeolocation:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/language.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/language.yml deleted file mode 100644 index d2858978..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/language.yml +++ /dev/null @@ -1,71 +0,0 @@ -admin_languages_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:index' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages - -admin_languages_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:searchGrid' - _legacy_controller: AdminLanguages - _legacy_link: - - AdminLanguages:submitFilterlang - - AdminLanguages:submitFiltercurrency - -admin_languages_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:create' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:addlang - -admin_languages_edit: - path: /{languageId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:edit' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:updatelang - requirements: - languageId: \d+ - -admin_languages_delete: - path: /{languageId}/delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:delete' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:deletelang - requirements: - languageId: \d+ - -admin_languages_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:bulkDelete' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:submitBulkdeletelang - -admin_languages_toggle_status: - path: /{languageId}/toggle-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:toggleStatus' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:statuslang - -admin_languages_bulk_toggle_status: - path: /bulk-toggle-status/{status} - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Language:bulkToggleStatus' - _legacy_controller: AdminLanguages - _legacy_link: AdminLanguages:submitBulkupdatelang - requirements: - status: enable|disable diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/localization.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/localization.yml deleted file mode 100644 index a4879ca6..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/localization.yml +++ /dev/null @@ -1,23 +0,0 @@ -admin_localization_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\Localization:index - _legacy_controller: AdminLocalization - _legacy_link: AdminLocalization - -admin_localization_save_options: - path: /options - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\Localization:saveOptions - _legacy_controller: AdminLocalization - _legacy_link: AdminLocalization:update - -admin_localization_import_pack: - path: /import-pack - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\Localization:importPack - _legacy_controller: AdminLocalization - _legacy_link: AdminLocalization:submitLocalizationPack diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/state.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/state.yml deleted file mode 100644 index 4a482085..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/state.yml +++ /dev/null @@ -1,6 +0,0 @@ -admin_country_states: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\State:getStates' - _legacy_controller: AdminStates diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax.yml deleted file mode 100644 index 9cd144d8..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax.yml +++ /dev/null @@ -1,91 +0,0 @@ -admin_taxes_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:index' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes - -admin_taxes_save_options: - path: /save-options - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:saveOptions' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:submitOptionstax - -admin_taxes_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:search' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:submitFiltertax - -admin_taxes_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:create' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:addtax - -admin_taxes_edit: - path: /{taxId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:edit' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:updatetax - _legacy_parameters: - id_tax: taxId - requirements: - taxId: \d+ - -admin_taxes_delete: - path: /{taxId}/delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:delete' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:deletetax - _legacy_parameters: - id_tax: taxId - requirements: - taxId: \d+ - -admin_taxes_toggle_status: - path: /{taxId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:toggleStatus' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:statustax - _legacy_parameters: - id_tax: taxId - requirements: - taxId: \d+ - -admin_taxes_bulk_enable_status: - path: /bulk-enable-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:bulkEnableStatus' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:submitBulkenableSelectiontax - -admin_taxes_bulk_disable_status: - path: /bulk-disable-status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:bulkDisableStatus' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:submitBulkdisableSelectiontax - -admin_taxes_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\International\Tax:bulkDelete' - _legacy_controller: AdminTaxes - _legacy_link: AdminTaxes:submitBulkdeletetax diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax_rules_groups.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax_rules_groups.yml deleted file mode 100644 index ce4d12c7..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/tax_rules_groups.yml +++ /dev/null @@ -1,85 +0,0 @@ -admin_tax_rules_groups_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:index - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup - -admin_tax_rules_groups_search: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - _legacy_controller: AdminTaxRulesGroup - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.tax_rules_group - redirectRoute: admin_tax_rules_groups_index -# _legacy_link: AdminTaxRulesGroup:submitFiltertax_rules_group - -admin_tax_rules_groups_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:create - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:addtax_rules_group - -admin_tax_rules_groups_edit: - path: /{taxRulesGroupId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:edit - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:updatetax_rules_group - _legacy_parameters: - id_tax_rules_group: taxRulesGroupId - requirements: - taxRulesGroupId: \d+ - -admin_tax_rules_groups_delete: - path: /{taxRulesGroupId}/delete - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:delete - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:deletetax_rules_group - _legacy_parameters: - id_tax_rules_group: taxRulesGroupId - requirements: - taxRulesGroupId: \d+ - -admin_tax_rules_groups_toggle_status: - path: /{taxRulesGroupId}/toggle-status - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:toggleStatus - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:statustax_rules_group - _legacy_parameters: - id_tax_rules_group: taxRulesGroupId - requirements: - taxRulesGroupId: \d+ - -admin_tax_rules_groups_bulk_enable_status: - path: /bulk-enable-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:bulkEnableStatus - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:submitBulkenableSelectiontax_rules_group - -admin_tax_rules_groups_bulk_disable_status: - path: /bulk-disable-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:bulkDisableStatus - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:submitBulkdisableSelectiontax_rules_group - -admin_tax_rules_groups_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Improve\International\TaxRulesGroup:bulkDelete - _legacy_controller: AdminTaxRulesGroup -# _legacy_link: AdminTaxRulesGroup:submitBulkdeletetax_rules_group diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/translations.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/translations.yml deleted file mode 100644 index c2b31b46..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/international/translations.yml +++ /dev/null @@ -1,46 +0,0 @@ -admin_international_translation_overview: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Translations:overview - _legacy_controller: AdminTranslations - _legacy_link: AdminTranslationSf - -admin_international_translations_export_theme: - path: /export - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Translations:exportThemeLanguage - _legacy_controller: AdminTranslations - _legacy_link: AdminTranslations:submitExport - -admin_international_translations_show_settings: - path: /settings - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Translations:showSettings - _legacy_controller: AdminTranslations - _legacy_link: AdminTranslations:settings - -admin_international_translations_modify: - path: /modify - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Translations:modifyTranslations - _legacy_controller: AdminTranslations - -admin_international_translations_add_update_language: - path: /add-update-language - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Translations:addUpdateLanguage - _legacy_controller: AdminTranslations - _legacy_link: AdminTranslations:submitAddLanguage - -admin_international_translations_copy_language: - path: /copy - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Translations:copyLanguage - _legacy_controller: AdminTranslations - _legacy_link: AdminTranslations:submitCopyLang diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/_modules.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/_modules.yml deleted file mode 100644 index a2a09b36..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/_modules.yml +++ /dev/null @@ -1,122 +0,0 @@ -_addons: - resource: "addons.yml" - prefix: /addons/ - -admin_module_cart: - path: /cart/{moduleId} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:getModuleCart - requirements: - moduleId: \d+ - -admin_module_catalog: - path: /catalog - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:catalog - _legacy_controller: AdminModulesCatalog - _legacy_link: AdminModulesCatalog - -admin_module_catalog_refresh: - path: /catalog/refresh/{category}/{keyword} - methods: [GET] - defaults: - category: - keyword: - _controller: PrestaShopBundle:Admin/Improve/Module:refreshCatalog - _legacy_controller: AdminModulesCatalog - _legacy_link: AdminModulesCatalog:refresh - -admin_module_catalog_post: - path: /catalog/recommended - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:getPreferredModules - _legacy_controller: AdminModulesCatalog - _legacy_link: AdminModulesCatalog:recommended - -admin_module_manage: - path: /manage/{category}/{keyword} - methods: [GET] - defaults: - category: - keyword: - _controller: PrestaShopBundle:Admin/Improve/Module:manage - _legacy_controller: AdminModulesManage - _legacy_link: - - AdminModulesManage - - AdminModulesSf - -admin_module_manage_action: - path: /manage/action/{action}/{module_name} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:module - requirements: - action: install|uninstall|enable|disable|enable_mobile|disable_mobile|reset|upgrade - -admin_module_configure_action: - path: /manage/action/configure/{module_name} - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:configureModule - _legacy_controller: AdminModules -# WARNING: This controller is not fully migrated yet, it is an overlay that redirects to the legacy controller, -# but here is the proper configuration when it will be really migrated -# _legacy_link: AdminModules:configure -# _legacy_parameters: -# configure: module_name - -admin_module_manage_action_bulk: - path: /manage/bulk/{action} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:module - requirements: - action: install|uninstall|configure|enable|disable|reset|upgrade - -admin_module_manage_update_all: - path: /manage/update/all - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Module:module - -admin_module_import: - path: /import - methods: [POST] - defaults: - module_name: - _controller: PrestaShopBundle:Admin/Improve/Module:importModule - -admin_module_notification: - path: /alerts - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Modules/Alerts:index - _legacy_controller: AdminModulesNotifications - _legacy_link: AdminModulesNotifications - -admin_module_notification_count: - path: /alerts/count - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Modules\Alerts:notificationsCount - _legacy_controller: AdminModulesNotifications - _legacy_link: AdminModulesNotifications:count - -admin_module_updates: - path: /updates - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Improve/Modules/Updates:index - _legacy_controller: AdminModulesUpdates - _legacy_link: AdminModulesUpdates - -admin_module_addons_store: - path: /addons-store - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Modules\AddonsStore:index' - _legacy_controller: AdminAddonsCatalog - _legacy_link: AdminAddonsCatalog diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/addons.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/addons.yml deleted file mode 100644 index 2fdcc78f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/modules/addons.yml +++ /dev/null @@ -1,11 +0,0 @@ -admin_addons_login: - path: /login - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Addons:login - -admin_addons_logout: - path: /logout - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Addons:logout diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/payment_methods.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/payment_methods.yml deleted file mode 100644 index 959cee0b..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/payment_methods.yml +++ /dev/null @@ -1,7 +0,0 @@ -admin_payment_methods: - path: /payment_methods - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Improve\Payment\PaymentMethods:index - _legacy_controller: AdminPayment - _legacy_link: AdminPayment diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/preferences.yml deleted file mode 100644 index 1ecae2cf..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/payment/preferences.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_payment_preferences: - path: /preferences - methods: [GET] - defaults: - _legacy_controller: AdminPaymentPreferences - _legacy_link: AdminPaymentPreferences - _controller: PrestaShopBundle:Admin\Improve\Payment\PaymentPreferences:index - -admin_payment_preferences_process: - path: /preferences - methods: [POST] - defaults: - _legacy_controller: AdminPaymentPreferences - _legacy_link: AdminPaymentPreferences:update - _controller: PrestaShopBundle:Admin\Improve\Payment\PaymentPreferences:processForm diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/improve/shipping/preferences.yml b/src/PrestaShopBundle/Resources/config/routing/admin/improve/shipping/preferences.yml deleted file mode 100644 index d8396e1f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/improve/shipping/preferences.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Preferences -admin_shipping_preferences: - path: preferences - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Shipping\Preferences:index' - _legacy_controller: AdminShipping - _legacy_link: AdminShipping - -admin_shipping_preferences_save: - path: preferences - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Improve\Shipping\Preferences:processForm' - _legacy_controller: AdminShipping - _legacy_link: AdminShipping:update diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/_sell.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/_sell.yml deleted file mode 100644 index fe3a117f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/_sell.yml +++ /dev/null @@ -1,22 +0,0 @@ -_catalog: - resource: "catalog/_catalog.yml" - prefix: /catalog/ - -_customers: - resource: "customer/_customer.yml" - -_customer_services: - resource: "customer_service/_customer_service.yml" - prefix: /customer-service/ - -_orders: - resource: "orders/_orders.yml" - prefix: /orders/ - -_stocks: - resource: "stocks.yml" - prefix: /stocks/ - -_attachment: - resource: "catalog/attachment.yml" - prefix: /attachments/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/_catalog.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/_catalog.yml deleted file mode 100644 index cb7bc3c5..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/_catalog.yml +++ /dev/null @@ -1,41 +0,0 @@ -_products: - resource: "products/products.yml" - prefix: /products/ - -_categories: - resource: "categories.yml" - prefix: /categories/ - -_suppliers: - resource: "suppliers.yml" - prefix: /suppliers/ - -_manufacturers: - resource: "manufacturer.yml" - prefix: /brands - -_monitoring: - resource: "monitoring.yml" - prefix: /monitoring - -_catalog_price_rules: - resource: "catalog_price_rule.yml" - prefix: /catalog-price-rules - -_features: - resource: "features.yml" - prefix: /features - -_attributes: - resource: "attribute.yml" - prefix: /attribute-groups/{attributeGroupId}/attributes/ - requirements: - attributeGroupId: \d+ - -_attribute_group: - resource: "attribute_group.yml" - prefix: /attribute-groups/ - -_cart_rule: - resource: "cart_rule.yml" - prefix: /cart-rules diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attachment.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attachment.yml deleted file mode 100644 index 094c1c54..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attachment.yml +++ /dev/null @@ -1,69 +0,0 @@ -admin_attachments_index: - path: / - methods: GET - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:index - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments - -admin_attachments_filter: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Common:searchGrid - _legacy_controller: AdminAttachments - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.attachment - redirectRoute: admin_attachments_index - _legacy_link: AdminAttachments:submitFilterattachment - -admin_attachments_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:create - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments:addattachment - -admin_attachments_edit: - path: /{attachmentId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:edit - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments:updateattachment - _legacy_parameters: - id_attachment: attachmentId - requirements: - attachmentId: \d+ - -admin_attachments_view: - path: /{attachmentId}/view - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:view - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments:viewattachment - _legacy_parameters: - id_attachment: attachmentId - requirements: - attachmentId: \d+ - -admin_attachments_delete_bulk: - path: /delete-bulk - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:deleteBulk - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments:submitBulkdeleteattachment - -admin_attachments_delete: - path: /{attachmentId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Attachment:delete - _legacy_controller: AdminAttachments - _legacy_link: AdminAttachments:deleteattachment - _legacy_parameters: - id_attachment: attachmentId - requirements: - attachmentId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute.yml deleted file mode 100644 index c2dd6283..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute.yml +++ /dev/null @@ -1,85 +0,0 @@ -# @todo: add legacy links after page is fully migrated -admin_attributes_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:index' - _legacy_controller: AdminAttributesGroups - redirectQueryParamsToKeep: - - 'attributeGroupId' -# _legacy_link: AdminAttributesGroups:viewattribute_group - _legacy_parameters: - id_attribute_group: attributeGroupId - requirements: - attributeGroupId: \d+ - -admin_attributes_search: - path: / - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - _legacy_controller: AdminAttributesGroups - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.attribute - redirectRoute: admin_attributes_index -# _legacy_link: AdminAttributesGroups:submitFilterattribute_values - redirectQueryParamsToKeep: - - 'attributeGroupId' - -admin_attributes_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:create' - _legacy_controller: AdminAttributesGroups - redirectQueryParamsToKeep: - - 'attributeGroupId' -# _legacy_link: AdminAttributesGroups:addattribute_group - -admin_attributes_edit: - path: /{attributeId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:edit' - _legacy_controller: AdminAttributesGroups - redirectQueryParamsToKeep: - - 'attributeGroupId' -# _legacy_link: AdminAttributesGroups:updateattribute - _legacy_parameters: - id_attribute_group: attributeGroupId - id_attribute: attributeId - requirements: - attributeId: \d+ - -admin_attributes_delete: - path: /{attributeId}/delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:delete' - _legacy_controller: AdminAttributesGroups - redirectQueryParamsToKeep: - - 'attributeGroupId' -# _legacy_link: AdminAttributesGroups:deleteattribute - _legacy_parameters: - id_attribute_group: attributeGroupId - id_attribute: attributeId - -admin_attributes_bulk_delete: - path: /delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:bulkDelete' - _legacy_controller: AdminAttributesGroups - redirectQueryParamsToKeep: - - 'attributeGroupId' -# _legacy_link: AdminAttributesGroups:bulkdeleteattribute - _legacy_parameters: - id_attribute_group: attributeGroupId - id_attribute: attributeId - -admin_attributes_update_position: - path: /update-position - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:updatePosition' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:updateAttributesPositions diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute_group.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute_group.yml deleted file mode 100644 index dcf9912b..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/attribute_group.yml +++ /dev/null @@ -1,87 +0,0 @@ -# @todo: uncomment legacy links after page migration -admin_attribute_groups_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:index' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups - -admin_attribute_groups_search: - path: / - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - _legacy_controller: AdminAttributesGroups - # _legacy_link: AdminAttributeGroups:submitFilterattribute_group - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.attribute_group - redirectRoute: admin_attribute_groups_index - -admin_attribute_groups_create: - path: /new - methods: [GET, POST] - defaults: - #todo: implement create - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:index' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributeGroups:addattribute_group - -admin_attribute_groups_view: - path: /{attributeGroupId}/view - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Attribute:index' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:viewattribute_group - _legacy_parameters: - id_attribute_group: attributeGroupId - requirements: - attributeGroupId: \d+ - -admin_attribute_groups_edit: - path: /{attributeGroupId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:edit' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:updateattribute_group - _legacy_parameters: - id_attribute_group: attributeGroupId - requirements: - attributeGroupId: \d+ - -admin_attribute_groups_delete: - path: /{attributeGroupId}/delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:delete' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:deleteattribute_group - _legacy_parameters: - id_attribute_group: attributeGroupId - requirements: - attributeGroupId: \d+ - -admin_attribute_groups_bulk_delete: - path: /bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:bulkDelete' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:submitBulkdeleteattribute_group - -admin_attribute_groups_export: - path: /export - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:export' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:exportattribute_group - -admin_attribute_groups_update_position: - path: /update-position - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/AttributeGroup:updatePosition' - _legacy_controller: AdminAttributesGroups -# _legacy_link: AdminAttributesGroups:updateGroupsPositions diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/cart_rule.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/cart_rule.yml deleted file mode 100644 index 67958c64..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/cart_rule.yml +++ /dev/null @@ -1,8 +0,0 @@ -admin_cart_rules_search: - path: /search - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/CartRule:search' - _legacy_controller: AdminCartRules - options: - expose: true diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/catalog_price_rule.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/catalog_price_rule.yml deleted file mode 100644 index ae1d8d63..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/catalog_price_rule.yml +++ /dev/null @@ -1,56 +0,0 @@ -#@todo: add legacy links after page is fully migrated. (including condition groups) -admin_catalog_price_rules_index: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:index' - _legacy_controller: AdminSpecificPriceRule -# _legacy_link: AdminSpecificPriceRule - -admin_catalog_price_rules_search: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:search' - _legacy_controller: AdminSpecificPriceRule -# _legacy_link: AdminSpecificPriceRule:submitFilterspecific_price_rule - -admin_catalog_price_rules_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:create' - _legacy_controller: AdminSpecificPriceRule - #_legacy_link: AdminSpecificPriceRule:addspecific_price_rule - -admin_catalog_price_rules_edit: - path: /{catalogPriceRuleId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:edit' - _legacy_controller: AdminSpecificPriceRule - #_legacy_link: AdminSpecificPriceRule:updatespecific_price_rule - _legacy_parameters: - id_specific_price_rule: catalogPriceRuleId - requirements: - catalogPriceRuleId: \d+ - -admin_catalog_price_rules_delete: - path: /{catalogPriceRuleId}/delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:delete' - _legacy_controller: AdminSpecificPriceRule -# _legacy_link: AdminSpecificPriceRule:deletespecific_price_rule - _legacy_parameters: - id_specific_price_rule: catalogPriceRuleId - requirements: - catalogPriceRuleId: \d+ - -admin_catalog_price_rules_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\CatalogPriceRule:bulkDelete' - _legacy_controller: AdminSpecificPriceRule -# _legacy_link: AdminSpecificPriceRule:submitBulkdeletespecific_price_rule diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/categories.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/categories.yml deleted file mode 100644 index 5485fb60..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/categories.yml +++ /dev/null @@ -1,149 +0,0 @@ -admin_categories_index: - path: /{categoryId} - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:index - _legacy_controller: AdminCategories - _legacy_link: AdminCategories - _legacy_parameters: - id_category: categoryId - categoryId: null - requirements: - categoryId: '\d+' - -admin_categories_search: - path: /search - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Catalog/Category:searchGrid - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:submitFiltercategory - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.category - redirectRoute: admin_categories_index - redirectQueryParamsToKeep: - - 'categoryId' - -admin_categories_bulk_enable_status: - path: /bulk-status-enable - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:bulkEnableStatus - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:submitBulkenableSelectioncategory - -admin_categories_bulk_disable_status: - path: /bulk-status-disable - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:bulkDisableStatus - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:submitBulkdisableSelectioncategory - -admin_categories_toggle_status: - path: /{categoryId}/toggle-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:toggleStatus - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:statuscategory - _legacy_parameters: - id_category: categoryId - -admin_categories_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:bulkDelete - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:submitBulkdeleteSelectioncategory - -admin_categories_delete: - path: /delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:delete - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:deletecategory - -admin_categories_export: - path: /export - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:export - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:exportcategory - -admin_categories_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:create - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:addcategory - -admin_categories_create_root: - path: /new-root - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:createRoot - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:addcategoryroot - _legacy_parameters: - id_category: categoryId - -admin_categories_edit: - path: /{categoryId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:edit - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:updatecategory - _legacy_parameters: - id_category: categoryId - requirements: - categoryId: \d+ - -admin_categories_edit_root: - path: /{categoryId}/edit-root - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:editRoot - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:updatecategory - _legacy_parameters: - id_category: categoryId - requirements: - categoryId: \d+ - -admin_categories_delete_cover_image: - path: /{categoryId}/delete-cover-image - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:deleteCoverImage - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:deleteImage - _legacy_parameters: - id_category: categoryId - requirements: - categoryId: \d+ - -admin_categories_delete_menu_thumbnail: - path: /{categoryId}/menu-thumbnails/{menuThumbnailId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:deleteMenuThumbnail - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:forceDeleteThumb - _legacy_parameters: - id_category: categoryId - requirements: - categoryId: \d+ - menuThumbnailId: 0|1|2 menu thumbnails only have 3 fixed ids - -admin_categories_update_position: - path: /update-positions - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Category:updatePosition - _legacy_controller: AdminCategories - _legacy_link: AdminCategories:updatePositions diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/features.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/features.yml deleted file mode 100644 index 0e1310ff..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/features.yml +++ /dev/null @@ -1,19 +0,0 @@ -admin_features_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Feature:create - _legacy_controller: AdminFeatures - #_legacy_link: AdminFeatures:addfeature - -admin_features_edit: - path: /{featureId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Catalog\Feature:edit - _legacy_controller: AdminFeatures - #_legacy_link: AdminFeatures:updatefeature - _legacy_parameters: - id_feature: featureId - requirements: - featureId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/manufacturer.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/manufacturer.yml deleted file mode 100644 index f1410d5c..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/manufacturer.yml +++ /dev/null @@ -1,157 +0,0 @@ -admin_manufacturers_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:index' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers - -# -# Manufacturer routes -# -admin_manufacturers_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:search' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:submitFiltermanufacturer - -admin_manufacturers_create: - path: /new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:create' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:addmanufacturer - -admin_manufacturers_view: - path: /{manufacturerId}/view - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:view' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:viewmanufacturer - _legacy_parameters: - id_manufacturer: manufacturerId - requirements: - manufacturerId: \d+ - -admin_manufacturers_edit: - path: /{manufacturerId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:edit' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:updatemanufacturer - _legacy_parameters: - id_manufacturer: manufacturerId - requirements: - manufacturerId: \d+ - -admin_manufacturers_delete: - path: /{manufacturerId}/delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:delete' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:deletemanufacturer - _legacy_parameters: - id_manufacturer: manufacturerId - requirements: - manufacturerId: \d+ - -admin_manufacturers_bulk_delete: - path: /bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:bulkDelete' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:submitBulkdeletemanufacturer - -admin_manufacturers_bulk_enable_status: - path: /bulk-enable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:bulkEnable' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:submitBulkenableSelectionmanufacturer - -admin_manufacturers_bulk_disable_status: - path: /bulk-disable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:bulkDisable' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:submitBulkdisableSelectionmanufacturer - -admin_manufacturers_toggle_status: - path: /{manufacturerId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:toggleStatus' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:statusmanufacturer - _legacy_parameters: - id_manufacturer: manufacturerId - requirements: - manufacturerId: \d+ - -admin_manufacturers_export: - path: /export - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:export' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:exportmanufacturer - -# -# Address routes -# -admin_manufacturer_addresses_create: - path: addresses/new - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:createAddress' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:addaddress - -admin_manufacturer_addresses_edit: - path: addresses/{addressId}/edit - methods: [GET, POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:editAddress' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:editaddresses - _legacy_parameters: - id_address: addressId - requirements: - addressId: \d+ - -admin_manufacturer_addresses_delete: - path: addresses/{addressId}/delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:deleteAddress' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:deleteaddress - _legacy_parameters: - id_address: addressId - requirements: - addressId: \d+ - -admin_manufacturer_addresses_bulk_delete: - path: addresses/bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:bulkDeleteAddress' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:submitBulkdeleteaddress - -admin_manufacturer_addresses_export: - path: addresses/export - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Manufacturer:exportAddress' - _legacy_controller: AdminManufacturers - _legacy_link: AdminManufacturers:exportaddress diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/monitoring.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/monitoring.yml deleted file mode 100644 index 83f7a402..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/monitoring.yml +++ /dev/null @@ -1,14 +0,0 @@ -admin_monitorings_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Monitoring:index' - _legacy_controller: AdminTracking - _legacy_link: AdminTracking - -admin_monitorings_search: - path: / - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Catalog/Monitoring:search' - _legacy_controller: AdminTracking diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/attributes.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/attributes.yml deleted file mode 100644 index af87b073..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/attributes.yml +++ /dev/null @@ -1,42 +0,0 @@ -admin_attribute_get_all: - path: /get-all - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Attribute:getAllAttributes - _format: json - _legacy_controller: AdminProducts - -admin_attribute_generator: - path: /generator - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Attribute:attributesGenerator - _legacy_controller: AdminProducts - -admin_delete_attribute: - path: /{idProduct} - methods: [DELETE] - defaults: - _controller: PrestaShopBundle:Admin/Attribute:deleteAttribute - _legacy_controller: AdminProducts - -admin_delete_all_attributes: - path: /delete-all/{idProduct} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Attribute:deleteAllAttribute - _legacy_controller: AdminProducts - idProduct: 0 - requirements: - idProduct: \d+ - -admin_get_form_images_combination: - path: /form-images/{idProduct} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Attribute:getFormImages - _format: json - _legacy_controller: AdminProducts - idProduct: 0 - requirements: - idProduct: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/categories.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/categories.yml deleted file mode 100644 index 168f0ee4..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/categories.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_category_simple_add_form: - path: /add/simple - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Category:addSimpleCategoryForm - -admin_get_ajax_categories: - path: /list/{limit} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Category:getAjaxCategories - _format: json - limit: 20 - requirements: - limit: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/combinations.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/combinations.yml deleted file mode 100644 index 37df4555..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/combinations.yml +++ /dev/null @@ -1,16 +0,0 @@ -admin_combination_generate_form: - path: /form/{combinationIds} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Combination:generateCombinationForm - combinationIds: 0 - -admin_get_product_combinations: - path: /{idProduct} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Combination:getProductCombinations - _format: json - idProduct: 0 - requirements: - idProduct: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/features.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/features.yml deleted file mode 100644 index 6f68e6bf..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/features.yml +++ /dev/null @@ -1,8 +0,0 @@ -admin_feature_get_feature_values: - path: /{idFeature} - methods: [GET] - defaults: - idFeature: 0 - _controller: PrestaShopBundle:Admin/Feature:getFeatureValues - requirements: - idFeature: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/product.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/product.yml deleted file mode 100644 index 84f0e3b1..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/product.yml +++ /dev/null @@ -1,102 +0,0 @@ -# Product Form -admin_product_new: - path: /new - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Product:new - -admin_product_form: - path: /{id} - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Product:form - _legacy_controller: AdminProducts - _legacy_param_mapper_class: PrestaShop\PrestaShop\Adapter\Product\AdminProductDataProvider - _legacy_param_mapper_method: mapLegacyParametersProductForm - requirements: - id: \d+ - options: - expose: true - -admin_product_virtual_save_action: - path: /virtual/save/{idProduct} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/VirtualProduct:save - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_virtual_remove_file_action: - path: /virtual/remove-file/{idProduct} - defaults: - _controller: PrestaShopBundle:Admin/VirtualProduct:removeFile - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_virtual_download_file_action: - path: /virtual/download-file/{idProduct} - defaults: - _controller: PrestaShopBundle:Admin/VirtualProduct:downloadFile - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_virtual_remove_action: - path: /virtual/remove/{idProduct} - defaults: - _controller: PrestaShopBundle:Admin/VirtualProduct:remove - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_attachement_add_action: - path: /attachment/form/add/{idProduct} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/AttachementProduct:add - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_image_upload: - path: /image/upload/{idProduct} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/ProductImage:uploadImage - idProduct: 0 - requirements: - idProduct: \d+ - -admin_product_image_positions: - path: /image/positions - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/ProductImage:updateImagePosition - -admin_product_image_form: - path: image/form/{idImage} - defaults: - _controller: PrestaShopBundle:Admin/ProductImage:form - idImage: 0 - requirements: - idImage: \d+ - -admin_product_image_delete: - path: /image/delete/{idImage} - defaults: - _controller: PrestaShopBundle:Admin/ProductImage:delete - idImage: 0 - requirements: - idImage: \d+ - -admin_product_toggle_status: - path: /{productId}/toggle-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Product:toggleStatus - _legacy_controller: AdminTracking - _legacy_link: AdminTracking:statusproduct - _legacy_parameters: - id_product: productId diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/products.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/products.yml deleted file mode 100644 index c5707b74..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/products.yml +++ /dev/null @@ -1,110 +0,0 @@ -_product: - resource: "product.yml" - -_product_attributes: - resource: "attributes.yml" - prefix: /attributes/ - -_product_categories: - resource: "categories.yml" - prefix: /categories/ - -_product_combinations: - resource: "combinations.yml" - prefix: /combinations/ - -_product_features: - resource: "features.yml" - prefix: /features/ - -_product_specific_prices: - resource: "specific_prices.yml" - prefix: /specific-prices/ - -_product_suppliers: - resource: "suppliers.yml" - prefix: /suppliers/ - -_product_warehouses: - resource: "warehouses.yml" - prefix: /warehouses/ - -# Product List -admin_product_catalog: - path: /{offset}/{limit}/{orderBy}/{sortOrder} - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Product:catalog - _legacy_controller: AdminProducts - limit: last - offset: 0 - orderBy: last - sortOrder: last - requirements: - limit: _limit|last|\d+ - orderBy: last|id_product|name|reference|name_category|price|sav_quantity|position|active|position_ordering - offset: last|\d+ - sortOrder: last|asc|desc - -admin_product_catalog_filters: - path: /filters/{quantity}/{active} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Product:catalogFilters - _legacy_controller: AdminProducts - quantity: 'none' - active: 'none' - requirements: - quantity: none|<=\d+|<\d+|>\d+|>=\d+ - active: none|1|0 - -admin_product_list: - path: /list/{offset}/{limit}/{orderBy}/{sortOrder}/{view} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Product:list - limit: last - offset: 0 - orderBy: last - sortOrder: last - view: full - requirements: - limit: _limit|last|\d+ - orderBy: last|id_product|name|reference|name_category|price|sav_quantity|position|active|position_ordering - offset: last|\d+ - sortOrder: last|asc|desc - view: full|quicknav - -admin_product_bulk_action: - path: /bulk/{action} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Product:bulk - requirements: - action: activate_all|deactivate_all|delete_all|duplicate_all - -admin_product_unit_action: - path: /unit/{action}/{id} - methods: [POST|GET] - defaults: - _controller: PrestaShopBundle:Admin/Product:unit - requirements: - action: delete|duplicate|activate|deactivate - id: \d+ - -admin_product_mass_edit_action: - path: /massedit/{action} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Product:massEdit - requirements: - action: sort - -admin_product_export_action: - path: /export.{_format} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Product:export - _format: csv - requirements: - _format: csv diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/specific_prices.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/specific_prices.yml deleted file mode 100644 index 332a3d15..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/specific_prices.yml +++ /dev/null @@ -1,42 +0,0 @@ -admin_specific_price_list: - path: /list/{idProduct} - methods: [GET] - defaults: - _controller: PrestaShopBundle\Controller\Admin\SpecificPriceController::listAction - _format: json - idProduct: 0 - requirements: - idProduct: \d+ - -admin_get_specific_price_update_form: - path: /form/{idSpecificPrice}/ - methods: [GET] - defaults: - _controller: PrestaShopBundle\Controller\Admin\SpecificPriceController::getUpdateFormAction - idSpecificPrice: 0 - requirements: - idSpecificPrice: \d+ - -admin_specific_price_add: - path: /add - methods: [POST] - defaults: - _controller: PrestaShopBundle\Controller\Admin\SpecificPriceController::addAction - -admin_specific_price_update: - path: /update/{idSpecificPrice}/ - methods: [POST] - defaults: - _controller: PrestaShopBundle\Controller\Admin\SpecificPriceController::updateAction - idSpecificPrice: 0 - requirements: - idSpecificPrice: \d+ - -admin_delete_specific_price: - path: /delete/{idSpecificPrice} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/SpecificPrice:delete - idSpecificPrice: 0 - requirements: - idSpecificPrice: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/suppliers.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/suppliers.yml deleted file mode 100644 index 7712e58f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/suppliers.yml +++ /dev/null @@ -1,10 +0,0 @@ -admin_supplier_refresh_product_supplier_combination_form: - path: /refresh-product-supplier-combination-form/{idProduct}/{supplierIds} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Supplier:refreshProductSupplierCombinationForm - supplierIds: 0 - idProduct: 0 - requirements: - idProduct: \d+ - diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/warehouses.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/warehouses.yml deleted file mode 100644 index 2d520fb0..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/products/warehouses.yml +++ /dev/null @@ -1,8 +0,0 @@ -admin_warehouse_refresh_product_warehouse_combination_form: - path: /refresh-product-warehouse-combination-form/{idProduct} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Warehouse:refreshProductWarehouseCombinationForm - idProduct: 0 - requirements: - idProduct: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/suppliers.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/suppliers.yml deleted file mode 100644 index ef834059..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/catalog/suppliers.yml +++ /dev/null @@ -1,106 +0,0 @@ -admin_suppliers_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:index' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers - -admin_suppliers_search: - path: / - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:submitFiltersupplier - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.supplier - redirectRoute: admin_suppliers_index - -admin_suppliers_view: - path: /{supplierId}/products - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:view' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:viewsupplier - _legacy_parameters: - id_supplier: supplierId - requirements: - supplierId: \d+ - -admin_suppliers_create: - path: /new - methods: [GET,POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:create' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:addsupplier - -admin_suppliers_edit: - path: /{supplierId}/edit - methods: [GET,POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:edit' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:updatesupplier - _legacy_parameters: - id_supplier: supplierId - requirements: - supplierId: \d+ - -admin_suppliers_delete: - path: /{supplierId}/delete - methods: DELETE - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:delete' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:deletesupplier - _legacy_parameters: - id_supplier: supplierId - requirements: - supplierId: \d+ - -admin_suppliers_bulk_delete: - path: /bulk-delete - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:bulkDelete' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:submitBulkdeletesupplier - -admin_suppliers_bulk_enable: - path: /bulk-enable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:bulkEnable' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:submitBulkenableSelectionsupplier - -admin_suppliers_bulk_disable: - path: /bulk-disable - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:bulkDisable' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:submitBulkdisableSelectionsupplier - -admin_suppliers_toggle_status: - path: /{supplierId}/toggle-status - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:toggleStatus' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:statussupplier - _legacy_parameters: - id_supplier: supplierId - requirements: - supplierId: \d+ - -admin_suppliers_export: - path: /export - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Catalog\Supplier:export' - _legacy_controller: AdminSuppliers - _legacy_link: AdminSuppliers:exportsupplier - diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/_customer.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/_customer.yml deleted file mode 100644 index 399dfca9..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/_customer.yml +++ /dev/null @@ -1,7 +0,0 @@ -_catalog: - resource: "customers.yml" - prefix: /customers/ - -_addresses: - resource: "addresses.yml" - prefix: /addresses/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/addresses.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/addresses.yml deleted file mode 100644 index 1e2672da..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/addresses.yml +++ /dev/null @@ -1,93 +0,0 @@ -admin_addresses_index: - path: / - methods: GET - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:index - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses - -admin_addresses_search: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.address - redirectRoute: admin_addresses_index - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:submitFilteraddress - -admin_addresses_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:create - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:addaddress - options: - expose: true - -admin_addresses_edit: - path: /{addressId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:edit - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:updateaddress - _legacy_parameters: - id_address: addressId - requirements: - addressId: \d+ - options: - expose: true - -admin_order_addresses_edit: - path: /order/{orderId}/{addressType}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:editOrderAddress - _legacy_controller: AdminAddresses - requirements: - orderId: \d+ - addressType: delivery|invoice - options: - expose: true - -admin_cart_addresses_edit: - path: /cart/{cartId}/{addressType}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:editCartAddress - _legacy_controller: AdminAddresses - requirements: - cartId: \d+ - addressType: delivery|invoice - options: - expose: true - -admin_addresses_delete_bulk: - path: /delete-bulk - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:deleteBulk - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:submitBulkdeleteaddress - -admin_addresses_delete: - path: /{addressId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:delete - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:deleteaddress - _legacy_parameters: - id_address: addressId - requirements: - addressId: \d+ - -admin_addresses_save_required_fields: - path: /save-required-fields - methods: POST - defaults: - _controller: PrestaShopBundle:Admin\Sell\Address\Address:saveRequiredFields - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:submitFields diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/customers.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/customers.yml deleted file mode 100644 index 21255bff..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer/customers.yml +++ /dev/null @@ -1,199 +0,0 @@ -admin_customers_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:index - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers - -admin_customers_filter: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:searchGrid - _legacy_controller: AdminCustomers - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.customer - redirectRoute: admin_customers_index - _legacy_link: AdminCustomers:submitFiltercustomer - -admin_customers_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:create - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:addcustomer - -admin_customers_edit: - path: /{customerId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:edit - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:updatecustomer - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - -admin_customers_view: - path: /{customerId}/view - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:view - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:viewcustomer - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - options: - expose: true - -admin_customers_set_private_note: - path: /{customerId}/set-private-note - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:setPrivateNote - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:updateCustomerNote - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - -admin_customers_toggle_status: - path: /{customerId}/toggle-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:toggleStatus - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:statuscustomer - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - -admin_customers_transform_guest_to_customer: - path: /{customerId}/transform-guest-to-customer - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:transformGuestToCustomer - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:guesttocustomer - _legacy_parameters: - id_customer: customerId - -admin_customers_toggle_newsletter_subscription: - path: /{customerId}/toggle-newsletter-subscription - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:toggleNewsletterSubscription - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:changeNewsletterVal - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - -admin_customers_set_required_fields: - path: /set-required-fields - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:setRequiredFields - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:submitFields - -admin_customers_toggle_partner_offer_subscription: - path: /{customerId}/toggle-partner-offer-subscription - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:togglePartnerOfferSubscription - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:changeOptinVal - _legacy_parameters: - id_customer: customerId - requirements: - customerId: \d+ - -admin_customers_delete_bulk: - path: /delete-bulk - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:deleteBulk - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:submitBulkdeletecustomer - -admin_customers_delete: - path: /delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:delete - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:deletecustomer - -admin_customers_enable_bulk: - path: /enable-bulk - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:enableBulk - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:submitBulkenableSelectioncustomer - -admin_customers_disable_bulk: - path: /disable-bulk - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:disableBulk - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:submitBulkdisableSelectioncustomer - -admin_customers_export: - path: /export - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:export - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:exportcustomer - -admin_customers_search: - path: /search - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:search - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers:searchCustomers - options: - expose: true - -admin_customer_for_address_information: - path: /customer-information - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Customer\Customer:getCustomerInformation - _legacy_controller: AdminAddresses - _legacy_link: AdminAddresses:loadNames - -admin_customers_carts: - path: /{customerId}/carts - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:getCarts - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers - requirements: - customerId: \d+ - options: - expose: true - -admin_customers_orders: - path: /{customerId}/orders - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Customer/Customer:getOrders - _legacy_controller: AdminCustomers - _legacy_link: AdminCustomers - requirements: - customerId: \d+ - options: - expose: true diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/_customer_service.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/_customer_service.yml deleted file mode 100644 index fad91e25..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/_customer_service.yml +++ /dev/null @@ -1,11 +0,0 @@ -_order_message: - resource: "order_message.yml" - prefix: /order-messages/ - -_merchandise_return: - resource: "merchandise_return.yml" - prefix: /merchandise-return/ - -_customer_threads: - resource: "customer_threads.yml" - prefix: /customer-threads/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/customer_threads.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/customer_threads.yml deleted file mode 100644 index 4c67d843..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/customer_threads.yml +++ /dev/null @@ -1,39 +0,0 @@ -admin_customer_threads_view: - path: /{customerThreadId}/view - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/CustomerThread:view - _legacy_controller: AdminCustomerThreads -# _legacy_link: AdminCustomerThreads - requirements: - customerThreadId: \d+ - -admin_customer_threads_reply: - path: /{customerThreadId}/reply - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/CustomerThread:reply - _legacy_controller: AdminCustomerThreads - # _legacy_link: AdminCustomerThreads - requirements: - customerThreadId: \d+ - -admin_customer_threads_update_status: - path: /{customerThreadId}/update-status/{newStatus} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/CustomerThread:updateStatus - _legacy_controller: AdminCustomerThreads - # _legacy_link: AdminCustomerThreads - requirements: - customerThreadId: \d+ - -admin_customer_threads_forward: - path: /{customerThreadId}/forward - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/CustomerThread:forward - _legacy_controller: AdminCustomerThreads - # _legacy_link: AdminCustomerThreads - requirements: - customerThreadId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/merchandise_return.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/merchandise_return.yml deleted file mode 100644 index 5f3c1d0f..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/merchandise_return.yml +++ /dev/null @@ -1,25 +0,0 @@ -admin_merchandise_returns_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/MerchandiseReturn:index - _legacy_controller: AdminReturn -# _legacy_link: AdminReturn - -admin_merchandise_returns_save_options: - path: /options - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/MerchandiseReturn:index - _legacy_controller: AdminReturn -# _legacy_link: AdminReturn:submitOptionsorder_return - -admin_merchandise_returns_filter: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.merchandise_return - redirectRoute: admin_merchandise_returns_index - _legacy_controller: AdminReturn -# _legacy_link: AdminReturn:submitFilterorder_return diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/order_message.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/order_message.yml deleted file mode 100644 index 8a38ee64..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/customer_service/order_message.yml +++ /dev/null @@ -1,59 +0,0 @@ -admin_order_messages_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/OrderMessage:index - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage - -admin_order_messages_filter: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.order_message - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage:submitFilterorder_message - redirectRoute: admin_order_messages_index - -admin_order_messages_create: - path: /new - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/OrderMessage:create - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage:addorder_message - -admin_order_messages_edit: - path: /{orderMessageId}/edit - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/OrderMessage:edit - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage:updateorder_message - legacy_parameters: - id_order_message: orderMessageId - requirements: - orderMessageId: \d+ - -admin_order_messages_delete: - path: /{orderMessageId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/OrderMessage:delete - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage:deleteorder_message - legacy_parameters: - id_order_message: orderMessageId - requirements: - orderMessageId: \d+ - -admin_order_messages_bulk_delete: - path: /bulk-delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/CustomerService/OrderMessage:bulkDelete - _legacy_controller: AdminOrderMessage - _legacy_link: AdminOrderMessage:submitBulkdeleteorder_message - legacy_parameters: - order_messageBox: order_message_order_messages_bulk diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/_orders.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/_orders.yml deleted file mode 100644 index f34f2ff7..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/_orders.yml +++ /dev/null @@ -1,19 +0,0 @@ -_delivery_slips: - resource: "delivery_slips.yml" - prefix: /delivery-slips/ - -_invoices: - resource: "invoices.yml" - prefix: /invoices/ - -_carts: - resource: "carts.yml" - prefix: /carts/ - -_orders: - resource: "orders.yml" - prefix: / - -_credit_slips: - resource: "credit_slips.yml" - prefix: /credit-slips/ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/carts.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/carts.yml deleted file mode 100644 index bc274c88..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/carts.yml +++ /dev/null @@ -1,152 +0,0 @@ -admin_carts_view: - path: /{cartId}/view - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:view - _legacy_controller: AdminCarts - _legacy_link: AdminCarts:viewcart - _legacy_parameters: - id_cart: cartId - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_info: - path: /{cartId}/info - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:getInfo - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_create: - path: /new - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:create - _legacy_controller: AdminCarts - options: - expose: true - -admin_carts_edit_addresses: - path: /{cartId}/addresses - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editAddresses - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_edit_carrier: - path: /{cartId}/carrier - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editCarrier - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_edit_currency: - path: /{cartId}/currency - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editCurrency - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_edit_language: - path: /{cartId}/language - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editLanguage - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_set_delivery_settings: - path: /{cartId}/rules/delivery-settings - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:updateDeliverySettings - _legacy_controller: AdminCarts - requirements: - cartId: \d+ - options: - expose: true - -admin_carts_add_cart_rule: - path: /{cartId}/cart-rules - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:addCartRule - _legacy_controller: AdminCarts - options: - expose: true - -admin_carts_delete_cart_rule: - path: /{cartId}/cart-rules/{cartRuleId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:deleteCartRule - _legacy_controller: AdminCarts - options: - expose: true - -admin_carts_add_product: - path: /{cartId}/products - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:addProduct - _legacy_controller: AdminCarts - options: - expose: true - requirements: - cartId: \d+ - -admin_carts_edit_product_price: - path: /{cartId}/products/{productId}/price - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editProductPrice - _legacy_controller: AdminCarts - options: - expose: true - requirements: - cartId: \d+ - productId: \d+ - -admin_carts_edit_product_quantity: - path: /{cartId}/products/{productId}/quantity - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:editProductQuantity - _legacy_controller: AdminCarts - options: - expose: true - requirements: - cartId: \d+ - productId: \d+ - -admin_carts_delete_product: - path: /{cartId}/delete-product - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Cart:deleteProduct - _legacy_controller: AdminCarts - options: - expose: true - requirements: - cartId: \d+ diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/credit_slips.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/credit_slips.yml deleted file mode 100644 index 2494d7fd..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/credit_slips.yml +++ /dev/null @@ -1,43 +0,0 @@ -admin_credit_slips_index: - path: / - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Order/CreditSlip:index' - _legacy_controller: AdminSlip - _legacy_link: AdminSlip - -admin_credit_slips_search: - path: /search - methods: POST - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Order/CreditSlip:search' - _legacy_controller: AdminSlip - _legacy_link: AdminSlip:submitFilterorder_slip - -admin_credit_slips_generate_pdf: - path: /{creditSlipId}/pdf - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Order/CreditSlip:generatePdf' - _legacy_controller: AdminSlip - _legacy_link: AdminSlip:submitgenerateOrderSlipPdf - _legacy_parameters: - id_order_slip: creditSlipId - requirements: - creditSlipId: \d+ - -_admin_credit_slips_pdf_by_date: - path: /pdf-by-date - methods: GET - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Order/CreditSlip:generatePdfByDate' - _legacy_link: AdminSlip:submitAddorder_slip - _legacy_controller: AdminSlip - -admin_credit_slips_process_options: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin/Sell/Order/CreditSlip:index' - _legacy_controller: AdminSlip - _legacy_link: AdminSlip:submitOptionsorder_slip diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/delivery_slips.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/delivery_slips.yml deleted file mode 100644 index 0c25bf3b..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/delivery_slips.yml +++ /dev/null @@ -1,15 +0,0 @@ -admin_order_delivery_slip: - path: / - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Delivery:slip - _legacy_controller: AdminDeliverySlip - _legacy_link: AdminDeliverySlip - -admin_order_delivery_slip_pdf: - path: /pdf - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Delivery:generatePdf - _legacy_controller: AdminDeliverySlip - _legacy_link: AdminDeliverySlip:submitAdddelivery diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/invoices.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/invoices.yml deleted file mode 100644 index b51fb378..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/invoices.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Invoices -admin_order_invoices: - path: / - methods: [GET] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Order\Invoices:index' - _legacy_controller: AdminInvoices - _legacy_link: AdminInvoices - -# Process Invoice Options form -admin_order_invoices_process: - path: / - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Order\Invoices:process' - _legacy_controller: AdminInvoices - _legacy_link: AdminInvoices:update - -# Generate PDF by date -admin_order_invoices_generate_by_date: - path: /by_date - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Order\Invoices:generatePdfByDate' - _legacy_controller: AdminInvoices - _legacy_link: AdminInvoices:submitAddinvoice_date - -# Generate PDF by status -admin_order_invoices_generate_by_status: - path: /by_status - methods: [POST] - defaults: - _controller: 'PrestaShopBundle:Admin\Sell\Order\Invoices:generatePdfByStatus' - _legacy_controller: AdminInvoices - _legacy_link: AdminInvoices:submitAddinvoice_status diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/orders.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/orders.yml deleted file mode 100644 index a87ff113..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/orders/orders.yml +++ /dev/null @@ -1,398 +0,0 @@ -admin_orders_index: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:index - _legacy_controller: AdminOrders - _legacy_link: AdminOrders - -admin_orders_create: - path: /new - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Order\Order:create - _legacy_controller: AdminOrders - _legacy_link: AdminOrders:addorder - -admin_orders_place: - path: /place - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Sell\Order\Order:place - _legacy_controller: AdminOrders - options: - expose: true - -admin_orders_search: - path: / - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin\Common:searchGrid - _legacy_controller: AdminOrders - gridDefinitionFactoryServiceId: prestashop.core.grid.definition.factory.order - redirectRoute: admin_orders_index - -admin_orders_generate_invoice_pdf: - path: /{orderId}/generate-invoice-pdf - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:generateInvoicePdf - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_generate_delivery_slip_pdf: - path: /{orderId}/generate-delivery-slip-pdf - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:generateDeliverySlipPdf - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_change_orders_status: - path: /change-orders-status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:changeOrdersStatus - _legacy_controller: AdminOrders - -admin_orders_export: - path: /export - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:export - _legacy_controller: AdminOrders - -admin_orders_view: - path: /{orderId}/view - methods: [GET, POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:view - _legacy_controller: AdminOrders - _legacy_link: AdminOrders:vieworder - _legacy_parameters: - id_order: orderId - options: - expose: true - requirements: - orderId: \d+ - -admin_orders_add_cart_rule: - path: /{orderId}/cart-rules - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:addCartRule - requirements: - orderId: \d+ - -admin_orders_list_update_status: - path: /list/{orderId}/status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:updateStatusFromList - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_update_status: - path: /{orderId}/status - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:updateStatus - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_add_payment: - path: /{orderId}/payment - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:addPayment - requirements: - orderId: \d+ - -admin_orders_duplicate_cart: - path: /{orderId}/duplicate-cart - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:duplicateOrderCart - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_change_currency: - path: /{orderId}/currency/change - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:changeCurrency - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_update_product: - path: /{orderId}/products/{orderDetailId} - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:updateProduct - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - orderDetailId: \d+ - options: - expose: true - -admin_orders_remove_cart_rule: - path: /{orderId}/cart-rules/{orderCartRuleId}/delete - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:removeCartRule - requirements: - orderId: \d+ - orderCartRuleId: \d+ - -admin_orders_resend_email: - path: /{orderId}/history/{orderHistoryId}/statuses/{orderStatusId}/resend-email - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:resendEmail - requirements: - orderId: \d+ - orderHistoryId: \d+ - orderStatusId: \d+ - -admin_orders_preview: - path: /{orderId}/preview - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:preview - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_update_shipping: - path: /{orderId}/shipping - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:updateShipping - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_update_invoice_note: - path: /{orderId}/invoice/{orderInvoiceId}/note - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:updateInvoiceNote - requirements: - orderId: \d+ - orderInvoiceId: \d+ - -admin_orders_generate_invoice: - path: /{orderId}/invoice - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:generateInvoice - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_change_customer_address: - path: /change-customer-address - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:changeCustomerAddress - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - -admin_orders_send_message: - path: /{orderId}/send-message - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:sendMessage - _legacy_controller: AdminOrders - -admin_orders_partial_refund: - path: /{orderId}/partial-refund - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:partialRefund - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_standard_refund: - path: /{orderId}/standard-refund - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:standardRefund - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_return_product: - path: /{orderId}/return-product - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:returnProduct - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_send_process_order_email: - path: /process-order-email - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:sendProcessOrderEmail - _legacy_controller: AdminOrders - options: - expose: true - -admin_orders_add_product: - path: /{orderId}/products - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:addProduct - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_delete_product: - path: /{orderId}/products/{orderDetailId}/delete - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:deleteProduct - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - orderDetailId: \d+ - options: - expose: true - -admin_orders_get_discounts: - path: /{orderId}/discounts - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getDiscounts - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_get_prices: - path: /{orderId}/prices - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getPrices - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_get_payments: - path: /{orderId}/payments - methods: [ GET ] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getPayments - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_get_products: - path: /{orderId}/products - methods: [ GET ] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getProductsList - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_get_invoices: - path: /{orderId}/invoices - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getInvoices - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_get_documents: - path: /{orderId}/documents - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getDocuments - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_cancellation: - path: /{orderId}/cancellation - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:cancellation - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_configure_product_pagination: - path: /configure-product-pagination - methods: [POST] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:configureProductPagination - _legacy_controller: AdminOrders - options: - expose: true - -admin_orders_display_customization_image: - path: /display-customization-image/{orderId}/{name}/{value} - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:displayCustomizationImage - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - name: \w+ - value: \w+ - -admin_orders_product_prices: - path: /{orderId}/products/prices - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:getProductPrices - _legacy_controller: AdminOrders - requirements: - orderId: \d+ - options: - expose: true - -admin_orders_products_search: - path: /products/search - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Sell/Order/Order:searchProducts - _legacy_controller: AdminOrders - options: - expose: true diff --git a/src/PrestaShopBundle/Resources/config/routing/admin/sell/stocks.yml b/src/PrestaShopBundle/Resources/config/routing/admin/sell/stocks.yml deleted file mode 100644 index 634e9651..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/admin/sell/stocks.yml +++ /dev/null @@ -1,14 +0,0 @@ -admin_stock_overview: - path: / - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Stock:overview - _legacy_controller: AdminStockManagement - _legacy_link: AdminStockManagement - -admin_stock_movements_overview: - path: /movements - methods: [GET] - defaults: - _controller: PrestaShopBundle:Admin/Stock:overview - _legacy_controller: AdminStockManagement diff --git a/src/PrestaShopBundle/Resources/config/routing/api.yml b/src/PrestaShopBundle/Resources/config/routing/api.yml deleted file mode 100644 index ab513281..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api.yml +++ /dev/null @@ -1,39 +0,0 @@ -_api_stocks: - resource: "api/stocks.yml" - prefix: /stocks - -_api_stock_movements: - resource: "api/stock_movements.yml" - prefix: /stock-movements - -_api_suppliers: - resource: "api/suppliers.yml" - prefix: /suppliers - -_api_manufacturers: - resource: "api/manufacturers.yml" - prefix: /manufacturers - -_api_categories: - resource: "api/categories.yml" - prefix: /categories - -_api_attributes: - resource: "api/attributes.yml" - prefix: /attributes - -_api_features: - resource: "api/features.yml" - prefix: /features - -_api_i18n: - resource: "api/i18n.yml" - prefix: /i18n - -_api_translations: - resource: "api/translations.yml" - prefix: /translations - -_api_positions: - resource: "api/improve/design/positions.yml" - prefix: /improve/design/positions diff --git a/src/PrestaShopBundle/Resources/config/routing/api/attributes.yml b/src/PrestaShopBundle/Resources/config/routing/api/attributes.yml deleted file mode 100644 index 9c149d67..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/attributes.yml +++ /dev/null @@ -1,5 +0,0 @@ -api_stock_list_attributes: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.attribute.controller:listAttributesAction diff --git a/src/PrestaShopBundle/Resources/config/routing/api/categories.yml b/src/PrestaShopBundle/Resources/config/routing/api/categories.yml deleted file mode 100644 index 7d554c2c..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/categories.yml +++ /dev/null @@ -1,5 +0,0 @@ -api_stock_list_categories: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.category.controller:listCategoriesAction diff --git a/src/PrestaShopBundle/Resources/config/routing/api/features.yml b/src/PrestaShopBundle/Resources/config/routing/api/features.yml deleted file mode 100644 index 37f57210..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/features.yml +++ /dev/null @@ -1,5 +0,0 @@ -api_stock_list_features: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.feature.controller:listFeaturesAction diff --git a/src/PrestaShopBundle/Resources/config/routing/api/i18n.yml b/src/PrestaShopBundle/Resources/config/routing/api/i18n.yml deleted file mode 100644 index 76c03d4c..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/i18n.yml +++ /dev/null @@ -1,7 +0,0 @@ -api_i18n_translations_list: - path: /{page} - methods: [GET] - defaults: - _controller: prestashop.core.api.i18n.controller:listTranslationAction - requirements: - page: \w+ diff --git a/src/PrestaShopBundle/Resources/config/routing/api/improve/design/positions.yml b/src/PrestaShopBundle/Resources/config/routing/api/improve/design/positions.yml deleted file mode 100644 index f87b568b..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/improve/design/positions.yml +++ /dev/null @@ -1,6 +0,0 @@ -api_improve_design_positions_update: - path: /update - methods: [POST] - defaults: - _controller: prestashop.core.api.improve.design.postions.controller:updateAction - _legacy_controller: AdminModulesPositions diff --git a/src/PrestaShopBundle/Resources/config/routing/api/manufacturers.yml b/src/PrestaShopBundle/Resources/config/routing/api/manufacturers.yml deleted file mode 100644 index 238cd2ab..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/manufacturers.yml +++ /dev/null @@ -1,5 +0,0 @@ -api_stock_list_manufacturers: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.manufacturer.controller:listManufacturersAction diff --git a/src/PrestaShopBundle/Resources/config/routing/api/stock_movements.yml b/src/PrestaShopBundle/Resources/config/routing/api/stock_movements.yml deleted file mode 100644 index 55a087b8..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/stock_movements.yml +++ /dev/null @@ -1,30 +0,0 @@ -api_stock_list_movements: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.stock_movement.controller:listMovementsAction - _legacy_controller: AdminStockManagement - -api_stock_product_list_movements: - path: /product/{productId} - methods: [GET] - defaults: - _controller: prestashop.core.api.stock_movement.controller:listMovementsAction - _legacy_controller: AdminStockManagement - requirements: - productId: \d+ - -api_stock_list_movements_employees: - path: /employees - methods: [GET] - defaults: - _controller: prestashop.core.api.stock_movement.controller:listMovementsEmployeesAction - _legacy_controller: AdminStockManagement - - -api_stock_list_movements_types: - path: /types - methods: [GET] - defaults: - _controller: prestashop.core.api.stock_movement.controller:listMovementsTypesAction - _legacy_controller: AdminStockManagement diff --git a/src/PrestaShopBundle/Resources/config/routing/api/stocks.yml b/src/PrestaShopBundle/Resources/config/routing/api/stocks.yml deleted file mode 100644 index f9a47adf..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/stocks.yml +++ /dev/null @@ -1,48 +0,0 @@ -api_stock_list_products: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.stock.controller:listProductsAction - _legacy_controller: AdminStockManagement - -api_stock_list_products_export: - path: /export - methods: [GET] - defaults: - _controller: prestashop.core.api.stock.controller:listProductsExportAction - _legacy_controller: AdminStockManagement - -api_stock_list_product_combinations: - path: /{productId} - methods: [GET] - defaults: - _controller: prestashop.core.api.stock.controller:listProductsAction - _legacy_controller: AdminStockManagement - requirements: - productId: \d+ - -api_stock_edit_product: - path: /product/{productId} - methods: [POST] - defaults: - _controller: prestashop.core.api.stock.controller:editProductAction - _legacy_controller: AdminStockManagement - requirements: - productId: \d+ - -api_stock_edit_product_combination: - path: /product/{productId}/combination/{combinationId} - methods: [POST] - defaults: - _controller: prestashop.core.api.stock.controller:editProductAction - _legacy_controller: AdminStockManagement - requirements: - productId: \d+ - combinationId: \d+ - -api_stock_bulk_edit_products: - path: /products - methods: [POST] - defaults: - _controller: prestashop.core.api.stock.controller:bulkEditProductsAction - _legacy_controller: AdminStockManagement diff --git a/src/PrestaShopBundle/Resources/config/routing/api/suppliers.yml b/src/PrestaShopBundle/Resources/config/routing/api/suppliers.yml deleted file mode 100644 index 3347e634..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/suppliers.yml +++ /dev/null @@ -1,5 +0,0 @@ -api_stock_list_suppliers: - path: / - methods: [GET] - defaults: - _controller: prestashop.core.api.supplier.controller:listSuppliersAction diff --git a/src/PrestaShopBundle/Resources/config/routing/api/translations.yml b/src/PrestaShopBundle/Resources/config/routing/api/translations.yml deleted file mode 100644 index 09de266d..00000000 --- a/src/PrestaShopBundle/Resources/config/routing/api/translations.yml +++ /dev/null @@ -1,30 +0,0 @@ -api_translation_domains_tree: - path: /tree/{lang}/{type}/{selected} - methods: [GET] - defaults: - _controller: prestashop.core.api.translation.controller:listTreeAction - _legacy_controller: AdminTranslations - selected: null - -api_translation_domain_catalog: - path: /{locale}/{domain}/{theme} - methods: [GET] - defaults: - _controller: prestashop.core.api.translation.controller:listDomainTranslationAction - _legacy_controller: AdminTranslations - theme: null - module: null - -api_translation_value_edit: - path: /edit - methods: [POST] - defaults: - _controller: prestashop.core.api.translation.controller:translationEditAction - _legacy_controller: AdminTranslations - -api_translation_value_reset: - path: /reset - methods: [POST] - defaults: - _controller: prestashop.core.api.translation.controller:translationResetAction - _legacy_controller: AdminTranslations diff --git a/src/PrestaShopBundle/Resources/config/services.yml b/src/PrestaShopBundle/Resources/config/services.yml deleted file mode 100644 index 76c4b041..00000000 --- a/src/PrestaShopBundle/Resources/config/services.yml +++ /dev/null @@ -1,8 +0,0 @@ -parameters: - multishop.settings.share_orders: !php/const Shop::SHARE_ORDER - -imports: - - { resource: services/bundle/*.yml } - - { resource: services/core/*.yml } - - { resource: services/adapter/*.yml } - - { resource: services/alias.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/address.yml b/src/PrestaShopBundle/Resources/config/services/adapter/address.yml deleted file mode 100644 index 35aa346a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/address.yml +++ /dev/null @@ -1,81 +0,0 @@ -services: - _defaults: - public: true - - # Command handlers - - prestashop.adapter.address.command_handler.delete_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\DeleteAddressHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\DeleteAddressCommand' } - - prestashop.adapter.address.command_handler.bulk_delete_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\BulkDeleteAddressHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\BulkDeleteAddressCommand' } - - prestashop.adapter.address.command_handler.add_manufacturer_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\AddManufacturerAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\AddManufacturerAddressCommand' - - prestashop.adapter.address.command_handler.edit_manufacturer_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\EditManufacturerAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\EditManufacturerAddressCommand' - - prestashop.adapter.address.query_handler.get_manufacturer_address_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\QueryHandler\GetManufacturerAddressForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Query\GetManufacturerAddressForEditing' - - prestashop.adapter.address.query_handler.get_required_fields_for_address: - class: 'PrestaShop\PrestaShop\Adapter\Address\QueryHandler\GetRequiredFieldsForAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Query\GetRequiredFieldsForAddress' - - prestashop.adapter.address.command_handler.set_required_fields_for_address: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\SetRequiredFieldsForAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\SetRequiredFieldsForAddressCommand' - - prestashop.adapter.address.command_handler.add_customer_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\AddCustomerAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\AddCustomerAddressCommand' - - prestashop.adapter.address.query_handler.get_customer_address_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\QueryHandler\GetCustomerAddressForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing' - - prestashop.adapter.address.command_handler.edit_customer_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\EditCustomerAddressHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCustomerAddressCommand' - - prestashop.adapter.address.command_handler.edit_order_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\EditOrderAddressHandler' - arguments: - - '@prestashop.adapter.address.command_handler.edit_customer_address_handler' - - '@prestashop.adapter.order.command_handler.change_order_delivery_address_handler' - - '@prestashop.adapter.order.command_handler.change_order_invoice_address_handler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\EditOrderAddressCommand' - - prestashop.adapter.address.command_handler.edit_cart_address_handler: - class: 'PrestaShop\PrestaShop\Adapter\Address\CommandHandler\EditCartAddressHandler' - arguments: - - '@prestashop.adapter.address.command_handler.edit_customer_address_handler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCartAddressCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/admin.yml b/src/PrestaShopBundle/Resources/config/services/adapter/admin.yml deleted file mode 100644 index 4b9723b8..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/admin.yml +++ /dev/null @@ -1,18 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.admin.page_preference: - class: PrestaShop\PrestaShop\Adapter\Admin\PagePreference - arguments: - - "@session" - decorates: prestashop.core.admin.page_preference_interface - public: false - - prestashop.adapter.admin.controller.category: - class: PrestaShop\PrestaShop\Adapter\Category\AdminCategoryControllerWrapper - - prestashop.adapter.legacy_db: - class: 'Db' - factory: ['Db', 'getInstance'] - deprecated: '%service_id% service is deprecated and will be removed in 1.8.' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/attachment.yml b/src/PrestaShopBundle/Resources/config/services/adapter/attachment.yml deleted file mode 100644 index 3da917a8..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/attachment.yml +++ /dev/null @@ -1,59 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.attachment.command_handler.delete_attachment_handler: - public: true - class: 'PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler\DeleteAttachmentHandler' - parent: 'prestashop.adapter.attachment.command_handler.abstract_attachment_handler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Command\DeleteAttachmentCommand' } - - prestashop.adapter.attachment.command_handler.bulk_delete_attachment_handler: - public: true - class: 'PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler\BulkDeleteAttachmentsHandler' - parent: 'prestashop.adapter.attachment.command_handler.abstract_attachment_handler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Command\BulkDeleteAttachmentsCommand' } - - prestashop.adapter.attachment.query_handler.get_attachment_handler: - class: 'PrestaShop\PrestaShop\Adapter\Attachment\QueryHandler\GetAttachmentHandler' - arguments: - - !php/const _PS_DOWNLOAD_DIR_ - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachment' } - - prestashop.adapter.contact.query_handler.get_attachment_handler: - class: 'PrestaShop\PrestaShop\Adapter\Attachment\QueryHandler\GetAttachmentForEditingHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Query\GetAttachmentForEditing' } - - prestashop.adapter.attachment.uploader.attachment_file_uploader: - class: 'PrestaShop\PrestaShop\Adapter\File\Uploader\AttachmentFileUploader' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.configuration.upload_size_configuration' - - prestashop.adapter.attachment.command_handler.abstract_attachment_handler: - abstract: true - class: 'PrestaShop\PrestaShop\Adapter\Attachment\AbstractAttachmentHandler' - arguments: - - '@validator' - - prestashop.adapter.attachment.command_handler.edit_attachment_handler: - public: true - class: 'PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler\EditAttachmentHandler' - parent: 'prestashop.adapter.attachment.command_handler.abstract_attachment_handler' - arguments: - - '@prestashop.adapter.attachment.uploader.attachment_file_uploader' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Command\EditAttachmentCommand' } - - prestashop.adapter.attachment.command_handler.create_attachment_handler: - public: true - class: 'PrestaShop\PrestaShop\Adapter\Attachment\CommandHandler\AddAttachmentHandler' - parent: 'prestashop.adapter.attachment.command_handler.abstract_attachment_handler' - arguments: - - '@prestashop.adapter.attachment.uploader.attachment_file_uploader' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Attachment\Command\AddAttachmentCommand' } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/attribute.yml b/src/PrestaShopBundle/Resources/config/services/adapter/attribute.yml deleted file mode 100644 index 5ea44176..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/attribute.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.attribute.command_handler.delete_attribute_handler: - class: 'PrestaShop\PrestaShop\Adapter\Attribute\CommandHandler\DeleteAttributeHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\DeleteAttributeCommand' - - prestashop.adapter.attribute.command_handler.bulk_delete_attribute_handler: - class: 'PrestaShop\PrestaShop\Adapter\Attribute\CommandHandler\BulkDeleteAttributeHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Attribute\Command\BulkDeleteAttributeCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/attribute_group.yml b/src/PrestaShopBundle/Resources/config/services/adapter/attribute_group.yml deleted file mode 100644 index c41e7a52..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/attribute_group.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.attribute_group.command_handler.delete_attribute_group_handler: - class: 'PrestaShop\PrestaShop\Adapter\AttributeGroup\CommandHandler\DeleteAttributeGroupHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\DeleteAttributeGroupCommand' - - prestashop.adapter.attribute_group.command_handler.bulk_delete_attribute_group_handler: - class: 'PrestaShop\PrestaShop\Adapter\AttributeGroup\CommandHandler\BulkDeleteAttributeGroupHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Product\AttributeGroup\Command\BulkDeleteAttributeGroupCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/backup.yml b/src/PrestaShopBundle/Resources/config/services/adapter/backup.yml deleted file mode 100644 index 05c0b846..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/backup.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.backup.database_creator: - class: 'PrestaShop\PrestaShop\Adapter\Backup\DatabaseBackupCreator' - - prestashop.adapter.backup.backup_provider: - class: 'PrestaShop\PrestaShop\Adapter\Backup\BackupRepository' - - prestashop.adapter.backup.backup_remover: - class: 'PrestaShop\PrestaShop\Adapter\Backup\BackupRemover' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/cache.yml b/src/PrestaShopBundle/Resources/config/services/adapter/cache.yml deleted file mode 100644 index ae571d91..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/cache.yml +++ /dev/null @@ -1,18 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.cache.clearer.class_index_cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\Clearer\ClassIndexCacheClearer' - - prestashop.adapter.cache.clearer.media_cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\Clearer\MediaCacheClearer' - - prestashop.adapter.cache.clearer.smarty_cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\Clearer\SmartyCacheClearer' - - prestashop.adapter.cache.clearer.symfony_cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\Clearer\SymfonyCacheClearer' - - prestashop.adapter.cache.clearer.xml_cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\Clearer\XmlCacheClearer' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/cart.yml b/src/PrestaShopBundle/Resources/config/services/adapter/cart.yml deleted file mode 100644 index 9c77d521..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/cart.yml +++ /dev/null @@ -1,131 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.cart.command_handler.create_empty_customer_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\CreateEmptyCustomerCartHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\CreateEmptyCustomerCartCommand' - - prestashop.adapter.cart.command_handler.update_cart_currency_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateCartCurrencyHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCurrencyCommand' - - prestashop.adapter.cart.command_handler.update_cart_language_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateCartLanguageHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartLanguageCommand' - - prestashop.adapter.cart.command_handler.update_cart_addresses_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateCartAddressesHandler' - arguments: - - '@prestashop.adapter.command_handler.update_cart_carrier_handler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartAddressesCommand' - - prestashop.adapter.cart.command_handler.update_delivery_options_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateCartDeliverySettingsHandler' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.configuration' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartDeliverySettingsCommand' - - prestashop.adapter.command_handler.update_product_quantity_in_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateProductQuantityInCartHandler' - arguments: - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductQuantityInCartCommand' - - prestashop.adapter.command_handler.update_cart_carrier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateCartCarrierHandler' - arguments: - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateCartCarrierCommand' - - prestashop.adapter.command_handler.add_cart_rule_to_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\AddCartRuleToCartHandler' - arguments: - - '@translator' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCartRuleToCartCommand' - - prestashop.adapter.command_handler.remove_cart_rule_from_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\RemoveCartRuleFromCartHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveCartRuleFromCartCommand' - - prestashop.adapter.command_handler.remove_product_from_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\RemoveProductFromCartHandler' - arguments: - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\RemoveProductFromCartCommand' - - prestashop.adapter.command_handler.update_product_price_in_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\UpdateProductPriceInCartHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\UpdateProductPriceInCartCommand' - - prestashop.adapter.command_handler.send_cart_to_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\SendCartToCustomerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\SendCartToCustomerCommand' - - prestashop.adapter.query_handler.get_cart_for_viewing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\QueryHandler\GetCartForViewingHandler' - arguments: - - '@prestashop.adapter.image_manager' - - "@prestashop.core.localization.locale.context_locale" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForViewing' - - prestashop.adapter.cart.query_handler.get_last_empty_customer_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\QueryHandler\GetLastEmptyCustomerCartHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetLastEmptyCustomerCart' - - prestashop.adapter.query_handler.get_cart_information_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\QueryHandler\GetCartForOrderCreationHandler' - arguments: - - "@prestashop.core.localization.locale.context_locale" - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@=service("prestashop.adapter.legacy.context").getContext().link' - - '@prestashop.adapter.context_state_manager' - - '@translator' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Query\GetCartForOrderCreation' - - prestashop.adapter.command_handler.add_customization_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\AddCustomizationHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddCustomizationCommand' - - prestashop.adapter.command_handler.add_product_to_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Cart\CommandHandler\AddProductToCartHandler' - arguments: - - '@prestashop.adapter.command_handler.add_customization_handler' - - '@prestashop.adapter.command_handler.update_product_quantity_in_cart_handler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Cart\Command\AddProductToCartCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/cart_rule.yml b/src/PrestaShopBundle/Resources/config/services/adapter/cart_rule.yml deleted file mode 100644 index c20bcc33..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/cart_rule.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.cart_rule.command_handler.add_cart_rule_handler: - class: PrestaShop\PrestaShop\Adapter\CartRule\CommandHandler\AddCartRuleHandler - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\CartRule\Command\AddCartRuleCommand } - - prestashop.adapter.cart_rule.query_handler.search_cart_rules_handler: - class: PrestaShop\PrestaShop\Adapter\CartRule\QueryHandler\SearchCartRulesHandler - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\CartRule\Query\SearchCartRules } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/catalog_price_rule.yml b/src/PrestaShopBundle/Resources/config/services/adapter/catalog_price_rule.yml deleted file mode 100644 index 46df1ca6..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/catalog_price_rule.yml +++ /dev/null @@ -1,33 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.catalog_price_rule.command_handler.delete_catalog_price_rule_handler: - class: 'PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler\DeleteCatalogPriceRuleHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\DeleteCatalogPriceRuleCommand' - - prestashop.adapter.catalog_price_rule.command_handler.bulk_delete_catalog_price_rule_handler: - class: 'PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler\BulkDeleteCatalogPriceRuleHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\BulkDeleteCatalogPriceRuleCommand' - - prestashop.adapter.catalog_price_rule.command_handler.add_catalog_price_rule_handler: - class: 'PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler\AddCatalogPriceRuleHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\AddCatalogPriceRuleCommand' - - prestashop.adapter.catalog_price_rule.command_handler.edit_catalog_price_rule_handler: - class: 'PrestaShop\PrestaShop\Adapter\CatalogPriceRule\CommandHandler\EditCatalogPriceRuleHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Command\EditCatalogPriceRuleCommand' - - prestashop.adapter.catalog_price_rule.command_handler.get_catalog_price_rule_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\CatalogPriceRule\QueryHandler\GetCatalogPriceRuleForEditingHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\CatalogPriceRule\Query\GetCatalogPriceRuleForEditing' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/category.yml b/src/PrestaShopBundle/Resources/config/services/adapter/category.yml deleted file mode 100644 index dbabab07..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/category.yml +++ /dev/null @@ -1,116 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.admin.controller.category: - class: PrestaShop\PrestaShop\Adapter\Category\AdminCategoryControllerWrapper - - prestashop.adapter.category.category_view_data_provider: - class: PrestaShop\PrestaShop\Adapter\Category\CategoryViewDataProvider - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.feature.multistore' - - '@prestashop.adapter.shop.context' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - prestashop.adapter.category.command_handler.bulk_update_categories_status_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\BulkUpdateCategoriesStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkUpdateCategoriesStatusCommand - - prestashop.adapter.category.command_handler.bulk_enable_categories_status_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\BulkUpdateCategoriesStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkEnableCategoriesCommand - - prestashop.adapter.category.command_handler.bulk_disable_categories_status_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\BulkUpdateCategoriesStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDisableCategoriesCommand - - prestashop.adapter.category.command_handler.set_category_is_enabled_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\SetCategoryIsEnabledHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\SetCategoryIsEnabledCommand - - prestashop.adapter.category.command_handler.delete_category_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\DeleteCategoryHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCommand - - prestashop.adapter.category.command_handler.bulk_delete_categories_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\BulkDeleteCategoriesHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\BulkDeleteCategoriesCommand - - prestashop.adapter.category.command_handler.add_category_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\AddCategoryHandler - public: true - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Category\Command\AddCategoryCommand } - - prestashop.adapter.category.command_handler.add_root_category_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\AddRootCategoryHandler - arguments: - - '@prestashop.adapter.legacy.configuration' - public: true - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\AddRootCategoryCommand - - prestashop.adapter.category.command_handler.edit_root_category_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\EditRootCategoryHandler - public: true - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\EditRootCategoryCommand - - prestashop.adapter.category.command_handler.edit_category_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\EditCategoryHandler - public: true - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Category\Command\EditCategoryCommand } - - prestashop.adapter.category.query_handler.get_category_for_editing: - class: PrestaShop\PrestaShop\Adapter\Category\QueryHandler\GetCategoryForEditingHandler - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryForEditing } - - prestashop.adapter.category.command_handler.delete_category_cover_image_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\DeleteCategoryCoverImageHandler - arguments: - - '@filesystem' - - '@prestashop.adapter.legacy.configuration' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryCoverImageCommand - - prestashop.adapter.category.command_handler.delete_category_menu_thumbnail_image_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\DeleteCategoryMenuThumbnailImageHandler - arguments: - - '@filesystem' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\DeleteCategoryMenuThumbnailImageCommand - - prestashop.adapter.category.command_handler.update_category_position_handler: - class: PrestaShop\PrestaShop\Adapter\Category\CommandHandler\UpdateCategoryPositionHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Command\UpdateCategoryPositionCommand - - prestashop.adapter.category.command_handler.get_category_status_handler: - class: PrestaShop\PrestaShop\Adapter\Category\QueryHandler\GetCategoryIsEnabledHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Category\Query\GetCategoryIsEnabled diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/cms_page.yml b/src/PrestaShopBundle/Resources/config/services/adapter/cms_page.yml deleted file mode 100644 index ad15bb12..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/cms_page.yml +++ /dev/null @@ -1,60 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.cms_page.command_handler.bulk_disable_cms_page: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\BulkDisableCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDisableCmsPageCommand - - prestashop.adapter.cms_page.command_handler.bulk_enable_cms_page: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\BulkEnableCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkEnableCmsPageCommand - - prestashop.adapter.cms_page.command_handler.toggle_cms_page_status: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\ToggleCmsPageStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\ToggleCmsPageStatusCommand - - prestashop.adapter.cms_page.query_handler.get_cms_category_id_for_redirection: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\QueryHandler\GetCmsCategoryIdForRedirectionHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsCategoryIdForRedirection - - prestashop.adapter.cms_page.command_handler.delete_cms_page: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\DeleteCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\DeleteCmsPageCommand - - prestashop.adapter.cms_page.command_handler.bulk_delete_cms_page: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\BulkDeleteCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\BulkDeleteCmsPageCommand - - prestashop.adapter.cms_page.command_handler.add_cms_page_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\AddCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\AddCmsPageCommand - - prestashop.adapter.cms_page.command_handler.edit_cms_page_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\CommandHandler\EditCmsPageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Command\EditCmsPageCommand - - prestashop.adapter.cms_page.query_handler.get_cms_page_for_editing_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\Page\QueryHandler\GetCmsPageForEditingHandler - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().link" - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPage\Query\GetCmsPageForEditing diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/cms_page_category.yml b/src/PrestaShopBundle/Resources/config/services/adapter/cms_page_category.yml deleted file mode 100644 index 89e28b9d..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/cms_page_category.yml +++ /dev/null @@ -1,94 +0,0 @@ -services: - _defaults: - public: true - -# Command handlers - - prestashop.adapter.cms_page_category.command_handler.abstract_cms_page_category_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\AbstractCmsPageCategoryHandler - abstract: true - arguments: - - '@validator' - - prestashop.adapter.cms_page_category.command_handler.delete_cms_page_category_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\DeleteCmsPageCategoryHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\DeleteCmsPageCategoryCommand - - prestashop.adapter.cms_page_category.command_handler.toggle_cms_page_category_status_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\ToggleCmsPageCategoryStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\ToggleCmsPageCategoryStatusCommand - - prestashop.adapter.cms_page_category.command_handler.bulk_delete_cms_page_category_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\BulkDeleteCmsPageCategoryHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDeleteCmsPageCategoryCommand - - prestashop.adapter.cms_page.command_handler.bulk_enable_cms_page_category_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\BulkEnableCmsPageCategoryHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkEnableCmsPageCategoryCommand - - prestashop.adapter.cms_page.command_handler.bulk_disable_cms_page_category_handler: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\BulkDisableCmsPageCategoryHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\BulkDisableCmsPageCategoryCommand - - prestashop.adapter.cms_page.command_handler.add_cms_page_category_handler: - class: 'PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\AddCmsPageCategoryHandler' - parent: 'prestashop.adapter.cms_page_category.command_handler.abstract_cms_page_category_handler' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\AddCmsPageCategoryCommand - public: true - - prestashop.adapter.cms_page.command_handler.edit_cms_page_category_handler: - class: 'PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CommandHandler\EditCmsPageCategoryHandler' - parent: 'prestashop.adapter.cms_page_category.command_handler.abstract_cms_page_category_handler' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Command\EditCmsPageCategoryCommand - public: true - - # Query handlers - - prestashop.adapter.cms_page.query_handler.get_cms_page_categories_for_breadcrumbs: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler\GetCmsPageCategoriesForBreadcrumbHandler - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoriesForBreadcrumb - - prestashop.adapter.cms_page.query_handler.get_cms_page_categories_for_redirection: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler\GetCmsPageParentCategoryIdForRedirectionHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageParentCategoryIdForRedirection - - prestashop.adapter.cms_page.query_handler.get_cms_page_category_for_editing: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler\GetCmsPageCategoryForEditingHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryForEditing - - prestashop.adapter.cms_page.categories_provider: - class: 'PrestaShop\PrestaShop\Adapter\CMS\PageCategory\CategoriesProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.adapter.cms_page.query_handler.get_cms_page_category_name_for_listing: - class: PrestaShop\PrestaShop\Adapter\CMS\PageCategory\QueryHandler\GetCmsPageCategoryNameForListingHandler - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@request_stack' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CmsPageCategory\Query\GetCmsPageCategoryNameForListing diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/common.yml b/src/PrestaShopBundle/Resources/config/services/adapter/common.yml deleted file mode 100644 index bba792b4..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/common.yml +++ /dev/null @@ -1,28 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.legacy.configuration: - class: PrestaShop\PrestaShop\Adapter\Configuration - - prestashop.adapter.tools: - class: PrestaShop\PrestaShop\Adapter\Tools - - prestashop.adapter.legacy.context: - class: PrestaShop\PrestaShop\Adapter\LegacyContext - arguments: - - "%mail_themes_uri%" - - '@prestashop.adapter.tools' - - prestashop.adapter.environment: - class: PrestaShop\PrestaShop\Adapter\Environment - arguments: - - !php/const _PS_MODE_DEV_ - - prestashop.adapter.validate: - class: PrestaShop\PrestaShop\Adapter\Validate - - prestashop.adapter.context_state_manager: - class: PrestaShop\PrestaShop\Adapter\ContextStateManager - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext()' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/configuration.yml b/src/PrestaShopBundle/Resources/config/services/adapter/configuration.yml deleted file mode 100644 index e9576c23..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/configuration.yml +++ /dev/null @@ -1,10 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.configuration.command_handler.switch_debug_mode_handler: - class: 'PrestaShop\PrestaShop\Adapter\Configuration\CommandHandler\SwitchDebugModeHandler' - arguments: - - '@prestashop.adapter.debug_mode' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Configuration\Command\SwitchDebugModeCommand } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/contact.yml b/src/PrestaShopBundle/Resources/config/services/adapter/contact.yml deleted file mode 100644 index f1074e89..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/contact.yml +++ /dev/null @@ -1,30 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.contact.repository: - class: 'PrestaShop\PrestaShop\Adapter\Support\ContactRepository' - - prestashop.adapter.contact.deleter: - class: 'PrestaShop\PrestaShop\Adapter\Support\ContactDeleter' - - prestashop.adapter.contact.query_handler.get_contact_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Contact\QueryHandler\GetContactForEditingHandler' - arguments: - - '@prestashop.bundle.form.data_transformer.string_array_to_integer_array' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Contact\Query\GetContactForEditing' } - - prestashop.adapter.contact.command_handler.edit_contact: - class: 'PrestaShop\PrestaShop\Adapter\Contact\CommandHandler\EditContactHandler' - arguments: - - '@validator' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Contact\Command\EditContactCommand' } - - prestashop.adapter.contact.command_handler.add_contact: - class: 'PrestaShop\PrestaShop\Adapter\Contact\CommandHandler\AddContactHandler' - arguments: - - '@validator' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Contact\Command\AddContactCommand' } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/context.yml b/src/PrestaShopBundle/Resources/config/services/adapter/context.yml deleted file mode 100644 index 168632f4..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/context.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - _defaults: - public: true - - #SECURITY - #@todo: is this service used? - prestashop.adapter.security.admin: - class: "%AdapterSecurityAdminClass%" - arguments: - - "@prestashop.adapter.legacy.context" - - "@security.token_storage" - - "@prestashop.security.admin.provider" - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/country.yml b/src/PrestaShopBundle/Resources/config/services/adapter/country.yml deleted file mode 100644 index 95f0b0fc..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/country.yml +++ /dev/null @@ -1,22 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.country.query_handler.get_country_required_fields: - class: 'PrestaShop\PrestaShop\Adapter\Country\QueryHandler\GetCountryRequiredFieldsHandler' - arguments: - - '@prestashop.adapter.country.country_required_fields_provider' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Country\Query\GetCountryRequiredFields' - - prestashop.adapter.country.country_zip_code_requirements_provider: - class: 'PrestaShop\PrestaShop\Adapter\Country\CountryZipCodeRequirementsProvider' - arguments: - - '@prestashop.adapter.legacy.context' - - '@prestashop.core.domain.country.zip_code_format_resolver' - - prestashop.adapter.country.country_required_fields_provider: - class: 'PrestaShop\PrestaShop\Adapter\Country\CountryRequiredFieldsProvider' - arguments: - - '@prestashop.adapter.data_provider.country' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/credit_slip.yml b/src/PrestaShopBundle/Resources/config/services/adapter/credit_slip.yml deleted file mode 100644 index 14fa44bd..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/credit_slip.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.credit_slip.query_handler.get_credit_slip_ids_by_date_range_handler: - class: 'PrestaShop\PrestaShop\Adapter\CreditSlip\QueryHandler\GetCreditSlipIdsByDateRangeHandler' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CreditSlip\Query\GetCreditSlipIdsByDateRange diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/currency.yml b/src/PrestaShopBundle/Resources/config/services/adapter/currency.yml deleted file mode 100644 index fccb6b9e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/currency.yml +++ /dev/null @@ -1,109 +0,0 @@ -services: - _defaults: - public: true - - # Command validator - prestashop.adapter.currency.command_handler.command_validator: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\CurrencyCommandValidator' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - '@prestashop.adapter.data_provider.currency' - - '@=service("prestashop.adapter.legacy.configuration").get("PS_CURRENCY_DEFAULT")' - - # Command handlers - - prestashop.adapter.currency.command_handler.toggle_currency_status: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\ToggleCurrencyStatusHandler' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("PS_CURRENCY_DEFAULT")' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleCurrencyStatusCommand' } - - prestashop.adapter.currency.command_handler.delete_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\DeleteCurrencyHandler' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("PS_CURRENCY_DEFAULT")' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\DeleteCurrencyCommand' } - - prestashop.adapter.currency.command_handler.create_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\AddOfficialCurrencyHandler' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - "@=service('prestashop.core.admin.lang.repository').findAll()" - - "@prestashop.adapter.currency.command_handler.command_validator" - - '@prestashop.adapter.data_provider.currency' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddCurrencyCommand' } - - prestashop.adapter.currency.command_handler.create_unofficial_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\AddUnofficialCurrencyHandler' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - "@=service('prestashop.core.admin.lang.repository').findAll()" - - "@prestashop.adapter.currency.command_handler.command_validator" - - '@prestashop.adapter.data_provider.currency' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\AddUnofficialCurrencyCommand' } - - prestashop.adapter.currency.command_handler.update_official_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\EditOfficialCurrencyHandler' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - "@=service('prestashop.core.admin.lang.repository').findAll()" - - "@prestashop.adapter.currency.command_handler.command_validator" - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditCurrencyCommand' } - - prestashop.adapter.currency.command_handler.update_unofficial_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\EditUnofficialCurrencyHandler' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - "@=service('prestashop.core.admin.lang.repository').findAll()" - - "@prestashop.adapter.currency.command_handler.command_validator" - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\EditUnofficialCurrencyCommand' } - - prestashop.adapter.currency.command_handler.update_exchange_rates: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\RefreshExchangeRatesHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\RefreshExchangeRatesCommand' } - - prestashop.adapter.currency.command_handler.update_live_exchange_rates: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CommandHandler\ToggleExchangeRateAutomatizationHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.legacy.context").getContext().shop' - - '@prestashop.adapter.shop.shop_url' - - '@translator' - - '@=service("prestashop.adapter.data_provider.module").isInstalled("cronjobs")' - - '@=service("prestashop.adapter.legacy.context").getAdminBaseUrl()' - - '%database_prefix%' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Command\ToggleExchangeRateAutomatizationCommand' } - - - # Query handlers - - prestashop.adapter.currency.query_handler.get_currency_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Currency\QueryHandler\GetCurrencyForEditingHandler' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyForEditing' } - - prestashop.adapter.currency.query_handler.get_currency_exchange_rate: - class: 'PrestaShop\PrestaShop\Adapter\Currency\QueryHandler\GetCurrencyExchangeRateHandler' - arguments: - - '@prestashop.core.exchange_rate.provider' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetCurrencyExchangeRate' } - - prestashop.adapter.currency.query_handler.get_reference_currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\QueryHandler\GetReferenceCurrencyHandler' - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - '@prestashop.core.query_bus' - - '@=service("prestashop.core.admin.lang.repository").findAll()' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Currency\Query\GetReferenceCurrency' } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/customer.yml b/src/PrestaShopBundle/Resources/config/services/adapter/customer.yml deleted file mode 100644 index 5a7bd90b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/customer.yml +++ /dev/null @@ -1,115 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.customer.query_handler.get_customer_for_viewing: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetCustomerForViewingHandler' - arguments: - - '@translator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().link" - - "@prestashop.core.localization.locale.context_locale" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForViewing' - - prestashop.adapter.customer.command_handler.set_private_note_about_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\SetPrivateNoteAboutCustomerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetPrivateNoteAboutCustomerCommand' - - prestashop.adapter.customer.command_handler.transform_guest_to_customer: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\TransformGuestToCustomerHandler' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\TransformGuestToCustomerCommand' - - prestashop.adapter.customer.command_handler.set_required_fields_for_customer: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\SetRequiredFieldsForCustomerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\SetRequiredFieldsForCustomerCommand' - - prestashop.adapter.customer.query_handler.get_required_fields_for_customer: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetRequiredFieldsForCustomerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetRequiredFieldsForCustomer' - - prestashop.adapter.customer.command_handler.add_customer: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\AddCustomerHandler' - arguments: - - '@prestashop.core.crypto.hashing' - - '@=service("prestashop.adapter.legacy.configuration").get("_COOKIE_KEY_")' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\AddCustomerCommand' - - prestashop.adapter.customer.query_handler.get_customer_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetCustomerForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForEditing' - - prestashop.adapter.customer.command_handler.edit_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\EditCustomerHandler' - arguments: - - '@prestashop.core.crypto.hashing' - - '@=service("prestashop.adapter.legacy.configuration").get("_COOKIE_KEY_")' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\EditCustomerCommand' - - prestashop.adapter.customer.command_handler.bulk_enable_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\BulkEnableCustomerHandler' - tags: - - { name: tactician.handler, command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkEnableCustomerCommand' } - - prestashop.adapter.customer.command_handler.bulk_disable_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\BulkDisableCustomerHandler' - tags: - - { name: tactician.handler, command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDisableCustomerCommand' } - - prestashop.adapter.customer.command_handler.delete_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\DeleteCustomerHandler' - tags: - - { name: tactician.handler, command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\DeleteCustomerCommand' } - - prestashop.adapter.customer.command_handler.bulk_delete_customer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CommandHandler\BulkDeleteCustomerHandler' - tags: - - { name: tactician.handler, command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Command\BulkDeleteCustomerCommand' } - - prestashop.adapter.customer.query_handler.search_customers: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\SearchCustomersHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\SearchCustomers' - - prestashop.adapter.customer.query_handler.get_customer_carts_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetCustomerCartsHandler' - arguments: - - "@prestashop.core.localization.locale.context_locale" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerCarts' - - prestashop.adapter.customer.query_handler.get_customer_orders_handler: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetCustomerOrdersHandler' - arguments: - - "@prestashop.core.localization.locale.context_locale" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerOrders' - - prestashop.adapter.customer.query_handler.get_customer_for_address_creation: - class: 'PrestaShop\PrestaShop\Adapter\Customer\QueryHandler\GetCustomerForAddressCreationHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Customer\Query\GetCustomerForAddressCreation' - - prestashop.adapter.customer.customer_data_source: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CustomerDataSource' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/customer_message.yml b/src/PrestaShopBundle/Resources/config/services/adapter/customer_message.yml deleted file mode 100644 index 17e798c3..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/customer_message.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.customer_message.command_handler.add_order_customer_message: - class: PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler\AddOrderCustomerMessageHandler - arguments: - - '@translator' - - '@validator' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@=service("prestashop.adapter.legacy.context").getContext().employee.id' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CustomerMessage\Command\AddOrderCustomerMessageCommand diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/customer_service.yml b/src/PrestaShopBundle/Resources/config/services/adapter/customer_service.yml deleted file mode 100644 index 102a4486..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/customer_service.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.customer_service.query_handler.get_customer_thread_for_viewing_handler: - class: 'PrestaShop\PrestaShop\Adapter\CustomerService\QueryHandler\GetCustomerThreadForViewingHandler' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext()' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerThreadForViewing' - - prestashop.adapter.customer_service.query_handler.get_customer_service_signature_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\CustomerService\QueryHandler\GetCustomerServiceSignatureHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\CustomerService\Query\GetCustomerServiceSignature' - - prestashop.adapter.customer_service.command_handler.forward_customer_thread_handler: - class: 'PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler\ForwardCustomerThreadHandler' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext()' - - '@prestashop.adapter.legacy.configuration' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ForwardCustomerThreadCommand' - - prestashop.adapter.customer_service.command_handler.reply_to_customer_thread_handler: - class: 'PrestaShop\PrestaShop\Adapter\CustomerService\CommandHandler\ReplyToCustomerThreadHandler' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext()' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\ReplyToCustomerThreadCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/data_configuration.yml b/src/PrestaShopBundle/Resources/config/services/adapter/data_configuration.yml deleted file mode 100644 index bd9b8a35..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/data_configuration.yml +++ /dev/null @@ -1,258 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.product_general.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Product\GeneralConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.product_pagination.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Product\PaginationConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.product_page.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Product\PageConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.product_stock.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Product\StockConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.customer.customer_configuration: - class: 'PrestaShop\PrestaShop\Adapter\Customer\CustomerConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.order_general.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Order\GeneralConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.order_gift.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Order\GiftOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.debug_mode.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Debug\DebugModeConfiguration' - arguments: - - '@prestashop.adapter.debug_mode' - - '@prestashop.adapter.legacy.configuration' - - '%ps_config_dir%/defines.inc.php' - - prestashop.adapter.optional_features.configuration: - class: 'PrestaShop\PrestaShop\Adapter\OptionalFeatures\OptionalFeaturesConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.combination_feature' - - '@prestashop.adapter.feature.feature' - - '@prestashop.adapter.group.feature' - - prestashop.adapter.ccc.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Cache\CombineCompressCacheConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@filesystem' - - '@prestashop.adapter.tools' - - '%themes_dir%' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.theme_name' - - prestashop.adapter.media_servers.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Media\MediaServerConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.caching.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Cache\CachingConfiguration' - arguments: - - '@prestashop.adapter.memcache_server.manager' - - '@prestashop.adapter.php_parameters' - - '@prestashop.adapter.cache.clearer.symfony_cache_clearer' - - '%ps_cache_enable%' - - '%ps_caching%' - - prestashop.adapter.general.configuration: - class: 'PrestaShop\PrestaShop\Adapter\GeneralConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.maintenance.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Shop\MaintenanceConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.preferences.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Preferences\PreferencesConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.upload_quota.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Upload\UploadQuotaConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.notifications.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Admin\NotificationsConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.smarty_cache.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Smarty\SmartyCacheConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.logs.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Configuration\LogsConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.order.delivery.slip.options.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Order\Delivery\SlipOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.order.delivery.slip.pdf.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Order\Delivery\SlipPdfConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.order.invoice_options.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Invoice\InvoiceOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.data_provider.language: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguageDataProvider' - - prestashop.adapter.language.activator: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguageActivator' - - prestashop.adapter.language.language_pack_installer: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguagePackInstaller' - arguments: - - '@translator' - - '@prestashop.core.foundation.version' - - prestashop.adapter.language.validator: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguageValidator' - - prestashop.adapter.language.copier: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguageCopier' - arguments: - - '@prestashop.adapter.data_provider.language' - - '@translator' - - '@filesystem' - - '@=service("prestashop.core.addon.theme.repository").getListAsCollection()' - - prestashop.adapter.manager.currency: - class: 'PrestaShop\PrestaShop\Adapter\Currency\CurrencyManager' - - prestashop.adapter.localization.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Localization\LocalizationConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.language.activator' - - '@prestashop.adapter.manager.currency' - - '@prestashop.adapter.admin.data_provider.module' - - prestashop.adapter.local_units.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Localization\LocalUnitsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.localization_advanced.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Localization\AdvancedConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.geolocation_by_ip_address.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Geolocation\GeolocationByIpAddressConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.geolocation_ip_address_whitelist.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Geolocation\GeolocationIpAddressWhitelistConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.geolocation_options.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Geolocation\GeolocationOptionsConfiguration' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.payment_module_preferences.configuration: - class: 'PrestaShop\PrestaShop\Core\Payment\PaymentModulePreferencesConfiguration' - arguments: - - '@prestashop.adapter.module.payment_module_provider' - - '@prestashop.core.module.configuration.payment_restrictions_configurator' - - prestashop.adapter.shipping_preferences.handling_configuration: - class: 'PrestaShop\PrestaShop\Adapter\Carrier\HandlingConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.shipping_preferences.carrier_options_configuration: - class: 'PrestaShop\PrestaShop\Adapter\Carrier\CarrierOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.email.email_configurator: - class: 'PrestaShop\PrestaShop\Core\Email\EmailDataConfigurator' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.email.smtp_configurator: - class: 'PrestaShop\PrestaShop\Core\Email\SmtpDataConfigurator' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.webservice.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\WebserviceConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.meta.set_up_urls.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Meta\SetUpUrlsDataConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.file.htaccess_file_generator' - - '@translator' - - prestashop.adapter.meta.shop_url.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Meta\ShopUrlDataConfiguration' - arguments: - - '@=service("prestashop.adapter.shop.shop_url").getMainShopUrl()' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.file.htaccess_file_generator' - - prestashop.adapter.meta.url_schema.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Meta\UrlSchemaDataConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.data_provider.default_route").getRules()' - - prestashop.adapter.meta.seo_options.configuration: - class: 'PrestaShop\PrestaShop\Adapter\Meta\SEOOptionsDataConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.team.employee.configuration.employee_options_configuration: - class: 'PrestaShop\PrestaShop\Core\Team\Employee\Configuration\EmployeeOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.team.employee.configuration.options_checker' - - prestashop.core.tax.tax_options_configuration: - class: 'PrestaShop\PrestaShop\Core\Tax\TaxOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.tax.ecotax.ecotax_resetter' - - prestashop.core.mail_theme.configuration: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\MailThemeConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.mail_template.theme_catalog' - - prestashop.core.merchandise_return.configuration.merchandise_return_options_configuration: - class: 'PrestaShop\PrestaShop\Core\MerchandiseReturn\Configuration\MerchandiseReturnOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.credit_slip.credit_slip_options.configuration: - class: 'PrestaShop\PrestaShop\Core\CreditSlip\CreditSlipOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/data_provider.yml b/src/PrestaShopBundle/Resources/config/services/adapter/data_provider.yml deleted file mode 100644 index 4a6f0a6b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/data_provider.yml +++ /dev/null @@ -1,117 +0,0 @@ -imports: - - { resource: ./data_provider_common.yml } - -services: - _defaults: - public: true - - prestashop.adapter.admin.data_provider.addons: - class: PrestaShop\PrestaShop\Adapter\Addons\AddonsDataProvider - decorates: prestashop.core.admin.data_provider.addons_interface - arguments: - - '@prestashop.addons.client_api' - - '@prestashop.module.zip.manager' - properties: - cacheDir: "%kernel.cache_dir%" - - prestashop.adapter.admin.data_provider.module: - class: PrestaShop\PrestaShop\Adapter\Module\AdminModuleDataProvider - arguments: - - "@translator" - - "@logger" - - "@prestashop.core.admin.data_provider.addons_interface" - - "@prestashop.categories_provider" - - "@prestashop.adapter.data_provider.module" - - "@doctrine.cache.provider" - - "@=service('prestashop.adapter.legacy.context').getContext().employee" - calls: - - [ setRouter, ['@router']] - decorates: prestashop.core.admin.data_provider.module_interface - public: false - - prestashop.adapter.data_provider.supplier: - class: PrestaShop\PrestaShop\Adapter\Supplier\SupplierDataProvider - - prestashop.adapter.data_provider.warehouse: - class: PrestaShop\PrestaShop\Adapter\Warehouse\WarehouseDataProvider - - prestashop.adapter.data_provider.category: - class: PrestaShop\PrestaShop\Adapter\Category\CategoryDataProvider - arguments: ["@=service('prestashop.adapter.legacy.context')"] - - prestashop.adapter.data_provider.group: - class: PrestaShop\PrestaShop\Adapter\Group\GroupDataProvider - - prestashop.adapter.data_provider.tax: - class: PrestaShop\PrestaShop\Adapter\Tax\TaxRuleDataProvider - - prestashop.adapter.data_provider.manufacturer: - class: PrestaShop\PrestaShop\Adapter\Manufacturer\ManufacturerDataProvider - - prestashop.adapter.data_provider.product: - class: PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider - - prestashop.adapter.data_provider.attachment: - class: PrestaShop\PrestaShop\Adapter\Product\AttachmentDataProvider - - prestashop.adapter.data_provider.feature: - class: PrestaShop\PrestaShop\Adapter\Feature\FeatureDataProvider - - prestashop.adapter.data_provider.carrier: - class: PrestaShop\PrestaShop\Adapter\Carrier\CarrierDataProvider - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.data_provider.order_invoice: - class: PrestaShop\PrestaShop\Adapter\Invoice\OrderInvoiceDataProvider - - prestashop.adapter.data_provider.order_state: - class: PrestaShop\PrestaShop\Adapter\OrderState\OrderStateDataProvider - - prestashop.adapter.data_provider.attribute: - class: PrestaShop\PrestaShop\Adapter\Attribute\AttributeDataProvider - - prestashop.adapter.data_provider.customer: - class: PrestaShop\PrestaShop\Adapter\Customer\CustomerDataProvider - - prestashop.adapter.data_provider.combination: - class: PrestaShop\PrestaShop\Adapter\CombinationDataProvider - arguments: - - "@prestashop.core.localization.locale.context_locale" - - prestashop.adapter.data_provider.cms: - class: PrestaShop\PrestaShop\Adapter\CMS\CMSDataProvider - - prestashop.adapter.data_provider.pack: - class: PrestaShop\PrestaShop\Adapter\Pack\PackDataProvider - - prestashop.adapter.data_provider.tab: - class: PrestaShop\PrestaShop\Adapter\Tab\TabDataProvider - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().employee.id_profile' - - '@=service("prestashop.adapter.legacy.configuration").getInt("_PS_ADMIN_PROFILE_")' - - prestashop.adapter.data_provider.profile: - class: PrestaShop\PrestaShop\Adapter\Profile\ProfileDataProvider - arguments: - - '@prestashop.adapter.data_provider.employee' - - '@=service("prestashop.adapter.legacy.configuration").getInt("_PS_ADMIN_PROFILE_")' - - prestashop.adapter.data_provider.module: - class: PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider - arguments: ["@prestashop.adapter.legacy.logger", "@translator", "@doctrine.orm.entity_manager"] - calls: - - [ "setEmployeeId", ["@=service('prestashop.adapter.legacy.context').getContext().employee?service('prestashop.adapter.legacy.context').getContext().employee.id:0"]] - - prestashop.categories_provider: - class: PrestaShopBundle\Service\DataProvider\Admin\CategoriesProvider - arguments: - - "%prestashop.addons.categories%" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.theme_name?service('prestashop.core.addon.theme.repository').getInstanceByName(service('prestashop.adapter.legacy.context').getContext().shop.theme_name).getModulesToEnable():[]" - - prestashop.adapter.data_provider.default_route: - class: PrestaShop\PrestaShop\Adapter\Routes\DefaultRouteProvider - - prestashop.adapter.data_provider.employee: - class: PrestaShop\PrestaShop\Adapter\Employee\ContextEmployeeProvider - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().employee' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/data_provider_common.yml b/src/PrestaShopBundle/Resources/config/services/adapter/data_provider_common.yml deleted file mode 100644 index 53d96bc9..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/data_provider_common.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.data_provider.country: - class: PrestaShop\PrestaShop\Adapter\Country\CountryDataProvider - - prestashop.adapter.data_provider.currency: - class: PrestaShop\PrestaShop\Adapter\Currency\CurrencyDataProvider - arguments: - - "@prestashop.adapter.legacy.configuration" - - "@=service('prestashop.adapter.legacy.context').getContext().shop?service('prestashop.adapter.legacy.context').getContext().shop.id" diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/email.yml b/src/PrestaShopBundle/Resources/config/services/adapter/email.yml deleted file mode 100644 index 2210296e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/email.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.email.email_configuration_tester: - class: 'PrestaShop\PrestaShop\Adapter\Email\EmailConfigurationTester' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@translator' - - prestashop.adapter.email.email_log_eraser: - class: 'PrestaShop\PrestaShop\Adapter\Email\EmailLogEraser' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/employee.yml b/src/PrestaShopBundle/Resources/config/services/adapter/employee.yml deleted file mode 100644 index 6fc926c8..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/employee.yml +++ /dev/null @@ -1,77 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.profile.employee.command_handler.toggle_employee_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\ToggleEmployeeStatusHandler' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\ToggleEmployeeStatusCommand } - - prestashop.adapter.profile.employee.command_handler.bulk_update_employee_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\BulkUpdateEmployeeStatusHandler' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkUpdateEmployeeStatusCommand } - - prestashop.adapter.profile.employee.command_handler.delete_employee_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\DeleteEmployeeHandler' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\DeleteEmployeeCommand } - - prestashop.adapter.profile.employee.command_handler.bulk_delete_employee_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\BulkDeleteEmployeeHandler' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\BulkDeleteEmployeeCommand } - - prestashop.adapter.employee.query_handler.get_employee_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\QueryHandler\GetEmployeeForEditingHandler' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeForEditing } - - prestashop.adapter.employee.form_access_checker: - class: 'PrestaShop\PrestaShop\Adapter\Employee\EmployeeFormAccessChecker' - arguments: - - '@prestashop.adapter.data_provider.employee' - - '@prestashop.adapter.employee.data_provider' - - '@prestashop.core.admin.tab.repository' - - prestashop.adapter.employee.command_handler.add_employee_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\AddEmployeeHandler' - arguments: - - '@prestashop.core.crypto.hashing' - - '@prestashop.core.employee.profile_access_checker' - - '@prestashop.adapter.data_provider.employee' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\AddEmployeeCommand } - - prestashop.adapter.employee.command_handler.edit_employee_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\Employee\CommandHandler\EditEmployeeHandler' - arguments: - - '@prestashop.core.crypto.hashing' - - '@prestashop.core.employee.profile_access_checker' - - '@prestashop.adapter.data_provider.employee' - - '@prestashop.adapter.legacy.context' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Command\EditEmployeeCommand } - - prestashop.adapter.employee.avatar_provider: - class: 'PrestaShop\PrestaShop\Adapter\Employee\AvatarProvider' - arguments: - - '@prestashop.adapter.tools' - - prestashop.adapter.employee.data_provider: - class: 'PrestaShop\PrestaShop\Adapter\Employee\EmployeeDataProvider' - - prestashop.adapter.employee.navigation_menu_toggler: - class: 'PrestaShop\PrestaShop\Adapter\Employee\NavigationMenuToggler' - arguments: - - '@prestashop.adapter.legacy.context' - - prestashop.adapter.employee.form_language_changer: - class: 'PrestaShop\PrestaShop\Adapter\Employee\FormLanguageChanger' - arguments: - - '@prestashop.adapter.legacy.context' - - prestashop.adapter.employee.query_handler.get_employee_email_by_id_handler: - class: PrestaShop\PrestaShop\Adapter\Profile\Employee\QueryHandler\GetEmployeeEmailByIdHandler - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Employee\Query\GetEmployeeEmailById } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/feature.yml b/src/PrestaShopBundle/Resources/config/services/adapter/feature.yml deleted file mode 100644 index 0b39e2b9..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/feature.yml +++ /dev/null @@ -1,18 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.feature.command_handler.add_feature_handler: - class: PrestaShop\PrestaShop\Adapter\Feature\CommandHandler\AddFeatureHandler - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Feature\Command\AddFeatureCommand } - - prestashop.adapter.feature.command_handler.edit_feature_handler: - class: PrestaShop\PrestaShop\Adapter\Feature\CommandHandler\EditFeatureHandler - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Feature\Command\EditFeatureCommand } - - prestashop.adapter.feature.query_handler.get_feature_for_editing: - class: PrestaShop\PrestaShop\Adapter\Feature\QueryHandler\GetFeatureForEditingHandler - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Feature\Query\GetFeatureForEditing } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/form.yml b/src/PrestaShopBundle/Resources/config/services/adapter/form.yml deleted file mode 100644 index ecb72281..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/form.yml +++ /dev/null @@ -1,64 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.form.choice_provider.profile_by_id_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\ProfileByIdChoiceProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.adapter.form.choice_provider.shop_tree_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\ShopTreeChoiceProvider' - - prestashop.adapter.form.choice_provider.category_tree_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\CategoryTreeChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.category' - - '@=service("prestashop.adapter.data_provider.category").getRootCategory().id' - - false - - prestashop.adapter.form.choice_provider.gender_by_id_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\GenderByIdChoiceProvider' - - prestashop.adapter.form.choice_provider.group_by_id_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\GroupByIdChoiceProvider' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.adapter.form.choice_provider.risk_by_id_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\RiskByIdChoiceProvider' - - prestashop.adapter.form.choice_provider.resources_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\ResourcesChoiceProvider' - - prestashop.adapter.form.choice_provider.manufacturer_name_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\ManufacturerNameByIdChoiceProvider' - arguments: - - '@=service("prestashop.adapter.data_provider.manufacturer").getManufacturers()' - - prestashop.adapter.form.choice_provider.country_state_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\CountryStateByIdChoiceProvider' - - prestashop.adapter.form.choice_provider.order_countries: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\OrderCountriesChoiceProvider' - - prestashop.adapter.form.choice_provider.order_invoice_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\OrderInvoiceByIdChoiceProvider' - arguments: - - '@prestashop.core.localization.locale.context_locale' - - prestashop.adapter.form.choice_provider.currency_symbol_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\CurrencySymbolByIdChoiceProvider' - - prestashop.adapter.form.choice_provider.installed_payment_modules: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\InstalledPaymentModulesChoiceProvider' - - prestashop.adapter.form.choice.provider.carrier_for_order_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\CarrierForOrderChoiceProvider' - - prestashop.adapter.form.choice_provider.shop_name_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\ShopNameByIdChoiceProvider' - - prestashop.adapter.form.choice_provider.employee_name_by_id: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\EmployeeNameByIdChoiceProvider' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/grid.yml b/src/PrestaShopBundle/Resources/config/services/adapter/grid.yml deleted file mode 100644 index 475f544a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/grid.yml +++ /dev/null @@ -1,19 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.grid.search.factory.search_criteria_with_category_parent_id: - class: 'PrestaShop\PrestaShop\Adapter\Grid\Search\Factory\SearchCriteriaWithCategoryParentIdFilterFactory' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.shop.context' - - '@prestashop.adapter.feature.multistore' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id_category' - - '@request_stack' - - # Action accessibility checkers - prestashop.adapter.grid.action.row.accessibility_checker.category_for_view: - class: 'PrestaShop\PrestaShop\Adapter\Grid\Action\Row\AccessibilityChecker\CategoryForViewAccessibilityChecker' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/group.yml b/src/PrestaShopBundle/Resources/config/services/adapter/group.yml deleted file mode 100644 index 59510304..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/group.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.group.provider.default_groups_provider: - class: 'PrestaShop\PrestaShop\Adapter\Group\Provider\DefaultGroupsProvider' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/image.yml b/src/PrestaShopBundle/Resources/config/services/adapter/image.yml deleted file mode 100644 index bcb83987..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/image.yml +++ /dev/null @@ -1,20 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.image.uploader.category_cover_image_uploader: - class: 'PrestaShop\PrestaShop\Adapter\Image\Uploader\CategoryCoverImageUploader' - - prestashop.adapter.image.uploader.category_thumbnail_image_uploader: - class: 'PrestaShop\PrestaShop\Adapter\Image\Uploader\CategoryThumbnailImageUploader' - - prestashop.adapter.image.uploader.category_menu_thumbnail_image_uploader: - class: 'PrestaShop\PrestaShop\Adapter\Image\Uploader\CategoryMenuThumbnailUploader' - arguments: - - '@prestashop.adapter.cache_clearer' - - prestashop.adapter.image.uploader.manufacturer_image_uploader: - class: 'PrestaShop\PrestaShop\Adapter\Image\Uploader\ManufacturerImageUploader' - - prestashop.adapter.image.uploader.supplier_image_uploader: - class: 'PrestaShop\PrestaShop\Adapter\Image\Uploader\SupplierImageUploader' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/import.yml b/src/PrestaShopBundle/Resources/config/services/adapter/import.yml deleted file mode 100644 index 643148e1..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/import.yml +++ /dev/null @@ -1,93 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.import.data_match_saver: - class: 'PrestaShop\PrestaShop\Adapter\Import\DataMatchSaver' - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.adapter.import.entity_deleter: - class: 'PrestaShop\PrestaShop\Adapter\Import\ImportEntityDeleter' - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.image.file_deleter' - - prestashop.adapter.import.excel_to_csv_converter: - class: 'PrestaShop\PrestaShop\Adapter\Converter\ExcelToCsvFileConverter' - arguments: - - '@filesystem' - - '@=service("prestashop.core.import.dir").getDir()' - - '@=service("prestashop.core.import.dir").getDir() ~ "csvfromexcel/"' - - prestashop.adapter.import.file_opener: - class: 'PrestaShop\PrestaShop\Adapter\Import\CsvFileOpener' - arguments: - - '@prestashop.adapter.import.excel_to_csv_converter' - - '@prestashop.core.import.dir' - - prestashop.adapter.import.handler.product: - class: 'PrestaShop\PrestaShop\Adapter\Import\Handler\ProductImportHandler' - arguments: - - '@prestashop.adapter.import.data_formatter' - - '@=service("prestashop.adapter.shop.context").getAllShopIds()' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@=service("prestashop.adapter.feature.multistore").isUsed()' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@translator' - - '@prestashop.adapter.legacy.logger' - - '@=service("prestashop.adapter.data_provider.employee").getId()' - - '@prestashop.adapter.database' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.getAddress()' - - '@prestashop.adapter.validate' - - '@prestashop.adapter.tools' - - '@prestashop.adapter.import.image_copier' - - prestashop.adapter.import.handler.category: - class: 'PrestaShop\PrestaShop\Adapter\Import\Handler\CategoryImportHandler' - arguments: - - '@prestashop.adapter.import.data_formatter' - - '@=service("prestashop.adapter.shop.context").getAllShopIds()' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@=service("prestashop.adapter.feature.multistore").isUsed()' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@translator' - - '@prestashop.adapter.legacy.logger' - - '@=service("prestashop.adapter.data_provider.employee").getId()' - - '@prestashop.adapter.database' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.validate' - - '@prestashop.adapter.import.image_copier' - - '@prestashop.adapter.tools' - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.adapter.import.handler_finder: - class: 'PrestaShop\PrestaShop\Adapter\Import\Handler\ImportHandlerFinder' - arguments: - - '@prestashop.adapter.import.handler.category' - - '@prestashop.adapter.import.handler.product' - - prestashop.adapter.import.data_formatter: - class: 'PrestaShop\PrestaShop\Adapter\Import\ImportDataFormatter' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.tools' - - prestashop.adapter.import.image_copier: - class: 'PrestaShop\PrestaShop\Adapter\Import\ImageCopier' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.tools' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@prestashop.core.hook.dispatcher' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/kpi.yml b/src/PrestaShopBundle/Resources/config/services/adapter/kpi.yml deleted file mode 100644 index 79393cc6..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/kpi.yml +++ /dev/null @@ -1,100 +0,0 @@ -services: - _defaults: - public: true - - # KPI implementations - prestashop.adapter.kpi.enabled_languages: - class: PrestaShop\PrestaShop\Adapter\Kpi\EnabledLanguagesKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminLanguages")' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "enabled_languages"})' - - prestashop.adapter.kpi.main_country: - class: PrestaShop\PrestaShop\Adapter\Kpi\MainCountryKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "main_country"})' - - prestashop.adapter.kpi.translations: - class: PrestaShop\PrestaShop\Adapter\Kpi\TranslationsKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "frontoffice_translations"})' - - prestashop.adapter.kpi.disabled_categories: - class: PrestaShop\PrestaShop\Adapter\Kpi\DisabledCategoriesKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "disabled_categories"})' - - prestashop.adapter.kpi.empty_categories: - class: PrestaShop\PrestaShop\Adapter\Kpi\EmptyCategoriesKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "empty_categories"})' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminTracking")' - - prestashop.adapter.kpi.top_category: - class: PrestaShop\PrestaShop\Adapter\Kpi\TopCategoryKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "top_category"})' - - "@=service('prestashop.adapter.legacy.context').getContext().employee.id_lang" - - prestashop.adapter.kpi.average_products_in_category: - class: PrestaShop\PrestaShop\Adapter\Kpi\AverageProductsInCategoryKpi - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "products_per_category"})' - - prestashop.adapter.kpi.most_common_customers_gender: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\MostCommonCustomersGenderKpi' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "customer_main_gender"})' - - prestashop.adapter.kpi.average_customer_age: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\AverageCustomerAgeKpi' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "avg_customer_age"})' - - prestashop.adapter.kpi.order_per_customer: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\OrdersPerCustomerKpi' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "orders_per_customer"})' - - prestashop.adapter.kpi.newsletter_registrations: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\NewsletterRegistrationsKpi' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.kpi_configuration' - - '@=service("prestashop.adapter.legacy.context").getAdminLink("AdminStats", true, {"ajax": 1, "action": "getKpi", "kpi": "newsletter_registrations"})' - - prestashop.adapter.kpi.shopping_cart_total_kpi: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\ShoppingCartTotalKpi' - arguments: - - "@prestashop.core.localization.locale.context_locale" - prestashop.adapter.kpi.abandoned_cart: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\AbandonedCartKpi' - - prestashop.adapter.kpi.average_order_value: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\AverageOrderValueKpi' - - prestashop.adapter.kpi.conversion_rate: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\ConversionRateKpi' - - prestashop.adapter.kpi.net_profit_per_visit: - class: 'PrestaShop\PrestaShop\Adapter\Kpi\NetProfitPerVisitKpi' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/language.yml b/src/PrestaShopBundle/Resources/config/services/adapter/language.yml deleted file mode 100644 index 76dad40a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/language.yml +++ /dev/null @@ -1,64 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.language.pack.importer: - class: 'PrestaShop\PrestaShop\Adapter\Language\Pack\LanguagePackImporter' - arguments: - - '@prestashop.adapter.language.language_pack_installer' - - '@prestashop.adapter.data_provider.language' - - '@prestashop.core.cache.clearer.cache_clearer_chain' - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_TRANSLATIONS_DIR_")' - - prestashop.adapter.language.language_flag_thumbnail_provider: - class: 'PrestaShop\PrestaShop\Adapter\Language\LanguageFlagThumbnailProvider' - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - - prestashop.adapter.language.rtl.installed_language_checker: - class: 'PrestaShop\PrestaShop\Adapter\Language\RTL\InstalledLanguageChecker' - arguments: - - '@prestashop.adapter.data_provider.language' - - prestashop.adapter.language.command_handler.add_language_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\AddLanguageHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\AddLanguageCommand' - - prestashop.adapter.language.command_handler.edit_language_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\EditLanguageHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\EditLanguageCommand' - - prestashop.adapter.language.query_handler.get_language_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Language\QueryHandler\GetLanguageForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Query\GetLanguageForEditing' - - prestashop.adapter.language.command_handler.toggle_language_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\ToggleLanguageStatusHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\ToggleLanguageStatusCommand' - - prestashop.adapter.language.command_handler.bulk_toggle_languages_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\BulkToggleLanguagesStatusHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkToggleLanguagesStatusCommand' - - prestashop.adapter.language.command_handler.bulk_delete_languages_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\BulkDeleteLanguagesHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\BulkDeleteLanguagesCommand' - - prestashop.adapter.language.command_handler.delete_language_handler: - class: 'PrestaShop\PrestaShop\Adapter\Language\CommandHandler\DeleteLanguageHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Language\Command\DeleteLanguageCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/mail_template.yml b/src/PrestaShopBundle/Resources/config/services/adapter/mail_template.yml deleted file mode 100644 index 41c74658..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/mail_template.yml +++ /dev/null @@ -1,32 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.mail_template.twig_renderer: - class: 'PrestaShop\PrestaShop\Adapter\MailTemplate\MailTemplateTwigRenderer' - arguments: - - '@templating.engine.twig' - - '@prestashop.core.mail_template.variables_builder' - - '@prestashop.core.hook.dispatcher' - calls: - - method: 'addTransformation' - arguments: - - '@prestashop.core.mail_template.transformation.css_inline' - - method: 'addTransformation' - arguments: - - '@prestashop.core.mail_template.transformation.html_textify' - - prestashop.adapter.mail_template.partial_template_renderer: - class: 'PrestaShop\PrestaShop\Adapter\MailTemplate\MailPartialTemplateRenderer' - arguments: - - "@=service('prestashop.adapter.legacy.context').getSmarty()" - - prestashop.adapter.mail_template.preview_variables_builder: - class: 'PrestaShop\PrestaShop\Adapter\MailTemplate\MailPreviewVariablesBuilder' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.legacy.context' - - '@prestashop.adapter.data_provider.employee' - - "@prestashop.adapter.mail_template.partial_template_renderer" - - "@prestashop.core.localization.locale.context_locale" - - "@translator" diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/manufacturer.yml b/src/PrestaShopBundle/Resources/config/services/adapter/manufacturer.yml deleted file mode 100644 index f1cd93b2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/manufacturer.yml +++ /dev/null @@ -1,56 +0,0 @@ -services: - _defaults: - public: true - - # Command handlers - - prestashop.adapter.manufacturer.manufacturer_logo_thumbnail_provider: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\ManufacturerLogoThumbnailProvider' - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - - prestashop.adapter.manufacturer.command_handler.toggle_manufacturer_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\ToggleManufacturerStatusHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\ToggleManufacturerStatusCommand' } - - prestashop.adapter.manufacturer.command_handler.bulk_toggle_manufacturer_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\BulkToggleManufacturerStatusHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkToggleManufacturerStatusCommand' } - - prestashop.adapter.manufacturer.command_handler.delete_manufacturer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\DeleteManufacturerHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\DeleteManufacturerCommand' } - - prestashop.adapter.manufacturer.command_handler.bulk_delete_manufacturer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\BulkDeleteManufacturerHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\BulkDeleteManufacturerCommand' } - - prestashop.adapter.manufacturer.query_handler.get_manufacturer_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\QueryHandler\GetManufacturerForEditingHandler' - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForEditing' - - prestashop.adapter.manufacturer.command_handler.edit_manufacturer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\EditManufacturerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\EditManufacturerCommand' - - prestashop.adapter.manufacturer.command_handler.add_manufacturer_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\CommandHandler\AddManufacturerHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Manufacturer\Command\AddManufacturerCommand' - - prestashop.adapter.manufacturer.query_handler.get_manufacturer_for_viewing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Manufacturer\QueryHandler\GetManufacturerForViewingHandler' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Manufacturer\Query\GetManufacturerForViewing diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/meta.yml b/src/PrestaShopBundle/Resources/config/services/adapter/meta.yml deleted file mode 100644 index c52de95b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/meta.yml +++ /dev/null @@ -1,48 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.meta.meta_eraser: - class: 'PrestaShop\PrestaShop\Adapter\Meta\MetaEraser' - - prestashop.adapter.meta.data_provider: - class: 'PrestaShop\PrestaShop\Adapter\Meta\MetaDataProvider' - - # COMMAND HANDLERS - - prestashop.adapter.meta.command_handler.save_meta: - class: 'PrestaShop\PrestaShop\Adapter\Meta\CommandHandler\AddMetaHandler' - arguments: - - '@prestashop.core.hook.dispatcher' - - '@validator' - - '@=service("prestashop.adapter.legacy.configuration").get("PS_LANG_DEFAULT")' - - '@prestashop.adapter.meta.data_provider' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Meta\Command\AddMetaCommand' - - prestashop.adapter.meta.command_handler.edit_meta: - class: 'PrestaShop\PrestaShop\Adapter\Meta\CommandHandler\EditMetaHandler' - arguments: - - '@validator' - - '@prestashop.adapter.meta.data_provider' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Meta\Command\EditMetaCommand' - - # QUERY HANDLERS - - prestashop.adapter.meta.query_handler.get_meta_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Meta\QueryHandler\GetMetaForEditingHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetMetaForEditing' - - - prestashop.adapter.meta.query_handler.get_pages_for_layout_customization_handler: - class: 'PrestaShop\PrestaShop\Adapter\Meta\QueryHandler\GetPagesForLayoutCustomizationHandler' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Meta\Query\GetPagesForLayoutCustomization' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/module.yml b/src/PrestaShopBundle/Resources/config/services/adapter/module.yml deleted file mode 100644 index b92ecdce..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/module.yml +++ /dev/null @@ -1,83 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.module.self_configurator: - class: PrestaShop\PrestaShop\Adapter\Module\Configuration\ModuleSelfConfigurator - arguments: - - "@prestashop.core.admin.module.repository" - - "@prestashop.adapter.legacy.configuration" - - "@doctrine.dbal.default_connection" - - "@filesystem" - - # MODULE TAB MANAGEMENT - prestashop.adapter.module.tab.register: - class: PrestaShop\PrestaShop\Adapter\Module\Tab\ModuleTabRegister - arguments: - - "@prestashop.core.admin.tab.repository" - - "@prestashop.core.admin.lang.repository" - - "@logger" - - "@translator" - - "@filesystem" - - "@=service('prestashop.adapter.legacy.context').getLanguages()" - - "@routing.loader.yml" - - prestashop.adapter.module.tab.unregister: - class: PrestaShop\PrestaShop\Adapter\Module\Tab\ModuleTabUnregister - arguments: - - "@prestashop.core.admin.tab.repository" - - "@prestashop.core.admin.lang.repository" - - "@logger" - - "@translator" - - prestashop.adapter.module.tab.eventsubscriber: - class: PrestaShop\PrestaShop\Adapter\Module\Tab\ModuleTabManagementSubscriber - arguments: - - "@prestashop.adapter.module.tab.register" - - "@prestashop.adapter.module.tab.unregister" - tags: - - { name: kernel.event_subscriber } - - prestashop.module.manager: - class: PrestaShop\PrestaShop\Core\Addon\Module\ModuleManager - arguments: - - "@prestashop.adapter.admin.data_provider.module" - - "@prestashop.adapter.data_provider.module" - - "@prestashop.core.module.updater" - - "@prestashop.core.admin.module.repository" - - "@prestashop.module.zip.manager" - - "@translator" - - "@event_dispatcher" - - "@prestashop.adapter.cache.clearer.symfony_cache_clearer" - - prestashop.module.zip.manager: - class: PrestaShop\PrestaShop\Adapter\Module\ModuleZipManager - arguments: - - "@filesystem" - - "@translator" - - "@event_dispatcher" - - prestashop.adapter.presenter.module: - class: PrestaShop\PrestaShop\Adapter\Presenter\Module\ModulePresenter - arguments: ["@=service('prestashop.adapter.legacy.context').getContext().currency", "@prestashop.adapter.formatter.price"] - - prestashop.adapter.module.data_provider.tab_module_list: - class: PrestaShop\PrestaShop\Adapter\Module\TabModuleListProvider - - prestashop.adapter.module.presenter.payment: - class: PrestaShop\PrestaShop\Adapter\Module\Presenter\PaymentModulesPresenter - arguments: - - '@prestashop.adapter.module.data_provider.tab_module_list' - - '@prestashop.adapter.data_provider.module' - - '@prestashop.adapter.presenter.module' - - '@prestashop.core.admin.module.repository' - - prestashop.adapter.module.payment_module_provider: - class: PrestaShop\PrestaShop\Adapter\Module\PaymentModuleListProvider - arguments: - - '@prestashop.core.admin.module.repository' - - '@prestashop.bundle.repository.module' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.adapter.legacy.module: - class: PrestaShop\PrestaShop\Adapter\Module\Module diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/news.yml b/src/PrestaShopBundle/Resources/config/services/adapter/news.yml deleted file mode 100644 index 2fb4af4e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/news.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.news.circuit_breaker.settings: - class: PrestaShop\CircuitBreaker\FactorySettings - arguments: - - !php/const \PrestaShop\PrestaShop\Adapter\News\NewsDataProvider::CLOSED_ALLOWED_FAILURES - - !php/const \PrestaShop\PrestaShop\Adapter\News\NewsDataProvider::CLOSED_TIMEOUT_SECONDS - - !php/const \PrestaShop\PrestaShop\Adapter\News\NewsDataProvider::OPEN_THRESHOLD_SECONDS - calls: - - ['setStrippedFailures', [!php/const \PrestaShop\PrestaShop\Adapter\News\NewsDataProvider::OPEN_ALLOWED_FAILURES]] - - ['setStrippedTimeout', [!php/const \PrestaShop\PrestaShop\Adapter\News\NewsDataProvider::OPEN_TIMEOUT_SECONDS]] - - ['setStorage', ['@prestashop.core.circuit_breaker.storage']] - - ['setClientOptions', [{'method': 'GET', 'subscribers': ['@prestashop.core.circuit_breaker.guzzle.cache_subscriber']}]] - - prestashop.adapter.news.circuit_breaker: - class: 'PrestaShop\CircuitBreaker\Contract\CircuitBreakerInterface' - factory: ["@prestashop.core.circuit_breaker.advanced_factory", create] - arguments: - - "@prestashop.adapter.news.circuit_breaker.settings" - - prestashop.adapter.news.provider: - class: PrestaShop\PrestaShop\Adapter\News\NewsDataProvider - arguments: - - "@prestashop.adapter.news.circuit_breaker" - - "@prestashop.adapter.data_provider.country" - - "@prestashop.adapter.tools" - - "@prestashop.adapter.legacy.configuration" - - "@prestashop.adapter.validate" - - "@=service('prestashop.adapter.legacy.context').getContext().mode" diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/notification.yml b/src/PrestaShopBundle/Resources/config/services/adapter/notification.yml deleted file mode 100644 index 7c019e70..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/notification.yml +++ /dev/null @@ -1,16 +0,0 @@ -services: - _defaults: - public: true - - - prestashop.adapter.notification.command_handler.update_employee_notification_last_element_handler: - class: 'PrestaShop\PrestaShop\Adapter\Notification\CommandHandler\UpdateEmployeeNotificationLastElementHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Notification\Command\UpdateEmployeeNotificationLastElementCommand' - - prestashop.adapter.notification.query_handler.get_notification_last_elements_handler: - class: 'PrestaShop\PrestaShop\Adapter\Notification\QueryHandler\GetNotificationLastElementsHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Notification\Query\GetNotificationLastElements' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/order.yml b/src/PrestaShopBundle/Resources/config/services/adapter/order.yml deleted file mode 100644 index b268beae..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/order.yml +++ /dev/null @@ -1,275 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.order.command_handler.duplicate_order_cart_handler: - class: 'PrestaShop\PrestaShop\Adapter\Order\CommandHandler\DuplicateOrderCartHandler' - arguments: - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Order\Command\DuplicateOrderCartCommand' - - prestashop.adapter.order.command_handler.add_order_from_back_office_handler: - class: 'PrestaShop\PrestaShop\Adapter\Order\CommandHandler\AddOrderFromBackOfficeHandler' - arguments: - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Order\Command\AddOrderFromBackOfficeCommand' - - prestashop.adapter.order.command_handler.add_product_to_order_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\AddProductToOrderHandler - arguments: - - '@translator' - - '@prestashop.adapter.context_state_manager' - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.product_quantity.updater' - - '@prestashop.adapter.order.order_detail.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\AddProductToOrderCommand - - prestashop.adapter.order.command_handler.update_order_status_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\UpdateOrderStatusHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderStatusCommand - - prestashop.adapter.order.command_handler.update_product_in_order_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\UpdateProductInOrderHandler - arguments: - - '@prestashop.adapter.order.product_quantity.updater' - - '@prestashop.adapter.order.order_detail.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\UpdateProductInOrderCommand - - prestashop.adapter.order.command_handler.change_order_delivery_address_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\ChangeOrderDeliveryAddressHandler - arguments: - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.order_detail.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderDeliveryAddressCommand - - prestashop.adapter.order.command_handler.change_order_invoice_address_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\ChangeOrderInvoiceAddressHandler - arguments: - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.order_detail.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderInvoiceAddressCommand - - prestashop.adapter.order.command_handler.change_order_currency_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\ChangeOrderCurrencyHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\ChangeOrderCurrencyCommand - - prestashop.adapter.order.command_handler.add_payment_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\AddPaymentHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Payment\Command\AddPaymentCommand - - prestashop.adapter.order.command_handler.generate_invoice_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\GenerateInvoiceHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\GenerateInvoiceCommand - - prestashop.adapter.order.command_handler.update_order_shipping_details_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\UpdateOrderShippingDetailsHandler - arguments: - - '@prestashop.adapter.order.amount.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\UpdateOrderShippingDetailsCommand - - prestashop.adapter.order.command_handler.delete_cart_rule_from_order_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\DeleteCartRuleFromOrderHandler - arguments: - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.product_quantity.updater' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\DeleteCartRuleFromOrderCommand - - prestashop.adapter.order.command_handler.add_cart_rule_to_order_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\AddCartRuleToOrderHandler - arguments: - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\AddCartRuleToOrderCommand - - prestashop.adapter.order.command_handler.update_invoice_note_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\UpdateInvoiceNoteHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Invoice\Command\UpdateInvoiceNoteCommand - - prestashop.adapter.order.command_handler.issue_partial_refund_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\IssuePartialRefundHandler - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.order.refund.order_refund_calculator' - - '@prestashop.adapter.order.refund.order_slip_creator' - - '@prestashop.adapter.order.refund.voucher_generator' - - '@prestashop.adapter.order.refund.updater' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\IssuePartialRefundCommand - - prestashop.adapter.order.command_handler.issue_standard_refund_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\IssueStandardRefundHandler - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.order.refund.order_refund_calculator' - - '@prestashop.adapter.order.refund.order_slip_creator' - - '@prestashop.adapter.order.refund.voucher_generator' - - '@prestashop.adapter.order.refund.updater' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueStandardRefundCommand - - prestashop.adapter.order.command_handler.issue_return_product_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\IssueReturnProductHandler - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.order.refund.order_refund_calculator' - - '@prestashop.adapter.order.refund.order_slip_creator' - - '@prestashop.adapter.order.refund.voucher_generator' - - '@prestashop.adapter.order.refund.updater' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\IssueReturnProductCommand - - prestashop.adapter.order.refund.order_refund_calculator: - class: PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundCalculator - - prestashop.adapter.order.refund.order_slip_creator: - class: PrestaShop\PrestaShop\Adapter\Order\Refund\OrderSlipCreator - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@translator' - - prestashop.adapter.order.refund.voucher_generator: - class: PrestaShop\PrestaShop\Adapter\Order\Refund\VoucherGenerator - arguments: - - '@prestashop.core.localization.locale.context_locale' - - '@translator' - - prestashop.adapter.order.refund.updater: - class: PrestaShop\PrestaShop\Adapter\Order\Refund\OrderRefundUpdater - - prestashop.adapter.order.product.remover: - class: PrestaShop\PrestaShop\Adapter\Order\Refund\OrderProductRemover - arguments: - - "@logger" - - "@translator" - - prestashop.adapter.order.command_handler.delete_product_from_order_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\DeleteProductFromOrderHandler - arguments: - - '@prestashop.adapter.context_state_manager' - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.product_quantity.updater' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Product\Command\DeleteProductFromOrderCommand - - prestashop.adapter.order.command_handler.bulk_change_order_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Order\CommandHandler\BulkChangeOrderStatusHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Order\Command\BulkChangeOrderStatusCommand' - - prestashop.adapter.order.query_handler.get_order_for_viewing_handler: - class: PrestaShop\PrestaShop\Adapter\Order\QueryHandler\GetOrderForViewingHandler - arguments: - - '@translator' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - "@prestashop.core.localization.locale.context_locale" - - '@=service("prestashop.adapter.legacy.context").getContext()' - - '@prestashop.adapter.data_provider.customer' - - '@prestashop.adapter.order.query_handler.get_order_products_for_viewing_handler' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderForViewing - - prestashop.adapter.order.query_handler.get_order_products_for_viewing_handler: - class: PrestaShop\PrestaShop\Adapter\Order\QueryHandler\GetOrderProductsForViewingHandler - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - "@prestashop.core.localization.locale.context_locale" - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderProductsForViewing - - - prestashop.adapter.order.command_handler.resend_order_email_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\ResendOrderEmailHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\ResendOrderEmailCommand - - prestashop.adapter.order.query_handler.get_order_preview_handler: - class: 'PrestaShop\PrestaShop\Adapter\Order\QueryHandler\GetOrderPreviewHandler' - arguments: - - '@prestashop.core.localization.locale.repository' - - "@=service('prestashop.adapter.legacy.context').getContext().language.getLocale()" - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Order\Query\GetOrderPreview' - - prestashop.adapter.order.command_handler.send_process_order_email_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\SendProcessOrderEmailHandler - arguments: - - '@translator' - - '@=service("prestashop.adapter.legacy.context").getContext().link' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\SendProcessOrderEmailCommand - - prestashop.adapter.order.command_handler.cancel_order_product_handler: - class: PrestaShop\PrestaShop\Adapter\Order\CommandHandler\CancelOrderProductHandler - arguments: - - '@prestashop.adapter.order.product_quantity.updater' - - '@logger' - - '@translator' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Order\Command\CancelOrderProductCommand - - prestashop.adapter.order.order_sibling_provider: - class: PrestaShop\PrestaShop\Adapter\Order\OrderSiblingProvider - - prestashop.adapter.order.amount.updater: - class: PrestaShop\PrestaShop\Adapter\Order\OrderAmountUpdater - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.context_state_manager' - - '@prestashop.adapter.order.order_detail.updater' - - prestashop.adapter.order.product_quantity.updater: - class: PrestaShop\PrestaShop\Adapter\Order\OrderProductQuantityUpdater - arguments: - - '@prestashop.adapter.order.amount.updater' - - '@prestashop.adapter.order.product.remover' - - '@prestashop.adapter.context_state_manager' - - prestashop.adapter.order.order_detail.updater: - class: PrestaShop\PrestaShop\Adapter\Order\OrderDetailUpdater - arguments: - - '@prestashop.adapter.context_state_manager' - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/order_message.yml b/src/PrestaShopBundle/Resources/config/services/adapter/order_message.yml deleted file mode 100644 index 8a958836..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/order_message.yml +++ /dev/null @@ -1,38 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.order_message.command_handler.add_order_message_handler: - class: PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler\AddOrderMessageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\AddOrderMessageCommand - - prestashop.adapter.order_message.command_handler.edit_order_message_handler: - class: PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler\EditOrderMessageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\EditOrderMessageCommand - - prestashop.adapter.order_message.query_handler.get_order_message_for_editing_handler: - class: PrestaShop\PrestaShop\Adapter\OrderMessage\QueryHandler\GetOrderMessageForEditingHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\OrderMessage\Query\GetOrderMessageForEditing - - prestashop.adapter.order_message.command_handler.delete_order_message_handler: - class: PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler\DeleteOrderMessageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\DeleteOrderMessageCommand - - prestashop.adapter.order_message.command_handler.bulk_delete_order_message_handler: - class: PrestaShop\PrestaShop\Adapter\OrderMessage\CommandHandler\BulkDeleteOrderMessageHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\OrderMessage\Command\BulkDeleteOrderMessageCommand - - prestashop.adapter.order_message.order_message_provider: - class: 'PrestaShop\PrestaShop\Adapter\OrderMessage\OrderMessageProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/pdf.yml b/src/PrestaShopBundle/Resources/config/services/adapter/pdf.yml deleted file mode 100644 index fa40bfbc..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/pdf.yml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: pdf/*.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/pdf/generator.yml b/src/PrestaShopBundle/Resources/config/services/adapter/pdf/generator.yml deleted file mode 100644 index 01238a93..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/pdf/generator.yml +++ /dev/null @@ -1,32 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.pdf.generator.invoice: - class: PrestaShop\PrestaShop\Adapter\PDF\PDFGenerator - arguments: - - "@=service('prestashop.adapter.legacy.context').getSmarty()" - - '@prestashop.adapter.pdf.type_provider.invoice' - - prestashop.adapter.pdf.order_invoice_pdf_generator: - class: PrestaShop\PrestaShop\Adapter\PDF\OrderInvoicePdfGenerator - arguments: - - '@translator' - - prestashop.adapter.pdf.delivery_slip_pdf_generator: - class: PrestaShop\PrestaShop\Adapter\PDF\DeliverySlipPdfGenerator - arguments: - - '@translator' - - prestashop.adapter.pdf.generator.credit_slip: - class: PrestaShop\PrestaShop\Adapter\PDF\PDFGenerator - arguments: - - "@=service('prestashop.adapter.legacy.context').getSmarty()" - - '@prestashop.adapter.pdf.type_provider.credit_slip' - - prestashop.adapter.pdf.credit_slip_pdf_generator: - class: PrestaShop\PrestaShop\Adapter\PDF\CreditSlipPdfGenerator - arguments: - - '@translator' - - '%database_prefix%' - - '@doctrine.dbal.default_connection' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/pdf/template_type_provider.yml b/src/PrestaShopBundle/Resources/config/services/adapter/pdf/template_type_provider.yml deleted file mode 100644 index 27265bb3..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/pdf/template_type_provider.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.pdf.type_provider.invoice: - class: PrestaShop\PrestaShop\Adapter\Invoice\InvoiceTemplateTypeProvider - - prestashop.adapter.pdf.type_provider.credit_slip: - class: PrestaShop\PrestaShop\Adapter\CreditSlip\CreditSlipTemplateTypeProvider diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/prestatrust.yml b/src/PrestaShopBundle/Resources/config/services/adapter/prestatrust.yml deleted file mode 100644 index 815ed5d4..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/prestatrust.yml +++ /dev/null @@ -1,19 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.module.prestatrust.checker: - class: PrestaShop\PrestaShop\Adapter\Module\PrestaTrust\PrestaTrustChecker - arguments: - - "@doctrine.cache.provider" - - "@prestashop.addons.client_api" - - "@translator" - - prestashop.adapter.module.prestatrust.eventsubscriber: - class: PrestaShop\PrestaShop\Adapter\Module\PrestaTrust\ModuleEventSubscriber - arguments: - - "@prestashop.adapter.module.prestatrust.checker" - calls: - - [ setEnabled, ['%prestashop.addons.prestatrust.enabled%']] - tags: - - { name: kernel.event_subscriber } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/product.yml b/src/PrestaShopBundle/Resources/config/services/adapter/product.yml deleted file mode 100644 index 38d04692..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/product.yml +++ /dev/null @@ -1,67 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.admin.data_provider.product: - class: PrestaShop\PrestaShop\Adapter\Product\AdminProductDataProvider - decorates: prestashop.core.admin.data_provider.product_interface - arguments: - - "@doctrine.orm.entity_manager" - - "@prestashop.adapter.image_manager" - - "@prestashop.static_cache.adapter" - public: false - - prestashop.adapter.admin.data_updater.product: - class: PrestaShop\PrestaShop\Adapter\Product\AdminProductDataUpdater - decorates: prestashop.core.admin.data_updater.product_interface - public: false - arguments: - - "@prestashop.core.hook.dispatcher" - - "@prestashop.static_cache.adapter" - - prestashop.adapter.admin.wrapper.product: - class: PrestaShop\PrestaShop\Adapter\Product\AdminProductWrapper - arguments: - - "@translator" - - "@=service('prestashop.adapter.legacy.context').getContext().employee.getAssociatedShops()" - - "@prestashop.core.localization.locale.context_locale" - - "@prestashop.utils.float_parser" - - prestashop.adapter.admin.controller.attribute_generator: - class: PrestaShop\PrestaShop\Adapter\Attribute\AdminAttributeGeneratorControllerWrapper - - prestashop.adapter.product.filter_categories_request_purifier: - class: 'PrestaShop\PrestaShop\Adapter\Product\FilterCategoriesRequestPurifier' - - prestashop.adapter.product.list_parameters_updater: - class: 'PrestaShop\PrestaShop\Adapter\Product\ListParametersUpdater' - - prestashop.adapter.product.command_handler.add_category_to_product_handler: - class: PrestaShop\PrestaShop\Adapter\Product\CommandHandler\AssignProductToCategoryHandler - public: true - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Product\Command\AssignProductToCategoryCommand } - - prestashop.adapter.product.command_handler.update_product_status_handler: - class: PrestaShop\PrestaShop\Adapter\Product\CommandHandler\UpdateProductStatusCommandHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Product\Command\UpdateProductStatusCommand - - prestashop.adapter.product.query_handler.search_products: - class: PrestaShop\PrestaShop\Adapter\Product\QueryHandler\SearchProductsHandler - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@prestashop.core.localization.locale.context_locale' - - '@prestashop.adapter.tools' - - '@prestashop.adapter.data_provider.currency' - - '@prestashop.adapter.context_state_manager' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Product\Query\SearchProducts - - prestashop.adapter.product.command_handler.get_product_is_enabled_handler: - class: PrestaShop\PrestaShop\Adapter\Product\QueryHandler\GetProductIsEnabledHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\Product\Query\GetProductIsEnabled diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/profile.yml b/src/PrestaShopBundle/Resources/config/services/adapter/profile.yml deleted file mode 100644 index b8cde9ca..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/profile.yml +++ /dev/null @@ -1,37 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.profile.command_handler.delete_profile: - class: 'PrestaShop\PrestaShop\Adapter\Profile\CommandHandler\DeleteProfileHandler' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_ADMIN_PROFILE_")' - - '@prestashop.adapter.data_provider.employee' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Profile\Command\DeleteProfileCommand' } - - prestashop.adapter.profile.command_handler.bulk_delete_profile: - class: 'PrestaShop\PrestaShop\Adapter\Profile\CommandHandler\BulkDeleteProfileHandler' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_ADMIN_PROFILE_")' - - '@prestashop.adapter.data_provider.employee' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Profile\Command\BulkDeleteProfileCommand' } - - prestashop.adapter.profile.command_handler.add_profile_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\CommandHandler\AddProfileHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Profile\Command\AddProfileCommand' - - prestashop.adapter.profile.command_handler.edit_profile_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\CommandHandler\EditProfileHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Profile\Command\EditProfileCommand' - - prestashop.adapter.profile.query_handler.get_profile_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Profile\QueryHandler\GetProfileForEditingHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Profile\Query\GetProfileForEditing' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/routes.yml b/src/PrestaShopBundle/Resources/config/services/adapter/routes.yml deleted file mode 100644 index 2fc8e316..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/routes.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.routes.route_validator: - class: 'PrestaShop\PrestaShop\Adapter\Routes\RouteValidator' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/services.yml b/src/PrestaShopBundle/Resources/config/services/adapter/services.yml deleted file mode 100644 index b93138f6..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/services.yml +++ /dev/null @@ -1,134 +0,0 @@ -imports: - - { resource: ./common.yml } - -services: - _defaults: - public: true - - prestashop.adapter.hosting_information: - class: 'PrestaShop\PrestaShop\Adapter\Hosting\HostingInformation' - - prestashop.adapter.shop_information: - class: 'PrestaShop\PrestaShop\Adapter\Shop\ShopInformation' - arguments: ['@prestashop.adapter.legacy.context'] - - prestashop.adapter.mailing_information: - class: 'PrestaShop\PrestaShop\Adapter\Mail\MailingInformation' - - prestashop.adapter.check_requirements: - class: 'PrestaShop\PrestaShop\Adapter\Requirement\CheckRequirements' - arguments: ['@translator'] - - prestashop.adapter.system_information: - class: 'PrestaShop\PrestaShop\Adapter\System\SystemInformation' - arguments: - - '@prestashop.adapter.hosting_information' - - '@prestashop.adapter.mailing_information' - - '@prestashop.adapter.shop_information' - - prestashop.adapter.check_missing_files: - class: 'PrestaShop\PrestaShop\Adapter\Requirement\CheckMissingOrUpdatedFiles' - - prestashop.adapter.cache_clearer: - class: 'PrestaShop\PrestaShop\Adapter\Cache\CacheClearer' - arguments: - - '@prestashop.core.cache.clearer.cache_clearer_chain' - - '@prestashop.adapter.cache.clearer.symfony_cache_clearer' - - '@prestashop.adapter.cache.clearer.media_cache_clearer' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - prestashop.adapter.debug_mode: - class: 'PrestaShop\PrestaShop\Adapter\Debug\DebugMode' - - prestashop.adapter.database: - class: 'PrestaShop\PrestaShop\Adapter\Database' - - prestashop.adapter.memcache_server.manager: - class: 'PrestaShop\PrestaShop\Adapter\Cache\MemcacheServerManager' - arguments: ['@database_connection', '%database_prefix%'] - - prestashop.adapter.php_parameters: - class: 'PrestaShop\PrestaShop\Adapter\Configuration\PhpParameters' - arguments: ['%kernel.root_dir%/config/parameters.php'] - - prestashop.adapter.legacy.kpi_configuration: - class: PrestaShop\PrestaShop\Adapter\Configuration\KpiConfiguration - - prestashop.adapter.legacy.logger: - class: PrestaShop\PrestaShop\Adapter\LegacyLogger - - prestashop.adapter.legacy.hook: - class: PrestaShop\PrestaShop\Adapter\Hook\HookInformationProvider - - # SSL middleware - prestashop.adapter.middleware.ssl: - class: PrestaShop\PrestaShop\Adapter\Security\SslMiddleware - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - - # Legacy Hooks registrator - prestashop.adapter.legacy.hook.subscriber: - class: PrestaShop\PrestaShop\Adapter\LegacyHookSubscriber - - prestashop.adapter.legacy.block.helper.subscriber: - class: PrestaShop\PrestaShop\Adapter\Admin\LegacyBlockHelperSubscriber - - prestashop.adapter.stock_manager: - class: PrestaShop\PrestaShop\Adapter\StockManager - decorates: prestashop.core.data_provider.stock_interface - public: false - - prestashop.adapter.formatter.price: - class: PrestaShop\PrestaShop\Adapter\Product\PriceFormatter - - # Other adapters - prestashop.adapter.shop.context: - class: PrestaShop\PrestaShop\Adapter\Shop\Context - - prestashop.adapter.image_manager: - class: PrestaShop\PrestaShop\Adapter\ImageManager - arguments: ["@prestashop.adapter.legacy.context"] - - prestashop.core.module.updater: - class: PrestaShop\PrestaShop\Adapter\Module\ModuleDataUpdater - arguments: - - "@prestashop.core.admin.data_provider.addons_interface" - - "@prestashop.adapter.admin.data_provider.module" - - prestashop.adapter.admin.model.product: - class: PrestaShopBundle\Model\Product\AdminModelAdapter - arguments: - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.admin.wrapper.product" - - "@prestashop.adapter.tools" - - "@prestashop.adapter.data_provider.product" - - "@prestashop.adapter.data_provider.supplier" - - "@prestashop.adapter.data_provider.warehouse" - - "@prestashop.adapter.data_provider.feature" - - "@prestashop.adapter.data_provider.pack" - - "@prestashop.adapter.shop.context" - - "@prestashop.adapter.data_provider.tax" - - "@router" - - "@prestashop.utils.float_parser" - - prestashop.adapter.translation_route_finder: - class: PrestaShop\PrestaShop\Adapter\Translations\TranslationRouteFinder - arguments: - - '@prestashop.service.translation' - - '@=service("prestashop.adapter.legacy.context").getContext().link' - - '@prestashop.core.admin.module.repository' - - prestashop.adapter.shop.shop_url: - class: 'PrestaShop\PrestaShop\Adapter\Shop\ShopUrlDataProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.adapter.file.htaccess_file_generator: - class: 'PrestaShop\PrestaShop\Adapter\File\HtaccessFileGenerator' - arguments: - - '@prestashop.adapter.cache_clearer' - - '@prestashop.adapter.tools' - - "@=service('prestashop.adapter.legacy.configuration').getBoolean('PS_HTACCESS_DISABLE_MULTIVIEWS')" - - prestashop.adapter.file.robots_text_file_generator: - class: 'PrestaShop\PrestaShop\Adapter\File\RobotsTextFileGenerator' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/shop.yml b/src/PrestaShopBundle/Resources/config/services/adapter/shop.yml deleted file mode 100644 index 22dfc992..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/shop.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.shop.command_handler.upload_logos_handler: - class: 'PrestaShop\PrestaShop\Adapter\Shop\CommandHandler\UploadLogosHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.shop.logo_uploader' - - '@prestashop.core.hook.dispatcher' - tags: - - { name: tactician.handler, command: 'PrestaShop\PrestaShop\Core\Domain\Shop\Command\UploadLogosCommand' } - - prestashop.adapter.shop.url.base_url_provider: - class: 'PrestaShop\PrestaShop\Adapter\Shop\Url\BaseUrlProvider' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().link" - - prestashop.adapter.shop.url.category_provider: - class: 'PrestaShop\PrestaShop\Adapter\Shop\Url\CategoryProvider' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().link" - - prestashop.adapter.shop.url.cms_provider: - class: 'PrestaShop\PrestaShop\Adapter\Shop\Url\CmsProvider' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().link" - - prestashop.adapter.shop.query_handler.get_logos_paths_handler: - class: 'PrestaShop\PrestaShop\Adapter\Shop\QueryHandler\GetLogosPathsHandler' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_IMG_")' - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_IMG_DIR_")' - tags: - - name: 'tactician.handler' - command: PrestaShop\PrestaShop\Core\Domain\Shop\Query\GetLogosPaths diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/shop_feature.yml b/src/PrestaShopBundle/Resources/config/services/adapter/shop_feature.yml deleted file mode 100644 index 596b0c2e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/shop_feature.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.combination_feature: - class: 'PrestaShop\PrestaShop\Adapter\Feature\CombinationFeature' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.feature.feature: - class: 'PrestaShop\PrestaShop\Adapter\Feature\FeatureFeature' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.group.feature: - class: 'PrestaShop\PrestaShop\Adapter\Feature\GroupFeature' - arguments: ['@prestashop.adapter.legacy.configuration'] - - prestashop.adapter.multistore_feature: - class: 'PrestaShop\PrestaShop\Adapter\Feature\MultistoreFeature' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.adapter.feature.multistore: - class: 'PrestaShop\PrestaShop\Adapter\Feature\MultistoreFeature' - arguments: - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/specific_price.yml b/src/PrestaShopBundle/Resources/config/services/adapter/specific_price.yml deleted file mode 100644 index 93e7d195..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/specific_price.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.specific_price.command_handler.add_specific_price: - class: PrestaShop\PrestaShop\Adapter\SpecificPrice\CommandHandler\AddSpecificPriceHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\AddSpecificPriceCommand - - prestashop.adapter.specific_price.command_handler.delete_specific_price_by_cart_product: - class: PrestaShop\PrestaShop\Adapter\SpecificPrice\CommandHandler\DeleteSpecificPriceByCartProductHandler - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\SpecificPrice\Command\DeleteSpecificPriceByCartProductCommand diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/sql_manager.yml b/src/PrestaShopBundle/Resources/config/services/adapter/sql_manager.yml deleted file mode 100644 index 544f2652..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/sql_manager.yml +++ /dev/null @@ -1,59 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.sql_manager.sql_query_validator: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\SqlQueryValidator' - - prestashop.adapter.sql_manager.request_sql_form_data_validator: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\SqlRequestFormDataValidator' - arguments: - - '@prestashop.adapter.sql_manager.sql_query_validator' - - # Command handlers - prestashop.adapter.sql_manager.command_handler.add_request_sql: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler\AddSqlRequestHandler' - arguments: - - '@prestashop.adapter.sql_manager.sql_query_validator' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\AddSqlRequestCommand' } - - prestashop.adapter.sql_manager.command_handler.edit_request_sql: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler\EditSqlRequestHandler' - arguments: - - '@prestashop.adapter.sql_manager.sql_query_validator' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\EditSqlRequestCommand' } - - prestashop.adapter.sql_manager.command_handler.delete_request_sql: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler\DeleteSqlRequestHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\DeleteSqlRequestCommand' } - - prestashop.adapter.sql_manager.command_handler.bulk_delete_request_sql: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\CommandHandler\BulkDeleteSqlRequestHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\BulkDeleteSqlRequestCommand' } - - # Query handlers - prestashop.adapter.sql_manager.query_handler.get_request_sql_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler\GetSqlRequestForEditingHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestForEditing' } - - prestashop.adapter.sql_manager.query_handler.get_request_sql_execution_result: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler\GetSqlRequestExecutionResultHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestExecutionResult' } - - prestashop.adapter.sql_manager.query_handler.get_database_tables_list: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler\GetDatabaseTablesListHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTablesList' } - - prestashop.adapter.sql_manager.query_handler.get_database_table_fields_list: - class: 'PrestaShop\PrestaShop\Adapter\SqlManager\QueryHandler\GetDatabaseTableFieldsListHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetDatabaseTableFieldsList' } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/supplier.yml b/src/PrestaShopBundle/Resources/config/services/adapter/supplier.yml deleted file mode 100644 index 8c903afd..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/supplier.yml +++ /dev/null @@ -1,89 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.supplier.provider.supplier_logo: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\SupplierLogoThumbnailProvider' - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - - '@prestashop.adapter.image_manager' - - prestashop.adapter.supplier.provider.supplier_address: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\SupplierAddressProvider' - - prestashop.adapter.supplier.supplier_order_validator: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\SupplierOrderValidator' - -# Command handlers - - prestashop.adapter.supplier.command_handler.abstract_delete_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\AbstractDeleteSupplierHandler' - abstract: true - arguments: - - '@prestashop.adapter.supplier.supplier_order_validator' - - '@prestashop.adapter.supplier.provider.supplier_address' - - '%database_prefix%' - public: false - - prestashop.adapter.supplier.command_handler.toggle_supplier_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\ToggleSupplierStatusHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\ToggleSupplierStatusCommand' - - prestashop.adapter.supplier.command_handler.delete_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\DeleteSupplierHandler' - parent: 'prestashop.adapter.supplier.command_handler.abstract_delete_supplier_handler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\DeleteSupplierCommand' - public: true - - prestashop.adapter.supplier.command_handler.bulk_delete_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\BulkDeleteSupplierHandler' - parent: 'prestashop.adapter.supplier.command_handler.abstract_delete_supplier_handler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDeleteSupplierCommand' - public: true - - prestashop.adapter.supplier.command_handler.bulk_disable_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\BulkDisableSupplierHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkDisableSupplierCommand' - - prestashop.adapter.supplier.command_handler.bulk_enable_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\BulkEnableSupplierHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\BulkEnableSupplierCommand' - - prestashop.adapter.supplier.query_handler.get_supplier_for_viewing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\QueryHandler\GetSupplierForViewingHandler' - arguments: - - '@prestashop.core.localization.locale.context_locale' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForViewing' - - prestashop.adapter.supplier.command_handler.add_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\AddSupplierHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\AddSupplierCommand' - - prestashop.adapter.supplier.query_handler.get_supplier_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\QueryHandler\GetSupplierForEditingHandler' - arguments: - - '@prestashop.core.image.parser.image_tag_source_parser' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Query\GetSupplierForEditing' - - prestashop.adapter.supplier.command_handler.edit_supplier_handler: - class: 'PrestaShop\PrestaShop\Adapter\Supplier\CommandHandler\EditSupplierHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\Supplier\Command\EditSupplierCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/tax.yml b/src/PrestaShopBundle/Resources/config/services/adapter/tax.yml deleted file mode 100644 index fcddc136..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/tax.yml +++ /dev/null @@ -1,45 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.tax.ecotax.ecotax_resetter: - class: 'PrestaShop\PrestaShop\Adapter\Tax\Ecotax\ProductEcotaxResetter' - - # Command handlers - prestashop.adapter.tax.command_handler.delete_tax_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\DeleteTaxHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\DeleteTaxCommand' } - - prestashop.adapter.tax.command_handler.toggle_tax_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\ToggleTaxStatusHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\ToggleTaxStatusCommand' } - - prestashop.adapter.tax.command_handler.bulk_toggle_tax_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\BulkToggleTaxStatusHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkToggleTaxStatusCommand' } - - prestashop.adapter.tax.command_handler.bulk_delete_tax_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\BulkDeleteTaxHandler' - tags: - - { name: 'tactician.handler', command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\BulkDeleteTaxCommand' } - - prestashop.adapter.tax.query_handler.get_tax_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\QueryHandler\GetTaxForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Query\GetTaxForEditing' - - prestashop.adapter.tax.command_handler.edit_tax_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\EditTaxHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\EditTaxCommand' - - prestashop.adapter.tax.command_handler.add_tax_handler: - class: 'PrestaShop\PrestaShop\Adapter\Tax\CommandHandler\AddTaxHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Tax\Command\AddTaxCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/tax_rules_group.yml b/src/PrestaShopBundle/Resources/config/services/adapter/tax_rules_group.yml deleted file mode 100644 index 6f8ef103..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/tax_rules_group.yml +++ /dev/null @@ -1,33 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.tax_rules_group.command_handler.delete_tax_rules_group_handler: - class: 'PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler\DeleteTaxRulesGroupHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\DeleteTaxRulesGroupCommand' - - prestashop.adapter.tax_rules_group.command_handler.bulk_delete_tax_rules_group_handler: - class: 'PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler\BulkDeleteTaxRulesGroupHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkDeleteTaxRulesGroupCommand' - - prestashop.adapter.tax_rules_group.command_handler.bulk_set_tax_rules_group_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler\BulkSetTaxRulesGroupStatusHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\BulkSetTaxRulesGroupStatusCommand' - - prestashop.adapter.tax_rules_group.query_handler.get_tax_rules_group_for_editing: - class: 'PrestaShop\PrestaShop\Adapter\TaxRulesGroup\QueryHandler\GetTaxRulesGroupForEditingHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Query\GetTaxRulesGroupForEditing' - - prestashop.adapter.tax_rules_group.command_handler.set_tax_rules_group_status_handler: - class: 'PrestaShop\PrestaShop\Adapter\TaxRulesGroup\CommandHandler\SetTaxRulesGroupStatusHandler' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\TaxRulesGroup\Command\SetTaxRulesGroupStatusCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/theme.yml b/src/PrestaShopBundle/Resources/config/services/adapter/theme.yml deleted file mode 100644 index e8cf8551..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/theme.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.theme.theme_multi_store_settings_form_data_provider: - class: 'PrestaShop\PrestaShop\Adapter\Theme\ThemeMultiStoreSettingsFormDataProvider' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.adapter.shop.context").isSingleShopContext()' diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/twig.yml b/src/PrestaShopBundle/Resources/config/services/adapter/twig.yml deleted file mode 100644 index cd1cf569..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/twig.yml +++ /dev/null @@ -1,10 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.twig.locale_extension: - class: PrestaShop\PrestaShop\Adapter\Twig\LocaleExtension - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.date_format_lite' - tags: - - { name: twig.extension } diff --git a/src/PrestaShopBundle/Resources/config/services/adapter/webservice.yml b/src/PrestaShopBundle/Resources/config/services/adapter/webservice.yml deleted file mode 100644 index 0f0e1dfd..00000000 --- a/src/PrestaShopBundle/Resources/config/services/adapter/webservice.yml +++ /dev/null @@ -1,29 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.webservice.webservice_key_eraser: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\WebserviceKeyEraser' - - prestashop.adapter.webservice.webservice_key_status_modifier: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\WebserviceKeyStatusModifier' - arguments: - - '@translator' - - prestashop.adapter.webservice.query_handler.get_webservice_key_for_editing_handler: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\QueryHandler\GetWebserviceKeyForEditingHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Webservice\Query\GetWebserviceKeyForEditing' - - prestashop.adapter.webservice.command_handler.add_webservice_key_handler: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\CommandHandler\AddWebserviceKeyHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Webservice\Command\AddWebserviceKeyCommand' - - prestashop.adapter.webservice.command_handler.edit_webservice_key_handler: - class: 'PrestaShop\PrestaShop\Adapter\Webservice\CommandHandler\EditWebserviceKeyHandler' - tags: - - name: tactician.handler - command: 'PrestaShop\PrestaShop\Core\Domain\Webservice\Command\EditWebserviceKeyCommand' diff --git a/src/PrestaShopBundle/Resources/config/services/alias.yml b/src/PrestaShopBundle/Resources/config/services/alias.yml deleted file mode 100644 index 74883fce..00000000 --- a/src/PrestaShopBundle/Resources/config/services/alias.yml +++ /dev/null @@ -1,13 +0,0 @@ -services: - _defaults: - public: true - - # Service aliases for backward campatibility - prestashop.core.api.stockMovement.repository: - alias: prestashop.core.api.stock_movement.repository - - prestashop.core.api.stockMovement.controller: - alias: prestashop.core.api.stock_movement.controller - - prestashop.twig.extension.dataFormatter: - alias: prestashop.twig.extension.data_formatter diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/api.yml b/src/PrestaShopBundle/Resources/config/services/bundle/api.yml deleted file mode 100644 index d082dc5d..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/api.yml +++ /dev/null @@ -1,25 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.api.query_params_collection: - abstract: true - class: PrestaShopBundle\Api\QueryParamsCollection - - prestashop.core.api.query_stock_params_collection: - parent: prestashop.core.api.query_params_collection - class: PrestaShopBundle\Api\QueryStockParamsCollection - public: true - - prestashop.core.api.query_stock_movement_params_collection: - parent: prestashop.core.api.query_params_collection - class: PrestaShopBundle\Api\QueryStockMovementParamsCollection - public: true - - prestashop.core.api.query_translation_params_collection: - parent: prestashop.core.api.query_params_collection - class: PrestaShopBundle\Api\QueryTranslationParamsCollection - public: true - - prestashop.core.api.stock.movements_collection: - class: PrestaShopBundle\Api\Stock\MovementsCollection diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/cache.yml b/src/PrestaShopBundle/Resources/config/services/bundle/cache.yml deleted file mode 100644 index be1d19b0..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/cache.yml +++ /dev/null @@ -1,29 +0,0 @@ -services: - _defaults: - public: true - - doctrine.cache.provider: - class: Doctrine\Common\Cache\FilesystemCache - arguments: - - "%kernel.cache_dir%/doctrine" - - guzzle.cache: - class: Csa\Bundle\GuzzleBundle\GuzzleHttp\Cache\DoctrineAdapter - arguments: - - "@doctrine.cache.provider" - - "%prestashop.addons.api_client.ttl%" - shared: false - - main.warmer.cache_warmer: - class: PrestaShopBundle\Cache\CacheWarmer - arguments: - - "@filesystem" - tags: - - { name: kernel.cache_warmer } - - prestashop.cache.refresh: - class: PrestaShopBundle\Service\Cache\Refresh - arguments: - - "@kernel" - calls: - - [addCacheClear, []] diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/controller.yml b/src/PrestaShopBundle/Resources/config/services/bundle/controller.yml deleted file mode 100644 index 96b65614..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/controller.yml +++ /dev/null @@ -1,135 +0,0 @@ -services: - _defaults: - public: true - - PrestaShopBundle\Controller\Api\ApiController: - abstract: true - class: PrestaShopBundle\Controller\Api\ApiController - calls: - - [setLogger, ['@logger']] - - [setContainer, ['@service_container']] - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.controller: - alias: PrestaShopBundle\Controller\Api\ApiController - - PrestaShopBundle\Controller\Api\StockController: - class: PrestaShopBundle\Controller\Api\StockController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - movements: "@prestashop.core.api.stock.movements_collection" - stockRepository: "@prestashop.core.api.stock.repository" - queryParams: "@prestashop.core.api.query_stock_params_collection" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.stock.controller: - alias: PrestaShopBundle\Controller\Api\StockController - - PrestaShopBundle\Controller\Api\StockMovementController: - class: PrestaShopBundle\Controller\Api\StockMovementController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - stockMovementRepository: "@prestashop.core.api.stock_movement.repository" - queryParams: "@prestashop.core.api.query_stock_movement_params_collection" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.stock_movement.controller: - alias: PrestaShopBundle\Controller\Api\StockMovementController - - PrestaShopBundle\Controller\Api\SupplierController: - class: PrestaShopBundle\Controller\Api\SupplierController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - supplierRepository: "@prestashop.core.api.supplier.repository" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.supplier.controller: - alias: PrestaShopBundle\Controller\Api\SupplierController - - PrestaShopBundle\Controller\Api\ManufacturerController: - class: PrestaShopBundle\Controller\Api\ManufacturerController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - manufacturerRepository: "@prestashop.core.api.manufacturer.repository" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.manufacturer.controller: - alias: PrestaShopBundle\Controller\Api\ManufacturerController - - PrestaShopBundle\Controller\Api\CategoryController: - class: PrestaShopBundle\Controller\Api\CategoryController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - categoryRepository: "@prestashop.core.api.category.repository" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.category.controller: - alias: PrestaShopBundle\Controller\Api\CategoryController - - PrestaShopBundle\Controller\Api\AttributeController: - class: PrestaShopBundle\Controller\Api\AttributeController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - featureAttributeRepository: "@prestashop.core.api.feature_attribute.repository" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.attribute.controller: - alias: PrestaShopBundle\Controller\Api\AttributeController - - PrestaShopBundle\Controller\Api\FeatureController: - class: PrestaShopBundle\Controller\Api\FeatureController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - featureAttributeRepository: "@prestashop.core.api.feature_attribute.repository" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.feature.controller: - alias: PrestaShopBundle\Controller\Api\FeatureController - - PrestaShopBundle\Controller\Api\I18nController: - class: PrestaShopBundle\Controller\Api\I18nController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.i18n.controller: - alias: PrestaShopBundle\Controller\Api\I18nController - - PrestaShopBundle\Controller\Api\TranslationController: - class: PrestaShopBundle\Controller\Api\TranslationController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - properties: - translationService: "@prestashop.service.translation" - queryParams: "@prestashop.core.api.query_translation_params_collection" - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.translation.controller: - alias: PrestaShopBundle\Controller\Api\TranslationController - - PrestaShopBundle\Controller\Api\Improve\Design\PositionsController: - class: PrestaShopBundle\Controller\Api\Improve\Design\PositionsController - parent: PrestaShopBundle\Controller\Api\ApiController - public: true - tags: - - { name: !php/const PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController::PRESTASHOP_CORE_CONTROLLERS_TAG } - - prestashop.core.api.improve.design.postions.controller: - alias: PrestaShopBundle\Controller\Api\Improve\Design\PositionsController diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/data_collector.yml b/src/PrestaShopBundle/Resources/config/services/bundle/data_collector.yml deleted file mode 100644 index 3f4d6117..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/data_collector.yml +++ /dev/null @@ -1,32 +0,0 @@ -services: - _defaults: - public: true - - prestashop.hooks_registry: - class: PrestaShopBundle\DataCollector\HookRegistry - - prestashop.hooks_collector: - class: PrestaShopBundle\DataCollector\HookDataCollector - arguments: ['@prestashop.hooks_registry'] - public: false - tags: - - {name: data_collector, template: '@PrestaShop/Admin/WebProfiler/hooks_collector.html.twig', id: 'ps.hooks_collector'} - - prestashop.bundle.data_collector.commands_and_queries_collector: - class: PrestaShopBundle\DataCollector\CommandsAndQueriesDataCollector - arguments: - - '@prestashop.core.command_bus.executed_command_registry' - tags: - - name: data_collector - id: ps.commands_and_queries_collector - template: '@PrestaShop/Admin/WebProfiler/commands_and_queries.html.twig' - - # Web Profiler Bundle - data_collector.config: - class: Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector - arguments: ["PrestaShop", "@=service('prestashop.core.foundation.version').getVersion()"] - public: false - calls: - - ["setKernel", ["@kernel"]] - tags: - - {name: data_collector, template: "@PrestaShop/Admin/WebProfiler/config.html.twig", id: "config", priority: "-255"} diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/event_listener.yml b/src/PrestaShopBundle/Resources/config/services/bundle/event_listener.yml deleted file mode 100644 index ef55f943..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/event_listener.yml +++ /dev/null @@ -1,112 +0,0 @@ -services: - _defaults: - public: true - - prestashop.user_locale.listener: - class: PrestaShopBundle\EventListener\UserLocaleListener - arguments: - - "@prestashop.adapter.legacy.context" - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 15 } - - prestashop.dispatcher.legacy_hooks.subscriber: - class: 'PrestaShopBundle\EventListener\ActionDispatcherLegacyHooksSubscriber' - arguments: ['@prestashop.core.hook.dispatcher'] - tags: - - { name: kernel.event_subscriber } - - prestashop.tokenized_url_listener: - class: PrestaShopBundle\EventListener\TokenizedUrlsListener - arguments: - - "@security.csrf.token_manager" - - "@router" - - "@=service('prestashop.user_provider').getUsername()" - - "@prestashop.adapter.legacy.context" - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - - # Priority 40 to be called before the RouterListener - prestashop.legacy_url_listener: - class: PrestaShopBundle\EventListener\LegacyUrlListener - arguments: - - "@prestashop.bundle.routing.converter.legacy_url_converter" - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 40 } - - # Priority 30 to be called after the RouterListener - prestashop.legacy_parameters_listener: - class: PrestaShopBundle\EventListener\LegacyParametersListener - arguments: - - "@prestashop.bundle.routing.converter.legacy_parameters_converter" - tags: - - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 30 } - - prestashop.multishop_command_listener: - class: PrestaShopBundle\EventListener\MultishopCommandListener - arguments: - - "@prestashop.adapter.shop.context" - - "@=service('kernel').getRootDir()" - tags: - - { name: kernel.event_listener, event: console.command, method: onConsoleCommand } - - prestashop.access_denied.listener: - class: PrestaShopBundle\EventListener\AccessDeniedListener - arguments: - - "@router" - - "@translator" - - "@session" - tags: - - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } - - prestashop.demo_mode_enabled.listener: - class: PrestaShopBundle\EventListener\DemoModeEnabledListener - arguments: - - "@router" - - "@translator" - - "@session" - - "@annotation_reader" - - "@=service('prestashop.adapter.legacy.configuration').getBoolean('_PS_MODE_DEMO_')" - tags: - - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } - - prestashop.module_activated.listener: - class: PrestaShopBundle\EventListener\ModuleActivatedListener - arguments: - - "@router" - - "@translator" - - "@session" - - "@annotation_reader" - - "@prestashop.core.admin.module.repository" - tags: - - { name: kernel.event_listener, event: kernel.controller, method: onKernelController } - - prestashop.bundle.event_listener.filter_category_search_criteria: - class: PrestaShopBundle\EventListener\FilterCategorySearchCriteriaListener - arguments: - - '@prestashop.adapter.grid.search.factory.search_criteria_with_category_parent_id' - tags: - - { name: kernel.event_listener, event: prestashop.search_criteria.filter, method: onFilterSearchCriteria } - - prestashop.bundle.event_listener.filter_cms_page_category_search_criteria: - class: PrestaShopBundle\EventListener\FilterCmsPageCategorySearchCriteriaListener - arguments: - - '@request_stack' - tags: - - { name: kernel.event_listener, event: prestashop.search_criteria.filter, method: onFilterSearchCriteria } - - prestashop.bundle.event_listener.back_url_redirect_response_listener: - class: PrestaShopBundle\EventListener\BackUrlRedirectResponseListener - arguments: - - '@prestashop.core.uti.back_url_provider' - - "@prestashop.adapter.legacy.context" - tags: - - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } - - prestashop.bundle.event_listener.module_guard_listener: - class: PrestaShopBundle\EventListener\ModuleGuardListener - arguments: - - '@prestashop.core.security.folder_guard.vendor' - - '%modules_dir%' - - '@logger' - tags: - - { name: kernel.event_subscriber } diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form.yml deleted file mode 100644 index 860de7a2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form.yml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: form/*.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_builder.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_builder.yml deleted file mode 100644 index 873e66e5..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_builder.yml +++ /dev/null @@ -1,17 +0,0 @@ -services: - _defaults: - public: true - - prestashop.admin.import.form_builder: - class: 'Symfony\Component\Form\FormBuilder' - factory: 'form.factory:createNamedBuilder' - arguments: - - '' - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportType' - - prestashop.admin.import_data_configuration.form_builder: - class: 'Symfony\Component\Form\FormBuilder' - factory: 'form.factory:createNamedBuilder' - arguments: - - '' - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportDataConfigurationType' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_provider.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_provider.yml deleted file mode 100644 index cba06c6e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_provider.yml +++ /dev/null @@ -1,194 +0,0 @@ -services: - _defaults: - public: true - - prestashop.admin.shipping_preferences.data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\Shipping\Preferences\PreferencesFormDataProvider' - arguments: - - '@prestashop.adapter.shipping_preferences.handling_configuration' - - '@prestashop.adapter.shipping_preferences.carrier_options_configuration' - - '@translator' - - prestashop.admin.order.invoices.by_date.data_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoicesByDateDataProvider' - arguments: - - '@prestashop.adapter.data_provider.order_invoice' - - prestashop.admin.order.invoices.by_status.data_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoicesByStatusDataProvider' - - prestashop.admin.order.invoices.options.data_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoiceOptionsDataProvider' - arguments: - - '@prestashop.adapter.order.invoice_options.configuration' - - '@=service("prestashop.adapter.data_provider.order_invoice").getNextInvoiceNumber()' - - prestashop.admin.customer_preferences.data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\CustomerPreferences\CustomerPreferencesDataProvider' - arguments: - - '@prestashop.adapter.customer.customer_configuration' - - '@translator' - - prestashop.admin.order_preferences.data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\OrderPreferences\OrderPreferencesFormDataProvider' - arguments: - - '@prestashop.adapter.order_general.configuration' - - '@prestashop.adapter.order_gift.configuration' - - '@translator' - - '@prestashop.adapter.data_provider.cms' - - prestashop.admin.product_preferences.data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\ProductPreferencesFormDataProvider' - arguments: - - '@prestashop.adapter.product_general.configuration' - - '@prestashop.adapter.product_pagination.configuration' - - '@prestashop.adapter.product_page.configuration' - - '@prestashop.adapter.product_stock.configuration' - - '@translator' - - prestashop.adapter.performance.form_provider: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\PerformanceFormDataProvider' - arguments: - - '@prestashop.adapter.smarty_cache.configuration' - - '@prestashop.adapter.debug_mode.configuration' - - '@prestashop.adapter.optional_features.configuration' - - '@prestashop.adapter.ccc.configuration' - - '@prestashop.adapter.media_servers.configuration' - - '@prestashop.adapter.caching.configuration' - - prestashop.adapter.maintenance.form_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\MaintenanceFormDataProvider' - arguments: - - '@prestashop.adapter.maintenance.configuration' - - prestashop.adapter.administration.form_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\FormDataProvider' - arguments: - - '@prestashop.adapter.general.configuration' - - '@prestashop.adapter.upload_quota.configuration' - - '@prestashop.adapter.notifications.configuration' - - prestashop.adapter.preferences.form_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\PreferencesFormDataProvider' - arguments: - - '@prestashop.adapter.preferences.configuration' - - prestashop.adapter.logs.form_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Logs\LogsFormDataProvider' - arguments: - - '@prestashop.adapter.logs.configuration' - - prestashop.admin.import.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportFormDataProvider' - arguments: - - '@prestashop.core.import.file_finder' - - '@session' - - prestashop.admin.import_data_configuration.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportDataConfigurationFormDataProvider' - arguments: - - '@prestashop.core.import.dir' - - '@prestashop.core.import.factory.data_row.collection_factory' - - '@prestashop.core.admin.import_match.repository' - - '@prestashop.adapter.import.data_match_saver' - - '@=service("prestashop.core.form.choice_provider.import_entity_field").getChoices()' - - prestashop.adapter.order.delivery.slip.options.form_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Delivery\SlipOptionsFormDataProvider' - arguments: - - '@prestashop.adapter.order.delivery.slip.options.configuration' - - prestashop.adapter.order.delivery.slip.pdf.form_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Delivery\SlipPdfFormDataProvider' - arguments: - - '@prestashop.adapter.order.delivery.slip.pdf.configuration' - - prestashop.admin.localization.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Localization\LocalizationFormDataProvider' - arguments: - - '@prestashop.adapter.localization.configuration' - - '@prestashop.adapter.local_units.configuration' - - '@prestashop.adapter.localization_advanced.configuration' - - prestashop.admin.geolocation.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Geolocation\GeolocationFormDataProvider' - arguments: - - '@prestashop.adapter.geolocation_by_ip_address.configuration' - - '@prestashop.adapter.geolocation_ip_address_whitelist.configuration' - - '@prestashop.adapter.geolocation_options.configuration' - - '@prestashop.core.geolocation.geo_lite_city.checker' - - '@prestashop.core.validation.validator' - - prestashop.admin.payment_preferences.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\Payment\Preferences\PaymentPreferencesFormDataProvider' - arguments: - - '@prestashop.adapter.payment_module_preferences.configuration' - - prestashop.admin.email_configuration.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Email\EmailConfigurationFormDataProvider' - arguments: - - '@prestashop.core.email.email_configurator' - - '@prestashop.core.email.smtp_configurator' - - prestashop.admin.request_sql_settings.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestSettingsFormDataProvider' - arguments: - - '@prestashop.core.sql_manager.configuration.sql_request_configuration' - - prestashop.admin.webservice.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Webservice\WebserviceFormDataProvider' - arguments: - - '@prestashop.adapter.webservice.configuration' - - prestashop.admin.backup.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Backup\BackupDataProvider' - arguments: - - '@prestashop.core.backup.options_configuration' - - prestashop.admin.traffic_seo.meta_settings.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\MetaSettingsFormDataProvider' - arguments: - - '@prestashop.adapter.meta.set_up_urls.configuration' - - '@prestashop.adapter.meta.shop_url.configuration' - - '@prestashop.adapter.meta.url_schema.configuration' - - '@prestashop.adapter.meta.seo_options.configuration' - - '@translator' - - '@prestashop.adapter.routes.route_validator' - - '@prestashop.adapter.validate' - - prestashop.admin.employee_options.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Employee\EmployeeOptionsFormDataProvider' - arguments: - - '@prestashop.core.team.employee.configuration.employee_options_configuration' - - prestashop.admin.currency.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Currencies\CurrencyFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.legacy.configuration").get("PS_ACTIVE_CRONJOB_EXCHANGE_RATE")' - - prestashop.admin.tax_options.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Tax\TaxOptionsFormDataProvider' - arguments: - - '@prestashop.core.tax.tax_options_configuration' - - prestashop.admin.improve.design.theme.shop_logos.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\ShopLogosFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.theme.theme_multi_store_settings_form_data_provider' - - prestashop.admin.mail_theme.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\MailThemeFormDataProvider' - arguments: - - '@prestashop.core.mail_theme.configuration' - - prestashop.admin.merchandise_return_options.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\CustomerService\MerchandiseReturn\MerchandiseReturnOptionsFormDataProvider' - arguments: - - '@prestashop.core.merchandise_return.configuration.merchandise_return_options_configuration' - - prestashop.admin.sell.order.credit_slip.credit_slip_options_form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip\CreditSlipOptionsFormDataProvider' - arguments: - - '@prestashop.core.credit_slip.credit_slip_options.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_transformer.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_transformer.yml deleted file mode 100644 index c7d7865a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_data_transformer.yml +++ /dev/null @@ -1,21 +0,0 @@ -services: - _defaults: - public: true - - prestashop.bundle.form.data_transformer.string_array_to_integer_array: - class: 'PrestaShopBundle\Form\DataTransformer\StringArrayToIntegerArrayDataTransformer' - - prestashop.bundle.form.data_transformer.default_language_to_filled_array: - class: 'PrestaShopBundle\Form\DataTransformer\DefaultLanguageToFilledArrayDataTransformer' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("PS_LANG_DEFAULT")' - - prestashop.bundle.form.data_transformer.arabic_to_latin_digit: - class: 'PrestaShopBundle\Form\DataTransformer\ArabicToLatinDigitDataTransformer' - arguments: - - '@prestashop.core.util.arabic_to_latin_digit_converter' - - prestashop.bundle.form.data_transformer.idn_converter: - class: 'PrestaShopBundle\Form\DataTransformer\IDNConverterDataTransformer' - arguments: - - '@prestashop.core.util.internationalized_domain_name_converter' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_extension.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_extension.yml deleted file mode 100644 index 8fd537e2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_extension.yml +++ /dev/null @@ -1,29 +0,0 @@ -services: - _defaults: - public: true - - form.type.extension.money: - class: 'PrestaShopBundle\Form\Admin\Type\CustomMoneyType' - tags: - - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\MoneyType } - - form.type.extension.resizable_text: - class: 'PrestaShopBundle\Form\Admin\Type\ResizableTextType' - tags: - - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\TextType } - - form.extension.help_text: - class: 'PrestaShopBundle\Form\Admin\Extension\HelpTextExtension' - tags: - - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType } - - form.extension.data_list: - class: 'PrestaShopBundle\Form\Extension\DataListExtension' - tags: - - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\TextType } - - form.extension.row_attributes: - class: 'PrestaShopBundle\Form\Admin\Extension\RowAttributesExtension' - tags: - - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType } - diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_factory.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_factory.yml deleted file mode 100644 index c90ccc67..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_factory.yml +++ /dev/null @@ -1,10 +0,0 @@ -services: - _defaults: - public: true - - prestashop.bundle.form.admin.improve.design.theme.page_layout_customization_form_factory: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\PageLayoutCustomizationFormFactory' - arguments: - - '@form.factory' - - '@prestashop.core.addon.theme.repository' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.theme.getName()' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_handler.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_handler.yml deleted file mode 100644 index ae3d7da7..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_handler.yml +++ /dev/null @@ -1,390 +0,0 @@ -services: - _defaults: - public: true - - prestashop.adapter.performance.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.performance.form_provider' - - - 'smarty': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\SmartyType' - 'debug_mode': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\DebugModeType' - 'optional_features': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\OptionalFeaturesType' - 'ccc': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\CombineCompressCacheType' - 'media_servers': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\MediaServersType' - 'caching': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\CachingType' - 'add_memcache_server': 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\MemcacheServerType' - - 'PerformancePage' - - prestashop.adapter.maintenance.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.maintenance.form_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\MaintenanceType' - - 'MaintenancePage' - - prestashop.adapter.administration.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.administration.form_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\GeneralType' - 'upload_quota': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\UploadQuotaType' - 'notifications': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\NotificationsType' - - 'AdministrationPage' - - prestashop.admin.shipping_preferences.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.shipping_preferences.data_provider' - - - 'handling': 'PrestaShopBundle\Form\Admin\Improve\Shipping\Preferences\HandlingType' - 'carrier_options': 'PrestaShopBundle\Form\Admin\Improve\Shipping\Preferences\CarrierOptionsType' - - 'ShippingPreferencesPage' - - prestashop.admin.order.invoices.by_date.form_handler: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoiceByDateFormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.order.invoices.by_date.data_provider' - - - 'generate_by_date': 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\GenerateByDateType' - - 'OrdersInvoicesByDate' - - '@prestashop.adapter.data_provider.order_invoice' - - '@prestashop.adapter.pdf.generator.invoice' - - prestashop.admin.order.invoices.by_status.form_handler: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoiceByStatusFormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.order.invoices.by_status.data_provider' - - - 'generate_by_status': 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\GenerateByStatusType' - - 'OrdersInvoicesByStatus' - - '@prestashop.adapter.data_provider.order_invoice' - - '@prestashop.adapter.pdf.generator.invoice' - - prestashop.admin.order.invoices.options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.order.invoices.options.data_provider' - - - 'invoice_options': 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoiceOptionsType' - - 'OrdersInvoicesOptions' - - prestashop.admin.customer_preferences.form_handler: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\CustomerPreferences\CustomerPreferencesFormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.customer_preferences.data_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\CustomerPreferences\GeneralType' - - 'CustomerPreferencesPage' - calls: - - method: setTabRepository - arguments: - - '@prestashop.core.admin.tab.repository' - - prestashop.admin.order_preferences.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.order_preferences.data_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\OrderPreferences\GeneralType' - 'gift_options': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\OrderPreferences\GiftOptionsType' - - 'OrderPreferencesPage' - - prestashop.admin.product_preferences.form_handler: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\ProductPreferencesFormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.product_preferences.data_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\GeneralType' - 'pagination': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\PaginationType' - 'page': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\PageType' - 'stock': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\StockType' - - 'ProductPreferencesPage' - calls: - - method: setCacheClearer - arguments: - - '@prestashop.adapter.cache_clearer' - - prestashop.adapter.preferences.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.preferences.form_provider' - - - 'general': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\PreferencesType' - - 'GeneralPage' - - prestashop.adapter.logs.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.logs.form_provider' - - - 'logs_by_email': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Logs\LogsByEmailType' - - 'LogsPage' - - prestashop.admin.import.form_handler: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportFormHandler' - arguments: - - '@prestashop.admin.import.form_builder' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.import.form_data_provider' - - 'Import' - - prestashop.admin.import_data_configuration.form_handler: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportFormHandler' - arguments: - - '@prestashop.admin.import_data_configuration.form_builder' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.import_data_configuration.form_data_provider' - - 'ImportDataConfiguration' - - prestashop.adapter.order.delivery.slip.options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.order.delivery.slip.options.form_provider' - - - 'options': 'PrestaShopBundle\Form\Admin\Sell\Order\Delivery\SlipOptionsType' - - 'OrderDeliverySlipOptions' - - prestashop.adapter.order.delivery.slip.pdf.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.adapter.order.delivery.slip.pdf.form_provider' - - - 'pdf': 'PrestaShopBundle\Form\Admin\Sell\Order\Delivery\SlipPdfType' - - 'OrderDeliverySlipPdf' - - 'slip_pdf_form' - - prestashop.admin.geolocation.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.geolocation.form_data_provider' - - - 'geolocation_by_id_address': 'PrestaShopBundle\Form\Admin\Improve\International\Geolocation\GeolocationByIpAddressType' - 'geolocation_ip_address_whitelist': 'PrestaShopBundle\Form\Admin\Improve\International\Geolocation\GeolocationIpAddressWhitelistType' - 'geolocation_options': 'PrestaShopBundle\Form\Admin\Improve\International\Geolocation\GeolocationOptionsType' - - 'GeolocationPage' - - prestashop.admin.localization.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.localization.form_data_provider' - - - 'configuration': 'PrestaShopBundle\Form\Admin\Improve\International\Localization\LocalizationConfigurationType' - 'local_units': 'PrestaShopBundle\Form\Admin\Improve\International\Localization\LocalUnitsType' - 'advanced': 'PrestaShopBundle\Form\Admin\Improve\International\Localization\AdvancedConfigurationType' - - 'LocalizationPage' - - prestashop.admin.payment_preferences.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.payment_preferences.form_data_provider' - - - 'payment_module_preferences': 'PrestaShopBundle\Form\Admin\Improve\Payment\Preferences\PaymentModulePreferencesType' - - 'PaymentPreferences' - - prestashop.admin.email_configuration.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.email_configuration.form_data_provider' - - - 'email_config': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Email\EmailConfigurationType' - 'smtp_config': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Email\SmtpConfigurationType' - - 'EmailConfiguration' - - prestashop.admin.request_sql_settings.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.request_sql_settings.form_data_provider' - - - 'settings': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestSettingsType' - - 'RequestSql' - - prestashop.admin.backup.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.backup.form_data_provider' - - - 'backup_options': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Backup\BackupOptionsType' - - 'Backup' - - prestashop.adapter.webservice.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.webservice.form_data_provider' - - - 'webservice_configuration': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Webservice\WebserviceConfigurationType' - - 'WebservicePage' - - prestashop.admin.translations_settings.modify_translations.form_handler: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\TranslationsSettingsFormHandler' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - 'PrestaShopBundle\Form\Admin\Improve\International\Translations\ModifyTranslationsType' - - 'TranslationSettingsPageModifyTranslations' - - prestashop.admin.translations_settings.add_update_language.form_handler: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\TranslationsSettingsFormHandler' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - 'PrestaShopBundle\Form\Admin\Improve\International\Translations\AddUpdateLanguageType' - - 'TranslationSettingsPageAddUpdateLanguage' - - prestashop.admin.translations_settings.export_language.form_handler: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\TranslationsSettingsFormHandler' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - 'PrestaShopBundle\Form\Admin\Improve\International\Translations\ExportThemeLanguageType' - - 'TranslationSettingsPageExportLanguage' - - prestashop.admin.translations_settings.copy_language.form_handler: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\TranslationsSettingsFormHandler' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - 'PrestaShopBundle\Form\Admin\Improve\International\Translations\CopyLanguageType' - - 'TranslationSettingsPageCopyLanguage' - - prestashop.admin.meta_settings.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.traffic_seo.meta_settings.form_data_provider' - - - 'set_up_urls': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\SetUpUrlType' - 'shop_urls': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\ShopUrlType' - 'url_schema': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\UrlSchemaType' - 'seo_options': 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\SEOOptionsType' - - 'MetaPage' - - 'meta_settings_form' - - prestashop.admin.employee_options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.employee_options.form_data_provider' - - - 'options': 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Employee\EmployeeOptionsType' - - 'Employee' - - prestashop.admin.currency_settings.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.currency.form_data_provider' - - - 'exchange_rates': 'PrestaShopBundle\Form\Admin\Improve\International\Currencies\CurrencyExchangeRateType' - - 'Currency' - - prestashop.admin.shop_logos_settings.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.improve.design.theme.shop_logos.form_data_provider' - - - 'shop_logos': 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\ShopLogosType' - - 'ShopLogo' - - # Entity form handler - prestashop.admin.request_sql.form_handler: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestFormHandler' - arguments: - - '@form.factory' - - '@prestashop.adapter.sql_manager.request_sql_form_data_validator' - - '@prestashop.bundle.form.admin.configure.advanced_parameters.request_sql.form_data_provider' - - prestashop.bundle.form.admin.configure.advanced_parameters.request_sql.form_data_provider: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.core.query_bus' - - prestashop.admin.tax_options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.tax_options.form_data_provider' - - - 'options': 'PrestaShopBundle\Form\Admin\Improve\International\Tax\TaxOptionsType' - - 'Tax' - - prestashop.admin.mail_theme.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.mail_theme.form_data_provider' - - - 'configuration': 'PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\MailThemeConfigurationType' - - 'MailTheme' - - prestashop.admin.merchandise_return_options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.merchandise_return_options.form_data_provider' - - - 'options': 'PrestaShopBundle\Form\Admin\Sell\CustomerService\MerchandiseReturn\MerchandiseReturnOptionsType' - - 'MerchandiseReturn' - - prestashop.admin.credit_slip_options.form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\FormHandler' - arguments: - - '@=service("form.factory").createBuilder()' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.admin.sell.order.credit_slip.credit_slip_options_form_data_provider' - - - 'options': 'PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip\CreditSlipOptionsType' - - 'CreditSlip' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type.yml deleted file mode 100644 index 797bd9aa..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type.yml +++ /dev/null @@ -1,1148 +0,0 @@ -imports: - - { resource: 'form_type/*' } - -services: - _defaults: - public: true - - form.type.date_picker: - class: PrestaShopBundle\Form\Admin\Type\DatePickerType - arguments: - - '@prestashop.bundle.form.data_transformer.arabic_to_latin_digit' - tags: - - { name: form.type } - - form.type.email: - class: PrestaShopBundle\Form\Admin\Type\EmailType - arguments: - - '@prestashop.bundle.form.data_transformer.idn_converter' - tags: - - { name: form.type } - - form.type.product.simple_category: - class: PrestaShopBundle\Form\Admin\Category\SimpleCategory - arguments: - - "@translator" - - "@prestashop.adapter.data_provider.category" - tags: - - { name: form.type } - - form.type.product.categories_tree: - class: 'PrestaShopBundle\Form\Admin\Type\ChoiceCategoriesTreeType' - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.translate: - class: 'PrestaShopBundle\Form\Admin\Type\TranslateType' - parent: 'form.type.common_type' - arguments: - - '@router.default' - - "@=service('prestashop.adapter.legacy.configuration').getBoolean('PS_BO_ALLOW_EMPLOYEE_FORM_LANG')" - - "@=service('prestashop.adapter.legacy.context').getContext().cookie.employee_form_lang" - - "@=service('prestashop.adapter.legacy.configuration').getInt('PS_LANG_DEFAULT')" - public: true - tags: - - { name: form.type } - - form.type.product.feature: - class: PrestaShopBundle\Form\Admin\Feature\ProductFeature - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@router" - - "@prestashop.adapter.data_provider.feature" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.attachment: - class: PrestaShopBundle\Form\Admin\Product\ProductAttachement - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.combination: - class: PrestaShopBundle\Form\Admin\Product\ProductCombination - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.custom_field: - class: PrestaShopBundle\Form\Admin\Product\ProductCustomField - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.information: - class: PrestaShopBundle\Form\Admin\Product\ProductInformation - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@router" - - "@prestashop.adapter.data_provider.category" - - "@prestashop.adapter.data_provider.product" - - "@prestashop.adapter.data_provider.feature" - - "@prestashop.adapter.data_provider.manufacturer" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.options: - class: PrestaShopBundle\Form\Admin\Product\ProductOptions - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.data_provider.product" - - "@prestashop.adapter.data_provider.supplier" - - "@prestashop.adapter.data_provider.currency" - - "@prestashop.adapter.data_provider.attachment" - - "@router" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.price: - class: PrestaShopBundle\Form\Admin\Product\ProductPrice - arguments: - - "@translator" - - "@prestashop.adapter.data_provider.tax" - - "@router" - - "@prestashop.adapter.shop.context" - - "@prestashop.adapter.data_provider.country" - - "@prestashop.adapter.data_provider.currency" - - "@prestashop.adapter.data_provider.group" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.data_provider.customer" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.quantity: - class: PrestaShopBundle\Form\Admin\Product\ProductQuantity - arguments: - - "@translator" - - "@router" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.seo: - class: PrestaShopBundle\Form\Admin\Product\ProductSeo - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@router" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.shipping: - class: PrestaShopBundle\Form\Admin\Product\ProductShipping - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.data_provider.warehouse" - - "@prestashop.adapter.data_provider.carrier" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.specific_price: - class: PrestaShopBundle\Form\Admin\Product\ProductSpecificPrice - arguments: - - "@router" - - "@translator" - - "@prestashop.adapter.shop.context" - - "@prestashop.adapter.data_provider.country" - - "@prestashop.adapter.data_provider.currency" - - "@prestashop.adapter.data_provider.group" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.data_provider.customer" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.supplier_combination: - class: PrestaShopBundle\Form\Admin\Product\ProductSupplierCombination - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.data_provider.currency" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.virtual: - class: PrestaShopBundle\Form\Admin\Product\ProductVirtual - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.product.warehouse_combination: - class: PrestaShopBundle\Form\Admin\Product\ProductWarehouseCombination - arguments: - - "@translator" - - "@prestashop.adapter.legacy.context" - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.typeahead.product: - class: PrestaShopBundle\Form\Admin\Type\TypeaheadProductCollectionType - arguments: - - "@prestashop.adapter.data_provider.product" - - "@prestashop.adapter.data_provider.category" - tags: - - { name: form.type } - - form.type.typeahead.product_pack: - class: PrestaShopBundle\Form\Admin\Type\TypeaheadProductPackCollectionType - arguments: - - "@prestashop.adapter.data_provider.product" - tags: - - { name: form.type } - - form.type.typeahead.customer: - class: PrestaShopBundle\Form\Admin\Type\TypeaheadCustomerCollectionType - arguments: - - "@prestashop.adapter.data_provider.customer" - tags: - - { name: form.type } - - form.type.product.combination_bulk: - class: PrestaShopBundle\Form\Admin\Product\ProductCombinationBulk - arguments: - - "@translator" - - "@prestashop.adapter.legacy.configuration" - tags: - - { name: form.type } - - form.type.product.categories: - class: PrestaShopBundle\Form\Admin\Product\ProductCategories - arguments: - - "@translator" - - "@prestashop.adapter.data_provider.category" - - "@=service('prestashop.adapter.legacy.context').getLanguages()" - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - tags: - - { name: form.type } - - form.type.translatable.aware: - abstract: true - parent: 'form.type.common_type' - public: true - arguments: - - "@translator" - - "@=service('prestashop.adapter.legacy.context').getLanguages()" - - form.type.order.invoices.generate_by_date: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\GenerateByDateType' - parent: 'form.type.common_type' - public: true - tags: - - { name: form.type } - - form.type.order.invoices.generate_by_status: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\GenerateByStatusType' - parent: 'form.type.common_type' - public: true - arguments: - - '@prestashop.core.form.choice_provider.order_state_by_id' - - '@=service("prestashop.core.api.order_invoice.repository").countByOrderState(service("prestashop.adapter.shop.context").getContextListShopID())' - tags: - - { name: form.type } - - form.type.order.invoices.invoice_options: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Invoices\InvoiceOptionsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@prestashop.core.form.choice_provider.invoice_model_by_name' - - '@=service("prestashop.adapter.data_provider.order_invoice").getNextInvoiceNumber()' - tags: - - { name: form.type } - - form.type.performance.smarty: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\SmartyType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.performance.debug_mode: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\DebugModeType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.performance.optional_features: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\OptionalFeaturesType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.combination_feature").isUsed()' - tags: - - { name: form.type } - - form.type.performance.ccc: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\CombineCompressCacheType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.performance.media_servers: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\MediaServersType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.performance.memcache_servers: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\MemcacheServerType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.performance.caching: - class: 'PrestaShopBundle\Form\Admin\AdvancedParameters\Performance\CachingType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.shop_parameters.general: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\PreferencesType' - parent: 'form.type.translatable.aware' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.adapter.shop.context").isShopContext()' - - '@=service("prestashop.adapter.shop.context").isAllContext()' - public: true - calls: - - ['setIsSecure', ["@=service('request_stack').getCurrentRequest().isSecure()"]] - tags: - - { name: form.type } - - form.type.maintenance.general: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\General\MaintenanceType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.admininistration.general: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\GeneralType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.administration.upload_quota: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\UploadQuotaType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.administration.notification: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Administration\NotificationsType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.common_type: - abstract: true - - form.type.shipping_preferences.handling: - class: 'PrestaShopBundle\Form\Admin\Improve\Shipping\Preferences\HandlingType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@prestashop.adapter.data_provider.currency' - tags: - - { name: form.type } - - form.type.shipping_preferences.carrier_options: - class: 'PrestaShopBundle\Form\Admin\Improve\Shipping\Preferences\CarrierOptionsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.data_provider.carrier").getActiveCarriersChoices()' - - '@=service("prestashop.adapter.data_provider.carrier").getOrderByChoices()' - - '@=service("prestashop.adapter.data_provider.carrier").getOrderWayChoices()' - tags: - - { name: form.type } - - form.type.product_preferences.general: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\GeneralType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.product_preferences.stock: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\ProductPreferences\StockType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.customer_preferences.general: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\CustomerPreferences\GeneralType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.order_preferences.general: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\OrderPreferences\GeneralType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.data_provider.currency").getDefaultCurrencyIsoCode()' - - '@=service("prestashop.adapter.data_provider.cms").getCmsChoices()' - tags: - - { name: form.type } - - form.type.order_preferences.gift_options: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\OrderPreferences\GiftOptionsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.data_provider.currency").getDefaultCurrencyIsoCode()' - - '@=service("prestashop.adapter.data_provider.tax").getTaxRulesGroupChoices()' - tags: - - { name: form.type } - - form.type.import.import: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.order.delivery.slip.options: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\Delivery\SlipOptionsType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.localization_configuration: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Localization\LocalizationConfigurationType' - arguments: - - '@=service("prestashop.core.form.choice_provider.language_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.currency_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.timezone_by_name").getChoices()' - tags: - - { name: form.type } - - form.type.localization.import_pack: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Localization\ImportLocalizationPackType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.localization_pack_by_iso_code").getChoices()' - tags: - - { name: form.type } - - form.type.geolocation.options: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Geolocation\GeolocationOptionsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.country_by_iso_code").getChoices()' - - '@prestashop.adapter.legacy.configuration' - tags: - - { name: form.type } - - form.type.payment.module_currency_restriction: - class: 'PrestaShopBundle\Form\Admin\Improve\Payment\Preferences\PaymentModulePreferencesType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.module.payment_module_provider").getPaymentModuleList()' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.group_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.carrier_by_reference_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.currency_by_id").getChoices()' - - '@prestashop.adapter.data_provider.country' - tags: - - { name: form.type } - - form.type.email.email_configuration: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Email\EmailConfigurationType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@prestashop.core.form.choice_provider.mail_method' - - '@prestashop.core.form.choice_provider.contact_by_id' - tags: - - { name: form.type } - - form.type.translations.modify: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\ModifyTranslationsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.translation_type").getChoices()' - - '@=service("prestashop.core.form.choice_provider.email_content_type").getChoices()' - - '@=service("prestashop.core.form.choice_provider.theme_by_name").getChoices()' - - '@=service("prestashop.core.form.choice_provider.module_by_name").getChoices()' - tags: - - { name: form.type } - - form.type.translations.add_update_language: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\AddUpdateLanguageType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.non_installed_localization").getChoices()' - tags: - - { name: form.type } - - form.type.translations.export_language: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\ExportThemeLanguageType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.theme_by_name").getChoices()' - tags: - - { name: form.type } - - form.type.translations.copy_language: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Translations\CopyLanguageType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.theme_by_name").getChoices()' - tags: - - { name: form.type } - - form.type.shop.traffic_seo.meta.set_up_url: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\SetUpUrlType' - arguments: - - '@=service("prestashop.core.form.choice_provider.canonical_redirect_type").getChoices()' - - '@=service("prestashop.core.util.url.url_file_checker").isHtaccessFileWritable()' - - '@=service("prestashop.adapter.hosting_information").isHostMode()' - tags: - - { name: form.type } - - form.type.shop.traffic_seo.meta.shop_url: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\ShopUrlType' - arguments: - - '@=service("prestashop.adapter.hosting_information").isHostMode()' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.shop_url").doesMainShopUrlExist()' - tags: - - { name: form.type } - - form.type.shop.traffic_seo.meta.url_schema: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\UrlSchemaType' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("PS_REWRITING_SETTINGS")' - tags: - - { name: form.type } - - form.type.shop.traffic_seo.meta: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\MetaType' - arguments: - - '@=service("prestashop.core.form.choice_provider.default_meta_page_name").getChoices()' - - '@=service("prestashop.core.form.choice_provider.module_meta_page_name").getChoices()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.catalog.abstract_category: - class: 'PrestaShopBundle\Form\Admin\Catalog\Category\AbstractCategoryType' - abstract: true - parent: 'form.type.translatable.aware' - arguments: - - '@=service("prestashop.core.form.choice_provider.group_by_id").getChoices()' - - '@prestashop.adapter.feature.multistore' - - '@prestashop.adapter.legacy.configuration' - public: true - - form.type.category.delete_categories: - class: 'PrestaShopBundle\Form\Admin\Sell\Category\DeleteCategoriesType' - arguments: - - '@=service("prestashop.core.form.choice_provider.category_delete_mode").getChoices()' - tags: - - { name: form.type } - - from.type.yes_and_no_choice: - class: 'PrestaShopBundle\Form\Admin\Type\YesAndNoChoiceType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.team.employee.employee_options: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Employee\EmployeeOptionsType' - parent: 'form.type.translatable.aware' - arguments: - - '@=service("prestashop.core.team.employee.configuration.options_checker").canBeChanged()' - public: true - tags: - - { name: form.type } - - form.type.common.team.profile_choice: - class: 'PrestaShopBundle\Form\Admin\Type\Common\Team\ProfileChoiceType' - arguments: - - '@=service("prestashop.adapter.form.choice_provider.profile_by_id_choice_provider").getChoices()' - tags: - - { name: form.type } - - form.type.import.import_data_configuration: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Import\ImportDataConfigurationType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.import_match_configuration").getChoices()' - - '@=service("prestashop.core.form.choice_provider.import_entity_field").getChoices()' - - form.type.common.country_choice: - class: 'PrestaShopBundle\Form\Admin\Type\CountryChoiceType' - arguments: - - '@prestashop.core.form.choice_provider.country_by_id' - - '@prestashop.core.form.choice_provider.country_by_id' - tags: - - { name: form.type } - - form.type.design.theme.page_layouts_customization: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\PageLayoutsCustomizationType' - arguments: - - '@=service("prestashop.core.form.choice_provider.theme_page_layouts").getChoices()' - tags: - - { name: form.type } - - form.type.catalog.category: - class: 'PrestaShopBundle\Form\Admin\Catalog\Category\CategoryType' - parent: 'form.type.catalog.abstract_category' - public: true - tags: - - { name: form.type } - - form.type.catalog.root_category: - class: 'PrestaShopBundle\Form\Admin\Catalog\Category\RootCategoryType' - parent: 'form.type.catalog.abstract_category' - public: true - tags: - - { name: form.type } - - form.type.common.category_choice_tree: - class: 'PrestaShopBundle\Form\Admin\Type\CategoryChoiceTreeType' - arguments: - - '@=service("prestashop.adapter.form.choice_provider.category_tree_choice_provider").getChoices()' - tags: - - { name: form.type } - - form.type.common.translatable: - class: 'PrestaShopBundle\Form\Admin\Type\TranslatableType' - arguments: - - "@=service('prestashop.adapter.legacy.context').getAvailableLanguages()" - - '@router.default' - - "@=service('prestashop.adapter.legacy.configuration').getBoolean('PS_BO_ALLOW_EMPLOYEE_FORM_LANG')" - - "@=service('prestashop.adapter.legacy.context').getContext().cookie.employee_form_lang" - - "@=service('prestashop.adapter.legacy.configuration').getInt('PS_LANG_DEFAULT')" - tags: - - { name: form.type } - - form.type.common.shop_choice_tree: - class: 'PrestaShopBundle\Form\Admin\Type\ShopChoiceTreeType' - arguments: - - "@=service('prestashop.adapter.form.choice_provider.shop_tree_choice_provider').getChoices()" - - '@prestashop.bundle.form.data_transformer.string_array_to_integer_array' - tags: - - { name: form.type } - - form.type.search_and_reset: - class: 'PrestaShopBundle\Form\Admin\Type\SearchAndResetType' - arguments: - - '@router.default' - tags: - - { name: form.type } - - form.type.database.sql_request: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestType' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.customer.required_fields: - class: 'PrestaShopBundle\Form\Admin\Sell\Customer\RequiredFieldsType' - arguments: - - '@=service("prestashop.core.form.choice_provider.customer_required_fields").getChoices()' - tags: - - { name: form.type } - - prestashop.bundle.form.admin.sell.customer.customer: - class: 'PrestaShopBundle\Form\Admin\Sell\Customer\CustomerType' - arguments: - - '@=service("prestashop.adapter.form.choice_provider.gender_by_id_choice_provider").getChoices()' - - '@=service("prestashop.adapter.form.choice_provider.group_by_id_choice_provider").getChoices()' - - '@=service("prestashop.adapter.form.choice_provider.risk_by_id_choice_provider").getChoices()' - - '@=service("prestashop.core.b2b.b2b_feature").isActive()' - - '@=service("prestashop.adapter.legacy.configuration").get("PS_CUSTOMER_OPTIN")' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.currency: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Currencies\CurrencyType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.currency_name_by_iso_code").getChoices()' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - tags: - - { name: form.type } - - form.type.customer.delete_customer: - class: 'PrestaShopBundle\Form\Admin\Sell\Customer\DeleteCustomersType' - arguments: - - '@=service("prestashop.core.form.choice_provider.customer_delete_method").getChoices()' - tags: - - { name: form.type } - - form.type.design.theme.import_theme: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\ImportThemeType' - arguments: - - '@=service("prestashop.core.form.choice_provider.theme_zip").getChoices()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.design.theme.adapt_theme_to_rtl_languages: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\AdaptThemeToRTLLanguagesType' - arguments: - - '@=service("prestashop.core.form.choice_provider.theme").getChoices()' - tags: - - { name: form.type } - - form.type.international.language: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Language\LanguageType' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isActive()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.currency_exchange_rate: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Currencies\CurrencyExchangeRateType' - arguments: - - '@=service("prestashop.adapter.data_provider.module").isInstalled("cronjobs")' - tags: - - { name: form.type } - - form.type.international.tax_options: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Tax\TaxOptionsType' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").getBoolean("PS_USE_ECOTAX")' - - '@=service("prestashop.core.form.choice_provider.tax_address_type_choice_provider")' - - '@=service("prestashop.core.form.choice_provider.tax_rule_group_choice_provider")' - tags: - - { name: form.type } - - form.type.contact: - class: 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\Contact\ContactType' - arguments: - - '@prestashop.bundle.form.data_transformer.default_language_to_filled_array' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.cms_page_category: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Pages\CmsPageCategoryType' - arguments: - - '@=service("prestashop.core.form.choice_provider.cms_categories").getChoices()' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.international.tax: - class: 'PrestaShopBundle\Form\Admin\Improve\International\Tax\TaxType' - arguments: - - '@translator' - tags: - - { name: form.type } - - form.type.sell.manufacturer: - class: 'PrestaShopBundle\Form\Admin\Sell\Manufacturer\ManufacturerType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.adapter.multistore_feature").isActive()' - tags: - - { name: form.type } - - prestashop.bundle.form.admin.configure.advanced_parameters.employee.employee: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Employee\EmployeeType' - arguments: - - '@=service("prestashop.core.form.choice_provider.all_languages").getChoices()' - - '@=service("prestashop.core.form.choice_provider.accessible_tab").getChoices()' - - '@=service("prestashop.core.form.choice_provider.profile").getChoices()' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.employee.avatar_provider").getDefaultAvatarUrl()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.change_password: - class: 'PrestaShopBundle\Form\Admin\Type\ChangePasswordType' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.addons_connect: - class: 'PrestaShopBundle\Form\Admin\Type\AddonsConnectType' - arguments: - - '@=service("prestashop.adapter.admin.data_provider.addons").isAddonsAuthenticated()' - - '@=service("prestashop.adapter.admin.data_provider.addons").getAddonsEmail()["username_addons"]' - tags: - - { name: form.type } - - form.type.cms_page: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Pages\CmsPageType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.cms_categories").getChoices()' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - tags: - - { name: form.type } - - form.type.manufacturer_address: - class: 'PrestaShopBundle\Form\Admin\Sell\Address\ManufacturerAddressType' - arguments: - - '@=service("prestashop.adapter.form.choice_provider.manufacturer_name_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoices()' - - '@prestashop.adapter.form.choice_provider.country_state_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' - - '@translator' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoicesAttributes()' - tags: - - { name: form.type } - - form.type.shop_logos: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\Theme\ShopLogosType' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.adapter.shop.context").isSingleShopContext()' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - tags: - - { name: form.type } - - form.type.localization.generate_mails: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\GenerateMailsType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.mail_themes").getChoices()' - - '@=service("prestashop.core.form.choice_provider.theme_by_name_with_emails").getChoices()' - tags: - - { name: form.type } - - form.type.localization.mail_theme_configuration: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\MailThemeConfigurationType' - public: true - arguments: - - '@=service("prestashop.core.form.choice_provider.mail_themes").getChoices()' - tags: - - { name: form.type } - - form.type.integer_min_max_filter: - class: 'PrestaShopBundle\Form\Admin\Type\IntegerMinMaxFilterType' - public: true - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.number_min_max_filter: - class: 'PrestaShopBundle\Form\Admin\Type\NumberMinMaxFilterType' - public: true - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.order.change_order_statuses: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\ChangeOrdersStatusType' - public: true - arguments: - - '@prestashop.core.form.choice_provider.order_state_by_id' - tags: - - { name: form.type } - - form.type.sell.supplier: - class: 'PrestaShopBundle\Form\Admin\Sell\Supplier\SupplierType' - arguments: - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoicesAttributes()' - - '@prestashop.adapter.form.choice_provider.country_state_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' - - '@translator' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - "@=service('prestashop.adapter.legacy.context').getLanguages()" - tags: - - { name: form.type } - - form.type.sell.catalog_price_rule: - class: 'PrestaShopBundle\Form\Admin\Sell\CatalogPriceRule\CatalogPriceRuleType' - public: true - arguments: - - '@translator' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.core.form.choice_provider.currency_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.country_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.group_by_id").getChoices()' - - '@=service("prestashop.adapter.form.choice_provider.shop_name_by_id").getChoices()' - - '@=service("prestashop.core.form.choice_provider.tax_inclusion").getChoices()' - tags: - - { name: form.type } - - form.type.reduction: - class: 'PrestaShopBundle\Form\Admin\Type\ReductionType' - parent: 'form.type.common_type' - arguments: - - '@=service("prestashop.core.form.choice_provider.price_reduction_type").getChoices()' - public: true - tags: - - { name: form.type } - - form.type.sell.customer.private_note: - class: 'PrestaShopBundle\Form\Admin\Sell\Customer\PrivateNoteType' - arguments: - - "@translator" - tags: - - { name: form.type } - - form.type.order.add_order_cart_rule: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\AddOrderCartRuleType' - arguments: - - '@prestashop.core.form.choice.provider.order_discount_type' - - '@prestashop.adapter.form.choice_provider.order_invoice_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@translator' - tags: - - { name: form.type } - - form.type.order.add_product_row: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\AddProductRowType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@prestashop.adapter.form.choice_provider.order_invoice_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - tags: - - { name: form.type } - - form.type.order.edit_product_row: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\EditProductRowType' - parent: 'form.type.translatable.aware' - public: true - arguments: - - '@prestashop.adapter.form.choice_provider.order_invoice_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - tags: - - { name: form.type } - - form.type.order.update_order_status: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\UpdateOrderStatusType' - arguments: - - '@prestashop.core.form.choice_provider.order_state_by_id' - - '@=service("prestashop.core.form.choice_provider.order_state_by_id").getChoicesAttributes()' - tags: - - { name: form.type } - - form.type.order.order_payment: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\OrderPaymentType' - arguments: - - '@translator' - - '@prestashop.adapter.form.choice_provider.currency_symbol_by_id' - - '@prestashop.adapter.form.choice_provider.order_invoice_by_id' - - '@prestashop.adapter.form.choice_provider.installed_payment_modules' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - tags: - - { name: form.type } - - form.type.feature: - class: 'PrestaShopBundle\Form\Admin\Sell\Catalog\FeatureType' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.order.change_order_currency: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\ChangeOrderCurrencyType' - arguments: - - '@prestashop.core.form.choice_provider.currency_by_id' - tags: - - { name: form.type } - - form.type.localization.translate_mails_body: - class: 'PrestaShopBundle\Form\Admin\Improve\Design\MailTheme\TranslateMailsBodyType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.order.update_order_shipping: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\UpdateOrderShippingType' - arguments: - - '@prestashop.adapter.form.choice.provider.carrier_for_order_choice_provider' - tags: - - { name: form.type } - - form.type.address.required_fields: - class: 'PrestaShopBundle\Form\Admin\Sell\Address\RequiredFieldsAddressType' - arguments: - - '@prestashop.core.form.choice_provider.address_required_fields' - tags: - - { name: form.type } - - form.type.customer_service.reply_to_customer_thread: - class: 'PrestaShopBundle\Form\Admin\Sell\CustomerService\ReplyToCustomerThreadType' - public: true - arguments: - - '@translator' - tags: - - { name: form.type } - - form.type.customer_service.forward_customer_thread: - class: 'PrestaShopBundle\Form\Admin\CustomerService\CustomerThread\ForwardCustomerThreadType' - public: true - arguments: - - '@translator' - - '@prestashop.adapter.form.choice_provider.employee_name_by_id' - tags: - - { name: form.type } - - form.type.order.credit_slip.generate_pdf_by_date: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip\GeneratePdfByDateType' - parent: 'form.type.common_type' - arguments: - - '@translator' - public: true - tags: - - { name: form.type } - - form.type.order.credit_slip.credit_slip_options: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\CreditSlip\CreditSlipOptionsType' - parent: 'form.type.common_type' - arguments: - - '@translator' - public: true - tags: - - { name: form.type } - - form.type.order.change_order_address: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\ChangeOrderAddressType' - arguments: - - '@prestashop.core.form.choice_provider.customer_addresses_by_id' - tags: - - { name: form.type } - - form.type.order.message: - class: 'PrestaShopBundle\Form\Admin\Sell\CustomerService\OrderMessageType' - tags: - - { name: form.type } - - form.type.order.customer_service_message: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\OrderMessageType' - arguments: - - '@prestashop.core.form.choice_provider.customer_service_order_messages_name' - - '@prestashop.core.form.choice_provider.customer_service_order_messages' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.customer_address: - class: 'PrestaShopBundle\Form\Admin\Sell\Address\CustomerAddressType' - arguments: - - '@translator' - - '@prestashop.adapter.form.choice_provider.country_state_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' - tags: - - { name: form.type } - - prestashop.bundle.form.admin.sell.attachment.attachment: - class: 'PrestaShopBundle\Form\Admin\Sell\Attachment\AttachmentType' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } - - form.type.order.cancel_product: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\CancelProductType' - parent: 'form.type.translatable.aware' - public: true - tags: - - { name: form.type } - - form.type.order.cart_summary: - class: 'PrestaShopBundle\Form\Admin\Sell\Order\CartSummaryType' - arguments: - - '@prestashop.core.form.choice_provider.order_state_by_id' - - '@prestashop.adapter.form.choice_provider.installed_payment_modules' - - '@translator' - tags: - - { name: form.type } - - form.type.configure.advanced_parameters.profile: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Profile\ProfileType' - public: true - arguments: - - '@translator' - tags: - - { name: form.type } diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type/webservice.yml b/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type/webservice.yml deleted file mode 100644 index 9c8f14bc..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/form/form_type/webservice.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - _defaults: - public: true - - form.type.webservice.webservice_key_type: - class: 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Webservice\WebserviceKeyType' - arguments: - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.adapter.form.choice_provider.resources_choice_provider").getChoices()' - - '@=service("prestashop.core.form.choice_provider.permissions_choice_provider").getChoices()' - calls: - - { method: setTranslator, arguments: ['@translator'] } - tags: - - { name: form.type } diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/grid.yml b/src/PrestaShopBundle/Resources/config/services/bundle/grid.yml deleted file mode 100644 index 229f4805..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/grid.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.bundle.grid.response_builder: - class: PrestaShopBundle\Service\Grid\ResponseBuilder - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' - - prestashop.bundle.grid.controller_response_builder: - class: PrestaShopBundle\Service\Grid\ControllerResponseBuilder - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/repository.yml b/src/PrestaShopBundle/Resources/config/services/bundle/repository.yml deleted file mode 100644 index 4772eaaa..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/repository.yml +++ /dev/null @@ -1,123 +0,0 @@ -services: - _defaults: - public: true - - prestashop.module_kernel.repository: - class: 'PrestaShopBundle\Kernel\ModuleRepository' - arguments: ['@doctrine.dbal.default_connection', '%database_prefix%'] - - prestashop.core.admin.tab.repository: - class: PrestaShopBundle\Entity\Repository\TabRepository - factory: ['@doctrine.orm.default_entity_manager', getRepository] - arguments: - - PrestaShopBundle\Entity\Tab - - prestashop.core.admin.shop.repository: - class: 'PrestaShopBundle\Entity\Repository\ShopRepository' - factory: ['@doctrine.orm.default_entity_manager', getRepository] - arguments: - - 'PrestaShopBundle\Entity\Shop' - - prestashop.core.admin.translation.repository: - class: PrestaShopBundle\Entity\Repository\TranslationRepository - factory: ['@doctrine.orm.default_entity_manager', getRepository] - arguments: - - PrestaShopBundle\Entity\Translation - - prestashop.core.admin.lang.repository: - class: PrestaShopBundle\Entity\Repository\LangRepository - factory: ['@doctrine.orm.default_entity_manager', getRepository] - arguments: - - PrestaShopBundle\Entity\Lang - - prestashop.core.admin.log.repository: - class: PrestaShopBundle\Entity\Repository\LogRepository - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - prestashop.core.api.stock.repository: - class: PrestaShopBundle\Entity\Repository\StockRepository - arguments: - - "@service_container" - - "@doctrine.dbal.default_connection" - - "@doctrine.orm.default_entity_manager" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.image_manager" - - "@prestashop.adapter.stock_manager" - - "%database_prefix%" - - prestashop.core.api.stock_movement.repository: - class: PrestaShopBundle\Entity\Repository\StockMovementRepository - arguments: - - "@service_container" - - "@doctrine.dbal.default_connection" - - "@doctrine.orm.default_entity_manager" - - "@prestashop.adapter.legacy.context" - - "@prestashop.adapter.image_manager" - - "%database_prefix%" - - prestashop.core.api.supplier.repository: - class: PrestaShopBundle\Entity\Repository\SupplierRepository - arguments: - - "@doctrine.dbal.default_connection" - - "@prestashop.adapter.legacy.context" - - "%database_prefix%" - - prestashop.core.api.manufacturer.repository: - class: PrestaShopBundle\Entity\Repository\ManufacturerRepository - arguments: - - "@doctrine.dbal.default_connection" - - "@prestashop.adapter.legacy.context" - - "%database_prefix%" - - prestashop.core.api.category.repository: - class: PrestaShopBundle\Entity\Repository\CategoryRepository - arguments: - - "@doctrine.dbal.default_connection" - - "@prestashop.adapter.legacy.context" - - "%database_prefix%" - - prestashop.core.api.feature_attribute.repository: - class: PrestaShopBundle\Entity\Repository\FeatureAttributeRepository - arguments: - - "@doctrine.dbal.default_connection" - - "@prestashop.adapter.legacy.context" - - "%database_prefix%" - - prestashop.core.admin.timezone.repository: - class: PrestaShopBundle\Entity\Repository\TimezoneRepository - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.core.admin.import_match.repository: - class: PrestaShopBundle\Entity\Repository\ImportMatchRepository - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.bundle.repository.module: - class: PrestaShopBundle\Entity\Repository\ModuleRepository - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.core.admin.request_sql.repository: - class: PrestaShopBundle\Entity\Repository\RequestSqlRepository - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.core.admin.admin_filter.repository: - class: PrestaShopBundle\Entity\Repository\AdminFilterRepository - factory: ['@doctrine.orm.default_entity_manager', getRepository] - arguments: - - PrestaShopBundle\Entity\AdminFilter - - prestashop.core.api.order_invoice.repository: - class: PrestaShopBundle\Entity\Repository\OrderInvoiceRepository - arguments: - - "@doctrine.dbal.default_connection" - - "%database_prefix%" diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/routing.yml b/src/PrestaShopBundle/Resources/config/services/bundle/routing.yml deleted file mode 100644 index d08f42da..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/routing.yml +++ /dev/null @@ -1,59 +0,0 @@ -services: - prestashop.bundle.routing.module_route_loader: - class: 'PrestaShopBundle\Routing\YamlModuleLoader' - arguments: - - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' - tags: [routing.loader] - - prestashop.bundle.routing.converter.legacy_url_converter: - class: 'PrestaShopBundle\Routing\Converter\LegacyUrlConverter' - public: true - arguments: - - '@router' - - '@prestashop.bundle.routing.converter.cache_provider' - - prestashop.bundle.routing.converter.legacy_parameters_converter: - class: 'PrestaShopBundle\Routing\Converter\LegacyParametersConverter' - public: true - - prestashop.bundle.routing.converter.router_provider: - class: 'PrestaShopBundle\Routing\Converter\RouterProvider' - arguments: - - '@router' - - # We set this alias so that we can override it in test environment (to avoid memory limit crashes) - prestashop.bundle.routing.converter.cache: - alias: Symfony\Component\Cache\Adapter\AdapterInterface - - prestashop.bundle.routing.converter.cache_provider: - class: 'PrestaShopBundle\Routing\Converter\CacheProvider' - arguments: - - '@prestashop.bundle.routing.converter.router_provider' - - '@prestashop.bundle.routing.converter.cache' - - '@prestashop.bundle.routing.converter.routing_cache_key_generator' - - prestashop.bundle.routing.converter.routing_cache_key_generator: - class: 'PrestaShopBundle\Routing\Converter\RoutingCacheKeyGenerator' - arguments: - - ["%kernel.project_dir%/src/PrestaShopBundle/Resources/config/routing/admin"] - - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' - - '%kernel.environment%' - - prestashop.bundle.routing.linter.security_annotation_linter: - class: 'PrestaShopBundle\Routing\Linter\SecurityAnnotationLinter' - arguments: - - '@annotation_reader' - - '@controller_name_converter' - - prestashop.bundle.routing.linter.naming_convention_linter: - class: 'PrestaShopBundle\Routing\Linter\NamingConventionLinter' - arguments: - - '@controller_name_converter' - - prestashop.bundle.routing.linter.legacy_link_linter: - class: 'PrestaShopBundle\Routing\Linter\LegacyLinkLinter' - - prestashop.bundle.routing.linter.admin_route_provider: - class: 'PrestaShopBundle\Routing\Linter\AdminRouteProvider' - arguments: - - '@router' diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/security.yml b/src/PrestaShopBundle/Resources/config/services/bundle/security.yml deleted file mode 100644 index 2d66d0e0..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/security.yml +++ /dev/null @@ -1,21 +0,0 @@ -parameters: - prestashop.security.voter.product.class: PrestaShopBundle\Security\Voter\PageVoter - -services: - _defaults: - public: true - - prestashop.security.admin.provider: - class: PrestaShopBundle\Security\Admin\EmployeeProvider - arguments: - - "@prestashop.adapter.legacy.context" - - "@prestashop.static_cache.adapter" - - prestashop.security.role.dynamic_role_hierarchy: - class: PrestaShopBundle\Security\Role\DynamicRoleHierarchy - - prestashop.security.voter.product: - class: "%prestashop.security.voter.product.class%" - tags: - - { name: security.voter } - public: false diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/services.yml b/src/PrestaShopBundle/Resources/config/services/bundle/services.yml deleted file mode 100644 index b05f2c4c..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/services.yml +++ /dev/null @@ -1,108 +0,0 @@ -parameters: - ps_root_dir: "%kernel.root_dir%/../" - ps_config_dir: "%ps_root_dir%config" - translations_dir: "%kernel.root_dir%/Resources/translations" - themes_translations_dir: "%kernel.cache_dir%/themes" - modules_dir: "%kernel.root_dir%/../modules" - themes_dir: "%kernel.root_dir%/../themes" - -services: - _defaults: - public: true - - # Interfaced services to decorate - prestashop.core.admin.data_provider.product_interface: - class: PrestaShopBundle\Service\DataProvider\Admin\ProductInterface - prestashop.core.admin.data_updater.product_interface: - class: PrestaShopBundle\Service\DataUpdater\Admin\ProductInterface - prestashop.core.admin.page_preference_interface: - class: PrestaShopBundle\Service\TransitionalBehavior\AdminPagePreferenceInterface - prestashop.core.admin.data_provider.addons_interface: - class: PrestaShopBundle\Service\DataProvider\Admin\AddonsInterface - prestashop.core.admin.data_provider.module_interface: - class: PrestaShopBundle\Service\DataProvider\Admin\ModuleInterface - - # URL generation - prestashop.core.admin.url_generator_factory: - class: PrestaShopBundle\Service\TransitionalBehavior\AdminUrlGeneratorFactory - arguments: - - "@router" - - prestashop.core.admin.url_generator_legacy: - class: Symfony\Component\Routing\Generator\UrlGeneratorInterface - factory: ["@prestashop.core.admin.url_generator_factory", forLegacy] - arguments: - - "@prestashop.adapter.legacy.context" - - prestashop.core.admin.url_generator: - class: Symfony\Component\Routing\Generator\UrlGeneratorInterface - factory: ["@prestashop.core.admin.url_generator_factory", forSymfony] - - prestashop.database.naming_strategy: - class: PrestaShopBundle\Service\Database\DoctrineNamingStrategy - arguments: ["%database_prefix%"] - - prestashop.data_provider.modules.recommended: - class: PrestaShopBundle\Service\DataProvider\Admin\RecommendedModules - arguments: ["@router"] - - prestashop.service.product: - class: PrestaShopBundle\Service\ProductService - arguments: - - "@prestashop.adapter.data_provider.product" - - prestashop.service.translation: - class: PrestaShopBundle\Service\TranslationService - properties: - container: "@service_container" - - # Interfaced services to decorate - prestashop.core.data_provider.stock_interface: - class: PrestaShopBundle\Service\DataProvider\StockInterface - - # DISPATCHERS - prestashop.hook.dispatcher: - class: PrestaShop\PrestaShop\Adapter\Hook\HookDispatcher - calls: - - [addSubscriber, ["@prestashop.adapter.legacy.hook.subscriber"]] - - [addSubscriber, ["@prestashop.adapter.legacy.block.helper.subscriber"]] - - prestashop.hook.finder: - class: PrestaShopBundle\Service\Hook\HookFinder - - # EVENT HANDLER - prestashop.handler.log: - class: PrestaShopBundle\Service\Log\LogHandler - arguments: - - "@service_container" - - # CSRF/XSS additional protection middleware - prestashop.user_provider: - class: PrestaShopBundle\Service\DataProvider\UserProvider - arguments: ['@security.token_storage'] - - prestashop.router: - class: PrestaShopBundle\Service\Routing\Router - parent: 'router.default' - public: true - calls: - - ['setTokenManager', ['@security.csrf.token_manager']] - - ['setUserProvider', ["@=service('prestashop.user_provider')"]] - - # Addons API Client - prestashop.addons.client_api: - class: PrestaShopBundle\Service\DataProvider\Marketplace\ApiClient - arguments: - - "@csa_guzzle.client.addons_api" - - "@=service('translator').getLocale()" - - "@=service('prestashop.adapter.data_provider.country').getIsoCodebyId()" - - "@prestashop.adapter.tools" - - "@=service('prestashop.adapter.legacy.configuration').get('_PS_BASE_URL_')" - - "@=service('prestashop.core.foundation.version').getVersion()" - calls: - - [ "setSslVerification", ["%prestashop.addons.api_client.verify_ssl%"]] - - # Product CSV Exporter - prestashop.core.product.csv_exporter: - class: PrestaShop\PrestaShop\Core\Product\ProductCsvExporter - arguments: ['@translator', '@prestashop.core.admin.data_provider.product_interface'] diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/translation.yml b/src/PrestaShopBundle/Resources/config/services/bundle/translation.yml deleted file mode 100644 index 3fd9d2e5..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/translation.yml +++ /dev/null @@ -1,189 +0,0 @@ -services: - _defaults: - public: true - - #TRANSLATIONS FACTORIES - prestashop.translation.translations_factory: - class: PrestaShopBundle\Translation\Factory\TranslationsFactory - - ps.translations_factory: - alias: "prestashop.translation.translations_factory" - - prestashop.translation.theme_translations_factory: - class: PrestaShopBundle\Translation\Factory\ThemeTranslationsFactory - arguments: ['@prestashop.translation.theme_provider'] - calls: - - [ addProvider, ['@prestashop.translation.theme_provider']] - - ps.theme_translations_factory: - alias: "prestashop.translation.theme_translations_factory" - - #TRANSLATIONS PROVIDERS - prestashop.translation.backoffice_provider: - class: PrestaShopBundle\Translation\Provider\BackOfficeProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.frontoffice_provider: - class: PrestaShopBundle\Translation\Provider\FrontOfficeProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.mails_provider: - class: PrestaShopBundle\Translation\Provider\MailsProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.mails_body_provider: - class: PrestaShopBundle\Translation\Provider\MailsBodyProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.others_provider: - class: PrestaShopBundle\Translation\Provider\OthersProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.theme_provider: - class: PrestaShopBundle\Translation\Provider\ThemeProvider - arguments: - - "@prestashop.translation.database_loader" - - "%themes_translations_dir%" - properties: - themeResourcesDirectory: "%themes_dir%" - filesystem: "@filesystem" - themeRepository: "@prestashop.core.addon.theme.repository" - themeExtractor: "@prestashop.translation.theme_extractor" - defaultTranslationDir: "%translations_dir%" - - prestashop.translation.modules_provider: - class: PrestaShopBundle\Translation\Provider\ModulesProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.external_module_provider: - class: PrestaShopBundle\Translation\Provider\ExternalModuleLegacySystemProvider - arguments: - - "@prestashop.translation.database_loader" - - "%modules_dir%" - - "@prestashop.translation.legacy_file_loader" - - "@prestashop.translation.legacy_module.extractor" - - "@prestashop.translation.module_provider" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.module_provider: - class: PrestaShopBundle\Translation\Provider\ModuleProvider - arguments: - - "@prestashop.translation.database_loader" - - "%translations_dir%" - tags: - - { name: "ps.translation_provider" } - - prestashop.translation.search_provider: - class: PrestaShopBundle\Translation\Provider\SearchProvider - arguments: - - "@prestashop.translation.database_loader" - - "@prestashop.translation.external_module_provider" - - "%translations_dir%" - - "%modules_dir%" - tags: - - { name: "ps.translation_provider" } - - # TRANSLATIONS - prestashop.translation.database_loader: - class: PrestaShopBundle\Translation\Loader\DatabaseTranslationLoader - arguments: - - "@doctrine.orm.entity_manager" - tags: - - {name: translation.loader, alias: db} - - prestashop.translation.sql_loader: - class: PrestaShopBundle\Translation\Loader\SqlTranslationLoader - tags: - - {name: translation.loader, alias: db} - - prestashop.translation.legacy_file_reader: - class: PrestaShopBundle\Translation\Loader\LegacyFileReader - arguments: - - "@prestashop.core.translation.locale.converter" - - prestashop.translation.legacy_file_loader: - class: PrestaShopBundle\Translation\Loader\LegacyFileLoader - arguments: - - "@prestashop.translation.legacy_file_reader" - tags: - - {name: translation.loader, alias: legacy_files} - - # cannot decorate the original one because it is loaded later - # this version activates loading legacy wordings in smarty files - prestashop.translation.extractor.smarty.legacy: - class: PrestaShop\TranslationToolsBundle\Translation\Extractor\SmartyExtractor - arguments: - - "@prestashop.compiler.smarty.template" - - true - - prestashop.translation.theme_extractor: - class: PrestaShopBundle\Translation\Extractor\ThemeExtractor - arguments: - - "@prestashop.translation.extractor.smarty.legacy" - - prestashop.translation.legacy_module.extractor: - class: PrestaShopBundle\Translation\Extractor\LegacyModuleExtractor - arguments: - - "@prestashop.translation.extractor.php" - - "@prestashop.translation.extractor.smarty.legacy" - - "@prestashop.translation.extractor.twig" - - "%modules_dir%" - - prestashop.translation.dumper.xliff: - class: PrestaShop\TranslationToolsBundle\Translation\Dumper\XliffFileDumper - - prestashop.translation.theme.exporter: - class: PrestaShopBundle\Translation\Exporter\ThemeExporter - arguments: - - "@prestashop.translation.theme_extractor" - - "@prestashop.translation.theme_provider" - - "@prestashop.core.addon.theme.repository" - - "@prestashop.translation.dumper.xliff" - - "@prestashop.utils.zip_manager" - - "@filesystem" - properties: - cacheDir: "%kernel.cache_dir%" - calls: - - [ setExportDir, ["%kernel.cache_dir%/export"]] - - # Api - i18n - prestashop.translation.api: - abstract: true - class: PrestaShopBundle\Translation\Api\AbstractApi - calls: - - [setTranslator, ['@translator']] - - prestashop.translation.api.stock: - class: PrestaShopBundle\Translation\Api\StockApi - parent: prestashop.translation.api - public: true - - prestashop.translation.api.international: - class: PrestaShopBundle\Translation\Api\InternationalApi - parent: prestashop.translation.api - public: true diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/twig.yml b/src/PrestaShopBundle/Resources/config/services/bundle/twig.yml deleted file mode 100644 index 40f2d4ff..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/twig.yml +++ /dev/null @@ -1,120 +0,0 @@ -services: - _defaults: - public: true - - prestashop.twig.modules.loader: - class: 'PrestaShopBundle\Twig\Locator\ModuleTemplateLoader' - arguments: - - - 'PrestaShop': '' - 'Product': '/Admin/Product' - 'Twig': '/Admin/TwigTemplateForm' - 'AdvancedParameters': '/Admin/Configure/AdvancedParameters' - 'ShopParameters': '/Admin/Configure/ShopParameters' - - '@=service("prestashop.module_kernel.repository").getActiveModulesPaths()' - tags: - - { name: twig.loader, priority: 1} - - # Extensions - - prestashop.twig.extension.stringloader: - class: Twig_Extension_StringLoader - tags: - - { name: twig.extension } - - prestashop.twig.extension.layout: - class: PrestaShopBundle\Twig\LayoutExtension - arguments: - - "@prestashop.adapter.legacy.context" - - "%kernel.environment%" - - "@prestashop.adapter.legacy.configuration" - - "@prestashop.adapter.data_provider.currency" - tags: - - { name: twig.extension } - - prestashop.twig.extension.translation: - class: PrestaShopBundle\Twig\TranslationsExtension - arguments: ["@service_container", "@router"] - properties: - logger: "@logger" - translator: "@translator" - tags: - - { name: twig.extension } - - prestashop.twig.extension.data_formatter: - class: PrestaShopBundle\Twig\DataFormatterExtension - tags: - - { name: twig.extension } - - prestashop.twig.extension.hook: - class: PrestaShopBundle\Twig\HookExtension - arguments: - - "@prestashop.core.hook.dispatcher" - - "@prestashop.adapter.data_provider.module" - - "@=service('prestashop.adapter.legacy.context').getContext().employee?service('prestashop.core.admin.module.repository'):null" - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.column: - class: 'PrestaShopBundle\Twig\Extension\GridExtension' - arguments: - - '@twig' - - '@prestashop.static_cache.adapter' - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.documentation_link_provider_extension: - class: 'PrestaShopBundle\Twig\Extension\DocumentationLinkExtension' - arguments: - - '@prestashop.core.util.helper_card.documentation_link_provider' - tags: - - { name: twig.extension } - - prestashop.twig.extension.context_iso_code_provider_extension: - class: PrestaShopBundle\Twig\ContextIsoCodeProviderExtension - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language ? service('prestashop.adapter.legacy.context').getContext().language.iso_code : 'en'" - properties: - logger: "@logger" - translator: "@translator" - tags: - - { name: twig.extension } - - prestashop.twig.extension.path_with_back_url_extension: - class: PrestaShopBundle\Twig\Extension\PathWithBackUrlExtension - arguments: - - '@twig.extension.routing' - - '@prestashop.core.uti.back_url_provider' - - '@=service("request_stack") ? service("request_stack") : null' - public: true - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.color_brightness_calculator_extension: - class: PrestaShopBundle\Twig\Extension\ColorBrightnessCalculatorExtension - arguments: - - '@prestashop.core.util.color_brightness_calculator' - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.js_router_metadata_extension: - class: PrestaShopBundle\Twig\Extension\JsRouterMetadataExtension - arguments: - - '@=service("request_stack")' - - '@=service("security.csrf.token_manager")' - - '@=service("prestashop.user_provider").getUsername()' - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.localization_extension: - class: 'PrestaShopBundle\Twig\Extension\LocalizationExtension' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language.date_format_full' - - '@=service("prestashop.adapter.legacy.context").getContext().language.date_format_lite' - tags: - - { name: twig.extension } - - prestashop.bundle.twig.extension.number_extension: - class: 'PrestaShopBundle\Twig\Extension\NumberExtension' - tags: - - { name: twig.extension } diff --git a/src/PrestaShopBundle/Resources/config/services/bundle/utils.yml b/src/PrestaShopBundle/Resources/config/services/bundle/utils.yml deleted file mode 100644 index 23ea7547..00000000 --- a/src/PrestaShopBundle/Resources/config/services/bundle/utils.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: true - - prestashop.utils.zip_manager: - class: PrestaShopBundle\Utils\ZipManager - - prestashop.utils.float_parser: - class: PrestaShopBundle\Utils\FloatParser - arguments: - - '@prestashop.core.util.arabic_to_latin_digit_converter' diff --git a/src/PrestaShopBundle/Resources/config/services/core/addon.yml b/src/PrestaShopBundle/Resources/config/services/core/addon.yml deleted file mode 100644 index f0f76a28..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/addon.yml +++ /dev/null @@ -1,59 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.admin.module.repository: - class: PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository - arguments: - - "@prestashop.adapter.admin.data_provider.module" - - "@prestashop.adapter.data_provider.module" - - "@prestashop.core.module.updater" - - "@prestashop.adapter.legacy.logger" - - "@translator" - - "@=service('prestashop.adapter.legacy.configuration').get('_PS_MODULE_DIR_')" - - "@doctrine.cache.provider" - calls: - - [setPrestaTrustChecker, ['@prestashop.adapter.module.prestatrust.checker']] - - prestashop.core.addon.theme.repository: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeRepository - arguments: - - "@prestashop.adapter.legacy.configuration" - - "@filesystem" - - "@=service('prestashop.adapter.legacy.context').getContext().shop" - - prestashop.core.addon.theme.exporter: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeExporter - arguments: - - "@prestashop.adapter.legacy.configuration" - - "@filesystem" - - "@prestashop.core.admin.lang.repository" - - "@prestashop.translation.theme.exporter" - - prestashop.core.addon.theme.theme_manager_builder: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext()' - - '@prestashop.adapter.legacy_db' - - prestashop.core.addon.theme.theme_manager: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManager - factory: 'prestashop.core.addon.theme.theme_manager_builder:build' - - prestashop.core.addon.theme.theme.page_layouts_customizer: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemePageLayoutsCustomizer - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().shop.theme' - - '@prestashop.core.addon.theme.theme_manager' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - prestashop.core.addon.theme.theme_zip_uploader: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeZipUploader - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.addon.theme.theme_provider: - class: PrestaShop\PrestaShop\Core\Addon\Theme\ThemeProvider - arguments: - - '@prestashop.core.addon.theme.repository' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.theme' diff --git a/src/PrestaShopBundle/Resources/config/services/core/attribute_group.yml b/src/PrestaShopBundle/Resources/config/services/core/attribute_group.yml deleted file mode 100644 index 76c5186d..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/attribute_group.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.attribute_group.attribute_group_view_data_provider: - class: 'PrestaShop\PrestaShop\Adapter\AttributeGroup\AttributeGroupViewDataProvider' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.configuration')" diff --git a/src/PrestaShopBundle/Resources/config/services/core/b2b.yml b/src/PrestaShopBundle/Resources/config/services/core/b2b.yml deleted file mode 100644 index 78a81848..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/b2b.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.b2b.b2b_feature: - class: 'PrestaShop\PrestaShop\Core\B2b\B2bFeature' - arguments: - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/core/backup.yml b/src/PrestaShopBundle/Resources/config/services/core/backup.yml deleted file mode 100644 index 82add452..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/backup.yml +++ /dev/null @@ -1,19 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.backup.options_configuration: - class: 'PrestaShop\PrestaShop\Core\Backup\Configuration\BackupOptionsConfiguration' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.backup.listing.grid_data_factory: - class: 'PrestaShop\PrestaShop\Core\Backup\Listing\BackupGridDataFactory' - arguments: - - '@prestashop.adapter.backup.backup_provider' - - '@prestashop.core.backup.comparator.backup_by_date_comparator' - - '@translator' - - '@=service("prestashop.adapter.legacy.context").getLanguage().date_format_full' - - prestashop.core.backup.comparator.backup_by_date_comparator: - class: 'PrestaShop\PrestaShop\Core\Backup\Comparator\BackupByDateComparator' diff --git a/src/PrestaShopBundle/Resources/config/services/core/cache.yml b/src/PrestaShopBundle/Resources/config/services/core/cache.yml deleted file mode 100644 index c4854694..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/cache.yml +++ /dev/null @@ -1,21 +0,0 @@ -services: - _defaults: - public: true - - # Cache adapter - prestashop.static_cache.adapter: - class: Symfony\Component\Cache\Adapter\ArrayAdapter - tags: - - { name: monolog.logger, channel: cache } - - { name: cache.pool, clearer: cache.default_clearer } - calls: - - ['setLogger', ['@logger']] - - prestashop.core.cache.clearer.cache_clearer_chain: - class: 'PrestaShop\PrestaShop\Core\Cache\Clearer\CacheClearerChain' - arguments: - - '@prestashop.adapter.cache.clearer.symfony_cache_clearer' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - '@prestashop.adapter.cache.clearer.xml_cache_clearer' - - '@prestashop.adapter.cache.clearer.media_cache_clearer' - - '@prestashop.adapter.cache.clearer.class_index_cache_clearer' diff --git a/src/PrestaShopBundle/Resources/config/services/core/circuit_breaker.yml b/src/PrestaShopBundle/Resources/config/services/core/circuit_breaker.yml deleted file mode 100644 index 974d52f7..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/circuit_breaker.yml +++ /dev/null @@ -1,33 +0,0 @@ -# circuit_breaker.yml -services: - _defaults: - public: true - - prestashop.core.circuit_breaker.doctrine_cache: - class: Doctrine\Common\Cache\FilesystemCache - arguments: - - '@=service("prestashop.adapter.environment").getCacheDir() ~ "/circuit_breaker"' - - prestashop.core.circuit_breaker.guzzle.cache_storage: - class: GuzzleHttp\Subscriber\Cache\CacheStorage - arguments: - - "@prestashop.core.circuit_breaker.doctrine_cache" - - "circuit_breaker_" - - 86400 - - prestashop.core.circuit_breaker.guzzle.cache_subscriber_factory: - class: PrestaShopBundle\Cache\Factory\CacheSubscriberFactory - - prestashop.core.circuit_breaker.guzzle.cache_subscriber: - class: GuzzleHttp\Subscriber\Cache\CacheSubscriber - factory: ['@prestashop.core.circuit_breaker.guzzle.cache_subscriber_factory', 'create'] - arguments: - - "@prestashop.core.circuit_breaker.guzzle.cache_storage" - - prestashop.core.circuit_breaker.storage: - class: PrestaShop\CircuitBreaker\Storage\DoctrineCache - arguments: - - "@prestashop.core.circuit_breaker.doctrine_cache" - - prestashop.core.circuit_breaker.advanced_factory: - class: PrestaShop\CircuitBreaker\AdvancedCircuitBreakerFactory diff --git a/src/PrestaShopBundle/Resources/config/services/core/cldr.yml b/src/PrestaShopBundle/Resources/config/services/core/cldr.yml deleted file mode 100644 index 6f2afbcc..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/cldr.yml +++ /dev/null @@ -1,91 +0,0 @@ -parameters: - ps_cache_dir: !php/const _PS_CACHE_DIR_ - -services: - _defaults: - public: true - - prestashop.core.localization.cache.adapter: - class: Symfony\Component\Cache\Adapter\ArrayAdapter - - prestashop.core.localization.cldr.cache.adapter: - class: Symfony\Component\Cache\Adapter\FilesystemAdapter - arguments: - - 'CLDR' - - 0 - - '%ps_cache_dir%/localization' - - prestashop.core.localization.locale.repository: - class: PrestaShop\PrestaShop\Core\Localization\Locale\Repository - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - '@prestashop.core.localization.currency.repository' - - prestashop.core.localization.locale.context_locale: - factory: ['@prestashop.core.localization.locale.repository', 'getLocale'] - class: PrestaShop\PrestaShop\Core\Localization\Locale - arguments: ['@=service("prestashop.adapter.legacy.context").getContext().language.getLocale()'] - - prestashop.core.localization.currency.repository: - class: PrestaShop\PrestaShop\Core\Localization\Currency\Repository - arguments: - - '@prestashop.core.localization.currency.datasource' - - prestashop.core.localization.cldr.locale_repository: - class: PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository - arguments: - - '@prestashop.core.localization.cldr.locale_data_source' - - prestashop.core.localization.cldr.locale_data_source: - class: PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleDataSource - arguments: - - '@prestashop.core.localization.cldr.datalayer.top_layer' - - prestashop.core.localization.cldr.datalayer.top_layer: '@prestashop.core.localization.cldr.datalayer.locale_cache' - - prestashop.core.localization.cldr.datalayer.locale_cache: - class: PrestaShop\PrestaShop\Core\Localization\CLDR\DataLayer\LocaleCache - arguments: - - '@prestashop.core.localization.cldr.cache.adapter' - calls: - - [ 'setLowerLayer', ["@prestashop.core.localization.cldr.datalayer.locale_reference"]] - - prestashop.core.localization.cldr.datalayer.locale_reference: - class: PrestaShop\PrestaShop\Core\Localization\CLDR\DataLayer\LocaleReference - arguments: - - '@prestashop.core.localization.cldr.reader' - - prestashop.core.localization.cldr.reader: - class: PrestaShop\PrestaShop\Core\Localization\CLDR\Reader - - prestashop.core.localization.currency.datasource: - class: PrestaShop\PrestaShop\Core\Localization\Currency\CurrencyDataSource - arguments: - - '@prestashop.core.localization.currency.middleware.top_layer' - - '@prestashop.core.localization.currency.middleware.installed' - - prestashop.core.localization.currency.middleware.top_layer: '@prestashop.core.localization.currency.middleware.cache' - - prestashop.core.localization.currency.middleware.cache: - class: PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer\CurrencyCache - arguments: - - '@prestashop.core.localization.cache.adapter' - calls: - - [ 'setLowerLayer', ["@prestashop.core.localization.currency.middleware.database"]] - - prestashop.core.localization.currency.middleware.database: - class: PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer\CurrencyDatabase - arguments: - - '@prestashop.adapter.data_provider.currency' - calls: - - [ 'setLowerLayer', ["@prestashop.core.localization.currency.middleware.reference"]] - - prestashop.core.localization.currency.middleware.reference: - class: PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer\CurrencyReference - arguments: - - '@prestashop.core.localization.cldr.locale_repository' - - prestashop.core.localization.currency.middleware.installed: - class: PrestaShop\PrestaShop\Core\Localization\Currency\DataLayer\CurrencyInstalled - arguments: - - '@prestashop.adapter.data_provider.currency' diff --git a/src/PrestaShopBundle/Resources/config/services/core/cms_page.yml b/src/PrestaShopBundle/Resources/config/services/core/cms_page.yml deleted file mode 100644 index c50f0f03..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/cms_page.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.cms_page.data_provider.cms_page_view: - class: 'PrestaShop\PrestaShop\Core\CMS\CmsPageViewDataProvider' - arguments: - - '@prestashop.core.query_bus' diff --git a/src/PrestaShopBundle/Resources/config/services/core/command_bus.yml b/src/PrestaShopBundle/Resources/config/services/core/command_bus.yml deleted file mode 100644 index 8cfa2080..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/command_bus.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.command_bus: - class: 'PrestaShop\PrestaShop\Core\CommandBus\TacticianCommandBusAdapter' - arguments: - - '@tactician.commandbus.default' - - prestashop.core.query_bus: - class: 'PrestaShop\PrestaShop\Core\CommandBus\TacticianCommandBusAdapter' - arguments: - - '@tactician.commandbus.default' - - prestashop.core.provider.command_definition_provider: - class: 'PrestaShop\PrestaShop\Core\CommandBus\Parser\CommandDefinitionParser' - - prestashop.core.command_bus.middleware.command_register_middleware: - class: PrestaShop\PrestaShop\Core\CommandBus\Middleware\CommandRegisterMiddleware - arguments: - - '@tactician.handler.locator.symfony' - - '@tactician.handler.command_name_extractor.class_name' - - '@prestashop.core.command_bus.executed_command_registry' - - prestashop.core.command_bus.executed_command_registry: - class: PrestaShop\PrestaShop\Core\CommandBus\ExecutedCommandRegistry - arguments: - - '@prestashop.core.command_bus.parser.command_type_parser' - - prestashop.core.command_bus.parser.command_type_parser: - class: PrestaShop\PrestaShop\Core\CommandBus\Parser\CommandTypeParser diff --git a/src/PrestaShopBundle/Resources/config/services/core/common.yml b/src/PrestaShopBundle/Resources/config/services/core/common.yml deleted file mode 100644 index be57c3ee..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/common.yml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: ./circuit_breaker.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/core/configuration.yml b/src/PrestaShopBundle/Resources/config/services/core/configuration.yml deleted file mode 100644 index d76f2508..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/configuration.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.configuration.ini_configuration: - class: 'PrestaShop\PrestaShop\Core\Configuration\IniConfiguration' - - prestashop.core.configuration.php_extension_checker: - class: 'PrestaShop\PrestaShop\Core\Configuration\PhpExtensionChecker' - public: true - - prestashop.core.configuration.upload_size_configuration: - class: 'PrestaShop\PrestaShop\Core\Configuration\UploadSizeConfiguration' - arguments: - - '@prestashop.core.configuration.ini_configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/core/constraint_validator.yml b/src/PrestaShopBundle/Resources/config/services/core/constraint_validator.yml deleted file mode 100644 index f903548e..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/constraint_validator.yml +++ /dev/null @@ -1,60 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.constraint_validator.is_url_rewrite_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\IsUrlRewriteValidator' - arguments: - - '@prestashop.adapter.legacy.configuration' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.default_language_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\DefaultLanguageValidator' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("PS_LANG_DEFAULT")' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.customer_name_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\CustomerNameValidator' - arguments: - - '@prestashop.core.string.character_cleaner' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.typed_regex_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\TypedRegexValidator' - arguments: - - '@prestashop.core.string.character_cleaner' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.existing_customer_email_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\ExistingCustomerEmailValidator' - arguments: - - '@prestashop.adapter.customer.customer_data_source' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.address_zip_code_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\AddressZipCodeValidator' - arguments: - - '@translator' - - '@prestashop.adapter.country.country_zip_code_requirements_provider' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.address_country_dni_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\AddressDniRequiredValidator' - arguments: - - '@prestashop.adapter.country.country_required_fields_provider' - tags: - - { name: validator.constraint_validator } - - prestashop.core.constraint_validator.address_country_state_validator: - class: 'PrestaShop\PrestaShop\Core\ConstraintValidator\AddressStateRequiredValidator' - arguments: - - '@prestashop.adapter.country.country_required_fields_provider' - tags: - - { name: validator.constraint_validator } diff --git a/src/PrestaShopBundle/Resources/config/services/core/currency.yml b/src/PrestaShopBundle/Resources/config/services/core/currency.yml deleted file mode 100644 index 9f37a4ea..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/currency.yml +++ /dev/null @@ -1,36 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.currency.grid_data_factory: - class: 'PrestaShop\PrestaShop\Core\Currency\CurrencyGridDataFactory' - arguments: - - '@prestashop.core.grid.data_provider.currency' - - '@translator' - - prestashop.core.currency.exchange_rate.settings: - class: PrestaShop\CircuitBreaker\FactorySettings - arguments: - - !php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::CLOSED_ALLOWED_FAILURES - - !php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::CLOSED_TIMEOUT_SECONDS - - !php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::OPEN_THRESHOLD_SECONDS - calls: - - ['setStrippedFailures', [!php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::OPEN_ALLOWED_FAILURES]] - - ['setStrippedTimeout', [!php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::OPEN_TIMEOUT_SECONDS]] - - ['setStorage', ['@prestashop.core.circuit_breaker.storage']] - - ['setClientOptions', [{'method': 'GET', 'subscribers': ['@prestashop.core.circuit_breaker.guzzle.cache_subscriber']}]] - # create a factory for cache_subscriber so that we can easily adapt the cache duration - - prestashop.core.currency.exchange_rate.circuit_breaker: - class: 'PrestaShop\CircuitBreaker\Contract\CircuitBreakerInterface' - factory: ["@prestashop.core.circuit_breaker.advanced_factory", create] - arguments: - - "@prestashop.core.currency.exchange_rate.settings" - - prestashop.core.exchange_rate.provider: - class: PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider - arguments: - - !php/const \PrestaShop\PrestaShop\Core\Currency\ExchangeRateProvider::CURRENCY_FEED_URL - - '@=service("prestashop.adapter.data_provider.currency").getDefaultCurrencyIsoCode()' - - '@prestashop.core.currency.exchange_rate.circuit_breaker' - - '@cache.app' diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain.yml b/src/PrestaShopBundle/Resources/config/services/core/domain.yml deleted file mode 100644 index b491df33..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain.yml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: domain/*.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/cart.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/cart.yml deleted file mode 100644 index bf647149..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/cart.yml +++ /dev/null @@ -1,3 +0,0 @@ -services: - _defaults: - public: true diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/country.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/country.yml deleted file mode 100644 index 6dcfbc08..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/country.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.domain.country.zip_code_format_resolver: - class: 'PrestaShop\PrestaShop\Core\Domain\Country\ZipCodePatternResolver' diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/customer_service.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/customer_service.yml deleted file mode 100644 index 3a0587a0..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/customer_service.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.domain.customer_service.command_handler.update_customer_thread_status_handler: - class: PrestaShop\PrestaShop\Core\Domain\CustomerService\CommandHandler\UpdateCustomerThreadStatusHandler - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\CustomerService\Command\UpdateCustomerThreadStatusCommand diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/showcase_card.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/showcase_card.yml deleted file mode 100644 index faa47e0f..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/showcase_card.yml +++ /dev/null @@ -1,28 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.showcase_card.configuration_map: - class: 'PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\ConfigurationMap' - - # Command handlers - - prestashop.core.showcase_card.command_handler.close_showcase_card: - class: 'PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\CommandHandler\CloseShowcaseCardHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.showcase_card.configuration_map' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Command\CloseShowcaseCardCommand' - - # Query handlers - - prestashop.core.domain.showcase_card.query_handler.get_showcase_card_is_closed_handler: - class: PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\QueryHandler\GetShowcaseCardIsClosedHandler - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.showcase_card.configuration_map' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\ShowcaseCard\Query\GetShowcaseCardIsClosed' diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/sql_management.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/sql_management.yml deleted file mode 100644 index bb10155d..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/sql_management.yml +++ /dev/null @@ -1,23 +0,0 @@ -services: - _defaults: - public: true - - # COMMAND HANDLERS - - prestashop.core.domain.sql_management.command_handler.save_settings: - class: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\CommandHandler\SaveSqlRequestSettingsHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Command\SaveSqlRequestSettingsCommand' - - # QUERY HANDLERS - - prestashop.core.domain.sql_management.query_handler.get_sql_request_settings: - class: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\QueryHandler\GetSqlRequestSettingsHandler' - arguments: - - '@prestashop.adapter.legacy.configuration' - tags: - - name: 'tactician.handler' - command: 'PrestaShop\PrestaShop\Core\Domain\SqlManagement\Query\GetSqlRequestSettings' diff --git a/src/PrestaShopBundle/Resources/config/services/core/domain/theme.yml b/src/PrestaShopBundle/Resources/config/services/core/domain/theme.yml deleted file mode 100644 index 0d431091..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/domain/theme.yml +++ /dev/null @@ -1,46 +0,0 @@ -services: - _defaults: - public: true - - # COMMAND HANDLERS - - prestashop.core.domain.theme.command_handler.import_theme_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler\ImportThemeHandler' - arguments: - - '@prestashop.core.addon.theme.theme_zip_uploader' - - '@prestashop.core.addon.theme.theme_manager' - - '@prestashop.adapter.legacy.configuration' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Theme\Command\ImportThemeCommand } - - prestashop.core.domain.theme.command_handler.enable_theme_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler\EnableThemeHandler' - arguments: - - '@prestashop.core.addon.theme.theme_manager' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - '@=service("prestashop.adapter.shop.context").isSingleShopContext()' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Theme\Command\EnableThemeCommand } - - prestashop.core.domain.theme.command_handler.delete_theme_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler\DeleteThemeHandler' - arguments: - - '@prestashop.core.addon.theme.theme_manager' - tags: - - { name: tactician.handler, command: PrestaShop\PrestaShop\Core\Domain\Theme\Command\DeleteThemeCommand } - - prestashop.core.domain.theme.command_handler.adapt_theme_to_rtl_languages_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler\AdaptThemeToRTLLanguagesHandler' - arguments: - - '@prestashop.core.localization.rtl.processor_factory' - tags: - - name: 'tactician.handler' - command: PrestaShop\PrestaShop\Core\Domain\Theme\Command\AdaptThemeToRTLLanguagesCommand - - prestashop.core.domain.theme.command_handler.reset_theme_layouts_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\Theme\CommandHandler\ResetThemeLayoutsHandler' - arguments: - - '@prestashop.core.addon.theme.theme_manager' - tags: - - name: 'tactician.handler' - command: PrestaShop\PrestaShop\Core\Domain\Theme\Command\ResetThemeLayoutsCommand diff --git a/src/PrestaShopBundle/Resources/config/services/core/employee.yml b/src/PrestaShopBundle/Resources/config/services/core/employee.yml deleted file mode 100644 index 5ecfc9ac..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/employee.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.team.employee.configuration.options_checker: - class: 'PrestaShop\PrestaShop\Core\Team\Employee\Configuration\OptionsChecker' - arguments: - - '@prestashop.adapter.multistore_feature' - - '@prestashop.adapter.shop.context' - - prestashop.core.employee.profile_access_checker: - class: 'PrestaShop\PrestaShop\Core\Employee\Access\ProfileAccessChecker' - arguments: - - '@prestashop.adapter.employee.data_provider' - - '@=service("prestashop.adapter.legacy.configuration").getInt("_PS_ADMIN_PROFILE_")' diff --git a/src/PrestaShopBundle/Resources/config/services/core/export.yml b/src/PrestaShopBundle/Resources/config/services/core/export.yml deleted file mode 100644 index 50870e9b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/export.yml +++ /dev/null @@ -1,13 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.export.dir: - class: 'PrestaShop\PrestaShop\Core\Export\ExportDirectory' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.export.file_writer.export_csv_file_writer: - class: 'PrestaShop\PrestaShop\Core\Export\FileWriter\ExportCsvFileWriter' - arguments: - - '@prestashop.core.export.dir' diff --git a/src/PrestaShopBundle/Resources/config/services/core/file.yml b/src/PrestaShopBundle/Resources/config/services/core/file.yml deleted file mode 100644 index 2e2f28bf..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/file.yml +++ /dev/null @@ -1,16 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.file.finder.invoice_model: - class: 'PrestaShop\PrestaShop\Core\File\InvoiceModelFinder' - arguments: - - [ - "@=service('prestashop.adapter.legacy.configuration').get('_PS_THEME_DIR_')~'pdf/'", - "@=service('prestashop.adapter.legacy.configuration').get('_PS_PDF_DIR_')" - ] - - prestashop.core.file.cached_finder.invoice_model: - class: 'PrestaShop\PrestaShop\Core\Proxy\CachedFileFinderProxy' - arguments: - - '@prestashop.core.file.finder.invoice_model' diff --git a/src/PrestaShopBundle/Resources/config/services/core/form.yml b/src/PrestaShopBundle/Resources/config/services/core/form.yml deleted file mode 100644 index b0040024..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form.yml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: form/*.yml } diff --git a/src/PrestaShopBundle/Resources/config/services/core/form/choice_provider.yml b/src/PrestaShopBundle/Resources/config/services/core/form/choice_provider.yml deleted file mode 100644 index 1e88cfac..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form/choice_provider.yml +++ /dev/null @@ -1,247 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.form.choice_provider.language_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\LanguageByIdChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.language' - - prestashop.core.form.choice_provider.all_languages: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\LanguageChoiceProvider' - arguments: - - '@=service("prestashop.adapter.data_provider.language").getLanguages(false)' - - prestashop.core.form.choice_provider.country_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CountryByIdChoiceProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - '@prestashop.adapter.data_provider.country' - - prestashop.core.form.choice_provider.currency_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CurrencyByIdChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.currency' - - prestashop.core.form.choice_provider.timezone_by_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\TimezoneByNameChoiceProvider' - arguments: - - '@prestashop.core.admin.timezone.repository' - - prestashop.core.form.choice_provider.localization_pack_by_iso_code: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\LocalizationPackByIsoCodeChoiceProvider' - arguments: - - '@prestashop.core.localization.pack.loader.remote' - - '@prestashop.core.localization.pack.loader.local' - - '@prestashop.adapter.legacy.configuration' - - '@translator' - - prestashop.core.form.choice_provider.non_installed_localization: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\NonInstalledLocalizationChoiceProvider' - arguments: - - '@=service("prestashop.core.language.pack.loader.remote").getLanguagePackList()' - - '@prestashop.adapter.language.validator' - - '@prestashop.adapter.data_provider.language' - - prestashop.core.form.choice_provider.country_by_iso_code: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CountryByIsoCodeChoiceProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - '@prestashop.adapter.data_provider.country' - - prestashop.core.form.choice_provider.group_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\GroupByIdChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.group' - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.core.form.choice_provider.carrier_by_reference_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CarrierByReferenceChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.carrier' - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.core.form.choice_provider.order_state_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\OrderStateByIdChoiceProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - '@prestashop.adapter.data_provider.order_state' - - '@prestashop.core.util.color_brightness_calculator' - - '@translator' - - prestashop.core.form.choice_provider.invoice_model_by_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\InvoiceModelByNameChoiceProvider' - arguments: - - '@prestashop.core.file.cached_finder.invoice_model' - - prestashop.core.form.choice_provider.mail_method: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\MailMethodChoiceProvider' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@translator' - - prestashop.core.form.choice_provider.contact_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ContactByIdChoiceProvider' - arguments: - - '@prestashop.adapter.contact.repository' - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.core.form.choice_provider.translation_type: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\TranslationTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.email_content_type: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\EmailContentTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.theme_by_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ThemeByNameChoiceProvider' - arguments: - - '@=service("prestashop.core.addon.theme.repository").getListAsCollection()' - - prestashop.core.form.choice_provider.theme_by_name_with_emails: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ThemeByNameWithEmailsChoiceProvider' - arguments: - - '@=service("prestashop.core.addon.theme.repository").getListAsCollection()' - - prestashop.core.form.choice_provider.module_by_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ModuleByNameChoiceProvider' - arguments: - - '@=service("prestashop.core.admin.module.repository").getInstalledModulesCollection()' - - prestashop.core.form.choice_provider.status: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\StatusChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.canonical_redirect_type: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CanonicalRedirectTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.category_delete_mode: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CategoryDeleteModeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.customer_required_fields: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CustomerRequiredFieldsChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.import_match_configuration: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ImportMatchConfigurationChoiceProvider' - arguments: - - '@=service("prestashop.core.admin.import_match.repository").findAll()' - - prestashop.core.form.choice_provider.import_entity_field: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ImportEntityFieldChoiceProvider' - arguments: - - '@=service("prestashop.core.import.fields_provider_finder")' - - '@=service("session").get("entity")' - - prestashop.core.form.choice_provider.customer_delete_method: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CustomerDeleteMethodChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.theme_page_layouts: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ThemePageLayoutsChoiceProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().shop.theme' - - prestashop.core.form.choice_provider.theme_zip: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ThemeZipChoiceProvider' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.form.choice_provider.theme: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ThemeChoiceProvider' - arguments: - - '@prestashop.core.addon.theme.theme_provider' - - prestashop.core.form.choice_provider.currency_name_by_iso_code: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CurrencyNameByIsoCodeChoiceProvider' - arguments: - - '@=service("prestashop.core.localization.cldr.locale_repository").getLocale(service("prestashop.adapter.legacy.context").getContext().language.getLocale()).getAllCurrencies()' - - prestashop.core.form.choice_provider.permissions_choice_provider: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\PermissionsChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.default_meta_page_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\DefaultMetaPageNameChoiceProvider' - arguments: - - '@request_stack' - - '@prestashop.adapter.meta.data_provider' - - prestashop.core.form.choice_provider.module_meta_page_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ModuleMetaPageNameChoiceProvider' - arguments: - - '@request_stack' - - '@prestashop.adapter.meta.data_provider' - - prestashop.core.form.choice_provider.tax_address_type_choice_provider: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\TaxAddressTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.tax_rule_group_choice_provider: - class: 'PrestaShop\PrestaShop\Adapter\Form\ChoiceProvider\TaxRuleGroupChoiceProvider' - - prestashop.core.form.choice_provider.cms_categories: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CmsCategoriesChoiceProvider' - arguments: - - '@=service("prestashop.adapter.cms_page.categories_provider").getAllNestedCategories()' - - prestashop.core.form.choice_provider.accessible_tab: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\TabChoiceProvider' - arguments: - - '@=service("prestashop.adapter.data_provider.tab").getViewableTabsForContextEmployee(service("prestashop.adapter.legacy.context").getLanguage().id)' - - prestashop.core.form.choice_provider.profile: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\ProfileChoiceProvider' - arguments: - - '@=service("prestashop.adapter.data_provider.profile").getProfiles(service("prestashop.adapter.legacy.context").getLanguage().id)' - - prestashop.core.form.choice_provider.mail_themes: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\MailThemeChoiceProvider' - arguments: - - '@prestashop.core.mail_template.theme_catalog' - - prestashop.core.form.choice.provider.order_discount_type: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\OrderDiscountTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.tax_inclusion: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\TaxInclusionChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.price_reduction_type: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\PriceReductionTypeChoiceProvider' - arguments: - - '@translator' - - prestashop.core.form.choice_provider.address_required_fields: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\AddressRequiredFieldsChoiceProvider' - - prestashop.core.form.choice_provider.customer_addresses_by_id: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CustomerAddressesChoiceProvider' - arguments: - - '@prestashop.adapter.data_provider.customer' - - '@=service("prestashop.adapter.legacy.context").getLanguage().id' - - prestashop.core.form.choice_provider.customer_service_order_messages_name: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CustomerServiceOrderMessagesNameChoiceProvider' - arguments: - - '@=service("prestashop.adapter.order_message.order_message_provider").getMessages()' - - prestashop.core.form.choice_provider.customer_service_order_messages: - class: 'PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CustomerServiceOrderMessagesChoiceProvider' - arguments: - - '@=service("prestashop.adapter.order_message.order_message_provider").getMessages()' diff --git a/src/PrestaShopBundle/Resources/config/services/core/form/form_builder.yml b/src/PrestaShopBundle/Resources/config/services/core/form/form_builder.yml deleted file mode 100644 index 0e8a4d1b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form/form_builder.yml +++ /dev/null @@ -1,170 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.form.builder.form_builder_factory: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilderFactory' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.form.builder.sql_request_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\RequestSql\SqlRequestType' - - '@prestashop.core.form.identifiable_object.data_provider.sql_request_form_data_provider' - - prestashop.core.form.identifiable_object.builder.customer_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Customer\CustomerType' - - '@prestashop.core.form.identifiable_object.data_provider.customer_form_data_provider' - - prestashop.core.form.identifiable_object.builder.language_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Improve\International\Language\LanguageType' - - '@prestashop.core.form.identifiable_object.data_provider.language_form_data_provider' - - prestashop.core.form.builder.currency_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Improve\International\Currencies\CurrencyType' - - '@prestashop.core.form.identifiable_object.data_provider.currency_form_data_provider' - - prestashop.core.form.identifiable_object.builder.webservice_key_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Webservice\WebserviceKeyType' - - '@prestashop.core.form.identifiable_object.data_provider.webservice_key_form_data_provider' - - prestashop.core.form.builder.meta_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\TrafficSeo\Meta\MetaType' - - '@prestashop.core.form.identifiable_object.data_provider.meta_form_data_provider' - - prestashop.core.form.identifiable_object.builder.category_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Catalog\Category\CategoryType' - - '@prestashop.core.form.identifiable_object.data_provider.category_form_data_provider' - - prestashop.core.form.identifiable_object.builder.root_category_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Catalog\Category\RootCategoryType' - - '@prestashop.core.form.identifiable_object.data_provider.category_form_data_provider' - - prestashop.core.form.identifiable_object.builder.contact_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\ShopParameters\Contact\ContactType' - - '@prestashop.core.form.identifiable_object.data_provider.contact_form_data_provider' - - prestashop.core.form.identifiable_object.builder.cms_page_category_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Improve\Design\Pages\CmsPageCategoryType' - - '@prestashop.core.form.identifiable_object.data_provider.cms_page_category_form_data_provider' - - prestashop.core.form.identifiable_object.builder.tax_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Improve\International\Tax\TaxType' - - '@prestashop.core.form.identifiable_object.data_provider.tax_form_data_provider' - - prestashop.core.form.identifiable_object.builder.manufacturer_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Manufacturer\ManufacturerType' - - '@prestashop.core.form.identifiable_object.data_provider.manufacturer_form_data_provider' - - prestashop.core.form.identifiable_object.builder.employee_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Employee\EmployeeType' - - '@prestashop.core.form.identifiable_object.data_provider.employee_form_data_provider' - - prestashop.core.form.identifiable_object.builder.profile_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Configure\AdvancedParameters\Profile\ProfileType' - - '@prestashop.core.form.identifiable_object.data_provider.profile_form_data_provider' - - prestashop.core.form.identifiable_object.builder.cms_page_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Improve\Design\Pages\CmsPageType' - - '@prestashop.core.form.identifiable_object.data_provider.cms_page_form_data_provider' - - prestashop.core.form.identifiable_object.builder.manufacturer_address_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Address\ManufacturerAddressType' - - '@prestashop.core.form.identifiable_object.data_provider.manufacturer_address_form_data_provider' - - prestashop.core.form.identifiable_object.builder.supplier_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Supplier\SupplierType' - - '@prestashop.core.form.identifiable_object.data_provider.supplier_form_data_provider' - - prestashop.core.form.identifiable_object.builder.feature_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Catalog\FeatureType' - - '@prestashop.core.form.identifiable_object.data_provider.feature_form_data_provider' - - prestashop.core.form.identifiable_object.builder.order_message_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\CustomerService\OrderMessageType' - - '@prestashop.core.form.identifiable_object.data_provider.order_message_form_data_provider' - - prestashop.core.form.identifiable_object.builder.catalog_price_rule_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\CatalogPriceRule\CatalogPriceRuleType' - - '@prestashop.core.form.identifiable_object.data_provider.catalog_price_rule_form_data_provider' - - prestashop.core.form.identifiable_object.builder.attachment_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Attachment\AttachmentType' - - '@prestashop.core.form.identifiable_object.data_provider.attachment_form_data_provider' - - prestashop.core.form.identifiable_object.builder.cancel_product_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Order\CancelProductType' - - '@prestashop.core.form.identifiable_object.data_provider.cancel_product_form_data_provider' - - prestashop.core.form.identifiable_object.builder.address_form_builder: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Builder\FormBuilder' - factory: 'prestashop.core.form.builder.form_builder_factory:create' - arguments: - - 'PrestaShopBundle\Form\Admin\Sell\Address\CustomerAddressType' - - '@prestashop.core.form.identifiable_object.data_provider.address_form_data_provider' diff --git a/src/PrestaShopBundle/Resources/config/services/core/form/form_data_handler.yml b/src/PrestaShopBundle/Resources/config/services/core/form/form_data_handler.yml deleted file mode 100644 index 262188fb..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form/form_data_handler.yml +++ /dev/null @@ -1,167 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.form.identifiable_object.sql_request_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\SqlRequestFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.customer_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CustomerFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@=service("prestashop.core.b2b.b2b_feature").isActive()' - - prestashop.core.form.identifiable_object.data_handler.language_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\LanguageFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.meta_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\MetaFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.currency_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CurrencyFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - - - '@prestashop.adapter.cache.clearer.symfony_cache_clearer' - - '@prestashop.adapter.cache.clearer.smarty_cache_clearer' - - prestashop.core.form.identifiable_object.data_handler.webservice_key_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\WebserviceKeyFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.core.form.identifiable_object.data_handler.category_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CategoryFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.image.uploader.category_cover_image_uploader' - - '@prestashop.adapter.image.uploader.category_thumbnail_image_uploader' - - '@prestashop.adapter.image.uploader.category_menu_thumbnail_image_uploader' - - prestashop.core.form.identifiable_object.data_handler.root_category_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\RootCategoryFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.image.uploader.category_cover_image_uploader' - - '@prestashop.adapter.image.uploader.category_thumbnail_image_uploader' - - '@prestashop.adapter.image.uploader.category_menu_thumbnail_image_uploader' - - prestashop.core.form.identifiable_object.data_handler.contact_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ContactFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.cms_page_category_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CmsPageCategoryFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.tax_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\TaxFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.manufacturer_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ManufacturerFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.image.uploader.manufacturer_image_uploader' - - prestashop.core.form.identifiable_object.data_handler.employee_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\EmployeeFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - '@=service("prestashop.adapter.legacy.configuration").getInt("_PS_ADMIN_PROFILE_")' - - '@prestashop.adapter.employee.form_access_checker' - - '@prestashop.adapter.employee.data_provider' - - '@prestashop.core.crypto.hashing' - - prestashop.core.form.identifiable_object.data_handler.profile_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ProfileFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.cms_page_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CmsPageFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.manufacturer_address_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ManufacturerAddressFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.supplier_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\SupplierFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.image.uploader.supplier_image_uploader' - - prestashop.core.form.identifiable_object.data_handler.feature_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\FeatureFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.order_message_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\OrderMessageFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.catalog_price_rule_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CatalogPriceRuleFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.core.form.identifiable_object.data_handler.attachment_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\AttachmentFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.attachment.uploader.attachment_file_uploader' - - prestashop.core.form.identifiable_object.partial_refund_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\PartialRefundFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.standard_refund_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\StandardRefundFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.return_product_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\ReturnProductFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.address_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\AddressFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.adapter.data_provider.customer' - - prestashop.core.form.identifiable_object.data_handler.order_address_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\OrderAddressFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_handler.cart_address_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CartAddressFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.cancellation_form_data_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataHandler\CancellationFormDataHandler' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.core.query_bus' diff --git a/src/PrestaShopBundle/Resources/config/services/core/form/form_data_provider.yml b/src/PrestaShopBundle/Resources/config/services/core/form/form_data_provider.yml deleted file mode 100644 index d94f66ce..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form/form_data_provider.yml +++ /dev/null @@ -1,140 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.form.identifiable_object.data_provider.sql_request_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\SqlRequestFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.customer_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CustomerFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.group.provider.default_groups_provider' - - '@=service("prestashop.core.b2b.b2b_feature").isActive()' - - prestashop.core.form.identifiable_object.data_provider.language_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\LanguageFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - prestashop.core.form.identifiable_object.data_provider.currency_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CurrencyFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.core.form.identifiable_object.data_provider.webservice_key_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\WebserviceKeyFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - - prestashop.core.form.identifiable_object.data_provider.meta_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\MetaFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.category_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CategoryFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.getCategory()' - - '@prestashop.adapter.group.provider.default_groups_provider' - - prestashop.core.form.identifiable_object.data_provider.contact_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\ContactFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@prestashop.bundle.form.data_transformer.string_array_to_integer_array' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.core.form.identifiable_object.data_provider.cms_page_category_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CmsPageCategoryFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.core.form.identifiable_object.data_provider.tax_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\TaxFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.manufacturer_address_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\ManufacturerAddressFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' - - prestashop.core.form.identifiable_object.data_provider.manufacturer_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\ManufacturerFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - prestashop.core.form.identifiable_object.data_provider.employee_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\EmployeeFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - prestashop.core.form.identifiable_object.data_provider.profile_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\ProfileFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.cms_page_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CmsPageFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.core.form.identifiable_object.data_provider.supplier_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\SupplierFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' - - prestashop.core.form.identifiable_object.data_provider.feature_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\FeatureFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - prestashop.core.form.identifiable_object.data_provider.order_message_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\OrderMessageFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.catalog_price_rule_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CatalogPriceRuleFormDataProvider' - arguments: - - '@prestashop.core.command_bus' - - prestashop.core.form.identifiable_object.data_provider.attachment_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\AttachmentFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - prestashop.core.form.identifiable_object.data_provider.cancel_product_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\CancelProductFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@prestashop.adapter.data_provider.currency' - - prestashop.core.form.identifiable_object.data_provider.address_form_data_provider: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\DataProvider\AddressFormDataProvider' - arguments: - - '@prestashop.core.query_bus' - - '@=service("prestashop.adapter.legacy.context").getContext().country.id' diff --git a/src/PrestaShopBundle/Resources/config/services/core/form/form_handler.yml b/src/PrestaShopBundle/Resources/config/services/core/form/form_handler.yml deleted file mode 100644 index 74e80f44..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/form/form_handler.yml +++ /dev/null @@ -1,179 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.form.identifiable_object.handler.form_handler_factory: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandlerFactory' - arguments: - - '@prestashop.core.hook.dispatcher' - - '@translator' - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_MODE_DEMO_")' - - prestashop.core.form.identifiable_object.sql_request_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.sql_request_form_data_handler' - - prestashop.core.form.identifiable_object.handler.customer_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.customer_form_data_handler' - - prestashop.core.form.identifiable_object.handler.language_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.language_form_data_handler' - - prestashop.core.form.identifiable_object.currency_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.currency_form_data_handler' - - prestashop.core.form.identifiable_object.handler.webservice_key_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.webservice_key_form_data_handler' - - - prestashop.core.form.identifiable_object.meta_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.meta_form_data_handler' - - prestashop.core.form.identifiable_object.handler.category_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.category_form_data_handler' - - prestashop.core.form.identifiable_object.handler.root_category_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.root_category_form_data_handler' - - prestashop.core.form.identifiable_object.handler.contact_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.contact_form_data_handler' - - prestashop.core.form.identifiable_object.handler.cms_page_category_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.cms_page_category_form_data_handler' - - prestashop.core.form.identifiable_object.handler.tax_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.tax_form_data_handler' - - prestashop.core.form.identifiable_object.handler.manufacturer_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.manufacturer_form_data_handler' - - prestashop.core.form.identifiable_object.handler.employee_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.employee_form_data_handler' - - prestashop.core.form.identifiable_object.handler.profile_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.profile_form_data_handler' - - prestashop.core.form.identifiable_object.handler.cms_page_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.cms_page_form_data_handler' - - prestashop.core.form.identifiable_object.handler.manufacturer_address_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.manufacturer_address_form_data_handler' - - prestashop.core.form.identifiable_object.handler.supplier_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.supplier_form_data_handler' - - prestashop.core.form.identifiable_object.handler.feature_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.feature_form_data_handler' - - prestashop.core.form.identifiable_object.handler.order_message_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.order_message_form_data_handler' - - prestashop.core.form.identifiable_object.handler.catalog_price_rule_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.catalog_price_rule_form_data_handler' - - prestashop.core.form.identifiable_object.handler.attachment_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.attachment_form_data_handler' - - prestashop.core.form.identifiable_object.partial_refund_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.partial_refund_form_data_handler' - - prestashop.core.form.identifiable_object.standard_refund_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.standard_refund_form_data_handler' - - prestashop.core.form.identifiable_object.return_product_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.return_product_form_data_handler' - - prestashop.core.form.identifiable_object.handler.address_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.address_form_data_handler' - - prestashop.core.form.identifiable_object.handler.order_address_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.order_address_form_data_handler' - - prestashop.core.form.identifiable_object.handler.cart_address_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.data_handler.cart_address_form_data_handler' - - prestashop.core.form.identifiable_object.cancellation_form_handler: - class: 'PrestaShop\PrestaShop\Core\Form\IdentifiableObject\Handler\FormHandler' - factory: 'prestashop.core.form.identifiable_object.handler.form_handler_factory:create' - arguments: - - '@prestashop.core.form.identifiable_object.cancellation_form_data_handler' diff --git a/src/PrestaShopBundle/Resources/config/services/core/foundation.yml b/src/PrestaShopBundle/Resources/config/services/core/foundation.yml deleted file mode 100644 index 223e39df..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/foundation.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.foundation.version: - class: PrestaShop\PrestaShop\Core\Foundation\Version - arguments: - - !php/const AppKernel::VERSION - - !php/const AppKernel::MAJOR_VERSION_STRING - - !php/const AppKernel::MAJOR_VERSION - - !php/const AppKernel::MINOR_VERSION - - !php/const AppKernel::RELEASE_VERSION diff --git a/src/PrestaShopBundle/Resources/config/services/core/geolocation.yml b/src/PrestaShopBundle/Resources/config/services/core/geolocation.yml deleted file mode 100644 index 533033c3..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/geolocation.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.geolocation.geo_lite_city.checker: - class: 'PrestaShop\PrestaShop\Core\Geolocation\GeoLite\GeoLiteCityChecker' - arguments: - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid.yml b/src/PrestaShopBundle/Resources/config/services/core/grid.yml deleted file mode 100644 index d23b8b7f..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid.yml +++ /dev/null @@ -1,44 +0,0 @@ -imports: - - { resource: grid/*.yml } - -parameters: - prestashop.core.grid.data.factory.doctrine_grid_data_factory: PrestaShop\PrestaShop\Core\Grid\Data\Factory\DoctrineGridDataFactory - -services: - _defaults: - public: true - - prestashop.core.grid.presenter.grid_presenter: - class: 'PrestaShop\PrestaShop\Core\Grid\Presenter\GridPresenter' - arguments: - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.query.doctrine_query_parser: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\DoctrineQueryParser' - - prestashop.core.query.doctrine_search_criteria_applicator: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\DoctrineSearchCriteriaApplicator' - - # Grid position updater - prestashop.core.grid.position.position_update_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionUpdateFactory' - arguments: - - 'positions' - - 'rowId' - - 'oldPosition' - - 'newPosition' - - 'parentId' - - prestashop.core.grid.position.update_handler.doctrine_position_update_handler: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\UpdateHandler\DoctrinePositionUpdateHandler' - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.core.grid.position.doctrine_grid_position_updater: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\GridPositionUpdater' - arguments: - - '@prestashop.core.grid.position.update_handler.doctrine_position_update_handler' - - prestashop.core.grid.query.filter.doctrine_filter_applicator: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Filter\DoctrineFilterApplicator' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/accessibility_checker.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/accessibility_checker.yml deleted file mode 100644 index 8b70c2b7..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/accessibility_checker.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.action.row.accessibility_checker.delete_profile: - class: 'PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\DeleteProfileAccessibilityChecker' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_ADMIN_PROFILE_")' - - prestashop.core.grid.action.row.accessibility_checker.print_invoice: - class: 'PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\PrintInvoiceAccessibilityChecker' - - prestashop.core.grid.action.row.accessibility_checker.print_delivery_slip: - class: 'PrestaShop\PrestaShop\Core\Grid\Action\Row\AccessibilityChecker\PrintDeliverySlipAccessibilityChecker' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/doctrine_query_builder.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/doctrine_query_builder.yml deleted file mode 100644 index b2b2d1d2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/doctrine_query_builder.yml +++ /dev/null @@ -1,291 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.abstract_query_builder: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\AbstractDoctrineQueryBuilder' - abstract: true - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - prestashop.core.grid.query_builder.email_logs: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\EmailLogsQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - public: true - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - prestashop.core.grid.query.webservice_key: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\WebserviceKeyQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@prestashop.core.grid.query.filter.doctrine_filter_applicator' - public: true - - prestashop.core.grid.query_builder.meta: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\MetaQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - public: true - - prestashop.core.grid.query_builder.employee: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\EmployeeQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.getContextListShopID()" - public: true - - prestashop.core.grid.query_builder.contact: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\ContactQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - public: true - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.shop.context').getContextListShopID()" - - prestashop.core.grid.query_builder.customer: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CustomerQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - '@=service("prestashop.adapter.shop.context").getContextListShopIDUsingCustomerSharingSettings()' - public: true - - prestashop.core.grid.quer_.builder.language: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\LanguageQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - public: true - - prestashop.core.grid.query_builder.currency: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CurrencyQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - public: true - - prestashop.core.grid.query_builder.supplier: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\SupplierQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.shop.context').getContextListShopID()" - public: true - - prestashop.core.grid.query_builder.profile: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\ProfileQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - public: true - - prestashop.core.grid.query_builder.cms_page_category: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CmsPageCategoryQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - public: true - - prestashop.core.grid.query_builder.tax: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\TaxQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().employee.id_lang" - public: true - - prestashop.core.grid.query_builder.manufacturer: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\ManufacturerQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopId()' - public: true - - prestashop.core.grid.query_builder.manufacturer_address: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\ManufacturerAddressQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - public: true - - prestashop.core.grid.query_builder.category: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CategoryQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - - '@prestashop.adapter.shop.context' - - '@prestashop.adapter.feature.multistore' - - "@=service('prestashop.adapter.legacy.configuration').get('PS_ROOT_CATEGORY')" - public: true - - prestashop.core.grid.query_builder.cms_page: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CmsPageQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - public: true - - prestashop.core.grid.query_builder.monitoring.empty_category: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\EmptyCategoryQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@prestashop.adapter.shop.context' - - "@=service('prestashop.adapter.legacy.configuration').get('PS_ROOT_CATEGORY')" - public: true - - prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\AbstractProductQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.legacy.context').getContext().shop.id" - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@prestashop.adapter.shop.context' - - '@prestashop.adapter.feature.multistore' - public: true - - prestashop.core.grid.query_builder.monitoring.no_qty_product_with_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\NoQtyProductWithCombinationQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.monitoring.no_qty_product_without_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\NoQtyProductWithoutCombinationQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.monitoring.disabled_product: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\DisabledProductQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.monitoring.product_without_image: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\ProductWithoutImageQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.monitoring.product_without_description: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\ProductWithoutDescriptionQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.monitoring.product_without_price: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\Monitoring\ProductWithoutPriceQueryBuilder' - parent: 'prestashop.core.grid.query_builder.monitoring.abstract_product_query_builder' - public: true - - prestashop.core.grid.query_builder.order: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\OrderQueryBuilder' - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - "@=service(\"prestashop.adapter.shop.context\").getContextListShopID(parameter('multishop.settings.share_orders'))" - - prestashop.core.grid.query_builder.catalog_price_rule: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CatalogPriceRuleQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getShops(true, true)' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - public: true - - prestashop.core.grid.query_builder.order_message: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\OrderMessageQueryBuilder' - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - '@prestashop.core.grid.query.filter.doctrine_filter_applicator' - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - prestashop.core.grid.query_builder.attachment: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\AttachmentQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().employee.id_lang" - public: true - - prestashop.core.grid.query_builder.attribute: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\AttributeQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@=service("request_stack").getCurrentRequest().attributes.getInt("attributeGroupId")' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - public: true - - prestashop.core.grid.query_builder.attribute_group: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\AttributeGroupQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.legacy.context").getContext().language.id' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - public: true - - prestashop.core.grid.query_builder.merchandise_return: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\MerchandiseReturnQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - public: true - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - "@=service('prestashop.adapter.shop.context').getContextListShopID()" - - prestashop.core.grid.query_builder.tax_rules_group: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\TaxRulesGroupQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.shop.context').getContextListShopID()" - public: true - - prestashop.core.grid.query_builder.address: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\AddressQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - public: true - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - "@=service('prestashop.adapter.legacy.context').getContext().language.id" - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - - prestashop.core.grid.query_builder.credit_slip: - class: 'PrestaShop\PrestaShop\Core\Grid\Query\CreditSlipQueryBuilder' - parent: 'prestashop.core.grid.abstract_query_builder' - arguments: - - '@prestashop.core.query.doctrine_search_criteria_applicator' - - '@=service("prestashop.adapter.shop.context").getContextListShopID()' - public: true diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_data_factory.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/grid_data_factory.yml deleted file mode 100644 index 134203e6..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_data_factory.yml +++ /dev/null @@ -1,359 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.data_factory.log: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.admin.log.repository' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'logs' - - prestashop.core.grid.data_factory.email_logs: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.email_logs' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'email_logs' - - prestashop.core.grid.data_factory.request_sql: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.admin.request_sql.repository' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'request_sql' - - prestashop.core.grid.data_factory.webservice_key: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query.webservice_key' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'webservice_key' - - prestashop.core.grid.data_provider.meta: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.meta' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'meta' - - prestashop.core.grid.data.factory.category: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.category' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'category' - - prestashop.core.grid.data.factory.category_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\CategoryDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.category' - - prestashop.core.grid.data_provider.employee: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.employee' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'employee' - - prestashop.core.grid.data_provider.contacts: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.contact' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'contact' - - prestashop.core.grid.data_provider.customer: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.customer' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'customer' - - prestashop.core.grid.data_provider.customer_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\CustomerGridDataFactoryDecorator' - arguments: - - '@prestashop.core.grid.data_provider.customer' - - "@prestashop.core.localization.locale.context_locale" - - "@=service('prestashop.adapter.legacy.context').getContext().currency.iso_code" - - prestashop.core.grid.data.factory.language: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.quer_.builder.language' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'language' - - prestashop.core.grid.factory.language_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\LanguageGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.language' - - '@prestashop.adapter.language.language_flag_thumbnail_provider' - - prestashop.core.grid.data_provider.currency: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.currency' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'currency' - - prestashop.core.grid.data_provider.supplier: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.supplier' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'suppliers' - - prestashop.core.grid.factory.supplier_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\SupplierGridDataFactory' - arguments: - - '@prestashop.core.grid.data_provider.supplier' - - '@prestashop.adapter.supplier.provider.supplier_logo' - - prestashop.core.grid.data_factory.profiles: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.profile' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'profile' - - prestashop.core.grid.data_provider.cms_page_category: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.cms_page_category' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'cms_page_category' - - prestashop.core.grid.data_factory.tax: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.tax' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'tax' - - prestashop.core.grid.data.factory.manufacturer: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.manufacturer' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'manufacturer' - - prestashop.core.grid.data.factory.manufacturer_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\ManufacturerGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.manufacturer' - - '@prestashop.adapter.manufacturer.manufacturer_logo_thumbnail_provider' - - prestashop.core.grid.data.factory.manufacturer_address: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\DoctrineGridDataFactory' - arguments: - - '@prestashop.core.grid.query_builder.manufacturer_address' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'manufacturer_address' - - prestashop.core.grid.data.factory.manufacturer_address_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\ManufacturerAddressGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.manufacturer_address' - - prestashop.core.grid.data_provider.cms_page: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.cms_page' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'cms_page' - - prestashop.core.grid.data.factory.empty_category: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.empty_category' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'empty_category' - - prestashop.core.grid.data.factory.empty_category_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\EmptyCategoryGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.empty_category' - - prestashop.core.grid.data.factory.no_qty_product_with_combination: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.no_qty_product_with_combination' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'no_qty_product_with_combination' - - prestashop.core.grid.data.factory.no_qty_product_without_combination: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.no_qty_product_without_combination' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'no_qty_product_without_combination' - - prestashop.core.grid.data.factory.disabled_product: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.disabled_product' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'disabled_product' - - prestashop.core.grid.data.factory.product_without_image: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.product_without_image' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'product_without_image' - - prestashop.core.grid.data.factory.product_without_description: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.product_without_description' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'product_without_description' - - prestashop.core.grid.data.factory.product_without_price: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.monitoring.product_without_price' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'product_without_price' - - prestashop.core.grid.data.factory.order: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.order' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'order' - - prestashop.core.grid.data.factory.order_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\OrderGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.order' - - '@prestashop.core.localization.locale.repository' - - '@prestashop.adapter.legacy.configuration' - - '@=service("prestashop.adapter.legacy.context").getContext().language.getLocale()' - - prestashop.core.grid.data.factory.catalog_price_rule: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.catalog_price_rule' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'catalog_price_rule' - - prestashop.core.grid.data.factory.catalog_price_rule_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\CatalogPriceRuleGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.catalog_price_rule' - - '@translator' - - prestashop.core.grid.data.factory.order_message: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.order_message' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'order_message' - - prestashop.core.grid.data_factory.attachment: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.attachment' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'attachment' - - prestashop.core.grid.data_factory.attachment_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\AttachmentGridDataFactoryDecorator' - arguments: - - '@prestashop.core.grid.data_factory.attachment' - - "@=service('prestashop.adapter.legacy.context').getContext().employee.id_lang" - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - "@prestashop.core.util.file_size.size_converter" - calls: - - [setTranslator, ['@translator']] - - prestashop.core.grid.data.factory.attribute: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.attribute' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'attribute' - - prestashop.core.grid.data.factory.attribute_group: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.attribute_group' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'attribute_group' - - prestashop.core.grid.data.factory.attribute_group_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\AttributeGroupGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.attribute_group' - - prestashop.core.grid.data_provider.merchandise_return: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.merchandise_return' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'merchandise_return' - - prestashop.core.grid.data.factory.tax_rules_group: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.tax_rules_group' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'tax_rules_group' - - prestashop.core.grid.data.factory.address: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.address' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'address' - - prestashop.core.grid.data.factory.credit_slip: - class: '%prestashop.core.grid.data.factory.doctrine_grid_data_factory%' - arguments: - - '@prestashop.core.grid.query_builder.credit_slip' - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.grid.query.doctrine_query_parser' - - 'credit_slip' - - prestashop.core.grid.data.factory.credit_slip_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Data\Factory\CreditSlipGridDataFactory' - arguments: - - '@prestashop.core.grid.data.factory.credit_slip' - - '@translator' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_definition_factory.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/grid_definition_factory.yml deleted file mode 100644 index abd29273..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_definition_factory.yml +++ /dev/null @@ -1,253 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.definition.factory.abstract_grid_definition: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AbstractGridDefinitionFactory' - abstract: true - arguments: - - '@prestashop.core.hook.dispatcher' - calls: - - [setTranslator, ['@translator']] - - prestashop.core.grid.definition.factory.logs: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\LogGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'logs', 'action': 'index'})" - - "@=service('router').generate('admin_logs_index')" - public: true - - prestashop.core.grid.definition.factory.email_logs: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\EmailLogsDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'email', 'action': 'index'})" - - "@=service('router').generate('admin_emails_index')" - - '@prestashop.core.form.choice_provider.language_by_id' - public: true - - prestashop.core.grid.definition.factory.request_sql: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\RequestSqlGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'sqlmanager', 'action': 'index'})" - - "@=service('router').generate('admin_sql_requests_index')" - public: true - - prestashop.core.grid.definition.factory.backup: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\BackupDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.webservice_key: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\WebserviceKeyDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@=service("prestashop.core.form.choice_provider.status").getChoices()' - - "@=service('router').generate('admin_common_reset_search', {'controller': 'webservice', 'action': 'index'})" - - "@=service('router').generate('admin_webservice_keys_index')" - public: true - - prestashop.core.grid.definition.factory.meta: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\MetaGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.category: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CategoryGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'category', 'action': 'index'})" - - "@=service('router').generate('admin_categories_index')" - - '@prestashop.adapter.shop.context' - - '@prestashop.adapter.grid.action.row.accessibility_checker.category_for_view' - public: true - - prestashop.core.grid.definition.factory.employee: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\EmployeeGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'employee', 'action': 'index'})" - - "@=service('router').generate('admin_employees_index')" - public: true - - prestashop.core.grid.definition.factory.contacts: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ContactGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'contacts', 'action': 'index'})" - - "@=service('router').generate('admin_contacts_index')" - public: true - - prestashop.core.grid.definition.factory.customer: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CustomerGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@=service("prestashop.core.b2b.b2b_feature").isActive()' - - '@=service("prestashop.adapter.multistore_feature").isActive()' - - '@=service("prestashop.adapter.form.choice_provider.gender_by_id_choice_provider").getChoices()' - public: true - - prestashop.core.grid.definition.factory.language: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\LanguageGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.currency: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CurrencyGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.supplier: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\SupplierGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.profile: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ProfileGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - "@=service('router').generate('admin_common_reset_search', {'controller': 'profile', 'action': 'index'})" - - "@=service('router').generate('admin_profiles_index')" - - '@prestashop.core.grid.action.row.accessibility_checker.delete_profile' - public: true - - prestashop.core.grid.definition.factory.cms_page_category: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageCategoryDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@request_stack' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - public: true - - prestashop.core.grid.definition.factory.tax: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\TaxGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.manufacturer: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.manufacturer_address: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\ManufacturerAddressGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.cms_page: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CmsPageDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@prestashop.core.query_bus' - - '@request_stack' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - public: true - - prestashop.core.grid.definition.factory.monitoring.empty_category: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\EmptyCategoryGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@prestashop.adapter.grid.action.row.accessibility_checker.category_for_view' - public: true - - prestashop.core.grid.definition.factory.monitoring.no_qty_product_with_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithCombinationGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.monitoring.no_qty_product_without_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\NoQtyProductWithoutCombinationGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.monitoring.disabled_product: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\DisabledProductGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.monitoring.product_without_image: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutImageGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.monitoring.product_without_description: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutDescriptionGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.monitoring.product_without_price: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\Monitoring\ProductWithoutPriceGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.order: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\OrderGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.form.choice_provider.order_countries' - - '@prestashop.core.form.choice_provider.order_state_by_id' - - '@=service("prestashop.adapter.legacy.context").getContext().language.date_format_full' - - '@prestashop.adapter.feature.multistore' - - '@prestashop.core.grid.action.row.accessibility_checker.print_invoice' - - '@prestashop.core.grid.action.row.accessibility_checker.print_delivery_slip' - - '@prestashop.core.form.choice_provider.order_state_by_id' - public: true - - prestashop.core.grid.definition.factory.catalog_price_rule: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CatalogPriceRuleGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@request_stack' - - '@prestashop.adapter.shop.context' - - '@=service("prestashop.adapter.multistore_feature").isUsed()' - public: true - - prestashop.core.grid.definition.factory.order_message: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\OrderMessageGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.attachment: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttachmentGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.attribute: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttributeGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@=service("request_stack").getCurrentRequest().attributes.getInt("attributeGroupId")' - - '@prestashop.core.attribute_group.attribute_group_view_data_provider' - public: true - - prestashop.core.grid.definition.factory.attribute_group: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AttributeGroupGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.merchandise_return: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\MerchandiseReturnGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.tax_rules_group: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\TaxRulesGroupGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.address: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\AddressGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - public: true - - prestashop.core.grid.definition.factory.credit_slip: - class: 'PrestaShop\PrestaShop\Core\Grid\Definition\Factory\CreditSlipGridDefinitionFactory' - parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' - arguments: - - '@=service("prestashop.adapter.legacy.context").getLanguage().date_format_lite' - public: true diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_factory.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/grid_factory.yml deleted file mode 100644 index d6cd401b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_factory.yml +++ /dev/null @@ -1,297 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.log_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.logs' - - '@prestashop.core.grid.data_factory.log' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.email_logs: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.email_logs' - - '@prestashop.core.grid.data_factory.email_logs' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.request_sql: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.request_sql' - - '@prestashop.core.grid.data_factory.request_sql' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.backup: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.backup' - - '@prestashop.core.backup.listing.grid_data_factory' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.webservice_key: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.webservice_key' - - '@prestashop.core.grid.data_factory.webservice_key' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.meta: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.meta' - - '@prestashop.core.grid.data_provider.meta' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.category: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.category' - - '@prestashop.core.grid.data.factory.category_decorator' - - '@prestashop.core.grid.filter.category_form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.category_decorator: - class: 'PrestaShop\PrestaShop\Core\Grid\Factory\CategoryGridFactoryDecorator' - arguments: - - '@prestashop.core.grid.factory.category' - - '@prestashop.core.grid.filter.category_form_factory' - - prestashop.core.grid.factory.employee: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.employee' - - '@prestashop.core.grid.data_provider.employee' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.contacts: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.contacts' - - '@prestashop.core.grid.data_provider.contacts' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.customer: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.customer' - - '@prestashop.core.grid.data_provider.customer_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.language: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.language' - - '@prestashop.core.grid.factory.language_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.supplier: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.supplier' - - '@prestashop.core.grid.factory.supplier_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.currency: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.currency' - - '@prestashop.core.currency.grid_data_factory' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.profiles: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.profile' - - '@prestashop.core.grid.data_factory.profiles' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.cms_page_category: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.cms_page_category' - - '@prestashop.core.grid.data_provider.cms_page_category' - - '@prestashop.core.grid.filter.cms_page_form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.tax: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.tax' - - '@prestashop.core.grid.data_factory.tax' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.manufacturer: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.manufacturer' - - '@prestashop.core.grid.data.factory.manufacturer_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.manufacturer_address: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.manufacturer_address' - - '@prestashop.core.grid.data.factory.manufacturer_address_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.cms_page: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.cms_page' - - '@prestashop.core.grid.data_provider.cms_page' - - '@prestashop.core.grid.filter.cms_page_form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.empty_category: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.empty_category' - - '@prestashop.core.grid.data.factory.empty_category_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.no_qty_product_with_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.no_qty_product_with_combination' - - '@prestashop.core.grid.data.factory.no_qty_product_with_combination' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.no_qty_product_without_combination: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.no_qty_product_without_combination' - - '@prestashop.core.grid.data.factory.no_qty_product_without_combination' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.disabled_product: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.disabled_product' - - '@prestashop.core.grid.data.factory.disabled_product' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.product_without_image: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.product_without_image' - - '@prestashop.core.grid.data.factory.product_without_image' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.product_without_description: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.product_without_description' - - '@prestashop.core.grid.data.factory.product_without_description' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.product_without_price: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.monitoring.product_without_price' - - '@prestashop.core.grid.data.factory.product_without_price' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.order: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.order' - - '@prestashop.core.grid.data.factory.order_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.catalog_price_rule: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.catalog_price_rule' - - '@prestashop.core.grid.data.factory.catalog_price_rule_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.order_message: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.order_message' - - '@prestashop.core.grid.data.factory.order_message' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.attachment: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.attachment' - - '@prestashop.core.grid.data_factory.attachment_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.attribute: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.attribute' - - '@prestashop.core.grid.data.factory.attribute' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.attribute_group: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.attribute_group' - - '@prestashop.core.grid.data.factory.attribute_group_decorator' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.merchandise_return: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.merchandise_return' - - '@prestashop.core.grid.data_provider.merchandise_return' - - '@prestashop.core.grid.filter.merchandise_return_form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.tax_rules_group: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.tax_rules_group' - - '@prestashop.core.grid.data.factory.tax_rules_group' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.grid_factory.address: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.address' - - '@prestashop.core.grid.data.factory.address' - - '@prestashop.core.grid.filter.form_factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.factory.credit_slip: - class: 'PrestaShop\PrestaShop\Core\Grid\GridFactory' - arguments: - - '@prestashop.core.grid.definition.factory.credit_slip' - - '@prestashop.core.grid.data.factory.credit_slip_decorator' - - '@prestashop.core.grid.filter.credit_slip_form_factory' - - '@prestashop.core.hook.dispatcher' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_filter_form_factory.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/grid_filter_form_factory.yml deleted file mode 100644 index 4acd122a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_filter_form_factory.yml +++ /dev/null @@ -1,38 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.filter.form_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Filter\GridFilterFormFactory' - arguments: - - '@form.factory' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.grid.filter.category_form_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Filter\CategoryFilterFormFactory' - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' - - '@request_stack' - - prestashop.core.grid.filter.cms_page_form_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Filter\CmsPageFilterFormFactory' - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' - - '@request_stack' - - prestashop.core.grid.filter.merchandise_return_form_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Filter\FilterFormFactoryFormActionDecorator' - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' - - 'admin_merchandise_returns_filter' - - - prestashop.core.grid.filter.credit_slip_form_factory: - class: 'PrestaShop\PrestaShop\Core\Grid\Filter\FilterFormFactoryFormActionDecorator' - arguments: - - '@prestashop.core.grid.filter.form_factory' - - '@router' - - 'admin_credit_slips_search' diff --git a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_position_definition_factory.yml b/src/PrestaShopBundle/Resources/config/services/core/grid/grid_position_definition_factory.yml deleted file mode 100644 index 0bca4905..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/grid/grid_position_definition_factory.yml +++ /dev/null @@ -1,34 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.grid.cms_page_category.position_definition: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition' - arguments: - $table: 'cms_category' - $idField: 'id_cms_category' - $positionField: 'position' - $parentIdField: 'id_parent' - - prestashop.core.grid.cms_page.position_definition: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition' - arguments: - $table: 'cms' - $idField: 'id_cms' - $positionField: 'position' - $parentIdField: 'id_cms_category' - - prestashop.core.grid.attribute.position_definition: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition' - arguments: - $table: 'attribute' - $idField: 'id_attribute' - $positionField: 'position' - $parentIdField: 'id_attribute_group' - - prestashop.core.grid.attribute_group.position_definition: - class: 'PrestaShop\PrestaShop\Core\Grid\Position\PositionDefinition' - arguments: - $table: 'attribute_group' - $idField: 'id_attribute_group' - $positionField: 'position' diff --git a/src/PrestaShopBundle/Resources/config/services/core/hook.yml b/src/PrestaShopBundle/Resources/config/services/core/hook.yml deleted file mode 100644 index 91b085da..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/hook.yml +++ /dev/null @@ -1,88 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.hook.dispatcher: - class: 'PrestaShop\PrestaShop\Core\Hook\HookDispatcher' - arguments: - - '@prestashop.hook.dispatcher' - - prestashop.core.hook.provider.grid_definition_hook_by_service_ids_provider: - class: PrestaShop\PrestaShop\Core\Hook\Provider\GridDefinitionHookByServiceIdsProvider - arguments: - - '@service_container' - - prestashop.core.hook.provider.identifiable_object_hook_by_form_type_provider: - class: PrestaShop\PrestaShop\Core\Hook\Provider\IdentifiableObjectHookByFormTypeProvider - arguments: - - '@form.factory' - - prestashop.core.hook.generator.hook_description_generator: - class: 'PrestaShop\PrestaShop\Core\Hook\Generator\HookDescriptionGenerator' - arguments: - - '%hook_descriptions%' - - '@prestashop.core.util.string.string_validator' - - '@prestashop.core.util.string.string_modifier' - -parameters: - hook_descriptions: - 'grid_definition_modifier': - 'prefix': 'action' - 'suffix': 'GridDefinitionModifier' - 'title': 'Modify %s grid definition' - 'description': 'This hook allows to alter %s grid columns, actions and filters' - 'grid_query_builder_modifier': - 'prefix': 'action' - 'suffix': 'GridQueryBuilderModifier' - 'title': 'Modify %s grid query builder' - 'description': 'This hook allows to alter Doctrine query builder for %s grid' - 'grid_data_modifier': - 'prefix': 'action' - 'suffix': 'GridDataModifier' - 'title': 'Modify %s grid data' - 'description': 'This hook allows to modify %s grid data' - 'grid_filter_form_modifier': - 'prefix': 'action' - 'suffix': 'GridFilterFormModifier' - 'title': 'Modify %s grid filters' - 'description': 'This hook allows to modify filters for %s grid' - 'grid_presenter_modifier': - 'prefix': 'action' - 'suffix': 'GridPresenterModifier' - 'title': 'Modify %s grid template data' - 'description': 'This hook allows to modify data which is about to be used in template for %s grid' - 'option_form': - 'prefix': 'action' - 'suffix': 'Form' - 'title': 'Modify %s options form content' - 'description': 'This hook allows to modify %s options form FormBuilder' - 'option_save': - 'prefix': 'action' - 'suffix': 'Save' - 'title': 'Modify %s options form saved data' - 'description': 'This hook allows to modify data of %s options form after it was saved' - 'form_builder_modifier': - 'prefix': 'action' - 'suffix': 'FormBuilderModifier' - 'title': 'Modify %s identifiable object form' - 'description': 'This hook allows to modify %s identifiable object forms content by modifying form builder data or FormBuilder itself' - 'action_before_update_form_handler': - 'prefix': 'actionBeforeUpdate' - 'suffix': 'FormHandler' - 'title': 'Modify %s identifiable object data before updating it' - 'description': 'This hook allows to modify %s identifiable object forms data before it was updated' - 'action_after_update_form_handler': - 'prefix': 'actionAfterUpdate' - 'suffix': 'FormHandler' - 'title': 'Modify %s identifiable object data after updating it' - 'description': 'This hook allows to modify %s identifiable object forms data after it was updated' - 'action_before_create_form_handler': - 'prefix': 'actionBeforeCreate' - 'suffix': 'FormHandler' - 'title': 'Modify %s identifiable object data before creating it' - 'description': 'This hook allows to modify %s identifiable object forms data before it was created' - 'action_after_create_form_handler': - 'prefix': 'actionAfterCreate' - 'suffix': 'FormHandler' - 'title': 'Modify %s identifiable object data after creating it' - 'description': 'This hook allows to modify %s identifiable object forms data after it was created' diff --git a/src/PrestaShopBundle/Resources/config/services/core/image.yml b/src/PrestaShopBundle/Resources/config/services/core/image.yml deleted file mode 100644 index 476a4c37..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/image.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.image.parser.image_tag_source_parser: - class: 'PrestaShop\PrestaShop\Core\Image\Parser\ImageTagSourceParser' - arguments: - - '@=service("prestashop.adapter.legacy.context").getRootUrl()' - - prestashop.core.image.file_deleter: - class: 'PrestaShop\PrestaShop\Core\Image\Deleter\ImageFileDeleter' diff --git a/src/PrestaShopBundle/Resources/config/services/core/import.yml b/src/PrestaShopBundle/Resources/config/services/core/import.yml deleted file mode 100644 index 1ec3fcf7..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/import.yml +++ /dev/null @@ -1,128 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.import.file_uploader: - class: 'PrestaShop\PrestaShop\Core\Import\File\FileUploader' - arguments: - - '@translator' - - '@prestashop.core.import.dir' - - prestashop.core.import.file_finder: - class: 'PrestaShop\PrestaShop\Core\Import\File\FileFinder' - arguments: - - '@prestashop.core.import.dir' - - prestashop.core.import.dir: - class: 'PrestaShop\PrestaShop\Core\Import\ImportDirectory' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.import.file_removal: - class: 'PrestaShop\PrestaShop\Core\Import\File\FileRemoval' - arguments: - - '@prestashop.core.import.dir' - - prestashop.core.import.sample.file_provider: - class: 'PrestaShop\PrestaShop\Core\Import\Sample\SampleFileProvider' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.import.csv_file_reader: - class: 'PrestaShop\PrestaShop\Core\Import\File\CsvFileReader' - arguments: - - '@prestashop.adapter.import.file_opener' - - '@=service("prestashop.core.import.normalizer.csv_value_separator").normalize(service("session").get("separator"))' - - prestashop.core.import.data_row.presenter: - class: 'PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowPresenter' - - prestashop.core.import.data_row.collection_presenter: - class: 'PrestaShop\PrestaShop\Core\Import\File\DataRow\DataRowCollectionPresenter' - arguments: - - '@prestashop.core.import.data_row.presenter' - - prestashop.core.import.factory.data_row.collection_factory: - class: 'PrestaShop\PrestaShop\Core\Import\File\DataRow\Factory\DataRowCollectionFactory' - arguments: - - '@prestashop.core.import.csv_file_reader' - - prestashop.core.import.fields_provider.product: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\ProductFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.category: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\CategoryFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.combination: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\CombinationFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.customer: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\CustomerFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.address: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\AddressFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.supplier: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\SupplierFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.alias: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\AliasFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.fields_provider.store_contact: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\StoreContactFieldsProvider' - arguments: - - '@translator' - - prestashop.core.import.normalizer.csv_value_separator: - class: 'PrestaShop\PrestaShop\Core\Import\CsvValueSeparatorNormalizer' - - prestashop.core.import.fields_provider_finder: - class: 'PrestaShop\PrestaShop\Core\Import\EntityField\Provider\EntityFieldsProviderFinder' - arguments: - - - 0: '@prestashop.core.import.fields_provider.category' - 1: '@prestashop.core.import.fields_provider.product' - 2: '@prestashop.core.import.fields_provider.combination' - 3: '@prestashop.core.import.fields_provider.customer' - 4: '@prestashop.core.import.fields_provider.address' - 5: '@prestashop.core.import.fields_provider.supplier' - 6: '@prestashop.core.import.fields_provider.supplier' - 7: '@prestashop.core.import.fields_provider.alias' - 8: '@prestashop.core.import.fields_provider.store_contact' - - prestashop.core.import.config_factory: - class: 'PrestaShop\PrestaShop\Core\Import\Configuration\ImportConfigFactory' - - prestashop.core.import.runtime_config_factory: - class: 'PrestaShop\PrestaShop\Core\Import\Configuration\ImportRuntimeConfigFactory' - - prestashop.core.import.request_validator: - class: 'PrestaShop\PrestaShop\Core\Import\Validator\ImportRequestValidator' - - prestashop.core.import.access_checker: - class: 'PrestaShop\PrestaShop\Core\Import\Access\ImportAccessChecker' - arguments: - - '@prestashop.adapter.data_provider.employee' - - prestashop.core.import.importer: - class: 'PrestaShop\PrestaShop\Core\Import\Importer' - arguments: - - '@prestashop.core.import.access_checker' - - '@prestashop.adapter.import.entity_deleter' - - '@prestashop.core.import.csv_file_reader' - - '@prestashop.core.import.dir' - - '@prestashop.core.configuration.ini_configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/core/kpi.yml b/src/PrestaShopBundle/Resources/config/services/core/kpi.yml deleted file mode 100644 index dbe7aac3..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/kpi.yml +++ /dev/null @@ -1,59 +0,0 @@ -services: - _defaults: - public: true - - # KPI Row presenter - prestashop.core.kpi_row.presenter: - class: PrestaShop\PrestaShop\Core\Kpi\Row\KpiRowPresenter - - # KPI Row factories - prestashop.core.kpi_row.factory.translations_page: - class: PrestaShop\PrestaShop\Core\Kpi\Row\HookableKpiRowFactory - arguments: - - - - '@prestashop.adapter.kpi.enabled_languages' - - '@prestashop.adapter.kpi.main_country' - - '@prestashop.adapter.kpi.translations' - - '@prestashop.core.hook.dispatcher' - - 'translations' - - prestashop.core.kpi_row.factory.categories: - class: PrestaShop\PrestaShop\Core\Kpi\Row\HookableKpiRowFactory - arguments: - - - - '@prestashop.adapter.kpi.disabled_categories' - - '@prestashop.adapter.kpi.empty_categories' - - '@prestashop.adapter.kpi.top_category' - - '@prestashop.adapter.kpi.average_products_in_category' - - '@prestashop.core.hook.dispatcher' - - 'categories' - - prestashop.core.kpi_row.factory.customers: - class: PrestaShop\PrestaShop\Core\Kpi\Row\HookableKpiRowFactory - arguments: - - - - '@prestashop.adapter.kpi.most_common_customers_gender' - - '@prestashop.adapter.kpi.average_customer_age' - - '@prestashop.adapter.kpi.order_per_customer' - - '@prestashop.adapter.kpi.newsletter_registrations' - - '@prestashop.core.hook.dispatcher' - - 'customers' - - prestashop.core.kpi_row.factory.cart: - class: PrestaShop\PrestaShop\Core\Kpi\Row\HookableKpiRowFactory - arguments: - - - - '@prestashop.adapter.kpi.shopping_cart_total_kpi' - - '@prestashop.core.hook.dispatcher' - - 'cart' - - prestashop.core.kpi_row.factory.orders: - class: PrestaShop\PrestaShop\Core\Kpi\Row\HookableKpiRowFactory - arguments: - - - - '@prestashop.adapter.kpi.conversion_rate' - - '@prestashop.adapter.kpi.abandoned_cart' - - '@prestashop.adapter.kpi.average_order_value' - - '@prestashop.adapter.kpi.net_profit_per_visit' - - '@prestashop.core.hook.dispatcher' - - 'orders' diff --git a/src/PrestaShopBundle/Resources/config/services/core/language.yml b/src/PrestaShopBundle/Resources/config/services/core/language.yml deleted file mode 100644 index 7778ec27..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/language.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.language.pack.loader.remote: - class: 'PrestaShop\PrestaShop\Core\Language\Pack\Loader\RemoteLanguagePackLoader' - arguments: - - '@prestashop.core.foundation.version' - - prestashop.core.language.language_default_fonts_catalog: - class: 'PrestaShop\PrestaShop\Core\Language\LanguageDefaultFontsCatalog' - arguments: - - - 'fa': 'Tahoma' - 'ar': 'Tahoma' diff --git a/src/PrestaShopBundle/Resources/config/services/core/localization.yml b/src/PrestaShopBundle/Resources/config/services/core/localization.yml deleted file mode 100644 index 9e99714c..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/localization.yml +++ /dev/null @@ -1,31 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.localozation.pack.factory.localization_pack: - class: 'PrestaShop\PrestaShop\Core\Localization\Pack\Factory\LocalizationPackFactory' - - prestashop.core.localization.pack.import.importer: - class: 'PrestaShop\PrestaShop\Core\Localization\Pack\Import\LocalizationPackImporter' - arguments: - - '@prestashop.core.localization.pack.loader.remote' - - '@prestashop.core.localization.pack.loader.local' - - '@prestashop.core.localozation.pack.factory.localization_pack' - - '@translator' - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.localization.pack.loader.local: - class: 'PrestaShop\PrestaShop\Core\Localization\Pack\Loader\LocalLocalizationPackLoader' - arguments: - - '@prestashop.adapter.legacy.configuration' - - prestashop.core.localization.pack.loader.remote: - class: 'PrestaShop\PrestaShop\Core\Localization\Pack\Loader\RemoteLocalizationPackLoader' - arguments: - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.core.foundation.version' - - prestashop.core.localization.rtl.processor_factory: - class: 'PrestaShop\PrestaShop\Core\Localization\RTL\StyleSheetProcessorFactory' - arguments: - - '@prestashop.adapter.legacy.configuration' diff --git a/src/PrestaShopBundle/Resources/config/services/core/mail_template.yml b/src/PrestaShopBundle/Resources/config/services/core/mail_template.yml deleted file mode 100644 index 8beffd2b..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/mail_template.yml +++ /dev/null @@ -1,50 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.mail_template.mail_template_renderer: '@prestashop.adapter.mail_template.twig_renderer' - prestashop.core.mail_template.theme_catalog: '@prestashop.core.mail_template.theme_folder_catalog' - - prestashop.core.mail_template.theme_folder_scanner: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\FolderThemeScanner' - - prestashop.core.mail_template.theme_folder_catalog: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\FolderThemeCatalog' - arguments: - - '%mail_themes_dir%' - - '@prestashop.core.mail_template.theme_folder_scanner' - - '@prestashop.core.hook.dispatcher' - - prestashop.core.mail_template.variables_builder: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\Layout\LayoutVariablesBuilder' - arguments: - - '@prestashop.core.hook.dispatcher' - - '@prestashop.core.language.language_default_fonts_catalog' - - - mailThemesUrl: "@=service('prestashop.adapter.legacy.context').getMailThemesUrl()" - - prestashop.core.mail_template.generator: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\MailTemplateGenerator' - arguments: - - '@prestashop.core.mail_template.mail_template_renderer' - - '@logger' - - prestashop.core.mail_template.transformation.css_inline: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\Transformation\CSSInlineTransformation' - - prestashop.core.mail_template.transformation.html_textify: - class: 'PrestaShop\PrestaShop\Core\MailTemplate\Transformation\HTMLToTextTransformation' - - prestashop.core.mail_template.command_handler.generate_theme_mails_handler: - class: 'PrestaShop\PrestaShop\Core\Domain\MailTemplate\CommandHandler\GenerateThemeMailTemplatesCommandHandler' - arguments: - - '@prestashop.core.admin.lang.repository' - - '@prestashop.core.mail_template.theme_catalog' - - '@prestashop.core.mail_template.generator' - - '@translator' - - '%kernel.project_dir%/mails' - - "@=service('prestashop.adapter.legacy.configuration').get('_PS_MODULE_DIR_')" - public: true - tags: - - name: tactician.handler - command: PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand diff --git a/src/PrestaShopBundle/Resources/config/services/core/module.yml b/src/PrestaShopBundle/Resources/config/services/core/module.yml deleted file mode 100644 index 5fa293b6..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/module.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.module.configuration.payment_restrictions_configurator: - class: PrestaShop\PrestaShop\Core\Module\Configuration\PaymentRestrictionsConfigurator - arguments: - - '@doctrine.dbal.default_connection' - - '%database_prefix%' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - '@prestashop.adapter.module.payment_module_provider' diff --git a/src/PrestaShopBundle/Resources/config/services/core/search.yml b/src/PrestaShopBundle/Resources/config/services/core/search.yml deleted file mode 100644 index 372ea826..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/search.yml +++ /dev/null @@ -1,62 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.admin.search_parameters: - class: PrestaShop\PrestaShop\Core\Search\SearchParameters - arguments: ['@prestashop.core.admin.admin_filter.repository'] - - # Controller Argument Resolver - prestashop.search_parameters.resolver: - class: 'PrestaShopBundle\Controller\ArgumentResolver\SearchParametersResolver' - arguments: - - '@prestashop.core.admin.search_parameters' - - '@security.token_storage' - - '@prestashop.core.admin.admin_filter.repository' - - '@event_dispatcher' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' -# tags: -# - { name: controller.argument_value_resolver, priority: 50 } - - # Filters builder argument resolver - prestashop.filters_builder.resolver: - class: 'PrestaShopBundle\Controller\ArgumentResolver\FiltersBuilderResolver' - arguments: - - '@prestashop.core.search.builder' - tags: - - { name: controller.argument_value_resolver, priority: 51 } - - prestashop.core.search.builder.class: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\ClassFiltersBuilder' - - prestashop.core.search.builder.request: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\RequestFiltersBuilder' - - prestashop.core.search.builder.repository: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\RepositoryFiltersBuilder' - arguments: - - '@prestashop.core.admin.admin_filter.repository' - - '@prestashop.adapter.data_provider.employee' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.core.search.builder.event: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\EventFiltersBuilder' - arguments: - - '@event_dispatcher' - - prestashop.core.search.builder.persist: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\PersistFiltersBuilder' - arguments: - - '@prestashop.core.admin.admin_filter.repository' - - '@prestashop.adapter.data_provider.employee' - - '@=service("prestashop.adapter.legacy.context").getContext().shop.id' - - prestashop.core.search.builder: - class: 'PrestaShop\PrestaShop\Core\Search\Builder\ChainedFiltersBuilder' - arguments: - - - - '@prestashop.core.search.builder.class' - - '@prestashop.core.search.builder.repository' - - '@prestashop.core.search.builder.request' - - '@prestashop.core.search.builder.event' - - '@prestashop.core.search.builder.persist' diff --git a/src/PrestaShopBundle/Resources/config/services/core/security.yml b/src/PrestaShopBundle/Resources/config/services/core/security.yml deleted file mode 100644 index 0c570bee..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/security.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.crypto.hashing: - class: 'PrestaShop\PrestaShop\Core\Crypto\Hashing' - - prestashop.core.security.folder_guard.vendor: - class: 'PrestaShop\PrestaShop\Core\Security\HtaccessFolderGuard' - arguments: - - '%kernel.root_dir%/Resources/security/.htaccess.dist' diff --git a/src/PrestaShopBundle/Resources/config/services/core/shop.yml b/src/PrestaShopBundle/Resources/config/services/core/shop.yml deleted file mode 100644 index bfe292de..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/shop.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.shop.logo_uploader: - class: 'PrestaShop\PrestaShop\Core\Shop\LogoUploader' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().shop' diff --git a/src/PrestaShopBundle/Resources/config/services/core/sql_request.yml b/src/PrestaShopBundle/Resources/config/services/core/sql_request.yml deleted file mode 100644 index 53975a34..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/sql_request.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.sql_manager.exporter.sql_request_exporter: - class: 'PrestaShop\PrestaShop\Core\SqlManager\Exporter\SqlRequestExporter' - arguments: - - '@prestashop.core.export.file_writer.export_csv_file_writer' - - prestashop.core.sql_manager.configuration.sql_request_configuration: - class: 'PrestaShop\PrestaShop\Core\SqlManager\Configuration\SqlRequestConfiguration' - arguments: - - '@prestashop.core.command_bus' - - '@prestashop.core.query_bus' diff --git a/src/PrestaShopBundle/Resources/config/services/core/string.yml b/src/PrestaShopBundle/Resources/config/services/core/string.yml deleted file mode 100644 index 4abcc674..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/string.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.string.character_cleaner: - class: 'PrestaShop\PrestaShop\Core\String\CharacterCleaner' diff --git a/src/PrestaShopBundle/Resources/config/services/core/translation.yml b/src/PrestaShopBundle/Resources/config/services/core/translation.yml deleted file mode 100644 index ed149af9..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/translation.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.translation.locale.converter: - class: 'PrestaShop\PrestaShop\Core\Translation\Locale\Converter' - arguments: - - '%translations_dir%/../legacy-to-standard-locales.json' diff --git a/src/PrestaShopBundle/Resources/config/services/core/util.yml b/src/PrestaShopBundle/Resources/config/services/core/util.yml deleted file mode 100644 index 65bd4bac..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/util.yml +++ /dev/null @@ -1,23 +0,0 @@ -imports: - - { resource: 'util/*' } - -services: - _defaults: - public: true - - prestashop.core.util.url.url_file_checker: - class: 'PrestaShop\PrestaShop\Core\Util\Url\UrlFileChecker' - arguments: - - '@=service("prestashop.adapter.legacy.configuration").get("_PS_ROOT_DIR_")' - - prestashop.core.uti.back_url_provider: - class: PrestaShop\PrestaShop\Core\Util\Url\BackUrlProvider - - prestashop.core.util.color_brightness_calculator: - class: PrestaShop\PrestaShop\Core\Util\ColorBrightnessCalculator - - prestashop.core.util.arabic_to_latin_digit_converter: - class: PrestaShop\PrestaShop\Core\Util\ArabicToLatinDigitConverter - - prestashop.core.util.internationalized_domain_name_converter: - class: 'PrestaShop\PrestaShop\Core\Util\InternationalizedDomainNameConverter' diff --git a/src/PrestaShopBundle/Resources/config/services/core/util/file_size.yml b/src/PrestaShopBundle/Resources/config/services/core/util/file_size.yml deleted file mode 100644 index 7c9dcfb2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/util/file_size.yml +++ /dev/null @@ -1,6 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.util.file_size.size_converter: - class: 'PrestaShop\PrestaShop\Core\Util\File\FileSizeConverter' diff --git a/src/PrestaShopBundle/Resources/config/services/core/util/helper_card.yml b/src/PrestaShopBundle/Resources/config/services/core/util/helper_card.yml deleted file mode 100644 index f3b94eb2..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/util/helper_card.yml +++ /dev/null @@ -1,73 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.util.helper_card.documentation_link_provider: - class: 'PrestaShop\PrestaShop\Core\Util\HelperCard\DocumentationLinkProvider' - arguments: - - '@=service("prestashop.adapter.legacy.context").getContext().language ? service("prestashop.adapter.legacy.context").getContext().language.iso_code : "en-US"' - - - 'team': - 'en': 'https://doc.prestashop.com/display/PS17/Team' - 'fr': 'http://doc.prestashop.com/pages/viewpage.action?pageId=51840334' - 'es': 'https://doc.prestashop.com/display/PS17/Equipo' - 'it': 'http://doc.prestashop.com/pages/viewpage.action?pageId=54266520' - '_fallback': 'https://doc.prestashop.com/display/PS17/Team' - 'meta': - 'fr': 'https://doc.prestashop.com/display/PS17/SEO+et+URL' - 'es': 'https://doc.prestashop.com/display/PS17/SEO+y+URLs' - 'it': 'https://doc.prestashop.com/display/PS17/SEO+e+URL' - '_fallback': 'https://doc.prestashop.com/display/PS17/SEO+and+URLs' - 'customer': - 'fr': 'https://doc.prestashop.com/display/PS17/Vos+clients' - 'es': 'https://doc.prestashop.com/display/PS17/Tus+clientes' - 'it': 'https://doc.prestashop.com/display/PS17/I+Tuoi+Clienti' - '_fallback': 'https://doc.prestashop.com/display/PS17/Your+customers' - 'supplier': - 'en': 'https://doc.prestashop.com/display/PS17/Managing+Suppliers' - 'fr': 'https://doc.prestashop.com/display/PS17/Gerer+les+fournisseurs' - 'es': 'https://doc.prestashop.com/display/PS17/Gestionar+Proveedores' - 'it': 'https://doc.prestashop.com/display/PS17/Gestire+Fornitori' - '_fallback': 'https://doc.prestashop.com/display/PS17/Managing+Suppliers' - 'category': - 'en': 'https://doc.prestashop.com/display/PS17/Managing+Categories' - 'fr': 'https://doc.prestashop.com/display/PS17/Gerer+les+categories' - 'es': 'https://doc.prestashop.com/display/PS17/Gestionar+las+categorias' - 'it': 'https://doc.prestashop.com/display/PS17/Gestire+Categorie' - '_fallback': 'https://doc.prestashop.com/display/PS17/Managing+Categories' - 'cms_pages': - 'en': 'https://doc.prestashop.com/display/PS17/Pages+-+Managing+Static+Content' - 'fr': 'https://doc.prestashop.com/display/PS17/Gerer+votre+contenu+statique+grace+aux+pages' - 'es': 'https://doc.prestashop.com/display/PS17/Paginas+-+Gestionar+el+Contenido+Estatico' - 'it': 'https://doc.prestashop.com/display/PS17/Pagine+-+Gestione+Contenuti+Statici' - '_fallback': 'https://doc.prestashop.com/display/PS17/Pages+-+Managing+Static+Content' - 'debug_mode': - 'en': 'https://doc.prestashop.com/display/PS17/Performance#Performance-Debugmode' - 'fr': 'http://doc.prestashop.com/pages/viewpage.action?pageId=51840325#Param%%C3%%A8tresdeperformances-Modedebug' - 'it': 'http://doc.prestashop.com/pages/viewpage.action?pageId=54266514' - 'es': 'https://doc.prestashop.com/display/PS17/Rendimiento#Rendimiento-ModoDepuraci%%C3%%B3n' - '_fallback': 'https://doc.prestashop.com/display/PS17/Performance#Performance-Debugmode' - 'attribute': - 'en': 'https://doc.prestashop.com/display/PS17/Managing+Product+Attributes' - 'fr': 'https://doc.prestashop.com/display/PS17/Gerer+les+attributs+de+vos+produits' - 'es': 'https://doc.prestashop.com/display/PS17/Gestionar+Atributos+del+Producto' - 'it': 'https://doc.prestashop.com/display/PS17/Gestire+gli+Attributi+dei+Prodotti' - '_fallback': 'https://doc.prestashop.com/display/PS17/Managing+Product+Attributes' - 'monitoring': - 'en': 'https://doc.prestashop.com/display/PS17/Monitoring+your+Catalog' - 'fr': 'https://doc.prestashop.com/display/PS17/Faire+le+suivi+de+votre+catalogue' - 'es': 'https://doc.prestashop.com/display/PS17/Monitorear+el+catalogo' - 'it': 'https://doc.prestashop.com/display/PS17/Monitorare+il+Catalogo' - '_fallback': 'https://doc.prestashop.com/display/PS17/Monitoring+your+Catalog' - 'attachment': - 'en': 'https://doc.prestashop.com/display/PS17/Managing+Files' - 'fr': 'https://doc.prestashop.com/display/PS17/Gerer+les+fichiers' - 'es': 'https://doc.prestashop.com/display/PS17/Gestionar+Archivos' - 'it': 'https://doc.prestashop.com/display/PS17/Gestire+i+Files' - '_fallback': 'https://doc.prestashop.com/display/PS17/Managing+Files' - 'credit_slip': - 'en': 'https://doc.prestashop.com/display/PS17/Credit+Slips' - 'fr': 'https://doc.prestashop.com/display/PS17/Avoirs' - 'es': 'https://doc.prestashop.com/display/PS17/Facturas+por+abono' - 'it': 'https://doc.prestashop.com/display/PS17/Note+di+credito' - '_fallback': 'https://doc.prestashop.com/display/PS17/Credit+Slips' diff --git a/src/PrestaShopBundle/Resources/config/services/core/util/string.yml b/src/PrestaShopBundle/Resources/config/services/core/util/string.yml deleted file mode 100644 index 3f0dbb00..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/util/string.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.util.string.string_validator: - class: 'PrestaShop\PrestaShop\Core\Util\String\StringValidator' - - prestashop.core.util.string.string_modifier: - class: 'PrestaShop\PrestaShop\Core\Util\String\StringModifier' diff --git a/src/PrestaShopBundle/Resources/config/services/core/validation.yml b/src/PrestaShopBundle/Resources/config/services/core/validation.yml deleted file mode 100644 index 5928dd1a..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/validation.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.validation.validator: - class: 'PrestaShop\PrestaShop\Core\Validation\Validator' - arguments: - - '@prestashop.adapter.validate' diff --git a/src/PrestaShopBundle/Resources/config/services/core/webservice.yml b/src/PrestaShopBundle/Resources/config/services/core/webservice.yml deleted file mode 100644 index b9b92976..00000000 --- a/src/PrestaShopBundle/Resources/config/services/core/webservice.yml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: true - - prestashop.core.webservice.server_requirements_checker: - class: 'PrestaShop\PrestaShop\Core\Webservice\ServerRequirementsChecker' - arguments: - - '@translator' - - '@prestashop.adapter.legacy.configuration' - - '@prestashop.adapter.hosting_information' - - '@prestashop.core.configuration.php_extension_checker' diff --git a/src/PrestaShopBundle/Resources/views/Admin/Category/categories.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Category/categories.html.twig deleted file mode 100644 index e3e3786d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Category/categories.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - -
    - -
    - {{ categories|json_encode }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/button.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/button.html.twig deleted file mode 100644 index 27b40b51..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/button.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_categories.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_categories.html.twig deleted file mode 100644 index 24856621..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_categories.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_customers.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_customers.html.twig deleted file mode 100644 index 6f745080..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/delete_customers.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/modal_form_submit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/modal_form_submit.html.twig deleted file mode 100644 index a4a9a9f6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/modal_form_submit.html.twig +++ /dev/null @@ -1,33 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/submit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/submit.html.twig deleted file mode 100644 index cd8e22ec..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Bulk/submit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/link.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/link.html.twig deleted file mode 100644 index 32d26367..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/link.html.twig +++ /dev/null @@ -1,33 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - - - {% if action.icon is not empty %} - {{ action.icon }} - {% endif %} - {{ action.name }} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/simple.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/simple.html.twig deleted file mode 100644 index 81a903c6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/simple.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/submit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/submit.html.twig deleted file mode 100644 index 55ddbbf5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Grid/submit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_category.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_category.html.twig deleted file mode 100644 index deb8a772..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_category.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set class = 'btn tooltip-link js-delete-category-row-action' %} - -{% if attributes.class is defined %} - {% set class = class ~ ' ' ~ attributes.class %} -{% endif %} - - - {% if action.icon is not empty %} - {{ action.icon }} - {% endif %} - {% if not attributes.tooltip_name %} - {{ action.name }} - {% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_customer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_customer.html.twig deleted file mode 100644 index 3ef8045f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/delete_customer.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set class = 'btn tooltip-link js-delete-customer-row-action' %} - -{% if attributes.class is defined %} - {% set class = class ~ ' ' ~ attributes.class %} -{% endif %} - - - {% if action.icon is not empty %} - {{ action.icon }} - {% endif %} - {% if not attributes.tooltip_name %} - {{ action.name }} - {% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/link.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/link.html.twig deleted file mode 100644 index a4b1a8b7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/link.html.twig +++ /dev/null @@ -1,55 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set class = 'btn tooltip-link js-link-row-action' %} - -{% if attributes.class is defined %} - {% set class = class ~ ' ' ~ attributes.class %} -{% endif %} - - {% set route_params = { (action.options.route_param_name) : (record[action.options.route_param_field]) } %} - {% set extra_route_params = action.options.extra_route_params %} - - {% for name, field in extra_route_params %} - {% set route_params = route_params|merge({ (name) : (record[field] ?? field) }) %} - {% endfor %} - - - {% if action.icon is not empty %} - {{ action.icon }} - {% endif %} - {% if not attributes.tooltip_name %} - {{ action.name }} - {% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/submit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/submit.html.twig deleted file mode 100644 index e55f3608..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Actions/Row/submit.html.twig +++ /dev/null @@ -1,62 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set class = 'btn tooltip-link js-submit-row-action' %} - -{% if attributes.class is defined %} - {% set class = class ~ ' ' ~ attributes.class %} -{% endif %} - -{% set confirmation_message = action.options.confirm_message %} -{% if action.options.confirm_message_type == 'dynamic' and record[action.options.dynamic_message_field] is defined %} - {% set dynamic_field = record[action.options.dynamic_message_field] %} - {% set confirmation_message = dynamic_field|default(action.options.confirm_message) %} -{% endif %} - -{% set route_params = { (action.options.route_param_name) : (record[action.options.route_param_field]) } %} -{% set extra_route_params = action.options.extra_route_params %} - -{% for name, field in extra_route_params %} - {% set route_params = route_params|merge({ (name) : (record[field]) }) %} -{% endfor %} - - - {% if action.icon is not empty %} - {{ action.icon }} - {% endif %} - {% if not attributes.tooltip_name %} - {{ action.name }} - {% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig deleted file mode 100644 index 8269579b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    warning

    -

    {{ 'No records found'|trans({}, 'Admin.Global') }}

    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/attachment.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/attachment.html.twig deleted file mode 100644 index 50bac490..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/attachment.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - - -

    {{ 'Upload files here'|trans({}, 'Admin.Catalog.Feature') }}

    - -

    - {{ 'Make some files available to your customers and facilitate their purchasing environment by adding them just here! It can be instruction manuals, technical works or anything you want to attach to a product.'|trans({}, 'Admin.Catalog.Feature') }} -

    - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/credit_slip.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/credit_slip.html.twig deleted file mode 100644 index 010e3e04..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/credit_slip.html.twig +++ /dev/null @@ -1,38 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - - -

    {{ 'Manage your credit slips'|trans({}, 'Admin.Catalog.Feature') }}

    - -

    - {{ 'When a customer returns a product, a credit slip must be created in his favor. Generate vouchers and have a look at their follow-up.'|trans({}, 'Admin.Catalog.Feature') }} -

    - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/order.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/order.html.twig deleted file mode 100644 index ba62f194..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/order.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - - -

    {{ 'Manage your orders'|trans({}, 'Admin.Orderscustomers.Feature') }}

    - -

    - {{ 'Find all your orders on this page and access their main information in one click: check the cart total, the payment method, the shipping details, or if it comes from a new client. You can even update the status from the listing!'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/supplier.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/supplier.html.twig deleted file mode 100644 index 72420415..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/EmptyState/supplier.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - - -

    {{ 'Keep in touch with your suppliers'|trans({}, 'Admin.Catalog.Feature') }}

    - -

    - {{ 'Having suppliers is optional if brands supply you directly. Make sure you don\'t confuse product suppliers and product brands to facilitate stock management.'|trans({}, 'Admin.Catalog.Feature') }} -

    - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/empty_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/empty_row.html.twig deleted file mode 100644 index d8be980c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/empty_row.html.twig +++ /dev/null @@ -1,38 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - {% if grid.attributes.is_empty_state %} - {% include [ - '@PrestaShop/Admin/Common/Grid/Blocks/EmptyState/'~grid.id~'.html.twig', - '@PrestaShop/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig' - ] with {'grid': grid} - %} - {% else %} - {% include '@PrestaShop/Admin/Common/Grid/Blocks/EmptyState/_default.html.twig' with {'grid': grid} %} - {% endif %} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/filters_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/filters_row.html.twig deleted file mode 100644 index 45bdec43..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/filters_row.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - {% for column in grid.columns %} - - {% if loop.first and grid.actions.bulk|length > 0 %} - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/bulk_actions_select_all.html.twig', {'grid': grid}) }} - {% endif %} - - {% if grid.filter_form|length > 1 %} - {% if grid.column_filters[column.id] is defined %} - {% for filter_name in grid.column_filters[column.id] %} - {{ form_widget(grid.filter_form[filter_name]) }} - {% endfor %} - {% endif %} - {% endif %} - - {% endfor %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/headers_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/headers_row.html.twig deleted file mode 100644 index a55777f4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/Table/headers_row.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - {% for column in grid.columns %} - - {{ column_header(column, grid) }} - - {% endfor %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions.html.twig deleted file mode 100644 index b7252526..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if grid.actions.bulk|length > 0 and grid.data.records_total > 0 %} -
    - - - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions_select_all.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions_select_all.html.twig deleted file mode 100644 index a8c43e17..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/bulk_actions_select_all.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/grid_actions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/grid_actions.html.twig deleted file mode 100644 index 6505d0d8..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/grid_actions.html.twig +++ /dev/null @@ -1,71 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if grid.actions.grid|length > 0 %} - {% set gridActionsButtonId = grid.id ~ '-grid-actions-button' %} - - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/pagination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/pagination.html.twig deleted file mode 100644 index 09601dbd..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/pagination.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block grid_pagination %} - {% if grid.data.records_total > 10 or grid.pagination.offset %} -
    -
    - {% set route_params = {} %} - - {% for param_name, param_value in app.request.attributes.get('_route_params') %} - {% set route_params = route_params|merge({ (param_name) : (param_value) }) %} - {% endfor %} - - {{ render(controller('PrestaShopBundle:Admin\\Common:pagination', { - 'limit': grid.pagination.limit, - 'offset': grid.pagination.offset, - 'total': grid.data.records_total, - 'prefix': grid.form_prefix, - 'caller_route': app.request.attributes.get('_route'), - 'caller_parameters': route_params - })) }} -
    -
    - {% endif %} -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig deleted file mode 100644 index 18ac8f18..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Blocks/table.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{{ form_start(grid.filter_form, {'attr': {'id': grid.id ~ '_filter_form', 'class': 'table-responsive'}}) }} - - - {% block grid_table_head %} - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/Table/headers_row.html.twig', {'grid': grid}) }} - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/Table/filters_row.html.twig', {'grid': grid}) }} - {% endblock %} - - - {% block grid_table_body %} - {% if grid.data.records is not empty %} - {% for record in grid.data.records %} - - {% for column in grid.columns %} - - {% endfor %} - - {% endfor %} - {% else %} - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/Table/empty_row.html.twig', {'grid': grid}) }} - {% endif %} - {% endblock %} - - {% block grid_table_footer %}{% endblock %} -
    - {{ column_content(record, column, grid) }} -
    -{{ form_end(grid.filter_form) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/action.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/action.html.twig deleted file mode 100644 index 4d4d31b5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/action.html.twig +++ /dev/null @@ -1,107 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set actions = column.options.actions %} - -{% if actions is not empty %} - {% set inlineActions = [] %} - {% set regularActions = [] %} - - {% for action in actions %} - {% if action.options['use_inline_display'] == true %} - {% set inlineActions = inlineActions|merge([action]) %} - {% else %} - {% set regularActions = regularActions|merge([action]) %} - {% endif %} - {% endfor %} - -
    - {% if inlineActions is not empty %} -
    - {% for inlineAction in inlineActions -%} - {% if inlineAction.isApplicable(record) %} - - {% set class = 'dropdown-item inline-dropdown-item' %} - - {{ include('@PrestaShop/Admin/Common/Grid/Actions/Row/'~inlineAction.type~'.html.twig', { - 'grid': grid, - 'column': column, - 'attributes': {'class': class, 'tooltip_name': true}, - 'record': record, - 'action': inlineAction - }) }} - {% endif %} - {% endfor %} -
    - {% endif %} - - {% if regularActions is not empty %} -
    - {% set skippedActions, isFirstRendered = 0, false %} - - {# Render first item that is not in dropwdown #} - {% for action in regularActions %} - {% if not isFirstRendered %} - {% set skippedActions = skippedActions + 1 %} - {% endif %} - - {% if action.isApplicable(record) and not isFirstRendered %} - {{ include('@PrestaShop/Admin/Common/Grid/Actions/Row/'~action.type~'.html.twig', { - 'grid': grid, - 'column': column, - 'attributes': {'class': 'dropdown-item', 'tooltip_name': true}, - 'record': record, - 'action': action - }) }} - - {% set isFirstRendered = true %} - {% endif %} - {% endfor %} - - {# Render remaining items in dropdown #} - {% if regularActions|length > skippedActions %} - - - - {% endif %} -
    - {% endif %} -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/attribute_color.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/attribute_color.html.twig deleted file mode 100644 index f7dc9a5f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/attribute_color.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/badge.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/badge.html.twig deleted file mode 100644 index 68d9a24e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/badge.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -{% if record[column.options.field] is not empty %} - - {{ record[column.options.field] }} - -{% else %} - {{ column.options.empty_value }} -{% endif %} -
    - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/boolean.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/boolean.html.twig deleted file mode 100644 index 8b01b81d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/boolean.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if record[column.options.field] %} - {{ column.options.true_name }} -{% else %} - {{ column.options.false_name }} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/bulk_action.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/bulk_action.html.twig deleted file mode 100644 index 3b8f8bdb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/bulk_action.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/category_position.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/category_position.html.twig deleted file mode 100644 index 5108b174..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/category_position.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% if grid.sorting.order_by == 'position' and grid.sorting.order_way == 'asc' %} -
    - - {{ record[column.options.field] + 1 }} - -
    - {% else %} -
    - - {{ record[column.options.field] + 1 }} - -
    - {% endif %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/choice.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/choice.html.twig deleted file mode 100644 index 9805631e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/choice.html.twig +++ /dev/null @@ -1,65 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set choices = column.options.choice_provider.getChoices(record) %} -{% set selectedChoice = record[column.options.field] %} -{% set selectedChoiceName = '' %} -{% set routeParams = record|array_pluck(column.options.record_route_params) %} - -{% for name,value in choices %} - {% if value == selectedChoice %} - {% set selectedChoiceName = name %} - {% endif %} -{% endfor %} - -{% set classes = 'btn btn-secondary dropdown-toggle dropdown-toggle-split rounded' %} - -{% if choices is not empty %} - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/color.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/color.html.twig deleted file mode 100644 index 6d9f1ded..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/color.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set textColor = is_color_bright(record[column.options.color_field]) ? '#383838' : 'white' %} - - - {{ record[column.options.field] }} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/data.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/data.html.twig deleted file mode 100644 index 5b5a02f2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/data.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{{ record[column.options.field]|raw }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/date_time.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/date_time.html.twig deleted file mode 100644 index 38b89bae..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/date_time.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set valueToDisplay = record[column.id]|date(column.options.format) %} - -{% if record[column.id] == constant('PrestaShop\\PrestaShop\\Core\\Util\\DateTime\\DateTime::NULL_VALUE') %} - {% set valueToDisplay = column.options.empty_data %} -{% endif %} - -{{ valueToDisplay }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/disableable_link.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/disableable_link.html.twig deleted file mode 100644 index 15b582c6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/disableable_link.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends "@PrestaShop/Admin/Common/Grid/Columns/Content/link.html.twig" %} - - -{% block link %} - {% if record[column.options.disabled_field] %} - {{ 'Deleted customer'|trans({}, 'Admin.Global') }} - {% else %} - {{ parent() }} - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/draggable.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/draggable.html.twig deleted file mode 100644 index b2da7af1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/draggable.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - drag_indicator - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/employee_name_with_avatar.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/employee_name_with_avatar.html.twig deleted file mode 100644 index 22020fea..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/employee_name_with_avatar.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if record.employee is not null %} - {% - set employeeName, employeeImage = record.employee, 'http://profile.prestashop.com/'~record.email|url_encode~'.jpg' - %} - - {{ employeeName }} - - {{ employeeName }} -{% else %} - {{ 'N/A'|trans({}, 'Admin.Global') }} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/identifier.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/identifier.html.twig deleted file mode 100644 index 0f6f0c07..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/identifier.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if column.options.with_bulk_field %} -
    - -
    -{% endif %} - -{{ record[column.options.identifier_field] }} - -{% if column.options.preview is not null %} - {% include '@PrestaShop/Admin/Common/Grid/Columns/Content/preview.html.twig' with { - 'column': column.options.preview, - 'record': record, - } - %} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/image.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/image.html.twig deleted file mode 100644 index 83ca6e5c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/image.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link.html.twig deleted file mode 100644 index 52c0983b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set color = column.options.color_template%} -{% set class = "text-" ~ color %} - -{% if column.options.button_template %} - {% set style = column.options.button_template %} - {% if style == 'normal' %} - {% set class = "btn btn-" ~ color %} - {% elseif style == 'outline' %} - {% set class = "btn btn-outline-" ~ color %} - {% endif %} -{% endif %} - -{% block link %} - - {% if column.options.icon is defined %} - {{ column.options.icon }} - {% endif %} - {{ record[column.options.field] }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link_group.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link_group.html.twig deleted file mode 100644 index b93c3b64..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/link_group.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% for link in column.options.links %} - {% if record[link.is_link_available_field] %} - - {{ link.icon }} - - {% endif %} - {% endfor %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/order_price.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/order_price.html.twig deleted file mode 100644 index ebb5cebf..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/order_price.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% if record[column.options.is_paid_field] %} - - {{ record[column.options.field] }} - - {% else %} - {{ record[column.options.field] }} - {% endif %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position.html.twig deleted file mode 100644 index 125d8fe0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {{ record[column.options.position_field] + 1 }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position_handle.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position_handle.html.twig deleted file mode 100644 index 3e03b31b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/position_handle.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set updateRouteParams = record|array_pluck(column.options.record_route_params) %} - -
    - drag_indicator -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/preview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/preview.html.twig deleted file mode 100644 index 9a37f16e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/preview.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - {{ column.options.icon_expand }} - {{ column.options.icon_collapse }} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/severity_level.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/severity_level.html.twig deleted file mode 100644 index 2602189b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/severity_level.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set severity = record.severity %} -{% set withMessage = column.options.with_message %} - -{% if severity == 1 %} - {% set severityClass = 'success' %} - {% set severityMessage = withMessage ? 'Informative only'|trans({}, 'Admin.Advparameters.Help') : '' %} -{% elseif severity == 2 %} - {% set severityClass = 'warning' %} - {% set severityMessage = withMessage ? 'Warning'|trans({}, 'Admin.Advparameters.Help') : '' %} -{% elseif severity == 3 %} - {% set severityClass = 'danger' %} - {% set severityMessage = withMessage ? 'Error'|trans({}, 'Admin.Advparameters.Help') : '' %} -{% elseif severity == 4 %} - {% set severityClass = 'dark' %} - {% set severityMessage = withMessage ? 'Major issue (crash)!'|trans({}, 'Admin.Advparameters.Help') : '' %} -{% else %} - {% set severityClass = '' %} -{% endif %} - - - {% if withMessage %} - {{ severityMessage }} ({{ severity }}) - {% else %} - {{ severity }} - {% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/toggle.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/toggle.html.twig deleted file mode 100644 index f50e12f1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Content/toggle.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set id_property_name = column.options.primary_field %} -{% set id_primary_key = record[id_property_name] %} -{% set record_id = record[id_property_name] %} - -{% set isValid = record[column.id] is same as('1') %} - -
    - - {% if isValid %} - check - {% else %} - clear - {% endif %} - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/action.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/action.html.twig deleted file mode 100644 index 712e79c5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/action.html.twig +++ /dev/null @@ -1,27 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - {{ column.name }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/default.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/default.html.twig deleted file mode 100644 index ce5f22bb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/default.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set orderBy, orderWay = grid.sorting.order_by, grid.sorting.order_way %} - -{% if column.options.sortable is defined and column.options.sortable and grid.data.records_total > 0 %} - {{ ps.sortable_column_header(column.name, column.id, orderBy, orderWay, grid.form_prefix) }} -{% else %} - {{ column.name }} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/position_handle.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/position_handle.html.twig deleted file mode 100644 index f4e4cf9d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/Columns/Header/Content/position_handle.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid.html.twig deleted file mode 100644 index 46aa0701..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    - {% block grid_header_row %} -
    - {% block grid_bulk_actions_block %} -
    -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/bulk_actions.html.twig', {'grid': grid}) }} -
    -
    -
    - {% endblock %} -
    - {% endblock %} - - {% block grid_table_row %} -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/table.html.twig', {'grid': grid}) }} -
    -
    - {% endblock %} - - {% block grid_footer_row %} -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/pagination.html.twig', {'grid': grid}) }} -
    -
    - {% endblock %} -
    -
    - -{% block grid_extra_content %}{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid_panel.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid_panel.html.twig deleted file mode 100644 index bc2cb0b3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Grid/grid_panel.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% block grid_panel_header %} -
    -

    - {{ grid.name }} ({{ grid.data.records_total }}) -

    - {% block grid_actions_block %} -
    - {{ include('@PrestaShop/Admin/Common/Grid/Blocks/grid_actions.html.twig', {'grid': grid}) }} -
    - {% endblock %} -
    - {% endblock %} - - {% block grid_panel_body %} -
    - {% block grid_view_block %} - {{ include('@PrestaShop/Admin/Common/Grid/grid.html.twig', {'grid': grid }) }} - {% endblock %} -
    - {% endblock %} - - {% block grid_panel_footer %}{% endblock %} -
    - -{% block grid_panel_extra_content %}{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/Kpi/kpi_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/Kpi/kpi_row.html.twig deleted file mode 100644 index 80da3211..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/Kpi/kpi_row.html.twig +++ /dev/null @@ -1,46 +0,0 @@ - {#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block kpi_row %} -
    -
    -
    - {% for kpi in kpiRow.kpis %} -
    - {{ kpi|raw }} -
    - {% endfor %} -
    -
    -
    - - {% if kpiRow.allowRefresh %} -
    - -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_form_field.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_form_field.html.twig deleted file mode 100644 index eb947425..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_form_field.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{{ form_widget(form, {'id': formId }) }} -{{ form_errors(form) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_sidebar.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_sidebar.html.twig deleted file mode 100644 index 01c88c78..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/_partials/_sidebar.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - -

    {{ title|raw|trans({}, 'AdminCommon') }}

    -
    -
    - -
    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/pagination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/pagination.html.twig deleted file mode 100644 index 8bc7ddd3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/pagination.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/pagination_quicknav.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/pagination_quicknav.html.twig deleted file mode 100644 index decaa3f9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/pagination_quicknav.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if previous_url or next_url %} - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Common/recommendedModules.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Common/recommendedModules.html.twig deleted file mode 100644 index c0381a41..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Common/recommendedModules.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_form.html.twig deleted file mode 100644 index 1170a021..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_form.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block backup_creation_form %} -
    - - - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_info.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_info.html.twig deleted file mode 100644 index 05457900..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_info.html.twig +++ /dev/null @@ -1,54 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block backup_info %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_warning.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_warning.html.twig deleted file mode 100644 index 1459bc6e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_warning.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block backup_warning %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/download_file.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/download_file.html.twig deleted file mode 100644 index 52b9d013..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/download_file.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -
    -

    - cloud_download - {{ 'Download'|trans({}, 'Admin.Actions') }} -

    -
    -

    - - cloud_download - {{ 'Download the backup file (%s MB)'|trans({'%s': downloadFile.size}) }} - -

    -

    {{ 'Tip: You can also download this file from your FTP server. Backup files are located in the "/adminXXXX/backups" directory.'|trans }}

    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/options.html.twig deleted file mode 100644 index cf762621..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/Blocks/options.html.twig +++ /dev/null @@ -1,73 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block backup_options_card %} - {{ form_start(backupForm) }} -
    -

    - settings {{ 'Backup options'|trans({}, 'Admin.Advparameters.Feature') }} -

    -
    -
    -
    - -
    - {{ form_errors(backupForm.backup_options.backup_all) }} - {{ form_widget(backupForm.backup_options.backup_all) }} - - - {{ 'Drop existing tables during import.'|trans({}, 'Admin.Advparameters.Help') }}
    - {{ '%prefix%connections, %prefix%connections_page %prefix%connections_source, %prefix%guest, %prefix%statssearch'|replace({'%prefix%': dbPrefix}) }} -
    -
    -
    - -
    - {% set helpMessage = 'If enabled, the backup script will drop your tables prior to restoring data.'|trans({}, 'Admin.Advparameters.Help') %} - {% set helpMessage = helpMessage ~ ' ' ~ '(ie. "DROP TABLE IF EXISTS")'|trans({}, 'Admin.Advparameters.Help') %} - - {{ ps.label_with_help(('Drop existing tables during import'|trans), helpMessage) }} -
    - {{ form_errors(backupForm.backup_options.backup_drop_tables) }} - {{ form_widget(backupForm.backup_options.backup_drop_tables) }} -
    -
    - - {% block backup_options_rest %} - {{ form_rest(backupForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(backupForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/download_view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/download_view.html.twig deleted file mode 100644 index d2ddb2a9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/download_view.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} -
    -
    -
    -
    -

    - cloud_download - {{ 'Download'|trans({}, 'Admin.Actions') }} -

    -
    - -

    {{ 'Backup files should automatically start downloading.'|trans({}, 'Admin.Advparameters.Notification') }}

    -

    {{ 'If not,[1][2] please click here[/1]!'|trans({'[1]': ' ', '[/1]': ' ', '[2]': ''}, 'Admin.Advparameters.Notification')|raw }}

    - - -
    -
    -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/index.html.twig deleted file mode 100644 index c18dbc39..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Backup/index.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} - {% block backup_download_file %} - {% if hasDownloadFile %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Backup/Blocks/download_file.html.twig' %} - {% endif %} - {% endblock %} - - {% block backup_alerts %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_warning.html.twig' %} -
    -
    - -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Backup/Blocks/backup_info.html.twig' %} -
    -
    - {% endblock %} - - {% block backup_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': backupGrid} %} -
    -
    - {% endblock %} - - {% block backup_options %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Backup/Blocks/options.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_available_fields.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_available_fields.html.twig deleted file mode 100644 index f170a138..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_available_fields.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -
    -

    - list {{ 'Available fields'|trans }} -

    -
    -
    - - - -

    {{ '* Required field'|trans({}, 'Admin.Advparameters.Feature') }}

    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_file_history.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_file_history.html.twig deleted file mode 100644 index 3acad9f3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_file_history.html.twig +++ /dev/null @@ -1,106 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -
    -
    - {{ 'History of uploaded files'|trans({}, 'Admin.Advparameters.Feature') }} - {{ importFileNames|length }} - - - -
    -
    - - - - - - - {% for fileName in importFileNames %} - - - - - {% endfor %} - -
    -
    - - - -
    -
    {{ fileName }} -
    - - - -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_panel.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_panel.html.twig deleted file mode 100644 index 75e3b13a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_panel.html.twig +++ /dev/null @@ -1,182 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{{ form_start(importForm, {'attr': { 'data-file-upload-url': importFileUploadUrl, 'data-delete-confirm-message': ('Are you sure you want to delete this entity:'|trans({}, 'Admin.Advparameters.Notification')), 'class': 'js-import-form' }}) }} -
    -

    - import_export {{ 'Import'|trans({}, 'Admin.Actions') }} -

    -
    - - -
    - -
    - - {{ form_errors(importForm.entity) }} - {{ form_widget(importForm.entity, {'attr': {'class': 'js-entity-select'}}) }} -
    - - - -
    - -
    - {{ form_errors(importForm.csv) }} - {{ form_widget(importForm.csv, {'attr': {'class': 'js-import-file-input'}}) }} -
    - -
    - -
    -
    - {{ form_errors(importForm.file) }} - {{ form_widget(importForm.file, {'attr': {'class': 'js-import-file', 'data-max-file-upload-size': maxFileUploadSize }}) }} -
    -
    - {{ 'or'|trans({}, 'Admin.Global') }} - -
    -
    - {{ 'Allowed formats: .csv, .xls, .xlsx, .xlst, .ods, .ots'|trans({}, 'Admin.Advparameters.Help') }} - {{ 'Only UTF-8 and ISO 8859-1 encodings are allowed'|trans({}, 'Admin.Advparameters.Help') }} - {{ 'You can also upload your file via FTP to the following directory: %s .'|trans({'%s': importDirectory}, 'Admin.Advparameters.Help') }} -
    - - - - - - {% block import_file_history_block %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Blocks/import_file_history.html.twig' %} - {% endblock %} - -
    - -
    - {{ ps.label_with_help(('Language of the file'|trans), ('The locale must be installed'|trans({}, 'Admin.Advparameters.Notification'))) }} - {{ form_errors(importForm.iso_lang) }} - {{ form_widget(importForm.iso_lang) }} -
    - -
    - - {{ form_errors(importForm.separator) }} - {{ form_widget(importForm.separator) }} - {{ 'e.g. '|trans({}, 'Admin.Advparameters.Help') }} 1; Blouse; 129.90; 5 -
    - -
    - - {{ form_errors(importForm.multiple_value_separator) }} - {{ form_widget(importForm.multiple_value_separator) }} - {{ 'e.g. '|trans({}, 'Admin.Advparameters.Help') }} Blouse; red.jpg, blue.jpg, green.jpg; 129.90 -
    - -
    - -
    - - {{ form_errors(importForm.truncate) }} - {{ form_widget(importForm.truncate) }} -
    - -
    - {{ ps.label_with_help(('Use product reference as key'|trans), ('If enabled, the product\'s reference number MUST be unique!'|trans({}, 'Admin.Advparameters.Help'))) }} - {{ form_errors(importForm.match_ref) }} - {{ form_widget(importForm.match_ref) }} -
    - -
    - - {{ form_errors(importForm.regenerate) }} - {{ form_widget(importForm.regenerate) }} -
    - -
    - {{ ps.label_with_help(('Force all ID numbers'|trans), ("If you enable this option, your imported items' ID number will be used as is. If you do not enable this option, the imported ID numbers will be ignored, and PrestaShop will instead create auto-incremented ID numbers for all the imported items."|trans({}, 'Admin.Advparameters.Help'))) }} - {{ form_errors(importForm.forceIDs) }} - {{ form_widget(importForm.forceIDs) }} -
    - -
    - {{ ps.label_with_help(('Send notification email'|trans), ('Sends an email to let you know your import is complete. It can be useful when handling large files, as the import may take some time.'|trans({}, 'Admin.Advparameters.Help'))) }} - {{ form_errors(importForm.sendemail) }} - {{ form_widget(importForm.sendemail) }} -
    - - {{ form_rest(importForm) }} -
    - -
    -{{ form_end(importForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_sample_files.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_sample_files.html.twig deleted file mode 100644 index 07aea531..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Blocks/import_sample_files.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -
    -

    - file_download {{ 'Download sample csv files'|trans({}, 'Admin.Advparameters.Feature') }} -

    - -
    -
    - {{ ps.import_file_sample('Sample Categories file', 'categories_import') }} - {{ ps.import_file_sample('Sample Products file', 'products_import') }} - {{ ps.import_file_sample('Sample Combinations file', 'combinations_import') }} - {{ ps.import_file_sample('Sample Customers file', 'customers_import') }} - {{ ps.import_file_sample('Sample Addresses file', 'addresses_import') }} - {{ ps.import_file_sample('Sample Brands file', 'manufacturers_import') }} - {{ ps.import_file_sample('Sample Suppliers file', 'suppliers_import') }} - {{ ps.import_file_sample('Sample Aliases file', 'alias_import') }} - {{ ps.import_file_sample('Sample Store Contacts file', 'store_contacts') }} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_configuration.html.twig deleted file mode 100644 index 282b5f9e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_configuration.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block email_configuration %} -
    -
    -

    - mail {{ 'Email'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - -
    - {{ form_errors(emailConfigurationForm.email_config.send_emails_to) }} - {{ form_widget(emailConfigurationForm.email_config.send_emails_to) }} - - {{ 'Where customers send messages from the order page.'|trans({}, 'Admin.Advparameters.Help') }} - -
    -
    - -
    - -
    - {{ form_errors(emailConfigurationForm.email_config.mail_method) }} - {{ form_widget(emailConfigurationForm.email_config.mail_method) }} -
    -
    - -
    - -
    - {{ form_errors(emailConfigurationForm.email_config.mail_type) }} - {{ form_widget(emailConfigurationForm.email_config.mail_type) }} -
    -
    - -
    - -
    - {{ form_errors(emailConfigurationForm.email_config.log_emails) }} - {{ form_widget(emailConfigurationForm.email_config.log_emails) }} -
    -
    - - {% block email_configuration_form_rest %} - {{ form_rest(emailConfigurationForm.email_config) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_logs_grid.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_logs_grid.html.twig deleted file mode 100644 index ebb4174b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/email_logs_grid.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with { 'grid': emailLogsGrid } %} - {% trans_default_domain 'Admin.Advparameters.Feature' %} - - {% block grid_footer %} - - {% endblock %} -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/smtp_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/smtp_configuration.html.twig deleted file mode 100644 index 8546161a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/smtp_configuration.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Advparameters.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block smtp_configuration %} -
    -
    -

    - settings {{ 'Email'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - {{ ps.label_with_help(('Mail domain name'|trans), ('Fully qualified domain name (keep this field empty if you don\'t know).'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(emailConfigurationForm.smtp_config.domain) }} - {{ form_widget(emailConfigurationForm.smtp_config.domain) }} -
    -
    - -
    - {{ ps.label_with_help(('SMTP server'|trans), ('IP address or server name (e.g. smtp.mydomain.com).'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(emailConfigurationForm.smtp_config.server) }} - {{ form_widget(emailConfigurationForm.smtp_config.server) }} -
    -
    - -
    - {{ ps.label_with_help(('SMTP username'|trans), ('Leave blank if not applicable.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(emailConfigurationForm.smtp_config.username) }} - {{ form_widget(emailConfigurationForm.smtp_config.username) }} -
    -
    - -
    - {{ ps.label_with_help(('SMTP password'|trans), ('Leave blank if not applicable.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(emailConfigurationForm.smtp_config.password) }} - {{ form_widget(emailConfigurationForm.smtp_config.password) }} -
    -
    - -
    - -
    - {{ form_errors(emailConfigurationForm.smtp_config.encryption) }} - {{ form_widget(emailConfigurationForm.smtp_config.encryption) }} - {% if not isOpenSslExtensionLoaded %} - - {{ 'SSL does not seem to be available on your server.'|trans({}, 'Admin.Advparameters.Notification') }} - - {% endif %} -
    -
    - -
    - {{ ps.label_with_help(('Port'|trans), ('Port number to use.'|trans)) }} -
    - {{ form_errors(emailConfigurationForm.smtp_config.port) }} - {{ form_widget(emailConfigurationForm.smtp_config.port) }} -
    -
    - - {% block smtp_configuration_form_rest %} - {{ form_rest(emailConfigurationForm.smtp_config) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/test_email_sending.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/test_email_sending.html.twig deleted file mode 100644 index 6c22064e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/Blocks/test_email_sending.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block test_email_sending %} - {{ form_start(testEmailSendingForm, {'action': path('admin_emails_send_test')}) }} -
    -
    -
    -

    - settings {{ 'Test your email configuration'|trans }} -

    -
    -
    -
    - -
    - {{ form_widget(testEmailSendingForm.send_email_to) }} -
    -
    - -
    -
    - - -
    -
    -
    -
    - -
    -
    -
    - {{ form_end(testEmailSendingForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/index.html.twig deleted file mode 100644 index 6009d9fd..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Email/index.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} - {% if isEmailLogsEnabled %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Email/Blocks/email_logs_grid.html.twig' %} -
    -
    - {% endif %} - - {{ form_start(emailConfigurationForm, {'action': path('admin_emails_save_options')}) }} -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Email/Blocks/email_configuration.html.twig' %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Email/Blocks/smtp_configuration.html.twig' %} - - {% block email_configuration_form_rest %} - {{ form_rest(emailConfigurationForm) }} - {% endblock %} -
    - {{ form_end(emailConfigurationForm) }} - - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Email/Blocks/test_email_sending.html.twig' %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/employee_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/employee_options.html.twig deleted file mode 100644 index 096de0cd..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/employee_options.html.twig +++ /dev/null @@ -1,95 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block employee_options_form %} - {{ form_start(employeeOptionsForm, {'action': path('admin_employees_save_options') }) }} -
    -

    - settings - {{ 'Employee options'|trans({}, 'Admin.Advparameters.Feature') }} -

    -
    -
    -
    - - -
    - {{ form_errors(employeeOptionsForm.options.password_change_time) }} - {{ form_widget(employeeOptionsForm.options.password_change_time) }} - - {{ 'Security: Minimum time to wait between two password changes.'|trans({}, 'Admin.Advparameters.Feature') }} - - - {% if not canOptionsBeChanged %} - - {% endif %} -
    -
    - -
    - - -
    - {{ form_errors(employeeOptionsForm.options.allow_employee_specific_language) }} - {{ form_widget(employeeOptionsForm.options.allow_employee_specific_language) }} - - {{ 'Allow employees to select a specific language for the Admin panel form.'|trans({}, 'Admin.Advparameters.Feature') }} - - - {% if not canOptionsBeChanged %} - - {% endif %} -
    -
    - - {% block employee_options_form_rest %} - {{ form_rest(employeeOptionsForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(employeeOptionsForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig deleted file mode 100644 index f43d1919..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig +++ /dev/null @@ -1,251 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block employee_addons_connect %} - {% include '@PrestaShop/Admin/Module/Includes/modal_addons_connect.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} -{% endblock %} - -{% block employee_form %} - {{ form_start(employeeForm) }} -
    -

    - {{ 'Employees'|trans }} -

    -
    -
    - {{ form_errors(employeeForm) }} - - {{ ps.form_group_row(employeeForm.firstname, {}, { - 'label': 'First name'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(employeeForm.lastname, {}, { - 'label': 'Last name'|trans({}, 'Admin.Global') - }) }} - -
    - -
    - - - -
    -
    - -
    - -
    - -
    -
    - - {{ ps.form_group_row(employeeForm.email, {}, { - 'label': 'Email address'|trans({}, 'Admin.Global') - }) }} - - {% set passwordHelpMessage = 'Password should be at least %num% characters long.'|trans({ '%num%': 8 }, 'Admin.Advparameters.Help') %} - - {% if isRestrictedAccess %} - {% set oldPasswordVars = employeeForm.change_password.old_password.vars|merge(old_password|default({})) %} - {% set newPasswordFirstVars = employeeForm.change_password.new_password.children.first.vars|merge(new_password.first_options|default({})) %} - {% set newPasswordSecondVars = employeeForm.change_password.new_password.children.second.vars|merge(new_password.second_options|default({})) %} - -
    - -
    - {# "Change password" button #} - {{ form_widget(employeeForm.change_password.change_password_button, { - label: 'Change password...'|trans({}, 'messages'), - attr: { - class: 'btn-outline-secondary js-change-password', - } - }) }} - -
    - {# Current password input #} - {{ ps.form_group_row(employeeForm.change_password.old_password, oldPasswordVars, { - label: 'Current password'|trans({}, 'messages'), - required: true, - }) }} - - {# New password first input #} -
    - {{ ps.label_with_help('New password'|trans({}, 'messages'), passwordHelpMessage, '', employeeForm.change_password.new_password.children.first.vars.id, true) }} -
    - {{ ps.form_widget_with_error(employeeForm.change_password.new_password.children.first, employeeForm.change_password.new_password.children.first.vars) }} -
    -
    - - {# New password second input (confirmation) #} - {# Empty help text needed to render the text container for validation feedback messages #} - {{ ps.form_group_row(employeeForm.change_password.new_password.children.second, newPasswordSecondVars, { - label: 'Confirm password'|trans({}, 'messages'), - help: '', - required: true, - }) }} - -
    - -
    - {{ form_widget(employeeForm.change_password.generated_password) }} -
    -
    - {{ form_widget(employeeForm.change_password.generate_password_button, { - label: 'Generate password'|trans({}, 'messages'), - attr: { - class: 'btn-outline-secondary', - } - }) }} -
    -
    - - {{ ps.form_group_row(employeeForm.change_password.cancel_button, { - label: 'Cancel'|trans({}, 'Admin.Actions'), - attr: { - class: 'btn-outline-secondary js-change-password-cancel', - } - }) }} - - {# Password strength feedback messages - used in JS #} -
    - {{ 'Invalid'|trans({}, 'messages') }} - {{ 'Okay'|trans({}, 'messages') }} - {{ 'Good'|trans({}, 'messages') }} - {{ 'Fabulous'|trans({}, 'messages') }} -
    -
    -
    -
    - {% else %} - {{ ps.form_group_row(employeeForm.password, {}, { - 'label': 'Password'|trans({}, 'Admin.Global'), - 'help': passwordHelpMessage, - }) }} - {% endif %} - - {% if isRestrictedAccess and showAddonsConnectButton %} -
    - -
    - {% if employeeForm.prestashop_addons.vars.is_addons_connected %} -

    - account_circle - {{ 'You are currently connected as %username%' - |trans({}, 'Admin.Advparameters.Feature') - |replace({ '%username%': employeeForm.prestashop_addons.vars.addons_username }) - }} -

    - {% endif %} - -
    - {% if employeeForm.prestashop_addons.vars.is_addons_connected %} - {% set label, target = - 'Sign out from PrestaShop Addons'|trans({}, 'Admin.Advparameters.Feature'), - '#module-modal-addons-logout' - %} - {% else %} - {% set label, target = - 'Sign in'|trans({}, 'Admin.Advparameters.Feature'), - '#module-modal-addons-connect' - %} - {% endif %} - - {{ form_widget(employeeForm.prestashop_addons, { - attr: { - 'class': 'btn-outline-secondary', - 'data-toggle': 'modal', - 'data-target': target, - }, - label: label, - }) }} -
    -
    -
    - {% endif %} - - {{ ps.form_group_row(employeeForm.default_page, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}, { - 'label': 'Default page'|trans, - 'help': 'This page will be displayed just after login.'|trans({}, 'Admin.Advparameters.Help') - }) }} - - {{ ps.form_group_row(employeeForm.language, {}, { - 'label': 'Language'|trans({}, 'Admin.Global') - }) }} - - {% if not isRestrictedAccess %} - {{ ps.form_group_row(employeeForm.active, {}, { - 'label': 'Active'|trans({}, 'Admin.Global'), - 'help': 'Allow or disallow this employee to log in to the Admin panel.'|trans({}, 'Admin.Advparameters.Help') - }) }} - - {{ ps.form_group_row(employeeForm.profile, { - 'attr': { - 'data-admin-profile': superAdminProfileId, - 'data-get-tabs-url': getTabsUrl, - } - }, { - 'label': 'Permission profile'|trans({}, 'Admin.Advparameters.Feature') - }) }} - - {% if employeeForm.shop_association is defined %} - {{ ps.form_group_row(employeeForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global'), - 'help': 'Select the shops the employee is allowed to access.'|trans({}, 'Admin.Advparameters.Help') - }) }} - {% endif %} - {% endif %} - - {% block employee_form_rest %} - {{ form_rest(employeeForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(employeeForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/showcase_card.html.twig deleted file mode 100644 index 4482b762..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,45 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not isShowcaseCardClosed %} -
    -
    - -
    -
    -

    {{ 'Manage your team'|trans({}, 'Admin.Advparameters.Feature') }}

    -

    {{ 'Create profiles for your employees with specific rights. SuperAdmin can access the entire store while other people can only be dedicated to the catalog or orders pages.'|trans({}, 'Admin.Advparameters.Feature') }}

    - - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - -
    - - close - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/create.html.twig deleted file mode 100644 index 446fc42f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/create.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig' with { - employeeForm: employeeForm, - level: level, - errorMessage: errorMessage, - isRestrictedAccess: false, - superAdminProfileId: superAdminProfileId, - getTabsUrl: getTabsUrl, - avatarUrl: employeeForm.vars.defaultAvatarUrl - } %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {# Password generation plugin #} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/edit.html.twig deleted file mode 100644 index 4358c1b4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/edit.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Edit: %lastname% %firstname%'|trans({ - '%firstname%': editableEmployee.firstName.value, - '%lastname%': editableEmployee.lastName.value -}, 'Admin.Advparameters.Feature') %} - -{% block content %} - {% if employeeForm.vars.errors is not empty %} -
    - {% for error in employeeForm.vars.errors %} -
    {{ error.message }}
    - {% endfor %} -
    - {% endif %} - -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/Blocks/form.html.twig' with { - employeeForm: employeeForm, - level: level, - errorMessage: errorMessage, - isRestrictedAccess: isRestrictedAccess, - superAdminProfileId: superAdminProfileId, - showAddonsConnectButton: showAddonsConnectButton, - getTabsUrl: getTabsUrl, - avatarUrl: editableEmployee.avatarUrl - } %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {# Password generation plugin #} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/index.html.twig deleted file mode 100644 index 69abda6e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Employee/index.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutHeaderToolbarBtn = { - 'add': { - 'href': path('admin_employees_create'), - 'desc': 'Add new employee'|trans({}, 'Admin.Advparameters.Feature'), - 'icon': 'add_circle_outline' - } -} %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% block employee_showcase_card %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/Blocks/showcase_card.html.twig' %} -
    -
    - {% endblock %} - - {% block employee_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with { 'grid': employeeGrid } %} -
    -
    - {% endblock %} - - {% block employee_options %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Employee/Blocks/employee_options.html.twig' %} - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_data_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_data_configuration.html.twig deleted file mode 100644 index 22762d14..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_data_configuration.html.twig +++ /dev/null @@ -1,174 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{{ form_start(importDataConfigurationForm, {attr: {class: 'import-data-configuration-form'}}) }} -
    -

    - list {{ 'Match your data'|trans }} -

    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    - {{ form_widget(importDataConfigurationForm.matches) }} -
    -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    - {{ form_widget(importDataConfigurationForm.match_name, {'attr': {'class': 'js-import-match-input', 'type': 'button'}}) }} -
    -
    - -
    -
    -
    -
    -
    - -
    - {{ form_widget(importDataConfigurationForm.skip, {'attr': {'class': 'col-xs-12 col-md-4 js-rows-skip', 'min': 0}}) }} - {{ 'Indicate how many of the first rows of your file should be skipped when importing the data. For instance set it to 1 if the first row of your file contains headers.'|trans }} -
    -
    -
    -
    - - -
    -
    -
    - - - - {% for importEntityField in importDataConfigurationForm.type_value %} - - {% endfor %} - - - - {% for row in dataRowCollection.rows %} - - {% for cell in row %} - maxVisibleColumns %} class="d-none"{% endif %}>{{ cell.value }} - {% endfor %} - - {% endfor %} - -
    - {{ form_errors(importEntityField) }} - {{ form_widget(importEntityField) }} -
    -
    -
    -
    - -
    -
    - -
    -
    - {{ form_rest(importDataConfigurationForm) }} -
    -
    - -
    -{{ form_end(importDataConfigurationForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_modal.html.twig deleted file mode 100644 index e1e97f14..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_modal.html.twig +++ /dev/null @@ -1,87 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Notification' %} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': 'import_progress_modal', - 'title': 'Importing your data...'|trans, - 'closable': false, - 'progressbar': { - id: 'import_progress_bar', - label: 'Validating data...'|trans - }, - 'actions': [ - { - 'type': 'button', - 'label': 'Ignore warnings and continue?'|trans, - 'class': 'btn btn-outline-warning btn-lg js-continue-import', - }, - { - 'type': 'button', - 'label': 'Abort import'|trans, - 'class': 'btn btn-outline-danger btn-lg js-abort-import', - }, - { - 'type': 'button', - 'label': 'Close'|trans({}, 'Admin.Actions'), - 'class': 'btn btn-outline-secondary btn-lg js-close-modal', - } - ], -} %} - {% block content %} - - {% endblock %} -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/index.html.twig deleted file mode 100644 index d1cbb590..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportDataConfiguration/index.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} -
    -
    - {% block import_data_configuration_panel %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_data_configuration.html.twig' %} - {% endblock %} - - {% block import_modal %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/ImportDataConfiguration/Blocks/import_modal.html.twig' %} - {% endblock %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig deleted file mode 100644 index 6f98b782..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/ImportPage/import.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} - {% if importForm is defined %} -
    -
    -
    -
    - {% block import_panel %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Blocks/import_panel.html.twig' %} - {% endblock %} -
    - -
    - {% block import_available_fields %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Blocks/import_available_fields.html.twig' %} - {% endblock %} - - {% block import_sample_files %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Blocks/import_sample_files.html.twig' %} - {% endblock %} -
    -
    -
    -
    - {% endif %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/severity_levels.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/severity_levels.html.twig deleted file mode 100644 index c3c26cf9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/Blocks/severity_levels.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain "Admin.Advparameters.Feature" %} -
    -
    -

    - warning {{ 'Severity levels'|trans({}, 'Admin.Advparameters.Help') }} -

    -
    -
    -

    {{ 'Meaning of severity levels:'|trans }}

    -
      -
    1. - - {{ 'Informative only'|trans({}, 'Admin.Advparameters.Help') }} - -
    2. -
    3. - - {{ 'Warning'|trans({}, 'Admin.Advparameters.Help') }} - -
    4. -
    5. - - {{ 'Error'|trans({}, 'Admin.Advparameters.Help') }} - -
    6. -
    7. - - {{ 'Major issue (crash)!'|trans({}, 'Admin.Advparameters.Help') }} - -
    8. -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/index.html.twig deleted file mode 100644 index b0043764..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/LogsPage/index.html.twig +++ /dev/null @@ -1,83 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block content %} - {% block logs_severity_level_meaning %} -
    - {{ include('@PrestaShop/Admin/Configure/AdvancedParameters/LogsPage/Blocks/severity_levels.html.twig') }} -
    - {% endblock %} - - {% block logs_main_panel %} -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/grid_panel.html.twig', {'grid': grid }) }} -
    -
    - {% endblock %} - - {% block logs_by_mail %} - {{ form_start(logsByEmailForm, {'action': path('admin_logs_save_settings')}) }} -
    -
    -
    -

    - business_center {{ 'Logs by email'|trans }} -

    -
    -
    -
    - {% set helptip = 'Enter "5" if you do not want to receive any emails.'|trans({}, 'Admin.Advparameters.Help') ~ ' ' ~ 'Emails will be sent to the shop owner.'|trans({}, 'Admin.Advparameters.Help') %} - {{ ps.label_with_help(('Minimum severity level'|trans), helptip, 'col-sm-2') }} -
    - {{ form_errors(logsByEmailForm.logs_by_email) }} - {{ form_widget(logsByEmailForm.logs_by_email) }} -
    -
    - - {% block logs_by_email_form_rest %} - {{ form_rest(logsByEmailForm) }} - {% endblock %} -
    -
    - -
    -
    -
    - {{ form_end(logsByEmailForm) }} - {% endblock %} -{% endblock %} -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig deleted file mode 100644 index 92403801..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(profileForm) }} -
    -

    - group - {{ 'Profile'|trans({}, 'Admin.Advparameters.Feature') }} -

    -
    -
    - {{ form_errors(profileForm) }} - - {{ ps.form_group_row(profileForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global') - }) }} - - {% block profile_form_rest %} - {{ form_rest(profileForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(profileForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/create.html.twig deleted file mode 100644 index a345e174..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/create.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/edit.html.twig deleted file mode 100644 index a345e174..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Profiles/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/index.html.twig deleted file mode 100644 index 60771001..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Profiles/index.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% block profiles_list_panel %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': grid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig deleted file mode 100644 index eded126b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Advparameters.Feature" %} - -
    -
    -
    -

    - {{ 'List of MySQL Tables'|trans }} -

    -
    -
    - -
    - - -
    -
    -
    -
    -
    -

    - {{ 'List of attributes for this MySQL table'|trans }} -

    -
    - - - - - - - - - - -
    {{ 'Attribute'|trans({}, 'Admin.Global') }}{{ 'Type'|trans({}, 'Admin.Global') }}{{ 'Action'|trans }}
    - -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig deleted file mode 100644 index 9a73d6d6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% block sql_request_form %} - {{ form_start(requestSqlForm) }} -
    -

    - {{ 'SQL query'|trans }} -

    -
    -
    - {{ form_errors(requestSqlForm) }} - -
    - - -
    - {{ ps.form_widget_with_error(requestSqlForm.name) }} -
    -
    - -
    - - -
    - {{ ps.form_widget_with_error(requestSqlForm.sql, {'attr': {'rows': 10}}) }} -
    -
    -
    - - {{ form_rest(requestSqlForm) }} -
    - -
    - {{ form_end(requestSqlForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/settings_panel.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/settings_panel.html.twig deleted file mode 100644 index 7652b590..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/Blocks/settings_panel.html.twig +++ /dev/null @@ -1,57 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{{ form_start(requestSqlSettingsForm, {'action': path('admin_sql_requests_process_settings') }) }} -
    -

    - settings - {{ 'Settings'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - -
    - {{ form_errors(requestSqlSettingsForm.settings.default_file_encoding) }} - {{ form_widget(requestSqlSettingsForm.settings.default_file_encoding) }} -
    -
    - - {% block request_sql_settings %} - {{ form_rest(requestSqlSettingsForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(requestSqlSettingsForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/create.html.twig deleted file mode 100644 index 28377b2b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/create.html.twig +++ /dev/null @@ -1,54 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} - {% if requestSqlForm.vars.errors is not empty %} -
    - {% for error in requestSqlForm.vars.errors %} -
    {{ error.message }}
    - {% endfor %} -
    - {% endif %} - -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig' %} - - {% block sql_manager_db_tables_panel %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig' %} - {% endblock %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/edit.html.twig deleted file mode 100644 index 28377b2b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/edit.html.twig +++ /dev/null @@ -1,54 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Advparameters.Feature' %} - -{% block content %} - {% if requestSqlForm.vars.errors is not empty %} -
    - {% for error in requestSqlForm.vars.errors %} -
    {{ error.message }}
    - {% endfor %} -
    - {% endif %} - -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/Blocks/form.html.twig' %} - - {% block sql_manager_db_tables_panel %} - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/Blocks/db_tables_panel.html.twig' %} - {% endblock %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/index.html.twig deleted file mode 100644 index 3c917174..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/index.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% block content %} - {% block sql_manager_info_block %} -
    -
    - -
    -
    - {% endblock %} - - {% block sql_manager_warning_block %} -
    -
    - -
    -
    - {% endblock %} - - {% block sql_manager_list_panel %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': requestSqlGrid} %} -
    -
    - {% endblock %} - - {% block sql_manager_settings_panel %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/RequestSql/Blocks/settings_panel.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/view.html.twig deleted file mode 100644 index f7569a7a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/RequestSql/view.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% block content %} - {% block request_sql_view_block %} -
    -
    -
    -
    -

    - list - {{ 'SQL query result'|trans }} ({{ sqlRequestResult.rows|length }}) -

    -
    -
    - {% if sqlRequestResult.rows is not empty %} -
    - - - - {% for column in sqlRequestResult.columns %} - - {% endfor %} - - - - {% for row in sqlRequestResult.rows %} - - {% for column in sqlRequestResult.columns %} - {% if requestSqlView.attributes[column] is defined %} - - {% else %} - - {% endif %} - {% endfor %} - - {% endfor %} - -
    {{ column }}
    {{ requestSqlView.attributes[column] }}{{ row[column] }}
    -
    - {% else %} -
    -

    - {{ 'This SQL query has no result.'|trans({}, 'Admin.Advparameters.Notification') }} -

    -
    - {% endif %} -
    -
    -
    -
    - {% endblock %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig deleted file mode 100644 index 7edb5821..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig +++ /dev/null @@ -1,88 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block webservice_key_form %} - {{ form_start(webserviceKeyForm) }} -
    -

    - {{ 'Webservice Accounts'|trans({}, 'Admin.Advparameters.Feature') }} -

    -
    -
    - {{ form_errors(webserviceKeyForm) }} - - {{ ps.form_group_row(webserviceKeyForm.key, {}, { - 'label': 'Key'|trans({}, 'Admin.Advparameters.Feature'), - 'help': 'Webservice account key.'|trans({}, 'Admin.Advparameters.Feature') - }) }} - - {{ ps.form_group_row(webserviceKeyForm.description, {}, { - 'label': 'Key description'|trans({}, 'Admin.Advparameters.Feature'), - 'help': 'Quick description of the key: who it is for, what permissions it has, etc.'|trans({}, 'Admin.Advparameters.Help') - }) }} - - {{ ps.form_group_row(webserviceKeyForm.status, {}, { - 'label': 'Status'|trans({}, 'Admin.Global') - }) }} - -
    - -
    - -
    -
    - - {{ ps.form_group_row(webserviceKeyForm.permissions, { - 'label': 'Resource'|trans({}, 'Admin.Global') - }, { - 'label': 'Permissions'|trans({}, 'Admin.Advparameters.Feature') - }) }} - - {% if webserviceKeyForm.shop_association is defined %} - {{ ps.form_group_row(webserviceKeyForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block webservice_key_form_rest %} - {{ form_rest(webserviceKeyForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(webserviceKeyForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/create.html.twig deleted file mode 100644 index 04f14551..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/create.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig deleted file mode 100644 index 04f14551..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/edit.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/index.html.twig deleted file mode 100644 index 239f4098..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/index.html.twig +++ /dev/null @@ -1,81 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% set layoutTitle = 'Webservice'|trans({}, 'Admin.Navigation.Menu') %} -{% set enableSidebar = true %} -{% set layoutHeaderToolbarBtn = { - 'add': { - 'href': path('admin_webservice_keys_create'), - 'desc': 'Add new webservice key'|trans({}, 'Admin.Advparameters.Feature'), - 'icon': 'add_circle_outline' - } -} %} - -{% block content %} - - {% block webservice_list_notifications %} - {% if configurationWarnings is not empty %} -
    -
    - -
    -
    - {% endif %} - {% endblock %} - -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/grid_panel.html.twig', {'grid': grid }) }} -
    -
    - -
    -
    - {{ form_start(form, {'action': path('admin_webservice_save_settings') ,'attr' : {'class': 'form', 'id': 'configuration_form'} }) }} - - {{ include('@PrestaShop/Admin/Configure/AdvancedParameters/Webservice/webservice_settings.html.twig') }} - - {% block webservice_configuration_form_rest %} - {{ form_rest(form) }} - {% endblock %} - - {{ form_end(form) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/webservice_settings.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/webservice_settings.html.twig deleted file mode 100644 index f4ba3e10..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/Webservice/webservice_settings.html.twig +++ /dev/null @@ -1,79 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% set webserviceConfigurationForm = form.webservice_configuration %} - -{% block webservice_form_configuration %} -
    -

    - settings {{ 'Configuration'|trans({}, 'Admin.Global') }} -

    - -
    -
    -
    - - -
    - {{ form_errors(webserviceConfigurationForm.enable_webservice) }} - {{ form_widget(webserviceConfigurationForm.enable_webservice) }} - - - {{ 'Before activating the webservice, you must be sure to: '|trans({}, 'Admin.Advparameters.Help') }} -
    - 1. {{ 'Check that URL rewriting is available on this server.'|trans({}, 'Admin.Advparameters.Help') }} -
    - 2. {{ 'Check that the five methods GET, POST, PUT, DELETE and HEAD are supported by this server.'|trans({}, 'Admin.Advparameters.Help') }} -
    -
    -
    - -
    - - -
    - {{ form_errors(webserviceConfigurationForm.enable_cgi) }} - {{ form_widget(webserviceConfigurationForm.enable_cgi) }} - - - {{ 'Before choosing "Yes", check that PHP is not configured as an Apache module on your server.'|trans({}, 'Admin.Advparameters.Help') }} - -
    -
    - - {% block webservice_configuration_form_rest %} - {{ form_rest(webserviceConfigurationForm) }} - {% endblock %} -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/administration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/administration.html.twig deleted file mode 100644 index ab0f3d10..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/administration.html.twig +++ /dev/null @@ -1,172 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set generalForm, uploadQuotaForm, notificationsForm = form.general, form.upload_quota, form.notifications %} - -{% block content %} - {{ form_start(form, {'attr' : {'class': 'form'} }) }} -
    - {% block administration_form_general %} -
    -
    -

    - settings {{ 'General'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - {{ ps.label_with_help(('Automatically check for module updates'|trans), ('New modules and updates are displayed on the modules page.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(generalForm.check_modules_update) }} - {{ form_widget(generalForm.check_modules_update, {'attr' : {'class': 'custom-select'} }) }} -
    -
    -
    - {{ ps.label_with_help(("Check the cookie's IP address"|trans), ('Check the IP address of the cookie in order to prevent your cookie from being stolen.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(generalForm.check_ip_address) }} - {{ form_widget(generalForm.check_ip_address, {'attr' : {'class': 'custom-select'} }) }} -
    -
    -
    - {{ ps.label_with_help(('Lifetime of front office cookies'|trans), ('Set the amount of hours during which the front office cookies are valid. After that amount of time, the customer will have to log in again.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(generalForm.front_cookie_lifetime) }} - {{ form_widget(generalForm.front_cookie_lifetime) }} -
    -
    -
    - {{ ps.label_with_help(('Lifetime of back office cookies'|trans), ('When you access your back office and decide to stay logged in, your cookies lifetime defines your browser session. Set here the number of hours during which you want them valid before logging in again.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(generalForm.back_cookie_lifetime) }} - {{ form_widget(generalForm.back_cookie_lifetime) }} -
    -
    - {{ form_rest(generalForm) }} -
    -
    - -
    -
    - {% endblock %} - - {% block administration_form_upload_quota %} -
    -
    -

    - file_upload {{ 'Upload quota'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Maximum size for attached files'|trans), ('Set the maximum size allowed for attachment files (in megabytes). This value has to be lower or equal to the maximum file upload allotted by your server (currently: %size% MB).'|trans({'%size%': 'PS_ATTACHMENT_MAXIMUM_SIZE'|configuration}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(uploadQuotaForm.max_size_attached_files) }} - {{ form_widget(uploadQuotaForm.max_size_attached_files) }} -
    -
    -
    - {{ ps.label_with_help(('Maximum size for a downloadable product'|trans), ('Define the upload limit for a downloadable product (in megabytes). This value has to be lower or equal to the maximum file upload allotted by your server (currently: %size% MB).'|trans({'%size%': 'PS_LIMIT_UPLOAD_FILE_VALUE'|configuration}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(uploadQuotaForm.max_size_downloadable_product) }} - {{ form_widget(uploadQuotaForm.max_size_downloadable_product) }} -
    -
    -
    - {{ ps.label_with_help(("Maximum size for a product's image"|trans), ('Define the upload limit for an image (in megabytes). This value has to be lower or equal to the maximum file upload allotted by your server (currently: %size% MB).'|trans({'%size%': 'PS_LIMIT_UPLOAD_IMAGE_VALUE'|configuration}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(uploadQuotaForm.max_size_product_image) }} - {{ form_widget(uploadQuotaForm.max_size_product_image) }} -
    -
    - {{ form_rest(uploadQuotaForm) }} -
    -
    - -
    -
    - {% endblock %} - - {% block administration_form_notifications %} -
    -
    -

    - priority_high {{ 'Notifications'|trans }} -

    -
    -
    - -
    -
    - {{ ps.infotip("Notifications are numbered bubbles displayed at the very top of your back office, right next to the shop's name. They display the number of new items since you last clicked on them."|trans({}, 'Admin.Advparameters.Help')) }} -
    -
    - -
    - {{ ps.label_with_help(('Show notifications for new orders'|trans), ("This will display notifications when new orders are made in your shop."|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(notificationsForm.show_notifs_new_orders) }} - {{ form_widget(notificationsForm.show_notifs_new_orders, {'attr' : {'class': 'custom-select'} }) }} -
    -
    -
    - {{ ps.label_with_help(('Show notifications for new customers'|trans), ('This will display notifications every time a new customer registers in your shop.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(notificationsForm.show_notifs_new_customers) }} - {{ form_widget(notificationsForm.show_notifs_new_customers, {'attr' : {'class': 'custom-select'} }) }} -
    -
    -
    - {{ ps.label_with_help(('Show notifications for new messages'|trans), ('This will display notifications when new messages are posted in your shop.'|trans({}, 'Admin.Advparameters.Help'))) }} -
    - {{ form_errors(notificationsForm.show_notifs_new_messages) }} - {{ form_widget(notificationsForm.show_notifs_new_messages, {'attr' : {'class': 'custom-select'} }) }} -
    -
    - {{ form_rest(notificationsForm) }} -
    -
    - -
    -
    - {% endblock %} -
    - {{ form_end(form) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/memcache_servers.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/memcache_servers.html.twig deleted file mode 100644 index f0dd4f5e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/memcache_servers.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% block perfs_memcache_servers %} - - -
    - {{ form_widget(form) }} - -
    -
    - - -
    -
    -
    - -
    -
    - - - - - - - - - - - - {% for server in servers %} - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'IP Address'|trans }}{{ 'Port'|trans }}{{ 'Weight'|trans }} 
    {{ server.id_memcached_server }}{{ server.ip }}{{ server.port }}{{ server.weight }} - {% set removeMsg = 'Do you really want to remove the server %serverIp%:%serverPort% ?'|trans({'%serverIp%': server.ip, '%serverPort%': server.port}, 'Admin.Advparameters.Notification')|json_encode|raw %} - remove_circle {{ 'Remove'|trans({}, 'Admin.Actions') }} -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/performance.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/performance.html.twig deleted file mode 100644 index 7b5dd8f4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/performance.html.twig +++ /dev/null @@ -1,226 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} -{% form_theme form 'PrestaShopBundle:Admin/TwigTemplateForm:prestashop_ui_kit.html.twig' %} - -{% - set smartyForm, debugModeForm, optionalFeaturesForm, combineCompressCacheForm, mediaServersForm, cachingForm, memcacheForm = - form.smarty, form.debug_mode, form.optional_features, form.ccc, form.media_servers, form.caching, form.add_memcache_server -%} - -{% block content %} - {{ form_start(form, {'attr' : {'class': 'form'} }) }} -
    - {% block perfs_form_smarty_cache %} -
    -
    -

    - business_center {{ 'Smarty'|trans }} -

    -
    -
    - {% block perfs_form_smarty_cache_form %} - {{ form_widget(smartyForm) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - - {% block perfs_form_debug_mode %} -
    -
    -

    - bug_report {{ 'Debug mode'|trans }} -

    -
    -
    - {% block perfs_form_debug_mode_form %} - {{ form_widget(debugModeForm) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - - {% block perfs_form_optional_features %} -
    -
    -

    - extension {{ 'Optional features'|trans }} -

    -
    -
    - -
    -
    - {{ ps.infotip('Some features can be disabled in order to improve performance.'|trans({}, 'Admin.Advparameters.Help')) }} -
    -
    - - {% block perfs_form_optional_features_form %} - {{ form_widget(optionalFeaturesForm) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - - {% block perfs_form_ccc %} -
    -
    -

    - zoom_out_map {{ 'CCC (Combine, Compress and Cache)'|trans }} -

    -
    -
    -
    -
    - {{ ps.infotip('CCC allows you to reduce the loading time of your page. With these settings you will gain performance without even touching the code of your theme. Make sure, however, that your theme is compatible with PrestaShop 1.4+. Otherwise, CCC will cause problems.'|trans({}, 'Admin.Advparameters.Help')) }} -
    -
    - - {% block perfs_form_ccc_form %} - {{ form_widget(combineCompressCacheForm) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - - {% block perfs_form_media_servers %} -
    -
    -

    - link {{ 'Media servers (use only with CCC)'|trans }} -

    -
    -
    -
    -
    - {{ ps.infotip('You must enter another domain, or subdomain, in order to use cookieless static content.'|trans({}, 'Admin.Advparameters.Feature')) }} -
    -
    - - {% block perfs_form_media_servers_form %} - {{ form_widget(mediaServersForm) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - - {% block perfs_form_caching %} -
    -
    -

    - link {{ 'Caching'|trans }} -

    -
    -
    - {% block perfs_form_caching_form %} - {{ form_widget(cachingForm) }} - {% endblock %} - - {{ include('@AdvancedParameters/memcache_servers.html.twig', {'form': memcacheForm}) }} -
    -
    - -
    -
    - {% endblock %} -
    - {{ form_end(form) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/system_information.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/system_information.html.twig deleted file mode 100644 index 9ab24d08..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/AdvancedParameters/system_information.html.twig +++ /dev/null @@ -1,287 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Advparameters.Feature" %} - -{% block content %} -
    -
    -
    -

    - info_outline {{ 'Configuration information'|trans }} -

    -
    -
    -

    {{ 'This information must be provided when you report an issue on our bug tracker or forum.'|trans }}

    -
    -
    -
    - {% if system.notHostMode %} -
    -

    - info_outline {{ 'Server information'|trans }} -

    -
    -
    - {% if system.uname is not empty %} -

    - {{ 'Server information'|trans }} {{ system.uname }} -

    - {% endif %} -

    - {{ 'Server software version:'|trans }} {{ system.server.version }} -

    -

    - {{ 'PHP version:'|trans }} {{ system.server.php.version }} -

    -

    - {{ 'Memory limit:'|trans }} {{ system.server.php.memoryLimit }} -

    -

    - {{ 'Max execution time:'|trans }} {{ system.server.php.maxExecutionTime }} -

    -

    - {{ 'Upload Max File size:'|trans }} {{ system.server.php.maxFileSizeUpload }} -

    - {% if system.instaWebInstalled %} -

    {{ 'PageSpeed module for Apache installed (mod_instaweb)'|trans }}

    - {% endif %} -
    -
    -
    - -
    -

    - info_outline {{ 'Database information'|trans({}, 'Admin.Advparameters.Feature') }} -

    -
    -
    -

    - {{ 'MySQL version:'|trans }} {{ system.database.version }} -

    -

    - {{ 'MySQL server:'|trans }} {{ system.database.server }} -

    -

    - {{ 'MySQL name:'|trans }} {{ system.database.name }} -

    -

    - {{ 'MySQL user:'|trans }} {{ system.database.user }} -

    -

    - {{ 'Tables prefix:'|trans }} {{ system.database.prefix }} -

    -

    - {{ 'MySQL engine:'|trans }} {{ system.database.engine }} -

    -

    - {{ 'MySQL driver:'|trans }} {{ system.database.driver }} -

    -
    -
    -
    -
    - {% endif %} -
    -
    -

    - info_outline {{ 'Store information'|trans }} -

    -
    -
    -

    - {{ 'PrestaShop version:'|trans }} {{ system.shop.version }} -

    -

    - {{ 'Shop URL:'|trans }} {{ system.shop.url }} -

    -

    - {{ 'Shop path:'|trans }} {{ system.shop.path }} -

    -

    - {{ 'Current theme in use:'|trans }} {{ system.shop.theme }} -

    -
    -
    -
    - -
    -

    - info_outline {{ 'Mail configuration'|trans }} -

    -
    -
    -

    - {{ 'Mail method:'|trans }} - - {% if system.isNativePHPmail %} - {{ 'You are using /usr/sbin/sendmail'|trans }} - {% else %} - {{ 'You are using your own SMTP parameters.'|trans }}

    -

    - {{ 'SMTP server:'|trans }} {{ system.smtp.server }} -

    -

    - {{ 'SMTP username:'|trans }} - {% if system.smtp.user is not empty %} - {{ 'Defined'|trans }} - {% else %} - {{ 'Not defined'|trans }} - {% endif %} -

    -

    - {{ 'SMTP password:'|trans }} - {% if system.smtp.password is not empty %} - {{ 'Defined'|trans }} - {% else %} - {{ 'Not defined'|trans }} - {% endif %} -

    -

    - {{ 'Encryption:'|trans }} {{ system.smtp.encryption }} -

    -

    - {{ 'SMTP port:'|trans }} {{ system.smtp.port }} -

    - {% endif %} -
    -
    -
    - -
    -

    - info_outline {{ 'Your information'|trans }} -

    -
    -
    -

    - {{ 'Your web browser:'|trans }} {{ userAgent }} -

    -
    -
    -
    - -
    -

    - info_outline {{ 'Check your configuration'|trans }} -

    -
    -
    -

    - {{ 'Required parameters:'|trans }} - {% if requirements.failRequired == false %} - {{ 'OK'|trans({}, 'Admin.Advparameters.Notification') }} -

    - {% else %} - {{ 'Please fix the following error(s)'|trans({}, 'Admin.Advparameters.Notification') }} -

    -
      - {% for key, value in requirements.testsRequired %} - {% if 'fail' == value %} -
    • {{ requirements.testsErrors[key] }}
    • - {% endif %} - {% endfor %} -
    - {% endif %} - {% if requirements.failOptional is defined %} -

    - {{ 'Optional parameters:'|trans }} - {% if requirements.failOptional == false %} - {{ 'OK'|trans({}, 'Admin.Advparameters.Notification') }} -

    - {% else %} - {{ 'Please fix the following error(s)'|trans({}, 'Admin.Advparameters.Notification') }} -

    -
      - {% for key, value in requirements.testsOptional %} - {% if 'fail' == value %} -
    • {{ requirements.testsErrors[key] }}
    • - {% endif %} - {% endfor %} -
    - {% endif %} - {% endif %} -
    -
    -
    -
    -
    -{% if system.notHostMode %} -
    -

    - info_outline {{ 'List of changed files'|trans }} -

    -
    -
    - loop {{ 'Checking files...'|trans({}, 'Admin.Advparameters.Notification') }} -
    -
    -
    -{% endif %} -{% if system.notHostMode %} - -{% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/customer_preferences_general.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/customer_preferences_general.html.twig deleted file mode 100644 index 87821792..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/customer_preferences_general.html.twig +++ /dev/null @@ -1,92 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block customer_preferences_general %} -
    -
    -

    - settings {{ 'General'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - {{ ps.label_with_help(('Re-display cart at login'|trans), ('After a customer logs in, you can recall and display the content of his/her last shopping cart.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.redisplay_cart_at_login) }} - {{ form_widget(generalForm.redisplay_cart_at_login) }} -
    -
    -
    - {{ ps.label_with_help(('Send an email after registration'|trans), ('Send an email with summary of the account information (email, password) after registration.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.send_email_after_registration) }} - {{ form_widget(generalForm.send_email_after_registration) }} -
    -
    -
    - {{ ps.label_with_help(('Password reset delay'|trans), ('Minimum time required between two requests for a password reset.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.password_reset_delay) }} - {{ form_widget(generalForm.password_reset_delay) }} -
    -
    -
    - {{ ps.label_with_help(('Enable B2B mode'|trans), ('Activate or deactivate B2B mode. When this option is enabled, B2B features will be made available.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.enable_b2b_mode) }} - {{ form_widget(generalForm.enable_b2b_mode) }} -
    -
    -
    - {{ ps.label_with_help(('Ask for birth date'|trans), ('Display or not the birth date field.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.ask_for_birthday) }} - {{ form_widget(generalForm.ask_for_birthday) }} -
    -
    -
    - {{ ps.label_with_help(('Enable partner offers'|trans), ('Display or not the partner offers tick box, to receive offers from the store\'s partners.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.enable_offers) }} - {{ form_widget(generalForm.enable_offers) }} -
    -
    - - {% block customer_general_preferences_form_rest %} - {{ form_rest(generalForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_general.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_general.html.twig deleted file mode 100644 index 28046504..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_general.html.twig +++ /dev/null @@ -1,102 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block product_preferences_general %} -
    -
    -

    - settings {{ 'Products (general)'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Catalog mode'|trans), ('Catalog mode disables the shopping cart on your store. Visitors will be able to browse your products catalog, but not buy them.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.catalog_mode) }} - {{ form_widget(generalForm.catalog_mode) }} - {{ 'Have specific needs? Edit particular groups to let them see prices or not.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - {{ ps.label_with_help(('Show prices'|trans), ('Display product prices when in catalog mode.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.catalog_mode_with_prices) }} - {{ form_widget(generalForm.catalog_mode_with_prices) }} -
    -
    -
    - -
    - {{ form_errors(generalForm.new_days_number) }} - {{ form_widget(generalForm.new_days_number) }} -
    -
    -
    - {{ ps.label_with_help(('Max size of product summary'|trans), ('Set the maximum size of the summary of your product description (in characters).'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.short_description_limit) }} - {{ form_widget(generalForm.short_description_limit) }} -
    -
    -
    - {{ ps.label_with_help(('Quantity discounts based on'|trans), ('How to calculate quantity discounts.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.quantity_discount) }} - {{ form_widget(generalForm.quantity_discount) }} -
    -
    -
    - {{ ps.label_with_help(('Force update of friendly URL'|trans), ('When active, friendly URL will be updated on every save.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.force_friendly_url) }} - {{ form_widget(generalForm.force_friendly_url) }} -
    -
    -
    - {{ ps.label_with_help(('Default activation status'|trans), ('When active, new products will be activated by default during creation.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.default_status) }} - {{ form_widget(generalForm.default_status) }} -
    -
    - - {% block product_general_preferences_form_rest %} - {{ form_rest(generalForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_page.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_page.html.twig deleted file mode 100644 index 6a69007f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_page.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block product_preferences_page %} -
    -
    -

    - shopping_basket {{ 'Product page'|trans }} -

    -
    -
    -
    - -
    - {{ form_errors(pageForm.display_quantities) }} - {{ form_widget(pageForm.display_quantities) }} -
    -
    -
    - {{ ps.label_with_help(('Display remaining quantities when the quantity is lower than'|trans), ('Set to "0" to disable this feature.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(pageForm.display_last_quantities) }} - {{ form_widget(pageForm.display_last_quantities) }} -
    -
    -
    - -
    - {{ form_errors(pageForm.display_unavailable_attributes) }} - {{ form_widget(pageForm.display_unavailable_attributes) }} -
    -
    -
    - {{ ps.label_with_help(('Display the "%add_to_cart_label%" button when a product has attributes'|trans({'%add_to_cart_label%': 'Add to cart'|trans({}, 'Shop.Theme.Actions')}, 'Admin.Shopparameters.Help')), ('Display or hide the "%add_to_cart_label%" button on category pages for products that have attributes forcing customers to see product details.'|trans({'%add_to_cart_label%': 'Add to cart'|trans({}, 'Shop.Theme.Actions')}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(pageForm.allow_add_variant_to_cart_from_listing) }} - {{ form_widget(pageForm.allow_add_variant_to_cart_from_listing) }} -
    -
    -
    - -
    - {{ form_errors(pageForm.attribute_anchor_separator) }} - {{ form_widget(pageForm.attribute_anchor_separator) }} -
    -
    -
    - -
    - {{ form_errors(pageForm.display_discount_price) }} - {{ form_widget(pageForm.display_discount_price) }} - {{ 'In the volume discounts board, display the new price with the applied discount instead of showing the discount (ie. "-5%").'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - - {% block product_page_preferences_form_rest %} - {{ form_rest(pageForm) }} - {% endblock %} -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_pagination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_pagination.html.twig deleted file mode 100644 index f88995b8..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_pagination.html.twig +++ /dev/null @@ -1,71 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block product_preferences_pagination %} -
    -
    -

    - view_headline {{ 'Pagination'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Products per page'|trans), ('Number of products displayed per page. Default is 10.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(paginationForm.products_per_page) }} - {{ form_widget(paginationForm.products_per_page) }} -
    -
    -
    - {{ ps.label_with_help(('Default order by'|trans), ('The order in which products are displayed in the product list.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(paginationForm.default_order_by) }} - {{ form_widget(paginationForm.default_order_by) }} -
    -
    -
    - {{ ps.label_with_help(('Default order method'|trans), ('Default order method for product list.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(paginationForm.default_order_way) }} - {{ form_widget(paginationForm.default_order_way) }} -
    -
    - - {% block product_pagination_preferences_form_rest %} - {{ form_rest(paginationForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_stock.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_stock.html.twig deleted file mode 100644 index c15895b7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Blocks/product_preferences_stock.html.twig +++ /dev/null @@ -1,116 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block product_preferences_stock %} -
    -
    -

    - shop {{ 'Products stock'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Allow ordering of out-of-stock products'|trans), ('By default, the "%add_to_cart_label%" button is hidden when a product is unavailable. You can choose to have it displayed in all cases.'|trans({'%add_to_cart_label%': 'Add to cart'|trans({}, 'Shop.Theme.Actions')}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(stockForm.allow_ordering_oos) }} - {{ form_widget(stockForm.allow_ordering_oos) }} -
    -
    -
    - -
    - {{ form_errors(stockForm.stock_management) }} - {{ form_widget(stockForm.stock_management) }} -
    -
    -
    - -
    - {{ form_errors(stockForm.stock_management) }} - {{ form_widget(stockForm.in_stock_label) }} -
    -
    -
    - -
    - {{ form_errors(stockForm.oos_allowed_backorders) }} - {{ form_widget(stockForm.oos_allowed_backorders) }} -
    -
    -
    - -
    - {{ form_errors(stockForm.oos_denied_backorders) }} - {{ form_widget(stockForm.oos_denied_backorders) }} -
    -
    -
    - {{ ps.label_with_help(('Delivery time of in-stock products'|trans), ('Advised for European merchants to be legally compliant (eg: Delivered within 3-4 days)'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(stockForm.delivery_time) }} - {{ form_widget(stockForm.delivery_time) }} - {{ 'Leave empty to disable'|trans }} -
    -
    -
    - {{ ps.label_with_help(('Delivery time of out-of-stock products with allowed backorders'|trans), ('Advised for European merchants to be legally compliant (eg: Delivered within 5-7 days)'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(stockForm.oos_delivery_time) }} - {{ form_widget(stockForm.oos_delivery_time) }} - {{ 'Leave empty to disable'|trans }} -
    -
    -
    - {{ ps.label_with_help(('Default pack stock management'|trans), ('When selling packs of products, how do you want your stock to be calculated?'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(stockForm.pack_stock_management) }} - {{ form_widget(stockForm.pack_stock_management) }} -
    -
    - - {% block product_stock_preferences_form_rest %} - {{ form_rest(stockForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig deleted file mode 100644 index f42d1248..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig +++ /dev/null @@ -1,79 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block contact_form %} - {{ form_start(contactForm) }} -
    -

    - mail_outline - {{ 'Contacts'|trans({}, 'Admin.Shopparameters.Feature') }} -

    -
    -
    - {{ form_errors(contactForm) }} - - {{ ps.form_group_row(contactForm.title, {}, { - 'label': 'Title'|trans({}, 'Admin.Global'), - 'help': 'Contact name (e.g. Customer Support).'|trans({}, 'Admin.Shopparameters.Help') - }) }} - - {{ ps.form_group_row(contactForm.email, {}, { - 'label': 'Email address'|trans({}, 'Admin.Global'), - 'help': 'Emails will be sent to this address.'|trans({}, 'Admin.Shopparameters.Help') - }) }} - - {{ ps.form_group_row(contactForm.is_messages_saving_enabled, {}, { - 'label': 'Save messages?'|trans({}, 'Admin.Shopparameters.Feature'), - 'help': 'If enabled, all messages will be saved in the "Customer Service" page under the "Customer" menu.'|trans({}, 'Admin.Shopparameters.Help') - }) }} - - {{ ps.form_group_row(contactForm.description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global') - }) }} - - {% if contactForm.shop_association is defined %} - {{ ps.form_group_row(contactForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block contact_form_rest %} - {{ form_rest(contactForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(contactForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/create.html.twig deleted file mode 100644 index 7161dd90..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/create.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/edit.html.twig deleted file mode 100644 index 7161dd90..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/ShopParameters/Contact/Contacts/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/index.html.twig deleted file mode 100644 index 55253f40..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/Contact/Contacts/index.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% block contacts_list_panel %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': contactGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_general.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_general.html.twig deleted file mode 100644 index a7747a16..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_general.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block order_preferences_general %} -
    -
    -

    - settings {{ 'General'|trans({}, 'Admin.Global') }} -

    -
    -
    - {% block order_general_preferences_form_rest %} - {{ form_rest(generalForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_gift_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_gift_options.html.twig deleted file mode 100644 index 38bfaaf6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_gift_options.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block order_preferences_gift_options %} -
    -
    -

    - cake {{ 'Gift options'|trans({}, 'Admin.Shopparameters.Feature') }} -

    -
    -
    - {% block order_gift_options_preferences_form_rest %} - {{ form_rest(giftOptionsForm) }} - {% endblock %} -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/order_preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/order_preferences.html.twig deleted file mode 100644 index 6a367325..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/OrderPreferences/order_preferences.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% set generalForm, giftOptionsForm = form.general, form.gift_options %} - -{% block content %} - {{ form_start(form, {'attr': {'class': 'form', 'id': 'configuration_form'}}) }} -
    - {# General options block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_general.html.twig' %} - - {# Gift options block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/OrderPreferences/Blocks/order_preferences_gift_options.html.twig' %} -
    - {{ form_end(form) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/domain_name_management.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/domain_name_management.html.twig deleted file mode 100644 index ac3ca040..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/domain_name_management.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% block domain_name_management %} -{% if isHostMode %} -
    -

    - settings {{ 'Manage domain name'|trans }} -

    -
    -
    -
    -
    - -
    -
    -
    -
    - - - -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig deleted file mode 100644 index 619a2aa0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig +++ /dev/null @@ -1,105 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(metaForm) }} -
    -
    - {{ 'Meta tags'|trans({}, 'Admin.Shopparameters.Feature') }} -
    -
    -
    - {{ form_errors(metaForm) }} - - {{ ps.form_group_row(metaForm.page_name, { - 'attr': { - 'class': 'js-meta-page-name', - 'data-toggle': 'select2', - 'data-minimumResultsForSearch': '7' - } - }, { - 'label': 'Page name'|trans({}, 'Admin.Shopparameters.Feature'), - 'help': 'Name of the related page.'|trans({}, 'Admin.Shopparameters.Help') - }) }} - - {% set pageTitleHelpLabel %} - {{ 'Title of this page.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'Invalid characters:'|trans({}, 'Admin.Shopparameters.Help') ~ ' <>={}'}} - {% endset %} - - {{ ps.form_group_row(metaForm.page_title, {}, { - 'label': 'Page title'|trans({}, 'Admin.Shopparameters.Feature'), - 'help': pageTitleHelpLabel - }) }} - - {% set metaDescriptionHelpLabel %} - {{ 'A short description of your shop.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'Invalid characters:'|trans({}, 'Admin.Shopparameters.Help') ~ ' <>={}' }} - {% endset %} - - {{ ps.form_group_row(metaForm.meta_description, {}, { - 'label': 'Meta description'|trans({}, 'Admin.Global'), - 'help': metaDescriptionHelpLabel - }) }} - - {% set metaKeywordsHelpLabel %} - {{ 'List of keywords for search engines.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'To add tags, click in the field, write something, and then press the "Enter" key.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'Invalid characters:'|trans({}, 'Admin.Shopparameters.Help') ~ ' <>={}' }} - {% endset %} - - {{ ps.form_group_row(metaForm.meta_keywords, {}, { - 'label': 'Meta keywords'|trans({}, 'Admin.Global'), - 'help': metaKeywordsHelpLabel - }) }} - - {% set rewriteUrlHelpLabel %} - {{ 'For instance, "contacts" for http://example.com/shop/contacts to redirect to http://example.com/shop/contact-form.php'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'Only letters and hyphens are allowed.'|trans({}, 'Admin.Shopparameters.Help') }} - {% endset %} - - {{ ps.form_group_row(metaForm.url_rewrite, {'attr': {'class': 'js-url-rewrite'}}, { - 'label': 'Rewritten URL'|trans({}, 'Admin.Shopparameters.Feature'), - 'help': rewriteUrlHelpLabel - }) }} - - {% block meta_form_rest %} - {{ form_rest(metaForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(metaForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig deleted file mode 100644 index 4b2b04d9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block keyword %} - {% if routeKeywords[idRoute] is defined%} - {% set formattedKeywords = [] %} - {% for keyword, value in routeKeywords[idRoute] %} - {% set formattedKeyword %} - {{ keyword }}{% if value['param'] is defined %}*{% endif %} - {% endset %} - - {% set formattedKeywords = formattedKeywords|merge([formattedKeyword]) %} - {% endfor %} - - {{ 'Keywords: %keywords%'|trans({'%keywords%': formattedKeywords|join(', ')}, 'Admin.Shopparameters.Feature') }} - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/meta_showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/meta_showcase_card.html.twig deleted file mode 100644 index d3f80004..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/meta_showcase_card.html.twig +++ /dev/null @@ -1,45 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% block meta_showcase_card %} - {% if not showcaseCardIsClosed %} -
    -
    - -
    -
    -

    {{ 'Improve your SEO'|trans }}

    -

    {{ 'Edit information about your pages to gain visibility and therefore reach more visitors. We advise you to start with the index page, it stands for your homepage.'|trans }}

    - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - {% if indexPageId and isGridDisplayed %} - {{ 'Configure index page'|trans }} - {% endif %} -
    - close -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/robots_file_generation.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/robots_file_generation.html.twig deleted file mode 100644 index 01a844f1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/robots_file_generation.html.twig +++ /dev/null @@ -1,65 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% block keyword %} -
    -

    - settings {{ 'Robots file generation'|trans }} -

    - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/seo_options_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/seo_options_configuration.html.twig deleted file mode 100644 index 936e7534..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/seo_options_configuration.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block seo_options_configuration %} -
    -

    - settings {{ 'SEO options'|trans }} -

    -
    -
    - -
    - {{ ps.label_with_help(('Display attributes in the product meta title'|trans), ('Enable this option if you want to display your product\'s attributes in its meta title.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(metaForm.seo_options.product_attributes_in_title) }} - {{ form_widget(metaForm.seo_options.product_attributes_in_title) }} -
    -
    - - {% block meta_form_rest %} - {{ form_rest(metaForm.seo_options) }} - {% endblock %} -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/set_up_urls_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/set_up_urls_configuration.html.twig deleted file mode 100644 index 990b6f21..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/set_up_urls_configuration.html.twig +++ /dev/null @@ -1,116 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block set_up_urls_configuration %} -
    -

    - settings {{ 'Set up URLs'|trans }} -

    -
    -
    - - {% if not isHtaccessFileValid %} -
    -
    - -
    -
    - {% endif %} - -
    - {% if isModRewriteActive %} - {{ ps.label_with_help('Friendly URL'|trans({}, 'Admin.Global'), ('Enable this option only if your server allows URL rewriting (recommended).'|trans({}, 'Admin.Shopparameters.Help'))) }} - {% endif %} -
    - {{ form_errors(metaForm.set_up_urls.friendly_url) }} - {{ form_widget(metaForm.set_up_urls.friendly_url) }} - - {% if not isModRewriteActive %} - - {{ 'URL rewriting (mod_rewrite) is not active on your server, or it is not possible to check your server configuration. If you want to use Friendly URLs, you must activate this mod.'|trans({}, 'Admin.Shopparameters.Help') }} - - {% endif %} -
    -
    - -
    - {{ ps.label_with_help(('Accented URL'|trans), ('Enable this option if you want to allow accented characters in your friendly URLs.'|trans({}, 'Admin.Shopparameters.Help') ~ ' ' ~ 'You should only activate this option if you are using non-latin characters ; for all the latin charsets, your SEO will be better without this option.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(metaForm.set_up_urls.accented_url) }} - {{ form_widget(metaForm.set_up_urls.accented_url) }} -
    -
    - -
    - -
    - {{ form_errors(metaForm.set_up_urls.canonical_url_redirection) }} - {{ form_widget(metaForm.set_up_urls.canonical_url_redirection) }} -
    -
    - - {% if metaForm.set_up_urls.disable_apache_multiview is defined %} -
    - {{ ps.label_with_help(("Disable Apache's MultiViews option"|trans), ('Enable this option only if you have problems with URL rewriting.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(metaForm.set_up_urls.disable_apache_multiview) }} - {{ form_widget(metaForm.set_up_urls.disable_apache_multiview) }} -
    -
    - {% endif %} - - {% if metaForm.set_up_urls.disable_apache_mod_security is defined %} -
    - {{ ps.label_with_help(("Disable Apache's mod_security module"|trans), ("Some of PrestaShop's features might not work correctly with a specific configuration of Apache's mod_security module. We recommend to turn it off."|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(metaForm.set_up_urls.disable_apache_mod_security) }} - {{ form_widget(metaForm.set_up_urls.disable_apache_mod_security) }} -
    -
    - {% endif %} - - {% block meta_form_rest %} - {{ form_rest(metaForm.set_up_urls) }} - {% endblock %} -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/shop_urls_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/shop_urls_configuration.html.twig deleted file mode 100644 index 4863a5f1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/shop_urls_configuration.html.twig +++ /dev/null @@ -1,115 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% set shopUrlForm = metaForm.shop_urls %} - -{% block shop_urls_configuration %} - - {% set cardHeaderLabel = 'Set shop URL'|trans %} - {% if isShopFeatureActive and not isHostMode %} -
    -
    - settings {{ cardHeaderLabel }} -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - {% endif %} - - {% if shopUrlForm.children is not empty %} -
    -

    - settings {{ cardHeaderLabel }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(shopUrlForm.domain) }} - {{ form_widget(shopUrlForm.domain) }} -
    -
    - -
    - -
    - {{ form_errors(shopUrlForm.domain_ssl) }} - {{ form_widget(shopUrlForm.domain_ssl) }} -
    -
    - -
    - -
    - {{ form_errors(shopUrlForm.physical_uri) }} - {{ form_widget(shopUrlForm.physical_uri, {'required': false}) }} -
    -
    - - {% block meta_form_rest %} - {{ form_rest(shopUrlForm) }} - {% endblock %} -
    -
    - - -
    - {% endif %} -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/url_schema_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/url_schema_configuration.html.twig deleted file mode 100644 index 70f3c6ce..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/url_schema_configuration.html.twig +++ /dev/null @@ -1,165 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% set urlSchemaForm = metaForm.url_schema %} - -{% block url_schema_configuration %} - {% if urlSchemaForm.children is not empty %} -
    -

    - settings {{ 'Schema of URLs'|trans }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.product_rule) }} - {{ form_widget(urlSchemaForm.product_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'product_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.category_rule) }} - {{ form_widget(urlSchemaForm.category_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'category_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.layered_rule) }} - {{ form_widget(urlSchemaForm.layered_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'layered_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.supplier_rule) }} - {{ form_widget(urlSchemaForm.supplier_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'supplier_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.manufacturer_rule) }} - {{ form_widget(urlSchemaForm.manufacturer_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'manufacturer_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.cms_rule) }} - {{ form_widget(urlSchemaForm.cms_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'cms_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.cms_category_rule) }} - {{ form_widget(urlSchemaForm.cms_category_rule) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'cms_category_rule'}) }} - -
    -
    - -
    - -
    - {{ form_errors(urlSchemaForm.module) }} - {{ form_widget(urlSchemaForm.module) }} - - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/keyword.html.twig', {'idRoute': 'module'}) }} - -
    -
    - -
    -
    - -
    - {% else %} - {% do urlSchemaForm.setRendered %} - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/create.html.twig deleted file mode 100644 index 5085b95d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/create.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig', {'metaForm': meta_form}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/edit.html.twig deleted file mode 100644 index 5085b95d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/edit.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/form.html.twig', {'metaForm': meta_form}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/index.html.twig deleted file mode 100644 index 691f67a5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/TrafficSeo/Meta/index.html.twig +++ /dev/null @@ -1,81 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/meta_showcase_card.html.twig' %} -
    -
    - {% if not isGridDisplayed %} -
    -
    - -
    -
    - {% else %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': grid} %} -
    -
    - {% endif %} - -
    -
    - {{ form_start(metaForm, {'action': path('admin_metas_save_options')}) }} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/set_up_urls_configuration.html.twig' %} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/shop_urls_configuration.html.twig' %} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/domain_name_management.html.twig' %} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/url_schema_configuration.html.twig' %} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/seo_options_configuration.html.twig' %} - - {% block meta_form_rest %} - {{ form_rest(metaForm) }} - {% endblock %} - - {{ form_end(metaForm) }} - - {{ form_start(robotsForm, {'action': path('admin_metas_generate_robots_text_file')}) }} - {% include '@PrestaShop/Admin/Configure/ShopParameters/TrafficSeo/Meta/Blocks/robots_file_generation.html.twig' %} - {{ form_rest(robotsForm) }} - {{ form_end(robotsForm) }} -
    -
    - -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/customer_preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/customer_preferences.html.twig deleted file mode 100644 index 0609545a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/customer_preferences.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% set generalForm = form.general %} - -{% block content %} - {{ form_start(form, {'attr': {'class': 'form', 'id': 'configuration_form'}}) }} -
    - {% include '@PrestaShop/Admin/Configure/ShopParameters/Blocks/customer_preferences_general.html.twig' %} -
    - {{ form_end(form) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/maintenance.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/maintenance.html.twig deleted file mode 100644 index 4e59f8c4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/maintenance.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set generalForm = form.general %} - -{% block content %} - {{ form_start(form, {'attr' : {'class': 'form'} }) }} -
    - {% block maintenance_form_general %} -
    -
    -

    - business_center {{ 'General'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - {{ ps.label_with_help(('Enable Shop'|trans), ('Activate or deactivate your shop (It is a good idea to deactivate your shop while you perform maintenance. Please note that the webservice will not be disabled).'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.enable_shop) }} - {{ form_widget(generalForm.enable_shop) }} -
    -
    -
    - {{ ps.label_with_help(('Maintenance IP'|trans), ('IP addresses allowed to access the front office even if the shop is disabled. Please use a comma to separate them (e.g. 42.24.4.2,127.0.0.1,99.98.97.96)'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.maintenance_ip) }} - {{ form_widget(generalForm.maintenance_ip, { 'currentIp': currentIp}) }} -
    -
    -
    - {{ ps.label_with_help(('Custom maintenance text'|trans), ('Custom text displayed on maintenance page while shop is deactivated.'|trans({}, 'Admin.Shopparameters.Help'))) }} -
    - {{ form_errors(generalForm.maintenance_text) }} - {{ form_widget(generalForm.maintenance_text) }} -
    -
    - {{ form_rest(generalForm) }} -
    -
    - -
    -
    - {% endblock %} -
    - {{ form_end(form) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/preferences.html.twig deleted file mode 100644 index b7dbe2d2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/preferences.html.twig +++ /dev/null @@ -1,184 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% - set generalForm = form.general -%} - -{% block content %} - {{ form_start(form, {'attr' : {'class': 'form', 'id': 'configuration_form'} }) }} -
    - {% block preferences_form_general %} -
    -
    -

    - settings {{ 'General'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    - {{ ps.label_with_help( - ('Enable SSL'|trans), - ('If you want to enable SSL on all the pages of your shop, activate the "Enable on all the pages" option below.'|trans({}, 'Admin.Shopparameters.Help')) - ) }} - {% if app.request.isSecure() %} -
    - {{ form_errors(generalForm.enable_ssl) }} - {{ form_widget(generalForm.enable_ssl) }} - {{ 'If you own an SSL certificate for your shop\'s domain name, you can activate SSL encryption (https://) for customer account identification and order processing.'|trans({}, 'Admin.Shopparameters.Help') }} -
    - {% else %} - - {% endif %} -
    -
    - -
    - {{ form_errors(generalForm.enable_ssl_everywhere) }} - {{ form_widget(generalForm.enable_ssl_everywhere) }} - {{ 'When enabled, all the pages of your shop will be SSL-secured.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.enable_token) }} - {{ form_widget(generalForm.enable_token) }} - {{ 'Enable or disable token in the Front Office to improve PrestaShop\'s security.'|trans({}, 'Admin.Shopparameters.Help') }} - - {% if generalForm.enable_token.vars.disabled %} - - {% endif %} -
    -
    -
    - -
    - {{ form_errors(generalForm.allow_html_iframes) }} - {{ form_widget(generalForm.allow_html_iframes) }} - {{ 'Allow iframes on text fields like product description. We recommend that you leave this option disabled.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.use_htmlpurifier) }} - {{ form_widget(generalForm.use_htmlpurifier) }} - {{ 'Clean the HTML content on text fields. We recommend that you leave this option enabled.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.price_round_mode) }} - {{ form_widget(generalForm.price_round_mode) }} - {{ 'You can choose among 6 different ways of rounding prices. "Round up away from zero ..." is the recommended behavior.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.price_round_type) }} - {{ form_widget(generalForm.price_round_type) }} - {{ 'You can choose when to round prices: either on each item, each line or the total (of an invoice, for example).'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.display_suppliers) }} - {{ form_widget(generalForm.display_suppliers) }} - {{ 'Enable suppliers page on your front office even when its module is disabled.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.display_manufacturers) }} - {{ form_widget(generalForm.display_manufacturers) }} - {{ 'Enable brands page on your front office even when its module is disabled.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.display_best_sellers) }} - {{ form_widget(generalForm.display_best_sellers) }} - {{ 'Enable best sellers page on your front office even when its respective module is disabled.'|trans({}, 'Admin.Shopparameters.Help') }} -
    -
    -
    - -
    - {{ form_errors(generalForm.multishop_feature_active) }} - {{ form_widget(generalForm.multishop_feature_active) }} - {{ 'The multistore feature allows you to manage several e-shops with one Back Office. If this feature is enabled, a "Multistore" page will be available in the "Advanced Parameters" menu.'|trans({}, 'Admin.Shopparameters.Help') }} - - {% if generalForm.multishop_feature_active.vars.disabled %} - - {% endif %} -
    -
    -
    - -
    - {{ form_errors(generalForm.shop_activity) }} - {{ form_widget(generalForm.shop_activity) }} -
    -
    - {% block shop_preferences_form_rest %} - {{ form_rest(form) }} - {% endblock %} -
    -
    - -
    -
    - {% endblock %} - -
    - {{ form_end(form) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/product_preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/product_preferences.html.twig deleted file mode 100644 index acf6f61b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Configure/ShopParameters/product_preferences.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Shopparameters.Feature" %} - -{% set generalForm, paginationForm, pageForm, stockForm = form.general, form.pagination, form.page, form.stock %} - -{% block content %} - {{ form_start(form, {'attr': {'class': 'form', 'id': 'configuration_form'}}) }} -
    - {# Product preferences General block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/Blocks/product_preferences_general.html.twig' %} - - {# Product preferences Page block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/Blocks/product_preferences_page.html.twig' %} - - {# Product preferences Stock block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/Blocks/product_preferences_stock.html.twig' %} - - {# Product preferences Pagination block #} - {% include '@PrestaShop/Admin/Configure/ShopParameters/Blocks/product_preferences_pagination.html.twig' %} -
    - {{ form_end(form) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Exception/error.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Exception/error.html.twig deleted file mode 100644 index 36a80450..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Exception/error.html.twig +++ /dev/null @@ -1,88 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '::base.html.twig' %} - -{% block stylesheets %} - -{% endblock %} - -{% block title %} - {{ 'Oops... looks like an unexpected error occurred'|trans({},'Admin.Notifications.Error' ) }} -{% endblock %} - -{% block body %} -
    -
    -
    -
    -
    - {{ 'Oops... looks like an unexpected error occurred'|trans({}, 'Admin.Notifications.Error') }} - -
    -

    - {{ 'Oops... looks like an unexpected error occurred'|trans({}, 'Admin.Notifications.Error') }} -

    - - {% if exception %} -
    -

    {{ exception.message }}

    -

    [{{ exception.class }} {{ exception.code }}]

    -
    - {% endif %} - -
    -
    - - - -
    - -
    - -

    - - {{ 'Learn more about debug mode'|trans({}, 'Admin.Actions') }} - arrow_right_alt - -

    -
    -
    -
    -
    -
    -
    -{% endblock %} - -{% block javascripts %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Helpers/bootstrap_popup.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Helpers/bootstrap_popup.html.twig deleted file mode 100644 index 776b81f7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Helpers/bootstrap_popup.html.twig +++ /dev/null @@ -1,84 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Helpers/dropdown_menu.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Helpers/dropdown_menu.html.twig deleted file mode 100644 index 7ddc3c6b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Helpers/dropdown_menu.html.twig +++ /dev/null @@ -1,73 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set buttonType = buttonType|default('primary') %} -{% set right = right|default(false) %} - -
    - - {% if default_item is defined %} - - {% if default_item.icon %} - {{ default_item.icon }} - {% endif %} - {{ default_item.label|default('') }} - - {% endif %} - - - - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_inputs.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_inputs.html.twig deleted file mode 100644 index a29b9ea0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_inputs.html.twig +++ /dev/null @@ -1,123 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{# Display a range input with min/max controls #} - -
    - - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_slider.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_slider.html.twig deleted file mode 100644 index cd0bfe45..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Helpers/range_slider.html.twig +++ /dev/null @@ -1,96 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/breadcrumb.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/breadcrumb.html.twig deleted file mode 100644 index d6beb127..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/breadcrumb.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if cmsPageView.breadcrumb_tree is not empty %} -
    -
    -
    -
    - -
    -
    -
    -
    -{% endif %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/category_form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/category_form.html.twig deleted file mode 100644 index 52b19c14..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/category_form.html.twig +++ /dev/null @@ -1,102 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block category_form %} - {{ form_start(cmsPageCategoryForm) }} - -
    -
    - {{ 'CMS Category'|trans({}, 'Admin.Design.Feature') }} -
    -
    -
    - - {% set invalidCharactersForCatalogLabel = 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ '<>;=#{}' %} - {% set invalidCharactersForNameLabel = 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ '<>={}' %} - - {{ ps.form_group_row(cmsPageCategoryForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': invalidCharactersForCatalogLabel - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.is_displayed, {}, { - 'label': 'Displayed'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.parent_category, {}, { - 'label': 'Parent category'|trans({}, 'Admin.Design.Feature'), - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.meta_title, {}, { - 'label': 'Meta title'|trans({}, 'Admin.Global'), - 'help': invalidCharactersForNameLabel - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.meta_description, {}, { - 'label': 'Meta description'|trans({}, 'Admin.Global'), - 'help': invalidCharactersForNameLabel - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.meta_keywords, {}, { - 'label': 'Meta keywords'|trans({}, 'Admin.Global'), - 'help': invalidCharactersForNameLabel - }) }} - - {{ ps.form_group_row(cmsPageCategoryForm.friendly_url, {}, { - 'label': 'Friendly URL'|trans({}, 'Admin.Global'), - 'help': 'Only letters and the minus (-) character are allowed.'|trans({}, 'Admin.Catalog.Help') - }) }} - - {% if cmsPageCategoryForm.shop_association is defined %} - {{ ps.form_group_row(cmsPageCategoryForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - -
    -
    - - - -
    - - {{ form_rest(cmsPageCategoryForm) }} - {{ form_end(cmsPageCategoryForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/form.html.twig deleted file mode 100644 index 032e5fb9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/form.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(cmsPageForm) }} -
    -
    - {{ 'Page'|trans({}, 'Admin.Shopparameters.Feature') }} -
    -
    -
    - {% block cms_page_form_rest %} - {{ form_rest(cmsPageForm) }} - {% endblock %} -
    -
    - - - -
    -{{ form_end(cmsPageForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/listing_panel_footer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/listing_panel_footer.html.twig deleted file mode 100644 index a2c2ee29..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/listing_panel_footer.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/seo_preview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/seo_preview.html.twig deleted file mode 100644 index ea7b27b2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/seo_preview.html.twig +++ /dev/null @@ -1,26 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/showcase_card.html.twig deleted file mode 100644 index 4631fa6b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block cms_pages_showcase_card %} - {% if not showcaseCardIsClosed %} -
    -
    - -
    -
    -

    {{ 'Create meaningful content'|trans({}, 'Admin.Design.Help') }}

    -

    {{ 'Because it is not just selling products but also creating a universe, build pages to tell stories and catch your visitors’ interest, to turn them into loyal customers.'|trans({}, 'Admin.Design.Help') }}

    - {{ 'Learn more'|trans({}, 'Admin.Actions') }} -
    - close -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/add.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/add.html.twig deleted file mode 100644 index 1e23a4fc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/add.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/Design/Cms/Blocks/form.html.twig', {}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/create_category.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/create_category.html.twig deleted file mode 100644 index 25d7761d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/create_category.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/Design/Cms/Blocks/category_form.html.twig', { - 'cmsPageCategoryForm': cmsPageCategoryForm, - 'cmsCategoryParentId': app.request.query.get('id_cms_category') - }) - }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit.html.twig deleted file mode 100644 index 01466ff1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/Design/Cms/Blocks/form.html.twig', {}) }} - -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit_category.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit_category.html.twig deleted file mode 100644 index d05c94e2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/edit_category.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/Design/Cms/Blocks/category_form.html.twig', { - 'cmsPageCategoryForm': cmsPageCategoryForm, - 'cmsCategoryParentId': cmsCategoryParentId - }) - }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/index.html.twig deleted file mode 100644 index cc2d8fc0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Cms/index.html.twig +++ /dev/null @@ -1,82 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutHeaderToolbarBtn = { - add_cms_category: { - href: path('admin_cms_pages_category_create', {'id_cms_category' : app.request.query.get('id_cms_category')}), - desc: 'Add new page category'|trans({}, 'Admin.Design.Help'), - icon: 'add_circle_outline', - }, - add_cms_page: { - href: path('admin_cms_pages_create', {'id_cms_category' : app.request.query.get('id_cms_category')}), - desc: 'Add new page'|trans({}, 'Admin.Design.Help'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - -
    -
    - {% include '@PrestaShop/Admin/Improve/Design/Cms/Blocks/showcase_card.html.twig' %} -
    -
    - - {% block cms_page_category_breadcrumb %} - {% include '@PrestaShop/Admin/Improve/Design/Cms/Blocks/breadcrumb.html.twig' %} - {% endblock %} - - {% block cms_category_grid %} -
    -
    - {% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': cmsCategoryGrid} %} - - {% block grid_panel_footer %} - {% if app.request.query.get('id_cms_category') and app.request.query.get('id_cms_category') != cmsPageView.root_category_id %} - {% include '@PrestaShop/Admin/Improve/Design/Cms/Blocks/listing_panel_footer.html.twig' %} - {% endif %} - {% endblock %} - {% endembed %} -
    -
    - {% endblock %} - - {% block cms_grid %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': cmsGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/configuration_form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/configuration_form.html.twig deleted file mode 100644 index 65e8bcb7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/configuration_form.html.twig +++ /dev/null @@ -1,65 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block mailThemeConfigurationFormBlock %} -
    -
    - {{ form_start(mailThemeConfigurationForm, {'action': path('admin_mail_theme_save_configuration')}) }} -
    -

    - settings {{ 'Configuration'|trans({}, 'Admin.Global') }} -

    - -
    -
    - -
    - -
    - {{ form_errors(mailThemeConfigurationForm.configuration.defaultTheme) }} - {{ form_widget(mailThemeConfigurationForm.configuration.defaultTheme) }} -
    -
    -
    -
    - - -
    - {{ form_end(mailThemeConfigurationForm) }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/generate_mails_form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/generate_mails_form.html.twig deleted file mode 100644 index 1309ad2f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/generate_mails_form.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block generateMailsFormBlock %} -
    -
    - {{ form_start(generateMailsForm, {'action': path('admin_mail_theme_generate')}) }} -
    -

    - email {{ 'Generate emails'|trans({}, 'Admin.Design.Feature') }} -

    - -
    -
    - -
    - -
    - {{ form_errors(generateMailsForm.mailTheme) }} - {{ form_widget(generateMailsForm.mailTheme) }} -
    -
    - -
    - -
    - {{ form_errors(generateMailsForm.language) }} - {{ form_widget(generateMailsForm.language) }} -
    -
    - -
    - -
    - {{ form_errors(generateMailsForm.theme) }} - {{ form_widget(generateMailsForm.theme) }} - {% if generateMailsForm.theme.vars.disabled %} - {{ 'No emails were detected in any theme folder so this field is disabled.'|trans({}, 'Admin.Design.Help') }} - {% endif %} -
    -
    - -
    - {{ ps.label_with_help( - ('Overwrite templates'|trans({}, 'Admin.Design.Feature')), - ('By default, existing email template files are not modified to avoid deleting any modification you may have done. Enable this option to force the overwrite.'|trans({}, 'Admin.Design.Help')) - ) }} -
    - {{ form_errors(generateMailsForm.overwrite) }} - {{ form_widget(generateMailsForm.overwrite) }} -
    -
    - -
    -
    - - -
    - {{ form_end(generateMailsForm) }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_theme_layouts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_theme_layouts.html.twig deleted file mode 100644 index 952892bc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_theme_layouts.html.twig +++ /dev/null @@ -1,121 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block generateMailsFormBlock %} -
    -
    -
    -

    - email {{ 'List %theme% layouts'|trans({'%theme%': mailTheme.name}, 'Admin.Design.Feature') }} -

    - -
    - - - - - - - - - - - {% for mailLayout in mailTheme.layouts %} - - - - - - {% endfor %} - -
    - {{ 'Name'|trans({}, 'Admin.Global') }} - - {{ 'Module'|trans({}, 'Admin.Global') }} - -
    - {{ 'Actions'|trans({}, 'Admin.Global') }} -
    -
    - {{ mailLayout.name }} - - {{ mailLayout.moduleName }} - - {% if mailLayout.moduleName is empty %} - {% set previewUrl = path('admin_mail_theme_preview_layout', {locale: app.request.locale, theme: mailTheme.name, layout: mailLayout.name, type: 'html'}) %} - {% set rawUrl = path('admin_mail_theme_raw_layout', {locale: app.request.locale, theme: mailTheme.name, layout: mailLayout.name, type: 'html'}) %} - {% set txtUrl = path('admin_mail_theme_raw_layout', {locale: app.request.locale, theme: mailTheme.name, layout: mailLayout.name, type: 'txt'}) %} - {% set mailUrl = path('admin_mail_theme_send_test_mail', {locale: app.request.locale, theme: mailTheme.name, layout: mailLayout.name}) %} - {% else %} - {% set previewUrl = path('admin_mail_theme_preview_module_layout', {locale: app.request.locale, theme: mailTheme.name, module: mailLayout.moduleName, layout: mailLayout.name, type: 'html'}) %} - {% set rawUrl = path('admin_mail_theme_raw_module_layout', {locale: app.request.locale, theme: mailTheme.name, module: mailLayout.moduleName, layout: mailLayout.name, type: 'html'}) %} - {% set txtUrl = path('admin_mail_theme_raw_module_layout', {locale: app.request.locale, theme: mailTheme.name, module: mailLayout.moduleName, layout: mailLayout.name, type: 'txt'}) %} - {% set mailUrl = path('admin_mail_theme_send_test_module_mail', {locale: app.request.locale, theme: mailTheme.name, module: mailLayout.moduleName, layout: mailLayout.name}) %} - {% endif %} - - -
    - -
    - - - -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_themes.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_themes.html.twig deleted file mode 100644 index 96f077cc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/list_mail_themes.html.twig +++ /dev/null @@ -1,71 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block generateMailsFormBlock %} -
    -
    -
    -

    - email {{ 'Email themes'|trans({}, 'Admin.Design.Feature') }} -

    - -
    - - - - - - - - - - {% for theme in mailThemes %} - - - - - {% endfor %} - -
    - {{ 'Name'|trans({}, 'Admin.Global') }} - -
    - {{ 'Actions'|trans({}, 'Admin.Global') }} -
    -
    - {{ theme.name }} - - -
    - -
    -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/translate_mails_body_form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/translate_mails_body_form.html.twig deleted file mode 100644 index a3216b42..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/Blocks/translate_mails_body_form.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block translateMailsBodyFormBlock %} -
    -
    - {{ form_start(translateMailsBodyForm, {'action': path('admin_mail_theme_translate_body')}) }} -
    -

    - email {{ 'Translate emails'|trans({}, 'Admin.Actions') }} -

    - -
    -
    -
    - -
    - {{ form_errors(translateMailsBodyForm.language) }} - {{ form_widget(translateMailsBodyForm.language) }} -
    -
    -
    -
    - - -
    - {{ form_end(translateMailsBodyForm) }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/index.html.twig deleted file mode 100644 index 746673c8..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/index.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {{ - include('@PrestaShop/Admin/Improve/Design/MailTheme/Blocks/configuration_form.html.twig', { - 'mailThemeConfigurationForm': mailThemeConfigurationForm - }) - }} - - {{ - include('@PrestaShop/Admin/Improve/Design/MailTheme/Blocks/generate_mails_form.html.twig', { - 'generateMailsForm': generateMailsForm - }) - }} - - {{ - include('@PrestaShop/Admin/Improve/Design/MailTheme/Blocks/translate_mails_body_form.html.twig', { - 'generateMailsForm': generateMailsForm - }) - }} - - {{ - include('@PrestaShop/Admin/Improve/Design/MailTheme/Blocks/list_mail_themes.html.twig', { - 'mailThemes': mailThemes - }) - }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/preview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/preview.html.twig deleted file mode 100644 index 5fb68bce..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/MailTheme/preview.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {{ - include('@PrestaShop/Admin/Improve/Design/MailTheme/Blocks/list_mail_theme_layouts.html.twig', { - 'mailTheme': mailTheme - }) - }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig deleted file mode 100644 index 96070245..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block logo_card %} -
    -
    -
    - {% block card_title %} - {% endblock %} -
    - {% block card_content %} - {% endblock %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig deleted file mode 100644 index 6564229e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig' %} - -{% block content %} -
    -
    - - {% block image %} - {% endblock %} - -
    - {% block button_container %} - {% endblock %} -
    -
    - -
    - - {{ themeName }} - - - {{ 'Version'|trans({}, 'Admin.Global') }} {{ themeVersion }} - - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig deleted file mode 100644 index 6744f7e5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% block content %} - {% endblock %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_catalog_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_catalog_card.html.twig deleted file mode 100644 index 432daf30..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/Partials/theme_catalog_card.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/theme_card_container.html.twig' %} - -{% block content %} -
    - -
    - {% block image %} - {% endblock %} -
    - -
    - {% block description %} - {% endblock %} -
    - -
    - {% block button_container %} - {% endblock %} -
    -
    -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/delete_theme_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/delete_theme_modal.html.twig deleted file mode 100644 index 89a7205f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/delete_theme_modal.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': 'delete_theme_modal' -} %} - {% block header %} - - {% endblock %} - - {% block footer %} - - {% endblock %} - -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/layouts_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/layouts_configuration.html.twig deleted file mode 100644 index 21de2869..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/layouts_configuration.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block layouts_configuration %} -
    -
    -
    - -
    - {{ 'Configure your page layouts'|trans({}, 'Admin.Design.Feature') }} -

    {{ 'Each page can use a different layout, choose it among the layouts bundled in your theme.'|trans({}, 'Admin.Design.Feature') }}

    -
    -
    -
    - - {{ 'Choose layouts'|trans({}, 'Admin.Design.Feature') }} - - - {% if isDevModeOn %} - - {% endif %} -
    -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/logo_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/logo_configuration.html.twig deleted file mode 100644 index 34e1b0aa..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/logo_configuration.html.twig +++ /dev/null @@ -1,154 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig' %} - {% import '@PrestaShop/Admin/macros.html.twig' as ps %} - {% block card_title %} - {{ form_widget(shopLogosForm.shop_logos.header_logo_is_restricted_to_shop) }} {{ 'Header logo'|trans({}, 'Admin.Design.Feature') }} - {% endblock %} - {% block card_content %} -

    - {{ 'Will appear on your main page. Recommended size for the default theme: height %height% and width %width%.'|trans({'%height%': '40px', '%width%': '200px'}, 'Admin.Design.Help') }} -

    - -
    - -
    - - {{ ps.form_group_row(shopLogosForm.shop_logos.header_logo) }} - {% endblock %} - {% endembed %} - - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig' %} - {% import '@PrestaShop/Admin/macros.html.twig' as ps %} - {% block card_title %} - - {% endblock %} - {% block card_content %} -
    -
    -

    - {{ 'Will appear on email headers. If undefined, the header logo will be used.'|trans({}, 'Admin.Design.Help') }} -

    - -
    - -
    -
    - {{ ps.form_group_row(shopLogosForm.shop_logos.mail_logo, {}, {'help': headerLogoPath == mailLogoPath ? 'Warning: if no email logo is available, the main logo will be used instead.'|trans({}, 'Admin.Design.Notification') : '' }) }} -
    -
    -
    -

    - {{ 'Will appear on invoice headers.'|trans({}, 'Admin.Design.Help') }} -

    - -
    - -
    -
    - {{ ps.form_group_row(shopLogosForm.shop_logos.invoice_logo, {}, {'help': headerLogoPath == invoiceLogoPath ? 'Warning: if no invoice logo is available, the main logo will be used instead.'|trans({}, 'Admin.Design.Help') : '' }) }} -
    -
    -
    - {% endblock %} - {% endembed %} - - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/logo_card.html.twig' %} - {% import '@PrestaShop/Admin/macros.html.twig' as ps %} - {% block card_title %} - {{ form_widget(shopLogosForm.shop_logos.favicon_is_restricted_to_shop) }} {{ 'Favicon'|trans({}, 'Admin.Design.Feature') }} - {% endblock %} - {% block card_content %} -

    - {{ 'It is the small icon that appears in browser tabs, next to the title.'|trans({}, 'Admin.Design.Help') }} -

    - -
    - -
    - -
    -
    - {{ ps.form_widget_with_error(shopLogosForm.shop_logos.favicon) }} - - {{ 'Use our [1]favicon generator on PrestaShop Marketplace[/1] to boost your brand image!'|trans({'[1]': '', '[/1]': ''}, 'Admin.Design.Help')|raw }} - -
    -
    - - {% endblock %} - {% endembed %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/multishop_switch.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/multishop_switch.html.twig deleted file mode 100644 index 8bb7c934..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/multishop_switch.html.twig +++ /dev/null @@ -1,38 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Multistore'|trans({}, 'Admin.Global') }} -

    -
    -
    - {{ ps.multistore_switch(shopLogosForm.shop_logos, { - 'label': 'Multistore'|trans({}, 'Admin.Global'), - }) }} -
    -
    -
    - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/rtl_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/rtl_configuration.html.twig deleted file mode 100644 index e7a8b341..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/rtl_configuration.html.twig +++ /dev/null @@ -1,70 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(adaptThemeToRtlLanguagesForm, {'action': path('admin_themes_adapt_to_rtl_languages')}) }} -
    -

    - {{ 'Adaptation to Right-to-Left languages'|trans({}, 'Admin.Design.Feature') }} -

    -
    -
    -
    -

    - {{ 'Be careful! Please check your theme in an RTL language before generating the RTL stylesheet: your theme could be already adapted to RTL.\nOnce you enable the "%generate_rtl_label%" option, any RTL-specific file that you might have added to your theme might be deleted by the created stylesheet.'|trans({'%generate_rtl_label%': 'Generate RTL stylesheet'|trans({}, 'Admin.Design.Feature')}, 'Admin.Design.Help') }} -

    -
    - - {{ ps.form_group_row(adaptThemeToRtlLanguagesForm.theme_to_adapt, {}, { - 'label': 'Theme to adapt'|trans({}, 'Admin.Design.Feature') - }) }} - - {{ ps.form_group_row(adaptThemeToRtlLanguagesForm.generate_rtl_css, {}, { - 'label': 'Generate RTL stylesheet'|trans({}, 'Admin.Design.Feature') - }) }} -
    -
    - - {% if isMultiShopFeatureUsed and isSingleShopContext %} -
    -
    -
    - {{ ps.multistore_switch(shopLogosForm.shop_logos, { - 'label': 'Multistore'|trans({}, 'Admin.Global'), - }) }} -
    -
    - {% endif %} - -
    -{{ form_rest(adaptThemeToRtlLanguagesForm) }} -{{ form_end(adaptThemeToRtlLanguagesForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/use_theme_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/use_theme_modal.html.twig deleted file mode 100644 index 1bab208f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/Blocks/use_theme_modal.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': 'use_theme_modal' -} %} - {% block header %} - - {% endblock %} - - {% block footer %} - - {% endblock %} - -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/customize_page_layouts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/customize_page_layouts.html.twig deleted file mode 100644 index 81fe32bc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/customize_page_layouts.html.twig +++ /dev/null @@ -1,74 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ form_start(pageLayoutCustomizationForm) }} -
    -
    -
    -

    - settings - {{ 'Choose layouts'|trans({}, 'Admin.Actions') }} -

    -
    - - - - - - - - - - {% for customizablePage in pages %} - - - - - - {% endfor %} - -
    {{ 'Page'|trans({}, 'Admin.Global') }}{{ 'Description'|trans({}, 'Admin.Global') }}{{ 'Layout'|trans({}, 'Admin.Global') }}
    {{ customizablePage.title|default(customizablePage.page) }}{{ customizablePage.description }}{{ form_widget(pageLayoutCustomizationForm['layouts'][customizablePage.page]) }}
    - - {% block page_layout_customization_form_rest %} - {{ form_rest(pageLayoutCustomizationForm) }} - {% endblock %} -
    - -
    -
    -
    - {{ form_end(pageLayoutCustomizationForm) }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/import.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/import.html.twig deleted file mode 100644 index e6516033..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/import.html.twig +++ /dev/null @@ -1,132 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set layoutTitle = 'Theme & Logo'|trans({}, 'Admin.Navigation.Menu') ~ ' > ' ~ 'Theme'|trans({}, 'Admin.Design.Feature') %} -{% set layoutHeaderToolbarBtn = { - 'add': { - 'href': path('admin_themes_import'), - 'desc': 'Add new theme'|trans({}, 'Admin.Design.Feature'), - 'icon': 'add' - }, - 'export': { - 'href': path('admin_themes_export_current'), - 'desc': 'Export current theme'|trans({}, 'Admin.Design.Feature'), - 'icon': 'cloud_download' - } -} %} - -{% block content %} -
    -
    - {{ form_errors(importThemeForm) }} - {{ form_start(importThemeForm) }} -
    -
    -
    -

    - file_copy - {{ 'Import from your computer'|trans({}, 'Admin.Design.Feature') }} -

    -
    -
    - {{ ps.form_group_row(importThemeForm.import_from_computer, {}, { - label: 'Zip file'|trans({}, 'Admin.Design.Feature'), - help: 'Browse your computer files and select the Zip file for your new theme.'|trans({}, 'Admin.Design.Help') - }) }} -
    -
    - -
    -
    - -
    -
    -

    - file_copy - {{ 'Import from the web'|trans({}, 'Admin.Design.Feature') }} -

    -
    -
    - {{ ps.form_group_row(importThemeForm.import_from_web, {}, { - label: 'Archive URL'|trans({}, 'Admin.Design.Feature'), - help: 'Indicate the complete URL to an online Zip file that contains your new theme. For instance, "http://example.com/files/theme.zip".'|trans({}, 'Admin.Design.Help') - }) }} -
    -
    - -
    -
    - -
    -
    -

    - file_copy - {{ 'Import from FTP'|trans({}, 'Admin.Design.Feature') }} -

    -
    -
    - {{ ps.form_group_row(importThemeForm.import_from_ftp, {}, { - label: 'Select the archive'|trans({}, 'Admin.Design.Feature'), - help: 'This selector lists the Zip files that you uploaded in the \'/themes\' folder.'|trans({}, 'Admin.Design.Help') - }) }} -
    -
    - -
    -
    -
    - - {% block import_theme_form_rest %} - {{ form_rest(importThemeForm) }} - {% endblock %} - - {{ form_end(importThemeForm) }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig deleted file mode 100644 index 172eee67..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/Theme/index.html.twig +++ /dev/null @@ -1,171 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Theme & Logo'|trans({}, 'Admin.Navigation.Menu') ~ ' > ' ~ 'Theme'|trans({}, 'Admin.Design.Feature') %} -{% set layoutHeaderToolbarBtn = { - 'add': { - 'href': path('admin_themes_import'), - 'desc': 'Add new theme'|trans({}, 'Admin.Design.Feature'), - 'icon': 'add' - }, - 'export': { - 'href': path('admin_themes_export_current'), - 'desc': 'Export current theme'|trans({}, 'Admin.Design.Feature'), - 'icon': 'cloud_download' - } - } %} - -{% block content %} -
    -
    -
    - - {% if not isSingleShopContext %} -
    -

    - {{ 'You must select a shop from the above list if you wish to choose a theme.'|trans({}, 'Admin.Design.Help') }} -

    -
    - {% endif %} - - {% if isInstalledRtlLanguage %} - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/rtl_configuration.html.twig' %} - {% endif %} - - {{ form_start(shopLogosForm.shop_logos, {'action': path('admin_themes_upload_logos')}) }} - {% if not isInstalledRtlLanguage and isSingleShopContext and isMultiShopFeatureUsed %} - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/multishop_switch.html.twig' %} - {% endif %} -
    -
    - {{ 'Logo'|trans({}, 'Admin.Global') }} -
    -
    - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/logo_configuration.html.twig' %} -
    - -
    - {{ form_rest(shopLogosForm.shop_logos) }} - {{ form_end(shopLogosForm.shop_logos) }} - -
    -
    - {{ 'My theme for %name% shop'|trans({'%name%': shopName}, 'Admin.Design.Feature') }} -
    -
    - - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig' with { - 'themeName': currentlyUsedTheme.get('display_name'), - 'themeVersion': currentlyUsedTheme.get('version'), - 'themeAuthor': currentlyUsedTheme.get('author.name'), - 'themeAuthorUrl': theme.get('author.url'), - 'isActive': true - } %} - {% block image %} - {{ currentlyUsedTheme.get('display_name')   }} - {% endblock %} - {% block button_container %} - - {% endblock %} - {% endembed %} - - {% if notUsedThemes is not empty %} - {% for theme in notUsedThemes %} - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/theme_card.html.twig' with { - 'themeName': theme.get('display_name'), - 'themeVersion': theme.get('version'), - 'themeAuthor': theme.get('author.name'), - 'themeAuthorUrl': theme.get('author.url'), - 'isActive': false - } %} - {% block image %} - {{ theme.get('display_name') }} - {% endblock %} - {% block button_container %} -
    - - -
    -
    - - -
    - {% endblock %} - {% endembed %} - {% endfor %} - - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/use_theme_modal.html.twig' %} - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/delete_theme_modal.html.twig' %} - {% endif %} - - {% embed '@PrestaShop/Admin/Improve/Design/Theme/Blocks/Partials/theme_catalog_card.html.twig' %} - {% block image %} - {{ 'Visit the theme catalog'|trans({}, 'Admin.Design.Feature') }} - {% endblock %} - - {% block description %} - {{ 'Explore more than a thousand themes'|trans({}, 'Admin.Design.Feature') }} - {% endblock %} - - {% block button_container %} - - {{ 'Visit the theme catalog'|trans({}, 'Admin.Design.Feature') }} - - {% endblock %} - - {% endembed %} - - {% include '@PrestaShop/Admin/Improve/Design/Theme/Blocks/layouts_configuration.html.twig' %} -
    -
    -
    -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/ThemesCatalogPage/addons_store.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/ThemesCatalogPage/addons_store.html.twig deleted file mode 100644 index 19eeadbb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/ThemesCatalogPage/addons_store.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {{ pageContent|raw }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/positions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/positions.html.twig deleted file mode 100644 index c08814c6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Design/positions.html.twig +++ /dev/null @@ -1,214 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Design.Feature" %} - -{% block content %} -
    - {% if not canMove %} -

    - {{ 'If you want to order/move the following data, please select a shop from the shop list.' | trans({}, 'Admin.Design.Notification') }} -

    - {% endif %} - -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    - search -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -

    - -

    -
    -
    -
    -
    -
    - -
    - {% for hook in hooks %} - - {% endfor %} - -
    - -
    -
    -
    -
    - -
    -
    -

    checked {{ 'Selection' | trans({}, 'Admin.Global') }}

    -
    -

    - {{ '1 module selected' | trans }} - - {{ 'modules selected' | trans({}, 'Admin.Design.Feature') }} - -

    -
    - -
    -
    -
    -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/exchange_rates.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/exchange_rates.html.twig deleted file mode 100644 index c2707c7d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/exchange_rates.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{{ form_start(exchangeRatesForm, {'action': path('admin_currencies_refresh_exchange_rates') }) }} -
    -

    - {{ 'Exchange rate'|trans({}, 'Admin.International.Feature') }} -

    -
    -
    -
    - -
    - {{ form_widget(exchangeRatesForm.live_exchange_rate, {'attr': {'class': 'js-live-exchange-rate', 'data-url': path('admin_currencies_update_live_exchange_rates')}}) }} - - {% if exchangeRatesForm.live_exchange_rate.vars.disabled %} - - {{ 'Please install the %module_name% module before using this feature.'|trans({'%module_name%': 'cronjobs'}, 'Admin.International.Notification') }} - - {% else %} - - {{ 'The exchange rates are not automatically updated'|trans({}, 'Admin.International.Feature') }} - - - {{ 'The exchange rates are automatically updated'|trans({}, 'Admin.International.Feature') }} - - {% endif %} -
    -
    -
    - -
    - -
    -
    - {% block currency_settings %} - {{ form_rest(exchangeRatesForm) }} - {% endblock %} -
    -
    -
    -{{ form_end(exchangeRatesForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/form.html.twig deleted file mode 100644 index 846d41df..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/Blocks/form.html.twig +++ /dev/null @@ -1,159 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block form %} - {{ form_start(currencyForm, { - 'attr': { - 'id': 'currency_form', - 'data-reference-url': path('admin_currencies_get_reference_data', {'currencyIsoCode': 'CURRENCY_ISO_CODE'})|replace({'/CURRENCY_ISO_CODE': '{/id}'}), - 'data-languages': languages|json_encode|replace("'", "'")|raw, - 'data-translations': { - 'step.symbol': '1. Enter symbol'|trans({}, 'Admin.International.Feature'), - 'step.format': '2. Choose format'|trans({}, 'Admin.International.Feature'), - 'modal.title': 'Customize symbol and format'|trans({}, 'Admin.International.Feature'), - 'modal.apply': 'Apply'|trans({}, 'Admin.Actions'), - 'modal.cancel': 'Cancel'|trans({}, 'Admin.Actions'), - 'modal.close': 'Close'|trans({}, 'Admin.Actions'), - 'list.language': 'Language'|trans({}, 'Admin.Global'), - 'list.example': 'Example'|trans({}, 'Admin.Global'), - 'list.edit': 'Edit symbol / format'|trans({}, 'Admin.International.Feature'), - 'list.reset': 'Reset'|trans({}, 'Admin.Actions'), - 'list.reset.success': 'Your symbol and format customizations have been successfully reset for this language.'|trans({}, 'Admin.Notifications.Success'), - 'list.example.format': '%price%'|trans({}, 'Admin.International.Feature'), - 'modal.restore.title': 'Are you sure you want to restore default settings?'|trans({}, 'Admin.International.Feature'), - 'modal.restore.apply': 'Restore'|trans({}, 'Admin.Actions'), - 'modal.restore.cancel': 'Cancel'|trans({}, 'Admin.Actions'), - 'modal.restore.body': 'Restoring your currency\'s default settings will delete all the customizations you made before. Parameters will look just the same as when the currency is freshly imported.'|trans({}, 'Admin.International.Feature') - }|json_encode|replace("'", "'")|raw - } - }) }} - -
    -
    - {{ 'Currencies'|trans({}, 'Admin.Global') }} -
    -
    -
    - {{ form_errors(currencyForm) }} - - {% if not currencyForm.vars.data.id is defined %} - {% set selectIsoCodeHelp %} - {{ 'By default, PrestaShop comes with a list of official currencies. If you want to use a local currency, you will have to add it manually. For example, to accept the Iranian Toman on your store, you need to create it before.'|trans({}, 'Admin.International.Help') }} - {% endset %} - {{ ps.form_group_row(currencyForm.selected_iso_code, {}, { - 'label': 'Select a currency'|trans({}, 'Admin.International.Feature'), - 'help': selectIsoCodeHelp - }) }} - - {{ ps.form_group_row(currencyForm.unofficial, {}, { - 'label': 'or'|trans({}, 'Admin.Global'), - }) }} - {% endif %} - - {{ ps.form_group_row(currencyForm.names, {}, { - 'label': 'Currency name'|trans({}, 'Admin.International.Feature'), - }) }} - - {% set symbolsClass = currencyForm.symbols.vars.errors|length ? '' : 'd-none' %} - {{ ps.form_group_row(currencyForm.symbols, {}, { - 'label': 'Symbol'|trans({}, 'Admin.International.Feature'), - 'class': symbolsClass - }) }} - - {{ ps.form_group_row(currencyForm.iso_code, {}, { - 'label': 'ISO code'|trans({}, 'Admin.International.Feature'), - 'help': 'ISO 4217 code (e.g. USD for Dollars, EUR for Euros, etc.)'|trans({}, 'Admin.International.Help') - }) }} - - {% set exchangeRateHelp %} - {{ 'Exchange rates are calculated from one unit of your shop\'s default currency. For example, if the default currency is euros and your chosen currency is dollars, type "1.20" (1€ = $1.20).'|trans({}, 'Admin.International.Help') }} - {% endset %} - - {{ ps.form_group_row(currencyForm.exchange_rate, {}, { - 'label': 'Exchange rate'|trans({}, 'Admin.International.Feature'), - 'help': exchangeRateHelp - }) }} - - {{ ps.form_group_row(currencyForm.precision, {}, { - 'label': 'Decimals'|trans({}, 'Admin.International.Feature') - }) }} - - {{ ps.form_group_row(currencyForm.active, {}, { - 'label': 'Status'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(currencyForm.transformations, {}, {'class': 'd-none'}) }} - - {% if isShopFeatureEnabled %} - {{ ps.form_group_row(currencyForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global'), - }) }} - {% endif %} - - {% block currency_form_rest %} - {{ form_rest(currencyForm) }} - {% endblock %} -
    -
    - - - -
    - {{ form_end(currencyForm) }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/create.html.twig deleted file mode 100644 index 33930256..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/create.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/International/Currency/Blocks/form.html.twig', {'currencyForm': currencyForm, 'languages': []}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/edit.html.twig deleted file mode 100644 index 7ee12b6e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/edit.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/International/Currency/Blocks/form.html.twig', {'currencyForm': currencyForm, 'languages': languages}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/index.html.twig deleted file mode 100644 index dc2970c5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Currency/index.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutHeaderToolbarBtn = { - add: { - href: path('admin_currencies_create'), - desc: 'Add new currency'|trans({}, 'Admin.International.Feature'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - -
    -
    - {{ include('@PrestaShop/Admin/Common/Grid/grid_panel.html.twig', {'grid': currencyGrid }) }} -
    -
    - - {% block exchange_rates_block %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/International/Currency/Blocks/exchange_rates.html.twig', {'exchangeRatesForm': currencySettingsForm.exchange_rates}) }} -
    -
    - {% endblock %} - -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_by_ip_address.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_by_ip_address.html.twig deleted file mode 100644 index 0bd94fe6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_by_ip_address.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block geolocation_by_ip_address %} -
    -

    - {{ 'Geolocation by IP address'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Geolocation by IP address'|trans), ('This option allows you, among other things, to restrict access to your shop for certain countries. See below.'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(geolocationByIpAddressForm.geolocation_enabled) }} - {{ form_widget(geolocationByIpAddressForm.geolocation_enabled) }} -
    -
    -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_ip_address_whitelist.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_ip_address_whitelist.html.twig deleted file mode 100644 index 5ea0b4d6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_ip_address_whitelist.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{% block geolocation_ip_address_whitelist %} -
    -

    - {{ 'IP address whitelist'|trans }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(geolocationIpAddressWhitelistForm.geolocation_whitelist) }} - {{ form_widget(geolocationIpAddressWhitelistForm.geolocation_whitelist) }} -
    -
    -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_options.html.twig deleted file mode 100644 index 16fb1e9a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/Blocks/geolocation_options.html.twig +++ /dev/null @@ -1,87 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{% block geolocation_options %} -
    -

    - {{ 'Options'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(geolocationOptionsForm.geolocation_behaviour) }} - {{ form_widget(geolocationOptionsForm.geolocation_behaviour) }} -
    -
    - -
    - -
    - {{ form_errors(geolocationOptionsForm.geolocation_na_behaviour) }} - {{ form_widget(geolocationOptionsForm.geolocation_na_behaviour) }} -
    -
    - -
    - - -
    -
    - {{ form_errors(geolocationOptionsForm.geolocation_countries) }} - {{ form_widget(geolocationOptionsForm.geolocation_countries) }} -
    -
    -
    -
    -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/index.html.twig deleted file mode 100644 index 774baf8a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Geolocation/index.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.International.Feature' %} - -{% set geolocationByIpAddressForm, geolocationIpAddressWhitelistForm, geolocationOptionsForm = geolocationForm.geolocation_by_id_address, geolocationForm.geolocation_ip_address_whitelist, geolocationForm.geolocation_options %} - -{% block content %} - {% if not geolocationDatabaseAvailable %} -
    -
    - -
    -
    - {% endif %} - - {{ form_start(geolocationForm, {'action': path('admin_geolocation_save_options')}) }} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Geolocation/Blocks/geolocation_by_ip_address.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Geolocation/Blocks/geolocation_options.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Geolocation/Blocks/geolocation_ip_address_whitelist.html.twig' %} -
    -
    - - {% block geolocation_form_rest %} - {{ form_rest(geolocationForm) }} - {% endblock %} - {{ form_end(geolocationForm) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/Blocks/form.html.twig deleted file mode 100644 index c0ca0369..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/Blocks/form.html.twig +++ /dev/null @@ -1,110 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(languageForm) }} -
    -

    - language - {{ 'Languages'|trans({}, 'Admin.Global') }} -

    -
    -
    - {{ form_errors(languageForm) }} - - {{ ps.form_group_row(languageForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(languageForm.iso_code, { - 'attr': { - 'maxlength': 2 - } - }, { - 'label': 'ISO code'|trans({}, 'Admin.International.Feature'), - 'help': 'Two-letter ISO code (e.g. FR, EN, DE).'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.tag_ietf, { - 'attr': { - 'maxlength': 5 - } - }, { - 'label': 'Language code'|trans({}, 'Admin.International.Feature'), - 'help': 'IETF language tag (e.g. en-US, pt-BR).'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.short_date_format, {}, { - 'label': 'Date format'|trans({}, 'Admin.International.Feature'), - 'help': 'Short date format (e.g., Y-m-d).'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.full_date_format, {}, { - 'label': 'Date format (full)'|trans({}, 'Admin.International.Feature'), - 'help': 'Full date format (e.g., Y-m-d H:i:s).'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.flag_image, {}, { - 'label': 'Flag'|trans({}, 'Admin.International.Feature'), - 'help': 'Upload the country flag from your computer.'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.no_picture_image, {}, { - 'label': '"No-picture" image'|trans({}, 'Admin.International.Feature'), - 'help': 'Image is displayed when "no picture is found".'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.is_rtl, {}, { - 'label': 'Is RTL language'|trans({}, 'Admin.International.Feature'), - 'help': 'Enable if this language is read from right to left.'|trans({}, 'Admin.International.Help') ~ '(Experimental: your theme must be compliant with RTL languages).'|trans({}, 'Admin.International.Help') - }) }} - - {{ ps.form_group_row(languageForm.is_active, {}, { - 'label': 'Status'|trans({}, 'Admin.Global'), - 'help': 'Activate this language.'|trans({}, 'Admin.International.Feature') - }) }} - - {% if languageForm.shop_association is defined %} - {{ ps.form_group_row(languageForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block language_form_rest %} - {{ form_rest(languageForm) }} - {% endblock %} -
    -
    -
    -
    -{{ form_end(languageForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/create.html.twig deleted file mode 100644 index 68224a6f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/create.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Language/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/edit.html.twig deleted file mode 100644 index 75d877ef..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/edit.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Edit: %value%'|trans({'%value%': editableLanguage.name}, 'Admin.Catalog.Feature') %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Language/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/index.html.twig deleted file mode 100644 index 0c5e8aa9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Language/index.html.twig +++ /dev/null @@ -1,67 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutHeaderToolbarBtn = { - 'add' : { - 'href': path('admin_languages_create'), - 'desc': 'Add new language'|trans({}, 'Admin.International.Feature'), - 'icon': 'add_circle_outline' - } -} %} -{% set layoutTitle = 'Languages'|trans({}, 'Admin.Global') %} -{% set enableSidebar = true %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - - - {% if not isHtaccessFileWriter %} - - {% endif %} -
    -
    - - {% block language_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with { 'grid': languageGrid } %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/advanced_configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/advanced_configuration.html.twig deleted file mode 100644 index 263da7cc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/advanced_configuration.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block localization_advanced_configuration %} -
    -

    - settings {{ 'Advanced'|trans({}, 'Admin.Global') }} -

    - -
    -
    -
    - {{ ps.label_with_help(('Language identifier'|trans), ('The ISO 639-1 identifier for the language of the country where your web server is located (en, fr, sp, ru, pl, nl, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(advancedForm.language_identifier) }} - {{ form_widget(advancedForm.language_identifier) }} -
    -
    - -
    - {{ ps.label_with_help(('Country identifier'|trans), ('The ISO 3166-1 alpha-2 identifier for the country/region where your web server is located, in lowercase (us, gb, fr, sp, ru, pl, nl, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(advancedForm.country_identifier) }} - {{ form_widget(advancedForm.country_identifier) }} -
    -
    -
    -
    - - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/configuration.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/configuration.html.twig deleted file mode 100644 index 598536cf..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/configuration.html.twig +++ /dev/null @@ -1,103 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block localization_configuration %} -
    -

    - settings {{ 'Configuration'|trans({}, 'Admin.Global') }} -

    - -
    -
    -
    - {{ ps.label_with_help(('Default language'|trans), ('The default language used in your shop.'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(configurationForm.default_language) }} - {{ form_widget(configurationForm.default_language, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    - -
    - -
    - {{ form_errors(configurationForm.detect_language_from_browser) }} - {{ form_widget(configurationForm.detect_language_from_browser) }} - {{ 'Set browser language as default language'|trans({}, 'Admin.International.Help') }} -
    -
    - -
    - {{ ps.label_with_help(('Default country'|trans), ('The default country used in your shop.'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(configurationForm.default_country) }} - {{ form_widget(configurationForm.default_country, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    - -
    - -
    - {{ form_errors(configurationForm.detect_country_from_browser) }} - {{ form_widget(configurationForm.detect_country_from_browser) }} - {{ 'Set country corresponding to browser language'|trans({}, 'Admin.International.Help') }} -
    -
    - -
    - {% set currencyChangeWarningMessage = 'Before changing the default currency, we strongly recommend that you enable maintenance mode. Indeed, any change on the default currency requires a manual adjustment of the price of each product and its combinations.'|trans({}, 'Admin.International.Notification') %} - - {{ ps.label_with_help(('Default currency'|trans), ('The default currency used in your shop.'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(configurationForm.default_currency) }} - {{ form_widget(configurationForm.default_currency, {'attr': {'data-warning-message': currencyChangeWarningMessage, 'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    - -
    - -
    - {{ form_errors(configurationForm.timezone) }} - {{ form_widget(configurationForm.timezone, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    -
    -
    - - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/import_localization_pack_block.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/import_localization_pack_block.html.twig deleted file mode 100644 index c41cec50..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/import_localization_pack_block.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{% block import_localization_pack %} - {{ form_start(localizationPackImportForm, {'action': path('admin_localization_import_pack')}) }} -
    -

    - language {{ 'Import a localization pack'|trans }} -

    - -
    -
    -
    - -
    - {{ form_errors(localizationPackImportForm.iso_localization_pack) }} - {{ form_widget(localizationPackImportForm.iso_localization_pack, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    - -
    - -
    - {{ form_errors(localizationPackImportForm.content_to_import) }} - {{ form_widget(localizationPackImportForm.content_to_import) }} -
    -
    - -
    - -
    - {{ form_errors(localizationPackImportForm.download_pack_data) }} - {{ form_widget(localizationPackImportForm.download_pack_data) }} - {{ 'If set to yes then the localization pack will be downloaded from prestashop.com. Otherwise the local xml file found in the localization folder of your PrestaShop installation will be used.'|trans({}, 'Admin.International.Help') }} -
    -
    -
    -
    - - -
    - {{ form_end(localizationPackImportForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/local_units.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/local_units.html.twig deleted file mode 100644 index fc4b393b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/Blocks/local_units.html.twig +++ /dev/null @@ -1,77 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block localization_local_units %} -
    -

    - language {{ 'Local units'|trans }} -

    - -
    -
    -
    - {{ ps.label_with_help(('Weight unit'|trans), ('The default weight unit for your shop (e.g. "kg" for kilograms, "lbs" for pound-mass, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(localUnitsForm.weight_unit) }} - {{ form_widget(localUnitsForm.weight_unit) }} -
    -
    - -
    - {{ ps.label_with_help(('Distance unit'|trans), ('The default distance unit for your shop (e.g. "km" for kilometer, "mi" for mile, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(localUnitsForm.distance_unit) }} - {{ form_widget(localUnitsForm.distance_unit) }} -
    -
    - -
    - {{ ps.label_with_help(('Volume unit'|trans), ('The default volume unit for your shop (e.g. "L" for liter, "gal" for gallon, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(localUnitsForm.volume_unit) }} - {{ form_widget(localUnitsForm.volume_unit) }} -
    -
    - -
    - {{ ps.label_with_help(('Dimension unit'|trans), ('The default dimension unit for your shop (e.g. "cm" for centimeter, "in" for inch, etc.).'|trans({}, 'Admin.International.Help'))) }} -
    - {{ form_errors(localUnitsForm.dimension_unit) }} - {{ form_widget(localUnitsForm.dimension_unit) }} -
    -
    -
    -
    - - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/index.html.twig deleted file mode 100644 index 23ea5fd3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Localization/index.html.twig +++ /dev/null @@ -1,62 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.International.Feature' %} - -{% set configurationForm, localUnitsForm, advancedForm = localizationForm.configuration, localizationForm.local_units, localizationForm.advanced %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Localization/Blocks/import_localization_pack_block.html.twig' %} -
    -
    - - {{ form_start(localizationForm, {'action': path('admin_localization_save_options')}) }} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Localization/Blocks/configuration.html.twig' %} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Localization/Blocks/local_units.html.twig' %} -
    -
    - {% include '@PrestaShop/Admin/Improve/International/Localization/Blocks/advanced_configuration.html.twig' %} -
    -
    - - {% block localization_settings_form_rest %} - {{ form_rest(localizationForm) }} - {% endblock %} - - {{ form_end(localizationForm) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/form.html.twig deleted file mode 100644 index a1271a83..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/form.html.twig +++ /dev/null @@ -1,79 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(taxForm) }} -
    -
    - {{ 'Taxes'|trans({}, 'Admin.Global') }} -
    - -
    -
    - {{ form_errors(taxForm) }} - - {% set nameHint %} - {{ 'Tax name to display in carts and on invoices (e.g. "VAT").'|trans({}, 'Admin.International.Help') }} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' }} - {% endset %} - - {{ ps.form_group_row(taxForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': nameHint, - }) }} - - {% set rateHint %} - {{ 'Format: XX.XX or XX.XXX (e.g. 19.60 or 13.925)'|trans({}, 'Admin.International.Help') }} - {% endset %} - - {{ ps.form_group_row(taxForm.rate, {}, { - 'label': 'Rate'|trans({}, 'Admin.International.Feature'), - 'help': rateHint, - }) }} - - {{ ps.form_group_row(taxForm.is_enabled, {}, { - 'label': 'Enable'|trans({}, 'Admin.Actions') - }) }} - - {% block tax_form_rest %} - {{ form_rest(taxForm) }} - {% endblock %} -
    -
    - - - -
    -{{ form_end(taxForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/tax_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/tax_options.html.twig deleted file mode 100644 index 75fce382..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/Blocks/tax_options.html.twig +++ /dev/null @@ -1,98 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(taxOptionsForm, {'action': path('admin_taxes_save_options')}) }} -
    -

    - {{ 'Tax options'|trans({}, 'Admin.International.Feature') }} -

    -
    -
    -
    - -
    - {{ form_widget(taxOptionsForm.options.enable_tax, {'attr': {'class': 'js-enable-tax'}}) }} - - {{ 'Select whether or not to include tax on purchases.'|trans({}, 'Admin.International.Help') }} - -
    -
    -
    - -
    - {{ form_widget(taxOptionsForm.options.display_tax_in_cart, {'attr': {'class': 'js-display-in-cart'}}) }} - - {{ 'Select whether or not to display tax on a distinct line in the cart.'|trans({}, 'Admin.International.Help') }} - -
    -
    -
    - -
    - {{ form_widget(taxOptionsForm.options.tax_address_type) }} -
    -
    -
    - -
    - {{ form_widget(taxOptionsForm.options.use_eco_tax) }} - {% if (taxOptionsForm.options.use_eco_tax.vars.value != 0) %} - - {{ 'If you disable the ecotax, the ecotax for all your products will be set to 0.'|trans({}, 'Admin.International.Help') }} - - {% endif %} -
    -
    - {% if taxOptionsForm.options.eco_tax_rule_group is defined %} - {{ ps.form_group_row(taxOptionsForm.options.eco_tax_rule_group, {}, { - label: 'Ecotax'|trans({}, 'Admin.International.Feature'), - help: 'Define the ecotax (e.g. French ecotax: 19.6%).'|trans({}, 'Admin.International.Help') - }) }} - {% endif %} - - {% block tax_options_rest %} - {{ form_rest(taxOptionsForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(taxOptionsForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/create.html.twig deleted file mode 100644 index 266b02c4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/create.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/International/Tax/Blocks/form.html.twig', {'taxForm': taxForm}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/edit.html.twig deleted file mode 100644 index bd2e280f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/edit.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Edit: %value%'|trans({'%value%': taxName}, 'Admin.Actions') %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Improve/International/Tax/Blocks/form.html.twig', {'taxForm': taxForm}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/index.html.twig deleted file mode 100644 index b372c346..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Tax/index.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutHeaderToolbarBtn = { - 'add' : { - 'href': path('admin_taxes_create'), - 'desc': 'Add new tax'|trans({}, 'Admin.International.Feature'), - 'icon': 'add_circle_outline' - } -} %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% trans_default_domain 'Admin.International.Feature' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': taxGrid} %} - {% include '@PrestaShop/Admin/Improve/International/Tax/Blocks/tax_options.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/TaxRulesGroup/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/TaxRulesGroup/index.html.twig deleted file mode 100644 index 020c659e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/TaxRulesGroup/index.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': taxRulesGroupGrid} %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/add_update_language.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/add_update_language.html.twig deleted file mode 100644 index 24ec7abc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/add_update_language.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{{ form_start(addUpdateLanguageForm, {action: path('admin_international_translations_add_update_language')}) }} - -
    -

    -
    arrow_drop_down_circle
    {{ 'Add / Update a language'|trans }} -

    - -
    -
    -
    -
    - -
    -
    -
    - -
    - {{ form_errors(addUpdateLanguageForm.iso_localization_pack) }} - {{ form_widget(addUpdateLanguageForm.iso_localization_pack, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    - {{ form_rest(addUpdateLanguageForm) }} -
    -
    - - -
    - -{{ form_end(addUpdateLanguageForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/copy_language.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/copy_language.html.twig deleted file mode 100644 index 546ad6ae..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/copy_language.html.twig +++ /dev/null @@ -1,95 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block copy_language %} - {{ form_start(copyLanguageForm, {action: path('admin_international_translations_copy_language')}) }} - -
    -

    - file_copy {{ 'Copy'|trans({}, 'Admin.Actions') }} -

    - -
    -
    -
    -
    - -
    -
    - -
    - -
    -
    - {{ form_errors(copyLanguageForm.from_language) }} - {{ form_widget(copyLanguageForm.from_language) }} - - {{ form_errors(copyLanguageForm.from_theme) }} - {{ form_widget(copyLanguageForm.from_theme) }} -
    -
    -
    - -
    - -
    -
    - {{ form_errors(copyLanguageForm.to_language) }} - {{ form_widget(copyLanguageForm.to_language) }} - - {{ form_errors(copyLanguageForm.to_theme) }} - {{ form_widget(copyLanguageForm.to_theme) }} -
    -
    -
    - {{ form_rest(copyLanguageForm) }} -
    -
    - - -
    - - {{ form_end(copyLanguageForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/export_language.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/export_language.html.twig deleted file mode 100644 index 683951af..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/export_language.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{{ form_start(exportLanguageForm, {action: path('admin_international_translations_export_theme')}) }} - -
    -

    - cloud_upload {{ 'Export a language'|trans }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(exportLanguageForm.iso_code) }} - {{ form_widget(exportLanguageForm.iso_code) }} -
    -
    - -
    - -
    - {{ form_errors(exportLanguageForm.theme_name) }} - {{ form_widget(exportLanguageForm.theme_name) }} -
    -
    - {{ form_rest(exportLanguageForm) }} -
    -
    - - -
    - -{{ form_end(exportLanguageForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/modify_translations.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/modify_translations.html.twig deleted file mode 100644 index 15706aa6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/Blocks/modify_translations.html.twig +++ /dev/null @@ -1,110 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain 'Admin.International.Feature' %} - -{% block modify_translations %} - {{ form_start(modifyTranslationsForm, {method: 'get', action: path('admin_international_translations_modify')}) }} - -
    -

    - description {{ 'Modify translations'|trans }} -

    - -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(modifyTranslationsForm.translation_type) }} - {{ form_widget(modifyTranslationsForm.translation_type, {'attr': {'class': 'js-translation-type'}}) }} -
    -
    -
    - -
    - {{ form_errors(modifyTranslationsForm.email_content_type) }} - {{ form_widget(modifyTranslationsForm.email_content_type, {'attr': {'class': 'js-email-content-type'}}) }} -
    -
    -
    - -
    - {{ form_errors(modifyTranslationsForm.theme) }} - {{ form_widget(modifyTranslationsForm.theme) }} -
    -
    -
    - -
    - {{ form_errors(modifyTranslationsForm.module) }} - {{ form_widget(modifyTranslationsForm.module, {'attr': {'data-minimumResultsForSearch': '7', 'data-toggle': 'select2'}}) }} -
    -
    -
    - -
    - {{ form_errors(modifyTranslationsForm.language) }} - {{ form_widget(modifyTranslationsForm.language) }} -
    -
    - {{ form_rest(modifyTranslationsForm) }} -
    -
    - - -
    - - {{ form_end(modifyTranslationsForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/translations_settings.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/translations_settings.html.twig deleted file mode 100644 index b4b9b2a4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/International/Translations/translations_settings.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.International.Feature' %} - -{% block content %} -
    -
    -
    - {% block translations_kpis_row %} -
    - {{ render(controller( - 'PrestaShopBundle:Admin\\Common:renderKpiRow', - { 'kpiRow': kpiRow } - )) }} -
    - {% endblock %} -
    -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Translations/Blocks/modify_translations.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Translations/Blocks/add_update_language.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Translations/Blocks/export_language.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Improve/International/Translations/Blocks/copy_language.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Module/addons_store.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Module/addons_store.html.twig deleted file mode 100644 index 19eeadbb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Module/addons_store.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {{ pageContent|raw }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig deleted file mode 100644 index c6784e76..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig +++ /dev/null @@ -1,70 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Payment.Feature' %} - -{% block payment_methods_module_list %} - {% if paymentModules|length > 0 %} -
    - {% for module in paymentModules %} -
    -
    -
    - {{ module.attributes.displayName }} -
    -
    -
    -

    - {{ module.attributes.displayName|raw }} - - {{ 'v%version% - by %author%'|trans({ '%version%' : module.attributes.version, '%author%' : module.attributes.author}, 'Admin.Modules.Feature') }} - -

    -

    - {{ module.attributes.description|raw }} -

    -
    - {% if module.attributes.is_configurable %} - - {% endif %} -
    - {% endfor %} -
    - {% else %} - - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/payment_methods.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/payment_methods.html.twig deleted file mode 100644 index 8ac67d68..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/PaymentMethods/payment_methods.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Payment.Feature' %} - -{% block content %} -
    -
    -
    - {% if isSingleShopContext %} -
    -

    - credit_card {{ 'Active payment'|trans }} -

    -
    - {% include '@PrestaShop/Admin/Improve/Payment/PaymentMethods/Blocks/payment_modules_list.html.twig' %} -
    -
    - {% else %} - - {% endif %} -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/Blocks/payment_preferences_form_block.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/Blocks/payment_preferences_form_block.html.twig deleted file mode 100644 index 6b7cffb4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/Blocks/payment_preferences_form_block.html.twig +++ /dev/null @@ -1,141 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% trans_default_domain 'Admin.Payment.Feature' %} - -{% block payment_preferences_form %} - {{ form_start(paymentPreferencesForm) }} - {% block payment_modules_currency_restrictions %} -
    -

    - euro_symbol - {{ 'Currency restrictions'|trans({}, 'Admin.Payment.Feature') }} -

    -
    -

    - - {{ 'Please mark each checkbox for the currency, or currencies, for which you want the payment module(s) to be available.'|trans({}, 'Admin.Payment.Help') }} - -

    - -
    - {{ form_widget(paymentPreferencesForm.payment_module_preferences.currency_restrictions) }} -
    -
    - -
    - {% endblock %} - - {% block payment_modules_group_restrictions %} -
    -

    - group - {{ 'Group restrictions'|trans({}, 'Admin.Payment.Feature') }} -

    -
    -

    - - {{ 'Please mark each checkbox for the customer group(s), for which you want the payment module(s) to be available.'|trans({}, 'Admin.Payment.Help') }} - -

    - -
    - {{ form_widget(paymentPreferencesForm.payment_module_preferences.group_restrictions) }} -
    -
    - -
    - {% endblock %} - - {% block payment_modules_country_restrictions %} -
    -

    - public - {{ 'Country restrictions'|trans({}, 'Admin.Payment.Feature') }} -

    -
    -

    - - {{ 'Please mark each checkbox for the country, or countries, in which you want the payment module(s) to be available.'|trans({}, 'Admin.Payment.Help') }} - -

    - -
    - {{ form_widget(paymentPreferencesForm.payment_module_preferences.country_restrictions) }} -
    -
    - -
    - {% endblock %} - - {% block payment_modules_carrier_restrictions %} -
    -

    - local_shipping - {{ 'Carrier restrictions'|trans({}, 'Admin.Payment.Feature') }} -

    -
    -

    - - {{ 'Please mark each checkbox for the carrier, or carrier, for which you want the payment module(s) to be available.'|trans({}, 'Admin.Payment.Help') }} - -

    -
    - {{ form_widget(paymentPreferencesForm.payment_module_preferences.carrier_restrictions) }} -
    -
    - -
    - {% endblock %} - - {% block payment_preferences_block_rest %} - {{ form_rest(paymentPreferencesForm) }} - {% endblock %} - - {{ form_end(paymentPreferencesForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/payment_preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/payment_preferences.html.twig deleted file mode 100644 index bbfefd49..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Payment/Preferences/payment_preferences.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain 'Admin.Payment.Feature' %} - -{% block content %} -
    -
    -
    - {% if not isSingleShopContext %} - - {% elseif paymentModulesCount == 0 %} - - {% else %} - - - {% include '@PrestaShop/Admin/Improve/Payment/Preferences/Blocks/payment_preferences_form_block.html.twig' %} - {% endif %} -
    -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_carrier_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_carrier_options.html.twig deleted file mode 100644 index 06386183..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_carrier_options.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shipping.Feature" %} - -{% block shipping_preferences_carrier_options %} -
    -
    -

    - local_shipping {{ 'Carrier options'|trans }} -

    -
    -
    -
    - -
    - {{ form_errors(carrierOptionsForm.default_carrier) }} - {{ form_widget(carrierOptionsForm.default_carrier) }} - {{ 'Your shop\'s default carrier'|trans({}, 'Admin.Shipping.Help') }} -
    -
    -
    - -
    - {{ form_errors(carrierOptionsForm.carrier_default_order_by) }} - {{ form_widget(carrierOptionsForm.carrier_default_order_by) }} - {{ 'This will only be visible in the front office.'|trans({}, 'Admin.Shipping.Help') }} -
    -
    -
    - -
    - {{ form_errors(carrierOptionsForm.carrier_default_order_way) }} - {{ form_widget(carrierOptionsForm.carrier_default_order_way) }} - {{ 'This will only be visible in the front office.'|trans({}, 'Admin.Shipping.Help') }} -
    -
    -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_handling.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_handling.html.twig deleted file mode 100644 index 386f27e4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_handling.html.twig +++ /dev/null @@ -1,83 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Shipping.Feature" %} - -{% block shipping_preferences_handling %} -
    -
    -

    - filter_none {{ 'Handling'|trans }} -

    -
    -
    -
    -
    - -
    -
    - -
    - -
    - {{ form_errors(handlingForm.shipping_handling_charges) }} - {{ form_widget(handlingForm.shipping_handling_charges) }} -
    -
    - -
    - -
    - {{ form_errors(handlingForm.free_shipping_price) }} - {{ form_widget(handlingForm.free_shipping_price) }} -
    -
    - -
    - -
    - {{ form_errors(handlingForm.free_shipping_weight) }} - {{ form_widget(handlingForm.free_shipping_weight) }} -
    -
    -
    -
    - -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/preferences.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/preferences.html.twig deleted file mode 100644 index 511b7098..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Improve/Shipping/Preferences/preferences.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set handlingForm, carrierOptionsForm = form.handling, form.carrier_options %} - -{% block content %} - {{ form_start(form, {'attr': {'class': 'form', 'id': 'configuration_form'}}) }} -
    - {# Block for "Handling" fieldset #} - {% include '@PrestaShop/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_handling.html.twig' %} - - {# Block for "Carrier options" fieldset #} - {% include '@PrestaShop/Admin/Improve/Shipping/Preferences/Blocks/shipping_preferences_carrier_options.html.twig' %} -
    - {{ form_end(form) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_button.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_button.html.twig deleted file mode 100644 index 1ec4af37..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_button.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set displayAction = action|title|replace({'_': " "})|trans({}, transDomain[action]) %} - -{% if (action == 'configure') %} - - - {{ displayAction }} - - -{% else %} - -
    - -
    - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_menu.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_menu.html.twig deleted file mode 100644 index 5646edc0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/action_menu.html.twig +++ /dev/null @@ -1,71 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set url, priceRaw, priceDisplay, url_active, urls, name, transDomains = - module.attributes.url, - module.attributes.price.raw, - module.attributes.price.displayPrice, - module.attributes.url_active, - module.attributes.urls, - module.attributes.name, - module.attributes.actionTranslationDomains -%} -
    - {% if url_active == 'buy' %} - - {{ 'Discover'|trans({}, 'Admin.Modules.Feature') }} - - {% elseif urls|length %} - {% include '@PrestaShop/Admin/Module/Includes/action_button.html.twig' with { - 'name': name, - 'classes_form': 'btn-group form-action-button', - 'classes' : 'btn btn-primary-reverse btn-outline-primary', - 'url': urls[url_active], - 'action': url_active, - 'transDomain': transDomains} - %} - {% if (urls|length > 1) %} - - - {{ 'Toggle Dropdown'|trans({}, 'Admin.Modules.Feature') }} - - {% endif %} - {% endif %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid.html.twig deleted file mode 100644 index 11a6ee78..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid.html.twig +++ /dev/null @@ -1,121 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set isModuleActive = module.database.active %} - -
    -
    -
    -
    - {{ module.attributes.displayName }} -
    -

    - {% if module.attributes.displayName %} - {{ module.attributes.displayName|raw }} - {% else %} - {{ module.attributes.name }} - {% endif %} - {% for pico in module.attributes.picos %} - {{pico.label}} - {% endfor %} -

    -
    - {% block addon_version %} - {% if module.attributes.productType == "service" %} - {{ 'Service by %author%'|trans({'%author%' : '' ~ module.attributes.author ~ ''}, 'Admin.Modules.Feature')|raw }} - {% else %} - {{ 'v%version% - by %author%'|trans({ '%version%' : module.attributes.version, '%author%' : '' ~ module.attributes.author ~ '' }, 'Admin.Modules.Feature')|raw }} - {% endif %} - {% endblock %} -
    -
    -
    - {% block addon_description %} -
    - {{ module.attributes.description|raw }} - {% if module.attributes.description|length > 0 and module.attributes.description|length < module.attributes.fullDescription|length %} - ... - {% endif %} -
    -
    - {% if module.attributes.id != "0" %} - {{ 'Read More'|trans({}, 'Admin.Modules.Feature') }} - {% endif %} -
    - {% endblock %} -
    - -
    -
    - {% set badges = module.attributes.badges %} - {% if badges %} - {% set badge = badges|first %} - {{badge.label}} - {{badge.label}} - {% endif %} -
    -
    - {% if module.attributes.nbRates > 0 %} -
    - ({{ module.attributes.nbRates }}) -
    - {% endif %} -
    - {% if module.attributes.url_active == 'buy' and module.attributes.price.raw != '0.00' %} - {{ module.attributes.price.displayPrice }} - {% elseif module.attributes.url_active != 'buy' %} - {{ 'Free'|trans({}, 'Admin.Modules.Feature') }} - {% endif %} -
    - {% if requireBulkActions is defined and requireBulkActions == true %} -
    - -
    - {% endif %} - {% include '@PrestaShop/Admin/Module/Includes/action_menu.html.twig' with { 'module': module, 'level' : level } %} -
    - {% include '@PrestaShop/Admin/Module/Includes/modal_read_more.html.twig' with { 'module': module, 'additionalModalSuffix': additionalModalSuffix|default(''), 'level' : level } %} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm.html.twig' with { 'module': module } %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid_addons.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid_addons.html.twig deleted file mode 100644 index 54777d7c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_grid_addons.html.twig +++ /dev/null @@ -1,33 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - - {{ 'Exit to PrestaShop Addons Marketplace'|trans({}, 'Admin.Modules.Feature') }} - - {{ 'See all results for your search on'|trans({}, 'Admin.Modules.Feature') }}
    - {{ 'PrestaShop Addons Marketplace'|trans({}, 'Admin.Modules.Feature') }} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list.html.twig deleted file mode 100644 index 5b0a1686..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list.html.twig +++ /dev/null @@ -1,112 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set isModuleActive = module.database.active|default('0') %} - -
    -
    -
    -
    -
    - {{ module.attributes.displayName }} -
    -
    -
    -
    -

    - {% if module.attributes.displayName %} - {{ module.attributes.displayName|raw }} - - {% else %} - {{ module.attributes.name }} - {% endif %} - - {% for pico in module.attributes.picos %} - {{pico.label}} {{ pico.text}} - {% endfor %} - -

    -
    -
    - - {% block addon_version %} - {% if module.attributes.productType == "service" %} - {{ 'Service by %author%'|trans({'%author%' : '' ~ module.attributes.author ~ ''}, 'Admin.Modules.Feature')|raw }} - {% else %} - {{ 'v%version% - by %author%'|trans({ '%version%' : module.attributes.version, '%author%' : '' ~ module.attributes.author ~ '' }, 'Admin.Modules.Feature')|raw }} - {% endif %} - {% endblock %} - -
    -
    - {% block addon_description %} - {{ module.attributes.description|raw }} - {% if module.attributes.description|length > 0 and module.attributes.description|length < module.attributes.fullDescription|length %} - ... - {% endif %} - - {% if module.attributes.id != "0" %} - {{ 'Read More'|trans({}, 'Admin.Modules.Feature') }} - {% endif %} - - {% endblock %} -
    -
    - {% if requireBulkActions is defined and requireBulkActions == true %} -
    - -
    - {% endif %} - {% include '@PrestaShop/Admin/Module/Includes/action_menu.html.twig' with { 'module': module } %} -
    - {% include '@PrestaShop/Admin/Module/Includes/modal_read_more.html.twig' with { 'module': module, 'additionalModalSuffix': additionalModalSuffix|default('') } %} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm.html.twig' with { 'module': module } %} -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list_addons.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list_addons.html.twig deleted file mode 100644 index 3f55f275..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_list_addons.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    - - {{ 'Exit to PrestaShop Addons Marketplace'|trans({}, 'Admin.Modules.Feature') }} - - {{ 'See all results for your search on'|trans({}, 'Admin.Modules.Feature') }}
    - {{ 'PrestaShop Addons Marketplace'|trans({}, 'Admin.Modules.Feature') }} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_manage_installed.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_manage_installed.html.twig deleted file mode 100644 index b5877ae4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_manage_installed.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/card_list.html.twig' %} - -{# Twig extension for "Addons to update" part in notification page #} - -{# Display database version #} -{% block addon_version %} - {% if module.attributes.productType == "service" %} - {{ 'Service by %author%'|trans({'%author%' : '' ~ module.attributes.author ~ ''}, 'Admin.Modules.Feature')|raw }} - {% else %} - {{ 'v%version% - by %author%'|trans({ '%version%' : module.attributes.version, '%author%' : '' ~ module.attributes.author ~ '' }, 'Admin.Modules.Feature')|raw }} - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_configure.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_configure.html.twig deleted file mode 100644 index 281e1d8b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_configure.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/card_manage_installed.html.twig' %} - -{# Twig extension for "Addons to configure" part in notification page #} - -{# Display the warning message instead of the addon description #} -{% block addon_description %} - {{module.attributes.warning}} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_update.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_update.html.twig deleted file mode 100644 index 8c4458c1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/card_notification_update.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/card_list.html.twig' %} - -{# Twig extension for "Addons to update" part in notification page #} - -{# Display "Old version -> New version" #} -{% block addon_version %} - v{{ module.database.version }} arrow_forward v{{ module.attributes.version_available }} -{% endblock %} - -{# Display changelog instead of the description #} -{% block addon_description %} - {% if module.attributes.changeLog is defined %} -
      - {% for version, lines in module.attributes.changeLog|arrayCast %} -
    • {{ version }}: - {% for line in lines %} - {{ line }}
      - {% endfor %} -
    • - {% endfor %} -
    - {% else %} - {{ 'No changelog provided'|trans({}, 'Admin.Modules.Notification') }} - {% endif %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_card.html.twig deleted file mode 100644 index 78b9e125..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_card.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - {{ category.name|trans({}, 'Admin.Modules.Feature') }} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_grid.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_grid.html.twig deleted file mode 100644 index 14897e95..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/categories_grid.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - {% for category in categories.subMenu|arrayCast %} - {# Module Card #} - {% include '@PrestaShop/Admin/Module/Includes/categories_card.html.twig' with { 'category': category } %} - {% endfor %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_bulk.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_bulk.html.twig deleted file mode 100644 index 96331f5e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_bulk.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories.html.twig deleted file mode 100644 index d2e3e88c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories.html.twig +++ /dev/null @@ -1,65 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories_catalog.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories_catalog.html.twig deleted file mode 100644 index ebc74268..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_categories_catalog.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_status.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_status.html.twig deleted file mode 100644 index e5089d65..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/dropdown_status.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid.html.twig deleted file mode 100644 index 9d9f5e16..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid.html.twig +++ /dev/null @@ -1,38 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - {% for index, module in modules %} - {% block addon_card %} - {% include '@PrestaShop/Admin/Module/Includes/card_list.html.twig' with { 'index': index, 'module': module, 'origin': origin|default('none'), 'category': id } %} - {% endblock %} - {% endfor %} - - {% block addon_search_card %} - {% if requireAddonsSearch is defined and requireAddonsSearch == true %} - {% include '@PrestaShop/Admin/Module/Includes/card_grid_addons.html.twig'%} - {% include '@PrestaShop/Admin/Module/Includes/card_list_addons.html.twig'%} - {% endif %} - {% endblock %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_loader.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_loader.html.twig deleted file mode 100644 index ea89f01f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_loader.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{#Simulate a bunch of module card #} -
    - {% for i in 0..8 %} - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - {% endfor %} -
    - -
    -
    -
    -
    - -
    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig deleted file mode 100644 index 11a9ef6e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_empty.html.twig +++ /dev/null @@ -1,33 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block catalog_category_empty %} -
    -

    - {{ 'You do not have module in « %categoryName% ».' | trans({'%categoryName%': category.name}, 'Admin.Modules.Feature') }}
    - {{ 'Discover the best-selling modules of this category in the %link% page.' | trans({'%link%': ''~category.name~''}, 'Admin.Modules.Feature') | raw }} -

    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_installed.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_installed.html.twig deleted file mode 100644 index a40c8bf7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_installed.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/grid.html.twig' %} - -{% block addon_card %} - {% include '@PrestaShop/Admin/Module/Includes/card_manage_installed.html.twig' with { 'display_type': display_type, 'module': module, 'origin': origin|default('none'), 'category': id } %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_recently_used.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_recently_used.html.twig deleted file mode 100644 index f595b399..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_manage_recently_used.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block catalog_recently_used %} -
    - {{ 'Recently Used' | trans({}, 'Admin.Modules.Feature') }} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_configure.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_configure.html.twig deleted file mode 100644 index da30ebc9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_configure.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/grid.html.twig' %} - -{% block addon_card %} - {% include '@PrestaShop/Admin/Module/Includes/card_notification_configure.html.twig' - with { - 'module': module, - 'display_type': display_type, - 'origin': origin|default('none') - } - %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_update.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_update.html.twig deleted file mode 100644 index 2d111b2b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/grid_notification_update.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/Includes/grid.html.twig' %} - -{% block addon_card %} - {% include '@PrestaShop/Admin/Module/Includes/card_notification_update.html.twig' - with { - 'module': module, - 'display_type': display_type, - 'origin': origin|default('none') - } - %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/menu_top.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/menu_top.html.twig deleted file mode 100644 index 9c0b2677..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/menu_top.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    - -
    - {% if topMenuData is defined %} -
    -

    {{ 'Category' | trans({}, 'Admin.Catalog.Feature') }}

    - {% include '@PrestaShop/Admin/Module/Includes/dropdown_categories.html.twig' with { 'topMenuData': topMenuData } %} -
    - {% endif %} - - {% if requireFilterStatus is defined and requireFilterStatus == true %} -
    -

    {{ 'Status' | trans({}, 'Admin.Global') }}

    - {% include '@PrestaShop/Admin/Module/Includes/dropdown_status.html.twig' %} -
    - {% endif %} - - {% if level > constant('PrestaShopBundle\\Security\\Voter\\PageVoter::LEVEL_UPDATE') and bulkActions is defined %} -
    -

    {{ 'Bulk Actions'|trans({}, 'Admin.Global') }}

    - {% include '@PrestaShop/Admin/Module/Includes/dropdown_bulk.html.twig' %} -
    - {% endif %} -
    -
    - -
    - -{% set js_translatable = { - "Search - placeholder": "Search modules: keyword, name, author..."|trans({}, 'Admin.Modules.Help'), - }|merge(js_translatable) %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_addons_connect.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_addons_connect.html.twig deleted file mode 100644 index 1b6da76e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_addons_connect.html.twig +++ /dev/null @@ -1,110 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm.html.twig deleted file mode 100644 index 348ee6a3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm.html.twig +++ /dev/null @@ -1,124 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if module.attributes.urls|length >= 1 %} - {% for module_action, module_url in module.attributes.urls %} - {% if module_action in ['disable', 'uninstall', 'reset'] %} - - {% endif %} - {% endfor %} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_bulk_action.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_bulk_action.html.twig deleted file mode 100644 index ada12a80..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_bulk_action.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_prestatrust.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_prestatrust.html.twig deleted file mode 100644 index 31fd1d20..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_confirm_prestatrust.html.twig +++ /dev/null @@ -1,73 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_import.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_import.html.twig deleted file mode 100644 index 1148403f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_import.html.twig +++ /dev/null @@ -1,90 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more.html.twig deleted file mode 100644 index 3e5675a4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more.html.twig +++ /dev/null @@ -1,27 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more_content.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more_content.html.twig deleted file mode 100644 index 752676ea..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/modal_read_more_content.html.twig +++ /dev/null @@ -1,207 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set ats = module.attributes %} -{% set name, displayName, nbRates, - starsRate, img, serviceUrl, version, cover, additionalDescription, - fullDescription, changeLog, customerBenefits, demoVideo, author, notFoundImg, features, badges = - ats.name, ats.displayName, ats.nbRates, ats.starsRate, ats.img, - ats.serviceUrl is defined and ats.serviceUrl|length > 0 ? ats.serviceUrl : false, - ats.version, ats.cover, - ats.additionalDescription is defined and ats.additionalDescription|length > 0 ? ats.additionalDescription : false, - ats.fullDescription is defined and ats.fullDescription|length > 0 ? ats.fullDescription : false, - ats.changeLog is defined and ats.changeLog|length > 0 ? ats.changeLog : false, - ats.customer_benefits is defined and ats.customer_benefits|length > 0 ? ats.customer_benefits : false, - ats.demo_video is defined and ats.demo_video|length > 0 ? ats.demo_video : false, - ats.author, 'https://cdn4.iconfinder.com/data/icons/ballicons-2-free/100/box-512.png', - ats.features, - ats.badges is defined and ats.badges|length > 0 ? ats.badges : false -%} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/see_more.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/see_more.html.twig deleted file mode 100644 index ccf5e0d4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/see_more.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -

    - - -

    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/sorting.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/sorting.html.twig deleted file mode 100644 index 77e8673b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/sorting.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    - {{ '%nbModules% modules and services selected for you'|trans({'%nbModules%' : totalModules}, 'Admin.Modules.Feature') }} - - -
    -
    -
    -
    - -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/tab-module-line.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/tab-module-line.html.twig deleted file mode 100644 index eff8f461..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/Includes/tab-module-line.html.twig +++ /dev/null @@ -1,74 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% - set moduleImage = module.attributes.img is null ? - constant('_MODULE_DIR_') ~ module.attributes.name ~ '/' ~ module.attributes.logo : - module.attributes.img -%} - - - {{ module.attributes.name }} - - -
    -
    - {{ module.attributes.name }} - {{ module.attributes.displayName }} - v{{ module.attributes.version }} - by {{ module.attributes.author }} - {% if module.attributes.type is not empty and module.attributes.type == 'addonsBought' %} - - {{ 'Bought'|trans({}, 'Admin.Modules.Help') }} - {% elseif module.attributes.type is not empty and module.attributes.type == 'addonsMustHave' %} - - {{ 'Popular'|trans({}, 'Admin.Modules.Help') }} - {% elseif module.attributes.type is not empty and module.attributes.type == 'addonsPartner' %} - - {{ 'Official'|trans({}, 'Admin.Modules.Help') }} - {% elseif module.attributes.id is defined and module.attributes.id >= 0 %} - {% if module.attributes.version_addons is defined and module.attributes.version_addons %} - {{ 'Need update'|trans({}, 'Admin.Modules.Help') }} - {% endif %} - {% endif %} -
    -

    - {% if module.attributes.description is defined and module.attributes.description is not empty %} - {{ module.attributes.description }} - {% endif %} -

    - {% if (module.attributes.message is defined and module.attributes.name is not empty) and (module.attributes.type is not defined or module.attributes.type != 'addonsMustHave' or module.attributes.type != 'addonsNative') %} - - {% endif %} -
    - - - {{ include('@PrestaShop/Admin/Module/Includes/action_menu.html.twig', {'module': module}) }} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/alerts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/alerts.html.twig deleted file mode 100644 index 50f1eb6a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/alerts.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/common.html.twig' %} - -{% block content %} - {# Addons connect modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_addons_connect.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# PrestaTrust modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm_prestatrust.html.twig' %} - {# Contains toolbar-nav for module page #} - {% include '@PrestaShop/Admin/Module/Includes/modal_import.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# Actual Page Content #} -
    -
    -
    - {{ '%nbModules% modules to configure'|trans({'%nbModules%' : modules|length}, 'Admin.Modules.Feature') }} - - -
    - {% include '@PrestaShop/Admin/Module/Includes/grid_notification_configure.html.twig' with { 'modules': modules, 'display_type': 'list', id: 'notification', 'category': 'notification' } %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/catalog-refresh.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/catalog-refresh.html.twig deleted file mode 100644 index 4c4af3a3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/catalog-refresh.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - {% for category in categories.subMenu %} - {% for module in category.modules %} - {% include '@PrestaShop/Admin/Module/Includes/card_grid.html.twig' with { 'module': module, 'origin': origin|default('none'), 'level' : level, 'category': category.refMenu } %} - {% endfor %} - {% endfor %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/catalog.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/catalog.html.twig deleted file mode 100644 index 1ae577fb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/catalog.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/common.html.twig' %} - -{% block javascripts %} - {{ parent() }} - -{% endblock %} - -{% block content %} -
    -
    - {# Addons connect modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_addons_connect.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# PrestaTrust modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm_prestatrust.html.twig' %} - {# Contains toolbar-nav for module page #} - {% include '@PrestaShop/Admin/Module/Includes/modal_import.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# Contains menu with Selection/Categories/Popular and Tag Search #} - {% include '@PrestaShop/Admin/Module/Includes/menu_top.html.twig' %} - {# Temporary loader until ajax has finished and display the full catalog #} - {% include '@PrestaShop/Admin/Module/Includes/grid_loader.html.twig' %} - {# Module Categories Grid #} - {% if topMenuData.categories is defined %} - {% include '@PrestaShop/Admin/Module/Includes/categories_grid.html.twig' with { 'categories' : topMenuData.categories } %} - {% endif %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/common.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/common.html.twig deleted file mode 100644 index 67dac761..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/common.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} - -{% set js_translatable = { - "Bulk Action - One module minimum": "You need to select at least one module to use the bulk action."|trans({}, 'Admin.Modules.Notification'), - "Bulk Action - Request not found": 'The action "[1]" is not available, impossible to perform your request.'|trans({}, 'Admin.Modules.Notification'), - "Bulk Action - Request not available for module": "The action [1] is not available for module [2]. Skipped."|trans({}, 'Admin.Modules.Notification'), -}|merge(js_translatable) -%} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/manage.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/manage.html.twig deleted file mode 100644 index 3e875468..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/manage.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/common.html.twig' %} - -{% block content %} -
    -
    - {# Bulk Action confirm modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm_bulk_action.html.twig' %} - {# PrestaTrust modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm_prestatrust.html.twig' %} - {# Addons connect modal with level authorization#} - {% include '@PrestaShop/Admin/Module/Includes/modal_addons_connect.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# Contains toolbar-nav for module page with level authorization #} - {% include '@PrestaShop/Admin/Module/Includes/modal_import.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# Contains menu with Selection/Categories/Popular and Tag Search #} - {% include '@PrestaShop/Admin/Module/Includes/menu_top.html.twig' with { 'topMenuData': topMenuData, 'bulkActions': bulkActions } %} - - {% include '@PrestaShop/Admin/Module/Includes/grid_manage_recently_used.html.twig' with { 'display_type': 'list', 'origin': 'manage' } %} - - {% block catalog_categories_listing %} - {% for category in categories.subMenu %} -
    - {{ category.name | trans({}, 'Admin.Modules.Feature') }} - - {% if category.modules is empty %} - {% include '@PrestaShop/Admin/Module/Includes/grid_manage_empty.html.twig' with { 'category': category, 'display_type': 'list', 'origin': 'manage' } %} - {% else %} - {% include '@PrestaShop/Admin/Module/Includes/grid_manage_installed.html.twig' with { 'modules': category.modules, 'display_type': 'list', 'origin': 'manage', 'id': category.refMenu } %} - - {% block addon_card_see_more %} - {% if (category.modules | length) > maxModulesDisplayed %} - {% include '@PrestaShop/Admin/Module/Includes/see_more.html.twig' with { 'id': category.refMenu } %} - {% endif %} - {% endblock %} - {% endif %} -
    - {% endfor %} - {% endblock %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/tab-modules-list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/tab-modules-list.html.twig deleted file mode 100644 index 7149f4f6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/tab-modules-list.html.twig +++ /dev/null @@ -1,77 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set modulesListShouldBeDisplayed = (modulesList is defined and modulesList is not empty) %} -{% if modulesListShouldBeDisplayed == true %} -
    -
    - -
    -
    - -{% endif %} - - -{% if modulesListShouldBeDisplayed == true %} - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Module/updates.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Module/updates.html.twig deleted file mode 100644 index 2b99b7ab..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Module/updates.html.twig +++ /dev/null @@ -1,50 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/Module/common.html.twig' %} - -{% block content %} - {# Addons connect modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_addons_connect.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# PrestaTrust modal #} - {% include '@PrestaShop/Admin/Module/Includes/modal_confirm_prestatrust.html.twig' %} - {# Contains toolbar-nav for module page #} - {% include '@PrestaShop/Admin/Module/Includes/modal_import.html.twig' with { 'level' : level, 'errorMessage' : errorMessage } %} - {# Actual Page Content #} -
    -
    -
    - {{ '%nbModules% modules to update'|trans({'%nbModules%' : modules|length}, 'Admin.Modules.Feature') }} - - - {% if (modules|length > 1) and (level >= constant('PrestaShopBundle\\Security\\Voter\\PageVoter::LEVEL_UPDATE')) %} - {{ "Upgrade All"|trans({}, 'Admin.Modules.Feature') }} - {% endif %} -
    - {% include '@PrestaShop/Admin/Module/Includes/grid_notification_update.html.twig' with { 'modules': modules, 'display_type': 'list', id: 'update', 'level' : level, 'category': 'notification' } %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/filters.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/filters.html.twig deleted file mode 100644 index ec7c5c80..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/filters.html.twig +++ /dev/null @@ -1,150 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    - {% block product_catalog_filter_by_categories %} - - {% endblock %} - - {% block product_catalog_filter_bulk_actions %} -
    - {% set buttons_action = [ - { - "onclick": "bulkProductAction(this, 'activate_all');", - "icon": "radio_button_checked", - "label": "Activate selection"|trans({}, 'Admin.Actions') - }, { - "onclick": "bulkProductAction(this, 'deactivate_all');", - "icon": "radio_button_unchecked", - "label": "Deactivate selection"|trans({}, 'Admin.Actions') - } - ] %} - - {% set buttons_action = buttons_action|merge([ - { - "divider": true - }, { - "onclick": "bulkProductAction(this, 'duplicate_all');", - "icon": "content_copy", - "label": "Duplicate selection"|trans({}, 'Admin.Actions') - } - ]) %} - - - {% set buttons_action = buttons_action|merge([ - { - "divider": true - }, { - "onclick": "bulkProductAction(this, 'delete_all');", - "icon": "delete", - "label": "Delete selection"|trans({}, 'Admin.Actions') - } - ]) %} - - {% include '@PrestaShop/Admin/Helpers/dropdown_menu.html.twig' with { - 'div_style': "btn-group dropdown bulk-catalog", - 'button_id': "product_bulk_menu", - 'disabled': true, - 'menu_label': "Bulk actions"|trans({}, 'Admin.Global'), - 'buttonType': "outline-secondary", - 'menu_icon': "icon-caret-up", - 'items': buttons_action - } %} -
    - {% endblock %} -
    -
    - - {% block product_catalog_filter_select_all %} -
    -
    -
    - -
    -
    -
    - {% endblock %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig deleted file mode 100644 index 1ab854fe..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Blocks/tools.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_edit_dropdown.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_edit_dropdown.html.twig deleted file mode 100644 index 10b4f528..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_edit_dropdown.html.twig +++ /dev/null @@ -1,67 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set buttonType = buttonType|default('primary') %} -{% set right = right|default(false) %} - -
    - - {% if default_item is defined %} - - {% if default_item.icon %} - {{ default_item.icon }} - {% endif %} - {{ default_item.label|default('') }} - - {% endif %} - - - - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_products.html.twig deleted file mode 100644 index 4a979369..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Forms/form_products.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    - -
    -
    - -
    -
    - {% block product_catalog_form_table %} - {{ include('@Product/CatalogPage/Lists/products_table.html.twig', { - 'limit': limit, - 'orderBy': orderBy, - 'offset': offset, - 'sortOrder': sortOrder, - 'filter_category': filter_category, - 'filter_column_id_product': filter_column_id_product, - 'filter_column_name': filter_column_name, - 'filter_column_reference': filter_column_reference, - 'filter_column_name_category': filter_column_name_category, - 'filter_column_price': filter_column_price, - 'filter_column_sav_quantity': filter_column_sav_quantity, - 'filter_column_active':filter_column_active, - 'has_category_filter': has_category_filter, - 'activate_drag_and_drop': activate_drag_and_drop, - 'products': products, - 'last_sql': last_sql - }) - }} - {% endblock %} -
    -
    - - {% if product_count_filtered > 20 %} -
    -
    - - {{ render(controller('PrestaShopBundle:Admin\\Common:pagination', { - 'limit': limit, - 'offset': offset, - 'total': product_count_filtered, - 'caller_route': app.request.attributes.get('_route'), - 'caller_parameters': pagination_parameters, - 'limit_choices': pagination_limit_choices - })) }} -
    -
    - {% endif %} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig deleted file mode 100644 index 4a4e5d7b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list.html.twig +++ /dev/null @@ -1,143 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - {% for product in products %} - {% block product_catalog_form_table_row %} - - -
    - -
    - - - - - - {{ product.image|raw }} - - - {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} - - - {{ product.reference|default('') }} - - - {{ product.name_category|default('') }} - - - {{ product.price|default('N/A'|trans({}, 'Admin.Global')) }} - - - {{ product.price_final|default('N/A'|trans({}, 'Admin.Global')) }} - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - - {% if product.sav_quantity is defined and product.sav_quantity > 0 %} - {{ product.sav_quantity }} - {% else %} - {{ product.sav_quantity|default('N/A'|trans({}, 'Admin.Global')) }} - {% endif %} - - - {% else %} - - {% endif %} - - {% if product.active|default(0) == 0 %} - - clear - - {% else %} - - check - - {% endif %} - - {% if product.position is defined %} - - {% if activate_drag_and_drop %} - - {% endif %} - {{ product.position }} - - - - {% endif %} - -
    - - {% set buttons_action = [ - { - "href": product.preview_url|default('#'), - "target": "_blank", - "icon": "remove_red_eye", - "label": "Preview"|trans({}, 'Admin.Actions') - } - ] %} - - {% set buttons_action = buttons_action|merge([ - { - "onclick": "unitProductAction(this, 'duplicate');", - "icon": "content_copy", - "label": "Duplicate"|trans({}, 'Admin.Actions') - } - ]) %} - - {% set buttons_action = buttons_action|merge([ - { - "onclick": "unitProductAction(this, 'delete');", - "icon": "delete", - "label": "Delete"|trans({}, 'Admin.Actions') - } - ]) %} - - {% include '@Product/CatalogPage/Forms/form_edit_dropdown.html.twig' with { - 'button_id': "product_list_id_" ~ product.id_product ~ "_menu", - 'default_item': { - "href": product.url|default('#'), - "icon": "mode_edit" - }, - 'right': true, - 'items': buttons_action - } %} -
    - - - {% endblock %} -{% else %} - - {{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} - -{% endfor %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list_quicknav.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list_quicknav.html.twig deleted file mode 100644 index 16ab7a39..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/list_quicknav.html.twig +++ /dev/null @@ -1,99 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - -

    {{ "Quick navigation"|trans({}, 'Admin.Global') }}

    -
    -
    - - - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% endif %} - - - - {% for product in products %} - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% endif %} - - {% else %} - - {% endfor %} - -
    - {{ "Name"|trans({}, 'Admin.Global') }} -
    - {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} -
    - {{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} -
    -
    - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/products_table.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/products_table.html.twig deleted file mode 100644 index f29fe701..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/Lists/products_table.html.twig +++ /dev/null @@ -1,211 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} -
    - - - {% block product_catalog_form_table_header %} - - - - - - - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% else %} - - {% endif %} - - - {% if has_category_filter == true %} - - {% endif %} - - - {% endblock %} - - {% block product_catalog_form_table_filters %} - {% set filters_disabled = activate_drag_and_drop %} - - - - - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% else %} - - {% endif %} - - - {% if has_category_filter == true %} - - {% endif %} - - - {% endblock %} - - {% block product_catalog_form_table_items %} - {{ render(controller('PrestaShopBundle\\Controller\\Admin\\ProductController::listAction', { - 'limit': limit, - 'offset': offset, - 'orderBy': orderBy, - 'sortOrder': sortOrder, - 'products': products, - 'last_sql': last_sql - })) }} - {% endblock %} -
    - {{ ps.sortable_column_header("ID"|trans({}, 'Admin.Global'), 'id_product', orderBy, sortOrder) }} - - {{ "Image"|trans({}, 'Admin.Global') }} - - {{ ps.sortable_column_header("Name"|trans({}, 'Admin.Global'), 'name', orderBy, sortOrder) }} - - {{ ps.sortable_column_header("Reference"|trans({}, 'Admin.Global'), 'reference', orderBy, sortOrder) }} - - {{ ps.sortable_column_header("Category"|trans({}, 'Admin.Catalog.Feature'), 'name_category', orderBy, sortOrder) }} - - {{ ps.sortable_column_header("Price (tax excl.)"|trans({}, 'Admin.Catalog.Feature'), 'price', orderBy, sortOrder) }} - - {{ "Price (tax incl.)"|trans({}, 'Admin.Catalog.Feature') }} - - {{ ps.sortable_column_header("Quantity"|trans({}, 'Admin.Catalog.Feature'), 'sav_quantity', orderBy, sortOrder) }} - - {{ ps.sortable_column_header("Status"|trans({}, 'Admin.Global'), 'active', orderBy, sortOrder) }} - - {{ ps.sortable_column_header("Position"|trans({}, 'Admin.Global'), 'position', orderBy, sortOrder) }} - - {{ "Actions"|trans({}, 'Admin.Global') }} -
    - {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { - 'input_name': "filter_column_id_product", - 'min': '0', - 'max': '1000000', - 'minLabel': "Min"|trans({}, 'Admin.Global'), - 'maxLabel': "Max"|trans({}, 'Admin.Global'), - 'value': filter_column_id_product, - 'disabled': filters_disabled, - } %} -   - - - - - - - {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { - 'input_name': "filter_column_price", - 'min': '0', - 'max': '1000000', - 'minLabel': "Min"|trans({}, 'Admin.Global'), - 'maxLabel': "Max"|trans({}, 'Admin.Global'), - 'value': filter_column_price, - 'disabled': filters_disabled, - } %} - - {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { - 'input_name': "filter_column_sav_quantity", - 'min': '-1000000', - 'max': '1000000', - 'minLabel': "Min"|trans({}, 'Admin.Global'), - 'maxLabel': "Max"|trans({}, 'Admin.Global'), - 'value': filter_column_sav_quantity, - 'disabled': filters_disabled, - } %} - -
    - -
    -
    - {% if not(activate_drag_and_drop) %} - - {% else %} - - {% endif %} - - - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig deleted file mode 100644 index bcfb0361..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig +++ /dev/null @@ -1,231 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% form_theme categories '@PrestaShop/Admin/Product/Themes/categories_theme.html.twig' %} - -{% block javascripts %} - {{ parent() }} - - - - - -{% endblock %} - -{% block content %} -
    - - {{ renderhook('legacy_block_kpi', {'kpi_controller': 'AdminProductsController'}) }} - -
    - - {% if permission_error|length %} -
    -
    - -
    -
    - {% endif %} - -
    - {% block product_catalog_tools %} - {{ include('@Product/CatalogPage/Blocks/tools.html.twig', {'import_link': import_link }) }} - {% endblock %} - - {% block product_catalog_filters %} - {{ include('@Product/CatalogPage/Blocks/filters.html.twig', { - 'limit': limit, - 'offset': offset, - 'orderBy': orderBy, - 'sortOrder': sortOrder - }) - }} - {% endblock %} -
    - - {% block product_catalog_form %} - {{ include('@Product/CatalogPage/Forms/form_products.html.twig', { - 'limit': limit, - 'orderBy': orderBy, - 'offset': offset, - 'sortOrder': sortOrder, - 'filter_category': filter_category, - 'filter_column_id_product': filter_column_id_product, - 'filter_column_name': filter_column_name, - 'filter_column_reference': filter_column_reference, - 'filter_column_name_category': filter_column_name_category, - 'filter_column_price': filter_column_price, - 'filter_column_sav_quantity': filter_column_sav_quantity, - 'filter_column_active': filter_column_active, - 'has_category_filter': has_category_filter, - 'activate_drag_and_drop': activate_drag_and_drop, - 'products': products, - 'last_sql': last_sql, - 'product_count_filtered': product_count_filtered, - 'pagination_parameters': pagination_parameters, - 'pagination_limit_choices': pagination_limit_choices - }) - }} - {% endblock %} - -
    -
    - - {# Duplication product modal #} - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_duplicate_all_modal", - 'title': "Duplicating products"|trans({}, 'Admin.Catalog.Notification'), - 'closable': true, - 'progressbar': { - 'id': "catalog_duplicate_all_progression", - 'label': "Duplicating..."|trans({}, 'Admin.Catalog.Notification') - }, - 'actions': [], - }%} - {% block content %} - - {% endblock %} - {% endembed %} - - - {# Activation product modal #} - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_activate_all_modal", - 'title': "Activating products"|trans({}, 'Admin.Catalog.Notification'), - 'closable': true, - 'progressbar': { - 'id': "catalog_activate_all_progression", - 'label': "Activating..."|trans({}, 'Admin.Catalog.Notification') - }, - 'actions': [], - }%} - {% block content %} - - {% endblock %} - {% endembed %} - - - {# Desactivation product modal #} - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_deactivate_all_modal", - 'title': "Deactivating products"|trans({}, 'Admin.Catalog.Notification'), - 'closable': true, - 'progressbar': { - 'id': "catalog_deactivate_all_progression", - 'label': "Deactivating..."|trans({}, 'Admin.Catalog.Notification') - }, - 'actions': [], - }%} - {% block content %} - - {% endblock %} - {% endembed %} - - - {# Deletion product modal #} - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_delete_all_modal", - 'title': "Deleting products"|trans({}, 'Admin.Catalog.Notification'), - 'closable': true, - 'progressbar': { - 'id': "catalog_delete_all_progression", - 'label': "Deleting..."|trans({}, 'Admin.Catalog.Notification') - }, - 'actions': [], - }%} - {% block content %} - - {% endblock %} - {% endembed %} - - - {# Confirmation deletion product modal #} - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_deletion_modal", - 'title': "Delete products?"|trans({}, 'Admin.Catalog.Feature'), - 'closable': true, - 'actions': [{ - 'type': 'button', - 'label': "Delete now"|trans({}, 'Admin.Actions'), - 'value': 'confirm', - 'class': 'btn btn-primary btn-lg', - }], - }%} - {% block content %} - - {% endblock %} - {% endembed %} - - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': "catalog_sql_query_modal", - 'title': "SQL query"|trans({}, 'Admin.Global'), - 'closable': true, - 'actions': [{ - 'type': 'button', - 'label': "Export to SQL Manager"|trans({}, 'Admin.Actions'), - 'value': 'sql_manager', - 'class': 'btn btn-primary btn-lg', - }], - } %} - {% block content %} -
    - -
    - {% endblock %} - {% endembed %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog_empty.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog_empty.html.twig deleted file mode 100644 index 66df64c5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog_empty.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - add_shopping_cart -
    - - {{ '[1]Add your first product[/1][2]or import a list of products (filetypes: .csv, .xls, .xlsx, .xlst, .ods, .ots).[/2]'|trans({}, 'Admin.Catalog.Feature')| - replace({ - '[1]': '', - '[2]': '', - })|raw - }} - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/footer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/footer.html.twig deleted file mode 100644 index 6a65a672..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/footer.html.twig +++ /dev/null @@ -1,151 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% block product_footer %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/header.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/header.html.twig deleted file mode 100644 index 5ea3e250..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/header.html.twig +++ /dev/null @@ -1,94 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    - {% if is_multishop_context %} -
    - -
    - {% endif %} - -
    -
    -
    - {{ form_widget(formName) }} -
    -
    - {{ form_widget(formType) }} - -
    -
    -
    - -
    -
    - -
    -
    -
    - {{ form_errors(formName) }} - {{ form_errors(formType) }} -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/tabs.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/tabs.html.twig deleted file mode 100644 index 73b30014..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Blocks/tabs.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_categories.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_categories.html.twig deleted file mode 100644 index 2c38a45f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_categories.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -

    {{ "Categories"|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    -
    -
    - - - {{ include('@PrestaShop/Admin/Category/categories.html.twig', {'categories': categories }) }} - {{ form_errors(form.id_category_default) }} - {{ form_widget(form.id_category_default) }} -
    - expand_more{{ "Expand"|trans({}, 'Admin.Actions') }} - expand_less{{ "Collapse"|trans({}, 'Admin.Actions') }} -
    - {{ form_widget(form.categories, {'defaultCategory': true}) }} {# see bootstrap_4_layout.html.twig #} -
    -
    - {{ form_errors(form.categories) }} - {{ form_widget(form.categories) }} {# see bootstrap_4_layout.html.twig #} -
    -
    -

    - {{ "Create a new category"|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    -
    -
    - - {{ form_errors(form.new_category) }} - {{ form_widget(form.new_category.name) }} -
    - -
    - -
    - - {{ form_widget(form.new_category.id_parent) }} -
    - -
    - - -
    -
    - - - add_circle - {{ 'Create a category'|trans({}, 'Admin.Catalog.Feature') }} - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig deleted file mode 100644 index 5b8834ee..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination.html.twig +++ /dev/null @@ -1,269 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - -
    - {{ form.vars.value.name }} - -
    -
    - {{ default_currency }} -
    - -
    - - - {{ form.vars.value.final_price }} {{ default_currency }} - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - -
    - -
    - - {% endif %} - - -
    - mode_edit -
    -
    - -
    -
    - -
    -

    - {{ "Combination details"|trans({}, 'Admin.Catalog.Feature') }} - - {{ form.vars.value.name }} -

    - {{ form_widget(form.attribute_default) }} -
    - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    -
    - - {{ form_errors(form.attribute_quantity) }} - {{ form_widget(form.attribute_quantity) }} -
    -
    - {% endif %} -
    -
    - - {{ form_errors(form.available_date_attribute) }} - {{ form_widget(form.available_date_attribute) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_minimal_quantity) }} - {{ form_widget(form.attribute_minimal_quantity) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_reference) }} - {{ form_widget(form.attribute_reference) }} -
    -
    -
    -

    - {{ 'Stock'|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    -
    - - {{ form_errors(form.attribute_location) }} - {{ form_widget(form.attribute_location) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_low_stock_threshold) }} - {{ form_widget(form.attribute_low_stock_threshold) }} -
    -
    -
    -
    - -
    - {{ form_errors(form.attribute_low_stock_alert) }} - {{ form_widget(form.attribute_low_stock_alert) }} - Team[/1]"|trans({'[1]':'','[/1]':''}, 'Admin.Catalog.Help')|raw }}" > -
    -
    -
    -
    -

    - {{ "Price and impact"|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    -
    - - {{ form_errors(form.attribute_wholesale_price) }} - {{ form_widget(form.attribute_wholesale_price) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_price) }} - {{ form_widget(form.attribute_price) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_priceTI) }} - {{ form_widget(form.attribute_priceTI) }} -
    -
    -
    - {{ "Final retail price (tax excl.) will be"|trans({}, 'Admin.Catalog.Feature') }} {{ form.vars.value.final_price }} {{ default_currency }} -
    -
    -
    -
    -
    - - {{ form_errors(form.attribute_ecotax) }} - {{ form_widget(form.attribute_ecotax) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_unity) }} - {{ form_widget(form.attribute_unity) }} -
    -
    -
    -
    - -
    -
    - {{ 'PS_WEIGHT_UNIT'|configuration }} -
    - {{ form_errors(form.attribute_weight) }} - {{ form_widget(form.attribute_weight) }} -
    -
    -
    -
    -

    - {{ "Specific references"|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    -
    - - {{ form_errors(form.attribute_isbn) }} - {{ form_widget(form.attribute_isbn) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_ean13) }} - {{ form_widget(form.attribute_ean13) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_upc) }} - {{ form_widget(form.attribute_upc) }} -
    -
    -
    -
    - - {{ form_errors(form.attribute_mpn) }} - {{ form_widget(form.attribute_mpn) }} -
    -
    -
    -

    - {{ "Images"|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    -
    - - {{ form_errors(form.id_image_attr) }} - {{ form_widget(form.id_image_attr) }} -
    -
    -
    - -
    -
    - {{ renderhook('displayAdminProductsCombinationBottom', { 'id_product': form.vars.value.id_product, 'id_product_attribute': form.vars.value.id_product_attribute }) }} -
    -
    - - {{ form_widget(form.id_product_attribute) }} -
    -
    - - - delete - - - {% set checked = form.vars.value.attribute_default == 1 ? 'checked' : '' %} - - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination_collection.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination_collection.html.twig deleted file mode 100644 index 76aa484b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combination_collection.html.twig +++ /dev/null @@ -1,27 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% for combinationForm in combinationForms %} - {{ include('@Product/ProductPage/Forms/form_combination.html.twig', {'form': combinationForm}) }} -{% endfor %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations.html.twig deleted file mode 100644 index a772f8e0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations.html.twig +++ /dev/null @@ -1,207 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -

    - {{ 'Manage your product combinations'|trans({}, 'Admin.Catalog.Feature') }} - Attributes & Features for this!"|trans({}, 'Admin.Catalog.Help') }}" - > -

    -
    - -
    -
    -
    - {{ form_errors(form.attributes) }} - {{ form_widget(form.attributes) }} -
    -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    -
    - {{ include('@Product/ProductPage/Forms/form_combinations_bulk.html.twig', { 'form': form_combination_bulk }) }} -
    -
    -
    -
    - -
    - - - - - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% endif %} - - - - - {% if has_combinations %} - - - - - - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} - - {% endif %} - - - {% endif %} - -
    - - {{ 'Combinations'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Impact on price (tax excl.)'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Final price (tax excl.)'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Quantity'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Default combination'|trans({}, 'Admin.Catalog.Feature') }}
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - {% for attribute_group in attribute_groups %} -
    - -
    -
    - {% for attribute in attribute_group.attributes %} -
    - - -
    - {% endfor %} -
    -
    -
    - {% endfor %} -
    -
    - -
    -
    - -
    -

    {{ 'Availability preferences'|trans({}, 'Admin.Catalog.Feature') }}

    -
    - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    - - {{ form_errors(form.out_of_stock) }} - {{ form_widget(form.out_of_stock) }} -
    - -
    - - {{ form_errors(form.available_now) }} - {{ form_widget(form.available_now) }} -
    - -
    - - {{ form_errors(form.available_later) }} - {{ form_widget(form.available_later) }} -
    - {% else %} -
    -

    {{ 'Stock management is disabled'|trans({}, 'Admin.Catalog.Feature') }}

    -
    - {% endif %} - - {% if not has_combinations %} -
    - - {{ form_errors(form.available_date) }} - {{ form_widget(form.available_date) }} -
    - {% endif %} - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations_bulk.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations_bulk.html.twig deleted file mode 100644 index d29420a7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_combinations_bulk.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    - - {{ form_errors(form.quantity) }} - {{ form_widget(form.quantity) }} -
    - {% endif %} - -
    - - {{ form_errors(form.cost_price) }} - {{ form_widget(form.cost_price) }} -
    - -
    - - {{ form_errors(form.impact_on_weight) }} - {{ form_widget(form.impact_on_weight) }} -
    - -
    - - {{ form_errors(form.impact_on_price_te) }} - {{ form_widget(form.impact_on_price_te) }} -
    - -
    - - {{ form_errors(form.impact_on_price_ti) }} - {{ form_widget(form.impact_on_price_ti) }} -
    - -
    - - {{ form_errors(form.date_availability) }} - {{ form_widget(form.date_availability) }} -
    - -
    - - {{ form_errors(form.reference) }} - {{ form_widget(form.reference) }} -
    - -
    - - {{ form_errors(form.minimal_quantity) }} - {{ form_widget(form.minimal_quantity) }} -
    - -
    - - {{ form_errors(form.low_stock_threshold) }} - {{ form_widget(form.low_stock_threshold) }} -
    - -
    -
    - {{ form_errors(form.low_stock_alert) }} - {{ form_widget(form.low_stock_alert) }} - -
    -
    -
    -
    - - - {{ form_widget(form) }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_custom_fields.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_custom_fields.html.twig deleted file mode 100644 index a0a0ad79..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_custom_fields.html.twig +++ /dev/null @@ -1,57 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - {{ form_widget(form.id_customization_field) }} -
    -
    - - {{ form_errors(form.label) }} - {{ form_widget(form.label) }} -
    -
    -
    -
    - - {{ form_errors(form.type) }} - {{ form_widget(form.type) }} -
    -
    -
    -
    - - delete -
    -
    -
    -
    -
    - -
    -
    - {{ form_widget(form.require, {'switch': 'tiny'}) }} -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_edit_specific_price_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_edit_specific_price_modal.html.twig deleted file mode 100644 index 7e11d431..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_edit_specific_price_modal.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_feature.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_feature.html.twig deleted file mode 100644 index cd14a3cd..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_feature.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    - - {{ form_widget(form.feature) }} -
    -
    -
    -
    - - {{ form_widget(form.value) }} -
    -
    -
    -
    - - {{ form_widget(form.custom_value) }} -
    -
    -
    - delete -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_manufacturer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_manufacturer.html.twig deleted file mode 100644 index 7f9fdea1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_manufacturer.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -

    {{ "Brand"|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    -
    - {{ form_widget(form) }} -
    - {{ form_errors(form) }} -
    -
    -
    -
    - delete -
    -
    -
    -
    -
    - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_related_products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_related_products.html.twig deleted file mode 100644 index f4cf0f7a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_related_products.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig deleted file mode 100644 index 6ec38119..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_seo.html.twig +++ /dev/null @@ -1,135 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - -

    {{ 'Search Engine Optimization'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Improve your ranking and how your product page will appear in search engines results.'|trans({}, 'Admin.Catalog.Feature') }}

    - - {% block product_catalog_tool_serp %} -

    {{ "Here is a preview of your search engine result, play with it!"|trans({}, 'Admin.Catalog.Feature') }}

    - {# Div targetted by the SERP component in VueJs. It displays a Google search result preview. #} -
    - {% endblock %} - -
    -
    -
    - {{ form_label(seoForm.meta_title) }} - {{ form_errors(seoForm.meta_title) }} - {{ form_widget(seoForm.meta_title) }} -
    -
    -
    - -
    -
    -
    - {{ form_label(seoForm.meta_description) }} - {{ form_errors(seoForm.meta_description) }} - {{ form_widget(seoForm.meta_description) }} -
    -
    -
    -
    - - {{ form_errors(seoForm.link_rewrite) }} -
    -
    - {{ form_widget(seoForm.link_rewrite) }} -
    -
    - -
    -
    -
    - -
    -
    - -
    -
    - -

    - {{ 'Redirection page'|trans({}, 'Admin.Catalog.Feature') }} - -

    - -
    - -
    -
    - - {{ form_errors(seoForm.redirect_type) }} - {{ form_widget(seoForm.redirect_type) }} -
    -
    - -
    -
    - - {{ form_errors(seoForm.id_type_redirected) }} - {{ form_widget(seoForm.id_type_redirected) }} -
    - -
    -
    -
    -
    - -
    -
    - - {{ form_rest(seoForm) }} - - {{ renderhook('displayAdminProductsSeoStepBottom', { 'id_product': productId }) }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig deleted file mode 100644 index 20564ed2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_shipping.html.twig +++ /dev/null @@ -1,161 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% set dimension_unit, weight_unit = 'PS_DIMENSION_UNIT'|configuration, 'PS_WEIGHT_UNIT'|configuration %} - -
    -

    {{ 'Package dimension'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Adjust your shipping costs by filling in the product dimensions.'|trans({}, 'Admin.Catalog.Feature') }}

    -
    - -
    -
    - - {{ form_errors(form.width) }} -
    - {{ form_widget(form.width) }} -
    - {{ dimension_unit }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(form.height) }} -
    - {{ form_widget(form.height) }} -
    - {{ dimension_unit }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(form.depth) }} -
    - {{ form_widget(form.depth) }} -
    - {{ dimension_unit }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(form.weight) }} -
    - {{ form_widget(form.weight) }} -
    - {{ weight_unit }} -
    -
    -
    -
    - -
    -
    -

    - {{ form.additional_delivery_times.vars.label }} - -

    -
    -
    - {% for child in form.additional_delivery_times %} - {% if child.vars.value == 1 %} - - {% else %} - {{ form_widget(child) }} - {% endif %} - {% endfor %} -
    -
    -
    -
    - -
    -
    - - {{ form_errors(form.delivery_in_stock) }} - {{ form_widget(form.delivery_in_stock) }} -

    {{ 'Leave empty to disable.'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    -
    -
    - - {{ form_errors(form.delivery_out_stock) }} - {{ form_widget(form.delivery_out_stock) }} -

    {{ 'Leave empty to disable.'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    - -
    -
    -

    - {{ form.additional_shipping_cost.vars.label }} - -

    - -
    -
    - {{ form_widget(form.additional_shipping_cost) }} -
    -
    -
    -
    - -
    -
    -

    {{ form.selectedCarriers.vars.label }}

    - {{ form_widget(form.selectedCarriers) }} -
    -
    - -
    - -
    - -
    -
    - {% if asm_globally_activated and isNotVirtual and isChecked %} - {{ include('@PrestaShop/Admin:Product/ProductPage/Forms/form_warehouse_combination.html.twig', { 'warehouses': warehouses, 'form': form }) }} - {% endif %} -
    -
    - -{{ renderhook('displayAdminProductsShippingStepBottom', { 'id_product': id_product }) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_specific_price.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_specific_price.html.twig deleted file mode 100644 index a3db3159..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_specific_price.html.twig +++ /dev/null @@ -1,174 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if is_modal is not defined %} - {% set is_modal = false %} -{% endif %} - -{% if is_modal == false %} - {% set column_default_md_3 = 'col-md-3' %} - {% set column_default_md_2 = 'col-md-2' %} - {% set column_default_xl_2 = 'col-xl-2' %} -{% else %} - {% set column_default_md_3 = 'col-md-9' %} - {% set column_default_md_2 = 'col-md-4' %} - {% set column_default_xl_2 = 'col-xl-4' %} -{% endif %} - -
    -

    {{ 'Specific price conditions'|trans({}, 'Admin.Catalog.Feature') }}

    - {{ form_errors(form) }} - - {% if form.sp_id_shop.vars.choices is defined %} -
    -
    -
    - - {{ form_errors(form.sp_id_shop) }} - {{ form_widget(form.sp_id_shop) }} -
    -
    -
    - {% else %} - {{ form_widget(form.sp_id_shop) }} - {% endif %} - -
    -
    -
    - - {{ form_errors(form.sp_id_currency) }} - {{ form_widget(form.sp_id_currency) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_id_country) }} - {{ form_widget(form.sp_id_country) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_id_group) }} - {{ form_widget(form.sp_id_group) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_id_customer) }} - {{ form_widget(form.sp_id_customer) }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(form.sp_id_product_attribute) }} - {{ form_widget(form.sp_id_product_attribute) }} -
    -
    -
    -
    -
    - - {{ form_errors(form.sp_from) }} - {{ form_widget(form.sp_from) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_to) }} - {{ form_widget(form.sp_to) }} -
    -
    - {% if is_modal == true %} -
    -
    - {% endif %} -
    -
    - - {{ form_errors(form.sp_from_quantity) }} -
    - {{ form_widget(form.sp_from_quantity) }} -
    - {{ 'Unit(s)'|trans({}, 'Admin.Catalog.Feature') }} -
    -
    -
    -
    -
    -
    - -

    {{ 'Impact on price'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    -
    - - {{ form_errors(form.sp_price) }} - {{ form_widget(form.sp_price) }} -
    -
    -
    -
    - - {{ form_errors(form.leave_bprice) }} - {{ form_widget(form.leave_bprice) }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(form.sp_reduction) }} - {{ form_widget(form.sp_reduction) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_reduction_type) }} - {{ form_widget(form.sp_reduction_type) }} -
    -
    -
    -
    - - {{ form_errors(form.sp_reduction_tax) }} - {{ form_widget(form.sp_reduction_tax) }} -
    -
    -
    -
    - {{ form_widget(form.cancel) }} - {{ form_widget(form.save) }} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_choice.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_choice.html.twig deleted file mode 100644 index cd1aa6a4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_choice.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if form.suppliers|length > 0 %} -
    -

    {{ form.suppliers.vars.label }}

    -
    -
    - -
    -
    - -
    -
    -
    - {{ form_errors(form.suppliers) }} - - - - - - - - - {% for key, supplier in form.suppliers %} - - - - - {% endfor %} - -
    {{ 'Choose the suppliers associated with this product'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Default supplier'|trans({}, 'Admin.Catalog.Feature') }}
    {{ form_widget(supplier) }}{{ form_widget(form.default_supplier[key]) }}
    -
    -
    -
    - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_combination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_combination.html.twig deleted file mode 100644 index 5b6fa658..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_supplier_combination.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if suppliers|length > 0 %} -

    {{ 'Supplier reference(s)'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    - -
    -
    -{% endif %} - -{% for supplierId in suppliers %} - {% set collectionName = 'supplier_combination_' ~ supplierId %} -
    -
    {{ form[collectionName].vars.label }}
    -
    -
    - {{ form_errors(form[collectionName]) }} - - - - - - - - - - - {% for supplier_combination in form[collectionName] %} - - - - - - - {% endfor %} - -
    {{ 'Product name'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Supplier reference'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Price (tax excl.)'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Currency'|trans({}, 'Admin.Global') }}
    {{ supplier_combination.vars.value.label }}{{ form_widget(supplier_combination.supplier_reference) }}{{ form_widget(supplier_combination.product_price) }} - {{ form_widget(supplier_combination.product_price_currency) }} - {{ form_widget(supplier_combination.id_product_attribute) }} - {{ form_widget(supplier_combination.supplier_id) }} -
    -
    -
    -
    -{% endfor %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_warehouse_combination.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_warehouse_combination.html.twig deleted file mode 100644 index e485ed9d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Forms/form_warehouse_combination.html.twig +++ /dev/null @@ -1,67 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if warehouses|length > 0 %} -

    {{ 'Product location in warehouses'|trans({}, 'Admin.Catalog.Feature') }}

    - - -

    {{ 'Please choose the warehouses associated with this product.'|trans({}, 'Admin.Catalog.Feature') }}

    - - {% for warehouse in warehouses %} -
    - {% set collectionName = 'warehouse_combination_' ~ warehouse.id_warehouse %} -
    - -
    - {{ form_errors(form[collectionName]) }} - {% for warehouse_combination in form[collectionName] %} -
    - -
    -
    {{ form_widget(warehouse_combination.activated) }}
    - {{ form_label(warehouse_combination.location) }} -
    {{ form_widget(warehouse_combination.location) }}
    - {{ form_widget(warehouse_combination.id_product_attribute) }} - {{ form_widget(warehouse_combination.warehouse_id) }} - {{ form_widget(warehouse_combination.product_id) }} -
    -
    - {% endfor %} -
    -
    -
    - {% endfor %} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig deleted file mode 100644 index a2f0caf7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/combinations.html.twig +++ /dev/null @@ -1,191 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    -
    - -
    - -
    -

    {{ 'Quantities'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    - - {{ form_errors(formStockQuantity) }} - {{ form_widget(formStockQuantity) }} -
    - {% endif %} -
    - - - {{ form_errors(formStockMinimalQuantity) }} - {{ form_widget(formStockMinimalQuantity) }} -
    -
    -
    - -

    {{ 'Stock'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    -
    - - {{ form_errors(formLocation) }} - {{ form_widget(formLocation) }} -
    -
    -
    -
    - - {{ form_errors(formLowStockThreshold) }} - {{ form_widget(formLowStockThreshold) }} -
    -
    - -
    - {{ form_errors(formLowStockAlert) }} - {{ form_widget(formLowStockAlert) }} - Team[/1]"|trans({'[1]':'','[/1]':''}, 'Admin.Catalog.Help')|raw }}" > -
    -
    -
    -
    -
    - -
    - -
    -
    -

    {{ formVirtualProduct.vars.label }}

    -
    -
    -
    - {{ form_widget(formVirtualProduct.is_virtual_file) }} -
    -
    -
    - -
    - {{ form_errors(formVirtualProduct) }} -
    -
    - - -
    - {{ form_widget(formVirtualProduct.file) }} -
    - -
    -
    -
    -
    - - - {{ form_errors(formVirtualProduct.name) }} - {{ form_widget(formVirtualProduct.name) }} -
    -
    -
    -
    - - - {{ form_errors(formVirtualProduct.nb_downloadable) }} - {{ form_widget(formVirtualProduct.nb_downloadable) }} -
    -
    -
    -
    - - - {{ form_errors(formVirtualProduct.expiration_date) }} - {{ form_widget(formVirtualProduct.expiration_date) }} -
    -
    -
    -
    - - - {{ form_errors(formVirtualProduct.nb_days) }} - {{ form_widget(formVirtualProduct.nb_days) }} -
    -
    -
    - {{ form_widget(formVirtualProduct.save) }} -
    -
    -
    - - {% if asm_globally_activated and formType.vars.value != "2" %} -
    - -
    - {{ form_errors(formAdvancedStockManagement) }} - {{ form_widget(formAdvancedStockManagement) }} - {% if form.step1.type_product.vars.value == "1" %} - {{ 'When enabling advanced stock management for a pack, please make sure it is also enabled for its product(s) – if you choose to decrement product quantities.'|trans({}, 'Admin.Catalog.Notification') }} - {% endif %} -
    -
    -
    - -
    - {{ form_errors(formDependsOnStocks) }} - {{ form_widget(formDependsOnStocks) }} -
    -
    - {% endif %} - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    -

    {{ formPackStockType.vars.label }}

    -
    -
    - {{ form_errors(formPackStockType) }} - {{ form_widget(formPackStockType) }} -
    -
    -
    - {% endif %} - {{ include('@Product/ProductPage/Forms/form_combinations.html.twig', {'form': formStep3, 'form_combination_bulk': formCombinations}) }} - - {{ renderhook('displayAdminProductsQuantitiesStepBottom', { 'id_product': productId }) }} - -
    -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig deleted file mode 100644 index 429b68ec..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/essentials.html.twig +++ /dev/null @@ -1,274 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    -
    - - {# LEFT #} -
    - -
    - {{ form_errors(formPackItems) }} - {{ form_widget(formPackItems) }} -
    - -
    -
    -
    -
    - add_a_photo
    - {{js_translatable['Drop images here']}}
    - {{js_translatable['or select files']}}
    - - {{js_translatable['files recommandations']}}
    - {{js_translatable['files recommandations2']}} -
    -
    - {% if images is defined %} - {% if editable %} -
    -
    +
    -
    - {% endif %} - {% for image in images %} -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - {% if image.cover %} -
    {{ 'Cover'|trans({}, 'Admin.Catalog.Feature') }}
    - {% endif %} -
    - {% endfor %} - {% endif %} -
    -
    -
    -
    -
    - {{ 'View all images'|trans({}, 'Admin.Catalog.Feature') }} - {{ 'View less'|trans({}, 'Admin.Catalog.Feature') }} -
    - -
    - -
    - - -
    -
    - {{ form_widget(formShortDescription) }} -
    -
    - {{ form_widget(formDescription) }} -
    -
    -
    - - {{ renderhook('displayAdminProductsMainStepLeftColumnMiddle', { 'id_product': productId }) }} - -
    -
    -

    {{ 'Features'|trans({}, 'Admin.Catalog.Feature') }}

    - {{ form_errors(formFeatures) }} -
    - {% for feature in formFeatures %} - {{ include('@Product/ProductPage/Forms/form_feature.html.twig', { 'form': feature }) }} - {% endfor %} -
    -
    -
    -
    - -
    -
    -
    - -
    - {{ include('@Product/ProductPage/Forms/form_manufacturer.html.twig', { 'form': formManufacturer }) }} -
    - - - - {{ renderhook('displayAdminProductsMainStepLeftColumnBottom', { 'id_product': productId }) }} - -
    - - {# RIGHT #} -
    - -
    -
    - - {% if is_combination_active %} -
    -

    - {{ "Combinations"|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    - -
    -
    - -
    - - {# First tag [1][/1] is for a HTML link. Second tag [2] is an icon (no closing tag needed). #} - {{ "Advanced settings in [1][2]Combinations[/1]"|trans({}, 'Admin.Catalog.Help')|replace({'[1]': '', '[/1]': '', '[2]': 'open_in_new'})|raw }} - -
    -
    -
    - {% endif %} - -
    -

    - {{ "Reference"|trans({}, 'Admin.Catalog.Feature') }} - -

    - {{ form_errors(formReference) }} -
    -
    - {{ form_widget(formReference) }} -
    -
    -
    - - {% if 'PS_STOCK_MANAGEMENT'|configuration %} -
    -

    - {{ "Quantity"|trans({}, 'Admin.Catalog.Feature') }} - -

    - {{ form_errors(formQuantityShortcut) }} -
    -
    - {{ form_widget(formQuantityShortcut) }} -
    -
    - - {# First tag [1][/1] is for a HTML link. Second tag [2] is an icon (no closing tag needed). #} - {{ "Advanced settings in [1][2]Quantities[/1]"|trans({}, 'Admin.Catalog.Help')|replace({'[1]': '', '[/1]': '', '[2]': 'open_in_new'})|raw }} - -
    - {% endif %} - -
    -

    - {{ "Price"|trans({}, 'Admin.Global') }} - -

    -
    -
    - - {{ form_widget(formPriceShortcut) }} - {{ form_errors(formPriceShortcut) }} -
    -
    - - {{ form_widget(formPriceShortcutTTC) }} - {{ form_errors(formPriceShortcutTTC) }} -
    -
    - - {{ render( - controller('PrestaShopBundle:Admin/Common:renderField', { - 'formName': 'step2', - 'formType': 'PrestaShopBundle\\Form\\Admin\\Product\\ProductPrice', - 'fieldName': 'id_tax_rules_group', - 'fieldData' : form.step2.id_tax_rules_group.vars.value - } - ) - ) - }} -
    -
    - - {# First tag [1][/1] is for a HTML link. Second tag [2] is an icon (no closing tag needed). #} - {{ "Advanced settings in [1][2]Pricing[/1]"|trans({}, 'Admin.Catalog.Help')|replace({'[1]': '', '[/1]': '', '[2]': 'open_in_new'})|raw }} - -
    -
    -
    -
    - -
    -
    -
    -
    - × -
    -
    - -
    - {{ include('@Product/ProductPage/Forms/form_categories.html.twig', { 'form': formCategories, 'productId': productId }) }} -
    - - {{ renderhook('displayAdminProductsMainStepRightColumnBottom', { 'id_product': productId }) }} - -
    -
    -
    -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig deleted file mode 100644 index 6f257470..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/options.html.twig +++ /dev/null @@ -1,228 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    -
    - -
    - - {{ renderhook('displayAdminProductsOptionsStepTop', { 'id_product': productId }) }} - -
    -
    -

    {{ 'Visibility'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Where do you want your product to appear?'|trans({}, 'Admin.Catalog.Feature') }}

    -
    -
    - -
    -
    - {{ form_errors(optionsForm.visibility) }} - {{ form_widget(optionsForm.visibility) }} -
    -
    - -
    -
    - {{ form_errors(optionsForm.display_options) }} -
    -
    - {{ form_widget(optionsForm.display_options.available_for_order) }} -
    -
    - {{ form_widget(optionsForm.display_options.show_price) }} -
    -
    - {{ form_widget(optionsForm.display_options.online_only) }} -
    -
    -
    -
    -
    -
    - - {{ form_errors(optionsForm.tags) }} - {{ form_widget(optionsForm.tags) }} - -
    -
    - -
    -
    -

    {{ 'Condition & References'|trans({}, 'Admin.Catalog.Feature')|raw }}

    -
    -
    - -
    -
    - - {{ form_errors(optionsForm.condition) }} - {{ form_widget(optionsForm.condition) }} -
    -
    - - {{ form_widget(optionsForm.show_condition) }} -
    -
    -
    -
    - - {{ form_errors(optionsForm.isbn) }} - {{ form_widget(optionsForm.isbn) }} -
    -
    - - {{ form_errors(optionsForm.ean13) }} - {{ form_widget(optionsForm.ean13) }} -
    -
    -
    -
    - - {{ form_errors(optionsForm.upc) }} - {{ form_widget(optionsForm.upc) }} -
    -
    - - {{ form_errors(optionsForm.mpn) }} - {{ form_widget(optionsForm.mpn) }} -
    -
    - -
    -
    -
    -

    {{ optionsForm.custom_fields.vars.label }}

    -

    {{ 'Customers can personalize the product by entering some text or by providing custom image files.'|trans({}, 'Admin.Catalog.Feature') }}

    - {{ form_errors(optionsForm.custom_fields) }} -
      - {% for field in optionsForm.custom_fields %} -
    • - {{ include('@Product/ProductPage/Forms/form_custom_fields.html.twig', { 'form': field }) }} -
    • - {% endfor %} -
    - - add_circle - {{ 'Add a customization field'|trans({}, 'Admin.Catalog.Feature') }} - -
    -
    -
    - -
    -
    -

    {{ 'Attached files'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Select the files (instructions, documentation, recipes, etc.) your customers can directly download on this product page.'|trans({}, 'Admin.Catalog.Feature') }}
    {{ 'Need to browse all files? Go to [1]Catalog > Files[/1]'|trans({'[1]':'','[/1]':''}, 'Admin.Catalog.Feature')|raw }}

    - {{ form_widget(optionsForm.attachments) }} -
    -
    -
    -
    - -
    - {{ form_errors(optionsForm.attachment_product) }} -
    -
    {{ form_widget(optionsForm.attachment_product.file) }}
    -
    {{ form_widget(optionsForm.attachment_product.name) }}
    -
    {{ form_widget(optionsForm.attachment_product.description) }}
    -
    - {{ form_widget(optionsForm.attachment_product.add) }} - {{ form_widget(optionsForm.attachment_product.cancel) }} -
    -
    -
    -
    -
    - -
    -
    - {{ include('@Product/ProductPage/Forms/form_supplier_choice.html.twig', { 'form': optionsForm }) }} -
    -
    -
    -
    - {{ include('@Product/ProductPage/Forms/form_supplier_combination.html.twig', { 'suppliers': optionsForm.suppliers.vars.value, 'form': optionsForm }) }} -
    -
    - - {{ renderhook('displayAdminProductsOptionsStepBottom', { 'id_product': productId }) }} - -
    -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig deleted file mode 100644 index 3d6da7f8..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/pricing.html.twig +++ /dev/null @@ -1,225 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    -
    - -
    -

    {{ 'Retail price'|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    - -
    -
    - -
    - - {{ form_errors(pricingForm.price) }} - {{ form_widget(pricingForm.price) }} -
    -
    - - {{ form_errors(pricingForm.price_ttc) }} - {{ form_widget(pricingForm.price_ttc) }} -
    - -
    - -
    -
    - {{ form_errors(pricingForm.unit_price) }} - {{ form_widget(pricingForm.unit_price) }} -
    -
    - {{ form_errors(pricingForm.unity) }} - {{ form_widget(pricingForm.unity) }} -
    -
    -
    -
    - - {{ form_errors(pricingForm.ecotax) }} - {{ form_widget(pricingForm.ecotax) }} -
    -
    -
    - -
    -
    -
    - - {{ form_errors(pricingForm.id_tax_rules_group) }} - {{ form_widget(pricingForm.id_tax_rules_group) }} -
    - -
    - {{ form_widget(pricingForm.on_sale) }} -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -

    - {{ 'Cost price'|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    -
    - - {{ form_errors(pricingForm.wholesale_price) }} - {{ form_widget(pricingForm.wholesale_price) }} -
    -
    -
    - -
    -
    -
    -

    - {{ 'Specific prices'|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    -
    -
    - -
    - {{ include('@Product/ProductPage/Forms/form_specific_price.html.twig', {'form': pricingForm.specific_price, 'is_multishop_context': is_multishop_context}) }} -
    - - - - - - - - - - - - - - - - - - -
    {{ 'Rule'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Combination'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Currency'|trans({}, 'Admin.Global') }}{{ 'Country'|trans({}, 'Admin.Global') }}{{ 'Group'|trans({}, 'Admin.Global') }}{{ 'Customer'|trans({}, 'Admin.Global') }}{{ 'Fixed price'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Impact'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Period'|trans({}, 'Admin.Global') }}{{ 'From'|trans({}, 'Admin.Catalog.Feature') }}
    -
    -
    -
    -
    - -
    - {{ include('@Product/ProductPage/Forms/form_edit_specific_price_modal.html.twig') }} -
    - - -
    -
    -
    -

    - {{ 'Priority management'|trans({}, 'Admin.Catalog.Feature') }} - -

    -
    -
    -
    - - {{ form_errors(pricingForm.specificPricePriority_0) }} - {{ form_widget(pricingForm.specificPricePriority_0) }} -
    -
    -
    -
    - - {{ form_errors(pricingForm.specificPricePriority_1) }} - {{ form_widget(pricingForm.specificPricePriority_1) }} -
    -
    -
    -
    - - {{ form_errors(pricingForm.specificPricePriority_2) }} - {{ form_widget(pricingForm.specificPricePriority_2) }} -
    -
    -
    -
    - - {{ form_errors(pricingForm.specificPricePriority_3) }} - {{ form_widget(pricingForm.specificPricePriority_3) }} -
    -
    -
    - {{ form_widget(pricingForm.specificPricePriorityToAll) }} -
    -
    -
    - - {{ renderhook('displayAdminProductsPriceStepBottom', { 'id_product': productId }) }} - -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/seo.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/seo.html.twig deleted file mode 100644 index 8bfe5a34..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/Panels/seo.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    -
    -
    -
    -
    - {{ include('@Product/ProductPage/Forms/form_seo.html.twig', { - 'seoForm' : seoForm, - 'productId': productId - }) - }} -
    -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/disabled_form_alert.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/disabled_form_alert.html.twig deleted file mode 100644 index 26d94b07..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/disabled_form_alert.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    - -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig deleted file mode 100644 index 8e492bfd..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/ProductPage/product.html.twig +++ /dev/null @@ -1,354 +0,0 @@ - {#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - - {% set hooks = renderhooksarray('displayAdminProductsExtra', { 'id_product': id_product }) %} - -
    - - {% if not editable %}
    {% endif %} - {# PRODUCT HEADER #} - {% block product_header %} - {{ include('@Product/ProductPage/Blocks/header.html.twig', { - 'formName': form.step1.name, - 'formType': form.step1.type_product, - 'is_multishop_context': is_multishop_context, - 'languages': languages, - 'help_link': help_link, - 'stats_link': stats_link - }) - }} - {% endblock %} - -
    -
    - {{ form_errors(form) }} -
    -
    - -
    - {# FORM TABS CONTAINER #} - {% block product_tabs_container %} - {{ include('@Product/ProductPage/Blocks/tabs.html.twig', { 'hooks': hooks }) }} - {% endblock %} -
    - - {# PANEL ESSENTIALS #} - {% block product_panel_essentials %} - {% set formQuantityShortcut = form.step1.qty_0_shortcut is defined ? form.step1.qty_0_shortcut : null %} - {{ include('@Product/ProductPage/Panels/essentials.html.twig', { - 'formPackItems': form.step1.inputPackItems, - 'productId': id_product, - 'images': form.step1.vars.value.images, - 'formShortDescription': form.step1.description_short, - 'formDescription': form.step1.description, - 'formFeatures': form.step1.features, - 'formManufacturer': form.step1.id_manufacturer, - 'formRelatedProducts': form.step1.related_products, - 'is_combination_active': is_combination_active, - 'has_combinations': has_combinations, - 'formReference': form.step6.reference, - 'formQuantityShortcut': formQuantityShortcut, - 'formPriceShortcut': form.step1.price_shortcut, - 'formPriceShortcutTTC': form.step1.price_ttc_shortcut, - 'formCategories': form.step1, - }) - }} - {% endblock %} - - {# PANEL COMBINATIONS #} - {% block product_panel_combinations %} - {% set formStockQuantity = form.step3.qty_0 is defined ? form.step3.qty_0 : null %} - {{ include('@Product/ProductPage/Panels/combinations.html.twig', { - 'formDependsOnStocks': form.step3.depends_on_stock, - 'productId': id_product, - 'formStockQuantity': formStockQuantity, - 'formStockMinimalQuantity': form.step3.minimal_quantity, - 'formLowStockThreshold': form.step3.low_stock_threshold, - 'formLocation': form.step3.location, - 'formLowStockAlert': form.step3.low_stock_alert, - 'formVirtualProduct': form.step3.virtual_product, - 'asm_globally_activated': asm_globally_activated, - 'formType': form.step1.type_product, - 'formAdvancedStockManagement': form.step3.advanced_stock_management, - 'formPackStockType': form.step3.pack_stock_type, - 'formStep3': form.step3, - 'formCombinations': formCombinations, - 'has_combinations': has_combinations, - 'max_upload_size': max_upload_size - }) - }} - {% endblock %} - - {# PANEL SHIPPING #} - {% block product_panel_shipping %} -
    -
    -
    -
    -
    - {{ include('@Product/ProductPage/Forms/form_shipping.html.twig', { - 'form' : form.step4, - 'asm_globally_activated': asm_globally_activated, - 'isNotVirtual': form.step1.type_product.vars.value != "2", - 'isChecked': form.step3.advanced_stock_management.vars.checked, - 'warehouses': warehouses - }) }} -
    -
    -
    -
    -
    - {% endblock %} - - {# PANEL PRICING #} - {% block product_panel_pricing %} - {{ include('@Product/ProductPage/Panels/pricing.html.twig', { - 'pricingForm': form.step2, - 'is_multishop_context': is_multishop_context, - 'productId': id_product - }) }} - {% endblock %} - - {# PANEL SEO #} - {% block product_panel_seo %} - {{ include('@Product/ProductPage/Panels/seo.html.twig', { - 'seoForm': form.step5, - 'productId': id_product - }) }} - {% endblock %} - - {# PANEL OPTIONS #} - {% block product_panel_options %} - {{ include('@Product/ProductPage/Panels/options.html.twig', { - 'optionsForm': form.step6, - 'productId': id_product - }) }} - {% endblock %} - - {# PANEL HOOKED MODULES #} - {% block product_panel_modules %} - {% if hooksarraycontent(hooks) is not empty %} -
    -
    -
    -
    -
    - - {# LEFT #} -
    - - -
    -

    -

    {{ 'Choose a module to configure'|trans({}, 'Admin.Catalog.Feature') }}

    - {{ 'These modules are relative to the product page of your shop.'|trans({}, 'Admin.Catalog.Feature') }}
    - {{ 'To manage all your modules go to the [1]Installed module page[/1]'|trans({}, 'Admin.Catalog.Feature')|replace({'[1]': '', '[/1]': ''})|raw }} -

    -
    - {% for module in hooks %} -
    -
    -
    - {{ module.attributes.displayName }} -

    - {{ module.attributes.displayName }} -

    -
    - {{ module.attributes.version }} by {{ module.attributes.author }} -
    -
    -
    - {{ module.attributes.description }} -
    -
    -
    - -
    -
    -
    -
    - {% endfor %} -
    -
    - - {% for module in hooks %} - - {% endfor %} -
    - -
    -
    -
    -
    -
    - {% endif %} - {% endblock %} -
    - - {{ form_widget(form.id_product) }} - {{ form_widget(form._token) }} - -
    - {# FOOTER #} - {{ include('@Product/ProductPage/Blocks/footer.html.twig', { - 'preview_link': preview_link, - 'preview_link_deactivate': preview_link_deactivate, - 'is_shop_context': is_shop_context, - 'editable': editable, - 'is_active': form.step1.vars.value.active, - 'productId': id_product - }) }} - {% if not editable %}
    {% endif %} -
    - - - {% embed '@PrestaShop/Admin/Helpers/bootstrap_popup.html.twig' with { - 'id': 'confirmation_modal', - 'title': "Warning"|trans({}, 'Admin.Notifications.Warning'), - 'closable': false, - 'actions': [ - { - 'type': 'button', - 'label': "No"|trans({}, 'Admin.Global'), - 'class': 'btn btn-outline-secondary btn-lg cancel' - }, - { - 'type': 'button', - 'label': "Yes"|trans({}, 'Admin.Global'), - 'class': 'btn btn-primary btn-lg continue' - } - ], - } %} - {% block content %} - - {% endblock %} - {% endembed %} - -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - - - - - - - - - - - - - - - - -{% endblock %} - -{% set js_translatable = { -"Are you sure to disable variations ? they will all be deleted": "This will delete all the combinations. Do you wish to proceed?"|trans({}, 'Admin.Catalog.Notification'), -}|merge(js_translatable) %} - -{% set js_translatable = { -"Form update success": "Settings updated."|trans({}, 'Admin.Notifications.Success'), -"Form update errors": "Unable to update settings."|trans({}, 'Admin.Notifications.Error'), -"Delete": "Delete"|trans({}, 'Admin.Actions'), -"ToLargeFile": "The file is too large. Maximum size allowed is: [1]. The file you are trying to upload is [2]."|trans({}, 'Admin.Notifications.Error')|replace({ '[1]': '{{maxFilesize}}', '[2]': '{{filesize}}' }), -"Drop images here": "Drop images here"|trans({}, 'Admin.Catalog.Feature'), -"or select files": "or select files"|trans({}, 'Admin.Catalog.Feature'), -"files recommandations": "Recommended size 800 x 800px for default theme."|trans({}, 'Admin.Catalog.Feature'), -"files recommandations2": "JPG, GIF or PNG format."|trans({}, 'Admin.Catalog.Feature'), -"Cover": "Cover"|trans({}, 'Admin.Catalog.Feature'), -"Are you sure to delete this?": "Are you sure to delete this?"|trans({}, 'Admin.Notifications.Warning'), -"This will delete the specific price. Do you wish to proceed?": "This will delete the specific price. Do you wish to proceed?"|trans({}, 'Admin.Catalog.Notification'), -"Quantities": "Quantities"|trans({}, 'Admin.Catalog.Feature'), -"Combinations": "Combinations"|trans({}, 'Admin.Catalog.Feature'), -"Virtual product": "Virtual product"|trans({}, 'Admin.Catalog.Feature'), -"tax incl.": "tax incl."|trans({}, 'Admin.Catalog.Feature'), -"tax excl.": "tax excl."|trans({}, 'Admin.Catalog.Feature'), -"You can't create pack product with variations. Are you sure to disable variations ? they will all be deleted.": "A pack of products can't have combinations."|trans({}, "Admin.Catalog.Notification") ~ ' ' ~ js_translatable['Are you sure to disable variations ? they will all be deleted'], -"You can't create virtual product with variations. Are you sure to disable variations ? they will all be deleted.": "A virtual product can't have combinations."|trans({}, "Admin.Catalog.Notification") ~ ' ' ~ js_translatable['Are you sure to disable variations ? they will all be deleted'], -}|merge(js_translatable) %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Product/Themes/categories_theme.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Product/Themes/categories_theme.html.twig deleted file mode 100644 index 699d41a1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Product/Themes/categories_theme.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% block choice_tree_widget -%} -
    -
      - - {%- for child in choices %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
    -
    - -{%- endblock choice_tree_widget %} - -{% block choice_tree_item_widget -%} -
  • - {% set checked = (form.vars.submitted_values is defined and submitted_values[child.id_category] is defined) ? 'checked="checked"' : '' %} - -
    - -
    - - {% if child.children is defined %} -
      - {% for item in child.children %} - {% set child = item %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
    - {% endif %} -
  • -{%- endblock choice_tree_item_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/ProductImage/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/ProductImage/form.html.twig deleted file mode 100644 index 19fb1461..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/ProductImage/form.html.twig +++ /dev/null @@ -1,45 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - -
    -
    - {{ form_widget(form.cover) }} -
    - -
    - - -{{ form_widget(form.legend) }} -{{ form_errors(form.legend) }} - -
    - - -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Security/compromised.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Security/compromised.html.twig deleted file mode 100644 index 0298803b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Security/compromised.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '::base.html.twig' %} - -{% block stylesheets %} - - -{% endblock %} - -{% block title %} - {{ 'Invalid token'|trans({},'Admin.Catalog.Help' ) }} -{% endblock %} -{% block body %} -
    -
    -
    - - -

    {{ 'Do you want to display this page?'|trans({},'Admin.Catalog.Help' ) }}

    - -
    -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/form.html.twig deleted file mode 100644 index 830dff49..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/form.html.twig +++ /dev/null @@ -1,153 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(addressForm) }} -
    -
    - mail_outline - {{ 'Addresses'|trans({}, 'Admin.Navigation.Menu') }} -
    - -
    -
    - {{ form_errors(addressForm) }} - - {% block customer_information %} - {% if customerInformation is not null %} - {% if addressForm.id_customer is defined %} - {{ ps.form_widget_with_error(addressForm.id_customer) }} - {% endif %} -
    - - -
    - {% endif %} - {% if addressForm.customer_email is defined %} - {{ ps.form_group_row(addressForm.customer_email, {'attr': { - 'data-customer-information-url': path('admin_customer_for_address_information') }}, { - 'label': 'Customer email'|trans({}, 'Admin.Orderscustomers.Feature'), - }) }} - {% endif %} - {% endblock %} - - {{ ps.form_group_row(addressForm.dni, {}, { - 'label': 'Identification number'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help' : 'The national ID card number of this person, or a unique tax identification number.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(addressForm.alias, {}, { - 'label': 'Address alias'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help' : 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' - }) }} - - {{ ps.form_group_row(addressForm.first_name, {}, { - 'label': 'First name'|trans({}, 'Admin.Global'), - 'help' : 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' 0-9!<>,;?=+()@#"�{}_$%:' - }) }} - - {{ ps.form_group_row(addressForm.last_name, {}, { - 'label': 'Last name'|trans({}, 'Admin.Global'), - 'help' : 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' 0-9!<>,;?=+()@#"�{}_$%:' - }) }} - - {{ ps.form_group_row(addressForm.company, {}, { - 'label': 'Company'|trans({}, 'Admin.Global'), - 'help' : 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' - }) }} - - {{ ps.form_group_row(addressForm.vat_number, {}, { - 'label': 'VAT number'|trans({}, 'Admin.Orderscustomers.Feature'), - }) }} - - {{ ps.form_group_row(addressForm.address1, {}, { - 'label': 'Address'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.address2, {}, { - 'label': 'Address (2)'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.postcode, {}, { - 'label': 'Zip/postal code'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(addressForm.city, {}, { - 'label': 'City'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(addressForm.id_country, {'attr': { - 'class': 'js-customer-country-select', - 'data-states-url': path('admin_country_states') }}, { - 'label': 'Country'|trans({}, 'Admin.Global'), - }) }} - -
    - {{ ps.form_group_row(addressForm.id_state, {}, { - 'label': 'State'|trans({}, 'Admin.Global'), - }) }} -
    - - {{ ps.form_group_row(addressForm.phone, {}, { - 'label': 'Phone'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(addressForm.phone_mobile, {}, { - 'label': 'Mobile phone'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(addressForm.other, {}, { - 'label': 'Other'|trans({}, 'Admin.Global'), - 'help' : 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' - }) }} - - {{ form_rest(addressForm) }} -
    -
    - - -
    -{{ form_end(addressForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/required_fields.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/required_fields.html.twig deleted file mode 100644 index a6b8afc1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/Blocks/required_fields.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {{ form_start(requiredFieldsForm, {'action': path('admin_addresses_save_required_fields')}) }} -
    -

    - {{ 'Required Fields'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    - - {{ form_widget(requiredFieldsForm.required_fields) }} - {{ form_rest(requiredFieldsForm) }} -
    - -
    - {{ form_end(requiredFieldsForm) }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/add.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/add.html.twig deleted file mode 100644 index f5ee0ed4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/add.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Sell/Address/Blocks/form.html.twig', {'addressForm': addressForm}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/edit.html.twig deleted file mode 100644 index f5ee0ed4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {{ include('@PrestaShop/Admin/Sell/Address/Blocks/form.html.twig', {'addressForm': addressForm}) }} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/index.html.twig deleted file mode 100644 index b3fa4c74..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/index.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block addresses_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': addressGrid} %} -
    -
    - {% endblock %} - - {% block address_required_fields_form %} -
    -
    -

    - -

    -
    - -
    - {% include '@PrestaShop/Admin/Sell/Address/Blocks/required_fields.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/modal_create_success.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/modal_create_success.html.twig deleted file mode 100644 index 83ecf833..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Address/modal_create_success.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -{% endblock %} - -{% block javascripts %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig deleted file mode 100644 index 9c1c584f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig +++ /dev/null @@ -1,85 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block attachment_form %} - {{ form_start(attachmentForm) }} -
    -

    - person - {{ 'File'|trans({}, 'Admin.Global') }} -

    -
    -
    - {{ form_errors(attachmentForm) }} - - {{ ps.form_group_row(attachmentForm.name, {}, { - 'label': 'File name'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(attachmentForm.file_description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global') - }) }} - -
    - -
    - {{ form_widget(attachmentForm.file) }} - {{ form_errors(attachmentForm.file) }} -
    - {% block attachment_download %}{% endblock %} -
    - - {% if attachmentId is defined %} - - {% endif %} - - {% block attachment_form_rest %} - {{ form_rest(attachmentForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(attachmentForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/add.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/add.html.twig deleted file mode 100644 index f741eadb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/add.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/edit.html.twig deleted file mode 100644 index 1ed81608..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Attachment/Blocks/form.html.twig' with {'attachmentId': attachmentId} %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/index.html.twig deleted file mode 100644 index 8024272a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attachment/index.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block attachments_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': attachmentGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attribute/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attribute/index.html.twig deleted file mode 100644 index 16b72eeb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Attribute/index.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% set layoutHeaderToolbarBtn = { - add: { - href: path('admin_attributes_create', { 'attributeGroupId': attributeGroupId}), - desc: 'Add new value'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - {% block attributes_listing %} -
    -
    - {% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': attributeGrid} %} - {% block grid_panel_footer %} - - {% endblock %} - {% endembed %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/Blocks/showcase_card.html.twig deleted file mode 100644 index 9cbc748d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not isShowcaseCardClosed %} -
    -
    - -
    -
    -

    {{ 'Create attributes'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Color, dimension, size, disk space... think about attributes as properties that change from one product to another. As a consequence, attributes allow you to build product combinations.'|trans({}, 'Admin.Catalog.Feature') }}

    - - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - -
    - - close - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/index.html.twig deleted file mode 100644 index 9f688cd6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/AttributeGroup/index.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% set layoutHeaderToolbarBtn = { - add: { - href: path('admin_attribute_groups_create'), - desc: 'Add new attribute'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - - {% block attribute_group_showcase_card %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/AttributeGroup/Blocks/showcase_card.html.twig' %} -
    -
    - {% endblock %} - - {% block attributes_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': attributeGroupGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig deleted file mode 100644 index 0532c84c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig +++ /dev/null @@ -1,104 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} -{{ form_start(catalogPriceRuleForm) }} -{{ form_errors(catalogPriceRuleForm) }} -
    -

    - attach_money - {{ 'Catalog price rules'|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    - {{ ps.form_group_row(catalogPriceRuleForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - }) }} - - {% if catalogPriceRuleForm.id_shop is defined %} - {{ ps.form_group_row(catalogPriceRuleForm.id_shop, {}, { - 'label': 'Shop'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {{ ps.form_group_row(catalogPriceRuleForm.id_currency, {}, { - 'label': 'Currency'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.id_country, {}, { - 'label': 'Country'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.id_group, {}, { - 'label': 'Group'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.from_quantity, {}, { - 'label': 'From quantity'|trans({}, 'Admin.Catalog.Feature'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.price, {}, { - 'label': 'Price (tax excl.)'|trans({}, 'Admin.Catalog.Feature'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.leave_initial_price, {}, {'label': ''}) }} - - {{ ps.form_group_row(catalogPriceRuleForm.date_range.from, {}, { - 'label': 'From'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.date_range.to, {}, { - 'label': 'To'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(catalogPriceRuleForm.reduction.type, {'attr': {'class': 'js-reduction-type-source'}}, { - 'label': 'Reduction type'|trans({}, 'Admin.Catalog.Feature'), - }) }} - -
    - {{ ps.form_group_row(catalogPriceRuleForm.include_tax, {'attr': {'class': 'js-include-tax-target'}}, { - 'label': 'Reduction with or without taxes'|trans({}, 'Admin.Catalog.Feature'), - }) }} -
    - - {{ ps.form_group_row(catalogPriceRuleForm.reduction.value, {}, { - 'label': 'Reduction'|trans({}, 'Admin.Catalog.Feature'), - }) }} - - {% block catalog_price_rule_form_rest %} - {{ form_rest(catalogPriceRuleForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(catalogPriceRuleForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/create.html.twig deleted file mode 100644 index 9a7a5399..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/create.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/edit.html.twig deleted file mode 100644 index 7bf706e7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/edit.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Edit: %name%'|trans({'%name%': catalogPriceRuleName}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/CatalogPriceRule/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/index.html.twig deleted file mode 100644 index 5771c326..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/CatalogPriceRule/index.html.twig +++ /dev/null @@ -1,52 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutHeaderToolbarBtn = { - add: { - href: path('admin_catalog_price_rules_create'), - desc: 'Add new catalog price rule'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - {% block catalog_price_rule_listing %} -
    -
    - {% include'@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': catalogPriceRuleGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/breadcrumb.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/breadcrumb.html.twig deleted file mode 100644 index 2099d74d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/breadcrumb.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/cover_image.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/cover_image.html.twig deleted file mode 100644 index 93c3df68..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/cover_image.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block category_cover_image %} - {% if coverImage is defined and coverImage is not null %} -
    -
    -
    - -
    -

    {{ 'File size'|trans({}, 'Admin.Advparameters.Feature') }} {{ coverImage.size }}

    - -
    -
    -
    -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_block.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_block.html.twig deleted file mode 100644 index 52f95e51..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_block.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if isDeleteSubmitted %} - {{ form_start(deleteCategoriesForm) }} -
    -
    -

    - {{ 'What do you want to do with the products associated with this category?'|trans({}, 'Admin.Catalog.Notification') }} -

    -
    -
    -
    -
    - {{ form_widget(deleteCategoriesForm.delete_mode) }} -
    -
    - {{ form_widget(deleteCategoriesForm.categories_to_delete) }} -
    -
    -
    -
    - -
    -
    - {{ form_end(deleteCategoriesForm) }} -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig deleted file mode 100644 index b953d72a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': grid.id ~ '_grid_delete_categories_modal', - 'title': "What do you want to do with the products associated with this category?"|trans({}, 'Admin.Catalog.Notification'), - 'closable': true, - 'actions': [{ - 'type': 'button', - 'label': "Delete"|trans({}, 'Admin.Actions'), - 'class': 'btn btn-danger btn-lg js-submit-delete-categories', - }], -} %} - {% block content %} - - {% endblock %} -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig deleted file mode 100644 index a6eb2476..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/form.html.twig +++ /dev/null @@ -1,213 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import 'PrestaShopBundle:Admin:macros.html.twig' as ps %} - -{% block category_form_block %} -{{ form_start(categoryForm) }} -
    -

    - {{ 'Category'|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    - {{ form_errors(categoryForm) }} - - {{ ps.form_group_row(categoryForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' - }) }} - -
    - {{ ps.label_with_help(('Displayed'|trans({}, 'Admin.Global')), ('Click on "%displayed_label%" to index the category on your shop.'|trans({'%displayed_label%': 'Displayed'|trans({}, 'Admin.Global')}, 'Admin.Catalog.Help'))) }} -
    - {{ form_widget(categoryForm.active) }} - - {{ 'If you want a category to appear in the menu of your shop, go to [1]Modules > Module Manager[/1] and configure your menu module.'|trans({ - '[1]': '', - '[/1]': '' - }, 'Admin.Catalog.Help')|raw }} - -
    -
    - - {% if categoryForm.id_parent is defined %} -
    - -
    - {{ form_widget(categoryForm.id_parent) }} -
    -
    - {% endif %} - - {{ ps.form_group_row(categoryForm.description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global'), - 'help': 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' - }) }} - -
    - -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/cover_image.html.twig' %} - - {{ form_widget(categoryForm.cover_image) }} - - - {{ 'This is the main image for your category, displayed in the category page. The category description will overlap this image and appear in its top-left corner.'|trans({}, 'Admin.Catalog.Help') }} - -
    -
    - -
    - -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/thumbnail_image.html.twig' %} - - {{ form_widget(categoryForm.thumbnail_image) }} - - - {{ 'Displays a small image in the parent category\'s page, if the theme allows it.'|trans({}, 'Admin.Catalog.Help') }} - -
    -
    - -
    - -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/menu_thumbnail_images.html.twig' %} - - {% if allowMenuThumbnailsUpload %} - {{ form_widget(categoryForm.menu_thumbnail_images) }} - {% else %} - {{ form_widget(categoryForm.menu_thumbnail_images, {'attr': {'class': 'd-none'}}) }} - - - {% endif %} - - {{ 'The category thumbnail appears in the menu as a small image representing the category, if the theme allows it.'|trans({}, 'Admin.Catalog.Help') }} - -
    -
    - - {{ renderhook('displayBackOfficeCategory') }} - - {% block category_tool_serp %} -
    - -
    -
    - - {{ 'Here is a preview of how your page will appear in search engine results.'|trans({}, 'Admin.Global') }} - -
    -
    - {% endblock %} - -
    - {{ ps.label_with_help(('Meta title'|trans({}, 'Admin.Global')), ('Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}')) }} -
    - {{ form_widget(categoryForm.meta_title) }} -
    -
    - -
    - {{ ps.label_with_help(('Meta description'|trans({}, 'Admin.Global')), ('Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}')) }} -
    - {{ form_widget(categoryForm.meta_description) }} -
    -
    - - {% set metaKeywordHelp %} - {{ 'To add tags, click in the field, write something, and then press the "Enter" key.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' }} - {% endset %} - - {{ ps.form_group_row(categoryForm.meta_keyword, {}, { - 'label': 'Meta keywords'|trans({}, 'Admin.Global'), - 'help': metaKeywordHelp - }) }} - - {{ ps.form_group_row(categoryForm.link_rewrite, {}, { - 'label': 'Friendly URL'|trans({}, 'Admin.Global'), - 'help': 'Only letters, numbers, underscore (_) and the minus (-) character are allowed.'|trans({}, 'Admin.Catalog.Help') - }) }} - - {{ ps.form_group_row(categoryForm.group_association, {}, { - 'label': 'Group access'|trans({}, 'Admin.Catalog.Feature'), - 'help': 'Mark all of the customer groups which you would like to have access to this category.'|trans({}, 'Admin.Catalog.Help') - }) }} - -
    - -
    -
    -

    - {{ 'You now have three default customer groups.'|trans({}, 'Admin.Catalog.Help') }} -

    - -

    {{ '%group_name% - All people without a valid customer account.'|trans({'%group_name%': '' ~ defaultGroups.visitorsGroup.name ~ ''}, 'Admin.Catalog.Feature')|raw }}

    -

    {{ '%group_name% - Customer who placed an order with the guest checkout.'|trans({'%group_name%': '' ~ defaultGroups.guestsGroup.name ~ ''}, 'Admin.Catalog.Feature')|raw }}

    -

    {{ '%group_name% - All people who have created an account on this site.'|trans({'%group_name%': '' ~ defaultGroups.customersGroup.name ~ ''}, 'Admin.Catalog.Feature')|raw }}

    -
    -
    -
    - - {% if categoryForm.shop_association is defined %} -
    - -
    - {{ form_widget(categoryForm.shop_association) }} -
    -
    - {% endif %} - - {% block category_form_rest %} - {{ form_rest(categoryForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(categoryForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig deleted file mode 100644 index 3848082d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block category_javascript_block %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/listing_panel_footer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/listing_panel_footer.html.twig deleted file mode 100644 index 97f64112..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/listing_panel_footer.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if app.request.query.has('id_category') and not currentCategoryView.is_home_category %} - {% if currentCategoryView.id_parent %} - {% set params = {'id_category': currentCategoryView.id_parent} %} - {% endif %} - - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/menu_thumbnail_images.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/menu_thumbnail_images.html.twig deleted file mode 100644 index 5b95ff65..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/menu_thumbnail_images.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block category_menu_thumbnails %} - {% if menuThumbnailImages is defined and menuThumbnailImages is not empty %} -
    - {% for menuThumbnail in menuThumbnailImages %} -
    - -
    - -
    -
    - {% endfor %} -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/showcase_card.html.twig deleted file mode 100644 index 82e74a75..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not isShowcaseCardClosed %} -
    -
    - -
    -
    -

    {{ 'Set categories'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Categories are essential, as they enable you to group equivalent products. This helps customers find their way through the variety of your catalog.'|trans({}, 'Admin.Catalog.Feature') }}

    - - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - -
    - - close - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/thumbnail_image.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/thumbnail_image.html.twig deleted file mode 100644 index 1c768efb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/Blocks/thumbnail_image.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block category_thumbnail_image %} - {% if thumbnailImage is defined and thumbnailImage is not null %} -
    -
    - -
    {{ 'File size'|trans({}, 'Admin.Advparameters.Feature') }} {{ thumbnailImage.size }}
    -
    -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create.html.twig deleted file mode 100644 index 8856f4e0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create_root.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create_root.html.twig deleted file mode 100644 index e3821ec3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/create_root.html.twig +++ /dev/null @@ -1,42 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/form.html.twig' with {'categoryForm': rootCategoryForm} %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit.html.twig deleted file mode 100644 index 373ee15a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Edit: %value%'|trans({'%value%': editableCategory.name[contextLangId]}, 'Admin.Catalog.Feature') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/form.html.twig' with { - 'categoryForm': editCategoryForm, - 'thumbnailImage': editableCategory.thumbnailImage, - 'coverImage': editableCategory.coverImage, - 'menuThumbnailImages': editableCategory.menuThumbnailImages, - } %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit_root.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit_root.html.twig deleted file mode 100644 index 22f7ee59..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/edit_root.html.twig +++ /dev/null @@ -1,47 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Edit: %value%'|trans({'%value%': editableCategory.name[contextLangId]}, 'Admin.Catalog.Feature') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/form.html.twig' with { - 'categoryForm': editRootCategoryForm, - 'thumbnailImage': editableCategory.thumbnailImage, - 'coverImage': editableCategory.coverImage, - 'menuThumbnailImages': editableCategory.menuThumbnailImages, - } %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/index.html.twig deleted file mode 100644 index fda2d3b9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Categories/index.html.twig +++ /dev/null @@ -1,86 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% if not currentCategoryView.is_home_category %} - {% set layoutTitle = currentCategoryView.name %} -{% endif %} - -{% block content %} - {% block category_showcase_card %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/showcase_card.html.twig' %} -
    -
    - {% endblock %} - - {% block categories_kpis %} -
    -
    -
    -
    - {{ render(controller( - 'PrestaShopBundle:Admin\\Common:renderKpiRow', - { 'kpiRow': categoriesKpi } - )) }} -
    -
    -
    -
    - {% endblock %} - - {% block categories_breadcrumb %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/breadcrumb.html.twig' %} -
    -
    - {% endblock %} - - {% block categories_listing %} -
    -
    - {% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': categoriesGrid} %} - {% block grid_panel_footer %} - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/listing_panel_footer.html.twig' %} - {% endblock %} - - {% block grid_panel_extra_content %} - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig' %} - {% endblock %} - {% endembed %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig deleted file mode 100644 index 6a51108e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set href = path('admin_performance') ~ '#optional_features' %} -{% set linkText = 'Performance'|trans({}, 'Admin.Global') %} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig deleted file mode 100644 index a227d9ec..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import 'PrestaShopBundle:Admin:macros.html.twig' as ps %} - -{% block feature_form_block %} - {{ form_start(featureForm) }} - -
    -

    - {{ 'Feature'|trans({}, 'Admin.Catalog.Feature') }} -

    - -
    -
    - {{ ps.form_group_row(featureForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>={}' - }) }} - - {{ renderhook('displayFeatureForm', {'id_feature': featureId}) }} - - {% if featureForm.shop_association is defined %} - {{ ps.form_group_row(featureForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block feature_form_rest %} - {{ form_rest(featureForm) }} - {% endblock %} -
    -
    - - -
    - - {{ form_end(featureForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig deleted file mode 100644 index 4c5c4cd4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block feature_javascript_block %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/create.html.twig deleted file mode 100644 index ca3b175c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/create.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Add a new feature'|trans({}, 'Admin.Catalog.Feature') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% if showDisabledFeatureWarning is defined and showDisabledFeatureWarning %} - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig' %} - {% else %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/form.html.twig' with { - featureId: null, - featureForm: featureForm - } %} -
    -
    - {% endif %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/edit.html.twig deleted file mode 100644 index e1a768c7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Features/edit.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Edit: %value%'|trans({'%value%': editableFeature.name[contextLangId]}, 'Admin.Catalog.Feature') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% if showDisabledFeatureWarning is defined and showDisabledFeatureWarning %} - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/disabled_feature_warning.html.twig' %} - {% else %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/form.html.twig' with { - featureId: editableFeature.featureId.getValue, - featureForm: featureForm - } %} -
    -
    - {% endif %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - {% include '@PrestaShop/Admin/Sell/Catalog/Features/Blocks/form_javascripts.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig deleted file mode 100644 index e358da40..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig +++ /dev/null @@ -1,120 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(addressForm) }} -
    -
    - {{ 'Addresses'|trans({}, 'Admin.Catalog.Feature') }} -
    -
    -
    - {{ form_errors(addressForm) }} - - {{ ps.form_group_row(addressForm.id_manufacturer, {}, { - 'label': 'Brand'|trans({}, 'Admin.Catalog.Feature'), - }) }} - - {% set nameHint = 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' 0-9!<>,;?=+()@#"�{}_$%:' %} - - {{ ps.form_group_row(addressForm.last_name, {}, { - 'label': 'Last name'|trans({}, 'Admin.Global'), - 'help': nameHint - }) }} - - {{ ps.form_group_row(addressForm.first_name, {}, { - 'label': 'First name'|trans({}, 'Admin.Global'), - 'help': nameHint - }) }} - - {{ ps.form_group_row(addressForm.address, {}, { - 'label': 'Address'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.address2, {}, { - 'label': 'Address (2)'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.post_code, {}, { - 'label': 'Zip/postal code'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.city, {}, { - 'label': 'City'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.id_country, {'attr': { - 'class': 'js-manufacturer-country-select', - 'data-states-url': path('admin_country_states') }}, { - 'label': 'Country'|trans({}, 'Admin.Global'), - }) }} - -
    - {{ ps.form_group_row(addressForm.id_state, {}, { - 'label': 'State'|trans({}, 'Admin.Global'), - }) }} -
    - - {{ ps.form_group_row(addressForm.dni, {}, { - 'label': 'DNI'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.home_phone, {}, { - 'label': 'Home phone'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(addressForm.mobile_phone, {}, { - 'label': 'Mobile phone'|trans({}, 'Admin.Global'), - }) }} - - {% set otherHint %} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>{}' }} - {% endset %} - - {{ ps.form_group_row(addressForm.other, {}, { - 'label': 'Other'|trans({}, 'Admin.Global'), - 'help': otherHint - }) }} - - {% block manufacturer_address_form_rest %} - {{ form_rest(addressForm) }} - {% endblock %} -
    -
    - - - -
    -{{ form_end(addressForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/create.html.twig deleted file mode 100644 index 10d76961..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/create.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/edit.html.twig deleted file mode 100644 index 10d76961..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Address/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Address/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/addresses.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/addresses.html.twig deleted file mode 100644 index f028a753..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/addresses.html.twig +++ /dev/null @@ -1,80 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Addresses'|trans({}, 'Admin.Global') }} - ({{ viewableManufacturer.manufacturerAddresses|length }}) -

    -
    - {% if viewableManufacturer.manufacturerAddresses is not empty %} - - - - - - - - - - - - - - - - {% for address in viewableManufacturer.manufacturerAddresses %} - - - - - - - - - - - - {% endfor %} - -
    {{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Address'|trans({}, 'Admin.Global') }}{{ 'Address (2)'|trans({}, 'Admin.Global') }}{{ 'City'|trans({}, 'Admin.Global') }}{{ 'State'|trans({}, 'Admin.Global') }}{{ 'Home phone'|trans({}, 'Admin.Global') }}{{ 'Mobile phone'|trans({}, 'Admin.Global') }}{{ 'Other'|trans({}, 'Admin.Global') }}
    {{ address.first_name }} {{ address.last_name }}{{ address.address1 }}{{ address.address2 }}{{ address.city }}{% if address.state %}{{ address.state }}{% else %}-{% endif %}{% if address.phone %}{{ address.phone }}{% else %}-{% endif %}{% if address.phone_mobile %}{{ address.phone_mobile }}{% else %}-{% endif %}{% if address.other %}{{ address.other|nl2br }}{% else %}-{% endif %} -
    - -
    -
    - {% else %} - {{ 'No address has been found for this brand.'|trans({}, 'Admin.Catalog.Notification') }} - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/products.html.twig deleted file mode 100644 index 09f9d9ac..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/View/products.html.twig +++ /dev/null @@ -1,120 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Products'|trans({}, 'Admin.Global') }} - ({{ viewableManufacturer.manufacturerProducts|length }}) -

    -
    - {% for product in viewableManufacturer.manufacturerProducts %} -
    -
    - {{ product.name }} - -
    -
    -
    - - -
    -
    -
    -
    -
    - {% if product.combinations is not empty %} - - - - - - - - - {% if not isAllShopContext and isStockManagementEnabled %} - - {% endif %} - - - - {% for combination in product.combinations %} - - - - - - - {% if not isAllShopContext and isStockManagementEnabled %} - - {% endif %} - - {% endfor %} - -
    {{ 'Attribute name'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Reference'|trans({}, 'Admin.Global') }}{{ 'EAN13'|trans({}, 'Admin.Catalog.Feature') }}{{ 'UPC'|trans({}, 'Admin.Catalog.Feature') }}{{ 'MPN'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Available quantity'|trans({}, 'Admin.Catalog.Feature') }}
    {{ combination.attributes }}{{ combination.reference }}{{ combination.ean13 }}{{ combination.upc }}{{ combination.mpn }}{{ combination.quantity }}
    - {% else %} - - - - - - - - {% if isStockManagementEnabled %} - - {% endif %} - - - - - - - - - {% if isStockManagementEnabled %} - - {% endif %} - - -
    {{ 'Ref:'|trans({}, 'Admin.Catalog.Feature') }}{{ 'EAN13:'|trans({}, 'Admin.Catalog.Feature') }}{{ 'UPC:'|trans({}, 'Admin.Catalog.Feature') }}{{ 'MPN:'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Qty:'|trans({}, 'Admin.Catalog.Feature') }}
    {{ product.reference }}{{ product.ean13 }}{{ product.upc }}{{ product.mpn }}{{ product.quantity }}
    - {% endif %} -
    -
    - {% endfor %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig deleted file mode 100644 index 160a0a78..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig +++ /dev/null @@ -1,121 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(manufacturerForm) }} -
    -

    - star - {{ 'Brands'|trans({}, 'Admin.Catalog.Feature') }} -

    -
    -
    - {{ form_errors(manufacturerForm) }} - - {% set invalidCatalogNameHint %} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' }} - {% endset %} - - {{ ps.form_group_row(manufacturerForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': invalidCatalogNameHint - }) }} - - {% set invalidGenericNameHint %} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>={}' }} - {% endset %} - - {{ ps.form_group_row(manufacturerForm.short_description, {}, { - 'label': 'Short description'|trans({}, 'Admin.Catalog.Feature'), - }) }} - - {{ ps.form_group_row(manufacturerForm.description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global') - }) }} - - {% set logoHint %} - {{ 'Upload a brand logo from your computer.'|trans({}, 'Admin.Catalog.Help') }} - {% endset %} - - {{ ps.form_group_row(manufacturerForm.logo, {}, { - 'label': 'Logo'|trans({}, 'Admin.Global'), - 'help': logoHint - }) }} - - {% if logoImage is defined and logoImage is not null %} -
    - -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/logo_image.html.twig' %} -
    -
    - {% endif %} - - {{ ps.form_group_row(manufacturerForm.meta_title, {}, { - 'label': 'Meta title'|trans({}, 'Admin.Catalog.Feature'), - 'help': invalidGenericNameHint - }) }} - - {{ ps.form_group_row(manufacturerForm.meta_description, {}, { - 'label': 'Meta description'|trans({}, 'Admin.Global'), - 'help': invalidGenericNameHint - }) }} - - {% set keywordHint %} - {{ 'To add tags, click in the field, write something, and then press the "Enter" key.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ invalidGenericNameHint }} - {% endset %} - - {{ ps.form_group_row(manufacturerForm.meta_keyword, {}, { - 'label': 'Meta keywords'|trans({}, 'Admin.Global'), - 'help': keywordHint - }) }} - - {{ ps.form_group_row(manufacturerForm.is_enabled, {}, { - 'label': 'Enabled'|trans({}, 'Admin.Global') - }) }} - - {% if manufacturerForm.shop_association is defined %} - {{ ps.form_group_row(manufacturerForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block manufacturer_form_rest %} - {{ form_rest(manufacturerForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(manufacturerForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/add.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/add.html.twig deleted file mode 100644 index 208244a2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/add.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/edit.html.twig deleted file mode 100644 index 94f863aa..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/edit.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Edit: %name%'|trans({'%name%': manufacturerName}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/index.html.twig deleted file mode 100644 index e16b8f36..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/index.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% set layoutHeaderToolbarBtn = { - add_manufacturer: { - href: path('admin_manufacturers_create'), - desc: 'Add new brand'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - }, - add_manufacturer_address: { - href: path('admin_manufacturer_addresses_create'), - desc: 'Add new brand address'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - }, -} -%} - -{% block content %} - {% block manufacturers_listing %} - {{ ps.infotip(settingsTipMessage, true) }} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': manufacturerGrid} %} -
    -
    - {% endblock %} - - {% block manufacturers_address_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': manufacturerAddressGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/logo_image.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/logo_image.html.twig deleted file mode 100644 index da8e989b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/logo_image.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - -
    {{ 'File size'|trans({}, 'Admin.Advparameters.Feature') }} {{ logoImage.size }}
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/view.html.twig deleted file mode 100644 index a413ed91..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Manufacturer/view.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Blocks/View/addresses.html.twig' %} -
    -
    - -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Manufacturer/Blocks/View/products.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/Blocks/showcase_card.html.twig deleted file mode 100644 index afbb4ad3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not isShowcaseCardClosed %} -
    -
    - -
    -
    -

    {{ 'Focus on your catalog'|trans({}, 'Admin.Catalog.Feature') }}

    -

    {{ 'Empty categories, disabled products, items that lack image or price... check the monitoring section to optimize your products management and make sure you forgot nothing.'|trans({}, 'Admin.Catalog.Feature') }}

    - - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - -
    - - close - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/index.html.twig deleted file mode 100644 index 0829c629..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Monitoring/index.html.twig +++ /dev/null @@ -1,120 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block monitoring_showcase_card %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Monitoring/Blocks/showcase_card.html.twig' %} -
    -
    - {% endblock %} - - {% block empty_categories_listing %} -
    -
    - {% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': emptyCategoryGrid} %} - - {% block grid_panel_body %} -
    -
    -
    - {{ 'An empty category is a category that has no product directly associated to it. An empty category may however contain products through its subcategories.'|trans({}, 'Admin.Catalog.Help') }} -
    -
    - {% block grid_view_block %} - {{ include('@PrestaShop/Admin/Common/Grid/grid.html.twig', {'grid': emptyCategoryGrid }) }} - {% endblock %} -
    - {% endblock %} - - {% block grid_panel_extra_content %} - {% include '@PrestaShop/Admin/Sell/Catalog/Categories/Blocks/delete_categories_modal.html.twig' - with {'deleteCategoriesForm': deleteCategoryForm } - %} - {% endblock %} - {% endembed %} -
    -
    - {% endblock %} - - {% block no_qty_product_with_combinations_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': noQtyProductWithCombinationGrid} %} -
    -
    - {% endblock %} - - {% block no_qty_product_without_combinations_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': noQtyProductWithoutCombinationGrid} %} -
    -
    - {% endblock %} - - {% block disabled_product_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': disabledProductGrid} %} -
    -
    - {% endblock %} - - {% block product_without_image_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': productWithoutImageGrid} %} -
    -
    - {% endblock %} - - {% block product_without_description_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': productWithoutDescriptionGrid} %} -
    -
    - {% endblock %} - - {% block product_without_price_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': productWithoutPriceGrid} %} -
    -
    - {% endblock %} - -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/View/products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/View/products.html.twig deleted file mode 100644 index e6ff545b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/View/products.html.twig +++ /dev/null @@ -1,92 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Products'|trans({}, 'Admin.Global') }} - ({{ viewableSupplier.supplierProducts|length }}) -

    -
    - {% for product in viewableSupplier.supplierProducts %} -
    - -
    - - - - - - - - - - {% if not isAllShopContext and isStockManagementEnabled %} - - {% endif %} - - - - {% if product.combinations is not empty %} - {% for combination in product.combinations %} - - - - - - - - {% if not isAllShopContext and isStockManagementEnabled %} - - {% endif %} - - {% endfor %} - {% else %} - - - - - - - - {% if not isAllShopContext and isStockManagementEnabled %} - - {% endif %} - - {% endif %} - -
    {{ 'Attribute name'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Supplier reference'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Wholesale price'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Reference'|trans({}, 'Admin.Global') }}{{ 'EAN13'|trans({}, 'Admin.Catalog.Feature') }}{{ 'UPC'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Available quantity'|trans({}, 'Admin.Catalog.Feature') }}
    {{ combination.attributes|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.supplier_reference|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.wholesale_price|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.reference|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.ean13|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.upc|default('N/A'|trans({}, 'Admin.Global')) }}{{ combination.quantity|default('N/A'|trans({}, 'Admin.Global')) }}
    {{ product.combinations|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.supplier_reference|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.wholesale_price|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.reference|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.ean13|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.upc|default('N/A'|trans({}, 'Admin.Global')) }}{{ product.quantity|default('N/A'|trans({}, 'Admin.Global')) }}
    -
    -
    - {% endfor %} - {% if viewableSupplier.supplierProducts is empty %} -
    -

    warning

    -

    {{ 'No records found'|trans({}, 'Admin.Global') }}

    -
    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig deleted file mode 100644 index 84a83576..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig +++ /dev/null @@ -1,162 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(supplierForm) }} -
    -

    - local_shipping - {{ 'Suppliers'|trans({}, 'Admin.Global') }} -

    -
    -
    - - {% set invalidCatalogNameHint %} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>;=#{}' }} - {% endset %} - - {{ ps.form_group_row(supplierForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global'), - 'help': invalidCatalogNameHint - }) }} - - {% set invalidGenericNameHint %} - {{ 'Invalid characters:'|trans({}, 'Admin.Notifications.Info') ~ ' <>={}' }} - {% endset %} - - {% set descriptionHint %} - {% autoescape false %} - {{ 'Will appear in the list of suppliers.'|trans({}, 'Admin.Catalog.Help')~ invalidCatalogNameHint }} - {% endautoescape %} - {% endset %} - - {{ ps.form_group_row(supplierForm.description, {}, { - 'label': 'Description'|trans({}, 'Admin.Global'), - 'help': descriptionHint - }) }} - - {{ ps.form_group_row(supplierForm.phone, {}, { - 'label': 'Home phone'|trans({}, 'Admin.Global'), - 'hint': 'Phone number for this supplier'|trans({}, 'Admin.Catalog.Help') - }) }} - - {{ ps.form_group_row(supplierForm.mobile_phone, {}, { - 'label': 'Mobile phone'|trans({}, 'Admin.Global'), - 'hint': 'Mobile phone number for this supplier.'|trans({}, 'Admin.Catalog.Help') - }) }} - - {{ ps.form_group_row(supplierForm.address, {}, { - 'label': 'Address'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(supplierForm.address2, {}, { - 'label': 'Address (2)'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(supplierForm.post_code, {}, { - 'label': 'Zip/postal code'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(supplierForm.city, {}, { - 'label': 'City'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(supplierForm.id_country, {'attr': { - 'class': 'js-supplier-country-select', - 'data-states-url': path('admin_country_states') }}, { - 'label': 'Country'|trans({}, 'Admin.Global'), - }) }} - -
    - {{ ps.form_group_row(supplierForm.id_state, {}, { - 'label': 'State'|trans({}, 'Admin.Global'), - }) }} -
    - - {{ ps.form_group_row(supplierForm.dni, {}, { - 'label': 'DNI'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(supplierForm.logo, {}, { - 'label': 'Logo'|trans({}, 'Admin.Global'), - 'help': 'Upload a supplier logo from your computer.'|trans({}, 'Admin.Catalog.Help') - }) }} - - {% if logoImage is defined and logoImage is not null %} -
    - -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Suppliers/logo_image.html.twig' %} -
    -
    - {% endif %} - - {{ ps.form_group_row(supplierForm.meta_title, {}, { - 'label': 'Meta title'|trans({}, 'Admin.Catalog.Feature'), - 'help': invalidGenericNameHint - }) }} - - {{ ps.form_group_row(supplierForm.meta_description, {}, { - 'label': 'Meta description'|trans({}, 'Admin.Global'), - 'help': invalidGenericNameHint - }) }} - - {% set keywordHint %} - {{ 'To add tags, click in the field, write something, and then press the "Enter" key.'|trans({}, 'Admin.Shopparameters.Help') }} - {{ invalidGenericNameHint }} - {% endset %} - - {{ ps.form_group_row(supplierForm.meta_keyword, {}, { - 'label': 'Meta keywords'|trans({}, 'Admin.Global'), - 'help': keywordHint - }) }} - - {{ ps.form_group_row(supplierForm.is_enabled, {}, { - 'label': 'Enabled'|trans({}, 'Admin.Global') - }) }} - - {% if supplierForm.shop_association is defined %} - {{ ps.form_group_row(supplierForm.shop_association, {}, { - 'label': 'Shop association'|trans({}, 'Admin.Global') - }) }} - {% endif %} - - {% block supplier_form_rest %} - {{ form_rest(supplierForm) }} - {% endblock %} - -
    -
    - -
    - {{ form_end(supplierForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/add.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/add.html.twig deleted file mode 100644 index 6b471172..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/add.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Add new'|trans({}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/edit.html.twig deleted file mode 100644 index 12715260..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/edit.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Edit: %name%'|trans({'%name%': supplierName}, 'Admin.Actions') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Suppliers/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/index.html.twig deleted file mode 100644 index 1720cc1e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/index.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutHeaderToolbarBtn = { - add: { - href: path('admin_suppliers_create'), - desc: 'Add new supplier'|trans({}, 'Admin.Catalog.Feature'), - icon: 'add_circle_outline', - } -} -%} - -{% block content %} - {% block supplier_grid %} - {{ ps.infotip(settingsTipMessage, true) }} -
    -
    - {% include'@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': supplierGrid} %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/logo_image.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/logo_image.html.twig deleted file mode 100644 index da8e989b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/logo_image.html.twig +++ /dev/null @@ -1,28 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
    - -
    {{ 'File size'|trans({}, 'Admin.Advparameters.Feature') }} {{ logoImage.size }}
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/view.html.twig deleted file mode 100644 index 6db0572a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Catalog/Suppliers/view.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Catalog/Suppliers/Blocks/View/products.html.twig' %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/Index/required_fields.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/Index/required_fields.html.twig deleted file mode 100644 index 47b16f8c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/Index/required_fields.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    - {{ form_start(customerRequiredFieldsForm, {'action': path('admin_customers_set_required_fields')}) }} -
    -

    - {{ 'Required Fields'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    - - - {{ form_widget(customerRequiredFieldsForm.required_fields) }} -
    - -
    - {{ form_end(customerRequiredFieldsForm) }} -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/addresses.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/addresses.html.twig deleted file mode 100644 index 5b559ee7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/addresses.html.twig +++ /dev/null @@ -1,120 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - location_on - {{ 'Addresses'|trans({}, 'Admin.Global') }} - - - add_circle - -

    - -
    - {% if customerInformation.addressesInformation is not empty %} - - - - - - - - - - - - - {% for address in customerInformation.addressesInformation %} - {% set addressEditUrl = getAdminLink('AdminAddresses', true, {'id_address': address.addressId, 'updateaddress': 1, 'back': app.request.uri}) %} - - - - - - - - - - {% endfor %} - -
    {{ 'Company'|trans({}, 'Admin.Global') }}{{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Address'|trans({}, 'Admin.Global') }}{{ 'Country'|trans({}, 'Admin.Global') }}{{ 'Phone number(s)'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
    {{ address.company }}{{ address.fullName }}{{ address.fullAddress }}{{ address.countryName }} - {% if address.phone %} - {{ address.phone }} - {% if address.phoneMobile is not empty %} -
    {{ address.phoneMobile }} - {% endif %} - {% elseif address.phoneMobile is not empty %} - {{ address.phoneMobile }} - {% else %} - -- - {% endif %} -
    -
    -
    - - edit - - - - - -
    -
    -
    - {% else %} -

    - {{ '%firstname% %lastname% has not registered any addresses yet'|trans({'%firstname%': customerInformation.personalInformation.firstName, '%lastname%': customerInformation.personalInformation.lastName}, 'Admin.Orderscustomers.Feature') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/bought_products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/bought_products.html.twig deleted file mode 100644 index 7862f5fa..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/bought_products.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if customerInformation.productsInformation.boughtProductsInformation is not empty %} -
    -

    - attach_money - {{ 'Purchased products'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerInformation.productsInformation.boughtProductsInformation|length }} -

    -
    - - - - - - - - - - {% for product in customerInformation.productsInformation.boughtProductsInformation %} - - - - - - {% endfor %} - -
    {{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Quantity'|trans({}, 'Admin.Global') }}
    {{ product.boughtDate }} - - {{ product.productName }} - - {{ product.boughtQuantity }}
    -
    -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/carts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/carts.html.twig deleted file mode 100644 index 0060d302..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/carts.html.twig +++ /dev/null @@ -1,77 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - shopping_cart - {{ 'Carts'|trans({}, 'Admin.Global') }} - {{ customerInformation.cartsInformation|length }} -

    -
    - {% if customerInformation.cartsInformation is not empty %} - - - - - - - - - - - - {% for cart in customerInformation.cartsInformation %} - {% set cartViewUrl = getAdminLink('AdminCarts', true, {'id_cart': cart.cartId, 'viewcart': 1}) %} - - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Carrier'|trans({}, 'Admin.Global') }}{{ 'Total'|trans({}, 'Admin.Global') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
    {{ cart.cartId }}{{ cart.cartCreationDate }}{{ cart.carrierName }}{{ cart.cartTotal }} - -
    - {% else %} -

    - {{ 'No cart is available'|trans({}, 'Admin.Orderscustomers.Notification') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/discounts.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/discounts.html.twig deleted file mode 100644 index 2ce78b44..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/discounts.html.twig +++ /dev/null @@ -1,104 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - loyalty - {{ 'Vouchers'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerInformation.discountsInformation|length }} -

    -
    - {% if customerInformation.discountsInformation is not empty %} - - - - - - - - - - - - - {% for discount in customerInformation.discountsInformation %} - {% set discountEditUrl = getAdminLink('AdminCartRules', true, {'id_cart_rule': discount.discountId, 'addcart_rule': 1, 'back': app.request.uri}) %} - - - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Code'|trans({}, 'Admin.Global') }}{{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Status'|trans({}, 'Admin.Global') }}{{ 'Qty available'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
    {{ discount.discountId }}{{ discount.code }}{{ discount.name }} - {% if discount.active %} - - check - - {% else %} - - clear - - {% endif %} - {{ discount.availableQuantity }} - -
    - {% else %} -

    - {{ '%firstname% %lastname% has no discount vouchers'|trans({'%firstname%': customerInformation.personalInformation.firstName, '%lastname%': customerInformation.personalInformation.lastName}, 'Admin.Orderscustomers.Feature') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/groups.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/groups.html.twig deleted file mode 100644 index b1ac7d44..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/groups.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - group - {{ 'Groups'|trans({}, 'Admin.Global') }} - {{ customerInformation.groupsInformation|length }} - - - edit - -

    -
    - {% if customerInformation.groupsInformation is not empty %} - - - - - - - - - {% for group in customerInformation.groupsInformation %} - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Name'|trans({}, 'Admin.Global') }}
    {{ group.groupId }} - - {{ group.name }} - -
    - {% else %} -

    - {{ 'No cart is available'|trans({}, 'Admin.Orderscustomers.Notification') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/last_connections.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/last_connections.html.twig deleted file mode 100644 index d0a30053..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/last_connections.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if customerInformation.lastConnectionsInformation is not empty %} -
    -

    - access_time - {{ 'Last connections'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerInformation.lastConnectionsInformation|length }} -

    -
    - - - - - - - - - - - - - {% for connection in customerInformation.lastConnectionsInformation %} - - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Pages viewed'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Total time'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Origin'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'IP Address'|trans({}, 'Admin.Orderscustomers.Feature') }}
    {{ connection.connectionId }}{{ connection.connectionDate }}{{ connection.pagesViewed }}{{ connection.totalTime }}{{ connection.httpReferer }}{{ connection.ipAddress }}
    -
    -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/messages.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/messages.html.twig deleted file mode 100644 index 5f943eb9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/messages.html.twig +++ /dev/null @@ -1,62 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - message - {{ 'Messages'|trans({}, 'Admin.Global') }} - {{ customerInformation.messagesInformation|length }} -

    -
    - {% if customerInformation.messagesInformation is not empty %} - - - - - - - - - - {% for message in customerInformation.messagesInformation %} - - - - - - {% endfor %} - -
    {{ 'Status'|trans({}, 'Admin.Global') }}{{ 'Message'|trans({}, 'Admin.Global') }}{{ 'Sent on'|trans({}, 'Admin.Orderscustomers.Feature') }}
    {{ message.status }} - - {{ message.message }}... - - {{ message.date }}
    - {% else %} -

    - {{ '%firstname% %lastname% has never contacted you'|trans({'%firstname%': customerInformation.personalInformation.firstName, '%lastname%': customerInformation.personalInformation.lastName}, 'Admin.Orderscustomers.Feature') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/orders.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/orders.html.twig deleted file mode 100644 index ebdd8ed4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/orders.html.twig +++ /dev/null @@ -1,156 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set validOrdersCount = customerInformation.ordersInformation.validOrders|length %} -{% set invalidOrdersCount = customerInformation.ordersInformation.invalidOrders|length %} -{% set ordersCount = validOrdersCount + invalidOrdersCount %} - -
    -

    - shopping_basket - {{ 'Orders'|trans({}, 'Admin.Global') }} - {{ ordersCount }} -

    -
    - {% if ordersCount > 0 %} -
    -
    -
    -
    - {{ 'Valid orders:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ validOrdersCount }} - {% set totalAmount = ''~customerInformation.ordersInformation.totalSpent~'' %} - {{ 'for a total amount of %s'|trans({}, 'Admin.Orderscustomers.Feature')|format(totalAmount)|raw }} -
    -
    - {{ 'Invalid orders:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ invalidOrdersCount }} -
    -
    -
    -
    - -
    -
    - {% if validOrdersCount %} - - - - - - - - - - - - - - {% for order in customerInformation.ordersInformation.validOrders %} - {% set orderViewUrl = getAdminLink('AdminOrders', true, {'id_order': order.orderId, 'vieworder': 1}) %} - - - - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Payment'|trans({}, 'Admin.Global') }}{{ 'Status'|trans({}, 'Admin.Global') }}{{ 'Products'|trans({}, 'Admin.Global') }}{{ 'Total spent'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
    {{ order.orderId }}{{ order.orderPlacedDate }}{{ order.paymentMethodName }}{{ order.orderStatus }}{{ order.orderProductsCount }}{{ order.totalPaid }} - -
    - {% endif %} -
    -
    - -
    -
    - {% if invalidOrdersCount %} - - - - - - - - - - - - - - {% for order in customerInformation.ordersInformation.invalidOrders %} - {% set orderViewUrl = getAdminLink('AdminOrders', true, {'id_order': order.orderId, 'vieworder': 1}) %} - - - - - - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Payment'|trans({}, 'Admin.Global') }}{{ 'Status'|trans({}, 'Admin.Global') }}{{ 'Products'|trans({}, 'Admin.Global') }}{{ 'Total spent'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
    {{ order.orderId }}{{ order.orderPlacedDate }}{{ order.paymentMethodName }}{{ order.orderStatus }}{{ order.orderProductsCount }}{{ order.totalPaid }} - -
    - {% endif %} -
    -
    - {% else %} -

    - {{ '%firstname% %lastname% has not placed any orders yet'|trans({'%firstname%': customerInformation.personalInformation.firstName, '%lastname%': customerInformation.personalInformation.lastName}, 'Admin.Orderscustomers.Feature') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/personal_information.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/personal_information.html.twig deleted file mode 100644 index af1a9cb4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/personal_information.html.twig +++ /dev/null @@ -1,184 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - person - {{ customerInformation.personalInformation.firstName }} - {{ customerInformation.personalInformation.lastName }} - {{ '[%06d]'|format(customerInformation.customerId.value) }} - - - - {{ customerInformation.personalInformation.email }} - - - - edit - -

    -
    -
    -
    - {{ 'Social Title'|trans({}, 'Admin.Global') }} -
    -
    - {{ customerInformation.personalInformation.socialTitle }} -
    -
    - -
    -
    - {{ 'Age'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {{ customerInformation.personalInformation.birthday }} -
    -
    - -
    -
    - {{ 'Registration Date'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {{ customerInformation.personalInformation.registrationDate }} -
    -
    - -
    -
    - {{ 'Last Visit'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {{ customerInformation.personalInformation.lastVisitDate }} -
    -
    - - {% if customerInformation.personalInformation.rankBySales %} -
    -
    - {{ 'Best Customer Rank'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {{ customerInformation.personalInformation.rankBySales }} -
    -
    - {% endif %} - - {% if isMultistoreEnabled %} -
    -
    - {{ 'Shop'|trans({}, 'Admin.Global') }} -
    -
    - {{ customerInformation.personalInformation.shopName }} -
    -
    - {% endif %} - -
    -
    - {{ 'Language'|trans({}, 'Admin.Global') }} -
    -
    - {{ customerInformation.personalInformation.languageName }} -
    -
    - -
    -
    - {{ 'Registrations'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {% set isNewsletterSubscribed = customerInformation.personalInformation.subscriptions.newsletterSubscribed %} - {% set isPartnerOffersSubscribed = customerInformation.personalInformation.subscriptions.partnerOffersSubscribed %} - - - {% if isNewsletterSubscribed %}check{% else %}cancel{% endif %} - {{ 'Newsletter'|trans({}, 'Admin.Global') }} - - - - {% if isPartnerOffersSubscribed %}check{% else %}cancel{% endif %} - {{ 'Partner offers'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
    -
    - -
    -
    - {{ 'Latest Update'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {{ customerInformation.personalInformation.lastUpdateDate }} -
    -
    - -
    -
    - {{ 'Status'|trans({}, 'Admin.Global') }} -
    -
    - {% set isCustomerActive = customerInformation.personalInformation.active %} - - - {% if isCustomerActive %} - check - {{ 'Active'|trans({}, 'Admin.Global') }} - {% else %} - cancel - {{ 'Inactive'|trans({}, 'Admin.Global') }} - {% endif %} - -
    -
    - - {% if customerInformation.personalInformation.guest %} -
    -
    - {{ 'This customer is registered as a Guest.'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - {% if customerInformation.generalInformation.customerBySameEmailExists %} -

    {{ 'A registered customer account using the defined email address already exists. '|trans({}, 'Admin.Orderscustomers.Notification') }}

    - {% else %} - {{ form_start(transferGuestAccountForm, {'action': path('admin_customers_transform_guest_to_customer', {'customerId': customerInformation.customerId.value})}) }} - - -

    {{ 'This feature generates a random password before sending an email to your customer.'|trans({}, 'Admin.Orderscustomers.Help') }}

    - {{ form_end(transferGuestAccountForm) }} - {% endif %} -
    -
    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/private_note.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/private_note.html.twig deleted file mode 100644 index e04c7fac..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/private_note.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - visibility_off - {{ 'Add a private note'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    - - - {{ form_start(privateNoteForm, {'action': path('admin_customers_set_private_note', {'customerId': customerInformation.customerId.value})}) }} - {{ form_widget(privateNoteForm.note) }} - - - {{ form_end(privateNoteForm) }} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/sent_emails.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/sent_emails.html.twig deleted file mode 100644 index 0620442e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/sent_emails.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - mail_outline - {{ 'Last emails'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerInformation.sentEmailsInformation|length }} -

    -
    - {% if customerInformation.sentEmailsInformation is not empty %} - - - - - - - - - - - {% for sentEmail in customerInformation.sentEmailsInformation %} - - - - - - - {% endfor %} - -
    {{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Language'|trans({}, 'Admin.Global') }}{{ 'Subject'|trans({}, 'Admin.Global') }}{{ 'Template'|trans({}, 'Admin.Global') }}
    {{ sentEmail.date }}{{ sentEmail.language }}{{ sentEmail.subject }}{{ sentEmail.template }}
    - {% else %} -

    - {{ 'No records found'|trans({}, 'Admin.Global') }} -

    - {% endif %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/viewed_products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/viewed_products.html.twig deleted file mode 100644 index 6946c509..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/View/viewed_products.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if customerInformation.productsInformation.viewedProductsInformation is not empty %} -
    -

    - remove_red_eye - {{ 'Viewed products'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerInformation.productsInformation.viewedProductsInformation|length }} -

    -
    - - - - - - - - - {% for product in customerInformation.productsInformation.viewedProductsInformation %} - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Name'|trans({}, 'Admin.Global') }}
    {{ product.productId }} - - {{ product.productName }} - -
    -
    -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/delete_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/delete_modal.html.twig deleted file mode 100644 index ac340fa2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/delete_modal.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': grid.id ~ '_grid_delete_customers_modal', - 'title': "How do you want to delete the selected customers?"|trans({}, 'Admin.Orderscustomers.Notification'), - 'closable': true, - 'actions': [{ - 'type': 'button', - 'label': "Delete"|trans({}, 'Admin.Actions'), - 'class': 'btn btn-danger btn-lg js-submit-delete-customers', - }], -} %} - {% block content %} - - {% endblock %} -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/form.html.twig deleted file mode 100644 index 2554421f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/form.html.twig +++ /dev/null @@ -1,141 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set allowedNameChars = '0-9!<>,;?=+()@#"°{}_$%:' %} -{% set isGuest = isGuest|default(false) %} - -{% block customer_form %} - {{ form_start(customerForm) }} -
    -

    - person - {{ 'Customer'|trans({}, 'Admin.Global') }} -

    -
    -
    - {{ form_errors(customerForm) }} - - {{ ps.form_group_row(customerForm.gender_id, {}, { - 'label': 'Social title'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(customerForm.first_name, {}, { - 'label': 'First name'|trans({}, 'Admin.Global'), - 'help': 'Only letters and the dot (.) character, followed by a space, are allowed.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(customerForm.last_name, {}, { - 'label': 'Last name'|trans({}, 'Admin.Global'), - 'help': 'Only letters and the dot (.) character, followed by a space, are allowed.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(customerForm.email, {}, { - 'label': 'Email'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(customerForm.password, {}, { - 'label': 'Password'|trans({}, 'Admin.Global'), - 'help': 'Password should be at least %length% characters long.'|trans({'%length%': minPasswordLength}, 'Admin.Notifications.Info'), - 'class': isGuest ? 'd-none' : '' - }) }} - - {{ ps.form_group_row(customerForm.birthday, {}, { - 'label': 'Birthday'|trans({}, 'Admin.Orderscustomers.Feature') - }) }} - - {{ ps.form_group_row(customerForm.is_enabled, {}, { - 'label': 'Enabled'|trans({}, 'Admin.Global'), - 'help': 'Enable or disable customer login.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(customerForm.is_partner_offers_subscribed, {}, { - 'label': 'Partner offers'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': 'This customer will receive your ads via email.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(customerForm.group_ids, {}, { - 'label': 'Group access'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': 'Select all the groups that you would like to apply to this customer.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(customerForm.default_group_id, {}, { - 'label': 'Default customer group'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': '%s %s'|format('This group will be the user\'s default group.'|trans({}, 'Admin.Orderscustomers.Help'), 'Only the discount for the selected group will be applied to this customer.'|trans({}, 'Admin.Orderscustomers.Help')) - }) }} - - {% if isB2bFeatureActive %} - {{ ps.form_group_row(customerForm.company_name, {}, { - 'label': 'Company'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(customerForm.siret_code, {}, { - 'label': 'SIRET'|trans({}, 'Admin.Orderscustomers.Feature') - }) }} - - {{ ps.form_group_row(customerForm.ape_code, {}, { - 'label': 'APE'|trans({}, 'Admin.Orderscustomers.Feature') - }) }} - - {{ ps.form_group_row(customerForm.website, {}, { - 'label': 'Website'|trans({}, 'Admin.Orderscustomers.Feature') - }) }} - - {{ ps.form_group_row(customerForm.allowed_outstanding_amount, {}, { - 'label': 'Allowed outstanding amount'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': '%s 0-9'|format('Valid characters:'|trans({}, 'Admin.Orderscustomers.Help')) - }) }} - - {{ ps.form_group_row(customerForm.max_payment_days, {}, { - 'label': 'Maximum number of payment days'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': '%s 0-9'|format('Valid characters:'|trans({}, 'Admin.Orderscustomers.Help')) - }) }} - - {{ ps.form_group_row(customerForm.risk_id, {}, { - 'label': 'Risk rating'|trans({}, 'Admin.Orderscustomers.Feature') - }) }} - {% endif %} - - {% block customer_form_rest %} - {{ form_rest(customerForm) }} - {% endblock %} -
    -
    - -
    - {{ form_end(customerForm) }} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/javascript.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/javascript.html.twig deleted file mode 100644 index dd00e545..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/javascript.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block customer_javascripts %} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/showcase_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/showcase_card.html.twig deleted file mode 100644 index 39678bd3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/Blocks/showcase_card.html.twig +++ /dev/null @@ -1,45 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not isShowcaseCardClosed %} -
    -
    - -
    -
    -

    {{ 'Administrate your customers'|trans({}, 'Admin.Orderscustomers.Feature') }}

    -

    {{ 'Taking good care of your customers starts with making sure their profiles contain all the information needed to have their packages shipped without mishap.'|trans({}, 'Admin.Orderscustomers.Feature') }}

    - - {{ 'Learn more'|trans({}, 'Admin.Actions') }} - -
    - - close - -
    -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/create.html.twig deleted file mode 100644 index d80909ad..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/create.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Creating a new Customer'|trans({}, 'Admin.Orderscustomers.Feature') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/javascript.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/edit.html.twig deleted file mode 100644 index 508fc871..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/edit.html.twig +++ /dev/null @@ -1,44 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set fullName = '%s. %s'|format(customerInformation.personalInformation.firstName[:1], customerInformation.personalInformation.lastName) %} -{% set layoutTitle = 'Editing customer %name%'|trans({'%name%': fullName}, 'Admin.Orderscustomers.Feature') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/form.html.twig' with {'isGuest': customerInformation.personalInformation.guest} %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/javascript.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/index.html.twig deleted file mode 100644 index 949ca04c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/index.html.twig +++ /dev/null @@ -1,118 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Manage your Customers'|trans({}, 'Admin.Orderscustomers.Feature') %} - -{% if isSingleShopContext %} - {% set layoutHeaderToolbarBtn = { - 'add': { - 'href': path('admin_customers_create'), - 'desc': 'Add new customer'|trans({}, 'Admin.Orderscustomers.Feature'), - 'icon': 'add_circle_outline' - } - } %} -{% endif %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block employee_helper_card %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/showcase_card.html.twig' %} -
    -
    - {% endblock %} - - {% block customers_kpis %} -
    -
    -
    -
    - {{ render(controller( - 'PrestaShopBundle:Admin\\Common:renderKpiRow', - { 'kpiRow': customersKpi } - )) }} -
    -
    -
    -
    - {% endblock %} - - {% block customers_listing %} - {% if not isSingleShopContext %} -
    -
    - -
    -
    - {% endif %} - -
    -
    - {% embed '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': customerGrid} %} - {% block grid_panel_extra_content %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/delete_modal.html.twig' %} - {% endblock %} - {% endembed %} -
    -
    - {% endblock %} - - {% block customer_required_fields_form %} -
    -
    -

    - -

    -
    - -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/Index/required_fields.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/javascript.html.twig' %} -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/modal_create_success.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/modal_create_success.html.twig deleted file mode 100644 index 02669e23..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/modal_create_success.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -{% endblock %} - -{% block javascripts %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig deleted file mode 100644 index 9631c88a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Customer/view.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set layoutTitle = 'Information about customer %name%'|trans({'%name%': customerInformation.personalInformation.firstName[0:1] ~ '. ' ~ customerInformation.personalInformation.lastName}, 'Admin.Orderscustomers.Feature') %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/personal_information.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/orders.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/carts.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/bought_products.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/viewed_products.html.twig' %} -
    - -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/private_note.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/messages.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/discounts.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/sent_emails.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/last_connections.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/groups.html.twig' %} -
    -
    - -
    - {{ renderhook('displayAdminCustomers', {'id_customer': customerInformation.customerId.value}) }} - -
    - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/View/addresses.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - {% include '@PrestaShop/Admin/Sell/Customer/Blocks/javascript.html.twig' %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/customer_information.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/customer_information.html.twig deleted file mode 100644 index be509297..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/customer_information.html.twig +++ /dev/null @@ -1,84 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    -
    - {% if customerThreadView.customerInformation.customerId %} - - - person - - - {% else %} - - person - - {% endif %} - -
    -

    - {% if customerThreadView.customerInformation.firstName %} - - {{ customerThreadView.customerInformation.firstName }} - {{ customerThreadView.customerInformation.lastName }} - ({{ customerThreadView.customerInformation.email }}) - - {% else %} - {{ customerThreadView.customerInformation.email }} - {% endif %} -

    -

    - {% if customerThreadView.contactName is not empty %} - {{ 'To:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ customerThreadView.contactName }} - {% endif %} -

    -
    - -
    -
    -
    - {% if customerThreadView.customerInformation.validatedOrdersCount %} - {{ '[1]%count%[/1] order(s) validated for a total amount of [2]%total%[/2]'|trans({ - '%count%': customerThreadView.customerInformation.validatedOrdersCount, - '%total%': customerThreadView.customerInformation.validatedOrdersAmount, - '[1]': '', - '[/1]': '', - '[2]': '', - '[/2]': '' - }, 'Admin.Orderscustomers.Feature')|raw }} - {% else %} - {{ 'No order validated for the moment. By default, an order is considered validated when its payment is accepted.'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} - -

    - {{ 'Customer since: %s'|trans( - {'%s': customerThreadView.customerInformation.customerSinceDate}, - 'Admin.Orderscustomers.Feature' - ) }} -

    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/forward_thread_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/forward_thread_modal.html.twig deleted file mode 100644 index f66b60a3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/forward_thread_modal.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_actions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_actions.html.twig deleted file mode 100644 index db60cdb6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_actions.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    - {% for action in customerThreadView.actions %} -
    - -
    - {% endfor %} - - - - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/forward_thread_modal.html.twig' %} -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_messages.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_messages.html.twig deleted file mode 100644 index bf34e4a6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/thread_messages.html.twig +++ /dev/null @@ -1,83 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -
    -
      - {% for message in customerThreadView.messages %} - {% if not loop.first %} -
    • -
      -
    • - {% endif %} - -
    • - {% if message.type == 'customer' %} - person - {% else %} - - {% endif %} - -
      -

      - reply - - {% if message.type == constant('PrestaShop\\PrestaShop\\Core\\Domain\\CustomerService\\ValueObject\\CustomerThreadMessageType::CUSTOMER') %} - {{ message.customerName }} - {% else %} - {{ message.employeeName }} - {% endif %} - - - calendar_today - - - {{ format_date(message.date) }} - access_time - - - {{ message.date|date('H:i') }} - - - {% if message.attachmentFile %} - attachment - - {{ 'Attachment'|trans({}, 'Admin.Catalog.Feature') }} - - {% endif %} - - {% if message.productId %} - library_books - - {{ 'Product'|trans({}, 'Admin.Global') }} - {{ message.productName }} - - {% endif %} -

      -

      {{ message.message|nl2br }}

      -
      -
    • - {% endfor %} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/timeline.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/timeline.html.twig deleted file mode 100644 index 4f8f9f67..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/timeline.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Orders and messages timeline'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    - {% for timelineItem in customerThreadView.timeline.timelineItems %} -
    -
    -
    - - {{ timelineItem.icon }} - - - - calendar_today - {{ format_date(timelineItem.date) }} - access_time - {{ timelineItem.date|date('H:i') }} - - - - {{ timelineItem.content|raw|nl2br }} - - - {% if timelineItem.relatedOrderId %} -

    - - {{ 'See more'|trans({}, 'Admin.Actions') }} - -

    - {% endif %} -
    -
    -
    - {% endfor %} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/your_answer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/your_answer.html.twig deleted file mode 100644 index 26e81137..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/Block/your_answer.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{{ form_start(replyToCustomerThreadForm, { - 'action': path('admin_customer_threads_reply', {'customerThreadId': customerThreadView.customerThreadId.value}) -}) }} -
    -

    - {{ 'Your answer to'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {% if customerThreadView.customerInformation.firstName %} - {{ customerThreadView.customerInformation.firstName }} - {{ customerThreadView.customerInformation.lastName }} - {% else %} - {{ customerThreadView.customerInformation.email }} - {% endif %} -

    - -
    -
    - -
    - {{ form_widget(replyToCustomerThreadForm.reply_message, {'attr': {'rows': 5}}) }} -
    -
    - -
    - {{ form_widget(replyToCustomerThreadForm._token) }} -
    - - {% block reply_to_customer_form_rest %} - {{ form_rest(replyToCustomerThreadForm) }} - {% endblock %} -
    - - -
    -{{ form_end(replyToCustomerThreadForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/view.html.twig deleted file mode 100644 index c828c4ed..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/CustomerThread/view.html.twig +++ /dev/null @@ -1,74 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    -
    -

    - {{ 'Thread'|trans({}, 'Admin.Orderscustomers.Feature') }} - #{{ customerThreadView.customerThreadId.value }} -

    -
    - {% block customer_thread_actions %} - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/thread_actions.html.twig' %} - {% endblock %} - - {% block customer_information %} - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/customer_information.html.twig' %} - {% endblock %} - - {% block customer_thread_messages %} - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/thread_messages.html.twig' %} - {% endblock %} -
    -
    -
    -
    - -
    -
    - {% block customer_thread_reply %} - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/your_answer.html.twig' %} - {% endblock %} -
    -
    - -
    -
    - {% block customer_thread_timeline %} - {% include '@PrestaShop/Admin/Sell/CustomerService/CustomerThread/Block/timeline.html.twig' %} - {% endblock %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/Blocks/options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/Blocks/options.html.twig deleted file mode 100644 index 04c1e9f4..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/Blocks/options.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(merchandiseReturnsOptionsForm, {action: path('admin_merchandise_returns_save_options')}) }} -
    -

    - {{ 'Merchandise return (RMA) options'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    - {{ ps.form_group_row(merchandiseReturnsOptionsForm.options.enable_order_return, {}, { - label: 'Enable returns'|trans({}, 'Admin.Orderscustomers.Feature'), - help: 'Would you like to allow merchandise returns in your shop?'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(merchandiseReturnsOptionsForm.options.order_return_period_in_days, {}, { - label: 'Time limit of validity'|trans({}, 'Admin.Orderscustomers.Feature'), - help: 'How many days after the delivery date does the customer have to return a product?'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {{ ps.form_group_row(merchandiseReturnsOptionsForm.options.order_return_prefix, {}, { - label: 'Returns prefix'|trans({}, 'Admin.Orderscustomers.Feature'), - help: 'Prefix used for return name (e.g. RE00001).'|trans({}, 'Admin.Orderscustomers.Help') - }) }} - - {% block merchandise_return_options_form_rest %} - {{ form_rest(merchandiseReturnsOptionsForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(merchandiseReturnsOptionsForm) }} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/index.html.twig deleted file mode 100644 index 7a1ced62..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/MerchandiseReturn/index.html.twig +++ /dev/null @@ -1,54 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set enableSidebar = true %} -{% set layoutTitle = 'Merchandise Returns'|trans({}, 'Admin.Orderscustomers.Feature') %} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block merchandise_returns_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': merchandiseReturnsGrid} %} -
    -
    - {% endblock %} - - {% block merchandise_returns_options %} -
    -
    - {% include '@PrestaShop/Admin/Sell/CustomerService/MerchandiseReturn/Blocks/options.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig deleted file mode 100644 index 130a87b7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{{ form_start(orderMessageForm) }} -
    -

    - person - {{ 'Order messages'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    - {{ form_errors(orderMessageForm) }} - - {{ ps.form_group_row(orderMessageForm.name, {}, { - 'label': 'Name'|trans({}, 'Admin.Global') - }) }} - - {{ ps.form_group_row(orderMessageForm.message, {}, { - 'label': 'Message'|trans({}, 'Admin.Global') - }) }} - - {% block order_message_form_rest %} - {{ form_rest(orderMessageForm) }} - {% endblock %} -
    -
    - -
    -{{ form_end(orderMessageForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/create.html.twig deleted file mode 100644 index 03bf4d67..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/create.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/edit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/edit.html.twig deleted file mode 100644 index 03bf4d67..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/edit.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Sell/CustomerService/OrderMessage/Blocks/form.html.twig' %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/index.html.twig deleted file mode 100644 index daa3454a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/CustomerService/OrderMessage/index.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': orderMessageGrid} %} -
    -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/cart_summary.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/cart_summary.html.twig deleted file mode 100644 index d9f01570..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/cart_summary.html.twig +++ /dev/null @@ -1,215 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Cart summary'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    - - - - - - - - - - - - - {% for product in cartView.cartSummary.products %} - {% if product.customization is not empty %} - - - - - - - - - - - - - - - - - - {% endif %} - - {% if product.customization is empty or product.cart_quantity > product.customization_quantity %} - - - - - - - - - {% endif %} - {% endfor %} - - - - - - - {% if cartView.cartSummary.total_discounts %} - - - - - {% endif %} - - {% if cartView.cartSummary.total_wrapping %} - - - - - {% endif %} - - {% if cartView.cartSummary.total_shipping %} - - - - - {% endif %} - - - - - - -
     {{ 'Product'|trans({}, 'Admin.Global') }}{{ 'Unit price'|trans({}, 'Admin.Global') }}{{ 'Quantity'|trans({}, 'Admin.Global') }}{{ 'Stock'|trans({}, 'Admin.Global') }}{{ 'Total'|trans({}, 'Admin.Global') }}
    {{ product.image|raw }} - - {{ product.name }} - - {% if product.attributes %} -
    {{ product.attributes }} - {% endif %} -
    - - {% if product.reference %} - {{ 'Ref:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ product.reference }} - {% endif %} - - {% if product.reference and product.supplier_reference %} - / {{ product.supplier_reference }} - {% endif %} -
    -
    {{ product.unit_price_formatted }}{{ product.quantity }}{{ product.stock_quantity }}{{ product.total_price_formatted }}
    - {% for customizationField in product.customization.fields %} -
    -
    - {% if customizationField.name %} - {{ customizationField.name }} - {% else %} - {{ 'Text #'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -
    -
    - {% if customizationField.type == 'customizable_file' %} - - {% else %} - {{ customizationField.value }} - {% endif %} -
    -
    - {% endfor %} -
    {{ product.customization.quantity }}
    {{ product.image|raw }} - - {{ product.name }} - - {% if product.attributes %} -
    {{ product.attributes }} - {% endif %} -
    - - {% if product.reference %} - {{ 'Ref:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ product.reference }} - {% endif %} - - {% if product.reference and product.supplier_reference %} - / {{ product.supplier_reference }} - {% endif %} -
    -
    {{ product.unit_price_formatted }}{{ product.cart_quantity }}{{ product.stock_quantity }}{{ product.total_price_formatted }}
    {{ 'Total cost of products:'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ cartView.cartSummary.total_products_formatted }}
    {{ 'Total value of vouchers:'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ cartView.cartSummary.total_discounts_formatted }}
    {{ 'Total cost of gift wrapping:'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ cartView.cartSummary.total_wrapping_formatted }}
    {{ 'Total shipping costs:'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ cartView.cartSummary.total_shipping_formatted }}
    - {{ 'Total'|trans({}, 'Admin.Global') }} - - {{ cartView.cartSummary.total_formatted }} -
    - - {% if cartView.cartSummary.cart_rules is not empty %} - - - - - - - - - - {% for cartRule in cartView.cartSummary.cart_rules %} - - - - - - {% endfor %} - -
    {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Discount name'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Value'|trans({}, 'Admin.Global') }}
    {{ cartRule.id }} - - {{ cartRule.name }} - - - {% if cartRule.is_free_shipping %} - {{ 'Free shipping'|trans({}, 'Admin.Shipping.Feature') }} - {% else %} - - {{ cartRule.formatted_value }} - {% endif %} -
    - {% endif %} - - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/customer_information.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/customer_information.html.twig deleted file mode 100644 index 26ae0990..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/customer_information.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Customer information'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    - {% if cartView.customerInformation.id %} -
    -

    - - {% if cartView.customerInformation.gender %} - {{ cartView.customerInformation.gender }} - {% endif %} - {{ cartView.customerInformation.first_name }} - {{ cartView.customerInformation.last_name }} - -

    - -

    - {{ 'Account registration date:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ cartView.customerInformation.registration_date }} -

    - -

    - {{ 'Valid orders placed:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ cartView.customerInformation.valid_orders_count }} -

    - -

    - {{ 'Total spent since registration:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ cartView.customerInformation.total_spent_since_registration }} -

    -
    - - - {% else %} -
    -

    {{ 'Guest not registered'|trans({}, 'Admin.Orderscustomers.Feature') }}

    -
    - {% endif %} -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/order_information.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/order_information.html.twig deleted file mode 100644 index 0ae00f25..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/Blocks/View/order_information.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Order information'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    -
    - {% if cartView.orderInformation.id %} -

    - - {{ 'Order #%d'|trans({ - '%d': cartView.orderInformation.id|format('"%06d') - }, 'Admin.Orderscustomers.Feature') }} - -

    - -

    - {{ 'Made on:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ cartView.orderInformation.placed_date }} -

    - {% else %} -

    {{ 'No order was created from this cart.'|trans({}, 'Admin.Orderscustomers.Feature') }}

    - - {% if cartView.customerInformation.id %} - - {{ 'Create an order from this cart.'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {% endif %} - {% endif %} -
    -
    -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/view.html.twig deleted file mode 100644 index 0200bcb2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Cart/view.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - {% block cart_kpis %} -
    -
    -
    -
    - {{ render(controller( - 'PrestaShopBundle:Admin\\Common:renderKpiRow', - { 'kpiRow': cartKpi } - )) }} -
    -
    -
    -
    - {% endblock %} - -
    -
    - {% block cart_customer_information %} - {% include '@PrestaShop/Admin/Sell/Order/Cart/Blocks/View/customer_information.html.twig' %} - {% endblock %} -
    -
    - {% block cart_order_information %} - {% include '@PrestaShop/Admin/Sell/Order/Cart/Blocks/View/order_information.html.twig' %} - {% endblock %} -
    -
    - -
    -
    - {% block cart_summary %} - {% include '@PrestaShop/Admin/Sell/Order/Cart/Blocks/View/cart_summary.html.twig' %} - {% endblock %} -
    -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/credit_slip_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/credit_slip_options.html.twig deleted file mode 100644 index 7c99d04a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/credit_slip_options.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(creditSlipOptionsForm, { - 'method': 'POST', - 'action': path('admin_credit_slips_process_options')}) -}} -
    - -

    - settings {{ 'Credit slip options'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    - -
    -
    - {{ ps.form_group_row(creditSlipOptionsForm.options.slip_prefix, {}, { - 'label': 'Credit slip prefix'|trans({}, 'Admin.Orderscustomers.Feature'), - 'help': 'Prefix used for credit slips.'|trans({}, 'Admin.Orderscustomers.Help') - }) }} -
    - {% block credit_slip_options_form_rest %} - {{ form_rest(creditSlipOptionsForm) }} - {% endblock %} -
    - - - -
    -{{ form_end(creditSlipOptionsForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/pdf_by_date.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/pdf_by_date.html.twig deleted file mode 100644 index 8a869d9e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/Blocks/pdf_by_date.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{{ form_start(pdfByDateForm, { - 'method': 'GET', - 'action': path('_admin_credit_slips_pdf_by_date')}) -}} -
    -

    - date_range {{ 'By date'|trans }} -

    - -
    -
    - {% set dateHint = 'Format: 2011-12-31 (inclusive).'|trans({}, 'Admin.Orderscustomers.Help') %} - {{ ps.form_group_row(pdfByDateForm.from, {}, { - 'label': 'From'|trans({}, 'Admin.Global'), - 'help': dateHint - }) }} - - {{ ps.form_group_row(pdfByDateForm.to, {}, { - 'label': 'To'|trans({}, 'Admin.Global'), - 'help': dateHint - }) }} -
    - {% block credit_slip_pdf_by_date_form_rest %} - {{ form_rest(pdfByDateForm) }} - {% endblock %} -
    - - -
    -{{ form_end(pdfByDateForm) }} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/index.html.twig deleted file mode 100644 index 32bf685c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/CreditSlip/index.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% block credit_slips_listing %} -
    -
    - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': creditSlipGrid} %} -
    -
    - {% endblock %} - - {% block credit_slips_print_pdf %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Order/CreditSlip/Blocks/pdf_by_date.html.twig' %} -
    -
    - {% endblock %} - - {% block credit_slips_options %} -
    -
    - {% include '@PrestaShop/Admin/Sell/Order/CreditSlip/Blocks/credit_slip_options.html.twig' %} -
    -
    - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Delivery/slip.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Delivery/slip.html.twig deleted file mode 100644 index 0bd591c0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Delivery/slip.html.twig +++ /dev/null @@ -1,118 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block content %} - {{ form_start(pdfForm, {'attr' : {'class': 'form', 'autocomplete': 'off'}, 'action': path('admin_order_delivery_slip_pdf') }) }} -
    - {% block admin_form_order_delivery_slip_pdf %} -
    -
    -

    - print {{ 'Print PDF'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help('From'|trans({}, 'Admin.Global'), ('Format: 2011-12-31 (inclusive).'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(pdfForm.pdf.date_from) }} - {{ form_widget(pdfForm.pdf.date_from) }} -
    -
    -
    - {{ ps.label_with_help('To'|trans({}, 'Admin.Global'), ('Format: 2011-12-31 (inclusive).'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(pdfForm.pdf.date_to) }} - {{ form_widget(pdfForm.pdf.date_to) }} -
    -
    - {{ form_rest(pdfForm) }} -
    -
    - -
    -
    - {% endblock %} -
    - {{ form_end(pdfForm) }} - - {{ form_start(optionsForm, {'attr' : {'class': 'form'} }) }} -
    - {% block admin_form_order_delivery_slip_options %} -
    -
    -

    - settings {{ 'Delivery slip options'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Delivery prefix'|trans), ('Prefix used for delivery slips.'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(optionsForm.options.prefix) }} - {{ form_widget(optionsForm.options.prefix) }} -
    -
    -
    - {{ ps.label_with_help(('Delivery Number'|trans), ('The next delivery slip will begin with this number and then increase with each additional slip.'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(optionsForm.options.number) }} - {{ form_widget(optionsForm.options.number) }} -
    -
    -
    - {{ ps.label_with_help(('Enable product image'|trans), ('Adds an image before product name on Delivery-slip'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(optionsForm.options.enable_product_image) }} - {{ form_widget(optionsForm.options.enable_product_image) }} -
    -
    - {{ form_rest(optionsForm) }} -
    -
    - -
    -
    - {% endblock %} -
    - {{ form_end(optionsForm) }} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_date.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_date.html.twig deleted file mode 100644 index 471a4c03..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_date.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block invoices_generate_by_date %} -
    - {{ form_start(generateByDateForm, {'method': 'POST', 'action': path('admin_order_invoices_generate_by_date')}) }} -
    -

    - date_range {{ 'By date'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('From'|trans({}, 'Admin.Global')), ('Format: 2011-12-31 (inclusive).'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(generateByDateForm.date_from) }} - {{ form_widget(generateByDateForm.date_from) }} -
    -
    -
    - {{ ps.label_with_help(('To'|trans({}, 'Admin.Global')), ('Format: 2011-12-31 (inclusive).'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(generateByDateForm.date_to) }} - {{ form_widget(generateByDateForm.date_to) }} -
    -
    -
    - {{ form_rest(generateByDateForm) }} -
    - -
    - {{ form_end(generateByDateForm) }} -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_status.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_status.html.twig deleted file mode 100644 index ea1e8639..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/generate_by_status.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% form_theme generateByStatusForm _self %} - -{% block invoices_generate_by_status %} -
    - {{ form_start(generateByStatusForm, {'method': 'POST', 'action': path('admin_order_invoices_generate_by_status')}) }} -
    -

    - schedule {{ 'By order status'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help(('Order statuses'|trans), ('You can also export orders which have not been charged yet.'|trans({}, 'Admin.Orderscustomers.Help'))) }} -
    - {{ form_errors(generateByStatusForm.order_states) }} - {{ form_widget(generateByStatusForm.order_states) }} -
    -
    -
    - {{ form_rest(generateByStatusForm) }} -
    - -
    - {{ form_end(generateByStatusForm) }} -
    -{% endblock %} - -{% block _form_generate_by_status_order_states_entry_label %} - {# Do not display the label if widget is not defined in order to prevent double label rendering #} - {% if widget is defined %} - {% if parent_label_class is defined %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} - {% endif %} -
    - - {{- widget|raw -}} - - {% set badgeType = orders_count > 0 ? 'success' : 'danger' %} - {{ orders_count }} - - {{- label is not same as(false) ? label|raw -}} - - -
    - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/invoice_options.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/invoice_options.html.twig deleted file mode 100644 index fe33d45f..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/Blocks/invoice_options.html.twig +++ /dev/null @@ -1,139 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% trans_default_domain "Admin.Orderscustomers.Feature" %} -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block invoice_options %} -
    - {{ form_start(invoiceOptionsForm, {'method': 'POST', 'action': path('admin_order_invoices_process')}) }} -
    -

    - settings {{ 'Invoice options'|trans }} -

    -
    -
    -
    - {{ ps.label_with_help('Enable invoices'|trans, 'If enabled, your customers will receive an invoice for the purchase.'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.enable_invoices) }} - {{ form_widget(invoiceOptionsForm.enable_invoices) }} -
    -
    -
    - {{ ps.label_with_help('Enable tax breakdown'|trans, 'If required, show the total amount per rate of the corresponding tax.'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.enable_tax_breakdown) }} - {{ form_widget(invoiceOptionsForm.enable_tax_breakdown) }} -
    -
    -
    - {{ ps.label_with_help('Enable product image'|trans, 'Adds an image in front of the product name on the invoice'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.enable_product_images) }} - {{ form_widget(invoiceOptionsForm.enable_product_images) }} -
    -
    -
    - {{ ps.label_with_help('Invoice prefix'|trans, 'Freely definable prefix for invoice number (e.g. #IN00001).'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.invoice_prefix) }} - {{ form_widget(invoiceOptionsForm.invoice_prefix) }} -
    -
    -
    - -
    - {{ form_errors(invoiceOptionsForm.add_current_year) }} - {{ form_widget(invoiceOptionsForm.add_current_year) }} -
    -
    -
    - -
    - {{ form_errors(invoiceOptionsForm.reset_number_annually) }} - {{ form_widget(invoiceOptionsForm.reset_number_annually) }} -
    -
    -
    - -
    - {{ form_errors(invoiceOptionsForm.year_position) }} - {{ form_widget(invoiceOptionsForm.year_position) }} -
    -
    -
    - {{ ps.label_with_help('Invoice number'|trans, 'The next invoice will begin with this number, and then increase with each additional invoice. Set to 0 if you want to keep the current number (which is #%number%).'|trans({'%number%': invoiceOptionsForm.vars.next_invoice_number}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.invoice_number) }} - {{ form_widget(invoiceOptionsForm.invoice_number) }} -
    -
    -
    - {{ ps.label_with_help('Legal free text'|trans, 'Use this field to show additional information on the invoice, below the payment methods summary (like specific legal information).'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.legal_free_text) }} - {{ form_widget(invoiceOptionsForm.legal_free_text) }} -
    -
    -
    - {{ ps.label_with_help('Footer text'|trans, 'This text will appear at the bottom of the invoice, below your company details.'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.footer_text) }} - {{ form_widget(invoiceOptionsForm.footer_text) }} -
    -
    -
    - {{ ps.label_with_help('Invoice model'|trans, 'Choose an invoice model.'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.invoice_model) }} - {{ form_widget(invoiceOptionsForm.invoice_model) }} -
    -
    -
    - {{ ps.label_with_help('Use the disk as cache for PDF invoices'|trans, 'Saves memory but slows down the PDF generation.'|trans({}, 'Admin.Orderscustomers.Help')) }} -
    - {{ form_errors(invoiceOptionsForm.use_disk_cache) }} - {{ form_widget(invoiceOptionsForm.use_disk_cache) }} -
    -
    - {{ form_rest(invoiceOptionsForm) }} -
    -
    - -
    - {{ form_end(invoiceOptionsForm) }} -
    -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/invoices.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/invoices.html.twig deleted file mode 100644 index 75969554..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Invoices/invoices.html.twig +++ /dev/null @@ -1,51 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set generateByDateForm, generateByStatusForm, invoiceOptionsForm = - byDateForm.generate_by_date, byStatusForm.generate_by_status, optionsForm.invoice_options -%} - -{% block content %} -
    - {# "By Date" block #} - {% include '@PrestaShop/Admin/Sell/Order/Invoices/Blocks/generate_by_date.html.twig' %} - - {# "By order status" block #} - {% include '@PrestaShop/Admin/Sell/Order/Invoices/Blocks/generate_by_status.html.twig' %} - -
    - -
    - {# "Invoice options" block #} - {% include '@PrestaShop/Admin/Sell/Order/Invoices/Blocks/invoice_options.html.twig' %} -
    -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/addresses.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/addresses.html.twig deleted file mode 100644 index 0ed0a662..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/addresses.html.twig +++ /dev/null @@ -1,72 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Addresses'|trans({}, 'Admin.Global') }} -

    -
    -
    -
    -
    -
    - {{ 'You must add at least one address to process the order.'|trans({}, 'Admin.Orderscustomers.Notification') }} -
    -
    -
    -
    -
    -
    - {{ 'Delivery'|trans({}, 'Admin.Global') }} - - - -
    -
    - {{ 'Invoice'|trans({}, 'Admin.Global') }} - - - -
    -
    - -
    -
    diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart.html.twig deleted file mode 100644 index 4bd6c862..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart.html.twig +++ /dev/null @@ -1,261 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    {{ 'Cart'|trans({}, 'Admin.Orderscustomers.Feature') }}

    -
    -
    -
    -
    -
    -
    - {{ 'Search for a product'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    - - - {{ 'Search for an existing product by typing the first letters of its name.'|trans({}, 'Admin.Orderscustomers.Help') }} - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    - -
    -
    -
    -
    - -
    -
    - {{ 'Product'|trans({}, 'Admin.Global') }} -
    -
    - -
    -
    - -
    -
    - {{ 'Combination'|trans({}, 'Admin.Global') }} -
    -
    - -
    -
    - -
    -
    - - {{ 'Customization'|trans({}, 'Admin.Catalog.Feature') }} - -
    -
    -
    - -
    -
    - {{ 'Quantity'|trans({}, 'Admin.Global') }} -
    -
    - - - {{ 'In stock'|trans({}, 'Admin.Orderscustomers.Feature') }} - - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - -
    {{ 'Product'|trans({}, 'Admin.Global') }}{{ 'Description'|trans({}, 'Admin.Global') }}{{ 'Reference'|trans({}, 'Admin.Global') }}{{ 'Price per unit'|trans({}, 'Admin.Catalog.Feature') }}{{ 'Quantity'|trans({}, 'Admin.Global') }}{{ 'Price'|trans({}, 'Admin.Global') }}
    -
    -
    -
    -
    -
    -
    - {{ 'The prices are without taxes.'|trans({}, 'Admin.Orderscustomers.Notification') }} -
    -
    -
    -
    -
    -
    - - {{ 'Currency'|trans({}, 'Admin.Global') }} - -
    -
    - -
    -
    -
    -
    - - {{ 'Language'|trans({}, 'Admin.Global') }} - -
    -
    - -
    -
    -
    -
    -
    -
    - -{% set requiredFieldMarkTemplate %} - * -{% endset %} - - - - - - - - - - - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart_rules.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart_rules.html.twig deleted file mode 100644 index f76c157b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/cart_rules.html.twig +++ /dev/null @@ -1,89 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    -

    - {{ 'Vouchers'|trans({}, 'Admin.Orderscustomers.Feature') }} -

    -
    -
    -
    - {{ 'Search for a voucher'|trans({}, 'Admin.Orderscustomers.Feature') }} -
    -
    -
    - -
      -
      - error_outline - -
      -
      -
      - -
      - - - - - - - - - - - -
      {{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Description'|trans({}, 'Admin.Global') }}{{ 'Value'|trans({}, 'Admin.Global') }}
      -
      -
      - - - - - - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/customer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/customer.html.twig deleted file mode 100644 index 2fcedf25..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/customer.html.twig +++ /dev/null @@ -1,247 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
      -

      {{ 'Customer'|trans({}, 'Admin.Global') }}

      -
      -
      -
      - {{ 'Search for a customer'|trans({}, 'Admin.Orderscustomers.Feature') }} -
      -
      - - - {{ 'Search for an existing customer by typing the first letters of his/her name.'|trans({}, 'Admin.Orderscustomers.Help') }} - -
      - -
      - -
      -
      -
      - -
      -
      -
      - -
      -
      -
      - -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - -
      {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Total'|trans({}, 'Admin.Global') }}
      -
      -
      - - - - - - - - - - - - - -
      {{ 'ID'|trans({}, 'Admin.Global') }}{{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Products'|trans({}, 'Admin.Global') }}{{ 'Total paid'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Payment'|trans({}, 'Admin.Global') }}{{ 'Status'|trans({}, 'Admin.Global') }}
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      -

      -
      - # -
      -
      -
      -

      -

      -
      - -
      -
      -
      - - - - - - - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/shipping.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/shipping.html.twig deleted file mode 100644 index 5d4319cb..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/shipping.html.twig +++ /dev/null @@ -1,123 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
      -

      - {{ 'Shipping'|trans({}, 'Admin.Actions') }} -

      -
      - -
      -
      -
      - - {{ 'Delivery option'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
      -
      - -
      -
      -
      -
      - - {{ 'Shipping price (Tax incl.)'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
      -
      -

      -
      -
      -
      -
      - - {{ 'Free shipping'|trans({}, 'Admin.Shipping.Feature') }} - -
      -
      - - - - - - - -
      -
      -
      -
      - - {{ 'Recycled packaging'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
      -
      - - - - - - - -
      -
      -
      -
      - - {{ 'Gift'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
      -
      - - - - - - - -
      - - - -
      -
      -
      - -
      -
      - -
      -
      -
      - -
      -
      -
      - {{ 'No carrier can be applied to this order'|trans({}, 'Admin.Orderscustomers.Notification') }} -
      -
      -
      -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig deleted file mode 100644 index 97aaa78e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig +++ /dev/null @@ -1,126 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
      -

      - {{ 'Summary'|trans({}, 'Admin.Global') }} -

      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -

      - {{ 'Total products'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -

      - {{ 'Total vouchers (Tax excl.)'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -

      - {{ 'Total shipping (Tax excl.)'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -

      - {{ 'Total taxes'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -

      - {{ 'Total (Tax excl.)'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -

      - {{ 'Total (Tax incl.)'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      - -
      -
      -
      -
      -
      -
      - - {{ form_start(summaryForm, {'action': path('admin_orders_place')}) }} -
      -
      - -
      - {{ ps.form_group_row(summaryForm.order_message, {}, { - 'label': 'Order message'|trans({}, 'Admin.Orderscustomers.Feature'), - }) }} -
      - -
      -
      - - - {{ 'Go on payment page to process the payment.'|trans({}, 'Admin.Orderscustomers.Help') }} - -
      -
      - - {{ ps.form_group_row(summaryForm.payment_module, {}, { - 'label': 'Payment'|trans({}, 'Admin.Global'), - }) }} - - {{ ps.form_group_row(summaryForm.order_state, {}, { - 'label': 'Order status'|trans({}, 'Admin.Orderscustomers.Feature'), - }) }} - -
      -
      - - {{ form_row(summaryForm.cart_id, {'attr': {'class': 'js-place-order-cart-id'}}) }} -
      -
      -
      -
      - {{ form_end(summaryForm) }} - -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_order_discount_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_order_discount_modal.html.twig deleted file mode 100644 index 3dbab78b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_order_discount_modal.html.twig +++ /dev/null @@ -1,107 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_product_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_product_modal.html.twig deleted file mode 100644 index 5094f40b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/add_product_modal.html.twig +++ /dev/null @@ -1,117 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_customer_address_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_customer_address_modal.html.twig deleted file mode 100644 index 6ffd1ef3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_customer_address_modal.html.twig +++ /dev/null @@ -1,61 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_product_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_product_modal.html.twig deleted file mode 100644 index f4e4cf9d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_product_modal.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig deleted file mode 100644 index f1299bf3..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_all_messages_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_all_messages_modal.html.twig deleted file mode 100644 index ca3d7ba7..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_all_messages_modal.html.twig +++ /dev/null @@ -1,59 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_product_pack_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_product_pack_modal.html.twig deleted file mode 100644 index 1a2f86e6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/Modal/view_product_pack_modal.html.twig +++ /dev/null @@ -1,81 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig deleted file mode 100644 index 076b375a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig +++ /dev/null @@ -1,91 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - {{ form_row(addProductRowForm.product_id) }} - {{ form_row(addProductRowForm.tax_rate) }} - {{ form_label(addProductRowForm.search) }} - {{ form_widget(addProductRowForm.search) }} - -
      -
      -
      {{ 'Combinations'|trans({}, 'Admin.Global') }}
      -
      - -
      - - -
      -
      - {{ form_widget(addProductRowForm.price_tax_excluded) }} -
      - -
      - {{ form_widget(addProductRowForm.price_tax_included) }} -
      -
      - - - {{ form_row(addProductRowForm.quantity, {'type':'number'}) }} - - - - - - {% if orderForViewing.hasInvoice() %} - - {{ form_row(addProductRowForm.invoice, { - 'attr': { - 'data-modal-title': 'Create a new invoice'|trans({}, 'Admin.Orderscustomers.Feature'), - 'data-modal-apply': 'Create'|trans({}, 'Admin.Actions'), - 'data-modal-cancel': 'Cancel'|trans({}, 'Admin.Actions'), - 'data-modal-body': 'Are you sure you want to create a new invoice?'|trans({}, 'Admin.Orderscustomers.Notification'), - 'data-modal-edit-price-title': 'Edit the price'|trans({}, 'Admin.Orderscustomers.Feature'), - 'data-modal-edit-price-apply': 'Update'|trans({}, 'Admin.Actions'), - 'data-modal-edit-price-cancel': 'Cancel'|trans({}, 'Admin.Actions'), - 'data-modal-edit-price-body': 'Are you sure you want to edit this product price? It will be applied to all invoices of this order.'|trans({}, 'Admin.Orderscustomers.Notification'), - }}) - }} - - {% endif %} - -
      - {{ form_row(addProductRowForm.cancel) }} - {{ form_row(addProductRowForm.add) }} -
      - - - - -
      -

      {{ 'New invoice information'|trans({}, 'Admin.Orderscustomers.Feature') }}

      -

      {{ 'Carrier'|trans({}, 'Admin.Shipping.Feature') }} : {{ orderForViewing.carrierName }}

      - {{ form_row(addProductRowForm.free_shipping) }} -
      - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/customer.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/customer.html.twig deleted file mode 100644 index 593044d0..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/customer.html.twig +++ /dev/null @@ -1,253 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
      -
      -

      - {{ 'Customer'|trans({}, 'Admin.Global') }} -

      -
      - -
      -
      -
      - {% if orderForViewing.customer is not null %} -
      -

      - account_box - - {{ orderForViewing.customer.gender }} - {{ orderForViewing.customer.firstName }} - {{ orderForViewing.customer.lastName }} - - #{{ orderForViewing.customer.id }} -

      - {% if orderForViewing.customer.isGuest %} - Guest - {% endif %} -
      - - {% else %} -
      -

      {{ 'Deleted customer'|trans({}, 'Admin.Global') }}

      -
      - {% endif %} -
      -
      - {% if orderForViewing.customer is not null %} -
      -
      -

      - {{ 'Email:'|trans({}, 'Admin.Global') }} -

      -

      - - {{ orderForViewing.customer.email }} - -

      - - {% if orderForViewing.customer.isGuest is same as(false) %} -

      - {{ 'Account registered:'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      -

      {{ orderForViewing.customer.accountRegistrationDate|date_format_full }}

      - {% endif %} -
      -
      -

      - {{ 'Validated orders placed:'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      -

      - {{ orderForViewing.customer.validOrdersPlaced }} -

      - - {% if orderForViewing.customer.isGuest is same as(false) %} -

      - {{ 'Total spent since registration:'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      -

      - {{ orderForViewing.customer.totalSpentSinceRegistration }} -

      - {% endif %} -
      -
      - {% endif %} -
      -
      - {% if orderForViewing.virtual is same as(false) %} -
      -
      - {{ 'Shipping address'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% if orderForViewing.customer is not null %} - - more_vert - - - - {% endif %} -
      - -

      {{ orderForViewing.shippingAddress.fullName }}

      - {% if orderForViewing.shippingAddress.companyName is not empty %} -

      {{ orderForViewing.shippingAddress.companyName }}

      - {% endif %} -

      {{ orderForViewing.shippingAddress.address1 }}

      - {% if orderForViewing.shippingAddress.address2 is not empty %} -

      {{ orderForViewing.shippingAddress.address2 }}

      - {% endif %} -

      - {{ orderForViewing.shippingAddress.cityName }}, - {% if orderForViewing.shippingAddress.stateName is not empty %} - {{ orderForViewing.shippingAddress.stateName }} - {% endif %} - {{ orderForViewing.shippingAddress.postCode }} -

      -

      {{ orderForViewing.shippingAddress.countryName }}

      -

      - {{ orderForViewing.shippingAddress.phoneNumber }} - {{ orderForViewing.shippingAddress.mobilePhoneNumber }} -

      -
      - {% endif %} -
      -
      - {{ 'Invoice address'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {% if orderForViewing.customer is not null %} - - more_vert - - - - {% endif %} -
      - -

      {{ orderForViewing.invoiceAddress.fullName }}

      - {% if orderForViewing.invoiceAddress.companyName is not empty %} -

      {{ orderForViewing.invoiceAddress.companyName }}

      - {% endif %} -

      {{ orderForViewing.invoiceAddress.address1 }}

      - {% if orderForViewing.invoiceAddress.address2 is not empty %} -

      {{ orderForViewing.invoiceAddress.address2 }}

      - {% endif %} -

      - {{ orderForViewing.invoiceAddress.cityName }}, - {% if orderForViewing.invoiceAddress.stateName is not empty %} - {{ orderForViewing.invoiceAddress.stateName }} - {% endif %} - {{ orderForViewing.invoiceAddress.postCode }} -

      -

      {{ orderForViewing.invoiceAddress.countryName }}

      -

      - {{ orderForViewing.invoiceAddress.phoneNumber }} - {{ orderForViewing.invoiceAddress.mobilePhoneNumber }} -

      -
      -
      -
      - {% if orderForViewing.customer is not null %} -
      -
      - {% set isPrivateNoteOpen = not orderForViewing.customer.privateNote is empty %} - -
      -

      - {{ 'Private note'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      -
      - - -
      - {{ form_start(privateNoteForm, { - 'action': path('admin_customers_set_private_note', { - 'customerId': orderForViewing.customer.id, - 'back': path('admin_orders_view', {'orderId': orderForViewing.id}) - }) - }) }} - - {{ form_widget(privateNoteForm.note) }} -
      - {{ form_rest(privateNoteForm) }} -
      - -
      - -
      - {{ form_end(privateNoteForm) }} -
      -
      -
      - {% endif %} -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig deleted file mode 100644 index 575642ef..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details.html.twig +++ /dev/null @@ -1,128 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set statusTitle %} - {{ 'Status'|trans({}, 'Admin.Global') }} ({{ orderForViewing.history.statuses|length }}) -{% endset %} - -{% set documentsTitle %} - {{ 'Documents'|trans({}, 'Admin.Orderscustomers.Feature') }} ({{ orderForViewing.documents.documents|length }}) -{% endset %} - -{% set carriersTitle %} - {{ 'Carriers'|trans({}, 'Admin.Shipping.Feature') }} ({{ orderForViewing.shipping.carriers|length }}) -{% endset %} - -{% set merchantReturnsTitle %} - {{ 'Merchandise returns'|trans({}, 'Admin.Orderscustomers.Feature') }} ({{ orderForViewing.returns.orderReturns|length }}) -{% endset %} - -
      - - -
      -
      - {% embed '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig' %} - {% block header %} - {{ statusTitle }} - {% endblock %} - {% block body %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/history.html.twig' %} - {% endblock %} - {% endembed %} -
      -
      - {% embed '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig' %} - {% block header %} - {{ documentsTitle }} - {% endblock %} - {% block body %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/documents.html.twig' %} - {% endblock %} - {% endembed %} -
      -
      - {% embed '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig' %} - {% block header %} - {{ carriersTitle }} - {% endblock %} - {% block body %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig' %} - {% endblock %} - {% endembed %} -
      -
      - {% embed '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig' %} - {% block header %} - {{ merchantReturnsTitle }} - {% endblock %} - {% block body %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/merchandise_returns.html.twig' %} - {% endblock %} - {% endembed %} -
      -
      -
      - -{% set displayAdminOrderTabLink = renderhook('displayAdminOrderTabLink', {'id_order': orderForViewing.id}) %} -{% set displayAdminOrderTabContent = renderhook('displayAdminOrderTabContent', {'id_order': orderForViewing.id}) %} -{% if displayAdminOrderTabLink is not empty or displayAdminOrderTabContent is not empty%} -
      - - -
      - {# Rendering of hook displayAdminOrderTabContent, we expect tab contents #} - {{ displayAdminOrderTabContent|raw }} -
      -
      -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig deleted file mode 100644 index a5fe887d..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/details_card.html.twig +++ /dev/null @@ -1,34 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
      -
      - {% block header %} - {% endblock %} -
      -
      - {% block body %} - {% endblock %} -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig deleted file mode 100644 index 440026ec..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig +++ /dev/null @@ -1,49 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - - - - - - - {% for discount in discounts %} - - - - - - {% endfor %} - -
      {{ 'Name'|trans({}, 'Admin.Global') }}{{ 'Value'|trans({}, 'Admin.Global') }}{{ 'Actions'|trans({}, 'Admin.Global') }}
      {{ discount.name }} - {% if discount.amountRaw.greaterThan(number(0)) %}-{% endif %} - {{ discount.amountFormatted }} - - - delete - -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/documents.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/documents.html.twig deleted file mode 100644 index 6e3d339a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/documents.html.twig +++ /dev/null @@ -1,149 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - - - - - - - - - - {% if orderForViewing.documents.documents is not empty %} - {% for document in orderForViewing.documents.documents %} - - - - - - - - {% if document.type == 'invoice' %} - - - - {% endif %} - {% endfor %} - {% else %} - - - - {% endif %} - -
      - {{ 'Date'|trans({}, 'Admin.Global') }} - - {{ 'Document'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {{ 'Number'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {{ 'Amount'|trans({}, 'Admin.Global') }} - - {{ 'Actions'|trans({}, 'Admin.Global') }} -
      - {{ document.createdAt|date_format_lite }} - - {% if document.type == 'invoice' %} - {{ 'Invoice'|trans({}, 'Admin.Global') }} - {% elseif document.type == 'credit_slip' %} - {{ 'Credit slip'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% else %} - {{ 'Delivery slip'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} - - {% if document.type == 'invoice' %} - - {{ document.referenceNumber }} - - {% elseif document.type == 'delivery_slip' %} - - {{ document.referenceNumber }} - - {% elseif document.type == 'credit_slip' %} - - {{ document.referenceNumber }} - - {% endif %} - - {% if document.amount %} -

      - {{ document.amount }} - - {% if document.amountMismatch %} - ({{ document.amountMismatch }}) - {% endif %} -

      - {% else %} - -- - {% endif %} -
      - {% if document.type == 'invoice' %} - {% if (document.isAddPaymentAllowed and document.amount) %} - - {% endif %} - - {% endif %} -
      -
      -
      - - - -
      -
      -
      - {{ 'There is no available document'|trans({}, 'Admin.Orderscustomers.Notification') }} -
      - -{% if orderForViewing.documents.documents is empty and orderForViewing.invoiceManagementIsEnabled %} -
      - -
      -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig deleted file mode 100644 index 2debee83..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - - - {{ form_row(editProductRowForm.price_tax_excluded) }} - {{ form_row(editProductRowForm.price_tax_included) }} - - - {{ form_row(editProductRowForm.quantity, {'type':'number'}) }} - - - - - - {% if orderForViewing.hasInvoice() %} - - {{ form_row(editProductRowForm.invoice, { - 'attr': { - 'data-modal-edit-price-title': 'Edit the price'|trans({}, 'Admin.Orderscustomers.Feature'), - 'data-modal-edit-price-apply': 'Update'|trans({}, 'Admin.Actions'), - 'data-modal-edit-price-cancel': 'Cancel'|trans({}, 'Admin.Actions'), - 'data-modal-edit-price-body': 'Are you sure you want to edit this product price? It will be applied to all invoices of this order.'|trans({}, 'Admin.Orderscustomers.Notification'), - }}) - }} - - {% endif %} - -
      - {{ form_row(editProductRowForm.cancel) }} - {{ form_row(editProductRowForm.save) }} -
      - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/extra_order_button_actions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/extra_order_button_actions.html.twig deleted file mode 100644 index d6f2a4b9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/extra_order_button_actions.html.twig +++ /dev/null @@ -1,90 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{# Rendering of hook actionGetAdminOrderButtons, see ActionsBarButtonsCollection #} -{% if (backOfficeOrderButtons.isEmpty() != true) %} - - {% set buttons = backOfficeOrderButtons.toArray() %} - {% if buttons|length > 2 %} - - {% set firstButton = buttons|first %} - - - {# Display other buttons into a dropdown #} - {% set buttons = buttons|slice(1, buttons|length) %} - -
      -
      - -
      -
      - {% else %} - {# If only 2 buttons, display them like this #} - - {% for button in buttons %} - - {% endfor %} - {% endif %} - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/header.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/header.html.twig deleted file mode 100644 index 6605db38..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/header.html.twig +++ /dev/null @@ -1,53 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -

      - #{{ orderForViewing.id }} - {{ orderForViewing.reference }} -

      - -

      - {{ 'from'|trans({}, 'Admin.Global') }} - - {% if orderForViewing.customer is not null %} - {{ orderForViewing.customer.firstName }} - {{ orderForViewing.customer.lastName }} - {% else %} - {{ 'Deleted customer'|trans({}, 'Admin.Global') }} - {% endif %} -

      - - - {{ orderForViewing.prices.totalAmountFormatted }} - - -

      - {{ orderForViewing.createdAt|date_format_lite }} - - {{ 'at'|trans({}, 'Admin.Global') }} - - {{ orderForViewing.createdAt|date('H:i:s') }} - -

      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/history.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/history.html.twig deleted file mode 100644 index 6a49a9f5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/history.html.twig +++ /dev/null @@ -1,75 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - - - {% for status in orderForViewing.history.statuses %} - - - - - - - {% endfor %} - -
      - - {{ status.name }} - - - {% if status.employeeLastName is not empty %} - {{ status.employeeFirstName ~ ' ' ~ status.employeeLastName }} - {% endif %} - - {{ status.createdAt|date_format_full }} - - {% if status.withEmail %} -
      - -
      - {% endif %} -
      - -
      -
      - {{ form_start(updateOrderStatusForm, {'action': path('admin_orders_update_status', {'orderId': orderForViewing.id}), 'attr': {'class': 'card-details-form'}, }) }} -
      - {{ form_widget(updateOrderStatusForm.new_order_status_id) }} - - -
      - -
      - {{ form_rest(updateOrderStatusForm) }} -
      - {{ form_end(updateOrderStatusForm) }} -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/linked_orders.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/linked_orders.html.twig deleted file mode 100644 index d7b2ea4a..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/linked_orders.html.twig +++ /dev/null @@ -1,75 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
      -
      -

      - {{ 'Linked orders'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ orderForViewing.linkedOrders.linkedOrders|length }} -

      -
      - -
      - - - - - - - - - - - {% if orderForViewing.linkedOrders.linkedOrders is not empty %} - {% for linkedOrder in orderForViewing.linkedOrders.linkedOrders %} - - - - - - {% endfor %} - {% endif %} - -
      - {{ 'Order ID'|trans({}, 'Admin.Orderscustomers.Feature') }} - - {{ 'Status'|trans({}, 'Admin.Global') }} - - {{ 'Amount'|trans({}, 'Admin.Global') }} -
      - - {{ linkedOrder.orderId }} - - - {{ linkedOrder.statusName }} - - {{ linkedOrder.amount }} - - - remove_red_eye - {{ 'View order'|trans({}, 'Admin.Orderscustomers.Feature') }} - -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/merchandise_returns.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/merchandise_returns.html.twig deleted file mode 100644 index a0645352..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/merchandise_returns.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not orderForViewing.virtual %} - {% if orderForViewing.returns.orderReturns is not empty %} - - - - - - - - - - - {% for return in orderForViewing.returns.orderReturns %} - - - - - - - {% endfor %} - -
      {{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Type'|trans({}, 'Admin.Global') }}{{ 'Carrier'|trans({}, 'Admin.Shipping.Feature') }}{{ 'Tracking number'|trans({}, 'Admin.Shipping.Feature') }}
      {{ return.date|date_format_full }}{{ return.type }}{{ return.stateName }} - {% if return.trackingNumber and return.trackingUrl %} - {{ return.trackingNumber }} - {% elseif return.trackingNumber %} - {{ return.trackingNumber }} - {% endif %} -
      - {% else %} -

      {{ 'No merchandise returned yet'|trans({}, 'Admin.Orderscustomers.Notification') }}

      - {% endif %} - - {% if orderForViewing.shipping.carrierModuleInfo %} - {{ orderForViewing.shipping.carrierModuleInfo|raw }} - {% endif %} -{% else %} -

      {{ 'Merchandise returns are not applicable for virtual orders'|trans({}, 'Admin.Orderscustomers.Notification') }}

      -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/messages.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/messages.html.twig deleted file mode 100644 index e6a5020b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/messages.html.twig +++ /dev/null @@ -1,109 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% set messagesToShow = 4 %} - -
      -
      -
      -
      -

      - {{ 'Messages'|trans({}, 'Admin.Global') }} ({{ orderForViewing.messages.total }}) -

      -
      - {% if orderForViewing.messages.total > messagesToShow %} - - {% endif %} -
      -
      - - {% if orderForViewing.messages.messages is not empty %} -
        - {% for message in orderForViewing.messages.messages|slice(0, messagesToShow)|reverse %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/msg_list_item.html.twig' %} - {% endfor %} -
      - {% endif %} - -
      - {{ form_start(orderMessageForm, { - 'action': path('admin_orders_send_message', { orderId: orderForViewing.id }) - }) }} - - {{ ps.form_group_row(orderMessageForm.order_message, {}, { - 'label': 'Choose your order message'|trans({}, 'Admin.Orderscustomers.Feature'), - 'label_on_top': true, - 'class': 'mb-0' - }) }} - -
      -
      {{ 'Do you want to overwrite your existing message?'|trans({}, 'Admin.Orderscustomers.Notification') }}
      - {% for id, message in orderMessageForm.vars['messages'] %} -
      - {{ message }} -
      - {% endfor %} -
      - - - - {{ ps.form_group_row(orderMessageForm.is_displayed_to_customer, {'material_design': true}) }} - - {{ ps.form_group_row(orderMessageForm.message, {'attr': { 'cols':30, 'rows':3 }}, { - 'label': 'Message'|trans({}, 'Admin.Global'), - 'label_on_top': true, - 'class': 'js-text-with-length-counter' - }) }} - - {% block order_message_form_rest %} - {{ form_rest(orderMessageForm) }} - {% endblock %} - -
      - -
      - - {{ form_end(orderMessageForm) }} -
      -
      - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/msg_list_item.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/msg_list_item.html.twig deleted file mode 100644 index 4e0fa679..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/msg_list_item.html.twig +++ /dev/null @@ -1,65 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
    • -
      - {% if not message.employeeId %} -
      - account_circle -
      - -
      -

      - {{ message.message|nl2br }} -

      -

      - {{ message.customerFirstName ~ ' ' ~ message.customerLastName }} - {{ message.messageDate.format }} -

      -
      - {% endif %} - - {% if message.employeeId %} -
      -

      - {{ message.message|nl2br }} -

      -

      - {% if message.isCurrentEmployeesMessage %} - {{ 'Me'|trans({}, 'Admin.Global') }} - {% else %} - {{ message.employeeFirstName ~ ' ' ~ message.employeeLastName }} - {% endif %} - - {{ message.messageDate.format }} -

      -
      - -
      - -
      - {% endif %} -
      -
    • diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_actions.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_actions.html.twig deleted file mode 100644 index 99ee0ff6..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_actions.html.twig +++ /dev/null @@ -1,125 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - {{ form_start(updateOrderStatusActionBarForm, { - 'action': path('admin_orders_update_status', {'orderId': orderForViewing.id}), - 'attr': { - 'id': 'update_order_status_action_form' - } - }) }} - -
      - {% set backgroundColor = '#ffffff' %} - {% set isBright = true %} - {% for choice in updateOrderStatusActionBarForm.new_order_status_id.vars.choices %} - {% if choice.value == updateOrderStatusActionBarForm.new_order_status_id.vars.data %} - {% set backgroundColor = choice.attr['data-background-color'] %} - {% set isBright = choice.attr['data-is-bright'] %} - {% endif %} - {% endfor %} -
      - {{ form_widget(updateOrderStatusActionBarForm.new_order_status_id, { - 'attr': { - 'class': 'select-status-colored', - }, - 'id': 'update_order_status_action_input', - }) }} -
      - - -
      - -
      - {{ form_rest(updateOrderStatusActionBarForm) }} -
      - {{ form_end(updateOrderStatusActionBarForm) }} - - {% if orderForViewing.documents.canGenerateInvoice %} -
      - -
      - {% endif %} - -
      -
      - -
      -
      - - {% if orderForViewing.documents.canGenerateDeliverySlip %} -
      - -
      - {% endif %} - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/extra_order_button_actions.html.twig' %} - - {% if merchandiseReturnEnabled %} - {% if orderForViewing.isDelivered() %} - - {% elseif orderForViewing.hasBeenPaid() or orderForViewing.hasPayments() %} - - {% else %} - - {% endif %} - {% endif %} - - {% if orderForViewing.hasBeenPaid() or orderForViewing.hasPayments() %} - - {% endif %} - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/order_navigation.html.twig' %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_navigation.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_navigation.html.twig deleted file mode 100644 index 8cfaf704..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/order_navigation.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments.html.twig deleted file mode 100644 index bc7c6810..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments.html.twig +++ /dev/null @@ -1,155 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -
      -
      -

      - {{ 'Payment'|trans({}, 'Admin.Global') }} ({{ orderForViewing.payments.payments|length }}) -

      -
      - -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/payments_alert.html.twig' with { - 'payments': orderForViewing.payments, - 'linkedOrders': orderForViewing.linkedOrders - } %} - - - - - - - - - - - - - - {% for payment in orderForViewing.payments.payments %} - - - - - - - - - - - - {% endfor %} - - {{ form_start(addOrderPaymentForm, {'action': path('admin_orders_add_payment', {'orderId': orderForViewing.id})}) }} - - - - - - - {{ form_end(addOrderPaymentForm) }} - - -
      {{ 'Date'|trans({}, 'Admin.Global') }}{{ 'Payment method'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Transaction ID'|trans({}, 'Admin.Orderscustomers.Feature') }}{{ 'Amount'|trans({}, 'Admin.Global') }}{{ 'Invoice'|trans({}, 'Admin.Global') }}
      {{ payment.date|date_format_full }}{{ payment.paymentMethod }}{{ payment.transactionId }}{{ payment.amount }}{% if payment.invoiceNumber %}{{ payment.invoiceNumber }}{% endif %} - -
      -

      - {{ 'Card number'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% if payment.cardNumber %} - {{ payment.cardNumber }} - {% else %} - {{ 'Not defined'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -

      -

      - {{ 'Card type'|trans({}, 'Admin.Orderscustomers.Feature') }}  - {% if payment.cardBrand %} - {{ payment.cardBrand }} - {% else %} - {{ 'Not defined'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -

      -

      - {{ 'Expiration date'|trans({}, 'Admin.Catalog.Feature') }}  - {% if payment.cardExpiration %} - {{ payment.cardExpiration }} - {% else %} - {{ 'Not defined'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -

      -

      - {{ 'Cardholder name'|trans({}, 'Admin.Orderscustomers.Feature') }}  - {% if payment.cardHolder %} - {{ payment.cardHolder }} - {% else %} - {{ 'Not defined'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -

      -
      - {{ form_widget(addOrderPaymentForm.date) }} - - {{ form_widget(addOrderPaymentForm.payment_method) }} - - {{ form_widget(addOrderPaymentForm.transaction_id) }} - -
      - {{ form_widget(addOrderPaymentForm.amount) }} - {{ form_widget(addOrderPaymentForm.id_currency) }} -
      -
      -
      - {{ form_widget(addOrderPaymentForm.id_invoice) }} -
      -
      - -
      - - {% if not orderForViewing.valid and changeOrderCurrencyForm.new_currency_id.vars.choices|length %} - {{ form_start(changeOrderCurrencyForm, {'action': path('admin_orders_change_currency', {'orderId': orderForViewing.id})}) }} -
      - -
      -
      - {{ form_widget(changeOrderCurrencyForm.new_currency_id) }} - -
      - -
      - {{ form_rest(changeOrderCurrencyForm) }} -
      - - - {{ 'Do not forget to update your exchange rate before making this change.'|trans({}, 'Admin.Orderscustomers.Help') }} - -
      -
      - {{ form_end(changeOrderCurrencyForm) }} - {% endif %} -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments_alert.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments_alert.html.twig deleted file mode 100644 index 17ab4631..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/payments_alert.html.twig +++ /dev/null @@ -1,24 +0,0 @@ -{% if payments.amountToPay and payments.paidAmount %} - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_order_statistics.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_order_statistics.html.twig deleted file mode 100644 index 9635a338..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_order_statistics.html.twig +++ /dev/null @@ -1,66 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -
      -
      -
      -
      -

      - {{ 'Date'|trans({}, 'Admin.Global') }} -

      - {{ orderForViewing.createdAt|date_format_full }} -
      -
      -

      - {{ 'Total'|trans({}, 'Admin.Global') }} -

      -

      - - {{ orderForViewing.prices.totalAmountFormatted }} - -

      -
      -
      -

      - - {{ 'Message'|trans({}, 'Admin.Global') }} - -

      - - {{ orderForViewing.messages.total }} - -
      -
      -

      - - {{ 'Products'|trans({}, 'Admin.Global') }} - -

      - - {{ orderForViewing.products.products|length }} - -
      -
      -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_title.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_title.html.twig deleted file mode 100644 index b722d814..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/print_title.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - {{ 'Order'|trans({}, 'Admin.Global') }} - - #{{ orderForViewing.id }} - - {{ orderForViewing.reference }} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product.html.twig deleted file mode 100644 index fd4aa55c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product.html.twig +++ /dev/null @@ -1,181 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set rowIsDisplayed = (productIndex is defined and paginationNum is defined and productIndex > paginationNum) %} - - - {% if product.imagePath %} - {{ product.name }} - {% endif %} - - - -

      {{ product.name }}

      - {% if product.reference %} -

      - {{ 'Reference number:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ product.reference }} -

      - {% endif %} - {% if product.supplierReference is not empty %} -

      - {{ 'Supplier reference:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ product.supplierReference }} -

      - {% endif %} -
      - {% if product.type == constant('PrestaShop\\PrestaShop\\Core\\Domain\\Order\\QueryResult\\OrderProductForViewing::TYPE_PACK') and product.customizations is null %} - - {{ 'View pack content'|trans({}, 'Admin.Actions') }} - - {% endif %} - - {{ product.unitPrice }} - - {% if product.quantity > 1 %} - {{ product.quantity }} - {% else %} - {{ product.quantity }} - {% endif %} - -
      - -
      - - {{ product.location }} - - {% if product.quantityRefunded > 0 %} - {{ product.quantityRefunded }} ({{ product.amountRefunded }} {{ 'Refunded'|trans({}, 'Admin.Orderscustomers.Feature') }}) - {% endif %} - - {{ product.availableQuantity }} - {{ product.totalPrice }} - {% if orderForViewing.hasInvoice() %} - {{ product.orderInvoiceNumber }} - {% endif %} - {% if not orderForViewing.delivered %} - - - - - {% endif %} - -
      -
      -
      - {{ form_widget(cancelProductForm['selected_' ~ product.orderDetailId]) }} -
      -
      - {{ form_label(cancelProductForm['quantity_' ~ product.orderDetailId]) }} -
      - {% set quantityInputOptions = { - 'attr': { - 'data-product-price-tax-incl': product.unitPriceTaxInclRaw, - 'data-product-price-tax-excl': product.unitPriceTaxExclRaw, - 'data-amount-refundable': product.amountRefundableRaw, - 'data-quantity-refundable': product.quantityRefundable, - } - } %} - {{ form_widget(cancelProductForm['quantity_' ~ product.orderDetailId], quantityInputOptions) }} -
      / {{ product.quantityRefundable }}
      -
      -
      -
      - {{ form_label(cancelProductForm['amount_' ~ product.orderDetailId]) }} -
      - {{ form_widget(cancelProductForm['amount_' ~ product.orderDetailId]) }} -
      {{ orderCurrency.symbol }}
      - - {{ '(Max %amount_refundable% %tax_method%)'|trans({ - '%amount_refundable%': product.amountRefundable, - '%tax_method%': orderForViewing.taxMethod - }, 'Admin.Orderscustomers.Help')|raw }} - -
      -
      -
      -
      - - -{% if product.customizations is not null %} - - - {% set colspan = 8 %} - {% set colspan = (orderForViewing.hasInvoice() ? colspan + 1 : colspan) %} - {% set colspan = (not orderForViewing.delivered ? colspan + 1 : colspan) %} - - {% if product.customizations.fileCustomizations %} -
      - {% for customization in product.customizations.fileCustomizations %} -
      -

      {{ customization.name }}

      -

      - - {{ customization.name }} - -

      -
      - {% endfor %} -
      - {% endif %} - {% for customization in product.customizations.textCustomizations %} -

      {{ customization.name }} : {{ customization.value }}

      - {% endfor %} - {% if product.type == constant('PrestaShop\\PrestaShop\\Core\\Domain\\Order\\QueryResult\\OrderProductForViewing::TYPE_PACK') %} -
      - {{ 'View pack content'|trans({}, 'Admin.Actions') }} -
      - {% endif %} - - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig deleted file mode 100644 index 2ba3375e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig +++ /dev/null @@ -1,10 +0,0 @@ -{% for product in orderForViewing.products.products %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/product.html.twig' with { - 'product': product, - 'productIndex': loop.index, - 'paginationNum': paginationNum, - 'isColumnLocationDisplayed': isColumnLocationDisplayed, - 'isColumnRefundedDisplayed': isColumnRefundedDisplayed, - 'isAvailableQuantityDisplayed': isAvailableQuantityDisplayed - } %} -{% endfor %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/products.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/products.html.twig deleted file mode 100644 index 962d469c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/products.html.twig +++ /dev/null @@ -1,257 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set isColumnLocationDisplayed = false %} -{% set isColumnRefundedDisplayed = false %} -{% for product in orderForViewing.products.products|slice(0, paginationNum) %} - {% if product.location is not empty %} - {% set isColumnLocationDisplayed = true %} - {% endif %} - {% if product.quantityRefunded > 0 %} - {% set isColumnRefundedDisplayed = true %} - {% endif %} -{% endfor %} -
      -
      -

      - {{ 'Products'|trans({}, 'Admin.Global') }} ({{ orderForViewing.products.products|length }}) -

      -
      - -
      -
      -
      -
      - {% set formOptions = { - 'attr': { - 'data-order-id': orderForViewing.id, - 'data-is-delivered': orderForViewing.isDelivered, - 'data-is-tax-included': orderForViewing.isTaxIncluded, - 'data-discounts-amount': orderForViewing.prices.discountsAmountRaw, - 'data-price-specification': priceSpecification|json_encode|replace("'", "'")|raw - } - } %} - {{ form_start(cancelProductForm, formOptions) }} - - - - - - - - - - - - {% if orderForViewing.hasInvoice() %} - - {% endif %} - {% if not orderForViewing.delivered %} - - {% endif %} - - - - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/product_list.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/add_product_row.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/edit_product_row.html.twig' %} - -
      -

      {{ 'Product'|trans({}, 'Admin.Global') }}

      -
      -

      {{ 'Price per unit'|trans({}, 'Admin.Advparameters.Feature') }}

      - {{ orderForViewing.taxMethod }} -
      -

      {{ 'Quantity'|trans({}, 'Admin.Global') }}

      -
      -

      {{ 'Stock location'|trans({}, 'Admin.Orderscustomers.Feature') }}

      -
      -

      {{ 'Refunded'|trans({}, 'Admin.Orderscustomers.Feature') }}

      -
      -

      {{ 'Available'|trans({}, 'Admin.Global') }}

      -
      -

      {{ 'Total'|trans({}, 'Admin.Global') }}

      - {{ orderForViewing.taxMethod }} -
      -

      {{ 'Invoice'|trans({}, 'Admin.Global') }}

      -
      -

      {{ 'Actions'|trans({}, 'Admin.Global') }}

      -
      -

      {{ 'Partial refund'|trans({}, 'Admin.Orderscustomers.Feature') }}

      -
      - -
      -
      -
      - -
      - -
      -
      - {% set numPages = max(orderForViewing.products.products|length / paginationNum, 1)|round(0, 'ceil') %} - -
      -
      - {% if not orderForViewing.delivered %} - - {% endif %} - -
      -
      - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/discount_list.html.twig' with { - 'discounts': orderForViewing.discounts.discounts, - 'orderId': orderForViewing.id - } %} - -
      -
      -
      -
      -
      -

      {{ 'Products'|trans({}, 'Admin.Global') }}

      - {{ orderForViewing.prices.productsPriceFormatted }} -
      - -
      -

      {{ 'Discounts'|trans({}, 'Admin.Global') }}

      - -{{ orderForViewing.prices.discountsAmountFormatted }} -
      - - {% if orderForViewing.prices.wrappingPriceRaw.greaterThan(number(0)) %} -
      -

      {{ 'Wrapping'|trans({}, 'Admin.Orderscustomers.Feature') }}

      - {{ orderForViewing.prices.wrappingPriceFormatted }} -
      - {% endif %} - -
      -

      {{ 'Shipping'|trans({}, 'Admin.Catalog.Feature') }}

      -
      - {{ orderForViewing.prices.shippingPriceFormatted }} -
      -
      - {{ form_widget(cancelProductForm.shipping_amount) }} -
      -
      {{ orderCurrency.symbol }}
      -
      -
      -

      (max {{ orderForViewing.prices.shippingRefundableAmountFormatted }} tax included)

      -
      -
      -
      - - {% if not orderForViewing.taxIncluded %} -
      -

      {{ 'Taxes'|trans({}, 'Admin.Global') }}

      - {{ orderForViewing.prices.taxesAmountFormatted }} -
      - {% endif %} - -
      -

      {{ 'Total'|trans({}, 'Admin.Global') }}

      - {{ orderForViewing.prices.totalAmountFormatted }} -
      - -
      -
      -
      -
      -

      - - {{ 'For this customer group, prices are displayed as: [1]%tax_method%[/1]'|trans({ - '%tax_method%': orderForViewing.taxMethod, - '[1]': '', - '[/1]': '' - }, 'Admin.Orderscustomers.Notification')|raw }}. - - {% if not 'PS_ORDER_RETURN'|configuration %} - {{ 'Merchandise returns are disabled'|trans({}, 'Admin.Orderscustomers.Notification') }} - {% endif %} - -

      -
      -
      - {{ form_widget(cancelProductForm.restock) }} -
      -
      - {{ form_widget(cancelProductForm.credit_slip) }} -
      -
      - {{ form_widget(cancelProductForm.voucher) }} -
      -
      -
      - {{ form_widget(cancelProductForm.shipping) }} - ({{ orderForViewing.prices.shippingRefundableAmountFormatted }}) -
      -
      -
      - {{ 'This order has been partially paid by voucher. Choose the amount you want to refund:'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ form_widget(cancelProductForm.voucher_refund_type) }} -
      - {{ 'Error. You cannot refund a negative amount.'|trans({}, 'Admin.Orderscustomers.Notification') }} -
      -
      -
      -
      -
      - {{ form_widget(cancelProductForm.cancel) }} - {{ form_widget(cancelProductForm.save) }} -
      -
      - {{ form_end(cancelProductForm) }} -
      -
      diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig deleted file mode 100644 index a1eb0bfe..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/shipping.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% if not orderForViewing.virtual %} - - {% if orderForViewing.shipping.giftMessage %} -
      - -
      - {{ orderForViewing.shipping.giftMessage }} -
      -
      - {% endif %} - - - - - - - - - - - - - - - {% for carrier in orderForViewing.shipping.carriers %} - - - - - - - - - - {% endfor %} - -
      {{ 'Date'|trans({}, 'Admin.Global') }} {{ 'Carrier'|trans({}, 'Admin.Shipping.Feature') }}{{ 'Weight'|trans({}, 'Admin.Global') }}{{ 'Shipping cost'|trans({}, 'Admin.Shipping.Feature') }}{{ 'Tracking number'|trans({}, 'Admin.Shipping.Feature') }}
      {{ carrier.date|date_format_lite }} {{ carrier.name }}{{ carrier.weight }}{{ carrier.price }} - {% if carrier.trackingNumber %} - {% if carrier.trackingUrl %} - {{ carrier.trackingNumber }} - {% else %} - {{ carrier.trackingNumber }} - {% endif %} - {% endif %} - - {% if carrier.canEdit %} - - {{ 'Edit'|trans({}, 'Admin.Actions') }} - - {% endif %} -
      - - {% if orderForViewing.shipping.carrierModuleInfo %} - {{ orderForViewing.shipping.carrierModuleInfo|raw }} - {% endif %} - - {% if orderForViewing.shipping.recycledPackaging %} - {{ 'Recycled packaging'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} - - {% if orderForViewing.shipping.giftWrapping %} - {{ 'Gift wrapping'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% endif %} -{% else %} -

      - {{ 'Shipping does not apply to virtual orders'|trans({}, 'Admin.Orderscustomers.Feature') }} -

      -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/sources.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/sources.html.twig deleted file mode 100644 index 4f7c2882..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/View/sources.html.twig +++ /dev/null @@ -1,63 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - - {% if orderForViewing.sources.sources is not empty %} -
      -
      -
      -
      - public - {{ 'Sources'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ orderForViewing.sources.sources|length }} -
      - -
        - {% for source in orderForViewing.sources.sources %} -
      • - {{ source.addedAt|date_format_full }} -
        - {{ 'From'|trans({}, 'Admin.Orderscustomers.Feature') }} - {% if source.httpReferer != '' %} - {{ source.httpReferer }} - {% else %} - - - {% endif %} -
        - {{ 'To'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ source.requestUri | slice(0,100) }} -
        - {% if source.keywords != '' %} - {{ 'Keywords'|trans({}, 'Admin.Global') }} -
        - {{ source.keywords }} - {% endif %} -
        -
      • - {% endfor %} -
      -
      -
      -
      - {% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/change_orders_status_modal.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/change_orders_status_modal.html.twig deleted file mode 100644 index 6603dd46..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/Blocks/change_orders_status_modal.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% embed 'PrestaShopBundle:Admin/Helpers:bootstrap_popup.html.twig' with { - 'id': 'changeOrdersStatusModal', - 'title': 'Choose an order status'|trans({}, 'Admin.Orderscustomers.Feature'), - 'closable': true, - 'actions': [{ - 'type': 'button', - 'label': 'Update status'|trans({}, 'Admin.Orderscustomers.Feature'), - 'class': 'btn btn-primary btn-lg js-submit-modal-form-btn', - }], -} %} - {% block content %} - - {% endblock %} -{% endembed %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/create.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/create.html.twig deleted file mode 100644 index 75590098..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/create.html.twig +++ /dev/null @@ -1,71 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% set layoutTitle = 'Create order'|trans({}, 'Admin.Orderscustomers.Feature') %} - -{% block content %} -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/customer.html.twig' %} -
      -
      -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/cart.html.twig' %} -
      -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/cart_rules.html.twig' %} -
      -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/addresses.html.twig' %} -
      -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/shipping.html.twig' %} -
      -
      -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/Create/summary.html.twig' %} -
      -
      -
      -
      -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/index.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/index.html.twig deleted file mode 100644 index 0a227187..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/index.html.twig +++ /dev/null @@ -1,60 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends 'PrestaShopBundle:Admin:layout.html.twig' %} - -{% block content %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/change_orders_status_modal.html.twig' %} - - {% block orders_kpi %} -
      -
      -
      -
      - {{ render(controller( - 'PrestaShopBundle:Admin\\Common:renderKpiRow', - { 'kpiRow': orderKpi } - )) }} -
      -
      -
      -
      - {% endblock %} - - {% block order_grid_row %} -
      -
      - {% include '@PrestaShop/Admin/Common/Grid/grid_panel.html.twig' with {'grid': orderGrid} %} -
      -
      - {% endblock %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig deleted file mode 100644 index 948c8c6e..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/preview.html.twig +++ /dev/null @@ -1,193 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block order_preview %} -
      -
      -
      -
      -
      -
      -

      - local_shipping -

      -
      -
      -

      - {{ 'Carrier'|trans({}, 'Admin.Global') }}: - {% if not orderPreview.isVirtual %} - {{ orderPreview.shippingDetails.carrierName }} - {% else %} - - - {% endif %} -

      - -

      - {{ 'Tracking number'|trans({}, 'Admin.Shipping.Feature') }}: - {% if not orderPreview.isVirtual and orderPreview.shippingDetails.trackingNumber is not empty %} - {{ orderPreview.shippingDetails.trackingNumber }} - {% else %} - - - {% endif %} -

      - -

      - {{ 'Shipping details'|trans({}, 'Admin.Orderscustomers.Feature') }}: - {% if orderPreview.virtual %} - - - {% endif %} -

      - - {% if not orderPreview.virtual %} -

      {{ orderPreview.shippingDetails.firstName }} {{ orderPreview.shippingDetails.lastName }}

      - {% if orderPreview.shippingDetails.company %} -

      {{ orderPreview.shippingDetails.company }}

      - {% endif %} - {% if orderPreview.shippingDetails.vatNumber %} -

      {{ orderPreview.shippingDetails.vatNumber }}

      - {% endif %} -

      {{ orderPreview.shippingDetails.address1 }}

      -

      {{ orderPreview.shippingDetails.address2 }}

      -

      - {{ orderPreview.shippingDetails.city }}, - {% if orderPreview.shippingDetails.stateName %} - {{ orderPreview.shippingDetails.stateName }} - {% endif %} - {{ orderPreview.shippingDetails.postalCode }} -

      -

      {{ orderPreview.shippingDetails.country }}

      -

      {{ orderPreview.shippingDetails.phone }}

      - {% endif %} -
      -
      -
      -
      -
      -
      -

      - receipt -

      -
      -
      -

      - {{ 'Invoice details'|trans({}, 'Admin.Orderscustomers.Feature') }}: -

      - -

      {{ orderPreview.invoiceDetails.firstName }} {{ orderPreview.invoiceDetails.lastName }}

      - {% if orderPreview.invoiceDetails.company %} -

      {{ orderPreview.invoiceDetails.company }}

      - {% endif %} - {% if orderPreview.invoiceDetails.vatNumber %} -

      {{ orderPreview.invoiceDetails.vatNumber }}

      - {% endif %} -

      {{ orderPreview.invoiceDetails.address1 }}

      -

      {{ orderPreview.invoiceDetails.address2 }}

      -

      {{ orderPreview.invoiceDetails.country }}

      -

      - {{ orderPreview.invoiceDetails.city }}, - {% if orderPreview.invoiceDetails.stateName %} - {{ orderPreview.invoiceDetails.stateName }} - {% endif %} - {{ orderPreview.invoiceDetails.postalCode }} -

      -

      {{ orderPreview.invoiceDetails.phone }}

      -

      {{ orderPreview.invoiceDetails.email }}

      -
      -
      -
      -
      -
      -
      -
      - - - - {% if orderPreview.taxIncluded %} - {% set taxInclusion = 'Tax included'|trans({}, 'Admin.Global') %} - {% else %} - {% set taxInclusion = 'Tax excluded'|trans({}, 'Admin.Global') %} - {% endif %} - - - - - {% if orderPreview.taxIncluded == false %} - - {% endif %} - - - - - - {% for productDetail in orderPreview.productDetails %} - - - - - {% if orderPreview.taxIncluded == false %} - - {% endif %} - - - - {% endfor %} - - {% if orderPreview.productDetails|length > productsPreviewLimit %} - - - - {% endif %} - -
      - {{ 'Products'|trans({}, 'Admin.Global') }} - ({{ orderPreview.productDetails|length }}) - {{ 'Reference'|trans({}, 'Admin.Global') }}{{ 'Stock location'|trans({}, 'Admin.Orderscustomers.Feature') }} - {{ 'Tax'|trans({}, 'Admin.Global') }} - {{ 'Quantity'|trans({}, 'Admin.Global') }} - {{ 'Total'|trans({}, 'Admin.Global') }} - {{ taxInclusion }} -
      {{ productDetail.name }}{{ productDetail.reference }} - {% if productDetail.location is not empty %}{{ productDetail.location }}{% endif %} - {{ productDetail.totalTax }}{{ productDetail.quantity }}{{ productDetail.totalPrice }}
      - - more_horiz - {{ '(%count% more)'|trans({ - '%count%': orderPreview.productDetails|length - productsPreviewLimit - }, 'Admin.Global') }} - -
      -
      - - -
      -
      - {{ renderhook('displayOrderPreview', {'order_id': orderId}) }} -{% endblock %} - diff --git a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig deleted file mode 100644 index e81a1db2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Sell/Order/Order/view.html.twig +++ /dev/null @@ -1,125 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% set use_regular_h1_structure = false %} -{% set layoutTitle %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/header.html.twig' %} -{% endset %} - -{% extends '@PrestaShop/Admin/layout.html.twig' %} - - -{% block content %} -
      -
      - {% set displayAdminOrderTopHookContent = renderhook('displayAdminOrderTop', {'id_order': orderForViewing.id}) %} - - {% if displayAdminOrderTopHookContent != '' %} -
      - {{ displayAdminOrderTopHookContent|raw }} -
      - {% endif %} -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/order_actions.html.twig' %} -
      -
      - -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/print_order_statistics.html.twig' %} -
      -
      - -
      -
      -
      - -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/print_title.html.twig' %} -
      -
      - -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/customer.html.twig' %} - - {{ renderhook('displayAdminOrderSide', {'id_order': orderForViewing.id}) }} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/messages.html.twig' %} - - {{ renderhook('displayAdminOrderSideBottom', {'id_order': orderForViewing.id}) }} -
      - -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/products.html.twig' %} -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/details.html.twig' %} - - {{ renderhook('displayAdminOrderMain', {'id_order': orderForViewing.id}) }} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/payments.html.twig' %} - - {{ renderhook('displayAdminOrderMainBottom', {'id_order': orderForViewing.id}) }} -
      -
      - - {% if orderForViewing.sources.sources is not empty %} -
      -
      - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/sources.html.twig' %} -
      -
      - {% endif %} - - {% if orderForViewing.linkedOrders.linkedOrders is not empty %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/linked_orders.html.twig' %} - {% endif %} - - {{ renderhook('displayAdminOrder', {'id_order': orderForViewing.id}) }} - - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/add_order_discount_modal.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_shipping_modal.html.twig' %} - {% if orderForViewing.customer is not null %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/update_customer_address_modal.html.twig' %} - {% endif %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/view_all_messages_modal.html.twig' %} - {% include '@PrestaShop/Admin/Sell/Order/Order/Blocks/View/Modal/view_product_pack_modal.html.twig' %} -
      -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - -{% endblock %} - -{% set js_translatable = { - "The product was successfully added.": 'The product was successfully added.'|trans({}, 'Admin.Notifications.Success'), - "The product was successfully removed.": 'The product was successfully removed.'|trans({}, 'Admin.Notifications.Success'), - "[1] products were successfully added.": '[1] products were successfully added.'|trans({}, 'Admin.Notifications.Success'), - "[1] products were successfully removed.": '[1] products were successfully removed.'|trans({}, 'Admin.Notifications.Success'), -}|merge(js_translatable) -%} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Stock/overview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Stock/overview.html.twig deleted file mode 100644 index 6add9736..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Stock/overview.html.twig +++ /dev/null @@ -1,73 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} - - {% if is_shop_context %} -
      - - {% else %} -
      - -
      - {% endif %} - -{% endblock %} - -{% block javascripts %} - - {% if is_shop_context %} - {{ parent() }} - - {% set productId = app.request.query.get('productId') ? app.request.query.get('productId') : false %} - - - {% if webpack_server %} - - {% else %} - - {% endif %} - {% endif %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/Translations/overview.html.twig b/src/PrestaShopBundle/Resources/views/Admin/Translations/overview.html.twig deleted file mode 100644 index 203ad028..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/Translations/overview.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@PrestaShop/Admin/layout.html.twig' %} - -{% block content %} -
      -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - - {% if webpack_server %} - - {% else %} - - {% endif %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_horizontal_layout.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_horizontal_layout.html.twig deleted file mode 100644 index aed51b65..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_horizontal_layout.html.twig +++ /dev/null @@ -1,151 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% use '@PrestaShop/Admin/TwigTemplateForm/bootstrap_4_layout.html.twig' %} -{% block form_start -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-horizontal')|trim}) %} - {{- parent() -}} -{%- endblock form_start %} - -{# Labels #} - -{% block form_label -%} - {% spaceless %} - {% if label is same as(false) %} -
      - {% else %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ block('form_label_class'))|trim}) %} - {{- parent() -}} - {% endif %} - {% endspaceless %} -{%- endblock form_label %} - -{% block form_label_class -%} - form-control-label -{%- endblock form_label_class %} - -{# Rows #} - -{% block form_row -%} - {% spaceless %} -
      - {{ form_label(form) }} -
      - {{ form_widget(form) }} - {{ form_errors(form) }} -
      -
      - {% endspaceless %} -{%- endblock form_row %} - -{% block checkbox_row -%} - {{- block('checkbox_radio_row') -}} -{%- endblock checkbox_row %} - -{% block radio_row -%} - {{- block('checkbox_radio_row') -}} -{%- endblock radio_row %} - -{% block checkbox_radio_row -%} - {% spaceless %} -
      -
      -
      - {{ form_widget(form) }} - {{ form_errors(form) }} -
      -
      - {% endspaceless %} -{%- endblock checkbox_radio_row %} - -{% block submit_row -%} - {% spaceless %} -
      -
      -
      - {{ form_widget(form) }} -
      -
      - {% endspaceless %} -{% endblock submit_row %} - -{% block form_group_class -%} - col-sm -{%- endblock form_group_class %} - -{% block form_row_class -%} - form-group row -{%- endblock form_row_class %} - -{% block text_with_unit_widget %} -
      - {{- block('form_widget_simple') -}} - {% if form.vars.unit is defined %} -
      - {{ form.vars.unit }} -
      - {% endif %} -
      -{% endblock text_with_unit_widget %} - -{% block ip_address_text_widget %} -
      - {{- block('form_widget_simple') -}} - -
      -{% endblock ip_address_text_widget %} - -{% block switch_widget %} -
      - {{- parent() -}} -
      -{% endblock switch_widget %} - -{% block text_with_length_counter_widget %} -
      - {% set current_length = form.vars.max_length - form.vars.value|length %} - - {% if form.vars.position == 'before' %} -
      - {{ current_length }} -
      - {% endif %} - - {% set attr = attr|merge({'data-max-length': form.vars.max_length, 'maxlength': form.vars.max_length, 'class': 'js-countable-input'}) -%} - - {% if form.vars.input == 'textarea' %} - {{- block('textarea_widget') -}} - {% else %} - {{- block('form_widget_simple') -}} - {% endif %} - - {% if form.vars.position == 'after' %} -
      - {{ current_length }} -
      - {% endif %} -
      -{% endblock text_with_length_counter_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_layout.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_layout.html.twig deleted file mode 100644 index 5db9e33c..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/bootstrap_4_layout.html.twig +++ /dev/null @@ -1,827 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% use '@PrestaShop/Admin/TwigTemplateForm/form_div_layout.html.twig' %} -{% use '@PrestaShop/Admin/TwigTemplateForm/typeahead.html.twig' %} -{% use '@PrestaShop/Admin/TwigTemplateForm/material.html.twig' %} - -{# Widgets #} - -{% block form_widget_simple -%} - {% if type is not defined or 'file' != type %} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%} - {% endif %} - {{- parent() -}} -{%- endblock form_widget_simple %} - -{% block textarea_widget -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %} - {{- parent() -}} - - {{ block('form_help') }} -{%- endblock textarea_widget %} - -{% block button_widget -%} - {% set attr = attr|merge({class: (attr.class|default('btn-default') ~ ' btn')|trim}) %} - {{- parent() -}} -{%- endblock %} - -{% block money_widget -%} -
      - {% set prepend = '{{' == money_pattern[0:2] %} - {% if not prepend %} -
      - {{ money_pattern|replace({ '{{ widget }}':''}) }} -
      - {% endif %} - {{- block('form_widget_simple') -}} - {% if prepend %} -
      - {{ money_pattern|replace({ '{{ widget }}':''}) }} -
      - {% endif %} -
      -{%- endblock money_widget %} - -{% block percent_widget -%} -
      - {{- block('form_widget_simple') -}} -
      - % -
      -
      -{%- endblock percent_widget %} - -{% block datetime_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} -
      - {{- form_errors(form.date) -}} - {{- form_errors(form.time) -}} - {{- form_widget(form.date, { datetime: true } ) -}} - {{- form_widget(form.time, { datetime: true } ) -}} -
      - {%- endif %} -{%- endblock datetime_widget %} - -{% block date_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or not datetime -%} -
      - {%- endif %} - {{- date_pattern|replace({ - '{{ year }}': form_widget(form.year), - '{{ month }}': form_widget(form.month), - '{{ day }}': form_widget(form.day), - })|raw -}} - {% if datetime is not defined or not datetime -%} -
      - {%- endif -%} - {% endif %} -{%- endblock date_widget %} - -{% block time_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or false == datetime -%} -
      - {%- endif -%} - {{- form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %} - {% if datetime is not defined or false == datetime -%} -
      - {%- endif -%} - {% endif %} -{%- endblock time_widget %} - -{% block choice_widget_collapsed -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-select')|trim}) %} - {{- parent() -}} -{%- endblock %} - -{% block choice_widget_expanded -%} - {% if '-inline' in label_attr.class|default('') -%} -
      - {%- for child in form %} - {{- form_widget(child, { - parent_label_class: label_attr.class|default(''), - translation_domain: choice_translation_domain, - }) -}} - {% endfor -%} -
      - {%- else -%} -
      - {%- for child in form %} - {{- form_widget(child, { - parent_label_class: label_attr.class|default(''), - translation_domain: choice_translation_domain, - }) -}} - {% endfor -%} -
      - {%- endif %} -{%- endblock choice_widget_expanded %} - -{% block checkbox_widget -%} - {% set parent_label_class = parent_label_class|default('') -%} - {% if 'checkbox-inline' in parent_label_class %} - {{- form_label(form, null, { widget: parent() }) -}} - {% else -%} -
      - {{- form_label(form, null, { widget: parent() }) -}} -
      - {%- endif %} -{%- endblock checkbox_widget %} - -{% block radio_widget -%} - {%- set parent_label_class = parent_label_class|default('') -%} - {% if 'radio-inline' in parent_label_class %} - {{- form_label(form, null, { widget: parent() }) -}} - {% else -%} -
      - {{- form_label(form, null, { widget: parent() }) -}} -
      - {%- endif %} -{%- endblock radio_widget %} - -{% block choice_tree_widget -%} -
      -
        -
      • {{ "Main category"|trans({}, 'Admin.Catalog.Feature') }}
      • - {%- for child in choices %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
      -
      -{%- endblock choice_tree_widget %} - -{% block choice_tree_item_widget -%} -
    • - {% set checked = (form.vars.submitted_values is defined and submitted_values[child.id_category] is defined) ? 'checked="checked"' : '' %} - {% if multiple -%} -
      - -
      - {%- else -%} -
      - -
      - {%- endif %} - {% if child.children is defined %} -
        - {% for item in child.children %} - {% set child = item %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
      - {% endif %} -
    • -{%- endblock choice_tree_item_widget %} - -{% block translatefields_widget %} - {{ form_errors(form) }} -
      - {% if hideTabs == false and form|length > 1 %} - - {% endif %} - -
      - {% for translationsFields in form %} -
      - {{ form_errors(translationsFields) }} - {{ form_widget(translationsFields) }} -
      - {% endfor %} -
      -
      -{% endblock %} - -{% block translate_fields_widget -%} - {% if type is not defined or 'file' != type %} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%} - {% endif %} - {{- parent() -}} -{%- endblock translate_fields_widget %} - -{% block translate_text_widget -%} - {{ form_errors(form) }} -
      - {% for translateField in form %} - {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} - - {% if default_locale.id_lang != translateField.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} - - {% set attr = translateField.vars.attr %} - - {{ form_widget(translateField, {attr: {'class': classes|trim}}) }} - {% endfor %} - - {% if not hide_locales %} - - {% endif %} -
      -{%- endblock translate_text_widget %} - -{% block translate_textarea_widget -%} - {{ form_errors(form) }} -
      - {% for textarea in form %} - {% set classes = textarea.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ textarea.vars.label %} - - {% if default_locale.id_lang != textarea.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} - -
      - {{ form_widget(textarea, {attr: {'class': classes|trim}}) }} -
      - {% endfor %} - - {% if show_locale_select %} - - {% endif %} -
      -{%- endblock translate_textarea_widget %} - -{% block date_picker_widget %} - {% spaceless %} - {% set attr = attr|merge({'class': ((attr.class|default('') ~ ' datepicker')|trim)}) %} -
      - -
      -
      - date_range -
      -
      -
      - {% endspaceless %} -{% endblock date_picker_widget %} - -{% block date_range_widget %} - {% spaceless %} - {{ form_widget(form.from) }} - {{ form_widget(form.to) }} - {% endspaceless %} -{% endblock date_range_widget %} - -{% block search_and_reset_widget %} - {% spaceless %} - - {% if show_reset_button %} -
      -
      - -
      - {% endif %} - {% endspaceless %} -{% endblock search_and_reset_widget %} - -{% block switch_widget %} - {% spaceless %} - - {% for choice in choices %} - {% set inputId = id ~'_' ~ choice.value %} - - - {% endfor %} - - - {% endspaceless %} -{% endblock switch_widget %} - -{% block _form_step6_attachments_widget %} -
      - {{ 'There is no attachment yet.'|trans({}, 'Admin.Catalog.Notification') }} -
      -
      -
      -
      - - - - - - - - - - {%- for child in form %} - - - - - - {% endfor -%} - -
      {{ 'Title'|trans({}, 'Admin.Global') }}{{ 'File name'|trans({}, 'Admin.Global') }}{{ 'Type'|trans({}, 'Admin.Catalog.Feature') }}
      {{ form_widget(child) }}{{ form.vars.attr.data[loop.index0]['file_name'] }}{{ form.vars.attr.data[loop.index0]['mime'] }}
      -
      -
      -
      -{% endblock %} - -{# Labels #} - -{% block form_label -%} - {{- parent() -}} -{%- endblock form_label %} - -{% block choice_label -%} - {# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #} - {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%} - {{- block('form_label') -}} -{% endblock %} - -{% block checkbox_label -%} - {{- block('checkbox_radio_label') -}} -{%- endblock checkbox_label %} - -{% block radio_label -%} - {{- block('checkbox_radio_label') -}} -{%- endblock radio_label %} - -{% block checkbox_radio_label %} - {# Do not display the label if widget is not defined in order to prevent double label rendering #} - {% if widget is defined %} - {% if required %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %} - {% endif %} - {% if parent_label_class is defined %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} - {% endif %} - {% if label is not same as(false) and label is empty %} - {% set label = name|humanize %} - {% endif %} - - {% if material_design is defined or attr.material_design is defined %} -
      - - {{- widget|raw -}} - - {{- label is not same as(false) ? (translation_domain is same as(false) ? label|raw : label|raw) -}} - -
      - {% else %} - - {{- widget|raw -}} - {{- label is not same as(false) ? (translation_domain is same as(false) ? label|raw : label|raw) -}} - - {% endif %} - {% endif %} -{% endblock checkbox_radio_label %} - -{# Rows #} - -{% block form_row -%} -
      - {{- form_label(form) -}} - {{- form_widget(form) -}} - {{- form_errors(form) -}} -
      -{%- endblock form_row %} - -{% block button_row -%} -
      - {{- form_widget(form) -}} -
      -{%- endblock button_row %} - -{% block choice_row -%} - {% set force_error = true %} - {{- block('form_row') }} -{%- endblock choice_row %} - -{% block date_row -%} - {% set force_error = true %} - {{- block('form_row') }} -{%- endblock date_row %} - -{% block time_row -%} - {% set force_error = true %} - {{- block('form_row') }} -{%- endblock time_row %} - -{% block datetime_row -%} - {% set force_error = true %} - {{- block('form_row') }} -{%- endblock datetime_row %} - -{% block checkbox_row -%} -
      - {{- form_widget(form) -}} - {{- form_errors(form) -}} -
      -{%- endblock checkbox_row %} - -{% block radio_row -%} -
      - {{- form_widget(form) -}} - {{- form_errors(form) -}} -
      -{%- endblock radio_row %} - -{# Errors #} - -{% block form_errors -%} - {% if errors|length > 0 -%} -
      - {%- if errors|length > 1 -%} -
        - {%- for error in errors -%} -
      • {{ - error.messagePluralization is null - ? error.messageTemplate|trans(error.messageParameters, 'form_error') - : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'form_error') - }} -
      • - {%- endfor -%} -
      - {%- else -%} -
      - {%- for error in errors -%} -

      {{ - error.messagePluralization is null - ? error.messageTemplate|trans(error.messageParameters, 'form_error') - : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'form_error') - }} -

      - {%- endfor -%} -
      - {%- endif -%} -
      - {%- endif %} -{%- endblock form_errors %} - - -{# Material design widgets #} - -{% block material_choice_table_widget %} - {% spaceless %} -
      - - - - - - - - {% for child in form %} - - - - {% endfor %} - -
      -
      - -
      -
      - {{ form_widget(child, {'material_design': true}) }} -
      -
      - {% endspaceless %} -{% endblock material_choice_table_widget %} - -{% block material_multiple_choice_table_widget %} - {% spaceless %} -
      - - - - - {% for child_choice in form %} - - {% endfor %} - - - - {% for choice_name, choice_value in choices %} - - - {% for child_choice_name, child_choice in form %} - - {% endfor %} - - {% endfor %} - -
      {{ label }} - {% if child_choice.vars.multiple and child_choice.vars.name not in headers_to_disable %} - - {{ child_choice.vars.label }} - - {% else %} - {{ child_choice.vars.label }} - {% endif %} -
      - {{ choice_name }} - - {% if child_choice_entry_index_mapping[choice_value][child_choice_name] is defined %} - {% set entry_index = child_choice_entry_index_mapping[choice_value][child_choice_name] %} - - {% if child_choice.vars.multiple %} - {{ form_widget(child_choice[entry_index], {'material_design': true}) }} - {% else %} - {{ form_widget(child_choice[entry_index]) }} - {% endif %} - {% else %} - -- - {% endif %} -
      -
      - {% endspaceless %} -{% endblock material_multiple_choice_table_widget %} - -{% block translatable_widget -%} -
      - {% for translateField in form %} - {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} - {% if default_locale.id_lang != translateField.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} -
      - {{ form_widget(translateField) }} -
      - {% endfor %} - {% if not hide_locales %} - - {% endif %} -
      -{%- endblock translatable_widget %} - -{% block birthday_widget %} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or not datetime -%} -
      - {%- endif %} - - {% set yearWidget = '
      ' ~ form_widget(form.year) ~ '
      '|raw %} - {% set monthWidget = '
      ' ~ form_widget(form.month) ~ '
      '|raw %} - {% set dayWidget = '
      ' ~ form_widget(form.day) ~ '
      '|raw %} - - {{- date_pattern|replace({ - '{{ year }}': yearWidget, - '{{ month }}': monthWidget, - '{{ day }}': dayWidget, - })|raw -}} - - {% if datetime is not defined or not datetime -%} -
      - {%- endif -%} - {% endif %} -{% endblock birthday_widget %} - -{% block file_widget %} - -
      - {% set attr = attr|merge({ - class: (attr.class|default('') ~ ' custom-file-input')|trim, - 'data-multiple-files-text': '%count% file(s)'|trans({}, 'Admin.Global'), - 'data-locale': get_context_iso_code() - }) -%} - - {% if attr.disabled is defined and attr.disabled %} - {% set attr = attr|merge({ - class: attr.class ~ ' disabled' - }) %} - {% endif %} - - {{ form_widget(form, {'attr': attr}) }} - - -
      -{% endblock file_widget %} - -{% block shop_restriction_checkbox_widget %} - {% if form.vars.attr.is_allowed_to_display %} -
      - -
      - {% endif %} -{% endblock %} - -{% block generatable_text_widget %} -
      - {{- block('form_widget') -}} - - - -
      -{% endblock generatable_text_widget %} - -{% block text_with_recommended_length_widget %} - {% set attr = attr|merge({ - 'data-recommended-length-counter': '#' ~ id ~ '_recommended_length_counter', - 'class': 'js-recommended-length-input' - }) -%} - - {% if input_type == 'textarea' %} - {{- block('textarea_widget') -}} - {% else %} - {{- block('form_widget_simple') -}} - {% endif %} - - - - {{ '[1][/1] of [2][/2] characters used (recommended)'|trans({}, 'Admin.Catalog.Feature')|replace({ - '[1]': '' ~ value|length, - '[/1]': '', - '[2]': '' ~ recommended_length, - '[/2]': '', - })|raw }} - - -{% endblock text_with_recommended_length_widget %} - -{% block integer_min_max_filter_widget %} - {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} - {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} -{% endblock %} - -{% block number_min_max_filter_widget %} - {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} - {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} -{% endblock %} - -{% block form_help %} - {% if help %} - {{ help }} - {% endif %} -{% endblock form_help %} - -{% block custom_content_widget %} - {% include template with data %} -{% endblock %} - -{% block text_widget %} - {% if data_list is not null %} - {%- set attr = attr|merge({'list': id ~ '_datalist'}) -%} - {% endif %} - - {{ form_widget(form, {'attr': attr}) }} - - {% if data_list is not null %} - - {% for item in data_list %} - - {% endfor%} - - {% endif %} -{% endblock text_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_div_layout.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_div_layout.html.twig deleted file mode 100644 index 2e38c430..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_div_layout.html.twig +++ /dev/null @@ -1,420 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{# Widgets #} - -{%- block form_widget -%} - {% if compound %} - {{- block('form_widget_compound') -}} - {% else %} - {{- block('form_widget_simple') -}} - {% endif %} - - {{- block('form_help') -}} -{%- endblock form_widget -%} - -{%- block form_widget_simple -%} - {%- set type = type|default('text') -%} - - {% include "@Twig/form_max_length.html.twig" with {"attr": attr} %} -{%- endblock form_widget_simple -%} - -{%- block form_widget_compound -%} -
      - {%- if form.parent is empty -%} - {{ form_errors(form) }} - {%- endif -%} - {{- block('form_rows') -}} - {{- form_rest(form) -}} -
      -{%- endblock form_widget_compound -%} - -{%- block collection_widget -%} - {% if prototype is defined %} - {%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%} - {% endif %} - {{- block('form_widget') -}} -{%- endblock collection_widget -%} - -{%- block textarea_widget -%} - - {% include "@Twig/form_max_length.html.twig" with {"attr": attr} %} -{%- endblock textarea_widget -%} - -{%- block choice_widget -%} - {% if expanded %} - {{- block('choice_widget_expanded') -}} - {% else %} - {{- block('choice_widget_collapsed') -}} - {% endif %} -{%- endblock choice_widget -%} - -{%- block choice_widget_expanded -%} -
      - {%- for child in form %} - {{- form_widget(child) -}} - {{- form_label(child, null, {translation_domain: choice_translation_domain}) -}} - {% endfor -%} -
      -{%- endblock choice_widget_expanded -%} - -{%- block choice_widget_collapsed -%} - {%- if required and placeholder is none and not placeholder_in_choices and not multiple -%} - {% set required = false %} - {%- endif -%} - -{%- endblock choice_widget_collapsed -%} - -{%- block choice_widget_options -%} - {% for group_label, choice in options %} - {%- if choice is iterable -%} - - {% set options = choice %} - {{- block('choice_widget_options') -}} - - {%- else -%} - - {%- endif -%} - {% endfor %} -{%- endblock choice_widget_options -%} - -{%- block checkbox_widget -%} - {% set switch = switch|default('') -%} - -{% endblock checkbox_widget -%} - -{%- block radio_widget -%} - -{% endblock radio_widget -%} - -{%- block datetime_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {%- else -%} -
      - {{- form_errors(form.date) -}} - {{- form_errors(form.time) -}} - {{- form_widget(form.date) -}} - {{- form_widget(form.time) -}} -
      - {%- endif -%} -{%- endblock datetime_widget -%} - -{%- block date_widget -%} - {%- if widget == 'single_text' -%} - {{ block('form_widget_simple') }} - {%- else -%} -
      - {{- date_pattern|replace({ - '{{ year }}': form_widget(form.year), - '{{ month }}': form_widget(form.month), - '{{ day }}': form_widget(form.day), - })|raw -}} -
      - {%- endif -%} -{%- endblock date_widget -%} - -{%- block time_widget -%} - {%- if widget == 'single_text' -%} - {{ block('form_widget_simple') }} - {%- else -%} - {%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%} -
      - {{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %} -
      - {%- endif -%} -{%- endblock time_widget -%} - -{%- block number_widget -%} - {# type="number" doesn't work with floats #} - {%- set type = type|default('text') -%} - {{ block('form_widget_simple') }} -{%- endblock number_widget -%} - -{%- block integer_widget -%} - {%- set type = type|default('number') -%} - {{ block('form_widget_simple') }} -{%- endblock integer_widget -%} - -{%- block money_widget -%} - {{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }} -{%- endblock money_widget -%} - -{%- block url_widget -%} - {%- set type = type|default('url') -%} - {{ block('form_widget_simple') }} -{%- endblock url_widget -%} - -{%- block search_widget -%} - {%- set type = type|default('search') -%} - {{ block('form_widget_simple') }} -{%- endblock search_widget -%} - -{%- block percent_widget -%} - {%- set type = type|default('text') -%} - {{ block('form_widget_simple') }} % -{%- endblock percent_widget -%} - -{%- block password_widget -%} - {%- set type = type|default('password') -%} - {{ block('form_widget_simple') }} -{%- endblock password_widget -%} - -{%- block hidden_widget -%} - {%- set type = type|default('hidden') -%} - {{ block('form_widget_simple') }} -{%- endblock hidden_widget -%} - -{%- block email_widget -%} - {%- set type = type|default('email') -%} - {{ block('form_widget_simple') }} -{%- endblock email_widget -%} - -{%- block button_widget -%} - {%- if label is empty -%} - {%- if label_format is not empty -%} - {% set label = label_format|replace({ - '%name%': name, - '%id%': id, - }) %} - {%- else -%} - {% set label = name|humanize %} - {%- endif -%} - {%- endif -%} - -{%- endblock button_widget -%} - -{%- block submit_widget -%} - {%- set type = type|default('submit') -%} - {{ block('button_widget') }} -{%- endblock submit_widget -%} - -{%- block reset_widget -%} - {%- set type = type|default('reset') -%} - {{ block('button_widget') }} -{%- endblock reset_widget -%} - -{# Labels #} - -{%- block form_label -%} - {% if label is not same as(false) -%} - {% if not compound -%} - {% set label_attr = label_attr|merge({'for': id}) %} - {%- endif %} - {% if required -%} - {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} - {%- endif %} - {% if label is empty -%} - {%- if label_format is not empty -%} - {% set label = label_format|replace({ - '%name%': name, - '%id%': id, - }) %} - {%- else -%} - {% set label = name|humanize %} - {%- endif -%} - {%- endif -%} - {{ translation_domain is same as(false) ? label|raw : label|raw }} - {% if label_attr['tooltip'] is defined %} - {% set placement = label_attr['tooltip_placement'] is defined ? label_attr['tooltip_placement'] : 'top' %} - - {% endif %} - - {% if label_attr['popover'] is defined %} - {% set placement = label_attr['popover_placement'] is defined ? label_attr['popover_placement'] : 'top' %} - - {% endif %} - - - {%- endif -%} -{%- endblock form_label -%} - -{%- block button_label -%}{%- endblock -%} - -{# Rows #} - -{%- block repeated_row -%} - {# - No need to render the errors here, as all errors are mapped - to the first child (see RepeatedTypeValidatorExtension). - #} - {{- block('form_rows') -}} -{%- endblock repeated_row -%} - -{%- block form_row -%} -
      - {{- form_label(form) -}} - {{- form_errors(form) -}} - {{- form_widget(form) -}} -
      -{%- endblock form_row -%} - -{%- block button_row -%} -
      - {{- form_widget(form) -}} -
      -{%- endblock button_row -%} - -{%- block hidden_row -%} - {{ form_widget(form) }} -{%- endblock hidden_row -%} - -{# Misc #} - -{%- block form -%} - {{ form_start(form) }} - {{- form_widget(form) -}} - {{ form_end(form) }} -{%- endblock form -%} - -{%- block form_start -%} - {% set method = method|upper %} - {%- if method in ["GET", "POST"] -%} - {% set form_method = method %} - {%- else -%} - {% set form_method = "POST" %} - {%- endif -%} -
      - {%- if form_method != method -%} - - {%- endif -%} -{%- endblock form_start -%} - -{%- block form_end -%} - {%- if not render_rest is defined or render_rest -%} - {{ form_rest(form) }} - {%- endif -%} -
      -{%- endblock form_end -%} - -{%- block form_enctype -%} - {% if multipart %}enctype="multipart/form-data"{% endif %} -{%- endblock form_enctype -%} - -{%- block form_errors -%} - {%- if errors|length > 0 -%} -
        - {%- for error in errors -%} -
      • {{ error.message }}
      • - {%- endfor -%} -
      - {%- endif -%} -{%- endblock form_errors -%} - -{%- block form_rest -%} - {% import '@PrestaShop/Admin/macros.html.twig' as ps %} - - {% for child in form -%} - {% if not child.rendered %} - {{- ps.form_group_row(child, { attr: child.vars.attr }, { - 'label': child.vars.label - }) -}} - {% endif %} - {%- endfor %} -{% endblock form_rest %} - -{# Support #} - -{%- block form_rows -%} - {% for child in form %} - {{- form_row(child) -}} - {% endfor %} -{%- endblock form_rows -%} - -{%- block widget_attributes -%} - id="{{ id }}" name="{{ full_name }}" - {%- if read_only|default(false) and attr.readonly is not defined %} readonly="readonly"{% endif -%} - {%- if disabled %} disabled="disabled"{% endif -%} - {%- if required %} required="required"{% endif -%} - {%- for attrname, attrvalue in attr -%} - {{- " " -}} - {%- if attrname in ['placeholder', 'title'] -%} - {{- attrname }}="{{ attrvalue }}" - {%- elseif attrvalue is same as(true) -%} - {{- attrname }}="{{ attrname }}" - {%- elseif attrvalue is not same as(false) -%} - {{- attrname }}="{{ attrvalue }}" - {%- endif -%} - {%- endfor -%} -{%- endblock widget_attributes -%} - -{%- block widget_container_attributes -%} - {%- if id is not empty %}id="{{ id }}"{% endif -%} - {%- for attrname, attrvalue in attr -%} - {{- " " -}} - {%- if attrname in ['placeholder', 'title'] -%} - {{- attrname }}="{{ attrvalue }}" - {%- elseif attrvalue is same as(true) -%} - {{- attrname }}="{{ attrname }}" - {%- elseif attrvalue is not same as(false) -%} - {{- attrname }}="{{ attrvalue }}" - {%- endif -%} - {%- endfor -%} -{%- endblock widget_container_attributes -%} - -{%- block button_attributes -%} - id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif -%} - {%- for attrname, attrvalue in attr -%} - {{- " " -}} - {%- if attrname in ['placeholder', 'title'] -%} - {{- attrname }}="{{ attrvalue }}" - {%- elseif attrvalue is same as(true) -%} - {{- attrname }}="{{ attrname }}" - {%- elseif attrvalue is not same as(false) -%} - {{- attrname }}="{{ attrvalue }}" - {%- endif -%} - {%- endfor -%} -{%- endblock button_attributes -%} - -{% block attributes -%} - {%- for attrname, attrvalue in attr -%} - {{- " " -}} - {%- if attrname in ['placeholder', 'title'] -%} - {{- attrname }}="{{ attrvalue }}" - {%- elseif attrvalue is same as(true) -%} - {{- attrname }}="{{ attrname }}" - {%- elseif attrvalue is not same as(false) -%} - {{- attrname }}="{{ attrvalue }}" - {%- endif -%} - {%- endfor -%} -{%- endblock attributes -%} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_max_length.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_max_length.html.twig deleted file mode 100644 index 160636cc..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_max_length.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% if attr.counter is defined %} - {% set isRecommandedType = attr.counter_type is defined and attr.counter_type == 'recommended' %} - - - {% if isRecommandedType %} - {{ '[1][/1] of [2][/2] characters used (recommended)'|trans({}, 'Admin.Catalog.Feature')|replace({ - '[1]': '', - '[/1]': '', - '[2]': ''~attr.counter, - '[/2]': '', - })|raw }} - {% else %} - {{ '[1][/1] of [2][/2] characters allowed'|trans({}, 'Admin.Catalog.Feature')|replace({ - '[1]': '', - '[/1]': '', - '[2]': ''~attr.counter, - '[/2]': '', - })|raw }} - {% endif %} - - -{% endif %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_table_layout.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_table_layout.html.twig deleted file mode 100644 index e5cf85c1..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/form_table_layout.html.twig +++ /dev/null @@ -1,68 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% use "form_div_layout.html.twig" %} - -{%- block form_row -%} - - - {{- form_label(form) -}} - - - {{- form_errors(form) -}} - {{- form_widget(form) -}} - - -{%- endblock form_row -%} - -{%- block button_row -%} - - - - {{- form_widget(form) -}} - - -{%- endblock button_row -%} - -{%- block hidden_row -%} - - - {{- form_widget(form) -}} - - -{%- endblock hidden_row -%} - -{%- block form_widget_compound -%} - - {%- if form.parent is empty and errors|length > 0 -%} - - - - {%- endif -%} - {{- block('form_rows') -}} - {{- form_rest(form) -}} -
      - {{- form_errors(form) -}} -
      -{%- endblock form_widget_compound -%} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/material.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/material.html.twig deleted file mode 100644 index ad9647b9..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/material.html.twig +++ /dev/null @@ -1,101 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% block material_choice_tree_widget %} -
      -
      - - expand_more - {{ 'Expand'|trans({}, 'Admin.Actions') }} - -
      - -
        - {% for choice in choices_tree %} - {{ block('material_choice_tree_item_widget') }} - {% endfor %} -
      -
      -{% endblock material_choice_tree_widget %} - -{% block material_choice_tree_item_widget %} - {% set has_children = choice[choice_children] is defined %} - -
    • - {% if multiple %} - {{ block('material_choice_tree_item_checkbox_widget') }} - {% else %} - {{ block('material_choice_tree_item_radio_widget') }} - {% endif %} - - {% if has_children %} -
        - {% for item in choice[choice_children] %} - {% set choice = item %} - {{ block('material_choice_tree_item_widget') }} - {% endfor %} -
      - {% endif %} -
    • -{% endblock material_choice_tree_item_widget %} - -{% block material_choice_tree_item_checkbox_widget %} -
      -
      - -
      -
      -{% endblock material_choice_tree_item_checkbox_widget %} - -{% block material_choice_tree_item_radio_widget %} -
      - -
      -{% endblock material_choice_tree_item_radio_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig deleted file mode 100644 index d8423a5b..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit.html.twig +++ /dev/null @@ -1,128 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% use 'bootstrap_4_horizontal_layout.html.twig' %} -{% use '@PrestaShop/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig' %} - -{# overrides from bootstrap_4_horizontal_layout #} - -{% block form_start -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-horizontal')|trim}) %} - {{- parent() -}} -{%- endblock form_start %} - -{# Labels #} - -{% block form_label -%} - {% spaceless %} - {% if label is same as(false) %} -
      - {% else %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ block('form_label_class'))|trim}) %} - {{- parent() -}} - {% endif %} - {% endspaceless %} -{%- endblock form_label %} - -{% block form_label_class -%} - form-control-label -{%- endblock form_label_class %} - -{# Rows #} - -{% block form_row -%} - {% spaceless %} -
      - {{ form_label(form) }} -
      - {{ form_widget(form) }} - {{ form_errors(form) }} -
      -
      - {% endspaceless %} -{%- endblock form_row %} - -{% block form_group_class -%} - col-sm -{%- endblock form_group_class %} - -{% block form_row_class -%} - form-group row{% if row_attr.class is defined %} {{ row_attr.class }}{% endif %} -{%- endblock form_row_class %} - -{# Widgets #} - -{% block text_with_unit_widget %} -
      - {{- block('form_widget_simple') -}} - {% if form.vars.unit is defined %} -
      - {{ form.vars.unit }} -
      - {% endif %} -
      -{% endblock text_with_unit_widget %} - -{% block ip_address_text_widget %} -
      - {{- block('form_widget_simple') -}} - -
      - -{% endblock ip_address_text_widget %} - -{% block switch_widget %} -
      - {{- parent() -}} -
      - {{ block('form_help') }} -{% endblock switch_widget %} - -{% block text_with_length_counter_widget %} -
      - {% set current_length = form.vars.max_length - form.vars.value|length %} - - {% if form.vars.position == 'before' %} -
      - {{ current_length }} -
      - {% endif %} - - {% set attr = attr|merge({'data-max-length': form.vars.max_length, 'maxlength': form.vars.max_length, 'class': 'js-countable-input'}) -%} - - {% if form.vars.input == 'textarea' %} - {{- block('textarea_widget') -}} - {% else %} - {{- block('form_widget_simple') -}} - {% endif %} - - {% if form.vars.position == 'after' %} -
      - {{ current_length }} -
      - {% endif %} -
      -{% endblock text_with_length_counter_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig deleted file mode 100644 index 495c49fa..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/prestashop_ui_kit_base.html.twig +++ /dev/null @@ -1,849 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% use 'bootstrap_4_layout.html.twig' %} -{% use '@PrestaShop/Admin/TwigTemplateForm/typeahead.html.twig' %} -{% use '@PrestaShop/Admin/TwigTemplateForm/material.html.twig' %} - -{# overrides from form_div_layout #} - -{#--deleted {% block form_start -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-horizontal')|trim}) %} - {{- parent() -}} -{%- endblock form_start %}#} - -{# Widgets #} - -{%- block form_widget -%} - {{ parent() }} - {{- block('form_help') -}} -{%- endblock form_widget -%} - -{%- block form_widget_simple -%} - {{ parent() }} - {% include "@Twig/form_max_length.html.twig" with {"attr": attr} %} -{%- endblock form_widget_simple -%} - -{#--deleted {%- block checkbox_widget -%} - {% set switch = switch|default('') -%} - -{%- endblock checkbox_widget -%}#} - -{# Labels #} - -{%- block form_label -%} - {% if label is not same as(false) -%} - {% if not compound -%} - {% set label_attr = label_attr|merge({'for': id}) %} - {%- endif %} - {% if required -%} - {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} - {%- endif %} - {% if label is empty -%} - {%- if label_format is not empty -%} - {% set label = label_format|replace({ - '%name%': name, - '%id%': id, - }) %} - {%- else -%} - {% set label = name|humanize %} - {%- endif -%} - {%- endif -%} - {{ translation_domain is same as(false) ? label|raw : label|raw }} - {% if label_attr['tooltip'] is defined %} - {% set placement = label_attr['tooltip_placement'] is defined ? label_attr['tooltip_placement'] : 'top' %} - - {% endif %} - - {% if label_attr['popover'] is defined %} - {% set placement = label_attr['popover_placement'] is defined ? label_attr['popover_placement'] : 'top' %} - - {% endif %} - - - {%- endif -%} -{%- endblock form_label -%} - -{# Misc #} - -{#--deleted {%- block form_row -%} - {% import '@PrestaShop/Admin/macros.html.twig' as ps %} - - {{- ps.form_group_row(form, { attr: form.vars.attr }, { - 'label': form.vars.label - }) -}} -{% endblock form_row %}#} - -{# overrides from bootstrap_4_layout #} - -{# Widgets #} - -{% block textarea_widget -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %} - {{- parent() -}} - - {{ block('form_help') }} -{%- endblock textarea_widget %} - -{% block money_widget -%} -
      - {% set prepend = '{{' == money_pattern[0:2] %} - {% if not prepend %} -
      - {{ money_pattern|replace({ '{{ widget }}':''}) }} -
      - {% endif %} - {{- block('form_widget_simple') -}} - {% if prepend %} -
      - {{ money_pattern|replace({ '{{ widget }}':''}) }} -
      - {% endif %} -
      -{%- endblock money_widget %} - -{% block percent_widget -%} -
      - {{- block('form_widget_simple') -}} -
      - % -
      -
      -{%- endblock percent_widget %} - -{% block datetime_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} -
      - {{- form_errors(form.date) -}} - {{- form_errors(form.time) -}} - {{- form_widget(form.date, { datetime: true } ) -}} - {{- form_widget(form.time, { datetime: true } ) -}} -
      - {%- endif %} -{%- endblock datetime_widget %} - -{% block date_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or not datetime -%} -
      - {%- endif %} - {{- date_pattern|replace({ - '{{ year }}': form_widget(form.year), - '{{ month }}': form_widget(form.month), - '{{ day }}': form_widget(form.day), - })|raw -}} - {% if datetime is not defined or not datetime -%} -
      - {%- endif -%} - {% endif %} -{%- endblock date_widget %} - -{% block time_widget -%} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or false == datetime -%} -
      - {%- endif -%} - {{- form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %} - {% if datetime is not defined or false == datetime -%} -
      - {%- endif -%} - {% endif %} -{%- endblock time_widget %} - -{% block button_widget -%} - {% set attr = attr|merge({class: (attr.class|default('btn-default') ~ ' btn')|trim}) %} - {{- parent() -}} -{%- endblock %} - -{#{% block checkbox_widget -%} - {% set parent_label_class = parent_label_class|default('') -%} - {% if 'checkbox-inline' in parent_label_class %} - {{- form_label(form, null, { widget: parent() }) -}} - {% else -%} -
      - {{- form_label(form, null, { widget: parent() }) -}} -
      - {%- endif %} -{%- endblock checkbox_widget %} - -{% block radio_widget -%} - {%- set parent_label_class = parent_label_class|default('') -%} - {% if 'radio-inline' in parent_label_class %} - {{- form_label(form, null, { widget: parent() }) -}} - {% else -%} -
      - {{- form_label(form, null, { widget: parent() }) -}} -
      - {%- endif %} -{%- endblock radio_widget %}#} - -{% block choice_widget %} - {{- parent() -}} - {{ block('form_help') }} -{% endblock choice_widget %} - -{% block choice_widget_collapsed -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-select')|trim}) %} - {{- parent() -}} -{%- endblock %} - -{% block choice_widget_expanded -%} - {% if '-inline' in label_attr.class|default('') -%} -
      - {%- for child in form %} - {{- form_widget(child, { - parent_label_class: label_attr.class|default(''), - translation_domain: choice_translation_domain, - valid: valid, - }) -}} - {% endfor -%} -
      - {%- else -%} -
      - {%- for child in form %} - {{- form_widget(child, { - parent_label_class: label_attr.class|default(''), - translation_domain: choice_translation_domain, - valid: valid, - }) -}} - {% endfor -%} -
      - {%- endif %} -{%- endblock choice_widget_expanded %} - -{% block choice_tree_widget -%} -
      -
        -
      • {{ "Main category"|trans({}, 'Admin.Catalog.Feature') }}
      • - {%- for child in choices %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
      -
      -{%- endblock choice_tree_widget %} - -{% block choice_tree_item_widget -%} -
    • - {% set checked = (form.vars.submitted_values is defined and submitted_values[child.id_category] is defined) ? 'checked="checked"' : '' %} - {% if multiple -%} -
      - -
      - {%- else -%} -
      - -
      - {%- endif %} - {% if child.children is defined %} -
        - {% for item in child.children %} - {% set child = item %} - {{ block('choice_tree_item_widget') }} - {% endfor -%} -
      - {% endif %} -
    • -{%- endblock choice_tree_item_widget %} - -{% block translatefields_widget %} - {{ form_errors(form) }} -
      - {% if hideTabs == false and form|length > 1 %} - - {% endif %} - -
      - {% for translationsFields in form %} -
      - {{ form_errors(translationsFields) }} - {{ form_widget(translationsFields) }} -
      - {% endfor %} -
      -
      -{% endblock %} - -{% block translate_fields_widget -%} - {% if type is not defined or 'file' != type %} - {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%} - {% endif %} - {{- parent() -}} -{%- endblock translate_fields_widget %} - -{% block translate_text_widget -%} - {{ form_errors(form) }} -
      - {% for translateField in form %} - {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} - - {% if default_locale.id_lang != translateField.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} - - {% set attr = translateField.vars.attr %} - - {{ form_widget(translateField, {attr: {'class': classes|trim}}) }} - {% endfor %} - - {% if not hide_locales %} - - {% endif %} -
      -{%- endblock translate_text_widget %} - -{% block translate_textarea_widget -%} - {{ form_errors(form) }} -
      - {% for textarea in form %} - {% set classes = textarea.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ textarea.vars.label %} - - {% if default_locale.id_lang != textarea.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} - -
      - {{ form_widget(textarea, {attr: {'class': classes|trim}}) }} -
      - {% endfor %} - - {% if show_locale_select %} - - {% endif %} -
      -{%- endblock translate_textarea_widget %} - -{% block date_picker_widget %} - {% spaceless %} - {% set attr = attr|merge({'class': ((attr.class|default('') ~ ' datepicker')|trim)}) %} -
      - -
      -
      - date_range -
      -
      -
      - {% endspaceless %} -{% endblock date_picker_widget %} - -{% block date_range_widget %} - {% spaceless %} - {{ form_widget(form.from) }} - {{ form_widget(form.to) }} - {% endspaceless %} -{% endblock date_range_widget %} - -{% block search_and_reset_widget %} - {% spaceless %} - - {% if show_reset_button %} -
      -
      - -
      - {% endif %} - {% endspaceless %} -{% endblock search_and_reset_widget %} - -{% block switch_widget %} - {% spaceless %} - - {% for choice in choices %} - {% set inputId = id ~'_' ~ choice.value %} - - - {% endfor %} - - - {% endspaceless %} -{% endblock switch_widget %} - -{% block _form_step6_attachments_widget %} -
      - {{ 'There is no attachment yet.'|trans({}, 'Admin.Catalog.Notification') }} -
      -
      -
      -
      - - - - - - - - - - {%- for child in form %} - - - - - - {% endfor -%} - -
      {{ 'Title'|trans({}, 'Admin.Global') }}{{ 'File name'|trans({}, 'Admin.Global') }}{{ 'Type'|trans({}, 'Admin.Catalog.Feature') }}
      {{ form_widget(child) }}{{ form.vars.attr.data[loop.index0]['file_name'] }}{{ form.vars.attr.data[loop.index0]['mime'] }}
      -
      -
      -
      -{% endblock %} - -{# Labels #} - -{% block choice_label -%} - {# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #} - {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%} - {{- block('form_label') -}} -{% endblock %} - -{% block checkbox_label -%} - {{- block('checkbox_radio_label') -}} -{%- endblock checkbox_label %} - -{% block radio_label -%} - {{- block('checkbox_radio_label') -}} -{%- endblock radio_label %} - -{% block checkbox_radio_label %} - {# Do not display the label if widget is not defined in order to prevent double label rendering #} - {% if widget is defined %} - {% if required %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %} - {% endif %} - {% if parent_label_class is defined %} - {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} - {% endif %} - {% if label is not same as(false) and label is empty %} - {% set label = name|humanize %} - {% endif %} - - {% if material_design is defined or attr.material_design is defined %} -
      - - {{- widget|raw -}} - - {{- label is not same as(false) ? (translation_domain is same as(false) ? label|raw : label|raw) -}} - -
      - {% else %} - - {{- widget|raw -}} - {{- label is not same as(false) ? (translation_domain is same as(false) ? label|raw : label|raw) -}} - - {% endif %} - {% endif %} -{% endblock checkbox_radio_label %} - -{# Errors #} - -{% block form_errors -%} - {% if errors|length > 0 -%} -
      - {%- if errors|length > 1 -%} -
        - {%- for error in errors -%} -
      • {{ - error.messagePluralization is null - ? error.messageTemplate|trans(error.messageParameters, 'form_error') - : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'form_error') - }} -
      • - {%- endfor -%} -
      - {%- else -%} -
      - {%- for error in errors -%} -

      {{ - error.messagePluralization is null - ? error.messageTemplate|trans(error.messageParameters, 'form_error') - : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'form_error') - }} -

      - {%- endfor -%} -
      - {%- endif -%} -
      - {%- endif %} -{%- endblock form_errors %} - -{# Material design widgets #} - -{% block material_choice_table_widget %} - {% spaceless %} -
      - - - - - - - - {% for child in form %} - - - - {% endfor %} - -
      -
      - -
      -
      - {{ form_widget(child, {'material_design': true}) }} -
      -
      - {% endspaceless %} -{% endblock material_choice_table_widget %} - -{% block material_multiple_choice_table_widget %} - {% spaceless %} -
      - - - - - {% for child_choice in form %} - - {% endfor %} - - - - {% for choice_name, choice_value in choices %} - - - {% for child_choice_name, child_choice in form %} - - {% endfor %} - - {% endfor %} - -
      {{ label }} - {% if child_choice.vars.multiple and child_choice.vars.name not in headers_to_disable %} - - {{ child_choice.vars.label }} - - {% else %} - {{ child_choice.vars.label }} - {% endif %} -
      - {{ choice_name }} - - {% if child_choice_entry_index_mapping[choice_value][child_choice_name] is defined %} - {% set entry_index = child_choice_entry_index_mapping[choice_value][child_choice_name] %} - - {% if child_choice.vars.multiple %} - {{ form_widget(child_choice[entry_index], {'material_design': true}) }} - {% else %} - {{ form_widget(child_choice[entry_index]) }} - {% endif %} - {% else %} - -- - {% endif %} -
      -
      - {% endspaceless %} -{% endblock material_multiple_choice_table_widget %} - -{% block translatable_widget -%} -
      - {% for translateField in form %} - {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} - {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} - {% if default_locale.id_lang != translateField.vars.name %} - {% set classes = classes ~ ' d-none' %} - {% endif %} -
      - {{ form_widget(translateField) }} -
      - {% endfor %} - {% if not hide_locales %} - - {% endif %} -
      -{%- endblock translatable_widget %} - -{% block birthday_widget %} - {% if widget == 'single_text' %} - {{- block('form_widget_simple') -}} - {% else -%} - {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} - {% if datetime is not defined or not datetime -%} -
      - {%- endif %} - - {% set yearWidget = '
      ' ~ form_widget(form.year) ~ '
      '|raw %} - {% set monthWidget = '
      ' ~ form_widget(form.month) ~ '
      '|raw %} - {% set dayWidget = '
      ' ~ form_widget(form.day) ~ '
      '|raw %} - - {{- date_pattern|replace({ - '{{ year }}': yearWidget, - '{{ month }}': monthWidget, - '{{ day }}': dayWidget, - })|raw -}} - - {% if datetime is not defined or not datetime -%} -
      - {%- endif -%} - {% endif %} -{% endblock birthday_widget %} - -{% block file_widget %} - -
      - {% set attr = attr|merge({ - class: (attr.class|default('') ~ ' custom-file-input')|trim, - 'data-multiple-files-text': '%count% file(s)'|trans({}, 'Admin.Global'), - 'data-locale': get_context_iso_code() - }) -%} - - {% if attr.disabled is defined and attr.disabled %} - {% set attr = attr|merge({ - class: attr.class ~ ' disabled' - }) %} - {% endif %} - - {{ form_widget(form, {'attr': attr}) }} - - -
      -{% endblock file_widget %} - -{% block shop_restriction_checkbox_widget %} - {% if form.vars.attr.is_allowed_to_display %} -
      - -
      - {% endif %} -{% endblock %} - -{% block generatable_text_widget %} -
      - {{- block('form_widget') -}} - - - -
      -{% endblock generatable_text_widget %} - -{% block text_with_recommended_length_widget %} - {% set attr = attr|merge({ - 'data-recommended-length-counter': '#' ~ id ~ '_recommended_length_counter', - 'class': 'js-recommended-length-input' - }) -%} - - {% if input_type == 'textarea' %} - {{- block('textarea_widget') -}} - {% else %} - {{- block('form_widget_simple') -}} - {% endif %} - - - - {{ '[1][/1] of [2][/2] characters used (recommended)'|trans({}, 'Admin.Catalog.Feature')|replace({ - '[1]': '' ~ value|length, - '[/1]': '', - '[2]': '' ~ recommended_length, - '[/2]': '', - })|raw }} - - -{% endblock text_with_recommended_length_widget %} - -{% block integer_min_max_filter_widget %} - {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} - {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} -{% endblock %} - -{% block number_min_max_filter_widget %} - {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} - {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} -{% endblock %} - -{% block form_help %} - {% if help %} - {{ help|raw }} - {% endif %} - {% if warning is defined %} - {{ warning }} - {% endif %} -{% endblock form_help %} - -{% block custom_content_widget %} - {% include template with data %} -{% endblock %} - -{% block text_widget %} - {% if data_list is not null %} - {%- set attr = attr|merge({'list': id ~ '_datalist'}) -%} - {% endif %} - - {{ form_widget(form, {'attr': attr}) }} - - {% if data_list is not null %} - - {% for item in data_list %} - - {% endfor%} - - {% endif %} -{% endblock text_widget %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/typeahead.html.twig b/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/typeahead.html.twig deleted file mode 100644 index 1cf9c830..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/TwigTemplateForm/typeahead.html.twig +++ /dev/null @@ -1,305 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% block typeahead_product_collection_widget %} - - -{% endblock %} - -{% block typeahead_product_pack_collection_widget %} -

      {{ 'List of products for this pack'|trans({}, 'Admin.Catalog.Feature') }}

      -
        - {% if collection is defined and collection|length > 0 %} - {% for item in collection %} -
      • -
        - {{ template_collection|format(item.name, item.ref, item.quantity)|raw }} - - -
        -
      • - {% endfor %} - {% endif %} -
      - -

      {{ form.vars.label }}

      - -
      -
      - -
      -
      -
      -
      - × -
      - -
      -
      -
      -
      - -
      -
      -
      - - -
      -{% endblock %} - -{% block typeahead_customer_collection_widget %} - {{ form_errors(form) }} - -
        - {% if collection is defined and collection|length > 0 %} - {% for item in collection %} -
      • -
        - {{ template_collection|format(item.name)|raw }} -
        - -
      • - {% endfor %} - {% endif %} -
      - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/commands_and_queries.html.twig b/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/commands_and_queries.html.twig deleted file mode 100644 index a0da7dd5..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/commands_and_queries.html.twig +++ /dev/null @@ -1,122 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} - -{% extends '@WebProfiler/Profiler/layout.html.twig' %} - -{% block toolbar %} - {% set icon %} - {{ include('@WebProfiler/Icon/request.svg') }} - Commands / Queries - {% endset %} - - {% set text %} -
      -
      - Commands / Queries -
      -
      - Commands - {% set commandsCount = collector.executedCommands|length %} - - {{ commandsCount }} - -
      -
      - Queries - {% set queriesCount = collector.executedQueries|length %} - - {{ queriesCount }} - -
      -
      - {% endset %} - - {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }} -{% endblock %} - -{% block menu %} - - {{ include('@WebProfiler/Icon/request.svg') }} - Commands / Queries - -{% endblock %} - -{% block panel %} -

      Commands

      - -
      - - - - - - - - - - {% if collector.executedCommands is not empty %} - {% for command in collector.executedCommands %} - - - - - - {% endfor %} - {% else %} - - - - {% endif %} - -
      CommandCommand HandlerCalled from
      {{ command.command }}{{ command.command_handler }}{{ command.trace.file }}:{{ command.trace.line }}
      No Commands where executed during request.
      - -

      Queries

      - - - - - - - - - - - {% if collector.executedQueries is not empty %} - {% for query in collector.executedQueries %} - - - - - - {% endfor %} - {% else %} - - - - {% endif %} - -
      QueryQuery HandlerCalled from
      {{ query.query }}{{ query.query_handler }}{{ query.trace.file }}:{{ query.trace.line }}
      No Queries where executed during request.
      -
      -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/config.html.twig b/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/config.html.twig deleted file mode 100644 index f8d5e1f2..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/config.html.twig +++ /dev/null @@ -1,274 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@WebProfiler/Profiler/layout.html.twig' %} - -{% block toolbar %} - {% if 'unknown' == collector.symfonyState %} - {% set block_status = '' %} - {% set symfony_version_status = 'Unable to retrieve information about the Symfony version.' %} - {% elseif 'eol' == collector.symfonyState %} - {% set block_status = 'red' %} - {% set symfony_version_status = 'This Symfony version will no longer receive security fixes.' %} - {% elseif 'eom' == collector.symfonyState %} - {% set block_status = 'yellow' %} - {% set symfony_version_status = 'This Symfony version will only receive security fixes.' %} - {% elseif 'dev' == collector.symfonyState %} - {% set block_status = 'yellow' %} - {% set symfony_version_status = 'This Symfony version is still in the development phase.' %} - {% else %} - {% set block_status = '' %} - {% set symfony_version_status = '' %} - {% endif %} - - {% set icon %} - - {{ collector.applicationversion }} - {% endset %} - - {% set text %} -
      -
      - {{ collector.applicationname }} - {{ collector.applicationversion }} -
      - -
      - Profiler token - - {% if profiler_url %} - {{ collector.token }} - {% else %} - {{ collector.token }} - {% endif %} - -
      - - -
      -
      -
      - PHP version - - {{ collector.phpversion }} -   View phpinfo() - -
      - -
      - PHP Extensions - xdebug - APCu - OPcache -
      - -
      - PHP SAPI - {{ collector.sapiName }} -
      -
      - -
      -
      - Resources - - {% set appVersion = collector.applicationversion|split('.')|join()[:2] %} - - Read PrestaShop {{ collector.applicationversion }} Docs - - -
      -
      - {% endset %} - - {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true, name: 'config', status: block_status, additional_classes: 'sf-toolbar-block-right', block_attrs: 'title="' ~ symfony_version_status ~ '"' }) }} -{% endblock %} - -{% block menu %} - - {{ include('@WebProfiler/Icon/config.svg') }} - Configuration - -{% endblock %} - -{% block panel %} - {% if collector.applicationname %} - {# this application is not the Symfony framework #} -

      Project Configuration

      - -
      -
      - {{ collector.applicationname }} - Application name -
      - -
      - {{ collector.applicationversion }} - Application version -
      -
      - -

      - Based on Symfony {{ collector.symfonyversion }} -

      - {% else %} -

      Symfony Configuration

      - -
      -
      - {{ collector.symfonyversion }} - Symfony version -
      - - {% if 'n/a' != collector.appname %} -
      - {{ collector.appname }} - Application name -
      - {% endif %} - - {% if 'n/a' != collector.env %} -
      - {{ collector.env }} - Environment -
      - {% endif %} - - {% if 'n/a' != collector.debug %} -
      - {{ collector.debug ? 'enabled' : 'disabled' }} - Debug -
      - {% endif %} -
      - - {% set symfony_status = { dev: 'Unstable Version', stable: 'Stable Version', eom: 'Maintenance Ended', eol: 'Version Expired' } %} - {% set symfony_status_class = { dev: 'warning', stable: 'success', eom: 'warning', eol: 'error' } %} - - - - - - - - - - - - - - - - - -
      Symfony StatusBugs {{ collector.symfonystate in ['eom', 'eol'] ? 'were' : 'are' }} fixed untilSecurity issues {{ collector.symfonystate == 'eol' ? 'were' : 'are' }} fixed until
      - {{ symfony_status[collector.symfonystate]|upper }} - {{ collector.symfonyeom }}{{ collector.symfonyeol }} - View roadmap -
      - {% endif %} - -

      PHP Configuration

      - -
      -
      - {{ collector.phpversion }}{% if collector.phpversionextra %} {{ collector.phpversionextra }}{% endif %} - PHP version -
      - -
      - {{ collector.phparchitecture }} bits - Architecture -
      - -
      - {{ collector.phpintllocale }} - Intl locale -
      - -
      - {{ collector.phptimezone }} - Timezone -
      -
      - -
      -
      - Resources - - {% set appVersion = collector.applicationversion|split('.')|join()[:2] %} - - Read PrestaShop {{ collector.applicationversion }} Docs - - -
      -
      -
      -
      - {{ include('@WebProfiler/Icon/' ~ (collector.haszendopcache ? 'yes' : 'no') ~ '.svg') }} - OPcache -
      - -
      - {{ include('@WebProfiler/Icon/' ~ (collector.hasapcu ? 'yes' : 'no') ~ '.svg') }} - APCu -
      - -
      - {{ include('@WebProfiler/Icon/' ~ (collector.hasxdebug ? 'yes' : 'no') ~ '.svg') }} - Xdebug -
      -
      - -

      - View full PHP configuration -

      - - {% if collector.bundles %} -

      Enabled Bundles ({{ collector.bundles|length }})

      - - - - - - - - - {% for name in collector.bundles|keys|sort %} - - - - - {% endfor %} - -
      NamePath
      {{ name }}{{ profiler_dump(collector.bundles[name]) }}
      - {% endif %} -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/hooks_collector.html.twig b/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/hooks_collector.html.twig deleted file mode 100644 index d9e13a16..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/WebProfiler/hooks_collector.html.twig +++ /dev/null @@ -1,165 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends '@WebProfiler/Profiler/layout.html.twig' %} - -{% import _self as helper %} - -{% block toolbar %} - {% set icon %} - {{ include('@WebProfiler/Icon/event.svg') }} - Hooks ({{ collector.calledHooks|length }}) - {% endset %} - - {% set text %} -
      -
      - {{ collector.calledHooks|length }} Hooks called -
      -
      - - - - - - - - - {% for hookName, hooks in collector.calledHooks %} - - {% else %} - - {% endfor %} - -
      Hook nameCall(s)
      {{ hookName }}{{ hooks|length }}
      No hook dispatched.
      -
      -
      - {% endset %} - - {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: true }) }} - -{% endblock %} - -{% block menu %} - {# This left-hand menu appears when using the full-screen profiler. #} - - {{ include('@WebProfiler/Icon/event.svg') }} - Hooks - -{% endblock %} - -{% block panel %} -

      Hooks

      - - {% if collector.notCalledHooks is empty %} -
      -

      No Hooks have been recorded. Check that debugging is enabled in the kernel.

      -
      - {% else %} -
      -
      -

      Called Hooks {{ collector.calledHooks|length }}

      - -
      - {{ helper.render_table(collector.calledHooks, true) }} -
      -
      - -
      -

      Not Called Hooks {{ collector.notCalledHooks|length }}

      -
      - {% if collector.notCalledHooks is empty %} -
      -

      - There are no uncalled hooks. -

      -

      - All hooks were called for this request or an error occurred - when trying to collect uncalled listeners (in which case check the - logs to get more information). -

      -
      - {% else %} - {{ helper.render_table(collector.notCalledHooks, false) }} - {% endif %} -
      -
      -
      - {% endif %} -{% endblock %} - -{% macro render_table(hookList, hookModules) %} - {% for hookName, hooks in hookList %} -

      {{ hookName }}

      - - - - - - - {% if hookModules %} - - {% endif %} - - - - {% for position, hook in hooks %} - - - - {% if hookModules %} - - {% endif %} - - {% endfor %} - -
      ArgumentsLocationHooked modules
      - {{ profiler_dump(hook.args) }} - - {{ hook.location }} - - {% set modules = hook.modules %} - {% for moduleName, module in modules %} -

      {{ moduleName|capitalize }}

      - - - - - - - - {% if module.callback is defined %} - - - - {% else %} - - - - {% endif %} -
      Module arguments
      {{ profiler_dump(module.callback.args) }}
      {{ profiler_dump(module.widget.args) }}
      - {% endfor %} -
      - {% endfor %} -{% endmacro %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/layout.html.twig b/src/PrestaShopBundle/Resources/views/Admin/layout.html.twig deleted file mode 100644 index 8a895867..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/layout.html.twig +++ /dev/null @@ -1,104 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% extends(template_from_string( - getLegacyLayout( - app.request.attributes.get('_legacy_controller'), - layoutTitle is defined ? layoutTitle : '', - layoutHeaderToolbarBtn is defined ? layoutHeaderToolbarBtn : [], - layoutDisplayType is defined ? layoutDisplayType : '', - showContentHeader is defined ? showContentHeader : true, - headerTabContent is defined ? headerTabContent : '', - enableSidebar is defined ? enableSidebar : false, - help_link is defined ? help_link : '', - js_router_metadata(), - meta_title is defined ? meta_title : '', - use_regular_h1_structure is defined ? use_regular_h1_structure : true - ) - )) %} - -{% import '@PrestaShop/Admin/macros.html.twig' as ps %} - -{% block javascripts %} - - - -{% endblock %} - -{% block translate_javascripts %} - -{% endblock %} - -{% block content_header %} - {% macro alert(type, flashbagContent) %} - - {% endmacro %} - {% import _self as layout %} - - {% if app.session.flashbag.peek('error')|length() > 0 %} - {{ layout.alert('danger', app.session.flashbag.get('error')) }} - {% endif %} - {% if app.session.flashbag.peek('failure')|length() > 0 %} - {{ layout.alert('danger', app.session.flashbag.get('failure')) }} - {% endif %} - {% if app.session.flashbag.peek('success')|length() > 0 %} - {{ layout.alert('success', app.session.flashbag.get('success')) }} - {% endif %} - {% if app.session.flashbag.peek('warning')|length() > 0 %} - {{ layout.alert('warning', app.session.flashbag.get('warning')) }} - {% endif %} -{% endblock %} - -{% block sidebar_right %} - -{% endblock %} diff --git a/src/PrestaShopBundle/Resources/views/Admin/macros.html.twig b/src/PrestaShopBundle/Resources/views/Admin/macros.html.twig deleted file mode 100644 index 5bdc8abe..00000000 --- a/src/PrestaShopBundle/Resources/views/Admin/macros.html.twig +++ /dev/null @@ -1,310 +0,0 @@ -{#** - * Copyright since 2007 PrestaShop SA and Contributors - * PrestaShop is an International Registered Trademark & Property of PrestaShop SA - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.md. - * It is also available through the world-wide-web at this URL: - * https://opensource.org/licenses/OSL-3.0 - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@prestashop.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - * versions in the future. If you wish to customize PrestaShop for your - * needs please refer to https://devdocs.prestashop.com/ for more information. - * - * @author PrestaShop SA and Contributors - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - *#} -{% macro form_label_tooltip(name, tooltip, placement) %} - {{ form_label(name, null, {'label_attr': {'tooltip': tooltip, 'tooltip_placement': placement|default('top')}}) }} -{% endmacro %} - -{% macro check(variable) %} - {{ variable is defined and variable|length > 0 ? variable : false }} -{% endmacro %} - -{% macro tooltip(text, icon, position) %} - - {{ icon }} - -{% endmacro %} - -{% macro infotip(text, use_raw = false)%} - -{% endmacro %} - -{% macro warningtip(text)%} - -{% endmacro %} - -{% macro label_with_help(label, help, class = '', for = '', isRequired = false) %} - - {% if isRequired %} - * - {% endif %} - - {{ label }} - - - -

      {{ help }}

      -{% endmacro %} - -{# Table column headers with sorting indicators #} -{% macro sortable_column_header(title, sortColumnName, orderBy, sortOrder, prefix) %} - {% set sortOrder, orderBy, prefix = sortOrder|default(''), orderBy|default, prefix|default('') %} -
      - {{ title }} - -
      - -{% endmacro %} - -{# Show link to import file sample #} -{% macro import_file_sample(label, filename) %} - - {{ label|trans({}, 'Admin.Advparameters.Feature') }} - -{% endmacro %} - -{# - Show form widget with errors rendered below it. It displays all nested errors for any form type. - If form type has error_by_locale parameter set then the error is being displayed with the specific locale assigned to it. - If form type has errors_by_locale parameter set then the errors are being assigned to the locales and are displayed - in the popover template. - If there are more then one error it also assigns all errors in the pop-up to appear. - On page load, user sees only the errors count but then user hovers over the element the popover - appears with the errors combined by language. -#} -{% macro form_widget_with_error(form, vars, extraVars) %} - {% import '@PrestaShop/Admin/macros.html.twig' as self %} - - {% set vars = vars|default({}) %} - {% set extraVars = extraVars|default({}) %} - {% set attr = vars.attr|default({}) %} - {% set attr = attr|merge({'class': (attr.class is defined ? attr.class : '')} ) %} - {% set vars = vars|merge({'attr': attr}) %} - - {{ form_widget(form, vars) }} - - {% if extraVars.help is defined and extraVars.help%} - {{ extraVars.help }} - {% elseif form.vars.help is defined and form.vars.help %} - {{ form.vars.help }} - {% endif %} - - {{ self.form_error_with_popover(form) }} - -{% endmacro %} - -{# - It displays all nested errors for any form type. - If form type has error_by_locale parameter set then the error is being displayed with the specific locale assigned to it. - If form type has errors_by_locale parameter set then the errors are being assigned to the locales and are displayed - in the popover template. - If there are more then one error it also assigns all errors in the pop-up to appear. - On page load, user sees only the errors count but then user hovers over the element the popover - appears with the errors combined by language. -#} -{% macro form_error_with_popover(form) %} - {% set errors = [] %} - - {% if form.vars.valid is defined and not form.vars.valid %} - {% for parentError in form.vars.errors %} - {% set errors = errors|merge([parentError.message]) %} - {% endfor %} - - {#iterating over child errors because errors can be nested#} - {% for child in form.children %} - {% for error in child.vars.errors %} - {% set errors = errors|merge([error.message]) %} - {% endfor %} - {% endfor %} - {% endif %} - - {% if errors|length > 0 %} - {# for form types which has locales and there are more then 1 error , additional errors are displaying inside popover #} - {% set errorPopover = null %} - - {% if errors|length > 1 %} - {% set popoverContainer = 'popover-error-container-'~form.vars.id %} -
      - - - {% if form.vars.errors_by_locale is defined %} - {% set popoverErrors = form.vars.errors_by_locale %} - - {# collecting translatable errors - the ones which has locale name attached #} - {% set translatableErrors = [] %} - {% for translatableError in popoverErrors %} - {% set translatableErrors = translatableErrors|merge([translatableError.error_message]) %} - {% endfor %} - - {# if an error found which does not exist in translatable errors array - it adds it to the popover error container #} - {% for error in errors %} - {% if error not in translatableErrors %} - {% set popoverErrors = popoverErrors|merge([error]) %} - {% endif %} - {% endfor %} - - {% else %} - {% set popoverErrors = errors %} - {% endif %} - - {% set errorMessages = [] %} - {% for popoverError in popoverErrors %} - {% set errorMessage = popoverError %} - - {% if popoverError.error_message is defined and popoverError.locale_name is defined %} - {% set errorMessage = '%error_message% - Language: %language_name%'|trans({'%error_message%': popoverError.error_message, '%language_name%': popoverError.locale_name}, 'Admin.Notifications.Error') %} - {% endif %} - - {% set errorMessages = errorMessages|merge([errorMessage]) %} - {% endfor %} - - {% set popoverErrorContent %} -
      -
        - {% for popoverError in errorMessages %} -
      • - {{ popoverError }} -
      • - {% endfor %} -
      -
      - {% endset %} - - - - {% set errorPopover %} - - error_outline {{ '%count% errors'|transchoice(popoverErrors|length, {}, 'Admin.Global') }} - - {% endset %} - - {% elseif form.vars.error_by_locale is defined %} - {% set errorByLocale = '%error_message% - Language: %language_name%'|trans({'%error_message%': form.vars.error_by_locale.error_message, '%language_name%': form.vars.error_by_locale.locale_name}, 'Admin.Notifications.Error') %} - {% set errors = [errorByLocale] %} - {% endif %} - -
      - {% if errorPopover is not null %} -
      - {{ errorPopover }} -
      - {% else %} -
      - error_outline -
      -
      - {% for error in errors %} -
      - {{ error }} -
      - {% endfor %} -
      - {% endif %} -
      - {% endif %} -{% endmacro %} - - {# - Helper function to render most common structure for single input - @param form - form view to render - @param vars - custom vars that are passed to form_widget - @param extraVars - parameters that are not related to form_widget, but are needed for input (label, help text & etc.) - #} -{% macro form_group_row(form, vars, extraVars) %} - {% import '@PrestaShop/Admin/macros.html.twig' as self %} - - {% set class = extraVars.class|default('') %} - {% set inputType = form.vars.block_prefixes.1|default('text') %} - {% set rowAttributes = extraVars.row_attr|default({}) %} -
      - {% set extraVars = extraVars|default({}) %} - - {# renders label above the form field if set to true #} - {% set labelOnTop = false %} - - {% if extraVars.label_on_top is defined %} - {% set labelOnTop = extraVars.label_on_top %} - {% endif %} - - {% if extraVars.label is defined %} - {% set isRequired = form.vars.required|default(false) %} - - {% if extraVars.required is defined %} - {% set isRequired = extraVars.required %} - {% endif %} - - - {% endif %} - -
      - {{ self.form_widget_with_error(form, vars, extraVars) }} -
      -
      -{% endmacro %} - -{% macro multistore_switch(form, extraVars) %} - {% import '@PrestaShop/Admin/macros.html.twig' as self %} - {% if form.shop_restriction_switch is defined %} - {% set defaultLabel %} - {{ 'Check / Uncheck all'|trans({}, 'Admin.Actions') }}
      - {{ 'You are editing this page for a specific shop or group. Click "%yes_label%" to check all fields, "%no_label%" to uncheck all.'|trans({'%yes_label%': 'Yes'|trans({}, 'Admin.Global'), '%no_label%': 'No'|trans({}, 'Admin.Global')}, 'Admin.Design.Help') }}
      - {{ 'If you check a field, change its value, and save, the multistore behavior will not apply to this shop (or group), for this particular parameter.'|trans({}, 'Admin.Design.Help') }} - {% endset %} - - {% if extraVars.help is not defined %} - {% set extraVars = extraVars|merge({'help': defaultLabel}) %} - {% endif %} - - {% set vars = { 'attr': { 'class': 'js-multi-store-restriction-switch'}} %} - - {{ self.form_group_row(form.shop_restriction_switch, vars, extraVars) }} - {% endif %} -{% endmacro %} diff --git a/src/PrestaShopBundle/Routing/Converter/AbstractLegacyRouteProvider.php b/src/PrestaShopBundle/Routing/Converter/AbstractLegacyRouteProvider.php deleted file mode 100644 index ac347261..00000000 --- a/src/PrestaShopBundle/Routing/Converter/AbstractLegacyRouteProvider.php +++ /dev/null @@ -1,150 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use PrestaShopBundle\Routing\Converter\Exception\RouteNotFoundException; - -/** - * Class AbstractLegacyRouteProvider. - */ -abstract class AbstractLegacyRouteProvider implements LegacyRouteProviderInterface -{ - /** - * @var array|null - */ - protected $controllersActions; - - /** - * This is the only method that child classes need to implement. - * - * @return LegacyRoute[] - */ - abstract public function getLegacyRoutes(); - - /** - * @return array - */ - public function getControllersActions() - { - $this->initControllerActions(); - - return $this->controllersActions; - } - - /** - * {@inheritdoc} - */ - public function getActionsByController($controller) - { - $this->initControllerActions(); - - $controllerActions = $this->getControllerActions($controller); - if (null === $controllerActions) { - throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy controller: %s', $controller)); - } - - return array_keys($controllerActions); - } - - /** - * {@inheritdoc} - */ - public function getLegacyRouteByAction($controller, $action) - { - $this->initControllerActions(); - - $controllerActions = $this->getControllerActions($controller); - if (null === $controllerActions) { - throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy controller: %s', $controller)); - } - - $action = LegacyRoute::isIndexAction($action) ? 'index' : $action; - $routeName = $this->getRouteName($controllerActions, $action); - if (null === $routeName) { - throw new RouteNotFoundException(sprintf('Could not find a route matching for legacy action: %s', $controller . ':' . $action)); - } - - return $this->getLegacyRoutes()[$routeName]; - } - - /** - * Get the route name. - * - * @param array $controllerActions - * @param string $action - * - * @return string|null - */ - private function getRouteName(array $controllerActions, $action) - { - $routeName = null; - foreach ($controllerActions as $controllerAction => $actionRoute) { - if (strtolower($controllerAction) == strtolower($action)) { - $routeName = $actionRoute; - break; - } - } - - if (is_array($routeName)) { - return $routeName[0]; - } - - return $routeName; - } - - /** - * Init the controller actions has map. - */ - private function initControllerActions() - { - if (null === $this->controllersActions) { - $this->controllersActions = []; - /** @var LegacyRoute $legacyRoute */ - foreach ($this->getLegacyRoutes() as $legacyRoute) { - $this->controllersActions = array_merge_recursive($this->controllersActions, $legacyRoute->getControllersActions()); - } - } - } - - /** - * @param string $controller - * - * @return array|null - */ - private function getControllerActions($controller) - { - $controllerActions = null; - foreach ($this->controllersActions as $listController => $actions) { - if (strtolower($listController) == strtolower($controller)) { - $controllerActions = $actions; - break; - } - } - - return $controllerActions; - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/CacheKeyGeneratorInterface.php b/src/PrestaShopBundle/Routing/Converter/CacheKeyGeneratorInterface.php deleted file mode 100644 index 1b7adc66..00000000 --- a/src/PrestaShopBundle/Routing/Converter/CacheKeyGeneratorInterface.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -/** - * Interface CacheKeyGeneratorInterface is used by CacheProvider to generate - * the key used for its cache, it allows to update the cache easily by varying the key. - */ -interface CacheKeyGeneratorInterface -{ - /** - * Returns a string used as key for caching the legacy routes information. - * You can vary this cache key in order to update the cache when needed. - * (e.g: RoutingCacheKeyGenerator generates its key based on the last modification - * date of routing files so that each modifications regenerate the cache). - * - * @return string - */ - public function getCacheKey(); -} diff --git a/src/PrestaShopBundle/Routing/Converter/CacheProvider.php b/src/PrestaShopBundle/Routing/Converter/CacheProvider.php deleted file mode 100644 index d42edb10..00000000 --- a/src/PrestaShopBundle/Routing/Converter/CacheProvider.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use Symfony\Component\Cache\Adapter\AdapterInterface; - -/** - * Class CacheProvider. - */ -class CacheProvider extends AbstractLegacyRouteProvider -{ - /** - * @var AdapterInterface - */ - private $cache; - - /** - * @var LegacyRouteProviderInterface - */ - private $legacyRouteProvider; - - /** - * @var CacheKeyGeneratorInterface - */ - private $cacheKeyGenerator; - - /** - * @var LegacyRoute[] - */ - private $legacyRoutes; - - public function __construct( - LegacyRouteProviderInterface $legacyRouteProvider, - AdapterInterface $cache, - CacheKeyGeneratorInterface $cacheKeyGenerator - ) { - $this->legacyRouteProvider = $legacyRouteProvider; - $this->cache = $cache; - $this->cacheKeyGenerator = $cacheKeyGenerator; - } - - /** - * {@inheritdoc} - */ - public function getLegacyRoutes() - { - if (null === $this->legacyRoutes) { - $cacheItem = $this->cache->getItem($this->cacheKeyGenerator->getCacheKey()); - if (!$cacheItem->isHit()) { - $this->legacyRoutes = $this->legacyRouteProvider->getLegacyRoutes(); - $cacheItem->set($this->serializeLegacyRoutes($this->legacyRoutes)); - $this->cache->save($cacheItem); - } else { - $this->legacyRoutes = $this->unserializeLegacyRoutes($cacheItem->get()); - } - } - - return $this->legacyRoutes; - } - - /** - * @param LegacyRoute[] $legacyRoutes - * - * @return string - */ - private function serializeLegacyRoutes(array $legacyRoutes) - { - $flattenRoutes = []; - /** @var LegacyRoute $legacyRoute */ - foreach ($legacyRoutes as $legacyRoute) { - $legacyLinks = []; - foreach ($legacyRoute->getLegacyLinks() as $legacyLink) { - if (empty($legacyLink['action'])) { - $legacyLinks[] = $legacyLink['controller']; - } else { - $legacyLinks[] = $legacyLink['controller'] . ':' . $legacyLink['action']; - } - } - $flattenRoutes[] = [ - 'route_name' => $legacyRoute->getRouteName(), - 'legacy_links' => $legacyLinks, - 'legacy_parameters' => $legacyRoute->getRouteParameters(), - ]; - } - - return json_encode($flattenRoutes); - } - - /** - * @param string $serializedLegacyRoutes - * - * @return LegacyRoute[] - */ - private function unserializeLegacyRoutes($serializedLegacyRoutes) - { - $flattenRoutes = json_decode($serializedLegacyRoutes, true); - - $legacyRoutes = []; - foreach ($flattenRoutes as $flattenRoute) { - $legacyRoutes[$flattenRoute['route_name']] = new LegacyRoute( - $flattenRoute['route_name'], - $flattenRoute['legacy_links'], - $flattenRoute['legacy_parameters'] - ); - } - - return $legacyRoutes; - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/Exception/AlreadyConvertedException.php b/src/PrestaShopBundle/Routing/Converter/Exception/AlreadyConvertedException.php deleted file mode 100644 index 44084b0b..00000000 --- a/src/PrestaShopBundle/Routing/Converter/Exception/AlreadyConvertedException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter\Exception; - -/** - * Class AlreadyConvertedException is thrown when trying to converting - * an already converted url. Thus you can detect no redirection is needed - * and avoid an infinite loop. - */ -class AlreadyConvertedException extends RoutingException -{ -} diff --git a/src/PrestaShopBundle/Routing/Converter/Exception/ArgumentException.php b/src/PrestaShopBundle/Routing/Converter/Exception/ArgumentException.php deleted file mode 100644 index a9c923af..00000000 --- a/src/PrestaShopBundle/Routing/Converter/Exception/ArgumentException.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter\Exception; - -/** - * Class ArgumentException. - */ -class ArgumentException extends RoutingException -{ -} diff --git a/src/PrestaShopBundle/Routing/Converter/Exception/RouteNotFoundException.php b/src/PrestaShopBundle/Routing/Converter/Exception/RouteNotFoundException.php deleted file mode 100644 index 9b89c5be..00000000 --- a/src/PrestaShopBundle/Routing/Converter/Exception/RouteNotFoundException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class RouteNotFoundException. - */ -class RouteNotFoundException extends CoreException -{ -} diff --git a/src/PrestaShopBundle/Routing/Converter/Exception/RoutingException.php b/src/PrestaShopBundle/Routing/Converter/Exception/RoutingException.php deleted file mode 100644 index bf5ffa14..00000000 --- a/src/PrestaShopBundle/Routing/Converter/Exception/RoutingException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter\Exception; - -use PrestaShop\PrestaShop\Core\Exception\CoreException; - -/** - * Class RoutingException. - */ -class RoutingException extends CoreException -{ -} diff --git a/src/PrestaShopBundle/Routing/Converter/LegacyParametersConverter.php b/src/PrestaShopBundle/Routing/Converter/LegacyParametersConverter.php deleted file mode 100644 index 4daadc39..00000000 --- a/src/PrestaShopBundle/Routing/Converter/LegacyParametersConverter.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShopBundle\Routing\Converter; - -/** - * This class converts the request information (attributes and query parameters) - * and returns an array of parameters adapted with their legacy names (based on - * the configuration from the routing). - */ -class LegacyParametersConverter -{ - /** - * Use the request attributes which contain the routing configuration along with query - * parameters to return an array containing the equivalent with legacy parameters names. - * - * Example with $request being a Symfony Request: - * - * $legacyParameters = $converter->getParameters($request->attributes->all(), $request->query->all()); - * - * @param array $requestAttributes - * @param array $queryParameters - * - * @return array|null - */ - public function getParameters(array $requestAttributes, array $queryParameters): ?array - { - if (!isset($requestAttributes['_legacy_parameters']) && !isset($requestAttributes['_legacy_link'])) { - return null; - } - - $legacyParameters = []; - - // Convert new parameters into legacy ones (search in attributes and query parameters) - $parametersMatching = $requestAttributes['_legacy_parameters'] ?? []; - foreach ($parametersMatching as $legacyParameter => $routingParameter) { - if (isset($requestAttributes[$routingParameter])) { - $legacyParameters[$legacyParameter] = $requestAttributes[$routingParameter]; - } elseif (isset($queryParameters[$routingParameter])) { - $legacyParameters[$legacyParameter] = $queryParameters[$routingParameter]; - } - } - - // Set controller and action based on _legacy_link - if (isset($requestAttributes['_legacy_link'])) { - $legacyLinks = $requestAttributes['_legacy_link']; - if (!is_array($legacyLinks)) { - $legacyLinks = [$legacyLinks]; - } - - // Loop through the _legacy_link until a controller and action is found - foreach ($legacyLinks as $legacyLink) { - $linkParts = explode(':', $legacyLink); - if (!isset($legacyParameters['controller'])) { - $legacyParameters['controller'] = $linkParts[0]; - } - if (!isset($legacyParameters['action']) && count($linkParts) > 1) { - $legacyParameters['action'] = $linkParts[1]; - } - if (isset($legacyParameters['controller'], $legacyParameters['action'])) { - break; - } - } - } - - return $legacyParameters; - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/LegacyRoute.php b/src/PrestaShopBundle/Routing/Converter/LegacyRoute.php deleted file mode 100644 index c98d4a8d..00000000 --- a/src/PrestaShopBundle/Routing/Converter/LegacyRoute.php +++ /dev/null @@ -1,178 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -/** - * Class LegacyRoute contains the info about a route, its legacyLinks, legacyParameters - * and controller actions hash map. This class can be built simply based on the routeDefaults - * parameters and its name. - */ -class LegacyRoute -{ - /** - * @var string - */ - private $routeName; - - /** - * @var array - */ - private $legacyLinks; - - /** - * @var array - */ - private $routeParameters; - - /** - * @var array - */ - private $controllersActions; - - /** - * @param string|null $action - * - * @return bool - */ - public static function isIndexAction($action) - { - $indexAliases = ['list', 'index']; - - return empty($action) || in_array(strtolower($action), $indexAliases); - } - - /** - * @param $routeName - * @param array $routeDefaults - * - * @return LegacyRoute - */ - public static function buildLegacyRoute($routeName, array $routeDefaults) - { - $legacyLinks = $routeDefaults['_legacy_link']; - if (!is_array($legacyLinks)) { - $legacyLinks = [$legacyLinks]; - } - - $legacyParameters = []; - if (!empty($routeDefaults['_legacy_parameters']) && is_array($routeDefaults['_legacy_parameters'])) { - $legacyParameters = $routeDefaults['_legacy_parameters']; - } - - return new static($routeName, $legacyLinks, $legacyParameters); - } - - /** - * LegacyRoute constructor. - * - * @param string $routeName - * @param array $legacyLinks - * @param array $routeParameters - */ - public function __construct($routeName, array $legacyLinks, array $routeParameters) - { - $this->routeName = $routeName; - $this->routeParameters = $routeParameters; - $this->legacyLinks = $this->buildLegacyLinks($legacyLinks); - $this->controllersActions = $this->buildControllerActions($this->legacyLinks, $routeName); - } - - /** - * @return string - */ - public function getRouteName() - { - return $this->routeName; - } - - /** - * @return array - */ - public function getLegacyLinks() - { - return $this->legacyLinks; - } - - /** - * @return array - */ - public function getRouteParameters() - { - return $this->routeParameters; - } - - /** - * @return array - */ - public function getControllersActions() - { - return $this->controllersActions; - } - - /** - * @param array $legacyLinks - * - * @return array - */ - private function buildLegacyLinks(array $legacyLinks) - { - $brokenLegacyLinks = []; - foreach ($legacyLinks as $legacyLink) { - $linkParts = explode(':', $legacyLink); - $legacyController = $linkParts[0]; - $legacyAction = isset($linkParts[1]) ? $linkParts[1] : null; - $brokenLegacyLinks[] = [ - 'controller' => $legacyController, - 'action' => $legacyAction, - ]; - } - - return $brokenLegacyLinks; - } - - /** - * @param array $legacyLinks - * @param string $routeName - * - * @return array - */ - private function buildControllerActions(array $legacyLinks, $routeName) - { - $controllersActions = []; - foreach ($legacyLinks as $legacyLink) { - $controller = $legacyLink['controller']; - if (!isset($controllersActions[$controller])) { - $controllersActions[$controller] = []; - } - - $action = self::isIndexAction($legacyLink['action']) ? 'index' : $legacyLink['action']; - $controllersActions[$controller][$action] = $routeName; - } - - return $controllersActions; - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/LegacyRouteProviderInterface.php b/src/PrestaShopBundle/Routing/Converter/LegacyRouteProviderInterface.php deleted file mode 100644 index 9d48ca59..00000000 --- a/src/PrestaShopBundle/Routing/Converter/LegacyRouteProviderInterface.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use PrestaShopBundle\Routing\Converter\Exception\RouteNotFoundException; - -/** - * Interface LegacyRouteProviderInterface is used by LegacyUrlConverter to fetch - * the information about legacy routes, stored in LegacyRoute objects. - */ -interface LegacyRouteProviderInterface -{ - /** - * Returns the list of LegacyRoute based on what was set in the routing files. - * - * @return LegacyRoute[] - */ - public function getLegacyRoutes(); - - /** - * Returns the list of controllers, their action and the associated route. - * e.g: $controllerActions = [ - * 'AdminPreferences' => [ - * 'index' => 'admin_preferences', - * 'update' => 'admin_preferences_save', - * ], - * 'AdminMeta' => [ - * 'index' => 'admin_metas_index', - * 'search' => 'admin_metas_search', - * ], - * ];. - * - * @return array - */ - public function getControllersActions(); - - /** - * Return the list of actions for a defined controller. - * - * @param string $controller - * - * @return string[] - */ - public function getActionsByController($controller); - - /** - * Return the LegacyRoute object matching $controller and $action. - * - * @param string $controller - * @param string $action - * - * @return LegacyRoute - * - * @throws RouteNotFoundException - */ - public function getLegacyRouteByAction($controller, $action); -} diff --git a/src/PrestaShopBundle/Routing/Converter/LegacyUrlConverter.php b/src/PrestaShopBundle/Routing/Converter/LegacyUrlConverter.php deleted file mode 100644 index 33ece2be..00000000 --- a/src/PrestaShopBundle/Routing/Converter/LegacyUrlConverter.php +++ /dev/null @@ -1,249 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use PrestaShopBundle\Routing\Converter\Exception\AlreadyConvertedException; -use PrestaShopBundle\Routing\Converter\Exception\ArgumentException; -use PrestaShopBundle\Routing\Converter\Exception\RouteNotFoundException; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Exception\Exceptioninterface; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Routing\RouterInterface; - -/** - * Class LegacyUrlConverter is able to convert query parameters or an url into a - * migrated Symfony url. It uses information set in the routes via _legacy_link - * to do so. - */ -final class LegacyUrlConverter -{ - /** - * @var LegacyRouteProviderInterface - */ - private $legacyRouteProvider; - - /** - * @var RouterInterface - */ - private $router; - - /** - * LegacyUrlConverter constructor. - * - * @param RouterInterface $router - * @param LegacyRouteProviderInterface $legacyRouteProvider - */ - public function __construct(RouterInterface $router, LegacyRouteProviderInterface $legacyRouteProvider) - { - $this->router = $router; - $this->legacyRouteProvider = $legacyRouteProvider; - } - - /** - * @param array $parameters - * - * @return string - * - * @throws ArgumentException - * @throws RouteNotFoundException - */ - public function convertByParameters(array $parameters) - { - //Tab parameter can be used as an alias for controller - if (!empty($parameters['tab'])) { - if (empty($parameters['controller'])) { - $parameters['controller'] = $parameters['tab']; - } - unset($parameters['tab']); - } - - if (empty($parameters['controller'])) { - throw new ArgumentException('Missing required controller argument'); - } - - /** @var LegacyRoute $legacyRoute */ - $legacyRoute = $this->findLegacyRouteNameByParameters($parameters); - $parameters = $this->convertLegacyParameters($parameters, $legacyRoute); - - return $this->router->generate($legacyRoute->getRouteName(), $parameters, UrlGeneratorInterface::ABSOLUTE_URL); - } - - /** - * @param string $url - * - * @return string - * - * @throws ArgumentException - * @throws RouteNotFoundException - * @throws AlreadyConvertedException - */ - public function convertByUrl($url) - { - $this->checkAlreadyMatchingRoute($url); - - $parsedUrl = parse_url($url); - $parameters = []; - if (isset($parsedUrl['query'])) { - parse_str($parsedUrl['query'], $parameters); - } - - return $this->convertByParameters($parameters); - } - - /** - * This conversion method is used by the listener, indeed it needs to update the - * router context because it is executed before the RouterListener. Thus the router - * does not have the appropriate information to generate an admin url and would redirect - * to the front office. - * - * @param Request $request - * - * @return string - * - * @throws ArgumentException - * @throws RouteNotFoundException - * @throws AlreadyConvertedException - */ - public function convertByRequest(Request $request) - { - $this->router->getContext()->fromRequest($request); - $this->checkAlreadyMatchingRoute($request->getRequestUri()); - - $parameters = array_merge($request->query->all(), $request->request->all()); - - return $this->convertByParameters($parameters); - } - - /** - * @param array $parameters - * @param LegacyRoute $legacyRoute - * - * @return array - */ - private function convertLegacyParameters(array $parameters, LegacyRoute $legacyRoute) - { - $legacyAction = $this->getActionFromParameters($parameters); - - foreach ($legacyRoute->getRouteParameters() as $legacyParameter => $parameter) { - if (isset($parameters[$legacyParameter])) { - $parameters[$parameter] = $parameters[$legacyParameter]; - unset($parameters[$legacyParameter]); - } - } - - unset( - $parameters['controller'], - $parameters['action'], - $parameters[$legacyAction] - ); - - return $parameters; - } - - /** - * @param array $parameters - * - * @return LegacyRoute - * - * @throws RouteNotFoundException - */ - private function findLegacyRouteNameByParameters(array $parameters) - { - $legacyController = $parameters['controller']; - $legacyAction = $this->getActionFromParameters($parameters); - - return $this->legacyRouteProvider->getLegacyRouteByAction($legacyController, $legacyAction); - } - - /** - * @param array $parameters - * - * @return string|null - */ - private function getActionFromParameters(array $parameters) - { - $legacyAction = null; - - if (!empty($parameters['action'])) { - $legacyAction = $parameters['action']; - } - - //Actions can be defined as simple query parameter (e.g: ?controller=AdminProducts&save) - if (null === $legacyAction) { - //We prioritize the actions defined in the migrated routes - $controllerActions = $this->legacyRouteProvider->getActionsByController($parameters['controller']); - foreach ($parameters as $parameter => $value) { - if (in_array($parameter, $controllerActions)) { - $legacyAction = $parameter; - - break; - } - } - } - - //Last chance if a non migrated action is present (note: a bit risky since any empty parameter can be - //interpreted as an action.. but some old link need this feature, ?controller=AdminModulesPositions&addToHook) - if (null === $legacyAction) { - foreach ($parameters as $parameter => $value) { - if ($value === '' || 1 === (int) $value) { - //Avoid confusing an entity/row id with an action - // e.g. - // create=1 is an action - // id_product=1 is NOT an action - if (false === strpos($parameter, 'id_') - && false === strpos($parameter, '_id')) { - $legacyAction = $parameter; - - break; - } - } - } - } - - return LegacyRoute::isIndexAction($legacyAction) ? 'index' : $legacyAction; - } - - /** - * We check that the router doesn't match the url, if no exception is thrown - * then the url is already converted and we throw our own AlreadyConvertedException - * - * @param string $url - * - * @throws AlreadyConvertedException - */ - private function checkAlreadyMatchingRoute($url) - { - try { - $urlPath = parse_url($url, PHP_URL_PATH); - if (!empty($urlPath)) { - $this->router->match($urlPath); - throw new AlreadyConvertedException(sprintf('%s is already a converted url', $url)); - } - } catch (ExceptionInterface $e) { - } - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/RouterProvider.php b/src/PrestaShopBundle/Routing/Converter/RouterProvider.php deleted file mode 100644 index 711dd6d1..00000000 --- a/src/PrestaShopBundle/Routing/Converter/RouterProvider.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouterInterface; - -/** - * Class RouterProvider. - */ -class RouterProvider extends AbstractLegacyRouteProvider -{ - /** - * @var LegacyRoute[] - */ - private $legacyRoutes; - - /** - * @var RouterInterface - */ - private $router; - - /** - * RouterProvider constructor. - * - * @param RouterInterface $router - */ - public function __construct(RouterInterface $router) - { - $this->router = $router; - } - - /** - * {@inheritdoc} - */ - public function getLegacyRoutes() - { - if (null == $this->legacyRoutes) { - $this->legacyRoutes = $this->buildLegacyRoutes(); - } - - return $this->legacyRoutes; - } - - /** - * @return array - */ - private function buildLegacyRoutes() - { - $legacyRoutes = []; - /** @var Route $route */ - foreach ($this->router->getRouteCollection() as $routeName => $route) { - $routeDefaults = $route->getDefaults(); - if (empty($routeDefaults['_legacy_link'])) { - continue; - } - - $legacyRoutes[$routeName] = LegacyRoute::buildLegacyRoute($routeName, $routeDefaults); - } - - return $legacyRoutes; - } -} diff --git a/src/PrestaShopBundle/Routing/Converter/RoutingCacheKeyGenerator.php b/src/PrestaShopBundle/Routing/Converter/RoutingCacheKeyGenerator.php deleted file mode 100644 index c97d48b1..00000000 --- a/src/PrestaShopBundle/Routing/Converter/RoutingCacheKeyGenerator.php +++ /dev/null @@ -1,134 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Converter; - -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; - -/** - * Class RoutingCacheKeyGenerator generates the cache key for the CacheProvider. - * In prod environment the key never changes so you need to use cache:clear if you - * need to update the cache. - * In dev environment this class inspects the routing files to get their last modification - * date which is then used to generate the key, hence each time a routing file is modified - * the cache key changes so the cache is regenerated. - */ -class RoutingCacheKeyGenerator implements CacheKeyGeneratorInterface -{ - /** - * @var array - */ - private $coreRoutingPaths; - - /** - * @var array - */ - private $activeModulesPaths; - - /** - * @var string - */ - private $environment; - - /** - * RoutingCacheKeyGenerator constructor. - * - * @param array $coreRoutingPaths - * @param array $activeModulesPaths - * @param string $environment - */ - public function __construct( - array $coreRoutingPaths, - array $activeModulesPaths, - $environment = 'dev' - ) { - $this->coreRoutingPaths = $coreRoutingPaths; - $this->activeModulesPaths = $activeModulesPaths; - $this->environment = $environment; - } - - /** - * @return array - */ - public function getLastModifications() - { - $routingFiles = []; - - if (count($this->coreRoutingPaths)) { - $finder = new Finder(); - $finder->files()->in($this->coreRoutingPaths); - $finder->name('/\.(yml|yaml)$/'); - /** @var SplFileInfo $yamlFile */ - foreach ($finder as $yamlFile) { - $routingFiles[$yamlFile->getPathname()] = $yamlFile->getMTime(); - } - } - - foreach ($this->activeModulesPaths as $modulePath) { - $extensions = ['yml', 'yaml']; - foreach ($extensions as $extension) { - $routingFile = $modulePath . '/config/routes.' . $extension; - if (file_exists($routingFile)) { - $routingFiles[$routingFile] = filemtime($routingFile); - } - } - } - - arsort($routingFiles); - - return $routingFiles; - } - - /** - * @return int|null - */ - public function getLatestModificationTime() - { - $lastModifications = $this->getLastModifications(); - if (!count($lastModifications)) { - return null; - } - - return reset($lastModifications); - } - - /** - * {@inheritdoc} - */ - public function getCacheKey() - { - $cacheKey = preg_replace('@\\\\@', '_', __NAMESPACE__); - if ('prod' !== $this->environment) { - $latestModification = $this->getLatestModificationTime(); - if (null !== $latestModification) { - $cacheKey .= '_' . $latestModification; - } - } - - return $cacheKey; - } -} diff --git a/src/PrestaShopBundle/Routing/Linter/AdminRouteProvider.php b/src/PrestaShopBundle/Routing/Linter/AdminRouteProvider.php deleted file mode 100644 index 98bd2f29..00000000 --- a/src/PrestaShopBundle/Routing/Linter/AdminRouteProvider.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter; - -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouterInterface; - -/** - * Get all configured routes for Back Office - */ -final class AdminRouteProvider -{ - /** - * @var RouterInterface - */ - private $router; - - /** - * @param RouterInterface $router - */ - public function __construct(RouterInterface $router) - { - $this->router = $router; - } - - /** - * @return Route[] As routeName => route - */ - public function getRoutes() - { - $adminRoutes = []; - - foreach ($this->router->getRouteCollection() as $routeName => $route) { - if (strpos($routeName, 'admin_') !== 0) { - continue; - } - - $adminRoutes[$routeName] = $route; - } - - return $adminRoutes; - } -} diff --git a/src/PrestaShopBundle/Routing/Linter/Exception/LinterException.php b/src/PrestaShopBundle/Routing/Linter/Exception/LinterException.php deleted file mode 100644 index 9ea0d0c8..00000000 --- a/src/PrestaShopBundle/Routing/Linter/Exception/LinterException.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter\Exception; - -use RuntimeException; - -/** - * Is thrown when error occurs during linting. - */ -class LinterException extends RuntimeException -{ -} diff --git a/src/PrestaShopBundle/Routing/Linter/Exception/NamingConventionException.php b/src/PrestaShopBundle/Routing/Linter/Exception/NamingConventionException.php deleted file mode 100644 index 4b7b9eff..00000000 --- a/src/PrestaShopBundle/Routing/Linter/Exception/NamingConventionException.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter\Exception; - -/** - * Thrown when naming convention is not followed - */ -class NamingConventionException extends LinterException -{ - /** - * @var string - */ - protected $expectedRouteName; - - public function __construct($message = '', $code = 0, \RuntimeException $previous = null, $expectedRouteName = null) - { - $this->expectedRouteName = $expectedRouteName; - parent::__construct($message, $code, $previous); - } - - /** - * @return string - */ - public function getExpectedRouteName(): string - { - return $this->expectedRouteName; - } -} diff --git a/src/PrestaShopBundle/Routing/Linter/LegacyLinkLinter.php b/src/PrestaShopBundle/Routing/Linter/LegacyLinkLinter.php deleted file mode 100644 index 49b79f88..00000000 --- a/src/PrestaShopBundle/Routing/Linter/LegacyLinkLinter.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter; - -use Symfony\Component\Routing\Route; - -/** - * Responsible for checking route _legacy_link configuration - */ -final class LegacyLinkLinter implements RouteLinterInterface -{ - /** - * Checks if _legacy_link is configured to route. - * Returns true if configured, false if not. - * - * {@inheritdoc} - */ - public function lint($routeName, Route $route) - { - if ($route->hasDefault($routeName)) { - return true; - } - - return false; - } -} diff --git a/src/PrestaShopBundle/Routing/Linter/NamingConventionLinter.php b/src/PrestaShopBundle/Routing/Linter/NamingConventionLinter.php deleted file mode 100644 index 144ce1a4..00000000 --- a/src/PrestaShopBundle/Routing/Linter/NamingConventionLinter.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter; - -use Doctrine\Common\Inflector\Inflector; -use PrestaShopBundle\Routing\Linter\Exception\NamingConventionException; -use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; -use Symfony\Component\Routing\Route; - -/** - * Checks that route and contoller follows naming conventions - */ -final class NamingConventionLinter implements RouteLinterInterface -{ - /** - * @var ControllerNameParser - */ - private $controllerNameParser; - - /** - * @param ControllerNameParser $controllerNameParser - */ - public function __construct(ControllerNameParser $controllerNameParser) - { - $this->controllerNameParser = $controllerNameParser; - } - - /** - * {@inheritdoc} - */ - public function lint($routeName, Route $route) - { - $controllerAndMethodName = $this->getControllerAndMethodName($route); - - $pluralizedController = Inflector::tableize( - Inflector::pluralize($controllerAndMethodName['controller']) - ); - - $expectedRouteName = strtr('admin_{resources}_{action}', [ - '{resources}' => $pluralizedController, - '{action}' => Inflector::tableize($controllerAndMethodName['method']), - ]); - - if ($routeName !== $expectedRouteName) { - throw new NamingConventionException( - sprintf('Route "%s" does not follow naming convention.', $routeName), - 0, - null, - $expectedRouteName - ); - } - } - - /** - * @param Route $route - * - * @return array - */ - private function getControllerAndMethodName(Route $route) - { - $controller = $route->getDefault('_controller'); - - if (strpos($controller, '::') === false) { - $controller = $this->controllerNameParser->parse($controller); - } - - list($controller, $method) = explode('::', $controller, 2); - - $controllerParts = explode('\\', $controller); - $controller = preg_replace('/Controller$/', '', end($controllerParts)); - - $method = preg_replace('/Action$/', '', $method); - - return [ - 'controller' => $controller, - 'method' => $method, - ]; - } -} diff --git a/src/PrestaShopBundle/Routing/Linter/RouteLinterInterface.php b/src/PrestaShopBundle/Routing/Linter/RouteLinterInterface.php deleted file mode 100644 index e99e6254..00000000 --- a/src/PrestaShopBundle/Routing/Linter/RouteLinterInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter; - -use PrestaShopBundle\Routing\Linter\Exception\LinterException; -use Symfony\Component\Routing\Route; - -/** - * Interface for service that performs linting on route - */ -interface RouteLinterInterface -{ - /** - * @param Route $route - * - * @throws LinterException when linting error occurs - */ - public function lint($routeName, Route $route); -} diff --git a/src/PrestaShopBundle/Routing/Linter/SecurityAnnotationLinter.php b/src/PrestaShopBundle/Routing/Linter/SecurityAnnotationLinter.php deleted file mode 100644 index a8c59277..00000000 --- a/src/PrestaShopBundle/Routing/Linter/SecurityAnnotationLinter.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing\Linter; - -use Doctrine\Common\Annotations\Reader; -use PrestaShopBundle\Routing\Linter\Exception\LinterException; -use PrestaShopBundle\Security\Annotation\AdminSecurity; -use ReflectionMethod; -use Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser; -use Symfony\Component\Routing\Route; - -/** - * Checks if SecurityAnnotation is configured for route's controller action - */ -final class SecurityAnnotationLinter implements RouteLinterInterface -{ - /** - * @var Reader - */ - private $annotationReader; - - /** - * @var ControllerNameParser - */ - private $controllerNameParser; - - /** - * @param Reader $annotationReader - * @param ControllerNameParser $controllerNameParser - */ - public function __construct(Reader $annotationReader, ControllerNameParser $controllerNameParser) - { - $this->annotationReader = $annotationReader; - $this->controllerNameParser = $controllerNameParser; - } - - /** - * {@inheritdoc} - */ - public function lint($routeName, Route $route) - { - $controllerAndMethod = $this->extractControllerAndMethodNamesFromRoute($route); - - $reflection = new ReflectionMethod( - $controllerAndMethod['controller'], - $controllerAndMethod['method'] - ); - - $annotation = $this->annotationReader->getMethodAnnotation($reflection, AdminSecurity::class); - - if (null === $annotation) { - throw new LinterException(sprintf('"%s:%s" does not have AdminSecurity annotation configured', $controllerAndMethod['controller'], $controllerAndMethod['method'])); - } - } - - /** - * @param Route $route - * - * @return array - */ - private function extractControllerAndMethodNamesFromRoute(Route $route) - { - $controller = $route->getDefault('_controller'); - - if (strpos($controller, '::') === false) { - // we need to support controllers defined as services & defined using short notation - $controller = $this->controllerNameParser->parse($controller); - } - - list($controller, $method) = explode('::', $controller, 2); - - return [ - 'controller' => $controller, - 'method' => $method, - ]; - } -} diff --git a/src/PrestaShopBundle/Routing/YamlModuleLoader.php b/src/PrestaShopBundle/Routing/YamlModuleLoader.php deleted file mode 100644 index c3fa1e64..00000000 --- a/src/PrestaShopBundle/Routing/YamlModuleLoader.php +++ /dev/null @@ -1,113 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Routing; - -use RuntimeException; -use Symfony\Component\Config\Loader\Loader; -use Symfony\Component\Routing\Route; -use Symfony\Component\Routing\RouteCollection; - -/** - * This class is responsible of loading routes of enabled modules. - */ -class YamlModuleLoader extends Loader -{ - /** - * @var array the list of activated modules - */ - private $activeModulesPaths; - - /** - * @var bool we load the route collection only once per request - */ - private $isLoaded = false; - - public function __construct(array $activeModulesPaths) - { - $this->activeModulesPaths = $activeModulesPaths; - } - - /** - * {@inheritdoc} - */ - public function load($resource, $type = null) - { - if (true === $this->isLoaded) { - throw new RuntimeException('Do not add the "module" loader twice.'); - } - - $routes = new RouteCollection(); - - foreach ($this->activeModulesPaths as $modulePath) { - $routingFile = $modulePath . '/config/routes.yml'; - if (file_exists($routingFile)) { - $loadedRoutes = $this->import($routingFile, 'yaml'); - $routes->addCollection($loadedRoutes); - } - } - - $this->isLoaded = true; - - return $routes; - } - - /** - * {@inheritdoc} - */ - public function supports($resource, $type = null) - { - return 'module' === $type; - } - - /** - * {@inheritdoc} - */ - public function import($resource, $type = null) - { - $loadedRoutes = parent::import($resource, $type); - - return $this->modifyRoutes($loadedRoutes); - } - - /** - * @param RouteCollection $routes - * - * @return RouteCollection - */ - private function modifyRoutes(RouteCollection $routes) - { - foreach ($routes->getIterator() as $route) { - if ($route->hasDefault('_disable_module_prefix') && $route->getDefault('_disable_module_prefix') === true) { - continue; - } - - $route->setPath('/modules' . $route->getPath()); - } - - return $routes; - } -} diff --git a/src/PrestaShopBundle/Security/Admin/Employee.php b/src/PrestaShopBundle/Security/Admin/Employee.php deleted file mode 100644 index fd8af08e..00000000 --- a/src/PrestaShopBundle/Security/Admin/Employee.php +++ /dev/null @@ -1,190 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Admin; - -use Symfony\Component\Security\Core\User\EquatableInterface; -use Symfony\Component\Security\Core\User\UserInterface; - -/** - * Class Employee is used for Symfony security components to authenticate the user. - */ -class Employee implements UserInterface, EquatableInterface -{ - /** - * @var int - */ - private $id; - - /** - * @var string - */ - private $username; - - /** - * @var string - */ - private $password; - - /** - * @var string - */ - private $salt; - - /** - * @var array - */ - private $roles = []; - - private $data; - - /** - * Constructor. - * - * @param object $data The employee legacy object - */ - public function __construct($data) - { - $this->username = $data->email; - $this->password = $data->passwd; - $this->salt = ''; - $this->data = $data; - $this->id = (int) $data->id; - } - - public function __toString() - { - return $this->username; - } - - /** - * Returns roles for the current employee. - * - * @return array - */ - public function getRoles() - { - return $this->roles; - } - - /** - * Get typed password. - * - * @return string - */ - public function getPassword() - { - return $this->password; - } - - /** - * The salt used to hash the password. - * - * @return string - */ - public function getSalt() - { - return $this->salt; - } - - /** - * Get the login of the current employee. - * - * @return string - */ - public function getUsername() - { - return $this->username; - } - - /** - * Get the id of the current employee. - * - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * Get the data parameter of the current employee. - * - * @return object - */ - public function getData() - { - return $this->data; - } - - /** - * Used by Symfony to ensure credentials are removed when logout. - */ - public function eraseCredentials() - { - } - - /** - * @param array $roles - * - * @return Employee - */ - public function setRoles(array $roles) - { - $this->roles = $roles; - - return $this; - } - - /** - * Test equality between two Employee entities - * (instance of class, password, salt and username). - * - * @param UserInterface $user - * - * @return bool - */ - public function isEqualTo(UserInterface $user) - { - if (!$user instanceof static) { - return false; - } - - if ($this->password !== $user->getPassword()) { - return false; - } - - if ($this->salt !== $user->getSalt()) { - return false; - } - - if ($this->username !== $user->getUsername()) { - return false; - } - - return true; - } -} diff --git a/src/PrestaShopBundle/Security/Admin/EmployeeProvider.php b/src/PrestaShopBundle/Security/Admin/EmployeeProvider.php deleted file mode 100644 index 1a30744f..00000000 --- a/src/PrestaShopBundle/Security/Admin/EmployeeProvider.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Admin; - -use Access; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Security\Core\Exception\UnsupportedUserException; -use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; - -/** - * Class EmployeeProvider To retrieve Employee entities for the Symfony security components. - */ -class EmployeeProvider implements UserProviderInterface -{ - const ROLE_EMPLOYEE = 'ROLE_EMPLOYEE'; - - private $legacyContext; - - /** - * @var CacheItemPoolInterface - */ - private $cache; - - public function __construct(LegacyContext $context, CacheItemPoolInterface $cache) - { - $this->legacyContext = $context->getContext(); - $this->cache = $cache; - } - - /** - * Fetch the Employee entity that matches the given username. - * Cache system doesn't supports "@" character, so we rely on a sha1 expression. - * - * @param string $username - * - * @return Employee - * - * @throws \Psr\Cache\InvalidArgumentException - * @throws \Symfony\Component\Security\Core\Exception\UsernameNotFoundException - */ - public function loadUserByUsername($username) - { - $cacheKey = sha1($username); - $cachedEmployee = $this->cache->getItem("app.employees_${cacheKey}"); - - if ($cachedEmployee->isHit()) { - return $cachedEmployee->get(); - } - - if ( - null !== $this->legacyContext->employee - && $this->legacyContext->employee->email === $username - ) { - $employee = new Employee($this->legacyContext->employee); - $employee->setRoles( - array_merge([self::ROLE_EMPLOYEE], Access::getRoles($this->legacyContext->employee->id_profile)) - ); - - $cachedEmployee->set($employee); - $this->cache->save($cachedEmployee); - - return $cachedEmployee->get(); - } - - throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username)); - } - - /** - * Reload an Employee and returns a fresh instance. - * - * @param UserInterface $employee - * - * @return Employee - */ - public function refreshUser(UserInterface $employee) - { - if (!$employee instanceof Employee) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($employee))); - } - - return $this->loadUserByUsername($employee->getUsername()); - } - - /** - * Tests if the given class supports the security layer. Here, only Employee class is allowed to be used to authenticate. - * - * @param string $class - * - * @return bool - */ - public function supportsClass($class) - { - return $class === 'PrestaShopBundle\Security\Admin\Employee'; - } -} diff --git a/src/PrestaShopBundle/Security/Annotation/AdminSecurity.php b/src/PrestaShopBundle/Security/Annotation/AdminSecurity.php deleted file mode 100644 index 4e584a19..00000000 --- a/src/PrestaShopBundle/Security/Annotation/AdminSecurity.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Annotation; - -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; - -/** - * Improves the existing Security annotation, adding: - * `domain`: to translate the sent message using a PrestaShop domain; - * `redirectRoute`: to select the route for redirection; - * `url`: only available in 1.7.x, to redirect to legacy pages;. - * - * @Annotation - */ -class AdminSecurity extends Security -{ - /** - * The translation domain for the message. - * - * @var string - */ - protected $domain = 'Admin.Notifications.Error'; - - /** - * The route for the redirection. - * - * @todo: Once the onboarding page is migrated, set default to his route name. - * - * @var string - */ - protected $redirectRoute; - - /** - * @deprecated once the back office is migrated, rely only on route. - * The url for the redirection - * - * @return string - */ - protected $url = 'admin_domain'; - - /** - * The route params which are used together to generate the redirect route. - * - * @var array - */ - protected $redirectQueryParamsToKeep = []; - - /** - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * @param string $domain the translation domain name - */ - public function setDomain($domain) - { - $this->domain = $domain; - } - - /** - * @return string - */ - public function getRedirectRoute() - { - return $this->redirectRoute; - } - - /** - * @param string $redirectRoute the route used for redirection - */ - public function setRedirectRoute($redirectRoute) - { - $this->redirectRoute = $redirectRoute; - } - - /** - * @return mixed - */ - public function getUrl() - { - return $this->url; - } - - /** - * @param string $url the url used for redirection - */ - public function setUrl($url) - { - $this->url = $url; - } - - /** - * @return array - */ - public function getRedirectQueryParamsToKeep() - { - return $this->redirectQueryParamsToKeep; - } - - /** - * @param array $redirectQueryParamsToKeep - */ - public function setRedirectQueryParamsToKeep($redirectQueryParamsToKeep) - { - $this->redirectQueryParamsToKeep = $redirectQueryParamsToKeep; - } -} diff --git a/src/PrestaShopBundle/Security/Annotation/DemoRestricted.php b/src/PrestaShopBundle/Security/Annotation/DemoRestricted.php deleted file mode 100644 index 70303a9c..00000000 --- a/src/PrestaShopBundle/Security/Annotation/DemoRestricted.php +++ /dev/null @@ -1,149 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Annotation; - -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation; - -/** - * Forbid access to the page if Demonstration mode is enabled. - * - * @Annotation - */ -class DemoRestricted extends ConfigurationAnnotation -{ - /** - * The translation domain for the message. - * - * @var string - */ - protected $domain = 'Admin.Notifications.Error'; - - /** - * The message of the exception. - * - * @var string - */ - protected $message = 'This functionality has been disabled.'; - - /** - * The route for the redirection. - * - * @var string - */ - protected $redirectRoute; - - /** - * The route params which are used together to generate the redirect route. - * - * @var array - */ - protected $redirectQueryParamsToKeep = []; - - /** - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * @param string $domain the translation domain name - */ - public function setDomain($domain) - { - $this->domain = $domain; - } - - /** - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * @param string $message the message displayed after redirection - */ - public function setMessage($message) - { - $this->message = $message; - } - - /** - * @return string - */ - public function getRedirectRoute() - { - return $this->redirectRoute; - } - - /** - * @param string $redirectRoute the route used for redirection - */ - public function setRedirectRoute($redirectRoute) - { - $this->redirectRoute = $redirectRoute; - } - - /** - * Returns the alias name for an annotated configuration. - * - * @return string - */ - public function getAliasName() - { - return 'demo_restricted'; - } - - /** - * Returns whether multiple annotations of this type are allowed. - * - * @return bool - */ - public function allowArray() - { - return true; - } - - /** - * @return array - */ - public function getRedirectQueryParamsToKeep() - { - return $this->redirectQueryParamsToKeep; - } - - /** - * @param array $redirectQueryParamsToKeep - */ - public function setRedirectQueryParamsToKeep($redirectQueryParamsToKeep) - { - $this->redirectQueryParamsToKeep = $redirectQueryParamsToKeep; - } -} diff --git a/src/PrestaShopBundle/Security/Annotation/ModuleActivated.php b/src/PrestaShopBundle/Security/Annotation/ModuleActivated.php deleted file mode 100644 index 55f99457..00000000 --- a/src/PrestaShopBundle/Security/Annotation/ModuleActivated.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Annotation; - -use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationAnnotation; - -/** - * Forbid access to the page if the defined module mode is inactive. - * - * @Annotation - */ -class ModuleActivated extends ConfigurationAnnotation -{ - /** - * The translation domain for the message. - * - * @var string - */ - protected $domain = 'Admin.Notifications.Error'; - - /** - * The message of the exception. - * - * @var string - */ - protected $message = 'The module %s is inactive.'; - - /** - * The route for the redirection. - * - * @var string - */ - protected $redirectRoute; - - /** - * The module name to check. - * - * @var string - */ - protected $moduleName; - - /** - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * @param string $domain the translation domain name - */ - public function setDomain($domain) - { - $this->domain = $domain; - } - - /** - * @return string - */ - public function getMessage() - { - return $this->message; - } - - /** - * @param string $message the message displayed after redirection - */ - public function setMessage($message) - { - $this->message = $message; - } - - /** - * @return string - */ - public function getRedirectRoute() - { - return $this->redirectRoute; - } - - /** - * @param string $redirectRoute the route used for redirection - */ - public function setRedirectRoute($redirectRoute) - { - $this->redirectRoute = $redirectRoute; - } - - /** - * Returns the alias name for an annotated configuration. - * - * @return string - */ - public function getAliasName() - { - return 'module_activated'; - } - - /** - * Returns the name of the module to check. - * - * @return string - */ - public function getModuleName() - { - return $this->moduleName; - } - - /** - * @param string $moduleName - */ - public function setModuleName($moduleName) - { - $this->moduleName = $moduleName; - } - - /** - * Returns whether multiple annotations of this type are allowed. - * - * @return bool - */ - public function allowArray() - { - return true; - } -} diff --git a/src/PrestaShopBundle/Security/Role/DynamicRoleHierarchy.php b/src/PrestaShopBundle/Security/Role/DynamicRoleHierarchy.php deleted file mode 100644 index a06b57e8..00000000 --- a/src/PrestaShopBundle/Security/Role/DynamicRoleHierarchy.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Role; - -use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; - -/** - * Class DynamicRoleHierarchy is used for Symfony role hierarchy voter to load roles from database. - */ -class DynamicRoleHierarchy implements RoleHierarchyInterface -{ - public function getReachableRoles(array $roles) - { - } -} diff --git a/src/PrestaShopBundle/Security/Voter/PageVoter.php b/src/PrestaShopBundle/Security/Voter/PageVoter.php deleted file mode 100644 index e0281cb2..00000000 --- a/src/PrestaShopBundle/Security/Voter/PageVoter.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Security\Voter; - -use Access; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Authorization\Voter\Voter; - -/** - * Decides on access rights to a Page. - */ -class PageVoter extends Voter -{ - const CREATE = 'create'; - - const UPDATE = 'update'; - - const DELETE = 'delete'; - - const READ = 'read'; - - const LEVEL_DELETE = 4; - - const LEVEL_UPDATE = 2; - - const LEVEL_CREATE = 3; - - const LEVEL_READ = 1; - - /** - * Indicates if this voter should pronounce on this attribute and subject. - * - * @param string $attribute Rights to test - * @param mixed $subject Subject to secure (a controller name) - * - * @return bool - */ - protected function supports($attribute, $subject) - { - return in_array($attribute, [self::CREATE, self::UPDATE, self::DELETE, self::READ]); - } - - /** - * @param string $attribute Access right to test - * @param string $subject Controller name - * @param TokenInterface $token - * - * @return bool - */ - protected function voteOnAttribute($attribute, $subject, TokenInterface $token) - { - $user = $token->getUser(); - $employeeProfileId = $user->getData()->id_profile; - $action = $this->buildAction($subject, $attribute); - - return $this->can($action, $employeeProfileId); - } - - /** - * Checks if the provided user profile is allowed to perform the requested action. - * - * @param string $action - * @param int $employeeProfileId - * - * @return bool - * - * @throws \Exception - */ - protected function can($action, $employeeProfileId) - { - return Access::isGranted('ROLE_MOD_TAB_' . strtoupper($action), $employeeProfileId); - } - - /** - * Builds the action name by joining subject and attribute. - * - * @param string $subject Subject the attribute is performed onto (usually a controller name) - * @param string $attribute - * - * @return string - */ - private function buildAction($subject, $attribute) - { - $action = $subject; - - // add underscore to join if needed - if (substr($action, -1) !== '_') { - $action .= '_'; - } - - return $action . $attribute; - } -} diff --git a/src/PrestaShopBundle/Service/Cache/Refresh.php b/src/PrestaShopBundle/Service/Cache/Refresh.php deleted file mode 100644 index c9c74574..00000000 --- a/src/PrestaShopBundle/Service/Cache/Refresh.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Cache; - -use PrestaShopBundle\Service\Command\AbstractCommand; - -class Refresh extends AbstractCommand -{ - /** - * Add doctrine:schema:update to the execution. - */ - public function addDoctrineSchemaUpdate() - { - $this->addCacheClear(); - - $this->commands[] = [ - 'command' => 'doctrine:schema:update', - '--force' => true, - ]; - } -} diff --git a/src/PrestaShopBundle/Service/Command/AbstractCommand.php b/src/PrestaShopBundle/Service/Command/AbstractCommand.php deleted file mode 100644 index b61242cb..00000000 --- a/src/PrestaShopBundle/Service/Command/AbstractCommand.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Command; - -use AppKernel; -use Exception; -use Symfony\Bundle\FrameworkBundle\Console\Application; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\BufferedOutput; - -abstract class AbstractCommand -{ - protected $kernel; - protected $application; - protected $commands = []; - - /** - * Constructor. - * - * Construct the symfony environment. - * - * @param AppKernel $kernel Symfony Kernel - */ - public function __construct(AppKernel $kernel = null) - { - set_time_limit(0); - - if (null === $kernel) { - global $kernel; - - if (null === $kernel) { - require_once _PS_ROOT_DIR_ . '/app/AppKernel.php'; - $kernel = new AppKernel(_PS_ENV_, _PS_MODE_DEV_); - } - } - - $this->kernel = $kernel; - $this->application = new Application($this->kernel); - $this->application->setAutoExit(false); - } - - /** - * Execute all defined commands. - * - * @throws Exception if no command defined - */ - public function execute() - { - $bufferedOutput = new BufferedOutput(); - $commandOutput = []; - - if (empty($this->commands)) { - throw new Exception('Error, you need to define at least one command'); - } - - foreach ($this->commands as $command) { - $exitCode = $this->application->run(new ArrayInput($command), $bufferedOutput); - - $commandOutput[$command['command']] = [ - 'exitCode' => $exitCode, - 'output' => $bufferedOutput->fetch(), - ]; - } - - return $commandOutput; - } - - /** - * Add cache:clear to the execution. - */ - public function addCacheClear() - { - $this->commands[] = [ - 'command' => 'doctrine:cache:clear-metadata', - '--flush' => true, - ]; - - $this->commands[] = [ - 'command' => 'doctrine:cache:clear-query', - '--flush' => true, - ]; - - $this->commands[] = [ - 'command' => 'doctrine:cache:clear-result', - '--flush' => true, - ]; - - $this->commands[] = [ - 'command' => 'cache:clear', - '--no-warmup' => true, - ]; - } -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Admin/AddonsInterface.php b/src/PrestaShopBundle/Service/DataProvider/Admin/AddonsInterface.php deleted file mode 100644 index 8e72870e..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Admin/AddonsInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Admin; - -/** - * Data provider for new Architecture, about Module object model. - * - * This class will provide data from DB / ORM about Modules for the Admin interface. - */ -interface AddonsInterface -{ - /** - * Send a request to addons.prestashop.com to retrieve Modules/Addons data. - * - * @param string $action the query type - * @param array $params the request parameters - */ - public function request($action, $params); -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php b/src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php deleted file mode 100644 index 0a5a5a4c..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Admin/CategoriesProvider.php +++ /dev/null @@ -1,247 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Admin; - -use PrestaShop\PrestaShop\Adapter\Module\Module as ApiModule; -use stdClass; - -/** - * Provide the categories used to order modules and themes on https://addons.prestashop.com. - */ -class CategoriesProvider -{ - const CATEGORY_OTHER = 'other'; - const CATEGORY_OTHER_NAME = 'Other'; - - const CATEGORY_THEME = 'theme_modules'; - const CATEGORY_THEME_NAME = 'Theme modules'; - - /** - * @var array - */ - private $modulesTheme; - - /** - * @var array - */ - private $categories; - - /** - * @var array - */ - private $categoriesFromSource; - - public function __construct(array $addonsCategories, array $modulesTheme) - { - $this->modulesTheme = $modulesTheme; - // We now avoid calling the API. This data is loaded from a local YML file - $this->categoriesFromSource = $this->sortCategories($addonsCategories); - } - - /** - * Return the list of categories with the associated modules. - * - * @param array|AddonsCollection the list of modules - * - * @return array the list of categories - */ - public function getCategoriesMenu($modules): array - { - if (null === $this->categories) { - // The Root category is "Categories" - $categories = $this->initializeCategories($this->categoriesFromSource); - foreach ($modules as $module) { - $category = $this->findModuleCategory($module, $categories); - - $categories['categories']->subMenu[$category]->modules[] = $module; - } - - // Clear custom categories if there is no module inside - if (empty($categories['categories']->subMenu[self::CATEGORY_THEME]->modules)) { - unset($categories['categories']->subMenu[self::CATEGORY_THEME]); - } - - $this->categories = $categories; - } - - return $this->categories; - } - - /** - * Initialize categories from API or if this one is empty, - * use theme and my modules categories. - * - * @param array|stdClass $categoriesListing Category listing - * - * @return array - */ - private function initializeCategories($categoriesListing) - { - $categories = [ - 'categories' => $this->createMenuObject('categories', 'Categories'), - ]; - - foreach ($categoriesListing as $category) { - $categories['categories']->subMenu[$category->name] = $this->createMenuObject( - $category->id_category, - $category->name, - [], - isset($category->tab) ? $category->tab : null - ); - } - - $categories['categories']->subMenu[self::CATEGORY_THEME] = $this->createMenuObject( - self::CATEGORY_THEME, - self::CATEGORY_THEME_NAME, - [], - self::CATEGORY_THEME - ); - $categories['categories']->subMenu[self::CATEGORY_OTHER] = $this->createMenuObject( - self::CATEGORY_OTHER, - self::CATEGORY_OTHER_NAME, - [], - self::CATEGORY_OTHER - ); - - return $categories; - } - - /** - * Considering a category name, return his category parent name. - * - * @param string the category - * - * @return string the category - */ - public function getParentCategory(string $categoryName): string - { - foreach ($this->categoriesFromSource as $parentCategory) { - foreach ($parentCategory->categories as $childCategory) { - if ($childCategory->name === $categoryName) { - return $parentCategory->name; - } - } - } - - return $categoryName; - } - - /** - * Re-organize category data into a Menu item. - * - * @param string $menu - * @param string $name - * @param array $moduleIds - * @param string $tab - * - * @return stdClass - */ - private function createMenuObject(string $menu, string $name, array $moduleIds = [], ?string $tab = null): stdClass - { - return (object) [ - 'tab' => $tab, - 'name' => $name, - 'refMenu' => $menu, - 'modules' => $moduleIds, - 'subMenu' => [], - ]; - } - - /** - * Find module category. - * - * @param ApiModule $installedProduct Installed product - * @param array $categories Available categories - */ - private function findModuleCategory(ApiModule $installedProduct, array $categories): string - { - $moduleCategoryParent = $installedProduct->attributes->get('categoryParentEnglishName'); - if (!isset($categories['categories']->subMenu[$moduleCategoryParent])) { - if (in_array($installedProduct->attributes->get('name'), $this->modulesTheme)) { - $moduleCategoryParent = self::CATEGORY_THEME; - } else { - $moduleCategoryParent = $this->getParentCategoryFromTabAttribute($installedProduct); - } - } - - if (array_key_exists($moduleCategoryParent, $categories['categories']->subMenu)) { - return $moduleCategoryParent; - } - - return self::CATEGORY_OTHER; - } - - /** - * Sort addons categories by order field. - * - * @param array $categories - * - * @return stdClass - */ - private function sortCategories(array $categories): stdClass - { - uasort( - $categories, - function ($a, $b) { - $a = !isset($a['order']) ? 0 : $a['order']; - $b = !isset($b['order']) ? 0 : $b['order']; - - if ($a === $b) { - return 0; - } - - return ($a < $b) ? -1 : 1; - } - ); - - // Convert array to object to be consistent with current API call - $categories = json_decode(json_encode($categories)); - - return $categories; - } - - /** - * Try to find the parent category depending on - * the module's tab attribute. - * - * @param ApiModule $module - * - * @return ?string - */ - private function getParentCategoryFromTabAttribute(ApiModule $module): ?string - { - foreach ($this->categoriesFromSource as $parentCategory) { - foreach ($parentCategory->categories as $category) { - if (isset($category->tab) && $category->tab === $module->attributes->get('tab')) { - return $parentCategory->name; - } - } - } - - return null; - } -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Admin/ModuleInterface.php b/src/PrestaShopBundle/Service/DataProvider/Admin/ModuleInterface.php deleted file mode 100644 index ae36d001..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Admin/ModuleInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Admin; - -/** - * Data provider for new Architecture, about Module object model. - * - * This class will provide data from DB / ORM about Modules for the Admin interface. - */ -interface ModuleInterface -{ - /** - * Return all module entities coming from DB. - * - * @return array|bool - */ - public function getAllModules(); -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Admin/ProductInterface.php b/src/PrestaShopBundle/Service/DataProvider/Admin/ProductInterface.php deleted file mode 100644 index 6a775e22..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Admin/ProductInterface.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Admin; - -/** - * Data provider for new Architecture, about Product object model. - * - * This class will provide data from DB / ORM about Products for the Admin interface. - */ -interface ProductInterface -{ - /** - * Will retrieve set of parameters from persistence, for product filters. - * - * @return string[] The old filter parameters values - */ - public function getPersistedFilterParameters(); - - /** - * Is there a specific category selected to filter product? - * - * @return bool true if a category is selected - */ - public function isCategoryFiltered(); - - /** - * Is there any column filter value? - * - * A filter with empty string '' is considered as not filtering, but 0 or '0' is a filter value! - * - * @return bool True if at least one column is filtered (except categories) - */ - public function isColumnFiltered(); - - /** - * Will persist set of parameters for product filters. - * - * @param string[] $parameters - */ - public function persistFilterParameters(array $parameters); - - /** - * Combines new filter values with old ones (persisted), then persists the combination and returns it. - * - * @param string[]|null $paramsIn New filter params values to take into account. If not given, the method will simply return persisted values. - * @param bool $avoidPersistence true to avoid persisting these preferences (for an export for example) - * - * @return string[] The new filter params values - */ - public function combinePersistentCatalogProductFilter($paramsIn = [], $avoidPersistence = false); - - /** - * Returns a collection of products, using default language, currency and others, from Context. - * - * @param int|string $offset an offset, or the 'last' token - * @param int|string $limit a limit, or the 'last' token - * @param string $orderBy Field name to sort during SQL query - * @param string $sortOrder 'asc' or 'desc' - * @param string[] $post filter params values to take into acount (often comes from POST data) - * @param bool $avoidPersistence True to avoid persisting these preferences (for an export for example) - * @param bool $formatCldr False to avoid CLDR formatting (heavy memory usage) - * - * @return array[mixed[]] A list of products, as an array of arrays of raw data - */ - public function getCatalogProductList($offset, $limit, $orderBy, $sortOrder, $post = [], $avoidPersistence = false, $formatCldr = true); - - /** - * Retrieve global product count (for the current shop). - * - * No filtering/limit/offset is applied to give this count. - * - * @return int The product count on the current shop - */ - public function countAllProducts(); - - /** - * Because pagination is tied to memory available on the server side, the choices can vary from one to another platform, - * depending on the memory_limit allocated to PHP. - * This will return Elements per page that are recommended to fetch products on the Admin catalog page. - * - * @return array[int] A list of pagination limits to show in the select dropbox in paginator component - */ - public function getPaginationLimitChoices(); - - /** - * Returns the last SQL query that was compiled on this Provider. - * - * @return string The last SQL query that was compiled with $this->compileSqlQuery() - */ - public function getLastCompiledSql(); - - /** - * Returns default activation state for new product. - * - * Duplication process could be different since duplicated product is always deactivated after duplication. - * - * @return bool true if a newly created product should be activated by default - */ - public function isNewProductDefaultActivated(); -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Admin/RecommendedModules.php b/src/PrestaShopBundle/Service/DataProvider/Admin/RecommendedModules.php deleted file mode 100644 index d9185a7d..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Admin/RecommendedModules.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Admin; - -use Module; -use Symfony\Component\Routing\Router; - -/** - * Data provider for new Architecture, about recommended modules. - * - * This class will provide modules data from Add-ons API depending on the domain to display recommended modules. - */ -class RecommendedModules -{ - /** - * @var Router - */ - private $router; - - /** - * Constructor. - * - * Dependency injection will give the required services. - * - * @param Router $router - */ - public function __construct(Router $router) - { - $this->router = $router; - } - - /** - * Gets all recommended modules for a specific domain. - * - * @param string $domain The given domain to filter recommended modules - * @param bool|false $randomize To shuffle results - * - * @return array A list of modules names (identifiers) - */ - public function getRecommendedModuleIdList($domain = 'administration', $randomize = false) - { - // FIXME: replace static by dynamic call from add-ons when available - switch ($domain) { - case 'products_quantity': - return ['pm_advancedpack', 'quotation', 'amazon', 'pushoncart', 'cartabandonmentpro']; - case 'products_shipping': - return ['orderpreparation', 'pqeasypost', 'printlabels', 'upstrackingv2']; - case 'products_price': - return ['ordertaxprofitreport', 'massiveprices', 'giftcards', 'groupinc', 'moneybookers', 'authorizeaim']; - case 'products_seo': - return ['ganalytics', 'gshopping', 'leguide', 'seoexpert', 'pm_seointernallinking', 'ec_seo404']; - case 'products_options': - return ['pm_multiplefeatures', 'pm_advancedsearch4', 'banipmod', 'mynewsletter', 'allinone_rewards', 'pm_cachemanager', 'lgcookieslaw', 'customfields']; - case 'products_others': - default: - return []; - } - } - - /** - * Filters the given module list to remove installed ones, and bad filled cases. - * - * @param array $moduleFullList The input list to filter - * - * @return array The filtered list of modules - */ - public function filterInstalledAndBadModules(array $moduleFullList) - { - $installed_modules = []; - array_map(function ($module) use (&$installed_modules) { - $installed_modules[$module['name']] = $module; - }, Module::getModulesInstalled()); - - foreach ($moduleFullList as $key => $module) { - if ((bool) array_key_exists($module->attributes->get('name'), $installed_modules) === true) { - unset($moduleFullList[$key]); - } - if (!isset($module->attributes->get('media')->img)) { - unset($moduleFullList[$key]); - } - } - - return $moduleFullList; - } -} diff --git a/src/PrestaShopBundle/Service/DataProvider/Marketplace/ApiClient.php b/src/PrestaShopBundle/Service/DataProvider/Marketplace/ApiClient.php deleted file mode 100644 index 48b67e6e..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/Marketplace/ApiClient.php +++ /dev/null @@ -1,346 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider\Marketplace; - -use GuzzleHttp\Client; - -class ApiClient -{ - private $addonsApiClient; - private $queryParameters = [ - 'format' => 'json', - ]; - private $defaultQueryParameters; - - /** - * @var \PrestaShop\PrestaShop\Adapter\Tools - */ - private $toolsAdapter; - - public function __construct( - Client $addonsApiClient, - $locale, - $isoCode, - $toolsAdapter, - $domain, - $shopVersion - ) { - $this->addonsApiClient = $addonsApiClient; - $this->toolsAdapter = $toolsAdapter; - - list($isoLang) = explode('-', $locale); - - $this->setIsoLang($isoLang) - ->setIsoCode($isoCode) - ->setVersion($shopVersion) - ->setShopUrl($domain); - $this->defaultQueryParameters = $this->queryParameters; - } - - public function setSslVerification($verifySsl) - { - $this->toolsAdapter->refreshCaCertFile(); - $this->addonsApiClient->setDefaultOption('verify', $verifySsl); - } - - /** - * @param Client $client - * - * @return $this - */ - public function setClient(Client $client) - { - $this->addonsApiClient = $client; - - return $this; - } - - /** - * In case you reuse the Client, you may want to clean the previous parameters. - */ - public function reset() - { - $this->queryParameters = $this->defaultQueryParameters; - } - - /** - * Check Addons client account credentials. - * - * @return object - */ - public function getCheckCustomer() - { - $response = $this->setMethod('check_customer') - ->getResponse(); - - return json_decode($response); - } - - public function getNativesModules() - { - $response = $this->setMethod('listing') - ->setAction('native') - ->getResponse(); - - $responseArray = json_decode($response); - - return isset($responseArray->modules) ? $responseArray->modules : []; - } - - public function getPreInstalledModules() - { - $response = $this->setMethod('listing') - ->setAction('install-modules') - ->getResponse(); - $responseDecoded = json_decode($response); - - return isset($responseDecoded->modules) ? $responseDecoded->modules : []; - } - - public function getMustHaveModules() - { - $response = $this->setMethod('listing') - ->setAction('must-have') - ->getResponse(); - - $responseArray = json_decode($response); - - return isset($responseArray->modules) ? $responseArray->modules : []; - } - - /** - * Prepare and call API for PrestaTrust integrity and property module details. - * - * @param string $hash Hash of module files - * @param string $sc_address Smart contract (Module licence) - * - * @return object List of checks made and their results - */ - public function getPrestaTrustCheck($hash, $sc_address) - { - $this->queryParameters['module_hash'] = $hash; - $this->queryParameters['sc_address'] = $sc_address; - - $response = $this->setMethod('trust') - ->getResponse(); - - return json_decode($response); - } - - public function getServices() - { - $response = $this->setMethod('listing') - ->setAction('service') - ->getResponse(); - - $responseArray = json_decode($response); - - return isset($responseArray->services) ? $responseArray->services : []; - } - - public function getCategories() - { - $response = $this->setMethod('listing') - ->setAction('categories') - ->getResponse(); - - $responseArray = json_decode($response); - - return isset($responseArray->module) ? $responseArray->module : []; - } - - public function getModule($moduleId) - { - $response = $this->setMethod('listing') - ->setAction('module') - ->setModuleId($moduleId) - ->getResponse(); - - $responseArray = json_decode($response); - - if (!empty($responseArray->modules)) { - return $responseArray->modules[0]; - } - } - - /** - * Call API for module ZIP content (= download). - * - * @param int $moduleId - * - * @return string binary content (zip format) - */ - public function getModuleZip($moduleId) - { - return $this->setMethod('module') - ->setModuleId($moduleId) - ->getPostResponse(); - } - - public function getCustomerModules($userMail, $password) - { - $response = $this->setMethod('listing') - ->setAction('customer') - ->setUserMail($userMail) - ->setPassword($password) - ->getPostResponse(); - - $responseArray = json_decode($response); - - if (!empty($responseArray->modules)) { - return $responseArray->modules; - } - - return []; - } - - /** - * Get list of themes bought by customer. - * - * @return object - */ - public function getCustomerThemes() - { - $response = $this->setMethod('listing') - ->setAction('customer-themes') - ->getPostResponse(); - - $responseDecoded = json_decode($response); - - if (!empty($responseDecoded->themes)) { - return $responseDecoded->themes; - } - - return []; - } - - public function getResponse() - { - return (string) $this->addonsApiClient - ->get( - null, - ['query' => $this->queryParameters, - ] - )->getBody(); - } - - public function getPostResponse() - { - return (string) $this->addonsApiClient - ->post( - null, - ['query' => $this->queryParameters, - ] - )->getBody(); - } - - /* - * REQUEST PARAMETER SETTERS. - * All parameters will have the same label as their function name. - */ - - public function setMethod($method) - { - $this->queryParameters['method'] = $method; - - return $this; - } - - public function setAction($action) - { - $this->queryParameters['action'] = $action; - - return $this; - } - - public function setIsoLang($isoLang) - { - $this->queryParameters['iso_lang'] = $isoLang; - - return $this; - } - - public function setIsoCode($isoCode) - { - $this->queryParameters['iso_code'] = $isoCode; - - return $this; - } - - public function setVersion($version) - { - $this->queryParameters['version'] = $version; - - return $this; - } - - public function setModuleId($moduleId) - { - $this->queryParameters['id_module'] = $moduleId; - - return $this; - } - - public function setModuleKey($moduleKey) - { - $this->queryParameters['module_key'] = $moduleKey; - - return $this; - } - - public function setModuleName($moduleName) - { - $this->queryParameters['module_name'] = $moduleName; - - return $this; - } - - public function setShopUrl($shop_url) - { - $this->queryParameters['shop_url'] = $shop_url; - - return $this; - } - - public function setUserMail($userMail) - { - $this->queryParameters['username'] = $userMail; - - return $this; - } - - public function setPassword($password) - { - $this->queryParameters['password'] = $password; - - return $this; - } - - /* - * END OF REQUEST PARAMETER SETTERS. - */ -} diff --git a/src/PrestaShopBundle/Service/DataProvider/StockInterface.php b/src/PrestaShopBundle/Service/DataProvider/StockInterface.php deleted file mode 100644 index 4e195618..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/StockInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider; - -/** - * Data provider for new Architecture, about Product stocks. - * - * This class will provide data from DB / ORM about Product stocks. - */ -interface StockInterface -{ - /** - * Returns True if Stocks are managed by a module (or by legacy ASM). - * - * @return bool True if Stocks are managed by a module (or by legacy ASM) - */ - public function isAsmGloballyActivated(); -} diff --git a/src/PrestaShopBundle/Service/DataProvider/UserProvider.php b/src/PrestaShopBundle/Service/DataProvider/UserProvider.php deleted file mode 100644 index fe014935..00000000 --- a/src/PrestaShopBundle/Service/DataProvider/UserProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataProvider; - -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage; -use Symfony\Component\Security\Core\User\User; - -/** - * Convenient way to access User, if exists. - */ -class UserProvider -{ - const ANONYMOUS_USER = 'ANONYMOUS_USER'; - - private $tokenStorage; - - public function __construct(TokenStorage $tokenStorage) - { - $this->tokenStorage = $tokenStorage; - } - - /** - * @see \Symfony\Bundle\FrameworkBundle\Controller::getUser() - */ - public function getUser() - { - if (null === $token = $this->tokenStorage->getToken()) { - return; - } - - if (!is_object($user = $token->getUser())) { - // e.g. anonymous authentication - return; - } - - return $user; - } - - public function getUsername() - { - if ($this->getUser() instanceof User) { - return $this->getUser()->getUsername(); - } - - return self::ANONYMOUS_USER; - } -} diff --git a/src/PrestaShopBundle/Service/DataUpdater/Admin/ProductInterface.php b/src/PrestaShopBundle/Service/DataUpdater/Admin/ProductInterface.php deleted file mode 100644 index 4a7793d9..00000000 --- a/src/PrestaShopBundle/Service/DataUpdater/Admin/ProductInterface.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\DataUpdater\Admin; - -/** - * Data updater for new Architecture, about Product object model. - * - * This class will provide data from DB / ORM about Products for the Admin interface. - */ -interface ProductInterface -{ - /** - * Activate or deactivate a list of products. - * - * @param array $productListId The ID list of products to (de)activate - * @param bool $activate true to activate, false to deactivate - * - * @throws \PrestaShopBundle\Exception\UpdateProductException If an error occured during update (not really blocking since its just activation flag) - * - * @return bool true when succeed - */ - public function activateProductIdList(array $productListId, $activate = true); - - /** - * Do a safe delete on given product IDs. - * - * @param array $productListId The ID list of products to delete - * - * @throws \PrestaShopBundle\Exception\UpdateProductException If deletion failed (some normal cases can brings this, it's not a Development error) - * - * @return bool true when succeed - */ - public function deleteProductIdList(array $productIdList); - - /** - * Duplicates the given product IDs. - * - * @param array $productListId The ID list of products to delete - * - * @throws \PrestaShopBundle\Exception\UpdateProductException if duplication failed - * - * @return bool true when succeed - */ - public function duplicateProductIdList(array $productIdList); - - /** - * Do a safe delete on given product ID. - * - * @param int $productId The product ID to delete - * - * @throws \PrestaShopBundle\Exception\UpdateProductException If deletion failed (some normal cases can brings this, it's not a Development error) - * - * @return bool - */ - public function deleteProduct($productId); - - /** - * Duplicates the given product, and returns the new ID. - * - * Code comes from Legacy controller! - * - * @param int $productId The product ID to duplicate - * - * @return int The new product ID (duplicate) - */ - public function duplicateProduct($productId); - - /** - * Do a sort on a page of products. - * - * Since the sort can be partial (only one page, with offset and limit), we MUST sort only the given IDs, - * and keep the others safely sorted without any functional change (even if we can bulk shift positions to fix gaps and duplicates). - * - * @param array $productList the list of products to sort (keys: ID, values: old positions) The natural order of the array is the new order to update - * @param array $filterParams Contains the ID of the category to sort. Take it from AdminProductDataProvider::getPersistedFilterParameters(). - * - * @throws \PrestaShopBundle\Exception\UpdateProductException If deletion failed (some normal cases can brings this, it's not a Development error) - * - * @return bool true when succeed - */ - public function sortProductIdList(array $productList, $filterParams); -} diff --git a/src/PrestaShopBundle/Service/Database/DoctrineNamingStrategy.php b/src/PrestaShopBundle/Service/Database/DoctrineNamingStrategy.php deleted file mode 100644 index 75b04546..00000000 --- a/src/PrestaShopBundle/Service/Database/DoctrineNamingStrategy.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Database; - -use Doctrine\ORM\Mapping\UnderscoreNamingStrategy; - -/** - * Naming strategy for Doctrine ORM to use prefixed database table names. - */ -class DoctrineNamingStrategy extends UnderscoreNamingStrategy -{ - private $prefix; - - /** - * Constructor. - * - * Prefix is given by injection, set in app/config/parameters.yml. - * - * @param string $prefix - */ - public function __construct($prefix = 'ps_') - { - parent::__construct(CASE_LOWER); - $this->prefix = $prefix; - } - - /** - * {@inheritdoc} - * - * This override adds a prefix to the underscored table name. - */ - public function classToTableName($className) - { - $underscored = parent::classToTableName($className); - - return $this->prefix . $underscored; - } - - /** - * {@inheritdoc} - * - * This override adds a prefix to the underscored table name. - */ - public function joinTableName($sourceEntity, $targetEntity, $propertyName = null) - { - return $this->prefix . parent::classToTableName($sourceEntity) . '_' . parent::classToTableName($targetEntity); - } -} diff --git a/src/PrestaShopBundle/Service/Database/Upgrade.php b/src/PrestaShopBundle/Service/Database/Upgrade.php deleted file mode 100644 index 0709e9e7..00000000 --- a/src/PrestaShopBundle/Service/Database/Upgrade.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Database; - -use PrestaShopBundle\Command\UpdateSchemaCommand; -use PrestaShopBundle\Service\Command\AbstractCommand; - -class Upgrade extends AbstractCommand -{ - /** - * Run the custom schemaUpgrade command. - */ - public function addDoctrineSchemaUpdate() - { - $command = new UpdateSchemaCommand(); - $this->application->add($command); - - $this->commands[] = [ - 'command' => 'prestashop:schema:update-without-foreign', - '--env' => _PS_ENV_, - ]; - } -} diff --git a/src/PrestaShopBundle/Service/Grid/ControllerResponseBuilder.php b/src/PrestaShopBundle/Service/Grid/ControllerResponseBuilder.php deleted file mode 100644 index e6d7a012..00000000 --- a/src/PrestaShopBundle/Service/Grid/ControllerResponseBuilder.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ -declare(strict_types=1); - -namespace PrestaShopBundle\Service\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\GridFilterFormFactoryInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Router; - -/** - * Before we introduced the filterId notion to store/clean filters on grids the solution - * used controller and action as a key to retrieve and filter. The filters were not scoped - * in the request either (which prevented having two grids on the same page). - * This class is responsible for building the controller response just like it worked before - * filterId, this allows us to keep a backward compatibility in CommonController::searchAction. - */ -class ControllerResponseBuilder -{ - /** @var GridFilterFormFactoryInterface */ - private $filterFormFactory; - - /** @var Router */ - private $router; - - /** - * @param GridFilterFormFactoryInterface $filterFormFactory - * @param Router $router - */ - public function __construct( - GridFilterFormFactoryInterface $filterFormFactory, - Router $router - ) { - $this->filterFormFactory = $filterFormFactory; - $this->router = $router; - } - - /** - * @param GridDefinitionFactoryInterface $definitionFactory - * @param Request $request - * @param string $redirectRoute - * @param array $queryParamsToKeep - * - * @return RedirectResponse - */ - public function buildSearchResponse( - GridDefinitionFactoryInterface $definitionFactory, - Request $request, - $redirectRoute, - array $queryParamsToKeep = [] - ) { - /** @var GridDefinitionInterface $definition */ - $definition = $definitionFactory->getDefinition(); - - /** @var FormInterface $filtersForm */ - $filtersForm = $this->filterFormFactory->create($definition); - $filtersForm->handleRequest($request); - - $redirectParams = []; - if ($filtersForm->isSubmitted()) { - $redirectParams = [ - 'filters' => $filtersForm->getData(), - ]; - } - - foreach ($queryParamsToKeep as $paramName) { - if ($request->query->has($paramName)) { - $redirectParams[$paramName] = $request->query->get($paramName); - } - if ($request->attributes->has($paramName)) { - $redirectParams[$paramName] = $request->attributes->get($paramName); - } - } - - $redirectUrl = $this->router->generate($redirectRoute, $redirectParams); - - return new RedirectResponse($redirectUrl, 302); - } -} diff --git a/src/PrestaShopBundle/Service/Grid/ResponseBuilder.php b/src/PrestaShopBundle/Service/Grid/ResponseBuilder.php deleted file mode 100644 index fb70527f..00000000 --- a/src/PrestaShopBundle/Service/Grid/ResponseBuilder.php +++ /dev/null @@ -1,102 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Grid; - -use PrestaShop\PrestaShop\Core\Grid\Definition\Factory\GridDefinitionFactoryInterface; -use PrestaShop\PrestaShop\Core\Grid\Definition\GridDefinitionInterface; -use PrestaShop\PrestaShop\Core\Grid\Filter\GridFilterFormFactoryInterface; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Router; - -class ResponseBuilder -{ - /** @var GridFilterFormFactoryInterface */ - private $filterFormFactory; - - /** @var Router */ - private $router; - - /** - * @param GridFilterFormFactoryInterface $filterFormFactory - * @param Router $router - */ - public function __construct( - GridFilterFormFactoryInterface $filterFormFactory, - Router $router - ) { - $this->filterFormFactory = $filterFormFactory; - $this->router = $router; - } - - /** - * @param GridDefinitionFactoryInterface $definitionFactory - * @param Request $request - * @param string $filterId - * @param string $redirectRoute - * @param array $queryParamsToKeep - * - * @return RedirectResponse - */ - public function buildSearchResponse( - GridDefinitionFactoryInterface $definitionFactory, - Request $request, - $filterId, - $redirectRoute, - array $queryParamsToKeep = [] - ) { - /** @var GridDefinitionInterface $definition */ - $definition = $definitionFactory->getDefinition(); - - /** @var FormInterface $filtersForm */ - $filtersForm = $this->filterFormFactory->create($definition); - $filtersForm->handleRequest($request); - - $redirectParams = []; - if ($filtersForm->isSubmitted()) { - $redirectParams = [ - $filterId => [ - 'filters' => $filtersForm->getData(), - ], - ]; - } - - foreach ($queryParamsToKeep as $paramName) { - if ($request->query->has($paramName)) { - $redirectParams[$paramName] = $request->query->get($paramName); - } - if ($request->attributes->has($paramName)) { - $redirectParams[$paramName] = $request->attributes->get($paramName); - } - } - - $redirectUrl = $this->router->generate($redirectRoute, $redirectParams); - - return new RedirectResponse($redirectUrl, 302); - } -} diff --git a/src/PrestaShopBundle/Service/Hook/HookContentClassInterface.php b/src/PrestaShopBundle/Service/Hook/HookContentClassInterface.php deleted file mode 100644 index ab026488..00000000 --- a/src/PrestaShopBundle/Service/Hook/HookContentClassInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Hook; - -interface HookContentClassInterface -{ - public function toArray(); -} diff --git a/src/PrestaShopBundle/Service/Hook/HookDispatcher.php b/src/PrestaShopBundle/Service/Hook/HookDispatcher.php deleted file mode 100644 index 4505f24f..00000000 --- a/src/PrestaShopBundle/Service/Hook/HookDispatcher.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Hook; - -use PrestaShop\PrestaShop\Adapter\Hook\HookDispatcher as HookDispatcherAdapter; - -/** - * This dispatcher is used to trigger hook listeners. - * - * The dispatch process cannot be stopped like a common EventDispatcher. - * - * If the event is a RenderingHookEvent, then the final result is - * an array of contents accessed from $event->getContent(). - * - * @deprecated since 1.7.5, to be removed in 1.8. Use PrestaShop\PrestaShop\Adapter\Hook\HookDispatcher instead. - */ -class HookDispatcher extends HookDispatcherAdapter -{ - public function __construct() - { - @trigger_error('Deprecated since 1.7.5, to be removed in 1.8. Use PrestaShop\PrestaShop\Core\Hook\HookDispatcher instead.', E_USER_DEPRECATED); - } -} diff --git a/src/PrestaShopBundle/Service/Hook/HookEvent.php b/src/PrestaShopBundle/Service/Hook/HookEvent.php deleted file mode 100644 index 7cbea0d9..00000000 --- a/src/PrestaShopBundle/Service/Hook/HookEvent.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Hook; - -use AppKernel; -use PrestaShop\PrestaShop\Adapter\SymfonyContainer; -use Symfony\Component\EventDispatcher\Event; - -/** - * HookEvent is used in HookDispatcher. - * - * A HookEvent can contains parameters to give to the listeners through getHookParameters. - */ -class HookEvent extends Event -{ - private $hookParameters = []; - - /** - * Sets the Hook parameters. - * - * @param array hook parameters - * - * @return $this, for fluent use of object - */ - public function setHookParameters($parameters) - { - $this->hookParameters = $parameters; - - return $this; - } - - /** - * Returns Hook parameters and default values. - * - * More values than the param set is returned: - * - _ps_version contains PrestaShop version, and is here only if the Hook is triggered by Symfony architecture. - * These values can either be overriden by setHookParameters using the same parameter key. - * - * @return array the array of hook parameters, more default fixed values - */ - public function getHookParameters() - { - $globalParameters = ['_ps_version' => AppKernel::VERSION]; - - $sfContainer = SymfonyContainer::getInstance(); - if (null !== $sfContainer && null !== $sfContainer->get('request_stack')->getCurrentRequest()) { - $request = $sfContainer->get('request_stack')->getCurrentRequest(); - $globalParameters['request'] = $request; - $globalParameters['route'] = $request->get('_route'); - } - - return array_merge($globalParameters, $this->hookParameters); - } -} diff --git a/src/PrestaShopBundle/Service/Hook/HookFinder.php b/src/PrestaShopBundle/Service/Hook/HookFinder.php deleted file mode 100644 index 91043058..00000000 --- a/src/PrestaShopBundle/Service/Hook/HookFinder.php +++ /dev/null @@ -1,228 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Hook; - -use PrestaShop\PrestaShop\Adapter\HookManager; - -/** - * This class declares the functions needed to get structured data - * from the modules, by asking them to follow a specific class. - */ -class HookFinder -{ - /** - * In order to not return wrong things to the caller, we ask for an - * instance of specific classes. - * Please note it must implement the function toArray(). - * - * @var string - */ - protected $expectedInstanceClasses = []; - - /** - * Because we cannot send the same parameters between two different finders, - * we need a attribute. It will be sent to the Hook::exec() function. - * - * @var array - */ - protected $params = []; - - /** - * The hook to call. - * - * @var string - */ - protected $hookName; - - /** - * Execute hook specified in params and check if the result matches the expected classes if asked. - * - * @return array Content returned by modules - * - * @throws \Exception if class doesn't match interface or expected classes - */ - public function find() - { - $hookContent = (new HookManager())->exec($this->hookName, $this->params, null, true); - if (!is_array($hookContent)) { - $hookContent = []; - } - - foreach ($hookContent as $moduleName => $moduleContents) { - if (!is_array($moduleContents)) { - continue; - } - foreach ($moduleContents as $content) { - // Check data returned if asked - if (!count($this->expectedInstanceClasses)) { - continue; - } - if (is_object($content) && !in_array(get_class($content), $this->expectedInstanceClasses)) { - throw new \Exception('The module ' . $moduleName . ' did not return expected class. Was ' . get_class($content) . ' instead of ' . implode(' or ', $this->expectedInstanceClasses) . '.'); - } elseif (!is_object($content)) { - throw new \Exception('The module ' . $moduleName . ' did not return expected type. Was ' . gettype($content) . ' instead of ' . implode(' or ', $this->expectedInstanceClasses) . '.'); - } - } - } - - return $hookContent; - } - - /** - * Present all extra content for templates, meaning converting them as arrays. - * - * @return array - */ - public function present() - { - $hookContent = $this->find(); - $presentedContents = []; - - foreach ($hookContent as $moduleName => $moduleContents) { - if (!is_array($moduleContents)) { - continue; - } - foreach ($moduleContents as $content) { - if (!$content instanceof HookContentClassInterface) { - throw new \Exception('The class returned must implement HookContentClassInterface to be presented'); - } - - $presentedContent = $content->toArray(); - $presentedContent['moduleName'] = $moduleName; - $presentedContents[] = $presentedContent; - } - } - - return $presentedContents; - } - - /** - * This array contains all the classes expected to be returned - * by the modules on Hook::exec. - * - * @return array - */ - public function getExpectedInstanceClasses() - { - return $this->expectedInstanceClasses; - } - - /** - * The hook going to be called when firing find(). - * - * @return string - */ - public function getHookName() - { - return $this->hookName; - } - - /** - * The $params sent to Hook::exec(). - * - * @return array - */ - public function getParams() - { - return $this->params; - } - - /** - * Add an instance of class to be returned by the hook without - * erasing the other values. - * - * @param string|array $expectedInstanceClasses - * - * @return \PrestaShopBundle\Service\Hook\Finder - */ - public function addExpectedInstanceClasses($expectedInstanceClasses) - { - if (is_array($expectedInstanceClasses)) { - $this->expectedInstanceClasses = array_merge($this->expectedInstanceClasses, $expectedInstanceClasses); - } else { - $this->expectedInstanceClasses[] = $expectedInstanceClasses; - } - - return $this; - } - - /** - * Replace all expected classes and types. - * - * @param array $expectedInstanceClasses - * - * @return \PrestaShopBundle\Service\Hook\Finder - */ - public function setExpectedInstanceClasses($expectedInstanceClasses) - { - $this->expectedInstanceClasses = $expectedInstanceClasses; - - return $this; - } - - /** - * Change the hook to be called. - * - * @param string $hookName - * - * @return \PrestaShopBundle\Service\Hook\Finder - */ - public function setHookName($hookName) - { - $this->hookName = $hookName; - - return $this; - } - - /** - * Add a hook param without erasing all the other values. - * - * @param array $params - * - * @return \PrestaShopBundle\Service\Hook\Finder - */ - public function addParams($params) - { - $this->params = array_merge($this->params, $params); - - return $this; - } - - /** - * Replace the params array. - * - * @param array $params - * - * @return \PrestaShopBundle\Service\Hook\Finder - */ - public function setParams($params) - { - $this->params = $params; - - return $this; - } -} diff --git a/src/PrestaShopBundle/Service/Hook/RenderingHookEvent.php b/src/PrestaShopBundle/Service/Hook/RenderingHookEvent.php deleted file mode 100644 index 6efc887a..00000000 --- a/src/PrestaShopBundle/Service/Hook/RenderingHookEvent.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Hook; - -/** - * RenderingHookEvent is used in HookDispatcher for rendering hooks. - * - * A HookEvent can contains parameters to give to the listeners through getHookParameters, - * but can also contains responses from subscribers, to deliver HTML or other data to the caller. - */ -class RenderingHookEvent extends HookEvent -{ - /** - * @var array - */ - private $currentContent = []; - /** - * @var string - */ - private $currentListener = ''; - - /** - * Sets the response from the listener. - * - * Should be called by the listener to store its response. - * This content will be pushed in a stack between each listener call. - * Every response is kept, but a given listener cannot see the previous listeners' responses. - * - * @param array $content The rendering content returned by the listener - * @param string $fromListener The listener that sets the content - * - * @return $this for fluent use - */ - public function setContent(array $content, $fromListener = '') - { - $this->currentContent = $content; - $this->currentListener = $fromListener; - - return $this; - } - - /** - * Gets the last pushed content (for the current listener). - * - * @return array - */ - public function getContent() - { - return $this->currentContent; - } - - /** - * Retrieves the last pushed content (and cleans the corresponding attribute). - * - * @return array - */ - public function popContent() - { - $content = $this->currentContent; - $this->currentContent = []; - - return $content; - } - - /** - * Gets the current listener that put the response (and cleans the corresponding attribute). - * - * @return string a listener - */ - public function popListener() - { - $listener = $this->currentListener; - $this->currentListener = ''; - - return $listener; - } -} diff --git a/src/PrestaShopBundle/Service/Log/LogHandler.php b/src/PrestaShopBundle/Service/Log/LogHandler.php deleted file mode 100644 index 82b7d6cd..00000000 --- a/src/PrestaShopBundle/Service/Log/LogHandler.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Log; - -use Monolog\Handler\AbstractProcessingHandler; -use Monolog\Logger; -use Symfony\Component\DependencyInjection\Container; - -class LogHandler extends AbstractProcessingHandler -{ - protected $container; - - public function __construct(Container $container, $level = Logger::DEBUG, $bubble = true) - { - $this->container = $container; - parent::__construct($level, $bubble); - } - - protected function write(array $record) - { - $logger = $this->container->get('prestashop.adapter.legacy.logger'); - $logger->log($record['level'], $record['message'], $record['context']); - } -} diff --git a/src/PrestaShopBundle/Service/ProductService.php b/src/PrestaShopBundle/Service/ProductService.php deleted file mode 100644 index 88827216..00000000 --- a/src/PrestaShopBundle/Service/ProductService.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service; - -use PrestaShop\PrestaShop\Adapter\Product\ProductDataProvider; -use Product; - -class ProductService -{ - /** @var ProductDataProvider */ - protected $dataProvider; - - public function __construct(ProductDataProvider $dataProvider) - { - $this->dataProvider = $dataProvider; - } - - public function cleanupOldTempProducts() - { - $oldProducts = Product::getOldTempProducts(); - - foreach ($oldProducts as $oldProduct) { - $id_product = $oldProduct['id_product']; - $product = $this->dataProvider->getProduct($id_product); - if ($product) { - $product->delete(); - } - } - } -} diff --git a/src/PrestaShopBundle/Service/Routing/Router.php b/src/PrestaShopBundle/Service/Routing/Router.php deleted file mode 100644 index 9bc34132..00000000 --- a/src/PrestaShopBundle/Service/Routing/Router.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\Routing; - -use PrestaShop\PrestaShop\Core\Feature\TokenInUrls; -use PrestaShopBundle\Service\DataProvider\UserProvider; -use Symfony\Bundle\FrameworkBundle\Routing\Router as BaseRouter; -use Symfony\Component\Security\Csrf\CsrfTokenManager; - -/** - * We extends Symfony Router in order to add a token to each url. - * - * This is done for Security purposes. - */ -class Router extends BaseRouter -{ - /** - * @var UserProvider - */ - private $userProvider; - - /** - * @var CsrfTokenManager - */ - private $tokenManager; - - /** - * @var array - */ - private $tokens = []; - - /** - * {@inheritdoc} - */ - public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) - { - $username = $this->userProvider->getUsername(); - // Do not generate token each time we want to generate a route for a user - if (!isset($this->tokens[$username])) { - $this->tokens[$username] = $this->tokenManager->getToken($username)->getValue(); - } - - $url = parent::generate($name, $parameters, $referenceType); - - return self::generateTokenizedUrl($url, $this->tokens[$username]); - } - - public function setTokenManager(CsrfTokenManager $tokenManager) - { - $this->tokenManager = $tokenManager; - } - - public function setUserProvider(UserProvider $userProvider) - { - $this->userProvider = $userProvider; - } - - public static function generateTokenizedUrl($url, $token) - { - if (TokenInUrls::isDisabled()) { - return $url; - } - - $components = parse_url($url); - $baseUrl = (isset($components['path']) ? $components['path'] : ''); - $queryParams = []; - if (isset($components['query'])) { - $query = $components['query']; - - parse_str($query, $queryParams); - } - - $queryParams['_token'] = $token; - - return $baseUrl . '?' . http_build_query($queryParams, '', '&'); - } -} diff --git a/src/PrestaShopBundle/Service/TransitionalBehavior/AdminPagePreferenceInterface.php b/src/PrestaShopBundle/Service/TransitionalBehavior/AdminPagePreferenceInterface.php deleted file mode 100644 index aa7f95f3..00000000 --- a/src/PrestaShopBundle/Service/TransitionalBehavior/AdminPagePreferenceInterface.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\TransitionalBehavior; - -/** - * Contract to know which page's version to display. - * - * This interface gives methods to use to take decision: - * - if we should display the new refactored page, or the old legacy one. - * - if we should display the switch on the admin layout to change this setting. - */ -interface AdminPagePreferenceInterface -{ - /** - * Use it to know if we need to redirect to legacy Controllers or not. - * - * @param string $page the page to look for - * - * @return bool true to redirect to legacy - */ - public function getTemporaryShouldUseLegacyPage($page); - - /** - * Set the temporary behavior of the new/old page on Admin interface. - * - * @param string $page the page to look for - * @param bool $useLegacy true to redirect to old legacy pages for Product controller - */ - public function setTemporaryShouldUseLegacyPage($page, $useLegacy); - - /** - * Use it to know if we need to display the 'switch to legacy page' button or not. - * In debug mode, always shown. - * - * @param string $page the page to look for - * - * @return bool true to show the switch to legacy page button - */ - public function getTemporaryShouldAllowUseLegacyPage($page = null); -} diff --git a/src/PrestaShopBundle/Service/TransitionalBehavior/AdminUrlGeneratorFactory.php b/src/PrestaShopBundle/Service/TransitionalBehavior/AdminUrlGeneratorFactory.php deleted file mode 100644 index 9cb75cf4..00000000 --- a/src/PrestaShopBundle/Service/TransitionalBehavior/AdminUrlGeneratorFactory.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service\TransitionalBehavior; - -use PrestaShop\PrestaShop\Adapter\Admin\UrlGenerator as LegacyUrlGenerator; -use PrestaShop\PrestaShop\Adapter\LegacyContext; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; -use Symfony\Component\Routing\Router; - -/** - * Factory to return a UrlGeneratorInterface. - * Either the base generator from Symfony (the Router class instance) - * Either an Adapter for Admin legacy controllers. - */ -class AdminUrlGeneratorFactory -{ - /** - * @var Router - */ - private $router; - - /** - * Constructor. - * - * @param Router $router - */ - public function __construct(Router $router) - { - $this->router = $router; - } - - /** - * Gets the UrlGeneratorInterface subclass for Legacy Admin controllers. - * - * @param LegacyContext $legacyContext The legacy context needed by Legacy UrlGenerator - * - * @return UrlGeneratorInterface the UrlGenerator instance for Admin legacy controllers - */ - public function forLegacy(LegacyContext $legacyContext) - { - return new LegacyUrlGenerator($legacyContext, $this->router); - } - - /** - * Gets the UrlGeneratorInterface subclass for Symfony routes. - * - * @return UrlGeneratorInterface the UrlGenerator instance for Admin Symfony routes - */ - public function forSymfony() - { - return $this->router; - } -} diff --git a/src/PrestaShopBundle/Service/TranslationService.php b/src/PrestaShopBundle/Service/TranslationService.php deleted file mode 100644 index f2c888c6..00000000 --- a/src/PrestaShopBundle/Service/TranslationService.php +++ /dev/null @@ -1,355 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Service; - -use Exception; -use PrestaShopBundle\Entity\Translation; -use PrestaShopBundle\Exception\InvalidLanguageException; -use PrestaShopBundle\Translation\Constraints\PassVsprintf; -use PrestaShopBundle\Translation\Provider\UseModuleInterface; -use Symfony\Component\DependencyInjection\Container; -use Symfony\Component\Validator\Validation; - -class TranslationService -{ - /** - * @var Container - */ - public $container; - - /** - * @param string $lang - * - * @return mixed - */ - public function langToLocale($lang) - { - $legacyToStandardLocales = $this->getLangToLocalesMapping(); - - return $legacyToStandardLocales[$lang]; - } - - /** - * @param string $locale - * - * @return mixed - * - * @throws InvalidLanguageException - */ - public function findLanguageByLocale($locale) - { - $doctrine = $this->container->get('doctrine'); - - $lang = $doctrine->getManager()->getRepository('PrestaShopBundle:Lang')->findOneByLocale($locale); - - if (!$lang) { - throw InvalidLanguageException::localeNotFound($locale); - } - - return $lang; - } - - /** - * @return mixed - * - * @throws Exception - */ - private function getLangToLocalesMapping() - { - $translationsDirectory = $this->getResourcesDirectory(); - - $legacyToStandardLocalesJson = file_get_contents($translationsDirectory . '/legacy-to-standard-locales.json'); - $legacyToStandardLocales = json_decode($legacyToStandardLocalesJson, true); - - $jsonLastErrorCode = json_last_error(); - if (JSON_ERROR_NONE !== $jsonLastErrorCode) { - throw new Exception('The legacy to standard locales JSON could not be decoded', $jsonLastErrorCode); - } - - return $legacyToStandardLocales; - } - - /** - * @return string - */ - private function getResourcesDirectory() - { - return $this->container->getParameter('kernel.root_dir') . '/Resources'; - } - - /** - * @param $lang - * @param $type - * @param $theme - * @param null $search - * - * @return array|mixed - */ - public function getTranslationsCatalogue($lang, $type, $theme, $search = null) - { - $factory = $this->container->get('ps.translations_factory'); - - if ($this->requiresThemeTranslationsFactory($theme, $type)) { - if ('classic' === $theme) { - $type = 'front'; - } else { - $type = $theme; - $factory = $this->container->get('ps.theme_translations_factory'); - } - } - - $locale = $this->langToLocale($lang); - - return $factory->createTranslationsArray($type, $locale, $theme, $search); - } - - /** - * @param $theme - * @param $type - * - * @return bool - */ - private function requiresThemeTranslationsFactory($theme, $type) - { - return $type === 'themes' && null !== $theme; - } - - /** - * List translations for a specific domain. - * - * @todo: we need module information here - * @todo: we need to improve the Vuejs application to send the information - * - * @param $locale - * @param $domain - * @param null $theme - * @param null $search - * @param null $module - * - * @return array - */ - public function listDomainTranslation($locale, $domain, $theme = null, $search = null, $module = null) - { - if (!empty($theme) && 'classic' !== $theme) { - $translationProvider = $this->container->get('prestashop.translation.theme_provider'); - $translationProvider->setThemeName($theme); - } else { - $translationProvider = $this->container->get('prestashop.translation.search_provider'); - if ($module !== null && $translationProvider instanceof UseModuleInterface) { - $translationProvider->setModuleName($module); - } - } - if ('Messages' === $domain) { - $domain = 'messages'; - } - - $translationProvider->setDomain($domain); - $translationProvider->setLocale($locale); - - $router = $this->container->get('router'); - $domains = [ - 'info' => [ - 'edit_url' => $router->generate('api_translation_value_edit'), - 'reset_url' => $router->generate('api_translation_value_reset'), - ], - 'data' => [], - ]; - $treeDomain = preg_split('/(?=[A-Z])/', $domain, -1, PREG_SPLIT_NO_EMPTY); - if (!empty($theme) && 'classic' !== $theme) { - $defaultCatalog = current($translationProvider->getThemeCatalogue()->all()); - } else { - $defaultCatalog = current($translationProvider->getDefaultCatalogue()->all()); - } - - $xliffCatalog = current($translationProvider->getXliffCatalogue()->all()); - $dbCatalog = current($translationProvider->getDatabaseCatalogue($theme)->all()); - - foreach ($defaultCatalog as $key => $message) { - $data = [ - 'default' => $key, - 'xliff' => (array_key_exists($key, (array) $xliffCatalog) ? $xliffCatalog[$key] : null), - 'database' => (array_key_exists($key, (array) $dbCatalog) ? $dbCatalog[$key] : null), - 'tree_domain' => $treeDomain, - ]; - // if search is empty or is in catalog default|xlf|database - if (empty($search) || $this->dataContainsSearchWord($search, $data)) { - if (empty($data['xliff']) && empty($data['database'])) { - array_unshift($domains['data'], $data); - } else { - $domains['data'][] = $data; - } - } - } - - return $domains; - } - - /** - * Check if data contains search word. - * - * @param $search - * @param $data - * - * @return bool - */ - private function dataContainsSearchWord($search, $data) - { - if (is_string($search)) { - $search = strtolower($search); - - return false !== strpos(strtolower($data['default']), $search) || - false !== strpos(strtolower($data['xliff']), $search) || - false !== strpos(strtolower($data['database']), $search); - } - - if (is_array($search)) { - $contains = true; - foreach ($search as $s) { - $s = strtolower($s); - $contains &= false !== strpos(strtolower($data['default']), $s) || - false !== strpos(strtolower($data['xliff']), $s) || - false !== strpos(strtolower($data['database']), $s); - } - - return $contains; - } - - return false; - } - - /** - * Save a translation in database. - * - * @param $lang - * @param $domain - * @param $key - * @param $translationValue - * @param null $theme - * - * @return bool - */ - public function saveTranslationMessage($lang, $domain, $key, $translationValue, $theme = null) - { - $doctrine = $this->container->get('doctrine'); - $entityManager = $doctrine->getManager(); - $logger = $this->container->get('logger'); - - if (empty($theme)) { - $theme = null; - } - - $translation = $entityManager->getRepository('PrestaShopBundle:Translation') - ->findOneBy([ - 'lang' => $lang, - 'domain' => $domain, - 'key' => $key, - 'theme' => $theme, - ]); - - if (null === $translation) { - $translation = new Translation(); - $translation->setDomain($domain); - $translation->setLang($lang); - $translation->setKey(htmlspecialchars_decode($key, ENT_QUOTES)); - $translation->setTranslation($translationValue); - if (!empty($theme)) { - $translation->setTheme($theme); - } - } else { - if (!empty($theme)) { - $translation->setTheme($theme); - } - $translation->setTranslation($translationValue); - } - - $validator = Validation::createValidator(); - $violations = $validator->validate($translation, new PassVsprintf()); - if (0 !== count($violations)) { - foreach ($violations as $violation) { - $logger->error($violation->getMessage()); - } - - return false; - } - - $updatedTranslationSuccessfully = false; - - try { - $entityManager->persist($translation); - $entityManager->flush(); - - $updatedTranslationSuccessfully = true; - } catch (Exception $exception) { - $logger->error($exception->getMessage()); - } - - return $updatedTranslationSuccessfully; - } - - /** - * Reset translation from database. - * - * @param $lang - * @param $domain - * @param $key - * @param null $theme - * - * @return bool - */ - public function resetTranslationMessage($lang, $domain, $key, $theme = null) - { - $doctrine = $this->container->get('doctrine'); - $entityManager = $doctrine->getManager(); - - $searchTranslation = [ - 'lang' => $lang, - 'domain' => $domain, - 'key' => $key, - ]; - if (!empty($theme)) { - $searchTranslation['theme'] = $theme; - } - - $translation = $entityManager->getRepository('PrestaShopBundle:Translation')->findOneBy($searchTranslation); - - $resetTranslationSuccessfully = false; - if (null === $translation) { - $resetTranslationSuccessfully = true; - } - - try { - $entityManager->remove($translation); - $entityManager->flush(); - - $resetTranslationSuccessfully = true; - } catch (Exception $exception) { - $this->container->get('logger')->error($exception->getMessage()); - } - - return $resetTranslationSuccessfully; - } -} diff --git a/src/PrestaShopBundle/Translation/Api/AbstractApi.php b/src/PrestaShopBundle/Translation/Api/AbstractApi.php deleted file mode 100644 index c194ce82..00000000 --- a/src/PrestaShopBundle/Translation/Api/AbstractApi.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Api; - -use Symfony\Component\Translation\TranslatorInterface; - -abstract class AbstractApi -{ - /** - * @var TranslatorInterface - */ - protected $translator; - - public function setTranslator(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - public function getFormattedTranslations() - { - $all = []; - - foreach ($this->getTranslations() as $key => $translation) { - $all[] = [ - 'translation_id' => $key, - 'name' => $translation, - ]; - } - - return $all; - } - - abstract public function getTranslations(); -} diff --git a/src/PrestaShopBundle/Translation/Api/InternationalApi.php b/src/PrestaShopBundle/Translation/Api/InternationalApi.php deleted file mode 100644 index 03d940c8..00000000 --- a/src/PrestaShopBundle/Translation/Api/InternationalApi.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Api; - -class InternationalApi extends AbstractApi -{ - /** - * @return string[] List of translations - */ - public function getTranslations() - { - return [ - 'button_reset' => $this->translator->trans('Reset', [], 'Admin.Actions'), - 'button_save' => $this->translator->trans('Save', [], 'Admin.Global'), - 'button_leave' => $this->translator->trans('Leave anyway', [], 'Admin.Notifications.Warning'), - 'button_search' => $this->translator->trans('Search', [], 'Admin.Actions'), - 'modal_title' => $this->translator->trans('Confirm this action', [], 'Admin.Actions'), - 'modal_content' => $this->translator->trans('Your modifications are not saved yet. Do you wish to save it before leaving?', [], 'Admin.Notifications.Warning'), - 'head_title' => $this->translator->trans('Translations', [], 'Admin.Navigation.Menu'), - /* Missing is plural, always > 1 */ - 'label_missing' => $this->translator->trans('%d missing', [], 'Admin.International.Feature'), - 'label_missing_singular' => $this->translator->trans('1 missing', [], 'Admin.International.Feature'), - 'label_total_domain' => $this->translator->trans('%nb_translations% expressions', [], 'Admin.International.Feature'), - /* nb_translations can be 0 or 1 */ - 'label_total_domain_singular' => $this->translator->trans('%nb_translation% expression', [], 'Admin.International.Feature'), - 'link_international' => $this->translator->trans('International', [], 'Admin.Navigation.Menu'), - 'link_translations' => $this->translator->trans('Translations', [], 'Admin.Navigation.Menu'), - 'no_result' => $this->translator->trans('There are no results matching your query "%s".', [], 'Admin.Navigation.Search'), - 'sidebar_expand' => $this->translator->trans('Expand', [], 'Admin.Actions'), - 'sidebar_collapse' => $this->translator->trans('Collapse', [], 'Admin.Actions'), - 'search_info' => $this->translator->trans('%d results match your query "%s".', [], 'Admin.Navigation.Search'), - /* %d can be 0 or 1 */ - 'search_info_singular' => $this->translator->trans('%d result matches your query "%s".', [], 'Admin.Navigation.Search'), - 'search_label' => $this->translator->trans('Search translations', [], 'Admin.International.Feature'), - 'search_placeholder' => $this->translator->trans('Search a word or expression, e.g.: "Order confirmation"', [], 'Admin.International.Help'), - ]; - } -} diff --git a/src/PrestaShopBundle/Translation/Api/StockApi.php b/src/PrestaShopBundle/Translation/Api/StockApi.php deleted file mode 100644 index 44d19dce..00000000 --- a/src/PrestaShopBundle/Translation/Api/StockApi.php +++ /dev/null @@ -1,90 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Api; - -class StockApi extends AbstractApi -{ - /** - * @return string[] List of translations - */ - public function getTranslations() - { - return [ - 'alert_bulk_edit' => $this->translator->trans('Use checkboxes to bulk edit quantities', [], 'Admin.Catalog.Feature'), - 'button_advanced_filter' => $this->translator->trans('Advanced filters', [], 'Admin.Catalog.Feature'), - 'button_apply_advanced_filter' => $this->translator->trans('Apply advanced filters', [], 'Admin.Catalog.Feature'), - 'button_movement_type' => $this->translator->trans('Apply new quantity', [], 'Admin.Catalog.Feature'), - 'button_search' => $this->translator->trans('Search', [], 'Admin.Actions'), - 'filter_categories' => $this->translator->trans('Filter by categories', [], 'Admin.Actions'), - 'filter_datepicker_from' => $this->translator->trans('From', [], 'Admin.Global'), - 'filter_datepicker_to' => $this->translator->trans('To', [], 'Admin.Global'), - 'filter_low_stock' => $this->translator->trans('Display products below low stock level first', [], 'Admin.Catalog.Feature'), - 'filter_movements_type' => $this->translator->trans('Filter by movement type', [], 'Admin.Catalog.Feature'), - 'filter_movements_employee' => $this->translator->trans('Filter by employee', [], 'Admin.Catalog.Feature'), - 'filter_movements_period' => $this->translator->trans('Filter by period', [], 'Admin.Catalog.Feature'), - 'filter_search_category' => $this->translator->trans('Search a category', [], 'Admin.Catalog.Feature'), - 'filter_search_suppliers' => $this->translator->trans('Search a supplier', [], 'Admin.Catalog.Feature'), - 'filter_status' => $this->translator->trans('Filter by status', [], 'Admin.Catalog.Feature'), - // 'All' refers to statuses as if "All statuses". Please adapt as necessary in your language - 'filter_status_all' => $this->translator->trans('All', [], 'Admin.Catalog.Feature'), - 'filter_status_disable' => $this->translator->trans('Disabled', [], 'Admin.Global'), - 'filter_status_enable' => $this->translator->trans('Enabled', [], 'Admin.Global'), - 'filter_suppliers' => $this->translator->trans('Filter by supplier', [], 'Admin.Catalog.Feature'), - 'head_title' => $this->translator->trans('Stock management', [], 'Admin.Catalog.Feature'), - 'link_catalog' => $this->translator->trans('Catalog', [], 'Admin.Navigation.Menu'), - 'link_movements' => $this->translator->trans('Movements', [], 'Admin.Catalog.Feature'), - 'link_overview' => $this->translator->trans('Stock', [], 'Admin.Global'), - 'link_stock' => $this->translator->trans('Stock management', [], 'Admin.Catalog.Feature'), - 'menu_stock' => $this->translator->trans('Stock', [], 'Admin.Global'), - 'menu_movements' => $this->translator->trans('Movements', [], 'Admin.Catalog.Feature'), - 'no_product' => $this->translator->trans('No product matches your search. Try changing search terms.', [], 'Admin.Catalog.Notification'), - 'none' => $this->translator->trans('None', [], 'Admin.Catalog.Feature'), - 'notification_stock_updated' => $this->translator->trans('Stock successfully updated', [], 'Admin.Catalog.Notification'), - 'product_search' => $this->translator->trans('Search products (search by name, reference, supplier)', [], 'Admin.Catalog.Feature'), - 'product_low_stock' => $this->translator->trans('This product is below the low stock level you have defined.', [], 'Admin.Catalog.Feature'), - 'product_low_stock_level' => $this->translator->trans('Low stock level:', [], 'Admin.Catalog.Feature'), - 'product_low_stock_alert' => $this->translator->trans('Low stock alert:', [], 'Admin.Catalog.Feature'), - 'title_available' => $this->translator->trans('Available', [], 'Admin.Global'), - 'title_bulk' => $this->translator->trans('Bulk edit quantity', [], 'Admin.Catalog.Feature'), - 'title_date' => $this->translator->trans('Date & Time', [], 'Admin.Catalog.Feature'), - 'title_edit_quantity' => $this->translator->trans('Edit quantity', [], 'Admin.Catalog.Feature'), - 'title_employee' => $this->translator->trans('Employee', [], 'Admin.Global'), - 'title_import' => $this->translator->trans('Go to the import system', [], 'Admin.Catalog.Feature'), - 'title_export' => $this->translator->trans('Export data into CSV', [], 'Admin.Catalog.Feature'), - 'title_movements_type' => $this->translator->trans('Type', [], 'Admin.Global'), - 'title_physical' => $this->translator->trans('Physical', [], 'Admin.Catalog.Feature'), - 'title_product' => $this->translator->trans('Product', [], 'Admin.Global'), - 'title_reference' => $this->translator->trans('Reference', [], 'Admin.Global'), - 'title_reserved' => $this->translator->trans('Reserved', [], 'Admin.Catalog.Feature'), - 'title_status' => $this->translator->trans('Status', [], 'Admin.Global'), - 'title_supplier' => $this->translator->trans('Supplier', [], 'Admin.Global'), - 'title_quantity' => $this->translator->trans('Quantity', [], 'Admin.Global'), - 'tree_expand' => $this->translator->trans('Expand', [], 'Admin.Actions'), - 'tree_reduce' => $this->translator->trans('Collapse', [], 'Admin.Actions'), - ]; - } -} diff --git a/src/PrestaShopBundle/Translation/Constraints/PassVsprintf.php b/src/PrestaShopBundle/Translation/Constraints/PassVsprintf.php deleted file mode 100644 index 0a304577..00000000 --- a/src/PrestaShopBundle/Translation/Constraints/PassVsprintf.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Constraints; - -use Symfony\Component\Validator\Constraint; - -/** - * @Annotation - * @Target({"CLASS", "ANNOTATION"}) - */ -class PassVsprintf extends Constraint -{ - public $message = 'You must specify as many arguments (%d, %s ...) as the original string.'; - - public function getTargets() - { - return static::CLASS_CONSTRAINT; - } -} diff --git a/src/PrestaShopBundle/Translation/Constraints/PassVsprintfValidator.php b/src/PrestaShopBundle/Translation/Constraints/PassVsprintfValidator.php deleted file mode 100644 index 90f2773e..00000000 --- a/src/PrestaShopBundle/Translation/Constraints/PassVsprintfValidator.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Constraints; - -use Exception; -use PrestaShopBundle\Entity\Translation; -use PrestaShopBundle\Translation\PrestaShopTranslatorTrait; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; - -class PassVsprintfValidator extends ConstraintValidator -{ - public function validate($translation, Constraint $constraint) - { - if (!$constraint instanceof PassVsprintf) { - throw new UnexpectedTypeException($constraint, 'PrestaShopBundle\Translation\Constraints\PassVsprintf'); - } - - if (!$translation instanceof Translation) { - throw new UnexpectedTypeException($translation, 'PrestaShopBundle\Entity\Translation'); - } - - if ($this->countArgumentsOfTranslation($translation->getKey()) != $this->countArgumentsOfTranslation($translation->getTranslation())) { - $this->context->buildViolation($constraint->message) - ->addViolation(); - } - } - - private function countArgumentsOfTranslation($property) - { - $matches = []; - if (preg_match_all(PrestaShopTranslatorTrait::$regexSprintfParams, $property, $matches) === false) { - throw new Exception('Preg_match failed'); - } - - return count($matches[0]); - } -} diff --git a/src/PrestaShopBundle/Translation/DataCollectorTranslator.php b/src/PrestaShopBundle/Translation/DataCollectorTranslator.php deleted file mode 100644 index 77f492df..00000000 --- a/src/PrestaShopBundle/Translation/DataCollectorTranslator.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use Symfony\Component\Translation\DataCollectorTranslator as BaseTranslator; - -class DataCollectorTranslator extends BaseTranslator -{ - use PrestaShopTranslatorTrait; -} diff --git a/src/PrestaShopBundle/Translation/DomainNormalizer.php b/src/PrestaShopBundle/Translation/DomainNormalizer.php deleted file mode 100644 index 53c7fb0f..00000000 --- a/src/PrestaShopBundle/Translation/DomainNormalizer.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use RuntimeException; - -/** - * Normalizes domain names by removing dots - */ -class DomainNormalizer -{ - /** - * @param string $domain Domain name - * - * @return string - * - * @throws RuntimeException - */ - public function normalize($domain) - { - // remove up to two dots from the domain name - // (because legacy domain translations CAN have dots in the third part) - $normalizedDomain = preg_replace('/\./', '', $domain, 2); - - if ($normalizedDomain === null) { - throw new RuntimeException(sprintf('An error occurred while normalizing domain "%s"', $domain)); - } - - return $normalizedDomain; - } -} diff --git a/src/PrestaShopBundle/Translation/Exception/InvalidLegacyTranslationKeyException.php b/src/PrestaShopBundle/Translation/Exception/InvalidLegacyTranslationKeyException.php deleted file mode 100644 index fa56dc36..00000000 --- a/src/PrestaShopBundle/Translation/Exception/InvalidLegacyTranslationKeyException.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Exception; - -/** - * Thrown when an invalid key is found in a legacy translation file - */ -class InvalidLegacyTranslationKeyException extends \Exception -{ - /** - * @var string The invalid key - */ - private $key = ''; - - /** - * @param string $missingElement The missing element - * @param string $key The offending key - * - * @return InvalidLegacyTranslationKeyException - */ - public static function missingElementFromKey($missingElement, $key) - { - $instance = new self( - sprintf('Invalid key in legacy translation file: "%s" (missing %s)', $key, $missingElement) - ); - $instance->setKey($key); - - return $instance; - } - - /** - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * @param string $key - */ - private function setKey($key) - { - $this->key = $key; - } -} diff --git a/src/PrestaShopBundle/Translation/Exception/LegacyFileFormattingException.php b/src/PrestaShopBundle/Translation/Exception/LegacyFileFormattingException.php deleted file mode 100644 index fb631499..00000000 --- a/src/PrestaShopBundle/Translation/Exception/LegacyFileFormattingException.php +++ /dev/null @@ -1,53 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Exception; - -use Symfony\Component\Translation\Exception\InvalidResourceException; - -/** - * Will be thrown if a legacy file for a locale is found, but invalid. - */ -final class LegacyFileFormattingException extends InvalidResourceException -{ - /** - * @param string $filePath the expected file path of the translations - * @param string $locale the translation locale - * - * @return self - */ - public static function fileIsInvalid($filePath, $locale) - { - $exceptionMessage = sprintf( - 'The locale "%s" is not supported, because we have found an invalid file in the module. - Have you updated the file "%s" manually?', - $locale, - $filePath - ); - - return new self($exceptionMessage); - } -} diff --git a/src/PrestaShopBundle/Translation/Exception/UnsupportedLocaleException.php b/src/PrestaShopBundle/Translation/Exception/UnsupportedLocaleException.php deleted file mode 100644 index 87a52802..00000000 --- a/src/PrestaShopBundle/Translation/Exception/UnsupportedLocaleException.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Exception; - -use Symfony\Component\Translation\Exception\NotFoundResourceException; - -/** - * Will be thrown if a locale is not supported in Legacy format - */ -final class UnsupportedLocaleException extends NotFoundResourceException -{ - /** - * @param string $filePath the expected file path of the translations - * @param string $locale the translation locale - * - * @return self - */ - public static function fileNotFound($filePath, $locale) - { - $exceptionMessage = sprintf( - 'The locale "%s" is not supported, because we can\'t find the related file in the module: - have you created the file "%s"?', - $locale, - $filePath - ); - - return new self($exceptionMessage); - } - - /** - * @param string $locale the translation locale - * - * @return self - */ - public static function invalidLocale($locale) - { - $exceptionMessage = sprintf( - 'The provided locale `%s` is invalid.', - $locale - ); - - return new self($exceptionMessage); - } -} diff --git a/src/PrestaShopBundle/Translation/Exception/UnsupportedModuleException.php b/src/PrestaShopBundle/Translation/Exception/UnsupportedModuleException.php deleted file mode 100644 index e836ee27..00000000 --- a/src/PrestaShopBundle/Translation/Exception/UnsupportedModuleException.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Exception; - -use Symfony\Component\Translation\Exception\NotFoundResourceException; - -/** - * Will be thrown if a module name is required by a provider and not set. - */ -final class UnsupportedModuleException extends NotFoundResourceException -{ - /** - * @param string $providerIdentifier the provider identifier - * - * @return self - */ - public static function moduleNotProvided($providerIdentifier) - { - $exceptionMessage = sprintf( - 'The translation provider with the identifier "%s" require a module to be set.', - $providerIdentifier - ); - - return new self($exceptionMessage); - } -} diff --git a/src/PrestaShopBundle/Translation/Exporter/ThemeExporter.php b/src/PrestaShopBundle/Translation/Exporter/ThemeExporter.php deleted file mode 100644 index 11ff4f19..00000000 --- a/src/PrestaShopBundle/Translation/Exporter/ThemeExporter.php +++ /dev/null @@ -1,410 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Exporter; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeRepository; -use PrestaShop\TranslationToolsBundle\Translation\Dumper\XliffFileDumper; -use PrestaShop\TranslationToolsBundle\Translation\Extractor\Util\Flattenizer; -use PrestaShopBundle\Translation\Extractor\ThemeExtractor; -use PrestaShopBundle\Translation\Provider\ThemeProvider; -use PrestaShopBundle\Utils\ZipManager; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\MessageCatalogue; - -class ThemeExporter -{ - /** - * @var ThemeExtractor the theme extractor - */ - private $themeExtractor; - - /** - * @var ThemeProvider the theme provider - */ - private $themeProvider; - - /** - * @var ZipManager the zip manager - */ - private $zipManager; - - /** - * @var ThemeRepository the theme repository - */ - private $themeRepository; - - /** - * @var XliffFileDumper the Xliff dumper - */ - private $dumper; - - /** - * @var Filesystem the Filesystem - */ - private $filesystem; - - /** - * @var string the cache directory path - */ - public $cacheDir; - - /** - * @var string the export directory path - */ - public $exportDir; - - public function __construct( - ThemeExtractor $themeExtractor, - ThemeProvider $themeProvider, - ThemeRepository $themeRepository, - XliffFileDumper $dumper, - ZipManager $zipManager, - Filesystem $filesystem - ) { - $this->themeExtractor = $themeExtractor; - $this->themeExtractor - ->setThemeProvider($themeProvider); - - $this->themeProvider = $themeProvider; - $this->themeRepository = $themeRepository; - $this->dumper = $dumper; - $this->zipManager = $zipManager; - $this->filesystem = $filesystem; - } - - /** - * @param string $themeName - * @param string $locale - * @param bool $rootDir - * - * @return string - */ - public function createZipArchive($themeName, $locale, $rootDir = false) - { - $archiveParentDirectory = $this->exportCatalogues($themeName, $locale, $rootDir); - $zipFilename = $this->makeZipFilename($themeName, $locale); - $this->zipManager->createArchive($zipFilename, $archiveParentDirectory); - - return $zipFilename; - } - - /** - * @param string $themeName - * @param string $locale - * @param bool $rootDir - * - * @return string - */ - public function exportCatalogues($themeName, $locale, $rootDir = false) - { - $this->themeProvider->setLocale($locale); - $this->themeProvider->setThemeName($themeName); - - $mergedTranslations = $this->getCatalogueExtractedFromTemplates($themeName, $locale, $rootDir); - - try { - $themeCatalogue = $this->themeProvider->getThemeCatalogue(); - } catch (\Exception $exception) { - $themeCatalogue = new MessageCatalogue($locale, []); - } - $databaseCatalogue = $this->themeProvider->getDatabaseCatalogue($themeName); - $databaseCatalogue = $this->addLocaleToDomain($locale, $databaseCatalogue); - - $mergedTranslations->addCatalogue($themeCatalogue); - $mergedTranslations->addCatalogue($databaseCatalogue); - - $this->updateCatalogueMetadata($mergedTranslations); - - $archiveParentDirectory = $this->makeArchiveParentDirectory($themeName, $locale); - - if ($this->ensureFileBelongsToExportDirectory($archiveParentDirectory)) { - // Clean up previously exported archives - $this->filesystem->remove($archiveParentDirectory); - } - - $this->filesystem->mkdir($archiveParentDirectory); - - $this->dumper->dump($mergedTranslations, [ - 'path' => $archiveParentDirectory, - 'default_locale' => $locale, - 'root_dir' => $rootDir, - ]); - - $this->renameCatalogues($locale, $archiveParentDirectory); - - return $archiveParentDirectory; - } - - /** - * @param string $exportDir - */ - public function setExportDir($exportDir) - { - $this->exportDir = str_replace('/export', DIRECTORY_SEPARATOR . 'export', $exportDir); - } - - /** - * @param string $filePath - * - * @return bool - * - * @throws \Exception - */ - protected function ensureFileBelongsToExportDirectory($filePath) - { - if (!$this->filesystem->exists($filePath)) { - return false; - } - - $validFileLocation = substr(realpath($filePath), 0, strlen(realpath($this->exportDir))) === realpath($this->exportDir); - - if (!$validFileLocation) { - throw new \Exception('Invalid file location. This file should belong to the export directory'); - } - - return $validFileLocation; - } - - /** - * @param string $themeName - * @param string $locale - * @param bool $rootDir - * - * @return \Symfony\Component\Translation\MessageCatalogue - */ - protected function getCatalogueExtractedFromTemplates($themeName, $locale, $rootDir = false) - { - $tmpFolderPath = $this->getTemporaryExtractionFolder($themeName); - $folderPath = $this->getFlattenizationFolder($themeName); - - $this->filesystem->remove($folderPath); - $this->filesystem->remove($tmpFolderPath); - - $this->filesystem->mkdir($folderPath); - $this->filesystem->mkdir($tmpFolderPath); - - $theme = $this->themeRepository->getInstanceByName($themeName); - $this->themeExtractor - ->setOutputPath($tmpFolderPath) - ->extract($theme, $locale, $rootDir); - - Flattenizer::flatten($tmpFolderPath . DIRECTORY_SEPARATOR . $locale, $folderPath . DIRECTORY_SEPARATOR . $locale, $locale); - - return $this->themeProvider->getCatalogueFromPaths($folderPath, $locale, '*'); - } - - /** - * @param string $locale - * @param string $archiveParentDirectory - */ - protected function renameCatalogues($locale, $archiveParentDirectory) - { - $finder = Finder::create(); - - foreach ($finder->in($archiveParentDirectory . DIRECTORY_SEPARATOR . $locale)->files() as $file) { - $parentDirectoryParts = explode(DIRECTORY_SEPARATOR, dirname($file)); - $destinationFilenameParts = [ - $archiveParentDirectory, - $parentDirectoryParts[count($parentDirectoryParts) - 1] . '.' . $locale . '.xlf', - ]; - $destinationFilename = implode(DIRECTORY_SEPARATOR, $destinationFilenameParts); - if ($this->filesystem->exists($destinationFilename)) { - $this->filesystem->remove($destinationFilename); - } - $this->filesystem->rename($file->getPathname(), $destinationFilename); - } - - $this->filesystem->remove($archiveParentDirectory . DIRECTORY_SEPARATOR . $locale); - } - - /** - * @param string $themeName - */ - public function cleanArtifacts($themeName) - { - $this->filesystem->remove($this->getFlattenizationFolder($themeName)); - $this->filesystem->remove($this->getTemporaryExtractionFolder($themeName)); - } - - /** - * @param string $themeName - * - * @return string - */ - protected function getTemporaryExtractionFolder($themeName) - { - return $this->cacheDir . DIRECTORY_SEPARATOR . $themeName . '-tmp'; - } - - /** - * @param string $themeName - * - * @return string - */ - protected function getFlattenizationFolder($themeName) - { - return $this->cacheDir . DIRECTORY_SEPARATOR . $themeName; - } - - /** - * @param string $themeName - * - * @return string - */ - protected function getExportDir($themeName) - { - return $this->exportDir . DIRECTORY_SEPARATOR . $themeName; - } - - /** - * @param string $themeName - * @param string $locale - * - * @return string - */ - protected function makeZipFilename($themeName, $locale) - { - if (!file_exists($this->exportDir)) { - mkdir($this->exportDir); - } - - $zipFilenameParts = [ - $this->exportDir, - $themeName, - $locale, - $themeName . '.' . $locale . '.zip', - ]; - - return implode(DIRECTORY_SEPARATOR, $zipFilenameParts); - } - - /** - * @param string $themeName - * @param string $locale - * - * @return string - * - * @throws \Exception - */ - protected function makeArchiveParentDirectory($themeName, $locale) - { - $zipFilename = $this->makeZipFilename($themeName, $locale); - - return dirname($zipFilename); - } - - /** - * @param MessageCatalogue $catalogue - */ - protected function updateCatalogueMetadata(MessageCatalogue $catalogue) - { - foreach ($catalogue->all() as $domain => $messages) { - $this->ensureCatalogueHasRequiredMetadata($catalogue, $messages, $domain); - } - } - - /** - * @param MessageCatalogue $catalogue - * @param array $messages - * @param string $domain - */ - protected function ensureCatalogueHasRequiredMetadata( - MessageCatalogue $catalogue, - array $messages, - $domain - ) { - foreach (array_keys($messages) as $id) { - $metadata = $catalogue->getMetadata($id, $domain); - if ($this->shouldAddFileMetadata($metadata)) { - $catalogue->setMetadata($id, $this->parseMetadataNotes($metadata), $domain); - } - } - } - - /** - * @param array|null $metadata - * - * @return bool - */ - protected function metadataContainNotes(array $metadata = null) - { - return null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes']) && - array_key_exists(0, $metadata['notes']) && is_array($metadata['notes'][0]) && - array_key_exists('content', $metadata['notes'][0]); - } - - /** - * @param array|null $metadata - * - * @return bool - */ - protected function shouldAddFileMetadata(array $metadata = null) - { - return null === $metadata || !array_key_exists('file', $metadata); - } - - /** - * @param string $locale - * @param MessageCatalogue $sourceCatalogue - * - * @return MessageCatalogue - */ - protected function addLocaleToDomain($locale, MessageCatalogue $sourceCatalogue) - { - $catalogue = new MessageCatalogue($locale, []); - foreach ($sourceCatalogue->all() as $domain => $messages) { - $catalogue->add($messages, $domain . '.' . $locale); - } - - return $catalogue; - } - - /** - * @param array|null $metadata - * - * @return array - */ - protected function parseMetadataNotes(array $metadata = null) - { - $defaultMetadata = ['file' => '', 'line' => '']; - - if (!$this->metadataContainNotes($metadata)) { - return $defaultMetadata; - } - - $notes = $metadata['notes'][0]['content']; - if (1 !== preg_match('/(?\S+):(?\S+)/m', $notes, $matches)) { - return $defaultMetadata; - } - - return [ - 'file' => $matches['file'], - 'line' => $matches['line'], - ]; - } -} diff --git a/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractor.php b/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractor.php deleted file mode 100644 index 612e8af5..00000000 --- a/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractor.php +++ /dev/null @@ -1,127 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Extractor; - -use PrestaShop\TranslationToolsBundle\Translation\Helper\DomainHelper; -use Symfony\Component\Translation\Extractor\ExtractorInterface; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Able to convert old translation files (in translations/es.php) into - * Symfony MessageCatalogue objects. - */ -final class LegacyModuleExtractor implements LegacyModuleExtractorInterface -{ - /** - * @var ExtractorInterface the PHP Code extractor - */ - private $phpExtractor; - - /** - * @var ExtractorInterface the Smarty Code extractor - */ - private $smartyExtractor; - - /** - * @var ExtractorInterface the Twig Code extractor - */ - private $twigExtractor; - - /** - * @var string the "modules" directory path - */ - private $modulesDirectory; - - /** - * @param ExtractorInterface $phpExtractor - * @param ExtractorInterface $smartyExtractor - * @param ExtractorInterface $twigExtractor - * @param string $modulesDirectory - */ - public function __construct( - ExtractorInterface $phpExtractor, - ExtractorInterface $smartyExtractor, - ExtractorInterface $twigExtractor, - $modulesDirectory - ) { - $this->phpExtractor = $phpExtractor; - $this->smartyExtractor = $smartyExtractor; - $this->twigExtractor = $twigExtractor; - $this->modulesDirectory = $modulesDirectory; - } - - /** - * {@inheritdoc} - * - * WARNING: The domains in the returned catalogue are dot-separated - */ - public function extract($moduleName, $locale) - { - $extractedCatalogue = new MessageCatalogue($locale); - - $this->phpExtractor->extract($this->modulesDirectory . '/' . $moduleName, $extractedCatalogue); - $extractedCatalogue = $this->postprocessPhpCatalogue($extractedCatalogue, $moduleName); - - $this->smartyExtractor->extract($this->modulesDirectory . '/' . $moduleName, $extractedCatalogue); - $this->twigExtractor->extract($this->modulesDirectory . '/' . $moduleName, $extractedCatalogue); - - return $extractedCatalogue; - } - - /** - * Modules usually don't use domain names when calling the l() function in PHP files. - * Therefore, the PHP extractor will stores those calls in the default domain named "messages". - * This process moves all wordings in the "messages" domain to the inferred module domain. - * - * @param MessageCatalogue $extractedCatalogue - * @param string $moduleName - * - * @return MessageCatalogue - */ - private function postprocessPhpCatalogue(MessageCatalogue $extractedCatalogue, $moduleName) - { - $defaultDomain = 'messages'; - - if (!in_array($defaultDomain, $extractedCatalogue->getDomains())) { - return $extractedCatalogue; - } - - $newDomain = DomainHelper::buildModuleDomainFromLegacySource($moduleName, ''); - - $allWordings = $extractedCatalogue->all(); - - // move default domain into the new domain (avoiding to overwrite existing translations) - $allWordings[$newDomain] = (isset($allWordings[$newDomain])) - ? array_merge($allWordings[$newDomain], $allWordings[$defaultDomain]) - : $allWordings[$defaultDomain]; - - unset($allWordings[$defaultDomain]); - - return new MessageCatalogue($extractedCatalogue->getLocale(), $allWordings); - } -} diff --git a/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractorInterface.php b/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractorInterface.php deleted file mode 100644 index a3825896..00000000 --- a/src/PrestaShopBundle/Translation/Extractor/LegacyModuleExtractorInterface.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Extractor; - -use Symfony\Component\Translation\MessageCatalogueInterface; - -/** - * Parse code content of module, searching for l() calls and retrieve - * a Message Catalogue with all the keys and translations. - */ -interface LegacyModuleExtractorInterface -{ - /** - * Extracts the wordings from source code and returns the translation messages. - * Note that domain names will contain separating dots. - * - * @param string $moduleName - * @param string $locale The locale used for the message catalogue. Note that wordings won't be translated in this locale. - * - * @return MessageCatalogueInterface - */ - public function extract($moduleName, $locale); -} diff --git a/src/PrestaShopBundle/Translation/Extractor/ThemeExtractor.php b/src/PrestaShopBundle/Translation/Extractor/ThemeExtractor.php deleted file mode 100644 index 3a27dcc6..00000000 --- a/src/PrestaShopBundle/Translation/Extractor/ThemeExtractor.php +++ /dev/null @@ -1,290 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Extractor; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShop\TranslationToolsBundle\Translation\Dumper\XliffFileDumper; -use PrestaShop\TranslationToolsBundle\Translation\Extractor\SmartyExtractor; -use PrestaShopBundle\Translation\Provider\ThemeProvider; -use Symfony\Component\Translation\Dumper\DumperInterface; -use Symfony\Component\Translation\Dumper\FileDumper; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Extract all theme translations from Theme templates. - * - * xliff is the default file format, you can add custom File dumpers. - */ -class ThemeExtractor -{ - /** - * @var MessageCatalogue|null the Message catalogue - */ - private $catalog; - - /** - * @var array the list of Translation dumpers - */ - private $dumpers = []; - - /** - * @var string the format of extracted files - */ - private $format = 'xlf'; - - /** - * @var string the output path for extraction - */ - private $outputPath; - - /** - * @var SmartyExtractor the Smarty Extractor - */ - private $smartyExtractor; - - /** - * @var ThemeProvider the Theme Provider - */ - private $themeProvider; - - /** - * @var bool checks wether we should override the database with results or not - */ - private $overrideFromDatabase = false; - - public function __construct(SmartyExtractor $smartyExtractor) - { - $this->smartyExtractor = $smartyExtractor; - $this->dumpers[] = new XliffFileDumper(); - } - - /** - * @param ThemeProvider $themeProvider - * - * @return $this - */ - public function setThemeProvider(ThemeProvider $themeProvider) - { - $this->themeProvider = $themeProvider; - - return $this; - } - - /** - * @param Theme $theme - * @param string $locale - * @param bool $rootDir - * - * @return mixed - * - * @throws \Exception - */ - public function extract(Theme $theme, $locale = 'en-US', $rootDir = false) - { - $this->catalog = new MessageCatalogue($locale); - // remove the last "/" - $themeDirectory = substr($theme->getDirectory(), 0, -1); - - $options = [ - 'path' => $themeDirectory, - 'default_locale' => $locale, - 'root_dir' => $rootDir, - ]; - $this->smartyExtractor->extract($themeDirectory, $this->catalog); - - $this->overrideFromDefaultCatalog($locale, $this->catalog); - - if ($this->overrideFromDatabase) { - $this->overrideFromDatabase($theme->getName(), $locale, $this->catalog); - } - - foreach ($this->dumpers as $dumper) { - if ($this->format === $dumper->getExtension()) { - if (null !== $this->outputPath) { - $options['path'] = $this->outputPath; - } - - return $dumper->dump($this->catalog, $options); - } - } - - throw new \LogicException(sprintf('The format %s is not supported.', $this->format)); - } - - /** - * Add default catalogue in this &$catalogue when the translation exists. - * - * @param string $locale - * @param MessageCatalogue $catalogue - */ - private function overrideFromDefaultCatalog($locale, &$catalogue) - { - $defaultCatalogue = $this->themeProvider - ->setLocale($locale) - ->getDefaultCatalogue(); - - if (empty($defaultCatalogue)) { - return; - } - - $defaultCatalogue = $defaultCatalogue->all(); - - if (empty($defaultCatalogue)) { - return; - } - - $defaultDomainsCatalogue = $catalogue->getDomains(); - - foreach ($defaultCatalogue as $domain => $translation) { - // AdminCatalogFeature.fr-FR to AdminCatalogFeature - $domain = str_replace('.' . $locale, '', $domain); - - // AdminCatalogFeature to Admin.Catalog.Feature - $domain = implode('.', preg_split('/(?=[A-Z])/', $domain, -1, PREG_SPLIT_NO_EMPTY)); - - if (in_array($domain, $defaultDomainsCatalogue, true)) { - foreach ($translation as $key => $trans) { - if ($catalogue->has($key, $domain)) { - $catalogue->set($key, $trans, $domain); - } - } - } - } - } - - /** - * Add database catalogue in this &$catalogue. - * - * @param string $themeName - * @param string $locale - * @param MessageCatalogue $catalogue - * - * @throws \Exception - */ - private function overrideFromDatabase($themeName, $locale, &$catalogue) - { - if (null === $this->themeProvider) { - throw new \Exception('Theme provider is required.'); - } - - $databaseCatalogue = $this->themeProvider - ->setLocale($locale) - ->setThemeName($themeName) - ->getDatabaseCatalogue(); - - $catalogue->addCatalogue($databaseCatalogue); - } - - /** - * @param FileDumper $dumper - * - * @return $this - */ - public function addDumper(FileDumper $dumper) - { - $this->dumpers[] = $dumper; - - return $this; - } - - /** - * @return DumperInterface[] - */ - public function getDumpers() - { - return $this->dumpers; - } - - /** - * @param string $format - * - * @return $this - */ - public function setFormat($format) - { - $this->format = $format; - - return $this; - } - - /** - * @return string - */ - public function getFormat() - { - return $this->format; - } - - /** - * @param $outputPath - * - * @return $this - */ - public function setOutputPath($outputPath) - { - $this->outputPath = $outputPath; - - return $this; - } - - /** - * @return string - */ - public function getOutputPath() - { - return $this->outputPath; - } - - /** - * @return MessageCatalogue|null - */ - public function getCatalog() - { - return $this->catalog; - } - - /** - * @return $this - */ - public function disableOverridingFromDatabase() - { - $this->overrideFromDatabase = false; - - return $this; - } - - /** - * @return $this - */ - public function enableOverridingFromDatabase() - { - $this->overrideFromDatabase = true; - - return $this; - } -} diff --git a/src/PrestaShopBundle/Translation/Factory/ProviderNotFoundException.php b/src/PrestaShopBundle/Translation/Factory/ProviderNotFoundException.php deleted file mode 100644 index 20e5de84..00000000 --- a/src/PrestaShopBundle/Translation/Factory/ProviderNotFoundException.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Factory; - -use Exception; - -/** - * Thrown if no provider is found for the selected identifier. - */ -class ProviderNotFoundException extends Exception -{ - public function __construct($identifier) - { - parent::__construct(sprintf('The provider with the identifier %s is not found.', $identifier), 0, null); - } -} diff --git a/src/PrestaShopBundle/Translation/Factory/ThemeTranslationsFactory.php b/src/PrestaShopBundle/Translation/Factory/ThemeTranslationsFactory.php deleted file mode 100644 index 3d2159c3..00000000 --- a/src/PrestaShopBundle/Translation/Factory/ThemeTranslationsFactory.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Factory; - -use PrestaShopBundle\Translation\Provider\ThemeProvider; - -/** - * This class returns a collection of translations, using locale and identifier. - * - * But in this particular case, the identifier is the theme name. - * - * Returns MessageCatalogue object or Translation tree array. - */ -class ThemeTranslationsFactory extends TranslationsFactory -{ - /** - * @var ThemeProvider the theme provider - */ - private $themeProvider; - - public function __construct(ThemeProvider $themeProvider) - { - $this->themeProvider = $themeProvider; - } - - /** - * {@inheritdoc} - */ - public function createCatalogue($themeName, $locale = 'en_US') - { - return $this->themeProvider - ->setThemeName($themeName) - ->setLocale($locale) - ->getMessageCatalogue(); - } - - /** - * {@inheritdoc} - */ - public function createTranslationsArray($themeName, $locale = 'en_US', $theme = null, $search = null) - { - $this->themeProvider - ->setThemeName($themeName) - ->setLocale($locale) - ->synchronizeTheme(); - - $translations = $this->getFrontTranslationsForThemeAndLocale($themeName, $locale, $search); - - ksort($translations); - - return $translations; - } - - /** - * @param string $locale the catalogue locale - * @param string $domain the catalogue domain - * - * @return string - */ - protected function removeLocaleFromDomain($locale, $domain) - { - return str_replace('.' . $locale, '', $domain); - } - - /** - * @param string $themeName the theme name - * @param string $locale the catalogue locale - * @param string|null $search - * - * @throws ProviderNotFoundException - * - * @return array - */ - protected function getFrontTranslationsForThemeAndLocale($themeName, $locale, $search = null) - { - return parent::createTranslationsArray('theme', $locale, $themeName, $search); - } -} diff --git a/src/PrestaShopBundle/Translation/Factory/TranslationsFactory.php b/src/PrestaShopBundle/Translation/Factory/TranslationsFactory.php deleted file mode 100644 index 6306dd9c..00000000 --- a/src/PrestaShopBundle/Translation/Factory/TranslationsFactory.php +++ /dev/null @@ -1,82 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Factory; - -use PrestaShopBundle\Translation\Provider\AbstractProvider; -use PrestaShopBundle\Translation\View\TreeBuilder; - -/** - * This class returns a collection of translations, using a locale and an identifier. - * - * Returns MessageCatalogue object or Translation tree array. - */ -class TranslationsFactory implements TranslationsFactoryInterface -{ - /** - * @var array the list of translation providers - */ - private $providers = []; - - /** - * {@inheritdoc} - */ - public function createCatalogue($domainIdentifier, $locale = 'en_US') - { - foreach ($this->providers as $provider) { - if ($domainIdentifier === $provider->getIdentifier()) { - return $provider->setLocale($locale)->getMessageCatalogue(); - } - } - - throw new ProviderNotFoundException($domainIdentifier); - } - - /** - * {@inheritdoc} - */ - public function createTranslationsArray($domainIdentifier, $locale = self::DEFAULT_LOCALE, $theme = null, $search = null) - { - foreach ($this->providers as $provider) { - if ($domainIdentifier === $provider->getIdentifier()) { - $treeBuilder = new TreeBuilder($locale, $theme); - - return $treeBuilder->makeTranslationArray($provider, $search); - } - } - - throw new ProviderNotFoundException($domainIdentifier); - } - - /** - * @param AbstractProvider $provider - */ - public function addProvider(AbstractProvider $provider) - { - $this->providers[] = $provider; - } -} diff --git a/src/PrestaShopBundle/Translation/Factory/TranslationsFactoryInterface.php b/src/PrestaShopBundle/Translation/Factory/TranslationsFactoryInterface.php deleted file mode 100644 index a3fe9fbd..00000000 --- a/src/PrestaShopBundle/Translation/Factory/TranslationsFactoryInterface.php +++ /dev/null @@ -1,61 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Factory; - -use Symfony\Component\Translation\MessageCatalogueInterface; - -interface TranslationsFactoryInterface -{ - const DEFAULT_LOCALE = 'en_US'; - - /** - * Generates extract of global Catalogue, using domain's identifiers. - * - * @param string $identifier Domain identifier - * @param string $locale Locale identifier - * - * @throws ProviderNotFoundException - * - * @return MessageCatalogueInterface - */ - public function createCatalogue($identifier, $locale = self::DEFAULT_LOCALE); - - /** - * Generates Translation tree in Back Office. - * - * @param string $domainIdentifier Domain identifier - * @param string $locale Locale identifier - * @param null $theme - * @param null $search - * - * @throws ProviderNotFoundException - * - * @return array Translation tree structure - */ - public function createTranslationsArray($domainIdentifier, $locale = self::DEFAULT_LOCALE, $theme = null, $search = null); -} diff --git a/src/PrestaShopBundle/Translation/Loader/DatabaseTranslationLoader.php b/src/PrestaShopBundle/Translation/Loader/DatabaseTranslationLoader.php deleted file mode 100644 index 6d4e85c8..00000000 --- a/src/PrestaShopBundle/Translation/Loader/DatabaseTranslationLoader.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Loader; - -use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\QueryBuilder; -use PrestaShopBundle\Entity\Lang; -use PrestaShopBundle\Entity\Translation; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; - -class DatabaseTranslationLoader implements LoaderInterface -{ - /** @var EntityManagerInterface */ - protected $entityManager; - - /** - * @param EntityManagerInterface $entityManager - */ - public function __construct(EntityManagerInterface $entityManager) - { - $this->entityManager = $entityManager; - } - - /** - * {@inheritdoc} - * - * @todo: this method doesn't match the interface - */ - public function load($resource, $locale, $domain = 'messages', $theme = null) - { - static $langs = []; - $catalogue = new MessageCatalogue($locale); - - // do not try and load translations for a locale that cannot be saved to DB anyway - if ($locale === 'default') { - return $catalogue; - } - - if (!array_key_exists($locale, $langs)) { - $langs[$locale] = $this->entityManager - ->getRepository('PrestaShopBundle:Lang') - ->findOneByLocale($locale); - } - - $translationRepository = $this->entityManager - ->getRepository('PrestaShopBundle:Translation'); - - $queryBuilder = $translationRepository->createQueryBuilder('t'); - - $this->addLangConstraint($queryBuilder, $langs[$locale]); - - $this->addThemeConstraint($queryBuilder, $theme); - - $this->addDomainConstraint($queryBuilder, $domain); - - $translations = $queryBuilder - ->getQuery() - ->getResult(); - - /** @var Translation $translation */ - foreach ($translations as $translation) { - $catalogue->set($translation->getKey(), $translation->getTranslation(), $translation->getDomain()); - } - - return $catalogue; - } - - /** - * @param QueryBuilder $queryBuilder - * @param Lang $currentLang - */ - private function addLangConstraint(QueryBuilder $queryBuilder, Lang $currentLang) - { - $queryBuilder->andWhere('t.lang =:lang') - ->setParameter('lang', $currentLang); - } - - /** - * @param QueryBuilder $queryBuilder - * @param string|null $theme - */ - private function addThemeConstraint(QueryBuilder $queryBuilder, $theme) - { - if (null === $theme) { - $queryBuilder->andWhere('t.theme IS NULL'); - } else { - $queryBuilder - ->andWhere('t.theme = :theme') - ->setParameter('theme', $theme); - } - } - - /** - * @param QueryBuilder $queryBuilder - * @param string $domain - */ - private function addDomainConstraint(QueryBuilder $queryBuilder, $domain) - { - if ($domain !== '*') { - $queryBuilder->andWhere('REGEXP(t.domain, :domain) = true') - ->setParameter('domain', $domain); - } - } -} diff --git a/src/PrestaShopBundle/Translation/Loader/LegacyFileLoader.php b/src/PrestaShopBundle/Translation/Loader/LegacyFileLoader.php deleted file mode 100644 index f2d83754..00000000 --- a/src/PrestaShopBundle/Translation/Loader/LegacyFileLoader.php +++ /dev/null @@ -1,98 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Loader; - -use PrestaShop\TranslationToolsBundle\Translation\Helper\DomainHelper; -use PrestaShopBundle\Translation\DomainNormalizer; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Able to convert old translation files (in translations/es.php) into - * Symfony MessageCatalogue objects. - */ -final class LegacyFileLoader implements LoaderInterface -{ - /** - * @var LegacyFileReader - */ - private $fileReader; - - /** - * @var DomainNormalizer - */ - private $domainNormalizer; - - /** - * @param LegacyFileReader $fileReader - */ - public function __construct(LegacyFileReader $fileReader) - { - $this->fileReader = $fileReader; - $this->domainNormalizer = new DomainNormalizer(); - } - - /** - * {@inheritdoc} - * - * Note that parameter "domain" is useless, as domain is inferred from source files - * - * @throws \PrestaShopBundle\Translation\Exception\InvalidLegacyTranslationKeyException - */ - public function load($path, $locale, $domain = 'messages') - { - $catalogue = new MessageCatalogue($locale); - - $tokens = $this->fileReader->load($path, $locale); - - foreach ($tokens as $translationKey => $translationValue) { - $parsed = LegacyTranslationKey::buildFromString($translationKey); - $id = $parsed->getHash(); - $catalogue->set($id, $translationValue, $this->buildDomain($parsed)); - } - - return $catalogue; - } - - /** - * Builds the domain using information in the translation key - * - * @param LegacyTranslationKey $translationKey - * - * @return string - */ - private function buildDomain(LegacyTranslationKey $translationKey) - { - $newDomain = DomainHelper::buildModuleDomainFromLegacySource( - $translationKey->getModule(), - $translationKey->getSource() - ); - - return $this->domainNormalizer->normalize($newDomain); - } -} diff --git a/src/PrestaShopBundle/Translation/Loader/LegacyFileReader.php b/src/PrestaShopBundle/Translation/Loader/LegacyFileReader.php deleted file mode 100644 index 45d2d27b..00000000 --- a/src/PrestaShopBundle/Translation/Loader/LegacyFileReader.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Loader; - -use PrestaShop\PrestaShop\Core\Translation\Locale\Converter; -use PrestaShopBundle\Translation\Exception\UnsupportedLocaleException; - -/** - * Reads legacy locale files - */ -class LegacyFileReader -{ - /** - * @var Converter Converts IETF language tags into two-letter language code - */ - private $localeConverter; - - public function __construct(Converter $converter) - { - $this->localeConverter = $converter; - } - - /** - * Loads legacy translations from a file - * - * @param string $path Path where the locale file should be looked up - * @param string $locale IETF language tag - * - * @return array Translation tokens - */ - public function load($path, $locale) - { - // Each legacy file declare this variable to store the translations - $_MODULE = []; - - $shopLocale = $this->localeConverter->toLegacyLocale($locale); - - $filePath = $path . "$shopLocale.php"; - - if (!file_exists($filePath)) { - throw UnsupportedLocaleException::fileNotFound($filePath, $locale); - } - - // Load a global array $_MODULE - include_once $filePath; - - return $_MODULE; - } -} diff --git a/src/PrestaShopBundle/Translation/Loader/LegacyTranslationKey.php b/src/PrestaShopBundle/Translation/Loader/LegacyTranslationKey.php deleted file mode 100644 index ffe5ed13..00000000 --- a/src/PrestaShopBundle/Translation/Loader/LegacyTranslationKey.php +++ /dev/null @@ -1,128 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Loader; - -use PrestaShopBundle\Translation\Exception\InvalidLegacyTranslationKeyException; - -/** - * Parses a legacy translation key and returns its data - */ -class LegacyTranslationKey -{ - /** - * @var string the expected format of a legacy translation key - */ - const LEGACY_TRANSLATION_FORMAT = '#\<\{(?[\w-]+)\}(?[\w-]+)\>(?[\.\w_-]+)_(?[0-9a-f]+)#'; - - /** - * @var string - */ - private $module; - /** - * @var string - */ - private $theme; - /** - * @var string - */ - private $source; - - /** - * @var string - */ - private $hash; - - /** - * Parses a legacy translation key and returns its data - * - * @param string $key Legacy translation key - * - * @return LegacyTranslationKey - * - * @throws InvalidLegacyTranslationKeyException - */ - public static function buildFromString($key) - { - $matches = []; - preg_match(self::LEGACY_TRANSLATION_FORMAT, $key, $matches); - - foreach (['module', 'theme', 'source', 'hash'] as $item) { - if (!isset($matches[$item])) { - throw InvalidLegacyTranslationKeyException::missingElementFromKey($item, $key); - } - } - - return new self($matches['module'], $matches['theme'], $matches['source'], $matches['hash']); - } - - /** - * @param string $module - * @param string $theme - * @param string $source - * @param string $hash - */ - public function __construct($module, $theme, $source, $hash) - { - $this->module = $module; - $this->theme = $theme; - $this->source = $source; - $this->hash = $hash; - } - - /** - * @return string - */ - public function getModule() - { - return $this->module; - } - - /** - * @return string - */ - public function getTheme() - { - return $this->theme; - } - - /** - * @return string - */ - public function getSource() - { - return $this->source; - } - - /** - * @return string - */ - public function getHash() - { - return $this->hash; - } -} diff --git a/src/PrestaShopBundle/Translation/Loader/SqlTranslationLoader.php b/src/PrestaShopBundle/Translation/Loader/SqlTranslationLoader.php deleted file mode 100644 index 685d3ef9..00000000 --- a/src/PrestaShopBundle/Translation/Loader/SqlTranslationLoader.php +++ /dev/null @@ -1,107 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Loader; - -use Db; -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use Symfony\Component\Translation\Exception\NotFoundResourceException; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\MessageCatalogueInterface; - -class SqlTranslationLoader implements LoaderInterface -{ - /** - * @var Theme the theme - */ - protected $theme; - - /** - * @param Theme $theme the theme - * - * @return $this - */ - public function setTheme(Theme $theme) - { - $this->theme = $theme; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function load($resource, $locale, $domain = 'messages') - { - static $localeResults = []; - - if (!array_key_exists($locale, $localeResults)) { - $locale = Db::getInstance()->escape($locale, false, true); - - $localeResults[$locale] = Db::getInstance()->getRow( - 'SELECT `id_lang` - FROM `' . _DB_PREFIX_ . 'lang` - WHERE `locale` = "' . $locale . '"' - ); - } - - if (empty($localeResults[$locale])) { - throw new NotFoundResourceException(sprintf('Language not found in database: %s', $locale)); - } - - $selectTranslationsQuery = ' - SELECT `key`, `translation`, `domain` - FROM `' . _DB_PREFIX_ . 'translation` - WHERE `id_lang` = ' . $localeResults[$locale]['id_lang']; - $translations = Db::getInstance()->executeS($selectTranslationsQuery) ?: []; - - $catalogue = new MessageCatalogue($locale); - $this->addTranslationsToCatalogue($translations, $catalogue); - - if (null !== $this->theme) { - $selectThemeTranslationsQuery = - $selectTranslationsQuery . "\n" . - "AND theme = '" . $this->theme->getName() . "'"; - $themeTranslations = Db::getInstance()->executeS($selectThemeTranslationsQuery) ?: []; - $this->addTranslationsToCatalogue($themeTranslations, $catalogue); - } - - return $catalogue; - } - - /** - * @param array $translations the list of translations - * @param MessageCatalogueInterface $catalogue the Message Catalogue - */ - protected function addTranslationsToCatalogue(array $translations, MessageCatalogueInterface $catalogue) - { - foreach ($translations as $translation) { - $catalogue->set($translation['key'], $translation['translation'], $translation['domain']); - } - } -} diff --git a/src/PrestaShopBundle/Translation/PrestaShopTranslatorTrait.php b/src/PrestaShopBundle/Translation/PrestaShopTranslatorTrait.php deleted file mode 100644 index 307611e5..00000000 --- a/src/PrestaShopBundle/Translation/PrestaShopTranslatorTrait.php +++ /dev/null @@ -1,208 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use PrestaShop\PrestaShop\Adapter\Localization\LegacyTranslator; -use Symfony\Component\Translation\Exception\InvalidArgumentException; - -trait PrestaShopTranslatorTrait -{ - public static $regexSprintfParams = '#(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])#'; - public static $regexClassicParams = '/%\w+%/'; - - /** - * Translates the given message. - * - * @param string $id The message id (may also be an object that can be cast to string) - * @param array $parameters An array of parameters for the message - * @param string|null $domain The domain for the message or null to use the default - * @param string|null $locale The locale or null to use the default - * - * @return string The translated string - * - * @throws InvalidArgumentException If the locale contains invalid characters - */ - public function trans($id, array $parameters = [], $domain = null, $locale = null) - { - if (isset($parameters['legacy'])) { - $legacy = $parameters['legacy']; - unset($parameters['legacy']); - } - - $translated = parent::trans($id, [], $this->normalizeDomain($domain), $locale); - - // @todo to remove after the legacy translation system has ben phased out - if ($this->shouldFallbackToLegacyModuleTranslation($id, $domain, $translated)) { - return $this->translateUsingLegacySystem($id, $parameters, $domain, $locale); - } - - if (isset($legacy) && 'htmlspecialchars' === $legacy) { - $translated = call_user_func($legacy, $translated, ENT_NOQUOTES); - } elseif (isset($legacy)) { - $translated = call_user_func($legacy, $translated); - } - - if (!empty($parameters) && $this->isSprintfString($id)) { - $translated = vsprintf($translated, $parameters); - } elseif (!empty($parameters)) { - $translated = strtr($translated, $parameters); - } - - return $translated; - } - - /** - * Performs a reverse search in the catalogue and returns the translation key if found. - * AVOID USING THIS, IT PROVIDES APPROXIMATE RESULTS. - * - * @param string $translated Translated string - * @param string $domain Translation domain - * @param string|null $locale Unused - * - * @return string The translation - * - * @deprecated This method should not be used and will be removed - */ - public function getSourceString($translated, $domain, $locale = null) - { - if (empty($domain)) { - return $translated; - } - - $domain = str_replace('.', '', $domain); - $contextCatalog = $this->getCatalogue()->all($domain); - - if ($untranslated = array_search($translated, $contextCatalog)) { - return $untranslated; - } - - return $translated; - } - - /** - * Translates the given choice message by choosing a translation according to a number. - * - * @param string $id The message id (may also be an object that can be cast to string) - * @param int $number The number to use to find the index of the message - * @param array $parameters An array of parameters for the message - * @param string|null $domain The domain for the message or null to use the default - * @param string|null $locale The locale or null to use the default - * - * @return string The translated string - * - * @throws InvalidArgumentException If the locale contains invalid characters - */ - public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) - { - if (null !== $domain) { - $domain = str_replace('.', '', $domain); - } - - if (!$this->isSprintfString($id)) { - return parent::transChoice($id, $number, $parameters, $domain, $locale); - } - - return vsprintf(parent::transChoice($id, $number, [], $domain, $locale), $parameters); - } - - /** - * @param string $string - * - * @return bool - */ - final private function isSprintfString($string) - { - return (bool) preg_match_all(static::$regexSprintfParams, $string) - && !(bool) preg_match_all(static::$regexClassicParams, $string); - } - - /** - * Tries to translate the provided message using the legacy system - * - * @param string $message - * @param array $parameters - * @param string $domain - * @param string|null $locale - * - * @return mixed|string - * - * @throws \Exception - */ - private function translateUsingLegacySystem($message, array $parameters, $domain, $locale = null) - { - $domainParts = explode('.', $domain); - if (count($domainParts) < 2) { - throw new InvalidArgumentException(sprintf('Invalid domain: "%s"', $domain)); - } - - $moduleName = strtolower($domainParts[1]); - $sourceFile = (!empty($domainParts[2])) ? strtolower($domainParts[2]) : $moduleName; - - // translate using the legacy system WITHOUT fallback and escape to the new system (to avoid infinite loop) - return (new LegacyTranslator())->translate($moduleName, $message, $sourceFile, $parameters, false, $locale, false, false); - } - - /** - * Indicates if we should try and translate the provided wording using the legacy system. - * - * @param string $message Message to translate - * @param string $domain Translation domain - * @param string $translated Message after first translation attempt - * - * @return bool - */ - private function shouldFallbackToLegacyModuleTranslation($message, $domain, $translated) - { - return - $message === $translated - && 'Modules.' === substr($domain, 0, 8) - && ( - !method_exists($this, 'getCatalogue') - || !$this->getCatalogue()->has($message, $this->normalizeDomain($domain)) - ) - ; - } - - /** - * Returns the domain without separating dots - * - * @param string|null $domain Domain name - * - * @return string|null - */ - private function normalizeDomain($domain) - { - // remove up to two dots from the domain name - // (because legacy domain translations CAN have dots in the third part) - $normalizedDomain = (!empty($domain)) ? - (new DomainNormalizer())->normalize($domain) - : null; - - return $normalizedDomain; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/AbstractProvider.php b/src/PrestaShopBundle/Translation/Provider/AbstractProvider.php deleted file mode 100644 index 9eadf4f9..00000000 --- a/src/PrestaShopBundle/Translation/Provider/AbstractProvider.php +++ /dev/null @@ -1,273 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\PrestaShop\Core\Translation\Locale\Converter; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\MessageCatalogueInterface; - -abstract class AbstractProvider implements ProviderInterface, XliffCatalogueInterface, DatabaseCatalogueInterface -{ - const DEFAULT_LOCALE = 'en-US'; - - /** - * @var LoaderInterface the loader interface - */ - private $databaseLoader; - - /** - * @var string the resource directory - */ - protected $resourceDirectory; - - /** - * @var string the Catalogue locale - */ - protected $locale; - - /** - * @var string the Catalogue domain - */ - protected $domain; - - public function __construct(LoaderInterface $databaseLoader, $resourceDirectory) - { - $this->databaseLoader = $databaseLoader; - $this->resourceDirectory = $resourceDirectory; - $this->locale = self::DEFAULT_LOCALE; - } - - /** - * {@inheritdoc} - */ - public function getDirectories() - { - return [$this->getResourceDirectory()]; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return []; - } - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['']; - } - - /** - * {@inheritdoc} - */ - public function getLocale() - { - return $this->locale; - } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->locale = $locale; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function setDomain($domain) - { - $this->domain = $domain; - - return $this; - } - - /** - * Get the PrestaShop locale from real locale. - * - * @return string The PrestaShop locale - * - * @deprecated since 1.7.6, to be removed in the next major - */ - public function getPrestaShopLocale() - { - @trigger_error( - '`AbstractProvider::getPrestaShopLocale` function is deprecated and will be removed in the next major', - E_USER_DEPRECATED - ); - - return Converter::toPrestaShopLocale($this->locale); - } - - /** - * {@inheritdoc} - */ - public function getMessageCatalogue() - { - $messageCatalogue = $this->getDefaultCatalogue(); - - $xlfCatalogue = $this->getXliffCatalogue(); - $messageCatalogue->addCatalogue($xlfCatalogue); - - $databaseCatalogue = $this->getDatabaseCatalogue(); - - // Merge database catalogue to xliff catalogue - $messageCatalogue->addCatalogue($databaseCatalogue); - - return $messageCatalogue; - } - - /** - * {@inheritdoc} - * - * @throws FileNotFoundException - */ - public function getDefaultCatalogue($empty = true) - { - $defaultCatalogue = new MessageCatalogue($this->locale); - - foreach ($this->getFilters() as $filter) { - $filteredCatalogue = $this->getCatalogueFromPaths( - [$this->getDefaultResourceDirectory()], - $this->locale, - $filter - ); - $defaultCatalogue->addCatalogue($filteredCatalogue); - } - - if ($empty && $this->locale !== self::DEFAULT_LOCALE) { - $defaultCatalogue = $this->emptyCatalogue($defaultCatalogue); - } - - return $defaultCatalogue; - } - - /** - * {@inheritdoc} - * - * @throws FileNotFoundException - */ - public function getXliffCatalogue() - { - $xlfCatalogue = new MessageCatalogue($this->locale); - - foreach ($this->getFilters() as $filter) { - $filteredCatalogue = $this->getCatalogueFromPaths( - $this->getDirectories(), - $this->locale, - $filter - ); - $xlfCatalogue->addCatalogue($filteredCatalogue); - } - - return $xlfCatalogue; - } - - /** - * Get the Catalogue from database only. - * - * @param null $theme - * - * @return MessageCatalogue A MessageCatalogue instance - */ - public function getDatabaseCatalogue($theme = null) - { - $databaseCatalogue = new MessageCatalogue($this->locale); - - foreach ($this->getTranslationDomains() as $translationDomain) { - $domainCatalogue = $this->getDatabaseLoader()->load(null, $this->locale, $translationDomain, $theme); - - if ($domainCatalogue instanceof MessageCatalogue) { - $databaseCatalogue->addCatalogue($domainCatalogue); - } - } - - return $databaseCatalogue; - } - - /** - * @return string Path to app/Resources/translations/{locale} - */ - public function getResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . $this->locale; - } - - /** - * @return LoaderInterface The database loader - */ - public function getDatabaseLoader() - { - return $this->databaseLoader; - } - - /** - * Empties out the catalogue by removing translations but leaving keys - * - * @param MessageCatalogueInterface $messageCatalogue - * - * @return MessageCatalogueInterface Empty the catalogue - */ - public function emptyCatalogue(MessageCatalogueInterface $messageCatalogue) - { - foreach ($messageCatalogue->all() as $domain => $messages) { - foreach (array_keys($messages) as $translationKey) { - $messageCatalogue->set($translationKey, '', $domain); - } - } - - return $messageCatalogue; - } - - /** - * @param array $paths a list of paths when we can look for translations - * @param string $locale the Symfony (not the PrestaShop one) locale - * @param string|null $pattern a regular expression - * - * @return MessageCatalogue - * - * @throws FileNotFoundException - */ - public function getCatalogueFromPaths($paths, $locale, $pattern = null) - { - return (new TranslationFinder())->getCatalogueFromPaths($paths, $locale, $pattern); - } - - /** - * {@inheritdoc} - */ - abstract public function getDefaultResourceDirectory(); -} diff --git a/src/PrestaShopBundle/Translation/Provider/BackOfficeProvider.php b/src/PrestaShopBundle/Translation/Provider/BackOfficeProvider.php deleted file mode 100644 index 40c2e1b2..00000000 --- a/src/PrestaShopBundle/Translation/Provider/BackOfficeProvider.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -/** - * Main translation provider of the Back Office - */ -class BackOfficeProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return [ - '^Admin[A-Z]', - '^Modules[A-Z](.*)Admin', - ]; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return [ - '#^Admin[A-Z]#', - '#^Modules[A-Z](.*)Admin#', - ]; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'back'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/DatabaseCatalogueInterface.php b/src/PrestaShopBundle/Translation/Provider/DatabaseCatalogueInterface.php deleted file mode 100644 index de369c9b..00000000 --- a/src/PrestaShopBundle/Translation/Provider/DatabaseCatalogueInterface.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Provide an Message Catalogue from the Database - */ -interface DatabaseCatalogueInterface -{ - /** - * @param string|null $themeName the Theme name - * - * @return MessageCatalogue - */ - public function getDatabaseCatalogue($themeName = null); -} diff --git a/src/PrestaShopBundle/Translation/Provider/ExternalModuleLegacySystemProvider.php b/src/PrestaShopBundle/Translation/Provider/ExternalModuleLegacySystemProvider.php deleted file mode 100644 index 02d25cb9..00000000 --- a/src/PrestaShopBundle/Translation/Provider/ExternalModuleLegacySystemProvider.php +++ /dev/null @@ -1,322 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use InvalidArgumentException; -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use PrestaShop\TranslationToolsBundle\Translation\Helper\DomainHelper; -use PrestaShopBundle\Translation\DomainNormalizer; -use PrestaShopBundle\Translation\Exception\UnsupportedLocaleException; -use PrestaShopBundle\Translation\Exception\UnsupportedModuleException; -use PrestaShopBundle\Translation\Extractor\LegacyModuleExtractorInterface; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\MessageCatalogueInterface; - -/** - * Be able to retrieve information from legacy translation files - */ -class ExternalModuleLegacySystemProvider extends AbstractProvider implements UseDefaultCatalogueInterface, SearchProviderInterface, UseModuleInterface -{ - /** - * @var SearchProviderInterface|ModuleProvider the module provider - */ - private $moduleProvider; - - /** - * @var LoaderInterface the translation loader from legacy files - */ - private $legacyFileLoader; - - /** - * @var LegacyModuleExtractorInterface the extractor - */ - private $legacyModuleExtractor; - - /** - * @var string the module name - */ - private $moduleName; - - /** - * @var MessageCatalogue[] - */ - private $defaultCatalogueCache; - - public function __construct( - LoaderInterface $databaseLoader, - $resourceDirectory, - LoaderInterface $legacyFileLoader, - LegacyModuleExtractorInterface $legacyModuleExtractor, - SearchProviderInterface $moduleProvider - ) { - $this->moduleProvider = $moduleProvider; - $this->legacyFileLoader = $legacyFileLoader; - $this->legacyModuleExtractor = $legacyModuleExtractor; - - parent::__construct($databaseLoader, $resourceDirectory); - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#^' . preg_quote($this->domain) . '([A-Z]|$)#']; - } - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['^' . preg_quote($this->domain) . '([A-Z]|$)']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'external_legacy_module'; - } - - /** - * {@inheritdoc} - */ - public function setModuleName($moduleName) - { - if (null === $this->moduleName || empty($this->moduleName)) { - UnsupportedModuleException::moduleNotProvided(self::getIdentifier()); - } - - $this->moduleName = $moduleName; - - // ugly hack, I know - $this->domain = DomainHelper::buildModuleBaseDomain($moduleName); - - return $this; - } - - /** - * @param string $domain - * - * @return AbstractProvider|SearchProviderInterface|void - */ - public function setDomain($domain) - { - throw new InvalidArgumentException(__CLASS__ . ' does not allow calls to setDomain()'); - } - - /** - * {@inheritdoc} - */ - public function getDefaultCatalogue($empty = true) - { - $defaultCatalogue = $this->getCachedDefaultCatalogue(); - - if ($empty && $this->locale !== self::DEFAULT_LOCALE) { - return $this->emptyCatalogue(clone $defaultCatalogue); - } - - return $defaultCatalogue; - } - - /** - * {@inheritdoc} - */ - public function getXliffCatalogue() - { - try { - $translationCatalogue = $this->moduleProvider - ->setModuleName($this->moduleName) - ->setLocale($this->locale) - ->getXliffCatalogue() - ; - } catch (FileNotFoundException $exception) { - $translationCatalogue = $this->buildTranslationCatalogueFromLegacyFiles(); - } - - return $translationCatalogue; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . $this->moduleName . DIRECTORY_SEPARATOR . 'translations' . DIRECTORY_SEPARATOR; - } - - /** - * {@inheritdoc} - */ - public function getResourceDirectory() - { - return $this->getDefaultResourceDirectory(); - } - - /** - * Builds the catalogue including the translated wordings ONLY - * - * @return MessageCatalogueInterface - */ - private function buildTranslationCatalogueFromLegacyFiles() - { - // the message catalogue needs to be indexed by original wording, but legacy files are indexed by hash - // therefore, we need to build the default catalogue (by analyzing source code) - // then cross reference the wordings found in the default catalogue - // with the hashes found in the module's legacy translation file. - - $legacyFilesCatalogue = new MessageCatalogue($this->locale); - $catalogueFromPhpAndSmartyFiles = $this->getDefaultCatalogue(false); - - try { - $catalogueFromLegacyTranslationFiles = $this->legacyFileLoader->load( - $this->getDefaultResourceDirectory(), - $this->locale - ); - } catch (UnsupportedLocaleException $exception) { - // this happens when there no translation file is found for the desired locale - return $catalogueFromPhpAndSmartyFiles; - } - - foreach ($catalogueFromPhpAndSmartyFiles->all() as $currentDomain => $items) { - foreach (array_keys($items) as $translationKey) { - $legacyKey = md5($translationKey); - - if ($catalogueFromLegacyTranslationFiles->has($legacyKey, $currentDomain)) { - $legacyFilesCatalogue->set( - $translationKey, - $catalogueFromLegacyTranslationFiles->get($legacyKey, $currentDomain), - // use current domain and not module domain, otherwise we'd lose the third part from the domain - $currentDomain - ); - } - } - } - - return $legacyFilesCatalogue; - } - - /** - * {@inheritdoc} - */ - public function getMessageCatalogue() - { - $messageCatalogue = $this->getDefaultCatalogue(); - - $translatedCatalogue = $this->buildTranslationCatalogueFromLegacyFiles(); - $messageCatalogue->addCatalogue($translatedCatalogue); - - $databaseCatalogue = $this->getDatabaseCatalogue(); - $messageCatalogue->addCatalogue($databaseCatalogue); - - return $messageCatalogue; - } - - /** - * Replaces dots in the catalogue's domain names - * and filters out domains not corresponding to the one from this module - * - * @param MessageCatalogueInterface $catalogue - * - * @return MessageCatalogue - */ - private function filterDomains(MessageCatalogueInterface $catalogue) - { - $normalizer = new DomainNormalizer(); - $newCatalogue = new MessageCatalogue($catalogue->getLocale()); - - // add delimiter to - $validTranslationDomains = $this->getFilters(); - - foreach ($catalogue->getDomains() as $domain) { - // remove dots - $newDomain = $normalizer->normalize($domain); - - // only add if the domain is relevant to this module - foreach ($validTranslationDomains as $pattern) { - if (preg_match($pattern, $newDomain)) { - $newCatalogue->add( - $catalogue->all($domain), - $newDomain - ); - break; - } - } - } - - return $newCatalogue; - } - - /** - * Builds the default catalogue - * - * @return MessageCatalogue - */ - private function buildFreshDefaultCatalogue() - { - $defaultCatalogue = new MessageCatalogue($this->locale); - - try { - // look up files in the core translations - $defaultCatalogue = $this->moduleProvider - ->setModuleName($this->moduleName) - ->setLocale($this->locale) - ->getDefaultCatalogue(); - } catch (FileNotFoundException $exception) { - // there are no xliff files for this module in the core - } - - try { - // analyze files and extract wordings - $additionalDefaultCatalogue = $this->legacyModuleExtractor->extract($this->moduleName, $this->locale); - $defaultCatalogue = $this->filterDomains($additionalDefaultCatalogue); - } catch (UnsupportedLocaleException $exception) { - // Do nothing as support of legacy files is deprecated - } - - return $defaultCatalogue; - } - - /** - * Returns the cached default catalogue - * - * @return MessageCatalogue - */ - private function getCachedDefaultCatalogue() - { - $catalogueCacheKey = $this->moduleName . '|' . $this->locale; - - if (!isset($this->defaultCatalogueCache[$catalogueCacheKey])) { - $this->defaultCatalogueCache[$catalogueCacheKey] = $this->buildFreshDefaultCatalogue(); - } - - return $this->defaultCatalogueCache[$catalogueCacheKey]; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/FrontOfficeProvider.php b/src/PrestaShopBundle/Translation/Provider/FrontOfficeProvider.php deleted file mode 100644 index 4efe1e1b..00000000 --- a/src/PrestaShopBundle/Translation/Provider/FrontOfficeProvider.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Main translation provider for the Front Office - */ -class FrontOfficeProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - const DEFAULT_THEME_NAME = 'classic'; - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return [ - '^Shop*', - '^Modules(.*)Shop', - ]; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return [ - '#^Shop*#', - '#^Modules(.*)Shop#', - ]; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'front'; - } - - /** - * @param null $themeName - * - * @return MessageCatalogue - */ - public function getDatabaseCatalogue($themeName = null) - { - if (null === $themeName) { - $themeName = self::DEFAULT_THEME_NAME; - } - - return parent::getDatabaseCatalogue($themeName); - } - - /**{@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/MailsBodyProvider.php b/src/PrestaShopBundle/Translation/Provider/MailsBodyProvider.php deleted file mode 100644 index 1de188a1..00000000 --- a/src/PrestaShopBundle/Translation/Provider/MailsBodyProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -/** - * Translation provider specific to email subjects. - */ -class MailsBodyProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['EmailsBody*']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#EmailsBody*#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'mails_body'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/MailsProvider.php b/src/PrestaShopBundle/Translation/Provider/MailsProvider.php deleted file mode 100644 index 703cdc10..00000000 --- a/src/PrestaShopBundle/Translation/Provider/MailsProvider.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -/** - * Translation provider specific to email subjects. - */ -class MailsProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['EmailsSubject*']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#EmailsSubject*#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'mails'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/ModuleProvider.php b/src/PrestaShopBundle/Translation/Provider/ModuleProvider.php deleted file mode 100644 index b92cb1f3..00000000 --- a/src/PrestaShopBundle/Translation/Provider/ModuleProvider.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\TranslationToolsBundle\Translation\Helper\DomainHelper; - -/** - * Translation provider for a specific native module (maintained by the core team) - * Used mainly for the display in the Translations Manager of the Back Office. - */ -class ModuleProvider extends AbstractProvider implements SearchProviderInterface, UseModuleInterface -{ - /** - * @var string the module name - */ - private $moduleName; - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['^' . preg_quote(DomainHelper::buildModuleBaseDomain($this->moduleName)) . '([A-Z]|$)']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#^' . preg_quote(DomainHelper::buildModuleBaseDomain($this->moduleName)) . '([A-Z]|\.|$)#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'module'; - } - - /** - * {@inheritdoc} - */ - public function setModuleName($moduleName) - { - $this->moduleName = $moduleName; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/ModulesProvider.php b/src/PrestaShopBundle/Translation/Provider/ModulesProvider.php deleted file mode 100644 index f9006357..00000000 --- a/src/PrestaShopBundle/Translation/Provider/ModulesProvider.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -/** - * Translation provider for native modules (maintained by the core team) - * Translations are provided by Crowdin. - */ -class ModulesProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['^Modules[A-Z]']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#^Modules[A-Z]#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'modules'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/OthersProvider.php b/src/PrestaShopBundle/Translation/Provider/OthersProvider.php deleted file mode 100644 index a244eadf..00000000 --- a/src/PrestaShopBundle/Translation/Provider/OthersProvider.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -/** - * Translations provider for keys not yet put in the right domain. - * Equivalent to so-called main "messages" domain in the Symfony ecosystem. - */ -class OthersProvider extends AbstractProvider implements UseDefaultCatalogueInterface -{ - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['^messages*']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#^messages*#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'others'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/ProviderInterface.php b/src/PrestaShopBundle/Translation/Provider/ProviderInterface.php deleted file mode 100644 index dda2d27c..00000000 --- a/src/PrestaShopBundle/Translation/Provider/ProviderInterface.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Define contract to retrieve translations. - */ -interface ProviderInterface -{ - /** - * @return string[] List of directories to parse - */ - public function getDirectories(); - - /** - * Returns a list of patterns for catalogue domain filtering (including XLF file lookup) - * - * @return string[] - */ - public function getFilters(); - - /** - * Returns a list of patterns for translation domains to get from database. - * - * @return string[] List of Mysql compatible regexes (no regex delimiter) - */ - public function getTranslationDomains(); - - /** - * @return string Locale used to build the MessageCatalogue - */ - public function getLocale(); - - /** - * @return MessageCatalogue A provider must return a MessageCatalogue - */ - public function getMessageCatalogue(); - - /** - * @return string Unique identifier - */ - public function getIdentifier(); -} diff --git a/src/PrestaShopBundle/Translation/Provider/SearchProvider.php b/src/PrestaShopBundle/Translation/Provider/SearchProvider.php deleted file mode 100644 index 6bd39641..00000000 --- a/src/PrestaShopBundle/Translation/Provider/SearchProvider.php +++ /dev/null @@ -1,196 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use Symfony\Component\Translation\Loader\LoaderInterface; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\MessageCatalogueInterface; - -/** - * Able to search translations for a specific translation domains across multiple sources - */ -class SearchProvider extends AbstractProvider implements UseDefaultCatalogueInterface, UseModuleInterface -{ - /** - * @var string the "modules" directory path - */ - private $modulesDirectory; - - /** - * @var ExternalModuleLegacySystemProvider - */ - private $externalModuleLegacySystemProvider; - - public function __construct( - LoaderInterface $databaseLoader, - ExternalModuleLegacySystemProvider $externalModuleLegacySystemProvider, - $resourceDirectory, - $modulesDirectory - ) { - $this->modulesDirectory = $modulesDirectory; - $this->externalModuleLegacySystemProvider = $externalModuleLegacySystemProvider; - - parent::__construct($databaseLoader, $resourceDirectory); - } - - /** - * Get domain. - * - * @deprecated since 1.7.6, to be removed in the next major - * - * @return mixed - */ - public function getDomain() - { - @trigger_error( - __METHOD__ . ' function is deprecated and will be removed in the next major', - E_USER_DEPRECATED - ); - - return $this->domain; - } - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - return ['^' . preg_quote($this->domain) . '([A-Z]|$)']; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - return ['#^' . preg_quote($this->domain, '#') . '([A-Z]|\.|$)#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'search'; - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->resourceDirectory . DIRECTORY_SEPARATOR . 'default'; - } - - public function getDefaultCatalogue($empty = true) - { - try { - $defaultCatalogue = parent::getDefaultCatalogue($empty); - } catch (FileNotFoundException $e) { - $defaultCatalogue = $this->externalModuleLegacySystemProvider->getDefaultCatalogue($empty); - $defaultCatalogue = $this->filterCatalogue($defaultCatalogue); - } - - return $defaultCatalogue; - } - - /** - * {@inheritdoc} - */ - public function getXliffCatalogue() - { - try { - $xliffCatalogue = parent::getXliffCatalogue(); - } catch (\Exception $e) { - $xliffCatalogue = $this->externalModuleLegacySystemProvider->getXliffCatalogue(); - $xliffCatalogue = $this->filterCatalogue($xliffCatalogue); - } - - return $xliffCatalogue; - } - - /** - * @deprecated since 1.7.6, to be removed in the next major - * - * @return string - */ - public function getModuleDirectory() - { - @trigger_error( - __METHOD__ . ' function is deprecated and will be removed in the next major', - E_USER_DEPRECATED - ); - - return $this->modulesDirectory; - } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->externalModuleLegacySystemProvider->setLocale($locale); - - return parent::setLocale($locale); - } - - /** - * {@inheritdoc} - */ - public function setModuleName($moduleName) - { - $this->externalModuleLegacySystemProvider->setModuleName($moduleName); - } - - /** - * Filters the catalogue so that only domains matching the filters are kept - * - * @param MessageCatalogueInterface $defaultCatalogue - * - * @return MessageCatalogueInterface - */ - private function filterCatalogue(MessageCatalogueInterface $defaultCatalogue) - { - // return only elements whose domain matches the filters - $filters = $this->getFilters(); - $allowedDomains = []; - - foreach ($defaultCatalogue->all() as $domain => $messages) { - foreach ($filters as $filter) { - if (preg_match($filter, $domain)) { - $allowedDomains[$domain] = $messages; - break; - } - } - } - - $defaultCatalogue = new MessageCatalogue($this->getLocale(), $allowedDomains); - - return $defaultCatalogue; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/SearchProviderInterface.php b/src/PrestaShopBundle/Translation/Provider/SearchProviderInterface.php deleted file mode 100644 index 2bd91ffd..00000000 --- a/src/PrestaShopBundle/Translation/Provider/SearchProviderInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -interface SearchProviderInterface extends ProviderInterface, UseDefaultCatalogueInterface, XliffCatalogueInterface, DatabaseCatalogueInterface -{ - /** - * @param string $domain - * - * @return self - */ - public function setDomain($domain); - - /** - * @param string $locale - * - * @return self - */ - public function setLocale($locale); -} diff --git a/src/PrestaShopBundle/Translation/Provider/ThemeProvider.php b/src/PrestaShopBundle/Translation/Provider/ThemeProvider.php deleted file mode 100644 index 2329780b..00000000 --- a/src/PrestaShopBundle/Translation/Provider/ThemeProvider.php +++ /dev/null @@ -1,240 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeRepository; -use PrestaShop\TranslationToolsBundle\Translation\Extractor\Util\Flattenizer; -use PrestaShopBundle\Translation\Extractor\ThemeExtractor; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\MessageCatalogueInterface; - -class ThemeProvider extends AbstractProvider -{ - /** - * @var string the theme name - */ - private $themeName; - - /** - * @var string the theme resources directory - */ - public $themeResourcesDirectory; - - /** - * @var Filesystem - */ - public $filesystem; - - /** - * @var ThemeRepository - */ - public $themeRepository; - - /** - * @var ThemeExtractor - */ - public $themeExtractor; - - /** - * @var string Path to app/Resources/translations/ - */ - public $defaultTranslationDir; - - /** - * Get domain. - * - * @deprecated since 1.7.6, to be removed in the next major - * - * @return mixed - */ - public function getDomain() - { - @trigger_error( - 'getDomain function is deprecated and will be removed in the next major', - E_USER_DEPRECATED - ); - - return $this->domain; - } - - /** - * {@inheritdoc} - */ - public function getTranslationDomains() - { - if (empty($this->domain)) { - return ['*']; - } - - return ['^' . $this->domain]; - } - - /** - * {@inheritdoc} - */ - public function getFilters() - { - if (empty($this->domain)) { - return ['*']; - } - - return ['#^' . $this->domain . '#']; - } - - /** - * {@inheritdoc} - */ - public function getIdentifier() - { - return 'theme'; - } - - /** - * {@inheritdoc} - */ - public function getMessageCatalogue() - { - $xlfCatalogue = $this->getXliffCatalogue(); - $databaseCatalogue = $this->getDatabaseCatalogue(); - - // Merge database catalogue to xliff catalogue - $xlfCatalogue->addCatalogue($databaseCatalogue); - - return $xlfCatalogue; - } - - /** - * @param string|null $baseDir - * - * @return string Path to app/themes/{themeName}/translations/{locale} - */ - public function getResourceDirectory($baseDir = null) - { - if (null === $baseDir) { - $baseDir = $this->resourceDirectory; - } - - $resourceDirectory = $baseDir . '/' . $this->themeName . '/translations/' . $this->getLocale(); - $this->filesystem->mkdir($resourceDirectory); - - return $resourceDirectory; - } - - /** - * {@inheritdoc} - */ - public function getDirectories() - { - return [ - $this->getResourceDirectory(), - $this->getThemeResourcesDirectory(), - ]; - } - - /** - * @return string the path to the Theme translations folder - */ - public function getThemeResourcesDirectory() - { - return $this->getResourceDirectory($this->themeResourcesDirectory); - } - - /** - * @param string $themeName The theme name - * - * @return self - */ - public function setThemeName($themeName) - { - $this->themeName = $themeName; - - return $this; - } - - /** - * @param string|null $themeName - * - * @return MessageCatalogueInterface - */ - public function getDatabaseCatalogue($themeName = null) - { - if (null === $themeName) { - $themeName = $this->themeName; - } - - return parent::getDatabaseCatalogue($themeName); - } - - /** - * @throws \Exception - * - * Will update translations files of the Theme - */ - public function synchronizeTheme() - { - $theme = $this->themeRepository->getInstanceByName($this->themeName); - - $path = $this->resourceDirectory . DIRECTORY_SEPARATOR . $this->themeName . DIRECTORY_SEPARATOR . 'translations'; - - $this->filesystem->remove($path); - $this->filesystem->mkdir($path); - - $this->themeExtractor - ->setOutputPath($path) - ->setThemeProvider($this) - ->extract($theme, $this->locale); - - $translationFilesPath = $path . DIRECTORY_SEPARATOR . $this->locale; - Flattenizer::flatten($translationFilesPath, $translationFilesPath, $this->locale, false); - - $finder = Finder::create(); - foreach ($finder->directories()->depth('== 0')->in($translationFilesPath) as $folder) { - $this->filesystem->remove($folder); - } - } - - /** - * @return MessageCatalogueInterface - * - * @throws \Exception - */ - public function getThemeCatalogue() - { - $path = $this->resourceDirectory . DIRECTORY_SEPARATOR . $this->themeName . DIRECTORY_SEPARATOR . 'translations'; - - return $this->getCatalogueFromPaths($path, $this->locale, current($this->getFilters())); - } - - /** - * {@inheritdoc} - */ - public function getDefaultResourceDirectory() - { - return $this->defaultTranslationDir . DIRECTORY_SEPARATOR . $this->locale; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/TranslationFinder.php b/src/PrestaShopBundle/Translation/Provider/TranslationFinder.php deleted file mode 100644 index 0673c8c6..00000000 --- a/src/PrestaShopBundle/Translation/Provider/TranslationFinder.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Finder\SplFileInfo; -use Symfony\Component\Translation\Loader\XliffFileLoader; -use Symfony\Component\Translation\MessageCatalogue; -use Symfony\Component\Translation\MessageCatalogueInterface; - -/** - * Helper used to build a MessageCataloguer from xliff files - */ -class TranslationFinder -{ - const ERR_NO_FILES_IN_DIRECTORY = 1; - const ERR_DIRECTORY_NOT_FOUND = 2; - - /** - * @param string|array $paths a list of paths when we can look for translations - * @param string $locale the Symfony (not the PrestaShop one) locale - * @param string|null $pattern a regular expression - * - * @return MessageCatalogue - * - * @throws FileNotFoundException - */ - public function getCatalogueFromPaths($paths, $locale, $pattern = null) - { - $translationFiles = $this->getTranslationFilesFromPath($paths, $pattern); - - return $this->buildCatalogueFromFiles($translationFiles, $locale); - } - - /** - * @param MessageCatalogueInterface $catalogue - * - * @return MessageCatalogue - */ - private function removeTrailingLocaleFromDomains(MessageCatalogueInterface $catalogue) - { - $messages = $catalogue->all(); - $locale = $catalogue->getLocale(); - $localeSuffix = '.' . $locale; - $suffixLength = strlen($localeSuffix); - - foreach ($catalogue->getDomains() as $domain) { - if (substr($domain, -$suffixLength) === $localeSuffix) { - $cleanDomain = substr($domain, 0, -$suffixLength); - $messages[$cleanDomain] = $messages[$domain]; - unset($messages[$domain]); - } - } - - return new MessageCatalogue($locale, $messages); - } - - /** - * @param $paths - * @param $pattern - * - * @return Finder - * - * @throws FileNotFoundException - */ - private function getTranslationFilesFromPath($paths, $pattern) - { - $finder = new Finder(); - - if (null !== $pattern) { - $finder->name($pattern); - } - - try { - $translationFiles = $finder->files()->notName('index.php')->in($paths); - } catch (\InvalidArgumentException $e) { - throw new FileNotFoundException(sprintf('Could not crawl for translation files: %s', $e->getMessage()), self::ERR_DIRECTORY_NOT_FOUND, $e); - } - - if (count($translationFiles) === 0) { - throw new FileNotFoundException('There are no translation file available.', self::ERR_NO_FILES_IN_DIRECTORY); - } - - return $translationFiles; - } - - /** - * @param Finder $translationFiles - * @param string $locale - * - * @return MessageCatalogue - */ - private function buildCatalogueFromFiles(Finder $translationFiles, $locale) - { - $messageCatalogue = new MessageCatalogue($locale); - $xliffFileLoader = new XliffFileLoader(); - - /** @var SplFileInfo $file */ - foreach ($translationFiles as $file) { - if ('xlf' === $file->getExtension()) { - $domain = $this->getDomainFromFile($file, $locale); - - $fileCatalogue = $xliffFileLoader->load($file->getPathname(), $locale, $domain); - $messageCatalogue->addCatalogue( - $this->removeTrailingLocaleFromDomains($fileCatalogue) - ); - } - } - - return $messageCatalogue; - } - - /** - * @param SplFileInfo $file - * @param string $locale - * - * @return string - */ - private function getDomainFromFile(SplFileInfo $file, $locale) - { - $basename = $file->getBasename('.xlf'); - - $domain = $basename; - if (strpos($basename, $locale) === false) { - $domain .= '.' . $locale; - } - - return $domain; - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/TranslationFinderTrait.php b/src/PrestaShopBundle/Translation/Provider/TranslationFinderTrait.php deleted file mode 100644 index 27ba8f1b..00000000 --- a/src/PrestaShopBundle/Translation/Provider/TranslationFinderTrait.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShop\PrestaShop\Core\Exception\FileNotFoundException; -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Helper used to retrieve a Symfony Catalogue object. - * - * @deprecated use TraslationFinder instead - */ -trait TranslationFinderTrait -{ - /** - * @param array $paths a list of paths when we can look for translations - * @param string $locale the Symfony (not the PrestaShop one) locale - * @param string|null $pattern a regular expression - * - * @return MessageCatalogue - * - * @throws FileNotFoundException - * - * @deprecated use TraslationFinder::getCatalogueFromPaths() instead - */ - public function getCatalogueFromPaths($paths, $locale, $pattern = null) - { - @trigger_error( - __FUNCTION__ . 'is deprecated since version 1.7.6.1 Use TranslationFinder::getCatalogueFromPaths() instead.', - E_USER_DEPRECATED - ); - - return (new TranslationFinder())->getCatalogueFromPaths($paths, $locale, $pattern); - } -} diff --git a/src/PrestaShopBundle/Translation/Provider/UseDefaultCatalogueInterface.php b/src/PrestaShopBundle/Translation/Provider/UseDefaultCatalogueInterface.php deleted file mode 100644 index 5bd86696..00000000 --- a/src/PrestaShopBundle/Translation/Provider/UseDefaultCatalogueInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use Symfony\Component\Translation\MessageCatalogueInterface; - -/** - * Defines what should be the default catalogue, contains all the translations keys. - */ -interface UseDefaultCatalogueInterface -{ - /** - * Get the default (aka untranslated) catalogue - * - * @param bool $empty if true, empty the catalogue values (keep the keys) - * - * @return MessageCatalogueInterface Return a default catalogue with all keys - */ - public function getDefaultCatalogue($empty = true); - - /** - * @return string Path to the default directory - * Most of the time, it's `app/Resources/translations/default/{locale}` - */ - public function getDefaultResourceDirectory(); -} diff --git a/src/PrestaShopBundle/Translation/Provider/UseModuleInterface.php b/src/PrestaShopBundle/Translation/Provider/UseModuleInterface.php deleted file mode 100644 index 9511342a..00000000 --- a/src/PrestaShopBundle/Translation/Provider/UseModuleInterface.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use PrestaShopBundle\Translation\Exception\UnsupportedModuleException; - -/** - * Defines that this provider may need information from module. - */ -interface UseModuleInterface -{ - /** - * Set the module name - * - * @param string $moduleName the name of the module - * - * @throws UnsupportedModuleException if the module is not supported or invalid - */ - public function setModuleName($moduleName); -} diff --git a/src/PrestaShopBundle/Translation/Provider/XliffCatalogueInterface.php b/src/PrestaShopBundle/Translation/Provider/XliffCatalogueInterface.php deleted file mode 100644 index 510a290f..00000000 --- a/src/PrestaShopBundle/Translation/Provider/XliffCatalogueInterface.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\Provider; - -use Symfony\Component\Translation\MessageCatalogue; - -/** - * Provide an Message Catalogue from Xliff files. - */ -interface XliffCatalogueInterface -{ - /** - * @return MessageCatalogue - */ - public function getXliffCatalogue(); -} diff --git a/src/PrestaShopBundle/Translation/Translator.php b/src/PrestaShopBundle/Translation/Translator.php deleted file mode 100644 index 87d523cb..00000000 --- a/src/PrestaShopBundle/Translation/Translator.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator; - -/** - * Replacement for the original Symfony FrameworkBundle translator - */ -class Translator extends BaseTranslator -{ - use PrestaShopTranslatorTrait; - use TranslatorLanguageTrait; - - /** - * {@inheritdoc} - */ - public function addResource($format, $resource, $locale, $domain = null) - { - parent::addResource($format, $resource, $locale, $domain); - parent::addResource('db', $domain . '.' . $locale . '.db', $locale, $domain); - } -} diff --git a/src/PrestaShopBundle/Translation/TranslatorAwareTrait.php b/src/PrestaShopBundle/Translation/TranslatorAwareTrait.php deleted file mode 100644 index 37d0e294..00000000 --- a/src/PrestaShopBundle/Translation/TranslatorAwareTrait.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use Symfony\Component\Translation\TranslatorInterface; - -/** - * Trait TranslatorAwareTrait is used for services that depends on translator. - */ -trait TranslatorAwareTrait -{ - /** - * @var TranslatorInterface - */ - protected $translator; - - /** - * Set translator instance. - * - * @param TranslatorInterface $translator - */ - public function setTranslator(TranslatorInterface $translator) - { - $this->translator = $translator; - } - - /** - * Shortcut method to translate text. - * - * @param string $id - * @param array $options - * @param string $domain - * - * @return string - */ - protected function trans($id, array $options, $domain) - { - return $this->translator->trans($id, $options, $domain); - } -} diff --git a/src/PrestaShopBundle/Translation/TranslatorComponent.php b/src/PrestaShopBundle/Translation/TranslatorComponent.php deleted file mode 100644 index 691b9844..00000000 --- a/src/PrestaShopBundle/Translation/TranslatorComponent.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use Symfony\Component\Translation\Translator as BaseTranslatorComponent; - -/** - * Translator used by Context - */ -class TranslatorComponent extends BaseTranslatorComponent -{ - use PrestaShopTranslatorTrait; - use TranslatorLanguageTrait; -} diff --git a/src/PrestaShopBundle/Translation/TranslatorLanguageLoader.php b/src/PrestaShopBundle/Translation/TranslatorLanguageLoader.php deleted file mode 100644 index f0161c03..00000000 --- a/src/PrestaShopBundle/Translation/TranslatorLanguageLoader.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -use PrestaShop\PrestaShop\Core\Addon\Theme\Theme; -use PrestaShopBundle\Translation\Loader\SqlTranslationLoader; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Translation\Loader\XliffFileLoader; -use Symfony\Component\Translation\TranslatorInterface; - -class TranslatorLanguageLoader -{ - const TRANSLATION_DIR = _PS_ROOT_DIR_ . '/app/Resources/translations'; - /** - * @var bool - */ - private $isAdminContext; - - /** - * TranslatorLanguageLoader constructor. - * - * @param $isAdminContext - */ - public function __construct($isAdminContext) - { - $this->isAdminContext = $isAdminContext; - } - - /** - * Loads a language into a translator - * - * @param TranslatorInterface $translator Translator to modifiy - * @param string $locale Locale code for the language to load - * @param bool $withDB [default=true] Whether to load translations from the database or not - * @param Theme|null $theme [default=false] Currently active theme (Front office only) - */ - public function loadLanguage(TranslatorInterface $translator, $locale, $withDB = true, Theme $theme = null) - { - if (!$translator->isLanguageLoaded($locale)) { - $translator->addLoader('xlf', new XliffFileLoader()); - - if ($withDB) { - $sqlTranslationLoader = new SqlTranslationLoader(); - if (null !== $theme) { - $sqlTranslationLoader->setTheme($theme); - } - $translator->addLoader('db', $sqlTranslationLoader); - } - - $finder = Finder::create() - ->files() - ->name('*.' . $locale . '.xlf') - ->notName($this->isAdminContext ? '^Shop*' : '^Admin*') - ->in($this->getTranslationResourcesDirectories($theme)); - - foreach ($finder as $file) { - list($domain, $locale, $format) = explode('.', $file->getBasename(), 3); - $translator->addResource($format, $file, $locale, $domain); - if ($withDB) { - $translator->addResource('db', $domain . '.' . $locale . '.db', $locale, $domain); - } - } - } - } - - /** - * @param Theme|null $theme - * - * @return array - */ - protected function getTranslationResourcesDirectories(Theme $theme = null) - { - $locations = [self::TRANSLATION_DIR]; - - if (null !== $theme) { - $activeThemeLocation = $theme->getDirectory() . '/translations'; - if (is_dir($activeThemeLocation)) { - $locations[] = $activeThemeLocation; - } - } - - return $locations; - } -} diff --git a/src/PrestaShopBundle/Translation/TranslatorLanguageTrait.php b/src/PrestaShopBundle/Translation/TranslatorLanguageTrait.php deleted file mode 100644 index a9c35098..00000000 --- a/src/PrestaShopBundle/Translation/TranslatorLanguageTrait.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation; - -/** - * Trait TranslatorLanguageTrait used to check if a language has been loaded and reset a language - */ -trait TranslatorLanguageTrait -{ - /** - * @param string $locale Locale code for the catalogue to check if loaded - * - * @return bool - */ - public function isLanguageLoaded($locale) - { - return !empty($this->catalogues[$locale]); - } - - /** - * @param string $locale Locale code for the catalogue to be cleared - */ - public function clearLanguage($locale) - { - unset($this->catalogues[$locale]); - } -} diff --git a/src/PrestaShopBundle/Translation/View/TreeBuilder.php b/src/PrestaShopBundle/Translation/View/TreeBuilder.php deleted file mode 100644 index 121db5c5..00000000 --- a/src/PrestaShopBundle/Translation/View/TreeBuilder.php +++ /dev/null @@ -1,316 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Translation\View; - -use Doctrine\Common\Util\Inflector; -use PrestaShopBundle\Translation\Provider\AbstractProvider; -use Symfony\Bundle\FrameworkBundle\Routing\Router; - -class TreeBuilder -{ - private $locale; - private $theme; - - public function __construct($locale, $theme) - { - $this->locale = $locale; - $this->theme = $theme; - } - - /** - * @param AbstractProvider $provider - * @param null $search - * - * @return array|mixed - */ - public function makeTranslationArray(AbstractProvider $provider, $search = null) - { - $provider->setLocale($this->locale); - - if ('theme' === $provider->getIdentifier()) { - $defaultCatalogue = $provider->getMessageCatalogue(); - } else { - $defaultCatalogue = $provider->getDefaultCatalogue(); - } - - $xliffCatalogue = $provider->getXliffCatalogue(); - $databaseCatalogue = $provider->getDatabaseCatalogue($this->theme); - - $translations = []; - - foreach ($defaultCatalogue->all() as $domain => $messages) { - $missingTranslations = 0; - - foreach ($messages as $translationKey => $translationValue) { - $data = [ - 'xlf' => $xliffCatalogue->defines($translationKey, $domain) - ? $xliffCatalogue->get($translationKey, $domain) - : null, - 'db' => $databaseCatalogue->defines($translationKey, $domain) - ? $databaseCatalogue->get($translationKey, $domain) - : null, - ]; - - // if search is empty or is in catalog default|xlf|database - if (empty($search) || $this->dataContainsSearchWord($search, array_merge(['default' => $translationKey], $data))) { - $translations[$domain][$translationKey] = $data; - - if (empty($data['xlf']) - && empty($data['db']) - ) { - ++$missingTranslations; - } - } - } - - $translations[$domain]['__metadata'] = ['missing_translations' => $missingTranslations]; - } - - ksort($translations); - - return $translations; - } - - /** - * Check if data contains search word. - * - * @param $search - * @param $data - * - * @return bool - */ - private function dataContainsSearchWord($search, $data) - { - if (is_string($search)) { - $search = strtolower($search); - - return false !== strpos(strtolower($data['default']), $search) || - false !== strpos(strtolower($data['xlf']), $search) || - false !== strpos(strtolower($data['db']), $search); - } - - if (is_array($search)) { - $contains = true; - foreach ($search as $s) { - $s = strtolower($s); - $contains &= false !== strpos(strtolower($data['default']), $s) || - false !== strpos(strtolower($data['xlf']), $s) || - false !== strpos(strtolower($data['db']), $s); - } - - return $contains; - } - - return false; - } - - /** - * @return array - */ - public function makeTranslationsTree($catalogue) - { - $translationsTree = []; - - foreach ($catalogue as $domain => $messages) { - $tableisedDomain = Inflector::tableize($domain); - // the third component of the domain may have underscores, so we need to limit pieces to 3 - $parts = explode('_', $tableisedDomain, 3); - $subtree = &$translationsTree; - - foreach ($parts as $part) { - $subdomain = ucfirst($part); - - if (!array_key_exists($subdomain, $subtree)) { - $subtree[$subdomain] = []; - } - - $subtree = &$subtree[$subdomain]; - } - - $subtree['__messages'] = [$domain => $messages]; - if (isset($messages['__metadata'])) { - $subtree['__fixed_length_id'] = '_' . sha1($domain); - list($subtree['__domain']) = explode('.', $domain); - $subtree['__metadata'] = $messages['__metadata']; - $subtree['__metadata']['domain'] = $subtree['__domain']; - unset($messages['__metadata']); - } - } - - return $translationsTree; - } - - /** - * Clean tree to use it with the new API system. - * - * @param $tree - * @param Router $router - * @param null $theme - * @param null $search - * @param null $module - * - * @return array - */ - public function cleanTreeToApi($tree, Router $router, $theme = null, $search = null, $module = null) - { - $rootTree = [ - 'tree' => [ - 'total_translations' => 0, - 'total_missing_translations' => 0, - 'children' => [], - ], - ]; - - $cleanTree = &$rootTree['tree']['children']; - - $index1 = 0; - foreach ($tree as $k1 => $t1) { - $index2 = 0; - if (is_array($t1) && '__' !== substr($k1, 0, 2)) { - $this->addTreeInfo($router, $cleanTree, $index1, $k1, $k1, $this->theme, $search, $module); - - if (array_key_exists('__messages', $t1)) { - $nbMessage = count(current($t1['__messages'])); - if (array_key_exists('__metadata', $t1)) { - --$nbMessage; - } - - $cleanTree[$index1]['total_translations'] += $nbMessage; - $rootTree['tree']['total_translations'] += $nbMessage; - - if (array_key_exists('__metadata', $t1) && array_key_exists('missing_translations', $t1['__metadata'])) { - $cleanTree[$index1]['total_missing_translations'] += (int) $t1['__metadata']['missing_translations']; - $rootTree['tree']['total_missing_translations'] += (int) $t1['__metadata']['missing_translations']; - } - } - - foreach ($t1 as $k2 => $t2) { - $index3 = 0; - if (is_array($t2) && '__' !== substr($k2, 0, 2)) { - $this->addTreeInfo($router, $cleanTree[$index1]['children'], $index2, $k2, $k1 . $k2, $this->theme, $search, $module); - - if (array_key_exists('__messages', $t2)) { - $nbMessage = count(current($t2['__messages'])); - if (array_key_exists('__metadata', $t2)) { - --$nbMessage; - } - - $cleanTree[$index1]['children'][$index2]['total_translations'] += $nbMessage; - $cleanTree[$index1]['total_translations'] += $nbMessage; - $rootTree['tree']['total_translations'] += $nbMessage; - - if (array_key_exists('__metadata', $t2) && array_key_exists('missing_translations', $t2['__metadata'])) { - $cleanTree[$index1]['children'][$index2]['total_missing_translations'] += (int) $t2['__metadata']['missing_translations']; - $cleanTree[$index1]['total_missing_translations'] += (int) $t2['__metadata']['missing_translations']; - $rootTree['tree']['total_missing_translations'] += (int) $t2['__metadata']['missing_translations']; - } - } - - foreach ($t2 as $k3 => $t3) { - if (is_array($t3) && '__' !== substr($k3, 0, 2)) { - $this->addTreeInfo($router, $cleanTree[$index1]['children'][$index2]['children'], $index3, $k3, $k1 . $k2 . $k3, $this->theme, $search, $module); - - if (array_key_exists('__messages', $t3)) { - $nbMessage = count(current($t3['__messages'])); - if (array_key_exists('__metadata', $t3)) { - --$nbMessage; - } - - $cleanTree[$index1]['children'][$index2]['children'][$index3]['total_translations'] += $nbMessage; - $cleanTree[$index1]['children'][$index2]['total_translations'] += $nbMessage; - $cleanTree[$index1]['total_translations'] += $nbMessage; - $rootTree['tree']['total_translations'] += $nbMessage; - } - - if (array_key_exists('__metadata', $t3) && array_key_exists('missing_translations', $t3['__metadata'])) { - $cleanTree[$index1]['children'][$index2]['children'][$index3]['total_missing_translations'] += (int) $t3['__metadata']['missing_translations']; - $cleanTree[$index1]['children'][$index2]['total_missing_translations'] += (int) $t3['__metadata']['missing_translations']; - $cleanTree[$index1]['total_missing_translations'] += (int) $t3['__metadata']['missing_translations']; - $rootTree['tree']['total_missing_translations'] += (int) $t3['__metadata']['missing_translations']; - } - - if (empty($cleanTree[$index1]['children'][$index2]['children'][$index3]['children'])) { - unset($cleanTree[$index1]['children'][$index2]['children'][$index3]['children']); - } - ++$index3; - } - } - - if (empty($cleanTree[$index1]['children'][$index2]['children'])) { - unset($cleanTree[$index1]['children'][$index2]['children']); - } - ++$index2; - } - } - - if (empty($cleanTree[$index1]['children'])) { - unset($cleanTree[$index1]['children']); - } - ++$index1; - } - } - - return $rootTree; - } - - /** - * @param Router $router - * @param $tree - * @param $index - * @param $name - * @param $fullName - * @param bool $theme - * @param null $search - * @param null $module - * - * @return mixed - */ - private function addTreeInfo(Router $router, &$tree, $index, $name, $fullName, $theme = false, $search = null, $module = false) - { - if (!isset($tree[$index])) { - $routeParams = [ - 'locale' => $this->locale, - 'domain' => $fullName, - 'theme' => $theme, - 'module' => $module, - ]; - - if (!empty($search)) { - $routeParams['search'] = $search; - } - - $tree[$index]['name'] = $name; - $tree[$index]['full_name'] = $fullName; - $tree[$index]['domain_catalog_link'] = $router->generate('api_translation_domain_catalog', $routeParams); - $tree[$index]['total_translations'] = 0; - $tree[$index]['total_missing_translations'] = 0; - $tree[$index]['children'] = []; - } - - return $tree; - } -} diff --git a/src/PrestaShopBundle/Twig/AdminExtension.php b/src/PrestaShopBundle/Twig/AdminExtension.php deleted file mode 100644 index d26aa99f..00000000 --- a/src/PrestaShopBundle/Twig/AdminExtension.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\RequestStack; - -/** - * Twig extension for the Symfony Asset component. - * - * @deprecated since 1.7.5.0 to be removed in 1.8.0.0 - * - * @author Mlanawo Mbechezi - */ -class AdminExtension extends \Twig_Extension implements \Twig_Extension_InitRuntimeInterface -{ - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var \Twig_Environment - */ - private $environment; - - /** - * @var \Symfony\Component\DependencyInjection\Container - */ - private $container; - - /** - * AdminExtension constructor. - * - * @param RequestStack|null $requestStack - * @param ContainerInterface $container - */ - public function __construct(RequestStack $requestStack = null, ContainerInterface $container) - { - $this->requestStack = $requestStack; - $this->container = $container; - } - - /** - * {@inheritdoc} - */ - public function initRuntime(\Twig_Environment $environment) - { - $this->environment = $environment; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'twig_admin_extension'; - } -} diff --git a/src/PrestaShopBundle/Twig/ContextIsoCodeProviderExtension.php b/src/PrestaShopBundle/Twig/ContextIsoCodeProviderExtension.php deleted file mode 100644 index f2eb2c7b..00000000 --- a/src/PrestaShopBundle/Twig/ContextIsoCodeProviderExtension.php +++ /dev/null @@ -1,64 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -/** - * Provides context language iso code - */ -class ContextIsoCodeProviderExtension extends \Twig_Extension -{ - /** - * @var string - */ - private $isoCode; - - /** - * @param $isoCode - */ - public function __construct($isoCode) - { - $this->isoCode = $isoCode; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('get_context_iso_code', [$this, 'getIsoCode']), - ]; - } - - /** - * @return string - */ - public function getIsoCode() - { - return $this->isoCode; - } -} diff --git a/src/PrestaShopBundle/Twig/DataFormatterExtension.php b/src/PrestaShopBundle/Twig/DataFormatterExtension.php deleted file mode 100644 index 0b259320..00000000 --- a/src/PrestaShopBundle/Twig/DataFormatterExtension.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -/** - * This class is used by Twig_Environment and provide some methods callable from a twig template. - */ -class DataFormatterExtension extends \Twig_Extension -{ - /** - * Define available filters. - * - * @return array Twig_SimpleFilter - */ - public function getFilters() - { - return [ - new \Twig_SimpleFilter('arrayCast', [$this, 'arrayCast']), - new \Twig_SimpleFilter('intCast', [$this, 'intCast']), - new \Twig_SimpleFilter('unsetElement', [$this, 'unsetElement']), - new \Twig_SimpleFilter('array_pluck', [$this, 'arrayPluck']), - ]; - } - - /** - * Define available functions. - * - * @return array Twig_SimpleFunction - */ - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('arrayCast', [$this, 'arrayCast']), - new \Twig_SimpleFunction('intCast', [$this, 'intCast']), - new \Twig_SimpleFunction('unsetElement', [$this, 'unsetElement']), - new \Twig_SimpleFunction('array_pluck', [$this, 'arrayPluck']), - ]; - } - - /** - * Cast to array the variable given. - * - * @param mixed $toCast Mixed value to be casted into an array - * - * @return array $toCast casted in array - */ - public function arrayCast($toCast) - { - return (array) $toCast; - } - - /** - * Cast to int the variable given. - * - * @param mixed $toCast Mixed value to be casted into an int - * - * @return int $toCast casted in int - */ - public function intCast($toCast) - { - return (int) $toCast; - } - - /** - * PHP 'unset()' exposed through twig template engine. - * - * @param string $array Array containing Element to unset - * @param string $key Element to be unset - */ - public function unsetElement($array, $key) - { - unset($array[$key]); - - return $array; - } - - /** - * Extract a subset of an array and returns only the wanted keys. - * If $extractedKeys is an associative array you can even rename the - * keys of the extracted array. - * - * ex: - * arrayPluck(['first_name' => 'John', 'last_name' => 'Doe'], ['first_name']) => ['first_name' => 'John'] - * arrayPluck(['first_name' => 'John', 'last_name' => 'Doe'], ['first_name' => 'name']) => ['name' => 'John'] - * - * @param array $array - * @param array $extractedKeys - * - * @return array - */ - public function arrayPluck(array $array, array $extractedKeys) - { - $extractedArray = []; - foreach ($extractedKeys as $key => $value) { - if (is_int($key)) { - $oldKey = $value; - $newKey = $value; - } else { - $oldKey = $key; - $newKey = $value; - } - if (isset($array[$oldKey])) { - $extractedArray[$newKey] = $array[$oldKey]; - } - } - - return $extractedArray; - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'twig_data_formatter_extension'; - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/ColorBrightnessCalculatorExtension.php b/src/PrestaShopBundle/Twig/Extension/ColorBrightnessCalculatorExtension.php deleted file mode 100644 index 54c1d51d..00000000 --- a/src/PrestaShopBundle/Twig/Extension/ColorBrightnessCalculatorExtension.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use PrestaShop\PrestaShop\Core\Util\ColorBrightnessCalculator; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFunction; - -/** - * Adds color calculation functions to Twig. - */ -class ColorBrightnessCalculatorExtension extends AbstractExtension -{ - /** - * @var ColorBrightnessCalculator - */ - private $brightnessCalculator; - - /** - * @param ColorBrightnessCalculator $brightnessCalculator - */ - public function __construct(ColorBrightnessCalculator $brightnessCalculator) - { - $this->brightnessCalculator = $brightnessCalculator; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new Twig_SimpleFunction( - 'is_color_bright', - [$this->brightnessCalculator, 'isBright'] - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/DocumentationLinkExtension.php b/src/PrestaShopBundle/Twig/Extension/DocumentationLinkExtension.php deleted file mode 100644 index f6b092a7..00000000 --- a/src/PrestaShopBundle/Twig/Extension/DocumentationLinkExtension.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use PrestaShop\PrestaShop\Core\Util\HelperCard\DocumentationLinkProviderInterface; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFunction; - -/** - * Adds "documentation_link" function to Twig so documentation links can be generated in templates - */ -class DocumentationLinkExtension extends AbstractExtension -{ - /** - * @var DocumentationLinkProviderInterface - */ - private $documentationLinkProvider; - - /** - * @param DocumentationLinkProviderInterface $documentationLinkProvider - */ - public function __construct(DocumentationLinkProviderInterface $documentationLinkProvider) - { - $this->documentationLinkProvider = $documentationLinkProvider; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new Twig_SimpleFunction( - 'documentation_link', - [$this->documentationLinkProvider, 'getLink'] - ), - ]; - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/GridExtension.php b/src/PrestaShopBundle/Twig/Extension/GridExtension.php deleted file mode 100644 index 27eb4f09..00000000 --- a/src/PrestaShopBundle/Twig/Extension/GridExtension.php +++ /dev/null @@ -1,226 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use RuntimeException; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Twig\Environment; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFunction as SimpleFunction; - -/** - * Class GridExtension is responsible for providing grid helpers functions. - * - * - column_content(column, record, grid): renders column content based on column type. - * - column_header(column, grid): renders column header based on column type. - */ -class GridExtension extends AbstractExtension -{ - const BASE_COLUMN_CONTENT_TEMPLATE_PATH = '@PrestaShop/Admin/Common/Grid/Columns/Content'; - const BASE_COLUMN_HEADER_TEMPLATE_PATH = '@PrestaShop/Admin/Common/Grid/Columns/Header/Content'; - - /** - * @var Environment - */ - private $twig; - - /** - * @var AdapterInterface - */ - private $cache; - - /** - * @param Environment $twig - * @param AdapterInterface $cache - */ - public function __construct(Environment $twig, AdapterInterface $cache) - { - $this->twig = $twig; - $this->cache = $cache; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new SimpleFunction('column_content', [$this, 'renderColumnContent'], [ - 'is_safe' => ['html'], - ]), - new SimpleFunction('column_header', [$this, 'renderColumnHeader'], [ - 'is_safe' => ['html'], - ]), - new SimpleFunction('is_ordering_column', [$this, 'isOrderingColumn'], [ - 'is_safe' => ['html'], - ]), - ]; - } - - /** - * Render column content. - * - * @param array $record - * @param array $column - * @param array $grid - * - * @return string - * - * @throws RuntimeException when template cannot be found for column - */ - public function renderColumnContent(array $record, array $column, array $grid) - { - $templateCacheKey = sprintf('column_%s_%s_%s_content', $grid['id'], $column['id'], $column['type']); - - if (false === $this->cache->hasItem($templateCacheKey)) { - $template = $this->getTemplatePath( - $column, - $grid, - self::BASE_COLUMN_CONTENT_TEMPLATE_PATH - ); - - if (null === $template) { - throw new RuntimeException(sprintf('Content template for column type "%s" was not found', $column['type'])); - } - - $this->cache->save( - $this->cache - ->getItem($templateCacheKey) - ->set($template) - ); - } - - return $this->twig->render($this->cache->getItem($templateCacheKey)->get(), [ - 'column' => $column, - 'record' => $record, - 'grid' => $grid, - ]); - } - - /** - * Render column header. - * - * @param array $column - * @param array $grid - * - * @return string - */ - public function renderColumnHeader(array $column, array $grid) - { - $templateCacheKey = sprintf( - 'column_%s_%s_%s_header', - $grid['id'], - $column['id'], - $column['type'] - ); - - if (!$this->cache->hasItem($templateCacheKey)) { - $template = $this->getTemplatePath( - $column, - $grid, - self::BASE_COLUMN_HEADER_TEMPLATE_PATH, - 'default.html.twig' - ); - - $this->cache->save( - $this->cache - ->getItem($templateCacheKey) - ->set($template) - ); - } - - return $this->twig->render($this->cache->getItem($templateCacheKey)->get(), [ - 'column' => $column, - 'grid' => $grid, - ]); - } - - /** - * @param array $grid - * - * @return bool - */ - public function isOrderingColumn(array $grid) - { - if (empty($grid['columns']) - || empty($grid['sorting']['order_by']) - || empty($grid['sorting']['order_way']) - || 'asc' != strtolower($grid['sorting']['order_way'])) { - return false; - } - - foreach ($grid['columns'] as $column) { - if ('position' == $column['type']) { - $positionField = $column['id']; - if (strtolower($positionField) == strtolower($grid['sorting']['order_by'])) { - return true; - } - } - } - - return false; - } - - /** - * Get template for column. - * - * @param array $column - * @param array $grid - * @param string $basePath - * @param string|null $defaultTemplate - * - * @return string|null - */ - private function getTemplatePath(array $column, array $grid, $basePath, $defaultTemplate = null) - { - $gridId = $grid['id']; - $columnId = $column['id']; - $columnType = $column['type']; - - $columnGridTemplate = sprintf('%s/%s_%s_%s.html.twig', $basePath, $gridId, $columnId, $columnType); - $gridTemplate = sprintf('%s/%s_%s.html.twig', $basePath, $gridId, $columnType); - $columnTemplate = sprintf('%s/%s.html.twig', $basePath, $columnType); - - if ($this->twig->getLoader()->exists($columnGridTemplate)) { - return $columnGridTemplate; - } - - if ($this->twig->getLoader()->exists($gridTemplate)) { - return $gridTemplate; - } - - if ($this->twig->getLoader()->exists($columnTemplate)) { - return $columnTemplate; - } - - if (null !== $defaultTemplate) { - return sprintf('%s/%s', $basePath, $defaultTemplate); - } - - return null; - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/JsRouterMetadataExtension.php b/src/PrestaShopBundle/Twig/Extension/JsRouterMetadataExtension.php deleted file mode 100644 index 0956ea5e..00000000 --- a/src/PrestaShopBundle/Twig/Extension/JsRouterMetadataExtension.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFunction; - -/** - * Provides data needed for Javascript router component - */ -class JsRouterMetadataExtension extends AbstractExtension -{ - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @var CsrfTokenManagerInterface - */ - private $tokenManager; - - /** - * @var string - */ - private $username; - - /** - * @param RequestStack $requestStack - * @param CsrfTokenManagerInterface $tokenManager - * @param string $username - */ - public function __construct( - RequestStack $requestStack, - CsrfTokenManagerInterface $tokenManager, - string $username - ) { - $this->requestStack = $requestStack; - $this->tokenManager = $tokenManager; - $this->username = $username; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new Twig_SimpleFunction('js_router_metadata', [$this, 'getJsRouterMetadata']), - ]; - } - - /** - * Get base url and security token used for javascript router component. - * - * @return array - */ - public function getJsRouterMetadata() - { - return [ - // base url for javascript router - 'base_url' => $this->requestStack->getCurrentRequest()->getBaseUrl(), - //security token for javascript router - 'token' => $this->tokenManager->getToken($this->username)->getValue(), - ]; - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/LocalizationExtension.php b/src/PrestaShopBundle/Twig/Extension/LocalizationExtension.php deleted file mode 100644 index 3b5d0211..00000000 --- a/src/PrestaShopBundle/Twig/Extension/LocalizationExtension.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use DateTime; -use DateTimeInterface; -use Twig\Extension\AbstractExtension; -use Twig_SimpleFilter; - -class LocalizationExtension extends AbstractExtension -{ - /** - * @var string - */ - private $dateFormatFull; - - /** - * @var string - */ - private $dateFormatLight; - - /** - * @param string $contextDateFormatFull - * @param string $contextDateFormatLight - */ - public function __construct(string $contextDateFormatFull, string $contextDateFormatLight) - { - $this->dateFormatFull = $contextDateFormatFull; - $this->dateFormatLight = $contextDateFormatLight; - } - - public function getFilters(): array - { - return [ - new Twig_SimpleFilter('date_format_full', [$this, 'dateFormatFull']), - new Twig_SimpleFilter('date_format_lite', [$this, 'dateFormatLite']), - ]; - } - - /** - * @param DateTimeInterface|string $date - * - * @return string - */ - public function dateFormatFull($date): string - { - if (!$date instanceof DateTimeInterface) { - $date = new DateTime($date); - } - - return $date->format($this->dateFormatFull); - } - - /** - * @param DateTimeInterface|string $date - * - * @return string - */ - public function dateFormatLite($date): string - { - if (!$date instanceof DateTimeInterface) { - $date = new DateTime($date); - } - - return $date->format($this->dateFormatLight); - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/NumberExtension.php b/src/PrestaShopBundle/Twig/Extension/NumberExtension.php deleted file mode 100644 index 3849cbf2..00000000 --- a/src/PrestaShopBundle/Twig/Extension/NumberExtension.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -declare(strict_types=1); - -namespace PrestaShopBundle\Twig\Extension; - -use PrestaShop\Decimal\Number; -use Twig\Extension\AbstractExtension; -use Twig\TwigFunction; - -/** - * Class NumberExtension provides helper function to create Prestashop/Decimal in twig - */ -class NumberExtension extends AbstractExtension -{ - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [new TwigFunction('number', [$this, 'createNumber'])]; - } - - public function createNumber($number) - { - return new Number((string) $number); - } -} diff --git a/src/PrestaShopBundle/Twig/Extension/PathWithBackUrlExtension.php b/src/PrestaShopBundle/Twig/Extension/PathWithBackUrlExtension.php deleted file mode 100644 index 14deae26..00000000 --- a/src/PrestaShopBundle/Twig/Extension/PathWithBackUrlExtension.php +++ /dev/null @@ -1,114 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Extension; - -use PrestaShop\PrestaShop\Core\Util\Url\BackUrlProvider; -use Symfony\Bridge\Twig\Extension\RoutingExtension; -use Symfony\Component\HttpFoundation\RequestStack; -use Twig\Extension\AbstractExtension; -use Twig\TwigFunction; - -/** - * This class adds a function to twig template which points to back url if such is found in current request. - */ -class PathWithBackUrlExtension extends AbstractExtension -{ - /** - * @var RoutingExtension - */ - private $routingExtension; - - /** - * @var BackUrlProvider - */ - private $backUrlProvider; - - /** - * @var RequestStack - */ - private $requestStack; - - /** - * @param RoutingExtension $routingExtension - * @param BackUrlProvider $backUrlProvider - * @param RequestStack|null $requestStack - */ - public function __construct( - RoutingExtension $routingExtension, - BackUrlProvider $backUrlProvider, - $requestStack - ) { - $this->routingExtension = $routingExtension; - $this->backUrlProvider = $backUrlProvider; - $this->requestStack = $requestStack; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return [ - new TwigFunction( - 'pathWithBackUrl', - [$this, 'getPathWithBackUrl'] - ), - ]; - } - - /** - * Gets original path or back url path. - * - * @param string $name - route name - * @param array $parameters - route parameters - * @param bool $relative - * - * @return string - */ - public function getPathWithBackUrl($name, $parameters = [], $relative = false) - { - $fallbackPath = $this->routingExtension->getPath($name, $parameters, $relative); - - if (null === $this->requestStack) { - return $fallbackPath; - } - - $request = $this->requestStack->getCurrentRequest(); - - if (null === $request) { - return $fallbackPath; - } - - $backUrl = $this->backUrlProvider->getBackUrl($request); - - if (!$backUrl) { - return $fallbackPath; - } - - return $backUrl; - } -} diff --git a/src/PrestaShopBundle/Twig/HookExtension.php b/src/PrestaShopBundle/Twig/HookExtension.php deleted file mode 100644 index 6b2c4ff3..00000000 --- a/src/PrestaShopBundle/Twig/HookExtension.php +++ /dev/null @@ -1,208 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -use PrestaShop\PrestaShop\Adapter\Module\ModuleDataProvider; -use PrestaShop\PrestaShop\Core\Addon\Module\ModuleRepository; -use PrestaShop\PrestaShop\Core\Hook\HookDispatcherInterface; - -/** - * This class is used by Twig_Environment and provide some methods callable from a twig template. - */ -class HookExtension extends \Twig_Extension -{ - /** - * @var HookDispatcherInterface - */ - private $hookDispatcher; - - /** - * @var ModuleDataProvider - */ - private $moduleDataProvider; - - /** - * @var ModuleRepository - */ - private $moduleRepository; - - /** - * Constructor. - * - * @param HookDispatcherInterface $hookDispatcher - * @param ModuleDataProvider $moduleDataProvider - */ - public function __construct( - HookDispatcherInterface $hookDispatcher, - ModuleDataProvider $moduleDataProvider, - ModuleRepository $moduleRepository = null - ) { - $this->hookDispatcher = $hookDispatcher; - $this->moduleDataProvider = $moduleDataProvider; - $this->moduleRepository = $moduleRepository; - } - - /** - * Defines available filters. - * - * @return array Twig_SimpleFilter - */ - public function getFilters() - { - return [ - new \Twig_SimpleFilter('renderhook', [$this, 'renderHook'], ['is_safe' => ['html']]), - new \Twig_SimpleFilter('renderhooksarray', [$this, 'renderHooksArray'], ['is_safe' => ['html']]), - new \Twig_SimpleFilter('hooksarraycontent', [$this, 'hooksArrayContent']), - ]; - } - - /** - * Defines available functions. - * - * @return array Twig_SimpleFilter - */ - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('renderhook', [$this, 'renderHook'], ['is_safe' => ['html']]), - new \Twig_SimpleFunction('renderhooksarray', [$this, 'renderHooksArray'], ['is_safe' => ['html']]), - new \Twig_SimpleFunction('hookcount', [$this, 'hookCount']), - new \Twig_SimpleFunction('hooksarraycontent', [$this, 'hooksArrayContent']), - ]; - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'twig_hook_extension'; - } - - /** - * Calls the HookDispatcher, and dispatch a RenderingHookEvent. - * - * The listeners will then return html data to display in the Twig template. - * - * @param string $hookName the name of the hook to trigger - * @param array $hookParameters the parameters to send to the Hook - * - * @throws \Exception if the hookName is missing - * - * @return array[string] All listener's responses, ordered by the listeners' priorities - */ - public function renderHooksArray($hookName, $hookParameters = []) - { - if ('' == $hookName) { - throw new \Exception('Hook name missing'); - } - - // The call to the render of the hooks is encapsulated into a ob management to avoid any call of echo from the - // modules. - ob_start(); - $renderedHook = $this->hookDispatcher->dispatchRenderingWithParameters($hookName, $hookParameters); - $renderedHook->outputContent(); - ob_end_clean(); - - $render = []; - foreach ($renderedHook->getContent() as $module => $hookRender) { - $moduleAttributes = $this->moduleRepository->getModuleAttributes($module); - $render[] = [ - 'id' => $module, - 'name' => $this->moduleDataProvider->getModuleName($module), - 'content' => $hookRender, - 'attributes' => $moduleAttributes->all(), - ]; - } - - return $render; - } - - /** - * Calls the HookDispatcher, and dispatch a RenderingHookEvent. - * - * The listeners will then return html data to display in the Twig template. - * - * @param string $hookName the name of the hook to trigger - * @param array $hookParameters the parameters to send to the Hook - * - * @throws \Exception if the hookName is missing - * - * @return string all listener's responses, concatenated in a simple string, ordered by the listeners' priorities - */ - public function renderHook($hookName, array $hookParameters = []) - { - if ($hookName == '') { - throw new \Exception('Hook name missing'); - } - - return $this->hookDispatcher - ->dispatchRenderingWithParameters($hookName, $hookParameters) - ->outputContent(); - } - - /** - * Return the concatenated content of a renderHooksArray response - * - * @param array $hooksArray the array returned by the renderHooksArray function - * - * @return string - */ - public function hooksArrayContent($hooksArray) - { - if (!is_array($hooksArray)) { - return ''; - } - - $content = ''; - - foreach ($hooksArray as $hook) { - $content .= $hook['content'] ?? ''; - } - - return $content; - } - - /** - * Count how many listeners will respond to the hook name. - * Does not trigger the hook, so maybe some listeners could not add a response to the result. - * - * @deprecated since 1.7.7.0 - * - * @param string $hookName - * - * @return number the listeners count that will respond to the hook name - */ - public function hookCount($hookName) - { - @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.7.7.0.', E_USER_DEPRECATED); - - return count($this->hookDispatcher->getListeners(strtolower($hookName))); - } -} diff --git a/src/PrestaShopBundle/Twig/LayoutExtension.php b/src/PrestaShopBundle/Twig/LayoutExtension.php deleted file mode 100644 index 29808cb7..00000000 --- a/src/PrestaShopBundle/Twig/LayoutExtension.php +++ /dev/null @@ -1,270 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -use Exception; -use PrestaShop\PrestaShop\Adapter\Configuration; -use PrestaShop\PrestaShop\Adapter\Currency\CurrencyDataProvider; -use PrestaShop\PrestaShop\Adapter\LegacyContext; - -/** - * This class is used by Twig_Environment and provide layout methods callable from a twig template. - */ -class LayoutExtension extends \Twig_Extension implements \Twig_Extension_GlobalsInterface -{ - /** @var LegacyContext */ - private $context; - - /** @var string */ - private $environment; - - /** @var Configuration */ - private $configuration; - - /** @var CurrencyDataProvider */ - private $currencyDataProvider; - - /** - * Constructor. - * - * Keeps the Context to look inside language settings. - * - * @param LegacyContext $context - * @param string $environment - * @param Configuration $configuration - * @param CurrencyDataProvider $currencyDataProvider - */ - public function __construct( - LegacyContext $context, - $environment, - Configuration $configuration, - CurrencyDataProvider $currencyDataProvider - ) { - $this->context = $context; - $this->environment = $environment; - $this->configuration = $configuration; - $this->currencyDataProvider = $currencyDataProvider; - } - - /** - * Provides globals for Twig templates. - * - * @return array the base globals available in twig templates - */ - public function getGlobals() - { - /* - * As this is a twig extension we need to be very resilient and prevent it from crashing - * the environment, for example the command debug:twig should not fail because of this extension - */ - - try { - $defaultCurrency = $this->context->getEmployeeCurrency() ?: $this->currencyDataProvider->getDefaultCurrency(); - } catch (\Exception $e) { - $defaultCurrency = null; - } - try { - $rootUrl = $this->context->getRootUrl(); - } catch (\Exception $e) { - $rootUrl = null; - } - - return [ - 'theme' => $this->context->getContext()->shop->theme, - 'default_currency' => $defaultCurrency, - 'root_url' => $rootUrl, - 'js_translatable' => [], - ]; - } - - /** - * Define available filters. - * - * @return array Twig_SimpleFilter - */ - public function getFilters() - { - return [ - new \Twig_SimpleFilter('configuration', [$this, 'getConfiguration']), - ]; - } - - /** - * Returns a list of functions to add to the existing list. - * - * @return array An array of functions - */ - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('getLegacyLayout', [$this, 'getLegacyLayout']), - new \Twig_SimpleFunction('getAdminLink', [$this, 'getAdminLink']), - new \Twig_SimpleFunction('youtube_link', [$this, 'getYoutubeLink']), - ]; - } - - /** - * Returns a legacy configuration key. - * - * @param string $key - * - * @return array An array of functions - */ - public function getConfiguration($key) - { - return $this->configuration->get($key); - } - - /** - * Get admin legacy layout into old controller context. - * - * Parameters can be set manually into twig template or sent from controller - * For details : check Resources/views/Admin/Layout.html.twig - * - * @param string $controllerName The legacy controller name - * @param string $title The page title to override default one - * @param array $headerToolbarBtn The header toolbar to override - * @param string $displayType The legacy display type variable - * @param bool $showContentHeader Can force header toolbar (buttons and title) to be hidden with false value - * @param array|string $headerTabContent Tabs labels - * @param bool $enableSidebar Allow to use right sidebar to display docs for instance - * @param string $helpLink If specified, will be used instead of legacy one - * @param string $metaTitle - * @param bool $useRegularH1Structure allows complex

      structure if set to false - * - * @throws Exception if legacy layout has no $content var replacement - * - * @return string The html layout - */ - public function getLegacyLayout( - $controllerName = '', - $title = '', - $headerToolbarBtn = [], - $displayType = '', - $showContentHeader = true, - $headerTabContent = '', - $enableSidebar = false, - $helpLink = '', - $jsRouterMetadata = [], - $metaTitle = '', - $useRegularH1Structure = true - ) { - if ($this->environment == 'test') { - return <<<'EOF' - - - Test layout - {% block stylesheets %}{% endblock %}{% block extra_stylesheets %}{% endblock %} - - - {% block content_header %}{% endblock %} - {% block content %}{% endblock %} - {% block content_footer %}{% endblock %} - {% block javascripts %}{% endblock %} - {% block extra_javascripts %}{% endblock %} - {% block translate_javascripts %}{% endblock %} - - -EOF; - } - - $layout = $this->context->getLegacyLayout( - $controllerName, - $title, - $headerToolbarBtn, - $displayType, - $showContentHeader, - $headerTabContent, - $enableSidebar, - $helpLink, - $jsRouterMetadata, - $metaTitle, - $useRegularH1Structure - ); - - //test if legacy template from "content.tpl" has '{$content}' - if (false === strpos($layout, '{$content}')) { - throw new Exception('PrestaShopBundle\Twig\LayoutExtension cannot find the {$content} string in legacy layout template', 1); - } - - $content = str_replace( - [ - '{$content}', - 'var currentIndex = \'index.php\';', - '', - '', - ], - [ - '{% block content_header %}{% endblock %} - {% block content %}{% endblock %} - {% block content_footer %}{% endblock %} - {% block sidebar_right %}{% endblock %}', - 'var currentIndex = \'' . $this->context->getAdminLink($controllerName) . '\';', - '{% block stylesheets %}{% endblock %}{% block extra_stylesheets %}{% endblock %}', - '{% block javascripts %}{% endblock %}{% block extra_javascripts %}{% endblock %}{% block translate_javascripts %}{% endblock %}', - ], - $layout - ); - - return $content; - } - - /** - * This is a Twig port of the Smarty {$link->getAdminLink()} function. - * - * @param string $controller the controller name - * @param bool $withToken - * @param array[string] $extraParams - * - * @return string - */ - public function getAdminLink($controllerName, $withToken = true, $extraParams = []) - { - return $this->context->getAdminLink($controllerName, $withToken, $extraParams); - } - - /** - * KISS function to get an embeded iframe from Youtube. - */ - public function getYoutubeLink($watchUrl) - { - $embedUrl = str_replace(['watch?v=', 'youtu.be/'], ['embed/', 'youtube.com/embed/'], $watchUrl); - - return ''; - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'twig_layout_extension'; - } -} diff --git a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateIterator.php b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateIterator.php deleted file mode 100644 index 6e9432de..00000000 --- a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateIterator.php +++ /dev/null @@ -1,109 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Locator; - -use Symfony\Bundle\TwigBundle\TemplateIterator; -use Symfony\Component\Finder\Finder; -use Symfony\Component\HttpKernel\KernelInterface; - -/** - * Extended class: Iterator for all templates in bundles and in the application Resources directory. - * This one applies a specific filter on the module folder, in order to take only *.twig - */ -class ModuleTemplateIterator extends TemplateIterator -{ - private $kernel; - private $rootDir; - private $templates; - private $paths; - private $defaultPath; - - /** - * @param KernelInterface $kernel A KernelInterface instance - * @param string $rootDir The directory where global templates can be stored - * @param array $paths Additional Twig paths to warm - * @param string $defaultPath The directory where global templates can be stored - */ - public function __construct(KernelInterface $kernel, $rootDir, array $paths = [], $defaultPath = null) - { - $this->paths = []; - $this->kernel = $kernel; - $this->rootDir = $rootDir; - $this->defaultPath = $defaultPath; - - $keyToRemove = array_search('Modules', $paths); - // If the key was found, move it in a new array - if (false !== $keyToRemove) { - $exceptionPath = $paths[$keyToRemove]; - unset($paths[$keyToRemove]); - $this->paths = [$keyToRemove => $exceptionPath]; - } - parent::__construct($kernel, $rootDir, $paths, $defaultPath); - } - - /** - * {@inheritdoc} - */ - public function getIterator() - { - if (null !== $this->templates) { - return $this->templates; - } - - // Not done yet, we need the array back - $this->templates = iterator_to_array(parent::getIterator()); - - foreach ($this->paths as $dir => $namespace) { - $this->templates = array_merge($this->templates, $this->findTemplatesInDirectory($dir, $namespace)); - } - - return $this->templates = new \ArrayIterator(array_unique($this->templates)); - } - - /** - * Find templates in the given directory. - * - * @param string $dir The directory where to look for templates - * @param string|null $namespace The template namespace - * - * @return array - */ - private function findTemplatesInDirectory($dir, $namespace = null, array $excludeDirs = []) - { - if (!is_dir($dir)) { - return []; - } - - $templates = []; - foreach (Finder::create()->files()->name('*.twig')->followLinks()->in($dir)->exclude($excludeDirs) as $file) { - $templates[] = (null !== $namespace ? '@' . $namespace . '/' : '') . str_replace('\\', '/', $file->getRelativePathname()); - } - - return $templates; - } -} diff --git a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php b/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php deleted file mode 100644 index f378ef37..00000000 --- a/src/PrestaShopBundle/Twig/Locator/ModuleTemplateLoader.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig\Locator; - -use Twig\Loader\FilesystemLoader; - -/** - * Loads templates from PrestaShop modules. - */ -class ModuleTemplateLoader extends FilesystemLoader -{ - /** - * @param array $namespaces a collection of path namespaces with namespace names - * @param array $modulePaths A path or an array of paths where to look for module templates - */ - public function __construct(array $namespaces, array $modulePaths = []) - { - if (!empty($modulePaths)) { - $this->registerNamespacesFromConfig($modulePaths, $namespaces); - } - } - - /** - * Register namespaces in module and link them to the right paths. - * - * @param array $modulePaths - * @param array $namespaces - */ - private function registerNamespacesFromConfig(array $modulePaths, array $namespaces) - { - foreach ($namespaces as $namespace => $namespacePath) { - $templatePaths = []; - - foreach ($modulePaths as $path) { - if (is_dir($dir = $path . '/views/PrestaShop/' . $namespacePath)) { - $templatePaths[] = $dir; - } - } - $this->setPaths($templatePaths, $namespace); - } - } -} diff --git a/src/PrestaShopBundle/Twig/TranslationsExtension.php b/src/PrestaShopBundle/Twig/TranslationsExtension.php deleted file mode 100644 index 5c70658f..00000000 --- a/src/PrestaShopBundle/Twig/TranslationsExtension.php +++ /dev/null @@ -1,573 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Twig; - -use Doctrine\Common\Util\Inflector; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Routing\RouterInterface; - -class TranslationsExtension extends \Twig_Extension -{ - /** - * @var \Symfony\Component\Translation\TranslatorInterface - */ - public $translator; - - /** - * @var \Psr\Log\LoggerInterface - */ - public $logger; - - /** - * @var ContainerInterface - */ - private $container; - - /** - * @var RouterInterface - */ - private $router; - - /** - * @var string - */ - private $theme; - - public function __construct(ContainerInterface $container, RouterInterface $router) - { - $this->container = $container; - $this->router = $router; - } - - /** - * Returns a list of functions to add to the existing list. - * - * @return array An array of functions - */ - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('getTranslationsTree', [$this, 'getTranslationsTree']), - new \Twig_SimpleFunction('getTranslationsForms', [$this, 'getTranslationsForms']), - ]; - } - - /** - * Returns concatenated edit translation forms. - * - * @param array $translationsTree - * @param null $themeName - * - * @return string - */ - public function getTranslationsForms(array $translationsTree, $themeName = null) - { - $output = ''; - $viewProperties = $this->getSharedEditFormViewProperties(); - $viewProperties['is_search_results'] = true; - $this->theme = $themeName; - - foreach ($translationsTree as $topLevelDomain => $tree) { - $output .= $this->concatenateEditTranslationForm($tree, $viewProperties); - } - - return $output; - } - - public function concatenateEditTranslationForm($subtree, $viewProperties) - { - $output = ''; - $hasMessages = $this->hasMessages($subtree); - - if ($hasMessages) { - $camelizedDomain = reset(array_keys($subtree['__messages'])); - $messages = $subtree['__messages'][$camelizedDomain]; - - foreach ($messages as $translationKey => $translation) { - $viewProperties['camelized_domain'] = $camelizedDomain; - $viewProperties['translation_key'] = $translationKey; - $viewProperties['translation'] = $translation; - - $output .= $this->renderEditTranslationForm($viewProperties); - } - } else { - foreach ($subtree as $tree) { - $output .= $this->concatenateEditTranslationForm($tree, $viewProperties); - } - } - - if ($hasMessages && count($subtree) > 1) { - unset($subtree['__messages']); - $output .= $this->concatenateEditTranslationForm($subtree, $viewProperties); - } - - return $output; - } - - /** - * Returns a tree of translations key values. - * - * @param array $translationsTree - * @param null $themeName - * - * @return string - */ - public function getTranslationsTree(array $translationsTree, $themeName = null) - { - $this->theme = $themeName; - - $output = ''; - - foreach ($translationsTree as $topLevelDomain => $tree) { - $output .= $this->concatenateSubtreeHeader($topLevelDomain, $tree); - } - - return $output; - } - - /** - * @param $tree - * @param int $level - * - * @return string - */ - public function makeSubtree($tree, $level = 3) - { - $output = ''; - $messagesSubtree = $this->hasMessages($tree); - - if ($messagesSubtree) { - $camelizedDomain = reset(array_keys($tree['__messages'])); - $messagesTree = $tree['__messages'][$camelizedDomain]; - - $formIndex = 0; - $pageIndex = 1; - $itemsPerPage = 25; - $output .= '
      '; - - $viewProperties = $this->getSharedEditFormViewProperties(); - - foreach ($messagesTree as $translationKey => $translation) { - $viewProperties['camelized_domain'] = $camelizedDomain; - $viewProperties['translation_key'] = $translationKey; - $viewProperties['translation'] = $translation; - - $output .= $this->renderEditTranslationForm($viewProperties); - - $isLastPage = $formIndex + 1 === count($messagesTree); - - if ($isLastPage) { - $output .= '
      '; - } elseif ((0 === $formIndex % $itemsPerPage) && ($formIndex > 0)) { - ++$pageIndex; - - // Close div with page class - $output .= '

      '; - $output .= '
      '; - } - - ++$formIndex; - } - - // Close div with page class when no message is available - if (count($messagesTree) === 0) { - $output .= '
      '; - } - } else { - foreach ($tree as $subdomain => $subtree) { - $output .= $this->concatenateSubtreeHeader($subdomain, $subtree, $level); - } - } - - return $output; - } - - /** - * @return array - */ - protected function getSharedEditFormViewProperties() - { - return [ - 'action' => $this->router->generate('admin_international_translations_edit'), - 'label_edit' => $this->translator->trans('Save', [], 'Admin.Actions'), - 'label_reset' => $this->translator->trans('Reset', [], 'Admin.Actions'), - 'notification_success' => $this->translator->trans( - 'Translation successfully updated', - [], - 'Admin.International.Notification' - ), - 'notification_error' => $this->translator->trans( - 'Failed to update translation', - [], - 'Admin.International.Notification' - ), - ]; - } - - /** - * @param $properties - * - * @return mixed|string - */ - protected function renderEditTranslationForm($properties) - { - list($domain, $locale) = explode('.', $properties['camelized_domain']); - $translationValue = $this->getTranslationValue($properties['translation']); - $defaultTranslationValue = $this->getDefaultTranslationValue( - $properties['translation_key'], - $domain, - $locale, - $properties['translation'] - ); - - $isSearchResults = false; - - if (array_key_exists('is_search_results', $properties)) { - $isSearchResults = $properties['is_search_results']; - } - - $breadcrumbParts = explode('_', Inflector::tableize($domain)); - - return $this->container->get('templating')->render( - '@PrestaShop/Admin/Translations/include/form-edit-message.html.twig', - [ - 'default_translation_value' => $defaultTranslationValue, - 'domain' => $domain, - 'edited_translation_value' => $translationValue, - 'is_translated' => '' !== $translationValue, - 'action' => $properties['action'], - 'label_edit' => $properties['label_edit'], - 'label_reset' => $properties['label_reset'], - 'locale' => $locale, - 'notification_error' => $properties['notification_error'], - 'notification_success' => $properties['notification_success'], - 'translation_key' => $properties['translation_key'], - 'hash' => $this->getTranslationHash($domain, $properties['translation_key']), - 'theme' => $this->theme, - 'breadcrumb_parts' => $breadcrumbParts, - 'is_search_results' => $isSearchResults, - ] - ); - } - - protected function getTranslationHash($domain, $translationKey) - { - return md5($domain . $translationKey); - } - - /** - * @param $translationKey - * @param $domain - * @param $locale - * @param $translationValue - * - * @return array - */ - protected function getDefaultTranslationValue($translationKey, $domain, $locale, $translationValue) - { - $defaultTranslationValue = $this->translator->trans($translationKey, [], $domain, $locale); - - // Extract default translation value from xliff files for reset - if (is_array($translationValue)) { - $defaultTranslationValue = $translationValue['xlf']; - } - - return $defaultTranslationValue; - } - - /** - * @param $translation - * - * @return mixed - */ - protected function getTranslationValue($translation) - { - return !empty($translation['db']) ? $translation['db'] : $translation['xlf']; - } - - /** - * @param $tree - * - * @return bool - */ - protected function hasMessages($tree) - { - return array_key_exists('__messages', $tree); - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'twig_translations_extension'; - } - - /** - * @param $subdomain - * @param $subtree - * @param int $level - * - * @return string - */ - protected function concatenateSubtreeHeader($subdomain, $subtree, $level = 2) - { - $hasMessagesSubtree = $this->hasMessages($subtree); - $subject = $subdomain; - - $id = null; - if ($hasMessagesSubtree) { - $id = $this->parseDomain($subtree); - } - - $output = $this->tagSubject($subject, $hasMessagesSubtree, $id); - - if (!$hasMessagesSubtree) { - $output = str_replace( - '{{ missing translations warning }}', - $this->translator->trans('%d missing', [], 'Admin.International.Feature'), - $output - ); - } else { - $output = $this->replaceWarningPlaceholder($output, $subtree); - } - - if ($hasMessagesSubtree) { - $output .= $this->container->get('templating')->render( - '@PrestaShop/Admin/Translations/include/button-toggle-messages-visibility.html.twig', - [ - 'label_show_messages' => $this->translator->trans('Show messages', [], 'Admin.International.Feature'), - 'label_hide_messages' => $this->translator->trans('Hide messages', [], 'Admin.International.Feature'), - ] - ); - - $output .= $this->getNavigation($this->parseDomain($subtree)); - } - - $formStart = $this->getTranslationsFormStart($subtree, $output); - $output = $this->container->get('templating')->render( - '@PrestaShop/Admin/Translations/include/translations-form-end.html.twig', - [ - 'form_start' => $formStart, - 'subtree' => $this->makeSubtree($subtree, $level + 1), - ] - ); - - if ($hasMessagesSubtree) { - // Close div with translation-domain class - $output .= ''; - - // A subtree with messages contains at least a subdomain - if (count($subtree) > 1) { - unset($subtree['__messages']); - $output .= $this->concatenateSubtreeHeader($subdomain, $subtree, $level); - } - } - - return $output; - } - - /** - * @param $subtree - * @param $output - * - * @return string - */ - protected function getTranslationsFormStart(&$subtree, $output) - { - $id = ''; - $parentAttribute = ' class="subdomains hide"'; - if (array_key_exists('__fixed_length_id', $subtree)) { - $fixedLengthId = $subtree['__fixed_length_id']; - unset($subtree['__fixed_length_id']); - $id = ' id="' . $fixedLengthId . '" '; - $parentAttribute = ' data-parent-of="' . $fixedLengthId . '"'; - } - - $domainAttribute = ''; - if (array_key_exists('__domain', $subtree)) { - $domainAttribute = ' data-domain="' . $subtree['__domain'] . '" '; - unset($subtree['__domain']); - } - - $totalTranslationsAttribute = ''; - if (array_key_exists('__messages', $subtree)) { - $totalTranslations = count(array_values($subtree['__messages'])[0]); - $totalTranslationsAttribute = ' data-total-translations="' . $this->translator->trans( - '%nb_translations% expressions', - ['%nb_translations%' => $totalTranslations], - 'Admin.International.Feature' - ) . '"'; - } - - $missingTranslationsAttribute = ''; - if (array_key_exists('__metadata', $subtree)) { - $missingTranslations = $subtree['__metadata']['missing_translations']; - $missingTranslationsAttribute = ' data-missing-translations="' . $missingTranslations . '"'; - unset($subtree['__metadata']); - } - - return $this->container->get('templating')->render( - '@PrestaShop/Admin/Translations/include/translations-form-start.html.twig', - [ - 'id' => $id, - 'domain' => $domainAttribute, - 'parent' => $parentAttribute, - 'total_translations' => $totalTranslationsAttribute, - 'missing_translations' => $missingTranslationsAttribute, - 'title' => $output, - ] - ); - } - - /** - * @param $output - * @param $subtree - * - * @return string - */ - protected function replaceWarningPlaceholder($output, $subtree) - { - $missingTranslationsMessage = ''; - $missingTranslationsLongMessage = ''; - $missingTranslationsClass = ''; - if (array_key_exists('__metadata', $subtree) && $subtree['__metadata']['missing_translations'] > 0) { - $missingTranslationsCount = $subtree['__metadata']['missing_translations']; - $domain = $subtree['__metadata']['domain']; - - $missingTranslationsMessage = - '
      ' . - $this->translator->trans( - '%nb_translations% missing', - ['%nb_translations%' => $missingTranslationsCount], - 'Admin.International.Feature' - ) . - '
      '; - $missingTranslationsLongMessage = - '
      ' . - $this->translator->trans( - '%nb_translations% translations are missing in %domain%', - [ - '%nb_translations%' => $missingTranslationsCount, - '%domain%' => $domain, - ], - 'Admin.International.Feature' - ) . - '
      '; - $missingTranslationsClass = ' missing-translations'; - } - - $warning = str_replace( - [ - '{{ missing translations message }}', - '{{ missing translations long message }}', - ], - [ - $missingTranslationsMessage, - $missingTranslationsLongMessage, - ], - '{{ missing translations message }}{{ missing translations long message }}' - ); - - return str_replace( - [ - '{{ missing translations warning }}', - '{{ missing translations class }}', - ], - [ - $warning, - $missingTranslationsClass, - ], - $output - ); - } - - /** - * @param $subtree - * - * @return mixed - */ - protected function parseDomain($subtree) - { - list($camelizedDomain) = $subtree['__messages']; - list($domain) = explode('.', $camelizedDomain); - - return $domain; - } - - /** - * @param $id - * - * @return string - */ - protected function getNavigation($id) - { - return $this->container->get('templating')->render( - '@PrestaShop/Admin/Translations/include/pagination-bar.html.twig', - ['page_id' => $id] - ); - } - - /** - * @param $subject - * @param $isLastChild - * @param null $id - * - * @return string - */ - protected function tagSubject($subject, $isLastChild, $id = null) - { - if ($isLastChild) { - $openingTag = '

      ' . - ''; - $closingTag = '{{ missing translations warning }}

      '; - } else { - $openingTag = '

      '; - $closingTag = '' . - '
      ' . - '' . - '{{ missing translations warning }}' . - '' . - '
      ' . - '

      '; - } - - if ($id) { - $openingTag = ''; - $closingTag = ''; - - if (!$isLastChild) { - $openingTag = '

      ' . $openingTag; - $closingTag = $closingTag . '

      '; - } - } - - return $openingTag . $subject . $closingTag; - } -} diff --git a/src/PrestaShopBundle/Utils/FloatParser.php b/src/PrestaShopBundle/Utils/FloatParser.php deleted file mode 100644 index 0d9402a7..00000000 --- a/src/PrestaShopBundle/Utils/FloatParser.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Utils; - -use PrestaShop\PrestaShop\Core\Util\ArabicToLatinDigitConverter; - -/** - * Converts strings into floats. - */ -class FloatParser -{ - /** - * @var ArabicToLatinDigitConverter - */ - private $arabicToLatinNumberConverter; - - public function __construct(ArabicToLatinDigitConverter $arabicToLatinDigitConverter = null) - { - $this->arabicToLatinNumberConverter = $arabicToLatinDigitConverter ?? new ArabicToLatinDigitConverter(); - } - - /** - * Constructs a float value from an arbitrarily-formatted string. - * - * This method supports any thousand and decimal separator. - * If the string is ambiguous (e.g. 123,456) the interpreter will interpret the last group of numbers - * as the decimal part. - * - * In order to prevent unexpected behavior, make sure that your value has a decimal part. - * - * Examples: - * - '123,456' --> 123.456 - * - '123,456,00' --> 123456.00 - * - '12,345,678 --> 12345.678 - * - * @param string $value - * - * @throws \InvalidArgumentException if the provided value is not a string - * or if it cannot be interpreted as a number - * - * @return float - */ - public function fromString($value) - { - if (!is_string($value)) { - throw new \InvalidArgumentException(sprintf('Invalid argument: string expected, got %s', gettype($value))); - } - - $value = trim($value); - if ('' === $value) { - return 0.0; - } - - // replace arabic numbers by latin - $value = $this->arabicToLatinNumberConverter->convert($value); - - // remove all non-digit characters - $split = preg_split('/[^\dE-]+/', $value); - - if (1 === count($split)) { - // there's no decimal part - return (float) $value; - } - - foreach ($split as $part) { - if ('' === $part) { - throw new \InvalidArgumentException(sprintf('Invalid argument: "%s" cannot be interpreted as a number', $value)); - } - } - - // use the last part as decimal - $decimal = array_pop($split); - - // reconstruct the number using dot as decimal separator - $value = implode('', $split) . '.' . $decimal; - - return (float) $value; - } -} diff --git a/src/PrestaShopBundle/Utils/ZipManager.php b/src/PrestaShopBundle/Utils/ZipManager.php deleted file mode 100644 index d72048fe..00000000 --- a/src/PrestaShopBundle/Utils/ZipManager.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright Since 2007 PrestaShop SA and Contributors - * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) - */ - -namespace PrestaShopBundle\Utils; - -use RecursiveDirectoryIterator; -use RecursiveIteratorIterator; -use ZipArchive; - -class ZipManager -{ - public function createArchive($filename, $folder) - { - $zip = new ZipArchive(); - - $zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE); - - $files = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($folder), - RecursiveIteratorIterator::LEAVES_ONLY - ); - - foreach ($files as $filename => $file) { - if (!$file->isDir()) { - $filePath = $file->getRealPath(); - $relativePath = substr($filename, strlen($folder) + 1); - - $zip->addFile($filePath, $relativePath); - } - } - - $zip->close(); - } -} diff --git a/themes/classic/assets/css/012cf6a10129e2275d79d6adac7f3b02.woff b/themes/classic/assets/css/012cf6a10129e2275d79d6adac7f3b02.woff deleted file mode 100644 index b648a3eea2d16b6ce783906d6b7d5f251b9eb56c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57620 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

      wF7DI|Kx|V1sBQ9FYs>m5C)C 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 BJ$(QG diff --git a/themes/classic/assets/css/0266b05265f317a7409560b751cd61e8.svg b/themes/classic/assets/css/0266b05265f317a7409560b751cd61e8.svg deleted file mode 100644 index 5c2fae4a..00000000 --- a/themes/classic/assets/css/0266b05265f317a7409560b751cd61e8.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - diff --git a/themes/classic/assets/css/082a71677e756fb75817e8f262a07cb4.svg b/themes/classic/assets/css/082a71677e756fb75817e8f262a07cb4.svg deleted file mode 100644 index 119defaa..00000000 --- a/themes/classic/assets/css/082a71677e756fb75817e8f262a07cb4.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - Artboard 3 - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/themes/classic/assets/css/154da4697acc779b55af0a67f1241e4e.ttf b/themes/classic/assets/css/154da4697acc779b55af0a67f1241e4e.ttf deleted file mode 100644 index dc93fea6cf3f0473c083ef20eb6a1ef2e6b8e857..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279268 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

      F?nB4BmI8- zuZt=C8AEB`k;XHY%^KCiKMhcM^S4x*44#)$8`{ze6Y9#_-NQHGSyA zmXG(6A#`bsR&LQf$056mGX5|vO2ymz07?o1tL7tqdXg3|v8*QraYZk$(FUWeYF^A) zrqf=JGq|_YI!h}Z|9aM^^CTkJdDaG2*sk65x5;R~Tgs?Rld8<5tb{HH!+Mg$LnERw zu*cKeW1D)p*~#((P5=B|?_dj-x0QqAStsfC$_QDCIVj1u{6-dXbu}0nIR`GvH_&e~ zXx&kX$+fRWF4|{C7StoYkBL%IsnWq^L1>amntl~~mK!dU6w%|Kn9$#WoAXa(^bAO; zA}lV}f!3j+kHh?Mp5(GTT;Sa>+%kx{v8?#G>5O`%M2nxk8S(45pN?DRPPL&|Pf26s zy`AYc&ish+WMb|P{#OU(`TShvU&lKGPK&2jQ{Hdt2IJu;iRk5EKa# z1Vm5}B}kGalCxwG1j&dF%K`*L!wRoX>^~jI=At$v`P_9@EkAqva}`x`{(X(R53*B> z-Zzy;r+Q3GHk)U$&uMj`LhT(1DDOr1)Yy|U%%t0e$Fe+i>^fpsbN}dl(KBC!6Ycvg z?}ZD2Wl%abgTcy(uuIx zQoTJ1C41DMrKWFmKox$rT9q|eGX?pM+$SKp$58fg4_y+$P?w3)>pFgq_m?If>p!q; zDvtK~taIW1yV&x|nO9yC4;IjS=1Eum>>KOu-x9v%73Wjw@PQhA@6m*^m#S1U7{}cxQa)6AO8C|L4Ym^4izevue2>izzJ6^wVxoq+Jr`miQbOEtDrD)$K#<@XI>{E`lYMkABT*-oT93H7?LyI2GOfGZm*PrmdySV1orjTRRbi&@B%hfVpJkacB)vm4 z!P~faVmH##TSG8olTLSHkvpWxZi$6$_{)5vnp^2of@%kWfAP3q=2%Y=8HlfhHAZSU z^>c~Sd{J*d2>F7Lf2njnL>^11yc>B%@Yt>oX%CpO(!>w=WM%(m&$A<4jh8+#yt^gj zsTLvyF$kLJuH>4t*^pU&TqY)Qo~+d>^yD}vU(t2r#H~Hyl)15dOPPf?ice^FGzg!E z%N-|ppbSo#a;ciSY}7`T#2E~qVMboh@T&4GY492M_^_e;;LR%b&ex|KcO!TA%kx~q zD)P83SBE)hki1KjkG2!qQ^2aW_S$0aY&|?sS%=%`-o8uLpHy9cL4a;}MMh%ML3%a! z?8yu`a~Er%)uVy|q0}4jn6~W>r7K)qrz~P@OyD0+zBtZQRaQlLItsMWW2;{!c?V?T z!ITi~soLe>scfYRF|q55wopm3I(+Zr`_%N(LdT>PX*4Rst#D0Bhki=#?ZY`kUh-0P zuP2dkLCPzp*?Q(jZVko^Or2Xf7nI6zOtZ^58bQja8}x!XKS4i-?`fSsNe|CCnrm0y zT_<`2qyTV6afKct(x@59&~2JtfXWS?x3aB|U1=JmeYJDf#yfyek5yZMutJV8bNp$+ zhTVKyBZNh(sJ~68go?N}-~o%zJy@>JbornhUCa&n59w*dYxxoi?qqZ5hK20Ci!l4I zR9vT%_VT;wPwYSS={#O*Iu?QOS6S>c2!|VtDnna%ZApcp_GvdVXoaKHocL60u}>@| ztLrqX)9Fu94Bd^b;2ES?s3lRKiVjaaSF}sX%e20 z4;G-m@>HZ@=8Nf6h{8pqlh%s6&)Mo2ju;*(u6nHOShtOm?x(P{;vXYDwO|6_ne(i* znJ8#^>u@qY(5dW@XyUVmqB4@Q5QA`CC)*Vr)!t4^D^A+!6}3+$HWXHeGp`UsG6+UO z;``zAQtLb}#8dDs?49S4N}>|uZmhF$ciCzRA+&wR_g-xY4n0TLzP(Z_aH(jXetKUj zGwE#&e}v)uQqdTSL+6=cf!Ra4kJx^(Bg_b6`K|d9#o9QkwqZBfr-M1-SUz}qYQO`@ zmv$rjmG;deH|49+UIq0Pq+jabUx19pUoZ*S7NYG( z%eQH)?UEK)i(iR0WmoTEajGptn=ty=YhLq3T?>A%85=LyT%vT>H}(@v zFWK_Wm$lv-y(eP~s4Fb16f>WcP8u~+p!H>y*JceiAaxw`Ur&(UtMXoy#*$(wy5EU( zrq$?OgbycYWn{0f4S{2~3ECcJA1719p1l~;X+g#ciJjRjjiPmZ_=>|(l3On`ox>bl znqROve5F!s(w=>xqqW1j{bQ?%6Q*}r&ef~)qm-6lse>Zx^k~~f=v@Za-ofqZYkU;N zYCH^j4qVyepQW!3GPn*JSw`Gr1Bo__G3finoZZOWXx`hm$;pOBJt2A4F zn?9xPYNHuqAjZHFo7}&@r!(5}j_5eobxA}94jqFG z=ZR-idsH!6J_K%0&bY|msD2h$U=&(#&&F)~)EO_;8}#%Gvg)zZL^S^F-Y7=Tv=DKN zk5=a+RtO?W91}!DMD2sTGxwIHLZ&9LogC!WL@a@GpGFU5m?b1=!U>NuNQIV@N|hNg z?MVkEX!0FtjJ4TH>bhi{>5Ujxco8v{XKzNdn6^W=zSrZMK$5|$XUa6=%=zT3@rFHf zre3gDxoj1|#T-tB=Q~Ds!`iggNCU(Bwpy;HFlg@fACIp)W|Z1~XvIVs*&Q{2eX*G$ z$(S=Ja148s{irmIvviIy#mDpM%{jj%e%5fh00Qlck59GHNQ>*%!mZMqL(H~PGR*FK z)D0{Bi(yf{PVX{f&$=`rUpq!6%ZSCQ*@{fMNa} zLUI2}N2IKn#LKQLbS2|+!!dBrxgKgIA~hKe@NxBG;j{CnUC%VHG4M~M3w;czbV?oERxLxKqRy`xH}7cRdhI3~p+ zb5&rAcVg#@i2I{i)1Z;*3w1G~17&ZZ`DvG4D!wxwr+0Hoh16Pwd)CCC3R0|d$~h!9 zQ}eL^9hb&w{UR35N-(A=#M>J03JP1F$GC_MuP+cbVJWYxJhxvzC-b#T{&O@rSE#pg z;uZr77x~#YPds&}-ukoix9ZbBDbYEspZl3;(4g{=LCykElLN(o`?P-$Qw!bRsRko2 zbgqzQOMI8+mg3%6)d~9K_I|PX?$hg2O^f#(n=X7E?l-nJ^XYSK<1kFfo8Mxi z4PI_DJo%c_dUV*qYEsQFVtgyc(@|d>t6%uq>IDtWY{zqvFR5JlOdd1~N<{P1&=D0x zdu&AED)BR9!ORBR2_y+Z=@;QErJB3+E_hJjqzK zJ`xo6j>t#sxfW`QeL;gKM>819l{vC#X57L<=}aEy_;Ym+L@8xzHbaCZ%lJI`>{$f} zcV(LAosYI4S?fj@-ZP73TN^0}T?eVjbCxz((&Gs!I9A!gt9{_N_?oYqG7 zlN*pp!CBu$?XEjl?}WyFCDuk7)c)xW)<5U>fa2a?{gHfPmMld1isvt269A zavZVSh?c%+Wwk7KUUKM(@@wGb>H!rxavE=bv;{Mod3ncd+3?W5WbM%eW6apeJQMaH z{;5ULBV=z9i*;!_(%C<~6iprszOEM20*?l+CykyV~JZX;hua1$$ z_=eW&B4<2@OhqRH#U+W90vf|su-eVYD$plCnfaSThQzmQ`$-jdPd|){Yy;7xmHK%t z?iWH-<1s9J-8T$h-^q*&Hf-g=pQq8K;g(AU;l+8kpDh&N3I^FGxcEHE40O$*`6MI`|1OJ=&C{! zKj~?T>qJ8B#s=s5qv*{}wi-u0XFNLDJb9k=Z0(qYDSJ#Y$#C~^RckdTDWS@bEvnQa ztTh`mi!a_{7?RHIjbK?TXKwI5QYBLCJo%^!ZE@WUoEL)_gd)Jp#o_vBCCYiljY@Q6J>+y~-BbwIr$w#@GQByMw@c>Mk*Ypb} zO{5#RO(*ue-O#&4<7*Q-4;dvA#}kHn>i2u*rMDT|rZO9vE{uqPv4jp_Io{qPkA)YD z$K0uFCewCO`3%J(a}PUUZYw3n_|w@q_0=?eV3U$x2G53#RO zM!u{JWaTqCFc&dPj4<+D)t@9yq&7bE?4$K%`tx-CTwbTf%vE%Z7jXDOojxyN!glzAlVnRY6>Je04sQ#Piv(hh}{oDqZ81RYwMbBfu% z96<^B5JXAmL>s)a(NyOWC}X|Bl)G0i_(0Jj|DAAi^$WeooocQbUg-MQ`FQUXQPmxV zGamle&yKVTr$?!ttan8!-JkU6n7dLYA)~2`A!9x1NKJ8-LsC;oG??g28(q(Ap@oNx zEjXt96Iq5V1!+NQ;I&$hGUC(G6z5k;Y5kffy%H{K0C|R4om!SYowzMdX7?Zz7Lnee zR?xLPDMrt()2oU-&xMI{6rf0SE#_gPGzS+2m$#ABNHH6)w&-u5Fo_9abmNKflOH~b z=m4pgPIVUaC7KKo-kMYqxW&0xv9NrdeI{H-eLJ_UMl`G zB`>$rd3Ggd>t8z-pAxuZiQQk=nDJyb2Tv%3IKYa8soSr%FZ%n=eKmF4KqgWTa_3{) zI$L@#OR~i{Pzi1w+MHk#J*>(m=hhziL6P)AjiOx^21HTa*fMr!qr#bFzy3K(kkcpT z4ac zx|&zD^d>qsXUaWv^ZHCm-|O*NP&W$@bBF2oA6KC>Fn=(p+A z0{M)FTQ+@qEeYWW*I|3xD29sbeLSpoMeMfn$Lzd%AALmMY~okBTW(F7)A=#ZCN)Q( z_DJr6Hj4jtME_0phfPj~&}gx$WjPw-Qpe5=CmA^M32jGynX2|l?xW!!+xoJ7*hO=~ z+HXIKRnBQ>;c&QZZ5(tLi(qIzlDlHB@!r89cZHQruA(tkrvAjo+h#m)(|mB_i3?UY zH+I!_`$Zp}7~p$G(PKK<`B@x6!=-;-6B0L1H;{2D18K8Y9NB0pD>$hoQ%C6dyk*Dp zs*;A4=i^uB*a=#-Ee2pTMh); zi>I`$B9*N4men8l6yah&$|3{DrZIvqu{kXYvV9_a9}t za}S&iQ^|JchD0wJu!p^jRYD@OJlP!AhEFycvA>N!>|@jSDxs~pvh`|&SciY+n>p_X z<4kAh44PzXV(S_TZQE-(CyH7?^eC%aJF-XnSFK*(a17UcMd^{!D^u5yTQ7#FlQZkr zMxIC|4O-u|c0G2R^EoL=3EEmKURH1V%ps1m)4mPavukBdmB}_cO>pYb>64xwlDqC+ z+P2#b(^C|pcd_N%TwCaV!wREyn9LOx>OP^SX3frX)AxPv>vOVSW6g4)9*fd4(oyN@ zdo^Opw%kPRj~x@p_OSNSigv@})7YCl! zvOfZ+WNbO#5-(O?JAI6|8tdud%oZ^6)Q;C^-D7sVwZazWp?=c{mxdZ`x4uk z%P^m#n(QzDQ9WFgtLUp?IV%FX>3p~?CQ976d$*Ol3 z=a%6!>!gO3-S$D}ZWP*2YQJQj#|}m{MCq!_DR>V}XFqgqsU75P;czr#enwfLl=Zgn zEM#%UcH&eUG2@Kt)r`Y~zRkxU(8#q!v+C*yO46E{-#?M^G=t_86YFDXW~D`GMvfP( z_oAi9Q)?6xrj8ma}-I$INa{-5@}>%OH9qzhdI`_MOo1^Y)AE*kGmPWpd3`X-C&R-M~1-6J-lyuH}S6zLJcD0QabEL!2kL~a#9mU~|_B!O|F3FJElZ?3CCGW_EUC;m) z+1qJdRBT%3ZhfWHdl5q+c9HE1WQ87DR;r}1L`ml5RbN+=%Jz_DVcLt9?9P%SMdjve znvDtm`*&Ex@|amfI=RN#zbH9AE{xtImiI0$RoEIC%O~?uaC_J+|NO;Tlb4t0m9h79 zNSyko>ZM9=_Fw_kL&H= zOb)y@A!4%LQAD0st`m@AMw8abT^t;iGZ^pr1X$8@x(+o)M9 z=Vrb}Dw%=I-d5NxyvbeFjddnmPraV2c5PxVj{Bie&B&XOn>(!UFUB&2^{h8Rq8cU7 zpWQ2e=>O8NzH~3KGC!&LX?}7V7VF8S&#~ZF^UmxGWoO{wnhBv9F;cW#UUF(N)!HOeqgZ19l0_(yzO?1OgPg5}&i1IU z+wn7jI$z&f20n{DB#yv2Y2>rKPY)nhzW~w>hqR&6_D(Qk8)r~_fJx&zq=P>K%qW* zS%vrEF*m`pA3749xSYwxUtHp}Qn?|L@1WZJn)?bCw4Gd?;~g$?Rb5?A{diu}MXvU& z*gngR9RKQyv~Iq*_)91YwD`bu{nG0%u+J-{V84!KgR(R%kbZQzJU7=AJ?eHWn!jMl z(=VVKV=+2P)qmF3EAISZh1Km+AdhN@rKjSQ_n7rb(7r4e(4Oks(>jP@e8$J!TsyeY&5M$rRKIa_s15q;X1oHk zz0vGk)`P^&_m-q9hx`#ei`9;sCf->!{%qO>pPgoDy4JX^2OC^BOfD)b>lx(DIgX`a zrgdtUWkmR$-9`8k+B#X!RUP>R>(&;X+^)-F{PKl>to!tlBcz8Ot4R`45sG)8F(!JL zeU=|C9v8casMf5#_A0msd&DJpUBa#Vg>l-CK3A4gx^GU(1`uAGNe4S-6^|6W61v?~hBzUWh#CzQB4MnP5d#`f#b z;mLX64?a|{cM~ub`CBWNMu(nPDH!XN$&j}dK}ZUBjBF4&_D+N~kB1cElqK?>mj_~+ zuWx~m9T(C6!;|ID50+XU4k!><-NX{*1U#2tvNm@D8GrgMSPl)ag>Ml8;r1CcK>*MM1i^KOFPnlOknd$P z5Ck`99302xkDUJXm8}6F1Q|IHSPSLu4Em8%oGkv%p!v7Ba7>wCPyibTw8_DmC?~WF z#taZ7j&~fF(g2qL22P}KJP44$kG=oALvlbHKQeOgWfxOt{M2Y+Tu}HHaXWQvZToAo=*;+#YD*!Ce2qt-!$? z|HSQq3j8En{Ph3-b1VIwTV5&jb@Ts9!Z2LI+HVpT_y-9K{4QaEKS}scYxCbrSmxjI z48?sj{+;E25Hs|5F$?@j%s;Gkawsm5EHH&IxDfsd6#x3c;6SJN(*X#I_+J0Jgn$CM z7yetP9|#IU1b^rbf%`5Vfy?E95CY&xB(M$;xV3@bK||uU(U5Qe1{1)Y;6N221WY6x zjs%el;-(Y{!`&tbR1y3@6<`_xm@$APjxGeCi^NgGSA_%*hKm3e5&!{C-`VtD>A+n!H?qzhYZ{V696iB zT2LVzTe#Z+@OMez?}r1rhXelK50C(UK7VjSc+2-EBk_a1AqPu30XwvS7v$#$LHW!cnC4S8U{Q|0qcY(k@I!XWp`R)~!Q6}cr z_Lg{T6%+RZYyo~jKrO&3)=o}9+m96VzKsLu=0~rDXBRIN0}vk^!4Kkt0xJLl2b2!N z53HFV<@c9&Gyv2OzclbVj$deq@9P7O({TY@D_&Reryq#m4f=n45`Y!=$4U6nE&Wd> z0iSAH6A<+O&LrU3{dbc9%*$Wl7GO94sRI-GU;m&8!2SRz_$vZuzL2;;;g=JD@CyWA z1;8-=KlXw|9vCwu;M~4(fPnwS2^{vV^}rSbrVD5igaKDU91`-I^+E~)w2`>Agus;q zf!K{4iE|bZh`?VK9)UBBaGae6@V;MxBJM5(fQ1kO#snAqUP9pR$FT>aJOG2@aG3c>d!_*02iJ7V#)Co{=t$9;CTMahyaW1 zz>*_@7y`l%gc&~y@kdLJkK^zvk6%JRpy8v!|G2E7|6r?s3vmA@vIczA|E8?*JpVgc z1BUL~v~a4U-B1{mIY`O_B#rTK0)hapzaNr;F#S8;w?>dA$^ngWcKQ+NXYB_bl+9ht zP#Dl3Ndwv=jX{~<9{MNmTw0x_`n??`)@E9 zU`K%g{sP0<@?T*{T%_?69zQ<>2xNbT!T6DY=Kcy31Rgbhg8||GuP`AbpxC(MZ~h=a zDDxW(id!qc;K6}^lkqDI7vBF2;|Bt)Utur-DBwbV#)ApqywJ}uegQ$ief$gqf_h+m z{tSZ%3E)Ci-0}A~1aR*57Z{Wu{;TXELU6#x{e}m`WIw|M07v&L3RZtvE5GL*}!QFLncXxLP1Pd;~-6gn7a3=&yaCf&w0t8)TafiiOxc}}R?%wX@ zYUW}3tCs1isji;xX3&yT;Na%uLu1(62QHy;Q*%+fSvjJKi2<}c+-$t9Z9S-&W!+pX zJ*@4ib){L*0J0vomR@fEq5lag+Pd0${4eV3e~6~6ytD@Of0&M?`+tnO-d2vb)?U=i zI=1d^9$x<;dJbOBw*MFXzf?K6xyo63{Rhj5@Nn_)a|v(@aC7tUa`A9*aWipoG5sf} z?q>7TY~HK>Pw4Nm6erJrSmN< zwk)sfv`TC3w4!JcdIW>C5kEU*w{X4GOa~&8%l3IVI}*#2lgob!ohAw;?{h-l`;Wj? znGt3Epq{JO=l)`WpexS@&r9Q?gMtjH#P95SnmlWE4JNy4MGU>ssT*$B*pQVuZI42Vyj z=juvPap2pMiaa3<$Q^Rv4@@KQ&=tO*!S+m*%OV)p>x$m4VrfZ~sIvZB`0H5wQ=A8@ zJ?f}V+B->+ev7eWlpYP=_YlQcV+u0GPIv6IrXNK7Zc8az1PN{5!LOF6e5kFWN2!1gG~Yeh|BGXGFd% z66dKUI1qkT^R?6~E~`EPoij~FWHvGbe>(jI+*2HHc(KZEDAL>uW%eSL|5dAh>WOPl z{G!n#Zy}JLWb3&m(3a8K)V{Wn&e&N|xhQGV|5owlT(Q$ zNL#|X`BE)}ZGk9}uZ1nLsfOr&@a;$BS_{sFX#|kRL^Vej{&T`}QzWSa)%GiDK+$$d z|H2V5tQBXAzl5VjlyQ67=L8_fx%2~lV2n6W;tS|DB{N>rx29c>7Bii-vU5=($TihG zYdcdSt9z37;NC-Aq8l7}yMe|MUsn74grVL3^U(>A*OecW`!&}>#D7n3r6y1Js#V+6 zY6HCimuMCTT4- zNt?|wa!o5p;Wzh_+JGHiej?CIAaZutPQ2ER>>uH|N?X@5m>yA*}s7 zq`+cmAv7|W!4glE=WDa#RH{cMZO;j{!*4zn(gdKH1Gj`~h3z71;yhF*!AmJXH#uG0 zBU$XTIV*_vLnB1xz4^xZ8`ZHQsM_LD*)NWWbrWJ>K;_C+BDWKLkiF zV^Yo;*y%vB#`9lJQ%3JFDfszT2I|_W^I~p3!>FS9TW_uOA>(MCzoI#K5qWWSkx2!E z3=lll#kTrKv10U=T6sU~XCoW;6ya&L+|E6;!u$L?BrzyDDEd9{wEEKOsRby~ewyNyKOe0w zU9}ID{O#QsN1M!|G_-xE-6lT_vb9z%{;vi42oC-8G$IX(kNuQ^Kqi1ss`!Z=zX5b4 z(|&@uRgTTxPJ0Z1mL6e*ebPnht;Sm)aX&ULzb1(VBK$Mr|J_q9Ws!$AYftL@&v<_5 zaOgHK1t??hpHNCvkGBFEosZ>=R4~9cwS(uYP=DeZ$m{*&^Pyp{ASfN`7?tEF*wTtz zdeAb^WM3%@5pphNir#v{U{5+K8SIq;$Pfj_na4n%nF1)<#zi59$6v1&UgsNAnQShMDx^OJ~_t-H1BL^BnzP304xW)>W~fu51)%XckSV5n|df-t~D&$?h(! zcfQSa>}b#Kb}D$s9}<`8Xh&}+bj?90DImPLn<@-3IIFuhY{*;H(l$-r%af5s>O`K! znw+evO4SmQ-Mt;}%;Edf5w0dw(Gee_j`yS9K2vhxv-z&3d(PdbCtJ-?i1GV^^)I%m z46}y30%u7wz9sQt%}bvCS+?|fYV9NoGO%ErW5M0?#{4Hc-G{UoCzA`l@)a_HX>q5Q zOviq)-k4R~UHRUF_YVH?ea%2^KXA#ZI)!xxI41t-S>w{h{vQ}3m|Sy7e6|P7BhB2+ z5zA`D%=-C6>Sehs#B`c2u%h?6rl5BWz8VCvT>CU{5sFp#gfF>$%jrDgXa6}mKris* zaPDa6X;pTW8j^^|R)D!*yTuu*oZkI4z`wo9-jTSwi(&9cO^BC~se6(V_jsksJ%1Oa z*~e?fH3gqDt)TnYSlc7pK8FYPsMocqoybDEqu_Q8Aav$Z6_fXsmgL=$*yGvGQta@R zBhr!V9E#(5^bGwqe(56+BugCn7zYGm{BVu3r+gJ0DGbVP(c~LJ-U?}4EzTNc`tE?E zK;S~o{1z>|R%^o09~ifV8gW^^aJ+HC5A|4h<|Lxp=BSs*gH7oVQS%MD zUDVnC%d?V?T3IaU{4UfX%9=rGNNo!(yTc0Ksn$5yrYu@X1u^p~r4eH2}LA4`) z9njY>?xd&NXcHV>Wj>^LR*NL&RQmC8f7rF=&EyWyMhUY)AJ%EY?bN?d-?Q1Jp??L}q!_IKF{nVp4hcSO@D!Nm;k%refA(PU-`o80|}! zu0r&N)61Butd5bxpkGwm>EOnmDkK1R%Kh}D&s}azjIla>;F#fSu(GfG!$OsVd7cmEI7*tDfyE! zS}Nu5+Hl-`UmOuF52cKPsl9#aT1mKlC_Qtj`IY35-t%@yEH2Pb_Ro&auE?0Pl#X#J z|0bpmD{T~OPfHmLrRQlK8sTnEo#wy1renpWkCC#RrKQI%x5t(qh#AL5Xj$xxG8KeG zqGr^ZBH>LDX;v`rhZb0r;Zhhzd;tUzqL_=|!#QIyTMV_j);T`@W^|}9)MB(B=JFk7 zuh}zc`jn^8QhjUwvNH3d~>=6iZ6*aZkbNPhM%6` z8d2v0tz5g_(9_?%`L`eFm!S8&1(>-b&?mJ^CLZj=pQA&R=Z(d}g^l0XUw*hEV916w z2PmZ1A|ZNoE)I;o&74eBRkW{y`zHbw(sJLN#eQXry?MXgmlwA3&zZ1)5~w0YUp_IE zF7%{6+gf^tBcbpsUf9v6ULqT#0a#KyroS<|*9kA#bwA%e+=XL8Lc#_EI)FFDb-0_-^PA9U$gZ&KVkB~Jp%pb$8scW#Pafk8SyOj+39iRD?X#M3Z%J#X+ zzg~~eAT@y1>hH^#Xh~_w3gj_!*L43dXF-18JN*eO^s%ed#khyiKh2}cb~Yj*BI22d ziP799gr2<1Z&%eY0#9&m-2Mor{$p1mGgRx@YCFicws^#Zn&O)fZmC_@**8`#V_O&oQKo{ zN0g~lQQQ*JQAji|p^Z}PILHuKzh2RB#qcyK9?eJ(>of_(i;hGfiG<+u+m5H~Oy~>~ zx81W4ry}TD_>&Ruql%|JFAk=Slbj*RgpA1_^CzKOfxFg$=|j&1;16o~pf2t!$)l^u zBR%9(gJ$_HE6m%@R!hr(8vsne+$j z^q8#y`HHnf<_tR}8qud_n7qgl(MMCs>c*wNRUKM&nZb!peSE1T8cBgV@@;B?`?5Xe zLzB9<=CWMa{X;fbb~Q`T9ytfEDzr&#fTRM&4e2zTy*X#g*?hu89e*O(|BnB+(T%p` zvSM&1onG09PF-&U`p>I zPdgxkbmZMVd1fQ5Q))cFenmgiihkOApHYTJ;dgrFkAk<)8WPvqi( zo5&1MM_UQ_zqB!5wjvXbZW|nyBF03#q1NexEpfQBO&$Q1TU=bUHc^GkJE0r8t z`|(q5QT}#Wj%S4ddz_qPc%OiGbb>1E2&@(n;AEMO{^yZ2c72rkLaU*ffxHNYeC%PPYuu|V>_%<2eZtF@+s=z#s*N`D?ll= zS8-0=ILo}e%ig2s*=QXq-pCIoWhY>L%W@y{smpn20I^aMaJPz5WQSGaJ48(;T2N$~ zt5tM=%BsUf`clnnp(LFawbQ}U4qQW3;oD$lJMP2f6!#B})##9G!T23-x}L>(&5k1K zxcghuTX9X{prjiC6#wB3PqxDiHt-J5f)~*XS5#fU>yjb%W)m&a!mobzUUhuwSJnL! z;_R7WcK|q` zl%Q`yAOf+B=Q=+zJ$x2bWPW8-is?vHixi zrGj-?7(t{}&>=bGWghZ@6@&*M?TbXLdNy1qYh^%&?VhluR$$JZpj?Vakg0>eWcT+5 zNXN0lU?8r*Xm8bUNd*rkPfDQGhcv*OK+P+zhX#C7s z{9$?kHBmCXFDKqNTZp-0X61@4A?vT{M-)lxMeXdx>mdk}M1KGIB@}5Kb$2!4T4O)9 zQ>F(f8tePuOSyXYT=^+)1$WSYUV_SJUJ9!c;Us)6~|mM1HsD)KNqnfEQi$E>;V$m{4gH9*)fPs54s>S*fi1OK;= zIZP3J5j3=mQz5rDi~>i*G4$U~^t>?BZGE0D0Jks^DJjBiU`iCVGvE~H4ut7(myGzG zFD)1uv0UIR+kqua8+oaNSK5#7f~2LekuJ5Z3xXp;o)WreUeFBX{!N?u0p^DpdnDj% z&Ug(MAGiwh0HbDmQoN~3f53d~NEtKjO5DT#M*RuriZ-8t36s)ZlHA@Q;ejOz=~oGz zdw*)>v$sPyF%}qcD}{y$_)QNG7G|f5X2|&oI^GJkw0YQhDef`8cC;C5(qZ zd^H{1>|53x?1v5M_Ry=S7vMSzy6e2_Ie6)u$6m0Dz;->ls5UE+#6jhQO^C3bb#$OOM$NK=dIhz;*ZcsSA{ zYkH)ldw3g!vtU^L$fujcTgvMNw=Dtoyn*H>-y_}qa1Ceg<@>Fe}C2=(8Pq)uS0ItUvjKuP<0Ld-`0G%ti2}!_zdv+fpOs9lc8{^BZRsb0=}L z8B|naJn@eF8&);K+}=wK8s^b!QkdqNri4Gb{*L(F`VwD!b3IDMfq>8T3`ZOg(1(n= zPIf%^7&%HZ=K3whjvFUjIF)Jr)_P}C4HNdMZ=Y5h7^)$AzGMP_B>EBx)*M(8dg>!x zAEs$sa)W_>fBgJvyu+SHC+R)*<4f+Fo6g9O9bcF+DrTfA(mStTf7)Wc_saG(`Y9gk z5ii}_U#;HaT_;F=d~aEoVO=ePGgmBjM)>%kkgpYIF(H#K&s6t2;+NtX0>w~vN9u%m z321%bzlvAFu*T}ivfR?v)tl%%h4e#&zZBFWK2)EGV)@|thhf=u?h94)&e#^AD4t_Be`23Qy0Digvs~yle)&s-#)c`Zzop+_`g;AVWK(eK{zN&oi6Anix1qO zail}ycWZ^N*=m}HUI0uL((TDoDw06syD*HY9F-@jizXaqxY%F-q&93Vrs3Ly+HIpe zyi5KyQAB?Gi)ryWI0X?4;S}Hd?tu!)8@`>?fs*?)n05ZL?Y}69uvjcY>8F@>RkO77 ziu7VMA}W<;5sFKUoEt_Qc189E(*x%VcN_=Zqd$( zJi>5#Cmep9(kszksrp3WM@)C!)VKEp)tgA~-l9+Iq6B4TautJEgm141;Aog)2`fcD1%rsz-47ehAFz`5^G`NaxB4Gzxpv*HvHpod&2 zbB>E}hSHZ(Vmi8ooT9CmT2$kPQTo2;?A+L4is$o*e|-da^JHwIRlLjz*Ay1br`Ve_ z#wIA8eN}Z+rE}bZ7X1y1!DH}u+_oiv0`g|af?*9`XawhdSH zg?mnnLZdvXl@IMbTw%R+;4LhF{3M5X7e49s2zl|kr}`b~QKg*Iy0PkF7zW}JR$E@g zIww~ODvoSByGJAOl@1AiKkenKvka;J6)6!kM)CpF28UBte+>WYP8T^|u$xbQ)J=Wo zjSR7h+ITYC?X!)ee729(3(kFNaS8x+$k02@{yJL8wm*Kf}9SeO$zz9)!OfKiWx)qf(;f z#sd-ht*=$*skwz`<~(KpA;P^3BYD9$dWOZ~#j+NYO?6(a>LY;0A-&-}FeBoz7XKw| zD-Q0j`#CTh#X@S5Bt}7u5m3tW@h|-dAklx@U!a2?AMN{3{S-MLD}f(68=`Pdw~Yf9 z7*ki5qeZn_L0FF31IPouGIqOX!oyPRhco@*t6?9+e)`nznhXXZq@Ftz-&WhifyQ@X zptxO>WaXWA^-R=)O}#LY#@%OO0KuF4vheE>^Lh@tRQb|v8k4(Q?3sC}{ySmn8M*Yf zU5Ng8&cbL$G%QWN=da2@U~c?uDD@R-wpl(J}vUxec; z?@R1AJD?tODYz(=*n!=XLwStSi419`qz#q)>&r54f4t#3jNQVIJhZX#VD(C&oTbN) zAGS^1u9N&Ga_A>vBTQ|9E@gppB(%gVO#=TRaBM(vxk(+I%meGM0D~W;!L8MI4q5;7 z==9V}iWS0SC$tzVMMMtci2GT< z-^dNAXJEUKjF64szkHxcywFWBga}llFz5PV~x9&T50Rbr+TD zEy0Ght+>7Ym#^?LNwH|=Cz9kqp&v67J{OE=&v|HD6OtROFgj%uKagtz{~)_D4clFL z;UAI=@4jVE^ad#K22lHHxN7N_J51^SzW>1NP63@c(C4pHdE9%FR(#D!xH9$X=^VMj zPw1^iwL!ZKMlRLY%{(Bv*4mR4r1$GDS?n8t`U}wDFmC>Cv$rTw>zj)ZY51g?zJecM zgIy}RHrmS*a`i$-V~XtY0|0hHROi3c%-R+2gifpuCFBBVCV2lD^+!Gj3rI9#h+q4X zFXH_=yubBCbKq+yl-ov!6Q~I>9_U++E#2G@EfBu|KYhG7*WQu*1r`z(UYUV zd?X#Q6kfR$Tv3kuLks6j=X?!f{JRuUgFw_TkVhP@hrs)BA+8jif$~tdV@LRkLZe2Y zR?Q*aYuXy@8n*eQ|0?^n^zoa5e|e@IBH#)_feek^@g)PVSruo-GNDqAKL&YjJUVPV z+DC$van4Ru{>A2|Tcy0BU59Z+wkLA=%}ZcGB_eAp`F`1+N+2U7;7}av4gebsmd&i^#ekY*!Ktr9VqT_ThZdd!7xLdfoc<# zVv(A+9^7wJ^+Vcv7p)8gDWmSwG}Jfc-eCsBB2K%CgFcF*U&VrWv8P z|4+(SfpeR_RqvFJlyAtD34t>uF@0L_FPd8Ue}H2yyZ8fw?y<<5)#g0T9k)KF$1u`B z`;AhGlxsUnw!#Yf3&xv5(tZe)$`L4bPpZgN=*d_cnSkuEWM1Qxq$5!300|LD7)TOK z@LrgY{Zs9Q?K8ckyzT8lCg3A(5sY*i-QoC*pEzmS0&~f&f;*d4gi&BDT}*;{DrbJP z#rotQir8;DdUb5)2!sv%eR-5>+KtVZB?BfZ0b(g^J(gIwmB{#$zHtmu0Y<~HU5A5= zrAcm`GD{iDW&*hcPfH~)28}RFFc=WKE>`*AT&DCJ=$r90Xx4>P2(;ieUIy6h3JGWj7COEa0Zup6%lV zFW?^MNP&(4Z~)k19vnw>v3Fl5VFqT%6^X;WtSj9WX*8-y`k9PJS1@w1@Qj!DMEV4G|;>uS1PV` zRs1giJ`g&!mZW0zXgJW0!q$c>m0;r_L6FVxj;h1CRvXo0yO8tMQ;$HFMFl0ILM>W} z2V^bU(C-2&Cp&B>Ui_(;6)?QvV$`Tg0;vuom1H5j^Wx4-`Z2NJC@ZM2J~B$o9=qp$ zgIq<6u~v*%QBJ7~m!vhH;RAJxkzPoS$BMh{Zam-T9)(0e<3bkQbBl2zpqjNtDqUsC zs`I~+`pIX-c~x3{FIWe%j0d&adIT@qn!iUjniiPeatw&zriCvy=PUw`-d6hr`$MbP z!_LX%OH&c)EM=?Wpr^`vfgCldfx2JtzXiunpK0Am#p_X(a=EbC9A>>>R|P=P?_oa^ z1-AaSQ1{iT$d<9Jx*EK)^ZoZKaJekah@b~o}bym8gE{j6u)MDUO%3Q??dqDCKie z1shkN>pkmCB$KkP-~!q`%G>G^!}{GzyCeFZ;ZO<}#Q%F&4d28Zyh{R2%@5e|bgSUW9Fl7s$yXOr%;>VgXbn55tT*)hzpC9)l~VAoIob&#&U zExkYZ5ufD;j;kg}x}qx&`bReEf%jxa^~5_s$Gbp9<`9*qDNuS=0#tYU84>wd^DGlD z06?gM>t$iE;W&LmmjA{~^5RP#)bN2fV7(*+PWj^_(gAd0^6AP6-41*_>a+_r--e+0 zQ7WcNazusnXkF{LYGR|#w`sx!;_j&(O6?@-QEg7n!r6Hj#6xTOzNCj!6sD31;V%Zl zibn?Y{yq^60-@Y(5ek7EoX|sU*k3K$7E!(l)L4K5WX4)g^HFRIU z_7C0->hr0IV-)$KKWSNnS`_sbredP~EmOD3p2Kc^Y_=c0Kf%c=7YoCv4axdJqEbE5xDgD!Kxjl^vF&O?wZ zCsY!24U{5lgvZXz0-lKQ|DcqjlK9e8?9+S%*J~$%-J-M}yb>bMv^EM{trR90Wz-_I zN0_IY;L~C~hCL>Q9f<&f;kW#Xl0ldsN&d4^C?EWm&)ml@o)h%53z|)jKZz|Z-$eV@ zO->Ozc{exlAI25=wkw9r)9h)7ka87h*-a!JSxe29n7nAf%1AHjQoZB?ceKaOfetaB zo+K`rPRCOvi|K$KBa({4>gdNJE@-#vQJ}Dz%ornA93Mf+*LZxpp0{L>25UM`)F#+t zI=RQK#@vKnQ5SXW=)eC$D85zCv**kp9%;i{k%0^qAWdXNp{UUwY1ru z`eW|b4TWdQ(`*Fo_1}Zk!RhE;^7w~$Y1B7^aBR;C6IMqjJ?mrG3Nn;;V`p<1=;#w= zpKvGi^=Sd-BP1kh_X@knBkSqXMSw7uaww<}&=*VQP^6JYL#0#U&A91JJM*4thu=}tgozfz661+YRLDEEa z6moYXZlc#9Ru;T|7j9FUHX5lDpZ9KD^6$Q6{i+`F?wYYj2fkQou5iC|HX!M7U;ij- zXG?E9vP*j~P!>3xn4TXf&Ti4KvLgGrZxtg5tF!|l0KVV56^P*dC zme*Q_N#2BkUCZ5nl0n!--b*m`h&<#1?JM}6A9%k|;>u{&cd_i2K-BM_N9^Dq9$xtm z);CJ1tcwg~=YnJWaWvO{XH1C{6SD1>xaEfL2&<-=e}CpjKb9^RF0qhDPyI(nGJHYN znml!&IzV?R-AyzQGA+}uuUmII^h8y1$t)>-PGwH|z;oWWa9UrYU80C9m>gPc z8cK5V{6hp(iy`@$vQhIR`wnj6&%!$SjP-l(&5^_RfanggRMLOltNl9g{rl-t{m5>t zGHY*Qm!1%GNkf10V{@~VPmdnIv!C7K2#gd;ivv%Y{u2JyMxN(ufkri{*F|buX+E$X zTX%EC>WEz4mr<#3nKQ_I6jt`BMJDztb03o5D*8$Gt^US@KC^ro&P|jGO$oz%6PC2V zf9=>4{POhqtF{lxUi%Qzp;3heT4=hA%N46FOly6X;rH&w;1Nm}Ua#+8|5bFyS#mPg z{Ewt z^Fy2nCb?E{ypEH4Pk)-ix7;USdDYQTo$MtdxniU{^^4Tj)T(!q2eoduL5KG z1ZPNi;a^~8Xu67y14>fP2ZOlWBsjG{Rg=0GUBfz_9!4V~A~PP=kKynn!H=?wh(PD8m+@Q>r;@fLY8GE*80p$9~s zPj9vD#L31>-usF~&S5P4e3cWk!|{%&bQ^g4`d2))wlXl~4WL?&^5x66z}SRz(k*BL zTM3*2a!^(Uf}l}vczYHDkV1wgagcM;gkm^QI#+)09?J?A*$S&AN)fDk;xR+1pm-fb zD1;O=dF8ug^&Db??F>(eMDUOCu{`XRg@|}m794yl(Q;=FZr}ZZ&W_Xuix%Jm7$Ul@ z?ol+Cs+kB(3W6UEb4_a`f>6%O&3EGz!38kA6JE?xZ00u9XPVh@pB_ zKY?t>Z_6nsasfWGc%>+x%T*FeXZEguY3V+t1@=(J zP}=YnEX;vA`Mja=%1#qR8xceHcWi0y)1PKjc1tlYA5|-lFxuszMR$M3&uB_J?7Ws2 zvlZr2!X*>D`AZ%Yu?J}_6KZ|#;{gu6J?6%Zto{e=x2VF!3f8+KUnsy*!)1}l4x@Fz zv9ZOZTZ}%en-+N0u#2#W_QDwV>Y&opPXGTB{ojIO&zwaReuS6SC9FXL70on-n56o_WYx48>a9KT1tFRxoi`1`#8{4oYX>*>i$cm1ZV{X!-`4{$xzT^sK<(=OL8D!0rh zSK||7PSBnchusYG66e^Btit7e|In#G9eegOKdAtS?kh3g*)@%+wTWju$E&K`1=sk= zDJZyZ3cT&^YGQ=icJR17?d_h$P6wOZ({aph_XJ7niWgAYYbecJS+iYWqh}2E1?Kv| zU%~STU(X<_gpG#LiYHdXZ*mYZ!z#co!4L{l?m2zZjKv)v_DvAF+`CyMx#8K~9Xt#{ zELTwsOHqgSf#;bD!MVYX{|mc1OuLzK#EmO4r37LgqVPkyo1n!$qR2?9hG&MYf>njd zGEZX)ztY${*gt{EhQWr97b7WFzNJ5*38KuT%xn%`DdNV8PeMFOiHi8_m@~xn)1XaJ z%RI9U^|kEt3YFQ)M@QXSy892(P?Y##2UcE6Bi=Zo2%Oja5;(u2X1ffi;a<&5e^2 z(ZPw662s$HrytQo%IxT>D5bR|7Y)b1_F0E+H*s^CGfy&ct8~^rQ=eTM z#|;Sfd|0Ly&1*iBYU2;|gD2u6vJ+OJ`)5WxCw8HBtJK3VoJ1O10v4Gc44)yKT@y1D zZY;^dbo6;dnB1ukO6+uK`8l_6{t56y%~e}Y&?7;CDNS+S{VRS_yUgnD-_7$r@=E(x z@o@?eq2!cBL7!#Y;pgNO%Hdb_s7G0W7XRY?R@t8JJc>q}b{?Sg`1GYB1+b#EDQ-5I zZms^SoLJfx>mT@JMz1C+2L_+{8}|pZaamW~z(%q^#HU-M!pR$(85He)J8nK^MNncl zB#t36O*t?12dVMvz2IaOO*Yw#{$^R7H@JB^zxuVx zu%kL>wPmwCL~EJE`}3ChYRUZ(v$HtB8K?2A@0X{X;mz@@-)H@v23GUc;J#P6&-&KW zM$5;ijJ#RP7mZeKsXVbkNT?ISdpAD7S2XP4}@qbDryAQl?mD zSq`+{Mo_hP-;f`Yem+gVbf;rAiz{SO4B}q$-0B34zTG~APUiqD{uD?WG(h$`t!#Tx z%)&>{NDU7f!TreQ=YWRmSI225Vk&Ic^r1w#PNB7Zot!G#hYly$O6-=qW@ z)`0;{w*q*qU}{{8t?w;vA2qH?A2 zOQ5~=Pf3WOPUldDyfAy-ftDjpIOzPX@YFFEwlJac3+qUSJV>nUkv9m5p z=jMB~ERK)0mMyKKd`+>gB}_VbChY_r4wC0nJ!09jMA;8LkgxhkuT-u|P8ap^P@%cf zIlxlp0ZamzeVDBGu%oj9#eqf*d5{y#SYa#N*L?W^mEyDRye;=b3t|> ziFv|~@gUW7FIz4V*4WWp{DC>(+x0>Gb5w=7&mk*gTMz?>g+}gYY9)G^oI7VWVa#`$ z2)TfLx1+T$j|DMr2M)}eWttdLk*SMV_&>VfH{xc}(#-wmtzA(k$HUs*u!@t(}wn$3JcS_VNXy9D6)v&A*-Ucuf~A6d&G8u>@J z?}e0+QY~bL$hBI- z=ZfdqQ?9q*xEMpk7n(NW49=-dFzconO+YFwmZ30Y3w=lsAV1mnwj}!XZ&VBF!SEgY z3C9nAK63WmiQd~gtZiVrxtXrmUqf-pLJ%LkhH3}eKR$0}fucFRO3^R+ z(5EJJmTjkxwkN$CrPtL_It@Zy)Xj$sKgf)#BW>j}#6XpT8{b}+qWsCstwFHSE{Sc3 zaCb1$Tlcs^SHfeldQlUsmwf$U?pc1GO{q(io`qNQqy02(B}$Sph=?(^^%T_JA>NBH zJ9##0a<6IHgchh>`>trgLymgmNB=Oo-_7+EEdf14rppDRcw~iSpx&vB{{oB zpL5f#HHLZD{mBX+f1g(76HDlKQ#o9AD{Gy0GBfm*k-%P%hWPzO-1mvH&4EZ24Z@sj zqPwO_-K63I(`>J>poSe$h;T**4nyEy-D?QCoQPgy0TBaM_yar zh4*FT)1l3y>N!WZ@%m|0RC)+BKqGhU!Ehy5y{*yWqljd+tv6}6l;(x1^~W*h4_fA| z03DX@^#5kxFBlrx#Y?t`9>Sooz~D7(FvTL)f0cWxTk;u+Oro}7c2%9)g589#1hd54 zlen_C1KY}3G-+8h^>v3Ov}~CcCoxMo{~CGNRMUxL`1#7O2B-obDYhcl0-pku#7!z6 zgI0KSEyh#0gNN~_#x#>3t$r$&Sf7J5KBLJnFg#cVX%vW90+56)B?sp}%ai8^_^qxL zU;ZGHv~P8bGg+U`$ho|ET70dt3yc?k@G=ZAa}IKrsjG|jPZviN4`kAHSRb%407ut` zGMZ`Qa=(RgdeAqIXmxZM@379yYJO!n@q(W#(+=EFDt39o@^bXdH6>qf1t-u z71?7QsrSLp1yfdZg;9lyQK4I%yFifxWF$9=Kfa^$wTeky0q#Yj)ryYhDJ?x>IbGM| zHK$wS4X<1K8I%Q*{SG=H)nsRqbtZd-PqX;Gf^V2UI3V zL=ckoHzR%650<$bm*I-m(^dj`{czzH-o1B}lV87U=_*q5IdHvr6RhNDvc-36%K597 z6;t|C0arCl8kRPH+B7o@j(;$TG(^kOh>Jw~%Buw^bm`ewOK|5g?h@+KJ6xzYw}a+x z`+L1sl??ZOd%Glv4BxF?JezogJnJn|g_=m!jtUQ8L>&t3d^MLMwV&>vJ2{^DR+4Xi{g;-MLG9 zd++U5Ww&An-mjHk%}u`!&+WUPlG=#Y|H&7{hc-n6dv@JAG+QQRO|#H5CAFAa;{_NF zRXUrN&Rdu}!Fq)zuE$m;qRdP200i^8+T5)-Yb47_H$M=3hHTI9uB25abJ|V=250 z$z+AJ5i6<%Cz3BsH3gMoZSdvWsDAHb7PjsLk$4}Y3$;!d2#d~H|F`7h;QqK3~`#s|zH(@$_-wiF*XU)!RTj_;A>ytA3PGqSpXK4j;zgc9uq1Cl}JA3?so~JvLYtExL0V zP6rGg zL?r+L8>?6$!9m=mTmhv40ce>WvCDNh7MJ!=quNjLZOEu06=m2sPn3gSeUYA#SDDwp zi-Ccul77-euWJ@RkFppihuVRY!3s&ZWrT!XguLM&SI1(mCz2}9KCVN`4{1~yzZTvX z_VBv8>5M!*yV?_~*E79k(j~{2y3RSr(fr7SJJ?IYHDp~*P61kzp;ViS$3LEPo86jM zC^J(7J()3|o2@)9E}Yyp-d+-`IV~Vw@(YXGY&rqpNiRtk8GoDCBd-f~ z=(f-GSW59*!^Kh+Sv4Rql`uG9<5p}n?3+vbo%TV$NKL7xHT-%aV4cW<3`88tZeHqV z(bE#&K+Dp@7e8xPIbTCcb6~qGFnpl^3(82Etu~6nd7UDfa~7DS65)J z?VGrE&j*xo0o%6QwpQ$Qol*Y>05?F$zj249GCr+|& zyk5aVmQGFD&s38oq*eZ~xy};CJ1SrBQBOfcbZl%~jH_^e1Gb6%iKHeV1oIewveMZ}88+e7aNza`?q&{{@CLuNGKQ(`(^)abPt}9f2ik=Zo~jsi{k$TrO?Wq(S4WAK7MMPgq{D zNHle6jrTZbree&XQc3nelKtxvwk9CHCcJo)U0wHdIF>hCx@;=OlK&{GH|Y_p)t-_f z*)3pf`|IqglmJI_ofH;W15juqigJaz>MA5E?1f>~Ozz%>s;ZeJlPkY>?>_RrX(x}d z>CCz7qFKAsJqfSecJJTvhTZqWKsKXpQe`4j+kWz}GIsL=m*2N?>7i%;ynXK6yAHH{ z+1K7PNAPLzlZhDpe72sC{vis{k2QxCS@@6X7Kas;S}H;+L#tAiS1c?uvu~!aS8cCX zdL8TaU5JT#u~N%=_nIDi(+;H_?(uw&_ucP%{@UXosh@emhMF^5*)=WQyW6Q%I^ObX z9?NT$dmWHfdn}7>WxEd~`@Ffml3UrJ7P~dG`=e|gMUzGP$QL>qBPMMZBZhHr@rSXn zR<<4CIrTZx_MFBXDF@*PrkU2G16rkzeIdSHtg+XTUJ|SfHt-Q&)DuxsR6+q~ZJ)Le zrx?o&BWwg`_UT%@QXJWk`s6$7{d9CKC z{dMSq&i4r3cD2H0gt-MCnxvI=R;7q^?Qb3PkP^ZGSidH1BU z!|Upo>}dPv)iZNl35gMx#Cfvj+~iJlcz2F;j@mus^4i@r{GfZRmD#Am>a)o{ z8_Nn~F(wEDCRmX7_@vf_xM2(chx;wX@<+-bAfz)P1wA6p8uFibH^ zR;|?>=L@Mbg;=c$Zx)xl7?A>KXc1ymSd2Tu4MmL=fH3*c!Fx|VC9S;Z-nKOM^|fuc zvN`qghLhJwcb=NYSJMovrq$|ja zoa9>AZI!yZ+a{?Yv7y`D@*Yd0`wCAwG-KXK%Di_Jq{K>_+yP=-uN}A&l%(c~6Rka~up1Zs-MKxj;5?jgieiF*P}&u3l6mPyN;8`uVEgHr?d<4g}cZ_t!#U+6+*apbI&CF+u7b!rVa?qp}H z*>#{!mR;8PRx|B~0^pJm)LiFMPOlC=3MQ9H;cG+FI;f+@vcRgyVDjpbZS!iF<+hEJ zt{k&`^_s;!+=&^vRU=k5?b@>FF{Y@)_a4mHwYhcS!TO9oo0wyUyez# zVcu6`v5($j5FW4E@%lgd@H7Mqn}D13ZGeUYJwl;z8kd|9`~6ByeMDP_Nc}vQ&d9cX~pa$l=kC>W+vDcL=ie=>WO9ObauMu_lIgpnj|_Lyezw$ z#}b*`Ev1{JMR=^~9*Y~?%APcXT;Xt~g{045-6EYcC^ZZZYB#~N4EB}OWKIW@I#6de z+u~WP=`Z{1;#C`zwU3(XY}PYJCMH}q1!WS~(;|9Bru8mhu%z3^2ZBr9dFB0gFHGBh z-IkZ;u6=3C^v8EF+xH7ky%agPvS8?>t2eJppQO(7SV!IU+|@IW`S)J4cS;LOKFEf& zRi7%~G_Ll8vfO)a-uI)Eud(6!ars`Xu~0e|kXVX-tR*UGpep{q3pf(YOqH`NW#qHg zS{tn|u;-<}u)j#htQZ0o%E;=o%95%;55L}*C`-|@EGe>8^$jjmKV%w+_94R}YGt<^ zYz$?g31RAC=~I%WPkdpd*cG2LT4_{N*Oc+H^j2H( z5_V(TmZf>)3zF60=|4WMJd@O;78Wh7#q4ds>`kC_Dq#1B`Fj}lgQdVxkd?8xU`=X$ zXnk0HVtvvEPknkr!2|L4Cf@I93EQ9eNcy80&xAY^`j$1;L?KMGN{N8`^yuyC7pq!2(*q=1X(a7i7#UxRkBUSe3oDV4Jc{tvA)1 zH$-fR+!nnp_GV?L`G$y{k+;R(m;O-3Lj|qMLGx#!{|Ngm{IiVD@-t0VOGZB`Vtw<~ zax;Y`W+>uej}!Kcrsi-GWlb)%K>k>;jyUq*wnJvvsnAy_`3h?b8w-yWDuwRH5Fukl zWno2ywuNRmk;B1FqTZdH#a3UB33cScwDL* zCXFe12Fs4lnn67xA?s5W2>%pr(s*NYW>9WKPGI2}D~C&d&gk%OS<)kkVU(dnX;?5H z@2}I;sGL^Q2hDX+!Icvy1WWp9quLZ37qC3V#-yjWv1s@biqbeS#6P?G&Z#dwaL*s> z_W6s3zti+&-Net%9c;yq#%ZBe-xOwE9rQ2Ry zJ$?D)rZ?->jhcV)s!_e><+goNd2j9Ix2>5pq-X(n-x#c@J(xXll)(b_bHSww*m zzMY}WQ&y|%%xf$chh1V_9d)sDi}{ME5Q}+Rrqti8X2iQP;#E1tqmW5G%w|$N^X<~`x!djiGWgfDj=Im45n!Rnr{V11bAanU}UqB(##QI z>2^=Iba%SL>Y72xHg2Sv;c|wiz*3FCBh}*R$O`$83dxn!Wb(9{zB^E7GKEus7m_tR z1%_*LUATG%FO1_mS$zWXsgI$|N#Kf%k7r;&1xu{kaO}0rJJxS|Y0jn3-hc6q_ny7; zaj77(Z1sqmt7=N8^|-8?M_S3!9-jTTN1C@h(6H~P58GB>zCb#(VdV4=E@|BL`o$Bo z`7XR)KhCzxe(=FKx&DohgG~|^sZnGonYbPlQ4qm*MOcSjk*JP4Brd)$0%YfwmT@Zk16w6M zN>4?V1zcs~e`qAtuP&r+uSPG?HdUw=7#4Tas zg$;2ICzzO$0xfQ1n-H$jxa9}|mbj&y-IBCG%aL7jIElhhTnekf-uL)?kM|}hNg*-JsOYsJi4rOfYU_)*%;s=; zAY(KuNuxO!F`E6j`G6M}`h9}CXmeQL&C8DEj>W>VNRQg@SSPIUtdD%wak+3sWScNX z@37zQ*dgq2?Tp+ef8FtQ;Q{B@BS#%ah3A4tBR_WhNcds+N0DDTUKieXyeqsL`N;8i z;iK?Jkw)IJLLz0TU0^2>;YcLJ+szX13;87J&WAVJC13 z4!gZdzM?zHh=(L2a`;h#FgmUZ4(V1-a8O>KkK=eQR0aRgc?Z0PeAKQxtE6_YCjuf> z@&nzj==NUwDLZBVj&kMgm`(!0sezMX5CKAD4I`Khx2GXQoa)+PH*nyN0eeo&?tr## zRwRUzK$!gR+a1D%ET?~oyvoz$&EvJA}v*6*RP)8pWf zkLQr1F6(bWqn~wR3mFlp%3@LJRZFdHt! z23{`@te$%Bf^z!v?|cAWeyt}Z=h;NUA!>Ki7oEBPwhK&&1f5eGHvt6&`GPpzvt? ziNfo_*Hf>j&2&eV{M|vv<*glvqC(LkD)s;4^%o1e+6Xs+NU=qarQt>j7Z=7CCUyqj z0I$V=QTT0wrQ;xBYY`|fBLzJXU)-1WYPpt0@#V#JV0~ai>R!?*5JJZqupvI!G2AiM zv8RIzYQdIXf)dzZJdzINX@;aC{zy;Zw)lhbHwvuMp?CClTuNR_4Vng-L3U8v##|M= zN*a!AjbD|zK7BKDt8{B*S7EH8)*bd+#$9xBETR=SI5_uzuXxYRwcedVSQFh{fy z8CpYU<@UyAbU;{Ca_JClkp$eFpeY(Pnr+S^K?8*b5W@XbPc$-aH@T+K>TsZ~%?7to z$OjIAT;ovCuH&I{$Ftz4gi2fjL@4*N=bz4IyH=fqbT>6Hk{uX9@7!son%vVUlsE`U=Ukm@I%i z+gt##NU}f`L34phNtpuBOt}J)2uBMavR!k7Vc44hO;s>DI!cU=oC6yK zQc4GiXsOD6aA+tR<$c*I`{98hUk2+WpBFOA#E_5V8>{TpfgwIuW#5NI-EoLm2;KyJ z5EEhkG0+DSQ%gAXg?xyySV={m2iTtQA)RGF64qIV^w=3i9r&lkmyEsj+o`d_nuI@` zT2&yIKXU244}D?khQy}wSMNUmg{L?7ZXG%F-L)_5n!jEmCnD!vbjzoYu1U1UMya7M zs*MRTe&m|VzUg4u%9mGN^O*0<7U|(@d%oI7n;_0#KK&b$1L}=<9h02LNAdtgdGhkT zjt3$SJ05l&b{uh8xCndzXq?^Pz1H_n)a|}+Q1=G+QqNGlm9o=hcq!FSnev?Aj7t#G zn+}l@08bNDYQ+^E?{Z`X1}coArUYahm1n23<_o?BnTmr^n~J6 z$OH#=Vkks;Y}ldX;SDfSF$Cj`_s|`~gGG8hF6=+|GjvQrIMWqJ2nCIJ8~syRp8w7_ zcl_eUZ71))`A65um(@-^Q+w*@?T10-xx05YxFk=|V!E3~GAh{qRB5wh)h5zeTcyZx!wl{!=h*6SjGF2=}`m@V+9w z68@RMiB6X%9HCe**b%%fLZ&%JmI!F<$dXNs`PG1&w%cuFAno%JT&SzZ1q`^TxpbGw zRh|CzVbu4oWiccZ=2uF33@9-$97A3dDyI6eRPbY|;K##+;=5J>N(BZtGC|bHJQTg8 zK6XeZOyMm=mZRAZ@nFufetCw~L&1o{D zAwR|nYvaBU;=DA_z`XD6{a)?rUv6LfE@-L!+o=s#CEC=hsG;pjW8(JOcmJdI+wcDD zQz5Vz_(1?H3_~7kfO>5Lj#vSV81nuz0}j^oBS9_si*#S=%t4h($JFypa?ygG35 z^uXIwaJUCfc41$?@Bu_Mu&7~p1G%YdstcJD!pRQ^;jdXxFYA#R$d`^>F3T`kp3eq@ z;Vf`K{BmdrfN++8wF5)h20Z3jGVHqvPEE$L62$fKQYQ zF}oo3aIBecAX(LFt%9U(<0LjLOMW%VKypDX8I#1=F}jGzQc{g&8`EaaN}EVXL~vmJ zO++k7q=ht@Ml_U2rIMu2&!w{Iy+j5O84a3{!_aaZXBe3UJuG-0o1%yG9AU>aV#nlQ z$24M(M#7jz!niSvX(aqm?!SqH(@+|8;bfY(adb}j!@xPRz{V!FHM4cPn3^deaf~2W zb5_!=nM~4TN^+b(381k4Ga?Ru(jbmx0!Ijvq{lB}vhZ_8Z10m~foTE}03?YV8H+iM zT$X}&j@q7~26!Ai{I@kdwnPG?7A^dn&8#$P%~MZneM!+~mLcI%f3n4bi$48XNCNM# z*itL?EKk(dUakgQVj|J3Tu%)d_1bHj`qOCimqKm)1k}bw@GzDXeP()bjtr!NX;Kh{ z0I9UL?q;M#_9aXhe3+!wGk<+oXOSSYbI7wl~vZoQNK7y3jiZKZCtOtw-> zIXKGVU!pEV1F<63&j+!71_vSPUZF2&ez4Imicu!rNZHd-9%SW+6^&yA4_SmkLl%iT zoxQGc7wK^IxJaZUw!5ZXw2MY#>w=2n?Fpe2^>i|NkZUxN*B;=k^(xO zTvpnAdwt}g;D_=cpTz@@Y2a;aB%?7GW;A(S8x)l+D{zT)DwAqRQH&J=KZok<1d1#; z*{r#Vu*Kj;Q0$!qpJJMTC1G!>yBUxbg@fT(#b=Q$0SM|zy1BWzktCyyK7SC>gw7B7 z{n5rE)yP0)F)`FgMeP{tMdzw~9I=?A^&u@N$S^Y0z7t`#lIlfqbFUMEJ&XaMFgfQ) zZ=>IX#M5`(cWYBSM(+K~*or&5h!xh zX5uJ5F&gX^sQ)6u@Y4uCdHBf@R=DNirvg7+us1F9h^-yM3Vfq>=^Wv8<($(X?G*@uycW`) zOuU0-*A^9{78Mhps;5f<^%CdiR!){kH7d%ION|C(38*n%mYizL<%H^o69Xioy8wsi zEI^}615tjM8{4?cbua*8lA>r8s@6gf1g0t!b(jKW59HYGOUiN zCsayPd(}aenpBUgBpTN9;aFnj1BK7XXk7zgwPTDU+DZpJP62BTCn=K@9zk+OYv9bX z|E2F|MvJ`m6Wt3t9(Q}ZuE&E!51I_sd;n{+3NwGDrG(tNZa^us5<=*+&8dtdII$s zs^}`}w@{SlHBRStal5&vIMegoTii74S+d@hzt=suD}A_+gNe7G1$QEzsFKYG)f3-B zR{q-q80Za*Ktx~f$CD=qMk-xKWOxS83qi?j4O&B;z+#pxfldNy@GdNqQMSg2G~w|8 z8-(fa9~!dpG$3$)1G3)V^+?TZ4>Pk4;CckCJ_@hmjusa@vi0JjfZC`OQvSG<$Ng?f z;m)4=%md&3r-82KfZVXL^}Ignp_#sqLh1QB?E3}eA8_ASZ?J#YPC~0;J8?C6gMFKJ zUFrJP=gm*sxX%&5MK8)ha&9Hpke?>U$esE)`G9`VHer9d@brTJwEeur=CT0FPBNsa z7S2MTKTq#n z^lk7k`KW%FJZ#=~-ZA1=#BuO5@-^yx;(c%m{MCHQ`e&QyEBK1V7OmI^9w5GEySL?@ zB43Y%sd+~<(iK^>&`WqV(ykFyO7sOJkrBB}Qc88ENF>arUcwvXWf{Q(mY?d9^fF^( zB?ch}HJX>Dv>NT|o+ovgXj(EkFp`jEDW%3biycxYAc&~l=7EM}H$foBXrET}Xj+i~ zwqmzwkw$bE=?)tptrj!Svi4#7^LEmnWNDW5`2u^zuFlSMIyJAO0|L0cDbep|7*mQg zab0)Qc1_FEV;nQ3zlV)z$$F zmJgAK7A|@gbYb^YV8%T)13n?_97U-|II-dFnOtsUmk6`}j2+lR19{k2DENWG^LCt6 zxC1$5VOe*{Lew$qjjivXXe2aMiILF->vcX~XzI?N*R+5h=pV?UxV^bm^w}zA#Zzvn zPM}3MB9Kd^%2L!Y?xgQqi(z^SNn3$y7H9J9xDTZt4m`A0O2-KK| z;4phxni2z;qeLvh{4Iuu*IAE})qS}}oFDxE>K12f8_|Y+RjAEQqCBb1;Pegux^C)* zj)J>XYsCDPoBHk?`FCC}-zbZot3hVI)X*Y>KQ}JDVx{j8d8+2Pp&uGkDN#%o!B1){ zK8BB@qM>5+&9zJ1LqOP=j`(8`Z~H2XJx3wWW}v-v1oEsx{08%^BoG2n2nFcTb>!vb zHRSEe1IpvdQN;?PRdAPHuy1Z%LtYdiq1K_)sIN_O&WoC5Nl;^otPmQZ6BO~gkW(N- zF_PjS(+-hU@9xH0bbZs%jAMjJ3a2|S-b#Q=<)>isnb?cdT3TqQy z?5wzKXq_ThTW-4apTBqoxQ4BbC)$;*)Ro9lkpK<)b!Ydkmc5?b)r2AYm_NgQ)JPil ztn2OiA-Sp0?fE_h$G*+gLWGumQ} zY86|xB_ie1Qesl07}2Ep{Zy97z`ahQ!(SFlfs$5f>1nxwxSrT1UKiM^-A?QjZ_yqg z?$aJ8zOC(P+1K)_{}pkv%UT_?q@x@wb}Y@SH2M6jY-*EVUp?f=sEqoM-U3}5T3Z|UdF(4zgE8;{cpHr6 z*TsFIL~nj-Qd<}EP5qU=`s}tF<%UF}sEktEHl)L;#F<~xc=zn>=MLO{<_-c(|91NK z&>mh%q`==WRj#<*1zfuTAoZToE)uxHBuJ4>?soUJ?)%BN$Z3*wN24wQSq4!RSq4!G zQAEsxC?e)^IRUiyTv3n96@}8^Te>5)7npe-kW!Fy@f03Ot82B>sR){&3zPr_?}QT$ zt1ttcPzAe0g@-aYc2X(n8K7hUil&npw+G$AtEyTQOh%yxR07sE2Y{vFfAbrWV zW+a4xo6dPdVFRqcgA?rxDmi&_M?C|~RR(2D94t!MCkBurN%O9ND+4M-+0{cVcWojz zxV8|VbzSfJI(QsB0}i=<4E_OJe@{~#4IisD< z1zHe2Vrq1g5>JpWK4s-OjIMc7ltNhEN$1dY3$}?6AySYMiys5mu}_jFcFIX$n3{*k z47`pAFn;#SQnCk9Bci^}d7a@-)5^0fWuKw1Gdt;pXP-MqZBH#~bi-eT{V&&=t|Y94 zMEpCZxaRv@kFk%N9~bCrz;)~na2rc6;B0Av@}?PH?2@TGMG}-ip(zMDWulga5mf{$ zB_*tf$*{9a;1!;9@G?*G%R==426B0?5=OEg8ouwDnE)+7LK*+Tq&sQ1I-3Xyh)ux5 z!kW(nYl7L<1Og=7xHxYU;itV##M~~HbhLIt4;S z+crEA%ZbzdT}~mDBu@ek+*G^1_I~Z%+D*TD{%?mrzw@ro9en(k3>6f8j#F;=!$fc9zL^;)&)^ZzCpGghp#&VXI2@nirLMuW) z5ByRxJ(dPPiofCiMf{D_>*@F7Oh}J~)0`cN_9&1gR*gZy?^R<&SZQnsrz^3Z7#WMP z-iEZ#=OsCoa}hxys0H=laL^Q7maE4yh#b&!`*P&&++^-}j>NYRXl?H3wDX#QYeJtaI_eDirHX8nMnKigg+;O&r-o$;M|4h(rcnAN-xRP&hCxR1F%vD5Rv$$K1~oSD0q^3BF1S@1|G zxvDtz3`80p2_g;fr^Ej~{>vXWk9LQIBO^0cj>p6iFkO_dr}k9i714y(0=-w-c%^kT8?Xvi1^5zDP426JKmK>x{xaL)tw3)bZav;gwH7%{iyZC;4$~qR z^?5NZdU2x{)1vpG(j`Z+LGv+hx-fwJRoN_}!@NO<`8ple;Rl+b3Qd{Od=}X?fuL}5 z#)bi|a!{-rEm=IP!kD@mYHE(eJTs~I}B28!4W;fMT-E83NYFJe~~qd%pTBkE`OFaT~WKYRw^jA zh!9GyEMWr2P#XN<^<%ppeiDd-w{JN+&mH1lcxm@d9hZ{VlK|AVeVoiIk6(RbHCemi z*7a8MYv8djZ{O{P_dDJ&nKt9B3k%gH96}Q?>{6ki4^_3Kr|f zTiaWMltgb5Hw88YH%W}iX0j6vlO6O{%U0V~`!>gLWLO@~4{JNQTP-_mJM1?*c4Qx; zA1eqhTftVemBNK^FN1~MrXKc8S72G01|8m^-KWWR(h~GB!#!gQY7+p7_}4w z4|*CPwOZ{StJR*hHrVMTj|(OSrl3WVZl+>slpz50NVEumj1pZyOc(Ob=bhwRPM|oS za=zuHoK_}VwTO-~tvSjC&4B?|zoffMrRG4OnIxMd5l?eF73P~6r~)R2 znkf&|3V)oF!BF|{!B7;^s?Xn!ko8gQCIttlR>?`- z&4VnV`|TB%1A>)a;whAdPNwxB$77kxWAVyknafB0J~Fc=v1-v|`;mJ+(b0gIyuhba5D&{Yq3qOm1(O9_5v z4!whc0tzVr;T4p{f^E3NWF#VRvRGwL9~zQLo8ZKfPdJB{(PWx)0jZ=BwVWgMu-Ar- zx#@2@k`}jodEfI89OtLLhmi8ao6^PQY*H|-ti8||?`S)7dIlBKR=a!XA}}A0fMxoG zX+Io+9N23hI}Mr*4f&#m^EczT)cbs)Vw&k-Rx;N)=tL}$YKgU^7R45&9!;^CR5?ZV zYFjNgI37$rpZa@}>9QNnYgv{8YP12nu-(Yr7=uPR)URYBZQ~oDjrFGq)Wfjy4mQAW z1@(3YSy}?mbGo(6=@4*p8b@--ukG}Bkj}*Vlfm9=WV9Kf0{lxCR!V{fhP6G~KJA1? zYqEj|Ucm#e;DJ}7F4uN9*y09mtaIIVbj%$=$J~MZ=~?@2V8+LT=8s?tE;}&m_`!2Y z>LEx7_*PtS-TpQX3W}tfHapQAIFfNBQi-@-X(9w?(wb=k7PBfOnuxR|f$%-RV!_B% z0|Suri4i0qq(ihsP@*5>Iv|p^1oj-+4CXG>BT1j|m#30Y1AZ(}ftk9l7pb3u6NTQa z_kxqJ{`wtFS%ebJihc1wc;&7uZu$3BP!A#p`T}`m>KCv6=9>?Gx&N=E>&EjFiBf!Y zYJbnGqszA*dYw#cR~iw|x}YWXuZU;KHbgNKW(OmaMm%!D2O@$E{_rDqne?%C2$fKD zup&$yKRyZaD52Qu5>(*hEak_20OKXmNEI%Wj8x&qJTCQ{lvwdEt~2r}m3rELRD345 zPyL8BJs#K_eAaZBIm()zFnx!4oPEOk9iQpz?6_mx^`LKDHGRgr*}s*(&OD}?Hu%>0 zd(}@fpJ7cK*?w-L`C@y&*QBexL?5-zw3;y~YLRaDE+&@QO$jE$rn$5??K466t!nC^ zdR#Tto$VpQt}13<(AVIje5?&UqGX2!ca&!= z)qXTD?TC*RB7m~nFbTs>ViE0P(yh-4WLVgLF@Qu`3X&|Equ~djJ{PTI`q!n2Ql^$l z)aaBDST>(*xVSwB`hlMBSY)!ARwis}^QX^zk^agCj~p{45_~S+^4YV$rJP%v!X*oo zFOW*5>EEz7LMkm&7tY4Z5A&cslk^}Ni`*S#iVX3ZL|a^>g(FZP+h49=Vm(K$0iLn3 zR?f_`X0yhWS(jaOm#y$4A!6nDqJ;8sVHtv@{w}Pv@}>N8zMo#te}`w1OqOf3q^)Up zI+&3f(y8WFrW`D4OPGc13d>Tdk6F*I=lad-t?Ps9wZ7)hFq_#S%N4;Zq$>;C=xxk4 zcANQH%MI2Wg4aqnhOSkv&fh}c$=x2hEq|M~v-zv+1D3npcZ&}M@0Y%oz9;`R?J@2N z{t3$y!N;V>Lr;XilRwBFg%QrJDi;je}X1LqzcBRs3Xq*$I#cbv{mhXIsd9)dh*#W)OY$RCYgz03HR@9ou zn#Y@|p5{%>gU!Qu=S1_VX0G{N?sxo!7U@vX@-(RsLGTaVqFZ~d$E}q0I~|=>^0NmG zW<-ay(Fm)Q6YT2oG&RJ)5FY(OWHq4!~74F74{QAE$?A$FY*tp$Y>zz zPUOP5sFF8Y=ioXM8+r$Gu{(uAN;s@E+gNAqSc$!{bY8@ht=*cg{kV24Ui(~=)w8G* zd?=RM8-e9FX$9K8?m)nuA%%E*u?f(CYz+I7^B~hFi?N%}JVRZ2_8atNU-TyviG&u7 zeQ}Bukn zGzC~v0tSqglZqr0>6}CufHoqArARy}`uz}~dthI(9Ea#Qno7gHw3zhg)2zm&*;G8ak-aB3_y zo?=r~^8SN)M9BfPutpG~ovxrbn@C~AO6%N=SHYs|s)nwUE^w7+!liSgrFdJPZrhRU zNEy>@aV!KGK427Nv1h?FeL}ZGDg|jorD!7}m$en?9aO;I{qBBid1kU1Ryiqw%7v+j zihT$~5S>=O?5)$tx;~dHVfn*_cIu70l1~*^WRXZ9=Uf4J_iI8>e&hzriJxOw5 zB;PX+NWk0`Zf%7mnp=Cx)KqQn49o`IWc%ipm^qPXY>Z!ATLHdxaW2#tz;p8n8bv>x zAdhL%r9(7|M&ncNV6olNE-W-Hcic+vv>oBmTqiyO&L141<#wSHjhJqv}&R##%W?uIzp5;d!VG{1bBiLsvnJ0m1M)19+j8RXEFc zs!MpMz95pZT!0bKFj{6!9gszEVuBE?D9nv~M&|1D-}f7Ft$yi<$>bCS&S}9Wt&`*c zUhc{8X3kyB1E?qopHfRejT)xUgJ*9c8^?B*RQ=38>ayDTLzfi1$&hK~8D{uNruIOB zel6dBJy?yrlFOz~Qah=qh!$cVb;q2!bV>#1GF5cMKVFH=B{+)(`6^Lsg0L1)gva7? zk!uP*bPC-6H8x%fh{e2!u?qOyLYc)S+k{=w3J)*I6^IC(Y1E2VorgEI>ftcjI^iK} zb^2#|1f68H(%VHK;#Lu#Aqt5I+to-D`ID8CP#X;3RI+ULSbhpI-OsYeKpyU3*flx% zW;Xkx@Uvqm!Aa7$SVFfKNZ0CC;8NuBSmiPPu$gjYT{jXp7H%c(u-s8%!Y*HjP#LSx zd}yUj3vesw4OMXAjc9QA)u2I&yWiUmheJFFPFVlaJe3l z^5te$x0e;RmmOm%fd!{nfTrFqn7`ojhU;i#bTo_RJZGW7hrIvLx}V7y`EUR-09v0+ zI5|=|i84&G&N4bDo6Q>%?f_*4P`(+{Y3nm-my|j~F_XKky|tZWc+Sj`j2cyHg7Oo} zQ7|$}3@liGpyC2(k%%mT*{&HrX%6L@2)H@B1aRiBpFo+BqDV)q#VY&mp&_ePiwLkbF$BjmQ{`+ELz;!| zs&f2+A=*-RQk_fBMhSN_%Tlzpwze4_TgL16oLi~_WvzH|20zN__Zt3RhON)-CYStE zymj8D8zPw>f3R+KC6Ofa$wYqN?(5I*47tpHhhX(~4PVyW0q$$;S-7@+<;|aS2EP2+ z1e5hhqZOJ-@EW`Fwhlf94s&01ZBtcnd!Hw zqo%tE9}x#1&dQGc5fhRD0+I$MkChN{AXu~_X9f}#Rz#?%30IJ$u%h#A=zObH^b<76 zyOBZS^yoZ1&EqAc1aDFMq4A9Tl$AHLhNBX5`kUEF;bqA7Xz@`4gF~o5Q1BM;I&=-X zHexa*69k%D#jFuYME~gL{CxuL!^$6ypeCy|nJ}_bq3D=IwPW?~J7%nHC+XJ-N$?1B zm^sA$UZzdS1-5}!C3!WqjlPxIL4TWil4F;!po8^dg@m#g&#h@?>Wf>vB6?UXUn0EQpqS@pN^x!jFuvUADe)MH4WoSICyqY z9ac%?IKgS)Y8dL33Acw_11mo|jPzExnSzQ0Dv9hs<;9bjn2w>&6a_yPNazHhqS1#%2v>0-DM@Mc>!mA4HCn|II)kIBu)@KY9NUxt_t21BzuEkcMt@tz^c1W zF@RtM#=t=)W8 z0uN|1k?cakP;l$Kom}Jg5D7TUjg1sWK}Z(n;Rn=F&zlhQOkz?-lML!3aiI%dMJN`E zLYIby!$1!YhRLvOfw!^vuvGNXNCd)P=s~4II~;IJq9clu&t>pA_~Do}43p1cIe9E= zh)XoJA&Ugin*#&KDrhz{6q%5djuQFl$%9Ll6!VCo&dcVCgZVGeUohQHkL91rPv%)Y zKb9wnysyEVU1M6q^=0p6*`+K{@@?iN=C$Vg>F+e`$+MIBQ(00`2t|Dw@`eR!=0#mf zk8-hcnR!ULUfE6TR-RywvM)DSlAJqb?RG`n3%%i#uR9b8FO=bB7P`@kdrfWxjg2y8 zkqL`xRS@WLc?W%CzNdVY>>KxyzV|b|402973m47iY)AZnk{M7C89552 zLmoo5@QEt>9;WcdDrcIdaJ+zLqMi%xf(W2AD{c)O;5WreP88Lu(>nQs1!K$aJ@NPN zU)KZ0ZZK;D&L)TIlbS5GQ#q#V(){{G8}|)uynOMzGcUaamaKaG8(8|DdGnh~LeAL8 zE8z8o!{weUe)yxGBg#jsB(0|Q5gsB;P0XSEH0Ohw)`}*_6LwtGXTy0lod77!lq3iN zZeWLE35+Vb6J?qaghfg?Su{VBM5zT6=xP?rYv% zv!_r{VgQpr1OoYEld~`&>>VTaKp{uXWV+%XVSJ-8uQZNGU0@YYm_OVgdoHWm3?}sEaSxp7A!AvGEzJ;CdG6SH?MBU6(uIX zuXkVU+vMLMZVa-3;u)6btS0X=W+!Y814zXmnL>1x}q9&mu5#Rj8KGKuq$@zlpWa7FX3Td+80C? z)G-q@Usg?xAiy+&65vll8wD>`Gm1zmI|>yDvJ#SYD~1Zqq&z0 z)=w}5Ajy$_Y}nwiz$o_6u<+X~v9eWfD%;?PLwYQY+%u>^vgCkd>`BJ4`kvX?GaGw6 z-qY=T*((If0mWIiDLB0lWItwM^dnipvKFV8sItF3H01SKoD!b9?_@1BUiHf|s~2ZX z3OD1g&(}9Jqzh@tgqk$M-oF5wH}BYROOx#V(fyCU|EI$bzC5)9JZ2ICm$t6HiR^rJ z>()!J_3Zo&0B^hx*dIU9u|D3ee+jK*GOxCn`XxkXoy0PtpPDjOe0BMH?@K<=N)b)M zMsi!jw$&ujz~q<guXm)t?vrtkr!%wa)ulBGRF{w&EE3 ziFfUvL*+fkyq$}nN7-F(=&*YoP0pILLIH|uCqUt@xgT9}X+Nq(jkH~;IlqsDsJg;OKVVS*_E~qjvib}A*yleX|07jae~VKlQp8ZLfg0;`gYc|WneRO~snzxqR!FW9x!ylQsmU6P>83Rn zi+WbmFd|Gw+_vFvdnmH6pBPfQBxtUIFyE$Q{`67iKkQE=G?RN1_Ld?gw2RH*4Hxt% zBfVAyX^xt3vpHC4v_NW32M*Z)R#Oqne z1kowq(Qj1>FL`-7@H zR0|3D|8gjSUc`6^5CxC$#9#t-m6K<0KHhO;oZ*m~dcKxsF-B*qQ^ySf41&ZQZMGHT zMnCu2JW<)(vH&_6Z~?CH7pX6-IIE7cThJO@18Edu4;c^W_&Tjc3aU+0S3Tp{OE=5D zytiFis_I#!E=r7AU>p0H=xCm5K9&mk509M-bAA}69p zZblU5G6ZD|KOh(>BP>UgDksaEQKe?qz2=!CLtHO}1Z9z@uJQ_7r;q_;!BFEL!8y4j zck3bhv3IY+*g&Gck!+E}@=+Fq1$2>~X;C&IQJS^Ji{>PI;b|bd4Kg{XVxxhE0Qw^7 zTOjC7qf?Bge!KmMajxq=5{%O8(|U?7C+ehZF9w(l)}R3b^%F3O$sN~U12RuOFzUKs z%UU%C#;I&ow`a5Zm|#^uxc%XNjVu!%sVgaYYOUY70l2=kOwk9PVDJWS*9ojeqV><+ zo_h!lukk`4CKGRq$27&Z%)YLWug110X@K1|!#Behl6B!yWTl0(S0)L$ie@s!&)t-9 zAS0&ynUf~bC_eL`QAQ*i90a!8vgS)MDZ+Rv+U5OGl zCvLkwA0dBM&HlDpEYqzL9UtPTpFds~^3X(aH?cxnTNJ%+8 zZC;!$?&B?&mT8^f6OyZ}kxipk49(dlP z0Z8fRGWa^yv~;yk)6j3j;5d%PSN%tw7UxQ9^co+C-osZKPEi<9VoMYHp7po8&<`Vd znx+OgIPhFER~Hp;VF2Hkadhna1uyCm6dXord~r#4e!b&h&{T~q|Vv5C>jX)kQKKki5>AM>ZE2AfAG{5?W@!r?9>_5mJtc-rrfHgKNw zULGPOD zihgTpMzmUAGK`RoQy4*NpS1DULM#t=aa)cGYsZBv`rDEg&^3ZpUHo{WFbN3L{Q5+j zd*WMnlzp#1D5>&MjAVHGjAaw3^$&%~6cHRQi*t&Y$UL?0fjhPAbQg$n;bhnRXTSOf zp_Qgi*%1Elv)enMfSV9v@l&5=dG7n?vl1F%#Echy?`OfE-j3DJwuLu^Y*`MAQVk&I zYm?mPII*+gc@+IF{+=E(F%c3{GeHlQ(P0IRwnvf^{awg{>niO+5WF1=i__{PslFLz zm}jX8Oxr=O5Xt^`D5S&7%!*;{Xe0ED3s_c0As3AWn+s{13G+xPdEC^WWKP7~G{T)l z=N5qhFz_^m2H2Gd7B9#uFF$(!WW8-EV<*U1x_C&kL_uX6nbVRJTb$C)<7>IenlqL1vOBYbuxsYVNbi8wgCJ+GV7V!E z&ei$k;3DRSeje;awn~9v_i(BMuZE;%Xnfltm-(cI)UMA5_d4~+Xq{B`N7S2%*LtcF zR(^KKfM!976;W^I(1m&d7(Ng;E0RFY=r(>)!?O91vVqWMgv`#!V@Q>|DquxTB@WEF zZAjf*K@$f3VS~5$TSCFH@vWpa7};UMKwDPmPy*=x=vKVCD5C@E6 zL>8+Mj_Bew1u+e}L^@HRtIzc}o`WBwt@o!f;MsbvJQSC7_{^E3{totuwZm-^cu39c zEkk2lXSmvq&tWN_4CIzJvchl10_a`x1bvZs+G^YzjhIiR$Bw zt7G7roFVjsy)jn$TNS4MKE66&&td;TLp#_2wNL3!o+KCg_dqCVJz{pCW2d%tL4G(< z5DtiBMFqgH*cb$5v0-(&mn-E=d)yE*8b#qw#F+w6`4B>;rQaP8e}TnmJ@ypki~-vB z=`~S=52`1AJxWczCiO9xq7Qz4W-aE^v}A4*&_C7WReQD0NCOOSAL~R2fex5SgpEWy z&)o6I4zE|gS(WVIqV@+JjcseYv_Ti~lzZOYX~0B96)u>BTMnTM%~P0e&S9d)G`7LI zqVlNy@G#ST;_QQJ=(weZcmaCLww>vDGz-onStvQUM@x}3k&8SSxB`SR(;hpRjDi>q z@}NVkc;?B&7Up_=a_XT$sV;fpMTy`vCeTz_CZP&fqW&{r4_u@7976Zz5VCR&Kmz%S zwO^++Y@{7on<5F|Crj?)H1Usk*%sWM&49}q+vIlwvJ6J*ZLOnGO;wvg0YBd@EHXuW z#J}HnwycemOV}?4=brj}zRQU;x#|1Z2q;P}`k)V0SL~zx=|l_Ff%L%6;%8WQcG)w7 z)={k_m!^VBKlLhnxW%69T*rz1_H$JaD0MOBu_clK&sFp71a!{5BUO9?BSGPoV8xLi zbDxFj(yTTIUl2Fyo?8{H7Dx))uNd~%448VnzkDpsC*G>)0w%keNFF?RO66=1Z;;V= z$zh)Q_Eg4H5O($Y9xu9yXxp-#sa721cT;QJB;lKas~a3o^8LZE@xX7S6hqPoG{5qo z^;y5EtK{RG05Mb&KG+Wc>8n<5J~Ad22kerHW8q>x%Du=vQ}PKaCJ%@xpWyCK5MANd z+Ss1oe_P)?#lM4p{qyd*6<)=HY>+A@K-O1e2rw{vN>m?|_G=y2?1_%|Q9PlE(GvKH z3ZofXy}Q7(pro33?`H=W!~_#7xkzJ<1w_nlhGbL%NpE1t5tXcd+x95p9~)SRS>$uV12!wW#k}rZ;%VcF@r_XO^92d!rq0xm`GnFCcYJ(W`oqUs;Bl9Rqz4(k z-EmyfMl{siylncHC3`V^ba%>tnMvj<+GJLf+dO zgIHM`;_Dxsd-9pcoBiRJ+rs7KgFGnJc&J{zt)Vl1#3A#?dPitZ6@m+~xxsUh1!3L% z-6qqDBw$IT-d0XdvOcg!8Vx4n4=i&TO=AhBjML@@9au7=U?O-H!~Vb!XC-9Qn^6he zp-;T3)d1id;Vuf}AJ0t9CiRDI1<)IK8|!@;OWiD18g=gB$hQGXy#^wrk+82cwxi9? zyIr=Oi(N>(e=cJ&{0HxChFAhJR$=fVYu+&NZLG9On9L45Z)FiM6(x{IrMTvolS_RUe}ey6L0@VU7vllHMkMQ2zP|45W+N5ia{8A&UZxMXt8uhkf=gd z4ynZL!h3oRs05zAR_=k7fwx4e)IOuZgir3rWQlf%v_u!2dId!*L~y=UZhcnPDrOB^ zlTNr3n!X`Sx6T_#{Z9B%i3Q>!HkXrj8j2wTAR{0PSvS`mrL!Cc_bMR`lZ=I7iIf_H zR8mU@;N#S%saI8KQh`?ev{#kL+>U<2_d;@>PwJC}T;QYjoM35i%tFNvoB^HcSe|zh zF*rx>OxH9q!#U~UBkJ?9a?b|E^lO1cxz9XC-3}gb% zN@VaZCLDDA%ZR;tggx(>dDY}}gAdd5viS5JVXQAw_62d@(+)$o0>&m$ROvqI_ zW?2s7FQOVR_1r`-(gIAKctSyA?S6_P%+=EX9tW0xz?})@ycyWCJtD^(#6c^Lp!8jXam;37 z3R^A5m<$45nNZ>pnMiaOfS?F zFVl`6&U3DN^h&$_Y&Xpuh*4i`Xk8|pw7(ceSFJjK5j<~qb^zicz~$M>z!vM)hK7IY zi(^Z*2J?=kgEgEW$v1S%jw6$lzG;poH+;GYv${p~kXD+Zc`X9GJEwmK!CJiT5P zKUg~b@!bp&DJb7R+6mC#!IWA5t8n+Ilb~H)P#L3$Cry+`71&4|_?tM^F069#aoD_N z5uSc>=n&#b=Zhe9LiZ5M0qEv6?nBpi-EBRXo?bxBW_qupPrP0BBbq&V&+K)`?-38F z@IgxO4wI|;$7F)?QGHCdTPy7+Qb-N+jywLH;@%&P=f&X11|C@(Vt_mFqhbcs^>*wG zv%`XO3MCAVrUvSVVzr-3i=Mq9?+Ziq?@V21eXyswLT%IEVfk+ENEDl(7x<*Um!k!c zaVw8{_Ib`^>68V(n5o5BfEuXv<&Yrf7jg8GWW&V@1_{Um^WrTCqb;nl3IHR4vgtN}YW2G=Ix{*m+BUqp-aQtZx+@1Nh1U3e-$@<4#O+f^pRNn! zGX@}v1qwFgAlOl(^*Q)-y+Rts=y+!peSrh6KS=Ki>>F)uc``(h{`9!*H|JV^4&SG4 zKAoJ*Bp;rC+>q+MjUkJ0fNma6Iq1)yI)#$eh@v>Ov))XyjFy1bPFkyF=Gk0KyNVZcB;u9+s3gDww_cs_gP%~UCL2Om)KW*1KH%F z`WI<(KB*Noe$5(ESMkjcTQMiGeZbmcfSrTyUO$f%>q884Gi%xclKSqEpn^iYyV=@m zF%j{kqhIR!mWDn@aS}AMQt~U|1tjWkZ>BqOZw1jMa{0_4$n78gXg(%NBuVLw=LRqW z*+YUb>v!83)-JP#Fk7S-Xv-8kMy_=M1J@_Ny*e{uwxS3FeJn#Y^%%z5qP-|KcOO7c zS*wDl%Tq5~wu$O2d&rxuzkw3YB|UITrhbL_9$p`nP3IuR!PK_ zay1By^*S5DPW9PZSs2XGjIp)lYuJ6M&UOEB5bw!c?s+kO>Onj9gMzL-zT2QkEOrg> zSiPDxfKC57ROh?u(pK|iRW+wT@(TJi8{FD}6#vFghIk)_xO1fy)BN=Rxc!t6LUu{K19CczSX}!mUD>sI@bEi_V(i1{3pVk5HnJ*(vok6z{c!n zz3!D{tk*S2d7xdY*y6_EX1@}5yFVU359tm*=?CJ)Zf@9IU>pC3VLI*nFH z^p8bcrUOKXs5#d6_#Q?yziJ>DWdNx<$h0I7*JOzwE%E1WkoSt|xy-=N$;UQdPP9*ZF*RB6!@tfOIGaz%CrLZFAoK3fY=*OlDGf znEuh;5k&^BRhjSrMaY;Tqaa#uIlA01{R^j)ZorAg@NSyonqmcwiYCgPoe_nV#*@MW zU5eqlqJ0~vT_dl7LP}*A!sC@IEwWS+$^C*1ogj^&TyOB<{laSdO_5&CZ}tHNuOV`| z7`S2bVYuvvoKPY?MyjL&Wi7)7MTATbYZ51!55(tQ9P01E0rG2eTpL`|*l`}EdFv~| za~JUad{J3r*-pM^S;Jl0?q3%py3;CeSc$!^LjC94@ zvBy4k3-qKwp|**jxrNm0gDr?V)ZY+ZNjpPjRGUk*M42U|q%-DQuN)0;vqhWjJdM+d z40C*)c+Ra@i}t1_U!9Bw?1x|RoEnmEgyBP@+Yg`e5)YCeU?AMnOToywfb{2w?Dh|f zTwy7t+8z_P5`}U5xJqdcd*o$)$=&s$q(|mP0o)b2s&g2Ev0fpVbB!p@&bZ)0;&H5c zb~qisvWRWz*+U5;LBY8Wzbx=&YLNP8M*~JQxJcZJ9K_s8GpAP(Yo4-|4L!}KXZvqS z?@l%4f{aF^)BFs`A~l|QL&ZR{uV4XRKi9k;|CU1wcGuc~>n80%_3ro;6+=*phkRpg zjhSelkWoZF5ZeFR=zY+=*FE=9L(i4CPAGj7`9mB-Zyw1?miDo2gt$$N>g))DwX^_q z)%*su5K>DpQBZ6KoIk_3OUqn!S_;+SYCO)GQV0<{_X=#-I1xn@aM&-7+XG>M1=gft z;fR2v_~t1A^#TFv9W+z51l4_@EtMb-D3=&DxZ^PJ3Us6;jp8MbTFDcNP1x;PZKL}D ze}C5@9#%~&s3^hwNe6``7@iH)?c!!dS*Bj*U|vbo9qKVej+-&Ll9nbn6`pt@?8${~ z>aZdBb=;aBtMAvJgM7wjgWXU4X0|<+R;p4#4a;+Cw(39b?;ZJ0FMRfDKJL2|G$5yA zCwU%!(WW}}6keecpMr?~fiDgt`aEJH>ltFAJ zms>HOWjz`5)5*o6t8zXnC>Ddn%tnAGTn*^Qz?m`(4mK(9;}66LMI=itLwgyRgjg#= zV9{J!GD4{+iImn`nshyld3gQr;&Q`d6)vhB$}HKMTNB8Q4^wBy)6>W|l+SzS;EaAj zgzhjw3g9Wh8AkR|1tBx9g|E?OO=i1FgV>_>Ot6n>_Cn@DZZynjA6+qC1~QLMoHfTG z5<*@Pr11QjrxuSX7x@$z5ck`%fApqw=Y0yNS7hq;V*SDve^Ie!q*OND^)e@eAuz#Y zM#5Iw3kI`S-wNCZd1$`3Vac-<i6;?mhh-vxhJX>rS&pY@GD#(Pd!u2@Kqi$i0{0k(3-Z#NJ3b{JMx^I* zENO|;!Me{1-=B{zribzB?n3uF+`2CUdNLrF*n7)}vNtW=dJyOXnD(WaipIexKX_lAb1gLwh`Jw8qx`=A)7}%GQEns9(<0Nui%PVFXYGX{4*hL|X(wNI0R1SD-`u zAl6DSfKrP76W-(u{?b6Ib2HpWP?T`956?$!Yih%VXN|GPX$gN(3f~`-ht(o5_2MN( z=8{ZG{4r$vP8EsV{#V|HLQG<5c`>%m_kIMTGfLV=2sc(0MQTY8(VG= zVqpf%Z$!V)%z*L^Uwf&c>5vbK^8-r23P^XbD1ak61DHc(s93uv%Wpb9y;~j5la-j3 zo#%Iwse_|mLSa`3f(E>G+*mtxPa`oIXSX|otmjl6+HIB&47(|5R2gKR4R4ujVSBXI z^M5idq-nMG>^|K3+VN&(oxPAffjzQ(R1T_*+mU>xdq(gP;Y`P3$z^_>aMG?jvx&4Z zv&q^)?!F|#V33JbL_>cgRe6+Jsrp=e_*}gEWWp>tqB<(hQdHB?>(ZKyWp>&88S!rI zWQX39W(5J;mHy_lCHz2cYTr^TwrMi;ZNxHL@jk6MpvVSTBuvx1ac#BYs>I+lWO^6C zO(FyM<5)Hb`i-XFeu!Ba)wtW=&m!yvMHqP_4akI$TpCI&2pv>)X_&mOcC?!R9LP1w z6EFHEyYoj!INR;2pV)hH64)kKeIn|M2R>a)$P17!NSlk&)iSXIde+fRE|_KTC~?Bd zkfDmr&_2^db>MvjM`cgQu<+gO0SsNsDd1L_=mutCvEu`#nJRa~RO=5Dq0n!$au3Pc z-EG36y$$vVNnUb8jP=R*CKCOrx;$16>~yIkb0g?H{5i{DcVr4+rN%-=tfz4OxXx#B z1?%A_jy-Q|Q56XUKl>o3r%HxN85G`}n}`)DGo-AgdB1(pF^O?p`U%`fbf#&}_q@!O z?3^|r)NT^oZPIDy^s=U#Y`s})Uzr1rPBNr!hH*U6-HM${a*NnXuZ0NFGAKB45un^f zj*=}?5Je#Pu>5>Y+G*_}<#|Z{{pqo;tSvmH-;hLR+16%TZw)zznDPW{n+pD@_8rhV z*AE~xVIS+%$rskmE9=d>;%J4_gfKTG_y_%lL$`9g`3MP-bMks?Lbi@`_h%>S&d_|i z-m~5fSKyEE!3ehY;^)NYIZ~!r%a%=UM!qWyOcG)>OoF`GKld`9;mPo1xGVTF4uxF_ z*tTqdPPbmRuxwRqi(9&DyIZ-~3FU+@9bM5~(8(*{N8xt{FMd3yc~)In-*Y^+^^IPP z2G7pJ=%?%R8zFUK-#rQDEv2?9cQbR2=_0p$HU(f05Kt^Alk9*%O{iupzfv&Qq`RBN3*dG*VXugY6+_T(Udqn^2W< zb!0`~d(y8_4?~RvB|)lL?7wD=*^M_bHs|P#h735}bKq%5oOLctbA{m{%!{YWyWD2y zjtt2Jo#ajTS48qq2Gs*00LmiJufYdr2TZrMwWy_-AIzCKiYoky zdrSuG?k|VK3v5fp=@uKaAh{3%>-NiU5`!M&C(--UfHo{;z@CDZLw;2E-NOdTBYTnn zp1C-Bkfxvw4ZPMfWY#8Z4$s)-o#ooBIHCPe60)_tA9AoGyC*?C*;H}xHvyzKY`Q+k zEIxUyaj{cGWCCr0(PIUc*Z@huhg{;c$DQQMW~W;A~K^dr!_W?ma2033ey-cm`d zeBXgis6+qH$)}uc?hf2Rnjg3Wy|iBYlLwQ1XBxb)h}-48ar)v+E!@d}C^2iPgImPP z)eDP$h=x29g+w}rBFUhmV?Cck+T_6etTvhoD}+`iu{6<;Cv{hREKadSC1*FLd@LXkqjwM;z`Pk+cSs}%9PsGiI(0KMleZc zBWBZ+^5=6DkVQRK$m(90MMerIO3vzHFBspmiS?&S|+_&L>wc5j_9bH2^V2@p4#JYltjObA*S{7pU)P2sLnSDc8r&H zC(Gu8X&+ZYkxE^h05mLZwRPO4XeT%6KEW#8P)hP!K2Wkvn(V*7 z+4L%6LdosjR|w3uzk#7yNh_ZzS9DXS3y_E>3b0to+&L4{n&rh?l9QTy>mgTRssuyJ z3#_~51oGx=L-3M5y_o3spu*Z~AF16#bJ|FI)&AVYSFg9tBVVO~Sg2U5Z!1(>h(qoY zKj~_0F|2|6RHmWm#1NgW$%%&Pay&J2rT>}au{$#pFL5#~Jr6ldxMhZ2&_WcxxP@6? z+E8L2H6hKExIH|?mQG2=p6<8(`+QsEyy7QEqzw8mUb9aoP4KI zSY&BR6K!Ll&%gy)s*WfBmjk4aV1Ut#4HD_SJjjiDOKeQSYzK#Y=1>->-S7?5c;Cd2 z8WpqU{s2-YM2V4U>8KJ+%_0oQ5TbB~4;0h1U~4&cl(;`66!-j+aWP6#0^b?tW>kYi z<|Xb*RYLn~$=9G_Lyv1Uq+m!{Nsffes2+f!6h*nO;g^*>z2=TyZqwGG4{O-@IBDf} zy)*(FR>6nMXa79p2pIo7UvXEoJG`+$|Beu$ZDX8xdLu#if)GWu1Niyh4=)%h|QaMfeJd5`?_ov;M0aS}Wvw zi0HOON2g)?lhpCH%g!U^vmSoE7kiqe*$N zep!XL#AUq?qfEAHo;%A^GtuE83A_R=lqoB+aCUyN;+F&6i$jMM^PF%qwv5Ia|c9Q5Q;WVrFtvUxs#3^*ju#-!4 zx`|3To}o4xFv0!Yvvfjf;&o?AVe!;Kc_9ZYVKNtH*otlC81t1mX-#QzCe>4ZnK6Nc z9_Mx>q#K`k>ugIaj&piZ&_=}Q6BZ63Q4;FZRW(vDSn~3K_AKpaEm)7mlq*BMyRauJ z7(n#U+;&2(-<;ZhSeZ9ESXf11SzZ@hq1L>~C07F-ULz&Cp#KSuzHo`5+X>F)<0I~w z7j+qflikI!W2vVG#zZe6oXqebpOOyBIIdmXHs zTCC~1;IS zUcRubH?_rSR zM1D4_VX8fXjWwM`E!>6);Otil;LO@#5O>W(F*EAY5iSo}I0O_6wwztx2&?)eoZTUM zz5w;6eW`%dBj)^glqsbPXG)oSqi~v0rqF^p8Lxx_A%d9gNkRtNBy1YW4+Dw9gKIX1 zv*O3O<55hwy0p!sWcDA#N_+L-%()-VxgPvHrS&KIHNotLxk$FWi zL%O*Zr=!osf{^e19>4xz+x>yDq~%EA=gDWjLmmMkL?P=#iI4{Mje;te8o4JVQk;hS z-9^jxO|zN4j=%ljadz!}$tdHZ`QSv97&(^joq6&AdAc1)>Fm7${Ni=%y}{0=B7!P; zRDg7C3FdOecfQ~LHdT8z=HLPZo$kq6`K($Quj)Gn!Vi2mpyANfh<@0M2D+x+U>4V* zVr{%CI-xW!QEzOS;v+f11yTHNpYgTiv>)*&;G@&`kXL{w{3DNR2+*3gL1(R6Y0cz= z8e_PIQ~An(&4?F7OH>Z9tzdL`Hmq_K+pv{tA=i!s-mlvB>oAmubsRAiE?45p?4n70 z5O#Lo&0-*ST3EPynU ziLDa>D+d6I{;$~I1}zgK3lzPClYzB`k$|n4wFvX$XJ`7%aETv=T}jau2l#>7$9 z#8uJG#=uryNk;ig#@fKlkpRF1#moC2SJ?jlT=}w6?MpAimmNY9!b;ziu0DukwBjZ;e06_3nz8cH~S}d#pf-lLxjDKn-HZ}ql z28RDp`I6Nk0I(8hu`w|bu(GoLQ~seDzZ9^r68xqAmVahs=lF+a{pw@?H~qKoOYY0e zFMIzg_&eyYz<&mEFn^iJ%JAC{&^zT)y9qy8iKcktJ|Is_a{|I+lOUWb5*=}YfllfJ~hS}b3E|KhWLMe^U&m$JVS z|7x*+#RI_3p`-KPGK~GdGECaU*38MAfR*Vh^S_eY$;9Dn=~x>$nFyO0*%_Ps9rW*o z=9Z;1KN_*hj{rK=)h#$`%&7ieW{W)*%&_bh51zjF?amxFL>;Z(Y`Z5`d$F8QKA6@1Sc z-J%1h^lsbA<>`3r{lR|w+6jDah@%>>YNp+&e9G>frtj1JTfJ^i=lJcV1J!JkEma=g zNNe|z6qm1!T=B+{kzA-jmv84r&Vt#-=k+aX>dI-8QQ8N0(&*ZQiACw6;(2BX#tgZG~qh}lO?2Uuyo+CBZ3 zzJ$V~48ib4`GzWvR{;|+9 z*LPe40yJvgWMqn#Jc0n2x)#@%|NYqPi;}){WgwpQ9G4-UeT6eM_So$IVu7b!$9MmV z%4)_p5S8U(W*{!b#Tgs20EY)StPuV}k>!GrHgFUSptP19VhA3G)Jp3+2*Ul#f>v6} z`UP3hC;MGi9@T|NG%egQ3IxDtDb0XfI0*Aato2DpVQHm>w;6&1ewf#VremQmDL(-Qaw_E4NWQX9s_(j3# z%Q*iuA^sGbx)dCpC_g?uMbyYT$Hv;twUpINFLJF@Z_dxam8{m!^*LefbjxJU9H+dy z+I3%UJOTz~Lq2RY7K8-giFjZy4uAcia#0;WeEv}G`l#T$QOLOd|AIWzf936ef&3Rl z{|9#dGQSY;UwCe8@CDajAmsS9TK^*37a%L!sn}ZlP3tfG`3LL%C!i)``!(V(p8jtz zq!s^fYl-8(Z2I?FVq|9pFhbG)tHnsb3}9va0>S^=;yUkg_fk@M;rqz)ypWkGv6!W` z$ZVF#B%_si^bQOuwnklsYUT$9T~1a(K>!90rXr%Mp=hN>r8KFlDj;elJZX(BWZz*O z*`g>YWPW_)Ws{(69rNn$nS6YFc~{usn&dgmx#yU4PjR#(W+Z~jFaABuZScVzx}BN= z9@pS6-eWLRHLM1MrN$RLBrjS-o#F6YjNGH$=|igU1d~LW9uRf)Hgqk{7vQv#M17#+ z_$Z`sN%W4SaIB`L?J-_;#I=V}&`sNVnZ|N>qcI-daW38?VB9#K#<8u~d>QW<9^w;u zvniWXr>{7v;W|#H`OX{hQ{I+Pk&cKfZpcgtC;o-Bu?&Bh!kNXHn7%17SVz)ZgHo|2PQ@G4 zRkTu1N-s|Maf<0Br>4Nw0tA-~cYPF!GJ52Q<)lWo#C+eIDj(at>qTv5ROF7L>!(lA zOBo-J@MQxPYZkqV#}sK}TupIida_A9lM8JdV~CYGA8yhZAs1y7*z|z1*gbQ)%Mgq= z6?0H?y{ntuow6KTouP}ocLWYba%O!wIdweu37%w$G*y9QMM<&~_`1wx9nM1b;b_Nj z1c#1fhX#8?t@1-vyZ_k}OaUXt@wgMYO^MpEim92iA|3uu?&H^pJ_|C@)->A!*CRce zB%QvR_?0I#y(UhX^%^|EbH%&aP%y)_$YZ*(iytc@;Kv+Sd)_I(Luxyg`1ai;1zwpp zGrM;yMBdRw^s9)?p>!mq%vlx=fIV_}i;(XCiRu0#^@qjW$3l2?e0l0BigqYSf^Boi zYwaPnMJi8cqS5H-fhM(rtg&6x!BU7bFvpzb8ZRk74_3cU5KOhSyNA37y?V2nNkqnH zgYB=N8?2}vSm60@Vcw|oz3mtnPZv%j3p#xXh_`tLa7Q!vfcy^C zEo{_mQI!B|v{-Ak%+#D>V~8*QUTiTVZGmRS9nR&>sYklHZ~83rEM$`JkT`j6CGRLc zBtub@kF;C!#|%eCkRJNF4bp2#^0ih|jG#$RD8si%Z#px`nYCU$rEf+9mY2Bp}a=E`M-FxVRGQF6cQbm(`osfs7i`0AA>~{6p+l%WH`f<3zP#Nl~Tm_3^({$f+ z9b(et8a5Bb${oche~ z&kkFOvK&hsO-_i>15c&1)yoEe?l_K1vRp?9Bo{Isk-Q~xSI+_6eIq`FO(}*U5Rvc!=QpsTPDh9!7i7u-E(1 z@50}hJ*~dse(-)KeZp)EsTZOwQ+Dh@xz~4U^VS&q$ss3OjEH*WEMhv(I%zqtI{!TB zo;kh4eEE1GeED-%?SaZ=LcJcMvvQ12asjy@gB7jd@DR`#xIPghS$!ixnZ;5YoKy;hV}!tpN=jFXMxf;-e`GOcm~!Q>TaBI zNRD=-s(@!takErhvsAV;dn^Lixy=Lqp-)kD6wVM{CdE|hGj7rWKys(_0laqrefCb| zQhK3+MeI&svu;7GQHFE+%t)&bM;R(Q&Etit${D;vsg#q?AKGx~PHmHNk)$fcHJ3_S zV3+?WI{c0?{3rhrFg($nU&`35R@5V2xh$*k2hTW=F+|wb&kHA?`PipDOK-r~qWmuK zjn|tXS*p+t?NxW;Fe^kqJ4NZ+YY65MrAz4@Kq~*<5lz}>tGsQI(g+;(*nvf z9M=GCxZmTN`$i(Sev~1D`K8p*1gsq8RUEwSMQ~+|yzcdge&qIz*d1Y0go*2yWO2h9 z;k`kiTe?Src6)By@MFwM=8JfRN2awkALzwc3H+Q8w^p|@-qY!XUaW+w3wDoSxmwR7 zt!j!Ck9opPQ#TiFoQIGQP9W`yWcpcB5>WSQyb`di#=e&Cy9$=1#Ek2iSbIqIz=e3f z^hq8^^NjJs_YtaEnfY3f9`W(1jKC+ADL}^&LeabC(Sx}K$k`YQYZQq(q(%dHZO0wG zI~A?pJ-*%wj>AeNp*@ zU|q8DZNDih2bWzt3kP_*MO?UEA1Bc)4vU9c8P>G=cYWge;)5z+c##-)qqUH4@EfotB6! zc8L6R-c6%26=LIPHo>)SZyT3RjeZQ0agyzHlJ z&*su?wJXE&LkX8?dCsY@&}4S%Wx`eIx2w>%6@H!Jc~>tbJtyx5eM4F?!Hj$(@yw<<9~C1_Z!xS5Q&t@UcW(jY7`rLRrf;^LJ9>()lOon{P6 ztY&@B&P7DukLj6{b(;sTLI0pEzr zT@8s$c1~}YEHmUo44)Q%$yb^Xr5IRBiCpR`cWHOx-m5gROLllSoO9nSE_ zOqhJc|1L&|fqU+I-*S%pGn`(ZUL@iYDH>SQ<^V=MSp<vTa#ZFaCNuj4WM_3cA@zKj>bwT6-6Z^2bI3|* zPrBUdf}X%$QdlcK7uqyL_f|Sf;%=C^0i-bJkXC3H>F(wG=_+I{IpV8PF7qxsH#5{` z>2J`i>^32%mXpeB=Vl;-^DSjv(Pq7@q-5&$;y!rA!t&(Q>COgg)5#*U{f?=$|IB&? zR;;$zLUsIUE26pF)3(0puB#0=F|Ch^pc?6Z<-oWy#P+scrC)6RlC}R`M@4Ouin09h zNf&l?#{Q>IOW;uDz9f;FaYT?1Nm+`(lon~A>PGXbRHJeSwH2nOhafgF?IgmO5p%xG z&0+dGZd+4KC&MT5it#6|U2S6&cOai#d5@E5UL&yU*vD7RP3?}7hS=Lm{6yHqXb@a%Q^bpdT>kn1l2iPs4eTB0XreZS`UlaXVl=E!vWOH+%6 z3?gJH6|!mI@Hx9UwEzzm#kO|zeRPmWVDKsME0Aw~Cco5v4e*nm(0ren8qEGB6+rY^ z>jR@hOzF;(}hd z%_y%Rnr&LQl{|UWY+QIJc z)>S{oR@Wf(8LaX+*&9LUdTlXAe|J8D1KINGM9Py)41bz?j=reF^qgoz)^{58PG6- zUp7av=USdDZgz6ST*=o%-aZt0jjPf$i$$CS4-2N#>{wrvg0lSVS}f}s6m~PeXVCc8 z;Po|$cic(PF#jrr4Pbj=Ns4|UJvz3>+Bm6eaBLm zEk3ltO#ptYc^3MDY5YXHcQ4##d{#s1@3V0tyopr5i0OY1xzkU;ykQq2)|n3X&5Qw! z?Fy$B5H^qoPxM)k@Mm1)V#Bi)9D+^3!ME2C+9a~+ z{$JAi!7)d@Ks92RHa!sOsJk$Y-ikvhap?rGLxYiufE@%zIYKqyiu0~mN*(NP2Xw}j zfrguq%Zo>gOS1trrNDxwBAK{%VI}YtzkN_V3j)Cgi66-C27RJ^WQf1j>!KD3=sHcY zoY1XlRW;1KI}jT8z-z)6OTtF+K1hN0lm@QDUTRYW!Fx0f zsJXl@eI7kzHvOG#oTVqc2Mhn{q+DfaunoeC#u9jbA?Vu;)H3AAzD+HmFAsU{;b^&s zEBSM$PDS1u^!|+?m38FQWnXjNXWh}KPvd=AT2Bdn{%%kViU*vhk9_T0aAVq2kM0m$`tWbf1}WBD4<+{Edk4o5_aZJ!56C%hd9(U5QJ65Rt102 z3G+c|D#g;}4%gWx6jw&E=kXM9FCw$aU3!7`s??BKn>#{=R^2JhD)V!!*n5Q+#q-Ln zf?tpLNolIhY`!u+b+SX~ktp{wQPkpbgP5xa>)!Yt&H(v;@pg|vmIZ5~u)A!#s!LsV zmu=hZvRz%aZQHi3UAAr8w!S)NX70?5nH%Se`{Vvwu`<@)J9E96xmUcoo_zU!@$`Jp z{ZvX@dO>3&u}t+7%ju0CiTiDBZq$eJjPQGTki*^yyEH}wGK0VlzbEygHm}x3Ies}$ zb-Gw^B4Nsu(LKeXozfnEx|`abe~E>1Js91+<7wr4#HnEF5>p7r+`NIXsIs(4kqd6-@r6 zz~w`|a^l*;lD|_5J^_YK1y9-Xyl8j3wePz_?o*)buXnf|L2_A`wdy7_$IXCjbO~)B zc3eC5Owt=s9~=q+S5SahdYix<+GZ{+ZF%~O{xhrBm(VjLQNss=qNkMEf`dJ)73{I# zxo5=?%yc19uB6+kjY4(|2_?bpheUzO4k9JvV<*)4~OQ1XPG=ZDuEHAkwxsIdh)=PpJJp3mJ1lN0 zoSDTThm;MzC-JYmHwTPZ_50$+t^}5x4>`CoLb8%2tW`Dt=Zh3FN!nfC8yOy(4*iNA zTkxT0&b_%oU#CVla-yeV-|ZDqpD|fa!CKP%0PQ6Q6*z}zAdZsQvcJ5(B_Hm(5LHXL z=UCgIRn+FJtO3D3RPvWhX%yh+Vo&iX$7w!UsiC)c`x8Ipsy}E7;%y_Dt$3mP zQ8GV}9a!Wd&%8l~dCNh61BdY8CMXK)y!dt~l6L_;BQ7EM!9N{kZbVrq`dk8C{-^@E zW%_ym?%MwX{?Ky2-QFjuGJ5N?p#y_k8)VsI zt7pRv(&`qRT=Lb;1CZ)Bm!L_sXv1CNht|@9gX=DezH33^9k5CDN*z7~I3 z7A1r^jV{!B;bXA4(BcMeXhL#+KrLq0e5Er@K}qM8oA#)t&6R3IEL#VUbpYlKBR=IJf27$dUI5`>Oh777b=dbKq=v z>AV-X)em+wgkUqa)t4&$EBNhlT5-h=-F{<(x5=4UAcGm1tzH%SRv^Vto= z6La6)_~T|FgtME92j+rTl7n89U1q$m8OZ4A&d`d^7~<@>mt2b#9CCmQeTE!>S1WyB~Toj}gJkr%<|vXpFiJ=6M-6v*dQy@fS|pZJz<`z{Z76Cl|7==vSSYrf=47<2U=f3u(sxxe&@FnA;CA=8dH zEc+I3tLZ@)<9!pj=Tq5^p$5l$+VF*omj>bnI}g5E)fp(%uy{38I_G!wLck3=40;G8 z_O|W)hQ|Y;{Jj0=ujlRiyHmr7e{>Z9P6L_?To)FQ4h--l8GZM2Kqq)-diDcI0zdTn z$Z7WJJRAV?Y}bah3VAdGbzH?AGa2 z@#iOlk(|w0(3%MPfxCJop7^`IMdsOu%4;3cU!NUXT2#?WS4;(c-Zy2zj`$^asNrqD z3{&0Y@If*?MR1|q6DuwAx_%vIE$Dp>{*E(IREfd<1os{S*QvvRi)WP!I+p#$b!BwS zM7Mx+U~DI~ukCoQnHKebnXx=l?}pZ6gwk6yA@HPy$Z}3H(p+QN@N0&#{oHdc=u=fP zyl#?EPKtf%V*Om_%oSFQCh55Y=g$au9MHeGb)e{^RlQePqhW=W4(a~?mciT8L@pnAOz|o|I_B!W zY`E7MjOp%H*ZUWxhwS|1H>I!Ccs2yC?9W3@t^Ct25VKFwPYW{d*X34B;ryfQp={BG z82GPO-WmJa35_q063jcZAC3AvyxQB%CZObBk-T46M7DV3-Xd#Y9}}(L*}(H0pssh; zDTsFmti$J4Ox5kwH5VEHnn_*Y@!1rjN7FolTURzI1`dbd-IX_l1Y;%8Zq|XL_ zS*GVFl!JvC+~0IBIvOA+=R6xo2e+uDx85T+U=R38k0%<0PH*F zx$G0j;2X#w)uhfBs02ynTxZy=R|ny4G_Suk?yI_J_Q_Lz_D9Jb(d&zRz6~Vk%Vy8m z4;>Ef_WSHm@Hd2pw=XwbZx!zk#`j{!m#ws??8r{W_gc6I*y+CAm9rNEbdSCkqHS2= z>2$R*#_se_Mz7a#1eJMlr!wG@E4Fszqob?Y=I(UzbX2|>n|;2F1sKrT&!dz1qCKfa z+xrzM=TH-5uNsQ3v26SlYKQns(dp!oL+`Ad0mHWg#RgIL$7=4cr!$^D%LnOWKkzR` zZw;zR&YGd-;i;Jdd!B6kPZy2wb_B3V!`a;U4xlzkyb>=`pO+?(T`VhXIZ&}~Hv(`( z6BI^1B#gR9AVBc1E7U1@d=R{zMi6(7exrXGGW#%tpU<%U@o#7?i^GL zWIPUBj=sZxCNA0dHrAmq0SY!pSOIndNDE$*=s|_o@WG*3DcZ?8&v81Os_=52*ppAO z5YWH!)}T}-w6fBmCZXyr;+}hM@^Gcl`Pw*-%j2x$2=A`L4gXrl^ydT82s;t+0oRrN zBH7z_%NFf?44mUvwu~Aa1J+dMZe1-B2p2=la<6H&-$8; zQaZ%+7Ulx|KCw+#mY(RofB|fxA|hSYRcLL;dS0pPe)W18{{%iIw@^IUN#U-BP7ARY}($0Kppip@g(}d8kPO&c{;q#MNu8JuF9ZFpf zWr5STa+Y#`X%4&M&SBdrrwjk|dn`k6NAh$(w$qJDDAk5;O@l(^&q5b~$MCIxF|`2M z56i7In>Er%Pxn2DsWduAjRd8Qwe&07%E#ON<4FF4=dFKh-Ewx*u?^HdGI$c}M^{1h zD`i!*1y9k|R3y3usHfd6?@Hs=9nj<*#HatqXY>JvV(R1N0#ZNv6@e4%^8oJDJgddj zpL&o_eQJjr!PPgZvm6V=V(79?4CI(*m=6})%_yFVo)nmO_8;f4TzeWt7*uI9j0{OMmH*?yr1Yf?im+VYUal)d!D!&r~il8Na`y zni6K-s-#_${l}Mk)>ig{mW<4>0L+z)YQ5GyBEjU#6_SsqIyg0OKx8TeKs(aoX51y= zo?E|HmOKt$v5RkYG&@KpjK~(f10*Ht47oMqa#yC-rl&k|l@Xqfwp+!=-Cys+Ofb3=Ll=9QrF4nM1W@+>xSU#HI70P#*rN>#fm1{|?`u(s1M8$C4!j8Fj$g&Bh@ZvDe!))razVqq(euh|TNA zhAhVWkbYCKFgWkVGsPi@V}rP4c9DU@_>37aI0bV9DvipuI4uD~n_++M6q-g`;pf~aFpzdX6b(CAG z)egenkI6fX+CtH%izT9t&LyG;jtzV(L0;O5Pr4p6ZQ%4Wj*Z8P*y2RKiQRlT@W=Qq zc;H;%nyBP=I*IYo@>yP8ZpYC%Yd~LgY3R_$5Zxxrx11><4AryPAGp`SHUYS;h|M`P zWTPqbbYKFTf^OOPqkAc5SA0jg9B}pxm|nG)Fb#8B8x%QQ0X$tVxI*%YgvbuGgSCNG z7u^u2U7+`HOig#|es{03cPRE}u=G=3PF4J%NA5cr108;lld>6}kRh&4gIAL;IA0l@ zd#rbZF86nca~0j4u*;=F7p;35E8^kZYh#9Vg;eaT?L)!Lp0eicpVg<Qtl`=@geJ&gRk5F5IKfU$1O+RPdQK3jleVm6@uYC7C!c*`*eMEFTwdg=PtE^5h<4 z+2X)=v-^!Iz~s}b_O!>$lp49ES}B(#mwlg0;FghUm#*Lrew5L7I=QBPx05rXT-`Nx zQ^h(k$~zsNf_M6d5!P(5Zm^g9p9F~cq5INP6b`CLIq-5CyM)!e?7;VEvqn3*%$RKX zEuSq;$O8!SDfudEl1>nB10ZOO zS!Bl^LAj#iLG_F=FZ-&&e52EUr^O7jSGl`X8sBqdJzOr-v8lx#)uA)Jn0_id8<_yN zsXUr$US#>J+78VH0C(fX?lClXU*Sc#0C`N!#P`Lmd@8G0NCVLImi0H`xlCwqstK#`)L+`#{T|JY)N!&1EaZc$B8t^>|CPz zn*fOO3j7(+!%FBjh8SYvg^=5B2E{qN`wW@ngL&-JAhcmY(4_IzvRdJtAspV|#U9$i zA=%+gx7oSW$sauM*4!r4rg~>)cR~UPH3s^{jltubRuX;Y>Jl z+Q<)ksv`nwW)lAZQUbsC0VM`v1b)i&VGfCEV?J$c}s2FXvVdZ^O5R zJW(_Yx};+Q@j4XyfM|f?`J1^Z!e|&;rP!tz2!M2@KehI3d~N)cY(wWD=6%lctAl;} zf<8~4NGN$vm&n2REDX;*7;Tmj0x7Pj#a8R|9ukqQG0e#=O;)KGgk^oJJ6Z+xn$aDPmchjhBouYseGw zI^uMF>vfvz9eByqA-%9`1M+MRoyaOrI~Ys#nZ>6n!%1KD0*o0>?^5M`dG!-9zJE5J zoK;d)f*W>jo~Gw%`+?4(1A&+E`ttmi&kf9`2%^#1Lx0}?^~^`)xO)oonB}Lv; zhohiNalcgcjI~rXI4G|ud+o*T6NC-EG&rOkjJCp%D40q@U2C#-MVI(svZv{MA{aQYm zzg?8Y6e8@E0ID?t7?uUXM-4=M{Ly}JgN*h<=M%T%@Ms@uU0gZJN8;CaoNKuIS+i*a za0OXtQ*U>rDgZFoX>{<&ug@w-3%XAyu@0)orUF%76L%z(lM{%hWcCIVM|a&VKtLy# zh@*ywtB9vBT^<8K>;unBGgY&~i%uVFN3^$kIp_P>q~+&*%xmT+-EODZ1LuZ+NME+H ztd!vd_U>m?Vay^c%@1i$P#v;1Mn(k-VqPdL6@C)FAe zvLT13AL>?#RZG@>5LzU*eBpVFP=vv}6@`c#fBHT%fh^5YC}IJBsR3^}y?$kZA4tBK zGefu=z<9^zJ%^v(b^omBxl7TBv~7_pMl~0|oyGEy<=v^~jWhX@4WH(4R_;z9>BXF&_rDeRZ-`|ur2ICi=e9$8#gSLKc zvd&%)yjkn!b`CbFQqW`d$>owRQSCJls9b3;$1nR@lLh*Ebe@sG2+Uf zVHra7FTU0H-qXU|!%x=Lr4-jqzHW9*t7$Wpy3I~RJz6ylCQMtBIKGwL^n6@jYvIOE zas5vce<(7~$vfH?^ykbQ8y`>6TF5ExbS$UFX`c&B$TJocefrm)tw*nyR2eUfu zxkx6H>TOA`YyD-wtJ71V&v(jiW?|u#+YCo6O0?EP7TGrU!8CAC910)V#PLzM2g7;+ zlC9yhH@ld*KBm}~n}5};+R~13zPA*Ppp0o+ym5xDn6e(^8kHIX{Iz~LN)f@YKs`PW z;(_HdU*H)W-mwl`-@@wPz@L(Xfj}dM*07c1_jg8Ut5*)uCZt`5KcU>YQ>COaM{eG1 zf;s|OSh5{M=t9_kqg0OjBGS>3F2Wuyn)Y}5x-b}rs<9sCtBs=PCX=d@o|>?=UJrNG zL=|^cvR2(LWzU9Ro!@hqHJT9`*QAlKKPQ8x5v?n}4k^z*L(Gz8bWM2AT6L|Yh`TnS z@k8~6lhvx^K=3&^ss$Zx@m5*#;7QYI!F;hC&wi<L~ z<)0X8Q)^-V1XGG)IY|MD#>b7oIx%=mHDYqi(%6JvHbfgW1-&xP>KuXvEw!Le@5i9F z8P|}tB!y{*A6oPPA&=q6(1T^ki#AQI#weSFCW$GDA!1jetV@v*YPo8@U2ks>-0*Ml-m+9|K?(O4Py4v5UGmxN3Al? zwGJrZqDJ8&G~pr&;i8~lidwOy-mw(r!wK?+r)EiEBmATzq<|Imi#MzeL;y^5}NOq15_j za&MeYHZ<4Lc+FC;o?}sYX$j5iM=LPc`||ja^B3Ufc|`JH<~%iXnB=U2^ScGryy=2Y zLvfJLbEIyaPWD`2RleAta}%vN+*8yQ%cZGQfcO3~b<9btXMO>C<4F=2i4&WJe*$*r zJZ;yw=t6D6QY-)1GP6>!FaMx&#t}TVUvF<-@cM;MQ9bji{t5NAb*H+vW!Efjnfw9w zB>yI_njYadwQm8I?PL+jl^7wF;7#CN@j?3p^0@Y4#ad_2v1$7DkTR=0iSnp! zYMf^urRni%3U(wkc^{(}J z+ko<@P`s!brC6So8Zn|rypb{Sc>iwv7BcI3{`*87W&7svIQiJ*>^l*3V)3BunFK|H#)ReYw~T=`3^7xTcIVzjI5KcB=I?Kxi7>oarH*~HkYC+e zkQ^tN;WH0CY*e_o)}|@UT4m|vs3;s)Ttj9sbogKyv^LXiq=6ulyD*AMV(iPbqINhg zK_6HNZxmWku+pk#L$!`oX{0YJw=pOyshuVDG6y}3a8<3Ug<7q#lNJO~KU5u37JUez zzFIqS1`I*~xQ{*uTqnOUlIQJAF0NmbCdA=rz;*?s%}cCKSl8)`yqX)-G?eB{njI<$ z;2zr5bTsS zs4GcnLBMOX3XN-mQyWgNHgu0$+7%ms+w}{9uZxM#wRGFHyRQ4ITkWq>p^5pOPPL1e zS1a(-g=zPQY>n}HH&Z*r*7`SvHN2!@UV{AMT$1^f@`2-X;e`cTJbSb;tNFmj`J)}EaZt9bVPzFKRPj`5FXQFvw_Om}n zL_CS)J4yCp=K=e)4m;=UY=iG#uuIOlFj~g~7;V#mv=0CGhtFS#anE0RRH0$dAl%%_ zS24>|9G>Y+BRJAw?~KKAo$rkKF8(qv>bq8!+mA89JYjb!Q%a4hT9!Oo%q5*+Wwus4 z;nnXQ3Bw6u7yz|ADHGiHZS`t_t~fy+F{zDmuTkkyn&aYXR!0V{K76vt&{}Kc=vZP~ z3VI@&0?Gd zw_|^e!k<%j0#8-nA&j7f<*_%;J6o0&PL8W_O7LU2mc3&0CpkvxXBcMOjBXPjPoiFs z>}l>QmR2y>tC}kss%$HoE9!Z+UDzIx#{3r#_ba0|W}}wBm$aUJ?wjD6&3u6;uPz(f z2$WC&TuVb!ceP3B7e+M!%?v0oBo6;xU zA^+_WsdhoRhq5eSQct6s*n5)>^My60suvj!3W;G+Y1+s!Y0DB(30jcVMTl32E`|*g zykN5 z{nu?uB1zC?EW@(NcG!^S!HtsZI7I4^)Lv*AetE+KQ#OyQflHK0?Mn<9!>9(H=pnwW z+hiU7h(}y1!fO}U8@3sX0mt=dnJfj(4A0CnC9NH&;=>88SLhX={?79BSP>H7ztMWb9;gRnljYMO>q(1 z`nUD(b*$HfT=sMIzO0%hxay(6tlh7euG);c(ZQO6k8OFbXM1LnItCj{Q$oNlSNH8$&Ds}q#A3`Gq1{4Xz;+67HkKE_5oCnEC{A4m| zQyD*a$1ju@F37qeNK<^j>}0$o51ov?T+?MvwN$U*LbpX$CavnEBH>VF#m#c>1>EzAd09+P3ceS01qL5dTht!WaPF^7oCZnP8@DVI4pwRN z7`;Ru8d)@Jsp_~dv_*Sn-&0_4mLhYW5I^gaU~o65E6hiC`d1t@DOt2;thToZ@aTGw zWSzzD?NX0)D3mIbu2e^++t}1;WxIK=dp2<@WGiGbSVvh#S;%-$J66}t;V}z@MAOm| z(uyA`8T#FCJVnfji+@GQr7Ww<8%mgFVL5V1gh_}+>pGFLud0nc?&(p({@h@Xr$>+G zc9PYN)^pCZ=2|JSYI3ql7fw8C5=}}LO%nC>4h%H(!ir;TudSWgyHN`#q#-Hf__`#D zltlKGl*c}LZ?7q^yA@^ys4jKN9%`kloh(MCKfSJNnNpi1*SS$+hp{`v0wN7 ziO<*8@eGUPYCKWi;@aA>XcLE{ewm}Hy195gPZL(@Lg%0uxFcoob1!TcA6jaR4oU-w zrN#4NNbz{|Ay;a9IxgfI#%G1A`()Mn9Q#O8M(!Y?UY~S+{h6I(8>Yp0cg^Px$OM(0 z1JX*-Pxb8B`N8RVPRDLN1;HTgW<8U_**%LVteH> z17&lZv&OkBJ1$`fGev|Zkz|-U?oAcqlBJ|H?SyoN%sQsPVq%9UF0_LQiYPZ}jR8tk zdU;zS+#&OveMWLIZ43GfJrbn>i6)xG=ZhPruukXO2GJBuLNZ^6y^-M(yIMk7FAE+D zNZS4+)IZknD5IuL%x!W<$!WWJ4$aTHw$LyY=r|T_aqrmX{W5QcgvwqxU6AQbBMP)XY6> z)m+R)V1c5zf&#yI1#=T|!!}qK7;-x7*!rJ$hu{(>;(QIIRc*wpVq0H_ ziaA*#;1|pgk^GMntHs;xDLN+D*Vl$(+omD=*8;3|RR`cc62n0v>OU>Nt!x*F4Ua*? zse?7mIKut{b$aEu*p#%1T$sQaE?o0dhpF5_#RYxomRnf91uo`z!bBw@@oQK%2H<>TVO_euSEonI~@* zvIhz*Vl%ERPwvJjf{K!s!3_pFmYSTlE|3(nI7o)s3;DHHUKN*<%}Mh-MBqiUaXu_B zZWm|-gi>^WUCo26o$hdRdB_yQ0%jw%A>Y*9)&-ZI)qoeZzJ?7I4(*^(VxzNa_fp#g zn-)3TKwm%8%-Z=rLJr-0{GoMi8A01wL`M6Pz(h*VHET^pem7!g29!5Mk+xa1-5@W2 zBhU=q(>487&%(~NHAd4wQ?rG>jj|8ds)%K>xxHBgC-6QnNjC!w0TnA@O1Ndhr1h8grvTL7Jj4BSe*&S&i+Dbst7&&@B4pb?RkwMdQ znW=??vT4tr7yTm@RWw8%>zmLUR`d~ZooqIl$3mKc(RDcfd#GKCaPEA6;?@vD*E(ct zc^QN0XM;{!U~2%Z+hGkmZkPJ(@l(gAX8-$UO3_AG>$F>eGGXiFlaRh)2nD61nEBUQ zXQ}$g$ypViiu=qt2oAb5ZR@gUsyseAQo24(6C8Edq;r|-B&tg8`t4c&%}B0%QOiv& zO7+ATCBFB?_x?4klYgdyq;X=EhX-4zv7l;qV%=2VG_M8#HxT9!^+$p0uDN%{f=49X zCO58nc-&Xwfzlz zPdaJ%Y?J>`rH$r(*|c(QpdY)KBYkMwA5jm!G}UYlL$FcbrzG>AA|JVxjj%(h}L#5oea))oGemNh0)wmh2?W?mgq-gB()Jn z3~;6ntX7g5DT#<^H}mT;NiGetx}fylW9cF3ZT$M4x#&kmC|C^aj722sR#pvroK}#K z7{Y@aYrQHxxH3qN7&nZCNZhRkMg-tgmC((Y>c#Rm5zj9St2cIJg+>2_-Nr4EN{-y5 zjx6qvPnX-U$-ce8`7EVStB|f(^d_5*>(83m|oa(bj}6kF_KO6Xcf4o zYQ%F^YNsfmpc|+G`7*dTaf0^P_iy{_uQfk>VrlPOB>Rd^<5T zNyva>arh~ux_VwPbO8HcCb>Nix&!I(*ToTz)d}_kX=>O|>R_u#yJ+!N*7po);L3a{ zkJakxiW{DYT!g?Fc#wKd>l`t5(9}>^luD$Tl1#{wg)&hmy{|GS&cT78rz;e-T~Kd5|>vWY!)osYOjVXi?@|%f2gvnR@aYq(lU+O zDV-jirRh=?I4TkFMc_Px;P%QTRUTT~gLJe3HTz{@!k&ju-YuHRJ(>q6A9kYS6^aT9 z!EfekYI)7H25Otv{Dx)I^+4Rxxo8pQ;kQIY?uTa&eF*V9q&%COG;~FOnmeY$pxuq4 zQ$|Pe=CgyInh{DOv3}<)TK$~v;$22vt%P4|6*ao}VQ;Po-E{u=jH#-P)4-?JQJ&7) z;o{LO+a|uTT9Bv3NVU8OtujMuYhzisq^^0=NP<35VVEeW8=%GAq;#nVQQFn-Ja3Kl zc>6=|tKtCL7Tu!1D)yqJfMoAuWSpAjr120PZQ|!&a~~!GKvjCwI+e_!Tw z8aiP-FB(MztS))(#aN8}-1K|z;YsQ$k#(#N%K`{X_Vx)r%&31DFj~_N+aFdMaGL}P z8~h1$PxA0uYF5}YqG$?eaY(G9eCVXAEDMLPW$V*iX1^wUK|jwxZd%0Y?QXUtPzoT% z=}yJ`I~Zd@m~J?h77yjVz(oXzdu7gqK=g#l@VV) zN*f>DxS3twk_E!Gq~Bm_G-_mYbn-S}5X-6%3;vH&5_=JahNb`S&M{xBY3##U%~txq z2L%t619T==24?&GKJkT6E=gZSB9u(O&QnG7CL7L$Xx4CWv*jEp!;J=#S1Z(2{+zJy zTvD%*$!4%^sAn;oJ>sWgPh#joUj0Nz+<dD|b1<(xjxC{n)E~~p2W-$USvhfhzyfY+Srk8tK= zixv-ofe^Z`x*rw>y1zNznLb(>OUVJA`B(jL<;`3pmQ*TCyew^B7rc@9HHTzo!{Yk93+lbn;x`tV>qswyb;HNsmQilVcq_@<0(jh4jcC7(r5jVr;Y8SfO=9B6$5t6) zW+FZPon-R2VtBxg9V=VWWr-T8h#c9R&ge@hR-J7-*;`wdv5`ODVJoMnpqV9Sp3yrD z#NY^^f3$NMz=_(6y87u6YEWsAzn3HEWXYh^vP8x-fFCs%&{V=UnGR76A>!a8{zC)n8ni;cOx^nt4ua z@?-(=j=fg~P)`y!<)D8%wdy@qXBc0iDH`UW3d_P$bspE4zsxB20^N?TE+vy^K@&V#IR*oJE9IomCfg?Z zRMl1E8%}l5hEC|G*x+GQwy0|5r&U{OcEoX>6=^@`tkyYV-W-L=J97WLl^J} zWS)5w==k_12`v@J3BxYwWP~%;m1bJP;-LK>MqXLePCYD8s|Qq=-N<1I3W@t7)FTo%lwji9e(rT~^$yFm zA={pk&;3*p@?)o#em-}Dw@?uz4D&JMzcLM1b7Xt5+3vq+S+DZ$$^e~6tDGEZ)?eDHtI24?M^lxS4B(XYREI1Mm7--rR@w7N%p9oBFJhBJ@EMC zYP00~;p}&=qYFcoR9k|+5cZZEH^l(SZ25W0J>^%-SFfXbM;yZMh2VwsB8m8C=2;If z@8ypo(L#t;sELk4=0Va&?4I!cX7TrPTT?OES@;`V-E0ctL1dgm$XfJ3+kE0tHCvk0 z5F9~-Z@*OBCS}SpA&IjAEhCGGm!CjU-fN`A*F zZdHxzC+5xGsQh}A4~v(33H^LP$RZBjENLxJQp$s7diF3h45OP>RGv8z<0jtPpnlUu zfLa5qTbYbojcs{ATE%Og7ANv{uWU#ey6w_q%5UC8@w_Bf zmi2Is9c?8@jLaYy8YJ5OJ5949ZpT-8K5QlmXmG918mchC4_lkKdWd(|8?-%)!s7(B zn`Q9~&tlYi)Cs7+JR~%|8tp|12c)gEW?d4iJDfZm9JNd%6DC8=N2%ej&j87|O*x0a z-BRHK8#ectvSEpl%^F01%Rnj?G?9q0R{4{i$Vs`Ua6CHWyrZ!(77vQ zRLwEzGA_Zv(|@r?L|VKEj2zeu+@6y{lZexa&nSF{{=^}>xCFG5nkfZQO>u{~2=x9< z2epygU6OSBH5-p(&IM)8MX_osJ|$L{l8O!^&Nyg$1M^6k{Nlyt!;n)f^c>uT1?3(S zlKkuhlkg7IlzcxfZoRLbvnDv3yE@0I)c!IKwX@!s%>yUSw&C*HA2@_85S|U2#qP`{ z&fN9W*E@~fs6*-NjVB$@&_F~$oIn2({SOuUf57zpvqitF_b;8ke_5;l+1GW3dCI1z#qyH}o*uRTgj7;Cb@~?m`t+-a}fZvEg?!19x z1!{Wm=|TcYdD4Qhf-Cz#YVK-;Uw|;9q)NfE`gOl~t=-G>|zO{}Y{b@laHuP+CdIzisP8@wSW7>X! zzgu9sUf8mBUmPAjQAGa2U`Sb5=SD|naeS>ub~93QHn0o^8*%riWk)6d5 z`~5b_cf1a!MifBqNMuLI3}W&X7~Xlh{w2Mo4%sR0nu`*iMI3=L#$7%eY9tdkA8N!O zHxqimEv`bAgey@v8(Jq+TIQHnCe}6=DiIeD85*{#x|~u{(uv9;uO4TYS>i+N@mqeT zoi@~K{mYpC z7g`%VLT>A8WqeXGN~VslG?+9W1_Iu8YN80a%5Y3NqJoA zmG{-16eQ4q=hnyO)zh2T$hG(6#lyP&RO?ixFD8<@DcZ<>O07q!#mU>&R(Oni$hd1g zMwa(X_ZzKk_lM}OO8vmg7;xYc#<~5Yu(~j4{yAw z(2ejMt$K=EaZ_lCE%&Y#491iOxwO@YZ&xO{(_|owvD6$qVD0eYPeR2S~2)0S$Ii~)KkED zR@=NNnK;#49f&!uH;z1&SVbg1#UEMRNM)1|Audj;%&$JZ+PO?kNaIL-1W z^-CO>hvj{il&8`bTiL;{vSnEFZ8_DCEwivw-Xpp(#u!gaaP-pZy%oSdSUsFg7oz%q zK8Q*#%?jQ_xFzw3nmJnLdC1rNVhX}c9T9CTIl*p=@`{di2hToA$uz1#B7Z?RM|79X zqVo=j!!Lw?P5K>SQ2hA;sjrQw8xdH6smGL8Rv)5yx*6p##p>VxO8>0>Of~J7|c!2r-_eGvf z$|yB;+yFfWl^)2QW4=hh(5t_->3_>rIJ6?Az~C+-8R9v?{KYapnJ1&0jF_s|JtOop)syR*IHooG6l{ zU%YtclDztzT3E+JZia~y8dp@ea&FfYwb6rT7+sTj4)*PjC3p@1lH&@}3)Tv`XT8NC z3RL$U*j1}yuab3C7!sTl@TKQC=KS6Lbpn400OZ6?wT`o<+jHURVa&Flq07LXC;Bu1 zL5nlE4s?U>wyUx>K3DMJQ}VCa_SZyn-O?kbvFWaAEMtOKlX{Wo`b|k2gLwK=^-s(4 zPMW_c6zulmso-KnBoqtE3+M{=>XaXc6K_dwwQenL5k{dKF|#XA;U6q6N+`zOZ*ST; z5x^+eSY1r6FXbp)JKqgm2fK~;)3zF#{ zA&#{;$XCaBv-L@%ZwYJ-B>5=&kcu#Rai&Y@X3+4~&l#-ntJJm^Wc|dXFm&m0fM6gLN z{!TLD6cDrU;pJ(Tcfgj`17CQ^aZslgSc%=R8yiq&PQ;zyj}pH^?|Jk6f2^HlPaVwD z#*rH+#ogVZKyg2~TXA>y;_gt~tvCmFcXx+#aCdii`!~;Lc#?Us*<|;{W-~k4nfYCM zQ7lzS$aPh-ce7HzZ`bbQ8^buk)EPst`L1kMa34ZF<{hRuYw+DV(luZlmwhptl>TY@ zG7;ItRGVNH(T?R-FoN2>G3FQ(5oDqW#qOVrG1Y852oKPtIkamyEqc=1ngG8nc=`e7z_#S&Z5o2)DGXQX?1 zsv(>*AlCJn3CV&>S?4$P#XxuBV7(?wYniBCb+t-MX8}w(*Ua4~{(E zH2dd(#uHNC|HjbJFUCzoHId96V0}lHSgmn|kZk!L_p??1WYIM67hkCh+IO z>fT;!*#>2A#(7RxET8z6$3EqvL}P3V$|U?`Kee@vYk0l$d-8pj!DPV`ut+~H43yVv zN^404L1}ATG;5hDCyo}aS-!J#$|{LT=oq_u#wPhhkF+|bAq&QwR^{Zf(YMwDu8h^{ z4zd-y4~Qf=ppP7@Z+{mV^NJQi^V*Z<8r!wSSeM4=KBRa$BxQPXX17ujd2~gsEd6pS z7Wb?-4E7wG8pihUce>k#=k~2HP%pi9^l8>PTiICS`_wYoONJN5wRM}STqlkytL(~z z9oHx-7jjOu7T@_-?PCJipsE+eK>Zg#>ayU&k~R4}I>gKg@E0<6%gXHJALp;J8^^Vp z=FFQpqirgyq^CwL$3Zq`3vB#zI%6se)=v?Xs*L4U3*|cU`S?q^n*{AMO#%*EtC_1r z>|H}RJacT$tI5Oap4u2S6suugHrg1>0vRs-QT-<61WPV)@+nJ;)KjjGSF24nx>cFO z9By$_+n{3V?U0v37LVLuJc>1oTTnjnQ=7Q@#&TyPgFQTo4 zrCx2UUr_$%!=zgho-Uop--_ym8CG3?PAxW8KcnJD@DhI-DNQ}zlr7OY--_Tq<(KqS zlrBR-U!(>;hvV&P(_+%@DQVzhb=6(#>0)zb_9C%1$HtzM$Kqv>LQ(1}`wiW@Lzzf;21!~(8CmKK!#lRG~p*jA|oCV?9JSXeK06Cg{C zdt86+rl6k<#LY5_*(QaY6vKTcZUbNn^n_QEH2eh&f{wdjO;h<7O3g{J`=i*Q1CcM}9V6>Oynk!0v-arvIvX0S(Dw0$D?hRE1AgUWRg9w`GDf0kp@LD_F4@RgAN zY6&A!lQEy}6k-1tO#+GwVf=S@g9B)K@VF(^cG8^q z>VK^Ws7D+da=r;nM4zyQXCS(FeKUByfaiqYI5(^_akyYwQrI25(l7ZpjvH*;y@9h*jtjmvM%@7T;PU27A{jrqh5dDA-SbLITb9NLQUjvbqUfg}WP`6l& z14iKY!J+(3ORxwj{>_aOr@&-R(VH+x?Nzz(m}@rNPmytonxH%PaAaf+Oe=LC-gsR!fX@iOao@5#?Hh@$SFM@DG=-8J7pGVnh$YC&6g z-$=Ju6_OI=OSt_1TC06gR$ZcpNvBITq+z~YF+V`ZO%+3(kl`1aCBS@SMmKWwqW5`c z;h4{gO-g>7FZPk53!nI}^Y4J&FgMThaxdrz=L5kv)XgW5eJ=n$tK~ocDN4B0Ba`VP zK!*JHATH5d@@l-lk$y;!u%vzfk5=h@VZUU)!R>)=Jhx=|xdojzclj}jvwC2*9EvnN1z)n<3(8K(GJ4lYUy(OYCAzXe z+$m2=)p>2kQ^n4H2r6~d50Bn28Q`r+oUdWHCQj$>{TZtOV9SmgV_QwfkH+rYm&f z61Q7HDQ!%%L8aAapEY(uis`5|8lmJ$y5rUX*Z~e}2_@W&>wIl@g94DE+%O>WK=BZ^ zON!t!K_q*jdBbKdNsbtyflrv?LS|r3A9;_+^-SB0kE8FucT% z@!O-BjTVb=(lfje{^=j|gcUTqug0T!S6 z9-i2p<32|atVKAEJw8uQN)jgY$XvkANMypEz#mj2dFD#t69QIz1`Iv?*RB6Ysc>z#$1bHU8;ptI(g6Hzpb)&j1=V7V$b>+oj!rgUgX+gs3;XgJ zbkj(2c_r0==kpus_A&6yL6z~UQ212s+9FUR7ft~29pQ!inEK_(CFwBF#?v?7Cw4+) zObDGh?&u78bMdFb+My(wfx^;e2FAs?^`6x#&1#^NI3UN|@c8HO32A)M+&1@#`RaGu z#7*H%Ul*zlwnl36 zKvAy@d>--lfnJqf;BQ^`YcBs0;Ks&>HA{-4lqYb5u%xgj?v)`;Xc#-x&3SZ! zj0A%5``IF*=NF)#hRgt^CqvYo4xu!TKWCq<>EtM&C*OYW_>0Q-y=a>ke=GM(<={hE ziYx5VBo<-l*&!dQPc%24I$Z>AImv~X5B*iRJB%H9Ly^vy|7xJybP}V#24_d$5T%nf zAkGu?yEV)yZytIRu)w1Of?hd9T9sK{KkFEke692Sr~8$ z@g2>L#*)Jl{hEHadjJ5HBEYR94eUVdLU-(|lX_yv(_^Oj3*inJ|0482ZH3$+fog!n z>79#Vuf@HAd+6+o60QmRf&(A)%6=n=W7p{Y!2JnhfBrS{1+xx^d3x{>?ji{2dq|jD z27YP1Vmyv87a8$U$a$}#eqm?(o3G9-egl1_TP~+^BVp|sF3ab-H2C^04#TTl#})DA z$$IChw6_sYxoTAlI)AXpg>JaTabtwDO!xIC=b~XbZKR*oeXbA;DjtZ1ZWGwaC7>GVDuN;E8z>G_d*NmxGCV4`~RIL~BZQd(MKnJ0xf!x@x zN%YOR{`v<@Jnz$-NB@PdtILG17y;MHz%~I?&q=RHv;G1PhoLr z4&;y@b~|R{m`~PgroZISwMj05BVX#oAT==@K8QHX^^Hg)IB2QgA?U}U6#)`^c0{iC zE#nd>)GwR`!_FYAjawqL7nKxt8CiFpW2sg^>FI4YNo;*OCGJnRu-4XlGSjmPrrV~m z{Z*es*w*wvDw;aEUp3^DM6fp52#y=y-ks%A6ua84El(!3@m5xT@{HCv+^(E`5O+m+ zA+Oa*#2w9^o(#Dl0jr+m+&@>TGH^6*fr`KJ1?r!+RVL-x$b00ryl zagBVIZhux~LUhlq$yt`pOkvy_nKPu?xV^iuy5}#r?GMC7{7%e{z zT=r{(wXsDs0^OGoW4gdM!0{_^I0GBF5nAewxj5u7R?!vW`Xcc9P8cuecxzyky zxbzZ!|Dds!26fs>T@iPOP9X5NLWLL9j#`P;h+@%OncKT+YYPqP&-cP&?^@bFnP{rdR~lAYbk=uMutMYlMtsL$Cw-yOAHDH%dmr zJ`pE5-)rzr=mV{ZcGn3w?MlCu&YphdlryeL55ZatW?$ z6=;qz)>EOVrIKnnO=>0T6pEDEeS1X;tnqwFxQGL0c8yq9g5j z2Ux+nz;)yNR|d(NmJC;>*dkz@z8)m-27R8bLUxrC`fe@WDW?t`@s%BV_oY0ahAqN6 z5iEg>53QpQJZd&^(D{z{z2_KXi)De0Mmu2ahjvou5MpO^<_#X>tz%A35GVd7>VhkN z?XIKuw&j{!(#Kg0(?d(tca{$1Cy;zTVMN}+1wOt4GSs>4rxv}CIc`puK2 zbU{hMyx?+&*`Gz~>$&hf9YkYWf>s6vUtx4?wjG(|KQ%NkLg|*c+NYrbB41ClTJPET z{xw(tlw)3;Z)ts7f=ocPzrk1DryNEC4f_2vYvjMOL~Zjvc&i2 z8s6H2|F~8yZ#mIBZooQj0fMY+lv57j?0}xT8+&Z*iklJz@@WMIqI8L87TQUr4p3VK z3mdp4Ju0bWB&~9-QvS@?<* zubm3s+r02|TJ9WvGqattPFuIip*jT~O&nL3+`8xM_6UaNfX`Gszd%y{J9zj81Mdn8 zid}nObk@gpS7HBfYp;~6AAa9weQm*Uh_9g@E&t+enhQ_=gObaJcTA+3hU$mKz0C>5 zjo=q}-eZ?1Qw3T7ot12stvVyGj5oN~^mTarxedQl=}`TyQ1tdonj1b7GgEYTXFpi$ zXXK@q_=telE=Y=X@Red9Eb`G$UpLl4qTt*>EB0B)!;ccu9MNSMDBzMyZz|?DqQii0 z1;W!u6;u%L_=#9CFd|{xs2j=^vN+B)oDWG5`a-r)um$0!|MMB|FS-(wp}qqt5aEV! z#}OsY#6uU{ay8Ty{W~+}b>QGr@#w~%m-(yA?@M>B1G@8___|TJjS-^1^lg zgY+7%^(A|ParZq?43O>K4af>evEeJy?lEg54zz=-`bgh>Cc;qi5$`b{1Qhrs|5(dzBU&maXyMXE%x$ z1!)hYkOAtI<99l(m;XKo;_o)D)-mBTy-acGdo1XqIvQTJ@kAcp^QH~~5WR{< zkJN1YVU31udchsL_MSo9+woxBkObed-}I_U-658VNFG^=E}McM{`e7_2yy(*0ggCu z-9HxnQ6OPBcOY^nXy;$Lt3f@<5~=CgC>=rZVmj^+A}Y)0k4nfXK`6mP)|f^2KEMEI0jX8XyiV@r4UDFVwc&4aiI&thwBz+!uqLDjHLVts07dC%Y;P{z-yA`by^36?@TFHdrl%!Pr;`+1{RP1BheXi^g8oaIpz z35)wwQVs^$2*Du`lPE-tHVkX_*gX4kPHX%je)dMTLXzKqxP8LB{dsD#e_&;(7*fqX z9G5$>v2?L9rx2U-PwBp8%kII4>p|rza@vJ?Pwt6b;pQvzO2un)jeAZYmhDB+^ULXv zyV-amSW@KDo~&c|YL7YavWe0~s+-3}mkG%i3J@6({Ta4RmH(sgY~V`H1|;&i7kGYZy0a>Tz`~<}-IlJId?SqEF z*oBH|m-7cHKGlBaqlZR>1NEmw!byc#e+c_CP+Q??;i&I8(Ai1P>uFe!y$6m6@?+l5 z$tAL+!=G@EqoQhrKZ*XboyaVI=>)a}9<|Sa2JYo}feB%IM6o$HdRGo^QEy%AZVbCm zULCg8*Ima*{oS~8Q`l&{-HwX@iAk08RtkpAv!_P*=MKX2?BM=K{^1kP?FW08^4MRx z9&wx;#s=P^oisaMp)33U^Ik9R0&M%kXC8Mns={r7UGpljJa3t$(UZKbw_)$0-4dxvj{l#?`=~ z#6WK1l4>DhzpqykutqEeNvRX`u6^*A+VX%#u)`lCIsV^I(9HM2f>E;zVIlUsgl1BD zo=Uk+HLVtQ0*qklnH+l|Z?Vk62w*|)(N1#~)Mo7E_QkQ%qx7~N{8JCypr#AlFwC!C zUo^cILM5Bj*H=|EaZAz%*Uf)!3R&EY3=s!VO;#{)*Dkq>{9&J4-NTOEasP%f86rMs zg|{OSZ{INqLZ$bujnDa1wj?}7JxT7f92$Hk!$x*W4IH6=O3g6M7a+ss8egi33?!&el9g^VBKhuhjvRe(cIgv?MpP;SK6Hc~Y1xQ62}&k~`8L68g@Xw^ z>wX9P#}1s@VU{dPDHH_Zi;zt>V)Q2n%MO9QR_L*JyMEhxto z;r`71P9i^y+**iBp=bS7j0n>mLlaL?Z?#pwYn5XxzJmU(E ze52W#&e(Z(#@ww>fy{!0URrc0T|j=+Rfkpap;HZ2+uHzYWvjt@5{Hni5q&gXwoCuQ&-M0c$mf&a}$j@#IraA_i*=kKpd%mv#_$Nd>wW(Y@eYW_V`Q zwQQO2Cvmesof$n6uqEaSg31_lN56z1FkQCai|q;Rw*D{77ulNY(a7w3!mE%&s6+!w zQXr#h`Q;g3Yax9BL~vr`2RT((e$l*V(uw0s1`EHrArRPuyJ3;SKsfifQ&8xLVhtw1 zr9!B7yi4n5$d6Uo2Z$|MMr|NB!h^LuyIw~!Y=!sEmT*g%^lyrF7slP;S(gV1{Adn= z<$JCWe=(#}lDb^CKcD%;c@>R>lOrU@-!H`XKalkDsS;qlvR~=nTV|$K{mvcy^CcTc zwk7{c2}Us~G5`7EJyur)u50h>;CjJ%T4ekI%m2${Ak0c}vfR`A;&>rBfBp2PxzDJN zW^K~R^Ug&9^kfz@pa_BVA+(TM5Uc*XRGu^_yVc164H(5O8QDvvi{sEO1?t1$=_n+L zb-y%Xekxl@90R~;P8clUnOX7VK>i{bOh#pWG2TKY`$FZ)DrGaQFZ*xuNoS%(d=8nGGg3F&f7-!o6g8jJ~$*9jQ#4%-0JmEPM>cAI5xqeKDo}UUHEPdIQKJb zxsazU+I|^#kx7qCH-5gHMGXyfE6+LZuusrTy(X;~0|8klaLX~*)mMMMbUe9EkNnq% zu`L30=rpok1d4LstaM1>AnczqSRPL?*!zo`MCFqiBUUg1SDSKi*n*-C??W0T%CW!6#7KmGU!N386--LPM!J!PC8<3be4!i}EE_H}TSUnh#)}6~~IEOY8-jR(332 zYyT%f_j)Du9^(&}{Z$QlT8-VKnE$0drWc+IMD4(IDRykh3x>W~FLr>bM$SFC{&!C@ z(fKc&?B`^)*pmb#*#;WVCU<3yZxX)Wj+`V z=D_S6DV1J9WY>){Ogk;o%lnjwC;W{q*RxOWQHD5#p0htlcSMh~nTDcvf$QxV652S% zf+RB!_Pk16u+1~e;J4K^DQB(YjqA3slOM;z0DNe@Vq7<07MEgUGoBakZU*%XI?05< zYj5mqY7wTxQCT`1n~G%7mGGAh+QU|nELmN$&9Jzk)rWMmo9;4&O-R3I#>EG;`<)uq zkY>{ecZQ-M4N1B^FekLc7y6LV-SEvc zgIH3{z;@IT?xHvqEm1F{J6pkAO%WY(CJRNi!Uh3yzDlFunO)*JxYsV6PX#b5w%5!M z5ZP5gKH&=HYn|{F*+fRf;>ewE!!+fRBC}Cs^1^aC)^(hc6ysyB7eAN~>#B_VIV;Mu zMlAP5OB8w7Rxls(0QnGIkwweCb z0n=2r#aQu~Pb<*p!gWK0(w*B*7A6t zn)PhIrP5?qh)M>9qQ9&61kXjJBj}rUGDN`2@$zPp)yO=5(6xq=Z1wUbjer2dtc&uWvNes!E1ioQm&_!|x;qbZxQQNB2 z8&&P^u)g7sp6L7_hoZ9@QlzVI46GlEfWVfL!eYTJEoUW!hCPXGUVq;mNO?b^em)bF zCJR-H&8c84$$LKQx@O~%avSz2_34~K3tQcv=Jd9$>zRf8_g>ARH;u1Zk&p_z`HM0@ z!jHAU+`ipJ?%UZdmKwv&`opB(VpTzzu7=QH_zCvT`7dB+_C|ei8^&S3Aj3tzp2c!X zDm#jrW%;09cq;kD@b4#Y!CgSVLeb(X`ssgCtcdZESU2!RY5=?865fS9VIIWq2X2d& zi?VOcUu0yk#y;`GXU|@2NNHMHXXyp$4VV&tBmnb*^=Ux}n0$KP`(fOI;|7gdB@^gpto&tiP;9KakEOjchtxZ(S(WW2xz<>IC^RO_eC(d286f15 z&OhmRVnySZ_z3CC-{k4+S3uoN`+DzRiPbxJ(v@C8{zjy+YcAdOO~HPFoF=;!{JHyu z+C*e?hfH5AQ{#i7+Lie$Q}z?08s%9er6=S}R&FlsZw509he1A;L6DX7rH~xlEarHa zCGef83i>ikM>v523b#+MKOtSEQ?^^An~-8>Ik?W`TUY%Q`jC#BCn>c$Wk(kCb!5qY zOYKfqDC@`VnvXcsGR2pSiQlL;f1zhVuNeB)2tZY*Gq*1M674TeEi(fZI_>Daue6<8cl)1l z5bb;cA_38DL_!A8s2om$1W@L=ke%AmFL6`>%TEP#XVb=jD3= z+cv#oaQi;04iaqWJO@jc`& zeEnh`LDVg&Vv~lWr_f?2g6)PfC3yw{Ncg*Ee#GtehJ0D+oFU!?g_`U ziFVSu6>Nd_1WhdU)I)Ad_U~k+Un>Ns^pa0N$%N_EauKX6OX=q+lN9O7HizAERt5)# zCw4RAE&oiMVM}7VMSR1dK(`eFMf)vP>Ir+ci)ywj)MeeZy%w7v=X)9n2zKXoTWe5n zRtFL!Qb)A)@ zu?lLWD#28&+Ase6=rt0;{?mg|y4?*1Sc&HSDcL~9El%pA3S*e4jk+zi&9e&-Gr8$B zX#IXuiCS$(9@90k6?ufVqaA)!TIwNEIP$Bx+lh$E~f_v^fq+ocEc~pfARS(?jMN#qKCg( zQlMGp(=|lyKYzxY+{h!C&r-QHn)K!)HaisaRpQac3nP+v0yMl&%$5t$mJ0{_H4OVT z?3N487Q4tb&S^V>i$n2)c!XC^UjO>LLAI&f<9Z_Zl}+areW#Vr$f3gW`lg#2M>zv1^b)ef0rrlP^!;{fUK~T~N z^BO^gu%{!zh5w!61P{WVIykFqQ}V4LhYrz+*Ik$^P(Zg;pb-HvoJpVfQ90su4s9*^ zgsS28M|#g);{Roc-vWFH{%(-$6DZ`Eeig2uM;iH~Om?FTHGpWta3%nMjGD0;1%4R> z&MO`_HH?&HnUQfrOvTZ7|A>zouA2&6CybYbZc8VPJKq1dEyg}q;0g@s6O8#5tdoP` zqf&fKU>1U>CxM~jjnm@5@S%%z9sp}53hJRVBsB0@b-h$8TvrdbMbD) z4ffK!fli~*McdGgDZd1tC{UaszoggtfGQWO^hi{B1fi_4PP>4DqcY>nw=&WWr|22F zO7Zt#d08PX0d}ERvw6N!~Ba zv48ueLD$c{h<~^o9X(uty|QzS@EkTy_@fKM#&_-|xls;@UAy_#F5Xp`l%G|ynGdnK zb04aIHy@olHZMFm+Di^-TPV8QXEMq>cj2r+O;7P$po?D0H%Rg=9ld6`d#-sB*o*IS zbRuKA*j;`21&2B@RZPaO1zs>$`35Hb7Vjum`NH~d z`#rZ|zlA}Grprv>g5nPCp6qQai$%vI9W_NPn;1Ot0%~Q72c^{d}v-~b*>0GfOW32 zUMe;$?jf_85>1Z>g7V$6?Z4Xdn$6SLKiew z27dp@B2D)qJBa-5ynrBHPnl!eu@sf~Z*AhmkUr(|B_sCCo`TrX@l4NLf&WOs8Xg~- z!Rdldrl`JBu*SGB{?^w(kCxh3j9jJN^6g8^JI#R(e^Wz1>LNiJNZMMDW8+{I;NNzm zbGMm#!glzZ*G~P+2~?S}_>zOa^k@`Q5@EkTGr-TWR#xX`y!R;aRhiNI^Q%@H)RF_{ttybr_1Y>l&lwl5s4~?}b=ngZ6(G?H^rgGyhD_Sq^mUNH5PQ zFF9_MkE}IrYAiHoSEJ&_PK_#Jqog<)pWpaiH-))lV;ys^+O!HmoMMn}Fji1o=&6eN z4WdaUI5@UoS>-Mk!!iR--;h(Wl&+ z8Yx&9l4%n0jbk@$wjRSDkeid5`dm)Xvb3~BJyj(gO1?Gh>R>R3e*1F&-4`H|ecbfx z5hJ9Y1W1+Ksq|&^!S!$p03P%}5u#~-0xX|vASCk+o)Vr?dX)VNbvHG>WIoUe1@6az z6k+?mFE#rlV`*^sjN57)ERENL7U>RSti2e-(@~_lx%O#UHly z(vzE^CuE2gGE%Z$P_S;vm=d8BFNG}I%bRUiDxry^oe|ZXZnW#o z6pX2-5EJ!NWdD&^O8#ebtGvLgJ~l(AI z6FXB(8Zgo#$`=;vNJyZ)#gk0G?M66KV4x)7BH@Bf{6ikN$K<)?*drsDD7zxLOCw~E z;$Cq_o0w=-E~v&jGWd`-S$6Ufp@pTRYRt}(gq?y)CEnB^`!VL|NR8cPF1-5@p=>Nu z?iwR&B;z!`2AAkl+S=A_61}%}_^L2}d8~=4r#_r-GCt1zip7!}=V|I-^#w^a1b;(& zNU7-D!{c~_SV539sE!4av8ETaQH{K(*AXbMe9v;0y#pasn^)jR!E)s+f!M;n`VG{6 zLwiT2{31uXm-J_5NfI{#fhSlf$g9RnpWW1t;tZ)2_!=~*KQ7IqC+iMPvWZk@94mvx zqlVc>Qju|gtqQK4IcBoQbyQHTo)@K>>D+yz5!0D0KBhZR zW2@2gnjqT@GHw>qCQC7iRen#H?GU4*msR&LGa-~DB2hB(g)1MUor+g?xlEikMnJyS zO%f$(kks;zBz@Xr7m12r)2bBgH>0bUO5GoY;ksTQVTrb+cZz~Ni7`>-vh%XLXtb*A zA#G}!8@eL;vzbKy)0-9Px&*@nE0K^!nsqE%8ts;Iv(!#G=hl>w1RB88c?`r7T`Gm? zW*`Iskq?cO#cRE=)+(mojM~~$?*>P~N}gf7Vd$eH60b>&Wf>|H_4o4ZR7JxbyA6r2 z+H&S@bv#|!TF@-koKl(QQUBoIRi8g@Exg{6wlo4H#~}FsAf8>7z^)ET(hCk>y0uer zDdM?C#jL#7-F(=Md2YRDyT9vf?Y_nyo=W)VujQt1Y)v6J-ifSt#>3b*hkuQ0VxWJQ z^o9Fk86E_8b5bho_e}k{4;ft@Jni&m6J227i>KDvDXlKpBOEiyj5|h?0rkS9y zLQ7bbk}c#>p4r9NMWlNWo|^#&#=g6DGhtl&YMIUg;+k|O<^LSfx8-UmsQgTwX zbi~|-d7TB5UHgmDb5{hZX*&$eo@OVvAL0vrX;>9pp7G2)3{=yA(mZY+jU-~vvWNbr zJ#)^bAFJ2fTW)q9*IY|iJfr5wZFRW}V+~z*7263X7FcbtjC-B+uux{O<{Syteu??Z zSDJL`D+7ERD)I<&=oO6-s2FcK{K>t<)O>HTyJ(4|(x0>)>8cHM=z$8?l?4E}YJus%R>Y@*|FqF>xGky&f}; z$2QVF5?0bI>c%eq%p}3*KTa+~+Py4}0w$d$iU;qVQ=-F-zEqFiTOT46=Qs9=Av1FnXE5@VGQZ|m^8!6aW zF!Gsv$Iv0`TutZeHJ;4UBe(sSx^Oz&Q=*R=4B|gjq*?&Voc8_gS)Nx{)|1Lq$`NB<-FUN8^K{6tO5!Jp{G zMgEaM5ZeR7UiV(`Bmhn0|Ng!4qN6P_{T(n|&r~_-YC&B~RB5=ePQbPL*wn($ySqx@ z2ID^XZ2iJ*9s-D8GA8tO>AhlK!MJetVenZRHpu+#eoh466XQu~eG zj@%O({$+uhjHYB|#AsTKcw%-d<6n%)TEN$Q{AsLfvMXF9cy%vXM#mXxlV(if&Qh%H z-oQs2RCIn`fWj8ihcV+1?2heLHekZdzliw3LbbIS_OP=HRCLmBVR@g>v%)8w7$MYC>A$7T4= z%HNI!{zLnj#TH2Z4i{7Zu$#uj7|!P;dfUnnmUPT9)4FnV z9ZEX$Oh)qjZ223$@FAn`^YHloP={gJ&a+%m!s$-?f_QS(h6Vai_iU9iSi(e)vt!~q_Tg0qe zeJB#)ADUDJa)~_D_=n7pW?>LHT}fc8RKn2G{LCcV%Ui1_&|beZ6X*0WwEaWs@Nq=! z*veOa_>b%iON0+EdS7m1X*#35{vhiv#b^PGKj_;^ZVZQgMAFK6$N_v}lfXT*KR$m(>_njlnxp2jg>oTO%n&kD*7CgIFvtP1W`i9Or%A;D_Cnt0YrbVEPqc z-2S=I`BVFA)v(rou`^6_eI4I~gRs}Sb~gL-TRmk(qWSP_b92MnyPL1D4&E3x23zK{ zA3EM%;-d_@G_rJJ?;#%}c7sTQcE^3214Z}Bkl)nPR9wc(-y23VT27>F zN2+NP^dpvtyT9{8t&%1#ZrT*f43+EUh`I&o{B?NIQzlVCB!c`#wM%?@)9|T9bSl2S z)U{#$nxKoQonz?^UTB{L_!zfJLCIKE;{u93V;hPi4-F4_EnCCg!riEpiXxjtuGP!w zb>p?f75hy*oHo6ravBkphS8hHb-&B`(Mrn5bA$ef-TfX65XS&i{6&U*slHxx?kV$w z63jzfGL0Cg=~TEbx+h1ORsyGvqp~@*_-a!9Ya1PaW7ff4%EE$5Skszi=m%R81JO7p3c^P-p@u*Q@GPJ_gy@u|hu|-r_zK4jS9>r(xdFD1DNOaq(-|kp4;BUQs+{${p zi2`-DAFotS3b#>IfHE_$8i(2mY|L{HzK5}R~24+lL@_fBQD^^;!P3ii) zj8<67mLQQhI$XzDMdX}GWVJYfI}a^d0S19uej>+rJdL1S>lBrJT`hfw6I0}6;pLtEEt?Hrb zHJm@Jh0KphOJ0tVOXx`nW_J=6Ma6|hg(aifsY_S~=?cDtV{_?CP-%R#JlREq+X+@v zm(82bklou_&g9Maff+32K0^P{fs~;UXbTU=9&iSaSaCj`)J^YM`7v)e@1A`_H3n^h z9*}1?Q}Xn3({u_G)weOD3bJ>bpVKwEV_~1aH+CkfQD8~@{`FIZxqS3DxNmwZZ2h+t zFBz0;(suX739Y{7_=2Zt7opl2l_>i5KE_h_(S&9iNr;AFlqRWp`#9Y2ykE#9`i#rf z7diwPm6u6`v$j#3Nr~8IHD`^urr>9uVZSDSrt8x`zV{W3S62162XWj~{BvzRHvDho zO6);wlz#8Q}X%i3SSEflcL|caGNne|aNg9P< z2)MbMBbySKND}#l>HRr1ZPK26{4cdOQ%{^&efz1ka!hK}cO!VM0lHL0LeU518sT?rKy8dmbCpTZOLi}{R z^YzWPR#y)yP?W1II?X+2?(>mSB{`)3?k!4BX)Wm1{Izt3p*2}Ke=vKSFPYSQcyZal zcV#x$_kM*?#bb*~FfCD-!^lxIomibzO}9F!Kk6-TRRG9s{U2lB0A0zq^gFR_+s28V zOl)IfO>Eot#I`lDolGXSlZkEno%!GU-S<7L_1;?NoUUEFs&-X%?_ZzQz0q@i%k`%?B8tek#NvJfHkWHd>Fe9*Uhm2DxKe`52u8Fc9#d=hTum=0zO6mBW(a%#)Q zH-5P3Ze~)-{Zi*cMGaX2GcFr*rJq159LbJe(#JY2r5 zP*JhUC3l$XcEj;ze~U2P4x3DD4Mm1rt8N^%ELY1{np7*u3k*}W%elF*$2hS2t&O`N zcB`Z&`#8YEmG5doIW#!U2V<;7O{8s(2eVILMnnK~WHF^=?pIN(w2F$iQ4-LTzowuA zqK=c&$4V0cOr%FGJIv&(1Ls~bOhecLbYQz}&{OCcxSaj&@t*Ron@gt}-J7*Wznvbd zJdK}sE(t%Z?AOqk>PyUR+x(<|R!$d9!W}dVx}Dy1xSqpz*Bfplj4|dsdZ{mcz-Ruf zzfEr;HKhp!5ASo_iVyW7b#iAW}ALAy-Y^mr?ojc#Y*(vEAr!U0z5c zs4u68%j9bH^59Ih7P?1GLSq&^W$!>HMgd`Yb_&YIA$0QlvEwmV zQnI8MX(_V_6V4cb6o&h{(W)7b0gv_U*_-va>bIX0ElX4wFSOpqJ}N$N-gG`KPZy8r zJ{r8Jn3PpA@o36#6ji}z9HnwUlg(QbqYxgD#|`Og4!*wena}Kq*k+u*Bor1Jm(_12 z15PW7kl-%i9G!8=&yoo$>WiN-0lRUS_1^{ZDQ0p&M+u%4XE>7_~ z?;aBWsKG_)R>wh&m<~y_C7F$-DnvZ`9|ywO>MVqPPL)EWZAmcqc+d~%+bPp8@~sfC zu!=0GPDBn7dtuZr;BCj?(=BO@h>tfjw&&{{5)o1!Yp;a^MJ~(y|3g4JZV`;uF$~WElXuOqrw&a_fG|VcqEGK0hBBa6rQB*+4pv@ChDiZFDwkoYwhg56k2Qk!+-4|% z&~m;rnnB3$EU`lgU@mnwFGAwAK>qw|@65|}92(2s&?qgno*>&%=@yc}(}OO-kT z0m?eKpBRCf%mSu-ntJAa6$cpcl}Z#n zxU*A9@$VUPcGpS_JYMk|P0jJokGnTQZ8>SOCZUWUN-)D6fSJJ#7n-pKo<*bmG%uC- zbwXw`bT+3YJ*7KAkh!k0Gz2~n=3g8}#cLA%rvy8 z=@@)i1<2k<1q$N?)>?0N3vBQ3c>l!0nIF399i93~hbtJ*$=Bzo#8U?Ic}*Pf%FSEn(9~B zwtb^BDToBx2x=K1pF*9|l^k&gO+43)Z>B=v@#M~1BccB3B0qyO3c4RnE6dP|W%DYYa{oj|{E4Wc0T z4C>GuqJ~0i=)#7C%ROlpw;Bzs=G5s_Og^4EkOZg1E!kv6y*tsN+Kn)G(y+sGK2i1LY& zG+5~w*aEl8vGjbur~>IDWg_xvI6%{6bDc6jxI7 zqusNkP#1ns6Sfk#g3wRwINHQ?o z$EyURFX$$5VBx(B7jF9zYL<=m30ug4lZWHO%Ff#a{_)oCvA;PQpmj`#XV(a2#+251 zMvC}xLTqM$_m+#Ny2ZMe;!dj$*HE^=*Ez@c9-c=R;@hx6mPBy6e# zYL~5JZ6YbQglCP+0IZWwRI46Djrz6*w=7-vnf13ijnoT&{BM9}-zkKzPnR)!`oO<9 zR2fq%EbPY62 zH14*KI14VnesWskoeRvwh@~E3@{1@de%~DG@IaCT9hx2eR)r78Kl5Wg>uY^jxDX2= zgA6w3M)d^fj3mC3FD2@O7^&g(3XG5d?yXoM%NO246zO1+X{})%s$wxRMk+WV4L42b zzG?q^hKp4E9gz*5?ubF@7cdvJdDH6`=?xYZ75ez8ti6W*2v8n%Eb0`OqBp_g6AO|#BC(CA3>iY zKCmhPl-7&&b1bbU6?3(@%tOf9`xXrhh{$46H;5+STc1V|c0=bA!6Tov0~oG{s3+U@X!ZYP(C4I!alCuwc&uvj`#Nt$wpTv{xJ$lASPbb{>Nw>jFa< zE)S?+B|lIy1U4aGqA?v};9{=Z(!7m!czx~P?9E7t;U)T!gEgZlG{;(KHoWY2yV;Egc{#{9Rfr^91gNZ=)YopI_$fsIK^1-&YzC{T867 zkNqN$QAcK@i&p|V<@+Ha&5?~$hrc(&;~kATo?`PgH*%6>>$KQ1Zz4-D#Z|CD9fcgm z=5g!H6Bbct@pYb@3CtlJ5^g-f$o|1NEw`iMr6`IQ+>0%L1?fUu7KRrncBw*HY$f{H zeeTKoB!86sYi(w$o&La|`#=IDQ*bY?D5R11d^EU<1$Fg0DX8VR^9l>%kK`C?eS3;K z=N_XZVvUbIlV_So+J@DdxgR{g*(>9_?wHj~%l4WpFKfEiaKGmJble+9&jwag6=F^7 zy0l%h4XkbC#V!&QqQn-WU$3JKK`d*Yw`s%B5X4X>BT6;Apda?i*Q5Ai8i`acckXBf-`HM+h6_EB1Jl=VGk;t}pV`{-X{ z0AVW3{n9l*{gr7LYUB}M{yD_@*iFU#+4*?}lKzs`9a}6Iyl|%@A&f86Q;kYB z>qnu1Bj4u}!1lp*Ehtlhj|Vax`i>;kuLn&w>RRx7-@Xq5HUWCql?0wE7+m(vDA_LT z5`}2Lqa`h{ylz`y@4T0Cc{5y7}5&81^lcx>ET|f zu8WF`#J^Xp$xX}zJrOaUP!s!&EM3?wDD_v?e-?^TGqr=dx{rWA3P!K zxeVn7h0{gp6C5IU&iS8Zu^2G6RQ0$8K_OD8E$I*Ucb&r~xrA%!XI7N#!^2h>iT)My z;fae0#zHNTY4O+2QB-?sf#uP&JEIteJi$m6O!~nqLKV;=+i)K6K^fw08juYX=9Oht z)u=G7U0~CS1x4(~wejs*lcu&MWyJf|l*}gRBaJy(TSd<$Y*dd`L~p!YMIjB@F%&Tn zV|2M~ZciVzc}+3dM8zLxWIB(&jzZQyQeVZSg{@`=lD1A-oi;w0ka^o(Pl9Oz05%W@ zP11QTTCPrkM)=eHnQA3~-q!`bT39V}rO3+Bl*wL2Fp z>TTly#+)eA8C#SbSFCVC>9!$T2`)m}znOtAoGMP^*C^HwugG-q(HZ4MG7+Gz!S?0w zRPoKtw^1o9NbW(w?Mac{1(8_T$SQ0mO(W6ZSy6IG>R)ou;q0JGTuY9Y%r~tgykTB& zeAJv}p9H;ewqdniI&AHp=W&#j-j6UhyWp+B^H-OBUf!qO^~)#j#Ag%C0ZhxCL3CA3 z7r(xvrN(@C9-d5WmZ^K+yvqpAJmqpWT^Cmym5mfrGniizbu}1IOcus5dVRK~gAM6! zD~`+8THWzKFUC0CIM&CvTJL56-1wgjsgFlZP}~ofbQmpk9Y&++T;JY*ODMoL<6QfS zEIezr+i14${>hXG2;Qg_DkDdMU!iN2c90q%b(3Xn+CdByBMQrjDCA zpAyY?sxSMFXexvc!v`l$LgFZ&q)GOR0~sBZnGhT13`Q}amAJo^i_{kDF`V++BMl7X zt~vsoC9oeSkr3qy$pJIN_S0m`*~E*dF-Exb!V$2WL}jxB|x+k7JR|BkYGTB?+RussZY)C<0=o z{d-hre~SAeDL18uNnsT8y>>(ebkLUy5J__8y5;(*G;*5m#(HUn-+1N%t<0B@xQ0qc zek({J@MFd}b^vj{FGFfs4E6p_lu<7nI0quQ9n@EF(0Fx`k^!4-xFyQIn2UncLC30c zk!O}?)iW>I*3_fnyZAwXwJSN4(^}-5A#I_hI&hmX$P_+PYDO1r5~+yjkd_kVNYQQd zX6RX*4tj&N#JVDzue~x)LM5#VfNs$rv&&qAg0`Ti>6B%5w7Jf|ucjD-*_c!2niAVE zx~P#JAv*+`PDW?K>PR!GqVl)M)^K-PTm!Z|p-gKv z$6qmu6~py;xSwB%_;u#>{6P5|>q&)0;Fjk7(xl)k5Li|RZO3wde%JdG`Ufq*^UwXC z%fOzo3_6hSw%5jS&1mo~wbn$(nqepw9n-=$LWKmpJP*$JM_kK>&s0z9ueE(deX6`Z z4f_Xw7}9we+`y6iN4lW;#(Ghq&8~ydd1(#wyvuCxqk+Rh`$b%!{8J33t?M;|`h=(l z9f_mMKXNItA;jxeE+ct%an1<7jKgpU(1w%H!`ZYge$O=fo$*B@caqx9-PL!DgocnJala{Eg`FX(I zr$NkMD1A6mhYmq{5Xj_f7#NM9L%8Uynw_8CNtg#vAt*)rMtgVqPR;b8lduC&HB37LG014}bW{~1(hJ>i_A$gq zgiq)h@0hQa5KJiU5(=VvlsyfzyfxRpiqH;b9|r*z6ze1$9iqC>r-aVJ>6hNeSC_G| zN9vT~LNn_nB0h^Vgwd3lv6P5Jh`{J%2v8(K{m<9~31<+B~k*Dq2mQ19V@WkPE4)3FK_DJ7Mzq zGehf}g4Lb+Pq)~gY1mth%*b`b+Eb5bD{V22qMe77;<^}OZw)=3VBQG2wB-<@n9^Ej%HOD@=VsW0WNrfkpN0;}jFMO-a zJj%Q=e1~R`hTaS>r2PxD*Zh1Gp6+fEIi=F8UiOP0jv=#VU)|5N2XX%x0WP|g?(S>0 zt?0>+qyuhGzE0rO|0wf3ufndO1SAE0l*F1|@|HnICic#l7X*SsvOl1>Z)Sq3=%d-4 zJxU=+mo{)6fsOLV;3dwyC5=!o07TdtO^l*Csxvb2h6M~d!>J(1Z|FSSFBUH_2M*hf zLyeIugTO~dCWJ*qCWNKA$cS@L=~y9HS#!w=d|Cm$?KruqX!Ig5sKeX#VPjvw+0@k~ zs0L4tDG~_G7WWU?;a;-rUi3j_3U3g&d{=P75)*K*DDb-7qVCP;62&WvzgT0zI~GA?9o zyhp8iISw%o5PZ&-z!ShtKaXsOOa(4=w5!2HO;ppXkWMt_*KjHM(e%a}(Q~mt$SLNOWJm9K$x8VxL^4MIHWja&2=>{_T%Nf07B2^Eh-<2fvFD}Sj(NVlh&S# zM*>RJgNE-G+#0WDRp3HO^lCvF!%BB-DUaS!o-DyTK@?B3i+9a#Lag7>lj}&2^IPYx zDir4`2(RbL%Y5dlKokVSbsfwDk1Ls#h&5A3{6_!gfIz>%aQEcLk0yI-?74`WR!v$1 zg$PX-Lku+`bVaaEEK31eG&XsHc}jHEGh}zPt71^E9jONU)2^inR4Q26 zxV-!&zNMic>&Lhej7DOPp}i*+l?9mB2x3I>olkqmNr51ZBWhj!hMwEGSCDjf+%GSZ z*$=HGSYg%y-@kw;lgQjuZ}6k6&?-{uMUmI^Jdc-P+7ne^;1+ggW540h14!&WZ8(jP{q|j$fq;m7HOf z-5W6i(~SEPGTd7rQJ>IsI{LfIQ#WRc3NMWl{g6YfLk<>~;1^J>BLl=XNyz&Z2vh!q z)r~cM+)=`*g2k#7g3(wrBoidFIMWHOFt96OmheFCQW-RZ$~+jdewJ;nhr^)sA>(#) zYkH4fW+T!x;y$4>>cRU5tscq9u~f8WJsQ}wy9!^c#a6&tC%|i_+Pp-rUrM)H2{9ij z^TTYR*68P)H0xJOUle1hA&epNV#9gNXpj!k#+~l*qFH8>xFMmym|{T@^%AmY=V#fNjT?;{?YiqVXT^^cIQ)4{_&k}X1@N;*Q~4&~lriBh zug=#1Z_hb%4gNOEu}nAmb=4K7^lD3}^-)c%2iI|{Q`xD(I#)->vE}OyqK_?JZQfco zpLbL@^5`FOoIANWW>@xA*`lxNo)|^bfS2YQ9k2 zP<|of>X^-WS?1}jtBzf*qd!M^2-gljN?tQ_csw_qxE?y+EYBE*VDgp_s3rEexB@)( zxcER4U_6NfVOltm;l2L^PkzD{aXA^)MC=kw=ZlDhKNw(~z-UG_42rscAspO-=C6Ju zJcSh?6;~|USnrH$3}drAZpF!n@r0Ea#g}#6GDo*x`jsfnPak2bqwDPWjZ>*~I9Q-- zrpEgm@%^}W$O zFFcY|ToX3|YeJ@*hrx6NA_uimdZgtz<)H{MakP=0Y}D71?yr?a~3MIFmOE{s&#^Sj-f z&7kA9WKt0h?X?q5eo~}v41+FGj&_t0FI;Z2hw@Wl2 z#hSlg*;1K?skbNa_#;|r>W|=Lpb*zT&V72elrum?PrYX(ZEtE``F2vfZ^n~o9=jm1 z6an=Z?coy(+iXS5?<~SgjMr>Q!-tOVfCheqTSOyNvxtUL{TxTu)tV>zS=- znle_2ZAzMD+!WooHye6RoA#Dzh)ftTlk0@DikEQ-9znSFDhI~%?SI>poHBD5?$Yys z?lHUgXe-h_+kO!Xgs!h&K0TGir^rhc=Ncnc{ZTP1ef*dx6=@!0Z_+XSgRd*5Et+FN zd$w&jbmf@qfi)Fmq{D5{Vz5n zOAOiGH{E_dz*p&xG&695-oEd}4JpqLelNYH`kqLhevd~QwivnuV~=D0pi#J@^F4+q zje)*($RCP2CD8c#HcGBq7n6PhuUW@s`zvSL{ZOMw<~r2`DXc1np1V;Nz@dDLi5MM2 zZ9C>GyiTtSafd{?Ll#a+Y-kVGLSIzlxQ}sutwuEmB#woo933$SmpTYJsX;cXwzKCA ziFsc^N>_u~3+X%IQX|aMBpuviN6i%IzFIebM^VzQuNGS<4>ucdnrp88PAL2Jxs3-! zS8di({cZfZ&HiFtNWtf%m2v)oaCwdpo0E)-F~cz7NG@{bCj%Scjl%m+mqtY}J>@>AOnM&hK9Vj1{zqNWH1LxQr-uS>M+1x$t{h9+d@;TG%fD;pv) zjrexL44GJl)Fo@*$5E(W>>SB1SX+D{Jrh&}}4mX1VncMVhZ@;Bp!8ZeU>xo1K zzg?9P4R}45*VW9+_WQxU)wi64?aA&0Z|~g`G1EB>!CPpe?u3_FIh%CgC{sZ{nvG03 zOhw@ir%`iM8=En0xZA+hr$6V_Hc+;$hcN*$_fVYccfSUs7aRQSBllxv4yRywj0LJB z9G8oJ-Ffx~KtFL#V6AQ6X?Re%-jfxm*u$U<=c4Nl`b$0(9g!1o$D@-m^*+{nm`f6N z&ue*R1VlsTG4!`)sl$<&g6jj2Tg6RnI0_NDu&%7!-F-~m6twh@2vTDZVAp-S79yV) zXN3jV&%=1W+}SM{k+F~us}CU#A`Z(AX#$$@++v612h)yrjMFHX+XYnSRzNEu6IZxm zaD>A27E~rkn|d@I#ZDL`Ll-4yjfsC`)bGH`>D2E`^jC#?5FgNt7cHG)v7bkZUz$8+ zFsiUdkbeRs`*k7m$}c%W|B!bfPU+x1af8GVeP_|n1Lyg3vbbQ=(zrS6T6_4gxVDDa zOlZx!=ui-JIt|Dg&;qp)!LyW#v;kk_+3WS16~NjuGyX-s;}!cSoh<3NTII(9$x4BH zE1)VwqQA1gaGStTrd2+jO1Yw9s^PPC;?|3yLXRY%i*me-shmnRx())PoT(t!-}Npx zo`qG|eQ|Os&Hg8gIA(DLfYqTiqd^@Hj3}4;c0{@(BUyL2oy0scyAGgenE@IP*x-;T4Jb8T&ZTXyURZ9_8L~(U7EB=PncQ*XQJcH#u=LH z>GOk~pjV4B8!DR-lZy5L_tzTx>h7EjN9Zh^0|}2Trrq1kHbC)J{7^Lw-6C7XMoNje z;VkKz6K8c*Hgew@e_M3&kLaxIo(x6JXk5{P$#^^zcWY*l_?=_r5zilzMpl}fdKiFLTX zuOVNU@#+CMB2fSb#6ZT>GA(0W`b$V314(CNQLe$>$r=OY!7nf8qRIj^X7&=dl5B}a zx%AgkGYn(exYANAx)PW82~B#-$>?4V`eUPPNjvfMnZ@4b{qS=2-46>T%a)Z3CXk}C z`gWA(4myXHnw+QNhElS$0c}tRgjrtJH5N5nM2=UTzsLlzU@hPG^GXh6;=uJ`yD^Fy z|Ja_{y)%;R!+N|a>3vdvDt}b-74N$pDt);5U!vCEW@mDXa+)ZWH(Cxy;2iZv2eHLY z=qwYrEJ=nyJnjUu&QvA zE756etwhF5>KX9&&)DZOB8yg!MBrHusIel2GrN8@ju6TF0+(kRp&6D=Xq&Oqu`T;J{Mtt< zOG5bUaw`b;VWR21l1~8@xE;o6kf5BqwfN~yMf1x%)S*u4Mr*9jd)8sJQ}=V*^c$h= z=rh}T2rUEwEDHQ7fZ57vD>}}xB&XepV+jT^?-)VqS5q9z6<*YZW~Y&i(cUeY##WXB z5_>^%-B_Xc!q~0+XS6tZ_96d}J*5);?vzoNu(_wdr}wF81EWs6k;yZ^7hbNOzEP4C z4?#DsK%I?ifwqli?EoWd3TWFo+Eu{0_ADLacg@;z)=_e_$7+fGRaBYAe&jDDjPzKv ztOP^NM;nK&ks$#d{D^gVe2HP~a%`}o@96KrFAm{1tfrpON`e7B@MKt*Utsbg5lKkO z6mFTW>ER{#q!MZi{pPZiX=x};Ml;X}e&S0-Uh}-9A0*F7DJAcV@lD<$TG<2S(#H+Y z#O3g*j(f`w8;b*2I}vz^qtzOPWF}AVzenJxAszT^g6-zC@ck-8n56M&)H01zKkmzR zq!MUs-UdrSh)bFL6ZB&cDtdRoyCtiF7jE4o?}%gy>l0wP}uI8*fVNm zW-TRfW@qLOGp=|FCT?3_z=;0KXz?7)#>fEDlQ1l%%82ra3VIv+%!10S4m{Gm4*iS? z4TiOr^^+Z~l6^%&G+Iep#NYtqRSIM51cU7r)^MH1lABVEt@eX+XdGJbZ?)YQrv9wS zq2xT1%XaF$ zwlP{f!N(Jif9l(p=NI43?TfdM=Cm;6IBf*}E{tKSV#-XCYC!FTBy4SCs&DGsn6~+V z#^Z1c;|YA8Mnt`0Ww_cvmR-xU!a0>(Az^-1F@qcX3YcqDu$fi1jNlYjk>v2U>`FIg zSL;eIyGxaJzc~ftxLlwS;69l zFP+*k5`MrQZtlKiy!!&5=u>!yQ1{|YdVFHfAsdfs&w?38GQ9iHjxtcxpP)#NoiFL4 zhTCJx4(Wrb0S`Vt!(Lt^J%GI*F5I#}1ctJj+x@+V3LpWhu8GrZY5*}AbQ`>8eMjA} z(X5M&aADxO<_gCfSX;OxcIwLZu<(2yuyH`}K=5|)MJ7^YI3-D>!VD*zP}AX=qA+KD z8M{J7VX=QWg=pP1NkshZ{dE8&eO+0(X?} zdzVWS_id2!r*xXTqu0C){Tb+&vP@=(2IiQq9CVFsK90ULMfzC$@^?7n(mac6hmKvX z`l?)U<6%?1X&r|1>tt|@i~WbPaJbcM3ISLnVmk4Vw0P6JrNc+CVt^|>0%J`prR4+vKYW~#aLyz1nk?yPtDpb=t%5^xC!cAyr!wiqZ~k?qMmj0YGHmA zC*nl2k=wv}?axJ3y8EZN3w>_QY=B>L#I@8yC1>}BE=s>JY-aFpOtH8pQWEVM4a{6I z!G3m22?a|H$7;QNOVl&1IOK^8?6|4hj2rEf(tfZ0TnHz1MaK;hbKpyeyf=dzn2Sos zY+iDw#+c>?ty&wzmfqp-S!SX&t|(^`q`_jRLOaz01sbmKmbP_UYJ*tPLxL3`EUkj{ zp(0{cR}5Yv%&K9hjhgm7mvM|(*~$|&n!ktI;O)!XIw{;C%KP{oe(e~h#K)R7xlf}O zj;kZ(*?W(2CE@RNLdnz~`Ntyb2M*2JTbNpiT6i5FqpCR8JFr4?7f^^NBR!PLh%3OF zvdvwm!jH>JFtha`l3s~zj;Jbs3C2UM^^J`&rucng3-$q9>4B=&JVmz~q|jITw2|SN zOdZa)OU};u4ji#J75_nt$tS);`{r{)Ne))k;*Q=m1eWlya%)^Zrcm)xBP3jA3hJIn zChv{h|0GoL9newR=7Idc|BESd$jBR@p8K*8JYn4UggBd6pz|*N-d*TF47n6?S#10y z&J%iBz(3a#PhkUaX|Ivm3XNv6R5x!b({lG_cBLnUdr{kEyva=F^JS+$8KH{C?4jl0 zlP1h0_I?nZ2;`L})S)OAxDSKrkz7rZ0KKkYK$TTxGN{})7+?NfCf*N@g(03^QV1cY zZF1r*_oMz*_wcU3?hZolq{mpic?2!2e0AqFWfC{W0Y+aW{zjkB^88Zg*53CZC|8Gz z>dg5WblwejtIbYMgB5?=_mNEo>ylv9;oRQjaB}n8>2y}pMsBOw`yA}lnAk{h$w&A@ z2Bk1EUlF&fQ-_VDpgjk2)xbcS0A*a*&1L{G+MzagOku0TmqqmUluO9=aP~}*MySqE`~va%VSA>~F4x08K*L5}Q$&yVp+Zk1{ZrOhkkvgqq`^@r z@d}*Te-yCs8(Z`bLC`f}5DB3u@!#2hqW=GU?Ej&sH+10laInocjgSq%Az8prw35I9 zlq|nxIF$5$MqDJyIZLdXI}MMx@0p#6r}fp z@n&F8%?!FD8Z+x6wXw{<_JTyk8prM;{zmzMm5a1`svhXBdsq+leCd3?!)7EdudB%$ z&Jq&)BpHy`y;jbMzI(`TFdUwA>`p&Z)ZR_bu3NG>e#d!{=CV{gpyPB5(mIiiKvkG- z8#qpxbjnP=#=&}dvPKlbi3ZK_d~D@qbTQ4$w{ZuTr9yRV&T_9a{Zo|jPcTCf`inzq zDLA#kj(3*+7f_0{@vjOq8h0A}YWfR;XE+ZCuS}&(ZVWLSlC{lxW7Q7Tx7D}$csdNW zsLid-&mWV1PG`+e)yEqlVe@WjZhdz6mrZXl-rwKjd3U+i5{;_hN4R7`&)J6>`y~z4 z`anq>+p=sq>tM6KBMb%__5KL80Faf$q{T#FF!;LR3#PA8y{I^Rm9@ApmqU|>HH7zW za1Dai-m#P!i^qNpH(E!a_eVi#m5$z?ON;oa7~lSTxf=48NJvy3>!Jf3EkrgYC2b7? zWOr}ps%OW1m%66pD}ZsQQoawon&DWr*RF|~0Uh*P0C7f&qwrzOMdIc#nr9_MV7{_2 zS%A-*{LwKey+Ns97YpN};YVFFa7#w9Nh|}x!2na9TjLem^q-2=m=ml<`Sg9>`LQYT z{j*stU8I$+4pQn921RjdW(mKnY~UZW#BCOz6RTK8^dBT8)C84(6#F*Po{|k| zc`B*rDtQH^t8miQm!pw?$fX3buL&9sC|%d*L=t^s-;a-3NRF!h*8HZn@Ar|y)hJh;nZD(5(p`iXv05Qf+zc^my^R8@Lpk%rib73%SP1@n#c8t^sJine z{jVwTD+FKq#aPgtmu-5_0@=|(*DIRQY=|0_Y=TG6 za%9U9ZZR$yJQG?FX(klR8?K#c_<7}uwzWY!N*WR;#b4A5ms^kEi(+$` z`nAd9#TX)9xiZ)K+GsnL11*1;aA#D3W^BKI0%wG%GjjzqOU8uyB@G`H@F%@bbcweA z`Lud7c!&ml6V)ks?~UoQ0jpC!O5b?8YH#iXr0NNl&Tk@-jNJs-m#~H8yxx41bt8vR zE{uUPaM!P$4MY#Q@H2B1-u<>^N@spgKW|nHd{DC{Lmjt)X~|#G3AfK|5B4MOg}^0+ zb>&p$(h^gPM(JAdN7b!|8!0B$In-*PLF;_bK_Ot?)w1wh?@r6I_MLtdjxjIPy5U?y zQO1TzajS4#vR8lW`>P)`#!3OjMRZ5X>Spu%;)5VZiYTQHwug0znUuzGD4#7IY`)Er z-W`5H0>Lattxe&%{Ms$Ys<>7;37s)f;Nn53+e-=|K(}N-A^>i#Yo}3ND{5|ku-2fV zqo!%gXv^X=@ZIV`^kM0Y>fHPc^HpsaaS~eD)u7&kYtMfk*}PnZW@1t+K&IEW4o(|5 zqcpJ|3B(y&s4@(kJ^;!y{NTo5a%Xt}GwL2z(q```qnd&;Y!2*n-A#2MjXy^`Jf(6@ zlihsMmOB44g5mUe`2fTrHzL@H)CPWzfSiA{y=8q~!zT8O4)$7>XRfu0GTIApg3xcq zv(T2xyx3FN;aChf6zl>6X4n4nTd|p=!@#BQ9`7#^<^&hF9j3NkA<Rt*DJCVnA#lnh$DGVxaMyD3)vIoz6E1=qF3NYV1~q&t{p*$U|V2~1GX-piuArc zT?Cj4?>n#knddgukwG_}Mn~Q`Y4rNoLb_Mq9bL`)GZnk?3)WQhmMSJ~5gzFEmo^Vi zGX10|6Qj7+MeNP|B+uoXYq}hN$sLeDeVLen3xM^lituv08eI?I!=3P>3^QV3A)(lb zO`~3I6XUaOIFSj9C;$41@{TPQfbYuLk|ZR;*GwB}ur-D6e)J=1Mb2RxI$ zq+3)_=ZjeScaM(;GuJpl@0ceWZlY2ntC@svdJrEvqDp+;e9QuEmla_s4f!$_78Wu$ zOPn8X>&X(hIrsdoW;=($y!W1D*}P#H>(9sslhKqyBm@eD8y1?f8gtY!8?B$i>tFI6 z1HM`roAL!tW0StZ6v)R9l0Ee?m5p6NuN#6pa`z|%rNv$At_&luw83m8vs{Q={^`J% z0Lglp$$xO|$z2b>#2Z#`6Yq+?%(PmE0-Km=SLRr|`~IR$mhHuxsql_A-etk?ud?{| zvNATg?-L3S&Ym3B)Yinw+0oR{<}YPuWC_c{PRvaFm*C@LQuVMmC1w)0vvn3TbuxCe zuy?j|gk=&nw3jrsF#qmM%*xIU%Ovb%Y-;OF%)!YC%k)?5Z-If81pvz=YdJcy}{e!GcFYuBjRhZVrAOAH{^0RVGF%mO5U z3}QAmHsZfWR!&Z005FsPKVP7ZE-@Piu?{CID=`NL2l3zIf6*K)%*32PV}HMFT-^T{ z{7e6p<7Q|3m+ap%%U^GRZv9mR066~35Rl15tn)YBy2KpJ|7inQ0J8t_4k*hGH1t;o zc+@54WdElENB~{>8^=HXadQ8wzy%EOuP9JemzWC}^*=gXoWPX)t45cY`(Mof3D$o# z@s9`#E6cy_vN8jufidV3v$6u)0!9L)06^J)CNnsG3NDTFy_ zo=mhn&k~F&KMtfFI(BtV>6R<(yI|8Dp7J@5?Mkm?ua&P>Ma8w8Do=*h_o%-5bUk-( zb~4^p`@Wf~kEi?K z{pVxlkmm_)gv?)l|ZFHZfNjH7%x=Ho5#6t2R#_4MX>%ph(NU&Pz$JPkZ zUCej%!6W_xz3A?_UjU;!oCLH&rtnT|pE$`!P#9hwOfqhqg6q_MQ zkQw=Cbd)BeqTnNP@m123K}lXQt>}5ny#+jzWiNDv(YnVI1lF@I&mefO+D+nt%}UN+ z|Bba3kzjb)fc=ey1x|gM;dvx7@mtGU-!4aFTrwS?$ts-t;(Z-U0D6HU%zwuMdiu8#yhBuhF9qS3Fd#%_5Z+fAQJxnhau0S?QeG`*8R_IgX@1!An?_Zgo-n;8^bag8~#;gW+(n{QL!@rPlbOY z02>Df5UBrO5YVKfWrsh4V%v8O2R4}E@(TSBka(tPd+&oi8^s_KNXp$#O$+;s%8O_a z%whlqeM5JPRrQ$==Donn#;eP=hQEpqU6WE+TUk+gnvGN!TX!iM@ znd|x^TB>?DSI~#e>3SuVm(nZUMQ)J1ns5tXpyeF^kz6}oQ2F}zG&p!O%9Y;4nT-zEJnj#5n&YL z2t&X^7QA=5RwtviNqd?zNAB(IIo6G@7?w4PE}a}C85F+_b=%3BC!;L&BV-H;Ae>F& zJs;fbOhv&21RHR53fx1V+5BL%F)F;C?djvXL?ILY2$tw(9w*C4LqV%7YN6tK4Ec7p z3hv1$Z`Pg6lykY>8O2wtKGn0 z^*BgyExnH6CZNUt>H8DXFnwNgQFD99#^I{|f0T9R@ld^808g|SV+%31#+rSd8M~jY zv5a-d7P5_H&=~s?r3n*aLUtKTmO{2<36Vm{5{*iTCWR1Dh`e`tdzb3Df84oeo^#He z^E~tU%=w=A+}o1+US)`X7v;pIa=H5jv}DUE#{nc{Lhulj;E}P=OY)n`+A{Uo-K*WQ z`7}2fis!fx<5DX+vI{A?AYsR%eM8LbD=41xIrpPP`!L-Cjt^2Y4!K|8Uu$@0Nv9xl zJGq1lNq2f5)iu1Gu+XWMP3fAFs^lREIv-ewMYBPtE=k~By zSt`X#K79IywS=Mb#c=}8lD^XY+Jg|oZbXSSG6`>nh1m88b#ZlZWY-lFR;8*(-xdTU z7mQkA)u$Ax_gicTgJ9yQBBVNmx%J>Rxv&2mGOsP_|FX@_Cw=;se=LXCVHtZUui>d3 zFq|^iB2_(nOsR(LDydwfN6@4~wINX==t$UiqC-t%X0v|>QH{`O-EVCmzW$(se4bm* zD*r}<*Z_j)$YYgyks(uYv_{Ax=cdEfI79D8Dny<0@$|!M=<#i~8Hp7qw(KJv@9SSD zbRJ{WJgkBHVtZ(zQb~Z2BMQ2H%9W%qu~)yvnz_%G_?e+d#%Ha2eB(#eo5O?M0{tV%w=+jo zJV06zD_PcuJL63w>5+G(W2fgn>Mtp~@CJgS1M5!`eyCgu(;DQ_27%$ro!k(@@WjT> zId>Br{X$fnBDI6}x!pRmRE&W3bqw!lLSEE>Tsz~bi@H){Zd{z-4s<1Yj#=celx8{R zN9oG?mnnFu4mk7A%bC=i(VOsnqLU~A;$sM1@PSZ!nqPJeaR{-65m7b-SLK`H{JCqp z=)~p@?_l6It|IbV)!1V)Q6Z)yiV_?%28@u(?+VT_-x2&4SMK@wT_W9>wcqwB)2lfx zbg*|%qH+zP{B)Q!EveT{h``!poFmWI2O}i@h z!1x4D>Z3{fV-8GolCO`h7r({!Hk-SPr*z-8)P8{v#!03zlg~-{oV^M4oExkZG`Z~s)9+4MY=k`X*E2~pakQ~~Z~ae1kI($UfbxzR zm+&sRf>4{(E8fRVoBaB~0-kS4?}T~Ho`+x)V9B4^RXvp; zT*&QjSa)zSLy8*O+toQX#}%7)&lZW*uYvJS z&@s+Ey^Ly#&&!Ygk4eUOFE5>pBtr8-P=b`ZMk=Q1Q)Ri7%x#_;8^ssI8mnsWLgC9O z*;#iI^7gcrOE&u;$J)l=>Z5(^S2|sri3o95Jy9>>Ci4M=eW^&D+Fc)Cvw)~-p?AJh z#V!A|3sA|G&(`9M!!wewbm8GV&>y!i8SyN-KqP>+)1{D$hGEByeHRgX&e%l zSE?HDr}K-IovOuZi{OW_1NF4^GO^Ycvr(2V{4SO2_F7hK?_FR~Z^9lua#< z`+SC|Q7!L#ktGTPOioo~SXJ4P2H0Oi*iLYiMCw{w>iU$;814^zM8uWrx)W@JJ{Wg` z?^I;qYwB6^)>G@oG>_{6Kjcm2&|Zwn3@24CG$jQVo4PEfENGSHwM>|(jG7p7RE%C~ z#djH3ZGGhFTd~8ybyGMVq9{udTe-NA#xi8)kVkJUK39VS%c48|GA~c|4XVb;LrW}& zVqT!4Bifw7Ef(02vf%T?FEp8lbCA8maV0x&`{<8I?wJ#ccS?>Z=n)zW4Sk!6>_*<) z?_&={lsUBRG4EYvpU_#vk8V1z8B(s5-q%m@AJLC2WfSfr(y#M8^*ZT@922IFjN%#K zI^RbG8Nab86TnS=qm8|zw#0wF42YOSr_S0C)2i5(CRMpdx<*#F*Q0A;;ikx2yDuG) zTI`|DLR&Q`&@ciXZepA$)QObbZ{VB>&k+-P0An5JV>XB(XG=O}6`^b{znfuAAluCJ z64J`(5JiqJ*4!UA1kRX7Px<`_dN_V>QA_!Ea{6fKbW%T|Wo)?L0aT+Th zICB_sNQjz}eH46WZCgjv^I_cGa9b4a?SXPG&DRaj-R(w(U3Js8!B-Y@dM{2;d@Cu} z3Axgz>0=hURz6b?cFf(Q>~^2cl^xAAmwlUG8QTO`v?<`gac_Gxgi_{XXIEo8)z`)+2-S4|!kF6$W-(Tw`?uIjk;;f8{c${-W7-=My@) zr2B#y)b1%~D7RzD@L&i=bLy_EcQ-u#C4fre4&WWfq+p|VT2FIq1JZ;aGnHii^6 z+?zj?!P~S2Ixjigkj=Vxy{~071<@Q|Wk~nXngUx?sFJr>5wTcqgsEvtX(hPGp6=t+ z)Lb*YGBY$m-TU&ygD8KU{Tb6s=JX%+?~8*HHYX-RU z{MKG)biww5mdyUQp|dP&dy|DhBFZeQ1cBLuLvez~mTGrBKD^3&5LI_qDE(%#7gr#K z_r+Eo5fR&>geuGGQIe#v9>qkx)|BHciEfjvKzH#o+hv)!Nw$yqL5*eyj!TX#iD@}G z)G?#Q!;0N|qfTgkefOP-Dcg`pH*+w$PE2G;j=!D%P13=g%@MNc263`sGwViZ-MPkT zk(%eO-je%wx5kG@`3@RtuoMPZK8$}yX}9c73k$gteom1tz(>i~kn^K9z6yUFP1b$F z!wM2yzC7_%G9u~-{ytONd%-D2Pa`6B=<4RtXUM{A>2&pP?1G#hV?&yrN*bJ}L1&yhOPUauC)os~CM7pqVa&u|#{mo0d{iPYn2&IjsHlf5~T zKbD|}Ge=2o%r}jC057;+{Z9h3i6+!-NVy z5ZRbID6~EhMnc}%M91noqOmOvnL6LTjuCajF~ux~$3nQXYAeFLH=ca9itLzJtczgE zLWY)3#HBsC-5$2FxKjTiCnSEgvB|miaV$4MFwwcdhPCccyZH;P_?0K_T3{t`l)c15 z9XFC2xy~{{H-i8sh;u(tu;lUNk&wxZ>$)5Zi*#O#=-N=aYQFCij9K%g@Ea=0ygBqi zHQmi%b|2?+vgB_L006H)K!By2H&DXr1LZz|GXY>qt6PEU-qJ0IMm!aP@|kvt#suR+ zgFG<701*Y=48nO>V}QzB-qHXGmAAn}0Nm0z0I;O@>#YClZ2Sw^{!~K(rTV|kAz@G& zT?Pyzm7z2?fu@zt^430XKS2TDgLbKp^T!2Q2fBG+pa2tq0%boA=LrA;s3Hv+{9DD| z!X1n82%*^rRA^de7*Aifp9Gl}3S12?2UUeB$^C}sXi@!!LugqDrg;pd1r3r%`FaBM z1Nt*v0R8~%{-WXl$^1iA-wmMKIB#0Y02}|w*#9&lf-qhnfW9h&0O0v+KoM}bG92m! z{jZD$T4)1$?w1S(R|81oZ!&NkGUzEjvh_bk(s1n70n3{>>e~jvGrZ(okTq)?) z%pDz^UH?NgtX*x*|1bJ~sj_ykmoRbt50>C#XJzMNf-Bm^H?dt6^!tM2iuT!=+y4~D#T8fZoc-a6+h@N203IKd zr34oNx4XfwFTi|mU$D!g%av~4VNSBhpUCeT%IvF_b$YuBc{Dv?3F}c8+B3TB9&<%m zB~B99N<|4-Ud`noNcYULR7wlJwKqsyWHE9`_Zl1_Y`0Z}m#%QyanA7kDaOeeFn2GX z_H`%&6KfhnyxV2GX;ohD*24fXfIIOL(mBjg9>EOU1xql-QTT0lxK$r-unI4T-M@mP zt~w=p(qzb#FbcALVQH{W0Z^ks%Io2$bW33e_WA{Y> z_?(}HT=6Lau|oaqAg)sNYD`H&_JlR2S4PO!suG^Ed8T`A#X|FYHnQR?4M}jLOp3aw zJbha9J?OfoXc|IUf>J1Y&(Ak?w!$+J<`bDR-Cg08?H{^V(dDo4iR$YyJNjMGp@`D) zJ(r3;zAAu-(p;<;#DuRS|Yg3P#C zphOhixvE=CR#mIwrJQ+`WM;s?C)G%te@h$~AimxF-B&1qIr-mt^1UEr)G8*EbTNHo z)=W>K`oy#owHSgcsQ76iEQ?>_E9oU=SnOX37TGRSCt4FisT?i5U?MEFuo*s9>^6sU z*<*q>KhX{bFvO*`(|xO;)9({gheO zX1Ms6WmIY$)%&xg(2yuav8Mv_2t+zn7G|~m#W!tEuQP}EL~kmcY*FU*dP{ls?jGSi zR%jFn%cXGoPW6>)sx$UN&)41rvx#n%Z92@9Yn&9YYkjTdKQ#sFUIK5Pufk8-;)uAc&h6iwe`jBJz7>__)om0{ZzQ^ zA3bD}sqj6H;Mjgk7@_19GvBgiB3p8yb6vspzPg{x}tc?-)-}yFlidohz*5TH*ry$zR3+Og)46t7y-^Za%eZ!$mi*wYy&_BuUZi&qy+JaF| z>uv)&W5!R}+`-#e1V8M%G}Fjp@iNvAyv~A z&r^!fpgU#+x)fQc8yz zxRT&snhr_!VrA*2FZ1|STHckybH4YluxB(U;GlVnG@4J{RY}04{i*PU{9hb{eR`6z z5?KN{Nm~HV6+@aB-HMvtfc;m1Ps)32>z7|X2d}G+3~0rN=`}T&L$j)@!yn%xRL~u$ z<vgWob9s|>~n+lTV4(35q^Ywf`G+?_~_I|vN00<|z32X1M~H?BC(@5^@a zPI0v#lAFO^?&Ud(zZl}n>yRey*{+A_elQy%W!_<*DVLbGIIwS4niVf8IUbdcIr*$(-R`>J^^ASh zi{Qo_;sey8K_72cvh*6P5*VLFXaPzlXzt0(iWDkLh zM-034gt!j}L)sygYjmf+zx+pAQ)uVM|6M-7uQ9`P7!WOimW;0}4Vkk%O+Pao--QS| z6&*eIr#thl22sc?~P6g`a~n!T8(+ zY0JL8_+pd#XgyY`4Ij+mLas!dP2MYfBn6aq1Le^FE?OI2J;XRVks<2TwnJTowSq`Y zPoB`rx-buMR=yrXJnQ zO^$g%>nn})g~X%{CI&W2A!csAZ|np1sBPh4;W|^aikfCos_tQ3P5(}n>mL|TuPDWx z+qVVDpcnYz79qJvRRSEb+q#TNydZ^B@d@5sH3$rY-z7ulrmn&;@9GRn+d@Fg#-*)! z@~FmOPwR%^{(U~y74|@nVSBA(m%-RhO=Q0I)qS&`Wf;(TsXIJ+%^7zYmzaG_(8^s# ziJL1dbbtsYU3jLaBx)GlY=ClD^Zs|zn5|^-Th!GpNuN#f6_LMl`iq@WVkknC&D$CUP*!6<2ecjjmnXX^p3`8#rktpCt3mflccEP4 z_3)IdI}VBEjOl5#mX|zWEoOikQPbg!F#GEdjUkYSvxE2`Z8^|M!EIEBAmHC(0UGe2 zvc|4LVtBa#wR(hCHNB;=Yz@R+Bt{p2`JoilmVH^bL)nU&;~&#CC0K7F%7j4M*suIc zyDJL^$1mdkSBlQAEurzH`-^1i9YmYA=|tQQE3`oH%fjlzub*&GFA!3ueApgCWTS=*|r^s zG}eEDBOLibU~NJ7w&q=uf#)t|Uw?}+S89p76(Hr+L34>;5v9<{qfgIA&37SDg%H*v zt9_AOmZ@>0rEf2r@)t^2u7FsnZKe9t^q3isj^}H8>xVfs&$owPRj~ea(=s-+#&vBY zEK9c;)cqM5$O2_TgbR5+|6;wm^Pj^l|7_=MeSj?DW2-WjK_JrrN^f_HUYndQo2dgE zOG)wCxi-yx&^7$t>)%l#X8cHzh*vyJZ<`7db%%=s8}h(_s`7b5HlRCF8u8jmJh287 zoh%o0ddksXC6n&&!^KfA!qrP=BXIbXQ@W>Z%NWQ4zr_sdj58}WKa-BX z9Jq4t=f1snTS8v*cZG|+OwiehYf9ub_vwCchUQ>vBU>!Zs+_uOaW8T!I4qr8w&%Kg z3{rOJ)!FN)sgjU>XuV&jeGNF|;_{60sxemjn?1_OIb}n&%F(+9mbWn-n6sQsBmSg! zh+P*RJa_M?wk%F6^T$0RHs(iSj+)5Yu)WKm1*{9$J3mnJC%W7{pIJo7hS*HnWX)q~ z`;EyS;1qtrJPg{{KOoO|(UG4{(k)TuJD{#2XpBa}`pB&PBay*NIAUc{jf>Qb_)U%g z??p!J&zHy>cy&f34#a^o*vc-F%IV0)yNp4&N>M8I>t#65vyHI~z*yKgU|Xb8LM;Be zz#^1XYVG5X9zxTXw8c>N(dZp5t?k9_bXS=a&VMqx@hJi|y@F^=$K!msp%54rq1}5D zg$#pD_5_t)Pbx{G&;7SAu_x_c;CyzgMXu*Fv3|OUynLy1`=!|x!6i%G6U;7365hdR zK?#reRf1CQ(0Qh6w{pYR{TlmYRiZ|mYUW8|7ya==6u{woy<;2_aFw~`b-5*nfux}v z-v`t0i|?{(!{Gvv8spt27h-Ys!# zIZGT#23+(Blc@;IN0v&`+%!Esw4ah&9MMAumiwx$2fOwA^?=KoTBm=ejSXx|Iu%Ml zl(QUIU2xtE!PrUP>mP)An9MC!3@>C@)#QU8LBFOmh1RFj+ww7O3!Y%RtuyjRG+!Ai z3;Q>BEUk*lzeK6}b{fkACXhdvZaT|BM>b=mbzxH&GBTXn_ZTcpl>?VmqF=_TAz#QM zh`2(8Ew~+NENyBD1hMC^R(HPJ^iAbOOIDVEa&%(gFIxB+b4@GC>G~s-2q*lw=;;$? z_jZvJjo;*-SZ=u$xxADjA_HQ2f`%+qs}j6E=K8B9iH=91ucr8w zAJ8P9Agt9%p7!O)VA|HhUzttT3U{SevIV&#J71c1pLQwnyvj&`dE%vUe{=BMK1o95*I~El|R0uC7OJ3 zzYq=hFaypaIef;D*5NhUZ_vOurpHYlwy09xLb;n$#j@&zq}|=9N?`_f z+!+C?X-zo>j+ndti`o=)>i8R#k&~P>)R!)hQ33K(HObDXv9_EuY+*3M7_lmd`zDM{1I@x z!+-O5$Ni4>&FhtqYE}q(OY78ieI|Gjx%m)=O)H%Q?A_&>k~S6#(RS==wW``-?U7{g z1cHL7%<*Y5k{*=jMhegTzlCn24WVAMJCs)+)Q?B-)c?h~v%p7B@un(L`Bd#pN#epp zA9*bTGQir^@48^RP@~ zBi@%h28e*Tcmb}REOFK!DK9M}y9jmSc$1)pDE(tH27OK?^8gPiw|p@BBJOO6&_Yjv zZxnxSkf}J4=01JkO@nv}F#FCokp)oxz$JMRr;xnN-n`Q}#UA?}ok7zpr1DJYox?5PRToOsLwb$qLWUwvJuc1($n_Qg zbE@bDm=1acoRM_ab&K-1r?9>!A41PiNP2RpV47w2Tv*(R{jWL#~h$5xPURI9D$%GtzviT<%xJ$zgDEbA&g+V$vVvAk#_se(p=tE+~x55 zFe4M^)E^i4qU(fc)KpTv3pUn8-#-m!eV<>4Nr~>T-Fed;L;TXsOT}Znetbxl!W^(* z;_seSPIhD&aM0|Lm!4ZmsbACY7A??d@bCJG;LWK>M>!ZoS;w2v%V7rsrt6jVK#bu5 zLUPF==fo$-o>-rVA@PBjzq&gvR;rZenE#cJ4c;?&fs;5nAWcK1Y8Y3hx&tQ=HfD-T^tWEGZt)E;*CfA^BQ;oeCCYCa~*X{nM`lB_c zDj`C`O8}i7bN_M~cS?B%HM}pr5#`og=y5IH44!?FrQ*ldYVj2w_zc_k%|dSfo#M7G z)Ie01mPPX07q3`O@yJxlV8T-HnJ|(U z&}i(Al`EYV*)Mq1I;F^54HIKHwq0)`5iHId!&dJf`s&fid>;Z-g{vpoO%3-Scz~0w zNncI?drj>A{?jHpMzWQs&$ewuiI^T$)-@YJY4+}x-Rr%RhQ}7E^=^J@mxZ)uOsqWG zU`8J9L%9rl=wX%Ri#Y-|aUM^m1m*|XUSJXlq4_<0)0|`(%#FS_?E7}&&p1}LVwLtr zIe$oPk9LC-P(?T*mIsa|!bZ%_;#14F*6pA^bExkKpAi*Jdu?s;F;c z7ZIMK3_u`)u{vj1Yl$v8L<=paFs1`$!3lW;&YR5x`Hi#vk)J2eXXAT~@8W>?zL(A~ zZ`Yb-fL<2R}LN}B%o2K2eI%J z-k#qUZ+A2Bu00RL(mLA`hcpxN_|g!9;7m^=gX#L1onIbAy2cUdb7Tv2{`6uc;+v@L zR?G+?vV3h-P3fmBEv$_a!2Cx#dldlhi??Gf>CbpT)3?kV(E?~9w2Ehe10nL=|904_ zzpV{=-g$-_Exmg#@Dof;uf*jfvkv?--*%5T6kdC-{(`Dlr2UMerQe1M_U5JiFoDx`!VUT~-P|H6bpK zqxGet{M0g_CQ5(Q%g^c)qQ6p(Zy@QAzeBtgCy2%GdJ&IrMX@*~8Nz9Cfy|djd^F3& z9n6ytmUY5^)$QBRu{kH`>16B-5S%wN&+Bc1RvZqv6WT%qb+A)N$h;U|v)rNGDaH#> z6ORyA_*g=oR{GR|{jZyY&;hvVzY7dLec|m%%r$ z??6qd4@@(g-XQDTYnNTodoI?L;^yxkwLJM3AArf*{KPr3!~4&FfRsB?9RxL@i1Bj3 z(Me5uUMXVEXn>I5QyYZ;oD8_SEz5!o;oq-$o^fHR0DT=mz$jYie68L28|J*zas{vz zKX%*b-9i(FR1{J7A$E#en8SELe?o&~5U7I4u8l2(WP7GCRfXOXs`=V}$p`8RV6^;L zM>%?|^+)+Yzg|x*rm|}d(ml=wZZw`5lB0Vcvse3XpYhNq^h>6kTDK zjz+fURxA7isv05iodzD4hPB{&BKecNar@I2i4NTPp|7nyOXL9&k*8D} z&?0P-J${5o_VV?VXWHZ-=N95zKT_t$fJa?xeq?}LQO!p;5878D6T79Pfv49}5cIwQQ-iSLwo^m$7_2MLB-tqCr8)C{j$`Vs5=J|= zmINaFANIgkKB&|Cfbm_zdYeT-^24@**y3F&!6vf1BAf)vaOk@9(HpN~1(hQYh6o;d$>r(jGewr`rr5$A#T>u zYXHZ*oe+8>*bkbOD?vFwoU_5}0R+851<6>j^7&$gbb$P?*cg6_+chj5)@z*{eUWL+ za*^Q{VI5*d7x3MYLM6WYb^Ut(@>U_%Ar%$6d&SN+9R*9bj4)caDdW6y zC_u$;C-aH&eVRT#e~?tt_q!+i8J7RG;{JwXqyUt!2b9~7nNLBnvfypKGVy?@K!0b- zTTS)oQ>O_P0yT{Jgn2nL@=$I88D3HSl_t#FSGAM-FS-;zWZ&U--)tv6>Fi)1)G^dl z6S6*`{19)YXod2R^@F;eGm}k<`CAGT0Q?LJK1Am)UmsZ06QxO*Y@e%?EZbmTUXrz9 z?(4-rS#3R%k^OjL#e!4LNywgHRV*?6%V=j>mB5H_Rt;$WTlhS8-fhiBIE%%6C%C5Z z6gtw^esG)Lu7o`Q@CDy1`29k9Ah7)9GrXD9&|EP`>mN4?nh%E5xML^4e=p%Z>)|x& zKyLE=5&I)mtXz}+&$(qnW04SZ@zQz0F;LEgkmTgRo4kSEk-6-bf?F@3k#zqFpA|mF z>FCsv*si8j^%|3Nz7GBfaYH}}ID`bSN)Z-L2tO8l_|dLS>_+6nWd}egaDX)+d(d#A zMS1@qZ85CZ9&1OvMZMPsmztp8@oSRZ?{dsM2gFff-t)WzMz&HHMdO7++`IFG@AHZ7 zai}*&j){-)a!*&EwEd5SCPA}1e7}tyav#p~yAWOM^?d4l*vlDg`366KKV7w7n%^fE z9JdExtt9g+7SA-~^Qk)ll$O^Ybb9M`BpTn8`dCEKH{6M?vjFY_63<*%ffOE%mkpH}KVTizvrrir{Q#cgiuVmhLcdul zWE}v6Tlp9=fsFUrmt;b>m&!jf0(NH zd$2qjTpqco#J~ta_2TfM8iR-sOxY|y(7O@dM*FH^f_%O;-Y#Uof+M^BUV6=BA-*Z0 zNjoaQJUJ98>>QNAEPA1XKwgDA5!ExR!qRiS22jMgY4HLS}%H^4Yk$oN7&e%EF z_Zz{U-4&RKU^?Wt({nE(JtkO?|A6)KTG%TeBqhG>PU2rs%Zs(O^_O5BEK^ldl?io^ z(2?qVu*^1kM>z@oq6Y;D<{8bDLY^ReZWC=gb38^kbxA=UyWKf% zhcUsJBZhj_hME_cRV}EH|3GWOB}5J-ay6p>tfO_3=vb6wD^#`M(TA);LJ8@H>4M}oXkV94Kn#I;E%E{DAR!sWQq zSK_BI#{944X1XkbFvX64OpufcFnW5GgLzJb;ehKDApF-70Rh=-p5Ei^^*e(*dhJDd*!F@T(+QDzaHYaeRq+IuKqM&jd_pv9iOX-gpyKvDNiKwpL zw=N{e}5&xn-?NRfgdV}}{c7z_1Oa@ci*2NH!yrtGL z9=t+@QT0#1(pdk90xv$7eyZ?&3gIH&ZVdE;qWKC|+7ZLt)j)llu-|^rd)BQ?o)lk$ zH+)6R=Z#OPUKqY5vy}V3D5uc=P+=L;oXr2JuvG-_7_S;_Rd;W;Glc?~l2M_%jRtG= zgI*b*H^2Ey3#or6Y@p2P8D{N(W!P5gbzI zu50`}50(KyxDUth9d{0nRkD>bV&o%Sfh-$@p#N_U{8n6Cq(IjNN1(^?<*5N6;v^Z@wooPQ~)0IGSVGKGNteFq_9;%Edr%w;@y#hnf0x$c$O|M!lwp}fUA`d9>F;Kn~+ z%-mA1Qw<+xw&Ny;!+@cKE&<~g$XX!0lf)y89@^n=$G0fBVjC>*iE(!Tx7lA9X8L`* zAofhUMO6;bShl=6$d&>=1Ni`2R-`FNftq>qIy>mfgujwq;Ljb!yW?{{++pXoTll;C z`ipDBOsA9z;%N?s_XJ=i8^SpY68Z75AsCZ?=g~Vl_aZd%vgVeiwD_Vl?f;%32VpZW z|EP2}_*~=+yIu022e303#}*aMKKTdJY^B8t?E+gmv2X~)JumMZ=Fn!_ z^eAE936V+I6)&`vzij`O4co|u$&Nf%H!zCGLR2e(Aca}$Q*zWV2Cy!j8&_bSbgoo~ zz1wsqQ?=rvaQI>R3wI4}wK>&euv@b(pFiiKT{5kR_)+YSE?~VNR;i%AcrZVJV!_=* zqDNk-WP2YX*$r+cEO&P%l*zE$)rtqsBWj9w;s__Tg@{pNxAcI!nm06`Q^lkea;Nxi zcC2vUUq2B=nB9;_OlK8B5C&Pk+}CvZ&x-oYYB?Q)@vBnu0&}4X?2z@4Y@g2q0Tn3R zT9Mwc8&3<0HUjq%qhodx65B&_aBh65!OAIFT2yc7S!j9tTK03s+QxRD(xEM{zk?8lGdZbSSQ zL-~|EKJp>OT}$|pr!oF6=W!4tX@Go-w}7|fGnZ5o4-d@x-bIi4VOp7_!IW-$i$RR} zp9NeN$OYS>{^yNd7XGVRj$WSl(HX$1#`q}G={}(D%o+eOh@uFnK zJ5gky{H=N{Odl;iJ`3F6ad}UNBF`S74EWQ!(C=r&-?-58cDL0f3=(|3yDgLMyW`H7Y-VMZfeOxnHr+a zypr~TI(4U7z}xHE?9LGsNqzjLsA>sIFzZzK>&IF7fz*eg2XP^s|KyHdUV2wh$J^^m zcmTqhCz)qKjjz&j<@h}mggWp; zq%25H6jNjwi2~o37H~3h=lW*<>@f8kLF~C6c`{zqAzPf*I?g|-M|v0ub$|P1>7N?Q zSnlpoUW2eu(G4x$W3&VgHg_NA7n3=NsygyvmQW!or84`h1I*cBLneW!<+?maOW%`| zu&QwQ+Y6~z8ubS+vAv$ivbB1G1JxUXLMi8vb4Wwi%c^z`&;Fsuo4ZpXtt592!&__1b{&fB?jI>$D!>5)n5YH$9n8$>W5jhW)G;7j{x)8KnN!S+; ztypk|&yWK?ZcsUM1ey`^#i2^e6Q3Vwn za(gr$;rZ!~8Z98;I;DEZ!=bsd?;h*u-1kOsL*~vk8to;4s+ME74#$N14y`H77fuMh zi}yL3&_D^5p9SE%9^?OvxY7N_6V1BLKs5x@CLc;;l1Gy%KK$MW-QVTvD~u?0En}2c z;LCDjn9?KaTdo~in5#PC&5L>~d7>Q0K<2n=ZH4%pt6it$^j6aRi!%ls^({Xb=#N7D z+!No3l+Apzo!AEn{^0l%(#0G6yOl!|SSE)-gK+!(Ki_mCG>9SXHYj=h@rlvNb54;( z=f58GsU@5EY!|bN(ufW%*LJrZyCc%Q{%n}U80^C*zyfrMbj1nm*(gg_;EWNBZbDn@ zwY))gozQPTR&4q zHnRir`d7OZ>-OecD~}63h|r>&(-+%QlmqJ=r@Q42ht6`7n`cr6~QE)hJOF17dS*dPG}FVaMNHm zh9P&tTF)DF1jE4c4L?8MWf zqP-FMVI-ChI1iSGwUF$QoVKcMDrU0ZrX9U98-hA=$tF*+S`P5BFoMzTPH(RpkVzR3 zXz|6!{Q30O(+|>?Lm(0t`|s!{`5ib`SXq3LacDDev2UyABbE4>EM4P6&{G|I;^^2Z zzu5S>W8zNiY0tZ*Jw2p#DnP!Zj~(TGLtVJAE-;oau&nTsF2&B2?9UgUCT&r`dKhoY zyi+~FyGroQH*5&_`-3^L*@a>>+i`;M!0SydC6KC#REbQ zg4tu5Cb58c|3y`(-qoIyacz9G8DJ~yYP-cY{4S{$w?jRlO6Q&IOJ@N9z;GxSg1T$E(J6KRQYo0zaClnf{&~F*mmUo zf!X+zPYd2ZNv>H7`nWp)@Egh_KBTLZevY_kt`Z-Vfl;4O@t z{((R(lH`^@0GCpokc-mdmu2btA@(2ME)FIqjf*6xCiF4$ySd-+5b;DM?aM&}wG z$XZrrX4`$u5_uN~n{%UpJJ0=ZWbURZ@_u2n{+DD}+)Dhk@JWtSH4zxgOyu7Vv=1;7 z(2{wpIceuS-{VUpEpEg3|H+>pK1_IPjx$;&Dv!Nz5~D6dpHmAEJg$O~d*+hV<-?d)!>~RXYM;HFujSbJ0(2ky6Z<<{s^ih5C!8`dYnDBnfFc3;UUZqj0Qc;+@KyIIv z2)@ZE)E_`zf4cy6FaE5=TRN2@>&)n#9G%}Pku-aza59%g(`DwAwt-p}SbmtAo!xo= z?=B{0fax>iV5;>X0j9CA!PP<)z}oup=nysQZ1-NoMaqrtaWB-maKlAgn*{f~nmvt} z@@V!lk5B;?@9r57Hzxn8!*w}!5<1lxsO+(n(^*;;JAsRQRf}2wEhK9v*27x0Kb|&k z;~xxp)WaO>1eZ-8J53*>=I?Ej-Vu|Xi{@lIdoP_Px;mv+H)w~-f7JydqAWXE7ES#A zndBZcJUZ#f*V+<@Uuw|iG3;dy#B+$G{~%iOzlL--nmY~9~$r^J6nA8TUVT!`}YIa=^(A#M#gNiT2_1&1J?Lidz+ zJUi!o*dGA#KDy|arWUr5TN4*HZ7Yy~gJT{(E{|x7-uf<&HjCbj<}rE>HZwwTv*+2( z^$4qTIfjT$wX1_9?FAh?ld8o1M+1&W)|N@qdrU<3i#%{N%Rv|zW_4CGM;#Mh@U^xo z&0Tad2o8t8rWA`M-Qq0TJjczPW2ib4^*Q;X1cJjkvaP!DIx)(RES?VOCD*~cSI>3N zsvmpz=*?VUXWx6mEeEP@KvUuLD``F1-saMUCrwwX7Y3h^yYQJOZEdQetvl(sJs0&} z)P+_QnImUm^1BRUV@O;?^D!T}bIgj*X5_F6n0dx&<0$WNdH?oe)RV&sd&`rm z=yww$UpN8SMZ;T?KxDL9|oY1Fri;5>9Tmb44w*lC=F>Z20z>n5n@v zc>3v1y7kp;$_#kM98UzLsebfw5# zeRGW3RySyP2$%|Zeobi6&@)i=m(d%LReYfQE2XE$mKM>>b;xx&{&So~l>OULDBbTu zjl4fI4o z5C#p{lA)qfTi}GP4#?pCi>0%<^-TD>KA6n;a6=)QTpk~}<-xahiOg9ZE>J{{S&jX` z>dvS5Btoo!Kpkr)MGOwOb8ugEkeSje1M>f-{d{@Q^BA@*_y;s!>h}Ct=$sW z_CADE%~YJ9J$5403QL=udzplI8a`>}Qg=p6Z;zf=?YU{*bY9(U(w$Wi>yK1PY5&Nq ztg)C)fwD^!6L0u#lWf3c-uOrZJ4}2Ejs|`|Z4gT^F5Dsx$mp7KfcMl;vQ}b<-=kBC zL^&32aF7@_{bCxuCC{S)UCC#dCW;Yt&~i@*op!`Qc;eL`@8qw2N7C-sX* zRC$Tdc#m8i|8nxW;FHntuDd7cCfU0-OBzs6FlI(&6Frm^M5xvwyn|I-Imn zB1Eo=lgZ8L46BK}?| zEoO|a`M!pIsd<_4SX#!{DllCh`_HD8Mz80u;qS%o>#dixmE5kfR(=(>m~P=mVGuFt zh$;*m>h5*tz^A#1R9T@eSw@f0@DzTt$_*2?bbimLB~NW{M9uWFd4-cvv`$|PNoe~5 zC_==Fdqe?aL?M_DSbA6Zyk%GqSSA69nM9Xwd&lW_LKQd8O2jP3Z3lQqPj>LRLUbad ziWsxeiO_lmSpdv612rr)oBzDxgf))^3JmoLF?p>A2SWMK zxiakUc4QUu(E9%59Tmc&Jw^BRp@~DAt?`i2`o($R0!EYyyEDg9f86>S6Z`8tNdP|x zq3f9QfJIq+7vIkmia0dIJ!5Qc|?rYN&B}%3wE_VpMFHz#OGHzoa{kJT7;!{&> zz&5%klE9qMbX@2{^;|r1kMxA(sN|lJ#`fsN#Dhs#NF(F zDLIox;Hb1sr501fIh&t`+;b4EBJ@|-mB>e~f`GbJkrunJb8)Yc_Gcu0wYm~*@$W#= zh^}kkFc~%MN-VFJl&xxu&{H%dHUA@I;KDb2g0G_5XWwz#)97 z6T5QrIld?<>gj8O4{%f;BQ$yH= zSoG5xkV!~WVE)7HCQ^M^1E%f$E4koZQkIN0SI?4~^c38h#wfkea`yT3x$b_nqon8c z&rMvu)0Fs}`^tM9-c;&0;PM82SLx_tm|3ZW%~7p)3D<5s@^;v`NiF1w$zGX7)aBN@ zQR{snt!BVzvFdX!9ZgzHfIQ0Y=9&3V=D^-SNrFAe;PK;MHAa$c(% z{aQ*n9@5^Gp`rH31jz}&9=ODelKL>s+iiQp{ z#xUO1_b)z^_Gy3lC<{xBfq6Ir0rJI$&TztkE1v*7yx?XkIRObE8;kL`NuHUqC}?Y3Ba53g6VGe+EFW20 zLjvtHKZbPtI~#7DJ$^fi%U!arEFZa_GlXU#@XAwSohms~eUSQJR*C|Hg+Rr-2ek5M zyN*`ZxpUS;87)`GoxURAqTa}$VM1G7Y;CXHGsgN>H(?ifm{7+W`uk?)1F&rN(h zy9);aKyx}bYbK)I!=MTuhm3%PKtEyoe`b*UaZLmGSai#NMUtwPS1MZ?1Lx&5oQ?=q zOBwRo+^0?!GoF-;1Q!}xEN}1oBs=S{X z&;6gCOAwDi4q1y&N!0q`kFrr0T&AD<)F?`ZoG<+yit$Rl0lRP8ir+5`Un0`_;r+t7 zg|#&M0-{}f*IBJ=y_qCcHGg7U{%IE$>-=_chQx4SArH4XRYa&7X|C*fW)=Hi_QF2P z!KBYwlschq%_R;Eo%c~x+;0+Jq(;+}xCYU5 zlt^JLRM0YFAPFkNfJ4 z|9XWeKXUnmmI&jHuyk#>{FV$XVW=mVuAPMrq8#x$sZgj4*y@lN>X>r;xU&2<@&Bg2 zTYi7_$hNc1#!EF?{2RZi5KzLS_jQY-SgI<@hfnM8&=PHT7KJ`xCho9BTuDe`Z-Yu{ zKGO)cI)Hk#rRlqI#US@I?dq332cR@-SS7WRB0N8jlRy&^DMejmJhFb)JyMy5j+q&u zu{eAOHhc%Xsi$|0hC?{ ziEfAQ+6JwV(7sNO2Gej5V;sSyyPS>RZOzuX=Ex9B(d5_FRV%H@zs*vQ-xhQj&)ovg z@MeG)+j&_N$BI|T0$$WT2^!ATyp5G{?V)?q;^nc)i|WF%PCp9&p5O1=vI&OGU9#Am zO9?S)JnH(sqcHU*4OrvoHsXO0V9v~S{JB8yH*1 zlb4n%M_I-j00J0wg_+TZBRer&XtB_Y-5s(~v^D28E}==B_d88u>EZ5Sd)Mhq zBJU3wET1#gQ(mvY4rc6k$teBF^QXhfw8Zah-a$HtHI4D>fMeQ`lDuLvXVkdDyh5J6 z?6@q0Y!iN}{at9;DBTc^OqP69hA0M;6G99|1S2~7Ifj*Lt{V6dqv5{%4Ux`lrE^;`Yt`_)V zn%P-dN==q)G7NlP*Veg#Li?4I1cHXDEiF&cDdb+(l9}%ls1f%`?tT+eu}quq3hRUU zZDidy`*gtHuPvt|r<3GnlKESI1wdRs4c0GxHD2nKY)%$d0=f5N9*37levANOwCT49 zSZa%^Wl&gRP49FWT&tvHymZ^A9lKQfp3HvTG2l}U_1=bYWGgnwD70n_e$B*a1}FGd zu&@hk9L3O2HP^P;wQ;TC>WgidFvODm==>i5F+k40-&;Jw4(?Gb=0gNuphfh}iIeOb zuUD{;rBjpkGu31XX_Y^0uCs*kj>;E&)Kd@<9UB`L<0>2|74pvEee)$7=87tw(k9jR zjSVq*5Widd#;h*y&=n);=tQy z82@(M+wsSoKPW%M#l)~=B|%M!Nr+8|OO7{L;zHv?lY1o$PPjU5o6{7ZAW3nF31JDE zRZfspEk2GbVNr^;mCf^6EWYTll6niXw8{m(FuR(#ErIP$csM~yI4l>SOSiT#DJ-Rx zZS`46`*2j$w5Y{V>!XyYR%Y@=`S4zdg$3dZ=XB&t^;jf z_OSvy?q2|n1c1=t7?sjUGj<>v; z$MRa`UI%2=9?N1|+3o|$K5uTXd+B#UaL83 ze;v9Yxz+SdbDiDVKF$DN$h`%>!`Q}(0d^TuH!fDFtU?;|#qH+noX-Z+ynanr-aV=8 z@VfdXJKFwv^~_vXLSn=vah|L>H@OoX-kl?zqjnFuy!N(v%CM_%Trg_#4ZC_CywrdB zp7M<3Y_nRTh3={wRn<4Sdud9@g;$Q6yZ%1@|670?9Kw7E!Ag+@Kj(N?53slrXEJg;}v`yZItb=4g}2Y?c+17G@@gm02HUx5HiyWxIV= zm1!2UrkPbGEKGTn4aIsivpK#{i^V3h-SWe-B)78feDSPAEMFU|1*be_lWm&M#7qg{ z9oFd5Vlk%0SfFtJ-OerBlA_#zrDH#}tT>`5LM%v_I0|GdciL<=@X}?_$Ckn@3{%XK zRckfJ`9kVUAy%uxo5dwBMx+25T7(!C7UPa^Ls4S|AWS}V@ZM8TNh>e9w=Io*eQn#V zY)-wr;p8>aou{Vp)ieXEX|+0>Tx^8syFvFTEV3qLe#&}vy|zC28f9y;sZc6(O^_!z zC%G1OTcxhk*^Z=4OWSp`P{W`$&Kar z!$G^$=wdEjh|l8m*&FSWJt6flyODh+diVHL2qXJc-jibC90vo08+w6QE|5)}<83nc z@T%xq;+_E0^I4a%WzsU|2DU-k;MBnVIMV~q8#JZb7rIbc962jxiMk|Nom#_hc-01F?W5*8oAu0*i3yiYL7Bw$w1{4jX}t>=Ea~>~f#8yNUU~oB3)8k= zx8douYC#my1)=_soclFF;{=L`iozlXR53(U` z)u+lgjjR2jEcc$9_xD~B$lEdYl%u4sEYsZ0*(YTQ{^m68TqWW z)<)|K?0M-g>@U(WD~5oDGP3%tvZN}|!>{)x%2Ko}ONwk&eS-_t519s{eaNtgTG=fJ z8$(%WLYR73`jlkp6JHo9cEzWRRvHymc})5{g&E_-ZQbKS)O^i#1+V>tH=xyT3SalM zu{10z)D_y5>Xn*eEDPuY%h2yh2SY+gfezDZb~M*fVB$v#(GM$!?_xmJHD$akz13E{ zgx%P-Woh2{f@F1g`j3w*&m{Gzg+)tiF?$;@dlM*~3fMhj{vL+?U@34EWMwQaSd&^G zS|3)QSf8}PQ=i^Y@Id^%iT8V2!uBUVlKyDMGa=7}zGaOyQ3%tlQlcdz)*6@Sv3kO* z*fs15>&Ea0D7-)QV^vhehIXIEF36Ztuz(h@`O@6<1sU@SE@f*oR%Nd(*rse#>rM6M z4G|k6w?%J@y;<35z9C{~|19IP{7jS8lF^TfSl@iL z+)QDK8H#w=KTN}>BPM95fC zSy)jad2znD?QwEkLa)Q@3xla~6X$Ee&`uoxI$-7S<-@ogj3txr%}q&-h*iun9+&Ed zNn=W$!Lp;XW>Akv$ofp8I&856IeLL%HfiqGdlcRmh?zs7-c9?8WzmQ z`|C6{DyP--L33SHaOK1a!IFO3s5ZsM1uRdoG3n`TEE>LqqBKqn@z1WlbLvYE-1En} zeg2~1?=(GGH*q!Vd5Le;oH_M{J$sKEy>(IDhV;SGzAGCiUin1xvf;ZHZXP*j>9!YF zPhUQ{>CL)zqvl_{YE-Xzxow|R-dlV5ZEGeCDOv#DHwG(e4`xpsWw3z#TySZ|+v;1X zZ)Yg;l-24w^BT*=VV77}M_ugPV!k3O#A4o-DfKt28S$=+cvVjEC}dI(vzZjneETy- zLso+$`YgGg#U7X&l)?uxTm^5uW`A59S>rk9OJuf3DAFG3jFcl=*=%sZOkZYwrtHhC z&1}p(mZ@Yi&O2R5<_mcuL<&jheuhqWBB0cr3dp7sgDKj-=3BuL0p3^?7}>0(G;>5) zy4}+)-JR~Rx@J(ajT@SHK#61XDc;~5xG!4m5>9D6PEj`iDKnse#1_g}o@y=U)y zTq=kxTRo!Ys+!ViJud6!kyf&_hiCuok>)KAH0=B7!?x9zFOUvx7&-leOB#2*e(}U? zz6B&y>MiHq-x0NJ^vWt__Xz*b3* z(o<1o0auy$9~w#Zs|%?cIi&G{GYr8GBbg&bN=YV2DN1%Q$g1ea1t34#e;u!7HVr)_N|HIgu0Jc%x`Q!6uMsw&K-6M^pnb9rFmd2K3TecI8$$eo% zoWltwrldfN+t?|NnEMd2ikv(!BRQKHuZL2|9z46cWRXie4L%D52t@w!VnVYz~(P zGDfqKG@64EquGy}4|s8*-zT_>Hire?yzE%+SS&1y^r-!gb;26Y`p9P;mkU=!wh3eO z4*Ttn9l{RR&d6=@*BxIM9&mm=a@28DcrJJ}@?*!3gdc`~6#1p&b>V%-yTZGXj~ss& zJ_>&nY2+O%BvOXj1$Gham%g`)f{T>QCJq`}} zcn&%0vi=q{`dKHokP(5ZEEbhswba_y+6D^1aED+AriG*)pZd#1(aulR)~pE>=7Tq5 z;Pvvr>Z$iGD5pRF&IjP-*LqTNo=qeiqINfZ(V6>iyTFu4&^fhn6R?r-sb8V!Ta+N^ zcOd475Lu#~{5LEkwGG6E$WG$6$j-t8!EdDY2KT1k3;sU!yS%lXxIT4V;lY*%3XjI0 zD7+qgJ@tCpOm|et-yL*Z-r9jEDikfEQvW|*f3cvejc^l)6kGII8g8U;abbL6VrTFT z@LK#Ah2JJvIt~)H7J>3IQqU9e#eHe7mTOrQUtU}X)(1AE?j@Z9A#|((8{&fF7>O1DOK6~;P#l>bHk{rErPfqu>*OS~EtWXY$-3UPv>8;Md@j#JT0 zdt-shMbo7c@5`k9ejk}jBPtt*s2H(KM+q0_pmk!YuNx;nsnxavo+2$+~G*D;&A>2>(L?h#NlWQ8S4hP!WY;YTe zeBcnsH4X*sIvy%_JPUqGsKg~egmN!?{^@MCYt>0ecT)o+*?|%C&Yfne={*S-C;OpE z--W1q^du(EQA5SR4-PY8XOG`7Fa2fYpMy%KJ70{Y#Ry=7Qa~aZCK-pSuaHcO$pXl; z%>@vPBnwm#G#99plqmqslq(R4aI`=~TBuS1qDY}D+ch^BhP?^UR0X4>qr~XQIj}(> zrF4LZma6OrhlZk2-j}ViA08O;Ww1{2c_Fh*4EadDvC2*z7~*qP_I+5?9fyd8;7!m6 zF%jk;1AQi@*nf#@P+tYkmJj-R}Dab#HJl^$f*ZDLYMums0(dDbEScxC9}+ z=@2Oa@HA1SRvcCyG^IlnsFH6Ta%T4lK&VpPhj!U^+ellL%IkR#kKSboK#Q>VDJPJf z6({Ko>X4xME=2?mQ5H!Nlbg6KvH4OAOR@u_*pL3<=m-RxBPb$0a(dwOJC&0koQC2L z;m=nvxhP(Vv9gI^(vtKg7>REptX{a`0;VQl_S>2e5&?5@$SAbRpkP))f)FA}Pbf}> zOmJW)hC-Cbh8;>C-T)&NLom*G58W|5SftnE!v1qVL&p?^GhK0nP|%3C(La^t`R{yl z$1iT&cJlt4e{`LES?$y_wWp5Wei&4qyL(rIOY#IQrYmcOpB&y<``KI7+MmZq9`hV} z>>p2`{W0i!W~t9DX;9P0pr%LO4>PR^cAuKLyh^VVh@%aKHNj?<>+P z;hzbd=yZ9)5sLMK9l_foWSV1SiGaqAEZNkUUk%7 zV~1qI6y8E)Ihy?t59TcEmuFZ#6pT2$Lc)`bI6`Yd&)N8yIGW+3nnRevBDo zcX7LTJ}ygPHJXs6tQzBV)S;Yex68c5v1lk%)WWJHDKioq5+oADAO;H;h)1(IqDepw zT=GAl%4^I*ntU`Yy&DRJIest4F?%b>t4pu~+rv`uUhn9=_+Hy`dmFQIQyyMA6x^#o zRQHxdNvnHH!_fGnN`!!iTEL?!;Gq_xi8vnWIBtyNp^iUPJaH84z`z#`GahTms{%uj)*MxNYJ6Bzy&F@ZMedc{l%PRh0yicRO zj+D31lK!-boO(Bw+geLs8j7WB-5XMVB|rbh+TMg;&@ZJ%z7$C(YCpfS*Xuxj7ZuWq z3~8kaT#HeBI$s45y)Ci1m8W_0zC3k*_UY`)**B>F$i7FvXFfxpG4sQwVP-p|o-xxH zvkOuW$C~*Dl2xtNDoE-!PGZBdU6ow26d71P9jN zM8uLrT1b;=L_>*GDoOhMTq>L1OJo3%(Vz)A3@yiThLKs&!-D6rDSAlH5q3-?c1#X- zOe6MaB#db!j2pw4M#2x}{+l>B4W&UBPNsPqN9Tk;44fkiY;0m%Gh3&NshJWI#|UyY zXC>X5$s|ptB**!a01E3rBjWHU4dO^9aD*U9di)|L3qNPX_C84#m?jVbK$6Ijv6$1y zWhr>)sO=eQfXBhZe_PXIOC&&Q(Zavk%u1uyJoU8JmlSPg84@n_CtEDI=+mEtB=G)< zEwxh5@oGI@o$GH!KbZu5B0>#{>JseE~~Tew$^7g%VqH!QR&4);sBcp-;5ZR_a#EWGl6l zgQG0|CF(*n5G!K+d=Tqra1f&I75aka2OIsO7-iCplsz5gK~|1f(Ktr%kVP0YWRa-T z+3Om2kq%dni$pqNyKCA-yJ$4FE~qHpp1_KtO8#B9n7ewDz>$=bBm|zPbOGHaDWK!Y zWu?ux*GC=-ekc#}Sv>HV2HwU-G8%JXMw8dIK~c%F0+&dqGO30X#aJQmbEwWvpvZ!g z&6=ACTMTXl#okHqDW(Zn685ILn*mu-I2evqd=|+PfS{hFo12>(Niy2#^9LbK==_l1 zA8jmBjSN&46GM$u)Q+)Ubgs(B5sNumAJT$?3?oDBI}v6psa_N}_c|fi!x#VxlXH&r zHu^nCJbl-Fw>Gt78&G;I z0#DES0FErtQP&fR>hy<)(6}aw)#+6${Bq+5#`jmlC;jTU7or$!ga z(tI^a%92@)xn)UGV^B>tsj-qQ%~NBr7h>_aG=JVai^WXlnwml(iF3K5q#gxtMS&94 zqQlWW(c{q*Q6^d?6+I{{8C){Cgi@A(C5sZ#Qg3mvNERPje95oG>?+~(C`#xQMne;owdbvT4+QdzA$2p3l(P(aaknQvCj3$T?ALG|Va4g+P)^v3G2p_z*ty6BHn}%>$j$y?|1H)h z9g_)@O9Wa%Pmn>*=*%$gMxPiGd;t=Wnn(ALy&mAHQszT}w2cpks?-0#eFH0}Cs3cE zimsx53q^Te<8*Epx0`#4Gd<6}#ZAMWCF@=Jd)*9@4_+}WowK`6CMw+ zL74vjp&=Vj0|NIqAnW~IkJQZeFf;1_u1CP?qwp&3XmPqJ`Dt>D+^LU~59kMN6ZWSIPcQgS+s|8UE(@USBtx27 z?jUxwJVfjTd+a}L;VcA7&NEqMK4NPi5+Ki4_#XaF;^pES#Gi`}-V(5AphOn*^Yq?D z-v$qpkLriX!{&YG9V32490xxmU!&e9-Up|^U(Khif3}Ifg0EO?(TaWG0pe@6dt2@) z^7UAlns-DaU6Dl#y@XdI?HWO)L|;G>8Ij8*rBr8%M8a(9CA>jimJvK)`Kc~RFEch) zVi0mrqj_0MtI@9Rc~X~&rX`aDBMDiSQfjQT*dcWSf{5B}9%x8*69jUM_Gv|rrWFZb zD|VX}X+(FC?yv#UYBBRHYag~hZzt_ZmS$O>FR)ka>g-IXQ}a4HAb{JO68(OLF{MZo z*L62-*R(u6W&*<|V5*Ysx>dLJ+Q=~**k^+nkNik)%sVjVbYRWo!1~G&g#ZRoZ5_a1 z`4D+%;i6|j7j{ntX53RV;1j~mQIvXw6C2*1$>m0Ni7@-m*nvGXkcWMRf*&Y6Z^uc6 zJCIWrmUWjbL>;r<*!m8NMnY4S7#Ur#Ugz_LrtbWCO$+FO{(&rt+nZZOpRHn6Jmr?^ z^ohelSr_bOl-hs5UM6760lYVPKtOww`(be|t-IfdiAlO$vlEnS%9Gj*PT%ma>!xn# zD7Z_tM$B)ysqfB_f9K`$jk4&u8f4~64J|VGbK}x0R{9Q+r)rKH`k^tE62)W@{G_(x zWB52K8Y)KLT)V_Q1cZ(0h(8ALwy(0-a}@Gy2HHzUAkQkqZ!phF0wDl}P=Fp?M_x`| zL*A}DpggV|RjeRd1$XHM`{vd)C-s94RYGs14twytS}0( zf^-N%aF^h~rmH|wp(=a&zz{{_v7%;7*A_$k0YCK#=b<-Q2M5?_ZKdy3x1M>Yur}ev z&Wg*1)+vIu<)%yj`HNS8YuMU&qFvcaU5OkO3DBTlcXsb;+3U$&O&GF|`7`WCjihlu zzUvTyo#6cTfGzFFI2ve;bxpgRb%Cwg?Zi&;7VQDz zKJ9Vh+uEL%eJ!v0UlAu;e&v5dJl=BB|9kQGffFqs694f3O-n2V%lwP;8$iE*ZT_?V zYXdKfFKMrduW7#(f2-LI&$%K?K{cAgQVXI)PK_D9bQMc1Wa<#WLx=$a1Vj;utNB{q zqltbkFXllW{&s&b5b%>c#}S04rP7?X5n`J_J{MIKb&tAFML6Pw%BTwY71d$G&1U7y}=Gx4~F` zUECK+^ya4~wRJJy)L-eV&u+U>Zb&4G$|$vMLpq#FocSeN6` z?ctR~3j7UI<%-)~z_kkiQtv74B7rMRf)v^0Zg*enzMp)HoF-X!H0lzNWe`=7We}wh zMZ`RaB4RF=6F_^<74^7WQ78?*r8`o4ftlw4DFrzfPvMcYx>h@#il7O)KnYOrPB`JP z3Nye7Rj^A`cqoHoCzX<(0ZIm-XgZm3d(bVss;Wi7WE5Ia*lNNCa1@!sW^7Ld(wBT| zMnV|4>6|wdHo*EjIML3al9MNQ)HA?bWl+Y%!J>qHVgM%rBI@g$*BS0Ktvt(8_8Iy*vy)zU_PKM^_SB+AH~dxD|8lMAO2SG= z#J^*TYrfC*82h;Sae=-DT*vMJx3TmB&Xy)9Z<^u7E}6oH*Uzzq~H*&^uuq*EFDCKiki(93w zp)aI|bN7VU>%=4Rr_;Zbei`~joC&0aTsm1!lvAB)Ew>@{nbdG@EN6L{0Krfuv?BEL zz%M1!V`=cC_#6IT#NSB0o_;^hg!EWA&DoJ?j{;d@)fg1~UNuI9mBxl}x)SS&k+B%- zZAklkUXo)u7ZDVKT2K!T2Tj3cxq2*v$N@dKFGudqP3Dg0s9Yn!Djr~E4zP*`QHLG# zaNVbgHN5?yrd$wF2S_Eku-9755z^((Fxq$JEFjKOY)`IOHI_W_;;E}QTFF9 zi&H${6UoF9Vm;VGZi(LjZXmCcuTr)}uT9(zb}08ZJqeyn97#UgG#&Rc%FW=;_|2&Y zz_hE{lIAZ*JhoPzZQs$)QGxL|P)C zg>8qnHS#{ibh0rKk4H)1AxRM5ODZJWka-k`WBlmnvI5)74zkoZP6#HXy`f?id_{M( zq{HD5>9E_O;m5gfa?5%nxn)sLiBO+X$sPzRNcE7=3iQ_D*5j>IYmvjW$l-qAFfDRX zpBK}j7dLt_EqWg+U2+r~G#~S(3j@esmCYhL%o}u=uhU^2exMnu(3Ba?XOUeK2nr`> zY#87w2gSP4lEt$sjH#=krshaYPBg{x1<)LUn_RT9K*Zvj(oz7#OoBeN=tqr6D%LXz zJkbGKE~gH7%4uZTc(CGt)l-LrvL-m7ssM(DfPe+LUE+;&m3;Wz3@@HAo6}5Y7rGjFM z2%+T45+-mArNJLwKep@PCxJM4`u(p%C)w093!+x`4NA@xL zv4Y^T6>LRYDO?B_!zC2TZ=#imB4;v9h52AUS)sLn7SUu)omZS!T54O`&}Ug|TPLi| ztj&gHAd^x-E=jF@Vqc&y*xzzd;iBS2rHfiOwAm?(CF8b8nV3cC=*(yxqpnf+&iMW8 z{rLy9$MTcu?=`%fo$NT(;W?jcmxwK-^c46BAi;J}&jiqIr3afsQh19jMIuj!QA;uK zpr-*+tJUtYTJ2eDgPl(DxL{&n3R)!TW-69O83I6$M2i5(DA5JPbRqA2-budY1d8)1 z=UYz7StWNIk@rTj0-DJLPmp)#!1K93=BA-o*O!#^+)v;RMdXy628BJHdloDv%3v{0 zR6z=PAUgt8@#twZ0cmt<6cUl4m$A&Qr+_0<-)`9WGtmiL8vw!xtQ*r?;u`BtCoPS9 zfyg+JKzG9ptHE7!leIuttc}@}0L8n*o@q$9por)44B{RmOo2Buxvmhtj}9PT!KIeV zY?lj{W|6M|K>b3D7^(hNi|8oRnxkCM92ju*OS-#MY7PXNNwPT-@ieznVZNDxDqv!$ znesrb@W(kB43+;L3`HTW`uyz(SrS!_dO56aenH12q{0jDP3I7CI!>V+6#U0jy z_QMg#fxQN@)1cYVkS}UDe>09tz0VgarkM_AC3BsFPQ((amRL(_QEXA_(G;6Wl~ZJ| zw$*ZjMJUm%*cT6kSMIvvmVaLb^&oPfFOWy3e(~yWzWLyn`~OP1ZahDcD8)yo z_V>Ixx_s-Q*U7|or4jM03tCeDig=c6LliS%b}%wLtsAR^e{4?kj;Ngr#6Pzgl` zE5g+AFs?dLX{FShr4O}g4k^ik_fs~MA`7U_2HVq%%ylwdM!noE1rJ`;rBs-_OA z$5m6^*&ZV7s$%v9eGNX!$J)>%N_Ge_SWdPhKYL|Bn0o1@myr7yd)X!3LzsX>IJ|=7 zuygQa*&mVQ>huoX>0=p%V_AszJP@du7zUAg$>&EikYxu1k_5>z{24#+|4#GizH#3v zAMJZr^XlGS?>_G-uSxL^dWXGZUfNqF-#@IV_o^tv7>cBU!0Cav2Oy2qJy2-&4AN<^ z6mjK$PbxMhna%!T%r=k(qevC;X391_?$T3qQ!RO*FpFR6q%DJ^ET(Us< z0;yD*{tbI0q|!2V;cUG8Fb~=@Ne_~-$lXDv$Plkdw8ceQI06N-{pAWK)^p?<;29fh z<;*;5Hfv0ob=gIC*$O`rB36zsN+=%}mLXW`@4`weU&=4%`|0)kcX%erWVuF5+M0H! zgBhtIooa4n%E6+xgjvY0uq>7OnDy*>uHU@gx<0sG>udfDvzZ;TToJrNy0Wm1-o|WW zx0$cC++e*Sc&&6}=vw9K{4MmI-0h*;^0#R_o4?9FV7c3UxA;Kte(7uJd-7k?9^;oX~!teZ+laIUD{+S$;+S)7llyJ9)ZY8j5U@Ki@=u zn*B6)1y8NuSISG%EAn)|v@U;vM)k72+y)CpvxFH!#E>uF5X#8SY}qmsh6)p|&JIcA zL$t+d^sMCKSPQUl<&+Dt2IP${%p5PhbZ$R7#f&1USDlR~f|ln--U z6nT8Ld^5wc=txLwhP%yfS1O%`#yLS+%w~>b`Ob%!N1Nf89nee7MuIg?m`*lnMXh